annotate noderef_view.module @ 15:bf2615aab48c tip

Make the module Coder-clean
author Franck Deroche <franck@defr.org>
date Tue, 31 Mar 2009 17:31:55 +0200
parents e060ad73e358
children
rev   line source
franck@0 1 <?php
franck@0 2 // vim: set ts=2 sw=2 expandtab syntax=php:
franck@0 3
franck@0 4 /**
franck@0 5 * @file
franck@0 6 * Fichier principale du module noderef_view
franck@0 7 *
franck@0 8 * Ce module permet d'ajouter à tous les champs de type "Node Reference"
franck@1 9 * pour lesquels une vue définissant les nodes autorisés a été définie
franck@1 10 * un lien 'Search' affichant la vue dans une popup (via le module Popups API),
franck@0 11 * permettant de choisir les nodes à mettre dans le champ en disposant de la
franck@1 12 * puissance de Views pour la recherche (Exposed Filters notamment).
franck@0 13 */
franck@0 14
franck@0 15 /**
franck@0 16 * Implémentation de hook_view_action_info().
franck@0 17 *
franck@0 18 * On crée une nouvelle action, nommée Select, et qui sera utilisée pour marquer
franck@0 19 * les nodes comme données à utiliser. L'utilisation concrète qui en est faite
franck@0 20 * dans ce module consiste à utiliser ces nœuds selectionés pour les ajouter
franck@0 21 * dans le champ Node Reference étant à l'origine de la recherche.
franck@0 22 */
franck@0 23 function noderef_view_action_info() {
franck@0 24 return array(
franck@0 25 'noderef_view_select' => array(
franck@9 26 'description' => t('Add selected values to field'),
franck@0 27 'type' => 'node',
franck@0 28 'configurable' => FALSE,
franck@0 29 'hooks' => array(
franck@0 30 'nodeapi' => array()
franck@0 31 )
franck@0 32 )
franck@0 33 );
franck@0 34 }
franck@0 35
franck@0 36 /**
franck@0 37 * Implémentation concrète de l'action de selection.
franck@0 38 *
franck@0 39 * On vide toute eventuelle selection précédente, puis on passe dans le cookie
franck@0 40 * les informations sur la selection qui a été faite.
franck@0 41 */
franck@0 42 function noderef_view_select($node, $context) {
franck@0 43 static $count = 0;
franck@0 44 if ($count == 0 && is_array($_COOKIE['noderef'])) {
franck@0 45 // Reset the cookies
franck@0 46 $before = time() - 300;
franck@15 47 foreach ($_COOKIE['noderef'] as $id => $val) {
franck@0 48 setcookie('noderef['. $id .']', 0, $before, '/');
franck@0 49 }
franck@0 50 }
franck@0 51 $count++;
franck@0 52 $five = time() + 300;
franck@0 53 setrawcookie('noderef['. $node->nid .']', rawurlencode($node->title), $five, '/');
franck@11 54 drupal_set_message(t('!title added to selection',
franck@11 55 array('!title' => $node->title)));
franck@0 56 }
franck@0 57
franck@0 58 /**
franck@0 59 * Implémentation de hook_form_alter().
franck@0 60 *
franck@0 61 * On parcoure tous les formulaires à la recherche d'éventuels champs
franck@0 62 * de type "Node Reference" sur lesquels appliqués nos transformations.
franck@0 63 */
franck@0 64 function noderef_view_form_alter(&$form, $form_state, $form_id) {
franck@0 65 if (isset($form['type']) && $form_id == $form['type']['#value'] .'_node_form') {
franck@0 66 // That's a node form, get the fields and alter the form if needed
franck@0 67 $fields = content_fields();
franck@11 68 $alter = _noderef_view_walk_form($form, $fields, $form);
franck@0 69 if ($alter) {
franck@0 70 // We've changed the form, add the JS-behavior and Views CSS
franck@0 71 // (the latter to deal with exposed filters in the popup)
franck@6 72 $path = drupal_get_path('module', 'noderef_view');
franck@6 73 drupal_add_js($path .'/noderef_view.js');
franck@6 74 drupal_add_css($path .'/noderef_view.css');
franck@0 75 drupal_add_css(drupal_get_path('module', 'views') .'/css/views.css');
franck@0 76 }
franck@0 77 }
franck@0 78 elseif ($form_id == 'views_exposed_form' && isset($_GET['destination'])) {
franck@0 79 // Views "Exposed Filter" forms doesn't preserve destination by default.
franck@0 80 $form['destination'] = array(
franck@0 81 '#type' => 'hidden',
franck@0 82 '#value' => $_GET['destination']
franck@0 83 );
franck@0 84 }
franck@0 85 }
franck@0 86
franck@0 87 /**
franck@0 88 * Parcoure le tableau contenant le formulaire à la recherche
franck@0 89 * d'élement à modifier.
franck@0 90 * @return
franck@0 91 * TRUE si un élement a été modifié, FALSE sinon
franck@0 92 */
franck@11 93 function _noderef_view_walk_form(&$form, $fields, $items) {
franck@0 94 $alter = FALSE;
franck@15 95 foreach ($items as $key => $item) {
franck@0 96 if (is_array($item)) {
franck@0 97 if (isset($fields[$key])) {
franck@0 98 $alter |= noderef_view_alter_item($form, $key, $fields[$key]);
franck@0 99 }
franck@0 100 else {
franck@11 101 $alter |= _noderef_view_walk_form($form, $fields, $item);
franck@0 102 }
franck@0 103 }
franck@0 104 }
franck@0 105 return $alter;
franck@0 106 }
franck@0 107
franck@0 108 /**
franck@0 109 * Modification d'un élement en particulier du formulaire.
franck@0 110 *
franck@0 111 * @return
franck@0 112 * TRUE si l'element a été modifié, FALSE sinon.
franck@0 113 */
franck@0 114 function noderef_view_alter_item(&$form, $key, $field) {
franck@0 115 if (is_array($field) && $field['type'] == 'nodereference') {
franck@2 116 $link = _noderef_view_get_link($field);
franck@0 117 if (!empty($link)) {
franck@0 118 return TRUE;
franck@0 119 }
franck@0 120 }
franck@0 121 return FALSE;
franck@0 122 }
franck@0 123
franck@0 124 /**
franck@0 125 * Création d'un lien vers une éventuelle vue associé au champ.
franck@0 126 *
franck@0 127 * @return
franck@0 128 * - Un lien vers la vue si une vue est associée
franck@0 129 * - Une chaine vide sinon
franck@11 130 */
franck@0 131 function _noderef_view_get_link($field) {
franck@0 132 $path = '';
franck@0 133 // Check if there's a view associated with this field
franck@0 134 if (isset($field['advanced_view']) && $field['advanced_view'] !== '--') {
franck@0 135 $view = views_get_view($field['advanced_view']);
franck@0 136 // Try to find a path for this view, looking at the displays
franck@13 137 if (!is_array($view->display)) {
franck@13 138 return '';
franck@13 139 }
franck@0 140 $path = '';
franck@15 141 foreach ($view->display as $display) {
franck@0 142 if (is_array($display->display_options)
franck@0 143 && isset($display->display_options['path'])) {
franck@0 144 $path = $display->display_options['path'];
franck@2 145 break;
franck@0 146 }
franck@0 147 }
franck@0 148 }
franck@0 149 // If we found a view with a suitable display, then link to it
franck@0 150 if (!empty($path)) {
franck@14 151 popups_add_popups(array('.noderef_view_link' => array(
franck@14 152 'noUpdate' => FALSE,
franck@14 153 'noMessage' => FALSE
franck@14 154 )));
franck@0 155 $options = array(
franck@14 156 'attributes' => array('class' => 'noderef_view_link'),
franck@0 157 'query' => array('destination' => 'node')
franck@0 158 );
franck@0 159 $path = l(t('Search'), $path, $options);
franck@0 160 }
franck@2 161 return $path;
franck@0 162 }
franck@0 163
franck@11 164 function noderef_view_theme() {
franck@11 165 return array(
franck@11 166 'noderef_view_autocomplete' => array(
franck@11 167 'arguments' => array('element' => NULL)
franck@11 168 )
franck@11 169 );
franck@11 170 }
franck@11 171
franck@11 172 function noderef_view_widget_info() {
franck@11 173 return array(
franck@11 174 'noderef_view_autocomplete' => array(
franck@11 175 'label' => t('Autocomplete text field with View'),
franck@11 176 'field types' => array('nodereference'),
franck@11 177 'multiple values' => CONTENT_HANDLE_CORE,
franck@11 178 'callbacks' => array(
franck@11 179 'default value' => CONTENT_CALLBACK_DEFAULT,
franck@11 180 ),
franck@11 181 ),
franck@11 182 );
franck@11 183 }
franck@11 184
franck@11 185 function noderef_view_elements() {
franck@11 186 return array(
franck@11 187 'noderef_view_autocomplete' => array(
franck@11 188 '#input' => TRUE,
franck@11 189 '#columns' => array('name'), '#delta' => 0,
franck@11 190 '#process' => array('noderef_view_autocomplete_process'),
franck@11 191 '#autocomplete_path' => FALSE,
franck@11 192 ),
franck@11 193 );
franck@11 194 }
franck@11 195
franck@11 196 function noderef_view_widget(&$form, &$form_state, $field, $items, $delta = 0) {
franck@11 197 switch ($field['widget']['type']) {
franck@11 198 case 'noderef_view_autocomplete':
franck@11 199 $element = array(
franck@11 200 '#type' => 'noderef_view_autocomplete',
franck@11 201 '#default_value' => isset($items[$delta]) ? $items[$delta] : NULL,
franck@11 202 '#value_callback' => 'nodereference_autocomplete_value',
franck@11 203 );
franck@11 204 break;
franck@11 205 }
franck@11 206 return $element;
franck@11 207 }
franck@11 208
franck@11 209 /**
franck@11 210 * Process an individual element.
franck@11 211 *
franck@11 212 * Build the form element. When creating a form using FAPI #process,
franck@11 213 * note that $element['#value'] is already set.
franck@11 214 *
franck@11 215 */
franck@11 216 function noderef_view_autocomplete_process($element, $edit, $form_state, $form) {
franck@11 217 // The nodereference autocomplete widget doesn't need to create its own
franck@11 218 // element, it can wrap around the text_textfield element and add an autocomplete
franck@11 219 // path and some extra processing to it.
franck@11 220 // Add a validation step where the value can be unwrapped.
franck@11 221 $fields = content_fields();
franck@11 222 $link = _noderef_view_get_link($fields[$element['#field_name']]);
franck@11 223 $field_key = $element['#columns'][0];
franck@11 224 $element[$field_key] = array(
franck@11 225 '#type' => 'text_textfield',
franck@11 226 '#default_value' => isset($element['#value']) ? $element['#value'] : '',
franck@11 227 '#autocomplete_path' => 'nodereference/autocomplete/'. $element['#field_name'],
franck@11 228 // The following values were set by the content module and need
franck@11 229 // to be passed down to the nested element.
franck@11 230 '#title' => $element['#title'],
franck@11 231 '#required' => $element['#required'],
franck@11 232 '#description' => $element['#description'],
franck@11 233 '#field_name' => $element['#field_name'],
franck@11 234 '#type_name' => $element['#type_name'],
franck@11 235 '#delta' => $element['#delta'],
franck@11 236 '#columns' => $element['#columns'],
franck@11 237 );
franck@11 238 if ($link) {
franck@11 239 $element[$field_key]['#noderef_view_link'] = $link;
franck@11 240 $element[$field_key]['#prefix'] = "<div class='noderef-view-wrapper'>";
franck@11 241 $element[$field_key]['#suffix'] = $link ."</div>";
franck@11 242 }
franck@11 243 if (empty($element[$field_key]['#element_validate'])) {
franck@11 244 $element[$field_key]['#element_validate'] = array();
franck@11 245 }
franck@11 246 array_unshift($element[$field_key]['#element_validate'], 'nodereference_autocomplete_validate');
franck@11 247
franck@11 248 // Used so that hook_field('validate') knows where to flag an error.
franck@11 249 $element['_error_element'] = array(
franck@11 250 '#type' => 'value',
franck@11 251 // Wrapping the element around a text_textfield element creates a
franck@11 252 // nested element, so the final id will look like 'field-name-0-nid-nid'.
franck@11 253 '#value' => implode('][', array_merge($element['#parents'], array($field_key, $field_key))),
franck@11 254 );
franck@11 255 return $element;
franck@11 256 }
franck@11 257
franck@11 258 function theme_noderef_view_autocomplete($element) {
franck@11 259 return <<<EOT
franck@11 260 <div class='noderef-view-wrapper'>
franck@11 261 {$element['#children']}
franck@11 262 {$element['#noderef_view_link']}
franck@11 263 <span class='clear-block'></span>
franck@11 264 </div>
franck@11 265 EOT;
franck@11 266 }