You are here

class mvf_handler_filter_mvf in Measured Value Field 7

Base Views Filter Handler for field types defined in MVF module.

Hierarchy

Expanded class hierarchy of mvf_handler_filter_mvf

1 string reference to 'mvf_handler_filter_mvf'
mvf_field_views_data in views/mvf.views.inc
Implements hook_field_views_data().

File

views/mvf_handler_filter_mvf.inc, line 6

View source
class mvf_handler_filter_mvf extends views_handler_filter_numeric {
  function option_definition() {
    $option = parent::option_definition();
    foreach ($option['value']['contains'] as $type => $v) {
      $option['value']['contains'][$type] = array(
        'contains' => array(
          mvf_subfield_to_column('value') => array(
            'default' => 0,
          ),
          mvf_subfield_to_column('unit') => array(
            'default' => NULL,
          ),
        ),
      );
    }
    $option['field_definition'] = array();
    return $option;
  }
  function set_default_options() {
    parent::set_default_options();

    // We load field API definition array of the MVF field on which current
    // instance of the filter operates.
    $this->options['field_definition'] = field_info_field($this->definition['field_name']);

    // Inserting "whatever" default units, now that we have MVF field on hands,
    // we can do it.
    $entityreference = mvf_field_mockup($this->options['field_definition'], 'unit');
    $entity_type = $entityreference['settings']['target_type'];
    $efq = new EntityFieldQuery();
    $efq
      ->entityCondition('entity_type', $entity_type);
    $efq
      ->entityCondition('bundle', reset($entityreference['settings']['handler_settings']['target_bundles']));
    $efq
      ->range(0, 1);
    $result = $efq
      ->execute();
    $default_unit_id = array_keys($result[$entity_type]);
    $default_unit_id = reset($default_unit_id);
    foreach ($this->options['value'] as $k => $v) {
      $this->options['value'][$k][mvf_subfield_to_column('unit')] = $default_unit_id;
    }
  }
  function operators() {
    $operators = parent::operators();

    // We can't support 'regular_expression' option because it quite doesn't
    // make sense in case of MVF.
    unset($operators['regular_expression']);

    // Additionally we want to supply meta info, which operator uses which
    // sub arrays of filter input values.
    foreach ($operators as $k => $v) {
      $required_subvalues = array();
      switch ($k) {
        case '<':
        case '<=':
        case '=':
        case '!=':
        case '>=':
        case '>':
          $required_subvalues = array(
            'value',
          );
          break;
        case 'between':
        case 'not between':
          $required_subvalues = array(
            'min',
            'max',
          );
          break;
        case 'empty':
        case 'not empty':
          $required_subvalues = array();
          break;
      }
      $operators[$k]['required subvalues'] = $required_subvalues;
    }
    return $operators;
  }
  function value_form(&$form, &$form_state) {
    parent::value_form($form, $form_state);

    // Loading any instance of this field in order to pass it down to process
    // function of form element of type 'mvf_widget'.
    $instance = mvf_field_instance($this->options['field_definition']);

    // parent might return us differently structured $form array.
    // 'value' element can be found in $form['value'] or in
    // $form['value']['value'].
    // And 'min' and 'max' elements might be present or not. It does so because
    // the form elements depend on filter's operator state and whether it's
    // exposed or not. We basically follow the same pattern. The only thing we
    // want to change about it is to override parent's 'textfield' with our
    // 'mvf_widget' form element introducing in such way an option to choose
    // unit measure for filtering value.
    $instance['label'] = '';
    $value_element = array(
      '#tree' => TRUE,
      '#type' => 'mvf_widget',
      '#field' => $this->options['field_definition'],
      '#instance' => $instance,
      '#entity_type' => $instance['entity_type'],
      '#pre_render' => array(
        'mvf_views_label_pre_render',
      ),
    ) + $this
      ->options_to_mvf_default_value($this->value['value']);
    if (isset($form['value']['#type'])) {
      $form['value'] = $value_element + $form['value'];
    }
    if (isset($form['value']['value']['#type'])) {
      $form['value']['value'] = $value_element + $form['value']['value'];
    }
    if (isset($form['value']['min']['#type'])) {
      $instance['label'] = t('Min');
      $form['value']['min'] = array(
        '#type' => 'mvf_widget',
        '#field' => $this->options['field_definition'],
        '#instance' => $instance,
        '#entity_type' => $instance['entity_type'],
        '#pre_render' => array(
          'mvf_views_label_pre_render',
        ),
      ) + $this
        ->options_to_mvf_default_value($this->value['min']) + $form['value']['min'];
    }
    if (isset($form['value']['max']['#type'])) {
      $instance['label'] = t('Max');
      $form['value']['max'] = array(
        '#type' => 'mvf_widget',
        '#field' => $this->options['field_definition'],
        '#instance' => $instance,
        '#entity_type' => $instance['entity_type'],
        '#pre_render' => array(
          'mvf_views_label_pre_render',
        ),
      ) + $this
        ->options_to_mvf_default_value($this->value['max']) + $form['value']['max'];
    }
  }
  function options_validate(&$form, &$form_state) {
    parent::options_validate($form, $form_state);

    // Additionally we want to validate filter data is entered.
    $operator = $this
      ->operators();
    $operator = $operator[$form_state['values']['options']['operator']];
    $required_subvalues = array();

    // There are required sub values only if the filter is not exposed or
    // exposed and required.
    if (!$this->options['exposed'] || $this->options['exposed'] && $form_state['values']['options']['expose']['required']) {
      $required_subvalues = drupal_map_assoc($operator['required subvalues']);
    }
    foreach (array_intersect_key($form_state['values']['options']['value'], $required_subvalues) as $type => $subvalue) {
      if (module_invoke('mvf', 'field_is_empty', $subvalue, $this->options['field_definition'])) {
        form_error($form['value'][$type], t('Please, enter values into %title', array(
          '%title' => $form['value'][$type]['#title'],
        )));
      }
    }
  }

  /**
   * Since our filter operates on 2 form elements we can't use parent's method.
   */
  function accept_exposed_input($input) {

    // Converting single value into array('value' => $value), as the rest of
    // this code expects it reside there.
    $value =& $input[$this->options['expose']['identifier']];
    $info = $this
      ->operators();
    $operator = $info[$this->operator];
    if ($operator['values'] == 1 && in_array('value', $operator['required subvalues'])) {
      $value = array(
        'value' => $value,
      );
    }
    $accept = parent::accept_exposed_input($input);
    if (!$accept) {
      return FALSE;
    }
    foreach ($operator['required subvalues'] as $required_subvalue) {
      if (module_invoke('mvf', 'field_is_empty', $value[$required_subvalue], $this->options['field_definition'])) {
        return FALSE;
      }
    }
    return $accept;
  }
  function build_group_validate($form, &$form_state) {

    // Out of the box our filter does not pass validation because our
    // value is an array of arrays, however, here is expected at most array of
    // strings/floats, or just a scalar value. So we need to substitute
    // our values with some dummy values that will pass validation and handle
    // input validation itself here in our method.
    $group_items = $form_state['values']['options']['group_info']['group_items'];

    // Our value will be substituted for parent's method call with this value
    // once we have validated it ourselves. This way we make sure no groundless
    // validation errors occur.
    $passable_value = 'pass me';
    foreach ($group_items as $id => $group) {

      // We keep only those sub arrays of 'value' that make sense for the
      // selected operator.
      $operator = $this
        ->operators();
      $required_subvalues = drupal_map_assoc($operator[$group['operator']]['required subvalues']);
      $group['value'] = array_intersect_key($group['value'], $required_subvalues);
      $is_valid = TRUE;
      foreach ($group['value'] as $subvalue) {

        // For validation we use hook_field_is_empty().
        if (module_invoke('mvf', 'field_is_empty', $subvalue, $this->options['field_definition'])) {
          $is_valid = FALSE;
          break;
        }
      }
      if ($is_valid) {

        // If this group is valid, we substitute its value with something
        // that will pass validation in parent's method.
        $form_state['values']['options']['group_info']['group_items'][$id]['value'] = $passable_value;
      }
    }
    parent::build_group_validate($form, $form_state);

    // Restoring real values once we are done with calling parent's method.
    $form_state['values']['options']['group_info']['group_items'] = $group_items;
  }
  function op_simple($field) {
    $field = array(
      'value' => $this->table_alias . '.' . $this->definition['field_name'] . '_' . mvf_subfield_to_column('value'),
      'unit' => $this->table_alias . '.' . $this->definition['field_name'] . '_' . mvf_subfield_to_column('unit'),
    );
    $measure = array_pop($this->options['field_definition']['settings']['unit']['handler_settings']['target_bundles']);
    $from_unit = units_unit_load($this->value['value'][mvf_subfield_to_column('unit')]);
    $where = db_or();
    foreach (units_unit_by_measure_load_multiple($measure) as $to_unit) {
      $converted_value = units_convert($this->value['value'][mvf_subfield_to_column('value')], $from_unit->machine_name, $to_unit->machine_name);
      $unit_id = entity_extract_ids('units_unit', $to_unit);
      $unit_id = array_shift($unit_id);
      $where
        ->condition(db_and()
        ->condition($field['value'], $converted_value, $this->operator)
        ->condition($field['unit'], $unit_id));
    }
    $this->query
      ->add_where($this->options['group'], $where);
  }
  function op_between($field) {
    $field = array(
      'value' => $this->table_alias . '.' . $this->definition['field_name'] . '_' . mvf_subfield_to_column('value'),
      'unit' => $this->table_alias . '.' . $this->definition['field_name'] . '_' . mvf_subfield_to_column('unit'),
    );
    $measure = array_pop($this->options['field_definition']['settings']['unit']['handler_settings']['target_bundles']);
    $where = db_or();
    foreach (units_unit_by_measure_load_multiple($measure) as $to_unit) {
      $from_units = array(
        'min' => $this->value['min'][mvf_subfield_to_column('unit')],
        'max' => $this->value['max'][mvf_subfield_to_column('unit')],
      );
      $tmp = units_unit_load_multiple(array_values($from_units));
      $converted_value = array();
      foreach ($from_units as $k => $v) {
        $from_units[$k] = $tmp[$v];
        $converted_value[$k] = units_convert($this->value[$k][mvf_subfield_to_column('value')], $from_units[$k]->machine_name, $to_unit->machine_name);
      }
      $to_unit = entity_extract_ids('units_unit', $to_unit);
      $to_unit = array_shift($to_unit);
      switch ($this->operator) {
        case 'between':
          $where
            ->condition(db_and()
            ->condition($field['value'], $converted_value, $this->operator)
            ->condition($field['unit'], $to_unit));
          break;
        case 'not between':
          $where
            ->condition(db_and()
            ->condition(db_or()
            ->condition($field['value'], $converted_value['min'], '<=')
            ->condition($field['value'], $converted_value['max'], '>='))
            ->condition($field['unit'], $to_unit));
          break;
      }
    }
    $this->query
      ->add_where($this->options['group'], $where);
  }
  function admin_summary() {
    if ($this
      ->is_a_group()) {
      return t('grouped');
    }
    if (!empty($this->options['exposed'])) {
      return t('exposed');
    }
    $operators = $this
      ->operators();
    $output = check_plain($operators[$this->operator]['short']) . ' ';
    switch ($operators[$this->operator]['values']) {
      case 1:
        $output .= t('@value @unit', array(
          '@value' => $this->value['value']['value'],
          '@unit' => entity_label('units_unit', units_unit_load($this->value['value'][mvf_subfield_to_column('unit')])),
        ));
        break;
      case 2:
        $units = units_unit_load_multiple(array(
          $this->value['min'][mvf_subfield_to_column('unit')],
          $this->value['max'][mvf_subfield_to_column('unit')],
        ));
        $units = array(
          'min' => $units[$this->value['min'][mvf_subfield_to_column('unit')]],
          'max' => $units[$this->value['max'][mvf_subfield_to_column('unit')]],
        );
        $output .= t('@min_value @min_unit and @max_value @max_unit', array(
          '@min_value' => $this->value['min'][mvf_subfield_to_column('value')],
          '@min_unit' => entity_label('units_unit', $units['min']),
          '@max_value' => $this->value['max'][mvf_subfield_to_column('value')],
          '@max_unit' => entity_label('units_unit', $units['max']),
        ));
        break;
    }
    return $output;
  }

  /**
   * Supportive function.
   *
   * Convert filter's entered options into the format expected by 'mvf_widget'
   * form element so the values entered into filter are used as default values
   * of the elements generated by 'mvf_widget'.
   *
   * @param array $options
   *
   * @return array
   *   Array to be merged into form element definition
   */
  function options_to_mvf_default_value($options) {
    return array(
      '#delta' => 0,
      '#items' => array(
        0 => $options,
      ),
    );
  }

}

Members

Namesort descending Modifiers Type Description Overrides
mvf_handler_filter_mvf::accept_exposed_input function Since our filter operates on 2 form elements we can't use parent's method. Overrides views_handler_filter_numeric::accept_exposed_input
mvf_handler_filter_mvf::admin_summary function Display the filter on the administrative summary. Overrides views_handler_filter_numeric::admin_summary
mvf_handler_filter_mvf::build_group_validate function Validate the build group options form. Overrides views_handler_filter::build_group_validate
mvf_handler_filter_mvf::operators function Overrides views_handler_filter_numeric::operators
mvf_handler_filter_mvf::options_to_mvf_default_value function Supportive function.
mvf_handler_filter_mvf::options_validate function Simple validate handler. Overrides views_handler_filter::options_validate
mvf_handler_filter_mvf::option_definition function Information about options for all kinds of purposes will be held here. Overrides views_handler_filter_numeric::option_definition
mvf_handler_filter_mvf::op_between function Overrides views_handler_filter_numeric::op_between
mvf_handler_filter_mvf::op_simple function Overrides views_handler_filter_numeric::op_simple
mvf_handler_filter_mvf::set_default_options function Set default options. Overrides views_object::set_default_options
mvf_handler_filter_mvf::value_form function Provide a simple textfield for equality Overrides views_handler_filter_numeric::value_form
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::access public function Check whether current user has access to this handler. 10
views_handler::broken public function Determine if the handler is considered 'broken'. 6
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_submit public function Submit the exposed handler form.
views_handler::exposed_validate public function Validate the exposed handler form. 4
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::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_exposed public function Determine if this item is 'exposed', meaning it provides form elements to let users modify the view.
views_handler::needs_style_plugin public function Determine if the argument needs a style plugin. 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_form public function Shortcut to display the exposed options form.
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_filter::$always_required public property Disable the possibility to allow a exposed input to be optional.
views_handler_filter::$group_info public property Contains the information of the selected item in a gruped filter.
views_handler_filter::$no_operator public property Disable the possibility to use operators. 2
views_handler_filter::$operator public property Contains the operator which is used on the query.
views_handler_filter::$value public property Contains the actual value of the field.
views_handler_filter::build_group_form public function Build the form to let users create the group of exposed filters.
views_handler_filter::build_group_options public function Provide default options for exposed filters.
views_handler_filter::build_group_submit public function Save new group items, re-enumerates and remove groups marked to delete.
views_handler_filter::can_build_group public function Determine if a filter can be converted into a group.
views_handler_filter::can_expose public function Determine if a filter can be exposed. Overrides views_handler::can_expose 5
views_handler_filter::can_group public function Can this filter be used in OR groups? 1
views_handler_filter::convert_exposed_input public function Transform the input from a grouped filter into a standard filter.
views_handler_filter::exposed_form public function Render our chunk of the exposed filter form when selecting. Overrides views_handler::exposed_form
views_handler_filter::exposed_info public function Tell the renderer about our exposed form. Overrides views_handler::exposed_info
views_handler_filter::exposed_translate public function Make some translations to a form item to make it more suitable to exposing.
views_handler_filter::expose_form public function Options form subform for exposed filter options. Overrides views_handler::expose_form 2
views_handler_filter::expose_options public function Provide default options for exposed filters. Overrides views_handler::expose_options 2
views_handler_filter::expose_validate public function Validate the options form. Overrides views_handler::expose_validate
views_handler_filter::group_form public function Build a form with a group of operator | values to apply as a single filter.
views_handler_filter::group_multiple_exposed_input public function Options available for a grouped filter which uses checkboxes.
views_handler_filter::init public function Provide some extra help to get the operator/value easier to use. Overrides views_handler::init 2
views_handler_filter::is_a_group public function Returns TRUE if the exposed filter works like a grouped filter. Overrides views_handler::is_a_group
views_handler_filter::multiple_exposed_input public function Indicate whether users can select multiple group items. Overrides views_handler::multiple_exposed_input
views_handler_filter::operator_form public function Options form subform for setting the operator. 6
views_handler_filter::operator_submit public function Perform any necessary changes to the form values prior to storage.
views_handler_filter::operator_validate public function Validate the operator form.
views_handler_filter::options_form public function Provide the basic form which calls through to subforms. Overrides views_handler::options_form 4
views_handler_filter::options_submit public function Simple submit handler. Overrides views_handler::options_submit
views_handler_filter::prepare_filter_select_options public function Sanitizes the HTML select element's options.
views_handler_filter::show_build_group_button public function Shortcut to display the build_group/hide button.
views_handler_filter::show_build_group_form public function Shortcut to display the exposed options form.
views_handler_filter::show_expose_button public function Shortcut to display the expose/hide button. Overrides views_handler::show_expose_button
views_handler_filter::show_operator_form public function Shortcut to display the operator form.
views_handler_filter::show_value_form public function Shortcut to display the value form.
views_handler_filter::store_exposed_input public function Store the exposed input for processing later. Overrides views_handler::store_exposed_input
views_handler_filter::store_group_input public function If set to remember exposed input in the session, store it there.
views_handler_filter::value_submit public function Perform any necessary changes to the form values prior to storage. 1
views_handler_filter::value_validate public function Validate the options form. 3
views_handler_filter_numeric::$always_multiple public property Exposed filter options. Overrides views_handler_filter::$always_multiple
views_handler_filter_numeric::operator_options public function Provide a list of all the numeric operators Overrides views_handler_filter::operator_options
views_handler_filter_numeric::operator_values public function
views_handler_filter_numeric::op_empty public function 2
views_handler_filter_numeric::op_not_regex public function
views_handler_filter_numeric::op_regex public function 1
views_handler_filter_numeric::query public function Add this filter to the query. Overrides views_handler_filter::query 2
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::construct public function Views handlers use a special construct function. 4
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_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