view noderef_view.module @ 0:a3c1e224e807

Import initial du module noderef_view
author Franck Deroche <franck@defr.org>
date Fri, 23 Jan 2009 14:52:03 +0100
parents
children 71a07534c366
line wrap: on
line source
<?php
// vim: set ts=2 sw=2 expandtab syntax=php:

/**
 * @file 
 * Fichier principale du module noderef_view
 * 
 * Ce module permet d'ajouter à tous les champs de type "Node Reference"
 * pour lesquels une view définissant les nodes autorisés a été définie
 * un lien 'Search' affichant la view dans une popup (via le module Popups API),
 * permettant de choisir les nodes à mettre dans le champ en disposant de la
 * puissance des Views pour la recherche (Exposed Filters notamment).
 */

/**
 * Implémentation de hook_view_action_info().
 * 
 * On crée une nouvelle action, nommée Select, et qui sera utilisée pour marquer
 * les nodes comme données à utiliser. L'utilisation concrète qui en est faite
 * dans ce module consiste à utiliser ces nœuds selectionés pour les ajouter
 * dans le champ Node Reference étant à l'origine de la recherche.
 */
function noderef_view_action_info() {
  return array(
    'noderef_view_select' => array(
      'description'  => t('Select for later use'),
      'type'         => 'node',
      'configurable' => FALSE,
      'hooks' => array(
        'nodeapi' => array()
      )
    )
  );
}

/**
 * Implémentation concrète de l'action de selection.
 * 
 * On vide toute eventuelle selection précédente, puis on passe dans le cookie
 * les informations sur la selection qui a été faite.
 */
function noderef_view_select($node, $context) {
  static $count = 0;
  if ($count == 0 && is_array($_COOKIE['noderef'])) {
    // Reset the cookies
    $before = time() - 300;
    foreach($_COOKIE['noderef'] as $id => $val) {
      setcookie('noderef['. $id .']', 0, $before, '/');
    }
  }
  $count++;
  $five = time() + 300;
  setrawcookie('noderef['. $node->nid .']', rawurlencode($node->title), $five, '/');
  dsm(t('!title added to selection', array('!title' => $node->title)));
}

/**
 * Implémentation de hook_form_alter().
 *
 * On parcoure tous les formulaires à la recherche d'éventuels champs
 * de type "Node Reference" sur lesquels appliqués nos transformations.
 */
function noderef_view_form_alter(&$form, $form_state, $form_id) {
  if (isset($form['type']) && $form_id == $form['type']['#value'] .'_node_form') {
    // That's a node form, get the fields and alter the form if needed
    $fields = content_fields();
    $alter = _noderef_view_walk_form($form, $fields);
    if ($alter) {
      // We've changed the form, add the JS-behavior and Views CSS
      // (the latter to deal with exposed filters in the popup)
      drupal_add_css(drupal_get_path('module', 'views') .'/css/views.css');
      drupal_add_js(drupal_get_path('module', 'noderef_view') .'/noderef_view.js');
    }
  }
  elseif ($form_id == 'views_exposed_form' && isset($_GET['destination'])) {
    // Views "Exposed Filter" forms doesn't preserve destination by default.
    $form['destination'] = array(
      '#type' => 'hidden',
      '#value' => $_GET['destination']
    );
  }
}

/**
 * Parcoure le tableau contenant le formulaire à la recherche
 * d'élement à modifier.
 * @return
 *   TRUE si un élement a été modifié, FALSE sinon
 */
function _noderef_view_walk_form(&$form, $fields) {
  $alter = FALSE;
  foreach($form as $key => $item) {
    if (is_array($item)) {
      if (isset($fields[$key])) {
        $alter |= noderef_view_alter_item($form, $key, $fields[$key]);
      }
      else {
        $alter |= _noderef_view_walk_form($item, $fields);
      }
    }
  }
  return $alter;
}

/**
 * Modification d'un élement en particulier du formulaire.
 *
 * @return 
 *   TRUE si l'element a été modifié, FALSE sinon.
 */
function noderef_view_alter_item(&$form, $key, $field) {
  if (is_array($field) && $field['type'] == 'nodereference') {
    list($link, $id) = _noderef_view_get_link($field);
    if (!empty($link)) {
      $form[$key]['#prefix'] .= "<div id='noderef_view_link_{$id}'>";
      $form[$key]['#suffix'] = $link .'</div>'. $form[$key]['#suffix'];
      return TRUE;
    }
  }
  return FALSE;
}

/**
 * Création d'un lien vers une éventuelle vue associé au champ.
 *
 * @return
 *  - Un lien vers la vue si une vue est associée
 *  - Une chaine vide sinon
 */
function _noderef_view_get_link($field) {
  static $id = 0;
  $path = '';
  // Check if there's a view associated with this field
  if (isset($field['advanced_view']) && $field['advanced_view'] !== '--') {
    $view = views_get_view($field['advanced_view']);
    // Try to find a path for this view, looking at the displays
    $path = '';
    foreach($view->display as $display) {
      if (is_array($display->display_options) 
        && isset($display->display_options['path'])) {
        $path = $display->display_options['path'];
	break;
      }
    }
  }
  // If we found a view with a suitable display, then link to it
  if (!empty($path)) {
    $id++;
    popups_add_popups();
    $options = array(
      'attributes' => array(
        'class' => 'popups noderef_view_link',
        'rel'   => 'noderef_view_link_'. $id),
      'query' => array('destination' => 'node')
    );
    $path = l(t('Search'), $path, $options);
  }
  return array($path, $id);
}