<?php

/**
 * @file
 * Views hook definitions for the Archibald module.
 */

/**
 * Actual implementation of hook_form_FORM_ID_alter() for views_exposed_form().
 *
 * @see archibald_form_views_exposed_form_alter()
 */
function archibald_lomch_descriptions_views_exposed_form_alter(&$form, $form_state) {
  global $user;
  $view = $form_state['view'];

  $path = drupal_get_path('module', 'archibald');
  $form['#attached']['css'][] = "$path/css/archibald.lomch_description_views.css";

  // We have special styles for certain admin themes, to make the form look a
  // bit better. Make sure the admin theme is active,  and that the user has
  // access to it.
  archibald_add_admin_theme_styles();

  // For the pending, published and to-republish displays, we allow users to show
  // only their own descriptions. In order to make this easier, we transform the
  // exposed Author UID filter to a "Only show my own content" checkbox.
  if (isset($form['uid_1']) && in_array($view->current_display, array('pending', 'published', 'republish'))) {
    // Transform the uid_1 filter to a checkbox.
    $form['uid_1'] = array(
      '#type' => 'checkbox',
      '#title' => t("Only show descriptions assigned to me"),
      '#value' => (!empty($form_state['input']['uid_1']) && $form_state['input']['uid_1'] == $user->name) ? $user->name : '',
      '#return_value' => $user->name,
      '#empty_value' => '',
    );
  }

  // We also use this opportunity to see if any descriptions require
  // re-publishing. If so, we display a warning message with a link. We also
  // display a status message if we are on the "republish" display, and all
  // descriptions are up to date.
  if (archibald_views_access('republish') && archibald_lomch_description_num_require_republishing()) {
    if ($view->current_display == 'republish') {
      drupal_set_message(t("The following descriptions use resources that have been updated (e.g.: a <em>VCard</em> or a <em>Taxonomy Term</em>). Because of this, the currently published version on the API does not match the version currently published locally. You can republish these descriptions to update them to the latest version, unpublish them completely, or simply ignore them."), 'warning');
    }
    else {
      drupal_set_message(t("There are currently published descriptions that may need to be republished. Please visit !link for more information.", array(
        '!link' => l('admin/archibald/description/republish', 'admin/archibald/description/republish'),
      )), 'warning');
    }
  }
  elseif ($view->current_display == 'republish') {
    drupal_set_message(t("All published descriptions are up to date."));
  }
}

/**
 * Implements hook_views_data().
 */
function archibald_views_data() {
  $data = array();

  $data['archibald_lom_id'] = array('table' => array());
  $data['archibald_lom_id']['table']['group'] = t("Content");
  $data['archibald_lom_id']['table']['join'] = array(
    'node' => array(
      'left_field' => 'nid',
      'field' => 'nid',
    ),
    'node_revision' => array(
      'left_field' => 'nid',
      'field' => 'nid',
    ),
  );
  $data['archibald_lom_id']['lom_id'] = array(
    'title' => t("LOM ID"),
    'help' => t("The LOM ID of this description. Only applies if the description is actually published."),
    'field' => array(
      'handler' => 'archibald_handler_field_node_lom_id',
      'click sortable' => TRUE,
    ),
    'sort' => array(
      'handler' => 'views_handler_sort',
    ),
    'filter' => array(
      'handler' => 'views_handler_filter_string',
    ),
    'argument' => array(
      'handler' => 'views_handler_argument_string',
    ),
  );
  $data['archibald_lom_id']['lom_id_url_encoded'] = array(
    'real field' => 'lom_id',
    'title' => t("LOM ID (URL encoded)"),
    'help' => t("The LOM ID of this description, URL encoded. Only applies if the description is actually published."),
    'field' => array(
      'handler' => 'archibald_handler_field_node_lom_id_url_encoded',
      'click sortable' => TRUE,
    ),
    'sort' => array(
      'handler' => 'views_handler_sort',
    ),
    'filter' => array(
      'handler' => 'views_handler_filter_string',
    ),
    'argument' => array(
      'handler' => 'views_handler_argument_string',
    ),
  );

  $data['archibald_lom_hash'] = array('table' => array());
  $data['archibald_lom_hash']['table']['group'] = t("Content");
  $data['archibald_lom_hash']['table']['join'] = array(
    'node' => array(
      'left_field' => 'nid',
      'field' => 'nid',
    ),
    'node_revision' => array(
      'left_field' => 'nid',
      'field' => 'nid',
    ),
  );
  $data['archibald_lom_hash']['current_hash'] = array(
    'title' => t("Current MD5 hash"),
    'help' => t("The MD5 hash of the current state of the description, locally. "),
    'field' => array(
      'handler' => 'archibald_handler_field_node_current_hash',
      'click sortable' => TRUE,
    ),
    'sort' => array(
      'handler' => 'views_handler_sort',
    ),
    'filter' => array(
      'handler' => 'views_handler_filter_string',
    ),
    'argument' => array(
      'handler' => 'views_handler_argument_string',
    ),
  );
  $data['archibald_lom_hash']['published_hash'] = array(
    'title' => t("Published MD5 hash"),
    'help' => t("The MD5 hash of the state of the published description, remotely. "),
    'field' => array(
      'handler' => 'archibald_handler_field_node_published_hash',
      'click sortable' => TRUE,
    ),
    'sort' => array(
      'handler' => 'views_handler_sort',
    ),
    'filter' => array(
      'handler' => 'views_handler_filter_string',
    ),
    'argument' => array(
      'handler' => 'views_handler_argument_string',
    ),
  );

  $data['node_revision']['relative_state'] = array(
    'title' => t("Relative state"),
    'help' => t("The revision state in relationship to the node's full lifecycle"),
    'field' => array(
      'handler' => 'archibald_handler_field_revision_state',
      'click sortable' => TRUE,
    ),
  );

  return $data;
}

/**
 * Implements hook_views_pre_view().
 */
function archibald_views_pre_view(&$view, &$display_id, &$args) {
  // Must we display a 'view on portal' link?
  if (
    $view->name == 'archibald_lomch_descriptions' &&
    $display_id == 'published' &&
    variable_get('archibald_show_link_to_dsb_portal', FALSE)
  ) {
    // Fetch the display handler.
    $handler = &$view->display[$display_id]->handler;

    // Add our field definition. See
    // archibald_views_custom_text_field_defaults() for the defaults concerning
    // custom text field. We would normally use the HTML token approach, as
    // documented in hook_views_post_render(). However, this approach does not
    // work (https://www.drupal.org/node/1064868). Instead, we inject actual
    // HTML, and make sure it's hidden. In archibald_views_post_render(), we
    // will replace the token with an actual link.
    $handler->options['fields']['view_on_portal'] = archibald_views_custom_text_field_defaults(
      'view_on_portal',
      '<div class="element-invisible archibald-view-on-portal-replacement-token">[lom_id]</div>'
    );
  }

  // Is the Node Clone module enabled?
  if (
    $view->name == 'archibald_lomch_descriptions' &&
    in_array($display_id, array('pending', 'proposals', 'published')) &&
    module_exists('clone')
  ) {
    // Fetch the display handler.
    $handler = &$view->display[$display_id]->handler;

    // Add our field definition. See
    // archibald_views_custom_text_field_defaults() for the defaults concerning
    // custom text field.
    $handler->options['fields']['clone'] = archibald_views_custom_text_field_defaults(
      'view_on_portal',
      // We want to use token substitutions here. This means we cannot use
      // Drupal's l() function, but have to code the link ourselves.
      '<a href="' . base_path() . 'node/[nid]/clone/confirm">' . t("clone") . '</a>'
    );
  }
}

/**
 * Implements hook_views_post_render().
 */
function archibald_views_post_render(&$view, &$output, &$cache) {
  if (
    $view->name == 'archibald_lomch_descriptions' &&
    variable_get('archibald_show_link_to_dsb_portal', FALSE)
  ) {
    $url = variable_get('archibald_dsb_portal_url', '');

    // First, extract all token that must be replaced.
    preg_match_all(
      '/<div.+?archibald-view-on-portal-replacement-token."?>(.+?)<\/div>/',
      $output,
      $match
    );

    // Replace them with links.
    foreach ($match[0] as $i => $token) {
      $link = l(
        t("view on portal", array(), array('context' => 'archibald:node_view')),
        str_replace(
          '[ID]',
          urlencode($match[1][$i]),
          $url
        ),
        array('attributes' => array('target' => '_blank'))
      );
      $output = str_replace($token, $link, $output);
    }
  }
}

/**
 * Helper function to provide default settings for "nothing" fields.
 *
 * Views allows the addition of "plain" text fields, called "nothing" fields,
 * which are not related to any database field. Because it requires quite a bit
 * of options just to work properly, we provide sensible defaults here. Use the
 * result of this function when adding a text field to an existing view on the
 * fly. See archibald_views_pre_view() for an example use-case.
 *
 * @see archibald_views_pre_view()
 *
 * @param string $id
 *    The identifier for the field.
 * @param string $value
 *    (optional) The default value for the text field. Defaults to an empty
 *    string.
 *
 * @return array
 *    An array containing a definition for a views "nothing" field.
 */
function archibald_views_custom_text_field_defaults($id, $value = '') {
  return array(
    'id' => $id,
    'table' => 'views',
    'field' => 'nothing',
    'relationship' => 'none',
    'group_type' => 'group',
    'ui_name' => '',
    'label' => '',
    'exclude' => FALSE,
    'alter' => array(
      'alter_text' => TRUE,
      'text' => $value,
      'make_link' => FALSE,
      'path' => '',
      'absolute' => FALSE,
      'external' => FALSE,
      'replace_spaces' => FALSE,
      'path_case' => 'none',
      'trim_whitespace' => FALSE,
      'alt' => '',
      'rel' => '',
      'link_class' => '',
      'prefix' => '',
      'suffix' => '',
      'target' => '',
      'nl2br' => FALSE,
      'max_length' => '',
      'word_boundary' => TRUE,
      'ellipsis' => TRUE,
      'more_link' => FALSE,
      'more_link_text' => '',
      'more_link_path' => '',
      'strip_tags' => FALSE,
      'trim' => FALSE,
      'preserve_tags' => '',
      'html' => FALSE,
    ),
    'element_type' => '',
    'element_class' => '',
    'element_label_type' => '',
    'element_label_class' => '',
    'element_label_colon' => TRUE,
    'element_wrapper_type' => '',
    'element_wrapper_class' => '',
    'element_default_classes' => TRUE,
    'empty' => '',
    'hide_empty' => FALSE,
    'empty_zero' => FALSE,
    'hide_alter_empty' => FALSE,
  );
}
