View source
<?php
namespace Drupal\efq_views\Plugin\views\query;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
use Drupal\views\Plugin\views\query\QueryPluginBase;
use Drupal\views\ViewExecutable;
use Symfony\Component\DependencyInjection\ContainerInterface;
class EntityFieldQuery extends QueryPluginBase {
public $query;
protected $entityTypeManager;
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entityTypeManager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->entityTypeManager = $entityTypeManager;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return parent::create($container, $configuration, $plugin_id, $plugin_definition);
}
protected function getEntityTypeId() {
return 'node';
}
public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
parent::init($view, $display, $options);
$this->query = $this->entityTypeManager
->getStorage($this
->getEntityTypeId())
->getQuery();
$this->tables = array();
$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;
}
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',
),
);
form_load_include($form_state, 'inc', 'views', 'plugins/views_plugin_query_default');
}
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);
}
function build(&$view) {
$view
->init_pager($view);
$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;
}
function add_field($base_table, $base_field) {
return $base_field;
}
function ensure_table($table) {
return $table;
}
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);
if (!empty($this->options['query_tags'])) {
foreach ($this->options['query_tags'] as $tag) {
$query
->addTag($tag);
$count_query
->addTag($tag);
}
}
$start = microtime(true);
$remote = FALSE;
$entity_controller = entity_get_controller($this->entity_type);
if (module_exists('remote_entity') && is_a($entity_controller, 'RemoteEntityAPIDefaultController')) {
$remote = TRUE;
$remote_query = $entity_controller
->getRemoteEntityQuery();
$remote_query
->buildFromEFQ($query);
$remote_entities = $entity_controller
->executeRemoteEntityQuery($remote_query);
}
if ($this->pager
->use_pager()) {
try {
if ($remote) {
$this->pager->total_items = count($remote_entities);
}
else {
$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;
}
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;
}
}
$this->pager
->pre_execute($query, $args);
if (!empty($this->limit) || !empty($this->offset)) {
$limit = intval(!empty($this->limit) ? $this->limit : 999999);
$offset = intval(!empty($this->offset) ? $this->offset : 0);
if ($remote) {
$remote_entities = array_slice($remote_entities, $offset, $limit, TRUE);
}
else {
$query
->range($offset, $limit);
}
}
$view->result = array();
try {
if ($remote) {
foreach ($remote_entities as $entity_id => $entity) {
$entity->entity_id = $entity_id;
$entity->entity_type = $this->entity_type;
$view->result[] = $entity;
}
}
else {
$results = $query
->execute();
foreach ($results as $entity_type => $ids) {
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) {
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;
}
}
}