Removing translation directories
[project/views.git] / handlers / views_handler_argument.inc
CommitLineData
8a718296 1<?php
8a718296
EM
2
3/**
4 * @defgroup views_argument_handlers Handlers for arguments
5 * @{
6 */
fe44beb7 7
8a718296
EM
8/**
9 * Base class for arguments.
10 *
11 * The basic argument works for very simple arguments such as nid and uid
11d03592
EM
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 *
fe44beb7 30 * @ingroup views_argument_handlers
8a718296
EM
31 */
32class views_handler_argument extends views_handler {
33 var $name_field = NULL;
34 /**
35 * Constructor
36 */
37 function construct() {
cb2cdc11
EM
38 parent::construct();
39
8a718296
EM
40 if (!empty($this->definition['name field'])) {
41 $this->name_field = $this->definition['name field'];
42 }
ca78ec49
EM
43 if (!empty($this->definition['name table'])) {
44 $this->name_table = $this->definition['name table'];
45 }
8a718296
EM
46 }
47
d5a58088
EM
48 function init(&$view, &$options) {
49 parent::init($view, $options);
d5a58088 50 }
c1e6b5b2 51
8a718296
EM
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 /**
d5a58088
EM
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
a45277c1
EM
71 function is_wildcard($arg = NULL) {
72 if (!isset($arg)) {
73 $arg = $this->argument;
74 }
75
69236c34 76 return !empty($this->options['wildcard']) && $this->options['wildcard'] === $arg;
d5a58088
EM
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']);
fe1dd793
EM
90 $validate_info = $this->default_actions($this->options['validate_fail']);
91 return !empty($info['style plugin']) || !empty($validate_info['style plugin']);
d5a58088
EM
92 }
93
cb2cdc11
EM
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');
99 $options['style_options'] = array('default' => array());
100 $options['wildcard'] = array('default' => 'all');
101 $options['wildcard_substitution'] = array('default' => t('All'), 'translatable' => TRUE);
102 $options['title'] = array('default' => '', 'translatable' => TRUE);
94437166 103 $options['breadcrumb'] = array('default' => '', 'translatable' => TRUE);
cb2cdc11
EM
104 $options['default_argument_type'] = array('default' => 'fixed');
105 $options['default_argument'] = array('default' => '');
106 $options['validate_type'] = array('default' => 'none');
107 $options['validate_fail'] = array('default' => 'not found');
108
109 return $options;
8a718296
EM
110 }
111
8a718296
EM
112 function options_form(&$form, &$form_state) {
113 $defaults = $this->default_actions();
d5a58088
EM
114
115 $form['title'] = array(
116 '#prefix' => '<div class="clear-block">',
8a718296 117 '#suffix' => '</div>',
d5a58088
EM
118 '#type' => 'textfield',
119 '#title' => t('Title'),
120 '#default_value' => $this->options['title'],
740306ef 121 '#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.'),
d5a58088 122 );
94437166
EM
123
124 $form['breadcrumb'] = array(
125 '#prefix' => '<div class="clear-block">',
126 '#suffix' => '</div>',
127 '#type' => 'textfield',
128 '#title' => t('Breadcrumb'),
129 '#default_value' => $this->options['breadcrumb'],
130 '#description' => t('The Breadcrumb title to use when this argument is present. If no breadcrumb is setted here, default Title values will be used, see "Title" for percent substitutions.'),
131 );
d5a58088 132
ad67ae57
EM
133 $form['clear_start'] = array(
134 '#value' => '<div class="clear-block">',
135 );
136
d5a58088
EM
137 $form['defaults_start'] = array(
138 '#value' => '<div class="views-left-50">',
139 );
140
141 $form['default_action'] = array(
8a718296
EM
142 '#type' => 'radios',
143 '#title' => t('Action to take if argument is not present'),
8a718296
EM
144 '#default_value' => $this->options['default_action'],
145 );
d5a58088
EM
146
147 $form['defaults_stop'] = array(
148 '#value' => '</div>',
149 );
150
8a718296 151 $form['wildcard'] = array(
ad67ae57 152 '#prefix' => '<div class="views-right-50">',
8a718296
EM
153 // prefix and no suffix means these two items will be grouped together.
154 '#type' => 'textfield',
155 '#title' => t('Wildcard'),
156 '#size' => 20,
157 '#default_value' => $this->options['wildcard'],
158 '#description' => t('If this value is received as an argument, the argument will be ignored; i.e, "all values"'),
159 );
ad67ae57 160
8a718296
EM
161 $form['wildcard_substitution'] = array(
162 '#suffix' => '</div>',
163 '#type' => 'textfield',
164 '#title' => t('Wildcard title'),
165 '#size' => 20,
166 '#default_value' => $this->options['wildcard_substitution'],
167 '#description' => t('The title to use for the wildcard in substitutions elsewhere.'),
168 );
d5a58088 169
ad67ae57
EM
170 $form['clear_stop'] = array(
171 '#value' => '</div>',
172 );
173
d5a58088
EM
174 $options = array();
175 $validate_options = array();
176 foreach ($defaults as $id => $info) {
177 $options[$id] = $info['title'];
178 if (empty($info['default only'])) {
179 $validate_options[$id] = $info['title'];
180 }
181 if (!empty($info['form method'])) {
182 $this->{$info['form method']}($form, $form_state);
183 }
184 }
185
186 $form['default_action']['#options'] = $options;
187
5aa40c4c
EM
188 $form['validate_options_div_prefix'] = array(
189 '#id' => 'views-validator-options',
190 '#value' => '<fieldset id="views-validator-options"><legend>' . t('Validator options') . '</legend>',
191 );
192
d5a58088
EM
193 $form['validate_type'] = array(
194 '#type' => 'select',
195 '#title' => t('Validator'),
196 '#default_value' => $this->options['validate_type'],
8a718296 197 );
d5a58088 198
849cadc1 199 $validate_types = array('none' => t('<Basic validation>'));
d5a58088
EM
200 $plugins = views_fetch_plugin_data('argument validator');
201 foreach ($plugins as $id => $info) {
b2a25279
EM
202 if (!empty($info['no ui'])) {
203 continue;
204 }
205
d5a58088
EM
206 $valid = TRUE;
207 if (!empty($info['type'])) {
208 $valid = FALSE;
209 if (empty($this->definition['validate type'])) {
210 continue;
211 }
212 foreach ((array) $info['type'] as $type) {
213 if ($type == $this->definition['validate type']) {
214 $valid = TRUE;
215 break;
216 }
217 }
218 }
219
220 // If we decide this validator is ok, add it to the list.
221 if ($valid) {
222 $plugin = views_get_plugin('argument validator', $id);
223 if ($plugin) {
224 $plugin->init($this->view, $this, $id);
5aa40c4c 225 if ($plugin->access() || $this->options['validate_type'] == $id) {
d5a58088
EM
226 $plugin->validate_form($form, $form_state, $id);
227 $validate_types[$id] = $info['title'];
228 }
229 }
230 }
231 }
232
849cadc1
EM
233 asort($validate_types);
234 $form['validate_type']['#options'] = $validate_types;
849cadc1
EM
235
236 $form['validate_fail'] = array(
237 '#type' => 'select',
238 '#title' => t('Action to take if argument does not validate'),
239 '#default_value' => $this->options['validate_fail'],
240 '#options' => $validate_options,
241 );
8a73826a
EM
242
243 $form['validate_options_div_suffix'] = array(
244 '#value' => '</fieldset>',
245 );
8a718296
EM
246 }
247
248 /**
249 * Provide a list of default behaviors for this argument if the argument
250 * is not present.
251 *
252 * Override this method to provide additional (or fewer) default behaviors.
253 */
254 function default_actions($which = NULL) {
255 $defaults = array(
256 'ignore' => array(
257 'title' => t('Display all values'),
258 'method' => 'default_ignore',
259 'breadcrumb' => TRUE, // generate a breadcrumb to here
260 ),
261 'not found' => array(
d5a58088 262 'title' => t('Hide view / Page not found (404)'),
8a718296 263 'method' => 'default_not_found',
0c4b06c1 264 'hard fail' => TRUE, // This is a hard fail condition
8a718296
EM
265 ),
266 'empty' => array(
267 'title' => t('Display empty text'),
268 'method' => 'default_empty',
269 'breadcrumb' => TRUE, // generate a breadcrumb to here
270 ),
271 'summary asc' => array(
272 'title' => t('Summary, sorted ascending'),
273 'method' => 'default_summary',
274 'method args' => array('asc'),
275 'style plugin' => TRUE,
276 'breadcrumb' => TRUE, // generate a breadcrumb to here
277 ),
278 'summary desc' => array(
279 'title' => t('Summary, sorted descending'),
280 'method' => 'default_summary',
281 'method args' => array('desc'),
282 'style plugin' => TRUE,
283 'breadcrumb' => TRUE, // generate a breadcrumb to here
284 ),
d5a58088
EM
285 'default' => array(
286 'title' => t('Provide default argument'),
287 'method' => 'default_default',
288 'form method' => 'default_argument_form',
289 'has default argument' => TRUE,
290 'default only' => TRUE, // this can only be used for missing argument, not validation failure
291 ),
8a718296
EM
292 );
293
294 if ($which) {
295 if (!empty($defaults[$which])) {
296 return $defaults[$which];
297 }
298 }
299 else {
300 return $defaults;
301 }
302 }
303
304 /**
d5a58088
EM
305 * Provide a form for selecting the default argument when the
306 * default action is set to provide default argument.
8a718296 307 */
d5a58088
EM
308 function default_argument_form(&$form, &$form_state) {
309 $plugins = views_fetch_plugin_data('argument default');
310 $options = array();
8a718296 311
8a73826a
EM
312 // This construct uses 'hidden' and not markup because process doesn't
313 // run. It also has an extra div because the dependency wants to hide
314 // the parent in situations like this, so we need a second div to
315 // make this work.
316 $form['default_options_div_prefix'] = array(
317 '#type' => 'hidden',
318 '#id' => 'views-default-options',
319 '#prefix' => '<div><fieldset id="views-default-options"><legend>' . t('Provide default argument options') . '</legend>',
320 '#process' => array('views_process_dependency'),
321 '#dependency' => array('radio:options[default_action]' => array('default')),
322 );
323
d5a58088
EM
324 $form['default_argument_type'] = array(
325 '#prefix' => '<div id="edit-options-default-argument-type-wrapper">',
326 '#suffix' => '</div>',
327 '#type' => 'radios',
328 '#id' => 'edit-options-default-argument-type',
329 '#title' => t('Default argument type'),
330 '#default_value' => $this->options['default_argument_type'],
331 '#process' => array('expand_radios', 'views_process_dependency'),
332 '#dependency' => array('radio:options[default_action]' => array('default')),
333 );
334
335 foreach ($plugins as $id => $info) {
336 $plugin = views_get_plugin('argument default', $id);
337 if ($plugin) {
338 $plugin->init($this->view, $this, $id);
339
340 if ($plugin->access() || $this->options['default_argument_type'] == $id) {
341 $options[$id] = $info['title'];
342 $plugin->argument_form($form, $form_state);
343 }
344 }
345 }
346
8a73826a
EM
347 $form['default_options_div_suffix'] = array(
348 '#value' => '</fieldset></div>',
349 );
350
d5a58088
EM
351 asort($options);
352 $form['default_argument_type']['#options'] = $options;
8a718296
EM
353 }
354
355 /**
356 * Handle the default action, which means our argument wasn't present.
357 *
358 * Override this method only with extreme care.
359 *
360 * @return
361 * A boolean value; if TRUE, continue building this view. If FALSE,
362 * building the view will be aborted here.
363 */
d5a58088
EM
364 function default_action($info = NULL) {
365 if (!isset($info)) {
366 $info = $this->default_actions($this->options['default_action']);
367 }
368
8a718296
EM
369 if (!$info) {
370 return FALSE;
371 }
372
373 if (!empty($info['method args'])) {
559b2ac7 374 return call_user_func_array(array(&$this, $info['method']), $info['method args']);
8a718296
EM
375 }
376 else {
377 return $this->{$info['method']}();
378 }
379 }
380
381 /**
d5a58088
EM
382 * How to act if validation failes
383 */
384 function validate_fail() {
385 $info = $this->default_actions($this->options['validate_fail']);
386 return $this->default_action($info);
387 }
388 /**
8a718296
EM
389 * Default action: ignore.
390 *
391 * If an argument was expected and was not given, in this case, simply
392 * ignore the argument entirely.
393 */
394 function default_ignore() {
395 return TRUE;
396 }
397
398 /**
399 * Default action: not found.
400 *
401 * If an argument was expected and was not given, in this case, report
402 * the view as 'not found' or hide it.
403 */
404 function default_not_found() {
405 // Set a failure condition and let the display manager handle it.
406 $this->view->build_info['fail'] = TRUE;
407 return FALSE;
408 }
409
410 /**
411 * Default action: empty
412 *
413 * If an argument was expected and was not given, in this case, display
414 * the view's empty text
415 */
416 function default_empty() {
417 // We return with no query; this will force the empty text.
418 $this->view->built = TRUE;
419 $this->view->executed = TRUE;
420 $this->view->result = array();
421 return FALSE;
422 }
423
424 /**
d5a58088
EM
425 * This just returns true. The view argument builder will know where
426 * to find the argument from.
427 */
428 function default_default() {
429 return TRUE;
430 }
431
432 /**
7e01ce12 433 * Determine if the argument is set to provide a default argument.
d5a58088 434 */
7e01ce12 435 function has_default_argument() {
d5a58088 436 $info = $this->default_actions($this->options['default_action']);
7e01ce12
EM
437 return !empty($info['has default argument']);
438 }
d5a58088 439
7e01ce12
EM
440 /**
441 * Get a default argument, if available.
442 */
443 function get_default_argument() {
d5a58088
EM
444 $plugin = views_get_plugin('argument default', $this->options['default_argument_type']);
445 if ($plugin) {
446 $plugin->init($this->view, $this);
447 return $plugin->get_argument();
448 }
449 }
450
451 /**
8a718296
EM
452 * Default action: summary.
453 *
454 * If an argument was expected and was not given, in this case, display
455 * a summary query.
456 */
457 function default_summary($order) {
458 $this->view->build_info['summary'] = TRUE;
459 $this->view->build_info['summary_level'] = $this->options['id'];
460
461 // Change the display style to the summary style for this
462 // argument.
43d5b2d9 463 $this->view->plugin_name = $this->options['style_plugin'];
8a718296
EM
464 $this->view->style_options = $this->options['style_options'];
465
466 // Clear out the normal primary field and whatever else may have
467 // been added and let the summary do the work.
468 $this->query->clear_fields();
469 $this->summary_query();
470
471 $this->summary_sort($order);
472
473 // Summaries have their own sorting and fields, so tell the View not
474 // to build these.
475 $this->view->build_sort = $this->view->build_fields = FALSE;
476 return TRUE;
477 }
478
479 /**
480 * Build the info for the summary query.
481 *
482 * This must:
483 * - add_groupby: group on this field in order to create summaries.
484 * - add_field: add a 'num_nodes' field for the count. Usually it will
ee23afa2 485 * be a count on $view->base_field
8a718296
EM
486 * - set_count_field: Reset the count field so we get the right paging.
487 *
488 * @return
489 * The alias used to get the number of records (count) for this entry.
490 */
491 function summary_query() {
492 $this->ensure_my_table();
493 // Add the field.
494 $this->base_alias = $this->query->add_field($this->table_alias, $this->real_field);
495
ca78ec49
EM
496 $this->summary_name_field();
497 return $this->summary_basics();
498 }
499
500 /**
501 * Add the name field, which is the field displayed in summary queries.
502 * This is often used when the argument is numeric.
503 */
504 function summary_name_field() {
8a718296
EM
505 // Add the 'name' field. For example, if this is a uid argument, the
506 // name field would be 'name' (i.e, the username).
ca78ec49
EM
507
508 if (isset($this->name_table)) {
509 // if the alias is different then we're probably added, not ensured,
510 // so look up the join and add it instead.
511 if ($this->table_alias != $this->table) {
512 $j = views_get_table_join($this->name_table, $this->table);
513 if ($j) {
514 $join = drupal_clone($j);
515 $join->left_table = $this->table_alias;
516 $this->name_table_alias = $this->query->add_table($this->name_table, $this->relationship, $join);
517 }
518 }
519 else {
ab9804a8 520 $this->name_table_alias = $this->query->ensure_table($this->name_table, $this->relationship);
ca78ec49
EM
521 }
522 }
523 else {
524 $this->name_table_alias = $this->table_alias;
525 }
526
8a718296 527 if (isset($this->name_field)) {
ca78ec49 528 $this->name_alias = $this->query->add_field($this->name_table_alias, $this->name_field);
8a718296
EM
529 }
530 else {
531 $this->name_alias = $this->base_alias;
532 }
8a718296
EM
533 }
534
535 /**
536 * Some basic summary behavior that doesn't need to be repeated as much as
537 * code that goes into summary_query()
538 */
539 function summary_basics($count_field = TRUE) {
540 // Add the number of nodes counter
2ca76814 541 $field = $this->query->base_table . '.' . $this->query->base_field;
05f93122 542 $distinct = ($this->view->display_handler->get_option('distinct') && empty($this->query->no_distinct));
2ca76814 543
05f93122
EM
544 $count_alias = $this->query->add_field(NULL, $field, 'num_records',
545 array('count' => TRUE, 'distinct' => $distinct));
ca78ec49 546 $this->query->add_groupby($this->name_alias);
8a718296
EM
547
548 if ($count_field) {
549 $this->query->set_count_field($this->table_alias, $this->real_field);
550 }
551
552 $this->count_alias = $count_alias;
553 }
554
555 /**
556 * Sorts the summary based upon the user's selection. The base variant of
557 * this is usually adequte.
558 *
559 * @param $order
560 * The order selected in the UI.
561 */
562 function summary_sort($order) {
ca78ec49 563 $this->query->add_orderby(NULL, NULL, $order, $this->name_alias);
8a718296
EM
564 }
565
566 /**
4d6c659c
EM
567 * Provide the argument to use to link from the summary to the next level;
568 * this will be called once per row of a summary, and used as part of
569 * $view->get_url().
8a718296
EM
570 *
571 * @param $data
572 * The query results for the row.
8a718296 573 */
4d6c659c
EM
574 function summary_argument($data) {
575 return $data->{$this->base_alias};
8a718296
EM
576 }
577
578 /**
579 * Provides the name to use for the summary. By default this is just
580 * the name field.
581 *
582 * @param $data
583 * The query results for the row.
584 */
585 function summary_name($data) {
ca78ec49 586 $value = $data->{$this->name_alias};
b2b1dd2a
EM
587 if (empty($value) && !empty($this->definition['empty field name'])) {
588 $value = $this->definition['empty field name'];
ca78ec49
EM
589 }
590 return check_plain($value);
8a718296
EM
591 }
592
593 /**
594 * Set up the query for this argument.
595 *
596 * The argument sent may be found at $this->argument.
597 */
598 function query() {
599 $this->ensure_my_table();
d5a58088
EM
600 $placeholder = empty($this->definition['numeric']) ? "'%s'" : '%d';
601 $this->query->add_where(0, "$this->table_alias.$this->real_field = $placeholder", $this->argument);
8a718296
EM
602 }
603
604 /**
605 * Get the title this argument will assign the view, given the argument.
606 *
607 * This usually needs to be overridden to provide a proper title.
608 */
609 function title() {
610 return check_plain($this->argument);
611 }
612
613 /**
d5a58088
EM
614 * Called by the view object to get the title. This may be set by a
615 * validator so we don't necessarily call through to title().
616 */
617 function get_title() {
618 if (isset($this->validated_title)) {
619 return $this->validated_title;
620 }
621 else {
622 return $this->title();
623 }
624 }
625
626 /**
8a718296
EM
627 * Validate that this argument works. By default, all arguments are valid.
628 */
0c4b06c1 629 function validate_arg($arg) {
d5a58088
EM
630 // By using % in URLs, arguments could be validated twice; this eases
631 // that pain.
632 if (isset($this->argument_validated)) {
633 return $this->argument_validated;
634 }
635
a45277c1
EM
636 if ($this->is_wildcard($arg)) {
637 return $this->argument_validated = TRUE;
638 }
639
d5a58088 640 if ($this->options['validate_type'] == 'none') {
7e9c7701 641 return $this->argument_validated = $this->validate_argument_basic($arg);
d5a58088
EM
642 }
643
644 $plugin = views_get_plugin('argument validator', $this->options['validate_type']);
645 if ($plugin) {
646 $plugin->init($this->view, $this, $this->options['validate_type']);
7e9c7701 647 return $this->argument_validated = $plugin->validate_argument($arg);
d5a58088
EM
648 }
649
849cadc1 650 // If the plugin isn't found, fall back to the basic validation path:
7e9c7701 651 return $this->argument_validated = $this->validate_argument_basic($arg);
849cadc1
EM
652 }
653
654 /**
0c4b06c1
EM
655 * Called by the menu system to validate an argument.
656 *
657 * This checks to see if this is a 'soft fail', which means that if the
658 * argument fails to validate, but there is an action to take anyway,
659 * then validation cannot actually fail.
660 */
661 function validate_argument($arg) {
662 $validate_info = $this->default_actions($this->options['validate_fail']);
663 if (empty($validate_info['hard fail'])) {
664 return TRUE;
665 }
666
2d54b7d7
EM
667 $rc = $this->validate_arg($arg);
668
669 // If the validator has changed the validate fail condition to a
670 // soft fail, deal with that:
671 $validate_info = $this->default_actions($this->options['validate_fail']);
672 if (empty($validate_info['hard fail'])) {
673 return TRUE;
674 }
675
676 return $rc;
0c4b06c1
EM
677 }
678
679 /**
849cadc1
EM
680 * Provide a basic argument validation.
681 *
682 * This can be overridden for more complex types; the basic
683 * validator only checks to see if the argument is not NULL
684 * or is numeric if the definition says it's numeric.
685 */
686 function validate_argument_basic($arg) {
687 if (!isset($arg) || $arg === '') {
688 return FALSE;
689 }
690
83b400cf 691 if (isset($this->definition['numeric']) && !isset($this->options['break_phrase']) && !is_numeric($arg)) {
849cadc1
EM
692 return FALSE;
693 }
694
695 return TRUE;
d5a58088
EM
696 }
697
698 /**
699 * Set the input for this argument
700 *
701 * @return TRUE if it successfully validates; FALSE if it does not.
702 */
703 function set_argument($arg) {
704 $this->argument = $arg;
0c4b06c1 705 return $this->validate_arg($arg);
8a718296 706 }
a8fc8590
EM
707
708 /**
709 * Get the value of this argument.
710 */
711 function get_value() {
712 // If we already processed this argument, we're done.
713 if (isset($this->argument)) {
714 return $this->argument;
715 }
716
717 // Otherwise, we have to pretend to process ourself to find the value.
718 $value = NULL;
719 // Find the position of this argument within the view.
720 $position = 0;
721 foreach ($this->view->argument as $id => $argument) {
722 if ($id == $this->options['id']) {
723 break;
724 }
725 $position++;
726 }
727
728 $arg = isset($this->view->args[$position]) ? $this->view->args[$position] : NULL;
729 $this->position = $position;
730
731 // Clone ourselves so that we don't break things when we're really
732 // processing the arguments.
733 $argument = drupal_clone($this);
734 if (!isset($arg) && $argument->has_default_argument()) {
735 $arg = $argument->get_default_argument();
736 }
737 // Set the argument, which will also validate that the argument can be set.
738 if ($argument->set_argument($arg)) {
739 $value = $argument->argument;
740 }
741 unset($argument);
742 return $value;
743 }
8a718296
EM
744}
745
746/**
11d03592 747 * A special handler to take the place of missing or broken handlers.
fe44beb7
EM
748 *
749 * @ingroup views_argument_handlers
11d03592
EM
750 */
751class views_handler_argument_broken extends views_handler_argument {
114e317f 752 function ui_name($short = FALSE) {
11d03592
EM
753 return t('Broken/missing handler');
754 }
755
756 function ensure_my_table() { /* No table to ensure! */ }
757 function query() { /* No query to run */ }
758 function options_form(&$form, &$form_state) {
759 $form['markup'] = array(
760 '#prefix' => '<div class="form-item description">',
761 '#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.'),
762 );
763 }
764
765 /**
766 * Determine if the handler is considered 'broken'
767 */
768 function broken() { return TRUE; }
769}
770
771/**
8a718296
EM
772 * @}
773 */