Drupal Module hooks : Module file

We have discussed about the hooks to be used in .install file in Drupal module hooks: install file and in this discussion we will look at the hooks to be used in .module file. Remember, a Drupal module can have multiple .module files and each .module file has one accompanying .info file providing information about the module.

So, here are the hooks

hook_node_info()

Drupal 5-7: An associative array having information about the node being created by the module

hook_node_info() hook declares the node being offered by the module. The node can have multiple fields including the title and the body field. From hook_node_info(), a developer can decide whether the node will have the body or not, what will be the labels of title field and the body field and how many number of words should be entered to be considered as description/body of the node, i.e. 10, 25. Body containing less than this number will not be considered as valid and will throw an error asking user to provide proper description/body.

here is an example of hook_node_info

/**
* Implementation of hook_node_info
*
* @author Drupal Developer
*/
function mynode_node_info() {
return array(
'mynode1' => array(
'name' => t("First Node"),
'help' => t("your first node in the module"),
'module' => 'mynode1',
'description' => t("Add a custom node type from a module"),
'min_word_count' => 20,
'locked' => TRUE,
),
'mynode2' => array(
'name' => t("Second node"),
'help' => t("Your second node in the module."),
'module' => 'mynode2',
'description' => t("Add second node from the same module"),
'min_word_count' => 10,
'locked' => TRUE,
),
);
}

Now, lets take a look at each key of the array.

'mynode1' and 'mynode2' are the machine readable names of the node being created.
'locked' indicates that the machine readable names can not be altered later, even by the admin.
'help': This text will be appeared on the node add/edit form to provide some guidance to create/modify the node
'module': Which function Drupal should look at when some operation is being carried out on a node, i.e. mynode1. Say, we are saving mynode1 node form, Drupal will call respective hooks starting with 'mynode1' as it is defined with the 'module' key.
'description': This will appear on the node/add page to assist the user what this node does.
'min_word_count': Minimum number of words that are required to recognize as valid body/description

hook_menu

Drupal 5: takes an argument $may_cache, which indicates what menu items to be cached.
Drupal 6 & 7: No extra arguments.

We will learn hook_menu for all the versions.
Drupal 5 hook_menu

/**
* Implementation of hook_menu
*
* @author Drupal Developer
*/
function mynode_menu($may_cache) {
$items = array();
global $user;
if ($may_cache) {
$items[] = array (
'path' => 'admin/mynode',
'title' => t("Admin page for my node"),
'description' => t("Manage mynode"),
'position' => 'left',
'weight' => -8,
'callback' => 'mynode_admin_manage',
'access' => user_access('administer site configuration'),
);
}

$items[] = array(
'type' => MENU_LOCAL_TASK,
'path' => 'user/%/mynode',
'title' => t("Admin page for my node"),
'description' => t("Manage mynode"),
'weight' => -8,
'callback' => 'mynode_user_data',
'callback arguments' => array(1),
'access' => user_access('edit own mynode'),
);

return $items;
}

Now lets have a look at each of the array key of $items.

'type': How the menu will be displayed. if not defined, default to 'MENU_NORMAL_ITEM', which displays the menu in the navigation menu.
'path': The path to which this menu will redirect.
'title': The title of the memu
'description': Description mentioning the what this menu does
'position': If this menu is to be shown at /admin, this values decides in which column it should be placed.
'callback': When clinking on the menu, the function defined with this key will be called and executed.
'callback arguments': The arguments to be passed to the function defined with 'callback'
'weight': If other than 'MENU_CALLBACK', the position of the menu item a positive integer will place the menu item below other items and a negative number will place it higher than other menu items. if left blank, the position is decided in alphabetic order
'access': The value defined with this key determines whether the current user can access the menu item or not. This should be either TRUE or FALSE. We can call a function which return a boolean value and determines the access permissions.

Drupal 6 hook_menu

/**
* Implementation of hook_menu
*
* @author Drupal Developer
*/
function account_menu() {
$item = array();

$item['admin/user/account'] = array(
'title' => 'User account',
'title callback' => 't',
'page callback' => 'drupal_get_form',
'page arguments' => array('admin_account_configure'),
'access callback' => 'user_access',
'access arguments' => array('administer account type'),
);

return $item;
}

Lets look at what has been changed in Drupal 6

There is no 'path' key in Drupal 6 any more. We can define the path as a key to $item.
'title callback': A function which translates the menu item title to current language.
'page callback': This is equivalent to 'callback' in Drupal 5.
'page arguments': This is equivalent to 'callback arguments' in Drupal 5.
'access callback': Unlike Drupal 5, we just need to define the function name.
'access arguments': Provide additional arguments to function defined in 'access'.
'file': Provide the name of the file in which the 'callback' is defined. If defined in the same file as hook_menu, do not add this key
'file path': The path to the file defined in 'file'. This must not include the file name.
'menu_name': Provide the name of the menu to which you want to place the menu item in. Default set to navigation menu.

hook_form

To display a form to users, we need to build a 'form' using Drupal APIs. This form can be a node form, a profile page or can be administrative settings form. All of them make use of Drupal APIs. Use of Drupal APIs makes it easy to handle different form operations like edit, load, submit, update and insert.
When defined in any custom node module, it can be access at node/add/. We can control all the elements on the form by writing proper code in hook_form and hook_form_alter.

Drupal 5: hook_form(&$node, $form_values)
Drupal 6: hook_form(&$node, $form_state)
Drupal 7: hook_form($node, $form_state)

The $form_values or $form_state holds the form state or the form values being submitted or loaded.

Here is an example for Drupal 6

/**
* Implemenation of hook_form
*
* @param $node
* @param $form_state
* @return $form
* @author Drupal Developer
*/
function mynode_form(&$node, $form_state) {
$form = array();
$form['title'] = array(
'' => 'textfield',
'' => t("Mynode title"),
'' => TRUE,
'' => $node->title,
'' => -20,
);

$form['gender'] = array(
'' => 'radios',
'' => t("Gender"),
'' => TRUE,
'' => $node->gender,
'' => array(
0 => t("Hide"),
1 => t("Male"),
2 => t("Female"),
),
'' => -10,
);

return $form;
}

hook_form_alter

hook_form_alter is used to alter the form elements after the form has been built but before it has been displayed on the browser. With hook_form_alter, we change the behavior or the appearance of an element by adding a css or javascript file on the fly. Here is the description of the hook_form_alter

Drupal 5: hook_form_alter($form, $form_id)
Drupal 6: hook_form_alter(&$form, $form_state, $form_id)
Drupal 7: hook_form_alter(&form, &$form_state, $form_id)

Arguments

$form: The associated array containing the form elements
$form_state: The current state of the form
$form_id: The unique id of the form by which we can alter a particular form

Here is an example of hook_form_alter for Drupal 6
/**
* Implementation of hook_form_id
* @param $form
* @param $form_state
* @param $form_id
* @return none
* @author Drupal Developer
*/
function mynode_form_alter(&$form, $form_state, $form_id) {
unset($form['options']); //remove the options from the form
$form['title'][''] = t('Name');
}

hook_insert

When we build a custom node module with some custom field other than title and body, we need to save them somewhere in the tables created by the module itself. The data should be inserted after the form has been submitted. hook_insert is used to insert the data to any specific table in the db such as the tables created by a custom module. hook_insert takes node as an argument and all the submitted values and generated node id can be access using object operater. i.e $node->title

Drupal 5, 6, 7: hook_insert($node)

/**
* Implementation of hook_insert
*
* @param $node
* @return unknown_type
* @author Drupal Developer
*/
function mynode_insert($node) {
db_query("INSERT INTO {mynode} VALUES(%d, '%s', '%s')", $node->nid, $node->firstname, $node->lastname);
drupal_set_message(t("Mynode has been created"));
}

hook_update

You have your data in your custom table and you can display those data at the time of editing a node. But how would you update those values after you complete the editing? This is where hook_update is used. hook_update executes after a form editing has been completed. At this time, hook_insert doesn't executed. You can update values in the database writing query in hook_update. As you have the $node, provided as an argument, you can alter any values in any table which have at least one field available with the $node i.e node id.

Drupal 5, 6, 7: hook_update($node)

/**
* Implementation of hook_update
*
* @param $node
* @return unknown_type
* @author Drupal Developer
*/
function mynode_update($node) {
db_query("UPDATE {mynode} SET firstname = '%s', lastname = '%s' WHERE nid = %d",
$node->firstname, $node->lastname, $node->nid);
}

hook_delete

hook_delete is get executed when a node is deleted. Any modules, which may want to remove some information they store to the database, associated with the node, can implement the hook_delete and perform necessary operation to remove those values. These values will become orphans if they are not deleted. But its better to free some space by removing such values. The node object will be removed from all the locations including memory and database after all the modules have finished performing operations within hook_delete.

Drupal 5, 6: hook_delete(&$node)
Drupal 7: hook_delete($node)

/**
* Implementation of hook_delete
* @param $node
* @return unknown_type
* @author Drupal Developer
*/
function mynode_delete(&$node) {
db_query("DELETE FROM {mynode} WHERE nid = %d", $node->nid);
}

hook_view

hook_view is responsible for displaying a node on the page after it has been saved to the database and all the modules have finished operating on hook_insert or hook_update. hook_view is get executed when we access the node by typing the path to the node in browser's location bar and when the node is saved for the first time and when the node is updated. We can alter the way node is displayed and can add more information related to the node. By implementing hook_view, a module is able to inject more information to the node object. The node display can be altered on teaser view which is a summary of the node or on the full view of the node or on both of these.

Drupal 5, 6: hook_view($node, $teaser = FALSE, $page = FALSE)
Drupal 7: hook_view($node, $view_mode = 'full')

/**
* Implementation of hook_view
* @param $node
* @param $teaser
* @param $page
* @return unknown_type
* @author Drupal Developer
*/
function mynode_view($node, $teaser = FALSE, $page = FALSE) {
if ($page) {
$breadcrumb = array();
$breadcrumb[] = l(t("home"), $base_url);
$breadcrumb[] = t("Testing");
drupal_set_breadcrumb($breadcrumb);
}
$node = node_prepare($node, $teaser);
$ss__data = theme_get_extra_info($node->nid);//a call to function which fetches information from database
$node->content['mynode'] = array(
'' => $ss__data ? $ss__data : t("No data found.")
." ". l(t("Add a mynode now!"), "node/add/mynode"),
'' => 10,
);
return $node;
}

hook_load

hook_load is a way to load extra information associated to the node which can not be fetch by Drupal itself; Since Drupal doesn't know about the tables, to and from which the module stores and retrieves data.

Drupal 5, 6: hook_load($node)
Drupal 7: hook_load($nodes)

/**
* Implementation of hook_load
*
* @param $node
* @return unknown_type
* @author Drupal Developer
*/
function codelet_load($node) {
$ss__code = theme_get_code($node->nid);
$node->code = $ss__code;
return $node;
}

hook_nodeapi

hook_nodeapi is implemented to execute codes on all the node operation, no matter in which module the hook_nodeapi is defined. hook_nodeapi is executed after all the hook_insert, hook_update, hook_delete, hook_view, hook_load have been executed, implemented by different modules. The main purpose of this hook is provide a way where we can execute operations common to all the node modules.

Drupal 5, 6, 7: hook_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL)

$node: The node being operated upon
$op: Current operation on the node. i.e. insert, update
$a3: In case, the $op is 'view', its $tease. For 'validate', its $form
$a4: In case, the $op is 'view', its $page

/**
* Implementation of hook_nodeapi
*
* @param $node
* @param $op
* @param $a3
* @param $a4
* @return unknown_type
* @author Drupal Developer
*/
function account_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
switch ($op) {
case 'view':
if (!empty($node->field_upload)) {
foreach ($node->field_upload as $key => $am__file) {
drupal_add_css(drupal_get_path("module", 'account') ."/share-file.css");
path_set_alias($am__file['filepath'], 'download/'. $am__file['fid']);
$ss__path = drupal_get_path_alias($node->field_upload[$key]['filepath']);
$node->field_upload[$key]['filepath'] = $ss__path;
}
if (!empty($node->field_upload)) {
$attributes = array(
'class' => 'share-file popups-form',
'id' => "node-". $node->nid,
);

$node->content['share'] = array(
'' => 'item',
'' => t("By sharing files, you can earn extra points"),
'' => -1,
'' => l(t("File permissions"), 'perm/'. $node->nid,
array('attributes' => $attributes)),
);
}
}
}
}
// this is an example from one of my test projects

QR code for this page URL This page URL
Feedback