You are here

class select_translation_filter_handler in Select translation 7

Hierarchy

Expanded class hierarchy of select_translation_filter_handler

1 string reference to 'select_translation_filter_handler'
select_translation_views_data_alter in ./select_translation.views.inc
Implements hook_views_data_alter().

File

./select_translation_filter_handler.inc, line 11
Views select translation filter handler.

View source
class select_translation_filter_handler extends views_handler_filter {

  // @ignore sniffer_namingconventions_validfunctionname_notlowercamel:class
  // Don't display empty space where the operator would be.
  // @ignore sniffer_namingconventions_validvariablename_lowercamelname
  var $no_operator = TRUE;

  /**
   * Returns admin summary of the filter options.
   */
  function admin_summary() {
    $options = array(
      'original' => t('Original language fallback'),
      'default' => t('Default site language fallback'),
      'list' => t('Custom fallback priority'),
    );
    return $options[$this->value];
  }

  /**
   * Returns an array of filter option defaults.
   */
  function option_definition() {
    $options = parent::option_definition();
    $options['value']['default'] = 'default';
    $options['priorities']['default'] = '';
    $options['default_language_only']['default'] = 0;
    $options['include_content_without_translation']['default'] = 1;
    $options['include_content_with_unpublished_translation']['default'] = 0;
    return $options;
  }

  /**
   * Returns the operator form.
   */
  function operator_form(&$form, &$form_state) {
    $form['operator'] = array();
  }

  /**
   * Returns a form with configurable options.
   */
  function value_form(&$form, &$form_state) {
    $form['value'] = array(
      '#type' => 'radios',
      '#title' => t('Select translation selection mode'),
      '#options' => array(
        'original' => t('Use current language ; if not available use original language'),
        'default' => t('Use current language ; if not available use default language ; if not available use original language'),
        'list' => t('Choose language priorities'),
      ),
      '#default_value' => $this->value,
    );
    $form['priorities'] = array(
      '#type' => 'textfield',
      '#title' => t('Language priorities'),
      '#description' => t('If selection mode is set to "Choose language priorities",
                           you can enter here a comma separated list of language codes.
                           The filter will then return the node in the first available langauge
                           in that list ; and the original version if no match were found.<br/><br/>
                           The special value "current" will be replaced with the current language,
                           "default" will be replaced with the default language,
                           and "original" with the original language of each node.
                           <br/><br/>
                           Example:<br/><em>en,fr,current,default,original</em><br/>
                           This will return the version in english if available, if not in french,
                           if not in the current language, if not in the default language.
                           If none are available it will return the original version.'),
      '#default_value' => !empty($this->options['priorities']) ? $this->options['priorities'] : '',
      '#dependency' => array(
        'radio:options[value]' => array(
          'list',
        ),
      ),
    );
    $form['default_language_only'] = array(
      '#type' => 'checkbox',
      '#title' => t('Display default language content *only*, if the currently selected user language is the default site language.'),
      '#description' => t("When you check this option, the order chosen above will be ignored when current language = site default language,\n        instead it will only show translations for the default language. "),
      '#default_value' => !empty($this->options['default_language_only']) ? $this->options['default_language_only'] : 0,
    );
    $form['include_content_without_translation'] = array(
      '#type' => 'checkbox',
      '#title' => t('Include content that does not have translations, aka it does not belong to a translation set (tnid = 0)'),
      '#description' => t('Sometimes you have content that is created originally in another language than English (e.g., Chinese)
        and it does not have translations, hence it does not belong to a translation set. With this option checked,
        the Chinese content will appear regardless of current language.'),
      '#default_value' => !empty($this->options['include_content_without_translation']) ? $this->options['include_content_without_translation'] : 0,
    );
    $form['include_content_with_unpublished_translation'] = array(
      '#type' => 'checkbox',
      '#title' => t('Return content in the site default language when a translation for the current language *does* exist, but it is unpublished.'),
      '#description' => t('When you check this option, in addition to the order chosen above, content will be shown in the default site language in the event that the translation in the current language is unpublished.'),
      '#default_value' => !empty($this->options['include_content_with_unpublished_translation']) ? $this->options['include_content_with_unpublished_translation'] : 0,
    );
  }

  /**
   * A query that doesn't use correlated sub-queries.
   *
   * Thus executing faster for larger data sets.
   */
  function better_query() {
    global $language_content;
    $default_language = language_default('language');
    $current_language = $language_content->language;

    // Limit the language list to default only, if the option was selected and
    // default_language == current_language.
    if ($this->options['default_language_only'] && $default_language == $current_language) {
      $list = array(
        'default',
      );
    }
    else {
      $list = array();
      if ($this->value == 'original') {
        $list = array(
          'current',
        );
      }
      elseif ($this->value == 'default') {
        $list = array(
          'current',
          'default',
        );
      }
      elseif (!empty($this->options['priorities'])) {
        $list = explode(',', $this->options['priorities']);
        foreach ($list as $i => $v) {
          $list[$i] = strtolower(trim($v));
        }
      }
      $list[] = 'original';
    }
    foreach ($list as $i => $v) {
      if ($list[$i] == 'current') {
        $list[$i] = $current_language;
      }
      elseif ($list[$i] == 'default') {
        $list[$i] = $default_language;
      }
    }
    $list = array_unique($list);

    // Now build the query.
    $query = $this->query;

    /* @var $query views_plugin_query_default */
    $alias = $query
      ->ensure_table('node');
    $condition_holder = db_or();

    // First include nodes that don't have translations, if option was checked.
    if ($this->options['include_content_without_translation']) {
      $condition_holder
        ->condition("{$alias}.tnid", 0);
    }
    $i = 0;
    $exclude = array();

    // Now go through each language.
    foreach ($list as $language) {
      $add_new_join = FALSE;
      if ($language != 'original') {

        // Create a views join on the node table, and add it as a relationship.
        // This is used to find if there are translations of a certain language.
        $join = new views_join();
        $add_new_join = TRUE;
        $sub_query_alias = 'nt' . $i;

        // Because domain module uses node_access, and rewrites the query to add
        // exists clauses for each left joined node table (maybe specific to all
        // node access modules), thus breaking the listing, we wrap the table in
        // a sub-query, avoiding the exists clause.
        $this
          ->node_access_join($join, $language, $alias, $sub_query_alias);

        // Add the join as a relationship.
        $query
          ->add_relationship($sub_query_alias, $join, 'node');
      }
      if ($language == 'original') {

        // Include nodes that are the base of a translation (aka original).
        $and = db_and()
          ->where("{$alias}.nid = {$alias}.tnid");
      }
      else {

        // Include nodes of specified language.
        $and = db_and()
          ->condition("{$alias}.language", $language);
      }

      // Add the currently processed language only if previous languages were
      // not found.
      foreach ($exclude as $e) {
        $and
          ->where($e);
      }
      $condition_holder
        ->condition($and);

      // Add to excludes the currently processed translation language.
      if (isset($sub_query_alias) && $add_new_join) {
        $exclude[] = $sub_query_alias . '.nid IS NULL';
        ++$i;
      }
    }

    // Include site default nodes in place of unpublished translations.
    if ($this->options['include_content_with_unpublished_translation']) {
      $sub_query_alias = 'nt' . $i;
      $join = new views_join();

      // Join with the currently selected language.
      $this
        ->node_access_join($join, $current_language, 'node', $sub_query_alias);

      // Add the join as a relationship.
      $query
        ->add_relationship($sub_query_alias, $join, 'node');

      // The default language node will be selected, if the current language
      // (translated) node is unpublished.
      $condition_holder
        ->condition(db_and()
        ->condition("{$alias}.language", $default_language)
        ->condition("{$sub_query_alias}.status", NODE_NOT_PUBLISHED));
    }

    // Add in the conditions.
    $query
      ->add_where($this->options['group'], $condition_holder);
  }

  /**
   * Join to the node table where the nodes have the given language.
   *
   * @param views_join $join
   *   The views join object.
   * @param string $language
   *   The language of the nodes that should be retrieved.
   * @param string $alias
   *   The alias of the main node table.
   * @param string $sub_query_alias
   *   The alias of the sub query node table.
   * @param string $extra
   *   A string with extra join conditions.
   */
  function node_access_join(&$join, $language, $alias, $sub_query_alias, $extra = NULL) {
    $sub_query = db_select('node', $sub_query_alias);
    $sub_query
      ->addField($sub_query_alias, 'nid');
    $sub_query
      ->addField($sub_query_alias, 'tnid');
    $sub_query
      ->addfield($sub_query_alias, 'status');
    $sub_query
      ->addField($sub_query_alias, 'language');
    $sub_query
      ->where("{$sub_query_alias}.language = '{$language}'");

    // If not extra argument was sent, use the default one.
    if ($extra === NULL) {

      // Nodes have translations when translation id is different from 0.
      $extra = "{$alias}.tnid != 0";
    }
    $join
      ->construct($sub_query, $alias, 'tnid', 'tnid', array(
      $extra,
    ));
  }

  /**
   * The default join is currently not used.
   */
  function default_join(&$join, $language, $alias, $sub_query_alias) {
    $extra = "{$sub_query_alias}.language = '{$language}' AND {$alias}.tnid != 0";

    /* @var $join views_join */
    $join
      ->construct('node', $alias, 'tnid', 'tnid', $extra);
  }

  /**
   * Executes the query.
   */
  public function query() {
    $this
      ->better_query();
  }

  /**
   * This was the original correlated query, which is currently not used.
   */
  function original_query() {

    // Prepare input.
    $list = array();
    if ($this->value == 'original') {
      $list = array(
        'current',
      );
    }
    elseif ($this->value == 'default') {
      $list = array(
        'current',
        'default',
      );
    }
    elseif (!empty($this->options['priorities'])) {
      $list = explode(',', $this->options['priorities']);
      foreach ($list as $i => $v) {
        $list[$i] = strtolower(trim($v));
      }
    }
    $list[] = 'original';
    foreach ($list as $i => $v) {
      if ($list[$i] == 'current') {
        $list[$i] = '***CURRENT_LANGUAGE***';
      }
      elseif ($list[$i] == 'default') {
        $list[$i] = language_default('language');
      }
    }
    $list = array_unique($list);
    $views_query = $this->query;

    /* @var $views_query views_plugin_query_default */

    // Now build the query. For every option, we need to exclude
    // the previous ones to ensure only one node gets selected in the end.
    $alias = $views_query
      ->ensure_table('node');

    // First include nodes that don't have translations.
    $query = "node.tnid = 0";
    $exclude = array();
    foreach ($list as $v) {
      if ($v == 'original') {

        // Include nodes that are the base of a translation (aka original).
        $add = "{$alias}.nid = {$alias}.tnid";
        $exc = "lmfh_node.tnid = lmfh_node.nid";
      }
      else {

        // Include nodes of specified language.
        $add = "{$alias}.language = '{$v}'";
        $exc = "lmfh_node.language = '{$v}'";
      }
      if (count($exclude)) {
        $add = $add . " AND\n          0 = (SELECT count(lmfh_node.nid)\n                 FROM {node} AS lmfh_node\n                WHERE lmfh_node.tnid = node.tnid AND\n                      ((" . implode(') OR (', $exclude) . ")))";
      }
      $exclude[] = $exc;
      $query = $query . "\n OR ({$add})";
    }
    $views_query
      ->add_where_expression($this->options['group'], $query);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
select_translation_filter_handler::$no_operator property Disable the possibility to use operators. Overrides views_handler_filter::$no_operator
select_translation_filter_handler::admin_summary function Returns admin summary of the filter options. Overrides views_handler_filter::admin_summary
select_translation_filter_handler::better_query function A query that doesn't use correlated sub-queries.
select_translation_filter_handler::default_join function The default join is currently not used.
select_translation_filter_handler::node_access_join function Join to the node table where the nodes have the given language.
select_translation_filter_handler::operator_form function Returns the operator form. Overrides views_handler_filter::operator_form
select_translation_filter_handler::option_definition function Returns an array of filter option defaults. Overrides views_handler_filter::option_definition
select_translation_filter_handler::original_query function This was the original correlated query, which is currently not used.
select_translation_filter_handler::query public function Executes the query. Overrides views_handler_filter::query
select_translation_filter_handler::value_form function Returns a form with configurable options. Overrides views_handler_filter::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_multiple public property Disable the possibility to force a single value. 6
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::$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::accept_exposed_input public function Check to see if input from the exposed filters should change the behavior. Overrides views_handler::accept_exposed_input 2
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::build_group_validate public function Validate the build group options form. 1
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_options public function Provide a list of options for the default operator form. 4
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::options_validate public function Simple validate handler. Overrides views_handler::options_validate 1
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_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_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