You are here

multiblock.module in MultiBlock 5

Same filename and directory in other branches
  1. 8 multiblock.module
  2. 6 multiblock.module
  3. 7 multiblock.module

File

multiblock.module
View source
<?php

/**
 * Implementation of hook_menu().
 */
function multiblock_menu($may_cache) {
  $items = array();
  if ($may_cache) {
    $items[] = array(
      'path' => 'admin/build/block/instances',
      'title' => t('Instances'),
      'description' => t('Create and delete instances of blocks.'),
      'callback' => 'multiblock_general',
      'access' => user_access('administer blocks'),
      'type' => MENU_LOCAL_TASK,
      'weight' => -1,
    );
    $items[] = array(
      'path' => 'admin/build/block/instances/delete',
      'title' => t('Delete Block Instance'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'multiblock_delete_form',
      ),
      'access' => user_access('administer blocks'),
      'type' => MENU_CALLBACK,
    );
  }
  return $items;
}

/**
 * Implementation of hook_block().
 */
function multiblock_block($op = 'list', $delta = 0, $edit = array()) {
  if ($op == 'list') {

    // Get all of the block instances that exist.
    $blocks = multiblock_get_block(NULL);
    $list = array();
    foreach ($blocks as $block) {
      $list[$block->delta] = array(
        'info' => $block->title,
      );
    }
    return $list;
  }
  else {
    if ($op == 'view' || $op == 'configure' || $op == 'save') {
      return multiblock_call_block($delta, $op, $edit);
    }
  }
}

/**
 * Fetch a given block from the multiblock database table.
 * 
 * @param $delta
 *   Optional. Retreive a single block based on this delta. If none specified,
 *   all multiblock instances are returned.
 * @param $reset
 *   Optional. Boolean value to reset the interal cache of this function.
 */
function multiblock_get_block($delta = NULL, $reset = FALSE) {
  static $blocks;
  if (!isset($blocks) || $reset) {
    $blocks = array();
    $result = db_query("SELECT * FROM {multiblock}");
    while ($row = db_fetch_object($result)) {
      $blocks[$row->delta] = $row;
    }
  }
  return is_numeric($delta) ? $blocks[$delta] : $blocks;
}

/**
 * Dispatch a hook_block call to it's respective module. Paramater $delta
 * is the new multiblock delta that we're using and $op is the op we are
 * dispatching.
 */
function multiblock_call_block($delta, $op, $edit) {
  $result = db_query("SELECT module, orig_delta, delta, multi_settings FROM {multiblock} WHERE delta='%s'", $delta);
  if ($block_info = db_fetch_object($result)) {

    // If this block is multiblock enabled, send it the delta of the block we're using.
    if ($block_info->multi_settings == 1) {
      $edit['multiblock_delta'] = array(
        '#type' => 'value',
        '#value' => $block_info->delta,
      );
    }
    return module_invoke($block_info->module, 'block', $op, $block_info->orig_delta, $edit);
  }

  // No such multiblock, shouldn't ever happen.
  return;
}

/**
 * Page callback for the "Manage Block Instances page".
 */
function multiblock_general() {
  if (func_num_args() && func_get_arg(0) == 'edit' && is_numeric($instance = func_get_arg(1))) {
    $req_block = multiblock_get_block($instance);
  }

  // Fetch blocks directly from modules using block.module function.
  $blocks = _block_rehash();

  // Sort blocks how we want them.
  usort($blocks, 'multiblock_block_sort');

  // Fetch "Add Instance" form.
  if (isset($req_block)) {
    $form = drupal_get_form('multiblock_add_form', $blocks, $req_block);
  }
  else {
    $form = drupal_get_form('multiblock_add_form', $blocks);
  }

  // Get an array of existing blocks.
  $multiblocks = multiblock_get_block(NULL, TRUE);
  return theme('multiblock_general', $form, $multiblocks, isset($req_block));
}

/**
 * "Add Instance" form.
 */
function multiblock_add_form($blocks, $update = NULL) {
  $form = array();
  $form['title'] = array(
    '#type' => 'textfield',
    '#title' => t('Instance Title'),
    '#maxlength' => 256,
    '#required' => TRUE,
    '#default_value' => $update ? $update->title : NULL,
  );
  if ($update) {
    $form['instance'] = array(
      '#type' => 'value',
      '#value' => $update->delta,
    );
  }
  else {

    // Turn $blocks into form options of block types.
    // Remember we need the module and delta to be able to tell what kind of
    // blocks we're talking about.
    $options = array();
    foreach ($blocks as $block) {

      // Don't include multiblock module blocks in the list.
      if ($block['module'] != 'multiblock') {
        $options[$block['module'] . '***MB***' . $block['delta']] = $block['info'];
      }
    }
    $form['block'] = array(
      '#type' => 'select',
      '#title' => t('Block type'),
      '#options' => $options,
      '#required' => TRUE,
    );
  }
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save'),
  );
  return $form;
}
function multiblock_delete_form($delta) {
  $block = multiblock_get_block($delta);
  if (empty($block)) {
    drupal_set_message(t('The multiblock with the delta @delta was not found.', array(
      '@delta' => $delta,
    )), 'error');
    return array();
  }
  $form['delta'] = array(
    '#type' => 'value',
    '#value' => $delta,
  );
  return confirm_form($form, t('Delete the block instance %title?', array(
    '%title' => $block->title,
  )), 'admin/build/block/instances', t('This will delete the instance of the block %title.', array(
    '%title' => $block->title,
  )), t('Delete'), t('Cancel'));
}
function multiblock_delete_form_submit($form_id, $form_values) {
  if (multiblock_delete($form_values['delta'])) {
    drupal_set_message(t('Block successfully deleted!'));
  }
  else {
    drupal_set_message(t('There was a problem deleting the block'));
  }
  return 'admin/build/block/instances';
}

/**
 * Add a multiblock instance.
 *
 * @param $original_block
 *   The original block for which an instance is being created.
 * @param $block_instance
 *   An object contain information about the particular block instance.
 * @return
 *   The delta of the newly added block.
 */
function multiblock_add($original_block, $block_instance) {

  // Create new delta for block instance.
  $delta = db_next_id('{multiblock}_delta');
  $sql = "INSERT INTO {multiblock}\n          (delta, title, module, orig_delta, multi_settings)\n          VALUES (%d, '%s', '%s', '%s', %d)";
  db_query($sql, $delta, $block_instance->title, $original_block->module, $original_block->delta, $block_instance->mb_enabled);
  return $delta;
}

/**
 * Delete a multiblock instance.
 */
function multiblock_delete($multiblock_delta) {
  $result = db_query('DELETE FROM {multiblock} WHERE delta = %d', (int) $multiblock_delta);
  if (ctype_digit($multiblock_delta) && db_affected_rows() == 1) {
    _block_rehash();
    return TRUE;
  }
  else {
    return FALSE;
  }
}

/**
 * Validate "Add Block Instance" form.
 */
function multiblock_add_form_validate($form_id, $form_values) {
  if (!isset($form_values['instance'])) {

    // Make sure we are getting a valid block to add.
    if (!preg_match('/^.+\\*\\*\\*MB\\*\\*\\*.+$/', $form_values['block'])) {
      form_set_error('block', t('Bad block module input, contact administrator'));
      return;
    }

    // Make sure the block and delta exist.
    $orig_block = multiblock_blockinfo_from_form($form_values['block']);
    if (!module_hook($orig_block['module'], 'block') || !array_key_exists($orig_block['delta'], module_invoke($orig_block['module'], 'block', 'list'))) {
      form_set_error('block', t('Module or block doesn\'t exist, contact administrator'));
    }
  }
}

/**
 * Add block instance to database from "Add Block Instance" form.
 */
function multiblock_add_form_submit($form_id, $form_values) {
  if (isset($form_values['instance'])) {
    db_query("UPDATE {multiblock} SET title='%s' WHERE delta=%d", $form_values['title'], $form_values['instance']);
    return 'admin/build/block/instances';
  }

  // Get the original block info.
  $orig_block = multiblock_blockinfo_from_form($form_values['block']);

  // Check whether this module is multiblock enabled.
  $mb_enabled = (int) (module_invoke($orig_block['module'], 'block', 'mb_enabled') == 'mb_enabled');

  // Create block instance information.
  $orig_block = (object) $orig_block;
  $instance = (object) array(
    'title' => $form_values['title'],
    'mb_enabled' => $mb_enabled,
  );

  // Add the block instance.
  multiblock_add($orig_block, $instance);
  drupal_set_message(t('Block instance %instance created.', array(
    '%instance' => $form_values['title'],
  )));
}

/**
 * Custom sort based on info element of array.
 */
function multiblock_block_sort($a, $b) {
  return strcmp($a['info'], $b['info']);
}

/**
 * Get the module and delta from the "Add Block Instance" block form element.
 */
function multiblock_blockinfo_from_form($form_value) {
  $matches = array();
  preg_match('/^(.+)\\*\\*\\*MB\\*\\*\\*(.+)$/', $form_value, $matches);
  return array(
    'module' => $matches[1],
    'delta' => $matches[2],
  );
}

/**
 * Get title of a block by its module and delta.
 */
function multiblock_get_block_title($module, $delta) {
  $block_info = module_invoke($module, 'block', 'list');
  return $block_info[$delta]['info'];
}

/**
 * Theme function for the "Manage Block Instances" page.
 */
function theme_multiblock_general($add_block_form, $multiblocks, $edit = FALSE) {
  $output = '';

  //  $noyes = array('No', 'Yes');
  $noyes = array(
    'misc/watchdog-error.png',
    'misc/watchdog-ok.png',
  );
  $output .= '<p><h3>' . ($edit ? t('Edit Instance') : t('Add Instance')) . '</h3>' . $add_block_form . '</p>';
  $header = array(
    t('Title'),
    t('Original Block Title'),
    t('Original Module'),
    t('MultiBlock Enabled'),
    t('Original Delta'),
    t('Action'),
  );
  foreach ($multiblocks as $row) {
    $ops_link = l(t('Edit'), 'admin/build/block/instances/edit/' . $row->delta) . ' ' . l(t('Delete'), 'admin/build/block/instances/delete/' . $row->delta);
    $title = multiblock_get_block_title($row->module, $row->orig_delta);
    $mb_enabled = $noyes[$row->multi_settings];
    $alt = t('Not Multiblock enabled');
    if ($row->multi_settings) {
      $alt = t('Multiblock enabled');
    }
    $rows[] = array(
      check_plain($row->title),
      $title,
      $row->module,
      array(
        'data' => theme('image', $mb_enabled, $alt, $alt),
        'align' => 'center',
      ),
      $row->orig_delta,
      $ops_link,
    );
  }
  $output .= '<p><h3>' . t('Manage Instances') . '</h3>' . theme('table', $header, $rows) . '</p>';
  return $output;
}

Functions

Namesort descending Description
multiblock_add Add a multiblock instance.
multiblock_add_form "Add Instance" form.
multiblock_add_form_submit Add block instance to database from "Add Block Instance" form.
multiblock_add_form_validate Validate "Add Block Instance" form.
multiblock_block Implementation of hook_block().
multiblock_blockinfo_from_form Get the module and delta from the "Add Block Instance" block form element.
multiblock_block_sort Custom sort based on info element of array.
multiblock_call_block Dispatch a hook_block call to it's respective module. Paramater $delta is the new multiblock delta that we're using and $op is the op we are dispatching.
multiblock_delete Delete a multiblock instance.
multiblock_delete_form
multiblock_delete_form_submit
multiblock_general Page callback for the "Manage Block Instances page".
multiblock_get_block Fetch a given block from the multiblock database table.
multiblock_get_block_title Get title of a block by its module and delta.
multiblock_menu Implementation of hook_menu().
theme_multiblock_general Theme function for the "Manage Block Instances" page.