Mercurial > hg > rr-repo
comparison modules/system/system.api.php @ 0:ff03f76ab3fe
initial version
author | danieleb <danielebarchiesi@me.com> |
---|---|
date | Wed, 21 Aug 2013 18:51:11 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:ff03f76ab3fe |
---|---|
1 <?php | |
2 | |
3 /** | |
4 * @file | |
5 * Hooks provided by Drupal core and the System module. | |
6 */ | |
7 | |
8 /** | |
9 * @addtogroup hooks | |
10 * @{ | |
11 */ | |
12 | |
13 /** | |
14 * Defines one or more hooks that are exposed by a module. | |
15 * | |
16 * Normally hooks do not need to be explicitly defined. However, by declaring a | |
17 * hook explicitly, a module may define a "group" for it. Modules that implement | |
18 * a hook may then place their implementation in either $module.module or in | |
19 * $module.$group.inc. If the hook is located in $module.$group.inc, then that | |
20 * file will be automatically loaded when needed. | |
21 * In general, hooks that are rarely invoked and/or are very large should be | |
22 * placed in a separate include file, while hooks that are very short or very | |
23 * frequently called should be left in the main module file so that they are | |
24 * always available. | |
25 * | |
26 * @return | |
27 * An associative array whose keys are hook names and whose values are an | |
28 * associative array containing: | |
29 * - group: A string defining the group to which the hook belongs. The module | |
30 * system will determine whether a file with the name $module.$group.inc | |
31 * exists, and automatically load it when required. | |
32 * | |
33 * See system_hook_info() for all hook groups defined by Drupal core. | |
34 * | |
35 * @see hook_hook_info_alter(). | |
36 */ | |
37 function hook_hook_info() { | |
38 $hooks['token_info'] = array( | |
39 'group' => 'tokens', | |
40 ); | |
41 $hooks['tokens'] = array( | |
42 'group' => 'tokens', | |
43 ); | |
44 return $hooks; | |
45 } | |
46 | |
47 /** | |
48 * Alter information from hook_hook_info(). | |
49 * | |
50 * @param $hooks | |
51 * Information gathered by module_hook_info() from other modules' | |
52 * implementations of hook_hook_info(). Alter this array directly. | |
53 * See hook_hook_info() for information on what this may contain. | |
54 */ | |
55 function hook_hook_info_alter(&$hooks) { | |
56 // Our module wants to completely override the core tokens, so make | |
57 // sure the core token hooks are not found. | |
58 $hooks['token_info']['group'] = 'mytokens'; | |
59 $hooks['tokens']['group'] = 'mytokens'; | |
60 } | |
61 | |
62 /** | |
63 * Inform the base system and the Field API about one or more entity types. | |
64 * | |
65 * Inform the system about one or more entity types (i.e., object types that | |
66 * can be loaded via entity_load() and, optionally, to which fields can be | |
67 * attached). | |
68 * | |
69 * @return | |
70 * An array whose keys are entity type names and whose values identify | |
71 * properties of those types that the system needs to know about: | |
72 * - label: The human-readable name of the type. | |
73 * - controller class: The name of the class that is used to load the objects. | |
74 * The class has to implement the DrupalEntityControllerInterface interface. | |
75 * Leave blank to use the DrupalDefaultEntityController implementation. | |
76 * - base table: (used by DrupalDefaultEntityController) The name of the | |
77 * entity type's base table. | |
78 * - revision table: The name of the entity type's revision table (if any). | |
79 * - static cache: (used by DrupalDefaultEntityController) FALSE to disable | |
80 * static caching of entities during a page request. Defaults to TRUE. | |
81 * - field cache: (used by Field API loading and saving of field data) FALSE | |
82 * to disable Field API's persistent cache of field data. Only recommended | |
83 * if a higher level persistent cache is available for the entity type. | |
84 * Defaults to TRUE. | |
85 * - load hook: The name of the hook which should be invoked by | |
86 * DrupalDefaultEntityController:attachLoad(), for example 'node_load'. | |
87 * - uri callback: The name of an implementation of | |
88 * callback_entity_info_uri(). | |
89 * - label callback: (optional) The name of an implementation of | |
90 * callback_entity_info_label(), which returns the label of the entity. The | |
91 * entity label is the main string associated with an entity; for example, | |
92 * the title of a node or the subject of a comment. If there is an entity | |
93 * object property that defines the label, then using the 'label' element of | |
94 * the 'entity keys' return value component suffices to provide this | |
95 * information (see below). Alternatively, specifying this callback allows | |
96 * more complex logic to determine the label of an entity. See also the | |
97 * entity_label() function, which implements this logic. | |
98 * - language callback: (optional) The name of an implementation of | |
99 * callback_entity_info_language(). In most situations, when needing to | |
100 * determine this value, inspecting a property named after the 'language' | |
101 * element of the 'entity keys' should be enough. The language callback is | |
102 * meant to be used primarily for temporary alterations of the property | |
103 * value: entity-defining modules are encouraged to always define a | |
104 * language property, instead of using the callback as main entity language | |
105 * source. In fact not having a language property defined is likely to | |
106 * prevent an entity from being queried by language. Moreover, given that | |
107 * entity_language() is not necessarily used everywhere it would be | |
108 * appropriate, modules implementing the language callback should be aware | |
109 * that this might not be always called. | |
110 * - fieldable: Set to TRUE if you want your entity type to accept fields | |
111 * being attached to it. | |
112 * - translation: An associative array of modules registered as field | |
113 * translation handlers. Array keys are the module names, array values | |
114 * can be any data structure the module uses to provide field translation. | |
115 * Any empty value disallows the module to appear as a translation handler. | |
116 * - entity keys: An array describing how the Field API can extract the | |
117 * information it needs from the objects of the type. Elements: | |
118 * - id: The name of the property that contains the primary id of the | |
119 * entity. Every entity object passed to the Field API must have this | |
120 * property and its value must be numeric. | |
121 * - revision: The name of the property that contains the revision id of | |
122 * the entity. The Field API assumes that all revision ids are unique | |
123 * across all entities of a type. This entry can be omitted if the | |
124 * entities of this type are not versionable. | |
125 * - bundle: The name of the property that contains the bundle name for the | |
126 * entity. The bundle name defines which set of fields are attached to | |
127 * the entity (e.g. what nodes call "content type"). This entry can be | |
128 * omitted if this entity type exposes a single bundle (all entities have | |
129 * the same collection of fields). The name of this single bundle will be | |
130 * the same as the entity type. | |
131 * - label: The name of the property that contains the entity label. For | |
132 * example, if the entity's label is located in $entity->subject, then | |
133 * 'subject' should be specified here. If complex logic is required to | |
134 * build the label, a 'label callback' should be defined instead (see | |
135 * the 'label callback' section above for details). | |
136 * - language: The name of the property, typically 'language', that contains | |
137 * the language code representing the language the entity has been created | |
138 * in. This value may be changed when editing the entity and represents | |
139 * the language its textual components are supposed to have. If no | |
140 * language property is available, the 'language callback' may be used | |
141 * instead. This entry can be omitted if the entities of this type are not | |
142 * language-aware. | |
143 * - bundle keys: An array describing how the Field API can extract the | |
144 * information it needs from the bundle objects for this type. This entry | |
145 * is required if the 'path' provided in the 'bundles'/'admin' section | |
146 * identifies the bundle using a named menu placeholder whose loader | |
147 * callback returns an object (e.g., $vocabulary for taxonomy terms, or | |
148 * $node_type for nodes). If the path does not include the bundle, or the | |
149 * bundle is just a string rather than an automatically loaded object, then | |
150 * this can be omitted. Elements: | |
151 * - bundle: The name of the property of the bundle object that contains | |
152 * the name of the bundle object. | |
153 * - bundles: An array describing all bundles for this object type. Keys are | |
154 * bundles machine names, as found in the objects' 'bundle' property | |
155 * (defined in the 'entity keys' entry above). This entry can be omitted if | |
156 * this entity type exposes a single bundle (all entities have the same | |
157 * collection of fields). The name of this single bundle will be the same as | |
158 * the entity type. Elements: | |
159 * - label: The human-readable name of the bundle. | |
160 * - uri callback: Same as the 'uri callback' key documented above for the | |
161 * entity type, but for the bundle only. When determining the URI of an | |
162 * entity, if a 'uri callback' is defined for both the entity type and | |
163 * the bundle, the one for the bundle is used. | |
164 * - admin: An array of information that allows Field UI pages to attach | |
165 * themselves to the existing administration pages for the bundle. | |
166 * Elements: | |
167 * - path: the path of the bundle's main administration page, as defined | |
168 * in hook_menu(). If the path includes a placeholder for the bundle, | |
169 * the 'bundle argument' and 'real path' keys below are required. | |
170 * - bundle argument: The position of the bundle placeholder in 'path', if | |
171 * any. | |
172 * - real path: The actual path (no placeholder) of the bundle's main | |
173 * administration page. This will be used to generate links. | |
174 * - access callback: As in hook_menu(). 'user_access' will be assumed if | |
175 * no value is provided. | |
176 * - access arguments: As in hook_menu(). | |
177 * - view modes: An array describing the view modes for the entity type. View | |
178 * modes let entities be displayed differently depending on the context. | |
179 * For instance, a node can be displayed differently on its own page | |
180 * ('full' mode), on the home page or taxonomy listings ('teaser' mode), or | |
181 * in an RSS feed ('rss' mode). Modules taking part in the display of the | |
182 * entity (notably the Field API) can adjust their behavior depending on | |
183 * the requested view mode. An additional 'default' view mode is available | |
184 * for all entity types. This view mode is not intended for actual entity | |
185 * display, but holds default display settings. For each available view | |
186 * mode, administrators can configure whether it should use its own set of | |
187 * field display settings, or just replicate the settings of the 'default' | |
188 * view mode, thus reducing the amount of display configurations to keep | |
189 * track of. Keys of the array are view mode names. Each view mode is | |
190 * described by an array with the following key/value pairs: | |
191 * - label: The human-readable name of the view mode | |
192 * - custom settings: A boolean specifying whether the view mode should by | |
193 * default use its own custom field display settings. If FALSE, entities | |
194 * displayed in this view mode will reuse the 'default' display settings | |
195 * by default (e.g. right after the module exposing the view mode is | |
196 * enabled), but administrators can later use the Field UI to apply custom | |
197 * display settings specific to the view mode. | |
198 * | |
199 * @see entity_load() | |
200 * @see hook_entity_info_alter() | |
201 */ | |
202 function hook_entity_info() { | |
203 $return = array( | |
204 'node' => array( | |
205 'label' => t('Node'), | |
206 'controller class' => 'NodeController', | |
207 'base table' => 'node', | |
208 'revision table' => 'node_revision', | |
209 'uri callback' => 'node_uri', | |
210 'fieldable' => TRUE, | |
211 'translation' => array( | |
212 'locale' => TRUE, | |
213 ), | |
214 'entity keys' => array( | |
215 'id' => 'nid', | |
216 'revision' => 'vid', | |
217 'bundle' => 'type', | |
218 'language' => 'language', | |
219 ), | |
220 'bundle keys' => array( | |
221 'bundle' => 'type', | |
222 ), | |
223 'bundles' => array(), | |
224 'view modes' => array( | |
225 'full' => array( | |
226 'label' => t('Full content'), | |
227 'custom settings' => FALSE, | |
228 ), | |
229 'teaser' => array( | |
230 'label' => t('Teaser'), | |
231 'custom settings' => TRUE, | |
232 ), | |
233 'rss' => array( | |
234 'label' => t('RSS'), | |
235 'custom settings' => FALSE, | |
236 ), | |
237 ), | |
238 ), | |
239 ); | |
240 | |
241 // Search integration is provided by node.module, so search-related | |
242 // view modes for nodes are defined here and not in search.module. | |
243 if (module_exists('search')) { | |
244 $return['node']['view modes'] += array( | |
245 'search_index' => array( | |
246 'label' => t('Search index'), | |
247 'custom settings' => FALSE, | |
248 ), | |
249 'search_result' => array( | |
250 'label' => t('Search result'), | |
251 'custom settings' => FALSE, | |
252 ), | |
253 ); | |
254 } | |
255 | |
256 // Bundles must provide a human readable name so we can create help and error | |
257 // messages, and the path to attach Field admin pages to. | |
258 foreach (node_type_get_names() as $type => $name) { | |
259 $return['node']['bundles'][$type] = array( | |
260 'label' => $name, | |
261 'admin' => array( | |
262 'path' => 'admin/structure/types/manage/%node_type', | |
263 'real path' => 'admin/structure/types/manage/' . str_replace('_', '-', $type), | |
264 'bundle argument' => 4, | |
265 'access arguments' => array('administer content types'), | |
266 ), | |
267 ); | |
268 } | |
269 | |
270 return $return; | |
271 } | |
272 | |
273 /** | |
274 * Alter the entity info. | |
275 * | |
276 * Modules may implement this hook to alter the information that defines an | |
277 * entity. All properties that are available in hook_entity_info() can be | |
278 * altered here. | |
279 * | |
280 * @param $entity_info | |
281 * The entity info array, keyed by entity name. | |
282 * | |
283 * @see hook_entity_info() | |
284 */ | |
285 function hook_entity_info_alter(&$entity_info) { | |
286 // Set the controller class for nodes to an alternate implementation of the | |
287 // DrupalEntityController interface. | |
288 $entity_info['node']['controller class'] = 'MyCustomNodeController'; | |
289 } | |
290 | |
291 /** | |
292 * Act on entities when loaded. | |
293 * | |
294 * This is a generic load hook called for all entity types loaded via the | |
295 * entity API. | |
296 * | |
297 * @param $entities | |
298 * The entities keyed by entity ID. | |
299 * @param $type | |
300 * The type of entities being loaded (i.e. node, user, comment). | |
301 */ | |
302 function hook_entity_load($entities, $type) { | |
303 foreach ($entities as $entity) { | |
304 $entity->foo = mymodule_add_something($entity, $type); | |
305 } | |
306 } | |
307 | |
308 /** | |
309 * Act on an entity before it is about to be created or updated. | |
310 * | |
311 * @param $entity | |
312 * The entity object. | |
313 * @param $type | |
314 * The type of entity being saved (i.e. node, user, comment). | |
315 */ | |
316 function hook_entity_presave($entity, $type) { | |
317 $entity->changed = REQUEST_TIME; | |
318 } | |
319 | |
320 /** | |
321 * Act on entities when inserted. | |
322 * | |
323 * @param $entity | |
324 * The entity object. | |
325 * @param $type | |
326 * The type of entity being inserted (i.e. node, user, comment). | |
327 */ | |
328 function hook_entity_insert($entity, $type) { | |
329 // Insert the new entity into a fictional table of all entities. | |
330 $info = entity_get_info($type); | |
331 list($id) = entity_extract_ids($type, $entity); | |
332 db_insert('example_entity') | |
333 ->fields(array( | |
334 'type' => $type, | |
335 'id' => $id, | |
336 'created' => REQUEST_TIME, | |
337 'updated' => REQUEST_TIME, | |
338 )) | |
339 ->execute(); | |
340 } | |
341 | |
342 /** | |
343 * Act on entities when updated. | |
344 * | |
345 * @param $entity | |
346 * The entity object. | |
347 * @param $type | |
348 * The type of entity being updated (i.e. node, user, comment). | |
349 */ | |
350 function hook_entity_update($entity, $type) { | |
351 // Update the entity's entry in a fictional table of all entities. | |
352 $info = entity_get_info($type); | |
353 list($id) = entity_extract_ids($type, $entity); | |
354 db_update('example_entity') | |
355 ->fields(array( | |
356 'updated' => REQUEST_TIME, | |
357 )) | |
358 ->condition('type', $type) | |
359 ->condition('id', $id) | |
360 ->execute(); | |
361 } | |
362 | |
363 /** | |
364 * Act on entities when deleted. | |
365 * | |
366 * @param $entity | |
367 * The entity object. | |
368 * @param $type | |
369 * The type of entity being deleted (i.e. node, user, comment). | |
370 */ | |
371 function hook_entity_delete($entity, $type) { | |
372 // Delete the entity's entry from a fictional table of all entities. | |
373 $info = entity_get_info($type); | |
374 list($id) = entity_extract_ids($type, $entity); | |
375 db_delete('example_entity') | |
376 ->condition('type', $type) | |
377 ->condition('id', $id) | |
378 ->execute(); | |
379 } | |
380 | |
381 /** | |
382 * Alter or execute an EntityFieldQuery. | |
383 * | |
384 * @param EntityFieldQuery $query | |
385 * An EntityFieldQuery. One of the most important properties to be changed is | |
386 * EntityFieldQuery::executeCallback. If this is set to an existing function, | |
387 * this function will get the query as its single argument and its result | |
388 * will be the returned as the result of EntityFieldQuery::execute(). This can | |
389 * be used to change the behavior of EntityFieldQuery entirely. For example, | |
390 * the default implementation can only deal with one field storage engine, but | |
391 * it is possible to write a module that can query across field storage | |
392 * engines. Also, the default implementation presumes entities are stored in | |
393 * SQL, but the execute callback could instead query any other entity storage, | |
394 * local or remote. | |
395 * | |
396 * Note the $query->altered attribute which is TRUE in case the query has | |
397 * already been altered once. This happens with cloned queries. | |
398 * If there is a pager, then such a cloned query will be executed to count | |
399 * all elements. This query can be detected by checking for | |
400 * ($query->pager && $query->count), allowing the driver to return 0 from | |
401 * the count query and disable the pager. | |
402 */ | |
403 function hook_entity_query_alter($query) { | |
404 $query->executeCallback = 'my_module_query_callback'; | |
405 } | |
406 | |
407 /** | |
408 * Act on entities being assembled before rendering. | |
409 * | |
410 * @param $entity | |
411 * The entity object. | |
412 * @param $type | |
413 * The type of entity being rendered (i.e. node, user, comment). | |
414 * @param $view_mode | |
415 * The view mode the entity is rendered in. | |
416 * @param $langcode | |
417 * The language code used for rendering. | |
418 * | |
419 * The module may add elements to $entity->content prior to rendering. The | |
420 * structure of $entity->content is a renderable array as expected by | |
421 * drupal_render(). | |
422 * | |
423 * @see hook_entity_view_alter() | |
424 * @see hook_comment_view() | |
425 * @see hook_node_view() | |
426 * @see hook_user_view() | |
427 */ | |
428 function hook_entity_view($entity, $type, $view_mode, $langcode) { | |
429 $entity->content['my_additional_field'] = array( | |
430 '#markup' => $additional_field, | |
431 '#weight' => 10, | |
432 '#theme' => 'mymodule_my_additional_field', | |
433 ); | |
434 } | |
435 | |
436 /** | |
437 * Alter the results of ENTITY_view(). | |
438 * | |
439 * This hook is called after the content has been assembled in a structured | |
440 * array and may be used for doing processing which requires that the complete | |
441 * entity content structure has been built. | |
442 * | |
443 * If a module wishes to act on the rendered HTML of the entity rather than the | |
444 * structured content array, it may use this hook to add a #post_render | |
445 * callback. Alternatively, it could also implement hook_preprocess_ENTITY(). | |
446 * See drupal_render() and theme() for details. | |
447 * | |
448 * @param $build | |
449 * A renderable array representing the entity content. | |
450 * @param $type | |
451 * The type of entity being rendered (i.e. node, user, comment). | |
452 * | |
453 * @see hook_entity_view() | |
454 * @see hook_comment_view_alter() | |
455 * @see hook_node_view_alter() | |
456 * @see hook_taxonomy_term_view_alter() | |
457 * @see hook_user_view_alter() | |
458 */ | |
459 function hook_entity_view_alter(&$build, $type) { | |
460 if ($build['#view_mode'] == 'full' && isset($build['an_additional_field'])) { | |
461 // Change its weight. | |
462 $build['an_additional_field']['#weight'] = -10; | |
463 | |
464 // Add a #post_render callback to act on the rendered HTML of the entity. | |
465 $build['#post_render'][] = 'my_module_node_post_render'; | |
466 } | |
467 } | |
468 | |
469 /** | |
470 * Change the view mode of an entity that is being displayed. | |
471 * | |
472 * @param string $view_mode | |
473 * The view_mode that is to be used to display the entity. | |
474 * @param array $context | |
475 * Array with contextual information, including: | |
476 * - entity_type: The type of the entity that is being viewed. | |
477 * - entity: The entity object. | |
478 * - langcode: The langcode the entity is being viewed in. | |
479 */ | |
480 function hook_entity_view_mode_alter(&$view_mode, $context) { | |
481 // For nodes, change the view mode when it is teaser. | |
482 if ($context['entity_type'] == 'node' && $view_mode == 'teaser') { | |
483 $view_mode = 'my_custom_view_mode'; | |
484 } | |
485 } | |
486 | |
487 /** | |
488 * Define administrative paths. | |
489 * | |
490 * Modules may specify whether or not the paths they define in hook_menu() are | |
491 * to be considered administrative. Other modules may use this information to | |
492 * display those pages differently (e.g. in a modal overlay, or in a different | |
493 * theme). | |
494 * | |
495 * To change the administrative status of menu items defined in another module's | |
496 * hook_menu(), modules should implement hook_admin_paths_alter(). | |
497 * | |
498 * @return | |
499 * An associative array. For each item, the key is the path in question, in | |
500 * a format acceptable to drupal_match_path(). The value for each item should | |
501 * be TRUE (for paths considered administrative) or FALSE (for non- | |
502 * administrative paths). | |
503 * | |
504 * @see hook_menu() | |
505 * @see drupal_match_path() | |
506 * @see hook_admin_paths_alter() | |
507 */ | |
508 function hook_admin_paths() { | |
509 $paths = array( | |
510 'mymodule/*/add' => TRUE, | |
511 'mymodule/*/edit' => TRUE, | |
512 ); | |
513 return $paths; | |
514 } | |
515 | |
516 /** | |
517 * Redefine administrative paths defined by other modules. | |
518 * | |
519 * @param $paths | |
520 * An associative array of administrative paths, as defined by implementations | |
521 * of hook_admin_paths(). | |
522 * | |
523 * @see hook_admin_paths() | |
524 */ | |
525 function hook_admin_paths_alter(&$paths) { | |
526 // Treat all user pages as administrative. | |
527 $paths['user'] = TRUE; | |
528 $paths['user/*'] = TRUE; | |
529 // Treat the forum topic node form as a non-administrative page. | |
530 $paths['node/add/forum'] = FALSE; | |
531 } | |
532 | |
533 /** | |
534 * Act on entities as they are being prepared for view. | |
535 * | |
536 * Allows you to operate on multiple entities as they are being prepared for | |
537 * view. Only use this if attaching the data during the entity_load() phase | |
538 * is not appropriate, for example when attaching other 'entity' style objects. | |
539 * | |
540 * @param $entities | |
541 * The entities keyed by entity ID. | |
542 * @param $type | |
543 * The type of entities being loaded (i.e. node, user, comment). | |
544 * @param $langcode | |
545 * The language to display the entity in. | |
546 */ | |
547 function hook_entity_prepare_view($entities, $type, $langcode) { | |
548 // Load a specific node into the user object for later theming. | |
549 if ($type == 'user') { | |
550 $nodes = mymodule_get_user_nodes(array_keys($entities)); | |
551 foreach ($entities as $uid => $entity) { | |
552 $entity->user_node = $nodes[$uid]; | |
553 } | |
554 } | |
555 } | |
556 | |
557 /** | |
558 * Perform periodic actions. | |
559 * | |
560 * Modules that require some commands to be executed periodically can | |
561 * implement hook_cron(). The engine will then call the hook whenever a cron | |
562 * run happens, as defined by the administrator. Typical tasks managed by | |
563 * hook_cron() are database maintenance, backups, recalculation of settings | |
564 * or parameters, automated mailing, and retrieving remote data. | |
565 * | |
566 * Short-running or non-resource-intensive tasks can be executed directly in | |
567 * the hook_cron() implementation. | |
568 * | |
569 * Long-running tasks and tasks that could time out, such as retrieving remote | |
570 * data, sending email, and intensive file tasks, should use the queue API | |
571 * instead of executing the tasks directly. To do this, first define one or | |
572 * more queues via hook_cron_queue_info(). Then, add items that need to be | |
573 * processed to the defined queues. | |
574 */ | |
575 function hook_cron() { | |
576 // Short-running operation example, not using a queue: | |
577 // Delete all expired records since the last cron run. | |
578 $expires = variable_get('mymodule_cron_last_run', REQUEST_TIME); | |
579 db_delete('mymodule_table') | |
580 ->condition('expires', $expires, '>=') | |
581 ->execute(); | |
582 variable_set('mymodule_cron_last_run', REQUEST_TIME); | |
583 | |
584 // Long-running operation example, leveraging a queue: | |
585 // Fetch feeds from other sites. | |
586 $result = db_query('SELECT * FROM {aggregator_feed} WHERE checked + refresh < :time AND refresh <> :never', array( | |
587 ':time' => REQUEST_TIME, | |
588 ':never' => AGGREGATOR_CLEAR_NEVER, | |
589 )); | |
590 $queue = DrupalQueue::get('aggregator_feeds'); | |
591 foreach ($result as $feed) { | |
592 $queue->createItem($feed); | |
593 } | |
594 } | |
595 | |
596 /** | |
597 * Declare queues holding items that need to be run periodically. | |
598 * | |
599 * While there can be only one hook_cron() process running at the same time, | |
600 * there can be any number of processes defined here running. Because of | |
601 * this, long running tasks are much better suited for this API. Items queued | |
602 * in hook_cron() might be processed in the same cron run if there are not many | |
603 * items in the queue, otherwise it might take several requests, which can be | |
604 * run in parallel. | |
605 * | |
606 * @return | |
607 * An associative array where the key is the queue name and the value is | |
608 * again an associative array. Possible keys are: | |
609 * - 'worker callback': The name of the function to call. It will be called | |
610 * with one argument, the item created via DrupalQueue::createItem() in | |
611 * hook_cron(). | |
612 * - 'time': (optional) How much time Drupal should spend on calling this | |
613 * worker in seconds. Defaults to 15. | |
614 * | |
615 * @see hook_cron() | |
616 * @see hook_cron_queue_info_alter() | |
617 */ | |
618 function hook_cron_queue_info() { | |
619 $queues['aggregator_feeds'] = array( | |
620 'worker callback' => 'aggregator_refresh', | |
621 'time' => 60, | |
622 ); | |
623 return $queues; | |
624 } | |
625 | |
626 /** | |
627 * Alter cron queue information before cron runs. | |
628 * | |
629 * Called by drupal_cron_run() to allow modules to alter cron queue settings | |
630 * before any jobs are processesed. | |
631 * | |
632 * @param array $queues | |
633 * An array of cron queue information. | |
634 * | |
635 * @see hook_cron_queue_info() | |
636 * @see drupal_cron_run() | |
637 */ | |
638 function hook_cron_queue_info_alter(&$queues) { | |
639 // This site has many feeds so let's spend 90 seconds on each cron run | |
640 // updating feeds instead of the default 60. | |
641 $queues['aggregator_feeds']['time'] = 90; | |
642 } | |
643 | |
644 /** | |
645 * Allows modules to declare their own Form API element types and specify their | |
646 * default values. | |
647 * | |
648 * This hook allows modules to declare their own form element types and to | |
649 * specify their default values. The values returned by this hook will be | |
650 * merged with the elements returned by hook_form() implementations and so | |
651 * can return defaults for any Form APIs keys in addition to those explicitly | |
652 * mentioned below. | |
653 * | |
654 * Each of the form element types defined by this hook is assumed to have | |
655 * a matching theme function, e.g. theme_elementtype(), which should be | |
656 * registered with hook_theme() as normal. | |
657 * | |
658 * For more information about custom element types see the explanation at | |
659 * http://drupal.org/node/169815. | |
660 * | |
661 * @return | |
662 * An associative array describing the element types being defined. The array | |
663 * contains a sub-array for each element type, with the machine-readable type | |
664 * name as the key. Each sub-array has a number of possible attributes: | |
665 * - "#input": boolean indicating whether or not this element carries a value | |
666 * (even if it's hidden). | |
667 * - "#process": array of callback functions taking $element, $form_state, | |
668 * and $complete_form. | |
669 * - "#after_build": array of callback functions taking $element and $form_state. | |
670 * - "#validate": array of callback functions taking $form and $form_state. | |
671 * - "#element_validate": array of callback functions taking $element and | |
672 * $form_state. | |
673 * - "#pre_render": array of callback functions taking $element and $form_state. | |
674 * - "#post_render": array of callback functions taking $element and $form_state. | |
675 * - "#submit": array of callback functions taking $form and $form_state. | |
676 * - "#title_display": optional string indicating if and how #title should be | |
677 * displayed, see theme_form_element() and theme_form_element_label(). | |
678 * | |
679 * @see hook_element_info_alter() | |
680 * @see system_element_info() | |
681 */ | |
682 function hook_element_info() { | |
683 $types['filter_format'] = array( | |
684 '#input' => TRUE, | |
685 ); | |
686 return $types; | |
687 } | |
688 | |
689 /** | |
690 * Alter the element type information returned from modules. | |
691 * | |
692 * A module may implement this hook in order to alter the element type defaults | |
693 * defined by a module. | |
694 * | |
695 * @param $type | |
696 * All element type defaults as collected by hook_element_info(). | |
697 * | |
698 * @see hook_element_info() | |
699 */ | |
700 function hook_element_info_alter(&$type) { | |
701 // Decrease the default size of textfields. | |
702 if (isset($type['textfield']['#size'])) { | |
703 $type['textfield']['#size'] = 40; | |
704 } | |
705 } | |
706 | |
707 /** | |
708 * Perform cleanup tasks. | |
709 * | |
710 * This hook is run at the end of most regular page requests. It is often | |
711 * used for page logging and specialized cleanup. This hook MUST NOT print | |
712 * anything because by the time it runs the response is already sent to | |
713 * the browser. | |
714 * | |
715 * Only use this hook if your code must run even for cached page views. | |
716 * If you have code which must run once on all non-cached pages, use | |
717 * hook_init() instead. That is the usual case. If you implement this hook | |
718 * and see an error like 'Call to undefined function', it is likely that | |
719 * you are depending on the presence of a module which has not been loaded yet. | |
720 * It is not loaded because Drupal is still in bootstrap mode. | |
721 * | |
722 * @param $destination | |
723 * If this hook is invoked as part of a drupal_goto() call, then this argument | |
724 * will be a fully-qualified URL that is the destination of the redirect. | |
725 */ | |
726 function hook_exit($destination = NULL) { | |
727 db_update('counter') | |
728 ->expression('hits', 'hits + 1') | |
729 ->condition('type', 1) | |
730 ->execute(); | |
731 } | |
732 | |
733 /** | |
734 * Perform necessary alterations to the JavaScript before it is presented on | |
735 * the page. | |
736 * | |
737 * @param $javascript | |
738 * An array of all JavaScript being presented on the page. | |
739 * | |
740 * @see drupal_add_js() | |
741 * @see drupal_get_js() | |
742 * @see drupal_js_defaults() | |
743 */ | |
744 function hook_js_alter(&$javascript) { | |
745 // Swap out jQuery to use an updated version of the library. | |
746 $javascript['misc/jquery.js']['data'] = drupal_get_path('module', 'jquery_update') . '/jquery.js'; | |
747 } | |
748 | |
749 /** | |
750 * Registers JavaScript/CSS libraries associated with a module. | |
751 * | |
752 * Modules implementing this return an array of arrays. The key to each | |
753 * sub-array is the machine readable name of the library. Each library may | |
754 * contain the following items: | |
755 * | |
756 * - 'title': The human readable name of the library. | |
757 * - 'website': The URL of the library's web site. | |
758 * - 'version': A string specifying the version of the library; intentionally | |
759 * not a float because a version like "1.2.3" is not a valid float. Use PHP's | |
760 * version_compare() to compare different versions. | |
761 * - 'js': An array of JavaScript elements; each element's key is used as $data | |
762 * argument, each element's value is used as $options array for | |
763 * drupal_add_js(). To add library-specific (not module-specific) JavaScript | |
764 * settings, the key may be skipped, the value must specify | |
765 * 'type' => 'setting', and the actual settings must be contained in a 'data' | |
766 * element of the value. | |
767 * - 'css': Like 'js', an array of CSS elements passed to drupal_add_css(). | |
768 * - 'dependencies': An array of libraries that are required for a library. Each | |
769 * element is an array listing the module and name of another library. Note | |
770 * that all dependencies for each dependent library will also be added when | |
771 * this library is added. | |
772 * | |
773 * Registered information for a library should contain re-usable data only. | |
774 * Module- or implementation-specific data and integration logic should be added | |
775 * separately. | |
776 * | |
777 * @return | |
778 * An array defining libraries associated with a module. | |
779 * | |
780 * @see system_library() | |
781 * @see drupal_add_library() | |
782 * @see drupal_get_library() | |
783 */ | |
784 function hook_library() { | |
785 // Library One. | |
786 $libraries['library-1'] = array( | |
787 'title' => 'Library One', | |
788 'website' => 'http://example.com/library-1', | |
789 'version' => '1.2', | |
790 'js' => array( | |
791 drupal_get_path('module', 'my_module') . '/library-1.js' => array(), | |
792 ), | |
793 'css' => array( | |
794 drupal_get_path('module', 'my_module') . '/library-2.css' => array( | |
795 'type' => 'file', | |
796 'media' => 'screen', | |
797 ), | |
798 ), | |
799 ); | |
800 // Library Two. | |
801 $libraries['library-2'] = array( | |
802 'title' => 'Library Two', | |
803 'website' => 'http://example.com/library-2', | |
804 'version' => '3.1-beta1', | |
805 'js' => array( | |
806 // JavaScript settings may use the 'data' key. | |
807 array( | |
808 'type' => 'setting', | |
809 'data' => array('library2' => TRUE), | |
810 ), | |
811 ), | |
812 'dependencies' => array( | |
813 // Require jQuery UI core by System module. | |
814 array('system', 'ui'), | |
815 // Require our other library. | |
816 array('my_module', 'library-1'), | |
817 // Require another library. | |
818 array('other_module', 'library-3'), | |
819 ), | |
820 ); | |
821 return $libraries; | |
822 } | |
823 | |
824 /** | |
825 * Alters the JavaScript/CSS library registry. | |
826 * | |
827 * Allows certain, contributed modules to update libraries to newer versions | |
828 * while ensuring backwards compatibility. In general, such manipulations should | |
829 * only be done by designated modules, since most modules that integrate with a | |
830 * certain library also depend on the API of a certain library version. | |
831 * | |
832 * @param $libraries | |
833 * The JavaScript/CSS libraries provided by $module. Keyed by internal library | |
834 * name and passed by reference. | |
835 * @param $module | |
836 * The name of the module that registered the libraries. | |
837 * | |
838 * @see hook_library() | |
839 */ | |
840 function hook_library_alter(&$libraries, $module) { | |
841 // Update Farbtastic to version 2.0. | |
842 if ($module == 'system' && isset($libraries['farbtastic'])) { | |
843 // Verify existing version is older than the one we are updating to. | |
844 if (version_compare($libraries['farbtastic']['version'], '2.0', '<')) { | |
845 // Update the existing Farbtastic to version 2.0. | |
846 $libraries['farbtastic']['version'] = '2.0'; | |
847 $libraries['farbtastic']['js'] = array( | |
848 drupal_get_path('module', 'farbtastic_update') . '/farbtastic-2.0.js' => array(), | |
849 ); | |
850 } | |
851 } | |
852 } | |
853 | |
854 /** | |
855 * Alter CSS files before they are output on the page. | |
856 * | |
857 * @param $css | |
858 * An array of all CSS items (files and inline CSS) being requested on the page. | |
859 * | |
860 * @see drupal_add_css() | |
861 * @see drupal_get_css() | |
862 */ | |
863 function hook_css_alter(&$css) { | |
864 // Remove defaults.css file. | |
865 unset($css[drupal_get_path('module', 'system') . '/defaults.css']); | |
866 } | |
867 | |
868 /** | |
869 * Alter the commands that are sent to the user through the Ajax framework. | |
870 * | |
871 * @param $commands | |
872 * An array of all commands that will be sent to the user. | |
873 * | |
874 * @see ajax_render() | |
875 */ | |
876 function hook_ajax_render_alter($commands) { | |
877 // Inject any new status messages into the content area. | |
878 $commands[] = ajax_command_prepend('#block-system-main .content', theme('status_messages')); | |
879 } | |
880 | |
881 /** | |
882 * Add elements to a page before it is rendered. | |
883 * | |
884 * Use this hook when you want to add elements at the page level. For your | |
885 * additions to be printed, they have to be placed below a top level array key | |
886 * of the $page array that has the name of a region of the active theme. | |
887 * | |
888 * By default, valid region keys are 'page_top', 'header', 'sidebar_first', | |
889 * 'content', 'sidebar_second' and 'page_bottom'. To get a list of all regions | |
890 * of the active theme, use system_region_list($theme). Note that $theme is a | |
891 * global variable. | |
892 * | |
893 * If you want to alter the elements added by other modules or if your module | |
894 * depends on the elements of other modules, use hook_page_alter() instead which | |
895 * runs after this hook. | |
896 * | |
897 * @param $page | |
898 * Nested array of renderable elements that make up the page. | |
899 * | |
900 * @see hook_page_alter() | |
901 * @see drupal_render_page() | |
902 */ | |
903 function hook_page_build(&$page) { | |
904 if (menu_get_object('node', 1)) { | |
905 // We are on a node detail page. Append a standard disclaimer to the | |
906 // content region. | |
907 $page['content']['disclaimer'] = array( | |
908 '#markup' => t('Acme, Inc. is not responsible for the contents of this sample code.'), | |
909 '#weight' => 25, | |
910 ); | |
911 } | |
912 } | |
913 | |
914 /** | |
915 * Alter a menu router item right after it has been retrieved from the database or cache. | |
916 * | |
917 * This hook is invoked by menu_get_item() and allows for run-time alteration of router | |
918 * information (page_callback, title, and so on) before it is translated and checked for | |
919 * access. The passed-in $router_item is statically cached for the current request, so this | |
920 * hook is only invoked once for any router item that is retrieved via menu_get_item(). | |
921 * | |
922 * Usually, modules will only want to inspect the router item and conditionally | |
923 * perform other actions (such as preparing a state for the current request). | |
924 * Note that this hook is invoked for any router item that is retrieved by | |
925 * menu_get_item(), which may or may not be called on the path itself, so implementations | |
926 * should check the $path parameter if the alteration should fire for the current request | |
927 * only. | |
928 * | |
929 * @param $router_item | |
930 * The menu router item for $path. | |
931 * @param $path | |
932 * The originally passed path, for which $router_item is responsible. | |
933 * @param $original_map | |
934 * The path argument map, as contained in $path. | |
935 * | |
936 * @see menu_get_item() | |
937 */ | |
938 function hook_menu_get_item_alter(&$router_item, $path, $original_map) { | |
939 // When retrieving the router item for the current path... | |
940 if ($path == $_GET['q']) { | |
941 // ...call a function that prepares something for this request. | |
942 mymodule_prepare_something(); | |
943 } | |
944 } | |
945 | |
946 /** | |
947 * Define menu items and page callbacks. | |
948 * | |
949 * This hook enables modules to register paths in order to define how URL | |
950 * requests are handled. Paths may be registered for URL handling only, or they | |
951 * can register a link to be placed in a menu (usually the Navigation menu). A | |
952 * path and its associated information is commonly called a "menu router item". | |
953 * This hook is rarely called (for example, when modules are enabled), and | |
954 * its results are cached in the database. | |
955 * | |
956 * hook_menu() implementations return an associative array whose keys define | |
957 * paths and whose values are an associative array of properties for each | |
958 * path. (The complete list of properties is in the return value section below.) | |
959 * | |
960 * @section sec_callback_funcs Callback Functions | |
961 * The definition for each path may include a page callback function, which is | |
962 * invoked when the registered path is requested. If there is no other | |
963 * registered path that fits the requested path better, any further path | |
964 * components are passed to the callback function. For example, your module | |
965 * could register path 'abc/def': | |
966 * @code | |
967 * function mymodule_menu() { | |
968 * $items['abc/def'] = array( | |
969 * 'page callback' => 'mymodule_abc_view', | |
970 * ); | |
971 * return $items; | |
972 * } | |
973 * | |
974 * function mymodule_abc_view($ghi = 0, $jkl = '') { | |
975 * // ... | |
976 * } | |
977 * @endcode | |
978 * When path 'abc/def' is requested, no further path components are in the | |
979 * request, and no additional arguments are passed to the callback function (so | |
980 * $ghi and $jkl would take the default values as defined in the function | |
981 * signature). When 'abc/def/123/foo' is requested, $ghi will be '123' and | |
982 * $jkl will be 'foo'. Note that this automatic passing of optional path | |
983 * arguments applies only to page and theme callback functions. | |
984 * | |
985 * @subsection sub_callback_arguments Callback Arguments | |
986 * In addition to optional path arguments, the page callback and other callback | |
987 * functions may specify argument lists as arrays. These argument lists may | |
988 * contain both fixed/hard-coded argument values and integers that correspond | |
989 * to path components. When integers are used and the callback function is | |
990 * called, the corresponding path components will be substituted for the | |
991 * integers. That is, the integer 0 in an argument list will be replaced with | |
992 * the first path component, integer 1 with the second, and so on (path | |
993 * components are numbered starting from zero). To pass an integer without it | |
994 * being replaced with its respective path component, use the string value of | |
995 * the integer (e.g., '1') as the argument value. This substitution feature | |
996 * allows you to re-use a callback function for several different paths. For | |
997 * example: | |
998 * @code | |
999 * function mymodule_menu() { | |
1000 * $items['abc/def'] = array( | |
1001 * 'page callback' => 'mymodule_abc_view', | |
1002 * 'page arguments' => array(1, 'foo'), | |
1003 * ); | |
1004 * return $items; | |
1005 * } | |
1006 * @endcode | |
1007 * When path 'abc/def' is requested, the page callback function will get 'def' | |
1008 * as the first argument and (always) 'foo' as the second argument. | |
1009 * | |
1010 * If a page callback function uses an argument list array, and its path is | |
1011 * requested with optional path arguments, then the list array's arguments are | |
1012 * passed to the callback function first, followed by the optional path | |
1013 * arguments. Using the above example, when path 'abc/def/bar/baz' is requested, | |
1014 * mymodule_abc_view() will be called with 'def', 'foo', 'bar' and 'baz' as | |
1015 * arguments, in that order. | |
1016 * | |
1017 * Special care should be taken for the page callback drupal_get_form(), because | |
1018 * your specific form callback function will always receive $form and | |
1019 * &$form_state as the first function arguments: | |
1020 * @code | |
1021 * function mymodule_abc_form($form, &$form_state) { | |
1022 * // ... | |
1023 * return $form; | |
1024 * } | |
1025 * @endcode | |
1026 * See @link form_api Form API documentation @endlink for details. | |
1027 * | |
1028 * @section sec_path_wildcards Wildcards in Paths | |
1029 * @subsection sub_simple_wildcards Simple Wildcards | |
1030 * Wildcards within paths also work with integer substitution. For example, | |
1031 * your module could register path 'my-module/%/edit': | |
1032 * @code | |
1033 * $items['my-module/%/edit'] = array( | |
1034 * 'page callback' => 'mymodule_abc_edit', | |
1035 * 'page arguments' => array(1), | |
1036 * ); | |
1037 * @endcode | |
1038 * When path 'my-module/foo/edit' is requested, integer 1 will be replaced | |
1039 * with 'foo' and passed to the callback function. Note that wildcards may not | |
1040 * be used as the first component. | |
1041 * | |
1042 * @subsection sub_autoload_wildcards Auto-Loader Wildcards | |
1043 * Registered paths may also contain special "auto-loader" wildcard components | |
1044 * in the form of '%mymodule_abc', where the '%' part means that this path | |
1045 * component is a wildcard, and the 'mymodule_abc' part defines the prefix for a | |
1046 * load function, which here would be named mymodule_abc_load(). When a matching | |
1047 * path is requested, your load function will receive as its first argument the | |
1048 * path component in the position of the wildcard; load functions may also be | |
1049 * passed additional arguments (see "load arguments" in the return value | |
1050 * section below). For example, your module could register path | |
1051 * 'my-module/%mymodule_abc/edit': | |
1052 * @code | |
1053 * $items['my-module/%mymodule_abc/edit'] = array( | |
1054 * 'page callback' => 'mymodule_abc_edit', | |
1055 * 'page arguments' => array(1), | |
1056 * ); | |
1057 * @endcode | |
1058 * When path 'my-module/123/edit' is requested, your load function | |
1059 * mymodule_abc_load() will be invoked with the argument '123', and should | |
1060 * load and return an "abc" object with internal id 123: | |
1061 * @code | |
1062 * function mymodule_abc_load($abc_id) { | |
1063 * return db_query("SELECT * FROM {mymodule_abc} WHERE abc_id = :abc_id", array(':abc_id' => $abc_id))->fetchObject(); | |
1064 * } | |
1065 * @endcode | |
1066 * This 'abc' object will then be passed into the callback functions defined | |
1067 * for the menu item, such as the page callback function mymodule_abc_edit() | |
1068 * to replace the integer 1 in the argument array. Note that a load function | |
1069 * should return FALSE when it is unable to provide a loadable object. For | |
1070 * example, the node_load() function for the 'node/%node/edit' menu item will | |
1071 * return FALSE for the path 'node/999/edit' if a node with a node ID of 999 | |
1072 * does not exist. The menu routing system will return a 404 error in this case. | |
1073 * | |
1074 * @subsection sub_argument_wildcards Argument Wildcards | |
1075 * You can also define a %wildcard_to_arg() function (for the example menu | |
1076 * entry above this would be 'mymodule_abc_to_arg()'). The _to_arg() function | |
1077 * is invoked to retrieve a value that is used in the path in place of the | |
1078 * wildcard. A good example is user.module, which defines | |
1079 * user_uid_optional_to_arg() (corresponding to the menu entry | |
1080 * 'tracker/%user_uid_optional'). This function returns the user ID of the | |
1081 * current user. | |
1082 * | |
1083 * The _to_arg() function will get called with three arguments: | |
1084 * - $arg: A string representing whatever argument may have been supplied by | |
1085 * the caller (this is particularly useful if you want the _to_arg() | |
1086 * function only supply a (default) value if no other value is specified, | |
1087 * as in the case of user_uid_optional_to_arg(). | |
1088 * - $map: An array of all path fragments (e.g. array('node','123','edit') for | |
1089 * 'node/123/edit'). | |
1090 * - $index: An integer indicating which element of $map corresponds to $arg. | |
1091 * | |
1092 * _load() and _to_arg() functions may seem similar at first glance, but they | |
1093 * have different purposes and are called at different times. _load() | |
1094 * functions are called when the menu system is collecting arguments to pass | |
1095 * to the callback functions defined for the menu item. _to_arg() functions | |
1096 * are called when the menu system is generating links to related paths, such | |
1097 * as the tabs for a set of MENU_LOCAL_TASK items. | |
1098 * | |
1099 * @section sec_render_tabs Rendering Menu Items As Tabs | |
1100 * You can also make groups of menu items to be rendered (by default) as tabs | |
1101 * on a page. To do that, first create one menu item of type MENU_NORMAL_ITEM, | |
1102 * with your chosen path, such as 'foo'. Then duplicate that menu item, using a | |
1103 * subdirectory path, such as 'foo/tab1', and changing the type to | |
1104 * MENU_DEFAULT_LOCAL_TASK to make it the default tab for the group. Then add | |
1105 * the additional tab items, with paths such as "foo/tab2" etc., with type | |
1106 * MENU_LOCAL_TASK. Example: | |
1107 * @code | |
1108 * // Make "Foo settings" appear on the admin Config page | |
1109 * $items['admin/config/system/foo'] = array( | |
1110 * 'title' => 'Foo settings', | |
1111 * 'type' => MENU_NORMAL_ITEM, | |
1112 * // Page callback, etc. need to be added here. | |
1113 * ); | |
1114 * // Make "Tab 1" the main tab on the "Foo settings" page | |
1115 * $items['admin/config/system/foo/tab1'] = array( | |
1116 * 'title' => 'Tab 1', | |
1117 * 'type' => MENU_DEFAULT_LOCAL_TASK, | |
1118 * // Access callback, page callback, and theme callback will be inherited | |
1119 * // from 'admin/config/system/foo', if not specified here to override. | |
1120 * ); | |
1121 * // Make an additional tab called "Tab 2" on "Foo settings" | |
1122 * $items['admin/config/system/foo/tab2'] = array( | |
1123 * 'title' => 'Tab 2', | |
1124 * 'type' => MENU_LOCAL_TASK, | |
1125 * // Page callback and theme callback will be inherited from | |
1126 * // 'admin/config/system/foo', if not specified here to override. | |
1127 * // Need to add access callback or access arguments. | |
1128 * ); | |
1129 * @endcode | |
1130 * | |
1131 * @return | |
1132 * An array of menu items. Each menu item has a key corresponding to the | |
1133 * Drupal path being registered. The corresponding array value is an | |
1134 * associative array that may contain the following key-value pairs: | |
1135 * - "title": Required. The untranslated title of the menu item. | |
1136 * - "title callback": Function to generate the title; defaults to t(). | |
1137 * If you require only the raw string to be output, set this to FALSE. | |
1138 * - "title arguments": Arguments to send to t() or your custom callback, | |
1139 * with path component substitution as described above. | |
1140 * - "description": The untranslated description of the menu item. | |
1141 * - "page callback": The function to call to display a web page when the user | |
1142 * visits the path. If omitted, the parent menu item's callback will be used | |
1143 * instead. | |
1144 * - "page arguments": An array of arguments to pass to the page callback | |
1145 * function, with path component substitution as described above. | |
1146 * - "delivery callback": The function to call to package the result of the | |
1147 * page callback function and send it to the browser. Defaults to | |
1148 * drupal_deliver_html_page() unless a value is inherited from a parent menu | |
1149 * item. Note that this function is called even if the access checks fail, | |
1150 * so any custom delivery callback function should take that into account. | |
1151 * See drupal_deliver_html_page() for an example. | |
1152 * - "access callback": A function returning TRUE if the user has access | |
1153 * rights to this menu item, and FALSE if not. It can also be a boolean | |
1154 * constant instead of a function, and you can also use numeric values | |
1155 * (will be cast to boolean). Defaults to user_access() unless a value is | |
1156 * inherited from the parent menu item; only MENU_DEFAULT_LOCAL_TASK items | |
1157 * can inherit access callbacks. To use the user_access() default callback, | |
1158 * you must specify the permission to check as 'access arguments' (see | |
1159 * below). | |
1160 * - "access arguments": An array of arguments to pass to the access callback | |
1161 * function, with path component substitution as described above. If the | |
1162 * access callback is inherited (see above), the access arguments will be | |
1163 * inherited with it, unless overridden in the child menu item. | |
1164 * - "theme callback": (optional) A function returning the machine-readable | |
1165 * name of the theme that will be used to render the page. If not provided, | |
1166 * the value will be inherited from a parent menu item. If there is no | |
1167 * theme callback, or if the function does not return the name of a current | |
1168 * active theme on the site, the theme for this page will be determined by | |
1169 * either hook_custom_theme() or the default theme instead. As a general | |
1170 * rule, the use of theme callback functions should be limited to pages | |
1171 * whose functionality is very closely tied to a particular theme, since | |
1172 * they can only be overridden by modules which specifically target those | |
1173 * pages in hook_menu_alter(). Modules implementing more generic theme | |
1174 * switching functionality (for example, a module which allows the theme to | |
1175 * be set dynamically based on the current user's role) should use | |
1176 * hook_custom_theme() instead. | |
1177 * - "theme arguments": An array of arguments to pass to the theme callback | |
1178 * function, with path component substitution as described above. | |
1179 * - "file": A file that will be included before the page callback is called; | |
1180 * this allows page callback functions to be in separate files. The file | |
1181 * should be relative to the implementing module's directory unless | |
1182 * otherwise specified by the "file path" option. Does not apply to other | |
1183 * callbacks (only page callback). | |
1184 * - "file path": The path to the directory containing the file specified in | |
1185 * "file". This defaults to the path to the module implementing the hook. | |
1186 * - "load arguments": An array of arguments to be passed to each of the | |
1187 * wildcard object loaders in the path, after the path argument itself. | |
1188 * For example, if a module registers path node/%node/revisions/%/view | |
1189 * with load arguments set to array(3), the '%node' in the path indicates | |
1190 * that the loader function node_load() will be called with the second | |
1191 * path component as the first argument. The 3 in the load arguments | |
1192 * indicates that the fourth path component will also be passed to | |
1193 * node_load() (numbering of path components starts at zero). So, if path | |
1194 * node/12/revisions/29/view is requested, node_load(12, 29) will be called. | |
1195 * There are also two "magic" values that can be used in load arguments. | |
1196 * "%index" indicates the index of the wildcard path component. "%map" | |
1197 * indicates the path components as an array. For example, if a module | |
1198 * registers for several paths of the form 'user/%user_category/edit/*', all | |
1199 * of them can use the same load function user_category_load(), by setting | |
1200 * the load arguments to array('%map', '%index'). For instance, if the user | |
1201 * is editing category 'foo' by requesting path 'user/32/edit/foo', the load | |
1202 * function user_category_load() will be called with 32 as its first | |
1203 * argument, the array ('user', 32, 'edit', 'foo') as the map argument, | |
1204 * and 1 as the index argument (because %user_category is the second path | |
1205 * component and numbering starts at zero). user_category_load() can then | |
1206 * use these values to extract the information that 'foo' is the category | |
1207 * being requested. | |
1208 * - "weight": An integer that determines the relative position of items in | |
1209 * the menu; higher-weighted items sink. Defaults to 0. Menu items with the | |
1210 * same weight are ordered alphabetically. | |
1211 * - "menu_name": Optional. Set this to a custom menu if you don't want your | |
1212 * item to be placed in Navigation. | |
1213 * - "expanded": Optional. If set to TRUE, and if a menu link is provided for | |
1214 * this menu item (as a result of other properties), then the menu link is | |
1215 * always expanded, equivalent to its 'always expanded' checkbox being set | |
1216 * in the UI. | |
1217 * - "context": (optional) Defines the context a tab may appear in. By | |
1218 * default, all tabs are only displayed as local tasks when being rendered | |
1219 * in a page context. All tabs that should be accessible as contextual links | |
1220 * in page region containers outside of the parent menu item's primary page | |
1221 * context should be registered using one of the following contexts: | |
1222 * - MENU_CONTEXT_PAGE: (default) The tab is displayed as local task for the | |
1223 * page context only. | |
1224 * - MENU_CONTEXT_INLINE: The tab is displayed as contextual link outside of | |
1225 * the primary page context only. | |
1226 * Contexts can be combined. For example, to display a tab both on a page | |
1227 * and inline, a menu router item may specify: | |
1228 * @code | |
1229 * 'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE, | |
1230 * @endcode | |
1231 * - "tab_parent": For local task menu items, the path of the task's parent | |
1232 * item; defaults to the same path without the last component (e.g., the | |
1233 * default parent for 'admin/people/create' is 'admin/people'). | |
1234 * - "tab_root": For local task menu items, the path of the closest non-tab | |
1235 * item; same default as "tab_parent". | |
1236 * - "position": Position of the block ('left' or 'right') on the system | |
1237 * administration page for this item. | |
1238 * - "type": A bitmask of flags describing properties of the menu item. | |
1239 * Many shortcut bitmasks are provided as constants in menu.inc: | |
1240 * - MENU_NORMAL_ITEM: Normal menu items show up in the menu tree and can be | |
1241 * moved/hidden by the administrator. | |
1242 * - MENU_CALLBACK: Callbacks simply register a path so that the correct | |
1243 * information is generated when the path is accessed. | |
1244 * - MENU_SUGGESTED_ITEM: Modules may "suggest" menu items that the | |
1245 * administrator may enable. | |
1246 * - MENU_LOCAL_ACTION: Local actions are menu items that describe actions | |
1247 * on the parent item such as adding a new user or block, and are | |
1248 * rendered in the action-links list in your theme. | |
1249 * - MENU_LOCAL_TASK: Local tasks are menu items that describe different | |
1250 * displays of data, and are generally rendered as tabs. | |
1251 * - MENU_DEFAULT_LOCAL_TASK: Every set of local tasks should provide one | |
1252 * "default" task, which should display the same page as the parent item. | |
1253 * If the "type" element is omitted, MENU_NORMAL_ITEM is assumed. | |
1254 * - "options": An array of options to be passed to l() when generating a link | |
1255 * from this menu item. Note that the "options" parameter has no effect on | |
1256 * MENU_LOCAL_TASK, MENU_DEFAULT_LOCAL_TASK, and MENU_LOCAL_ACTION items. | |
1257 * | |
1258 * For a detailed usage example, see page_example.module. | |
1259 * For comprehensive documentation on the menu system, see | |
1260 * http://drupal.org/node/102338. | |
1261 */ | |
1262 function hook_menu() { | |
1263 $items['example'] = array( | |
1264 'title' => 'Example Page', | |
1265 'page callback' => 'example_page', | |
1266 'access arguments' => array('access content'), | |
1267 'type' => MENU_SUGGESTED_ITEM, | |
1268 ); | |
1269 $items['example/feed'] = array( | |
1270 'title' => 'Example RSS feed', | |
1271 'page callback' => 'example_feed', | |
1272 'access arguments' => array('access content'), | |
1273 'type' => MENU_CALLBACK, | |
1274 ); | |
1275 | |
1276 return $items; | |
1277 } | |
1278 | |
1279 /** | |
1280 * Alter the data being saved to the {menu_router} table after hook_menu is invoked. | |
1281 * | |
1282 * This hook is invoked by menu_router_build(). The menu definitions are passed | |
1283 * in by reference. Each element of the $items array is one item returned | |
1284 * by a module from hook_menu. Additional items may be added, or existing items | |
1285 * altered. | |
1286 * | |
1287 * @param $items | |
1288 * Associative array of menu router definitions returned from hook_menu(). | |
1289 */ | |
1290 function hook_menu_alter(&$items) { | |
1291 // Example - disable the page at node/add | |
1292 $items['node/add']['access callback'] = FALSE; | |
1293 } | |
1294 | |
1295 /** | |
1296 * Alter the data being saved to the {menu_links} table by menu_link_save(). | |
1297 * | |
1298 * @param $item | |
1299 * Associative array defining a menu link as passed into menu_link_save(). | |
1300 * | |
1301 * @see hook_translated_menu_link_alter() | |
1302 */ | |
1303 function hook_menu_link_alter(&$item) { | |
1304 // Make all new admin links hidden (a.k.a disabled). | |
1305 if (strpos($item['link_path'], 'admin') === 0 && empty($item['mlid'])) { | |
1306 $item['hidden'] = 1; | |
1307 } | |
1308 // Flag a link to be altered by hook_translated_menu_link_alter(). | |
1309 if ($item['link_path'] == 'devel/cache/clear') { | |
1310 $item['options']['alter'] = TRUE; | |
1311 } | |
1312 // Flag a link to be altered by hook_translated_menu_link_alter(), but only | |
1313 // if it is derived from a menu router item; i.e., do not alter a custom | |
1314 // menu link pointing to the same path that has been created by a user. | |
1315 if ($item['link_path'] == 'user' && $item['module'] == 'system') { | |
1316 $item['options']['alter'] = TRUE; | |
1317 } | |
1318 } | |
1319 | |
1320 /** | |
1321 * Alter a menu link after it has been translated and before it is rendered. | |
1322 * | |
1323 * This hook is invoked from _menu_link_translate() after a menu link has been | |
1324 * translated; i.e., after dynamic path argument placeholders (%) have been | |
1325 * replaced with actual values, the user access to the link's target page has | |
1326 * been checked, and the link has been localized. It is only invoked if | |
1327 * $item['options']['alter'] has been set to a non-empty value (e.g., TRUE). | |
1328 * This flag should be set using hook_menu_link_alter(). | |
1329 * | |
1330 * Implementations of this hook are able to alter any property of the menu link. | |
1331 * For example, this hook may be used to add a page-specific query string to all | |
1332 * menu links, or hide a certain link by setting: | |
1333 * @code | |
1334 * 'hidden' => 1, | |
1335 * @endcode | |
1336 * | |
1337 * @param $item | |
1338 * Associative array defining a menu link after _menu_link_translate() | |
1339 * @param $map | |
1340 * Associative array containing the menu $map (path parts and/or objects). | |
1341 * | |
1342 * @see hook_menu_link_alter() | |
1343 */ | |
1344 function hook_translated_menu_link_alter(&$item, $map) { | |
1345 if ($item['href'] == 'devel/cache/clear') { | |
1346 $item['localized_options']['query'] = drupal_get_destination(); | |
1347 } | |
1348 } | |
1349 | |
1350 /** | |
1351 * Inform modules that a menu link has been created. | |
1352 * | |
1353 * This hook is used to notify modules that menu items have been | |
1354 * created. Contributed modules may use the information to perform | |
1355 * actions based on the information entered into the menu system. | |
1356 * | |
1357 * @param $link | |
1358 * Associative array defining a menu link as passed into menu_link_save(). | |
1359 * | |
1360 * @see hook_menu_link_update() | |
1361 * @see hook_menu_link_delete() | |
1362 */ | |
1363 function hook_menu_link_insert($link) { | |
1364 // In our sample case, we track menu items as editing sections | |
1365 // of the site. These are stored in our table as 'disabled' items. | |
1366 $record['mlid'] = $link['mlid']; | |
1367 $record['menu_name'] = $link['menu_name']; | |
1368 $record['status'] = 0; | |
1369 drupal_write_record('menu_example', $record); | |
1370 } | |
1371 | |
1372 /** | |
1373 * Inform modules that a menu link has been updated. | |
1374 * | |
1375 * This hook is used to notify modules that menu items have been | |
1376 * updated. Contributed modules may use the information to perform | |
1377 * actions based on the information entered into the menu system. | |
1378 * | |
1379 * @param $link | |
1380 * Associative array defining a menu link as passed into menu_link_save(). | |
1381 * | |
1382 * @see hook_menu_link_insert() | |
1383 * @see hook_menu_link_delete() | |
1384 */ | |
1385 function hook_menu_link_update($link) { | |
1386 // If the parent menu has changed, update our record. | |
1387 $menu_name = db_query("SELECT menu_name FROM {menu_example} WHERE mlid = :mlid", array(':mlid' => $link['mlid']))->fetchField(); | |
1388 if ($menu_name != $link['menu_name']) { | |
1389 db_update('menu_example') | |
1390 ->fields(array('menu_name' => $link['menu_name'])) | |
1391 ->condition('mlid', $link['mlid']) | |
1392 ->execute(); | |
1393 } | |
1394 } | |
1395 | |
1396 /** | |
1397 * Inform modules that a menu link has been deleted. | |
1398 * | |
1399 * This hook is used to notify modules that menu items have been | |
1400 * deleted. Contributed modules may use the information to perform | |
1401 * actions based on the information entered into the menu system. | |
1402 * | |
1403 * @param $link | |
1404 * Associative array defining a menu link as passed into menu_link_save(). | |
1405 * | |
1406 * @see hook_menu_link_insert() | |
1407 * @see hook_menu_link_update() | |
1408 */ | |
1409 function hook_menu_link_delete($link) { | |
1410 // Delete the record from our table. | |
1411 db_delete('menu_example') | |
1412 ->condition('mlid', $link['mlid']) | |
1413 ->execute(); | |
1414 } | |
1415 | |
1416 /** | |
1417 * Alter tabs and actions displayed on the page before they are rendered. | |
1418 * | |
1419 * This hook is invoked by menu_local_tasks(). The system-determined tabs and | |
1420 * actions are passed in by reference. Additional tabs or actions may be added, | |
1421 * or existing items altered. | |
1422 * | |
1423 * Each tab or action is an associative array containing: | |
1424 * - #theme: The theme function to use to render. | |
1425 * - #link: An associative array containing: | |
1426 * - title: The localized title of the link. | |
1427 * - href: The system path to link to. | |
1428 * - localized_options: An array of options to pass to l(). | |
1429 * - #active: Whether the link should be marked as 'active'. | |
1430 * | |
1431 * @param $data | |
1432 * An associative array containing: | |
1433 * - actions: An associative array containing: | |
1434 * - count: The amount of actions determined by the menu system, which can | |
1435 * be ignored. | |
1436 * - output: A list of of actions, each one being an associative array | |
1437 * as described above. | |
1438 * - tabs: An indexed array (list) of tab levels (up to 2 levels), each | |
1439 * containing an associative array: | |
1440 * - count: The amount of tabs determined by the menu system. This value | |
1441 * does not need to be altered if there is more than one tab. | |
1442 * - output: A list of of tabs, each one being an associative array as | |
1443 * described above. | |
1444 * @param $router_item | |
1445 * The menu system router item of the page. | |
1446 * @param $root_path | |
1447 * The path to the root item for this set of tabs. | |
1448 */ | |
1449 function hook_menu_local_tasks_alter(&$data, $router_item, $root_path) { | |
1450 // Add an action linking to node/add to all pages. | |
1451 $data['actions']['output'][] = array( | |
1452 '#theme' => 'menu_local_task', | |
1453 '#link' => array( | |
1454 'title' => t('Add new content'), | |
1455 'href' => 'node/add', | |
1456 'localized_options' => array( | |
1457 'attributes' => array( | |
1458 'title' => t('Add new content'), | |
1459 ), | |
1460 ), | |
1461 ), | |
1462 ); | |
1463 | |
1464 // Add a tab linking to node/add to all pages. | |
1465 $data['tabs'][0]['output'][] = array( | |
1466 '#theme' => 'menu_local_task', | |
1467 '#link' => array( | |
1468 'title' => t('Example tab'), | |
1469 'href' => 'node/add', | |
1470 'localized_options' => array( | |
1471 'attributes' => array( | |
1472 'title' => t('Add new content'), | |
1473 ), | |
1474 ), | |
1475 ), | |
1476 // Define whether this link is active. This can be omitted for | |
1477 // implementations that add links to pages outside of the current page | |
1478 // context. | |
1479 '#active' => ($router_item['path'] == $root_path), | |
1480 ); | |
1481 } | |
1482 | |
1483 /** | |
1484 * Alter links in the active trail before it is rendered as the breadcrumb. | |
1485 * | |
1486 * This hook is invoked by menu_get_active_breadcrumb() and allows alteration | |
1487 * of the breadcrumb links for the current page, which may be preferred instead | |
1488 * of setting a custom breadcrumb via drupal_set_breadcrumb(). | |
1489 * | |
1490 * Implementations should take into account that menu_get_active_breadcrumb() | |
1491 * subsequently performs the following adjustments to the active trail *after* | |
1492 * this hook has been invoked: | |
1493 * - The last link in $active_trail is removed, if its 'href' is identical to | |
1494 * the 'href' of $item. This happens, because the breadcrumb normally does | |
1495 * not contain a link to the current page. | |
1496 * - The (second to) last link in $active_trail is removed, if the current $item | |
1497 * is a MENU_DEFAULT_LOCAL_TASK. This happens in order to do not show a link | |
1498 * to the current page, when being on the path for the default local task; | |
1499 * e.g. when being on the path node/%/view, the breadcrumb should not contain | |
1500 * a link to node/%. | |
1501 * | |
1502 * Each link in the active trail must contain: | |
1503 * - title: The localized title of the link. | |
1504 * - href: The system path to link to. | |
1505 * - localized_options: An array of options to pass to url(). | |
1506 * | |
1507 * @param $active_trail | |
1508 * An array containing breadcrumb links for the current page. | |
1509 * @param $item | |
1510 * The menu router item of the current page. | |
1511 * | |
1512 * @see drupal_set_breadcrumb() | |
1513 * @see menu_get_active_breadcrumb() | |
1514 * @see menu_get_active_trail() | |
1515 * @see menu_set_active_trail() | |
1516 */ | |
1517 function hook_menu_breadcrumb_alter(&$active_trail, $item) { | |
1518 // Always display a link to the current page by duplicating the last link in | |
1519 // the active trail. This means that menu_get_active_breadcrumb() will remove | |
1520 // the last link (for the current page), but since it is added once more here, | |
1521 // it will appear. | |
1522 if (!drupal_is_front_page()) { | |
1523 $end = end($active_trail); | |
1524 if ($item['href'] == $end['href']) { | |
1525 $active_trail[] = $end; | |
1526 } | |
1527 } | |
1528 } | |
1529 | |
1530 /** | |
1531 * Alter contextual links before they are rendered. | |
1532 * | |
1533 * This hook is invoked by menu_contextual_links(). The system-determined | |
1534 * contextual links are passed in by reference. Additional links may be added | |
1535 * or existing links can be altered. | |
1536 * | |
1537 * Each contextual link must at least contain: | |
1538 * - title: The localized title of the link. | |
1539 * - href: The system path to link to. | |
1540 * - localized_options: An array of options to pass to url(). | |
1541 * | |
1542 * @param $links | |
1543 * An associative array containing contextual links for the given $root_path, | |
1544 * as described above. The array keys are used to build CSS class names for | |
1545 * contextual links and must therefore be unique for each set of contextual | |
1546 * links. | |
1547 * @param $router_item | |
1548 * The menu router item belonging to the $root_path being requested. | |
1549 * @param $root_path | |
1550 * The (parent) path that has been requested to build contextual links for. | |
1551 * This is a normalized path, which means that an originally passed path of | |
1552 * 'node/123' became 'node/%'. | |
1553 * | |
1554 * @see hook_contextual_links_view_alter() | |
1555 * @see menu_contextual_links() | |
1556 * @see hook_menu() | |
1557 * @see contextual_preprocess() | |
1558 */ | |
1559 function hook_menu_contextual_links_alter(&$links, $router_item, $root_path) { | |
1560 // Add a link to all contextual links for nodes. | |
1561 if ($root_path == 'node/%') { | |
1562 $links['foo'] = array( | |
1563 'title' => t('Do fu'), | |
1564 'href' => 'foo/do', | |
1565 'localized_options' => array( | |
1566 'query' => array( | |
1567 'foo' => 'bar', | |
1568 ), | |
1569 ), | |
1570 ); | |
1571 } | |
1572 } | |
1573 | |
1574 /** | |
1575 * Perform alterations before a page is rendered. | |
1576 * | |
1577 * Use this hook when you want to remove or alter elements at the page | |
1578 * level, or add elements at the page level that depend on an other module's | |
1579 * elements (this hook runs after hook_page_build(). | |
1580 * | |
1581 * If you are making changes to entities such as forms, menus, or user | |
1582 * profiles, use those objects' native alter hooks instead (hook_form_alter(), | |
1583 * for example). | |
1584 * | |
1585 * The $page array contains top level elements for each block region: | |
1586 * @code | |
1587 * $page['page_top'] | |
1588 * $page['header'] | |
1589 * $page['sidebar_first'] | |
1590 * $page['content'] | |
1591 * $page['sidebar_second'] | |
1592 * $page['page_bottom'] | |
1593 * @endcode | |
1594 * | |
1595 * The 'content' element contains the main content of the current page, and its | |
1596 * structure will vary depending on what module is responsible for building the | |
1597 * page. Some legacy modules may not return structured content at all: their | |
1598 * pre-rendered markup will be located in $page['content']['main']['#markup']. | |
1599 * | |
1600 * Pages built by Drupal's core Node and Blog modules use a standard structure: | |
1601 * | |
1602 * @code | |
1603 * // Node body. | |
1604 * $page['content']['system_main']['nodes'][$nid]['body'] | |
1605 * // Array of links attached to the node (add comments, read more). | |
1606 * $page['content']['system_main']['nodes'][$nid]['links'] | |
1607 * // The node object itself. | |
1608 * $page['content']['system_main']['nodes'][$nid]['#node'] | |
1609 * // The results pager. | |
1610 * $page['content']['system_main']['pager'] | |
1611 * @endcode | |
1612 * | |
1613 * Blocks may be referenced by their module/delta pair within a region: | |
1614 * @code | |
1615 * // The login block in the first sidebar region. | |
1616 * $page['sidebar_first']['user_login']['#block']; | |
1617 * @endcode | |
1618 * | |
1619 * @param $page | |
1620 * Nested array of renderable elements that make up the page. | |
1621 * | |
1622 * @see hook_page_build() | |
1623 * @see drupal_render_page() | |
1624 */ | |
1625 function hook_page_alter(&$page) { | |
1626 // Add help text to the user login block. | |
1627 $page['sidebar_first']['user_login']['help'] = array( | |
1628 '#weight' => -10, | |
1629 '#markup' => t('To post comments or add new content, you first have to log in.'), | |
1630 ); | |
1631 } | |
1632 | |
1633 /** | |
1634 * Perform alterations before a form is rendered. | |
1635 * | |
1636 * One popular use of this hook is to add form elements to the node form. When | |
1637 * altering a node form, the node object can be accessed at $form['#node']. | |
1638 * | |
1639 * In addition to hook_form_alter(), which is called for all forms, there are | |
1640 * two more specific form hooks available. The first, | |
1641 * hook_form_BASE_FORM_ID_alter(), allows targeting of a form/forms via a base | |
1642 * form (if one exists). The second, hook_form_FORM_ID_alter(), can be used to | |
1643 * target a specific form directly. | |
1644 * | |
1645 * The call order is as follows: all existing form alter functions are called | |
1646 * for module A, then all for module B, etc., followed by all for any base | |
1647 * theme(s), and finally for the theme itself. The module order is determined | |
1648 * by system weight, then by module name. | |
1649 * | |
1650 * Within each module, form alter hooks are called in the following order: | |
1651 * first, hook_form_alter(); second, hook_form_BASE_FORM_ID_alter(); third, | |
1652 * hook_form_FORM_ID_alter(). So, for each module, the more general hooks are | |
1653 * called first followed by the more specific. | |
1654 * | |
1655 * @param $form | |
1656 * Nested array of form elements that comprise the form. | |
1657 * @param $form_state | |
1658 * A keyed array containing the current state of the form. The arguments | |
1659 * that drupal_get_form() was originally called with are available in the | |
1660 * array $form_state['build_info']['args']. | |
1661 * @param $form_id | |
1662 * String representing the name of the form itself. Typically this is the | |
1663 * name of the function that generated the form. | |
1664 * | |
1665 * @see hook_form_BASE_FORM_ID_alter() | |
1666 * @see hook_form_FORM_ID_alter() | |
1667 * @see forms_api_reference.html | |
1668 */ | |
1669 function hook_form_alter(&$form, &$form_state, $form_id) { | |
1670 if (isset($form['type']) && $form['type']['#value'] . '_node_settings' == $form_id) { | |
1671 $form['workflow']['upload_' . $form['type']['#value']] = array( | |
1672 '#type' => 'radios', | |
1673 '#title' => t('Attachments'), | |
1674 '#default_value' => variable_get('upload_' . $form['type']['#value'], 1), | |
1675 '#options' => array(t('Disabled'), t('Enabled')), | |
1676 ); | |
1677 } | |
1678 } | |
1679 | |
1680 /** | |
1681 * Provide a form-specific alteration instead of the global hook_form_alter(). | |
1682 * | |
1683 * Modules can implement hook_form_FORM_ID_alter() to modify a specific form, | |
1684 * rather than implementing hook_form_alter() and checking the form ID, or | |
1685 * using long switch statements to alter multiple forms. | |
1686 * | |
1687 * Form alter hooks are called in the following order: hook_form_alter(), | |
1688 * hook_form_BASE_FORM_ID_alter(), hook_form_FORM_ID_alter(). See | |
1689 * hook_form_alter() for more details. | |
1690 * | |
1691 * @param $form | |
1692 * Nested array of form elements that comprise the form. | |
1693 * @param $form_state | |
1694 * A keyed array containing the current state of the form. The arguments | |
1695 * that drupal_get_form() was originally called with are available in the | |
1696 * array $form_state['build_info']['args']. | |
1697 * @param $form_id | |
1698 * String representing the name of the form itself. Typically this is the | |
1699 * name of the function that generated the form. | |
1700 * | |
1701 * @see hook_form_alter() | |
1702 * @see hook_form_BASE_FORM_ID_alter() | |
1703 * @see drupal_prepare_form() | |
1704 * @see forms_api_reference.html | |
1705 */ | |
1706 function hook_form_FORM_ID_alter(&$form, &$form_state, $form_id) { | |
1707 // Modification for the form with the given form ID goes here. For example, if | |
1708 // FORM_ID is "user_register_form" this code would run only on the user | |
1709 // registration form. | |
1710 | |
1711 // Add a checkbox to registration form about agreeing to terms of use. | |
1712 $form['terms_of_use'] = array( | |
1713 '#type' => 'checkbox', | |
1714 '#title' => t("I agree with the website's terms and conditions."), | |
1715 '#required' => TRUE, | |
1716 ); | |
1717 } | |
1718 | |
1719 /** | |
1720 * Provide a form-specific alteration for shared ('base') forms. | |
1721 * | |
1722 * By default, when drupal_get_form() is called, Drupal looks for a function | |
1723 * with the same name as the form ID, and uses that function to build the form. | |
1724 * In contrast, base forms allow multiple form IDs to be mapped to a single base | |
1725 * (also called 'factory') form function. | |
1726 * | |
1727 * Modules can implement hook_form_BASE_FORM_ID_alter() to modify a specific | |
1728 * base form, rather than implementing hook_form_alter() and checking for | |
1729 * conditions that would identify the shared form constructor. | |
1730 * | |
1731 * To identify the base form ID for a particular form (or to determine whether | |
1732 * one exists) check the $form_state. The base form ID is stored under | |
1733 * $form_state['build_info']['base_form_id']. | |
1734 * | |
1735 * See hook_forms() for more information on how to implement base forms in | |
1736 * Drupal. | |
1737 * | |
1738 * Form alter hooks are called in the following order: hook_form_alter(), | |
1739 * hook_form_BASE_FORM_ID_alter(), hook_form_FORM_ID_alter(). See | |
1740 * hook_form_alter() for more details. | |
1741 * | |
1742 * @param $form | |
1743 * Nested array of form elements that comprise the form. | |
1744 * @param $form_state | |
1745 * A keyed array containing the current state of the form. | |
1746 * @param $form_id | |
1747 * String representing the name of the form itself. Typically this is the | |
1748 * name of the function that generated the form. | |
1749 * | |
1750 * @see hook_form_alter() | |
1751 * @see hook_form_FORM_ID_alter() | |
1752 * @see drupal_prepare_form() | |
1753 * @see hook_forms() | |
1754 */ | |
1755 function hook_form_BASE_FORM_ID_alter(&$form, &$form_state, $form_id) { | |
1756 // Modification for the form with the given BASE_FORM_ID goes here. For | |
1757 // example, if BASE_FORM_ID is "node_form", this code would run on every | |
1758 // node form, regardless of node type. | |
1759 | |
1760 // Add a checkbox to the node form about agreeing to terms of use. | |
1761 $form['terms_of_use'] = array( | |
1762 '#type' => 'checkbox', | |
1763 '#title' => t("I agree with the website's terms and conditions."), | |
1764 '#required' => TRUE, | |
1765 ); | |
1766 } | |
1767 | |
1768 /** | |
1769 * Map form_ids to form builder functions. | |
1770 * | |
1771 * By default, when drupal_get_form() is called, the system will look for a | |
1772 * function with the same name as the form ID, and use that function to build | |
1773 * the form. If no such function is found, Drupal calls this hook. Modules | |
1774 * implementing this hook can then provide their own instructions for mapping | |
1775 * form IDs to constructor functions. As a result, you can easily map multiple | |
1776 * form IDs to a single form constructor (referred to as a 'base' form). | |
1777 * | |
1778 * Using a base form can help to avoid code duplication, by allowing many | |
1779 * similar forms to use the same code base. Another benefit is that it becomes | |
1780 * much easier for other modules to apply a general change to the group of | |
1781 * forms; hook_form_BASE_FORM_ID_alter() can be used to easily alter multiple | |
1782 * forms at once by directly targeting the shared base form. | |
1783 * | |
1784 * Two example use cases where base forms may be useful are given below. | |
1785 * | |
1786 * First, you can use this hook to tell the form system to use a different | |
1787 * function to build certain forms in your module; this is often used to define | |
1788 * a form "factory" function that is used to build several similar forms. In | |
1789 * this case, your hook implementation will likely ignore all of the input | |
1790 * arguments. See node_forms() for an example of this. Note, node_forms() is the | |
1791 * hook_forms() implementation; the base form itself is defined in node_form(). | |
1792 * | |
1793 * Second, you could use this hook to define how to build a form with a | |
1794 * dynamically-generated form ID. In this case, you would need to verify that | |
1795 * the $form_id input matched your module's format for dynamically-generated | |
1796 * form IDs, and if so, act appropriately. | |
1797 * | |
1798 * @param $form_id | |
1799 * The unique string identifying the desired form. | |
1800 * @param $args | |
1801 * An array containing the original arguments provided to drupal_get_form() | |
1802 * or drupal_form_submit(). These are always passed to the form builder and | |
1803 * do not have to be specified manually in 'callback arguments'. | |
1804 * | |
1805 * @return | |
1806 * An associative array whose keys define form_ids and whose values are an | |
1807 * associative array defining the following keys: | |
1808 * - callback: The name of the form builder function to invoke. This will be | |
1809 * used for the base form ID, for example, to target a base form using | |
1810 * hook_form_BASE_FORM_ID_alter(). | |
1811 * - callback arguments: (optional) Additional arguments to pass to the | |
1812 * function defined in 'callback', which are prepended to $args. | |
1813 * - wrapper_callback: (optional) The name of a form builder function to | |
1814 * invoke before the form builder defined in 'callback' is invoked. This | |
1815 * wrapper callback may prepopulate the $form array with form elements, | |
1816 * which will then be already contained in the $form that is passed on to | |
1817 * the form builder defined in 'callback'. For example, a wrapper callback | |
1818 * could setup wizard-alike form buttons that are the same for a variety of | |
1819 * forms that belong to the wizard, which all share the same wrapper | |
1820 * callback. | |
1821 */ | |
1822 function hook_forms($form_id, $args) { | |
1823 // Simply reroute the (non-existing) $form_id 'mymodule_first_form' to | |
1824 // 'mymodule_main_form'. | |
1825 $forms['mymodule_first_form'] = array( | |
1826 'callback' => 'mymodule_main_form', | |
1827 ); | |
1828 | |
1829 // Reroute the $form_id and prepend an additional argument that gets passed to | |
1830 // the 'mymodule_main_form' form builder function. | |
1831 $forms['mymodule_second_form'] = array( | |
1832 'callback' => 'mymodule_main_form', | |
1833 'callback arguments' => array('some parameter'), | |
1834 ); | |
1835 | |
1836 // Reroute the $form_id, but invoke the form builder function | |
1837 // 'mymodule_main_form_wrapper' first, so we can prepopulate the $form array | |
1838 // that is passed to the actual form builder 'mymodule_main_form'. | |
1839 $forms['mymodule_wrapped_form'] = array( | |
1840 'callback' => 'mymodule_main_form', | |
1841 'wrapper_callback' => 'mymodule_main_form_wrapper', | |
1842 ); | |
1843 | |
1844 return $forms; | |
1845 } | |
1846 | |
1847 /** | |
1848 * Perform setup tasks for all page requests. | |
1849 * | |
1850 * This hook is run at the beginning of the page request. It is typically | |
1851 * used to set up global parameters that are needed later in the request. | |
1852 * | |
1853 * Only use this hook if your code must run even for cached page views. This | |
1854 * hook is called before the theme, modules, or most include files are loaded | |
1855 * into memory. It happens while Drupal is still in bootstrap mode. | |
1856 * | |
1857 * @see hook_init() | |
1858 */ | |
1859 function hook_boot() { | |
1860 // We need user_access() in the shutdown function. Make sure it gets loaded. | |
1861 drupal_load('module', 'user'); | |
1862 drupal_register_shutdown_function('devel_shutdown'); | |
1863 } | |
1864 | |
1865 /** | |
1866 * Perform setup tasks for non-cached page requests. | |
1867 * | |
1868 * This hook is run at the beginning of the page request. It is typically | |
1869 * used to set up global parameters that are needed later in the request. | |
1870 * When this hook is called, the theme and all modules are already loaded in | |
1871 * memory. | |
1872 * | |
1873 * This hook is not run on cached pages. | |
1874 * | |
1875 * To add CSS or JS that should be present on all pages, modules should not | |
1876 * implement this hook, but declare these files in their .info file. | |
1877 * | |
1878 * @see hook_boot() | |
1879 */ | |
1880 function hook_init() { | |
1881 // Since this file should only be loaded on the front page, it cannot be | |
1882 // declared in the info file. | |
1883 if (drupal_is_front_page()) { | |
1884 drupal_add_css(drupal_get_path('module', 'foo') . '/foo.css'); | |
1885 } | |
1886 } | |
1887 | |
1888 /** | |
1889 * Define image toolkits provided by this module. | |
1890 * | |
1891 * The file which includes each toolkit's functions must be declared as part of | |
1892 * the files array in the module .info file so that the registry will find and | |
1893 * parse it. | |
1894 * | |
1895 * The toolkit's functions must be named image_toolkitname_operation(). | |
1896 * where the operation may be: | |
1897 * - 'load': Required. See image_gd_load() for usage. | |
1898 * - 'save': Required. See image_gd_save() for usage. | |
1899 * - 'settings': Optional. See image_gd_settings() for usage. | |
1900 * - 'resize': Optional. See image_gd_resize() for usage. | |
1901 * - 'rotate': Optional. See image_gd_rotate() for usage. | |
1902 * - 'crop': Optional. See image_gd_crop() for usage. | |
1903 * - 'desaturate': Optional. See image_gd_desaturate() for usage. | |
1904 * | |
1905 * @return | |
1906 * An array with the toolkit name as keys and sub-arrays with these keys: | |
1907 * - 'title': A string with the toolkit's title. | |
1908 * - 'available': A Boolean value to indicate that the toolkit is operating | |
1909 * properly, e.g. all required libraries exist. | |
1910 * | |
1911 * @see system_image_toolkits() | |
1912 */ | |
1913 function hook_image_toolkits() { | |
1914 return array( | |
1915 'working' => array( | |
1916 'title' => t('A toolkit that works.'), | |
1917 'available' => TRUE, | |
1918 ), | |
1919 'broken' => array( | |
1920 'title' => t('A toolkit that is "broken" and will not be listed.'), | |
1921 'available' => FALSE, | |
1922 ), | |
1923 ); | |
1924 } | |
1925 | |
1926 /** | |
1927 * Alter an email message created with the drupal_mail() function. | |
1928 * | |
1929 * hook_mail_alter() allows modification of email messages created and sent | |
1930 * with drupal_mail(). Usage examples include adding and/or changing message | |
1931 * text, message fields, and message headers. | |
1932 * | |
1933 * Email messages sent using functions other than drupal_mail() will not | |
1934 * invoke hook_mail_alter(). For example, a contributed module directly | |
1935 * calling the drupal_mail_system()->mail() or PHP mail() function | |
1936 * will not invoke this hook. All core modules use drupal_mail() for | |
1937 * messaging, it is best practice but not mandatory in contributed modules. | |
1938 * | |
1939 * @param $message | |
1940 * An array containing the message data. Keys in this array include: | |
1941 * - 'id': | |
1942 * The drupal_mail() id of the message. Look at module source code or | |
1943 * drupal_mail() for possible id values. | |
1944 * - 'to': | |
1945 * The address or addresses the message will be sent to. The formatting of | |
1946 * this string will be validated with the | |
1947 * @link http://php.net/manual/filter.filters.validate.php PHP e-mail validation filter. @endlink | |
1948 * - 'from': | |
1949 * The address the message will be marked as being from, which is | |
1950 * either a custom address or the site-wide default email address. | |
1951 * - 'subject': | |
1952 * Subject of the email to be sent. This must not contain any newline | |
1953 * characters, or the email may not be sent properly. | |
1954 * - 'body': | |
1955 * An array of strings containing the message text. The message body is | |
1956 * created by concatenating the individual array strings into a single text | |
1957 * string using "\n\n" as a separator. | |
1958 * - 'headers': | |
1959 * Associative array containing mail headers, such as From, Sender, | |
1960 * MIME-Version, Content-Type, etc. | |
1961 * - 'params': | |
1962 * An array of optional parameters supplied by the caller of drupal_mail() | |
1963 * that is used to build the message before hook_mail_alter() is invoked. | |
1964 * - 'language': | |
1965 * The language object used to build the message before hook_mail_alter() | |
1966 * is invoked. | |
1967 * - 'send': | |
1968 * Set to FALSE to abort sending this email message. | |
1969 * | |
1970 * @see drupal_mail() | |
1971 */ | |
1972 function hook_mail_alter(&$message) { | |
1973 if ($message['id'] == 'modulename_messagekey') { | |
1974 if (!example_notifications_optin($message['to'], $message['id'])) { | |
1975 // If the recipient has opted to not receive such messages, cancel | |
1976 // sending. | |
1977 $message['send'] = FALSE; | |
1978 return; | |
1979 } | |
1980 $message['body'][] = "--\nMail sent out from " . variable_get('site_name', t('Drupal')); | |
1981 } | |
1982 } | |
1983 | |
1984 /** | |
1985 * Alter the registry of modules implementing a hook. | |
1986 * | |
1987 * This hook is invoked during module_implements(). A module may implement this | |
1988 * hook in order to reorder the implementing modules, which are otherwise | |
1989 * ordered by the module's system weight. | |
1990 * | |
1991 * Note that hooks invoked using drupal_alter() can have multiple variations | |
1992 * (such as hook_form_alter() and hook_form_FORM_ID_alter()). drupal_alter() | |
1993 * will call all such variants defined by a single module in turn. For the | |
1994 * purposes of hook_module_implements_alter(), these variants are treated as | |
1995 * a single hook. Thus, to ensure that your implementation of | |
1996 * hook_form_FORM_ID_alter() is called at the right time, you will have to | |
1997 * change the order of hook_form_alter() implementation in | |
1998 * hook_module_implements_alter(). | |
1999 * | |
2000 * @param $implementations | |
2001 * An array keyed by the module's name. The value of each item corresponds | |
2002 * to a $group, which is usually FALSE, unless the implementation is in a | |
2003 * file named $module.$group.inc. | |
2004 * @param $hook | |
2005 * The name of the module hook being implemented. | |
2006 */ | |
2007 function hook_module_implements_alter(&$implementations, $hook) { | |
2008 if ($hook == 'rdf_mapping') { | |
2009 // Move my_module_rdf_mapping() to the end of the list. module_implements() | |
2010 // iterates through $implementations with a foreach loop which PHP iterates | |
2011 // in the order that the items were added, so to move an item to the end of | |
2012 // the array, we remove it and then add it. | |
2013 $group = $implementations['my_module']; | |
2014 unset($implementations['my_module']); | |
2015 $implementations['my_module'] = $group; | |
2016 } | |
2017 } | |
2018 | |
2019 /** | |
2020 * Return additional themes provided by modules. | |
2021 * | |
2022 * Only use this hook for testing purposes. Use a hidden MYMODULE_test.module | |
2023 * to implement this hook. Testing themes should be hidden, too. | |
2024 * | |
2025 * This hook is invoked from _system_rebuild_theme_data() and allows modules to | |
2026 * register additional themes outside of the regular 'themes' directories of a | |
2027 * Drupal installation. | |
2028 * | |
2029 * @return | |
2030 * An associative array. Each key is the system name of a theme and each value | |
2031 * is the corresponding path to the theme's .info file. | |
2032 */ | |
2033 function hook_system_theme_info() { | |
2034 $themes['mymodule_test_theme'] = drupal_get_path('module', 'mymodule') . '/mymodule_test_theme/mymodule_test_theme.info'; | |
2035 return $themes; | |
2036 } | |
2037 | |
2038 /** | |
2039 * Alter the information parsed from module and theme .info files | |
2040 * | |
2041 * This hook is invoked in _system_rebuild_module_data() and in | |
2042 * _system_rebuild_theme_data(). A module may implement this hook in order to | |
2043 * add to or alter the data generated by reading the .info file with | |
2044 * drupal_parse_info_file(). | |
2045 * | |
2046 * @param $info | |
2047 * The .info file contents, passed by reference so that it can be altered. | |
2048 * @param $file | |
2049 * Full information about the module or theme, including $file->name, and | |
2050 * $file->filename | |
2051 * @param $type | |
2052 * Either 'module' or 'theme', depending on the type of .info file that was | |
2053 * passed. | |
2054 */ | |
2055 function hook_system_info_alter(&$info, $file, $type) { | |
2056 // Only fill this in if the .info file does not define a 'datestamp'. | |
2057 if (empty($info['datestamp'])) { | |
2058 $info['datestamp'] = filemtime($file->filename); | |
2059 } | |
2060 } | |
2061 | |
2062 /** | |
2063 * Define user permissions. | |
2064 * | |
2065 * This hook can supply permissions that the module defines, so that they | |
2066 * can be selected on the user permissions page and used to grant or restrict | |
2067 * access to actions the module performs. | |
2068 * | |
2069 * Permissions are checked using user_access(). | |
2070 * | |
2071 * For a detailed usage example, see page_example.module. | |
2072 * | |
2073 * @return | |
2074 * An array whose keys are permission names and whose corresponding values | |
2075 * are arrays containing the following key-value pairs: | |
2076 * - title: The human-readable name of the permission, to be shown on the | |
2077 * permission administration page. This should be wrapped in the t() | |
2078 * function so it can be translated. | |
2079 * - description: (optional) A description of what the permission does. This | |
2080 * should be wrapped in the t() function so it can be translated. | |
2081 * - restrict access: (optional) A boolean which can be set to TRUE to | |
2082 * indicate that site administrators should restrict access to this | |
2083 * permission to trusted users. This should be used for permissions that | |
2084 * have inherent security risks across a variety of potential use cases | |
2085 * (for example, the "administer filters" and "bypass node access" | |
2086 * permissions provided by Drupal core). When set to TRUE, a standard | |
2087 * warning message defined in user_admin_permissions() and output via | |
2088 * theme_user_permission_description() will be associated with the | |
2089 * permission and displayed with it on the permission administration page. | |
2090 * Defaults to FALSE. | |
2091 * - warning: (optional) A translated warning message to display for this | |
2092 * permission on the permission administration page. This warning overrides | |
2093 * the automatic warning generated by 'restrict access' being set to TRUE. | |
2094 * This should rarely be used, since it is important for all permissions to | |
2095 * have a clear, consistent security warning that is the same across the | |
2096 * site. Use the 'description' key instead to provide any information that | |
2097 * is specific to the permission you are defining. | |
2098 * | |
2099 * @see theme_user_permission_description() | |
2100 */ | |
2101 function hook_permission() { | |
2102 return array( | |
2103 'administer my module' => array( | |
2104 'title' => t('Administer my module'), | |
2105 'description' => t('Perform administration tasks for my module.'), | |
2106 ), | |
2107 ); | |
2108 } | |
2109 | |
2110 /** | |
2111 * Register a module (or theme's) theme implementations. | |
2112 * | |
2113 * The implementations declared by this hook have two purposes: either they | |
2114 * specify how a particular render array is to be rendered as HTML (this is | |
2115 * usually the case if the theme function is assigned to the render array's | |
2116 * #theme property), or they return the HTML that should be returned by an | |
2117 * invocation of theme(). See | |
2118 * @link http://drupal.org/node/933976 Using the theme layer Drupal 7.x @endlink | |
2119 * for more information on how to implement theme hooks. | |
2120 * | |
2121 * The following parameters are all optional. | |
2122 * | |
2123 * @param array $existing | |
2124 * An array of existing implementations that may be used for override | |
2125 * purposes. This is primarily useful for themes that may wish to examine | |
2126 * existing implementations to extract data (such as arguments) so that | |
2127 * it may properly register its own, higher priority implementations. | |
2128 * @param $type | |
2129 * Whether a theme, module, etc. is being processed. This is primarily useful | |
2130 * so that themes tell if they are the actual theme being called or a parent | |
2131 * theme. May be one of: | |
2132 * - 'module': A module is being checked for theme implementations. | |
2133 * - 'base_theme_engine': A theme engine is being checked for a theme that is | |
2134 * a parent of the actual theme being used. | |
2135 * - 'theme_engine': A theme engine is being checked for the actual theme | |
2136 * being used. | |
2137 * - 'base_theme': A base theme is being checked for theme implementations. | |
2138 * - 'theme': The actual theme in use is being checked. | |
2139 * @param $theme | |
2140 * The actual name of theme, module, etc. that is being being processed. | |
2141 * @param $path | |
2142 * The directory path of the theme or module, so that it doesn't need to be | |
2143 * looked up. | |
2144 * | |
2145 * @return array | |
2146 * An associative array of theme hook information. The keys on the outer | |
2147 * array are the internal names of the hooks, and the values are arrays | |
2148 * containing information about the hook. Each information array must contain | |
2149 * either a 'variables' element or a 'render element' element, but not both. | |
2150 * Use 'render element' if you are theming a single element or element tree | |
2151 * composed of elements, such as a form array, a page array, or a single | |
2152 * checkbox element. Use 'variables' if your theme implementation is | |
2153 * intended to be called directly through theme() and has multiple arguments | |
2154 * for the data and style; in this case, the variables not supplied by the | |
2155 * calling function will be given default values and passed to the template | |
2156 * or theme function. The returned theme information array can contain the | |
2157 * following key/value pairs: | |
2158 * - variables: (see above) Each array key is the name of the variable, and | |
2159 * the value given is used as the default value if the function calling | |
2160 * theme() does not supply it. Template implementations receive each array | |
2161 * key as a variable in the template file (so they must be legal PHP | |
2162 * variable names). Function implementations are passed the variables in a | |
2163 * single $variables function argument. | |
2164 * - render element: (see above) The name of the renderable element or element | |
2165 * tree to pass to the theme function. This name is used as the name of the | |
2166 * variable that holds the renderable element or tree in preprocess and | |
2167 * process functions. | |
2168 * - file: The file the implementation resides in. This file will be included | |
2169 * prior to the theme being rendered, to make sure that the function or | |
2170 * preprocess function (as needed) is actually loaded; this makes it | |
2171 * possible to split theme functions out into separate files quite easily. | |
2172 * - path: Override the path of the file to be used. Ordinarily the module or | |
2173 * theme path will be used, but if the file will not be in the default | |
2174 * path, include it here. This path should be relative to the Drupal root | |
2175 * directory. | |
2176 * - template: If specified, this theme implementation is a template, and | |
2177 * this is the template file without an extension. Do not put .tpl.php on | |
2178 * this file; that extension will be added automatically by the default | |
2179 * rendering engine (which is PHPTemplate). If 'path', above, is specified, | |
2180 * the template should also be in this path. | |
2181 * - function: If specified, this will be the function name to invoke for | |
2182 * this implementation. If neither 'template' nor 'function' is specified, | |
2183 * a default function name will be assumed. For example, if a module | |
2184 * registers the 'node' theme hook, 'theme_node' will be assigned to its | |
2185 * function. If the chameleon theme registers the node hook, it will be | |
2186 * assigned 'chameleon_node' as its function. | |
2187 * - base hook: A string declaring the base theme hook if this theme | |
2188 * implementation is actually implementing a suggestion for another theme | |
2189 * hook. | |
2190 * - pattern: A regular expression pattern to be used to allow this theme | |
2191 * implementation to have a dynamic name. The convention is to use __ to | |
2192 * differentiate the dynamic portion of the theme. For example, to allow | |
2193 * forums to be themed individually, the pattern might be: 'forum__'. Then, | |
2194 * when the forum is themed, call: | |
2195 * @code | |
2196 * theme(array('forum__' . $tid, 'forum'), $forum) | |
2197 * @endcode | |
2198 * - preprocess functions: A list of functions used to preprocess this data. | |
2199 * Ordinarily this won't be used; it's automatically filled in. By default, | |
2200 * for a module this will be filled in as template_preprocess_HOOK. For | |
2201 * a theme this will be filled in as phptemplate_preprocess and | |
2202 * phptemplate_preprocess_HOOK as well as themename_preprocess and | |
2203 * themename_preprocess_HOOK. | |
2204 * - override preprocess functions: Set to TRUE when a theme does NOT want | |
2205 * the standard preprocess functions to run. This can be used to give a | |
2206 * theme FULL control over how variables are set. For example, if a theme | |
2207 * wants total control over how certain variables in the page.tpl.php are | |
2208 * set, this can be set to true. Please keep in mind that when this is used | |
2209 * by a theme, that theme becomes responsible for making sure necessary | |
2210 * variables are set. | |
2211 * - type: (automatically derived) Where the theme hook is defined: | |
2212 * 'module', 'theme_engine', or 'theme'. | |
2213 * - theme path: (automatically derived) The directory path of the theme or | |
2214 * module, so that it doesn't need to be looked up. | |
2215 * | |
2216 * @see hook_theme_registry_alter() | |
2217 */ | |
2218 function hook_theme($existing, $type, $theme, $path) { | |
2219 return array( | |
2220 'forum_display' => array( | |
2221 'variables' => array('forums' => NULL, 'topics' => NULL, 'parents' => NULL, 'tid' => NULL, 'sortby' => NULL, 'forum_per_page' => NULL), | |
2222 ), | |
2223 'forum_list' => array( | |
2224 'variables' => array('forums' => NULL, 'parents' => NULL, 'tid' => NULL), | |
2225 ), | |
2226 'forum_topic_list' => array( | |
2227 'variables' => array('tid' => NULL, 'topics' => NULL, 'sortby' => NULL, 'forum_per_page' => NULL), | |
2228 ), | |
2229 'forum_icon' => array( | |
2230 'variables' => array('new_posts' => NULL, 'num_posts' => 0, 'comment_mode' => 0, 'sticky' => 0), | |
2231 ), | |
2232 'status_report' => array( | |
2233 'render element' => 'requirements', | |
2234 'file' => 'system.admin.inc', | |
2235 ), | |
2236 'system_date_time_settings' => array( | |
2237 'render element' => 'form', | |
2238 'file' => 'system.admin.inc', | |
2239 ), | |
2240 ); | |
2241 } | |
2242 | |
2243 /** | |
2244 * Alter the theme registry information returned from hook_theme(). | |
2245 * | |
2246 * The theme registry stores information about all available theme hooks, | |
2247 * including which callback functions those hooks will call when triggered, | |
2248 * what template files are exposed by these hooks, and so on. | |
2249 * | |
2250 * Note that this hook is only executed as the theme cache is re-built. | |
2251 * Changes here will not be visible until the next cache clear. | |
2252 * | |
2253 * The $theme_registry array is keyed by theme hook name, and contains the | |
2254 * information returned from hook_theme(), as well as additional properties | |
2255 * added by _theme_process_registry(). | |
2256 * | |
2257 * For example: | |
2258 * @code | |
2259 * $theme_registry['user_profile'] = array( | |
2260 * 'variables' => array( | |
2261 * 'account' => NULL, | |
2262 * ), | |
2263 * 'template' => 'modules/user/user-profile', | |
2264 * 'file' => 'modules/user/user.pages.inc', | |
2265 * 'type' => 'module', | |
2266 * 'theme path' => 'modules/user', | |
2267 * 'preprocess functions' => array( | |
2268 * 0 => 'template_preprocess', | |
2269 * 1 => 'template_preprocess_user_profile', | |
2270 * ), | |
2271 * ); | |
2272 * @endcode | |
2273 * | |
2274 * @param $theme_registry | |
2275 * The entire cache of theme registry information, post-processing. | |
2276 * | |
2277 * @see hook_theme() | |
2278 * @see _theme_process_registry() | |
2279 */ | |
2280 function hook_theme_registry_alter(&$theme_registry) { | |
2281 // Kill the next/previous forum topic navigation links. | |
2282 foreach ($theme_registry['forum_topic_navigation']['preprocess functions'] as $key => $value) { | |
2283 if ($value == 'template_preprocess_forum_topic_navigation') { | |
2284 unset($theme_registry['forum_topic_navigation']['preprocess functions'][$key]); | |
2285 } | |
2286 } | |
2287 } | |
2288 | |
2289 /** | |
2290 * Return the machine-readable name of the theme to use for the current page. | |
2291 * | |
2292 * This hook can be used to dynamically set the theme for the current page | |
2293 * request. It should be used by modules which need to override the theme | |
2294 * based on dynamic conditions (for example, a module which allows the theme to | |
2295 * be set based on the current user's role). The return value of this hook will | |
2296 * be used on all pages except those which have a valid per-page or per-section | |
2297 * theme set via a theme callback function in hook_menu(); the themes on those | |
2298 * pages can only be overridden using hook_menu_alter(). | |
2299 * | |
2300 * Note that returning different themes for the same path may not work with page | |
2301 * caching. This is most likely to be a problem if an anonymous user on a given | |
2302 * path could have different themes returned under different conditions. | |
2303 * | |
2304 * Since only one theme can be used at a time, the last (i.e., highest | |
2305 * weighted) module which returns a valid theme name from this hook will | |
2306 * prevail. | |
2307 * | |
2308 * @return | |
2309 * The machine-readable name of the theme that should be used for the current | |
2310 * page request. The value returned from this function will only have an | |
2311 * effect if it corresponds to a currently-active theme on the site. Do not | |
2312 * return a value if you do not wish to set a custom theme. | |
2313 */ | |
2314 function hook_custom_theme() { | |
2315 // Allow the user to request a particular theme via a query parameter. | |
2316 if (isset($_GET['theme'])) { | |
2317 return $_GET['theme']; | |
2318 } | |
2319 } | |
2320 | |
2321 /** | |
2322 * Register XML-RPC callbacks. | |
2323 * | |
2324 * This hook lets a module register callback functions to be called when | |
2325 * particular XML-RPC methods are invoked by a client. | |
2326 * | |
2327 * @return | |
2328 * An array which maps XML-RPC methods to Drupal functions. Each array | |
2329 * element is either a pair of method => function or an array with four | |
2330 * entries: | |
2331 * - The XML-RPC method name (for example, module.function). | |
2332 * - The Drupal callback function (for example, module_function). | |
2333 * - The method signature is an array of XML-RPC types. The first element | |
2334 * of this array is the type of return value and then you should write a | |
2335 * list of the types of the parameters. XML-RPC types are the following | |
2336 * (See the types at http://www.xmlrpc.com/spec): | |
2337 * - "boolean": 0 (false) or 1 (true). | |
2338 * - "double": a floating point number (for example, -12.214). | |
2339 * - "int": a integer number (for example, -12). | |
2340 * - "array": an array without keys (for example, array(1, 2, 3)). | |
2341 * - "struct": an associative array or an object (for example, | |
2342 * array('one' => 1, 'two' => 2)). | |
2343 * - "date": when you return a date, then you may either return a | |
2344 * timestamp (time(), mktime() etc.) or an ISO8601 timestamp. When | |
2345 * date is specified as an input parameter, then you get an object, | |
2346 * which is described in the function xmlrpc_date | |
2347 * - "base64": a string containing binary data, automatically | |
2348 * encoded/decoded automatically. | |
2349 * - "string": anything else, typically a string. | |
2350 * - A descriptive help string, enclosed in a t() function for translation | |
2351 * purposes. | |
2352 * Both forms are shown in the example. | |
2353 */ | |
2354 function hook_xmlrpc() { | |
2355 return array( | |
2356 'drupal.login' => 'drupal_login', | |
2357 array( | |
2358 'drupal.site.ping', | |
2359 'drupal_directory_ping', | |
2360 array('boolean', 'string', 'string', 'string', 'string', 'string'), | |
2361 t('Handling ping request')) | |
2362 ); | |
2363 } | |
2364 | |
2365 /** | |
2366 * Alters the definition of XML-RPC methods before they are called. | |
2367 * | |
2368 * This hook allows modules to modify the callback definition of declared | |
2369 * XML-RPC methods, right before they are invoked by a client. Methods may be | |
2370 * added, or existing methods may be altered. | |
2371 * | |
2372 * Note that hook_xmlrpc() supports two distinct and incompatible formats to | |
2373 * define a callback, so care must be taken when altering other methods. | |
2374 * | |
2375 * @param $methods | |
2376 * An asssociative array of method callback definitions, as returned from | |
2377 * hook_xmlrpc() implementations. | |
2378 * | |
2379 * @see hook_xmlrpc() | |
2380 * @see xmlrpc_server() | |
2381 */ | |
2382 function hook_xmlrpc_alter(&$methods) { | |
2383 // Directly change a simple method. | |
2384 $methods['drupal.login'] = 'mymodule_login'; | |
2385 | |
2386 // Alter complex definitions. | |
2387 foreach ($methods as $key => &$method) { | |
2388 // Skip simple method definitions. | |
2389 if (!is_int($key)) { | |
2390 continue; | |
2391 } | |
2392 // Perform the wanted manipulation. | |
2393 if ($method[0] == 'drupal.site.ping') { | |
2394 $method[1] = 'mymodule_directory_ping'; | |
2395 } | |
2396 } | |
2397 } | |
2398 | |
2399 /** | |
2400 * Log an event message. | |
2401 * | |
2402 * This hook allows modules to route log events to custom destinations, such as | |
2403 * SMS, Email, pager, syslog, ...etc. | |
2404 * | |
2405 * @param $log_entry | |
2406 * An associative array containing the following keys: | |
2407 * - type: The type of message for this entry. | |
2408 * - user: The user object for the user who was logged in when the event | |
2409 * happened. | |
2410 * - uid: The user ID for the user who was logged in when the event happened. | |
2411 * - request_uri: The request URI for the page the event happened in. | |
2412 * - referer: The page that referred the user to the page where the event | |
2413 * occurred. | |
2414 * - ip: The IP address where the request for the page came from. | |
2415 * - timestamp: The UNIX timestamp of the date/time the event occurred. | |
2416 * - severity: The severity of the message; one of the following values as | |
2417 * defined in @link http://www.faqs.org/rfcs/rfc3164.html RFC 3164: @endlink | |
2418 * - WATCHDOG_EMERGENCY: Emergency, system is unusable. | |
2419 * - WATCHDOG_ALERT: Alert, action must be taken immediately. | |
2420 * - WATCHDOG_CRITICAL: Critical conditions. | |
2421 * - WATCHDOG_ERROR: Error conditions. | |
2422 * - WATCHDOG_WARNING: Warning conditions. | |
2423 * - WATCHDOG_NOTICE: Normal but significant conditions. | |
2424 * - WATCHDOG_INFO: Informational messages. | |
2425 * - WATCHDOG_DEBUG: Debug-level messages. | |
2426 * - link: An optional link provided by the module that called the watchdog() | |
2427 * function. | |
2428 * - message: The text of the message to be logged. Variables in the message | |
2429 * are indicated by using placeholder strings alongside the variables | |
2430 * argument to declare the value of the placeholders. See t() for | |
2431 * documentation on how the message and variable parameters interact. | |
2432 * - variables: An array of variables to be inserted into the message on | |
2433 * display. Will be NULL or missing if a message is already translated or if | |
2434 * the message is not possible to translate. | |
2435 */ | |
2436 function hook_watchdog(array $log_entry) { | |
2437 global $base_url, $language; | |
2438 | |
2439 $severity_list = array( | |
2440 WATCHDOG_EMERGENCY => t('Emergency'), | |
2441 WATCHDOG_ALERT => t('Alert'), | |
2442 WATCHDOG_CRITICAL => t('Critical'), | |
2443 WATCHDOG_ERROR => t('Error'), | |
2444 WATCHDOG_WARNING => t('Warning'), | |
2445 WATCHDOG_NOTICE => t('Notice'), | |
2446 WATCHDOG_INFO => t('Info'), | |
2447 WATCHDOG_DEBUG => t('Debug'), | |
2448 ); | |
2449 | |
2450 $to = 'someone@example.com'; | |
2451 $params = array(); | |
2452 $params['subject'] = t('[@site_name] @severity_desc: Alert from your web site', array( | |
2453 '@site_name' => variable_get('site_name', 'Drupal'), | |
2454 '@severity_desc' => $severity_list[$log_entry['severity']], | |
2455 )); | |
2456 | |
2457 $params['message'] = "\nSite: @base_url"; | |
2458 $params['message'] .= "\nSeverity: (@severity) @severity_desc"; | |
2459 $params['message'] .= "\nTimestamp: @timestamp"; | |
2460 $params['message'] .= "\nType: @type"; | |
2461 $params['message'] .= "\nIP Address: @ip"; | |
2462 $params['message'] .= "\nRequest URI: @request_uri"; | |
2463 $params['message'] .= "\nReferrer URI: @referer_uri"; | |
2464 $params['message'] .= "\nUser: (@uid) @name"; | |
2465 $params['message'] .= "\nLink: @link"; | |
2466 $params['message'] .= "\nMessage: \n\n@message"; | |
2467 | |
2468 $params['message'] = t($params['message'], array( | |
2469 '@base_url' => $base_url, | |
2470 '@severity' => $log_entry['severity'], | |
2471 '@severity_desc' => $severity_list[$log_entry['severity']], | |
2472 '@timestamp' => format_date($log_entry['timestamp']), | |
2473 '@type' => $log_entry['type'], | |
2474 '@ip' => $log_entry['ip'], | |
2475 '@request_uri' => $log_entry['request_uri'], | |
2476 '@referer_uri' => $log_entry['referer'], | |
2477 '@uid' => $log_entry['uid'], | |
2478 '@name' => $log_entry['user']->name, | |
2479 '@link' => strip_tags($log_entry['link']), | |
2480 '@message' => strip_tags($log_entry['message']), | |
2481 )); | |
2482 | |
2483 drupal_mail('emaillog', 'entry', $to, $language, $params); | |
2484 } | |
2485 | |
2486 /** | |
2487 * Prepare a message based on parameters; called from drupal_mail(). | |
2488 * | |
2489 * Note that hook_mail(), unlike hook_mail_alter(), is only called on the | |
2490 * $module argument to drupal_mail(), not all modules. | |
2491 * | |
2492 * @param $key | |
2493 * An identifier of the mail. | |
2494 * @param $message | |
2495 * An array to be filled in. Elements in this array include: | |
2496 * - id: An ID to identify the mail sent. Look at module source code | |
2497 * or drupal_mail() for possible id values. | |
2498 * - to: The address or addresses the message will be sent to. The formatting | |
2499 * of this string will be validated with the | |
2500 * @link http://php.net/manual/filter.filters.validate.php PHP e-mail validation filter. @endlink | |
2501 * - subject: Subject of the e-mail to be sent. This must not contain any | |
2502 * newline characters, or the mail may not be sent properly. drupal_mail() | |
2503 * sets this to an empty string when the hook is invoked. | |
2504 * - body: An array of lines containing the message to be sent. Drupal will | |
2505 * format the correct line endings for you. drupal_mail() sets this to an | |
2506 * empty array when the hook is invoked. | |
2507 * - from: The address the message will be marked as being from, which is | |
2508 * set by drupal_mail() to either a custom address or the site-wide | |
2509 * default email address when the hook is invoked. | |
2510 * - headers: Associative array containing mail headers, such as From, | |
2511 * Sender, MIME-Version, Content-Type, etc. drupal_mail() pre-fills | |
2512 * several headers in this array. | |
2513 * @param $params | |
2514 * An array of parameters supplied by the caller of drupal_mail(). | |
2515 */ | |
2516 function hook_mail($key, &$message, $params) { | |
2517 $account = $params['account']; | |
2518 $context = $params['context']; | |
2519 $variables = array( | |
2520 '%site_name' => variable_get('site_name', 'Drupal'), | |
2521 '%username' => format_username($account), | |
2522 ); | |
2523 if ($context['hook'] == 'taxonomy') { | |
2524 $entity = $params['entity']; | |
2525 $vocabulary = taxonomy_vocabulary_load($entity->vid); | |
2526 $variables += array( | |
2527 '%term_name' => $entity->name, | |
2528 '%term_description' => $entity->description, | |
2529 '%term_id' => $entity->tid, | |
2530 '%vocabulary_name' => $vocabulary->name, | |
2531 '%vocabulary_description' => $vocabulary->description, | |
2532 '%vocabulary_id' => $vocabulary->vid, | |
2533 ); | |
2534 } | |
2535 | |
2536 // Node-based variable translation is only available if we have a node. | |
2537 if (isset($params['node'])) { | |
2538 $node = $params['node']; | |
2539 $variables += array( | |
2540 '%uid' => $node->uid, | |
2541 '%node_url' => url('node/' . $node->nid, array('absolute' => TRUE)), | |
2542 '%node_type' => node_type_get_name($node), | |
2543 '%title' => $node->title, | |
2544 '%teaser' => $node->teaser, | |
2545 '%body' => $node->body, | |
2546 ); | |
2547 } | |
2548 $subject = strtr($context['subject'], $variables); | |
2549 $body = strtr($context['message'], $variables); | |
2550 $message['subject'] .= str_replace(array("\r", "\n"), '', $subject); | |
2551 $message['body'][] = drupal_html_to_text($body); | |
2552 } | |
2553 | |
2554 /** | |
2555 * Add a list of cache tables to be cleared. | |
2556 * | |
2557 * This hook allows your module to add cache table names to the list of cache | |
2558 * tables that will be cleared by the Clear button on the Performance page or | |
2559 * whenever drupal_flush_all_caches is invoked. | |
2560 * | |
2561 * @return | |
2562 * An array of cache table names. | |
2563 * | |
2564 * @see drupal_flush_all_caches() | |
2565 */ | |
2566 function hook_flush_caches() { | |
2567 return array('cache_example'); | |
2568 } | |
2569 | |
2570 /** | |
2571 * Perform necessary actions after modules are installed. | |
2572 * | |
2573 * This function differs from hook_install() in that it gives all other modules | |
2574 * a chance to perform actions when a module is installed, whereas | |
2575 * hook_install() is only called on the module actually being installed. See | |
2576 * module_enable() for a detailed description of the order in which install and | |
2577 * enable hooks are invoked. | |
2578 * | |
2579 * @param $modules | |
2580 * An array of the modules that were installed. | |
2581 * | |
2582 * @see module_enable() | |
2583 * @see hook_modules_enabled() | |
2584 * @see hook_install() | |
2585 */ | |
2586 function hook_modules_installed($modules) { | |
2587 if (in_array('lousy_module', $modules)) { | |
2588 variable_set('lousy_module_conflicting_variable', FALSE); | |
2589 } | |
2590 } | |
2591 | |
2592 /** | |
2593 * Perform necessary actions after modules are enabled. | |
2594 * | |
2595 * This function differs from hook_enable() in that it gives all other modules a | |
2596 * chance to perform actions when modules are enabled, whereas hook_enable() is | |
2597 * only called on the module actually being enabled. See module_enable() for a | |
2598 * detailed description of the order in which install and enable hooks are | |
2599 * invoked. | |
2600 * | |
2601 * @param $modules | |
2602 * An array of the modules that were enabled. | |
2603 * | |
2604 * @see hook_enable() | |
2605 * @see hook_modules_installed() | |
2606 * @see module_enable() | |
2607 */ | |
2608 function hook_modules_enabled($modules) { | |
2609 if (in_array('lousy_module', $modules)) { | |
2610 drupal_set_message(t('mymodule is not compatible with lousy_module'), 'error'); | |
2611 mymodule_disable_functionality(); | |
2612 } | |
2613 } | |
2614 | |
2615 /** | |
2616 * Perform necessary actions after modules are disabled. | |
2617 * | |
2618 * This function differs from hook_disable() in that it gives all other modules | |
2619 * a chance to perform actions when modules are disabled, whereas hook_disable() | |
2620 * is only called on the module actually being disabled. | |
2621 * | |
2622 * @param $modules | |
2623 * An array of the modules that were disabled. | |
2624 * | |
2625 * @see hook_disable() | |
2626 * @see hook_modules_uninstalled() | |
2627 */ | |
2628 function hook_modules_disabled($modules) { | |
2629 if (in_array('lousy_module', $modules)) { | |
2630 mymodule_enable_functionality(); | |
2631 } | |
2632 } | |
2633 | |
2634 /** | |
2635 * Perform necessary actions after modules are uninstalled. | |
2636 * | |
2637 * This function differs from hook_uninstall() in that it gives all other | |
2638 * modules a chance to perform actions when a module is uninstalled, whereas | |
2639 * hook_uninstall() is only called on the module actually being uninstalled. | |
2640 * | |
2641 * It is recommended that you implement this hook if your module stores | |
2642 * data that may have been set by other modules. | |
2643 * | |
2644 * @param $modules | |
2645 * An array of the modules that were uninstalled. | |
2646 * | |
2647 * @see hook_uninstall() | |
2648 * @see hook_modules_disabled() | |
2649 */ | |
2650 function hook_modules_uninstalled($modules) { | |
2651 foreach ($modules as $module) { | |
2652 db_delete('mymodule_table') | |
2653 ->condition('module', $module) | |
2654 ->execute(); | |
2655 } | |
2656 mymodule_cache_rebuild(); | |
2657 } | |
2658 | |
2659 /** | |
2660 * Registers PHP stream wrapper implementations associated with a module. | |
2661 * | |
2662 * Provide a facility for managing and querying user-defined stream wrappers | |
2663 * in PHP. PHP's internal stream_get_wrappers() doesn't return the class | |
2664 * registered to handle a stream, which we need to be able to find the handler | |
2665 * for class instantiation. | |
2666 * | |
2667 * If a module registers a scheme that is already registered with PHP, it will | |
2668 * be unregistered and replaced with the specified class. | |
2669 * | |
2670 * @return | |
2671 * A nested array, keyed first by scheme name ("public" for "public://"), | |
2672 * then keyed by the following values: | |
2673 * - 'name' A short string to name the wrapper. | |
2674 * - 'class' A string specifying the PHP class that implements the | |
2675 * DrupalStreamWrapperInterface interface. | |
2676 * - 'description' A string with a short description of what the wrapper does. | |
2677 * - 'type' (Optional) A bitmask of flags indicating what type of streams this | |
2678 * wrapper will access - local or remote, readable and/or writeable, etc. | |
2679 * Many shortcut constants are defined in stream_wrappers.inc. Defaults to | |
2680 * STREAM_WRAPPERS_NORMAL which includes all of these bit flags: | |
2681 * - STREAM_WRAPPERS_READ | |
2682 * - STREAM_WRAPPERS_WRITE | |
2683 * - STREAM_WRAPPERS_VISIBLE | |
2684 * | |
2685 * @see file_get_stream_wrappers() | |
2686 * @see hook_stream_wrappers_alter() | |
2687 * @see system_stream_wrappers() | |
2688 */ | |
2689 function hook_stream_wrappers() { | |
2690 return array( | |
2691 'public' => array( | |
2692 'name' => t('Public files'), | |
2693 'class' => 'DrupalPublicStreamWrapper', | |
2694 'description' => t('Public local files served by the webserver.'), | |
2695 'type' => STREAM_WRAPPERS_LOCAL_NORMAL, | |
2696 ), | |
2697 'private' => array( | |
2698 'name' => t('Private files'), | |
2699 'class' => 'DrupalPrivateStreamWrapper', | |
2700 'description' => t('Private local files served by Drupal.'), | |
2701 'type' => STREAM_WRAPPERS_LOCAL_NORMAL, | |
2702 ), | |
2703 'temp' => array( | |
2704 'name' => t('Temporary files'), | |
2705 'class' => 'DrupalTempStreamWrapper', | |
2706 'description' => t('Temporary local files for upload and previews.'), | |
2707 'type' => STREAM_WRAPPERS_LOCAL_HIDDEN, | |
2708 ), | |
2709 'cdn' => array( | |
2710 'name' => t('Content delivery network files'), | |
2711 'class' => 'MyModuleCDNStreamWrapper', | |
2712 'description' => t('Files served by a content delivery network.'), | |
2713 // 'type' can be omitted to use the default of STREAM_WRAPPERS_NORMAL | |
2714 ), | |
2715 'youtube' => array( | |
2716 'name' => t('YouTube video'), | |
2717 'class' => 'MyModuleYouTubeStreamWrapper', | |
2718 'description' => t('Video streamed from YouTube.'), | |
2719 // A module implementing YouTube integration may decide to support using | |
2720 // the YouTube API for uploading video, but here, we assume that this | |
2721 // particular module only supports playing YouTube video. | |
2722 'type' => STREAM_WRAPPERS_READ_VISIBLE, | |
2723 ), | |
2724 ); | |
2725 } | |
2726 | |
2727 /** | |
2728 * Alters the list of PHP stream wrapper implementations. | |
2729 * | |
2730 * @see file_get_stream_wrappers() | |
2731 * @see hook_stream_wrappers() | |
2732 */ | |
2733 function hook_stream_wrappers_alter(&$wrappers) { | |
2734 // Change the name of private files to reflect the performance. | |
2735 $wrappers['private']['name'] = t('Slow files'); | |
2736 } | |
2737 | |
2738 /** | |
2739 * Load additional information into file objects. | |
2740 * | |
2741 * file_load_multiple() calls this hook to allow modules to load | |
2742 * additional information into each file. | |
2743 * | |
2744 * @param $files | |
2745 * An array of file objects, indexed by fid. | |
2746 * | |
2747 * @see file_load_multiple() | |
2748 * @see file_load() | |
2749 */ | |
2750 function hook_file_load($files) { | |
2751 // Add the upload specific data into the file object. | |
2752 $result = db_query('SELECT * FROM {upload} u WHERE u.fid IN (:fids)', array(':fids' => array_keys($files)))->fetchAll(PDO::FETCH_ASSOC); | |
2753 foreach ($result as $record) { | |
2754 foreach ($record as $key => $value) { | |
2755 $files[$record['fid']]->$key = $value; | |
2756 } | |
2757 } | |
2758 } | |
2759 | |
2760 /** | |
2761 * Check that files meet a given criteria. | |
2762 * | |
2763 * This hook lets modules perform additional validation on files. They're able | |
2764 * to report a failure by returning one or more error messages. | |
2765 * | |
2766 * @param $file | |
2767 * The file object being validated. | |
2768 * @return | |
2769 * An array of error messages. If there are no problems with the file return | |
2770 * an empty array. | |
2771 * | |
2772 * @see file_validate() | |
2773 */ | |
2774 function hook_file_validate($file) { | |
2775 $errors = array(); | |
2776 | |
2777 if (empty($file->filename)) { | |
2778 $errors[] = t("The file's name is empty. Please give a name to the file."); | |
2779 } | |
2780 if (strlen($file->filename) > 255) { | |
2781 $errors[] = t("The file's name exceeds the 255 characters limit. Please rename the file and try again."); | |
2782 } | |
2783 | |
2784 return $errors; | |
2785 } | |
2786 | |
2787 /** | |
2788 * Act on a file being inserted or updated. | |
2789 * | |
2790 * This hook is called when a file has been added to the database. The hook | |
2791 * doesn't distinguish between files created as a result of a copy or those | |
2792 * created by an upload. | |
2793 * | |
2794 * @param $file | |
2795 * The file that has just been created. | |
2796 * | |
2797 * @see file_save() | |
2798 */ | |
2799 function hook_file_presave($file) { | |
2800 // Change the file timestamp to an hour prior. | |
2801 $file->timestamp -= 3600; | |
2802 } | |
2803 | |
2804 /** | |
2805 * Respond to a file being added. | |
2806 * | |
2807 * This hook is called after a file has been added to the database. The hook | |
2808 * doesn't distinguish between files created as a result of a copy or those | |
2809 * created by an upload. | |
2810 * | |
2811 * @param $file | |
2812 * The file that has been added. | |
2813 * | |
2814 * @see file_save() | |
2815 */ | |
2816 function hook_file_insert($file) { | |
2817 // Add a message to the log, if the file is a jpg | |
2818 $validate = file_validate_extensions($file, 'jpg'); | |
2819 if (empty($validate)) { | |
2820 watchdog('file', 'A jpg has been added.'); | |
2821 } | |
2822 } | |
2823 | |
2824 /** | |
2825 * Respond to a file being updated. | |
2826 * | |
2827 * This hook is called when file_save() is called on an existing file. | |
2828 * | |
2829 * @param $file | |
2830 * The file that has just been updated. | |
2831 * | |
2832 * @see file_save() | |
2833 */ | |
2834 function hook_file_update($file) { | |
2835 $file_user = user_load($file->uid); | |
2836 // Make sure that the file name starts with the owner's user name. | |
2837 if (strpos($file->filename, $file_user->name) !== 0) { | |
2838 $old_filename = $file->filename; | |
2839 $file->filename = $file_user->name . '_' . $file->filename; | |
2840 $file->save(); | |
2841 | |
2842 watchdog('file', t('%source has been renamed to %destination', array('%source' => $old_filename, '%destination' => $file->filename))); | |
2843 } | |
2844 } | |
2845 | |
2846 /** | |
2847 * Respond to a file that has been copied. | |
2848 * | |
2849 * @param $file | |
2850 * The newly copied file object. | |
2851 * @param $source | |
2852 * The original file before the copy. | |
2853 * | |
2854 * @see file_copy() | |
2855 */ | |
2856 function hook_file_copy($file, $source) { | |
2857 $file_user = user_load($file->uid); | |
2858 // Make sure that the file name starts with the owner's user name. | |
2859 if (strpos($file->filename, $file_user->name) !== 0) { | |
2860 $file->filename = $file_user->name . '_' . $file->filename; | |
2861 $file->save(); | |
2862 | |
2863 watchdog('file', t('Copied file %source has been renamed to %destination', array('%source' => $source->filename, '%destination' => $file->filename))); | |
2864 } | |
2865 } | |
2866 | |
2867 /** | |
2868 * Respond to a file that has been moved. | |
2869 * | |
2870 * @param $file | |
2871 * The updated file object after the move. | |
2872 * @param $source | |
2873 * The original file object before the move. | |
2874 * | |
2875 * @see file_move() | |
2876 */ | |
2877 function hook_file_move($file, $source) { | |
2878 $file_user = user_load($file->uid); | |
2879 // Make sure that the file name starts with the owner's user name. | |
2880 if (strpos($file->filename, $file_user->name) !== 0) { | |
2881 $file->filename = $file_user->name . '_' . $file->filename; | |
2882 $file->save(); | |
2883 | |
2884 watchdog('file', t('Moved file %source has been renamed to %destination', array('%source' => $source->filename, '%destination' => $file->filename))); | |
2885 } | |
2886 } | |
2887 | |
2888 /** | |
2889 * Respond to a file being deleted. | |
2890 * | |
2891 * @param $file | |
2892 * The file that has just been deleted. | |
2893 * | |
2894 * @see file_delete() | |
2895 */ | |
2896 function hook_file_delete($file) { | |
2897 // Delete all information associated with the file. | |
2898 db_delete('upload')->condition('fid', $file->fid)->execute(); | |
2899 } | |
2900 | |
2901 /** | |
2902 * Control access to private file downloads and specify HTTP headers. | |
2903 * | |
2904 * This hook allows modules enforce permissions on file downloads when the | |
2905 * private file download method is selected. Modules can also provide headers | |
2906 * to specify information like the file's name or MIME type. | |
2907 * | |
2908 * @param $uri | |
2909 * The URI of the file. | |
2910 * @return | |
2911 * If the user does not have permission to access the file, return -1. If the | |
2912 * user has permission, return an array with the appropriate headers. If the | |
2913 * file is not controlled by the current module, the return value should be | |
2914 * NULL. | |
2915 * | |
2916 * @see file_download() | |
2917 */ | |
2918 function hook_file_download($uri) { | |
2919 // Check if the file is controlled by the current module. | |
2920 if (!file_prepare_directory($uri)) { | |
2921 $uri = FALSE; | |
2922 } | |
2923 if (strpos(file_uri_target($uri), variable_get('user_picture_path', 'pictures') . '/picture-') === 0) { | |
2924 if (!user_access('access user profiles')) { | |
2925 // Access to the file is denied. | |
2926 return -1; | |
2927 } | |
2928 else { | |
2929 $info = image_get_info($uri); | |
2930 return array('Content-Type' => $info['mime_type']); | |
2931 } | |
2932 } | |
2933 } | |
2934 | |
2935 /** | |
2936 * Alter the URL to a file. | |
2937 * | |
2938 * This hook is called from file_create_url(), and is called fairly | |
2939 * frequently (10+ times per page), depending on how many files there are in a | |
2940 * given page. | |
2941 * If CSS and JS aggregation are disabled, this can become very frequently | |
2942 * (50+ times per page) so performance is critical. | |
2943 * | |
2944 * This function should alter the URI, if it wants to rewrite the file URL. | |
2945 * | |
2946 * @param $uri | |
2947 * The URI to a file for which we need an external URL, or the path to a | |
2948 * shipped file. | |
2949 */ | |
2950 function hook_file_url_alter(&$uri) { | |
2951 global $user; | |
2952 | |
2953 // User 1 will always see the local file in this example. | |
2954 if ($user->uid == 1) { | |
2955 return; | |
2956 } | |
2957 | |
2958 $cdn1 = 'http://cdn1.example.com'; | |
2959 $cdn2 = 'http://cdn2.example.com'; | |
2960 $cdn_extensions = array('css', 'js', 'gif', 'jpg', 'jpeg', 'png'); | |
2961 | |
2962 // Most CDNs don't support private file transfers without a lot of hassle, | |
2963 // so don't support this in the common case. | |
2964 $schemes = array('public'); | |
2965 | |
2966 $scheme = file_uri_scheme($uri); | |
2967 | |
2968 // Only serve shipped files and public created files from the CDN. | |
2969 if (!$scheme || in_array($scheme, $schemes)) { | |
2970 // Shipped files. | |
2971 if (!$scheme) { | |
2972 $path = $uri; | |
2973 } | |
2974 // Public created files. | |
2975 else { | |
2976 $wrapper = file_stream_wrapper_get_instance_by_scheme($scheme); | |
2977 $path = $wrapper->getDirectoryPath() . '/' . file_uri_target($uri); | |
2978 } | |
2979 | |
2980 // Clean up Windows paths. | |
2981 $path = str_replace('\\', '/', $path); | |
2982 | |
2983 // Serve files with one of the CDN extensions from CDN 1, all others from | |
2984 // CDN 2. | |
2985 $pathinfo = pathinfo($path); | |
2986 if (isset($pathinfo['extension']) && in_array($pathinfo['extension'], $cdn_extensions)) { | |
2987 $uri = $cdn1 . '/' . $path; | |
2988 } | |
2989 else { | |
2990 $uri = $cdn2 . '/' . $path; | |
2991 } | |
2992 } | |
2993 } | |
2994 | |
2995 /** | |
2996 * Check installation requirements and do status reporting. | |
2997 * | |
2998 * This hook has three closely related uses, determined by the $phase argument: | |
2999 * - Checking installation requirements ($phase == 'install'). | |
3000 * - Checking update requirements ($phase == 'update'). | |
3001 * - Status reporting ($phase == 'runtime'). | |
3002 * | |
3003 * Note that this hook, like all others dealing with installation and updates, | |
3004 * must reside in a module_name.install file, or it will not properly abort | |
3005 * the installation of the module if a critical requirement is missing. | |
3006 * | |
3007 * During the 'install' phase, modules can for example assert that | |
3008 * library or server versions are available or sufficient. | |
3009 * Note that the installation of a module can happen during installation of | |
3010 * Drupal itself (by install.php) with an installation profile or later by hand. | |
3011 * As a consequence, install-time requirements must be checked without access | |
3012 * to the full Drupal API, because it is not available during install.php. | |
3013 * For localization you should for example use $t = get_t() to | |
3014 * retrieve the appropriate localization function name (t() or st()). | |
3015 * If a requirement has a severity of REQUIREMENT_ERROR, install.php will abort | |
3016 * or at least the module will not install. | |
3017 * Other severity levels have no effect on the installation. | |
3018 * Module dependencies do not belong to these installation requirements, | |
3019 * but should be defined in the module's .info file. | |
3020 * | |
3021 * The 'runtime' phase is not limited to pure installation requirements | |
3022 * but can also be used for more general status information like maintenance | |
3023 * tasks and security issues. | |
3024 * The returned 'requirements' will be listed on the status report in the | |
3025 * administration section, with indication of the severity level. | |
3026 * Moreover, any requirement with a severity of REQUIREMENT_ERROR severity will | |
3027 * result in a notice on the administration configuration page. | |
3028 * | |
3029 * @param $phase | |
3030 * The phase in which requirements are checked: | |
3031 * - install: The module is being installed. | |
3032 * - update: The module is enabled and update.php is run. | |
3033 * - runtime: The runtime requirements are being checked and shown on the | |
3034 * status report page. | |
3035 * | |
3036 * @return | |
3037 * An associative array where the keys are arbitrary but must be unique (it | |
3038 * is suggested to use the module short name as a prefix) and the values are | |
3039 * themselves associative arrays with the following elements: | |
3040 * - title: The name of the requirement. | |
3041 * - value: The current value (e.g., version, time, level, etc). During | |
3042 * install phase, this should only be used for version numbers, do not set | |
3043 * it if not applicable. | |
3044 * - description: The description of the requirement/status. | |
3045 * - severity: The requirement's result/severity level, one of: | |
3046 * - REQUIREMENT_INFO: For info only. | |
3047 * - REQUIREMENT_OK: The requirement is satisfied. | |
3048 * - REQUIREMENT_WARNING: The requirement failed with a warning. | |
3049 * - REQUIREMENT_ERROR: The requirement failed with an error. | |
3050 */ | |
3051 function hook_requirements($phase) { | |
3052 $requirements = array(); | |
3053 // Ensure translations don't break during installation. | |
3054 $t = get_t(); | |
3055 | |
3056 // Report Drupal version | |
3057 if ($phase == 'runtime') { | |
3058 $requirements['drupal'] = array( | |
3059 'title' => $t('Drupal'), | |
3060 'value' => VERSION, | |
3061 'severity' => REQUIREMENT_INFO | |
3062 ); | |
3063 } | |
3064 | |
3065 // Test PHP version | |
3066 $requirements['php'] = array( | |
3067 'title' => $t('PHP'), | |
3068 'value' => ($phase == 'runtime') ? l(phpversion(), 'admin/reports/status/php') : phpversion(), | |
3069 ); | |
3070 if (version_compare(phpversion(), DRUPAL_MINIMUM_PHP) < 0) { | |
3071 $requirements['php']['description'] = $t('Your PHP installation is too old. Drupal requires at least PHP %version.', array('%version' => DRUPAL_MINIMUM_PHP)); | |
3072 $requirements['php']['severity'] = REQUIREMENT_ERROR; | |
3073 } | |
3074 | |
3075 // Report cron status | |
3076 if ($phase == 'runtime') { | |
3077 $cron_last = variable_get('cron_last'); | |
3078 | |
3079 if (is_numeric($cron_last)) { | |
3080 $requirements['cron']['value'] = $t('Last run !time ago', array('!time' => format_interval(REQUEST_TIME - $cron_last))); | |
3081 } | |
3082 else { | |
3083 $requirements['cron'] = array( | |
3084 'description' => $t('Cron has not run. It appears cron jobs have not been setup on your system. Check the help pages for <a href="@url">configuring cron jobs</a>.', array('@url' => 'http://drupal.org/cron')), | |
3085 'severity' => REQUIREMENT_ERROR, | |
3086 'value' => $t('Never run'), | |
3087 ); | |
3088 } | |
3089 | |
3090 $requirements['cron']['description'] .= ' ' . $t('You can <a href="@cron">run cron manually</a>.', array('@cron' => url('admin/reports/status/run-cron'))); | |
3091 | |
3092 $requirements['cron']['title'] = $t('Cron maintenance tasks'); | |
3093 } | |
3094 | |
3095 return $requirements; | |
3096 } | |
3097 | |
3098 /** | |
3099 * Define the current version of the database schema. | |
3100 * | |
3101 * A Drupal schema definition is an array structure representing one or | |
3102 * more tables and their related keys and indexes. A schema is defined by | |
3103 * hook_schema() which must live in your module's .install file. | |
3104 * | |
3105 * This hook is called at install and uninstall time, and in the latter | |
3106 * case, it cannot rely on the .module file being loaded or hooks being known. | |
3107 * If the .module file is needed, it may be loaded with drupal_load(). | |
3108 * | |
3109 * The tables declared by this hook will be automatically created when | |
3110 * the module is first enabled, and removed when the module is uninstalled. | |
3111 * This happens before hook_install() is invoked, and after hook_uninstall() | |
3112 * is invoked, respectively. | |
3113 * | |
3114 * By declaring the tables used by your module via an implementation of | |
3115 * hook_schema(), these tables will be available on all supported database | |
3116 * engines. You don't have to deal with the different SQL dialects for table | |
3117 * creation and alteration of the supported database engines. | |
3118 * | |
3119 * See the Schema API Handbook at http://drupal.org/node/146843 for | |
3120 * details on schema definition structures. | |
3121 * | |
3122 * @return | |
3123 * A schema definition structure array. For each element of the | |
3124 * array, the key is a table name and the value is a table structure | |
3125 * definition. | |
3126 * | |
3127 * @ingroup schemaapi | |
3128 */ | |
3129 function hook_schema() { | |
3130 $schema['node'] = array( | |
3131 // example (partial) specification for table "node" | |
3132 'description' => 'The base table for nodes.', | |
3133 'fields' => array( | |
3134 'nid' => array( | |
3135 'description' => 'The primary identifier for a node.', | |
3136 'type' => 'serial', | |
3137 'unsigned' => TRUE, | |
3138 'not null' => TRUE, | |
3139 ), | |
3140 'vid' => array( | |
3141 'description' => 'The current {node_revision}.vid version identifier.', | |
3142 'type' => 'int', | |
3143 'unsigned' => TRUE, | |
3144 'not null' => TRUE, | |
3145 'default' => 0, | |
3146 ), | |
3147 'type' => array( | |
3148 'description' => 'The {node_type} of this node.', | |
3149 'type' => 'varchar', | |
3150 'length' => 32, | |
3151 'not null' => TRUE, | |
3152 'default' => '', | |
3153 ), | |
3154 'title' => array( | |
3155 'description' => 'The title of this node, always treated as non-markup plain text.', | |
3156 'type' => 'varchar', | |
3157 'length' => 255, | |
3158 'not null' => TRUE, | |
3159 'default' => '', | |
3160 ), | |
3161 ), | |
3162 'indexes' => array( | |
3163 'node_changed' => array('changed'), | |
3164 'node_created' => array('created'), | |
3165 ), | |
3166 'unique keys' => array( | |
3167 'nid_vid' => array('nid', 'vid'), | |
3168 'vid' => array('vid'), | |
3169 ), | |
3170 'foreign keys' => array( | |
3171 'node_revision' => array( | |
3172 'table' => 'node_revision', | |
3173 'columns' => array('vid' => 'vid'), | |
3174 ), | |
3175 'node_author' => array( | |
3176 'table' => 'users', | |
3177 'columns' => array('uid' => 'uid'), | |
3178 ), | |
3179 ), | |
3180 'primary key' => array('nid'), | |
3181 ); | |
3182 return $schema; | |
3183 } | |
3184 | |
3185 /** | |
3186 * Perform alterations to existing database schemas. | |
3187 * | |
3188 * When a module modifies the database structure of another module (by | |
3189 * changing, adding or removing fields, keys or indexes), it should | |
3190 * implement hook_schema_alter() to update the default $schema to take its | |
3191 * changes into account. | |
3192 * | |
3193 * See hook_schema() for details on the schema definition structure. | |
3194 * | |
3195 * @param $schema | |
3196 * Nested array describing the schemas for all modules. | |
3197 * | |
3198 * @ingroup schemaapi | |
3199 */ | |
3200 function hook_schema_alter(&$schema) { | |
3201 // Add field to existing schema. | |
3202 $schema['users']['fields']['timezone_id'] = array( | |
3203 'type' => 'int', | |
3204 'not null' => TRUE, | |
3205 'default' => 0, | |
3206 'description' => 'Per-user timezone configuration.', | |
3207 ); | |
3208 } | |
3209 | |
3210 /** | |
3211 * Perform alterations to a structured query. | |
3212 * | |
3213 * Structured (aka dynamic) queries that have tags associated may be altered by any module | |
3214 * before the query is executed. | |
3215 * | |
3216 * @param $query | |
3217 * A Query object describing the composite parts of a SQL query. | |
3218 * | |
3219 * @see hook_query_TAG_alter() | |
3220 * @see node_query_node_access_alter() | |
3221 * @see QueryAlterableInterface | |
3222 * @see SelectQueryInterface | |
3223 */ | |
3224 function hook_query_alter(QueryAlterableInterface $query) { | |
3225 if ($query->hasTag('micro_limit')) { | |
3226 $query->range(0, 2); | |
3227 } | |
3228 } | |
3229 | |
3230 /** | |
3231 * Perform alterations to a structured query for a given tag. | |
3232 * | |
3233 * @param $query | |
3234 * An Query object describing the composite parts of a SQL query. | |
3235 * | |
3236 * @see hook_query_alter() | |
3237 * @see node_query_node_access_alter() | |
3238 * @see QueryAlterableInterface | |
3239 * @see SelectQueryInterface | |
3240 */ | |
3241 function hook_query_TAG_alter(QueryAlterableInterface $query) { | |
3242 // Skip the extra expensive alterations if site has no node access control modules. | |
3243 if (!node_access_view_all_nodes()) { | |
3244 // Prevent duplicates records. | |
3245 $query->distinct(); | |
3246 // The recognized operations are 'view', 'update', 'delete'. | |
3247 if (!$op = $query->getMetaData('op')) { | |
3248 $op = 'view'; | |
3249 } | |
3250 // Skip the extra joins and conditions for node admins. | |
3251 if (!user_access('bypass node access')) { | |
3252 // The node_access table has the access grants for any given node. | |
3253 $access_alias = $query->join('node_access', 'na', '%alias.nid = n.nid'); | |
3254 $or = db_or(); | |
3255 // If any grant exists for the specified user, then user has access to the node for the specified operation. | |
3256 foreach (node_access_grants($op, $query->getMetaData('account')) as $realm => $gids) { | |
3257 foreach ($gids as $gid) { | |
3258 $or->condition(db_and() | |
3259 ->condition($access_alias . '.gid', $gid) | |
3260 ->condition($access_alias . '.realm', $realm) | |
3261 ); | |
3262 } | |
3263 } | |
3264 | |
3265 if (count($or->conditions())) { | |
3266 $query->condition($or); | |
3267 } | |
3268 | |
3269 $query->condition($access_alias . 'grant_' . $op, 1, '>='); | |
3270 } | |
3271 } | |
3272 } | |
3273 | |
3274 /** | |
3275 * Perform setup tasks when the module is installed. | |
3276 * | |
3277 * If the module implements hook_schema(), the database tables will | |
3278 * be created before this hook is fired. | |
3279 * | |
3280 * Implementations of this hook are by convention declared in the module's | |
3281 * .install file. The implementation can rely on the .module file being loaded. | |
3282 * The hook will only be called the first time a module is enabled or after it | |
3283 * is re-enabled after being uninstalled. The module's schema version will be | |
3284 * set to the module's greatest numbered update hook. Because of this, any time | |
3285 * a hook_update_N() is added to the module, this function needs to be updated | |
3286 * to reflect the current version of the database schema. | |
3287 * | |
3288 * See the @link http://drupal.org/node/146843 Schema API documentation @endlink | |
3289 * for details on hook_schema and how database tables are defined. | |
3290 * | |
3291 * Note that since this function is called from a full bootstrap, all functions | |
3292 * (including those in modules enabled by the current page request) are | |
3293 * available when this hook is called. Use cases could be displaying a user | |
3294 * message, or calling a module function necessary for initial setup, etc. | |
3295 * | |
3296 * Please be sure that anything added or modified in this function that can | |
3297 * be removed during uninstall should be removed with hook_uninstall(). | |
3298 * | |
3299 * @see hook_schema() | |
3300 * @see module_enable() | |
3301 * @see hook_enable() | |
3302 * @see hook_disable() | |
3303 * @see hook_uninstall() | |
3304 * @see hook_modules_installed() | |
3305 */ | |
3306 function hook_install() { | |
3307 // Populate the default {node_access} record. | |
3308 db_insert('node_access') | |
3309 ->fields(array( | |
3310 'nid' => 0, | |
3311 'gid' => 0, | |
3312 'realm' => 'all', | |
3313 'grant_view' => 1, | |
3314 'grant_update' => 0, | |
3315 'grant_delete' => 0, | |
3316 )) | |
3317 ->execute(); | |
3318 } | |
3319 | |
3320 /** | |
3321 * Perform a single update. | |
3322 * | |
3323 * For each change that requires one or more actions to be performed when | |
3324 * updating a site, add a new hook_update_N(), which will be called by | |
3325 * update.php. The documentation block preceding this function is stripped of | |
3326 * newlines and used as the description for the update on the pending updates | |
3327 * task list. Schema updates should adhere to the | |
3328 * @link http://drupal.org/node/150215 Schema API. @endlink | |
3329 * | |
3330 * Implementations of hook_update_N() are named (module name)_update_(number). | |
3331 * The numbers are composed of three parts: | |
3332 * - 1 digit for Drupal core compatibility. | |
3333 * - 1 digit for your module's major release version (e.g., is this the 7.x-1.* | |
3334 * (1) or 7.x-2.* (2) series of your module?). This digit should be 0 for | |
3335 * initial porting of your module to a new Drupal core API. | |
3336 * - 2 digits for sequential counting, starting with 00. | |
3337 * | |
3338 * Examples: | |
3339 * - mymodule_update_7000(): This is the required update for mymodule to run | |
3340 * with Drupal core API 7.x when upgrading from Drupal core API 6.x. | |
3341 * - mymodule_update_7100(): This is the first update to get the database ready | |
3342 * to run mymodule 7.x-1.*. | |
3343 * - mymodule_update_7200(): This is the first update to get the database ready | |
3344 * to run mymodule 7.x-2.*. Users can directly update from 6.x-2.* to 7.x-2.* | |
3345 * and they get all 70xx and 72xx updates, but not 71xx updates, because | |
3346 * those reside in the 7.x-1.x branch only. | |
3347 * | |
3348 * A good rule of thumb is to remove updates older than two major releases of | |
3349 * Drupal. See hook_update_last_removed() to notify Drupal about the removals. | |
3350 * For further information about releases and release numbers see: | |
3351 * @link http://drupal.org/node/711070 Maintaining a drupal.org project with Git @endlink | |
3352 * | |
3353 * Never renumber update functions. | |
3354 * | |
3355 * Implementations of this hook should be placed in a mymodule.install file in | |
3356 * the same directory as mymodule.module. Drupal core's updates are implemented | |
3357 * using the system module as a name and stored in database/updates.inc. | |
3358 * | |
3359 * Not all module functions are available from within a hook_update_N() function. | |
3360 * In order to call a function from your mymodule.module or an include file, | |
3361 * you need to explicitly load that file first. | |
3362 * | |
3363 * During database updates the schema of any module could be out of date. For | |
3364 * this reason, caution is needed when using any API function within an update | |
3365 * function - particularly CRUD functions, functions that depend on the schema | |
3366 * (for example by using drupal_write_record()), and any functions that invoke | |
3367 * hooks. See @link update_api Update versions of API functions @endlink for | |
3368 * details. | |
3369 * | |
3370 * If your update task is potentially time-consuming, you'll need to implement a | |
3371 * multipass update to avoid PHP timeouts. Multipass updates use the $sandbox | |
3372 * parameter provided by the batch API (normally, $context['sandbox']) to store | |
3373 * information between successive calls, and the $sandbox['#finished'] value | |
3374 * to provide feedback regarding completion level. | |
3375 * | |
3376 * See the batch operations page for more information on how to use the | |
3377 * @link http://drupal.org/node/180528 Batch API. @endlink | |
3378 * | |
3379 * @param $sandbox | |
3380 * Stores information for multipass updates. See above for more information. | |
3381 * | |
3382 * @throws DrupalUpdateException, PDOException | |
3383 * In case of error, update hooks should throw an instance of DrupalUpdateException | |
3384 * with a meaningful message for the user. If a database query fails for whatever | |
3385 * reason, it will throw a PDOException. | |
3386 * | |
3387 * @return | |
3388 * Optionally, update hooks may return a translated string that will be | |
3389 * displayed to the user after the update has completed. If no message is | |
3390 * returned, no message will be presented to the user. | |
3391 * | |
3392 * @see batch | |
3393 * @see schemaapi | |
3394 * @see update_api | |
3395 * @see hook_update_last_removed() | |
3396 * @see update_get_update_list() | |
3397 */ | |
3398 function hook_update_N(&$sandbox) { | |
3399 // For non-multipass updates, the signature can simply be; | |
3400 // function hook_update_N() { | |
3401 | |
3402 // For most updates, the following is sufficient. | |
3403 db_add_field('mytable1', 'newcol', array('type' => 'int', 'not null' => TRUE, 'description' => 'My new integer column.')); | |
3404 | |
3405 // However, for more complex operations that may take a long time, | |
3406 // you may hook into Batch API as in the following example. | |
3407 | |
3408 // Update 3 users at a time to have an exclamation point after their names. | |
3409 // (They're really happy that we can do batch API in this hook!) | |
3410 if (!isset($sandbox['progress'])) { | |
3411 $sandbox['progress'] = 0; | |
3412 $sandbox['current_uid'] = 0; | |
3413 // We'll -1 to disregard the uid 0... | |
3414 $sandbox['max'] = db_query('SELECT COUNT(DISTINCT uid) FROM {users}')->fetchField() - 1; | |
3415 } | |
3416 | |
3417 $users = db_select('users', 'u') | |
3418 ->fields('u', array('uid', 'name')) | |
3419 ->condition('uid', $sandbox['current_uid'], '>') | |
3420 ->range(0, 3) | |
3421 ->orderBy('uid', 'ASC') | |
3422 ->execute(); | |
3423 | |
3424 foreach ($users as $user) { | |
3425 $user->name .= '!'; | |
3426 db_update('users') | |
3427 ->fields(array('name' => $user->name)) | |
3428 ->condition('uid', $user->uid) | |
3429 ->execute(); | |
3430 | |
3431 $sandbox['progress']++; | |
3432 $sandbox['current_uid'] = $user->uid; | |
3433 } | |
3434 | |
3435 $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']); | |
3436 | |
3437 // To display a message to the user when the update is completed, return it. | |
3438 // If you do not want to display a completion message, simply return nothing. | |
3439 return t('The update did what it was supposed to do.'); | |
3440 | |
3441 // In case of an error, simply throw an exception with an error message. | |
3442 throw new DrupalUpdateException('Something went wrong; here is what you should do.'); | |
3443 } | |
3444 | |
3445 /** | |
3446 * Return an array of information about module update dependencies. | |
3447 * | |
3448 * This can be used to indicate update functions from other modules that your | |
3449 * module's update functions depend on, or vice versa. It is used by the update | |
3450 * system to determine the appropriate order in which updates should be run, as | |
3451 * well as to search for missing dependencies. | |
3452 * | |
3453 * Implementations of this hook should be placed in a mymodule.install file in | |
3454 * the same directory as mymodule.module. | |
3455 * | |
3456 * @return | |
3457 * A multidimensional array containing information about the module update | |
3458 * dependencies. The first two levels of keys represent the module and update | |
3459 * number (respectively) for which information is being returned, and the | |
3460 * value is an array of information about that update's dependencies. Within | |
3461 * this array, each key represents a module, and each value represents the | |
3462 * number of an update function within that module. In the event that your | |
3463 * update function depends on more than one update from a particular module, | |
3464 * you should always list the highest numbered one here (since updates within | |
3465 * a given module always run in numerical order). | |
3466 * | |
3467 * @see update_resolve_dependencies() | |
3468 * @see hook_update_N() | |
3469 */ | |
3470 function hook_update_dependencies() { | |
3471 // Indicate that the mymodule_update_7000() function provided by this module | |
3472 // must run after the another_module_update_7002() function provided by the | |
3473 // 'another_module' module. | |
3474 $dependencies['mymodule'][7000] = array( | |
3475 'another_module' => 7002, | |
3476 ); | |
3477 // Indicate that the mymodule_update_7001() function provided by this module | |
3478 // must run before the yet_another_module_update_7004() function provided by | |
3479 // the 'yet_another_module' module. (Note that declaring dependencies in this | |
3480 // direction should be done only in rare situations, since it can lead to the | |
3481 // following problem: If a site has already run the yet_another_module | |
3482 // module's database updates before it updates its codebase to pick up the | |
3483 // newest mymodule code, then the dependency declared here will be ignored.) | |
3484 $dependencies['yet_another_module'][7004] = array( | |
3485 'mymodule' => 7001, | |
3486 ); | |
3487 return $dependencies; | |
3488 } | |
3489 | |
3490 /** | |
3491 * Return a number which is no longer available as hook_update_N(). | |
3492 * | |
3493 * If you remove some update functions from your mymodule.install file, you | |
3494 * should notify Drupal of those missing functions. This way, Drupal can | |
3495 * ensure that no update is accidentally skipped. | |
3496 * | |
3497 * Implementations of this hook should be placed in a mymodule.install file in | |
3498 * the same directory as mymodule.module. | |
3499 * | |
3500 * @return | |
3501 * An integer, corresponding to hook_update_N() which has been removed from | |
3502 * mymodule.install. | |
3503 * | |
3504 * @see hook_update_N() | |
3505 */ | |
3506 function hook_update_last_removed() { | |
3507 // We've removed the 5.x-1.x version of mymodule, including database updates. | |
3508 // The next update function is mymodule_update_5200(). | |
3509 return 5103; | |
3510 } | |
3511 | |
3512 /** | |
3513 * Remove any information that the module sets. | |
3514 * | |
3515 * The information that the module should remove includes: | |
3516 * - variables that the module has set using variable_set() or system_settings_form() | |
3517 * - modifications to existing tables | |
3518 * | |
3519 * The module should not remove its entry from the {system} table. Database | |
3520 * tables defined by hook_schema() will be removed automatically. | |
3521 * | |
3522 * The uninstall hook must be implemented in the module's .install file. It | |
3523 * will fire when the module gets uninstalled but before the module's database | |
3524 * tables are removed, allowing your module to query its own tables during | |
3525 * this routine. | |
3526 * | |
3527 * When hook_uninstall() is called, your module will already be disabled, so | |
3528 * its .module file will not be automatically included. If you need to call API | |
3529 * functions from your .module file in this hook, use drupal_load() to make | |
3530 * them available. (Keep this usage to a minimum, though, especially when | |
3531 * calling API functions that invoke hooks, or API functions from modules | |
3532 * listed as dependencies, since these may not be available or work as expected | |
3533 * when the module is disabled.) | |
3534 * | |
3535 * @see hook_install() | |
3536 * @see hook_schema() | |
3537 * @see hook_disable() | |
3538 * @see hook_modules_uninstalled() | |
3539 */ | |
3540 function hook_uninstall() { | |
3541 variable_del('upload_file_types'); | |
3542 } | |
3543 | |
3544 /** | |
3545 * Perform necessary actions after module is enabled. | |
3546 * | |
3547 * The hook is called every time the module is enabled. It should be | |
3548 * implemented in the module's .install file. The implementation can | |
3549 * rely on the .module file being loaded. | |
3550 * | |
3551 * @see module_enable() | |
3552 * @see hook_install() | |
3553 * @see hook_modules_enabled() | |
3554 */ | |
3555 function hook_enable() { | |
3556 mymodule_cache_rebuild(); | |
3557 } | |
3558 | |
3559 /** | |
3560 * Perform necessary actions before module is disabled. | |
3561 * | |
3562 * The hook is called every time the module is disabled. It should be | |
3563 * implemented in the module's .install file. The implementation can rely | |
3564 * on the .module file being loaded. | |
3565 * | |
3566 * @see hook_uninstall() | |
3567 * @see hook_modules_disabled() | |
3568 */ | |
3569 function hook_disable() { | |
3570 mymodule_cache_rebuild(); | |
3571 } | |
3572 | |
3573 /** | |
3574 * Perform necessary alterations to the list of files parsed by the registry. | |
3575 * | |
3576 * Modules can manually modify the list of files before the registry parses | |
3577 * them. The $modules array provides the .info file information, which includes | |
3578 * the list of files registered to each module. Any files in the list can then | |
3579 * be added to the list of files that the registry will parse, or modify | |
3580 * attributes of a file. | |
3581 * | |
3582 * A necessary alteration made by the core SimpleTest module is to force .test | |
3583 * files provided by disabled modules into the list of files parsed by the | |
3584 * registry. | |
3585 * | |
3586 * @param $files | |
3587 * List of files to be parsed by the registry. The list will contain | |
3588 * files found in each enabled module's info file and the core includes | |
3589 * directory. The array is keyed by the file path and contains an array of | |
3590 * the related module's name and weight as used internally by | |
3591 * _registry_update() and related functions. | |
3592 * | |
3593 * For example: | |
3594 * @code | |
3595 * $files["modules/system/system.module"] = array( | |
3596 * 'module' => 'system', | |
3597 * 'weight' => 0, | |
3598 * ); | |
3599 * @endcode | |
3600 * @param $modules | |
3601 * An array containing all module information stored in the {system} table. | |
3602 * Each element of the array also contains the module's .info file | |
3603 * information in the property 'info'. An additional 'dir' property has been | |
3604 * added to the module information which provides the path to the directory | |
3605 * in which the module resides. The example shows how to take advantage of | |
3606 * both properties. | |
3607 * | |
3608 * @see _registry_update() | |
3609 * @see simpletest_test_get_all() | |
3610 */ | |
3611 function hook_registry_files_alter(&$files, $modules) { | |
3612 foreach ($modules as $module) { | |
3613 // Only add test files for disabled modules, as enabled modules should | |
3614 // already include any test files they provide. | |
3615 if (!$module->status) { | |
3616 $dir = $module->dir; | |
3617 foreach ($module->info['files'] as $file) { | |
3618 if (substr($file, -5) == '.test') { | |
3619 $files["$dir/$file"] = array('module' => $module->name, 'weight' => $module->weight); | |
3620 } | |
3621 } | |
3622 } | |
3623 } | |
3624 } | |
3625 | |
3626 /** | |
3627 * Return an array of tasks to be performed by an installation profile. | |
3628 * | |
3629 * Any tasks you define here will be run, in order, after the installer has | |
3630 * finished the site configuration step but before it has moved on to the | |
3631 * final import of languages and the end of the installation. You can have any | |
3632 * number of custom tasks to perform during this phase. | |
3633 * | |
3634 * Each task you define here corresponds to a callback function which you must | |
3635 * separately define and which is called when your task is run. This function | |
3636 * will receive the global installation state variable, $install_state, as | |
3637 * input, and has the opportunity to access or modify any of its settings. See | |
3638 * the install_state_defaults() function in the installer for the list of | |
3639 * $install_state settings used by Drupal core. | |
3640 * | |
3641 * At the end of your task function, you can indicate that you want the | |
3642 * installer to pause and display a page to the user by returning any themed | |
3643 * output that should be displayed on that page (but see below for tasks that | |
3644 * use the form API or batch API; the return values of these task functions are | |
3645 * handled differently). You should also use drupal_set_title() within the task | |
3646 * callback function to set a custom page title. For some tasks, however, you | |
3647 * may want to simply do some processing and pass control to the next task | |
3648 * without ending the page request; to indicate this, simply do not send back | |
3649 * a return value from your task function at all. This can be used, for | |
3650 * example, by installation profiles that need to configure certain site | |
3651 * settings in the database without obtaining any input from the user. | |
3652 * | |
3653 * The task function is treated specially if it defines a form or requires | |
3654 * batch processing; in that case, you should return either the form API | |
3655 * definition or batch API array, as appropriate. See below for more | |
3656 * information on the 'type' key that you must define in the task definition | |
3657 * to inform the installer that your task falls into one of those two | |
3658 * categories. It is important to use these APIs directly, since the installer | |
3659 * may be run non-interactively (for example, via a command line script), all | |
3660 * in one page request; in that case, the installer will automatically take | |
3661 * care of submitting forms and processing batches correctly for both types of | |
3662 * installations. You can inspect the $install_state['interactive'] boolean to | |
3663 * see whether or not the current installation is interactive, if you need | |
3664 * access to this information. | |
3665 * | |
3666 * Remember that a user installing Drupal interactively will be able to reload | |
3667 * an installation page multiple times, so you should use variable_set() and | |
3668 * variable_get() if you are collecting any data that you need to store and | |
3669 * inspect later. It is important to remove any temporary variables using | |
3670 * variable_del() before your last task has completed and control is handed | |
3671 * back to the installer. | |
3672 * | |
3673 * @param array $install_state | |
3674 * An array of information about the current installation state. | |
3675 * | |
3676 * @return array | |
3677 * A keyed array of tasks the profile will perform during the final stage of | |
3678 * the installation. Each key represents the name of a function (usually a | |
3679 * function defined by this profile, although that is not strictly required) | |
3680 * that is called when that task is run. The values are associative arrays | |
3681 * containing the following key-value pairs (all of which are optional): | |
3682 * - display_name: The human-readable name of the task. This will be | |
3683 * displayed to the user while the installer is running, along with a list | |
3684 * of other tasks that are being run. Leave this unset to prevent the task | |
3685 * from appearing in the list. | |
3686 * - display: This is a boolean which can be used to provide finer-grained | |
3687 * control over whether or not the task will display. This is mostly useful | |
3688 * for tasks that are intended to display only under certain conditions; | |
3689 * for these tasks, you can set 'display_name' to the name that you want to | |
3690 * display, but then use this boolean to hide the task only when certain | |
3691 * conditions apply. | |
3692 * - type: A string representing the type of task. This parameter has three | |
3693 * possible values: | |
3694 * - normal: (default) This indicates that the task will be treated as a | |
3695 * regular callback function, which does its processing and optionally | |
3696 * returns HTML output. | |
3697 * - batch: This indicates that the task function will return a batch API | |
3698 * definition suitable for batch_set(). The installer will then take care | |
3699 * of automatically running the task via batch processing. | |
3700 * - form: This indicates that the task function will return a standard | |
3701 * form API definition (and separately define validation and submit | |
3702 * handlers, as appropriate). The installer will then take care of | |
3703 * automatically directing the user through the form submission process. | |
3704 * - run: A constant representing the manner in which the task will be run. | |
3705 * This parameter has three possible values: | |
3706 * - INSTALL_TASK_RUN_IF_NOT_COMPLETED: (default) This indicates that the | |
3707 * task will run once during the installation of the profile. | |
3708 * - INSTALL_TASK_SKIP: This indicates that the task will not run during | |
3709 * the current installation page request. It can be used to skip running | |
3710 * an installation task when certain conditions are met, even though the | |
3711 * task may still show on the list of installation tasks presented to the | |
3712 * user. | |
3713 * - INSTALL_TASK_RUN_IF_REACHED: This indicates that the task will run on | |
3714 * each installation page request that reaches it. This is rarely | |
3715 * necessary for an installation profile to use; it is primarily used by | |
3716 * the Drupal installer for bootstrap-related tasks. | |
3717 * - function: Normally this does not need to be set, but it can be used to | |
3718 * force the installer to call a different function when the task is run | |
3719 * (rather than the function whose name is given by the array key). This | |
3720 * could be used, for example, to allow the same function to be called by | |
3721 * two different tasks. | |
3722 * | |
3723 * @see install_state_defaults() | |
3724 * @see batch_set() | |
3725 */ | |
3726 function hook_install_tasks(&$install_state) { | |
3727 // Here, we define a variable to allow tasks to indicate that a particular, | |
3728 // processor-intensive batch process needs to be triggered later on in the | |
3729 // installation. | |
3730 $myprofile_needs_batch_processing = variable_get('myprofile_needs_batch_processing', FALSE); | |
3731 $tasks = array( | |
3732 // This is an example of a task that defines a form which the user who is | |
3733 // installing the site will be asked to fill out. To implement this task, | |
3734 // your profile would define a function named myprofile_data_import_form() | |
3735 // as a normal form API callback function, with associated validation and | |
3736 // submit handlers. In the submit handler, in addition to saving whatever | |
3737 // other data you have collected from the user, you might also call | |
3738 // variable_set('myprofile_needs_batch_processing', TRUE) if the user has | |
3739 // entered data which requires that batch processing will need to occur | |
3740 // later on. | |
3741 'myprofile_data_import_form' => array( | |
3742 'display_name' => st('Data import options'), | |
3743 'type' => 'form', | |
3744 ), | |
3745 // Similarly, to implement this task, your profile would define a function | |
3746 // named myprofile_settings_form() with associated validation and submit | |
3747 // handlers. This form might be used to collect and save additional | |
3748 // information from the user that your profile needs. There are no extra | |
3749 // steps required for your profile to act as an "installation wizard"; you | |
3750 // can simply define as many tasks of type 'form' as you wish to execute, | |
3751 // and the forms will be presented to the user, one after another. | |
3752 'myprofile_settings_form' => array( | |
3753 'display_name' => st('Additional options'), | |
3754 'type' => 'form', | |
3755 ), | |
3756 // This is an example of a task that performs batch operations. To | |
3757 // implement this task, your profile would define a function named | |
3758 // myprofile_batch_processing() which returns a batch API array definition | |
3759 // that the installer will use to execute your batch operations. Due to the | |
3760 // 'myprofile_needs_batch_processing' variable used here, this task will be | |
3761 // hidden and skipped unless your profile set it to TRUE in one of the | |
3762 // previous tasks. | |
3763 'myprofile_batch_processing' => array( | |
3764 'display_name' => st('Import additional data'), | |
3765 'display' => $myprofile_needs_batch_processing, | |
3766 'type' => 'batch', | |
3767 'run' => $myprofile_needs_batch_processing ? INSTALL_TASK_RUN_IF_NOT_COMPLETED : INSTALL_TASK_SKIP, | |
3768 ), | |
3769 // This is an example of a task that will not be displayed in the list that | |
3770 // the user sees. To implement this task, your profile would define a | |
3771 // function named myprofile_final_site_setup(), in which additional, | |
3772 // automated site setup operations would be performed. Since this is the | |
3773 // last task defined by your profile, you should also use this function to | |
3774 // call variable_del('myprofile_needs_batch_processing') and clean up the | |
3775 // variable that was used above. If you want the user to pass to the final | |
3776 // Drupal installation tasks uninterrupted, return no output from this | |
3777 // function. Otherwise, return themed output that the user will see (for | |
3778 // example, a confirmation page explaining that your profile's tasks are | |
3779 // complete, with a link to reload the current page and therefore pass on | |
3780 // to the final Drupal installation tasks when the user is ready to do so). | |
3781 'myprofile_final_site_setup' => array( | |
3782 ), | |
3783 ); | |
3784 return $tasks; | |
3785 } | |
3786 | |
3787 /** | |
3788 * Change the page the user is sent to by drupal_goto(). | |
3789 * | |
3790 * @param $path | |
3791 * A Drupal path or a full URL. | |
3792 * @param $options | |
3793 * An associative array of additional URL options to pass to url(). | |
3794 * @param $http_response_code | |
3795 * The HTTP status code to use for the redirection. See drupal_goto() for more | |
3796 * information. | |
3797 */ | |
3798 function hook_drupal_goto_alter(&$path, &$options, &$http_response_code) { | |
3799 // A good addition to misery module. | |
3800 $http_response_code = 500; | |
3801 } | |
3802 | |
3803 /** | |
3804 * Alter XHTML HEAD tags before they are rendered by drupal_get_html_head(). | |
3805 * | |
3806 * Elements available to be altered are only those added using | |
3807 * drupal_add_html_head_link() or drupal_add_html_head(). CSS and JS files | |
3808 * are handled using drupal_add_css() and drupal_add_js(), so the head links | |
3809 * for those files will not appear in the $head_elements array. | |
3810 * | |
3811 * @param $head_elements | |
3812 * An array of renderable elements. Generally the values of the #attributes | |
3813 * array will be the most likely target for changes. | |
3814 */ | |
3815 function hook_html_head_alter(&$head_elements) { | |
3816 foreach ($head_elements as $key => $element) { | |
3817 if (isset($element['#attributes']['rel']) && $element['#attributes']['rel'] == 'canonical') { | |
3818 // I want a custom canonical URL. | |
3819 $head_elements[$key]['#attributes']['href'] = mymodule_canonical_url(); | |
3820 } | |
3821 } | |
3822 } | |
3823 | |
3824 /** | |
3825 * Alter the full list of installation tasks. | |
3826 * | |
3827 * @param $tasks | |
3828 * An array of all available installation tasks, including those provided by | |
3829 * Drupal core. You can modify this array to change or replace any part of | |
3830 * the Drupal installation process that occurs after the installation profile | |
3831 * is selected. | |
3832 * @param $install_state | |
3833 * An array of information about the current installation state. | |
3834 */ | |
3835 function hook_install_tasks_alter(&$tasks, $install_state) { | |
3836 // Replace the "Choose language" installation task provided by Drupal core | |
3837 // with a custom callback function defined by this installation profile. | |
3838 $tasks['install_select_locale']['function'] = 'myprofile_locale_selection'; | |
3839 } | |
3840 | |
3841 /** | |
3842 * Alter MIME type mappings used to determine MIME type from a file extension. | |
3843 * | |
3844 * This hook is run when file_mimetype_mapping() is called. It is used to | |
3845 * allow modules to add to or modify the default mapping from | |
3846 * file_default_mimetype_mapping(). | |
3847 * | |
3848 * @param $mapping | |
3849 * An array of mimetypes correlated to the extensions that relate to them. | |
3850 * The array has 'mimetypes' and 'extensions' elements, each of which is an | |
3851 * array. | |
3852 * | |
3853 * @see file_default_mimetype_mapping() | |
3854 */ | |
3855 function hook_file_mimetype_mapping_alter(&$mapping) { | |
3856 // Add new MIME type 'drupal/info'. | |
3857 $mapping['mimetypes']['example_info'] = 'drupal/info'; | |
3858 // Add new extension '.info' and map it to the 'drupal/info' MIME type. | |
3859 $mapping['extensions']['info'] = 'example_info'; | |
3860 // Override existing extension mapping for '.ogg' files. | |
3861 $mapping['extensions']['ogg'] = 189; | |
3862 } | |
3863 | |
3864 /** | |
3865 * Declares information about actions. | |
3866 * | |
3867 * Any module can define actions, and then call actions_do() to make those | |
3868 * actions happen in response to events. The trigger module provides a user | |
3869 * interface for associating actions with module-defined triggers, and it makes | |
3870 * sure the core triggers fire off actions when their events happen. | |
3871 * | |
3872 * An action consists of two or three parts: | |
3873 * - an action definition (returned by this hook) | |
3874 * - a function which performs the action (which by convention is named | |
3875 * MODULE_description-of-function_action) | |
3876 * - an optional form definition function that defines a configuration form | |
3877 * (which has the name of the action function with '_form' appended to it.) | |
3878 * | |
3879 * The action function takes two to four arguments, which come from the input | |
3880 * arguments to actions_do(). | |
3881 * | |
3882 * @return | |
3883 * An associative array of action descriptions. The keys of the array | |
3884 * are the names of the action functions, and each corresponding value | |
3885 * is an associative array with the following key-value pairs: | |
3886 * - 'type': The type of object this action acts upon. Core actions have types | |
3887 * 'node', 'user', 'comment', and 'system'. | |
3888 * - 'label': The human-readable name of the action, which should be passed | |
3889 * through the t() function for translation. | |
3890 * - 'configurable': If FALSE, then the action doesn't require any extra | |
3891 * configuration. If TRUE, then your module must define a form function with | |
3892 * the same name as the action function with '_form' appended (e.g., the | |
3893 * form for 'node_assign_owner_action' is 'node_assign_owner_action_form'.) | |
3894 * This function takes $context as its only parameter, and is paired with | |
3895 * the usual _submit function, and possibly a _validate function. | |
3896 * - 'triggers': An array of the events (that is, hooks) that can trigger this | |
3897 * action. For example: array('node_insert', 'user_update'). You can also | |
3898 * declare support for any trigger by returning array('any') for this value. | |
3899 * - 'behavior': (optional) A machine-readable array of behaviors of this | |
3900 * action, used to signal additionally required actions that may need to be | |
3901 * triggered. Currently recognized behaviors by Trigger module: | |
3902 * - 'changes_property': If an action with this behavior is assigned to a | |
3903 * trigger other than a "presave" hook, any save actions also assigned to | |
3904 * this trigger are moved later in the list. If no save action is present, | |
3905 * one will be added. | |
3906 * Modules that are processing actions (like Trigger module) should take | |
3907 * special care for the "presave" hook, in which case a dependent "save" | |
3908 * action should NOT be invoked. | |
3909 * | |
3910 * @ingroup actions | |
3911 */ | |
3912 function hook_action_info() { | |
3913 return array( | |
3914 'comment_unpublish_action' => array( | |
3915 'type' => 'comment', | |
3916 'label' => t('Unpublish comment'), | |
3917 'configurable' => FALSE, | |
3918 'behavior' => array('changes_property'), | |
3919 'triggers' => array('comment_presave', 'comment_insert', 'comment_update'), | |
3920 ), | |
3921 'comment_unpublish_by_keyword_action' => array( | |
3922 'type' => 'comment', | |
3923 'label' => t('Unpublish comment containing keyword(s)'), | |
3924 'configurable' => TRUE, | |
3925 'behavior' => array('changes_property'), | |
3926 'triggers' => array('comment_presave', 'comment_insert', 'comment_update'), | |
3927 ), | |
3928 'comment_save_action' => array( | |
3929 'type' => 'comment', | |
3930 'label' => t('Save comment'), | |
3931 'configurable' => FALSE, | |
3932 'triggers' => array('comment_insert', 'comment_update'), | |
3933 ), | |
3934 ); | |
3935 } | |
3936 | |
3937 /** | |
3938 * Executes code after an action is deleted. | |
3939 * | |
3940 * @param $aid | |
3941 * The action ID. | |
3942 */ | |
3943 function hook_actions_delete($aid) { | |
3944 db_delete('actions_assignments') | |
3945 ->condition('aid', $aid) | |
3946 ->execute(); | |
3947 } | |
3948 | |
3949 /** | |
3950 * Alters the actions declared by another module. | |
3951 * | |
3952 * Called by actions_list() to allow modules to alter the return values from | |
3953 * implementations of hook_action_info(). | |
3954 * | |
3955 * @see trigger_example_action_info_alter() | |
3956 */ | |
3957 function hook_action_info_alter(&$actions) { | |
3958 $actions['node_unpublish_action']['label'] = t('Unpublish and remove from public view.'); | |
3959 } | |
3960 | |
3961 /** | |
3962 * Declare archivers to the system. | |
3963 * | |
3964 * An archiver is a class that is able to package and unpackage one or more files | |
3965 * into a single possibly compressed file. Common examples of such files are | |
3966 * zip files and tar.gz files. All archiver classes must implement | |
3967 * ArchiverInterface. | |
3968 * | |
3969 * Each entry should be keyed on a unique value, and specify three | |
3970 * additional keys: | |
3971 * - class: The name of the PHP class for this archiver. | |
3972 * - extensions: An array of file extensions that this archiver supports. | |
3973 * - weight: This optional key specifies the weight of this archiver. | |
3974 * When mapping file extensions to archivers, the first archiver by | |
3975 * weight found that supports the requested extension will be used. | |
3976 * | |
3977 * @see hook_archiver_info_alter() | |
3978 */ | |
3979 function hook_archiver_info() { | |
3980 return array( | |
3981 'tar' => array( | |
3982 'class' => 'ArchiverTar', | |
3983 'extensions' => array('tar', 'tar.gz', 'tar.bz2'), | |
3984 ), | |
3985 ); | |
3986 } | |
3987 | |
3988 /** | |
3989 * Alter archiver information declared by other modules. | |
3990 * | |
3991 * See hook_archiver_info() for a description of archivers and the archiver | |
3992 * information structure. | |
3993 * | |
3994 * @param $info | |
3995 * Archiver information to alter (return values from hook_archiver_info()). | |
3996 */ | |
3997 function hook_archiver_info_alter(&$info) { | |
3998 $info['tar']['extensions'][] = 'tgz'; | |
3999 } | |
4000 | |
4001 /** | |
4002 * Define additional date types. | |
4003 * | |
4004 * Next to the 'long', 'medium' and 'short' date types defined in core, any | |
4005 * module can define additional types that can be used when displaying dates, | |
4006 * by implementing this hook. A date type is basically just a name for a date | |
4007 * format. | |
4008 * | |
4009 * Date types are used in the administration interface: a user can assign | |
4010 * date format types defined in hook_date_formats() to date types defined in | |
4011 * this hook. Once a format has been assigned by a user, the machine name of a | |
4012 * type can be used in the format_date() function to format a date using the | |
4013 * chosen formatting. | |
4014 * | |
4015 * To define a date type in a module and make sure a format has been assigned to | |
4016 * it, without requiring a user to visit the administrative interface, use | |
4017 * @code variable_set('date_format_' . $type, $format); @endcode | |
4018 * where $type is the machine-readable name defined here, and $format is a PHP | |
4019 * date format string. | |
4020 * | |
4021 * To avoid namespace collisions with date types defined by other modules, it is | |
4022 * recommended that each date type starts with the module name. A date type | |
4023 * can consist of letters, numbers and underscores. | |
4024 * | |
4025 * @return | |
4026 * An array of date types where the keys are the machine-readable names and | |
4027 * the values are the human-readable labels. | |
4028 * | |
4029 * @see hook_date_formats() | |
4030 * @see format_date() | |
4031 */ | |
4032 function hook_date_format_types() { | |
4033 // Define the core date format types. | |
4034 return array( | |
4035 'long' => t('Long'), | |
4036 'medium' => t('Medium'), | |
4037 'short' => t('Short'), | |
4038 ); | |
4039 } | |
4040 | |
4041 /** | |
4042 * Modify existing date types. | |
4043 * | |
4044 * Allows other modules to modify existing date types like 'long'. Called by | |
4045 * _system_date_format_types_build(). For instance, A module may use this hook | |
4046 * to apply settings across all date types, such as locking all date types so | |
4047 * they appear to be provided by the system. | |
4048 * | |
4049 * @param $types | |
4050 * A list of date types. Each date type is keyed by the machine-readable name | |
4051 * and the values are associative arrays containing: | |
4052 * - is_new: Set to FALSE to override previous settings. | |
4053 * - module: The name of the module that created the date type. | |
4054 * - type: The machine-readable date type name. | |
4055 * - title: The human-readable date type name. | |
4056 * - locked: Specifies that the date type is system-provided. | |
4057 */ | |
4058 function hook_date_format_types_alter(&$types) { | |
4059 foreach ($types as $name => $type) { | |
4060 $types[$name]['locked'] = 1; | |
4061 } | |
4062 } | |
4063 | |
4064 /** | |
4065 * Define additional date formats. | |
4066 * | |
4067 * This hook is used to define the PHP date format strings that can be assigned | |
4068 * to date types in the administrative interface. A module can provide date | |
4069 * format strings for the core-provided date types ('long', 'medium', and | |
4070 * 'short'), or for date types defined in hook_date_format_types() by itself | |
4071 * or another module. | |
4072 * | |
4073 * Since date formats can be locale-specific, you can specify the locales that | |
4074 * each date format string applies to. There may be more than one locale for a | |
4075 * format. There may also be more than one format for the same locale. For | |
4076 * example d/m/Y and Y/m/d work equally well in some locales. You may wish to | |
4077 * define some additional date formats that aren't specific to any one locale, | |
4078 * for example, "Y m". For these cases, the 'locales' component of the return | |
4079 * value should be omitted. | |
4080 * | |
4081 * Providing a date format here does not normally assign the format to be | |
4082 * used with the associated date type -- a user has to choose a format for each | |
4083 * date type in the administrative interface. There is one exception: locale | |
4084 * initialization chooses a locale-specific format for the three core-provided | |
4085 * types (see locale_get_localized_date_format() for details). If your module | |
4086 * needs to ensure that a date type it defines has a format associated with it, | |
4087 * call @code variable_set('date_format_' . $type, $format); @endcode | |
4088 * where $type is the machine-readable name defined in hook_date_format_types(), | |
4089 * and $format is a PHP date format string. | |
4090 * | |
4091 * @return | |
4092 * A list of date formats to offer as choices in the administrative | |
4093 * interface. Each date format is a keyed array consisting of three elements: | |
4094 * - 'type': The date type name that this format can be used with, as | |
4095 * declared in an implementation of hook_date_format_types(). | |
4096 * - 'format': A PHP date format string to use when formatting dates. It | |
4097 * can contain any of the formatting options described at | |
4098 * http://php.net/manual/en/function.date.php | |
4099 * - 'locales': (optional) An array of 2 and 5 character locale codes, | |
4100 * defining which locales this format applies to (for example, 'en', | |
4101 * 'en-us', etc.). If your date format is not language-specific, leave this | |
4102 * array empty. | |
4103 * | |
4104 * @see hook_date_format_types() | |
4105 */ | |
4106 function hook_date_formats() { | |
4107 return array( | |
4108 array( | |
4109 'type' => 'mymodule_extra_long', | |
4110 'format' => 'l jS F Y H:i:s e', | |
4111 'locales' => array('en-ie'), | |
4112 ), | |
4113 array( | |
4114 'type' => 'mymodule_extra_long', | |
4115 'format' => 'l jS F Y h:i:sa', | |
4116 'locales' => array('en', 'en-us'), | |
4117 ), | |
4118 array( | |
4119 'type' => 'short', | |
4120 'format' => 'F Y', | |
4121 'locales' => array(), | |
4122 ), | |
4123 ); | |
4124 } | |
4125 | |
4126 /** | |
4127 * Alter date formats declared by another module. | |
4128 * | |
4129 * Called by _system_date_format_types_build() to allow modules to alter the | |
4130 * return values from implementations of hook_date_formats(). | |
4131 */ | |
4132 function hook_date_formats_alter(&$formats) { | |
4133 foreach ($formats as $id => $format) { | |
4134 $formats[$id]['locales'][] = 'en-ca'; | |
4135 } | |
4136 } | |
4137 | |
4138 /** | |
4139 * Alters the delivery callback used to send the result of the page callback to the browser. | |
4140 * | |
4141 * Called by drupal_deliver_page() to allow modules to alter how the | |
4142 * page is delivered to the browser. | |
4143 * | |
4144 * This hook is intended for altering the delivery callback based on | |
4145 * information unrelated to the path of the page accessed. For example, | |
4146 * it can be used to set the delivery callback based on a HTTP request | |
4147 * header (as shown in the code sample). To specify a delivery callback | |
4148 * based on path information, use hook_menu() or hook_menu_alter(). | |
4149 * | |
4150 * This hook can also be used as an API function that can be used to explicitly | |
4151 * set the delivery callback from some other function. For example, for a module | |
4152 * named MODULE: | |
4153 * @code | |
4154 * function MODULE_page_delivery_callback_alter(&$callback, $set = FALSE) { | |
4155 * static $stored_callback; | |
4156 * if ($set) { | |
4157 * $stored_callback = $callback; | |
4158 * } | |
4159 * elseif (isset($stored_callback)) { | |
4160 * $callback = $stored_callback; | |
4161 * } | |
4162 * } | |
4163 * function SOMEWHERE_ELSE() { | |
4164 * $desired_delivery_callback = 'foo'; | |
4165 * MODULE_page_delivery_callback_alter($desired_delivery_callback, TRUE); | |
4166 * } | |
4167 * @endcode | |
4168 * | |
4169 * @param $callback | |
4170 * The name of a function. | |
4171 * | |
4172 * @see drupal_deliver_page() | |
4173 */ | |
4174 function hook_page_delivery_callback_alter(&$callback) { | |
4175 // jQuery sets a HTTP_X_REQUESTED_WITH header of 'XMLHttpRequest'. | |
4176 // If a page would normally be delivered as an html page, and it is called | |
4177 // from jQuery, deliver it instead as an Ajax response. | |
4178 if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' && $callback == 'drupal_deliver_html_page') { | |
4179 $callback = 'ajax_deliver'; | |
4180 } | |
4181 } | |
4182 | |
4183 /** | |
4184 * Alters theme operation links. | |
4185 * | |
4186 * @param $theme_groups | |
4187 * An associative array containing groups of themes. | |
4188 * | |
4189 * @see system_themes_page() | |
4190 */ | |
4191 function hook_system_themes_page_alter(&$theme_groups) { | |
4192 foreach ($theme_groups as $state => &$group) { | |
4193 foreach ($theme_groups[$state] as &$theme) { | |
4194 // Add a foo link to each list of theme operations. | |
4195 $theme->operations[] = array( | |
4196 'title' => t('Foo'), | |
4197 'href' => 'admin/appearance/foo', | |
4198 'query' => array('theme' => $theme->name) | |
4199 ); | |
4200 } | |
4201 } | |
4202 } | |
4203 | |
4204 /** | |
4205 * Alters inbound URL requests. | |
4206 * | |
4207 * @param $path | |
4208 * The path being constructed, which, if a path alias, has been resolved to a | |
4209 * Drupal path by the database, and which also may have been altered by other | |
4210 * modules before this one. | |
4211 * @param $original_path | |
4212 * The original path, before being checked for path aliases or altered by any | |
4213 * modules. | |
4214 * @param $path_language | |
4215 * The language of the path. | |
4216 * | |
4217 * @see drupal_get_normal_path() | |
4218 */ | |
4219 function hook_url_inbound_alter(&$path, $original_path, $path_language) { | |
4220 // Create the path user/me/edit, which allows a user to edit their account. | |
4221 if (preg_match('|^user/me/edit(/.*)?|', $path, $matches)) { | |
4222 global $user; | |
4223 $path = 'user/' . $user->uid . '/edit' . $matches[1]; | |
4224 } | |
4225 } | |
4226 | |
4227 /** | |
4228 * Alters outbound URLs. | |
4229 * | |
4230 * @param $path | |
4231 * The outbound path to alter, not adjusted for path aliases yet. It won't be | |
4232 * adjusted for path aliases until all modules are finished altering it, thus | |
4233 * being consistent with hook_url_inbound_alter(), which adjusts for all path | |
4234 * aliases before allowing modules to alter it. This may have been altered by | |
4235 * other modules before this one. | |
4236 * @param $options | |
4237 * A set of URL options for the URL so elements such as a fragment or a query | |
4238 * string can be added to the URL. | |
4239 * @param $original_path | |
4240 * The original path, before being altered by any modules. | |
4241 * | |
4242 * @see url() | |
4243 */ | |
4244 function hook_url_outbound_alter(&$path, &$options, $original_path) { | |
4245 // Use an external RSS feed rather than the Drupal one. | |
4246 if ($path == 'rss.xml') { | |
4247 $path = 'http://example.com/rss.xml'; | |
4248 $options['external'] = TRUE; | |
4249 } | |
4250 | |
4251 // Instead of pointing to user/[uid]/edit, point to user/me/edit. | |
4252 if (preg_match('|^user/([0-9]*)/edit(/.*)?|', $path, $matches)) { | |
4253 global $user; | |
4254 if ($user->uid == $matches[1]) { | |
4255 $path = 'user/me/edit' . $matches[2]; | |
4256 } | |
4257 } | |
4258 } | |
4259 | |
4260 /** | |
4261 * Alter the username that is displayed for a user. | |
4262 * | |
4263 * Called by format_username() to allow modules to alter the username that's | |
4264 * displayed. Can be used to ensure user privacy in situations where | |
4265 * $account->name is too revealing. | |
4266 * | |
4267 * @param $name | |
4268 * The string that format_username() will return. | |
4269 * | |
4270 * @param $account | |
4271 * The account object passed to format_username(). | |
4272 * | |
4273 * @see format_username() | |
4274 */ | |
4275 function hook_username_alter(&$name, $account) { | |
4276 // Display the user's uid instead of name. | |
4277 if (isset($account->uid)) { | |
4278 $name = t('User !uid', array('!uid' => $account->uid)); | |
4279 } | |
4280 } | |
4281 | |
4282 /** | |
4283 * Provide replacement values for placeholder tokens. | |
4284 * | |
4285 * This hook is invoked when someone calls token_replace(). That function first | |
4286 * scans the text for [type:token] patterns, and splits the needed tokens into | |
4287 * groups by type. Then hook_tokens() is invoked on each token-type group, | |
4288 * allowing your module to respond by providing replacement text for any of | |
4289 * the tokens in the group that your module knows how to process. | |
4290 * | |
4291 * A module implementing this hook should also implement hook_token_info() in | |
4292 * order to list its available tokens on editing screens. | |
4293 * | |
4294 * @param $type | |
4295 * The machine-readable name of the type (group) of token being replaced, such | |
4296 * as 'node', 'user', or another type defined by a hook_token_info() | |
4297 * implementation. | |
4298 * @param $tokens | |
4299 * An array of tokens to be replaced. The keys are the machine-readable token | |
4300 * names, and the values are the raw [type:token] strings that appeared in the | |
4301 * original text. | |
4302 * @param $data | |
4303 * (optional) An associative array of data objects to be used when generating | |
4304 * replacement values, as supplied in the $data parameter to token_replace(). | |
4305 * @param $options | |
4306 * (optional) An associative array of options for token replacement; see | |
4307 * token_replace() for possible values. | |
4308 * | |
4309 * @return | |
4310 * An associative array of replacement values, keyed by the raw [type:token] | |
4311 * strings from the original text. | |
4312 * | |
4313 * @see hook_token_info() | |
4314 * @see hook_tokens_alter() | |
4315 */ | |
4316 function hook_tokens($type, $tokens, array $data = array(), array $options = array()) { | |
4317 $url_options = array('absolute' => TRUE); | |
4318 if (isset($options['language'])) { | |
4319 $url_options['language'] = $options['language']; | |
4320 $language_code = $options['language']->language; | |
4321 } | |
4322 else { | |
4323 $language_code = NULL; | |
4324 } | |
4325 $sanitize = !empty($options['sanitize']); | |
4326 | |
4327 $replacements = array(); | |
4328 | |
4329 if ($type == 'node' && !empty($data['node'])) { | |
4330 $node = $data['node']; | |
4331 | |
4332 foreach ($tokens as $name => $original) { | |
4333 switch ($name) { | |
4334 // Simple key values on the node. | |
4335 case 'nid': | |
4336 $replacements[$original] = $node->nid; | |
4337 break; | |
4338 | |
4339 case 'title': | |
4340 $replacements[$original] = $sanitize ? check_plain($node->title) : $node->title; | |
4341 break; | |
4342 | |
4343 case 'edit-url': | |
4344 $replacements[$original] = url('node/' . $node->nid . '/edit', $url_options); | |
4345 break; | |
4346 | |
4347 // Default values for the chained tokens handled below. | |
4348 case 'author': | |
4349 $name = ($node->uid == 0) ? variable_get('anonymous', t('Anonymous')) : $node->name; | |
4350 $replacements[$original] = $sanitize ? filter_xss($name) : $name; | |
4351 break; | |
4352 | |
4353 case 'created': | |
4354 $replacements[$original] = format_date($node->created, 'medium', '', NULL, $language_code); | |
4355 break; | |
4356 } | |
4357 } | |
4358 | |
4359 if ($author_tokens = token_find_with_prefix($tokens, 'author')) { | |
4360 $author = user_load($node->uid); | |
4361 $replacements += token_generate('user', $author_tokens, array('user' => $author), $options); | |
4362 } | |
4363 | |
4364 if ($created_tokens = token_find_with_prefix($tokens, 'created')) { | |
4365 $replacements += token_generate('date', $created_tokens, array('date' => $node->created), $options); | |
4366 } | |
4367 } | |
4368 | |
4369 return $replacements; | |
4370 } | |
4371 | |
4372 /** | |
4373 * Alter replacement values for placeholder tokens. | |
4374 * | |
4375 * @param $replacements | |
4376 * An associative array of replacements returned by hook_tokens(). | |
4377 * @param $context | |
4378 * The context in which hook_tokens() was called. An associative array with | |
4379 * the following keys, which have the same meaning as the corresponding | |
4380 * parameters of hook_tokens(): | |
4381 * - 'type' | |
4382 * - 'tokens' | |
4383 * - 'data' | |
4384 * - 'options' | |
4385 * | |
4386 * @see hook_tokens() | |
4387 */ | |
4388 function hook_tokens_alter(array &$replacements, array $context) { | |
4389 $options = $context['options']; | |
4390 | |
4391 if (isset($options['language'])) { | |
4392 $url_options['language'] = $options['language']; | |
4393 $language_code = $options['language']->language; | |
4394 } | |
4395 else { | |
4396 $language_code = NULL; | |
4397 } | |
4398 $sanitize = !empty($options['sanitize']); | |
4399 | |
4400 if ($context['type'] == 'node' && !empty($context['data']['node'])) { | |
4401 $node = $context['data']['node']; | |
4402 | |
4403 // Alter the [node:title] token, and replace it with the rendered content | |
4404 // of a field (field_title). | |
4405 if (isset($context['tokens']['title'])) { | |
4406 $title = field_view_field('node', $node, 'field_title', 'default', $language_code); | |
4407 $replacements[$context['tokens']['title']] = drupal_render($title); | |
4408 } | |
4409 } | |
4410 } | |
4411 | |
4412 /** | |
4413 * Provide information about available placeholder tokens and token types. | |
4414 * | |
4415 * Tokens are placeholders that can be put into text by using the syntax | |
4416 * [type:token], where type is the machine-readable name of a token type, and | |
4417 * token is the machine-readable name of a token within this group. This hook | |
4418 * provides a list of types and tokens to be displayed on text editing screens, | |
4419 * so that people editing text can see what their token options are. | |
4420 * | |
4421 * The actual token replacement is done by token_replace(), which invokes | |
4422 * hook_tokens(). Your module will need to implement that hook in order to | |
4423 * generate token replacements from the tokens defined here. | |
4424 * | |
4425 * @return | |
4426 * An associative array of available tokens and token types. The outer array | |
4427 * has two components: | |
4428 * - types: An associative array of token types (groups). Each token type is | |
4429 * an associative array with the following components: | |
4430 * - name: The translated human-readable short name of the token type. | |
4431 * - description: A translated longer description of the token type. | |
4432 * - needs-data: The type of data that must be provided to token_replace() | |
4433 * in the $data argument (i.e., the key name in $data) in order for tokens | |
4434 * of this type to be used in the $text being processed. For instance, if | |
4435 * the token needs a node object, 'needs-data' should be 'node', and to | |
4436 * use this token in token_replace(), the caller needs to supply a node | |
4437 * object as $data['node']. Some token data can also be supplied | |
4438 * indirectly; for instance, a node object in $data supplies a user object | |
4439 * (the author of the node), allowing user tokens to be used when only | |
4440 * a node data object is supplied. | |
4441 * - tokens: An associative array of tokens. The outer array is keyed by the | |
4442 * group name (the same key as in the types array). Within each group of | |
4443 * tokens, each token item is keyed by the machine name of the token, and | |
4444 * each token item has the following components: | |
4445 * - name: The translated human-readable short name of the token. | |
4446 * - description: A translated longer description of the token. | |
4447 * - type (optional): A 'needs-data' data type supplied by this token, which | |
4448 * should match a 'needs-data' value from another token type. For example, | |
4449 * the node author token provides a user object, which can then be used | |
4450 * for token replacement data in token_replace() without having to supply | |
4451 * a separate user object. | |
4452 * | |
4453 * @see hook_token_info_alter() | |
4454 * @see hook_tokens() | |
4455 */ | |
4456 function hook_token_info() { | |
4457 $type = array( | |
4458 'name' => t('Nodes'), | |
4459 'description' => t('Tokens related to individual nodes.'), | |
4460 'needs-data' => 'node', | |
4461 ); | |
4462 | |
4463 // Core tokens for nodes. | |
4464 $node['nid'] = array( | |
4465 'name' => t("Node ID"), | |
4466 'description' => t("The unique ID of the node."), | |
4467 ); | |
4468 $node['title'] = array( | |
4469 'name' => t("Title"), | |
4470 'description' => t("The title of the node."), | |
4471 ); | |
4472 $node['edit-url'] = array( | |
4473 'name' => t("Edit URL"), | |
4474 'description' => t("The URL of the node's edit page."), | |
4475 ); | |
4476 | |
4477 // Chained tokens for nodes. | |
4478 $node['created'] = array( | |
4479 'name' => t("Date created"), | |
4480 'description' => t("The date the node was posted."), | |
4481 'type' => 'date', | |
4482 ); | |
4483 $node['author'] = array( | |
4484 'name' => t("Author"), | |
4485 'description' => t("The author of the node."), | |
4486 'type' => 'user', | |
4487 ); | |
4488 | |
4489 return array( | |
4490 'types' => array('node' => $type), | |
4491 'tokens' => array('node' => $node), | |
4492 ); | |
4493 } | |
4494 | |
4495 /** | |
4496 * Alter the metadata about available placeholder tokens and token types. | |
4497 * | |
4498 * @param $data | |
4499 * The associative array of token definitions from hook_token_info(). | |
4500 * | |
4501 * @see hook_token_info() | |
4502 */ | |
4503 function hook_token_info_alter(&$data) { | |
4504 // Modify description of node tokens for our site. | |
4505 $data['tokens']['node']['nid'] = array( | |
4506 'name' => t("Node ID"), | |
4507 'description' => t("The unique ID of the article."), | |
4508 ); | |
4509 $data['tokens']['node']['title'] = array( | |
4510 'name' => t("Title"), | |
4511 'description' => t("The title of the article."), | |
4512 ); | |
4513 | |
4514 // Chained tokens for nodes. | |
4515 $data['tokens']['node']['created'] = array( | |
4516 'name' => t("Date created"), | |
4517 'description' => t("The date the article was posted."), | |
4518 'type' => 'date', | |
4519 ); | |
4520 } | |
4521 | |
4522 /** | |
4523 * Alter batch information before a batch is processed. | |
4524 * | |
4525 * Called by batch_process() to allow modules to alter a batch before it is | |
4526 * processed. | |
4527 * | |
4528 * @param $batch | |
4529 * The associative array of batch information. See batch_set() for details on | |
4530 * what this could contain. | |
4531 * | |
4532 * @see batch_set() | |
4533 * @see batch_process() | |
4534 * | |
4535 * @ingroup batch | |
4536 */ | |
4537 function hook_batch_alter(&$batch) { | |
4538 // If the current page request is inside the overlay, add ?render=overlay to | |
4539 // the success callback URL, so that it appears correctly within the overlay. | |
4540 if (overlay_get_mode() == 'child') { | |
4541 if (isset($batch['url_options']['query'])) { | |
4542 $batch['url_options']['query']['render'] = 'overlay'; | |
4543 } | |
4544 else { | |
4545 $batch['url_options']['query'] = array('render' => 'overlay'); | |
4546 } | |
4547 } | |
4548 } | |
4549 | |
4550 /** | |
4551 * Provide information on Updaters (classes that can update Drupal). | |
4552 * | |
4553 * An Updater is a class that knows how to update various parts of the Drupal | |
4554 * file system, for example to update modules that have newer releases, or to | |
4555 * install a new theme. | |
4556 * | |
4557 * @return | |
4558 * An associative array of information about the updater(s) being provided. | |
4559 * This array is keyed by a unique identifier for each updater, and the | |
4560 * values are subarrays that can contain the following keys: | |
4561 * - class: The name of the PHP class which implements this updater. | |
4562 * - name: Human-readable name of this updater. | |
4563 * - weight: Controls what order the Updater classes are consulted to decide | |
4564 * which one should handle a given task. When an update task is being run, | |
4565 * the system will loop through all the Updater classes defined in this | |
4566 * registry in weight order and let each class respond to the task and | |
4567 * decide if each Updater wants to handle the task. In general, this | |
4568 * doesn't matter, but if you need to override an existing Updater, make | |
4569 * sure your Updater has a lighter weight so that it comes first. | |
4570 * | |
4571 * @see drupal_get_updaters() | |
4572 * @see hook_updater_info_alter() | |
4573 */ | |
4574 function hook_updater_info() { | |
4575 return array( | |
4576 'module' => array( | |
4577 'class' => 'ModuleUpdater', | |
4578 'name' => t('Update modules'), | |
4579 'weight' => 0, | |
4580 ), | |
4581 'theme' => array( | |
4582 'class' => 'ThemeUpdater', | |
4583 'name' => t('Update themes'), | |
4584 'weight' => 0, | |
4585 ), | |
4586 ); | |
4587 } | |
4588 | |
4589 /** | |
4590 * Alter the Updater information array. | |
4591 * | |
4592 * An Updater is a class that knows how to update various parts of the Drupal | |
4593 * file system, for example to update modules that have newer releases, or to | |
4594 * install a new theme. | |
4595 * | |
4596 * @param array $updaters | |
4597 * Associative array of updaters as defined through hook_updater_info(). | |
4598 * Alter this array directly. | |
4599 * | |
4600 * @see drupal_get_updaters() | |
4601 * @see hook_updater_info() | |
4602 */ | |
4603 function hook_updater_info_alter(&$updaters) { | |
4604 // Adjust weight so that the theme Updater gets a chance to handle a given | |
4605 // update task before module updaters. | |
4606 $updaters['theme']['weight'] = -1; | |
4607 } | |
4608 | |
4609 /** | |
4610 * Alter the default country list. | |
4611 * | |
4612 * @param $countries | |
4613 * The associative array of countries keyed by ISO 3166-1 country code. | |
4614 * | |
4615 * @see country_get_list() | |
4616 * @see _country_get_predefined_list() | |
4617 */ | |
4618 function hook_countries_alter(&$countries) { | |
4619 // Elbonia is now independent, so add it to the country list. | |
4620 $countries['EB'] = 'Elbonia'; | |
4621 } | |
4622 | |
4623 /** | |
4624 * Control site status before menu dispatching. | |
4625 * | |
4626 * The hook is called after checking whether the site is offline but before | |
4627 * the current router item is retrieved and executed by | |
4628 * menu_execute_active_handler(). If the site is in offline mode, | |
4629 * $menu_site_status is set to MENU_SITE_OFFLINE. | |
4630 * | |
4631 * @param $menu_site_status | |
4632 * Supported values are MENU_SITE_OFFLINE, MENU_ACCESS_DENIED, | |
4633 * MENU_NOT_FOUND and MENU_SITE_ONLINE. Any other value than | |
4634 * MENU_SITE_ONLINE will skip the default menu handling system and be passed | |
4635 * for delivery to drupal_deliver_page() with a NULL | |
4636 * $default_delivery_callback. | |
4637 * @param $path | |
4638 * Contains the system path that is going to be loaded. This is read only, | |
4639 * use hook_url_inbound_alter() to change the path. | |
4640 */ | |
4641 function hook_menu_site_status_alter(&$menu_site_status, $path) { | |
4642 // Allow access to my_module/authentication even if site is in offline mode. | |
4643 if ($menu_site_status == MENU_SITE_OFFLINE && user_is_anonymous() && $path == 'my_module/authentication') { | |
4644 $menu_site_status = MENU_SITE_ONLINE; | |
4645 } | |
4646 } | |
4647 | |
4648 /** | |
4649 * Register information about FileTransfer classes provided by a module. | |
4650 * | |
4651 * The FileTransfer class allows transferring files over a specific type of | |
4652 * connection. Core provides classes for FTP and SSH. Contributed modules are | |
4653 * free to extend the FileTransfer base class to add other connection types, | |
4654 * and if these classes are registered via hook_filetransfer_info(), those | |
4655 * connection types will be available to site administrators using the Update | |
4656 * manager when they are redirected to the authorize.php script to authorize | |
4657 * the file operations. | |
4658 * | |
4659 * @return array | |
4660 * Nested array of information about FileTransfer classes. Each key is a | |
4661 * FileTransfer type (not human readable, used for form elements and | |
4662 * variable names, etc), and the values are subarrays that define properties | |
4663 * of that type. The keys in each subarray are: | |
4664 * - 'title': Required. The human-readable name of the connection type. | |
4665 * - 'class': Required. The name of the FileTransfer class. The constructor | |
4666 * will always be passed the full path to the root of the site that should | |
4667 * be used to restrict where file transfer operations can occur (the $jail) | |
4668 * and an array of settings values returned by the settings form. | |
4669 * - 'file': Required. The include file containing the FileTransfer class. | |
4670 * This should be a separate .inc file, not just the .module file, so that | |
4671 * the minimum possible code is loaded when authorize.php is running. | |
4672 * - 'file path': Optional. The directory (relative to the Drupal root) | |
4673 * where the include file lives. If not defined, defaults to the base | |
4674 * directory of the module implementing the hook. | |
4675 * - 'weight': Optional. Integer weight used for sorting connection types on | |
4676 * the authorize.php form. | |
4677 * | |
4678 * @see FileTransfer | |
4679 * @see authorize.php | |
4680 * @see hook_filetransfer_info_alter() | |
4681 * @see drupal_get_filetransfer_info() | |
4682 */ | |
4683 function hook_filetransfer_info() { | |
4684 $info['sftp'] = array( | |
4685 'title' => t('SFTP (Secure FTP)'), | |
4686 'file' => 'sftp.filetransfer.inc', | |
4687 'class' => 'FileTransferSFTP', | |
4688 'weight' => 10, | |
4689 ); | |
4690 return $info; | |
4691 } | |
4692 | |
4693 /** | |
4694 * Alter the FileTransfer class registry. | |
4695 * | |
4696 * @param array $filetransfer_info | |
4697 * Reference to a nested array containing information about the FileTransfer | |
4698 * class registry. | |
4699 * | |
4700 * @see hook_filetransfer_info() | |
4701 */ | |
4702 function hook_filetransfer_info_alter(&$filetransfer_info) { | |
4703 if (variable_get('paranoia', FALSE)) { | |
4704 // Remove the FTP option entirely. | |
4705 unset($filetransfer_info['ftp']); | |
4706 // Make sure the SSH option is listed first. | |
4707 $filetransfer_info['ssh']['weight'] = -10; | |
4708 } | |
4709 } | |
4710 | |
4711 /** | |
4712 * @} End of "addtogroup hooks". | |
4713 */ | |
4714 | |
4715 /** | |
4716 * @addtogroup callbacks | |
4717 * @{ | |
4718 */ | |
4719 | |
4720 /** | |
4721 * Return the URI for an entity. | |
4722 * | |
4723 * Callback for hook_entity_info(). | |
4724 * | |
4725 * @param $entity | |
4726 * The entity to return the URI for. | |
4727 * | |
4728 * @return | |
4729 * An associative array with the following elements: | |
4730 * - 'path': The URL path for the entity. | |
4731 * - 'options': (optional) An array of options for the url() function. | |
4732 * The actual entity URI can be constructed by passing these elements to | |
4733 * url(). | |
4734 */ | |
4735 function callback_entity_info_uri($entity) { | |
4736 return array( | |
4737 'path' => 'node/' . $entity->nid, | |
4738 ); | |
4739 } | |
4740 | |
4741 /** | |
4742 * Return the label of an entity. | |
4743 * | |
4744 * Callback for hook_entity_info(). | |
4745 * | |
4746 * @param $entity | |
4747 * The entity for which to generate the label. | |
4748 * @param $entity_type | |
4749 * The entity type; e.g., 'node' or 'user'. | |
4750 * | |
4751 * @return | |
4752 * An unsanitized string with the label of the entity. | |
4753 * | |
4754 * @see entity_label() | |
4755 */ | |
4756 function callback_entity_info_label($entity, $entity_type) { | |
4757 return empty($entity->title) ? 'Untitled entity' : $entity->title; | |
4758 } | |
4759 | |
4760 /** | |
4761 * Return the language code of the entity. | |
4762 * | |
4763 * Callback for hook_entity_info(). | |
4764 * | |
4765 * The language callback is meant to be used primarily for temporary alterations | |
4766 * of the property value. | |
4767 * | |
4768 * @param $entity | |
4769 * The entity for which to return the language. | |
4770 * @param $entity_type | |
4771 * The entity type; e.g., 'node' or 'user'. | |
4772 * | |
4773 * @return | |
4774 * The language code for the language of the entity. | |
4775 * | |
4776 * @see entity_language() | |
4777 */ | |
4778 function callback_entity_info_language($entity, $entity_type) { | |
4779 return $entity->language; | |
4780 } | |
4781 | |
4782 /** | |
4783 * @} End of "addtogroup callbacks". | |
4784 */ | |
4785 | |
4786 /** | |
4787 * @defgroup update_api Update versions of API functions | |
4788 * @{ | |
4789 * Functions that are similar to normal API functions, but do not invoke hooks. | |
4790 * | |
4791 * These simplified versions of core API functions are provided for use by | |
4792 * update functions (hook_update_N() implementations). | |
4793 * | |
4794 * During database updates the schema of any module could be out of date. For | |
4795 * this reason, caution is needed when using any API function within an update | |
4796 * function - particularly CRUD functions, functions that depend on the schema | |
4797 * (for example by using drupal_write_record()), and any functions that invoke | |
4798 * hooks. | |
4799 * | |
4800 * Instead, a simplified utility function should be used. If a utility version | |
4801 * of the API function you require does not already exist, then you should | |
4802 * create a new function. The new utility function should be named | |
4803 * _update_N_mymodule_my_function(). N is the schema version the function acts | |
4804 * on (the schema version is the number N from the hook_update_N() | |
4805 * implementation where this schema was introduced, or a number following the | |
4806 * same numbering scheme), and mymodule_my_function is the name of the original | |
4807 * API function including the module's name. | |
4808 * | |
4809 * Examples: | |
4810 * - _update_6000_mymodule_save(): This function performs a save operation | |
4811 * without invoking any hooks using the 6.x schema. | |
4812 * - _update_7000_mymodule_save(): This function performs the same save | |
4813 * operation using the 7.x schema. | |
4814 * | |
4815 * The utility function should not invoke any hooks, and should perform database | |
4816 * operations using functions from the | |
4817 * @link database Database abstraction layer, @endlink | |
4818 * like db_insert(), db_update(), db_delete(), db_query(), and so on. | |
4819 * | |
4820 * If a change to the schema necessitates a change to the utility function, a | |
4821 * new function should be created with a name based on the version of the schema | |
4822 * it acts on. See _update_7000_bar_get_types() and _update_7001_bar_get_types() | |
4823 * in the code examples that follow. | |
4824 * | |
4825 * For example, foo.install could contain: | |
4826 * @code | |
4827 * function foo_update_dependencies() { | |
4828 * // foo_update_7010() needs to run after bar_update_7000(). | |
4829 * $dependencies['foo'][7010] = array( | |
4830 * 'bar' => 7000, | |
4831 * ); | |
4832 * | |
4833 * // foo_update_7036() needs to run after bar_update_7001(). | |
4834 * $dependencies['foo'][7036] = array( | |
4835 * 'bar' => 7001, | |
4836 * ); | |
4837 * | |
4838 * return $dependencies; | |
4839 * } | |
4840 * | |
4841 * function foo_update_7000() { | |
4842 * // No updates have been run on the {bar_types} table yet, so this needs | |
4843 * // to work with the 6.x schema. | |
4844 * foreach (_update_6000_bar_get_types() as $type) { | |
4845 * // Rename a variable. | |
4846 * } | |
4847 * } | |
4848 * | |
4849 * function foo_update_7010() { | |
4850 * // Since foo_update_7010() is going to run after bar_update_7000(), it | |
4851 * // needs to operate on the new schema, not the old one. | |
4852 * foreach (_update_7000_bar_get_types() as $type) { | |
4853 * // Rename a different variable. | |
4854 * } | |
4855 * } | |
4856 * | |
4857 * function foo_update_7036() { | |
4858 * // This update will run after bar_update_7001(). | |
4859 * foreach (_update_7001_bar_get_types() as $type) { | |
4860 * } | |
4861 * } | |
4862 * @endcode | |
4863 * | |
4864 * And bar.install could contain: | |
4865 * @code | |
4866 * function bar_update_7000() { | |
4867 * // Type and bundle are confusing, so we renamed the table. | |
4868 * db_rename_table('bar_types', 'bar_bundles'); | |
4869 * } | |
4870 * | |
4871 * function bar_update_7001() { | |
4872 * // Database table names should be singular when possible. | |
4873 * db_rename_table('bar_bundles', 'bar_bundle'); | |
4874 * } | |
4875 * | |
4876 * function _update_6000_bar_get_types() { | |
4877 * db_query('SELECT * FROM {bar_types}')->fetchAll(); | |
4878 * } | |
4879 * | |
4880 * function _update_7000_bar_get_types() { | |
4881 * db_query('SELECT * FROM {bar_bundles'})->fetchAll(); | |
4882 * } | |
4883 * | |
4884 * function _update_7001_bar_get_types() { | |
4885 * db_query('SELECT * FROM {bar_bundle}')->fetchAll(); | |
4886 * } | |
4887 * @endcode | |
4888 * | |
4889 * @see hook_update_N() | |
4890 * @see hook_update_dependencies() | |
4891 */ | |
4892 | |
4893 /** | |
4894 * @} End of "defgroup update_api". | |
4895 */ |