You are here

class efq_views_plugin_query in EntityFieldQuery Views Backend 7

Hierarchy

Expanded class hierarchy of efq_views_plugin_query

1 string reference to 'efq_views_plugin_query'
efq_views_views_plugins in ./efq_views.views.inc
Implements hook_views_plugins().

File

./efq_views_plugin_query.inc, line 3

View source
class efq_views_plugin_query extends views_plugin_query {

  /**
   * The EntityFieldQuery object used for the query.
   */
  var $query;

  /**
   * Entity type, if set.
   */
  var $entity_type;

  /**
   * Constructor; Create the basic query object and fill with default values.
   */
  function init($base_table, $base_field, $options) {
    parent::init($base_table, $base_field, $options);
    $this->query = new EntityFieldQuery();
    $this->tables = array();

    // An entity type (such as EntityFieldQuery: Node) was selected.
    // We have entity type passed in as base table, prefixed with 'efq_'
    $entity_type = preg_replace('/^efq_/', '', $base_table);
    $this->entity_type = $entity_type;
    $this->query
      ->entityCondition('entity_type', $entity_type);
  }
  function option_definition() {
    $options = parent::option_definition();
    $options['field_language'] = array(
      'default' => '***CURRENT_LANGUAGE***',
    );
    $options['query_tags'] = array(
      'default' => array(),
    );
    return $options;
  }

  /**
   * Show field language settings if the entity type we are querying has
   * field translation enabled.
   * If we are querying multiple entity types, then the settings are shown
   * if at least one entity type has field translation enabled.
   */
  function options_form(&$form, &$form_state) {
    if (isset($this->entity_type)) {
      $entities = array();
      $entities[$this->entity_type] = entity_get_info($this->entity_type);
    }
    else {
      $entities = entity_get_info();
    }
    $has_translation_handlers = FALSE;
    foreach ($entities as $type => $entity_info) {
      if (!empty($entity_info['translation'])) {
        $has_translation_handlers = TRUE;
      }
    }
    if ($has_translation_handlers) {
      $languages = array(
        '***CURRENT_LANGUAGE***' => t("Current user's language"),
        '***DEFAULT_LANGUAGE***' => t("Default site language"),
        LANGUAGE_NONE => t('No language'),
      );
      $languages = array_merge($languages, locale_language_list());
      $form['field_language'] = array(
        '#type' => 'select',
        '#title' => t('Field Language'),
        '#description' => t('All fields which support translations will be displayed in the selected language.'),
        '#options' => $languages,
        '#default_value' => $this->options['field_language'],
      );
    }
    $form['query_tags'] = array(
      '#type' => 'textfield',
      '#title' => t('Query Tags'),
      '#description' => t('If set, these tags will be appended to the query and can be used to identify the query in a module. This can be helpful for altering queries.'),
      '#default_value' => implode(', ', $this->options['query_tags']),
      '#element_validate' => array(
        'views_element_validate_tags',
      ),
    );

    // The function views_element_validate_tags() is defined here.
    form_load_include($form_state, 'inc', 'views', 'plugins/views_plugin_query_default');
  }

  /**
   * Special submit handling.
   */
  function options_submit(&$form, &$form_state) {
    $element = array(
      '#parents' => array(
        'query',
        'options',
        'query_tags',
      ),
    );
    $value = explode(',', drupal_array_get_nested_value($form_state['values'], $element['#parents']));
    $value = array_filter(array_map('trim', $value));
    form_set_value($element, $value, $form_state);
  }

  /**
   * Builds the necessary info to execute the query.
   */
  function build(&$view) {
    $view
      ->init_pager($view);

    // Let the pager modify the query to add limits.
    $this->pager
      ->query();
    $count_query = clone $this->query;
    $count_query
      ->count(true);
    $view->build_info['efq_query'] = $this->query;
    $view->build_info['count_query'] = $count_query;
  }

  /**
   * This is used by the style row plugins for node view and comment view.
   */
  function add_field($base_table, $base_field) {
    return $base_field;
  }

  /**
   * This is used by the field field handler.
   */
  function ensure_table($table) {
    return $table;
  }

  /**
   * Executes the query and fills the associated view object with according
   * values.
   *
   * Values to set: $view->result, $view->total_rows, $view->execute_time,
   * $view->pager['current_page'].
   */
  function execute(&$view) {
    $query = $view->build_info['efq_query'];
    $count_query = $view->build_info['count_query'];
    $args = $view->build_info['query_args'];
    $query
      ->addMetaData('view', $view);
    $count_query
      ->addMetaData('view', $view);

    // Add the query tags.
    if (!empty($this->options['query_tags'])) {
      foreach ($this->options['query_tags'] as $tag) {
        $query
          ->addTag($tag);
        $count_query
          ->addTag($tag);
      }
    }
    $start = microtime(true);

    // Determine if the query entity type is local or remote.
    $remote = FALSE;
    $entity_controller = entity_get_controller($this->entity_type);
    if (module_exists('remote_entity') && is_a($entity_controller, 'RemoteEntityAPIDefaultController')) {

      // We're dealing with a remote entity so get the fully loaded list of
      // entities from its query class instead of EntityFieldQuery.
      $remote = TRUE;
      $remote_query = $entity_controller
        ->getRemoteEntityQuery();
      $remote_query
        ->buildFromEFQ($query);
      $remote_entities = $entity_controller
        ->executeRemoteEntityQuery($remote_query);
    }

    // if we are using the pager, calculate the total number of results
    if ($this->pager
      ->use_pager()) {
      try {

        //  Fetch number of pager items differently based on data locality.
        if ($remote) {

          // Count the number of items already received in the remote query.
          $this->pager->total_items = count($remote_entities);
        }
        else {

          /* !$remote */

          // Execute the local count query.
          $this->pager->total_items = $count_query
            ->execute();
        }
        if (!empty($this->pager->options['offset'])) {
          $this->pager->total_items -= $this->pager->options['offset'];
        }
        $this->pager
          ->update_page_info();
      } catch (Exception $e) {
        if (!empty($view->simpletest)) {
          throw $e;
        }

        // Show the full exception message in Views admin.
        if (!empty($view->live_preview)) {
          drupal_set_message($e
            ->getMessage(), 'error');
        }
        else {
          vpr('Exception in @human_name[@view_name]: @message', array(
            '@human_name' => $view->human_name,
            '@view_name' => $view->name,
            '@message' => $e
              ->getMessage(),
          ));
        }
        return;
      }
    }

    // Let the pager set limit and offset.
    $this->pager
      ->pre_execute($query, $args);
    if (!empty($this->limit) || !empty($this->offset)) {

      // We can't have an offset without a limit, so provide a very large limit instead.
      $limit = intval(!empty($this->limit) ? $this->limit : 999999);
      $offset = intval(!empty($this->offset) ? $this->offset : 0);

      // Set the range for the query.
      if ($remote) {

        // The remote query was already executed so slice the results as necessary.
        $remote_entities = array_slice($remote_entities, $offset, $limit, TRUE);
      }
      else {

        /* !$remote */

        // Set the range on the local query.
        $query
          ->range($offset, $limit);
      }
    }
    $view->result = array();
    try {

      // Populate the result array.
      if ($remote) {

        // Give each entity its ID and add it to the result array.
        foreach ($remote_entities as $entity_id => $entity) {
          $entity->entity_id = $entity_id;
          $entity->entity_type = $this->entity_type;
          $view->result[] = $entity;
        }
      }
      else {

        /* !$remote */

        // Execute the local query.
        $results = $query
          ->execute();

        // Load each entity, give it its ID, and then add to the result array.
        foreach ($results as $entity_type => $ids) {

          // This is later used for field rendering
          foreach (entity_load($entity_type, array_keys($ids)) as $entity_id => $entity) {
            $entity->entity_id = $entity_id;
            $entity->entity_type = $entity_type;
            $view->result[] = $entity;
          }
        }
      }
      $this->pager
        ->post_execute($view->result);
      if ($this->pager
        ->use_pager()) {
        $view->total_rows = $this->pager
          ->get_total_items();
      }
    } catch (Exception $e) {

      // Show the full exception message in Views admin.
      if (!empty($view->live_preview)) {
        drupal_set_message($e
          ->getMessage(), 'error');
      }
      else {
        vpr('Exception in @human_name[@view_name]: @message', array(
          '@human_name' => $view->human_name,
          '@view_name' => $view->name,
          '@message' => $e
            ->getMessage(),
        ));
      }
      return;
    }
    $view->execute_time = microtime(true) - $start;
  }
  function get_result_entities($results, $relationship = NULL) {
    $entity = reset($results);
    return array(
      $entity->entity_type,
      $results,
    );
  }
  function add_selector_orderby($selector, $order = 'ASC') {
    $views_data = views_fetch_data($this->base_table);
    $sort_data = $views_data[$selector]['sort'];
    switch ($sort_data['handler']) {
      case 'efq_views_handler_sort_entity':
        $this->query
          ->entityOrderBy($selector, $order);
        break;
      case 'efq_views_handler_sort_property':
        $this->query
          ->propertyOrderBy($selector, $order);
        break;
      case 'efq_views_handler_sort_field':
        $this->query
          ->fieldOrderBy($sort_data['field_name'], $sort_data['field'], $order);
        break;
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
efq_views_plugin_query::$entity_type property Entity type, if set.
efq_views_plugin_query::$query property The EntityFieldQuery object used for the query.
efq_views_plugin_query::add_field function This is used by the style row plugins for node view and comment view.
efq_views_plugin_query::add_selector_orderby function
efq_views_plugin_query::build function Builds the necessary info to execute the query. Overrides views_plugin_query::build
efq_views_plugin_query::ensure_table function This is used by the field field handler.
efq_views_plugin_query::execute function Executes the query and fills the associated view object with according values. Overrides views_plugin_query::execute
efq_views_plugin_query::get_result_entities function Returns the according entity objects for the given query results. Overrides views_plugin_query::get_result_entities
efq_views_plugin_query::init function Constructor; Create the basic query object and fill with default values. Overrides views_plugin_query::init
efq_views_plugin_query::options_form function Show field language settings if the entity type we are querying has field translation enabled. If we are querying multiple entity types, then the settings are shown if at least one entity type has field translation enabled. Overrides views_plugin_query::options_form
efq_views_plugin_query::options_submit function Special submit handling. Overrides views_plugin_query::options_submit
efq_views_plugin_query::option_definition function Information about options for all kinds of purposes will be held here. Overrides views_object::option_definition
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
views_plugin::$display public property The current used views display.
views_plugin::$plugin_name public property The plugin name of this plugin, for example table or full.
views_plugin::$plugin_type public property The plugin type of this plugin, for example style or query.
views_plugin::$view public property The top object of a view. Overrides views_object::$view 1
views_plugin::additional_theme_functions public function Provide a list of additional theme functions for the theme info page.
views_plugin::plugin_title public function Return the human readable name of the display.
views_plugin::theme_functions public function Provide a full list of possible theme templates used by this style.
views_plugin::validate public function Validate that the plugin is correct and can be saved. 3
views_plugin_query::$pager public property A pager plugin that should be provided by the display. 1
views_plugin_query::add_signature public function Add a signature to the query, if such a thing is feasible. 1
views_plugin_query::alter public function Let modules modify the query just prior to finalizing it. 1
views_plugin_query::get_aggregation_info public function Get aggregation info for group by queries. 1
views_plugin_query::options_validate public function Validate the options form. Overrides views_plugin::options_validate
views_plugin_query::query public function Generate a query and a countquery from all of the information supplied to the object. Overrides views_plugin::query 1
views_plugin_query::render_pager public function Render the pager, if necessary.
views_plugin_query::set_group_operator public function Control how all WHERE and HAVING groups are put together.
views_plugin_query::set_limit public function Set a LIMIT on the query, specifying a maximum number of results.
views_plugin_query::set_offset public function Set an OFFSET on the query, specifying a number of results to skip
views_plugin_query::set_where_group public function Create a new grouping for the WHERE or HAVING clause.
views_plugin_query::summary_title public function Returns the summary of the settings in the display. Overrides views_plugin::summary_title