<?php
/**
 * Disable breadcrumbs
 *
 * @file
 * Disable breadcrumbs on a per page/node or per content type basis.
 *
 */

/**
 * Implements hook_help().
 */
function disable_breadcrumbs_help($path, $arg) {
  switch ($path) {
    case 'admin/help#disable_breadcrumbs':
      return '<p>' . t('The disable breadcrumbs module allows you to disable (remove) breadcrumbs on a per node, 
      	per content type, or per path basis. For any content types that have been enabled on the disable breadcrumbs 
      	settings page a breadcrumb option will appear when editing nodes. Path settings work much the same as the 
      	block visibility system; So breadcrumbs can be disabled by path (e.g. content/123) or using wildcards to 
      	match multiple paths or site sections (e.g. content/* or content/area/*).') . '</p>';
  }
}

/**
 * Implements hook_permission().
 */
function disable_breadcrumbs_permission() {
  return array(
    'administer breadcrumbs' => array(
      'title' => t('Administer disable breadcrumbs settings'), 
      'description' => t('Administer Disable breadcrumbs settings for nodes/content types'),
    ),
    'disable node breadcrumbs' => array(
      'title' => t('Disable per node breadcrumbs'),
      'description' => t('Disable breadcrumbs on node edit forms that are enabled content types'),
    ),
  );
}

/**
 * Implements hook_menu().
 */
function disable_breadcrumbs_menu() {
  $items['admin/appearance/disable_breadcrumbs'] = array(
    'title' => 'Disable breadcrumbs',
    'description' => 'Settings for Disable breadcrumbs',
    'page callback' => 'disable_breadcrumbs_settings_page',
    'access arguments' => array('administer breadcrumbs'),
    'file' => 'disable_breadcrumbs.admin.inc',
  );
  return $items;
}

/**
 * Implements hook_theme().
 */
function disable_breadcrumbs_theme() {
    return array(
    'disable_breadcrumbs_checked_nodes' => array(
      'variables' => NULL,
      'file' => 'disable_breadcrumbs.admin.inc',
    ),
  );
}

/**
 * Implements hook_init();
 */
function disable_breadcrumbs_init() {
  $disable_breadcrumbs_all = variable_get('disable_breadcrumbs_all', NULL);

  if ($disable_breadcrumbs_all) {
    _disable_breadcrumbs_set();
    return;
  }

  // Check to see if current path is in disable breadcrumbs path settings.
  $disable_breadcrumbs_node_paths = variable_get('disable_breadcrumbs_node_paths', "");

  if (!empty($disable_breadcrumbs_node_paths)) {
    $current_path = drupal_get_path_alias($_GET['q']);
    $path_match = drupal_match_path($current_path, $disable_breadcrumbs_node_paths);

    if ($path_match) {
      _disable_breadcrumbs_set();
    }
   }
}

/**
 * Gets disable_breadcrumb status of current node.
 */
function _disable_breadcrumbs_node_query($nid) {
  //Returns '1' currently (from disable_breadcrumb field), kept in for more flexibility in the future.
  return db_select('disable_breadcrumbs', 'db')
    ->fields('db', array('disable_breadcrumb'))
    ->condition('nid', $nid)
    ->addTag('node_access')
    ->execute()
    ->fetchField();
}

/**
 * Implements hook_node_load().
 */
function disable_breadcrumbs_node_load($nodes) {
  $disable_breadcrumbs_all = variable_get('disable_breadcrumbs_all', NULL);

  // Return if all breadcrumbs are disabled.
  if ($disable_breadcrumbs_all) {
    return;
  }

  $enabled_content_types = variable_get('disable_breadcrumbs_node_types', array());
  $all_breadcrumbs_disabled_content_types = variable_get('disable_breadcrumbs_node_types_all', array());

  foreach ($nodes as $node) {
    //Just in case node hasn't been created - will have no nid.
    if (!isset($node->nid)) {
      continue;
    }
    // Check if node type is enabled.
    if (in_array($node->type, $enabled_content_types, TRUE)) {
      // Check to see if node has been checked.
      if (_disable_breadcrumbs_node_query($node->nid)) {
        $node->disable_breadcrumb = 1;
      }
      else {
        $node->disable_breadcrumb = 0;
      }
    }
    // If node type has been checked in disable all settings...
    elseif (in_array($node->type, $all_breadcrumbs_disabled_content_types, TRUE)) {
      $node->disable_breadcrumb = 1;
    }
    // Otherwise, set it to 0.
    else {
      $node->disable_breadcrumb = 0;
    }
  }

  return $nodes;
}

/**
 * Implements hook_node_view().
 */
function disable_breadcrumbs_node_view($node, $view_mode) {
  $disable_breadcrumbs_all = variable_get('disable_breadcrumbs_all', NULL);

  // Return if all breadcrumbs are disabled.
  if ($disable_breadcrumbs_all) {
    return;
  }

  // Only disable breadcrumb if disable_breadcrumb has been set to 1 in hook_node_load().
  if ($node->disable_breadcrumb == 1 && $view_mode == 'full') {
    _disable_breadcrumbs_set();
  }

  return $node;
}

/**
 * Wrapper function to disable (unset) breadcrumb.
 */
function _disable_breadcrumbs_set() {
  //Set breadcrumb as empty array.
  drupal_set_breadcrumb(array());
}

/**
 * Implements hook_node_delete().
 */
function disable_breadcrumbs_node_delete($node) {
  db_delete('disable_breadcrumbs')
    ->condition('nid', $node->nid)
    ->execute();
}

/**
 * Implements hook_form_alter().
 */
function disable_breadcrumbs_form_alter(&$form, &$form_state, $form_id) {

  $enabled_content_types = variable_get('disable_breadcrumbs_node_types', array());

  // Only perform alteration if node edit form, content type is checked in settings, and user has permissions.
  if (strpos($form_id, "_node_form") !== FALSE && 
    in_array($form['#node']->type, $enabled_content_types, TRUE) && 
    (user_access('administer breadcrumbs') || 
    user_access('disable node breadcrumbs'))) {

    $form['breadcrumb'] = array(
      '#type' => 'fieldset',
      '#title' => t("Breadcrumb"),
      '#group' => 'additional_settings',
    );
    $form['breadcrumb']['disable_breadcrumb'] = array(
      '#type' => 'checkbox',
      '#title' => t("Disable breadcrumb"),
      '#return_value' => 1,
      '#default_value' => isset($form['#node']->disable_breadcrumb) ? $form['#node']->disable_breadcrumb : '',
      '#description' => t("Hide the breadcrumb trail when this node is viewed."),
    );

    if (!isset($form['#node']->nid)) {
      // If it's a new node, add submit handler to node 'save' button submit instead.
      $form['actions']['submit']['#submit'][] = 'disable_breadcrumbs_node_form_submit';
    }
    else {
      // Append another submit function to update disabled_node field in node table
      $form['#submit'][] = 'disable_breadcrumbs_node_form_submit';
    }

  }

}

function disable_breadcrumbs_node_form_submit($form, $form_state) {

  // Get default value from form.
  $breadcrumb_status = $form_state['values']['disable_breadcrumb'];

  // Get value before update to db to check whether to display message on save
  $check_status = _disable_breadcrumbs_node_query($form_state['node']->nid) ? 1 : 0;

  if ($breadcrumb_status == 1 && $check_status == 0) {
    // Insert db record.
    db_insert('disable_breadcrumbs')
      ->fields(array(
        'disable_breadcrumb' => $breadcrumb_status, //For now, this will always be 1.
        'nid' => $form_state['node']->nid,
      ))
      ->execute();

    drupal_set_message(t("The breadcrumb for %title (node %nid) has been disabled.", 
      array('%nid' => $form_state['node']->nid, '%title' => $form_state['node']->title)));
  }

  if ($breadcrumb_status == 0 && $check_status == 1) {
    // Remove db record.
    db_delete('disable_breadcrumbs')
      ->condition('nid', $form_state['node']->nid)
      ->execute();

    drupal_set_message(t("The breadcrumb for %title (node %nid) has been enabled.", 
      array('%nid' => $form_state['node']->nid, '%title' => $form_state['node']->title)));
  }

}

/**
 * Implements hook_node_operations().
 */
function disable_breadcrumbs_node_operations() {
  $operations = array(
    'disable_breadcrumbs' => array(
      'label' => t('Disable breadcrumbs on selected nodes'), 
      'callback' => 'disable_breadcrumbs_operations',
      'callback arguments' => array('action' => 'disable_breadcrumbs'),
    ), 
    'enable_breadcrumbs' => array(
      'label' => t('Enable breadcrumbs on selected nodes'), 
      'callback' => 'disable_breadcrumbs_operations',
      'callback arguments' => array('action' => 'enable_breadcrumbs'),
    ), 
  );

  return $operations;
}

/**
 * Node operations callback.
 */
function disable_breadcrumbs_operations($nodes, $action) {
  switch ($action) {
    case 'disable_breadcrumbs':
      $enabled_content_types = variable_get('disable_breadcrumbs_node_types', array());
      $all_breadcrumbs_disabled_content_types = variable_get('disable_breadcrumbs_node_types_all', array());

      $message_show = FALSE;
      $not_enabled_content_types = array();
      $disabled_nodes = array();

      foreach ($nodes as $node) {
        $node = node_load($node);
        if (!in_array($node->type, $all_breadcrumbs_disabled_content_types, TRUE) && 
          in_array($node->type, $enabled_content_types, TRUE)) {

          //Use db_merge so we don't get duplicates.
          db_merge('disable_breadcrumbs')
            ->key(array('nid' => $node->nid))
            ->fields(array(
              'nid' => $node->nid,
              'disable_breadcrumb' => 1,
            ))
            ->execute();

          $message_show = TRUE;
          $disabled_nodes[] = $node->nid;
        }
        elseif (!in_array($node->type, $enabled_content_types, TRUE)) {
          $not_enabled_content_types[] = $node->type;
        }
      }

      if ($message_show) {
        drupal_set_message(t("Breadcrumbs have been disabled for nodes: %nodes", 
          array('%nodes' => implode(", ", $disabled_nodes))));
      }

      if ($not_enabled_content_types) {
        $not_enabled_content_types = array_unique($not_enabled_content_types);
        drupal_set_message(t("Breadcrumbs cannot be disabled for node type(s): %types", 
          array('%types' => implode(", ", $not_enabled_content_types))), 'warning');
      }
    break;
    case 'enable_breadcrumbs':
      db_delete('disable_breadcrumbs')
        ->condition('nid', $nodes)
        ->execute();

      drupal_set_message(t("Disable breadcrumb status has been unchecked for nodes: %nodes", 
        array('%nodes' => implode(", ", $nodes))));
    break;
  }
}

/**
 * Alter admin content form to show disable breadcrumb status of each node.
 */
function disable_breadcrumbs_form_node_admin_content_alter(&$form, &$form_state) {

  // This key in $form array will only exist when viewing admin screen
  // and not when confirming a bulk operation.
  if (array_key_exists('admin', $form)) {
    // All nodes in current table list
    $nodes = $form['admin']['nodes']['#options'];
    // Nodes that exist in disable_breadcrumbs table
    $breadcrumb_nodes = array();
    // Array of all nodes in table list with their disable_breadcrumb status.
    // In the form of nid => status.
    $breadcrumb_status = array();

    // Query will only return set of nid that breadcrumb is disabled for.
    $result = db_select('disable_breadcrumbs', 'db')
      ->fields('db', array('nid'))
      ->execute();

    foreach ($result as $data) {
      $breadcrumb_nodes[]= $data->nid;
    }

    foreach ($nodes as $key => $value) {
      if (in_array($key, $breadcrumb_nodes)) {
        $breadcrumb_status[$key] = 1;
      }
      else {
        $breadcrumb_status[$key] = 0;
      }
    }

    // Disable breadcrumbs image on admin content page.
    $content_image_settings = array(
      'path' => drupal_get_path('module', 'disable_breadcrumbs') . '/images/content_image.png',
      'attributes' => array(
        'class' => 'disable-breadcrumbs-icon',
        'style' => 'padding-left: 5px;',
      ),
      'title' => t('Breadcrumb disabled'),
    );

    $content_image = theme('image', $content_image_settings);

    $form['disable_breadcrumbs'] = array(
      '#type' => 'fieldset',
      '#weight' => -5,
    );
    $form['disable_breadcrumbs']['markup'] = array(
      '#markup' => '<em>' . $content_image . ' Denotes nodes that currently have their breadcrumb disabled.*</em>',
    );

    // Check #options key exists (user may not have sufficient permissions when form table is rendered).
    if ($options = $form['admin']['nodes']['#options']) {
      foreach ($options as $key => $value) {
        if ($breadcrumb_status[$key] == 1) {
          $form['admin']['nodes']['#options'][$key]['status'] = $value['status'] . $content_image; 
        }
      }
    }
  }
}
