2008-11-25 02:37:33 +00:00
< ? php
// $Id$
/**
* @ file
* Hooks provided by Drupal core and the System module .
*/
/**
* @ addtogroup hooks
* @ {
*/
2009-10-16 03:01:55 +00:00
/**
* 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 .
2010-04-29 04:47:31 +00:00
*
* @ see hook_hook_info_alter () .
2009-10-16 03:01:55 +00:00
*/
function hook_hook_info () {
$hooks [ 'token_info' ] = array (
'group' => 'tokens' ,
);
$hooks [ 'tokens' ] = array (
'group' => 'tokens' ,
);
return $hooks ;
}
2010-04-29 04:47:31 +00:00
/**
* 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' ;
}
2009-08-25 21:53:48 +00:00
/**
* 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
2009-12-26 16:50:09 +00:00
* properties of those types that the system needs to know about :
2009-12-29 20:23:10 +00:00
* - label : The human - readable name of the type .
2009-11-05 03:04:24 +00:00
* - controller class : The name of the class that is used to load the objects .
2009-12-17 08:00:59 +00:00
* The class has to implement the DrupalEntityControllerInterface interface .
2009-12-29 20:23:10 +00:00
* Leave blank to use the DrupalDefaultEntityController implementation .
* - base table : ( used by DrupalDefaultEntityController ) The name of the
2009-11-05 03:04:24 +00:00
* entity type ' s base table .
2009-12-29 20:23:10 +00:00
* - static cache : ( used by DrupalDefaultEntityController ) FALSE to disable
2009-08-25 21:53:48 +00:00
* static caching of entities during a page request . Defaults to TRUE .
2010-03-27 18:41:14 +00:00
* - 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 .
2009-11-05 03:04:24 +00:00
* - load hook : The name of the hook which should be invoked by
* DrupalDefaultEntityController : attachLoad (), for example 'node_load' .
2010-02-11 15:52:13 +00:00
* - uri callback : A function taking an entity as argument and returning the
* uri elements of the entity , e . g . 'path' and 'options' . The actual entity
* uri can be constructed by passing these elements to url () .
2009-11-05 03:04:24 +00:00
* - fieldable : Set to TRUE if you want your entity type to be fieldable .
2010-03-27 05:52:50 +00:00
* - entity keys : An array describing how the Field API can extract the
2009-11-05 03:04:24 +00:00
* information it needs from the objects of the type . Elements :
2009-08-25 21:53:48 +00:00
* - id : The name of the property that contains the primary id of the
2010-04-04 12:48:18 +00:00
* entity . Every entity object passed to the Field API must have this
* property and its value must be numeric .
2009-08-25 21:53:48 +00:00
* - revision : The name of the property that contains the revision id of
2010-04-04 12:48:18 +00:00
* 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 .
2009-08-25 21:53:48 +00:00
* - bundle : The name of the property that contains the bundle name for the
2010-04-04 12:48:18 +00:00
* 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
2010-04-26 13:09:15 +00:00
* the same collection of fields ) . The name of this single bundle will be
* the same as the entity type .
2009-08-25 21:53:48 +00:00
* - bundle keys : An array describing how the Field API can extract the
* information it needs from the bundle objects for this type ( e . g
2010-04-04 12:48:18 +00:00
* $vocabulary objects for terms ; not applicable for nodes ) . This entry can
* be omitted if this type ' s bundles do not exist as standalone objects .
* Elements :
2009-08-25 21:53:48 +00:00
* - bundle : The name of the property that contains the name of the bundle
* object .
2010-04-04 12:48:18 +00:00
* - 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 :
2009-08-25 21:53:48 +00:00
* - label : The human - readable name of the bundle .
2010-04-06 19:49:03 +00:00
* - 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 .
2010-01-30 07:59:26 +00:00
* - admin : An array of information that allows Field UI pages to attach
* themselves to the existing administration pages for the bundle .
2010-01-29 00:42:29 +00:00
* Elements :
2009-08-25 21:53:48 +00:00
* - 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' , 'bundle helper' and 'real path' keys below
* are required .
* - bundle argument : The position of the placeholder in 'path' , if any .
* - 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 () .
2009-12-26 16:50:09 +00:00
* - 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
2010-05-23 19:10:23 +00:00
* 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 :
2009-12-26 16:50:09 +00:00
* - label : The human - readable name of the view mode
2010-05-23 19:10:23 +00:00
* - custom settings : A boolean specifying whether the view mode should by
* 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 .
2010-06-29 00:23:57 +00:00
*
* @ see entity_load ()
* @ see hook_entity_info_alter ()
2009-08-25 21:53:48 +00:00
*/
function hook_entity_info () {
$return = array (
'node' => array (
2009-12-29 20:23:10 +00:00
'label' => t ( 'Node' ),
2009-08-25 21:53:48 +00:00
'controller class' => 'NodeController' ,
'base table' => 'node' ,
2009-12-29 20:23:10 +00:00
'revision table' => 'node_revision' ,
2010-05-23 19:10:23 +00:00
'uri callback' => 'node_uri' ,
2009-08-25 21:53:48 +00:00
'fieldable' => TRUE ,
2010-03-27 05:52:50 +00:00
'entity keys' => array (
2009-12-29 20:23:10 +00:00
'id' => 'nid' ,
'revision' => 'vid' ,
'bundle' => 'type' ,
),
'bundle keys' => array (
'bundle' => 'type' ,
),
'bundles' => array (),
'view modes' => array (
'full' => array (
2010-05-23 19:10:23 +00:00
'label' => t ( 'Full content' ),
'custom settings' => FALSE ,
2009-12-29 20:23:10 +00:00
),
'teaser' => array (
'label' => t ( 'Teaser' ),
2010-05-23 19:10:23 +00:00
'custom settings' => TRUE ,
2009-12-29 20:23:10 +00:00
),
'rss' => array (
'label' => t ( 'RSS' ),
2010-05-23 19:10:23 +00:00
'custom settings' => FALSE ,
2009-12-29 20:23:10 +00:00
),
),
2009-08-25 21:53:48 +00:00
),
);
2009-12-29 20:23:10 +00:00
// 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' ),
2010-05-23 19:10:23 +00:00
'custom settings' => FALSE ,
2009-12-29 20:23:10 +00:00
),
'search_result' => array (
'label' => t ( 'Search result' ),
2010-05-23 19:10:23 +00:00
'custom settings' => FALSE ,
2009-12-29 20:23:10 +00:00
),
);
}
// 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' ),
),
);
}
2009-08-25 21:53:48 +00:00
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 .
2010-06-29 00:23:57 +00:00
*
* @ see hook_entity_info ()
2009-08-25 21:53:48 +00:00
*/
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' ;
}
2009-10-16 03:47:14 +00:00
/**
* 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 ) {
2009-12-31 13:22:35 +00:00
$entity -> foo = mymodule_add_something ( $entity , $type );
2009-10-16 03:47:14 +00:00
}
}
2010-01-30 02:01:41 +00:00
/**
* 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 ) {
}
/**
* 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 ) {
}
2010-06-14 15:41:03 +00:00
/**
* 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 .
*/
function hook_entity_query_alter ( $query ) {
$query -> executeCallback = 'my_module_query_callback' ;
}
#610234 by Gábor Hojtsy, ksenzee, cwgordon7, David_Rothstein, seutje, marcvangend, sun, JoshuaRogers, markus_petrux, Bojhan, Rob Loach, Everett Zufelt, drifter, markboulton, leisareichelt, et al: Added Overlay module to core, which shows administrative pages in a JS overlay, retaining context on the front-end site.
2009-12-02 07:28:22 +00:00
/**
* 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 ;
}
2010-01-13 05:00:25 +00:00
/**
* 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 ) .
*/
function hook_entity_prepare_view ( $entities , $type ) {
// 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 ];
}
}
}
2008-11-25 02:37:33 +00:00
/**
* Perform periodic actions .
*
2009-09-25 23:48:24 +00:00
* This hook will only be called if cron . php is run ( e . g . by crontab ) .
*
2008-11-25 02:37:33 +00:00
* Modules that require to schedule some commands to be executed at regular
* intervals can implement hook_cron () . The engine will then call the hook
* at the appropriate intervals defined by the administrator . This interface
* is particularly handy to implement timers or to automate certain tasks .
2009-09-25 15:20:12 +00:00
* Database maintenance , recalculation of settings or parameters are good
* candidates for cron tasks .
2008-11-25 02:37:33 +00:00
*
2009-09-25 23:48:24 +00:00
* Short - running or not resource intensive tasks can be executed directly .
*
* Long - running tasks should use the queue API . To do this , one or more queues
* need to be defined via hook_cron_queue_info () . Items that need to be
* processed are appended to the defined queue , instead of processing them
* directly in hook_cron () .
* Examples of jobs that are good candidates for
* hook_cron_queue_info () include automated mailing , retrieving remote data , and
* intensive file tasks .
*
* @ return
* None .
*
* @ see hook_cron_queue_info ()
2008-11-25 02:37:33 +00:00
*/
function hook_cron () {
2009-09-25 23:48:24 +00:00
// 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 );
2008-11-25 02:37:33 +00:00
2009-09-25 23:48:24 +00:00
// Long-running operation example, leveraging a queue:
// Fetch feeds from other sites.
$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 );
2008-11-25 02:37:33 +00:00
}
}
2009-09-25 15:20:12 +00:00
/**
* 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
2009-09-25 23:48:24 +00:00
* 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 .
2009-09-25 15:20:12 +00:00
*
* @ return
* An associative array where the key is the queue name and the value is
* again an associative array . Possible keys are :
2009-09-25 23:48:24 +00:00
* - '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 ()
2010-02-27 10:51:25 +00:00
* @ see hook_cron_queue_info_alter ()
2009-09-25 15:20:12 +00:00
*/
function hook_cron_queue_info () {
$queues [ 'aggregator_feeds' ] = array (
'worker callback' => 'aggregator_refresh' ,
2010-02-27 10:51:25 +00:00
'time' => 60 ,
2009-09-25 15:20:12 +00:00
);
return $queues ;
}
2010-02-27 10:51:25 +00:00
/**
* Alter cron queue information before cron runs .
*
2010-04-26 14:33:54 +00:00
* Called by drupal_cron_run () to allow modules to alter cron queue settings
2010-02-27 10:51:25 +00:00
* before any jobs are processesed .
*
* @ param array $queues
* An array of cron queue information .
*
2010-04-27 09:59:00 +00:00
* @ see hook_cron_queue_info ()
* @ see drupal_cron_run ()
2010-02-27 10:51:25 +00:00
*/
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 ;
}
2008-11-25 02:37:33 +00:00
/**
* Allows modules to declare their own Forms API element types and specify their
* 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 .
*
* Form more information about custom element types see the explanation at
* 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 ) .
2009-10-01 13:16:17 +00:00
* - " #process " : array of callback functions taking $element , $form_state ,
* and $complete_form .
2008-11-25 02:37:33 +00:00
* - " #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 .
2009-12-02 15:09:16 +00:00
* - " #title_display " : optional string indicating if and how #title should be
* displayed , see theme_form_element () and theme_form_element_label () .
2009-09-10 06:31:39 +00:00
*
* @ see hook_element_info_alter ()
* @ see system_element_info ()
2008-11-25 02:37:33 +00:00
*/
2009-09-10 06:31:39 +00:00
function hook_element_info () {
$types [ 'filter_format' ] = array (
'#input' => TRUE ,
);
return $types ;
2008-11-25 02:37:33 +00:00
}
2009-07-23 21:20:16 +00:00
/**
* 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 .
*
* @ param & $type
2009-09-10 06:31:39 +00:00
* All element type defaults as collected by hook_element_info () .
2009-07-23 21:20:16 +00:00
*
2009-09-10 06:31:39 +00:00
* @ see hook_element_info ()
2009-07-23 21:20:16 +00:00
*/
function hook_element_info_alter ( & $type ) {
// Decrease the default size of textfields.
if ( isset ( $type [ 'textfield' ][ '#size' ])) {
$type [ 'textfield' ][ '#size' ] = 40 ;
}
}
2008-11-25 02:37:33 +00:00
/**
* Perform cleanup tasks .
*
* This hook is run at the end of each page request . It is often used for
2009-10-13 21:16:44 +00:00
* page logging and specialized cleanup . This hook MUST NOT print anything .
2008-11-25 02:37:33 +00:00
*
* Only use this hook if your code must run even for cached page views .
* If you have code which must run once on all non cached pages , use
* hook_init instead . Thats the usual case . If you implement this hook
* 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 ) {
2009-05-16 18:34:23 +00:00
db_update ( 'counter' )
-> expression ( 'hits' , 'hits + 1' )
-> condition ( 'type' , 1 )
-> execute ();
2008-11-25 02:37:33 +00:00
}
/**
* 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 .
2010-03-26 17:14:46 +00:00
*
2008-11-25 02:37:33 +00:00
* @ 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' ;
}
2009-07-04 18:26:42 +00:00
/**
* 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
2010-05-04 14:52:02 +00:00
* 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 .
2009-07-04 18:26:42 +00:00
*
* 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.
2010-05-04 14:52:02 +00:00
array ( 'system' , 'ui' ),
2009-07-04 18:26:42 +00:00
// 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 (),
);
}
}
}
2009-07-30 19:57:10 +00:00
/**
* 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 .
2010-03-26 17:14:46 +00:00
*
2009-07-30 19:57:10 +00:00
* @ 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' ]);
}
2010-02-15 22:11:21 +00:00
/**
* 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 .
2010-03-26 17:14:46 +00:00
*
2010-02-15 22:11:21 +00:00
* @ 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' ));
}
2009-08-31 16:46:32 +00:00
/**
* 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 ,
);
}
}
2010-04-28 05:08:24 +00:00
/**
* 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' ,
* );
* }
*
* 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
* components are numbered starting from zero ) . This substitution feature allows
* you to re - use a callback function for several different paths . For example :
* @ code
* function mymodule_menu () {
* $items [ 'abc/def' ] = array (
* 'page callback' => 'mymodule_abc_view' ,
* 'page arguments' => array ( 1 , 'foo' ),
* );
* }
* @ endcode
* When path 'abc/def' is requested , the page callback function will get 'def'
* as the first argument and ( always ) 'foo' as the second argument .
*
* Note that if a page or theme callback function has an argument list array ,
* these arguments will be passed first to the function , followed by any
* any arguments generated by optional path arguments as described above .
*
* Special care should be taken for the page callback drupal_get_form (), because
* your specific form callback function will always receive $form and
* & $form_state as the first function arguments :
* @ code
* function mymodule_abc_form ( $form , & $form_state ) {
* // ...
* return $form ;
* }
* @ endcode
* See @ link form_api Form API documentation @ endlink for details .
*
* Wildcards within paths also work with integer substitution . For example ,
* your module could register path 'my-module/%/edit' :
* @ code
* $items [ 'my-module/%/edit' ] = array (
* 'page callback' => 'mymodule_abc_edit' ,
* 'page arguments' => array ( 1 ),
* );
* @ endcode
* When path 'my-module/foo/edit' is requested , integer 1 will be replaced
* with 'foo' and passed to the callback function .
*
* Registered paths may also contain special " auto-loader " wildcard components
* in the form of '%mymodule_abc' , where the '%' part means that this path
* component is a wildcard , and the 'mymodule_abc' part defines the prefix for a
* load function , which here would be named mymodule_abc_load () . When a matching
* path is requested , your load function will receive as its first argument the
* path component in the position of the wildcard ; load functions may also be
* passed additional arguments ( see " load arguments " in the return value
* section below ) . For example , your module could register path
* 'my-module/%mymodule_abc/edit' :
* @ code
* $items [ 'my-module/%mymodule_abc/edit' ] = array (
* 'page callback' => 'mymodule_abc_edit' ,
* 'page arguments' => array ( 1 ),
* );
* @ endcode
* When path 'my-module/123/edit' is requested , your load function
* mymodule_abc_load () will be invoked with the argument '123' , and should
* load and return an " abc " object with internal id 123 :
* @ code
* function mymodule_abc_load ( $abc_id ) {
* return db_query ( " SELECT * FROM { mymodule_abc} WHERE abc_id = :abc_id " , array ( ':abc_id' => $abc_id )) -> fetchObject ();
* }
* @ endcode
* This 'abc' object will then be passed into the page callback function
* mymodule_abc_edit () to replace the integer 1 in the page arguments .
*
* You can also make groups of menu items to be rendered ( by default ) as tabs
* on a page . To do that , first create one menu item of type MENU_NORMAL_ITEM ,
* with your chosen path , such as 'foo' . Then duplicate that menu item , using a
* subdirectory path , such as 'foo/tab1' , and changing the type to
* MENU_DEFAULT_LOCAL_TASK to make it the default tab for the group . Then add
* the additional tab items , with paths such as " foo/tab2 " etc . , with type
* MENU_LOCAL_TASK . Example :
* @ code
* // Make "Foo settings" appear on the admin Config page
* $items [ 'admin/config/foo' ] = array (
* 'title' => 'Foo settings' ,
* 'type' => MENU_NORMAL_ITEM ,
* // page callback, etc. need to be added here
* );
* // Make "Global settings" the main tab on the "Foo settings" page
* $items [ 'admin/config/foo/global' ] = array (
* 'title' => 'Global settings' ,
* 'type' => MENU_DEFAULT_LOCAL_TASK ,
* // access callback, page callback, and theme callback will be inherited
* // from 'admin/config/foo', if not specified here to override
* );
* // Make an additional tab called "Node settings" on "Foo settings"
* $items [ 'admin/config/foo/node' ] = array (
* 'title' => 'Node settings' ,
* 'type' => MENU_LOCAL_TASK ,
* // access callback, page callback, and theme callback will be inherited
* // from 'admin/config/foo', if not specified here to override
* );
* @ endcode
*
* @ return
* An array of menu items . Each menu item has a key corresponding to the
* Drupal path being registered . The corresponding array value is an
* associative array that may contain the following key - value pairs :
* - " title " : Required . The untranslated title of the menu item .
* - " title callback " : Function to generate the title ; defaults to t () .
* If you require only the raw string to be output , set this to FALSE .
* - " title arguments " : Arguments to send to t () or your custom callback ,
* with path component substitution as described above .
* - " description " : The untranslated description of the menu item .
* - " page callback " : The function to call to display a web page when the user
* visits the path . If omitted , the parent menu item ' s callback will be used
* instead .
* - " page arguments " : An array of arguments to pass to the page callback
* function , with path component substitution as described above .
* - " delivery callback " : The function to call to package the result of the
* page callback function and send it to the browser . Defaults to
* drupal_deliver_html_page () unless a value is inherited from a parent menu
* item .
* - " access callback " : A function returning a boolean value that determines
* whether the user has access rights to this menu item . Defaults to
* user_access () unless a value is inherited from a parent menu item .
* - " access arguments " : An array of arguments to pass to the access callback
* function , with path component substitution as described above .
* - " theme callback " : Optional . A function returning the machine - readable
* name of the default theme that will be used to render the page . If this
* function is provided , it is expected to return a currently - active theme
* on the site ( otherwise , the main site theme will be used instead ) . If no
* function is provided , the main site theme will also be used , unless a
* value is inherited from a parent menu item . In all cases , the results of
* this function can be dynamically overridden for a particular page
* request by modules which implement hook_custom_theme () .
* - " theme arguments " : An array of arguments to pass to the theme callback
* function , with path component substitution as described above .
* - " file " : A file that will be included before the page callback is called ;
* this allows page callback functions to be in separate files . The file
* should be relative to the implementing module ' s directory unless
* otherwise specified by the " file path " option . Does not apply to other
* callbacks ( only page callback ) .
* - " file path " : The path to the directory containing the file specified in
* " file " . This defaults to the path to the module implementing the hook .
* - " load arguments " : An array of arguments to be passed to each of the
* wildcard object loaders in the path , after the path argument itself .
* For example , if a module registers path node /% node / revisions /%/ view
* with load arguments set to array ( 3 ), the '%node' in the path indicates
* that the loader function node_load () will be called with the second
* path component as the first argument . The 3 in the load arguments
* indicates that the fourth path component will also be passed to
* node_load () ( numbering of path components starts at zero ) . So , if path
* node / 12 / revisions / 29 / view is requested , node_load ( 12 , 29 ) will be called .
* There are also two " magic " values that can be used in load arguments .
* " %index " indicates the index of the wildcard path component . " %map "
* indicates the path components as an array . For example , if a module
* registers for several paths of the form 'user/%user_category/edit/*' , all
* of them can use the same load function user_category_load (), by setting
* the load arguments to array ( '%map' , '%index' ) . For instance , if the user
* is editing category 'foo' by requesting path 'user/32/edit/foo' , the load
* function user_category_load () will be called with 32 as its first
* argument , the array ( 'user' , 32 , 'edit' , 'foo' ) as the map argument ,
* and 1 as the index argument ( because % user_category is the second path
* component and numbering starts at zero ) . user_category_load () can then
* use these values to extract the information that 'foo' is the category
* being requested .
* - " weight " : An integer that determines the relative position of items in
* the menu ; higher - weighted items sink . Defaults to 0. Menu items with the
* same weight are ordered alphabetically .
* - " menu_name " : Optional . Set this to a custom menu if you don ' t want your
* item to be placed in Navigation .
* - " context " : ( optional ) Defines the context a tab may appear in . By
* default , all tabs are only displayed as local tasks when being rendered
* in a page context . All tabs that should be accessible as contextual links
* in page region containers outside of the parent menu item ' s primary page
* context should be registered using one of the following contexts :
* - MENU_CONTEXT_PAGE : ( default ) The tab is displayed as local task for the
* page context only .
* - MENU_CONTEXT_INLINE : The tab is displayed as contextual link outside of
* the primary page context only .
* Contexts can be combined . For example , to display a tab both on a page
* and inline , a menu router item may specify :
* @ code
* 'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE ,
* @ endcode
* - " tab_parent " : For local task menu items , the path of the task ' s parent
* item ; defaults to the same path without the last component ( e . g . , the
* default parent for 'admin/people/create' is 'admin/people' ) .
* - " tab_root " : For local task menu items , the path of the closest non - tab
* item ; same default as " tab_parent " .
* - " block callback " : Name of a function used to render the block on the
* system administration page for this item ( called with no arguments ) .
* If not provided , system_admin_menu_block () is used to generate it .
* - " position " : Position of the block ( 'left' or 'right' ) on the system
* administration page for this item .
* - " type " : A bitmask of flags describing properties of the menu item .
* Many shortcut bitmasks are provided as constants in menu . inc :
* - MENU_NORMAL_ITEM : Normal menu items show up in the menu tree and can be
* moved / hidden by the administrator .
* - MENU_CALLBACK : Callbacks simply register a path so that the correct
* information is generated when the path is accessed .
* - MENU_SUGGESTED_ITEM : Modules may " suggest " menu items that the
* administrator may enable .
* - MENU_LOCAL_ACTION : Local actions are menu items that describe actions
* on the parent item such as adding a new user or block , and are
* rendered in the action - links list in your theme .
* - MENU_LOCAL_TASK : Local tasks are menu items that describe different
* displays of data , and are generally rendered as tabs .
* - MENU_DEFAULT_LOCAL_TASK : Every set of local tasks should provide one
* " default " task , which should display the same page as the parent item .
* If the " type " element is omitted , MENU_NORMAL_ITEM is assumed .
*
* For a detailed usage example , see page_example . module .
* For comprehensive documentation on the menu system , see
* http :// drupal . org / node / 102338.
*/
function hook_menu () {
$items [ 'blog' ] = array (
'title' => 'blogs' ,
'page callback' => 'blog_page' ,
'access arguments' => array ( 'access content' ),
'type' => MENU_SUGGESTED_ITEM ,
);
$items [ 'blog/feed' ] = array (
'title' => 'RSS feed' ,
'page callback' => 'blog_feed' ,
'access arguments' => array ( 'access content' ),
'type' => MENU_CALLBACK ,
);
return $items ;
}
/**
* Alter the data being saved to the { menu_router } table after hook_menu is invoked .
*
* This hook is invoked by menu_router_build () . The menu definitions are passed
* in by reference . Each element of the $items array is one item returned
* by a module from hook_menu . Additional items may be added , or existing items
* altered .
*
* @ param $items
* Associative array of menu router definitions returned from hook_menu () .
*/
function hook_menu_alter ( & $items ) {
// Example - disable the page at node/add
$items [ 'node/add' ][ 'access callback' ] = FALSE ;
}
/**
* Alter the data being saved to the { menu_links } table by menu_link_save () .
*
* @ param $item
* Associative array defining a menu link as passed into menu_link_save () .
*/
function hook_menu_link_alter ( & $item ) {
// Example 1 - make all new admin links hidden (a.k.a disabled).
if ( strpos ( $item [ 'link_path' ], 'admin' ) === 0 && empty ( $item [ 'mlid' ])) {
$item [ 'hidden' ] = 1 ;
}
// Example 2 - flag a link to be altered by hook_translated_menu_link_alter()
if ( $item [ 'link_path' ] == 'devel/cache/clear' ) {
$item [ 'options' ][ 'alter' ] = TRUE ;
}
}
/**
* Alter a menu link after it 's translated, but before it' s rendered .
*
* This hook may be used , for example , to add a page - specific query string .
* For performance reasons , only links that have $item [ 'options' ][ 'alter' ] == TRUE
* will be passed into this hook . The $item [ 'options' ][ 'alter' ] flag should
* generally be set using hook_menu_link_alter () .
*
* @ param $item
* Associative array defining a menu link after _menu_link_translate ()
* @ param $map
* Associative array containing the menu $map ( path parts and / or objects ) .
*/
function hook_translated_menu_link_alter ( & $item , $map ) {
if ( $item [ 'href' ] == 'devel/cache/clear' ) {
$item [ 'localized_options' ][ 'query' ] = drupal_get_destination ();
}
}
/**
* Inform modules that a menu link has been created .
*
* This hook is used to notify modules that menu items have been
* created . Contributed modules may use the information to perform
* actions based on the information entered into the menu system .
*
* @ param $link
* Associative array defining a menu link as passed into menu_link_save () .
*
* @ see hook_menu_link_update ()
* @ see hook_menu_link_delete ()
*/
function hook_menu_link_insert ( $link ) {
// In our sample case, we track menu items as editing sections
// of the site. These are stored in our table as 'disabled' items.
$record [ 'mlid' ] = $link [ 'mlid' ];
$record [ 'menu_name' ] = $link [ 'menu_name' ];
$record [ 'status' ] = 0 ;
drupal_write_record ( 'menu_example' , $record );
}
/**
* Inform modules that a menu link has been updated .
*
* This hook is used to notify modules that menu items have been
* updated . Contributed modules may use the information to perform
* actions based on the information entered into the menu system .
*
* @ param $link
* Associative array defining a menu link as passed into menu_link_save () .
*
* @ see hook_menu_link_insert ()
* @ see hook_menu_link_delete ()
*/
function hook_menu_link_update ( $link ) {
// If the parent menu has changed, update our record.
$menu_name = db_result ( db_query ( " SELECT mlid, menu_name, status FROM { menu_example} WHERE mlid = :mlid " , array ( ':mlid' => $link [ 'mlid' ])));
if ( $menu_name != $link [ 'menu_name' ]) {
db_update ( 'menu_example' )
-> fields ( array ( 'menu_name' => $link [ 'menu_name' ]))
-> condition ( 'mlid' , $link [ 'mlid' ])
-> execute ();
}
}
/**
* Inform modules that a menu link has been deleted .
*
* This hook is used to notify modules that menu items have been
* deleted . Contributed modules may use the information to perform
* actions based on the information entered into the menu system .
*
* @ param $link
* Associative array defining a menu link as passed into menu_link_save () .
*
* @ see hook_menu_link_insert ()
* @ see hook_menu_link_update ()
*/
function hook_menu_link_delete ( $link ) {
// Delete the record from our table.
db_delete ( 'menu_example' )
-> condition ( 'mlid' , $link [ 'mlid' ])
-> execute ();
}
/**
* Alter tabs and actions displayed on the page before they are rendered .
*
* This hook is invoked by menu_local_tasks () . The system - determined tabs and
* actions are passed in by reference . Additional tabs or actions may be added ,
* or existing items altered .
*
* Each tab or action is an associative array containing :
* - #theme: The theme function to use to render.
* - #link: An associative array containing:
* - title : The localized title of the link .
* - href : The system path to link to .
* - localized_options : An array of options to pass to url () .
* - #active: Whether the link should be marked as 'active'.
*
* @ param $data
* An associative array containing :
* - actions : An associative array containing :
* - count : The amount of actions determined by the menu system , which can
* be ignored .
* - output : A list of of actions , each one being an associative array
* as described above .
* - tabs : An indexed array ( list ) of tab levels ( up to 2 levels ), each
* containing an associative array :
* - count : The amount of tabs determined by the menu system . This value
* does not need to be altered if there is more than one tab .
* - output : A list of of tabs , each one being an associative array as
* described above .
2010-07-26 13:38:30 +00:00
* @ param $router_item
* The menu system router item of the page .
* @ param $root_path
* The path to the root item for this set of tabs .
2010-04-28 05:08:24 +00:00
*/
function hook_menu_local_tasks_alter ( & $data , $router_item , $root_path ) {
// Add an action linking to node/add to all pages.
$data [ 'actions' ][ 'output' ][] = array (
'#theme' => 'menu_local_task' ,
'#link' => array (
'title' => t ( 'Add new content' ),
'href' => 'node/add' ,
'localized_options' => array (
'attributes' => array (
'title' => t ( 'Add new content' ),
),
),
),
);
// Add a tab linking to node/add to all pages.
$data [ 'tabs' ][ 0 ][ 'output' ][] = array (
'#theme' => 'menu_local_task' ,
'#link' => array (
'title' => t ( 'Example tab' ),
'href' => 'node/add' ,
'localized_options' => array (
'attributes' => array (
'title' => t ( 'Add new content' ),
),
),
),
// Define whether this link is active. This can be omitted for
// implementations that add links to pages outside of the current page
// context.
'#active' => ( $router_item [ 'path' ] == $root_path ),
);
}
/**
* Alter contextual links before they are rendered .
*
* This hook is invoked by menu_contextual_links () . The system - determined
* contextual links are passed in by reference . Additional links may be added
* or existing links can be altered .
*
* Each contextual link must at least contain :
* - title : The localized title of the link .
* - href : The system path to link to .
* - localized_options : An array of options to pass to url () .
*
* @ param $links
* An associative array containing contextual links for the given $root_path ,
* as described above . The array keys are used to build CSS class names for
* contextual links and must therefore be unique for each set of contextual
* links .
* @ param $router_item
* The menu router item belonging to the $root_path being requested .
* @ param $root_path
* The ( parent ) path that has been requested to build contextual links for .
* This is a normalized path , which means that an originally passed path of
* 'node/123' became 'node/%' .
*
* @ see menu_contextual_links ()
* @ see hook_menu ()
* @ see system_preprocess ()
*/
function hook_menu_contextual_links_alter ( & $links , $router_item , $root_path ) {
// Add a link to all contextual links for nodes.
if ( $root_path == 'node/%' ) {
$links [ 'foo' ] = array (
'title' => t ( 'Do fu' ),
'href' => 'foo/do' ,
'localized_options' => array (
'query' => array (
'foo' => 'bar' ,
),
),
);
}
}
2009-01-27 00:22:27 +00:00
/**
* Perform alterations before a page is rendered .
*
2009-08-31 16:46:32 +00:00
* Use this hook when you want to remove or alter elements at the page
* level , or add elements at the page level that depend on an other module ' s
* elements ( this hook runs after hook_page_build () .
*
* If you are making changes to entities such as forms , menus , or user
2009-01-27 00:22:27 +00:00
* profiles , use those objects ' native alter hooks instead ( hook_form_alter (),
* for example ) .
*
* The $page array contains top level elements for each block region :
* @ code
2009-08-31 16:46:32 +00:00
* $page [ 'page_top' ]
2009-01-27 00:22:27 +00:00
* $page [ 'header' ]
2009-08-11 12:20:26 +00:00
* $page [ 'sidebar_first' ]
2009-01-27 00:22:27 +00:00
* $page [ 'content' ]
2009-08-11 12:20:26 +00:00
* $page [ 'sidebar_second' ]
2009-08-31 16:46:32 +00:00
* $page [ 'page_bottom' ]
2009-01-27 00:22:27 +00:00
* @ endcode
*
* The 'content' element contains the main content of the current page , and its
* structure will vary depending on what module is responsible for building the
* page . Some legacy modules may not return structured content at all : their
* pre - rendered markup will be located in $page [ 'content' ][ 'main' ][ '#markup' ] .
*
* Pages built by Drupal ' s core Node and Blog modules use a standard structure :
*
* @ code
* // Node body.
* $page [ 'content' ][ 'nodes' ][ $nid ][ 'body' ]
* // Array of links attached to the node (add comments, read more).
* $page [ 'content' ][ 'nodes' ][ $nid ][ 'links' ]
* // The node object itself.
* $page [ 'content' ][ 'nodes' ][ $nid ][ '#node' ]
* // The results pager.
* $page [ 'content' ][ 'pager' ]
2009-02-09 15:42:52 +00:00
* @ endcode
2009-01-27 00:22:27 +00:00
*
* Blocks may be referenced by their module / delta pair within a region :
* @ code
2009-08-11 12:20:26 +00:00
* // The login block in the first sidebar region.
2009-08-31 16:46:32 +00:00
* $page [ 'sidebar_first' ][ 'user_login' ][ '#block' ];
2009-01-27 00:22:27 +00:00
* @ endcode
*
* @ param $page
* Nested array of renderable elements that make up the page .
*
2009-08-31 16:46:32 +00:00
* @ see hook_page_build ()
2009-01-27 00:22:27 +00:00
* @ see drupal_render_page ()
*/
2009-08-31 16:46:32 +00:00
function hook_page_alter ( & $page ) {
// Add help text to the user login block.
$page [ 'sidebar_first' ][ 'user_login' ][ 'help' ] = array (
'#weight' => - 10 ,
'#markup' => t ( 'To post comments or add new content, you first have to log in.' ),
);
2009-01-27 00:22:27 +00:00
}
2008-11-25 02:37:33 +00:00
/**
* Perform alterations before a form is rendered .
*
* One popular use of this hook is to add form elements to the node form . When
2010-05-05 07:02:13 +00:00
* altering a node form , the node object can be accessed at $form [ '#node' ] .
2008-11-25 02:37:33 +00:00
*
2009-04-28 00:27:06 +00:00
* Note that instead of hook_form_alter (), which is called for all forms , you
2010-04-28 12:36:26 +00:00
* can also use hook_form_FORM_ID_alter () to alter a specific form . For each
* module ( in system weight order ) the general form alter hook implementation
* is invoked first , then the form ID specific alter implementation is called .
* After all module hook implementations are invoked , the hook_form_alter ()
* implementations from themes are invoked in the same manner .
2009-03-08 03:46:31 +00:00
*
2008-11-25 02:37:33 +00:00
* @ param $form
* Nested array of form elements that comprise the form .
* @ param $form_state
* A keyed array containing the current state of the form .
* @ param $form_id
* String representing the name of the form itself . Typically this is the
* name of the function that generated the form .
2010-04-28 12:36:26 +00:00
*
* @ see hook_form_FORM_ID_alter ()
2008-11-25 02:37:33 +00:00
*/
2009-07-31 21:21:33 +00:00
function hook_form_alter ( & $form , & $form_state , $form_id ) {
2008-11-25 02:37:33 +00:00
if ( isset ( $form [ 'type' ]) && $form [ 'type' ][ '#value' ] . '_node_settings' == $form_id ) {
$form [ 'workflow' ][ 'upload_' . $form [ 'type' ][ '#value' ]] = array (
'#type' => 'radios' ,
'#title' => t ( 'Attachments' ),
'#default_value' => variable_get ( 'upload_' . $form [ 'type' ][ '#value' ], 1 ),
'#options' => array ( t ( 'Disabled' ), t ( 'Enabled' )),
);
}
}
/**
* Provide a form - specific alteration instead of the global hook_form_alter () .
*
* Modules can implement hook_form_FORM_ID_alter () to modify a specific form ,
* rather than implementing hook_form_alter () and checking the form ID , or
* using long switch statements to alter multiple forms .
*
* @ param $form
* Nested array of form elements that comprise the form .
* @ param $form_state
* A keyed array containing the current state of the form .
*
2010-04-28 12:36:26 +00:00
* @ see hook_form_alter ()
2010-03-26 17:14:46 +00:00
* @ see drupal_prepare_form ()
2008-11-25 02:37:33 +00:00
*/
function hook_form_FORM_ID_alter ( & $form , & $form_state ) {
// Modification for the form with the given form ID goes here. For example, if
2009-10-10 16:48:39 +00:00
// FORM_ID is "user_register_form" this code would run only on the user
2008-11-25 02:37:33 +00:00
// registration form.
// Add a checkbox to registration form about agreeing to terms of use.
$form [ 'terms_of_use' ] = array (
'#type' => 'checkbox' ,
'#title' => t ( " I agree with the website's terms and conditions. " ),
'#required' => TRUE ,
);
}
/**
2010-03-06 12:43:45 +00:00
* Map form_ids to form builder functions .
2008-11-25 02:37:33 +00:00
*
2010-03-06 12:43:45 +00:00
* By default , when drupal_get_form () is called , the system will look for a
* function with the same name as the form ID , and use that function to build
* the form . This hook allows you to override that behavior in two ways .
2008-11-25 02:37:33 +00:00
*
2010-03-06 12:43:45 +00:00
* First , you can use this hook to tell the form system to use a different
* function to build certain forms in your module ; this is often used to define
* a form " factory " function that is used to build several similar forms . In
* this case , your hook implementation will likely ignore all of the input
* arguments . See node_forms () for an example of this .
2008-11-25 02:37:33 +00:00
*
2010-03-06 12:43:45 +00:00
* Second , you could use this hook to define how to build a form with a
* dynamically - generated form ID . In this case , you would need to verify that
* the $form_id input matched your module ' s format for dynamically - generated
* form IDs , and if so , act appropriately .
2008-11-25 02:37:33 +00:00
*
2009-04-26 16:44:25 +00:00
* @ param $form_id
* The unique string identifying the desired form .
* @ param $args
2010-03-06 12:43:45 +00:00
* An array containing the original arguments provided to drupal_get_form ()
* or drupal_form_submit () . These are always passed to the form builder and
* do not have to be specified manually in 'callback arguments' .
2009-11-04 05:39:14 +00:00
*
2008-11-25 02:37:33 +00:00
* @ return
2009-11-04 05:39:14 +00:00
* An associative array whose keys define form_ids and whose values are an
* associative array defining the following keys :
* - callback : The name of the form builder function to invoke .
* - callback arguments : ( optional ) Additional arguments to pass to the
* function defined in 'callback' , which are prepended to $args .
* - wrapper_callback : ( optional ) The name of a form builder function to
* invoke before the form builder defined in 'callback' is invoked . This
* wrapper callback may prepopulate the $form array with form elements ,
* which will then be already contained in the $form that is passed on to
* the form builder defined in 'callback' . For example , a wrapper callback
* could setup wizard - alike form buttons that are the same for a variety of
* forms that belong to the wizard , which all share the same wrapper
* callback .
2008-11-25 02:37:33 +00:00
*/
2009-04-26 16:44:25 +00:00
function hook_forms ( $form_id , $args ) {
2009-11-04 05:39:14 +00:00
// Simply reroute the (non-existing) $form_id 'mymodule_first_form' to
// 'mymodule_main_form'.
2008-11-25 02:37:33 +00:00
$forms [ 'mymodule_first_form' ] = array (
2009-11-04 05:39:14 +00:00
'callback' => 'mymodule_main_form' ,
2008-11-25 02:37:33 +00:00
);
2009-11-04 05:39:14 +00:00
// Reroute the $form_id and prepend an additional argument that gets passed to
// the 'mymodule_main_form' form builder function.
2008-11-25 02:37:33 +00:00
$forms [ 'mymodule_second_form' ] = array (
2009-11-04 05:39:14 +00:00
'callback' => 'mymodule_main_form' ,
'callback arguments' => array ( 'some parameter' ),
);
// Reroute the $form_id, but invoke the form builder function
// 'mymodule_main_form_wrapper' first, so we can prepopulate the $form array
// that is passed to the actual form builder 'mymodule_main_form'.
$forms [ 'mymodule_wrapped_form' ] = array (
'callback' => 'mymodule_main_form' ,
'wrapper_callback' => 'mymodule_main_form_wrapper' ,
2008-11-25 02:37:33 +00:00
);
2009-04-26 16:44:25 +00:00
2008-11-25 02:37:33 +00:00
return $forms ;
}
/**
* Perform setup tasks . See also , hook_init .
*
* This hook is run at the beginning of the page request . It is typically
* used to set up global parameters which are needed later in the request .
*
* Only use this hook if your code must run even for cached page views . This hook
* is called before modules or most include files are loaded into memory .
* It happens while Drupal is still in bootstrap mode .
*/
function hook_boot () {
// we need user_access() in the shutdown function. make sure it gets loaded
drupal_load ( 'module' , 'user' );
2010-02-17 22:44:52 +00:00
drupal_register_shutdown_function ( 'devel_shutdown' );
2008-11-25 02:37:33 +00:00
}
/**
* Perform setup tasks . See also , hook_boot .
*
* This hook is run at the beginning of the page request . It is typically
* used to set up global parameters which are needed later in the request .
* when this hook is called , all modules are already loaded in memory .
*
* For example , this hook is a typical place for modules to add CSS or JS
* that should be present on every page . This hook is not run on cached
* pages - though CSS or JS added this way will be present on a cached page .
*/
function hook_init () {
drupal_add_css ( drupal_get_path ( 'module' , 'book' ) . '/book.css' );
}
/**
2009-03-09 11:44:54 +00:00
* Define image toolkits provided by this module .
*
* The file which includes each toolkit ' s functions must be declared as part of
* the files array in the module . info file so that the registry will find and
* parse it .
*
* The toolkit ' s functions must be named image_toolkitname_operation () .
* where the operation may be :
* - 'load' : Required . See image_gd_load () for usage .
* - 'save' : Required . See image_gd_save () for usage .
* - 'settings' : Optional . See image_gd_settings () for usage .
* - 'resize' : Optional . See image_gd_resize () for usage .
2009-03-10 09:43:01 +00:00
* - 'rotate' : Optional . See image_gd_rotate () for usage .
2009-03-09 11:44:54 +00:00
* - 'crop' : Optional . See image_gd_crop () for usage .
* - 'desaturate' : Optional . See image_gd_desaturate () for usage .
*
* @ return
* An array with the toolkit name as keys and sub - arrays with these keys :
* - 'title' : A string with the toolkit ' s title .
* - 'available' : A Boolean value to indicate that the toolkit is operating
* properly , e . g . all required libraries exist .
*
* @ see system_image_toolkits ()
*/
2008-11-25 02:37:33 +00:00
function hook_image_toolkits () {
2009-03-09 11:44:54 +00:00
return array (
'working' => array (
'title' => t ( 'A toolkit that works.' ),
'available' => TRUE ,
),
'broken' => array (
'title' => t ( 'A toolkit that is "broken" and will not be listed.' ),
'available' => FALSE ,
),
);
2008-11-25 02:37:33 +00:00
}
/**
2009-08-28 07:22:44 +00:00
* Alter an email message created with the drupal_mail () function .
*
* hook_mail_alter () allows modification of email messages created and sent
* with drupal_mail () . Usage examples include adding and / or changing message
* text , message fields , and message headers .
*
* Email messages sent using functions other than drupal_mail () will not
* invoke hook_mail_alter () . For example , a contributed module directly
2009-10-16 03:01:55 +00:00
* calling the drupal_mail_system () -> mail () or PHP mail () function
2009-09-01 17:40:28 +00:00
* will not invoke this hook . All core modules use drupal_mail () for
2010-01-25 10:38:35 +00:00
* messaging , it is best practice but not mandatory in contributed modules .
2008-11-25 02:37:33 +00:00
*
* @ param $message
2009-08-28 07:22:44 +00:00
* An array containing the message data . Keys in this array include :
2009-06-27 10:19:31 +00:00
* - 'id' :
2009-08-28 07:22:44 +00:00
* The drupal_mail () id of the message . Look at module source code or
2009-09-29 15:13:57 +00:00
* drupal_mail () for possible id values .
2009-08-28 07:22:44 +00:00
* - 'to' :
2009-06-27 10:19:31 +00:00
* The address or addresses the message will be sent to . The
2008-11-25 02:37:33 +00:00
* formatting of this string must comply with RFC 2822.
2009-08-28 07:22:44 +00:00
* - 'from' :
2009-06-27 10:19:31 +00:00
* The address the message will be marked as being from , which is
* either a custom address or the site - wide default email address .
2009-08-28 07:22:44 +00:00
* - 'subject' :
* Subject of the email to be sent . This must not contain any newline
* characters , or the email may not be sent properly .
* - 'body' :
* An array of strings containing the message text . The message body is
2009-09-29 15:13:57 +00:00
* created by concatenating the individual array strings into a single text
2009-08-28 07:22:44 +00:00
* string using " \n \n " as a separator .
* - 'headers' :
2009-06-27 10:19:31 +00:00
* Associative array containing mail headers , such as From , Sender ,
2009-07-11 13:56:22 +00:00
* MIME - Version , Content - Type , etc .
2009-08-28 07:22:44 +00:00
* - 'params' :
* An array of optional parameters supplied by the caller of drupal_mail ()
* that is used to build the message before hook_mail_alter () is invoked .
* - 'language' :
* The language object used to build the message before hook_mail_alter ()
* is invoked .
*
* @ see drupal_mail ()
2008-11-25 02:37:33 +00:00
*/
function hook_mail_alter ( & $message ) {
2009-08-26 03:09:12 +00:00
if ( $message [ 'id' ] == 'modulename_messagekey' ) {
$message [ 'body' ][] = " -- \n Mail sent out from " . variable_get ( 'sitename' , t ( 'Drupal' ));
2008-11-25 02:37:33 +00:00
}
}
2010-04-22 22:36:01 +00:00
/**
* Alter the registry of modules implementing a hook .
*
* This hook is invoked during module_implements () . A module may implement this
* hook in order to reorder the implementing modules , which are otherwise
* ordered by the module ' s system weight .
*
* @ param & $implementations
* An array keyed by the module ' s name . The value of each item corresponds
* to a $group , which is usually FALSE , unless the implementation is in a
* file named $module . $group . inc .
* @ param $hook
* The name of the module hook being implemented .
*/
function hook_module_implements_alter ( & $implementations , $hook ) {
if ( $hook == 'rdf_mapping' ) {
// Move my_module_rdf_mapping() to the end of the list. module_implements()
// iterates through $implementations with a foreach loop which PHP iterates
// in the order that the items were added, so to move an item to the end of
// the array, we remove it and then add it.
$group = $implementations [ 'my_module' ];
unset ( $implementations [ 'my_module' ]);
$implementations [ 'my_module' ] = $group ;
}
}
2008-11-25 02:37:33 +00:00
/**
* Alter the information parsed from module and theme . info files
*
2009-10-13 05:26:57 +00:00
* This hook is invoked in _system_rebuild_module_data () and in
* _system_rebuild_theme_data () . A module may implement this hook in order to
* add to or alter the data generated by reading the . info file with
* drupal_parse_info_file () .
2008-11-25 02:37:33 +00:00
*
* @ param & $info
* The . info file contents , passed by reference so that it can be altered .
* @ param $file
* Full information about the module or theme , including $file -> name , and
* $file -> filename
2009-09-25 23:48:24 +00:00
* @ param $type
* Either 'module' or 'theme' , depending on the type of . info file that was
* passed .
2008-11-25 02:37:33 +00:00
*/
2009-09-25 23:48:24 +00:00
function hook_system_info_alter ( & $info , $file , $type ) {
2008-11-25 02:37:33 +00:00
// Only fill this in if the .info file does not define a 'datestamp'.
if ( empty ( $info [ 'datestamp' ])) {
$info [ 'datestamp' ] = filemtime ( $file -> filename );
}
}
/**
* Define user permissions .
*
* This hook can supply permissions that the module defines , so that they
2009-06-18 10:20:22 +00:00
* can be selected on the user permissions page and used to grant or restrict
2008-11-25 02:37:33 +00:00
* access to actions the module performs .
*
* Permissions are checked using user_access () .
*
* For a detailed usage example , see page_example . module .
2009-09-05 13:05:31 +00:00
*
2009-08-01 20:48:59 +00:00
* @ return
2010-03-21 21:20:43 +00:00
* An array whose keys are permission names and whose corresponding values
* are arrays containing the following key - value pairs :
* - title : The human - readable name of the permission , to be shown on the
* permission administration page . This should be wrapped in the t ()
* function so it can be translated .
* - description : ( optional ) A description of what the permission does . This
* should be wrapped in the t () function so it can be translated .
* - restrict access : ( optional ) A boolean which can be set to TRUE to
* indicate that site administrators should restrict access to this
* permission to trusted users . This should be used for permissions that
* have inherent security risks across a variety of potential use cases
* ( for example , the " administer filters " and " bypass node access "
* permissions provided by Drupal core ) . When set to TRUE , a standard
* warning message defined in user_admin_permissions () will be associated
* with the permission and displayed with it on the permission
* administration page . Defaults to FALSE .
2008-11-25 02:37:33 +00:00
*/
2009-07-05 18:00:11 +00:00
function hook_permission () {
2008-11-25 02:37:33 +00:00
return array (
2009-06-18 10:20:22 +00:00
'administer my module' => array (
'title' => t ( 'Administer my module' ),
'description' => t ( 'Perform administration tasks for my module.' ),
),
2008-11-25 02:37:33 +00:00
);
}
/**
* Register a module ( or theme ' s ) theme implementations .
*
* The following parameters are all optional .
*
2010-04-29 04:57:59 +00:00
* @ param array $existing
2008-11-25 02:37:33 +00:00
* An array of existing implementations that may be used for override
* purposes . This is primarily useful for themes that may wish to examine
* existing implementations to extract data ( such as arguments ) so that
* it may properly register its own , higher priority implementations .
* @ param $type
2010-04-29 04:57:59 +00:00
* Whether a theme , module , etc . is being processed . This is primarily useful
* so that themes tell if they are the actual theme being called or a parent
* theme . May be one of :
* - 'module' : A module is being checked for theme implementations .
* - 'base_theme_engine' : A theme engine is being checked for a theme that is
* a parent of the actual theme being used .
* - 'theme_engine' : A theme engine is being checked for the actual theme
* being used .
* - 'base_theme' : A base theme is being checked for theme implementations .
* - 'theme' : The actual theme in use is being checked .
2008-11-25 02:37:33 +00:00
* @ param $theme
2010-04-29 04:57:59 +00:00
* The actual name of theme , module , etc . that is being being processed .
2008-11-25 02:37:33 +00:00
* @ param $path
* The directory path of the theme or module , so that it doesn ' t need to be
* looked up .
*
2010-04-29 04:57:59 +00:00
* @ return array
* An associative array of theme hook information . The keys on the outer
* array are the internal names of the hooks , and the values are arrays
* containing information about the hook . Each array may contain the
* following elements :
* - variables : ( required if " render element " not present ) An array of
* variables that this theme hook uses . This value allows the theme layer to
* properly utilize templates . Each array key represents the name of the
* variable and the value will be used as the default value if it is not
* given when theme () is called . Template implementations receive these
* arguments as variables in the template file . Function implementations
* are passed this array data in the $variables parameter .
* - render element : ( required if " variables " not present ) A string that is
* the name of the sole renderable element to pass to the theme function .
* The string represents the name of the " variable " that will hold the
* renderable array inside any optional preprocess or process functions .
* Cannot be used with the " variables " item ; only one or the other , not
* both , can be present in a hook ' s info array .
* - file : The file the implementation resides in . This file will be included
* prior to the theme being rendered , to make sure that the function or
* preprocess function ( as needed ) is actually loaded ; this makes it
* possible to split theme functions out into separate files quite easily .
* - path : Override the path of the file to be used . Ordinarily the module or
* theme path will be used , but if the file will not be in the default path ,
* include it here . This path should be relative to the Drupal root
* directory .
* - template : If specified , this theme implementation is a template , and this
* is the template file without an extension . Do not put . tpl . php on this
* file ; that extension will be added automatically by the default rendering
* engine ( which is PHPTemplate ) . If 'path' , above , is specified , the
* template should also be in this path .
* - function : If specified , this will be the function name to invoke for this
* implementation . If neither file nor function is specified , a default
* function name will be assumed . For example , if a module registers
* the 'node' theme hook , 'theme_node' will be assigned to its function .
* If the chameleon theme registers the node hook , it will be assigned
* 'chameleon_node' as its function .
* - pattern : A regular expression pattern to be used to allow this theme
* implementation to have a dynamic name . The convention is to use __ to
* differentiate the dynamic portion of the theme . For example , to allow
* forums to be themed individually , the pattern might be : 'forum__' . Then ,
* when the forum is themed , call :
* @ code
* theme ( array ( 'forum__' . $tid , 'forum' ), $forum )
* @ endcode
* - preprocess functions : A list of functions used to preprocess this data .
* Ordinarily this won 't be used; it' s automatically filled in . By default ,
* for a module this will be filled in as template_preprocess_HOOK . For
* a theme this will be filled in as phptemplate_preprocess and
* phptemplate_preprocess_HOOK as well as themename_preprocess and
* themename_preprocess_HOOK .
* - override preprocess functions : Set to TRUE when a theme does NOT want the
* standard preprocess functions to run . This can be used to give a theme
* FULL control over how variables are set . For example , if a theme wants
* total control over how certain variables in the page . tpl . php are set ,
* this can be set to true . Please keep in mind that when this is used
* by a theme , that theme becomes responsible for making sure necessary
* variables are set .
* - type : ( automatically derived ) Where the theme hook is defined :
* 'module' , 'theme_engine' , or 'theme' .
* - theme path : ( automatically derived ) The directory path of the theme or
* module , so that it doesn ' t need to be looked up .
2008-11-25 02:37:33 +00:00
*/
function hook_theme ( $existing , $type , $theme , $path ) {
return array (
'forum_display' => array (
2009-10-23 22:24:19 +00:00
'variables' => array ( 'forums' => NULL , 'topics' => NULL , 'parents' => NULL , 'tid' => NULL , 'sortby' => NULL , 'forum_per_page' => NULL ),
2008-11-25 02:37:33 +00:00
),
'forum_list' => array (
2009-10-23 22:24:19 +00:00
'variables' => array ( 'forums' => NULL , 'parents' => NULL , 'tid' => NULL ),
2008-11-25 02:37:33 +00:00
),
'forum_topic_list' => array (
2009-10-23 22:24:19 +00:00
'variables' => array ( 'tid' => NULL , 'topics' => NULL , 'sortby' => NULL , 'forum_per_page' => NULL ),
2008-11-25 02:37:33 +00:00
),
'forum_icon' => array (
2009-10-23 22:24:19 +00:00
'variables' => array ( 'new_posts' => NULL , 'num_posts' => 0 , 'comment_mode' => 0 , 'sticky' => 0 ),
),
'status_report' => array (
'render element' => 'requirements' ,
'file' => 'system.admin.inc' ,
),
'system_date_time_settings' => array (
'render element' => 'form' ,
'file' => 'system.admin.inc' ,
2008-11-25 02:37:33 +00:00
),
);
}
/**
* Alter the theme registry information returned from hook_theme () .
*
* The theme registry stores information about all available theme hooks ,
* including which callback functions those hooks will call when triggered ,
* what template files are exposed by these hooks , and so on .
*
* Note that this hook is only executed as the theme cache is re - built .
* Changes here will not be visible until the next cache clear .
*
* The $theme_registry array is keyed by theme hook name , and contains the
* information returned from hook_theme (), as well as additional properties
* added by _theme_process_registry () .
*
* For example :
* @ code
* $theme_registry [ 'user_profile' ] = array (
2009-10-23 22:24:19 +00:00
* 'variables' => array (
2008-11-25 02:37:33 +00:00
* 'account' => NULL ,
* ),
* 'template' => 'modules/user/user-profile' ,
* 'file' => 'modules/user/user.pages.inc' ,
* 'type' => 'module' ,
* 'theme path' => 'modules/user' ,
* 'preprocess functions' => array (
* 0 => 'template_preprocess' ,
* 1 => 'template_preprocess_user_profile' ,
* ),
* )
* );
* @ endcode
*
* @ param $theme_registry
* The entire cache of theme registry information , post - processing .
2010-06-29 00:23:57 +00:00
*
2008-11-25 02:37:33 +00:00
* @ see hook_theme ()
* @ see _theme_process_registry ()
*/
function hook_theme_registry_alter ( & $theme_registry ) {
// Kill the next/previous forum topic navigation links.
foreach ( $theme_registry [ 'forum_topic_navigation' ][ 'preprocess functions' ] as $key => $value ) {
if ( $value = 'template_preprocess_forum_topic_navigation' ) {
unset ( $theme_registry [ 'forum_topic_navigation' ][ 'preprocess functions' ][ $key ]);
}
}
}
2010-01-30 03:38:22 +00:00
/**
* Return the machine - readable name of the theme to use for the current page .
*
* This hook can be used to dynamically set the theme for the current page
* request . It overrides the default theme as well as any per - page or
* per - section theme set by the theme callback function in hook_menu () . This
* should be used by modules which need to override the theme based on dynamic
* conditions .
*
* Since only one theme can be used at a time , the last ( i . e . , highest
* weighted ) module which returns a valid theme name from this hook will
* prevail .
*
* @ return
* The machine - readable name of the theme that should be used for the current
* page request . The value returned from this function will only have an
* effect if it corresponds to a currently - active theme on the site .
*/
function hook_custom_theme () {
// Allow the user to request a particular theme via a query parameter.
if ( isset ( $_GET [ 'theme' ])) {
return $_GET [ 'theme' ];
}
}
2008-11-25 02:37:33 +00:00
/**
* Register XML - RPC callbacks .
*
* This hook lets a module register callback functions to be called when
* particular XML - RPC methods are invoked by a client .
*
* @ return
* An array which maps XML - RPC methods to Drupal functions . Each array
* element is either a pair of method => function or an array with four
* entries :
* - The XML - RPC method name ( for example , module . function ) .
* - The Drupal callback function ( for example , module_function ) .
* - The method signature is an array of XML - RPC types . The first element
* of this array is the type of return value and then you should write a
* list of the types of the parameters . XML - RPC types are the following
* ( See the types at http :// www . xmlrpc . com / spec ) :
* - " boolean " : 0 ( false ) or 1 ( true ) .
* - " double " : a floating point number ( for example , - 12.214 ) .
* - " int " : a integer number ( for example , - 12 ) .
* - " array " : an array without keys ( for example , array ( 1 , 2 , 3 )) .
* - " struct " : an associative array or an object ( for example ,
* array ( 'one' => 1 , 'two' => 2 )) .
* - " date " : when you return a date , then you may either return a
* timestamp ( time (), mktime () etc . ) or an ISO8601 timestamp . When
* date is specified as an input parameter , then you get an object ,
* which is described in the function xmlrpc_date
* - " base64 " : a string containing binary data , automatically
* encoded / decoded automatically .
* - " string " : anything else , typically a string .
* - A descriptive help string , enclosed in a t () function for translation
* purposes .
* Both forms are shown in the example .
*/
function hook_xmlrpc () {
return array (
'drupal.login' => 'drupal_login' ,
array (
'drupal.site.ping' ,
'drupal_directory_ping' ,
array ( 'boolean' , 'string' , 'string' , 'string' , 'string' , 'string' ),
t ( 'Handling ping request' ))
);
}
2009-12-13 13:06:45 +00:00
/**
* Alter the definition of XML - RPC methods before they are called .
*
* This hook lets at module modify the callback definition for already
* declared XML - RPC methods , when they are being invoked by a client .
*
* This hook is invoked by xmlrpc . php . The method definitions are
* passed in by reference . Each element of the $methods array is one
* callback definition returned by a module from hook_xmlrpc . Additional
* methods may be added , or existing items altered .
*
* Modules implementing this hook must take care of the fact that
* hook_xmlrpc allows two distinct and incompatible formats for callback
* definition , so module must be prepared to handle either format for
* each callback being altered .
*
* @ param $methods
* Associative array of method callback definitions returned from
* hook_xmlrpc .
2010-06-29 00:23:57 +00:00
*
* @ see hook_xmlrpc ()
2009-12-13 13:06:45 +00:00
*/
function hook_xmlrpc_alter ( & $methods ) {
// Direct update for methods defined the simple way
$methods [ 'drupal.login' ] = 'mymodule_login' ;
// Lookup update for methods defined the complex way
foreach ( $methods as $key => & $method ) {
if ( ! is_int ( $key )) {
continue ;
}
if ( $method [ 0 ] == 'drupal.site.ping' ) {
$method [ 1 ] = 'mymodule_directory_ping' ;
}
}
}
2008-11-25 02:37:33 +00:00
/**
* Log an event message
*
* This hook allows modules to route log events to custom destinations , such as
* SMS , Email , pager , syslog , ... etc .
*
* @ param $log_entry
2008-12-28 20:41:19 +00:00
* An associative array containing the following keys :
2008-11-25 02:37:33 +00:00
* - type : The type of message for this entry . For contributed modules , this is
* normally the module name . Do not use 'debug' , use severity WATCHDOG_DEBUG instead .
* - user : The user object for the user who was logged in when the event happened .
* - request_uri : The Request URI for the page the event happened in .
* - referer : The page that referred the use to the page where the event occurred .
* - ip : The IP address where the request for the page came from .
2010-01-25 10:38:35 +00:00
* - timestamp : The UNIX timestamp of the date / time the event occurred
2008-11-25 02:37:33 +00:00
* - severity : One of the following values as defined in RFC 3164 http :// www . faqs . org / rfcs / rfc3164 . html
2010-03-11 21:23:06 +00:00
* WATCHDOG_EMERGENCY Emergency : system is unusable
2008-11-25 02:37:33 +00:00
* WATCHDOG_ALERT Alert : action must be taken immediately
* WATCHDOG_CRITICAL Critical : critical conditions
* WATCHDOG_ERROR Error : error conditions
* WATCHDOG_WARNING Warning : warning conditions
* WATCHDOG_NOTICE Notice : normal but significant condition
* WATCHDOG_INFO Informational : informational messages
* WATCHDOG_DEBUG Debug : debug - level messages
* - link : an optional link provided by the module that called the watchdog () function .
* - message : The text of the message to be logged .
*/
2008-12-28 20:41:19 +00:00
function hook_watchdog ( array $log_entry ) {
global $base_url , $language ;
2008-11-25 02:37:33 +00:00
$severity_list = array (
2010-03-11 21:23:06 +00:00
WATCHDOG_EMERGENCY => t ( 'Emergency' ),
WATCHDOG_ALERT => t ( 'Alert' ),
WATCHDOG_CRITICAL => t ( 'Critical' ),
WATCHDOG_ERROR => t ( 'Error' ),
WATCHDOG_WARNING => t ( 'Warning' ),
WATCHDOG_NOTICE => t ( 'Notice' ),
WATCHDOG_INFO => t ( 'Info' ),
WATCHDOG_DEBUG => t ( 'Debug' ),
2008-11-25 02:37:33 +00:00
);
2008-12-28 20:41:19 +00:00
$to = 'someone@example.com' ;
$params = array ();
$params [ 'subject' ] = t ( '[@site_name] @severity_desc: Alert from your web site' , array (
'@site_name' => variable_get ( 'site_name' , 'Drupal' ),
'@severity_desc' => $severity_list [ $log_entry [ 'severity' ]],
));
$params [ 'message' ] = " \n Site: @base_url " ;
$params [ 'message' ] .= " \n Severity: (@severity) @severity_desc " ;
$params [ 'message' ] .= " \n Timestamp: @timestamp " ;
$params [ 'message' ] .= " \n Type: @type " ;
$params [ 'message' ] .= " \n IP Address: @ip " ;
$params [ 'message' ] .= " \n Request URI: @request_uri " ;
$params [ 'message' ] .= " \n Referrer URI: @referer_uri " ;
$params [ 'message' ] .= " \n User: (@uid) @name " ;
$params [ 'message' ] .= " \n Link: @link " ;
$params [ 'message' ] .= " \n Message: \n \n @message " ;
$params [ 'message' ] = t ( $params [ 'message' ], array (
2008-11-25 02:37:33 +00:00
'@base_url' => $base_url ,
2008-12-28 20:41:19 +00:00
'@severity' => $log_entry [ 'severity' ],
'@severity_desc' => $severity_list [ $log_entry [ 'severity' ]],
'@timestamp' => format_date ( $log_entry [ 'timestamp' ]),
'@type' => $log_entry [ 'type' ],
'@ip' => $log_entry [ 'ip' ],
'@request_uri' => $log_entry [ 'request_uri' ],
'@referer_uri' => $log_entry [ 'referer' ],
'@uid' => $log_entry [ 'user' ] -> uid ,
'@name' => $log_entry [ 'user' ] -> name ,
'@link' => strip_tags ( $log_entry [ 'link' ]),
'@message' => strip_tags ( $log_entry [ 'message' ]),
2008-11-25 02:37:33 +00:00
));
2008-12-28 20:41:19 +00:00
drupal_mail ( 'emaillog' , 'entry' , $to , $language , $params );
2008-11-25 02:37:33 +00:00
}
/**
2009-06-27 10:19:31 +00:00
* Prepare a message based on parameters ; called from drupal_mail () .
2008-11-25 02:37:33 +00:00
*
* @ param $key
* An identifier of the mail .
* @ param $message
* An array to be filled in . Keys in this array include :
2009-06-27 10:19:31 +00:00
* - 'id' :
* An id to identify the mail sent . Look at module source code
* or drupal_mail () for possible id values .
2008-11-25 02:37:33 +00:00
* - 'to' :
2009-06-27 10:19:31 +00:00
* The address or addresses the message will be sent to . The
2008-11-25 02:37:33 +00:00
* formatting of this string must comply with RFC 2822.
* - 'subject' :
* Subject of the e - mail to be sent . This must not contain any newline
2009-06-27 10:19:31 +00:00
* characters , or the mail may not be sent properly . drupal_mail () sets
* this to an empty string when the hook is invoked .
2008-11-25 02:37:33 +00:00
* - 'body' :
* An array of lines containing the message to be sent . Drupal will format
2009-06-27 10:19:31 +00:00
* the correct line endings for you . drupal_mail () sets this to an empty
* array when the hook is invoked .
2008-11-25 02:37:33 +00:00
* - 'from' :
2009-06-27 10:19:31 +00:00
* The address the message will be marked as being from , which is
2009-07-11 13:56:22 +00:00
* set by drupal_mail () to either a custom address or the site - wide
2009-06-27 10:19:31 +00:00
* default email address when the hook is invoked .
2008-11-25 02:37:33 +00:00
* - 'headers' :
2009-06-27 10:19:31 +00:00
* Associative array containing mail headers , such as From , Sender ,
* MIME - Version , Content - Type , etc . drupal_mail () pre - fills
* several headers in this array .
2008-11-25 02:37:33 +00:00
* @ param $params
2009-06-27 10:19:31 +00:00
* An array of parameters supplied by the caller of drupal_mail () .
2008-11-25 02:37:33 +00:00
*/
function hook_mail ( $key , & $message , $params ) {
$account = $params [ 'account' ];
$context = $params [ 'context' ];
$variables = array (
'%site_name' => variable_get ( 'site_name' , 'Drupal' ),
2009-11-01 21:26:44 +00:00
'%username' => format_username ( $account ),
2008-11-25 02:37:33 +00:00
);
if ( $context [ 'hook' ] == 'taxonomy' ) {
2010-03-27 05:52:50 +00:00
$entity = $params [ 'entity' ];
2010-02-11 17:44:47 +00:00
$vocabulary = taxonomy_vocabulary_load ( $entity -> vid );
2008-11-25 02:37:33 +00:00
$variables += array (
2010-02-11 17:44:47 +00:00
'%term_name' => $entity -> name ,
'%term_description' => $entity -> description ,
'%term_id' => $entity -> tid ,
2008-11-25 02:37:33 +00:00
'%vocabulary_name' => $vocabulary -> name ,
'%vocabulary_description' => $vocabulary -> description ,
'%vocabulary_id' => $vocabulary -> vid ,
);
}
// Node-based variable translation is only available if we have a node.
if ( isset ( $params [ 'node' ])) {
$node = $params [ 'node' ];
$variables += array (
'%uid' => $node -> uid ,
'%node_url' => url ( 'node/' . $node -> nid , array ( 'absolute' => TRUE )),
2009-06-04 03:33:29 +00:00
'%node_type' => node_type_get_name ( $node ),
2010-01-09 21:54:01 +00:00
'%title' => $node -> title ,
2008-11-25 02:37:33 +00:00
'%teaser' => $node -> teaser ,
'%body' => $node -> body ,
);
}
$subject = strtr ( $context [ 'subject' ], $variables );
$body = strtr ( $context [ 'message' ], $variables );
$message [ 'subject' ] .= str_replace ( array ( " \r " , " \n " ), '' , $subject );
$message [ 'body' ][] = drupal_html_to_text ( $body );
}
/**
* Add a list of cache tables to be cleared .
*
* This hook allows your module to add cache table names to the list of cache
* tables that will be cleared by the Clear button on the Performance page or
* whenever drupal_flush_all_caches is invoked .
*
* @ return
* An array of cache table names .
2010-06-29 00:23:57 +00:00
*
* @ see drupal_flush_all_caches ()
2008-11-25 02:37:33 +00:00
*/
function hook_flush_caches () {
return array ( 'cache_example' );
}
/**
* Perform necessary actions after modules are installed .
*
2010-06-26 12:34:44 +00:00
* This function differs from hook_install () in that it gives all other modules
* a chance to perform actions when a module is installed , whereas
* hook_install () is only called on the module actually being installed . See
* module_enable () for a detailed description of the order in which install and
* enable hooks are invoked .
2008-11-25 02:37:33 +00:00
*
* @ param $modules
* An array of the installed modules .
2010-06-26 12:34:44 +00:00
*
* @ see module_enable ()
* @ see hook_modules_enabled ()
* @ see hook_install ()
2008-11-25 02:37:33 +00:00
*/
function hook_modules_installed ( $modules ) {
if ( in_array ( 'lousy_module' , $modules )) {
variable_set ( 'lousy_module_conflicting_variable' , FALSE );
}
}
/**
* Perform necessary actions after modules are enabled .
*
2010-06-26 12:34:44 +00:00
* This function differs from hook_enable () in that it gives all other modules a
* chance to perform actions when modules are enabled , whereas hook_enable () is
* only called on the module actually being enabled . See module_enable () for a
* detailed description of the order in which install and enable hooks are
* invoked .
2008-11-25 02:37:33 +00:00
*
* @ param $modules
* An array of the enabled modules .
2010-06-26 12:34:44 +00:00
*
* @ see hook_enable ()
* @ see hook_modules_installed ()
* @ see module_enable ()
2008-11-25 02:37:33 +00:00
*/
function hook_modules_enabled ( $modules ) {
if ( in_array ( 'lousy_module' , $modules )) {
drupal_set_message ( t ( 'mymodule is not compatible with lousy_module' ), 'error' );
mymodule_disable_functionality ();
}
}
/**
* Perform necessary actions after modules are disabled .
*
2010-06-26 12:34:44 +00:00
* This function differs from hook_disable () in that it gives all other modules
* a chance to perform actions when modules are disabled , whereas hook_disable ()
* is only called on the module actually being disabled .
2008-11-25 02:37:33 +00:00
*
* @ param $modules
* An array of the disabled modules .
2010-06-26 12:34:44 +00:00
*
* @ see hook_disable ()
* @ see hook_modules_uninstalled ()
2008-11-25 02:37:33 +00:00
*/
function hook_modules_disabled ( $modules ) {
if ( in_array ( 'lousy_module' , $modules )) {
mymodule_enable_functionality ();
}
}
/**
* Perform necessary actions after modules are uninstalled .
*
2010-06-26 12:34:44 +00:00
* This function differs from hook_uninstall () in that it gives all other
* modules a chance to perform actions when a module is uninstalled , whereas
* hook_uninstall () is only called on the module actually being uninstalled .
2008-11-25 02:37:33 +00:00
*
* It is recommended that you implement this module if your module
* stores data that may have been set by other modules .
*
* @ param $modules
2010-02-20 14:35:03 +00:00
* An array of the uninstalled modules .
2010-06-26 12:34:44 +00:00
*
* @ see hook_uninstall ()
* @ see hook_modules_disabled ()
2008-11-25 02:37:33 +00:00
*/
function hook_modules_uninstalled ( $modules ) {
foreach ( $modules as $module ) {
db_delete ( 'mymodule_table' )
-> condition ( 'module' , $module )
-> execute ();
}
mymodule_cache_rebuild ();
}
2009-07-27 19:53:18 +00:00
/**
* Registers PHP stream wrapper implementations associated with a module .
*
* Provide a facility for managing and querying user - defined stream wrappers
* in PHP . PHP 's internal stream_get_wrappers() doesn' t return the class
* registered to handle a stream , which we need to be able to find the handler
* for class instantiation .
*
* If a module registers a scheme that is already registered with PHP , it will
* be unregistered and replaced with the specified class .
*
* @ return
* A nested array , keyed first by scheme name ( " public " for " public:// " ),
* then keyed by the following values :
* - 'name' A short string to name the wrapper .
* - 'class' A string specifying the PHP class that implements the
* DrupalStreamWrapperInterface interface .
* - 'description' A string with a short description of what the wrapper does .
2010-02-07 00:42:00 +00:00
* - 'type' A bitmask of flags indicating what type of streams this wrapper
* will access - local or remote , readable and / or writeable , etc . Many
2010-03-06 06:39:01 +00:00
* shortcut constants are defined in stream_wrappers . inc .
2009-07-27 19:53:18 +00:00
*
* @ see file_get_stream_wrappers ()
* @ see hook_stream_wrappers_alter ()
* @ see system_stream_wrappers ()
*/
function hook_stream_wrappers () {
return array (
'public' => array (
'name' => t ( 'Public files' ),
'class' => 'DrupalPublicStreamWrapper' ,
'description' => t ( 'Public local files served by the webserver.' ),
),
'private' => array (
'name' => t ( 'Private files' ),
'class' => 'DrupalPrivateStreamWrapper' ,
'description' => t ( 'Private local files served by Drupal.' ),
),
'temp' => array (
'name' => t ( 'Temporary files' ),
'class' => 'DrupalTempStreamWrapper' ,
'description' => t ( 'Temporary local files for upload and previews.' ),
2010-02-07 00:42:00 +00:00
'type' => STREAM_WRAPPERS_HIDDEN ,
2009-07-27 19:53:18 +00:00
)
);
}
/**
* Alters the list of PHP stream wrapper implementations .
*
* @ see file_get_stream_wrappers ()
* @ see hook_stream_wrappers ()
*/
function hook_stream_wrappers_alter ( & $wrappers ) {
// Change the name of private files to reflect the performance.
$wrappers [ 'private' ][ 'name' ] = t ( 'Slow files' );
}
2008-11-25 02:37:33 +00:00
/**
2008-12-31 11:08:47 +00:00
* Load additional information into file objects .
2008-11-25 02:37:33 +00:00
*
2008-12-31 11:08:47 +00:00
* file_load_multiple () calls this hook to allow modules to load
* additional information into each file .
2008-11-25 02:37:33 +00:00
*
2008-12-31 11:08:47 +00:00
* @ param $files
* An array of file objects , indexed by fid .
2008-11-25 02:37:33 +00:00
*
2008-12-31 11:08:47 +00:00
* @ see file_load_multiple ()
* @ see upload_file_load ()
2008-11-25 02:37:33 +00:00
*/
2008-12-31 11:08:47 +00:00
function hook_file_load ( $files ) {
2008-11-25 02:37:33 +00:00
// Add the upload specific data into the file object.
2008-12-31 11:08:47 +00:00
$result = db_query ( 'SELECT * FROM {upload} u WHERE u.fid IN (:fids)' , array ( ':fids' => array_keys ( $files ))) -> fetchAll ( PDO :: FETCH_ASSOC );
foreach ( $result as $record ) {
foreach ( $record as $key => $value ) {
$files [ $record [ 'fid' ]] -> $key = $value ;
}
2008-11-25 02:37:33 +00:00
}
}
/**
* Check that files meet a given criteria .
*
* This hook lets modules perform additional validation on files . They ' re able
* to report a failure by returning one or more error messages .
*
* @ param $file
* The file object being validated .
* @ return
* An array of error messages . If there are no problems with the file return
* an empty array .
*
* @ see file_validate ()
*/
function hook_file_validate ( & $file ) {
$errors = array ();
if ( empty ( $file -> filename )) {
$errors [] = t ( " The file's name is empty. Please give a name to the file. " );
}
if ( strlen ( $file -> filename ) > 255 ) {
$errors [] = t ( " The file's name exceeds the 255 characters limit. Please rename the file and try again. " );
}
return $errors ;
}
/**
* Respond to a file being added .
*
* This hook is called when a file has been added to the database . The hook
* doesn ' t distinguish between files created as a result of a copy or those
* created by an upload .
*
* @ param $file
* The file that has just been created .
*
* @ see file_save ()
*/
2010-05-07 12:59:07 +00:00
function hook_file_insert ( $file ) {
2008-11-25 02:37:33 +00:00
}
/**
* Respond to a file being updated .
*
* This hook is called when file_save () is called on an existing file .
*
* @ param $file
* The file that has just been updated .
*
* @ see file_save ()
*/
2010-05-07 12:59:07 +00:00
function hook_file_update ( $file ) {
2008-11-25 02:37:33 +00:00
}
/**
* Respond to a file that has been copied .
*
* @ param $file
* The newly copied file object .
* @ param $source
* The original file before the copy .
*
* @ see file_copy ()
*/
function hook_file_copy ( $file , $source ) {
}
/**
* Respond to a file that has been moved .
*
* @ param $file
* The updated file object after the move .
* @ param $source
* The original file object before the move .
*
* @ see file_move ()
*/
function hook_file_move ( $file , $source ) {
}
/**
* Report the number of times a file is referenced by a module .
*
* This hook is called to determine if a files is in use . Multiple modules may
* be referencing the same file and to prevent one from deleting a file used by
* another this hook is called .
*
* @ param $file
* The file object being checked for references .
* @ return
* If the module uses this file return an array with the module name as the
* key and the value the number of times the file is used .
*
* @ see file_delete ()
* @ see upload_file_references ()
*/
function hook_file_references ( $file ) {
2010-03-21 20:28:28 +00:00
// If user.module is still using a file, do not let other modules delete it.
2010-03-25 12:19:34 +00:00
$file_used = ( bool ) db_query_range ( 'SELECT 1 FROM {user} WHERE pictire = :fid' , 0 , 1 , array ( ':fid' => $file -> fid )) -> fetchField ();
if ( $file_used ) {
2008-11-25 02:37:33 +00:00
// Return the name of the module and how many references it has to the file.
2010-03-25 12:19:34 +00:00
return array ( 'user' => 1 );
2008-11-25 02:37:33 +00:00
}
}
/**
* Respond to a file being deleted .
*
* @ param $file
* The file that has just been deleted .
*
* @ see file_delete ()
* @ see upload_file_delete ()
*/
function hook_file_delete ( $file ) {
// Delete all information associated with the file.
db_delete ( 'upload' ) -> condition ( 'fid' , $file -> fid ) -> execute ();
}
/**
* Control access to private file downloads and specify HTTP headers .
*
* This hook allows modules enforce permissions on file downloads when the
* private file download method is selected . Modules can also provide headers
* to specify information like the file ' s name or MIME type .
*
2009-10-20 00:55:30 +00:00
* @ param $uri
* The URI of the file .
2008-11-25 02:37:33 +00:00
* @ return
* If the user does not have permission to access the file , return - 1. If the
* user has permission , return an array with the appropriate headers . If the
* file is not controlled by the current module , the return value should be
* NULL .
*
* @ see file_download ()
* @ see upload_file_download ()
*/
2009-10-20 00:55:30 +00:00
function hook_file_download ( $uri ) {
2008-11-25 02:37:33 +00:00
// Check if the file is controlled by the current module.
2009-10-20 00:55:30 +00:00
if ( ! file_prepare_directory ( $uri )) {
$uri = FALSE ;
2009-08-17 19:14:42 +00:00
}
2010-04-10 17:30:15 +00:00
$result = db_query ( " SELECT f.* FROM { file_managed} f INNER JOIN { upload} u ON f.fid = u.fid WHERE uri = :uri " , array ( 'uri' => $uri ));
2009-05-16 18:34:23 +00:00
foreach ( $result as $file ) {
2008-11-25 02:37:33 +00:00
if ( ! user_access ( 'view uploaded files' )) {
return - 1 ;
}
return array (
2009-04-24 08:16:56 +00:00
'Content-Type' => $file -> filemime ,
'Content-Length' => $file -> filesize ,
2008-11-25 02:37:33 +00:00
);
}
}
/**
2009-08-29 06:57:27 +00:00
* Alter the URL to a file .
*
* This hook is called from file_create_url (), and is called fairly
* frequently ( 10 + times per page ), depending on how many files there are in a
* given page .
* If CSS and JS aggregation are disabled , this can become very frequently
* ( 50 + times per page ) so performance is critical .
*
* This function should alter the URI , if it wants to rewrite the file URL .
*
* @ param $uri
* The URI to a file for which we need an external URL , or the path to a
* shipped file .
*/
function hook_file_url_alter ( & $uri ) {
global $user ;
// User 1 will always see the local file in this example.
if ( $user -> uid == 1 ) {
return ;
}
$cdn1 = 'http://cdn1.example.com' ;
$cdn2 = 'http://cdn2.example.com' ;
$cdn_extensions = array ( 'css' , 'js' , 'gif' , 'jpg' , 'jpeg' , 'png' );
// Most CDNs don't support private file transfers without a lot of hassle,
// so don't support this in the common case.
$schemes = array ( 'public' );
$scheme = file_uri_scheme ( $uri );
// Only serve shipped files and public created files from the CDN.
if ( ! $scheme || in_array ( $scheme , $schemes )) {
// Shipped files.
if ( ! $scheme ) {
$path = $uri ;
}
// Public created files.
else {
$wrapper = file_stream_wrapper_get_instance_by_scheme ( $scheme );
$path = $wrapper -> getDirectoryPath () . '/' . file_uri_target ( $uri );
}
// Clean up Windows paths.
$path = str_replace ( '\\' , '/' , $path );
// Serve files with one of the CDN extensions from CDN 1, all others from
// CDN 2.
$pathinfo = pathinfo ( $path );
if ( array_key_exists ( 'extension' , $pathinfo ) && in_array ( $pathinfo [ 'extension' ], $cdn_extensions )) {
$uri = $cdn1 . '/' . $path ;
}
else {
$uri = $cdn2 . '/' . $path ;
}
}
}
/**
2008-11-25 02:37:33 +00:00
* Check installation requirements and do status reporting .
*
* This hook has two closely related uses , determined by the $phase argument :
* checking installation requirements ( $phase == 'install' )
* and status reporting ( $phase == 'runtime' ) .
*
* Note that this hook , like all others dealing with installation and updates ,
* must reside in a module_name . install file , or it will not properly abort
* the installation of the module if a critical requirement is missing .
*
* During the 'install' phase , modules can for example assert that
* library or server versions are available or sufficient .
* Note that the installation of a module can happen during installation of
* Drupal itself ( by install . php ) with an installation profile or later by hand .
* As a consequence , install - time requirements must be checked without access
* to the full Drupal API , because it is not available during install . php .
2008-12-30 16:43:20 +00:00
* For localization you should for example use $t = get_t () to
* retrieve the appropriate localization function name ( t () or st ()) .
2008-11-25 02:37:33 +00:00
* If a requirement has a severity of REQUIREMENT_ERROR , install . php will abort
* or at least the module will not install .
* Other severity levels have no effect on the installation .
* Module dependencies do not belong to these installation requirements ,
* but should be defined in the module ' s . info file .
*
* The 'runtime' phase is not limited to pure installation requirements
* but can also be used for more general status information like maintenance
* tasks and security issues .
* The returned 'requirements' will be listed on the status report in the
* administration section , with indication of the severity level .
* Moreover , any requirement with a severity of REQUIREMENT_ERROR severity will
* result in a notice on the the administration overview page .
*
* @ param $phase
* The phase in which hook_requirements is run :
* - 'install' : the module is being installed .
* - 'runtime' : the runtime requirements are being checked and shown on the
* status report page .
*
* @ return
* A keyed array of requirements . Each requirement is itself an array with
* the following items :
* - 'title' : the name of the requirement .
* - 'value' : the current value ( e . g . version , time , level , ... ) . During
* install phase , this should only be used for version numbers , do not set
* it if not applicable .
* - 'description' : description of the requirement / status .
* - 'severity' : the requirement ' s result / severity level , one of :
* - REQUIREMENT_INFO : For info only .
* - REQUIREMENT_OK : The requirement is satisfied .
* - REQUIREMENT_WARNING : The requirement failed with a warning .
* - REQUIREMENT_ERROR : The requirement failed with an error .
*/
function hook_requirements ( $phase ) {
$requirements = array ();
// Ensure translations don't break at install time
$t = get_t ();
// Report Drupal version
if ( $phase == 'runtime' ) {
$requirements [ 'drupal' ] = array (
'title' => $t ( 'Drupal' ),
'value' => VERSION ,
'severity' => REQUIREMENT_INFO
);
}
// Test PHP version
$requirements [ 'php' ] = array (
'title' => $t ( 'PHP' ),
'value' => ( $phase == 'runtime' ) ? l ( phpversion (), 'admin/logs/status/php' ) : phpversion (),
);
if ( version_compare ( phpversion (), DRUPAL_MINIMUM_PHP ) < 0 ) {
$requirements [ 'php' ][ 'description' ] = $t ( 'Your PHP installation is too old. Drupal requires at least PHP %version.' , array ( '%version' => DRUPAL_MINIMUM_PHP ));
$requirements [ 'php' ][ 'severity' ] = REQUIREMENT_ERROR ;
}
// Report cron status
if ( $phase == 'runtime' ) {
2009-01-31 16:50:57 +00:00
$cron_last = variable_get ( 'cron_last' );
2008-11-25 02:37:33 +00:00
if ( is_numeric ( $cron_last )) {
$requirements [ 'cron' ][ 'value' ] = $t ( 'Last run !time ago' , array ( '!time' => format_interval ( REQUEST_TIME - $cron_last )));
}
else {
$requirements [ 'cron' ] = array (
2010-01-09 23:03:22 +00:00
'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' )),
2008-11-25 02:37:33 +00:00
'severity' => REQUIREMENT_ERROR ,
'value' => $t ( 'Never run' ),
);
}
$requirements [ 'cron' ][ 'description' ] .= ' ' . t ( 'You can <a href="@cron">run cron manually</a>.' , array ( '@cron' => url ( 'admin/logs/status/run-cron' )));
$requirements [ 'cron' ][ 'title' ] = $t ( 'Cron maintenance tasks' );
}
return $requirements ;
}
/**
* Define the current version of the database schema .
*
* A Drupal schema definition is an array structure representing one or
* more tables and their related keys and indexes . A schema is defined by
* hook_schema () which must live in your module ' s . install file .
*
* By implementing hook_schema () and specifying the tables your module
* declares , you can easily create and drop these tables on all
* supported database engines . You don ' t have to deal with the
* different SQL dialects for table creation and alteration of the
* supported database engines .
*
* See the Schema API Handbook at http :// drupal . org / node / 146843 for
* details on schema definition structures .
*
* @ return
2008-12-20 18:24:41 +00:00
* A schema definition structure array . For each element of the
2008-11-25 02:37:33 +00:00
* array , the key is a table name and the value is a table structure
* definition .
*/
function hook_schema () {
$schema [ 'node' ] = array (
// example (partial) specification for table "node"
2009-05-20 19:56:36 +00:00
'description' => 'The base table for nodes.' ,
2008-11-25 02:37:33 +00:00
'fields' => array (
'nid' => array (
2009-05-20 19:56:36 +00:00
'description' => 'The primary identifier for a node.' ,
2008-11-25 02:37:33 +00:00
'type' => 'serial' ,
'unsigned' => TRUE ,
'not null' => TRUE ),
'vid' => array (
2009-05-20 19:56:36 +00:00
'description' => 'The current {node_revision}.vid version identifier.' ,
2008-11-25 02:37:33 +00:00
'type' => 'int' ,
'unsigned' => TRUE ,
'not null' => TRUE ,
'default' => 0 ),
'type' => array (
2009-05-20 19:56:36 +00:00
'description' => 'The {node_type} of this node.' ,
2008-11-25 02:37:33 +00:00
'type' => 'varchar' ,
'length' => 32 ,
'not null' => TRUE ,
'default' => '' ),
'title' => array (
2009-05-20 19:56:36 +00:00
'description' => 'The title of this node, always treated a non-markup plain text.' ,
2008-11-25 02:37:33 +00:00
'type' => 'varchar' ,
'length' => 255 ,
'not null' => TRUE ,
'default' => '' ),
),
'indexes' => array (
'node_changed' => array ( 'changed' ),
'node_created' => array ( 'created' ),
),
'unique keys' => array (
'nid_vid' => array ( 'nid' , 'vid' ),
'vid' => array ( 'vid' )
),
'primary key' => array ( 'nid' ),
);
return $schema ;
}
/**
* Perform alterations to existing database schemas .
*
* When a module modifies the database structure of another module ( by
* changing , adding or removing fields , keys or indexes ), it should
2010-07-10 01:59:02 +00:00
* implement hook_schema_alter () to update the default $schema to take its
* changes into account .
2008-11-25 02:37:33 +00:00
*
* See hook_schema () for details on the schema definition structure .
*
* @ param $schema
* Nested array describing the schemas for all modules .
*/
function hook_schema_alter ( & $schema ) {
// Add field to existing schema.
2009-02-26 07:30:29 +00:00
$schema [ 'users' ][ 'fields' ][ 'timezone_id' ] = array (
2008-11-25 02:37:33 +00:00
'type' => 'int' ,
'not null' => TRUE ,
'default' => 0 ,
2009-05-20 19:56:36 +00:00
'description' => 'Per-user timezone configuration.' ,
2008-11-25 02:37:33 +00:00
);
}
2009-01-04 19:56:51 +00:00
/**
* Perform alterations to a structured query .
*
* Structured ( aka dynamic ) queries that have tags associated may be altered by any module
* before the query is executed .
*
2010-06-29 00:23:57 +00:00
* @ param $query
* A Query object describing the composite parts of a SQL query .
*
2009-01-04 19:56:51 +00:00
* @ see hook_query_TAG_alter ()
* @ see node_query_node_access_alter ()
2009-04-20 07:42:22 +00:00
* @ see QueryAlterableInterface
* @ see SelectQueryInterface
2009-01-04 19:56:51 +00:00
*/
function hook_query_alter ( QueryAlterableInterface $query ) {
2009-04-20 07:42:22 +00:00
if ( $query -> hasTag ( 'micro_limit' )) {
$query -> range ( 0 , 2 );
}
2009-01-04 19:56:51 +00:00
}
/**
* Perform alterations to a structured query for a given tag .
*
2010-06-29 00:23:57 +00:00
* @ param $query
* An Query object describing the composite parts of a SQL query .
*
2009-01-04 19:56:51 +00:00
* @ see hook_query_alter ()
* @ see node_query_node_access_alter ()
2009-04-20 07:42:22 +00:00
* @ see QueryAlterableInterface
* @ see SelectQueryInterface
2009-01-04 19:56:51 +00:00
*/
function hook_query_TAG_alter ( QueryAlterableInterface $query ) {
// Skip the extra expensive alterations if site has no node access control modules.
if ( ! node_access_view_all_nodes ()) {
// Prevent duplicates records.
$query -> distinct ();
// The recognized operations are 'view', 'update', 'delete'.
if ( ! $op = $query -> getMetaData ( 'op' )) {
$op = 'view' ;
}
// Skip the extra joins and conditions for node admins.
if ( ! user_access ( 'bypass node access' )) {
// The node_access table has the access grants for any given node.
2010-06-25 19:33:47 +00:00
$access_alias = $query -> join ( 'node_access' , 'na' , '%alias.nid = n.nid' );
2009-01-04 19:56:51 +00:00
$or = db_or ();
// If any grant exists for the specified user, then user has access to the node for the specified operation.
foreach ( node_access_grants ( $op , $query -> getMetaData ( 'account' )) as $realm => $gids ) {
foreach ( $gids as $gid ) {
$or -> condition ( db_and ()
2010-06-25 19:33:47 +00:00
-> condition ( $access_alias . '.gid' , $gid )
-> condition ( $access_alias . '.realm' , $realm )
2009-01-04 19:56:51 +00:00
);
}
}
if ( count ( $or -> conditions ())) {
$query -> condition ( $or );
}
2009-01-26 14:08:44 +00:00
2010-06-25 19:33:47 +00:00
$query -> condition ( $access_alias . 'grant_' . $op , 1 , '>=' );
2009-01-04 19:56:51 +00:00
}
}
}
2008-11-25 02:37:33 +00:00
/**
2009-09-10 06:38:20 +00:00
* Perform setup tasks when the module is installed .
*
* If the module implements hook_schema (), the database tables will
* be created before this hook is fired .
2008-11-25 02:37:33 +00:00
*
2010-06-26 12:34:44 +00:00
* This hook will only be called the first time a module is enabled or after it
* is re - enabled after being uninstalled . The module ' s schema version will be
* set to the module ' s greatest numbered update hook . Because of this , anytime a
* hook_update_N () is added to the module , this function needs to be updated to
* reflect the current version of the database schema .
2008-11-25 02:37:33 +00:00
*
2009-01-29 14:37:40 +00:00
* See the Schema API documentation at
* @ link http :// drupal . org / node / 146843 http :// drupal . org / node / 146843 @ endlink
2009-09-10 06:38:20 +00:00
* for details on hook_schema and how database tables are defined .
2008-11-25 02:37:33 +00:00
*
* Note that since this function is called from a full bootstrap , all functions
* ( including those in modules enabled by the current page request ) are
* available when this hook is called . Use cases could be displaying a user
* message , or calling a module function necessary for initial setup , etc .
*
* Please be sure that anything added or modified in this function that can
* be removed during uninstall should be removed with hook_uninstall () .
*
2009-09-10 06:38:20 +00:00
* @ see hook_schema ()
2010-06-26 12:34:44 +00:00
* @ see module_enable ()
* @ see hook_enable ()
* @ see hook_disable ()
* @ see hook_uninstall ()
* @ see hook_modules_installed ()
2008-11-25 02:37:33 +00:00
*/
function hook_install () {
2009-09-10 06:38:20 +00:00
// Populate the default {node_access} record.
db_insert ( 'node_access' )
-> fields ( array (
'nid' => 0 ,
'gid' => 0 ,
'realm' => 'all' ,
'grant_view' => 1 ,
'grant_update' => 0 ,
'grant_delete' => 0 ,
))
-> execute ();
2008-11-25 02:37:33 +00:00
}
/**
2010-02-23 05:04:50 +00:00
* Perform a single update .
2008-11-25 02:37:33 +00:00
*
2010-02-23 05:04:50 +00:00
* For each patch which requires a database change add a new hook_update_N ()
2010-03-06 06:39:01 +00:00
* which will be called by update . php . The database updates are numbered
2010-02-23 05:04:50 +00:00
* sequentially according to the version of Drupal you are compatible with .
2008-11-25 02:37:33 +00:00
*
2009-01-29 14:37:40 +00:00
* Schema updates should adhere to the Schema API :
* @ link http :// drupal . org / node / 150215 http :// drupal . org / node / 150215 @ endlink
2008-11-25 02:37:33 +00:00
*
* Database updates consist of 3 parts :
* - 1 digit for Drupal core compatibility
* - 1 digit for your module ' s major release version ( e . g . is this the 5. x - 1. * ( 1 ) or 5. x - 2. * ( 2 ) series of your module ? )
* - 2 digits for sequential counting starting with 00
*
* The 2 nd digit should be 0 for initial porting of your module to a new Drupal
* core API .
*
* Examples :
* - mymodule_update_5200 ()
* - This is the first update to get the database ready to run mymodule 5. x - 2. *.
* - mymodule_update_6000 ()
* - This is the required update for mymodule to run with Drupal core API 6. x .
* - mymodule_update_6100 ()
* - This is the first update to get the database ready to run mymodule 6. x - 1. *.
* - mymodule_update_6200 ()
* - This is the first update to get the database ready to run mymodule 6. x - 2. *.
* Users can directly update from 5. x - 2. * to 6. x - 2. * and they get all 60 XX
* and 62 XX updates , but not 61 XX updates , because those reside in the
* 6. x - 1. x branch only .
*
* A good rule of thumb is to remove updates older than two major releases of
2009-01-17 20:28:46 +00:00
* Drupal . See hook_update_last_removed () to notify Drupal about the removals .
2008-11-25 02:37:33 +00:00
*
* Never renumber update functions .
*
* Further information about releases and release numbers :
2009-01-29 14:37:40 +00:00
* - @ link http :// drupal . org / handbook / version - info http :// drupal . org / handbook / version - info @ endlink
* - @ link http :// drupal . org / node / 93999 http :// drupal . org / node / 93999 @ endlink ( Overview of contributions branches and tags )
* - @ link http :// drupal . org / handbook / cvs / releases http :// drupal . org / handbook / cvs / releases @ endlink
2008-11-25 02:37:33 +00:00
*
* Implementations of this hook should be placed in a mymodule . install file in
2009-01-17 20:28:46 +00:00
* the same directory as mymodule . module . Drupal core ' s updates are implemented
2008-11-25 02:37:33 +00:00
* using the system module as a name and stored in database / updates . inc .
*
2009-05-24 17:39:35 +00:00
* If your update task is potentially time - consuming , you ' ll need to implement a
* multipass update to avoid PHP timeouts . Multipass updates use the $sandbox
* parameter provided by the batch API ( normally , $context [ 'sandbox' ]) to store
2009-09-29 15:13:57 +00:00
* information between successive calls , and the $sandbox [ '#finished' ] value
2009-03-29 23:11:09 +00:00
* to provide feedback regarding completion level .
*
2009-05-24 17:39:35 +00:00
* See the batch operations page for more information on how to use the batch API :
2009-03-29 23:11:09 +00:00
* @ link http :// drupal . org / node / 146843 http :// drupal . org / node / 146843 @ endlink
*
2009-09-29 15:13:57 +00:00
* @ throws DrupalUpdateException , PDOException
* In case of error , update hooks should throw an instance of DrupalUpdateException
* with a meaningful message for the user . If a database query fails for whatever
* reason , it will throw a PDOException .
*
* @ return
* Optionally update hooks may return a translated string that will be displayed
* to the user . If no message is returned , no message will be presented to the
* user .
2008-11-25 02:37:33 +00:00
*/
2009-11-15 08:48:39 +00:00
function hook_update_N ( & $sandbox ) {
// For non-multipass updates, the signature can simply be;
// function hook_update_N() {
2009-03-29 23:11:09 +00:00
// For most updates, the following is sufficient.
2009-09-29 15:13:57 +00:00
db_add_field ( 'mytable1' , 'newcol' , array ( 'type' => 'int' , 'not null' => TRUE , 'description' => 'My new integer column.' ));
2009-05-24 17:39:35 +00:00
// However, for more complex operations that may take a long time,
2009-03-29 23:11:09 +00:00
// you may hook into Batch API as in the following example.
2009-05-24 17:39:35 +00:00
2009-03-29 23:11:09 +00:00
// Update 3 users at a time to have an exclamation point after their names.
// (They're really happy that we can do batch API in this hook!)
if ( ! isset ( $sandbox [ 'progress' ])) {
$sandbox [ 'progress' ] = 0 ;
$sandbox [ 'current_uid' ] = 0 ;
// We'll -1 to disregard the uid 0...
$sandbox [ 'max' ] = db_query ( 'SELECT COUNT(DISTINCT uid) FROM {users}' ) -> fetchField () - 1 ;
}
2010-07-07 00:57:44 +00:00
$users = db_select ( 'users' , 'u' )
2009-05-16 18:34:23 +00:00
-> fields ( 'u' , array ( 'uid' , 'name' ))
-> condition ( 'uid' , $sandbox [ 'current_uid' ], '>' )
-> range ( 0 , 3 )
-> orderBy ( 'uid' , 'ASC' )
-> execute ();
2010-07-07 00:57:44 +00:00
2009-03-29 23:11:09 +00:00
foreach ( $users as $user ) {
$user -> name .= '!' ;
2009-09-29 15:13:57 +00:00
db_update ( 'users' )
-> fields ( array ( 'name' => $user -> name ))
-> condition ( 'uid' , $user -> uid )
-> execute ();
2009-05-24 17:39:35 +00:00
2009-03-29 23:11:09 +00:00
$sandbox [ 'progress' ] ++ ;
$sandbox [ 'current_uid' ] = $user -> uid ;
}
2009-09-29 15:13:57 +00:00
$sandbox [ '#finished' ] = empty ( $sandbox [ 'max' ]) ? 1 : ( $sandbox [ 'progress' ] / $sandbox [ 'max' ]);
// To display a message to the user when the update is completed, return it.
// If you do not want to display a completion message, simply return nothing.
return t ( 'The update did what it was supposed to do.' );
2009-05-24 17:39:35 +00:00
2009-09-29 15:13:57 +00:00
// In case of an error, simply throw an exception with an error message.
throw new DrupalUpdateException ( 'Something went wrong; here is what you should do.' );
2008-11-25 02:37:33 +00:00
}
2010-02-03 18:16:23 +00:00
/**
* Return an array of information about module update dependencies .
*
* This can be used to indicate update functions from other modules that your
* module ' s update functions depend on , or vice versa . It is used by the update
* system to determine the appropriate order in which updates should be run , as
* well as to search for missing dependencies .
*
* Implementations of this hook should be placed in a mymodule . install file in
* the same directory as mymodule . module .
*
* @ return
* A multidimensional array containing information about the module update
* dependencies . The first two levels of keys represent the module and update
* number ( respectively ) for which information is being returned , and the
* value is an array of information about that update ' s dependencies . Within
* this array , each key represents a module , and each value represents the
* number of an update function within that module . In the event that your
* update function depends on more than one update from a particular module ,
* you should always list the highest numbered one here ( since updates within
* a given module always run in numerical order ) .
*
* @ see update_resolve_dependencies ()
* @ see hook_update_N ()
*/
function hook_update_dependencies () {
// Indicate that the mymodule_update_7000() function provided by this module
// must run after the another_module_update_7002() function provided by the
// 'another_module' module.
$dependencies [ 'mymodule' ][ 7000 ] = array (
'another_module' => 7002 ,
);
// Indicate that the mymodule_update_7001() function provided by this module
// must run before the yet_another_module_update_7004() function provided by
// the 'yet_another_module' module. (Note that declaring dependencies in this
// direction should be done only in rare situations, since it can lead to the
// following problem: If a site has already run the yet_another_module
// module's database updates before it updates its codebase to pick up the
// newest mymodule code, then the dependency declared here will be ignored.)
$dependencies [ 'yet_another_module' ][ 7004 ] = array (
'mymodule' => 7001 ,
);
return $dependencies ;
}
2009-01-17 20:28:46 +00:00
/**
* Return a number which is no longer available as hook_update_N () .
*
* If you remove some update functions from your mymodule . install file , you
* should notify Drupal of those missing functions . This way , Drupal can
* ensure that no update is accidentally skipped .
*
* Implementations of this hook should be placed in a mymodule . install file in
* the same directory as mymodule . module .
*
* @ return
* An integer , corresponding to hook_update_N () which has been removed from
* mymodule . install .
*
* @ see hook_update_N ()
*/
function hook_update_last_removed () {
// We've removed the 5.x-1.x version of mymodule, including database updates.
// The next update function is mymodule_update_5200().
return 5103 ;
}
2008-11-25 02:37:33 +00:00
/**
* Remove any information that the module sets .
*
* The information that the module should remove includes :
* - variables that the module has set using variable_set () or system_settings_form ()
* - modifications to existing tables
*
2010-06-29 00:23:57 +00:00
* The module should not remove its entry from the { system } table . Database
* tables defined by hook_schema () will be removed automatically .
2008-11-25 02:37:33 +00:00
*
2009-09-10 06:38:20 +00:00
* The uninstall hook will fire when the module gets uninstalled but before the
* module ' s database tables are removed , allowing your module to query its own
* tables during this routine .
*
* @ see hook_install ()
* @ see hook_schema ()
2010-06-26 12:34:44 +00:00
* @ see hook_disable ()
* @ see hook_modules_uninstalled ()
2008-11-25 02:37:33 +00:00
*/
function hook_uninstall () {
variable_del ( 'upload_file_types' );
}
/**
* Perform necessary actions after module is enabled .
*
2010-06-26 12:34:44 +00:00
* The hook is called every time the module is enabled .
*
* @ see module_enable ()
* @ see hook_install ()
* @ see hook_modules_enabled ()
2008-11-25 02:37:33 +00:00
*/
function hook_enable () {
mymodule_cache_rebuild ();
}
/**
* Perform necessary actions before module is disabled .
*
2010-06-26 12:34:44 +00:00
* The hook is called every time the module is disabled .
*
* @ see hook_uninstall ()
* @ see hook_modules_disabled ()
2008-11-25 02:37:33 +00:00
*/
function hook_disable () {
mymodule_cache_rebuild ();
}
2009-06-08 09:23:55 +00:00
/**
* Perform necessary alterations to the list of files parsed by the registry .
*
* Modules can manually modify the list of files before the registry parses
* them . The $modules array provides the . info file information , which includes
* the list of files registered to each module . Any files in the list can then
* be added to the list of files that the registry will parse , or modify
* attributes of a file .
*
* A necessary alteration made by the core SimpleTest module is to force . test
* files provided by disabled modules into the list of files parsed by the
* registry .
*
* @ param $files
* List of files to be parsed by the registry . The list will contain
* files found in each enabled module ' s info file and the core includes
* directory . The array is keyed by the file path and contains an array of
* the related module ' s name and weight as used internally by
2009-12-28 10:48:51 +00:00
* _registry_update () and related functions .
2009-06-08 09:23:55 +00:00
*
* For example :
* @ code
* $files [ " modules/system/system.module " ] = array (
* 'module' => 'system' ,
* 'weight' => 0 ,
* );
* @ endcode
* @ param $modules
2009-12-28 10:48:51 +00:00
* An array containing all module information stored in the { system } table .
* Each element of the array also contains the module ' s . info file
* information in the property 'info' . An additional 'dir' property has been
* added to the module information which provides the path to the directory
* in which the module resides . The example shows how to take advantage of
* both properties .
*
* @ see _registry_update ()
2009-06-08 09:23:55 +00:00
* @ see simpletest_test_get_all ()
*/
2009-12-28 10:48:51 +00:00
function hook_registry_files_alter ( & $files , $modules ) {
2009-06-08 09:23:55 +00:00
foreach ( $modules as $module ) {
// Only add test files for disabled modules, as enabled modules should
// already include any test files they provide.
if ( ! $module -> status ) {
$dir = $module -> dir ;
foreach ( $module -> info [ 'files' ] as $file ) {
if ( substr ( $file , - 5 ) == '.test' ) {
$files [ " $dir / $file " ] = array ( 'module' => $module -> name , 'weight' => $module -> weight );
}
}
}
}
}
2009-07-15 02:08:41 +00:00
/**
2009-07-28 12:13:47 +00:00
* Return an array of tasks to be performed by an installation profile .
*
* Any tasks you define here will be run , in order , after the installer has
* finished the site configuration step but before it has moved on to the
* final import of languages and the end of the installation . You can have any
* number of custom tasks to perform during this phase .
*
* Each task you define here corresponds to a callback function which you must
* separately define and which is called when your task is run . This function
* will receive the global installation state variable , $install_state , as
* input , and has the opportunity to access or modify any of its settings . See
* the install_state_defaults () function in the installer for the list of
* $install_state settings used by Drupal core .
*
* At the end of your task function , you can indicate that you want the
* installer to pause and display a page to the user by returning any themed
* output that should be displayed on that page ( but see below for tasks that
* use the form API or batch API ; the return values of these task functions are
* handled differently ) . You should also use drupal_set_title () within the task
* callback function to set a custom page title . For some tasks , however , you
* may want to simply do some processing and pass control to the next task
* without ending the page request ; to indicate this , simply do not send back
* a return value from your task function at all . This can be used , for
* example , by installation profiles that need to configure certain site
* settings in the database without obtaining any input from the user .
*
* The task function is treated specially if it defines a form or requires
* batch processing ; in that case , you should return either the form API
* definition or batch API array , as appropriate . See below for more
* information on the 'type' key that you must define in the task definition
* to inform the installer that your task falls into one of those two
* categories . It is important to use these APIs directly , since the installer
* may be run non - interactively ( for example , via a command line script ), all
* in one page request ; in that case , the installer will automatically take
* care of submitting forms and processing batches correctly for both types of
* installations . You can inspect the $install_state [ 'interactive' ] boolean to
* see whether or not the current installation is interactive , if you need
* access to this information .
*
* Remember that a user installing Drupal interactively will be able to reload
* an installation page multiple times , so you should use variable_set () and
* variable_get () if you are collecting any data that you need to store and
* inspect later . It is important to remove any temporary variables using
* variable_del () before your last task has completed and control is handed
* back to the installer .
2009-07-15 02:08:41 +00:00
*
* @ return
2009-07-28 12:13:47 +00:00
* A keyed array of tasks the profile will perform during the final stage of
* the installation . Each key represents the name of a function ( usually a
* function defined by this profile , although that is not strictly required )
* that is called when that task is run . The values are associative arrays
* containing the following key - value pairs ( all of which are optional ) :
* - 'display_name'
* The human - readable name of the task . This will be displayed to the
* user while the installer is running , along with a list of other tasks
* that are being run . Leave this unset to prevent the task from
* appearing in the list .
* - 'display'
* This is a boolean which can be used to provide finer - grained control
* over whether or not the task will display . This is mostly useful for
* tasks that are intended to display only under certain conditions ; for
* these tasks , you can set 'display_name' to the name that you want to
* display , but then use this boolean to hide the task only when certain
* conditions apply .
* - 'type'
* A string representing the type of task . This parameter has three
* possible values :
* - 'normal' : This indicates that the task will be treated as a regular
* callback function , which does its processing and optionally returns
* HTML output . This is the default behavior which is used when 'type' is
* not set .
* - 'batch' : This indicates that the task function will return a batch
* API definition suitable for batch_set () . The installer will then take
* care of automatically running the task via batch processing .
* - 'form' : This indicates that the task function will return a standard
* form API definition ( and separately define validation and submit
* handlers , as appropriate ) . The installer will then take care of
* automatically directing the user through the form submission process .
* - 'run'
* A constant representing the manner in which the task will be run . This
* parameter has three possible values :
* - INSTALL_TASK_RUN_IF_NOT_COMPLETED : This indicates that the task will
* run once during the installation of the profile . This is the default
* behavior which is used when 'run' is not set .
* - INSTALL_TASK_SKIP : This indicates that the task will not run during
* the current installation page request . It can be used to skip running
* an installation task when certain conditions are met , even though the
* task may still show on the list of installation tasks presented to the
* user .
* - INSTALL_TASK_RUN_IF_REACHED : This indicates that the task will run
* on each installation page request that reaches it . This is rarely
* necessary for an installation profile to use ; it is primarily used by
* the Drupal installer for bootstrap - related tasks .
* - 'function'
* Normally this does not need to be set , but it can be used to force the
* installer to call a different function when the task is run ( rather
* than the function whose name is given by the array key ) . This could be
* used , for example , to allow the same function to be called by two
* different tasks .
*
* @ see install_state_defaults ()
* @ see batch_set ()
2009-07-15 02:08:41 +00:00
*/
2009-10-13 07:09:26 +00:00
function hook_install_tasks () {
2009-07-28 12:13:47 +00:00
// Here, we define a variable to allow tasks to indicate that a particular,
// processor-intensive batch process needs to be triggered later on in the
// installation.
$myprofile_needs_batch_processing = variable_get ( 'myprofile_needs_batch_processing' , FALSE );
$tasks = array (
// This is an example of a task that defines a form which the user who is
// installing the site will be asked to fill out. To implement this task,
// your profile would define a function named myprofile_data_import_form()
// as a normal form API callback function, with associated validation and
// submit handlers. In the submit handler, in addition to saving whatever
// other data you have collected from the user, you might also call
// variable_set('myprofile_needs_batch_processing', TRUE) if the user has
// entered data which requires that batch processing will need to occur
// later on.
'myprofile_data_import_form' => array (
'display_name' => st ( 'Data import options' ),
'type' => 'form' ,
2009-07-15 02:08:41 +00:00
),
2009-07-28 12:13:47 +00:00
// Similarly, to implement this task, your profile would define a function
// named myprofile_settings_form() with associated validation and submit
// handlers. This form might be used to collect and save additional
// information from the user that your profile needs. There are no extra
// steps required for your profile to act as an "installation wizard"; you
// can simply define as many tasks of type 'form' as you wish to execute,
// and the forms will be presented to the user, one after another.
'myprofile_settings_form' => array (
'display_name' => st ( 'Additional options' ),
'type' => 'form' ,
2009-07-15 02:08:41 +00:00
),
2009-07-28 12:13:47 +00:00
// This is an example of a task that performs batch operations. To
// implement this task, your profile would define a function named
// myprofile_batch_processing() which returns a batch API array definition
// that the installer will use to execute your batch operations. Due to the
// 'myprofile_needs_batch_processing' variable used here, this task will be
// hidden and skipped unless your profile set it to TRUE in one of the
// previous tasks.
'myprofile_batch_processing' => array (
'display_name' => st ( 'Import additional data' ),
'display' => $myprofile_needs_batch_processing ,
'type' => 'batch' ,
'run' => $myprofile_needs_batch_processing ? INSTALL_TASK_RUN_IF_NOT_COMPLETED : INSTALL_TASK_SKIP ,
2009-07-15 02:08:41 +00:00
),
2009-07-28 12:13:47 +00:00
// This is an example of a task that will not be displayed in the list that
// the user sees. To implement this task, your profile would define a
// function named myprofile_final_site_setup(), in which additional,
// automated site setup operations would be performed. Since this is the
// last task defined by your profile, you should also use this function to
// call variable_del('myprofile_needs_batch_processing') and clean up the
// variable that was used above. If you want the user to pass to the final
// Drupal installation tasks uninterrupted, return no output from this
// function. Otherwise, return themed output that the user will see (for
// example, a confirmation page explaining that your profile's tasks are
// complete, with a link to reload the current page and therefore pass on
// to the final Drupal installation tasks when the user is ready to do so).
'myprofile_final_site_setup' => array (
2009-07-15 02:08:41 +00:00
),
);
2009-09-05 13:05:31 +00:00
return $tasks ;
}
/**
* Change the page the user is sent to by drupal_goto () .
*
2009-10-15 16:18:46 +00:00
* @ param & $path
* A Drupal path or a full URL .
* @ param & $options
* An associative array of additional URL options to pass to url () .
* @ param & $http_response_code
* The HTTP status code to use for the redirection . See drupal_goto () for more
* information .
*/
function hook_drupal_goto_alter ( & $path , & $options , & $http_response_code ) {
2009-09-05 13:05:31 +00:00
// A good addition to misery module.
2009-10-15 16:18:46 +00:00
$http_response_code = 500 ;
2009-07-15 02:08:41 +00:00
}
2009-11-03 06:47:23 +00:00
/**
* Alter XHTML HEAD tags before they are rendered by drupal_get_html_head () .
*
* Elements available to be altered are only those added using
* drupal_add_html_head_link () or drupal_add_html_head () . CSS and JS files
* are handled using drupal_add_css () and drupal_add_js (), so the head links
* for those files will not appear in the $head_elements array .
*
* @ param $head_elements
* An array of renderable elements . Generally the values of the #attributes
* array will be the most likely target for changes .
*/
function hook_html_head_alter ( & $head_elements ) {
foreach ( $head_elements as $key => $element ) {
if ( isset ( $element [ '#attributes' ][ 'rel' ]) && $element [ '#attributes' ][ 'rel' ] == 'canonical' ) {
// I want a custom canonical url.
$head_elements [ $key ][ '#attributes' ][ 'href' ] = mymodule_canonical_url ();
}
}
}
2009-10-13 07:09:26 +00:00
/**
* Alter the full list of installation tasks .
*
* @ param $tasks
* An array of all available installation tasks , including those provided by
* Drupal core . You can modify this array to change or replace any part of
* the Drupal installation process that occurs after the installation profile
* is selected .
* @ param $install_state
2009-10-16 13:18:32 +00:00
* An array of information about the current installation state .
2009-10-13 07:09:26 +00:00
*/
function hook_install_tasks_alter ( & $tasks , $install_state ) {
// Replace the "Choose language" installation task provided by Drupal core
// with a custom callback function defined by this installation profile.
$tasks [ 'install_select_locale' ][ 'function' ] = 'myprofile_locale_selection' ;
}
2009-08-31 05:47:34 +00:00
/**
* Alter MIME type mappings used to determine MIME type from a file extension .
*
* This hook is run when file_mimetype_mapping () is called . It is used to
* allow modules to add to or modify the default mapping from
* file_default_mimetype_mapping () .
*
* @ param $mapping
* An array of mimetypes correlated to the extensions that relate to them .
* The array has 'mimetypes' and 'extensions' elements , each of which is an
* array .
2010-06-29 00:23:57 +00:00
*
2009-08-31 05:47:34 +00:00
* @ see file_default_mimetype_mapping ()
*/
function hook_file_mimetype_mapping_alter ( & $mapping ) {
// Add new MIME type 'drupal/info'.
$mapping [ 'mimetypes' ][ 'example_info' ] = 'drupal/info' ;
// Add new extension '.info' and map it to the 'drupal/info' MIME type.
$mapping [ 'extensions' ][ 'info' ] = 'example_info' ;
// Override existing extension mapping for '.ogg' files.
$mapping [ 'extensions' ][ 'ogg' ] = 189 ;
}
2009-09-19 11:07:37 +00:00
/**
* Declares information about actions .
*
* Any module can define actions , and then call actions_do () to make those
* actions happen in response to events . The trigger module provides a user
* interface for associating actions with module - defined triggers , and it makes
* sure the core triggers fire off actions when their events happen .
*
* An action consists of two or three parts :
* - an action definition ( returned by this hook )
* - a function which performs the action ( which by convention is named
* MODULE_description - of - function_action )
* - an optional form definition function that defines a configuration form
* ( which has the name of the action function with '_form' appended to it . )
*
* The action function takes two to four arguments , which come from the input
* arguments to actions_do () .
*
* @ return
* An associative array of action descriptions . The keys of the array
* are the names of the action functions , and each corresponding value
* is an associative array with the following key - value pairs :
* - 'type' : The type of object this action acts upon . Core actions have types
* 'node' , 'user' , 'comment' , and 'system' .
* - 'label' : The human - readable name of the action , which should be passed
* through the t () function for translation .
* - 'configurable' : If FALSE , then the action doesn ' t require any extra
* configuration . If TRUE , then your module must define a form function with
* the same name as the action function with '_form' appended ( e . g . , the
* form for 'node_assign_owner_action' is 'node_assign_owner_action_form' . )
* This function takes $context as its only parameter , and is paired with
* the usual _submit function , and possibly a _validate function .
* - 'triggers' : An array of the events ( that is , hooks ) that can trigger this
* action . For example : array ( 'node_insert' , 'user_update' ) . You can also
* declare support for any trigger by returning array ( 'any' ) for this value .
2009-11-06 03:59:06 +00:00
* - 'behavior' : ( optional ) A machine - readable array of behaviors of this
* action , used to signal additionally required actions that may need to be
* triggered . Currently recognized behaviors by Trigger module :
* - 'changes_property' : If an action with this behavior is assigned to a
* trigger other than a " presave " hook , any save actions also assigned to
* this trigger are moved later in the list . If no save action is present ,
* one will be added .
* Modules that are processing actions ( like Trigger module ) should take
* special care for the " presave " hook , in which case a dependent " save "
* action should NOT be invoked .
2010-02-26 16:55:18 +00:00
*
* @ ingroup actions
2009-09-19 11:07:37 +00:00
*/
function hook_action_info () {
return array (
'comment_unpublish_action' => array (
'type' => 'comment' ,
'label' => t ( 'Unpublish comment' ),
'configurable' => FALSE ,
2009-11-06 03:59:06 +00:00
'behavior' => array ( 'changes_property' ),
'triggers' => array ( 'comment_presave' , 'comment_insert' , 'comment_update' ),
2009-09-19 11:07:37 +00:00
),
'comment_unpublish_by_keyword_action' => array (
'type' => 'comment' ,
'label' => t ( 'Unpublish comment containing keyword(s)' ),
'configurable' => TRUE ,
2009-11-06 03:59:06 +00:00
'behavior' => array ( 'changes_property' ),
'triggers' => array ( 'comment_presave' , 'comment_insert' , 'comment_update' ),
),
'comment_save_action' => array (
'type' => 'comment' ,
'label' => t ( 'Save comment' ),
'configurable' => FALSE ,
2009-09-19 11:07:37 +00:00
'triggers' => array ( 'comment_insert' , 'comment_update' ),
),
);
}
/**
* Executes code after an action is deleted .
*
* @ param $aid
* The action ID .
*/
function hook_actions_delete ( $aid ) {
db_delete ( 'actions_assignments' )
-> condition ( 'aid' , $aid )
-> execute ();
}
/**
* Alters the actions declared by another module .
*
* Called by actions_list () to allow modules to alter the return values from
* implementations of hook_action_info () .
*
2010-03-26 17:14:46 +00:00
* @ see trigger_example_action_info_alter ()
2009-09-19 11:07:37 +00:00
*/
function hook_action_info_alter ( & $actions ) {
$actions [ 'node_unpublish_action' ][ 'label' ] = t ( 'Unpublish and remove from public view.' );
}
2009-10-15 17:55:55 +00:00
/**
* Declare archivers to the system .
*
* An archiver is a class that is able to package and unpackage one or more files
* into a single possibly compressed file . Common examples of such files are
* zip files and tar . gz files . All archiver classes must implement
* ArchiverInterface .
*
* Each entry should be keyed on a unique value , and specify three
* additional keys :
2009-10-16 13:18:32 +00:00
* - class : The name of the PHP class for this archiver .
* - extensions : An array of file extensions that this archiver supports .
* - weight : This optional key specifies the weight of this archiver .
* When mapping file extensions to archivers , the first archiver by
* weight found that supports the requested extension will be used .
2010-02-10 20:22:57 +00:00
*
* @ see hook_archiver_info_alter ()
2009-10-15 17:55:55 +00:00
*/
2009-10-16 13:18:32 +00:00
function hook_archiver_info () {
2009-10-15 17:55:55 +00:00
return array (
'tar' => array (
'class' => 'ArchiverTar' ,
'extensions' => array ( 'tar' , 'tar.gz' , 'tar.bz2' ),
),
);
}
2010-02-10 20:22:57 +00:00
/**
* Alter archiver information declared by other modules .
*
* See hook_archiver_info () for a description of archivers and the archiver
* information structure .
*
* @ param $info
* Archiver information to alter ( return values from hook_archiver_info ()) .
*/
function hook_archiver_info_alter ( & $info ) {
$info [ 'tar' ][ 'extensions' ][] = 'tgz' ;
}
2009-10-15 17:55:55 +00:00
2009-10-13 21:34:15 +00:00
/**
* Defines additional date types .
*
* Next to the 'long' , 'medium' and 'short' date types defined in core , any
* module can define additional types that can be used when displaying dates . A
* date type is a key which can be passed to format_date () to return a date in
* the configured display format .
*
* To avoid namespace collisions with date types defined by other modules , it is
* recommended that each date type starts with the module name . A date type
* can consist of letters , numbers and underscores .
*
* @ return
* A list of date types in 'key' => 'label' format .
2010-06-29 00:23:57 +00:00
*
* @ see hook_date_formats ()
* @ see format_date ()
2009-10-13 21:34:15 +00:00
*/
function hook_date_format_types () {
return array (
'long' => t ( 'Long' ),
'medium' => t ( 'Medium' ),
'short' => t ( 'Short' ),
);
}
2010-04-30 19:21:52 +00:00
/**
* Modify existing date format types .
*
* Allows other modules to modify existing date types like 'long' . Called
* by _system_date_format_types_build () . For instance , A module may use this
* hook to apply settings across all date format types , such as locking all
* date format types so they appear to be provided by the system .
*
* @ param $types
* An associative array of date format types containing :
* - types : An array of date format types including configuration settings
* for each type :
* - is_new : Set to FALSE to override previous settings .
* - module : The name of the module that created the date format type .
* - type : The date type name .
* - title : The title of the date type .
* - locked : Specifies that the date type is system - provided .
*/
function hook_date_format_types_alter ( & $types ) {
foreach ( $types as $type_name => $type ) {
$types [ $type_name ][ 'locked' ] = 1 ;
}
}
2009-10-13 21:34:15 +00:00
/**
* Defines additional date formats .
*
* Next to the 'long' , 'medium' and 'short' date types defined in core , any
* module can define additional types that can be used when displaying dates . A
* date type is a key which can be passed to format_date () to return a date in
* the configured displayed format . A date format is a string defining the date
2009-10-16 13:18:32 +00:00
* and time elements to use . For example , a date type could be
2009-10-13 21:34:15 +00:00
* 'mymodule_extra_long' , while a date format is like 'Y-m-d' .
*
* New date types must first be declared using hook_date_format_types () . It is
* then possible to define one or more date formats for each .
*
* A module may also extend the list date formats defined for a date type
* provided by another module .
*
* There may be more than one format for the same locale . For example d / m / Y and
* Y / m / d work equally well in some locales . It may also be necessary to define
* multiple versions of the same date format , for example , one using AM , one
* with PM and one without the time at all .
*
* However at the same time you may wish to define some additional date formats
* that aren ' t specific to any one locale , for example , " Y m " . For these cases
* the locales field should be omitted .
*
* @ return
* A list of date formats . Each date format is a keyed array
* consisting of three elements :
* - 'type' : the date type is a key used to identify which date format to
* display . It consists of letters , numbers and underscores , e . g . 'long' ,
* 'short' , 'mymodule_extra_long' . It must first be declared in
* hook_date_format_types () unless extending a type provided by another
* module .
2009-10-16 13:18:32 +00:00
* - 'format' : a string defining the date and time elements to use . It
2009-10-13 21:34:15 +00:00
* can contain any of the formatting options described at
* http :// php . net / manual / en / function . date . php
* - 'locales' : ( optional ) an array of 2 and 5 character language codes , for
* example , 'en' , 'en-us' . The language codes are used to determine which
* date format to display for the user ' s current language . If more than one
* date format is suggested for the same date type and locale , then the
* first one will be used unless overridden via
* admin / config / regional / date - time / locale . If your date format is not
* language specific , leave this field empty .
2010-06-29 00:23:57 +00:00
*
* @ see hook_date_format_types ()
2009-10-13 21:34:15 +00:00
*/
function hook_date_formats () {
return array (
array (
'type' => 'mymodule_extra_long' ,
'format' => 'l jS F Y H:i:s e' ,
'locales' => array ( 'en-ie' ),
),
array (
'type' => 'mymodule_extra_long' ,
'format' => 'l jS F Y h:i:sa' ,
'locales' => array ( 'en' , 'en-us' ),
),
array (
'type' => 'short' ,
'format' => 'F Y' ,
'locales' => array (),
),
);
}
/**
* Alters date types and formats declared by another module .
*
* Called by _system_date_format_types_build () to allow modules to alter the
* return values from implementations of hook_date_formats () .
*/
function hook_date_formats_alter ( & $formats ) {
foreach ( $formats as $id => $format ) {
$formats [ $id ][ 'locales' ][] = 'en-ca' ;
}
}
2009-10-15 14:07:30 +00:00
/**
* Alters the delivery callback used to send the result of the page callback to the browser .
*
* Called by drupal_deliver_page () to allow modules to alter how the
* page is delivered to the browser .
*
* This hook is intended for altering the delivery callback based on
* information unrelated to the path of the page accessed . For example ,
* it can be used to set the delivery callback based on a HTTP request
* header ( as shown in the code sample ) . To specify a delivery callback
2010-07-01 00:46:57 +00:00
* based on path information , use hook_menu () or hook_menu_alter () .
2009-10-15 14:07:30 +00:00
*
* This hook can also be used as an API function that can be used to explicitly
* set the delivery callback from some other function . For example , for a module
* named MODULE :
* @ code
* function MODULE_page_delivery_callback_alter ( & $callback , $set = FALSE ) {
* static $stored_callback ;
* if ( $set ) {
* $stored_callback = $callback ;
* }
* elseif ( isset ( $stored_callback )) {
* $callback = $stored_callback ;
* }
* }
* function SOMEWHERE_ELSE () {
* $desired_delivery_callback = 'foo' ;
* MODULE_page_delivery_callback_alter ( $desired_delivery_callback , TRUE );
* }
* @ endcode
*
* @ param $callback
* The name of a function .
*
* @ see drupal_deliver_page ()
*/
function hook_page_delivery_callback_alter ( & $callback ) {
// jQuery sets a HTTP_X_REQUESTED_WITH header of 'XMLHttpRequest'.
// If a page would normally be delivered as an html page, and it is called
// from jQuery, deliver it instead as an AJAX response.
if ( isset ( $_SERVER [ 'HTTP_X_REQUESTED_WITH' ]) && $_SERVER [ 'HTTP_X_REQUESTED_WITH' ] == 'XMLHttpRequest' && $callback == 'drupal_deliver_html_page' ) {
$callback = 'ajax_deliver' ;
}
}
2009-12-01 00:39:35 +00:00
/**
* Alters theme operation links .
*
* @ param $theme_groups
* An associative array containing groups of themes .
*
* @ see system_themes_page ()
*/
function hook_system_themes_page_alter ( & $theme_groups ) {
foreach ( $theme_groups as $state => & $group ) {
foreach ( $theme_groups [ $state ] as & $theme ) {
// Add a foo link to each list of theme operations.
$theme -> operations [] = l ( t ( 'Foo' ), 'admin/appearance/foo' , array ( 'query' => array ( 'theme' => $theme -> name )));
}
}
}
2009-10-24 05:13:44 +00:00
/**
* Alters inbound URL requests .
*
* @ param $path
* The path being constructed , which , if a path alias , has been resolved to a
* Drupal path by the database , and which also may have been altered by other
* modules before this one .
* @ param $original_path
* The original path , before being checked for path aliases or altered by any
* modules .
* @ param $path_language
* The language of the path .
*
* @ see drupal_get_normal_path ()
*/
function hook_url_inbound_alter ( & $path , $original_path , $path_language ) {
// Create the path user/me/edit, which allows a user to edit their account.
if ( preg_match ( '|^user/me/edit(/.*)?|' , $path , $matches )) {
global $user ;
$path = 'user/' . $user -> uid . '/edit' . $matches [ 1 ];
}
}
/**
* Alters outbound URLs .
*
* @ param $path
* The outbound path to alter , not adjusted for path aliases yet . It won ' t be
* adjusted for path aliases until all modules are finished altering it , thus
* being consistent with hook_url_alter_inbound (), which adjusts for all path
* aliases before allowing modules to alter it . This may have been altered by
* other modules before this one .
* @ param $options
* A set of URL options for the URL so elements such as a fragment or a query
* string can be added to the URL .
* @ param $original_path
* The original path , before being altered by any modules .
*
* @ see url ()
*/
function hook_url_outbound_alter ( & $path , & $options , $original_path ) {
// Use an external RSS feed rather than the Drupal one.
if ( $path == 'rss.xml' ) {
$path = 'http://example.com/rss.xml' ;
$options [ 'external' ] = TRUE ;
}
// Instead of pointing to user/[uid]/edit, point to user/me/edit.
if ( preg_match ( '|^user/([0-9]*)/edit(/.*)?|' , $path , $matches )) {
global $user ;
if ( $user -> uid == $matches [ 1 ]) {
$path = 'user/me/edit' . $matches [ 2 ];
}
}
}
2009-11-01 21:26:44 +00:00
/**
* Alter the username that is displayed for a user .
*
* Called by format_username () to allow modules to alter the username that ' s
* displayed . Can be used to ensure user privacy in situations where
* $account -> name is too revealing .
*
* @ param & $name
* The string that format_username () will return .
*
* @ param $account
* The account object passed to format_username () .
*
* @ see format_username ()
*/
function hook_username_alter ( & $name , $account ) {
// Display the user's uid instead of name.
if ( isset ( $account -> uid )) {
$name = t ( 'User !uid' , array ( '!uid' => $account -> uid ));
}
}
2010-01-05 05:03:32 +00:00
/**
* Provide replacement values for placeholder tokens .
*
* @ param $type
* The type of token being replaced . 'node' , 'user' , and 'date' are common .
* @ param $tokens
* An array of tokens to be replaced , keyed by the literal text of the token
* as it appeared in the source text .
* @ param $data
2010-01-08 11:07:01 +00:00
* ( optional ) An associative array of objects to be used when generating replacement
2010-01-05 05:03:32 +00:00
* values .
* @ param $options
2010-01-08 11:07:01 +00:00
* ( optional ) A associative array of options to control the token
2010-01-05 05:03:32 +00:00
* replacement process . Common options are :
* - 'language' A language object to be used when generating locale - sensitive
* tokens .
* - 'sanitize' A boolean flag indicating that tokens should be sanitized for
* display to a web browser .
2010-01-08 11:07:01 +00:00
*
2010-01-05 05:03:32 +00:00
* @ return
* An associative array of replacement values , keyed by the original 'raw'
* tokens that were found in the source text . For example :
* $results [ '[node:title]' ] = 'My new node' ;
*/
function hook_tokens ( $type , $tokens , array $data = array (), array $options = array ()) {
2010-01-08 11:07:01 +00:00
$url_options = array ( 'absolute' => TRUE );
if ( isset ( $options [ 'language' ])) {
$url_options [ 'language' ] = $options [ 'language' ];
$language_code = $options [ 'language' ] -> language ;
}
else {
$language_code = NULL ;
}
$sanitize = ! empty ( $options [ 'sanitize' ]);
$replacements = array ();
if ( $type == 'node' && ! empty ( $data [ 'node' ])) {
$node = $data [ 'node' ];
foreach ( $tokens as $name => $original ) {
switch ( $name ) {
// Simple key values on the node.
case 'nid' :
$replacements [ $original ] = $node -> nid ;
break ;
case 'title' :
2010-01-09 21:54:01 +00:00
$replacements [ $original ] = $sanitize ? check_plain ( $node -> title ) : $node -> title ;
2010-01-08 11:07:01 +00:00
break ;
case 'edit-url' :
$replacements [ $original ] = url ( 'node/' . $node -> nid . '/edit' , $url_options );
break ;
// Default values for the chained tokens handled below.
case 'author' :
$name = ( $node -> uid == 0 ) ? variable_get ( 'anonymous' , t ( 'Anonymous' )) : $node -> name ;
$replacements [ $original ] = $sanitize ? filter_xss ( $name ) : $name ;
break ;
case 'created' :
$replacements [ $original ] = format_date ( $node -> created , 'medium' , '' , NULL , $language_code );
break ;
}
}
if ( $author_tokens = token_find_with_prefix ( $tokens , 'author' )) {
$author = user_load ( $node -> uid );
$replacements += token_generate ( 'user' , $author_tokens , array ( 'user' => $author ), $options );
}
if ( $created_tokens = token_find_with_prefix ( $tokens , 'created' )) {
$replacements += token_generate ( 'date' , $created_tokens , array ( 'date' => $node -> created ), $options );
}
}
return $replacements ;
2010-01-05 05:03:32 +00:00
}
/**
* Provide metadata about available placeholder tokens and token types .
*
* @ return
* An associative array of available tokens and token types , each containing
* the raw name of the token or type , its user - friendly name , and a verbose
* description .
*
2010-01-08 11:07:01 +00:00
* @ see hook_token_info_alter ()
2010-01-05 05:03:32 +00:00
*/
function hook_token_info () {
2010-01-08 11:07:01 +00:00
$type = array (
'name' => t ( 'Nodes' ),
'description' => t ( 'Tokens related to individual nodes.' ),
'needs-data' => 'node' ,
);
// Core tokens for nodes.
$node [ 'nid' ] = array (
'name' => t ( " Node ID " ),
'description' => t ( " The unique ID of the node. " ),
);
$node [ 'title' ] = array (
'name' => t ( " Title " ),
'description' => t ( " The title of the node. " ),
);
$node [ 'edit-url' ] = array (
'name' => t ( " Edit URL " ),
'description' => t ( " The URL of the node's edit page. " ),
);
// Chained tokens for nodes.
$node [ 'created' ] = array (
'name' => t ( " Date created " ),
'description' => t ( " The date the node was posted. " ),
'type' => 'date' ,
);
$node [ 'author' ] = array (
'name' => t ( " Author " ),
'description' => t ( " The author of the node. " ),
'type' => 'user' ,
);
return array (
'types' => array ( 'node' => $type ),
'tokens' => array ( 'node' => $node ),
);
}
2010-04-20 18:48:05 +00:00
/**
* Alter batch information before a batch is processed .
*
* Called by batch_process () to allow modules to alter a batch before it is
* processed .
*
* @ param $batch
* The associative array of batch information . See batch_set () for details on
* what this could contain .
*
* @ see batch_set ()
* @ see batch_process ()
*
* @ ingroup batch
*/
function hook_batch_alter ( & $batch ) {
// If the current page request is inside the overlay, add ?render=overlay to
// the success callback URL, so that it appears correctly within the overlay.
if ( overlay_get_mode () == 'child' ) {
if ( isset ( $batch [ 'url_options' ][ 'query' ])) {
$batch [ 'url_options' ][ 'query' ][ 'render' ] = 'overlay' ;
}
else {
$batch [ 'url_options' ][ 'query' ] = array ( 'render' => 'overlay' );
}
}
}
2010-01-08 11:07:01 +00:00
/**
* Alter the metadata about available placeholder tokens and token types .
*
* @ param $data
* The associative array of token definitions from hook_token_info () .
*
* @ see hook_token_info ()
*/
function hook_token_info_alter ( & $data ) {
// Modify description of node tokens for our site.
2010-06-26 22:17:02 +00:00
$data [ 'tokens' ][ 'node' ][ 'nid' ] = array (
2010-01-08 11:07:01 +00:00
'name' => t ( " Node ID " ),
'description' => t ( " The unique ID of the article. " ),
);
2010-06-26 22:17:02 +00:00
$data [ 'tokens' ][ 'node' ][ 'title' ] = array (
2010-01-08 11:07:01 +00:00
'name' => t ( " Title " ),
'description' => t ( " The title of the article. " ),
);
// Chained tokens for nodes.
2010-06-26 22:17:02 +00:00
$data [ 'tokens' ][ 'node' ][ 'created' ] = array (
2010-01-08 11:07:01 +00:00
'name' => t ( " Date created " ),
'description' => t ( " The date the article was posted. " ),
'type' => 'date' ,
);
2010-01-05 05:03:32 +00:00
}
2010-04-30 16:27:02 +00:00
/**
* Provide information on Updaters ( classes that can update Drupal ) .
*
* An Updater is a class that knows how to update various parts of the Drupal
* file system , for example to update modules that have newer releases , or to
* install a new theme .
*
* @ return
* An associative array of information about the updater ( s ) being provided .
* This array is keyed by a unique identifier for each updater , and the
* values are subarrays that can contain the following keys :
* - class : The name of the PHP class which implements this updater .
* - name : Human - readable name of this updater .
* - weight : Controls what order the Updater classes are consulted to decide
* which one should handle a given task . When an update task is being run ,
* the system will loop through all the Updater classes defined in this
* registry in weight order and let each class respond to the task and
* decide if each Updater wants to handle the task . In general , this
* doesn ' t matter , but if you need to override an existing Updater , make
* sure your Updater has a lighter weight so that it comes first .
*
* @ see drupal_get_updaters ()
* @ see hook_updater_info_alter ()
*/
function hook_updater_info () {
return array (
'module' => array (
'class' => 'ModuleUpdater' ,
'name' => t ( 'Update modules' ),
'weight' => 0 ,
),
'theme' => array (
'class' => 'ThemeUpdater' ,
'name' => t ( 'Update themes' ),
'weight' => 0 ,
),
);
}
/**
* Alter the Updater information array .
*
* An Updater is a class that knows how to update various parts of the Drupal
* file system , for example to update modules that have newer releases , or to
* install a new theme .
*
* @ param array $updaters
* Associative array of updaters as defined through hook_updater_info () .
* Alter this array directly .
*
* @ see drupal_get_updaters ()
* @ see hook_updater_info ()
*/
function hook_updater_info_alter ( & $updaters ) {
// Adjust weight so that the theme Updater gets a chance to handle a given
// update task before module updaters.
$updaters [ 'theme' ][ 'weight' ] = - 1 ;
}
2010-02-18 01:40:46 +00:00
/**
* Alter the default country list .
*
* @ param $countries
* The associative array of countries keyed by ISO 3166 - 1 country code .
*
* @ see country_get_list ()
* @ see _country_get_predefined_list ()
*/
function hook_countries_alter ( & $countries ) {
2010-04-24 07:17:29 +00:00
// Elbonia is now independent, so add it to the country list.
$countries [ 'EB' ] = 'Elbonia' ;
2010-02-18 01:40:46 +00:00
}
2010-04-20 18:46:41 +00:00
/**
* Provide information on available file transfer backends .
*
* File transfer backends are used by modules to transfer files from remote
* locations to Drupal sites . For instance , update . module uses a file transfer
* backend to download new versions of modules and themes from drupal . org .
*
* @ return
2010-04-26 14:33:54 +00:00
* An associative array of information about the file transfer backend ( s ) .
2010-04-20 18:46:41 +00:00
* being provided . This array can contain the following keys :
* - title : Title of the backend to be shown to the end user .
* - class : Name of the PHP class which implements this backend .
* - settings_form : An optional callback function that provides additional
* configuration information required by this backend ( for instance a port
* number . )
* - weight : Controls what order the backends are presented to the user .
*
* @ see authorize . php
* @ see FileTransfer
*/
function hook_filetransfer_backends () {
$backends = array ();
// This is the default, will be available on most systems.
if ( function_exists ( 'ftp_connect' )) {
$backends [ 'ftp' ] = array (
'title' => t ( 'FTP' ),
'class' => 'FileTransferFTP' ,
'settings_form' => 'system_filetransfer_backend_form_ftp' ,
'weight' => 0 ,
);
}
// SSH2 lib connection is only available if the proper PHP extension is
// installed.
if ( function_exists ( 'ssh2_connect' )) {
$backends [ 'ssh' ] = array (
'title' => t ( 'SSH' ),
'class' => 'FileTransferSSH' ,
'settings_form' => 'system_filetransfer_backend_form_ssh' ,
'weight' => 20 ,
);
}
return $backends ;
}
2010-07-07 08:05:01 +00:00
/**
* Control site status before menu dispatching .
*
* The hook is called after checking whether the site is offline but before
* the current router item is retrieved and executed by
* menu_execute_active_handler () . If the site is in offline mode ,
* $menu_site_status is set to MENU_SITE_OFFLINE .
*
* @ param $menu_site_status
* Supported values are MENU_SITE_OFFLINE , MENU_ACCESS_DENIED ,
* MENU_NOT_FOUND and MENU_SITE_ONLINE . Any other value than
* MENU_SITE_ONLINE will skip the default menu handling system and be passed
* for delivery to drupal_deliver_page () with a NULL
* $default_delivery_callback .
* @ param $path
* Contains the system path that is going to be loaded . This is read only ,
* use hook_url_inbound_alter () to change the path .
*/
function hook_menu_site_status_alter ( & $menu_site_status , $path ) {
// Allow access to my_module/authentication even if site is in offline mode.
if ( $menu_site_status == MENU_SITE_OFFLINE && user_is_anonymous () && $path == 'my_module/authentication' ) {
$menu_site_status = MENU_SITE_ONLINE ;
}
}
2008-11-25 02:37:33 +00:00
/**
* @ } End of " addtogroup hooks " .
*/