You are here

class views_handler_argument in Views (for Drupal 7) 7.3

Same name and namespace in other branches
  1. 6.3 handlers/views_handler_argument.inc \views_handler_argument
  2. 6.2 handlers/views_handler_argument.inc \views_handler_argument

Base class for arguments.

The basic argument works for very simple arguments such as nid and uid.

Definition terms for this handler:

  • name field: The field to use for the name to use in the summary, which is the displayed output. For example, for the node: nid argument, the argument itself is the nid, but node.title is displayed.
  • name table: The table to use for the name, should it not be in the same table as the argument.
  • empty field name: For arguments that can have no value, such as taxonomy which can have "no term", this is the string which will be displayed for this lack of value. Be sure to use t().
  • validate type: A little used string to allow an argument to restrict which validator is available to just one. Use the validator ID. This probably should not be used at all, and may disappear or change.
  • numeric: If set to TRUE this field is numeric and will use %d instead of %s in queries.

Hierarchy

Expanded class hierarchy of views_handler_argument

Related topics

3 string references to 'views_handler_argument'
book_views_data in modules/book.views.inc
Implements hook_views_data().
comment_views_data in modules/comment.views.inc
Implements hook_views_data().
search_views_plugins in modules/search.views.inc
Implements hook_views_plugins().

File

handlers/views_handler_argument.inc, line 36
Definition of views_handler_argument.

View source
class views_handler_argument extends views_handler {

  /**
   * @var object
   */
  public $validator = NULL;

  /**
   * @var mixed
   */
  public $argument = NULL;

  /**
   * @var mixed
   */
  public $value = NULL;

  /**
   * The table to use for the name, if not the same table as the argument.
   *
   * @var string
   */
  public $name_table;

  /**
   * The field to use for the name to use in the summary.
   *
   * Used as the displayed output. For example, for the node: nid argument, the
   * argument itself is the nid, but node.title is displayed.
   *
   * @var string
   */
  public $name_field;

  /**
   * {@inheritdoc}
   */
  public function construct() {
    parent::construct();
    if (!empty($this->definition['name field'])) {
      $this->name_field = $this->definition['name field'];
    }
    if (!empty($this->definition['name table'])) {
      $this->name_table = $this->definition['name table'];
    }
  }

  /**
   * {@inheritdoc}
   */
  public function init(&$view, &$options) {
    parent::init($view, $options);

    // Compatibility: The new UI changed several settings.
    if (!empty($options['wildcard']) && !isset($options['exception']['value'])) {
      $this->options['exception']['value'] = $options['wildcard'];
    }
    if (!empty($options['wildcard_substitution']) && !isset($options['exception']['title'])) {

      // Enable the checkbox if the title is filled in.
      $this->options['exception']['title_enable'] = 1;
      $this->options['exception']['title'] = $options['wildcard_substitution'];
    }
    if (!isset($options['summary']['format']) && !empty($options['style_plugin'])) {
      $this->options['summary']['format'] = $options['style_plugin'];
    }

    // Setup default value.
    $options['style_options'] = isset($options['style_options']) ? $options['style_options'] : array();
    if (!isset($options['summary']['sort_order']) && !empty($options['default_action']) && $options['default_action'] == 'summary asc') {
      $this->options['default_action'] = 'summary';
      $this->options['summary']['sort_order'] = 'asc';
      $this->options['summary']['number_of_records'] = 0;
      $this->options['summary_options'] = $options['style_options'];
    }
    elseif (!isset($options['summary']['sort_order']) && !empty($options['default_action']) && $options['default_action'] == 'summary desc') {
      $this->options['default_action'] = 'summary';
      $this->options['summary']['sort_order'] = 'desc';
      $this->options['summary']['number_of_records'] = 0;
      $this->options['summary_options'] = $options['style_options'];
    }
    elseif (!isset($options['summary']['sort_order']) && !empty($options['default_action']) && $options['default_action'] == 'summary asc by count') {
      $this->options['default_action'] = 'summary';
      $this->options['summary']['sort_order'] = 'asc';
      $this->options['summary']['number_of_records'] = 1;
      $this->options['summary_options'] = $options['style_options'];
    }
    elseif (!isset($options['summary']['sort_order']) && !empty($options['default_action']) && $options['default_action'] == 'summary desc by count') {
      $this->options['default_action'] = 'summary';
      $this->options['summary']['sort_order'] = 'desc';
      $this->options['summary']['number_of_records'] = 1;
      $this->options['summary_options'] = $options['style_options'];
    }
    if (!empty($options['title']) && !isset($options['title_enable'])) {
      $this->options['title_enable'] = 1;
    }
    if (!empty($options['breadcrumb']) && !isset($options['breadcrumb_enable'])) {
      $this->options['breadcrumb_enable'] = 1;
    }
    if (!empty($options['validate_type']) && !isset($options['validate']['type'])) {
      $this->options['validate']['type'] = $options['validate_type'];
      $this->options['specify_validation'] = 1;
    }
    if (!empty($options['validate_fail']) && !isset($options['validate']['fail'])) {
      $this->options['validate']['fail'] = $options['validate_fail'];
      $this->options['specify_validation'] = 1;
    }
  }

  /**
   * Give an argument the opportunity to modify the breadcrumb, if it wants.
   *
   * Only gets called on displays where a breadcrumb is actually used.
   *
   * The breadcrumb will be in the form of an array, with the keys being
   * the path and the value being the already sanitized title of the path.
   */
  public function set_breadcrumb(&$breadcrumb) {
  }

  /**
   * Determine if the argument can generate a breadcrumb.
   *
   * @return bool
   *   Indicates whether the argument can generate a breadcrumb.
   */
  public function uses_breadcrumb() {
    $info = $this
      ->default_actions($this->options['default_action']);
    return !empty($info['breadcrumb']);
  }

  /**
   * {@inheritdoc}
   */
  public function is_exception($arg = NULL) {
    if (!isset($arg)) {
      $arg = isset($this->argument) ? $this->argument : NULL;
    }
    return !empty($this->options['exception']['value']) && $this->options['exception']['value'] === $arg;
  }

  /**
   * Work out which title to use.
   *
   * @return string
   *   The title string to use.
   */
  public function exception_title() {

    // If title overriding is off for the exception, return the normal title.
    if (empty($this->options['exception']['title_enable'])) {
      return $this
        ->get_title();
    }
    return $this->options['exception']['title'];
  }

  /**
   * Determine if the argument needs a style plugin.
   *
   * @return bool
   *   the argument needs a plugin style.
   */
  public function needs_style_plugin() {
    $info = $this
      ->default_actions($this->options['default_action']);
    $validate_info = $this
      ->default_actions($this->options['validate']['fail']);
    return !empty($info['style plugin']) || !empty($validate_info['style plugin']);
  }

  /**
   * {@inheritdoc}
   */
  public function option_definition() {
    $options = parent::option_definition();
    $options['default_action'] = array(
      'default' => 'ignore',
    );
    $options['exception'] = array(
      'contains' => array(
        'value' => array(
          'default' => 'all',
        ),
        'title_enable' => array(
          'default' => FALSE,
          'bool' => TRUE,
        ),
        'title' => array(
          'default' => 'All',
          'translatable' => TRUE,
        ),
      ),
    );
    $options['title_enable'] = array(
      'default' => FALSE,
      'bool' => TRUE,
    );
    $options['title'] = array(
      'default' => '',
      'translatable' => TRUE,
    );
    $options['breadcrumb_enable'] = array(
      'default' => FALSE,
      'bool' => TRUE,
    );
    $options['breadcrumb'] = array(
      'default' => '',
      'translatable' => TRUE,
    );
    $options['default_argument_type'] = array(
      'default' => 'fixed',
      'export' => 'export_plugin',
    );
    $options['default_argument_options'] = array(
      'default' => array(),
      'export' => FALSE,
    );
    $options['default_argument_skip_url'] = array(
      'default' => FALSE,
      'bool' => TRUE,
    );
    $options['summary_options'] = array(
      'default' => array(),
      'export' => FALSE,
    );
    $options['summary'] = array(
      'contains' => array(
        'sort_order' => array(
          'default' => 'asc',
        ),
        'number_of_records' => array(
          'default' => 0,
        ),
        'format' => array(
          'default' => 'default_summary',
          'export' => 'export_summary',
        ),
      ),
    );
    $options['specify_validation'] = array(
      'default' => FALSE,
      'bool' => TRUE,
    );
    $options['validate'] = array(
      'contains' => array(
        'type' => array(
          'default' => 'none',
          'export' => 'export_validation',
        ),
        'fail' => array(
          'default' => 'not found',
        ),
      ),
    );
    $options['validate_options'] = array(
      'default' => array(),
      'export' => FALSE,
    );
    return $options;
  }

  /**
   * {@inheritdoc}
   */
  public function options_form(&$form, &$form_state) {
    parent::options_form($form, $form_state);
    $argument_text = $this->view->display_handler
      ->get_argument_text();
    $form['#pre_render'][] = 'views_ui_pre_render_move_argument_options';
    $form['description'] = array(
      '#markup' => $argument_text['description'],
      '#theme_wrappers' => array(
        'container',
      ),
      '#attributes' => array(
        'class' => array(
          'description',
        ),
      ),
    );
    $form['no_argument'] = array(
      '#type' => 'fieldset',
      '#title' => $argument_text['filter value not present'],
    );

    // Everything in the fieldset is floated, so the last element needs to
    // clear those floats.
    $form['no_argument']['clearfix'] = array(
      '#weight' => 1000,
      '#markup' => '<div class="clearfix"></div>',
    );
    $form['default_action'] = array(
      '#type' => 'radios',
      '#process' => array(
        'views_ui_process_container_radios',
      ),
      '#default_value' => $this->options['default_action'],
      '#fieldset' => 'no_argument',
    );
    $form['exception'] = array(
      '#type' => 'fieldset',
      '#title' => t('Exceptions'),
      '#collapsible' => TRUE,
      '#collapsed' => TRUE,
      '#fieldset' => 'no_argument',
    );
    $form['exception']['value'] = array(
      '#type' => 'textfield',
      '#title' => t('Exception value'),
      '#size' => 20,
      '#default_value' => $this->options['exception']['value'],
      '#description' => t('If this value is received, the filter will be ignored; i.e, "all values"'),
    );
    $form['exception']['title_enable'] = array(
      '#type' => 'checkbox',
      '#title' => t('Override title'),
      '#default_value' => $this->options['exception']['title_enable'],
    );
    $form['exception']['title'] = array(
      '#type' => 'textfield',
      '#title' => t('Override title'),
      '#title_display' => 'invisible',
      '#size' => 20,
      '#default_value' => $this->options['exception']['title'],
      '#description' => t('Override the view and other argument titles. Use "%1" for the first argument, "%2" for the second, etc.'),
      '#dependency' => array(
        'edit-options-exception-title-enable' => array(
          '1',
        ),
      ),
    );
    $options = array();
    $defaults = $this
      ->default_actions();
    $validate_options = array();
    foreach ($defaults as $id => $info) {
      $options[$id] = $info['title'];
      if (empty($info['default only'])) {
        $validate_options[$id] = $info['title'];
      }
      if (!empty($info['form method'])) {
        $this
          ->{$info['form method']}($form, $form_state);
      }
    }
    $form['default_action']['#options'] = $options;
    $form['argument_present'] = array(
      '#type' => 'fieldset',
      '#title' => $argument_text['filter value present'],
    );
    $form['title_enable'] = array(
      '#type' => 'checkbox',
      '#title' => t('Override title'),
      '#default_value' => $this->options['title_enable'],
      '#fieldset' => 'argument_present',
    );
    $form['title'] = array(
      '#type' => 'textfield',
      '#title' => t('Provide title'),
      '#title_display' => 'invisible',
      '#default_value' => $this->options['title'],
      '#description' => t('Override the view and other argument titles. Use "%1" for the first argument, "%2" for the second, etc.'),
      '#dependency' => array(
        'edit-options-title-enable' => array(
          '1',
        ),
      ),
      '#fieldset' => 'argument_present',
    );
    $form['breadcrumb_enable'] = array(
      '#type' => 'checkbox',
      '#title' => t('Override breadcrumb'),
      '#default_value' => $this->options['breadcrumb_enable'],
      '#fieldset' => 'argument_present',
    );
    $form['breadcrumb'] = array(
      '#type' => 'textfield',
      '#title' => t('Provide breadcrumb'),
      '#title_display' => 'invisible',
      '#default_value' => $this->options['breadcrumb'],
      '#description' => t('Enter a breadcrumb name you would like to use. See "Title" for percent substitutions.'),
      '#dependency' => array(
        'edit-options-breadcrumb-enable' => array(
          '1',
        ),
      ),
      '#fieldset' => 'argument_present',
    );
    $form['specify_validation'] = array(
      '#type' => 'checkbox',
      '#title' => t('Specify validation criteria'),
      '#default_value' => $this->options['specify_validation'],
      '#fieldset' => 'argument_present',
    );
    $form['validate'] = array(
      '#type' => 'container',
      '#fieldset' => 'argument_present',
    );

    // @todo The mockup wanted to use "Validate using" here, but it doesn't
    // work well with many options (they'd need to be changed as well)
    $form['validate']['type'] = array(
      '#type' => 'select',
      '#title' => t('Validator'),
      '#default_value' => $this->options['validate']['type'],
      '#dependency' => array(
        'edit-options-specify-validation' => array(
          '1',
        ),
      ),
    );
    $validate_types = array(
      'none' => t('- Basic validation -'),
    );
    $plugins = views_fetch_plugin_data('argument validator');
    foreach ($plugins as $id => $info) {
      if (!empty($info['no ui'])) {
        continue;
      }
      $valid = TRUE;
      if (!empty($info['type'])) {
        $valid = FALSE;
        if (empty($this->definition['validate type'])) {
          continue;
        }
        foreach ((array) $info['type'] as $type) {
          if ($type == $this->definition['validate type']) {
            $valid = TRUE;
            break;
          }
        }
      }

      // If we decide this validator is ok, add it to the list.
      if ($valid) {
        $plugin = $this
          ->get_plugin('argument validator', $id);
        if ($plugin) {
          if ($plugin
            ->access() || $this->options['validate']['type'] == $id) {
            $form['validate']['options'][$id] = array(
              '#prefix' => '<div id="edit-options-validate-options-' . $id . '-wrapper">',
              '#suffix' => '</div>',
              '#type' => 'item',
              // Even if the plugin has no options, add the key to the
              // form_state. Trick it into checking input to make #process run.
              '#input' => TRUE,
              '#dependency' => array(
                'edit-options-specify-validation' => array(
                  '1',
                ),
                'edit-options-validate-type' => array(
                  $id,
                ),
              ),
              '#dependency_count' => 2,
              '#id' => 'edit-options-validate-options-' . $id,
            );
            $plugin
              ->options_form($form['validate']['options'][$id], $form_state);
            $validate_types[$id] = $info['title'];
          }
        }
      }
    }
    asort($validate_types);
    $form['validate']['type']['#options'] = $validate_types;
    $form['validate']['fail'] = array(
      '#type' => 'select',
      '#title' => t('Action to take if filter value does not validate'),
      '#default_value' => $this->options['validate']['fail'],
      '#options' => $validate_options,
      '#dependency' => array(
        'edit-options-specify-validation' => array(
          '1',
        ),
      ),
      '#fieldset' => 'argument_present',
    );
  }

  /**
   * {@inheritdoc}
   */
  public function options_validate(&$form, &$form_state) {
    if (empty($form_state['values']['options'])) {
      return;
    }

    // Let the plugins do validation.
    $default_id = $form_state['values']['options']['default_argument_type'];
    $plugin = $this
      ->get_plugin('argument default', $default_id);
    if ($plugin && isset($form['argument_default'][$default_id]) && isset($form_state['values']['options']['argument_default'][$default_id])) {
      $plugin
        ->options_validate($form['argument_default'][$default_id], $form_state, $form_state['values']['options']['argument_default'][$default_id]);
    }

    // Validate summary plugin options if one is present.
    if (isset($form_state['values']['options']['summary']['format'])) {
      $summary_id = $form_state['values']['options']['summary']['format'];
      $plugin = $this
        ->get_plugin('style', $summary_id);
      if ($plugin) {
        $plugin
          ->options_validate($form['summary']['options'][$summary_id], $form_state, $form_state['values']['options']['summary']['options'][$summary_id]);
      }
    }
    $validate_id = $form_state['values']['options']['validate']['type'];
    $plugin = $this
      ->get_plugin('argument validator', $validate_id);
    if ($plugin) {
      $plugin
        ->options_validate($form['validate']['options'][$default_id], $form_state, $form_state['values']['options']['validate']['options'][$validate_id]);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function options_submit(&$form, &$form_state) {
    if (empty($form_state['values']['options'])) {
      return;
    }

    // Let the plugins make submit modifications if necessary.
    $default_id = $form_state['values']['options']['default_argument_type'];
    $plugin = $this
      ->get_plugin('argument default', $default_id);
    if ($plugin) {
      $options =& $form_state['values']['options']['argument_default'][$default_id];
      $plugin
        ->options_submit($form['argument_default'][$default_id], $form_state, $options);

      // Copy the now submitted options to their final resting place so they
      // get saved.
      $form_state['values']['options']['default_argument_options'] = $options;
    }

    // Handle summary plugin options if one is present.
    if (isset($form_state['values']['options']['summary']['format'])) {
      $summary_id = $form_state['values']['options']['summary']['format'];
      $plugin = $this
        ->get_plugin('style', $summary_id);
      if ($plugin) {
        $options =& $form_state['values']['options']['summary']['options'][$summary_id];
        $plugin
          ->options_submit($form['summary']['options'][$summary_id], $form_state, $options);

        // Copy the now submitted options to their final resting place so they
        // get saved.
        $form_state['values']['options']['summary_options'] = $options;
      }
    }
    $validate_id = $form_state['values']['options']['validate']['type'];
    $plugin = $this
      ->get_plugin('argument validator', $validate_id);
    if ($plugin) {
      $options =& $form_state['values']['options']['validate']['options'][$validate_id];
      $plugin
        ->options_submit($form['validate']['options'][$validate_id], $form_state, $options);

      // Copy the now submitted options to their final resting place so they
      // get saved.
      $form_state['values']['options']['validate_options'] = $options;
    }

    // Clear out the content of title if it's not enabled.
    $options =& $form_state['values']['options'];
    if (empty($options['title_enable'])) {
      $options['title'] = '';
    }
  }

  /**
   * List of default behaviors for this argument if the argument is not present.
   *
   * Override this method to provide additional (or fewer) default behaviors.
   */
  public function default_actions($which = NULL) {
    $defaults = array(
      'ignore' => array(
        'title' => t('Display all results for the specified field'),
        'method' => 'default_ignore',
        // Generate a breadcrumb to here.
        'breadcrumb' => TRUE,
      ),
      'default' => array(
        'title' => t('Provide default value'),
        'method' => 'default_default',
        'form method' => 'default_argument_form',
        'has default argument' => TRUE,
        // This can only be used for missing argument, not validation failure.
        'default only' => TRUE,
        // Generate a breadcrumb to here.
        'breadcrumb' => TRUE,
      ),
      'not found' => array(
        'title' => t('Hide view'),
        'method' => 'default_not_found',
        // This is a hard fail condition.
        'hard fail' => TRUE,
      ),
      'summary' => array(
        'title' => t('Display a summary'),
        'method' => 'default_summary',
        'form method' => 'default_summary_form',
        'style plugin' => TRUE,
        // Generate a breadcrumb to here.
        'breadcrumb' => TRUE,
      ),
      'empty' => array(
        'title' => t('Display contents of "No results found"'),
        'method' => 'default_empty',
        // Generate a breadcrumb to here.
        'breadcrumb' => TRUE,
      ),
      'access denied' => array(
        'title' => t('Display "Access Denied"'),
        'method' => 'default_access_denied',
        // Generate a breadcrumb to here.
        'breadcrumb' => FALSE,
      ),
    );
    if ($this->view->display_handler
      ->has_path()) {
      $defaults['not found']['title'] = t('Show "Page not found"');
    }
    if ($which) {
      if (!empty($defaults[$which])) {
        return $defaults[$which];
      }
    }
    else {
      return $defaults;
    }
  }

  /**
   * Provide a form for selecting the default argument.
   *
   * Used when the default action is set to provide default argument.
   */
  public function default_argument_form(&$form, &$form_state) {
    $plugins = views_fetch_plugin_data('argument default');
    $options = array();
    $form['default_argument_skip_url'] = array(
      '#type' => 'checkbox',
      '#title' => t('Skip default argument for view URL'),
      '#default_value' => $this->options['default_argument_skip_url'],
      '#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.'),
    );
    $form['default_argument_type'] = array(
      '#prefix' => '<div id="edit-options-default-argument-type-wrapper">',
      '#suffix' => '</div>',
      '#type' => 'select',
      '#id' => 'edit-options-default-argument-type',
      '#title' => t('Type'),
      '#default_value' => $this->options['default_argument_type'],
      '#dependency' => array(
        'radio:options[default_action]' => array(
          'default',
        ),
      ),
      // Views custom key, moves this element to the appropriate container
      // under the radio button.
      '#argument_option' => 'default',
    );
    foreach ($plugins as $id => $info) {
      if (!empty($info['no ui'])) {
        continue;
      }
      $plugin = $this
        ->get_plugin('argument default', $id);
      if ($plugin) {
        if ($plugin
          ->access() || $this->options['default_argument_type'] == $id) {
          $form['argument_default']['#argument_option'] = 'default';
          $form['argument_default'][$id] = array(
            '#prefix' => '<div id="edit-options-argument-default-options-' . $id . '-wrapper">',
            '#suffix' => '</div>',
            '#id' => 'edit-options-argument-default-options-' . $id,
            '#type' => 'item',
            // Even if the plugin has no options add the key to the form_state.
            '#input' => TRUE,
            '#dependency' => array(
              'radio:options[default_action]' => array(
                'default',
              ),
              'edit-options-default-argument-type' => array(
                $id,
              ),
            ),
            '#dependency_count' => 2,
          );
          $options[$id] = $info['title'];
          $plugin
            ->options_form($form['argument_default'][$id], $form_state);
        }
      }
    }
    asort($options);
    $form['default_argument_type']['#options'] = $options;
  }

  /**
   * Form for selecting further summary options.
   *
   * Only used when the default action is set to display one.
   */
  public function default_summary_form(&$form, &$form_state) {
    $style_plugins = views_fetch_plugin_data('style');
    $summary_plugins = array();
    $format_options = array();
    foreach ($style_plugins as $key => $plugin) {
      if (isset($plugin['type']) && $plugin['type'] == 'summary') {
        $summary_plugins[$key] = $plugin;
        $format_options[$key] = $plugin['title'];
      }
    }
    $form['summary'] = array(
      // Views custom key, moves this element to the appropriate container
      // under the radio button.
      '#argument_option' => 'summary',
    );
    $form['summary']['sort_order'] = array(
      '#type' => 'radios',
      '#title' => t('Sort order'),
      '#options' => array(
        'asc' => t('Ascending'),
        'desc' => t('Descending'),
      ),
      '#default_value' => $this->options['summary']['sort_order'],
      '#dependency' => array(
        'radio:options[default_action]' => array(
          'summary',
        ),
      ),
    );
    $form['summary']['number_of_records'] = array(
      '#type' => 'radios',
      '#title' => t('Sort by'),
      '#default_value' => $this->options['summary']['number_of_records'],
      '#options' => array(
        0 => $this
          ->get_sort_name(),
        1 => t('Number of records'),
      ),
      '#dependency' => array(
        'radio:options[default_action]' => array(
          'summary',
        ),
      ),
    );
    $form['summary']['format'] = array(
      '#type' => 'radios',
      '#title' => t('Format'),
      '#options' => $format_options,
      '#default_value' => $this->options['summary']['format'],
      '#dependency' => array(
        'radio:options[default_action]' => array(
          'summary',
        ),
      ),
    );
    foreach ($summary_plugins as $id => $info) {
      if (empty($info['uses options'])) {
        continue;
      }
      $plugin = $this
        ->get_plugin('style', $id);
      if ($plugin) {
        $form['summary']['options'][$id] = array(
          '#prefix' => '<div id="edit-options-summary-options-' . $id . '-wrapper">',
          '#suffix' => '</div>',
          '#id' => 'edit-options-summary-options-' . $id,
          '#type' => 'item',
          // Trick it into checking input to make #process run.
          '#input' => TRUE,
          '#dependency' => array(
            'radio:options[default_action]' => array(
              'summary',
            ),
            'radio:options[summary][format]' => array(
              $id,
            ),
          ),
          '#dependency_count' => 2,
        );
        $options[$id] = $info['title'];
        $plugin
          ->options_form($form['summary']['options'][$id], $form_state);
      }
    }
  }

  /**
   * Handle the default action, which means our argument wasn't present.
   *
   * Override this method only with extreme care.
   *
   * @return bool
   *   A boolean value; if TRUE, continue building this view. If FALSE,
   *   building the view will be aborted here.
   */
  public function default_action($info = NULL) {
    if (!isset($info)) {
      $info = $this
        ->default_actions($this->options['default_action']);
    }
    if (!$info) {
      return FALSE;
    }
    if (!empty($info['method args'])) {
      return call_user_func_array(array(
        &$this,
        $info['method'],
      ), $info['method args']);
    }
    else {
      return $this
        ->{$info['method']}();
    }
  }

  /**
   * How to act if validation fails.
   */
  public function validate_fail() {
    $info = $this
      ->default_actions($this->options['validate']['fail']);
    return $this
      ->default_action($info);
  }

  /**
   * Default action: ignore.
   *
   * If an argument was expected and was not given, in this case, simply ignore
   * the argument entirely.
   */
  public function default_ignore() {
    return TRUE;
  }

  /**
   * Default action: not found.
   *
   * If an argument was expected and was not given, in this case, report the
   * view as 'not found' or hide it.
   */
  public function default_not_found() {

    // Set a failure condition and let the display manager handle it.
    $this->view->build_info['fail'] = TRUE;
    return FALSE;
  }

  /**
   * Default action: access denied.
   *
   * If an argument was expected and was not given, in this case, report the
   * view as 'access denied'.
   */
  public function default_access_denied() {
    $this->view->build_info['denied'] = TRUE;
    return FALSE;
  }

  /**
   * Default action: empty.
   *
   * If an argument was expected and was not given, in this case, display the
   * view's empty text.
   */
  public function default_empty() {

    // We return with no query; this will force the empty text.
    $this->view->built = TRUE;
    $this->view->executed = TRUE;
    $this->view->result = array();
    return FALSE;
  }

  /**
   * This just returns true.
   *
   * The view argument builder will know where to find the argument from.
   *
   * @todo Why is this needed?
   */
  public function default_default() {
    return TRUE;
  }

  /**
   * Determine if the argument is set to provide a default argument.
   */
  public function has_default_argument() {
    $info = $this
      ->default_actions($this->options['default_action']);
    return !empty($info['has default argument']);
  }

  /**
   * Get a default argument, if available.
   */
  public function get_default_argument() {
    $plugin = $this
      ->get_plugin('argument default');
    if ($plugin) {
      return $plugin
        ->get_argument();
    }
  }

  /**
   * Process the summary arguments for display.
   *
   * For example, the validation plugin may want to alter an argument for use in
   * the URL.
   */
  public function process_summary_arguments(&$args) {
    if ($this->options['validate']['type'] != 'none') {
      if (isset($this->validator) || ($this->validator = $this
        ->get_plugin('argument validator'))) {
        $this->validator
          ->process_summary_arguments($args);
      }
    }
  }

  /**
   * Default action: summary.
   *
   * If an argument was expected and was not given, in this case, display a
   * summary query.
   */
  public function default_summary() {
    $this->view->build_info['summary'] = TRUE;
    $this->view->build_info['summary_level'] = $this->options['id'];

    // Change the display style to the summary style for this argument.
    $this->view->plugin_name = $this->options['summary']['format'];
    $this->view->style_options = $this->options['summary_options'];

    // Clear out the normal primary field and whatever else may have been added
    // and let the summary do the work.
    $this->query
      ->clear_fields();
    $this
      ->summary_query();
    $by = $this->options['summary']['number_of_records'] ? 'num_records' : NULL;
    $this
      ->summary_sort($this->options['summary']['sort_order'], $by);

    // Summaries have their own sorting and fields, so tell the View not
    // to build these.
    $this->view->build_sort = $this->view->build_fields = FALSE;
    return TRUE;
  }

  /**
   * Build the info for the summary query.
   *
   * This must:
   * - add_groupby: group on this field in order to create summaries.
   * - add_field: add a 'num_nodes' field for the count. Usually it will be a
   *   count on $view->base_field
   * - set_count_field: Reset the count field so we get the right paging.
   *
   * @return string
   *   The alias used to get the number of records (count) for this entry.
   */
  public function summary_query() {
    $this
      ->ensure_my_table();

    // Add the field.
    $this->base_alias = $this->query
      ->add_field($this->table_alias, $this->real_field);
    $this
      ->summary_name_field();
    return $this
      ->summary_basics();
  }

  /**
   * Add the name field, which is the field displayed in summary queries.
   *
   * This is often used when the argument is numeric.
   */
  public function summary_name_field() {

    // Add the 'name' field. For example, if this is a uid argument, the name
    // field would be 'name' (i.e, the username).
    if (isset($this->name_table)) {

      // If the alias is different then we're probably added, not ensured, so
      // look up the join and add it instead.
      if ($this->table_alias != $this->name_table) {
        $j = views_get_table_join($this->name_table, $this->table);
        if ($j) {
          $join = clone $j;
          $join->left_table = $this->table_alias;
          $this->name_table_alias = $this->query
            ->add_table($this->name_table, $this->relationship, $join);
        }
      }
      else {
        $this->name_table_alias = $this->query
          ->ensure_table($this->name_table, $this->relationship);
      }
    }
    else {
      $this->name_table_alias = $this->table_alias;
    }
    if (isset($this->name_field)) {
      $this->name_alias = $this->query
        ->add_field($this->name_table_alias, $this->name_field);
    }
    else {
      $this->name_alias = $this->base_alias;
    }
  }

  /**
   * Some basic summary behavior.
   *
   * This doesn't need to be repeated as much as code that goes into
   * summary_query().
   */
  public function summary_basics($count_field = TRUE) {

    // Add the number of nodes counter.
    $distinct = $this->view->display_handler
      ->get_option('distinct') && empty($this->query->no_distinct);
    $count_alias = $this->query
      ->add_field($this->query->base_table, $this->query->base_field, 'num_records', array(
      'count' => TRUE,
      'distinct' => $distinct,
    ));
    $this->query
      ->add_groupby($this->name_alias);
    if ($count_field) {
      $this->query
        ->set_count_field($this->table_alias, $this->real_field);
    }
    $this->count_alias = $count_alias;
  }

  /**
   * Sorts the summary based upon the user's selection.
   *
   * The base variant of this is usually adequte.
   *
   * @param string $order
   *   The order selected in the UI.
   * @param string $by
   *   Optional alias for this field.
   */
  public function summary_sort($order, $by = NULL) {
    $this->query
      ->add_orderby(NULL, NULL, $order, !empty($by) ? $by : $this->name_alias);
  }

  /**
   * Provide the argument to use to link from the summary to the next level.
   *
   * This will be called once per row of a summary, and used as part of
   * $view->get_url().
   *
   * @param object $data
   *   The query results for the row.
   */
  public function summary_argument($data) {
    return $data->{$this->base_alias};
  }

  /**
   * Provides the name to use for the summary.
   *
   * By default this is just the name field.
   *
   * @param object $data
   *   The query results for the row.
   *
   * @return string
   *   The summary.
   */
  public function summary_name($data) {
    $value = $data->{$this->name_alias};
    if (empty($value) && !empty($this->definition['empty field name'])) {
      $value = $this->definition['empty field name'];
    }
    return check_plain($value);
  }

  /**
   * Set up the query for this argument.
   *
   * The argument sent may be found at $this->argument.
   *
   * @param bool $group_by
   *   Whether the query uses a group-by.
   */
  public function query($group_by = FALSE) {
    $this
      ->ensure_my_table();
    $this->query
      ->add_where(0, "{$this->table_alias}.{$this->real_field}", $this->argument);
  }

  /**
   * Get the title this argument will assign the view, given the argument.
   *
   * This usually needs to be overridden to provide a proper title.
   */
  public function title() {
    return check_plain($this->argument);
  }

  /**
   * Called by the view object to get the title.
   *
   * This may be set by a validator so we don't necessarily call through to
   * title().
   */
  public function get_title() {
    if (isset($this->validated_title)) {
      return $this->validated_title;
    }
    else {
      return $this
        ->title();
    }
  }

  /**
   * Validate that this argument works. By default, all arguments are valid.
   */
  public function validate_arg($arg) {

    // By using % in URLs, arguments could be validated twice; this eases
    // that pain.
    if (isset($this->argument_validated)) {
      return $this->argument_validated;
    }
    if ($this
      ->is_exception($arg)) {
      return $this->argument_validated = TRUE;
    }
    if ($this->options['validate']['type'] == 'none') {
      return $this->argument_validated = $this
        ->validate_argument_basic($arg);
    }
    $plugin = $this
      ->get_plugin('argument validator');
    if ($plugin) {
      return $this->argument_validated = $plugin
        ->validate_argument($arg);
    }

    // If the plugin isn't found, fall back to the basic validation path.
    return $this->argument_validated = $this
      ->validate_argument_basic($arg);
  }

  /**
   * Called by the menu system to validate an argument.
   *
   * This checks to see if this is a 'soft fail', which means that if the
   * argument fails to validate, but there is an action to take anyway, then
   * validation cannot actually fail.
   */
  public function validate_argument($arg) {
    $validate_info = $this
      ->default_actions($this->options['validate']['fail']);
    if (empty($validate_info['hard fail'])) {
      return TRUE;
    }
    $rc = $this
      ->validate_arg($arg);

    // If the validator has changed the validate fail condition to a soft fail,
    // deal with that.
    $validate_info = $this
      ->default_actions($this->options['validate']['fail']);
    if (empty($validate_info['hard fail'])) {
      return TRUE;
    }
    return $rc;
  }

  /**
   * Provide a basic argument validation.
   *
   * This can be overridden for more complex types; the basic validator only
   * checks to see if the argument is not NULL or is numeric if the definition
   * says it's numeric.
   *
   * @return bool
   *   Whether or not the argument validates.
   */
  public function validate_argument_basic($arg) {
    if (!isset($arg) || $arg === '') {
      return FALSE;
    }
    if (!empty($this->definition['numeric']) && !isset($this->options['break_phrase']) && !is_numeric($arg)) {
      return FALSE;
    }
    return TRUE;
  }

  /**
   * Set the input for this argument.
   *
   * @return bool
   *   TRUE if it successfully validates; FALSE if it does not.
   */
  public function set_argument($arg) {
    $this->argument = $arg;
    return $this
      ->validate_arg($arg);
  }

  /**
   * Get the value of this argument.
   *
   * @return string
   *   The value.
   */
  public function get_value() {

    // If we already processed this argument, we're done.
    if (isset($this->argument)) {
      return $this->argument;
    }

    // Otherwise, we have to pretend to process ourself to find the value.
    $value = NULL;

    // Find the position of this argument within the view.
    $position = 0;
    foreach ($this->view->argument as $id => $argument) {
      if ($id == $this->options['id']) {
        break;
      }
      $position++;
    }
    $arg = isset($this->view->args[$position]) ? $this->view->args[$position] : NULL;
    $this->position = $position;

    // Clone ourselves so that we don't break things when we're really
    // processing the arguments.
    $argument = clone $this;
    if (!isset($arg) && $argument
      ->has_default_argument()) {
      $arg = $argument
        ->get_default_argument();
    }

    // Set the argument, which will also validate that the argument can be set.
    if ($argument
      ->set_argument($arg)) {
      $value = $argument->argument;
    }
    unset($argument);
    return $value;
  }

  /**
   * Export handler for summary export.
   *
   * Arguments can have styles for the summary view. This special export
   * handler makes sure this works properly.
   *
   * @return string
   *   The export summary.
   */
  public function export_summary($indent, $prefix, $storage, $option, $definition, $parents) {
    $output = '';
    $name = $this->options['summary'][$option];
    $options = $this->options['summary_options'];
    $plugin = views_get_plugin('style', $name);
    if ($plugin) {
      $plugin
        ->init($this->view, $this->view->display_handler->display, $options);

      // Write which plugin to use.
      $output .= $indent . $prefix . "['summary']['{$option}'] = '{$name}';\n";

      // Pass off to the plugin to export itself.
      $output .= $plugin
        ->export_options($indent, $prefix . "['summary_options']");
    }
    return $output;
  }

  /**
   * Export handler for validation export.
   *
   * Arguments use validation plugins. This special export handler makes sure
   * this works properly.
   *
   * @return string
   *   The validation response.
   */
  public function export_validation($indent, $prefix, $storage, $option, $definition, $parents) {
    $output = '';
    $name = $this->options['validate'][$option];
    $options = $this->options['validate_options'];
    $plugin = views_get_plugin('argument validator', $name);
    if ($plugin) {
      $plugin
        ->init($this->view, $this->display, $options);

      // Write which plugin to use.
      $output .= $indent . $prefix . "['validate']['{$option}'] = '{$name}';\n";

      // Pass off to the plugin to export itself.
      $output .= $plugin
        ->export_options($indent, $prefix . "['validate_options']");
    }
    return $output;
  }

  /**
   * Generic plugin export handler.
   *
   * Since style and validation plugins have their own export handlers, this
   * one is currently only used for default argument plugins.
   *
   * @return string
   *   Export string.
   */
  public function export_plugin($indent, $prefix, $storage, $option, $definition, $parents) {
    $output = '';
    if ($option == 'default_argument_type') {
      $type = 'argument default';
      $option_name = 'default_argument_options';
    }
    $plugin = $this
      ->get_plugin($type);
    $name = $this->options[$option];
    if ($plugin) {

      // Write which plugin to use.
      $output .= $indent . $prefix . "['{$option}'] = '{$name}';\n";

      // Pass off to the plugin to export itself.
      $output .= $plugin
        ->export_options($indent, $prefix . "['{$option_name}']");
    }
    return $output;
  }

  /**
   * Get the display or row plugin, if it exists.
   */
  public function get_plugin($type = 'argument default', $name = NULL) {
    $options = array();
    switch ($type) {
      case 'argument default':
        $plugin_name = $this->options['default_argument_type'];
        $options_name = 'default_argument_options';
        break;
      case 'argument validator':
        $plugin_name = $this->options['validate']['type'];
        $options_name = 'validate_options';
        break;
      case 'style':
        $plugin_name = $this->options['summary']['format'];
        $options_name = 'summary_options';
        break;
    }
    if (!$name) {
      $name = $plugin_name;
    }

    // We only fetch the options if we're fetching the plugin actually in use.
    if ($name == $plugin_name) {
      $options = $this->options[$options_name];
    }
    $plugin = views_get_plugin($type, $name);
    if ($plugin) {

      // Style plugins expects different parameters as argument related plugins.
      if ($type == 'style') {
        $plugin
          ->init($this->view, $this->view->display_handler->display, $options);
      }
      else {
        $plugin
          ->init($this->view, $this, $options);
      }
      return $plugin;
    }
  }

  /**
   * Return a description of how the argument would normally be sorted.
   *
   * Subclasses should override this to specify what the default sort order of
   * their argument is (e.g. alphabetical, numeric, date).
   *
   * @return string
   *   The label for the sorter.
   */
  public function get_sort_name() {
    return t('Default sort', array(), array(
      'context' => 'Sort order',
    ));
  }

}

Members

Namesort descending Modifiers Type Description Overrides
views_handler::$handler_type public property The type of the handler, for example filter/footer/field.
views_handler::$query public property Where the $query object will reside:. 1
views_handler::$real_field public property The actual field in the database table, maybe different on other kind of query plugins/special handlers.
views_handler::$relationship public property The relationship used for this field.
views_handler::$table_alias public property The alias of the table of this handler which is used in the query.
views_handler::$view public property The top object of a view. Overrides views_object::$view
views_handler::accept_exposed_input public function Take input from exposed handlers and assign to this handler, if necessary. 1
views_handler::access public function Check whether current user has access to this handler. 10
views_handler::admin_summary public function Provide text for the administrative summary. 4
views_handler::broken public function Determine if the handler is considered 'broken'. 6
views_handler::can_expose public function Determine if a handler can be exposed. 2
views_handler::case_transform public function Transform a string by a certain method.
views_handler::ensure_my_table public function Ensure the main table for this handler is in the query. This is used a lot. 8
views_handler::exposed_form public function Render our chunk of the exposed handler form when selecting. 1
views_handler::exposed_info public function Get information about the exposed form for the form renderer. 1
views_handler::exposed_submit public function Submit the exposed handler form.
views_handler::exposed_validate public function Validate the exposed handler form. 4
views_handler::expose_form public function Form for exposed handler options. 2
views_handler::expose_options public function Set new exposed option defaults when exposed setting is flipped on. 2
views_handler::expose_submit public function Perform any necessary changes to the form exposes prior to storage. There is no need for this function to actually store the data.
views_handler::expose_validate public function Validate the options form. 1
views_handler::extra_options public function Provide defaults for the handler.
views_handler::extra_options_form public function Provide a form for setting options. 1
views_handler::extra_options_submit public function Perform any necessary changes to the form values prior to storage. There is no need for this function to actually store the data.
views_handler::extra_options_validate public function Validate the options form.
views_handler::get_field public function Shortcut to get a handler's raw field value.
views_handler::get_join public function Get the join object that should be used for this handler.
views_handler::groupby_form public function Provide a form for aggregation settings. 1
views_handler::groupby_form_submit public function Perform any necessary changes to the form values prior to storage. There is no need for this function to actually store the data. 1
views_handler::has_extra_options public function If a handler has 'extra options' it will get a little settings widget and another form called extra_options. 1
views_handler::is_a_group public function Returns TRUE if the exposed filter works like a grouped filter. 1
views_handler::is_exposed public function Determine if this item is 'exposed', meaning it provides form elements to let users modify the view.
views_handler::multiple_exposed_input public function Define if the exposed input has to be submitted multiple times. This is TRUE when exposed filters grouped are using checkboxes as widgets. 1
views_handler::placeholder public function Provides a unique placeholders for handlers.
views_handler::post_execute public function Run after the view is executed, before the result is cached. 1
views_handler::pre_query public function Run before the view is built. 1
views_handler::sanitize_value public function Sanitize the value for output.
views_handler::set_relationship public function Called just prior to query(), this lets a handler set up any relationship it needs.
views_handler::show_expose_button public function Shortcut to display the expose/hide button. 2
views_handler::show_expose_form public function Shortcut to display the exposed options form.
views_handler::store_exposed_input public function If set to remember exposed input in the session, store it there. 1
views_handler::ui_name public function Return a string representing this handler's name in the UI. 9
views_handler::use_group_by public function Provides the handler some groupby. 2
views_handler::validate public function Validates the handler against the complete View. 1
views_handler_argument::$argument public property
views_handler_argument::$name_field public property The field to use for the name to use in the summary.
views_handler_argument::$name_table public property The table to use for the name, if not the same table as the argument.
views_handler_argument::$validator public property
views_handler_argument::$value public property 1
views_handler_argument::construct public function Views handlers use a special construct function. Overrides views_object::construct 5
views_handler_argument::default_access_denied public function Default action: access denied.
views_handler_argument::default_action public function Handle the default action, which means our argument wasn't present.
views_handler_argument::default_actions public function List of default behaviors for this argument if the argument is not present. 4
views_handler_argument::default_argument_form public function Provide a form for selecting the default argument. 1
views_handler_argument::default_default public function This just returns true.
views_handler_argument::default_empty public function Default action: empty.
views_handler_argument::default_ignore public function Default action: ignore.
views_handler_argument::default_not_found public function Default action: not found.
views_handler_argument::default_summary public function Default action: summary.
views_handler_argument::default_summary_form public function Form for selecting further summary options.
views_handler_argument::exception_title public function Work out which title to use.
views_handler_argument::export_plugin public function Generic plugin export handler. 1
views_handler_argument::export_summary public function Export handler for summary export.
views_handler_argument::export_validation public function Export handler for validation export.
views_handler_argument::get_default_argument public function Get a default argument, if available. 1
views_handler_argument::get_plugin public function Get the display or row plugin, if it exists.
views_handler_argument::get_sort_name public function Return a description of how the argument would normally be sorted. 5
views_handler_argument::get_title public function Called by the view object to get the title.
views_handler_argument::get_value public function Get the value of this argument.
views_handler_argument::has_default_argument public function Determine if the argument is set to provide a default argument.
views_handler_argument::init public function Init the handler with necessary data. Overrides views_handler::init 3
views_handler_argument::is_exception public function
views_handler_argument::needs_style_plugin public function Determine if the argument needs a style plugin. Overrides views_handler::needs_style_plugin
views_handler_argument::options_form public function Build the options form. Overrides views_handler::options_form 8
views_handler_argument::options_submit public function Perform any necessary changes to the form values prior to storage. There is no need for this function to actually store the data. Overrides views_handler::options_submit
views_handler_argument::options_validate public function Validate the options form. Overrides views_handler::options_validate
views_handler_argument::option_definition public function Information about options for all kinds of purposes will be held here. Overrides views_handler::option_definition 6
views_handler_argument::process_summary_arguments public function Process the summary arguments for display.
views_handler_argument::query public function Set up the query for this argument. 12
views_handler_argument::set_argument public function Set the input for this argument.
views_handler_argument::set_breadcrumb public function Give an argument the opportunity to modify the breadcrumb, if it wants. 3
views_handler_argument::summary_argument public function Provide the argument to use to link from the summary to the next level. 4
views_handler_argument::summary_basics public function Some basic summary behavior.
views_handler_argument::summary_name public function Provides the name to use for the summary. 10
views_handler_argument::summary_name_field public function Add the name field, which is the field displayed in summary queries.
views_handler_argument::summary_query public function Build the info for the summary query. 3
views_handler_argument::summary_sort public function Sorts the summary based upon the user's selection.
views_handler_argument::title public function Get the title this argument will assign the view, given the argument. 13
views_handler_argument::uses_breadcrumb public function Determine if the argument can generate a breadcrumb.
views_handler_argument::validate_arg public function Validate that this argument works. By default, all arguments are valid.
views_handler_argument::validate_argument public function Called by the menu system to validate an argument.
views_handler_argument::validate_argument_basic public function Provide a basic argument validation. 1
views_handler_argument::validate_fail public function How to act if validation fails.
views_object::$definition public property Handler's definition.
views_object::$options public property Except for displays, options for the object will be held here. 1
views_object::altered_option_definition function Collect this handler's option definition and alter them, ready for use.
views_object::destroy public function Destructor. 2
views_object::export_option public function 1
views_object::export_options public function
views_object::export_option_always public function Always exports the option, regardless of the default value.
views_object::options Deprecated public function Set default options on this object. 1
views_object::set_default_options public function Set default options.
views_object::set_definition public function Let the handler know what its full definition is.
views_object::unpack_options public function Unpack options over our existing defaults, drilling down into arrays so that defaults don't get totally blown away.
views_object::unpack_translatable public function Unpack a single option definition.
views_object::unpack_translatables public function Unpacks each handler to store translatable texts.
views_object::_set_option_defaults public function