Newer
Older
Angie Byron
committed
<?php
/**
* @file
* Hooks provided by Drupal core and the System module.
*/
/**
* @addtogroup hooks
* @{
*/
/**
* Defines one or more hooks that are exposed by a module.
*
* Normally hooks do not need to be explicitly defined. However, by declaring a
* hook explicitly, a module may define a "group" for it. Modules that implement
* a hook may then place their implementation in either $module.module or in
* $module.$group.inc. If the hook is located in $module.$group.inc, then that
* file will be automatically loaded when needed.
* In general, hooks that are rarely invoked and/or are very large should be
* placed in a separate include file, while hooks that are very short or very
* frequently called should be left in the main module file so that they are
* always available.
*
* @return
* An associative array whose keys are hook names and whose values are an
* associative array containing:
* - group: A string defining the group to which the hook belongs. The module
* system will determine whether a file with the name $module.$group.inc
* exists, and automatically load it when required.
*
* See system_hook_info() for all hook groups defined by Drupal core.
*
* @see hook_hook_info_alter().
*/
function hook_hook_info() {
$hooks['token_info'] = array(
'group' => 'tokens',
);
$hooks['tokens'] = array(
'group' => 'tokens',
);
return $hooks;
}
/**
* Alter information from hook_hook_info().
*
* @param $hooks
* Information gathered by module_hook_info() from other modules'
* implementations of hook_hook_info(). Alter this array directly.
* See hook_hook_info() for information on what this may contain.
*/
function hook_hook_info_alter(&$hooks) {
// Our module wants to completely override the core tokens, so make
// sure the core token hooks are not found.
$hooks['token_info']['group'] = 'mytokens';
$hooks['tokens']['group'] = 'mytokens';
}
Dries Buytaert
committed
/**
* Inform the base system and the Field API about one or more entity types.
*
* Inform the system about one or more entity types (i.e., object types that
* can be loaded via entity_load() and, optionally, to which fields can be
* attached).
*
* @return
* An array whose keys are entity type names and whose values identify
* properties of those types that the system needs to know about:
* - label: The human-readable name of the type.
* - controller class: The name of the class that is used to load the objects.
Dries Buytaert
committed
* The class has to implement the DrupalEntityControllerInterface interface.
* Leave blank to use the DrupalDefaultEntityController implementation.
* - base table: (used by DrupalDefaultEntityController) The name of the
* entity type's base table.
Angie Byron
committed
* - revision table: The name of the entity type's revision table (if any).
* - static cache: (used by DrupalDefaultEntityController) FALSE to disable
Dries Buytaert
committed
* static caching of entities during a page request. Defaults to TRUE.
Dries Buytaert
committed
* - field cache: (used by Field API loading and saving of field data) FALSE
* to disable Field API's persistent cache of field data. Only recommended
* if a higher level persistent cache is available for the entity type.
* Defaults to TRUE.
* - load hook: The name of the hook which should be invoked by
* DrupalDefaultEntityController:attachLoad(), for example 'node_load'.
Angie Byron
committed
* - uri callback: A function taking an entity as argument and returning the
Jennifer Hodgdon
committed
* URI elements of the entity, e.g. 'path' and 'options'. The actual entity
* URI can be constructed by passing these elements to url().
Angie Byron
committed
* - label callback: (optional) A function taking an entity and an entity type
* as arguments and returning the label of the entity. The entity label is
* the main string associated with an entity; for example, the title of a
* node or the subject of a comment. If there is an entity object property
* that defines the label, use the 'label' element of the 'entity keys'
* return value component to provide this information (see below). If more
* complex logic is needed to determine the label of an entity, you can
* instead specify a callback function here, which will be called to
* determine the entity label. See also the entity_label() function, which
* implements this logic.
* - language callback: (optional) A function taking an entity and an entity
* type as arguments and returning a language code. In most situations, when
* needing to determine this value, inspecting a property named after the
* 'language' element of the 'entity keys' should be enough. The language
* callback is meant to be used primarily for temporary alterations of the
* property value: entity-defining modules are encouraged to always define a
* language property, instead of using the callback as main entity language
* source. In fact not having a language property defined is likely to
* prevent an entity from being queried by language. Moreover, given that
* entity_language() is not necessarily used everywhere it would be
* appropriate, modules implementing the language callback should be aware
* that this might not be always called.
Angie Byron
committed
* - fieldable: Set to TRUE if you want your entity type to accept fields
* being attached to it.
* - translation: An associative array of modules registered as field
* translation handlers. Array keys are the module names, array values
* can be any data structure the module uses to provide field translation.
* Any empty value disallows the module to appear as a translation handler.
* - entity keys: An array describing how the Field API can extract the
* information it needs from the objects of the type. Elements:
Dries Buytaert
committed
* - id: The name of the property that contains the primary id of the
Dries Buytaert
committed
* entity. Every entity object passed to the Field API must have this
* property and its value must be numeric.
Dries Buytaert
committed
* - revision: The name of the property that contains the revision id of
Dries Buytaert
committed
* the entity. The Field API assumes that all revision ids are unique
* across all entities of a type. This entry can be omitted if the
* entities of this type are not versionable.
Dries Buytaert
committed
* - bundle: The name of the property that contains the bundle name for the
Dries Buytaert
committed
* entity. The bundle name defines which set of fields are attached to
* the entity (e.g. what nodes call "content type"). This entry can be
* omitted if this entity type exposes a single bundle (all entities have
* the same collection of fields). The name of this single bundle will be
* the same as the entity type.
* - label: The name of the property that contains the entity label. For
Angie Byron
committed
* example, if the entity's label is located in $entity->subject, then
* 'subject' should be specified here. If complex logic is required to
* build the label, a 'label callback' should be defined instead (see
* the 'label callback' section above for details).
* - language: The name of the property, typically 'language', that contains
* the language code representing the language the entity has been created
* in. This value may be changed when editing the entity and represents
* the language its textual components are supposed to have. If no
* language property is available, the 'language callback' may be used
* instead. This entry can be omitted if the entities of this type are not
* language-aware.
Dries Buytaert
committed
* - bundle keys: An array describing how the Field API can extract the
* information it needs from the bundle objects for this type. This entry
* is required if the 'path' provided in the 'bundles'/'admin' section
* identifies the bundle using a named menu placeholder whose loader
* callback returns an object (e.g., $vocabulary for taxonomy terms, or
* $node_type for nodes). If the path does not include the bundle, or the
* bundle is just a string rather than an automatically loaded object, then
* this can be omitted. Elements:
* - bundle: The name of the property of the bundle object that contains
* the name of the bundle object.
Dries Buytaert
committed
* - bundles: An array describing all bundles for this object type. Keys are
* bundles machine names, as found in the objects' 'bundle' property
* (defined in the 'entity keys' entry above). Elements:
Dries Buytaert
committed
* - label: The human-readable name of the bundle.
Dries Buytaert
committed
* - uri callback: Same as the 'uri callback' key documented above for the
* entity type, but for the bundle only. When determining the URI of an
* entity, if a 'uri callback' is defined for both the entity type and
* the bundle, the one for the bundle is used.
Dries Buytaert
committed
* - admin: An array of information that allows Field UI pages to attach
* themselves to the existing administration pages for the bundle.
Angie Byron
committed
* Elements:
Dries Buytaert
committed
* - path: the path of the bundle's main administration page, as defined
* in hook_menu(). If the path includes a placeholder for the bundle,
* the 'bundle argument' and 'real path' keys below are required.
* - bundle argument: The position of the bundle placeholder in 'path', if
* any.
Dries Buytaert
committed
* - real path: The actual path (no placeholder) of the bundle's main
* administration page. This will be used to generate links.
* - access callback: As in hook_menu(). 'user_access' will be assumed if
* no value is provided.
* - access arguments: As in hook_menu().
* - view modes: An array describing the view modes for the entity type. View
* modes let entities be displayed differently depending on the context.
* For instance, a node can be displayed differently on its own page
* ('full' mode), on the home page or taxonomy listings ('teaser' mode), or
* in an RSS feed ('rss' mode). Modules taking part in the display of the
* entity (notably the Field API) can adjust their behavior depending on
Dries Buytaert
committed
* the requested view mode. An additional 'default' view mode is available
* for all entity types. This view mode is not intended for actual entity
* display, but holds default display settings. For each available view
* mode, administrators can configure whether it should use its own set of
* field display settings, or just replicate the settings of the 'default'
* view mode, thus reducing the amount of display configurations to keep
* track of. Keys of the array are view mode names. Each view mode is
* described by an array with the following key/value pairs:
* - label: The human-readable name of the view mode
Dries Buytaert
committed
* - custom settings: A boolean specifying whether the view mode should by
Dries Buytaert
committed
* default use its own custom field display settings. If FALSE, entities
* displayed in this view mode will reuse the 'default' display settings
* by default (e.g. right after the module exposing the view mode is
* enabled), but administrators can later use the Field UI to apply custom
* display settings specific to the view mode.
Dries Buytaert
committed
*
* @see entity_load()
* @see hook_entity_info_alter()
Dries Buytaert
committed
*/
function hook_entity_info() {
$return = array(
'node' => array(
'label' => t('Node'),
Dries Buytaert
committed
'controller class' => 'NodeController',
'base table' => 'node',
'revision table' => 'node_revision',
Dries Buytaert
committed
'uri callback' => 'node_uri',
Dries Buytaert
committed
'fieldable' => TRUE,
'translation' => array(
'locale' => TRUE,
),
'entity keys' => array(
'id' => 'nid',
'revision' => 'vid',
'bundle' => 'type',
'language' => 'language',
),
'bundle keys' => array(
'bundle' => 'type',
),
'bundles' => array(),
'view modes' => array(
'full' => array(
Dries Buytaert
committed
'label' => t('Full content'),
'custom settings' => FALSE,
),
'teaser' => array(
'label' => t('Teaser'),
Dries Buytaert
committed
'custom settings' => TRUE,
),
'rss' => array(
'label' => t('RSS'),
Dries Buytaert
committed
'custom settings' => FALSE,
),
),
Dries Buytaert
committed
),
);
// Search integration is provided by node.module, so search-related
// view modes for nodes are defined here and not in search.module.
if (module_exists('search')) {
$return['node']['view modes'] += array(
'search_index' => array(
'label' => t('Search index'),
Dries Buytaert
committed
'custom settings' => FALSE,
),
'search_result' => array(
'label' => t('Search result'),
Dries Buytaert
committed
'custom settings' => FALSE,
),
);
}
// Bundles must provide a human readable name so we can create help and error
// messages, and the path to attach Field admin pages to.
foreach (node_type_get_names() as $type => $name) {
$return['node']['bundles'][$type] = array(
'label' => $name,
'admin' => array(
'path' => 'admin/structure/types/manage/%node_type',
'real path' => 'admin/structure/types/manage/' . str_replace('_', '-', $type),
'bundle argument' => 4,
'access arguments' => array('administer content types'),
),
);
}
Dries Buytaert
committed
return $return;
}
/**
* Alter the entity info.
*
* Modules may implement this hook to alter the information that defines an
* entity. All properties that are available in hook_entity_info() can be
* altered here.
*
* @param $entity_info
* The entity info array, keyed by entity name.
Dries Buytaert
committed
*
* @see hook_entity_info()
Dries Buytaert
committed
*/
function hook_entity_info_alter(&$entity_info) {
// Set the controller class for nodes to an alternate implementation of the
// DrupalEntityController interface.
$entity_info['node']['controller class'] = 'MyCustomNodeController';
}
/**
* Act on entities when loaded.
*
* This is a generic load hook called for all entity types loaded via the
* entity API.
*
* @param $entities
* The entities keyed by entity ID.
* @param $type
* The type of entities being loaded (i.e. node, user, comment).
*/
function hook_entity_load($entities, $type) {
foreach ($entities as $entity) {
Dries Buytaert
committed
$entity->foo = mymodule_add_something($entity, $type);
/**
* Act on an entity before it is about to be created or updated.
*
* @param $entity
* The entity object.
* @param $type
* The type of entity being saved (i.e. node, user, comment).
*/
function hook_entity_presave($entity, $type) {
$entity->changed = REQUEST_TIME;
}
Angie Byron
committed
/**
* Act on entities when inserted.
*
* @param $entity
* The entity object.
* @param $type
* The type of entity being inserted (i.e. node, user, comment).
*/
function hook_entity_insert($entity, $type) {
Angie Byron
committed
// Insert the new entity into a fictional table of all entities.
$info = entity_get_info($type);
list($id) = entity_extract_ids($type, $entity);
Angie Byron
committed
db_insert('example_entity')
->fields(array(
'type' => $type,
'id' => $id,
'created' => REQUEST_TIME,
'updated' => REQUEST_TIME,
))
->execute();
Angie Byron
committed
}
/**
* Act on entities when updated.
*
* @param $entity
* The entity object.
* @param $type
* The type of entity being updated (i.e. node, user, comment).
*/
function hook_entity_update($entity, $type) {
Angie Byron
committed
// Update the entity's entry in a fictional table of all entities.
$info = entity_get_info($type);
list($id) = entity_extract_ids($type, $entity);
Angie Byron
committed
db_update('example_entity')
->fields(array(
'updated' => REQUEST_TIME,
))
->condition('type', $type)
->condition('id', $id)
->execute();
}
/**
* Act on entities when deleted.
*
* @param $entity
* The entity object.
* @param $type
* The type of entity being deleted (i.e. node, user, comment).
*/
function hook_entity_delete($entity, $type) {
// Delete the entity's entry from a fictional table of all entities.
$info = entity_get_info($type);
list($id) = entity_extract_ids($type, $entity);
Angie Byron
committed
db_delete('example_entity')
->condition('type', $type)
->condition('id', $id)
->execute();
Angie Byron
committed
}
/**
* Alter or execute an EntityFieldQuery.
*
* @param EntityFieldQuery $query
* An EntityFieldQuery. One of the most important properties to be changed is
* EntityFieldQuery::executeCallback. If this is set to an existing function,
* this function will get the query as its single argument and its result
* will be the returned as the result of EntityFieldQuery::execute(). This can
* be used to change the behavior of EntityFieldQuery entirely. For example,
* the default implementation can only deal with one field storage engine, but
* it is possible to write a module that can query across field storage
* engines. Also, the default implementation presumes entities are stored in
* SQL, but the execute callback could instead query any other entity storage,
* local or remote.
Angie Byron
committed
*
* Note the $query->altered attribute which is TRUE in case the query has
* already been altered once. This happens with cloned queries.
* If there is a pager, then such a cloned query will be executed to count
* all elements. This query can be detected by checking for
* ($query->pager && $query->count), allowing the driver to return 0 from
* the count query and disable the pager.
*/
function hook_entity_query_alter($query) {
$query->executeCallback = 'my_module_query_callback';
}
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
/**
* Act on entities being assembled before rendering.
*
* @param $entity
* The entity object.
* @param $type
* The type of entity being rendered (i.e. node, user, comment).
* @param $view_mode
* The view mode the entity is rendered in.
* @param $langcode
* The language code used for rendering.
*
* The module may add elements to $entity->content prior to rendering. The
* structure of $entity->content is a renderable array as expected by
* drupal_render().
*
* @see hook_entity_view_alter()
* @see hook_comment_view()
* @see hook_node_view()
* @see hook_user_view()
*/
function hook_entity_view($entity, $type, $view_mode, $langcode) {
$entity->content['my_additional_field'] = array(
'#markup' => $additional_field,
'#weight' => 10,
'#theme' => 'mymodule_my_additional_field',
);
}
/**
* Alter the results of ENTITY_view().
*
* This hook is called after the content has been assembled in a structured
* array and may be used for doing processing which requires that the complete
* entity content structure has been built.
*
* If a module wishes to act on the rendered HTML of the entity rather than the
* structured content array, it may use this hook to add a #post_render
* callback. Alternatively, it could also implement hook_preprocess_ENTITY().
* See drupal_render() and theme() for details.
*
* @param $build
* A renderable array representing the entity content.
* @param $type
* The type of entity being rendered (i.e. node, user, comment).
*
* @see hook_entity_view()
* @see hook_comment_view_alter()
* @see hook_node_view_alter()
* @see hook_taxonomy_term_view_alter()
* @see hook_user_view_alter()
*/
function hook_entity_view_alter(&$build, $type) {
if ($build['#view_mode'] == 'full' && isset($build['an_additional_field'])) {
// Change its weight.
$build['an_additional_field']['#weight'] = -10;
// Add a #post_render callback to act on the rendered HTML of the entity.
$build['#post_render'][] = 'my_module_node_post_render';
}
}
Angie Byron
committed
/**
* Change the view mode of an entity that is being displayed.
*
* @param string $view_mode
* The view_mode that is to be used to display the entity.
* @param array $context
* Array with contextual information, including:
* - entity_type: The type of the entity that is being viewed.
* - entity: The entity object.
* - langcode: The langcode the entity is being viewed in.
*/
function hook_entity_view_mode_alter(&$view_mode, $context) {
// For nodes, change the view mode when it is teaser.
if ($context['entity_type'] == 'node' && $view_mode == 'teaser') {
$view_mode = 'my_custom_view_mode';
}
}
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
/**
* Define administrative paths.
*
* Modules may specify whether or not the paths they define in hook_menu() are
* to be considered administrative. Other modules may use this information to
* display those pages differently (e.g. in a modal overlay, or in a different
* theme).
*
* To change the administrative status of menu items defined in another module's
* hook_menu(), modules should implement hook_admin_paths_alter().
*
* @return
* An associative array. For each item, the key is the path in question, in
* a format acceptable to drupal_match_path(). The value for each item should
* be TRUE (for paths considered administrative) or FALSE (for non-
* administrative paths).
*
* @see hook_menu()
* @see drupal_match_path()
* @see hook_admin_paths_alter()
*/
function hook_admin_paths() {
$paths = array(
'mymodule/*/add' => TRUE,
'mymodule/*/edit' => TRUE,
);
return $paths;
}
/**
* Redefine administrative paths defined by other modules.
*
* @param $paths
* An associative array of administrative paths, as defined by implementations
* of hook_admin_paths().
*
* @see hook_admin_paths()
*/
function hook_admin_paths_alter(&$paths) {
// Treat all user pages as administrative.
$paths['user'] = TRUE;
$paths['user/*'] = TRUE;
// Treat the forum topic node form as a non-administrative page.
$paths['node/add/forum'] = FALSE;
}
Angie Byron
committed
/**
* Act on entities as they are being prepared for view.
*
* Allows you to operate on multiple entities as they are being prepared for
* view. Only use this if attaching the data during the entity_load() phase
* is not appropriate, for example when attaching other 'entity' style objects.
*
* @param $entities
* The entities keyed by entity ID.
* @param $type
* The type of entities being loaded (i.e. node, user, comment).
Angie Byron
committed
* @param $langcode
* The language to display the entity in.
Angie Byron
committed
*/
Angie Byron
committed
function hook_entity_prepare_view($entities, $type, $langcode) {
Angie Byron
committed
// Load a specific node into the user object for later theming.
if ($type == 'user') {
$nodes = mymodule_get_user_nodes(array_keys($entities));
foreach ($entities as $uid => $entity) {
$entity->user_node = $nodes[$uid];
}
}
}
Angie Byron
committed
/**
* Perform periodic actions.
*
* Modules that require some commands to be executed periodically can
* implement hook_cron(). The engine will then call the hook whenever a cron
* run happens, as defined by the administrator. Typical tasks managed by
* hook_cron() are database maintenance, backups, recalculation of settings
* or parameters, automated mailing, and retrieving remote data.
Angie Byron
committed
*
* Short-running or non-resource-intensive tasks can be executed directly in
* the hook_cron() implementation.
* Long-running tasks and tasks that could time out, such as retrieving remote
* data, sending email, and intensive file tasks, should use the queue API
* instead of executing the tasks directly. To do this, first define one or
* more queues via hook_cron_queue_info(). Then, add items that need to be
* processed to the defined queues.
Angie Byron
committed
*/
function hook_cron() {
// Short-running operation example, not using a queue:
// Delete all expired records since the last cron run.
$expires = variable_get('mymodule_cron_last_run', REQUEST_TIME);
db_delete('mymodule_table')
->condition('expires', $expires, '>=')
->execute();
variable_set('mymodule_cron_last_run', REQUEST_TIME);
Angie Byron
committed
// Long-running operation example, leveraging a queue:
// Fetch feeds from other sites.
Angie Byron
committed
$result = db_query('SELECT * FROM {aggregator_feed} WHERE checked + refresh < :time AND refresh <> :never', array(
':time' => REQUEST_TIME,
':never' => AGGREGATOR_CLEAR_NEVER,
));
$queue = DrupalQueue::get('aggregator_feeds');
foreach ($result as $feed) {
$queue->createItem($feed);
Angie Byron
committed
}
}
Dries Buytaert
committed
/**
* Declare queues holding items that need to be run periodically.
*
* While there can be only one hook_cron() process running at the same time,
* there can be any number of processes defined here running. Because of
* this, long running tasks are much better suited for this API. Items queued
* in hook_cron() might be processed in the same cron run if there are not many
* items in the queue, otherwise it might take several requests, which can be
* run in parallel.
Dries Buytaert
committed
*
* @return
* An associative array where the key is the queue name and the value is
* again an associative array. Possible keys are:
* - 'worker callback': The name of the function to call. It will be called
* with one argument, the item created via DrupalQueue::createItem() in
* hook_cron().
* - 'time': (optional) How much time Drupal should spend on calling this
* worker in seconds. Defaults to 15.
*
* @see hook_cron()
Dries Buytaert
committed
* @see hook_cron_queue_info_alter()
Dries Buytaert
committed
*/
function hook_cron_queue_info() {
$queues['aggregator_feeds'] = array(
'worker callback' => 'aggregator_refresh',
Dries Buytaert
committed
'time' => 60,
Dries Buytaert
committed
);
return $queues;
}
Dries Buytaert
committed
/**
* Alter cron queue information before cron runs.
*
Dries Buytaert
committed
* Called by drupal_cron_run() to allow modules to alter cron queue settings
Dries Buytaert
committed
* before any jobs are processesed.
*
* @param array $queues
* An array of cron queue information.
*
* @see hook_cron_queue_info()
* @see drupal_cron_run()
Dries Buytaert
committed
*/
function hook_cron_queue_info_alter(&$queues) {
// This site has many feeds so let's spend 90 seconds on each cron run
// updating feeds instead of the default 60.
$queues['aggregator_feeds']['time'] = 90;
}
Angie Byron
committed
/**
Jennifer Hodgdon
committed
* Allows modules to declare their own Form API element types and specify their
Angie Byron
committed
* default values.
*
* This hook allows modules to declare their own form element types and to
* specify their default values. The values returned by this hook will be
* merged with the elements returned by hook_form() implementations and so
* can return defaults for any Form APIs keys in addition to those explicitly
* mentioned below.
*
* Each of the form element types defined by this hook is assumed to have
* a matching theme function, e.g. theme_elementtype(), which should be
* registered with hook_theme() as normal.
*
* For more information about custom element types see the explanation at
Angie Byron
committed
* http://drupal.org/node/169815.
*
* @return
* An associative array describing the element types being defined. The array
* contains a sub-array for each element type, with the machine-readable type
* name as the key. Each sub-array has a number of possible attributes:
* - "#input": boolean indicating whether or not this element carries a value
* (even if it's hidden).
Dries Buytaert
committed
* - "#process": array of callback functions taking $element, $form_state,
* and $complete_form.
Angie Byron
committed
* - "#after_build": array of callback functions taking $element and $form_state.
* - "#validate": array of callback functions taking $form and $form_state.
* - "#element_validate": array of callback functions taking $element and
* $form_state.
* - "#pre_render": array of callback functions taking $element and $form_state.
* - "#post_render": array of callback functions taking $element and $form_state.
* - "#submit": array of callback functions taking $form and $form_state.
Dries Buytaert
committed
* - "#title_display": optional string indicating if and how #title should be
* displayed, see theme_form_element() and theme_form_element_label().
Dries Buytaert
committed
*
* @see hook_element_info_alter()
* @see system_element_info()
Angie Byron
committed
*/
Dries Buytaert
committed
function hook_element_info() {
$types['filter_format'] = array(
'#input' => TRUE,
);
return $types;
Angie Byron
committed
}
Angie Byron
committed
/**
* Alter the element type information returned from modules.
*
* A module may implement this hook in order to alter the element type defaults
* defined by a module.
*
Dries Buytaert
committed
* @param $type
Dries Buytaert
committed
* All element type defaults as collected by hook_element_info().
Angie Byron
committed
*
Dries Buytaert
committed
* @see hook_element_info()
Angie Byron
committed
*/
function hook_element_info_alter(&$type) {
// Decrease the default size of textfields.
if (isset($type['textfield']['#size'])) {
$type['textfield']['#size'] = 40;
}
}
Angie Byron
committed
/**
* Perform cleanup tasks.
*
* This hook is run at the end of each page request. It is often used for
* page logging and specialized cleanup. This hook MUST NOT print anything
* because by the time it runs the response is already sent to the browser.
Angie Byron
committed
*
* Only use this hook if your code must run even for cached page views.
Dries Buytaert
committed
* If you have code which must run once on all non-cached pages, use
* hook_init() instead. That is the usual case. If you implement this hook
Angie Byron
committed
* and see an error like 'Call to undefined function', it is likely that
* you are depending on the presence of a module which has not been loaded yet.
* It is not loaded because Drupal is still in bootstrap mode.
*
* @param $destination
* If this hook is invoked as part of a drupal_goto() call, then this argument
* will be a fully-qualified URL that is the destination of the redirect.
*/
function hook_exit($destination = NULL) {
Dries Buytaert
committed
db_update('counter')
->expression('hits', 'hits + 1')
->condition('type', 1)
->execute();
Angie Byron
committed
}
/**
* Perform necessary alterations to the JavaScript before it is presented on
* the page.
*
* @param $javascript
* An array of all JavaScript being presented on the page.
Dries Buytaert
committed
*
Angie Byron
committed
* @see drupal_add_js()
* @see drupal_get_js()
* @see drupal_js_defaults()
*/
function hook_js_alter(&$javascript) {
// Swap out jQuery to use an updated version of the library.
$javascript['misc/jquery.js']['data'] = drupal_get_path('module', 'jquery_update') . '/jquery.js';
}
Angie Byron
committed
/**
* Registers JavaScript/CSS libraries associated with a module.
*
* Modules implementing this return an array of arrays. The key to each
* sub-array is the machine readable name of the library. Each library may
* contain the following items:
*
* - 'title': The human readable name of the library.
* - 'website': The URL of the library's web site.
* - 'version': A string specifying the version of the library; intentionally
* not a float because a version like "1.2.3" is not a valid float. Use PHP's
* version_compare() to compare different versions.
* - 'js': An array of JavaScript elements; each element's key is used as $data
* argument, each element's value is used as $options array for
* drupal_add_js(). To add library-specific (not module-specific) JavaScript
* settings, the key may be skipped, the value must specify
* 'type' => 'setting', and the actual settings must be contained in a 'data'
* element of the value.
* - 'css': Like 'js', an array of CSS elements passed to drupal_add_css().
* - 'dependencies': An array of libraries that are required for a library. Each
* element is an array listing the module and name of another library. Note
* that all dependencies for each dependent library will also be added when
* this library is added.
Angie Byron
committed
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
*
* Registered information for a library should contain re-usable data only.
* Module- or implementation-specific data and integration logic should be added
* separately.
*
* @return
* An array defining libraries associated with a module.
*
* @see system_library()
* @see drupal_add_library()
* @see drupal_get_library()
*/
function hook_library() {
// Library One.
$libraries['library-1'] = array(
'title' => 'Library One',
'website' => 'http://example.com/library-1',
'version' => '1.2',
'js' => array(
drupal_get_path('module', 'my_module') . '/library-1.js' => array(),
),
'css' => array(
drupal_get_path('module', 'my_module') . '/library-2.css' => array(
'type' => 'file',
'media' => 'screen',
),
),
);
// Library Two.
$libraries['library-2'] = array(
'title' => 'Library Two',
'website' => 'http://example.com/library-2',
'version' => '3.1-beta1',
'js' => array(
// JavaScript settings may use the 'data' key.
array(
'type' => 'setting',
'data' => array('library2' => TRUE),
),
),
'dependencies' => array(
// Require jQuery UI core by System module.
array('system', 'ui'),
Angie Byron
committed
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
// Require our other library.
array('my_module', 'library-1'),
// Require another library.
array('other_module', 'library-3'),
),
);
return $libraries;
}
/**
* Alters the JavaScript/CSS library registry.
*
* Allows certain, contributed modules to update libraries to newer versions
* while ensuring backwards compatibility. In general, such manipulations should
* only be done by designated modules, since most modules that integrate with a
* certain library also depend on the API of a certain library version.
*
* @param $libraries
* The JavaScript/CSS libraries provided by $module. Keyed by internal library
* name and passed by reference.
* @param $module
* The name of the module that registered the libraries.
*
* @see hook_library()
*/
function hook_library_alter(&$libraries, $module) {
// Update Farbtastic to version 2.0.
if ($module == 'system' && isset($libraries['farbtastic'])) {
// Verify existing version is older than the one we are updating to.
if (version_compare($libraries['farbtastic']['version'], '2.0', '<')) {
// Update the existing Farbtastic to version 2.0.
$libraries['farbtastic']['version'] = '2.0';
$libraries['farbtastic']['js'] = array(
drupal_get_path('module', 'farbtastic_update') . '/farbtastic-2.0.js' => array(),
);
}
}
}
Dries Buytaert
committed
/**
* Alter CSS files before they are output on the page.
*
* @param $css
* An array of all CSS items (files and inline CSS) being requested on the page.
Dries Buytaert
committed
*
Dries Buytaert
committed
* @see drupal_add_css()
* @see drupal_get_css()
*/
function hook_css_alter(&$css) {
// Remove defaults.css file.
unset($css[drupal_get_path('module', 'system') . '/defaults.css']);
}
* Alter the commands that are sent to the user through the Ajax framework.
*
* @param $commands
* An array of all commands that will be sent to the user.
Dries Buytaert
committed
*
* @see ajax_render()
*/
function hook_ajax_render_alter($commands) {
// Inject any new status messages into the content area.
$commands[] = ajax_command_prepend('#block-system-main .content', theme('status_messages'));
}
Angie Byron
committed
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
/**
* Add elements to a page before it is rendered.
*
* Use this hook when you want to add elements at the page level. For your
* additions to be printed, they have to be placed below a top level array key
* of the $page array that has the name of a region of the active theme.
*
* By default, valid region keys are 'page_top', 'header', 'sidebar_first',
* 'content', 'sidebar_second' and 'page_bottom'. To get a list of all regions
* of the active theme, use system_region_list($theme). Note that $theme is a
* global variable.
*
* If you want to alter the elements added by other modules or if your module
* depends on the elements of other modules, use hook_page_alter() instead which
* runs after this hook.
*
* @param $page
* Nested array of renderable elements that make up the page.
*
* @see hook_page_alter()
* @see drupal_render_page()
*/
function hook_page_build(&$page) {
if (menu_get_object('node', 1)) {
// We are on a node detail page. Append a standard disclaimer to the
// content region.
$page['content']['disclaimer'] = array(
'#markup' => t('Acme, Inc. is not responsible for the contents of this sample code.'),
'#weight' => 25,
);
}
}
Angie Byron
committed
/**
* Alter a menu router item right after it has been retrieved from the database or cache.
*
* This hook is invoked by menu_get_item() and allows for run-time alteration of router
* information (page_callback, title, and so on) before it is translated and checked for
Dries Buytaert
committed
* access. The passed-in $router_item is statically cached for the current request, so this
Angie Byron
committed
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
* hook is only invoked once for any router item that is retrieved via menu_get_item().
*
* Usually, modules will only want to inspect the router item and conditionally
* perform other actions (such as preparing a state for the current request).
* Note that this hook is invoked for any router item that is retrieved by
* menu_get_item(), which may or may not be called on the path itself, so implementations
* should check the $path parameter if the alteration should fire for the current request
* only.
*
* @param $router_item
* The menu router item for $path.
* @param $path
* The originally passed path, for which $router_item is responsible.
* @param $original_map
* The path argument map, as contained in $path.
*
* @see menu_get_item()
*/
function hook_menu_get_item_alter(&$router_item, $path, $original_map) {
// When retrieving the router item for the current path...
if ($path == $_GET['q']) {
// ...call a function that prepares something for this request.
mymodule_prepare_something();
}
}
Angie Byron
committed
/**
* Define menu items and page callbacks.
*
* This hook enables modules to register paths in order to define how URL
* requests are handled. Paths may be registered for URL handling only, or they
* can register a link to be placed in a menu (usually the Navigation menu). A
* path and its associated information is commonly called a "menu router item".
* This hook is rarely called (for example, when modules are enabled), and
* its results are cached in the database.
*
* hook_menu() implementations return an associative array whose keys define
* paths and whose values are an associative array of properties for each
* path. (The complete list of properties is in the return value section below.)
*
* The definition for each path may include a page callback function, which is
* invoked when the registered path is requested. If there is no other
* registered path that fits the requested path better, any further path
* components are passed to the callback function. For example, your module
* could register path 'abc/def':
* @code
* function mymodule_menu() {
* $items['abc/def'] = array(
* 'page callback' => 'mymodule_abc_view',
* );
* return $items;
Angie Byron
committed
* }
*
* function mymodule_abc_view($ghi = 0, $jkl = '') {
* // ...
* }
* @endcode
* When path 'abc/def' is requested, no further path components are in the
* request, and no additional arguments are passed to the callback function (so
* $ghi and $jkl would take the default values as defined in the function
* signature). When 'abc/def/123/foo' is requested, $ghi will be '123' and
* $jkl will be 'foo'. Note that this automatic passing of optional path
* arguments applies only to page and theme callback functions.
*
* In addition to optional path arguments, the page callback and other callback
* functions may specify argument lists as arrays. These argument lists may
* contain both fixed/hard-coded argument values and integers that correspond
* to path components. When integers are used and the callback function is
* called, the corresponding path components will be substituted for the
* integers. That is, the integer 0 in an argument list will be replaced with
* the first path component, integer 1 with the second, and so on (path
Angie Byron
committed
* components are numbered starting from zero). To pass an integer without it
* being replaced with its respective path component, use the string value of
* the integer (e.g., '1') as the argument value. This substitution feature
* allows you to re-use a callback function for several different paths. For
* example:
Angie Byron
committed
* @code
* function mymodule_menu() {
* $items['abc/def'] = array(
* 'page callback' => 'mymodule_abc_view',
* 'page arguments' => array(1, 'foo'),
* );
* return $items;