You are here

block_machine_name.module in Block Machine Name 7

File

block_machine_name.module
View source
<?php

/**
 * Drupal hooks.
 */

/**
 * Implements hook_form_alter().
 * @todo - Alter various block forms to add our field elements or submit/validate handlers
 */
function block_machine_name_form_alter(&$form, $form_state, $form_id) {
  $default_values = array();

  // Try to get the module supplying the block from the form
  $module = empty($form['module']['#value']) ? '' : $form['module']['#value'];

  // When deleting, $module is often not in the form. In this case, try to infer the value from the form_id
  switch ($form_id) {

    // menu_block module
    case 'menu_block_delete_form':
      $form['module'] = array(
        '#type' => 'value',
        '#value' => 'menu_block',
      );
      $form['#submit'][] = 'block_machine_name_delete';
      return;
      break;

    // block module
    case 'block_custom_block_delete':

      // The block's delta is stored in the 'bid' element for block_custom and imageblock, and our form handler
      // expects to use the 'delta' value
      $form['delta'] = array(
        '#type' => 'value',
        '#value' => $form['bid']['#value'],
      );
      $form['module'] = array(
        '#type' => 'value',
        '#value' => 'block',
      );
      $form['#submit'][] = 'block_machine_name_delete';
      return;
      break;

    // imageblock module
    case 'imageblock_custom_block_delete':

      // The block's delta is stored in the 'bid' element for block_custom and imageblock, and our form handler
      // expects to use the 'delta' value
      $form['delta'] = array(
        '#type' => 'value',
        '#value' => $form['bid']['#value'],
      );
      $form['module'] = array(
        '#type' => 'value',
        '#value' => 'imageblock',
      );
      $form['#submit'][] = 'block_machine_name_delete';
      return;
      break;
  }

  // Return unless this is a supported module.
  // Currently we are supporting core Block, Menu Block, and Image Block
  if (!in_array($module, array(
    'block',
    'menu_block',
    'imageblock',
  ))) {
    return;
  }

  // Adding a block - we'll add the machine name field
  if ($form_id == $module . '_add_block_form') {
    $default_values['machine_name'] = '';
  }
  elseif ($form_id == 'block_admin_configure') {
    $machine_name = block_machine_name_get_machine_name($form['delta']['#value'], $module);
    $default_values['machine_name'] = empty($machine_name) ? '' : $machine_name;
  }

  // Here's the actual form alterations.
  // We'll do these alterations if we've determined above that we should
  if (!empty($default_values)) {
    $form['settings']['machine_name'] = array(
      '#type' => 'textfield',
      '#title' => t('Machine name'),
      '#default_value' => $default_values['machine_name'],
      '#maxlength' => 32,
      '#description' => t('Give the block a machine name a unique identifier for CSS, template files, etc. Lowercase letters, numbers, and underscores only.'),
      '#weight' => -50,
    );
    $form['module'] = array(
      '#type' => 'value',
      '#value' => $module,
    );

    // Add our validate and submit handlers:
    $form['#validate'][] = 'block_machine_name_validate';
    $form['#submit'][] = 'block_machine_name_submit';
  }
}

/**
 * Validate machine name.
 */
function block_machine_name_validate($form, &$form_state) {

  // If the user did not put in a value, don't try to validate.
  if (empty($form_state['values']['machine_name'])) {
    return;
  }

  // We need to know the module of this block to manage a machine name. If we couldn't gather this, warn the
  // user that their machine name will not be saved.
  if (empty($form_state['values']['module'])) {
    drupal_set_message('Block machine name could not find all required information in the form, your machine name will not be saved.', 'warning');
    return;
  }
  $delta = $form_state['values']['delta'];
  $module = $form_state['values']['module'];
  $machine_name = $form_state['values']['machine_name'];

  // Check for invalid characters
  if (!preg_match('!^[a-z0-9_]+$!', $machine_name)) {
    form_set_error('machine_name', t('The machine-readable name must contain only lowercase letters, numbers, and underscores.'));
    return;
  }

  // Query to see if any blocks are already using this machine name
  $table = 'block_machine_name_boxes';
  $query = db_select($table)
    ->condition('machine_name', $machine_name, '=');

  // If this is an existing block, exclude it from the query so we don't think the name is already in use.
  if (!empty($delta)) {
    $query
      ->condition('delta', $delta, '<>')
      ->condition('module', $module, '<>');
  }

  // Run the query
  $count = $query
    ->countQuery()
    ->execute()
    ->fetchField();
  if ($count > 0) {
    form_set_error('machine_name', t('The machine-readable name has been taken. Please pick another one.'));
  }
}

/**
 * Save machine name.
 */
function block_machine_name_submit($form, &$form_state) {

  // If the user didn't supply a value, don't do anything
  if (empty($form_state['values']['machine_name'])) {
    return;
  }

  // Build a record to insert
  $delta = $form_state['values']['delta'];
  $module = $form_state['values']['module'];
  $machine_name = $form_state['values']['machine_name'];
  $record = array(
    // Block delta
    'delta' => $delta,
    // The user supplied machine name
    'machine_name' => $machine_name,
    // The module controlling this block - module + delta yield a unique identifier for this block
    'module' => $module,
  );

  // Clear out any existing entry for this block and then insert the new record
  $table = 'block_machine_name_boxes';
  db_delete($table)
    ->condition('delta', $delta)
    ->condition('module', $module)
    ->execute();
  drupal_write_record($table, $record);
}

/**
 * Delete machine name.
 */
function block_machine_name_delete($form, &$form_state) {
  $table = 'block_machine_name_boxes';
  db_delete($table)
    ->condition('delta', $form_state['values']['delta'])
    ->condition('module', $form_state['values']['module'])
    ->execute();
}

/**
 * Implements of hook_block_list_alter().
 */
function block_machine_name_block_list_alter(&$blocks) {

  // Help the user by preventing a site crash when updates have not been run yet, and provide a warning.
  $schema_version = db_query("SELECT schema_version FROM {system} WHERE name = 'block_machine_name'")
    ->fetchField();
  if ($schema_version < 7100) {
    drupal_set_message('Block Machine Name requires system updates to function. Please run update.php', 'warning');
    return;
  }

  // Query for block module blocks that have a machine name
  $query = db_select('block_machine_name_boxes', 'bmachine');
  $query
    ->join('block', 'b', 'bmachine.delta = b.delta AND bmachine.module = b.module');
  $query
    ->fields('bmachine')
    ->fields('b');
  $result = $query
    ->execute();

  // Add the machine name to the block's data in the list
  foreach ($result as $k => $block) {

    // Search for this block in the blocks list
    foreach ($blocks as $system_block) {
      if ($system_block->module == $block->module && $system_block->delta == $block->delta) {
        $system_block->machine_name = $block->machine_name;
      }
    }
  }
}

/**
 * Returns the machine name that corresponds to a given block id.
 *
 * @param int $delta
 *   The block id for which to retrieve the machine name.
 *
 * @return string | FALSE
 *   The machine name, or FALSE if it could not be found.
 */
function block_machine_name_get_machine_name($delta, $module) {
  $machine_names =& drupal_static(__FUNCTION__);
  $key = $module . '_' . $delta;
  if (!isset($machine_names[$key])) {
    $result = db_select('block_machine_name_boxes')
      ->fields('block_machine_name_boxes', array(
      'machine_name',
    ))
      ->condition('delta', $delta)
      ->condition('module', $module)
      ->execute()
      ->fetch();
    if (empty($result)) {

      // Couldn't find a machine name
      return FALSE;
    }
    $machine_names[$key] = $result->machine_name;
  }
  return $machine_names[$key];
}

/**
 * Implements hook_preprocess_block();
 */
function block_machine_name_preprocess_block(&$vars) {
  $block = $vars['block'];
  if (isset($block->machine_name)) {

    // Add a class
    $vars['classes_array'][] = 'block-' . str_replace('_', '-', $block->machine_name);

    // Make a template suggestion
    $vars['theme_hook_suggestions'][] = 'block__' . $block->machine_name;
  }
}

Functions

Namesort descending Description
block_machine_name_block_list_alter Implements of hook_block_list_alter().
block_machine_name_delete Delete machine name.
block_machine_name_form_alter Implements hook_form_alter(). @todo - Alter various block forms to add our field elements or submit/validate handlers
block_machine_name_get_machine_name Returns the machine name that corresponds to a given block id.
block_machine_name_preprocess_block Implements hook_preprocess_block();
block_machine_name_submit Save machine name.
block_machine_name_validate Validate machine name.