core.php

  1. drupal
    1. 4.6 developer/hooks/core.php
    2. 4.7 developer/hooks/core.php
    3. 5 developer/hooks/core.php
    4. 6 developer/hooks/core.php

These are the hooks that are invoked by the Drupal core.

Core hooks are typically called in all modules at once using module_invoke_all().

Functions & methods

NameDescription
hook_blockDeclare a block or set of blocks.
hook_commentAct on comments.
hook_cronPerform periodic actions.
hook_db_rewrite_sqlAdd JOIN and WHERE statements to queries and decide whether the primary_field shall be made DISTINCT. For node objects, primary field is always called nid. For taxonomy terms, it is tid and for vocabularies it is vid. For comments, it is cid. Primary…
hook_elementsAllows modules to declare their own form element types and specify their default values.
hook_exitPerform cleanup tasks.
hook_file_downloadAllow file downloads.
hook_filterDefine content filters.
hook_filter_tipsProvide tips for using filters.
hook_footerInsert closing HTML.
hook_form_alterPerform alterations before a form is rendered. One popular use of this hook is to add form elements to the node form.
hook_helpProvide online user help.
hook_initPerform setup tasks.
hook_linkDefine internal Drupal links.
hook_menuDefine menu items and page callbacks.
hook_nodeapiAct on nodes defined by other modules.
hook_node_grantsGrant access to nodes.
hook_permDefine user permissions.
hook_pingPing another server.
hook_searchDefine a custom search routine.
hook_search_preprocessPreprocess text for the search index.
hook_settingsDeclare administrative settings for a module.
hook_taxonomyAct on taxonomy changes.
hook_update_indexUpdate Drupal's full-text index for this module.
hook_userAct on user account actions.
hook_xmlrpcRegister XML-RPC callbacks.

File

developer/hooks/core.php
View source
  1. <?php
  2. /**
  3. * @file
  4. * These are the hooks that are invoked by the Drupal core.
  5. *
  6. * Core hooks are typically called in all modules at once using
  7. * module_invoke_all().
  8. */
  9. /**
  10. * @addtogroup hooks
  11. * @{
  12. */
  13. /**
  14. * Declare a block or set of blocks.
  15. *
  16. * Any module can export a block (or blocks) to be displayed by defining
  17. * the _block hook. This hook is called by theme.inc to display a block,
  18. * and also by block.module to procure the list of available blocks.
  19. *
  20. * As of 4.7, all block properties (except theme) can be set in hook_block's
  21. * 'view' operation. You can give your blocks an explicit weight, enable them,
  22. * limit them to given pages, etc. These settings will be registered when the
  23. * block is first loaded at admin/block, and from there can be changed manually
  24. * via block administration.
  25. *
  26. * Note that if you set a region that isn't available in a given theme, the
  27. * block will be registered instead to that theme's default region (the first
  28. * item in the _regions array).
  29. *
  30. * @param $op
  31. * What kind of information to retrieve about the block or blocks.
  32. * Possible values:
  33. * - 'list': A list of all blocks defined by the module.
  34. * - 'configure': A configuration form.
  35. * - 'save': Save the configuration options.
  36. * - 'view': Information about a particular block and default settings.
  37. * @param $delta
  38. * Which block to return (not applicable if $op is 'list'). Although it is
  39. * most commonly an integer starting at 0, this is not mandatory. For
  40. * instance, aggregator.module uses string values for $delta
  41. * @param $edit
  42. * If $op is 'save', the submitted form data from the configuration form.
  43. * @return
  44. * If $op is 'list', return an array of arrays, each of which must define an
  45. * 'info' element describing the block. If $op is 'configure', optionally
  46. * return a string containing the configuration form. If $op is 'save',
  47. * return nothing, If $op is 'view', return an array which must define a
  48. * 'subject' element and a 'content' element defining the block indexed by
  49. * $delta.
  50. *
  51. * The functions mymodule_display_block_1 and 2, as used in the example,
  52. * should of course be defined somewhere in your module and return the
  53. * content you want to display to your users. If the "content" element
  54. * is empty, no block will be displayed even if "subject" is present.
  55. *
  56. * After completing your blocks, do not forget to enable them in the
  57. * block admin menu.
  58. *
  59. * For a detailed usage example, see block_example.module.
  60. */
  61. function hook_block($op = 'list', $delta = 0, $edit = array()) {
  62. if ($op == 'list') {
  63. $blocks[0] = array('info' => t('Mymodule block #1 shows ...'),
  64. 'weight' => 0, 'enabled' => 1, 'region' => 'left');
  65. $blocks[1] = array('info' => t('Mymodule block #2 describes ...'),
  66. 'weight' => 0, 'enabled' => 0, 'region' => 'right');
  67. return $blocks;
  68. }
  69. else if ($op == 'configure' && $delta == 0) {
  70. $form['items'] = array(
  71. '#type' => 'select',
  72. '#title' => t('Number of items'),
  73. '#default_value' => variable_get('mymodule_block_items', 0),
  74. '#options' => array('1', '2', '3'),
  75. );
  76. return $form;
  77. }
  78. else if ($op == 'save' && $delta == 0) {
  79. variable_set('mymodule_block_items', $edit['items']);
  80. }
  81. else if ($op == 'view') {
  82. switch($delta) {
  83. case 0:
  84. $block = array('subject' => t('Title of block #1'),
  85. 'content' => mymodule_display_block_1());
  86. break;
  87. case 1:
  88. $block = array('subject' => t('Title of block #2'),
  89. 'content' => mymodule_display_block_2());
  90. break;
  91. }
  92. return $block;
  93. }
  94. }
  95. /**
  96. * Act on comments.
  97. *
  98. * This hook allows modules to extend the comments system.
  99. *
  100. * @param $a1
  101. * Dependent on the action being performed.
  102. * - For "form", passes in the comment form.
  103. * - For "validate","update","insert", passes in an array of form values submitted by the user.
  104. * - For all other operations, passes in the comment the action is being performed on.
  105. * @param $op
  106. * What kind of action is being performed. Possible values:
  107. * - "insert": The comment is being inserted.
  108. * - "update": The comment is being updated.
  109. * - "view": The comment is being viewed. This hook can be used to add additional data to the comment before theming.
  110. * - "form": The comment form is about to be shown. Modules may add fields to the form at this point.
  111. * - "validate": The user has just finished editing the comment and is
  112. * trying to preview or submit it. This hook can be used to check or
  113. * even modify the node. Errors should be set with form_set_error().
  114. * - "publish": The comment is being published by the moderator.
  115. * - "unpublish": The comment is being unpublished by the moderator.
  116. * - "delete": The comment is being deleted by the moderator.
  117. * @return
  118. * Dependent on the action being performed.
  119. * - For "form", an array of form elements to add to the comment form.
  120. * - For all other operations, nothing.
  121. */
  122. function hook_comment($a1, $op) {
  123. if ($op == 'insert' || $op == 'update') {
  124. $nid = $a1['nid'];
  125. }
  126. cache_clear_all_like(drupal_url(array('id' => $nid)));
  127. }
  128. /**
  129. * Perform periodic actions.
  130. *
  131. * Modules that require to schedule some commands to be executed at regular
  132. * intervals can implement hook_cron(). The engine will then call the hook
  133. * at the appropriate intervals defined by the administrator. This interface
  134. * is particularly handy to implement timers or to automate certain tasks.
  135. * Database maintenance, recalculation of settings or parameters, and
  136. * automatic mailings are good candidates for cron tasks.
  137. *
  138. * @return
  139. * None.
  140. *
  141. * This hook will only be called if cron.php is run (e.g. by crontab).
  142. */
  143. function hook_cron() {
  144. $result = db_query('SELECT * FROM {site} WHERE checked = 0 OR checked
  145. + refresh < %d', time());
  146. while ($site = db_fetch_array($result)) {
  147. cloud_update($site);
  148. }
  149. }
  150. /**
  151. * Add JOIN and WHERE statements to queries and decide whether the primary_field shall
  152. * be made DISTINCT. For node objects, primary field is always called nid. For taxonomy terms, it is tid
  153. * and for vocabularies it is vid. For comments, it is cid.
  154. * Primary table is the table where the primary object (node, file, term_node etc.) is.
  155. *
  156. * You shall return an associative array. Possible keys are 'join', 'where' and 'distinct'. The value of 'distinct' shall be 1 if you want that the primary_field made DISTINCT.
  157. *
  158. * @param $query
  159. * Query to be rewritten.
  160. * @param $primary_table
  161. * Name or alias of the table which has the primary key field for this query. Possible values are: comments, forum, node, term_data, vocabulary.
  162. * Typical table names would be: {blocks}, {comments}, {forum}, {node},
  163. * {menu}, {term_data} or {vocabulary}. However, it is more common for
  164. * $primary_table to contain the usual table alias: b, c, f, n, m, t or v.
  165. * @param $primary_field
  166. * Name of the primary field.
  167. * @param $args
  168. * Array of additional arguments.
  169. * @return
  170. * An array of join statements, where statements, distinct decision.
  171. */
  172. function hook_db_rewrite_sql($query, $primary_table, $primary_field, $args) {
  173. switch ($primary_field) {
  174. case 'nid':
  175. // this query deals with node objects
  176. $return = array();
  177. if ($primary_table != 'n') {
  178. $return['join'] = "LEFT JOIN {node} n ON $primary_table.nid = n.nid";
  179. }
  180. $return['where'] = 'created >' . mktime(0, 0, 0, 1, 1, 2005);
  181. return $return;
  182. break;
  183. case 'tid':
  184. // this query deals with taxonomy objects
  185. break;
  186. case 'vid':
  187. // this query deals with vocabulary objects
  188. break;
  189. }
  190. }
  191. /**
  192. * Allows modules to declare their own form element types and specify their default values.
  193. *
  194. * @return
  195. * An array of element types
  196. */
  197. function hook_elements() {
  198. $type['filter_format'] = array('#input' => TRUE);
  199. return $type;
  200. }
  201. /**
  202. * Perform cleanup tasks.
  203. *
  204. * This hook is run at the end of each page request. It is often used for
  205. * page logging and printing out debugging information.
  206. *
  207. * Only use this hook if your code must run even for cached page views.
  208. * If you have code which must run once on all non cached pages, use hook_menu(!$may_cache)
  209. * instead. Thats the usual case. If you implement this hook and see an error like 'Call to
  210. * undefined function', it is likely that you are depending on the presence of a module which
  211. * has not been loaded yet. It is not loaded because Drupal is still in bootstrap mode.
  212. * The usual fix is to move your code to hook_menu(!$may_cache).
  213. *
  214. * @param $destination
  215. * If this hook is invoked as part of a drupal_goto() call, then this argument
  216. * will be a fully-qualified URL that is the destination of the redirect.
  217. * Modules may use this to react appropriately; for example, nothing should
  218. * be output in this case, because PHP will then throw a "headers cannot be
  219. * modified" error when attempting the redirection.
  220. * @return
  221. * None.
  222. */
  223. function hook_exit($destination = NULL) {
  224. db_query('UPDATE {counter} SET hits = hits + 1 WHERE type = 1');
  225. }
  226. /**
  227. * Allow file downloads.
  228. *
  229. * @param $file
  230. * String of the file's path.
  231. * @return
  232. * If the user does not have permission to access the file, return -1. If the
  233. * user has permission, return an array with the appropriate headers.
  234. */
  235. function hook_file_download($file) {
  236. if (user_access('access content')) {
  237. if ($filemime = db_result(db_query("SELECT filemime FROM {fileupload} WHERE filepath = '%s'", file_create_path($file)))) {
  238. return array('Content-type:' . $filemime);
  239. }
  240. }
  241. else {
  242. return -1;
  243. }
  244. }
  245. /**
  246. * Define content filters.
  247. *
  248. * Content in Drupal is passed through all enabled filters before it is
  249. * output. This lets a module modify content to the site administrator's
  250. * liking.
  251. *
  252. * This hook contains all that is needed for having a module provide filtering
  253. * functionality.
  254. *
  255. * Depending on $op, different tasks are performed.
  256. *
  257. * A module can contain as many filters as it wants. The 'list' operation tells
  258. * the filter system which filters are available. Every filter has a numerical
  259. * 'delta' which is used to refer to it in every operation.
  260. *
  261. * Filtering is a two-step process. First, the content is 'prepared' by calling
  262. * the 'prepare' operation for every filter. The purpose of 'prepare' is to
  263. * escape HTML-like structures. For example, imagine a filter which allows the
  264. * user to paste entire chunks of programming code without requiring manual
  265. * escaping of special HTML characters like @< or @&. If the programming code
  266. * were left untouched, then other filters could think it was HTML and change
  267. * it. For most filters however, the prepare-step is not necessary, and they can
  268. * just return the input without changes.
  269. *
  270. * Filters should not use the 'prepare' step for anything other than escaping,
  271. * because that would short-circuits the control the user has over the order
  272. * in which filters are applied.
  273. *
  274. * The second step is the actual processing step. The result from the
  275. * prepare-step gets passed to all the filters again, this time with the
  276. * 'process' operation. It's here that filters should perform actual changing of
  277. * the content: transforming URLs into hyperlinks, converting smileys into
  278. * images, etc.
  279. *
  280. * An important aspect of the filtering system are 'input formats'. Every input
  281. * format is an entire filter setup: which filters to enable, in what order
  282. * and with what settings. Filters that provide settings should usually store
  283. * these settings per format.
  284. *
  285. * If the filter's behaviour depends on an extensive list and/or external data
  286. * (e.g. a list of smileys, a list of glossary terms) then filters are allowed
  287. * to provide a separate, global configuration page rather than provide settings
  288. * per format. In that case, there should be a link from the format-specific
  289. * settings to the separate settings page.
  290. *
  291. * For performance reasons content is only filtered once; the result is stored
  292. * in the cache table and retrieved the next time the piece of content is
  293. * displayed. If a filter's output is dynamic it can override the cache
  294. * mechanism, but obviously this feature should be used with caution: having one
  295. * 'no cache' filter in a particular input format disables caching for the
  296. * entire format, not just for one filter.
  297. *
  298. * Beware of the filter cache when developing your module: it is advised to set
  299. * your filter to 'no cache' while developing, but be sure to remove it again
  300. * if it's not needed. You can clear the cache by running the SQL query 'DELETE
  301. * FROM cache';
  302. *
  303. * @param $op
  304. * Which filtering operation to perform. Possible values:
  305. * - list: provide a list of available filters.
  306. * Returns an associative array of filter names with numerical keys.
  307. * These keys are used for subsequent operations and passed back through
  308. * the $delta parameter.
  309. * - no cache: Return true if caching should be disabled for this filter.
  310. * - description: Return a short description of what this filter does.
  311. * - prepare: Return the prepared version of the content in $text.
  312. * - process: Return the processed version of the content in $text.
  313. * - settings: Return HTML form controls for the filter's settings. These
  314. * settings are stored with variable_set() when the form is submitted.
  315. * Remember to use the $format identifier in the variable and control names
  316. * to store settings per input format (e.g. "mymodule_setting_$format").
  317. * @param $delta
  318. * Which of the module's filters to use (applies to every operation except
  319. * 'list'). Modules that only contain one filter can ignore this parameter.
  320. * @param $format
  321. * Which input format the filter is being used in (applies to 'prepare',
  322. * 'process' and 'settings').
  323. * @param $text
  324. * The content to filter (applies to 'prepare' and 'process').
  325. * @return
  326. * The return value depends on $op. The filter hook is designed so that a
  327. * module can return $text for operations it does not use/need.
  328. *
  329. * For a detailed usage example, see filter_example.module. For an example of
  330. * using multiple filters in one module, see filter_filter() and
  331. * filter_filter_tips().
  332. */
  333. function hook_filter($op, $delta = 0, $format = -1, $text = '') {
  334. switch ($op) {
  335. case 'list':
  336. return array(0 => t('Code filter'));
  337. case 'description':
  338. return t('Allows users to post code verbatim using &lt;code&gt; and &lt;?php ?&gt; tags.');
  339. case 'prepare':
  340. // Note: we use the bytes 0xFE and 0xFF to replace < > during the filtering process.
  341. // These bytes are not valid in UTF-8 data and thus least likely to cause problems.
  342. $text = preg_replace('@<code>(.+?)</code>@se', "'\xFEcode\xFF'. codefilter_escape('\\1') .'\xFE/code\xFF'", $text);
  343. $text = preg_replace('@<(\?(php)?|%)(.+?)(\?|%)>@se', "'\xFEphp\xFF'. codefilter_escape('\\3') .'\xFE/php\xFF'", $text);
  344. return $text;
  345. case "process":
  346. $text = preg_replace('@\xFEcode\xFF(.+?)\xFE/code\xFF@se', "codefilter_process_code('$1')", $text);
  347. $text = preg_replace('@\xFEphp\xFF(.+?)\xFE/php\xFF@se', "codefilter_process_php('$1')", $text);
  348. return $text;
  349. default:
  350. return $text;
  351. }
  352. }
  353. /**
  354. * Provide tips for using filters.
  355. *
  356. * A module's tips should be informative and to the point. Short tips are
  357. * preferably one-liners.
  358. *
  359. * @param $delta
  360. * Which of this module's filters to use. Modules which only implement one
  361. * filter can ignore this parameter.
  362. * @param $format
  363. * Which format we are providing tips for.
  364. * @param $long
  365. * If set to true, long tips are requested, otherwise short tips are needed.
  366. * @return
  367. * The text of the filter tip.
  368. *
  369. *
  370. */
  371. function hook_filter_tips($delta, $format, $long = false) {
  372. if ($long) {
  373. return t('To post pieces of code, surround them with &lt;code&gt;...&lt;/code&gt; tags. For PHP code, you can use &lt;?php ... ?&gt;, which will also colour it based on syntax.');
  374. }
  375. else {
  376. return t('You may post code using &lt;code&gt;...&lt;/code&gt; (generic) or &lt;?php ... ?&gt; (highlighted PHP) tags.');
  377. }
  378. }
  379. /**
  380. * Insert closing HTML.
  381. *
  382. * This hook enables modules to insert HTML just before the \</body\> closing
  383. * tag of web pages. This is useful for including javascript code and for
  384. * outputting debug information.
  385. *
  386. * @param $main
  387. * Whether the current page is the front page of the site.
  388. * @return
  389. * The HTML to be inserted.
  390. */
  391. function hook_footer($main = 0) {
  392. if (variable_get('dev_query', 0)) {
  393. print '<div style="clear:both;">'. devel_query_table() .'</div>';
  394. }
  395. }
  396. /**
  397. * Perform alterations before a form is rendered. One popular use of this hook is to
  398. * add form elements to the node form.
  399. *
  400. * @param $form_id
  401. * String representing the name of the form itself. Typically this is the
  402. * name of the function that generated the form.
  403. * @param $form
  404. * Nested array of form elements that comprise the form.
  405. * @return
  406. * None.
  407. */
  408. function hook_form_alter($form_id, &$form) {
  409. if (isset($form['type']) && $form['type']['#value'] .'_node_settings' == $form_id) {
  410. $form['workflow']['upload_'. $form['type']['#value']] = array(
  411. '#type' => 'radios',
  412. '#title' => t('Attachments'),
  413. '#default_value' => variable_get('upload_'. $form['type']['#value'], 1),
  414. '#options' => array(t('Disabled'), t('Enabled')),
  415. );
  416. }
  417. }
  418. /**
  419. * Provide online user help.
  420. *
  421. * By implementing hook_help(), a module can make documentation
  422. * available to the engine or to other modules. All user help should be
  423. * returned using this hook; developer help should be provided with
  424. * Doxygen/api.module comments.
  425. *
  426. * @param $section
  427. * Drupal URL path (or: menu item) the help is being requested for, e.g.
  428. * admin/node or user/edit. Recognizes special descriptors after a "#"
  429. * sign. Some examples:
  430. * - admin/modules#name
  431. * The name of a module (unused, but there)
  432. * - admin/modules#description
  433. * The description found on the admin/system/modules page.
  434. * - admin/help#modulename
  435. * The module's help text, displayed on the admin/help page and through
  436. * the module's individual help link.
  437. * - user/help#modulename
  438. * The help for a distributed authorization module (if applicable).
  439. * - node/add#nodetype
  440. * The description of a node type (if applicable).
  441. * @return
  442. * A localized string containing the help text. Every web link, l(), or
  443. * url() must be replaced with %something and put into the final t()
  444. * call:
  445. * $output .= 'A role defines a group of users that have certain
  446. * privileges as defined in %permission.';
  447. * $output = t($output, array('%permission' => l(t('user permissions'),
  448. * 'admin/user/permission')));
  449. *
  450. * For a detailed usage example, see page_example.module.
  451. */
  452. function hook_help($section) {
  453. switch ($section) {
  454. case 'admin/help#block':
  455. return t('<p>Blocks are the boxes visible in the sidebar(s)
  456. of your web site. These are usually generated automatically by
  457. modules (e.g. recent forum topics), but you can also create your
  458. own blocks using either static HTML or dynamic PHP content.</p>');
  459. break;
  460. case 'admin/modules#description':
  461. return t('Controls the boxes that are displayed around the main content.');
  462. break;
  463. }
  464. }
  465. /**
  466. * Perform setup tasks.
  467. *
  468. * This hook is run at the beginning of the page request. It is typically
  469. * used to set up global parameters which are needed later in the request.
  470. *
  471. * Only use this hook if your code must run even for cached page views.
  472. * If you have code which must run once on all non cached pages, use hook_menu(!$may_cache)
  473. * instead. Thats the usual case. If you implement this hook and see an error like 'Call to
  474. * undefined function', it is likely that you are depending on the presence of a module which
  475. * has not been loaded yet. It is not loaded because Drupal is still in bootstrap mode.
  476. * The usual fix is to move your code to hook_menu(!$may_cache).
  477. *
  478. * @return
  479. * None.
  480. */
  481. function hook_init() {
  482. global $recent_activity;
  483. if ((variable_get('statistics_enable_auto_throttle', 0)) &&
  484. (!rand(0, variable_get('statistics_probability_limiter', 9)))) {
  485. $throttle = throttle_status();
  486. // if we're at throttle level 5, we don't do anything
  487. if ($throttle < 5) {
  488. $multiplier = variable_get('statistics_throttle_multiplier', 60);
  489. // count all hits in past sixty seconds
  490. $result = db_query('SELECT COUNT(timestamp) AS hits FROM
  491. {accesslog} WHERE timestamp >= %d', (time() - 60));
  492. $recent_activity = db_fetch_array($result);
  493. throttle_update($recent_activity['hits']);
  494. }
  495. }
  496. }
  497. /**
  498. * Define internal Drupal links.
  499. *
  500. * This hook enables modules to add links to many parts of Drupal. Links
  501. * may be added in nodes or in the navigation block, for example.
  502. *
  503. * @param $type
  504. * An identifier declaring what kind of link is being requested.
  505. * Possible values:
  506. * - node: Links to be placed below a node being viewed.
  507. * - comment: Links to be placed below a comment being viewed.
  508. * @param $node
  509. * A node object passed in case of node links.
  510. * @param $teaser
  511. * In case of node link: a 0/1 flag depending on whether the node is
  512. * displayed with its teaser or its full form (on a node/nid page)
  513. * @return
  514. * An array of the requested links.
  515. *
  516. * For a detailed usage example, see node_example.module.
  517. */
  518. function hook_link($type, $node = NULL, $teaser = FALSE) {
  519. $links = array();
  520. if ($type == 'node' && $node->type == 'book') {
  521. if (book_access('update', $node)) {
  522. $links[] = l(t('edit this page'), "node/$node->nid/edit",
  523. array('title' => t('Suggest an update for this book page.')));
  524. }
  525. if (!$teaser) {
  526. $links[] = l(t('printer-friendly version'), "book/print/$node->nid",
  527. array('title' => t('Show a printer-friendly version of this book page
  528. and its sub-pages.')));
  529. }
  530. }
  531. return $links;
  532. }
  533. /**
  534. * Define menu items and page callbacks.
  535. *
  536. * This hook enables modules to register paths, which determines whose
  537. * requests are to be handled. Depending on the type of registration
  538. * requested by each path, a link is placed in the the navigation block and/or
  539. * an item appears in the menu administration page (q=admin/menu).
  540. *
  541. * This hook is also a good place to put code which should run exactly once
  542. * per page view. Put it in an if (!may_cache) block.
  543. *
  544. * @param $may_cache
  545. * A boolean indicating whether cacheable menu items should be returned. The
  546. * menu cache is per-user, so items can be cached so long as they are not
  547. * dependent on the user's current location. See the local task definitions
  548. * in node_menu() for an example of uncacheable menu items.
  549. * @return
  550. * An array of menu items. Each menu item is an associative array that may
  551. * contain the following key-value pairs:
  552. * - "path": Required. The path to link to when the user selects the item.
  553. * - "title": Required. The translated title of the menu item.
  554. * - "callback": The function to call to display a web page when the user
  555. * visits the path. If omitted, the parent menu item's callback will be used
  556. * instead.
  557. * - "callback arguments": An array of arguments to pass to the callback function.
  558. * - "access": A boolean value that determines whether the user has access
  559. * rights to this menu item. Usually determined by a call to user_access().
  560. * If omitted and "callback" is also absent, the access rights of the parent
  561. * menu item will be used instead.
  562. * - "weight": An integer that determines relative position of items in the menu;
  563. * higher-weighted items sink. Defaults to 0. When in doubt, leave this alone;
  564. * the default alphabetical order is usually best.
  565. * - "type": A bitmask of flags describing properties of the menu item.
  566. * Many shortcut bitmasks are provided as constants in menu.inc:
  567. * - MENU_NORMAL_ITEM: Normal menu items show up in the menu tree and can be
  568. * moved/hidden by the administrator.
  569. * - MENU_ITEM_GROUPING: Item groupings are used for pages like "node/add"
  570. * that simply list subpages to visit.
  571. * - MENU_CALLBACK: Callbacks simply register a path so that the correct
  572. * function is fired when the URL is accessed.
  573. * - MENU_DYNAMIC_ITEM: Dynamic menu items change frequently, and so should
  574. * not be stored in the database for administrative customization.
  575. * - MENU_SUGGESTED_ITEM: Modules may "suggest" menu items that the
  576. * administrator may enable.
  577. * - MENU_LOCAL_TASK: Local tasks are rendered as tabs by default.
  578. * - MENU_DEFAULT_LOCAL_TASK: Every set of local tasks should provide one
  579. * "default" task, that links to the same path as its parent when clicked.
  580. * If the "type" key is omitted, MENU_NORMAL_ITEM is assumed.
  581. *
  582. * For a detailed usage example, see page_example.module.
  583. *
  584. */
  585. function hook_menu($may_cache) {
  586. global $user;
  587. $items = array();
  588. if ($may_cache) {
  589. $items[] = array('path' => 'node/add/blog', 'title' => t('blog entry'),
  590. 'access' => user_access('maintain personal blog'));
  591. $items[] = array('path' => 'blog', 'title' => t('blogs'),
  592. 'callback' => 'blog_page',
  593. 'access' => user_access('access content'),
  594. 'type' => MENU_SUGGESTED_ITEM);
  595. $items[] = array('path' => 'blog/'. $user->uid, 'title' => t('my blog'),
  596. 'access' => user_access('maintain personal blog'),
  597. 'type' => MENU_DYNAMIC_ITEM);
  598. $items[] = array('path' => 'blog/feed', 'title' => t('RSS feed'),
  599. 'callback' => 'blog_feed',
  600. 'access' => user_access('access content'),
  601. 'type' => MENU_CALLBACK);
  602. }
  603. return $items;
  604. }
  605. /**
  606. * Grant access to nodes.
  607. *
  608. * This hook is for implementation by node access modules. In addition to
  609. * managing entries in the node_access table in the database, such modules must
  610. * implement this hook to inform Drupal which "grants" the current user has.
  611. * For example, in a role-based access scheme, this function would return a
  612. * list of the roles the user belongs to.
  613. *
  614. * @param $user
  615. * The user object whose grants are requested.
  616. * @param $op
  617. * The node operation to be performed, such as "view", "update", or "delete".
  618. * @return
  619. * An array whose keys are "realms" of grants such as "user" or "role", and
  620. * whose values are linear lists of grant IDs.
  621. *
  622. * For a detailed example, see node_access_example.module.
  623. */
  624. function hook_node_grants($user, $op) {
  625. $grants = array();
  626. if ($op == 'view') {
  627. if (user_access('access content')) {
  628. $grants[] = 0;
  629. }
  630. if (user_access('access private content')) {
  631. $grants[] = 1;
  632. }
  633. }
  634. if ($op == 'update' || $op == 'delete') {
  635. if (user_access('edit content')) {
  636. $grants[] = 0;
  637. }
  638. if (user_access('edit private content')) {
  639. $grants[] = 1;
  640. }
  641. }
  642. return array('example' => $grants);
  643. }
  644. /**
  645. * Act on nodes defined by other modules.
  646. *
  647. * Despite what its name might make you think, hook_nodeapi() is not
  648. * reserved for node modules. On the contrary, it allows modules to react
  649. * to actions affecting all kinds of nodes, regardless of whether that
  650. * module defined the node.
  651. *
  652. * @param &$node
  653. * The node the action is being performed on.
  654. * @param $op
  655. * What kind of action is being performed. Possible values:
  656. * - "delete": The node is being deleted.
  657. * - "insert": The node is being created (inserted in the database).
  658. * - "load": The node is about to be loaded from the database. This hook
  659. * can be used to load additional data at this time.
  660. * - "prepare": The node is about to be shown on the add/edit form.
  661. * - "search result": The node is displayed as a search result. If you
  662. * want to display extra information with the result, return it.
  663. * - "print": Prepare a node view for printing. Used for printer-friendly view in book_module
  664. * - "update": The node is being updated.
  665. * - "submit": The node passed validation and will soon be saved. Modules may
  666. * use this to make changes to the node before it is saved to the database.
  667. * - "update index": The node is being indexed. If you want additional
  668. * information to be indexed which is not already visible through
  669. * nodeapi "view", then you should return it here.
  670. * - "validate": The user has just finished editing the node and is
  671. * trying to preview or submit it. This hook can be used to check
  672. * the node data. Errors should be set with form_set_error().
  673. * - "view": The node is about to be presented to the user. The module
  674. * may change $node->body prior to presentation. This hook will be called
  675. * after hook_view(), so the module may assume the node is filtered and
  676. * now contains HTML.
  677. * - "rss item": An RSS feed is generated. The module can return properties
  678. * to be added to the RSS item generated for this node. See comment_nodeapi()
  679. * and upload_nodeapi() for examples. The $node passed can also be modified
  680. * to add or remove contents to the feed item.
  681. * @param $a3
  682. * - For "view", passes in the $teaser parameter from node_view().
  683. * - For "validate", passes in the $form parameter from node_validate().
  684. * @param $a4
  685. * - For "view", passes in the $page parameter from node_view().
  686. * @return
  687. * This varies depending on the operation.
  688. * - The "submit", "insert", "update", "delete", "print' and "view" operations have no
  689. * return value.
  690. * - The "load" operation should return an array containing pairs
  691. * of fields => values to be merged into the node object.
  692. *
  693. * If you are writing a node module, do not use this hook to perform
  694. * actions on your type of node alone. Instead, use the hooks set aside
  695. * for node modules, such as hook_insert() and hook_form().
  696. */
  697. function hook_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  698. switch ($op) {
  699. case 'submit':
  700. if ($node->nid && $node->moderate) {
  701. // Reset votes when node is updated:
  702. $node->score = 0;
  703. $node->users = '';
  704. $node->votes = 0;
  705. }
  706. break;
  707. case 'insert':
  708. case 'update':
  709. if ($node->moderate && user_access('access submission queue')) {
  710. drupal_set_message(t('The post is queued for approval'));
  711. }
  712. elseif ($node->moderate) {
  713. drupal_set_message(t('The post is queued for approval. The editors will decide whether it should be published.'));
  714. }
  715. break;
  716. }
  717. }
  718. /**
  719. * Define user permissions.
  720. *
  721. * This hook can supply permissions that the module defines, so that they
  722. * can be selected on the user permissions page and used to restrict
  723. * access to actions the module performs.
  724. *
  725. * @return
  726. * An array of permissions strings.
  727. *
  728. * Permissions are checked using user_access().
  729. *
  730. * For a detailed usage example, see page_example.module.
  731. */
  732. function hook_perm() {
  733. return array('administer my module');
  734. }
  735. /**
  736. * Ping another server.
  737. *
  738. * This hook allows a module to notify other sites of updates on your
  739. * Drupal site.
  740. *
  741. * @param $name
  742. * The name of your Drupal site.
  743. * @param $url
  744. * The URL of your Drupal site.
  745. * @return
  746. * None.
  747. */
  748. function hook_ping($name = '', $url = '') {
  749. $feed = url('node/feed');
  750. $client = new xmlrpc_client('/RPC2', 'rpc.weblogs.com', 80);
  751. $message = new xmlrpcmsg('weblogUpdates.ping',
  752. array(new xmlrpcval($name), new xmlrpcval($url)));
  753. $result = $client->send($message);
  754. if (!$result || $result->faultCode()) {
  755. watchdog('error', 'failed to notify "weblogs.com" (site)');
  756. }
  757. unset($client);
  758. }
  759. /**
  760. * Define a custom search routine.
  761. *
  762. * This hook allows a module to perform searches on content it defines
  763. * (custom node types, users, or comments, for example) when a site search
  764. * is performed.
  765. *
  766. * Note that you can use form API to extend the search. You will need to use
  767. * hook_form_alter() to add any additional required form elements. You can
  768. * process their values on submission using a custom validation function.
  769. * You will need to merge any custom search values into the search keys
  770. * using a key:value syntax. This allows all search queries to have a clean
  771. * and permanent URL. See node_form_alter() for an example.
  772. *
  773. * @param $op
  774. * A string defining which operation to perform:
  775. * - 'name': the hook should return a translated name defining the type of
  776. * items that are searched for with this module ('content', 'users', ...)
  777. * - 'reset': the search index is going to be rebuilt. Modules which use
  778. * hook_update_index() should update their indexing bookkeeping so that it
  779. * starts from scratch the next time hook_update_index() is called.
  780. * - 'search': the hook should perform a search using the keywords in $keys
  781. * - 'status': if the module implements hook_update_index(), it should return
  782. * an array containing the following keys:
  783. * - remaining: the amount of items that still need to be indexed
  784. * - total: the total amount of items (both indexed and unindexed)
  785. *
  786. * @param $keys
  787. * The search keywords as entered by the user.
  788. *
  789. * @return
  790. * An array of search results.
  791. * Each item in the result set array may contain whatever information
  792. * the module wishes to display as a search result.
  793. * To use the default search result display, each item should be an
  794. * array which can have the following keys:
  795. * - link: the URL of the found item
  796. * - type: the type of item
  797. * - title: the name of the item
  798. * - user: the author of the item
  799. * - date: a timestamp when the item was last modified
  800. * - extra: an array of optional extra information items
  801. * - snippet: an excerpt or preview to show with the result
  802. * (can be generated with search_excerpt())
  803. * Only 'link' and 'title' are required, but it is advised to fill in
  804. * as many of these fields as possible.
  805. *
  806. * The example given here is for node.module, which uses the indexed search
  807. * capabilities. To do this, node module also implements hook_update_index()
  808. * which is used to create and maintain the index.
  809. *
  810. * We call do_search() with the keys, the module name and extra SQL fragments
  811. * to use when searching. See hook_update_index() for more information.
  812. *
  813. * @ingroup search
  814. */
  815. function hook_search($op = 'search', $keys = null) {
  816. switch ($op) {
  817. case 'name':
  818. return t('content');
  819. case 'reset':
  820. variable_del('node_cron_last');
  821. return;
  822. case 'search':
  823. $find = do_search($keys, 'node', 'INNER JOIN {node} n ON n.nid = i.sid '. node_access_join_sql() .' INNER JOIN {users} u ON n.uid = u.uid', 'n.status = 1 AND '. node_access_where_sql());
  824. $results = array();
  825. foreach ($find as $item) {
  826. $node = node_load(array('nid' => $item));
  827. $extra = node_invoke_nodeapi($node, 'search result');
  828. $results[] = array('link' => url('node/'. $item),
  829. 'type' => node_invoke($node, 'node_name'),
  830. 'title' => $node->title,
  831. 'user' => theme('username', $node),
  832. 'date' => $node->changed,
  833. 'extra' => $extra,
  834. 'snippet' => search_excerpt($keys, check_output($node->body, $node->format)));
  835. }
  836. return $results;
  837. }
  838. }
  839. /**
  840. * Preprocess text for the search index.
  841. *
  842. * This hook is called both for text added to the search index, as well as
  843. * the keywords users have submitted for searching.
  844. *
  845. * This is required for example to allow Japanese or Chinese text to be
  846. * searched. As these languages do not use spaces, it needs to be split into
  847. * separate words before it can be indexed. There are various external
  848. * libraries for this.
  849. *
  850. * @param $text
  851. * The text to split. This is a single piece of plain-text that was
  852. * extracted from between two HTML tags. Will not contain any HTML entities.
  853. * @return
  854. * The text after processing.
  855. */
  856. function hook_search_preprocess($text) {
  857. // Do processing on $text
  858. return $text;
  859. }
  860. /**
  861. * Declare administrative settings for a module.
  862. *
  863. * This hook provides an administrative interface for controlling various
  864. * settings for this module. A menu item for the module under "administration >>
  865. * settings" will appear in the administrative menu when this hook is implemented.
  866. *
  867. * @return
  868. * An array containing form items to place on the module settings
  869. * page.
  870. *
  871. * The form items defined on the settings page will be saved with
  872. * variable_set(), and can be later retrieved with variable_get(). If you
  873. * need to store more complicated data (for example, in a separate table),
  874. * define your own administration page and link to it using hook_menu().
  875. *
  876. * NOTE: if you are using 'checkboxes' or a multiple select, you may wish to
  877. * include the array_filter element within your form:
  878. * $form['array_filter'] = array('#type' => 'value', '#value' => TRUE);
  879. */
  880. function hook_settings() {
  881. $form['example_a'] = array(
  882. '#type' => 'textfield',
  883. '#title' => t('Setting A'),
  884. '#default_value' => variable_get('example_a', 'Default setting'),
  885. '#size' => 20,
  886. '#maxlength' => 255,
  887. '#description' => t('A description of this setting.'),
  888. );
  889. $form['example_b'] = array(
  890. '#type' => 'checkbox',
  891. '#title' => t('Setting B'),
  892. '#default_value' => variable_get('example_b', 0),
  893. '#description' => t('A description of this setting.'),
  894. );
  895. return $form;
  896. }
  897. /**
  898. * Act on taxonomy changes.
  899. *
  900. * This hook allows modules to take action when the terms and vocabularies
  901. * in the taxonomy are modified.
  902. *
  903. * @param $op
  904. * What is being done to $object. Possible values:
  905. * - "delete"
  906. * - "insert"
  907. * - "update"
  908. * - "form"
  909. * @param $type
  910. * What manner of item $object is. Possible values:
  911. * - "term"
  912. * - "vocabulary"
  913. * @param $object
  914. * The item on which $op is being performed.
  915. * @return
  916. * None for delete, insert and update.
  917. * For operations "form", a $form object containing the form api elements that you wish
  918. * to display on the form.
  919. */
  920. function hook_taxonomy($op, $type, $object = NULL) {
  921. if ($type == 'vocabulary' && ($op == 'insert' || $op == 'update')) {
  922. if (variable_get('forum_nav_vocabulary', '') == ''
  923. && in_array('forum', $object['nodes'])) {
  924. // since none is already set, silently set this vocabulary as the navigation vocabulary
  925. variable_set('forum_nav_vocabulary', $object['vid']);
  926. }
  927. }
  928. }
  929. /**
  930. * Update Drupal's full-text index for this module.
  931. *
  932. * Modules can implement this hook if they want to use the full-text indexing
  933. * mechanism in Drupal.
  934. *
  935. * This hook is called every cron run if search.module is enabled. A module
  936. * should check which of its items were modified or added since the last
  937. * run. It is advised that you implement a throttling mechanism which indexes
  938. * at most 'search_cron_limit' items per run (see example below).
  939. *
  940. * You should also be aware that indexing may take too long and be aborted if
  941. * there is a PHP time limit. That's why you should update your internal
  942. * bookkeeping multiple times per run, preferably after every item that
  943. * is indexed.
  944. *
  945. * Per item that needs to be indexed, you should call search_index() with
  946. * its content as a single HTML string. The search indexer will analyse the
  947. * HTML and use it to assign higher weights to important words (such as
  948. * titles). It will also check for links that point to nodes, and use them to
  949. * boost the ranking of the target nodes.
  950. *
  951. * @ingroup search
  952. */
  953. function hook_update_index() {
  954. $last = variable_get('node_cron_last', 0);
  955. $limit = (int)variable_get('search_cron_limit', 100);
  956. $result = db_query_range('SELECT n.nid, c.last_comment_timestamp FROM {node} n LEFT JOIN {node_comment_statistics} c ON n.nid = c.nid WHERE n.status = 1 AND n.moderate = 0 AND (n.created > %d OR n.changed > %d OR c.last_comment_timestamp > %d) ORDER BY GREATEST(n.created, n.changed, c.last_comment_timestamp) ASC', $last, $last, $last, 0, $limit);
  957. while ($node = db_fetch_object($result)) {
  958. $last_comment = $node->last_comment_timestamp;
  959. $node = node_load(array('nid' => $node->nid));
  960. // We update this variable per node in case cron times out, or if the node
  961. // cannot be indexed (PHP nodes which call drupal_goto, for example).
  962. // In rare cases this can mean a node is only partially indexed, but the
  963. // chances of this happening are very small.
  964. variable_set('node_cron_last', max($last_comment, $node->changed, $node->created));
  965. // Get node output (filtered and with module-specific fields).
  966. if (node_hook($node, 'view')) {
  967. node_invoke($node, 'view', false, false);
  968. }
  969. else {
  970. $node = node_prepare($node, false);
  971. }
  972. // Allow modules to change $node->body before viewing.
  973. node_invoke_nodeapi($node, 'view', false, false);
  974. $text = '<h1>'. drupal_specialchars($node->title) .'</h1>'. $node->body;
  975. // Fetch extra data normally not visible
  976. $extra = node_invoke_nodeapi($node, 'update index');
  977. foreach ($extra as $t) {
  978. $text .= $t;
  979. }
  980. // Update index
  981. search_index($node->nid, 'node', $text);
  982. }
  983. }
  984. /**
  985. * Act on user account actions.
  986. *
  987. * This hook allows modules to react when operations are performed on user
  988. * accounts.
  989. *
  990. * @param $op
  991. * What kind of action is being performed. Possible values:
  992. * - "categories": A set of user information categories is requested.
  993. * - "delete": The user account is being deleted. The module should remove its
  994. * custom additions to the user object from the database.
  995. * - "form": The user account edit form is about to be displayed. The module
  996. * should present the form elements it wishes to inject into the form.
  997. * - "submit": Modify the account before it gets saved.
  998. * - "insert": The user account is being added. The module should save its
  999. * custom additions to the user object into the database and set the saved
  1000. * fields to NULL in $edit.
  1001. * - "login": The user just logged in.
  1002. * - "logout": The user just logged out.
  1003. * - "load": The user account is being loaded. The module may respond to this
  1004. * and insert additional information into the user object.
  1005. * - "register": The user account registration form is about to be displayed.
  1006. * The module should present the form elements it wishes to inject into the form.
  1007. * - "update": The user account is being changed. The module should save its
  1008. * custom additions to the user object into the database and set the saved
  1009. * fields to NULL in $edit.
  1010. * - "validate": The user account is about to be modified. The module should
  1011. * validate its custom additions to the user object, registering errors as
  1012. * necessary.
  1013. * - "view": The user's account information is being displayed. The module
  1014. * should format its custom additions for display.
  1015. * @param &$edit
  1016. * The array of form values submitted by the user.
  1017. * @param &$account
  1018. * The user object on which the operation is being performed.
  1019. * @param $category
  1020. * The active category of user information being edited.
  1021. * @return
  1022. * This varies depending on the operation.
  1023. * - "categories": A linear array of associative arrays. These arrays have keys:
  1024. * - "name": The internal name of the category.
  1025. * - "title": The human-readable, localized name of the category.
  1026. * - "weight": An integer specifying the category's sort ordering.
  1027. * - "submit": None.
  1028. * - "insert": None.
  1029. * - "update": None.
  1030. * - "delete": None.
  1031. * - "login": None.
  1032. * - "logout": None.
  1033. * - "load": None.
  1034. * - "form": A $form array containing the form elements to display.
  1035. * - "register": A linear array of form groups for the specified category. Each group
  1036. * is represented as an associative array with keys:
  1037. * - "title": The human-readable, localized name of the group.
  1038. * - "data": A string containing the form elements to display.
  1039. * - "weight": An integer specifying the group's sort ordering.
  1040. * - "validate": None.
  1041. * - "view": An associative array of strings to display, keyed by category name.
  1042. */
  1043. function hook_user($op, &$edit, &$account, $category = NULL) {
  1044. if ($op == 'form' && $category == 'account') {
  1045. $form['comment_settings'] = array(
  1046. '#type' => 'fieldset',
  1047. '#title' => t('Comment settings'),
  1048. '#collapsible' => TRUE,
  1049. '#weight' => 4);
  1050. $form['comment_settings']['signature'] = array(
  1051. '#type' => 'textarea',
  1052. '#title' => t('Signature'),
  1053. '#default_value' => $edit['signature'],
  1054. '#description' => t('Your signature will be publicly displayed at the end of your comments.'));
  1055. return $form;
  1056. }
  1057. }
  1058. /**
  1059. * Register XML-RPC callbacks.
  1060. *
  1061. * This hook lets a module register callback functions to be called when
  1062. * particular XML-RPC methods are invoked by a client.
  1063. *
  1064. * @return
  1065. * An array which maps XML-RPC methods to Drupal functions. Each array
  1066. * element is either a pair of method => function or an array with four
  1067. * entries:
  1068. * - The XML-RPC method name (for example, module.function).
  1069. * - The Drupal callback function (for example, module_function).
  1070. * - The method signature is an array of XML-RPC types. The first element
  1071. * of this array is the type of return value and then you should write a
  1072. * list of the types of the parameters. XML-RPC types are the following
  1073. * (See the types at http://www.xmlrpc.com/spec):
  1074. * - "boolean": 0 (false) or 1 (true).
  1075. * - "double": a floating point number (for example, -12.214).
  1076. * - "int": a integer number (for example, -12).
  1077. * - "array": an array without keys (for example, array(1, 2, 3)).
  1078. * - "struct": an associative array or an object (for example,
  1079. * array('one' => 1, 'two' => 2)).
  1080. * - "date": when you return a date, then you may either return a
  1081. * timestamp (time(), mktime() etc.) or an ISO8601 timestamp. When
  1082. * date is specified as an input parameter, then you get an object,
  1083. * which is described in the function xmlrpc_date
  1084. * - "base64": a string containing binary data, automatically
  1085. * encoded/decoded automatically.
  1086. * - "string": anything else, typically a string.
  1087. * - A descriptive help string, enclosed in a t() function for translation purposes.
  1088. * Both forms are shown in the example.
  1089. */
  1090. function hook_xmlrpc() {
  1091. return array(
  1092. 'drupal.login' => 'drupal_login',
  1093. array(
  1094. 'drupal.site.ping',
  1095. 'drupal_directory_ping',
  1096. array('boolean', 'string', 'string', 'string', 'string', 'string'),
  1097. t('Handling ping request'))
  1098. );
  1099. }
  1100. /**
  1101. * @} End of "addtogroup hooks".
  1102. */
Login or register to post comments