You are here

nodesinblock.module in Nodes In Block 7

Same filename and directory in other branches
  1. 6 nodesinblock.module

Nodes in block makes it possible to add multiple nodes in one block.

File

nodesinblock.module
View source
<?php

/**
 * @file
 * Nodes in block makes it possible to add multiple nodes in one block.
 */

/**
 * Implements hook_permission().
 */
function nodesinblock_permission() {
  return array(
    'administer nodes in block configuration' => array(
      'title' => t('Configure Nodes in block'),
    ),
    'administer nodes in block queue' => array(
      'title' => t('Administer nodes in block queue'),
    ),
    'deny configuration on node form' => array(
      'title' => t('Deny configuration on node form'),
    ),
  );
}

/**
 * Implements hook_theme().
 */
function nodesinblock_theme() {
  return array(
    'nodesinblock_queue' => array(
      'render element' => 'form',
    ),
  );
}

/**
 * Implements hook_menu().
 */
function nodesinblock_menu() {
  $items = array();
  $items['node/%node/nodesinblock'] = array(
    'title' => 'Nodes in block',
    'description' => 'Nodes in block queue. ',
    'title callback' => 'nodesinblock_tabtitle',
    'title arguments' => array(
      1,
    ),
    'page callback' => 'nodesinblock_nodequeue',
    'page arguments' => array(
      1,
    ),
    'access callback' => 'nodesinblock_nodequeue_access',
    'access arguments' => array(
      1,
    ),
    'type' => MENU_LOCAL_TASK,
    'weight' => 2,
  );
  $items['admin/structure/nodesinblock'] = array(
    'title' => 'Nodes in block',
    'description' => 'Setup nodes in block. ',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'nodesinblock_settings',
    ),
    'access arguments' => array(
      'administer nodes in block configuration',
    ),
    'file' => 'nodesinblock.admin.inc',
  );
  $items['admin/structure/nodesinblock/default'] = array(
    'title' => 'Configure',
    'description' => 'Configure node in block. ',
    'type' => MENU_DEFAULT_LOCAL_TASK,
  );
  $items['admin/structure/nodesinblock/queue'] = array(
    'title' => 'Queue',
    'description' => 'Nodes in block queue. ',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'nodesinblock_queue',
    ),
    'access arguments' => array(
      'administer nodes in block queue',
    ),
    'file' => 'nodesinblock.admin.inc',
    'type' => MENU_LOCAL_TASK,
  );
  $items['admin/structure/nodesinblock/clear'] = array(
    'title' => 'Clear settings',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'nodesinblock_settings_clear_confirm',
    ),
    'access arguments' => array(
      'administer nodes in block configuration',
    ),
    'file' => 'nodesinblock.admin.inc',
    'type' => MENU_CALLBACK,
  );
  return $items;
}

/**
 * Implements hook_form_BASE_FORM_ID_alter().
 */
function nodesinblock_form_node_form_alter(&$form, $form_state) {
  $node = $form['#node'];
  $saved_types = variable_get('nodesinblock_contenttypes', array());
  if (isset($saved_types[$node->type]) && $saved_types[$node->type] != '0') {
    $a = 1;
    $i = 0;
    $block_options[-1] = t('None');
    $deltas = variable_get('nodesinblock_' . $node->type . '_block', array());
    foreach ($deltas as $key => $value) {
      if ($deltas[$a] != 0) {
        $block_name = check_plain(variable_get('nodesinblock_friendlyname_' . $i, t('Nodes in block ' . $a)));
        $type = variable_get('nodesinblock_visibility_' . $i, '1') == '1' ? t('(Pos)') : t('(Neg)');
        $block_options[$i] = $block_name . ' ' . $type;
      }
      $a++;
      $i++;
    }
    if (!empty($block_options)) {
      $node_info = array(
        'weight' => 0,
        'visibility' => '*',
        'delta' => -1,
        'render' => 'full',
      );
      if (!empty($form_state['values']) && isset($form_state['values']['nodesinblock_visibility'])) {
        $node_info['visibility'] = $form_state['values']['nodesinblock_visibility'];
        $node_info['weight'] = $form_state['values']['nodesinblock_weight'];
        $node_info['delta'] = $form_state['values']['nodesinblock_delta'];
        $node_info['render'] = $form_state['values']['nodesinblock_render'];
      }
      elseif (!empty($form['nid']['#value'])) {
        $node_info = db_query("SELECT * FROM {nodesinblock} WHERE nid = :nid", array(
          ':nid' => $form['nid']['#value'],
        ))
          ->fetchAssoc();
      }
      else {
        if (variable_get('nodesinblock_referer', FALSE) && isset($_SERVER['HTTP_REFERER'])) {
          $end = '';
          if (substr($_SERVER['HTTP_REFERER'], -1) === '/') {
            $end = '/';
          }
          $base = url(NULL, array(
            'absolute' => TRUE,
          )) . $end;
          if (strpos($_SERVER['HTTP_REFERER'], $base) === 0) {
            $node_info['visibility'] = str_replace($base, '', $_SERVER['HTTP_REFERER']);
          }
        }
        $node_info['render'] = '';
      }
      $form['nodesinblock'] = array(
        '#type' => 'fieldset',
        '#title' => check_plain(variable_get('nodesinblock_' . $node->type . '_label', t('Nodes in block'))),
        '#collapsible' => variable_get('nodesinblock_' . $node->type . '_collapsible', TRUE),
        '#collapsed' => variable_get('nodesinblock_' . $node->type . '_collapsed', TRUE),
        '#group' => 'additional_settings',
        '#attached' => array(
          'js' => array(
            drupal_get_path('module', 'nodesinblock') . '/nodesinblock-node-form.js',
          ),
        ),
        '#weight' => 40,
      );
      $nodesinblock_enable = TRUE;
      if (user_access('deny configuration on node form') && $GLOBALS['user']->uid != 1) {
        $nodesinblock_enable = FALSE;
        $form['nodesinblock']['#access'] = FALSE;
      }
      $form['nodesinblock']['nodesinblock_enable'] = array(
        '#type' => 'value',
        '#value' => $nodesinblock_enable,
      );
      $form['nodesinblock']['nodesinblock_delta'] = array(
        '#type' => 'select',
        '#title' => t('Select region'),
        '#options' => $block_options,
        '#default_value' => $node_info['delta'],
        '#description' => t('The code between the round brackets indicate the visibility setting of the block.<br />Pos = Show on only the listed pages.<br />Neg = Show on every page except the listed pages.'),
      );
      $form['nodesinblock']['nodesinblock_weight'] = array(
        '#type' => 'value',
        '#value' => $node_info['weight'],
      );
      $form['nodesinblock']['nodesinblock_render'] = array(
        '#type' => 'select',
        '#title' => t('Render node as'),
        '#options' => _nodesinblock_render_options(),
        '#default_value' => $node_info['render'],
      );
      if (variable_get('nodesinblock_' . $node->type . '_render', '0') != '0') {
        $form['nodesinblock']['nodesinblock_render']['#type'] = 'value';
        $form['nodesinblock']['nodesinblock_render']['#value'] = variable_get('nodesinblock_' . $node->type . '_render', 0);
      }
      $form['nodesinblock']['nodesinblock_visibility'] = array(
        '#title' => t('Visibility'),
        '#type' => 'textarea',
        '#description' => t('Enter one page per line as Drupal paths. The \'*\' character is a wildcard. Example paths are blog for the blog page and blog/* for every personal blog. &lt;front&gt; is the front page.'),
        '#default_value' => $node_info['visibility'],
        '#wysiwyg' => FALSE,
      );
    }
  }
}

/**
 * Implements hook_node_validate().
 */
function nodesinblock_node_validate($node) {
  if (isset($node->nodesinblock_enable)) {
    _nodesinblock_validate($node);
  }
}

/**
 * Implements hook_node_insert().
 */
function nodesinblock_node_insert($node) {
  if (isset($node->nodesinblock_enable)) {
    _nodesinblock_save($node, 'insert');
  }
}

/**
 * Implements hook_node_update().
 */
function nodesinblock_node_update($node) {
  if (isset($node->nodesinblock_enable)) {
    _nodesinblock_save($node, 'update');
  }
}

/**
 * Implements hook_node_delete().
 */
function nodesinblock_node_delete($node) {
  _nodeisblock_load($node);
  if (isset($node->nodesinblock)) {
    $node->nodesinblock_delta = $node->nodesinblock;
    _nodesinblock_save($node, 'delete');
  }
}

/**
 * Implements hook_block_info().
 */
function nodesinblock_block_info() {
  $number_of_blocks = variable_get('nodesinblock_nrofblocks', 1);
  for ($i = 0, $a = 1; $i < $number_of_blocks; $i++, $a++) {
    $blocks[$i] = array(
      'info' => check_plain(variable_get('nodesinblock_friendlyname_' . $i, t('Nodes in block ' . $a))),
    );
  }
  return $blocks;
}

/**
 * Implements hook_block_view().
 */
function nodesinblock_block_view($delta = '') {
  $a = $delta + 1;
  $content = _nodesinblock_show($delta, variable_get('nodesinblock_visibility_' . $delta, '1'));
  $title = check_plain(variable_get('nodesinblock_friendlyname_' . $delta, t('Nodes in block ' . $a)));
  $block = array(
    'subject' => $title,
    'content' => $content,
  );
  return $block;
}

/**
 * Tab title.
 *
 * @param $node
 *   The current node.
 * @return $title
 *   The title
 */
function nodesinblock_tabtitle($node) {
  $i = $node->nodesinblock;
  $a = $i + 1;
  $title = check_plain(variable_get('nodesinblock_friendlyname_' . $i, t('Nodes in block ' . $a)));
  return $title;
}

/**
 * Access callback: check that user has access to configure nodes in block queue.
 *
 * @param $node
 *   The current node.
 * @return $boolean.
 *   TRUE or FALSE
 */
function nodesinblock_nodequeue_access($node) {
  _nodeisblock_load($node);
  $saved_types = variable_get('nodesinblock_contenttypes', array());
  if (node_access('update', $node) && user_access('administer nodes in block queue') && isset($node->nodesinblock) && isset($saved_types[$node->type]) && $saved_types[$node->type] != '0') {
    return TRUE;
  }
  return FALSE;
}

/**
 * Nodes in block queue tab.
 */
function nodesinblock_nodequeue($node) {
  module_load_include('inc', 'nodesinblock', 'nodesinblock.admin');
  $form = drupal_get_form('nodesinblock_queue', $node->nodesinblock, FALSE, FALSE);
  return drupal_render($form);
}

/**
 * Function callback: validate node. Returns error if visibility is empty and status is enabled.
 */
function _nodesinblock_validate($node) {
  $visibility = $node->nodesinblock_visibility;
  if ($node->nodesinblock_delta != -1 && empty($visibility)) {
    form_set_error('nodesinblock_visibility', t('Visibility field is required.'));
  }
}

/**
 * Helper function to return the status.
 *
 * @param $type
 *   The name of the bundle.
 * @return $render_status
 *   Colleciton of view modes.
 */
function _nodesinblock_render_options() {
  static $render_options = array();
  if (empty($render_options)) {
    $entity_info = entity_get_info();
    foreach ($entity_info['node']['view modes'] as $key => $view_mode) {
      $render_options[$key . ':' . TRUE] = $view_mode['label'] . ' ' . t('With links');
      $render_options[$key . ':' . FALSE] = $view_mode['label'] . ' ' . t('Without links');
    }
  }
  return $render_options;
}

/**
 * Helper function to load node data for nodesinblock.
 */
function _nodeisblock_load($node) {
  $delta = db_query("SELECT delta, nid FROM {nodesinblock} WHERE nid = :nid", array(
    ':nid' => $node->nid,
  ))
    ->fetchObject();
  if (isset($delta->nid)) {
    $node->nodesinblock = $delta->delta;
  }
}

/**
 * Function callback: save node settings into nodesinblock table and update block visibility pages.
 */
function _nodesinblock_save($node, $op) {

  // Delete old record.
  db_delete('nodesinblock')
    ->condition('nid', $node->nid)
    ->execute();

  // Save if node is not deleted
  if ($op != 'delete' && $node->nodesinblock_delta != -1) {
    $nodeinblock = new stdClass();
    $nodeinblock->nid = $node->nid;
    $nodeinblock->delta = $node->nodesinblock_delta;
    $nodeinblock->weight = $node->nodesinblock_weight;
    $nodeinblock->visibility = trim($node->nodesinblock_visibility);
    $nodeinblock->render = $node->nodesinblock_render;
    drupal_write_record('nodesinblock', $nodeinblock);
  }

  // Get visibility paths.
  $visibility = array();
  $result = db_query("SELECT visibility FROM {nodesinblock} nib INNER JOIN {node} n on n.nid = nib.nid WHERE nib.delta = :delta AND n.status = 1", array(
    ':delta' => $node->nodesinblock_delta,
  ));
  foreach ($result as $row) {
    $node_visibility = explode("\n", $row->visibility);
    foreach ($node_visibility as $path) {
      $visibility[] = trim($path);
    }
  }

  // Update blocks table.
  $visibility = array_unique($visibility);
  db_update('block')
    ->condition('module', 'nodesinblock')
    ->condition('delta', $node->nodesinblock_delta)
    ->fields(array(
    'visibility' => variable_get('nodesinblock_visibility_' . $node->nodesinblock_delta, '1'),
    'pages' => implode("\n", $visibility),
  ))
    ->execute();
}

/**
 * Function callback: get content for a block.
 */
function _nodesinblock_show($delta, $visibility) {
  static $nids = array();
  $i = 0;
  $output = '';
  $path = drupal_get_path_alias($_GET['q']);
  $query = db_select('nodesinblock', 'nib');
  $query
    ->join('node', 'n', 'nib.nid = n.nid');
  $query
    ->fields('nib', array(
    'nid',
    'visibility',
    'render',
    'weight',
  ))
    ->condition('n.status', 1)
    ->condition('delta', $delta)
    ->orderBy('weight', 'ASC')
    ->addTag('node_access');
  $results = $query
    ->execute()
    ->fetchAll();
  $num_items = count($results);
  foreach ($results as $row) {
    $paths = explode("\n", trim($row->visibility));
    foreach ($paths as $key => $val) {

      // Match the path.
      $page_match = drupal_match_path($path, $val);
      if ($path != $_GET['q']) {
        $page_match = $page_match || drupal_match_path($_GET['q'], $val);
      }
      $page_match = !($visibility xor $page_match);

      // We have a match, load the node.
      if ($page_match && !isset($nids[$delta][$row->nid])) {
        $nids[$delta][$row->nid] = $row->nid;
        $node = node_load($row->nid);

        // Support for translation. Use Translation Helpers module if it's installed.
        // @todo Provide granular control. Maybe we want to show nodes of language x in a block which gets
        //   displayed on language y. This might break other contexts (i.e. show blocks on language)
        if (function_exists('translation_helpers_get_translation')) {
          $tnode = translation_helpers_get_translation($node, $language->language);
          if ($tnode) {
            $node = $tnode;
          }
        }
        $node->nodesinblock = TRUE;

        // In case the the render selection has changed, make sure
        // we select the exact render mode.
        if (variable_get('nodesinblock_' . $node->type . '_render', '0') != '0') {
          $row->render = variable_get('nodesinblock_' . $node->type . '_render', '0');
        }

        // Assemble classes.
        $classes = array(
          'nodesinblock',
        );
        if ($i == 0) {
          $classes[] = 'first';
        }
        if ($i == $num_items - 1) {
          $classes[] = 'last';
        }
        if ($i % 2 == 0) {
          $classes[] = 'odd';
        }
        else {
          $classes[] = 'even';
        }
        $i++;

        // Render node.
        list($view_mode, $links) = explode(':', $row->render);
        $node_content = node_view($node, $view_mode);
        if (!$links) {
          unset($node_content['links']);
        }

        // Return output.
        $output .= '<div class="' . implode(' ', $classes) . '" id="nodesinblock-' . $node->nid . '">';
        $output .= render($node_content);
        $output .= '</div>';
      }
    }
  }
  return $output;
}

Functions

Namesort descending Description
nodesinblock_block_info Implements hook_block_info().
nodesinblock_block_view Implements hook_block_view().
nodesinblock_form_node_form_alter Implements hook_form_BASE_FORM_ID_alter().
nodesinblock_menu Implements hook_menu().
nodesinblock_nodequeue Nodes in block queue tab.
nodesinblock_nodequeue_access Access callback: check that user has access to configure nodes in block queue.
nodesinblock_node_delete Implements hook_node_delete().
nodesinblock_node_insert Implements hook_node_insert().
nodesinblock_node_update Implements hook_node_update().
nodesinblock_node_validate Implements hook_node_validate().
nodesinblock_permission Implements hook_permission().
nodesinblock_tabtitle Tab title.
nodesinblock_theme Implements hook_theme().
_nodeisblock_load Helper function to load node data for nodesinblock.
_nodesinblock_render_options Helper function to return the status.
_nodesinblock_save Function callback: save node settings into nodesinblock table and update block visibility pages.
_nodesinblock_show Function callback: get content for a block.
_nodesinblock_validate Function callback: validate node. Returns error if visibility is empty and status is enabled.