source: sipes/modules_contrib/views/handlers/views_handler_argument.inc @ 59029b2

stableversion-3.0
Last change on this file since 59029b2 was 59029b2, checked in by José Gregorio Puentes <jpuentes@…>, 8 años ago

se actualizo la version del modulo views

  • Propiedad mode establecida a 100644
File size: 30.3 KB
Línea 
1<?php
2
3/**
4 * @defgroup views_argument_handlers Handlers for arguments
5 * @{
6 */
7
8/**
9 * Base class for arguments.
10 *
11 * The basic argument works for very simple arguments such as nid and uid
12 *
13 * Definition terms for this handler:
14 * - name field: The field to use for the name to use in the summary, which is
15 *               the displayed output. For example, for the node: nid argument,
16 *               the argument itself is the nid, but node.title is displayed.
17 * - name table: The table to use for the name, should it not be in the same
18 *               table as the argument.
19 * - empty field name: For arguments that can have no value, such as taxonomy
20 *                     which can have "no term", this is the string which
21 *                     will be displayed for this lack of value. Be sure to use
22 *                     t().
23 * - validate type: A little used string to allow an argument to restrict
24 *                  which validator is available to just one. Use the
25 *                  validator ID. This probably should not be used at all,
26 *                  and may disappear or change.
27 * - numeric: If set to TRUE this field is numeric and will use %d instead of
28 *            %s in queries.
29 *
30 * @ingroup views_argument_handlers
31 */
32class views_handler_argument extends views_handler {
33  var $name_field = NULL;
34  /**
35   * Constructor
36   */
37  function construct() {
38    parent::construct();
39
40    if (!empty($this->definition['name field'])) {
41      $this->name_field = $this->definition['name field'];
42    }
43    if (!empty($this->definition['name table'])) {
44      $this->name_table = $this->definition['name table'];
45    }
46  }
47
48  function init(&$view, $options) {
49    parent::init($view, $options);
50  }
51
52  /**
53   * Give an argument the opportunity to modify the breadcrumb, if it wants.
54   * This only gets called on displays where a breadcrumb is actually used.
55   *
56   * The breadcrumb will be in the form of an array, with the keys being
57   * the path and the value being the already sanitized title of the path.
58   */
59  function set_breadcrumb(&$breadcrumb) { }
60
61  /**
62   * Determine if the argument can generate a breadcrumb
63   *
64   * @return TRUE/FALSE
65   */
66  function uses_breadcrumb() {
67    $info = $this->default_actions($this->options['default_action']);
68    return !empty($info['breadcrumb']);
69  }
70
71  function is_wildcard($arg = NULL) {
72    if (!isset($arg)) {
73      $arg = $this->argument;
74    }
75
76    return !empty($this->options['wildcard']) && $this->options['wildcard'] === $arg;
77  }
78
79  function wildcard_title() {
80    return $this->options['wildcard_substitution'];
81  }
82
83  /**
84   * Determine if the argument needs a style plugin.
85   *
86   * @return TRUE/FALSE
87   */
88  function needs_style_plugin() {
89    $info = $this->default_actions($this->options['default_action']);
90    $validate_info = $this->default_actions($this->options['validate_fail']);
91    return !empty($info['style plugin']) || !empty($validate_info['style plugin']);
92  }
93
94  function option_definition() {
95    $options = parent::option_definition();
96
97    $options['default_action'] = array('default' => 'ignore');
98    $options['style_plugin'] = array('default' => 'default_summary', 'export' => 'export_style');
99    $options['style_options'] = array('default' => array(), 'export' => FALSE);
100    $options['wildcard'] = array('default' => 'all');
101    $options['wildcard_substitution'] = array('default' => t('All'), 'translatable' => TRUE);
102    $options['title'] = array('default' => '', 'translatable' => TRUE);
103    $options['breadcrumb'] = array('default' => '', 'translatable' => TRUE);
104    $options['default_argument_type'] = array('default' => 'fixed', 'export' => 'export_plugin');
105    $options['default_argument_options'] = array('default' => array(), 'export' => FALSE);
106    $options['default_argument_skip_url'] = array('default' => FALSE);
107    $options['validate_type'] = array('default' => 'none', 'export' => 'export_plugin');
108    $options['validate_options'] = array('default' => array(), 'export' => FALSE);
109    $options['validate_fail'] = array('default' => 'not found');
110
111    return $options;
112  }
113
114  function options_form(&$form, &$form_state) {
115    parent::options_form($form, $form_state);
116    $defaults = $this->default_actions();
117
118    $form['title'] = array(
119      '#prefix' => '<div class="clear-block">',
120      '#suffix' => '</div>',
121      '#type' => 'textfield',
122      '#title' => t('Title'),
123      '#default_value' => $this->options['title'],
124      '#description' => t('The title to use when this argument is present. It will override the title of the view and titles from previous arguments. You can use percent substitution here to replace with argument titles. Use "%1" for the first argument, "%2" for the second, etc.'),
125    );
126
127    $form['breadcrumb'] = array(
128      '#prefix' => '<div class="clear-block">',
129      '#suffix' => '</div>',
130      '#type' => 'textfield',
131      '#title' => t('Breadcrumb'),
132      '#default_value' => $this->options['breadcrumb'],
133      '#description' => t('The Breadcrumb title to use when this argument is present. If no breadcrumb is set here, default Title values will be used, see "Title" for percent substitutions.'),
134    );
135
136    $form['clear_start'] = array(
137      '#value' => '<div class="clear-block">',
138    );
139
140    $form['defaults_start'] = array(
141      '#value' => '<div class="views-left-50">',
142    );
143
144    $form['default_action'] = array(
145      '#type' => 'radios',
146      '#title' => t('Action to take if argument is not present'),
147      '#default_value' => $this->options['default_action'],
148    );
149
150    $form['defaults_stop'] = array(
151      '#value' => '</div>',
152    );
153
154    $form['wildcard'] = array(
155      '#prefix' => '<div class="views-right-50">',
156      // prefix and no suffix means these two items will be grouped together.
157      '#type' => 'textfield',
158      '#title' => t('Wildcard'),
159      '#size' => 20,
160      '#default_value' => $this->options['wildcard'],
161      '#description' => t('If this value is received as an argument, the argument will be ignored; i.e, "all values"'),
162    );
163
164    $form['wildcard_substitution'] = array(
165      '#suffix' => '</div>',
166      '#type' => 'textfield',
167      '#title' => t('Wildcard title'),
168      '#size' => 20,
169      '#default_value' => $this->options['wildcard_substitution'],
170      '#description' => t('The title to use for the wildcard in substitutions elsewhere.'),
171    );
172
173    $form['clear_stop'] = array(
174      '#value' => '</div>',
175    );
176
177    $options = array();
178    $validate_options = array();
179    foreach ($defaults as $id => $info) {
180      $options[$id] = $info['title'];
181      if (empty($info['default only'])) {
182        $validate_options[$id] = $info['title'];
183      }
184      if (!empty($info['form method'])) {
185        $this->{$info['form method']}($form, $form_state);
186      }
187    }
188
189    $form['default_action']['#options'] = $options;
190
191    $form['validate_options_div_prefix'] = array(
192      '#id' => 'views-validator-options',
193      '#value' => '<fieldset id="views-validator-options"><legend>' . t('Validator options') . '</legend>',
194    );
195
196    $form['validate_type'] = array(
197      '#type' => 'select',
198      '#title' => t('Validator'),
199      '#default_value' => $this->options['validate_type'],
200    );
201
202    $validate_types = array('none' => t('- Basic validation -'));
203    $plugins = views_fetch_plugin_data('argument validator');
204    foreach ($plugins as $id => $info) {
205      if (!empty($info['no ui'])) {
206        continue;
207      }
208
209      $valid = TRUE;
210      if (!empty($info['type'])) {
211        $valid = FALSE;
212        if (empty($this->definition['validate type'])) {
213          continue;
214        }
215        foreach ((array) $info['type'] as $type) {
216          if ($type == $this->definition['validate type']) {
217            $valid = TRUE;
218            break;
219          }
220        }
221      }
222
223      // If we decide this validator is ok, add it to the list.
224      if ($valid) {
225        $plugin = $this->get_plugin('argument validator', $id);
226        if ($plugin) {
227          if ($plugin->access() || $this->options['validate_type'] == $id) {
228            $form['argument_validate'][$id] = array(
229              '#type' => 'item',
230              '#input' => TRUE, // trick it into checking input to make #process run
231              '#process' => array('views_process_dependency'),
232              '#dependency' => array(
233                'edit-options-validate-type' => array($id)
234              ),
235            );
236            $plugin->options_form($form['argument_validate'][$id], $form_state);
237            $validate_types[$id] = $info['title'];
238          }
239        }
240      }
241    }
242
243    asort($validate_types);
244    $form['validate_type']['#options'] = $validate_types;
245
246    $form['validate_fail'] = array(
247      '#type' => 'select',
248      '#title' => t('Action to take if argument does not validate'),
249      '#default_value' => $this->options['validate_fail'],
250      '#options' => $validate_options,
251    );
252
253    $form['validate_options_div_suffix'] = array(
254      '#value' => '</fieldset>',
255    );
256  }
257
258  function options_validate(&$form, &$form_state) {
259    if (empty($form_state['values']['options'])) {
260      return;
261    }
262
263    // Let the plugins do validation.
264    $default_id = $form_state['values']['options']['default_argument_type'];
265    $plugin = $this->get_plugin('argument default', $default_id);
266    if ($plugin) {
267      $plugin->options_validate($form['argument_default'][$default_id], $form_state, $form_state['values']['options']['argument_default'][$default_id]);
268    }
269
270    $validate_id = $form_state['values']['options']['validate_type'];
271    $plugin = $this->get_plugin('argument validator', $validate_id);
272    if ($plugin) {
273      $plugin->options_validate($form['argument_validate'][$default_id], $form_state, $form_state['values']['options']['argument_validate'][$validate_id]);
274    }
275
276  }
277
278  function options_submit($form, &$form_state) {
279    if (empty($form_state['values']['options'])) {
280      return;
281    }
282
283    // Let the plugins make submit modifications if necessary.
284    $default_id = $form_state['values']['options']['default_argument_type'];
285    $plugin = $this->get_plugin('argument default', $default_id);
286    if ($plugin) {
287      $options = &$form_state['values']['options']['argument_default'][$default_id];
288      $plugin->options_submit($form['argument_default'][$default_id], $form_state, $options);
289      // Copy the now submitted options to their final resting place so they get saved.
290      $form_state['values']['options']['default_argument_options'] = $options;
291    }
292
293    $validate_id = $form_state['values']['options']['validate_type'];
294    $plugin = $this->get_plugin('argument validator', $validate_id);
295    if ($plugin) {
296      $options = &$form_state['values']['options']['argument_validate'][$validate_id];
297      $plugin->options_submit($form['argument_validate'][$validate_id], $form_state, $options);
298      // Copy the now submitted options to their final resting place so they get saved.
299      $form_state['values']['options']['validate_options'] = $options;
300    }
301  }
302
303  /**
304   * Provide a list of default behaviors for this argument if the argument
305   * is not present.
306   *
307   * Override this method to provide additional (or fewer) default behaviors.
308   */
309  function default_actions($which = NULL) {
310    $defaults = array(
311      'ignore' => array(
312        'title' => t('Display all values'),
313        'method' => 'default_ignore',
314        'breadcrumb' => TRUE, // generate a breadcrumb to here
315      ),
316      'not found' => array(
317        'title' => t('Hide view / Page not found (404)'),
318        'method' => 'default_not_found',
319        'hard fail' => TRUE, // This is a hard fail condition
320      ),
321      'empty' => array(
322        'title' => t('Display empty text'),
323        'method' => 'default_empty',
324        'breadcrumb' => TRUE, // generate a breadcrumb to here
325      ),
326      'summary asc' => array(
327        'title' => t('Summary, sorted ascending'),
328        'method' => 'default_summary',
329        'method args' => array('asc'),
330        'style plugin' => TRUE,
331        'breadcrumb' => TRUE, // generate a breadcrumb to here
332      ),
333      'summary desc' => array(
334        'title' => t('Summary, sorted descending'),
335        'method' => 'default_summary',
336        'method args' => array('desc'),
337        'style plugin' => TRUE,
338        'breadcrumb' => TRUE, // generate a breadcrumb to here
339      ),
340      'summary asc by count' => array(
341        'title' => t('Summary, sorted by number of records ascending'),
342        'method' => 'default_summary',
343        'method args' => array('asc', 'num_records'),
344        'style plugin' => TRUE,
345        'breadcrumb' => TRUE, // generate a breadcrumb to here
346      ),
347      'summary desc by count' => array(
348        'title' => t('Summary, sorted by number of records descending'),
349        'method' => 'default_summary',
350        'method args' => array('desc', 'num_records'),
351        'style plugin' => TRUE,
352        'breadcrumb' => TRUE, // generate a breadcrumb to here
353      ),
354      'default' => array(
355        'title' => t('Provide default argument'),
356        'method' => 'default_default',
357        'form method' => 'default_argument_form',
358        'has default argument' => TRUE,
359        'default only' => TRUE, // this can only be used for missing argument, not validation failure
360      ),
361    );
362
363    if ($which) {
364      if (!empty($defaults[$which])) {
365        return $defaults[$which];
366      }
367    }
368    else {
369      return $defaults;
370    }
371  }
372
373  /**
374   * Provide a form for selecting the default argument when the
375   * default action is set to provide default argument.
376   */
377  function default_argument_form(&$form, &$form_state) {
378    $plugins = views_fetch_plugin_data('argument default');
379    $options = array();
380
381    // This construct uses 'hidden' and not markup because process doesn't
382    // run. It also has an extra div because the dependency wants to hide
383    // the parent in situations like this, so we need a second div to
384    // make this work.
385    $form['default_options_div_prefix'] = array(
386      '#type' => 'hidden',
387      '#id' => 'views-default-options',
388      '#prefix' => '<div><fieldset id="views-default-options"><legend>' . t('Provide default argument options') . '</legend>',
389      '#process' => array('views_process_dependency'),
390      '#dependency' => array('radio:options[default_action]' => array('default')),
391    );
392
393    $form['default_argument_skip_url'] = array(
394      '#type' => 'checkbox',
395      '#title' => t('Skip default argument for view URL'),
396      '#default_value' => $this->options['default_argument_skip_url'],
397      '#description' => t('Select whether to include this default argument when constructing the URL for this view. Skipping default arguments is useful e.g. in the case of feeds.')
398    );
399
400    $form['default_argument_type'] = array(
401      '#prefix' => '<div id="edit-options-default-argument-type-wrapper">',
402      '#suffix' => '</div>',
403      '#type' => 'radios',
404      '#id' => 'edit-options-default-argument-type',
405      '#title' => t('Default argument type'),
406      '#default_value' => $this->options['default_argument_type'],
407    );
408
409    foreach ($plugins as $id => $info) {
410      if (!empty($info['no ui'])) {
411        continue;
412      }
413
414      $plugin = $this->get_plugin('argument default', $id);
415      if ($plugin) {
416        if ($plugin->access() || $this->options['default_argument_type'] == $id) {
417          $form['argument_default'][$id] = array(
418            '#type' => 'item',
419            '#input' => TRUE, // trick it into checking input to make #process run
420            '#process' => array('views_process_dependency'),
421            '#dependency' => array(
422              'radio:options[default_action]' => array('default'),
423              'radio:options[default_argument_type]' => array($id)
424            ),
425            '#dependency_count' => 2,
426          );
427          $options[$id] = $info['title'];
428          $plugin->options_form($form['argument_default'][$id], $form_state);
429        }
430      }
431    }
432
433    $form['default_options_div_suffix'] = array(
434      '#value' => '</fieldset></div>',
435    );
436
437    asort($options);
438    $form['default_argument_type']['#options'] = $options;
439  }
440
441  /**
442   * Handle the default action, which means our argument wasn't present.
443   *
444   * Override this method only with extreme care.
445   *
446   * @return
447   *   A boolean value; if TRUE, continue building this view. If FALSE,
448   *   building the view will be aborted here.
449   */
450  function default_action($info = NULL) {
451    if (!isset($info)) {
452      $info = $this->default_actions($this->options['default_action']);
453    }
454
455    if (!$info) {
456      return FALSE;
457    }
458
459    if (!empty($info['method args'])) {
460      return call_user_func_array(array(&$this, $info['method']), $info['method args']);
461    }
462    else {
463      return $this->{$info['method']}();
464    }
465  }
466
467  /**
468   * How to act if validation failes
469   */
470  function validate_fail() {
471    $info = $this->default_actions($this->options['validate_fail']);
472    return $this->default_action($info);
473  }
474  /**
475   * Default action: ignore.
476   *
477   * If an argument was expected and was not given, in this case, simply
478   * ignore the argument entirely.
479   */
480  function default_ignore() {
481    return TRUE;
482  }
483
484  /**
485   * Default action: not found.
486   *
487   * If an argument was expected and was not given, in this case, report
488   * the view as 'not found' or hide it.
489   */
490  function default_not_found() {
491    // Set a failure condition and let the display manager handle it.
492    $this->view->build_info['fail'] = TRUE;
493    return FALSE;
494  }
495
496  /**
497   * Default action: empty
498   *
499   * If an argument was expected and was not given, in this case, display
500   * the view's empty text
501   */
502  function default_empty() {
503    // We return with no query; this will force the empty text.
504    $this->view->built = TRUE;
505    $this->view->executed = TRUE;
506    $this->view->result = array();
507    return FALSE;
508  }
509
510  /**
511   * This just returns true. The view argument builder will know where
512   * to find the argument from.
513   */
514  function default_default() {
515    return TRUE;
516  }
517
518  /**
519   * Determine if the argument is set to provide a default argument.
520   */
521  function has_default_argument() {
522    $info = $this->default_actions($this->options['default_action']);
523    return !empty($info['has default argument']);
524  }
525
526  /**
527   * Get a default argument, if available.
528   */
529  function get_default_argument() {
530    $plugin = $this->get_plugin('argument default');
531    if ($plugin) {
532      return $plugin->get_argument();
533    }
534  }
535
536  /**
537   * Default action: summary.
538   *
539   * If an argument was expected and was not given, in this case, display
540   * a summary query.
541   */
542  function default_summary($order, $by = NULL) {
543    $this->view->build_info['summary'] = TRUE;
544    $this->view->build_info['summary_level'] = $this->options['id'];
545
546    // Change the display style to the summary style for this
547    // argument.
548    $this->view->plugin_name = $this->options['style_plugin'];
549    $this->view->style_options = $this->options['style_options'];
550
551    // Clear out the normal primary field and whatever else may have
552    // been added and let the summary do the work.
553    $this->query->clear_fields();
554    $this->summary_query();
555
556    $this->summary_sort($order, $by);
557
558    // Summaries have their own sorting and fields, so tell the View not
559    // to build these.
560    $this->view->build_sort = $this->view->build_fields = FALSE;
561    return TRUE;
562  }
563
564  /**
565   * Build the info for the summary query.
566   *
567   * This must:
568   * - add_groupby: group on this field in order to create summaries.
569   * - add_field: add a 'num_nodes' field for the count. Usually it will
570   *   be a count on $view->base_field
571   * - set_count_field: Reset the count field so we get the right paging.
572   *
573   * @return
574   *   The alias used to get the number of records (count) for this entry.
575   */
576  function summary_query() {
577    $this->ensure_my_table();
578    // Add the field.
579    $this->base_alias = $this->query->add_field($this->table_alias, $this->real_field);
580
581    $this->summary_name_field();
582    return $this->summary_basics();
583  }
584
585  /**
586   * Add the name field, which is the field displayed in summary queries.
587   * This is often used when the argument is numeric.
588   */
589  function summary_name_field() {
590    // Add the 'name' field. For example, if this is a uid argument, the
591    // name field would be 'name' (i.e, the username).
592
593    if (isset($this->name_table)) {
594      // if the alias is different then we're probably added, not ensured,
595      // so look up the join and add it instead.
596      if ($this->table_alias != $this->name_table) {
597        $j = views_get_table_join($this->name_table, $this->table);
598        if ($j) {
599          $join = drupal_clone($j);
600          $join->left_table = $this->table_alias;
601          $this->name_table_alias = $this->query->add_table($this->name_table, $this->relationship, $join);
602        }
603      }
604      else {
605        $this->name_table_alias = $this->query->ensure_table($this->name_table, $this->relationship);
606      }
607    }
608    else {
609      $this->name_table_alias = $this->table_alias;
610    }
611
612    if (isset($this->name_field)) {
613      $this->name_alias = $this->query->add_field($this->name_table_alias, $this->name_field);
614    }
615    else {
616      $this->name_alias = $this->base_alias;
617    }
618  }
619
620  /**
621   * Some basic summary behavior that doesn't need to be repeated as much as
622   * code that goes into summary_query()
623   */
624  function summary_basics($count_field = TRUE) {
625    // Add the number of nodes counter
626    $field = $this->query->base_table . '.' . $this->query->base_field;
627    $distinct = ($this->view->display_handler->get_option('distinct') && empty($this->query->no_distinct));
628
629    $count_alias = $this->query->add_field(NULL, $field, 'num_records',
630                                           array('count' => TRUE, 'distinct' => $distinct));
631    $this->query->add_groupby($this->name_alias);
632
633    if ($count_field) {
634      $this->query->set_count_field($this->table_alias, $this->real_field);
635    }
636
637    $this->count_alias = $count_alias;
638  }
639
640  /**
641   * Sorts the summary based upon the user's selection. The base variant of
642   * this is usually adequte.
643   *
644   * @param $order
645   *   The order selected in the UI.
646   */
647  function summary_sort($order, $by = NULL) {
648    $this->query->add_orderby(NULL, NULL, $order, (!empty($by) ? $by : $this->name_alias));
649  }
650
651  /**
652   * Provide the argument to use to link from the summary to the next level;
653   * this will be called once per row of a summary, and used as part of
654   * $view->get_url().
655   *
656   * @param $data
657   *   The query results for the row.
658   */
659  function summary_argument($data) {
660    return $data->{$this->base_alias};
661  }
662
663  /**
664   * Provides the name to use for the summary. By default this is just
665   * the name field.
666   *
667   * @param $data
668   *   The query results for the row.
669   */
670  function summary_name($data) {
671    $value = $data->{$this->name_alias};
672    if (empty($value) && !empty($this->definition['empty field name'])) {
673      $value = $this->definition['empty field name'];
674    }
675    return check_plain($value);
676  }
677
678  /**
679   * Set up the query for this argument.
680   *
681   * The argument sent may be found at $this->argument.
682   */
683  function query() {
684    $this->ensure_my_table();
685    $placeholder = empty($this->definition['numeric']) ? "'%s'" : '%d';
686    $this->query->add_where(0, "$this->table_alias.$this->real_field = $placeholder", $this->argument);
687  }
688
689  /**
690   * Get the title this argument will assign the view, given the argument.
691   *
692   * This usually needs to be overridden to provide a proper title.
693   */
694  function title() {
695    return check_plain($this->argument);
696  }
697
698  /**
699   * Called by the view object to get the title. This may be set by a
700   * validator so we don't necessarily call through to title().
701   */
702  function get_title() {
703    if (isset($this->validated_title)) {
704      return $this->validated_title;
705    }
706    else {
707      return $this->title();
708    }
709  }
710
711  /**
712   * Validate that this argument works. By default, all arguments are valid.
713   */
714  function validate_arg($arg) {
715    // By using % in URLs, arguments could be validated twice; this eases
716    // that pain.
717    if (isset($this->argument_validated)) {
718      return $this->argument_validated;
719    }
720
721    if ($this->is_wildcard($arg)) {
722      return $this->argument_validated = TRUE;
723    }
724
725    if ($this->options['validate_type'] == 'none') {
726      return $this->argument_validated = $this->validate_argument_basic($arg);
727    }
728
729    $plugin = $this->get_plugin('argument validator');
730    if ($plugin) {
731      return $this->argument_validated = $plugin->validate_argument($arg);
732    }
733
734    // If the plugin isn't found, fall back to the basic validation path:
735    return $this->argument_validated = $this->validate_argument_basic($arg);
736  }
737
738  /**
739   * Called by the menu system to validate an argument.
740   *
741   * This checks to see if this is a 'soft fail', which means that if the
742   * argument fails to validate, but there is an action to take anyway,
743   * then validation cannot actually fail.
744   */
745  function validate_argument($arg) {
746    $validate_info = $this->default_actions($this->options['validate_fail']);
747    if (empty($validate_info['hard fail'])) {
748      return TRUE;
749    }
750
751    $rc = $this->validate_arg($arg);
752
753    // If the validator has changed the validate fail condition to a
754    // soft fail, deal with that:
755    $validate_info = $this->default_actions($this->options['validate_fail']);
756    if (empty($validate_info['hard fail'])) {
757      return TRUE;
758    }
759
760    return $rc;
761  }
762
763  /**
764   * Provide a basic argument validation.
765   *
766   * This can be overridden for more complex types; the basic
767   * validator only checks to see if the argument is not NULL
768   * or is numeric if the definition says it's numeric.
769   */
770  function validate_argument_basic($arg) {
771    if (!isset($arg) || $arg === '') {
772      return FALSE;
773    }
774
775    if (!empty($this->definition['numeric']) && !isset($this->options['break_phrase']) && !is_numeric($arg)) {
776      return FALSE;
777    }
778
779    return TRUE;
780  }
781
782  /**
783   * Set the input for this argument
784   *
785   * @return TRUE if it successfully validates; FALSE if it does not.
786   */
787  function set_argument($arg) {
788    $this->argument = $arg;
789    return $this->validate_arg($arg);
790  }
791
792  /**
793   * Get the value of this argument.
794   */
795  function get_value() {
796    // If we already processed this argument, we're done.
797    if (isset($this->argument)) {
798      return $this->argument;
799    }
800
801    // Otherwise, we have to pretend to process ourself to find the value.
802    $value = NULL;
803    // Find the position of this argument within the view.
804    $position = 0;
805    foreach ($this->view->argument as $id => $argument) {
806      if ($id == $this->options['id']) {
807        break;
808      }
809      $position++;
810    }
811
812    $arg = isset($this->view->args[$position]) ? $this->view->args[$position] : NULL;
813    $this->position = $position;
814
815    // Clone ourselves so that we don't break things when we're really
816    // processing the arguments.
817    $argument = drupal_clone($this);
818    if (!isset($arg) && $argument->has_default_argument()) {
819      $arg = $argument->get_default_argument();
820
821      // remember that this argument was computed, not passed on the URL.
822      $this->is_default = TRUE;
823    }
824    // Set the argument, which will also validate that the argument can be set.
825    if ($argument->set_argument($arg)) {
826      $value = $argument->argument;
827    }
828    unset($argument);
829    return $value;
830  }
831
832  /**
833   * Special handling for the style export.
834   *
835   * Arguments can have styles for the summary view. This special export
836   * handler makes sure this works properly.
837   */
838  function export_style($indent, $prefix, $storage, $option, $definition, $parents) {
839    $output = '';
840    $name = $storage[$option];
841    $options = $storage['style_options'];
842
843    $plugin = views_get_plugin('style', $name);
844    if ($plugin) {
845      $plugin->init($this->view, $this->display, $options);
846      // Write which plugin to use.
847      $output .= $indent . $prefix . "['$option'] = '$name';\n";
848
849      // Pass off to the plugin to export itself.
850      $output .= $plugin->export_options($indent, $prefix . "['style_options']");
851    }
852
853    return $output;
854  }
855
856  /**
857   * Special handling for the style export.
858   *
859   * Arguments can have styles for the summary view. This special export
860   * handler makes sure this works properly.
861   */
862  function export_plugin($indent, $prefix, $storage, $option, $definition, $parents) {
863    $output = '';
864    if ($option == 'default_argument_type') {
865      $type = 'argument default';
866      $option_name = 'default_argument_options';
867    }
868    else {
869      $type = 'argument validator';
870      $option_name = 'validate_options';
871    }
872    $plugin = $this->get_plugin($type);
873    $name = $this->options[$option];
874
875    if ($plugin) {
876      // Write which plugin to use.
877      $output .= $indent . $prefix . "['$option'] = '$name';\n";
878
879      // Pass off to the plugin to export itself.
880      $output .= $plugin->export_options($indent, $prefix . "['$option_name']");
881    }
882
883    return $output;
884  }
885
886  /**
887   * Get the display or row plugin, if it exists.
888   */
889  function get_plugin($type = 'argument default', $name = NULL) {
890    $options = array();
891    switch ($type) {
892      case 'argument default':
893        $plugin_name = 'default_argument_type';
894        $options_name = 'default_argument_options';
895        break;
896      case 'argument validator':
897        $plugin_name = 'validate_type';
898        $options_name = 'validate_options';
899    }
900
901    if (!$name) {
902      $name = $this->options[$plugin_name];
903    }
904
905    // we only fetch the options if we're fetching the plugin actually
906    // in use.
907    if ($name == $this->options[$plugin_name]) {
908      $options = $this->options[$options_name];
909    }
910
911    $plugin = views_get_plugin($type, $name);
912    if ($plugin) {
913      $plugin->init($this->view, $this, $options);
914      return $plugin;
915    }
916  }
917}
918
919/**
920 * A special handler to take the place of missing or broken handlers.
921 *
922 * @ingroup views_argument_handlers
923 */
924class views_handler_argument_broken extends views_handler_argument {
925  function ui_name($short = FALSE) {
926    return t('Broken/missing handler');
927  }
928
929  function ensure_my_table() { /* No table to ensure! */ }
930  function query() { /* No query to run */ }
931  function options_form(&$form, &$form_state) {
932    $form['markup'] = array(
933      '#prefix' => '<div class="form-item description">',
934      '#value' => t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.'),
935    );
936  }
937
938  /**
939   * Determine if the handler is considered 'broken'
940   */
941  function broken() { return TRUE; }
942}
943
944/**
945 * @}
946 */
Nota: Vea TracBrowser para ayuda de uso del navegador del repositorio.