Views Bulk Operations development guide (Drupal 6)

Last updated on
30 April 2025

This guide applies to Drupal 6 only, last updated for release 6.x-1.13. There is a Drupal 7 VBO development guide available. Please note that the Drupal 6 version of VBO is no longer safe to use. (Read the Security Advisory)

Developing operations for VBO

VBO reuses existing Drupal infrastructure to allow new operations to be added. The main method to create a new operation is by writing a Drupal Action. Please read the linked page first. VBO supports a superset of the capabilities of actions, so here are the steps to create an action that fully utilizes VBO.

Implement hook_action_info()

VBO supports a superset of the attributes that describe an action. Here are the added attributes:

  • parameters (optional): keyed array. This attribute gets appended as is to the $context array that is passed to action_function().
  • behavior (optional): array of flags. This attribute exists in the original Action specification, but is augmented here with additional flags:
    • views_node_property to signify that this action will show the node on-screen.
    • deletes_node_property to signify that this action might delete the node.

    These flags, along with the original changes_node_property, cause VBO to call node_access() on each node that is about to be acted upon, with the $op parameter corresponding to the specified flag(s). If VBO is invoked in direct execution mode or through Batch API, the current user's permissions are checked against the required node access. If a deferred execution mode such as Job Queue is used, then the uid of the user who fired the job is used.

  • permissions (optional): array of permissions. VBO calls user_access on each permission before accepting to execute the selected action.
  • aggregate (optional): boolean. If TRUE, all selected objects' IDs (oids) will be packed in an array and passed as the first argument to the action function, instead of passing each object one by one. This is useful to implement aggregate functions that perform a single operation on the whole selection set.

Implement action_function(&$object, $context)

TODO

Implement action_function_form($context)

TODO

Implement action_function_submit($form, $form_state)

TODO

Implement action_function_validate($form, $form_state)

TODO

Implement action_function_views_bulk_operations_form($settings, $entityType, $settings_dom_id)

This hook allows you provide extra form items at configuration action form (when you add an action to the view).

/**
 * Implements ACTION_FUNCTION_views_bulk_operations_form().
 */
function action_function_views_bulk_operations_form($settings, $entityType, $settings_dom_id) {

  $settings += array(
    'set_tag' => array("bar"),
  );

  $form['set_tag'] = array(
    '#title' => t('Set a tag by default'),
    '#type' => 'select',
    '#options' => array(
      "foo" => "foo",
      "bar" => "Bar"
    ),
    '#default_value' => $settings['set_tag'],
  );

  return $form;
}

So, the "set_tag" will be available at action execution time (as $context key), then you will can use to apply your logic.

Describing operations for custom tables

First, you need to describe the action to Drupal. If the type is not a node or user, then you will have to create a new one and describe it with hook_views_bulk_operations_object_info.

/**
 * Implements hook_action_info
 */
function MODULE_action_info() {
  return array(
    'MODULE_ACTIONNAME_action' => array(
      'type' => 'OBJECTTYPE',
      'description' => t('ACTIONDESCRIPTION'),
      'configurable' => FALSE,
      'hooks' => array(
        'any' => TRUE,
      ),
      // Set to TRUE if you want to operate on an array of identifiers
      // Set to FALSE if you want to operate on each separately as an object
      'aggregate' => FALSE,
    ),
  );
}

This is the glue that tells VBO what object to use with a particular table.

/**
 * Implements hook_views_bulk_operations_object_info
 */
function MODULE_views_bulk_operations_object_info() {
  return array(
    'OBJECTTYPE' => array(
      'type' => 'OBJECTTYPE',
      'base_table' => 'TABLENAME',
      'load' => '_OBJECTTYPELOAD',
      'title' => t('OBJECTTITLE'),
    ),
  );
}

Define how the object is created.

/**
 * Load an _OBJECTTYPE object; required for VBO
 * 
 * @param int $ID
 * @return object
 */
function _OBJECTTYPELOAD($ID) {
  $sql_query  = 'SELECT * ';
  $sql_query .= 'FROM {TABLENAME} ';
  $sql_query .= 'WHERE ID = %d ';
  return db_fetch_object(db_query($sql_query, $ID));
}

Finally, perform the action.

/**
 * Implementation of a Drupal action
 * 
 * @param object $object
 * @param array $context
 */
function MODULE_ACTIONNAME_action(&$object, $context = array()) {
  // If aggregate is set to TRUE, $object will be an array containing the identifier.
  // Else, it will be the object from _OBJECTTYPELOAD
  dsm($object); // Debug the object with devel module
  dsm($context); // Debug the context with devel module
}

Help improve this page

Page status: Not set

You can: