more_fields-2.2.19/src/Plugin/views/filter/MoreFieldsSearchApiTerm.php
src/Plugin/views/filter/MoreFieldsSearchApiTerm.php
<?php
namespace Drupal\more_fields\Plugin\views\filter;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\Element\EntityAutocomplete;
use Drupal\taxonomy\Entity\Term;
use Drupal\search_api\Entity\Index;
use Drupal\Core\Entity\Query\QueryInterface;
use Drupal\mysql\Driver\Database\mysql\Select;
use Drupal\monitoring_drupal\Services\TimerMonitoring;
use Drupal\search_api\Plugin\views\filter\SearchApiTerm;
/**
* Filter by term id.
* Permet de retouner les items de taxonomie possedant au moins une entité.
* plugin : search_api_term
*
* @ingroup views_filter_handlers
*/
class MoreFieldsSearchApiTerm extends SearchApiTerm implements FilterCountInterface {
use MoreFieldsBaseFilterSearchApi;
/**
* Sanitizes the HTML select element's options.
*
* The function is recursive to support optgroups.
*/
protected function prepareFilterSelectOptions(&$options) {
// On retourne les données sans les filtrées risque de securitée.
}
/**
* Copier de la ersion : Drupal core 9.5.9
*
* {@inheritdoc}
* @see \Drupal\taxonomy\Plugin\views\filter\TaxonomyIndexTid::valueForm()
*/
protected function valueForm(&$form, FormStateInterface $form_state) {
// xhprof_enable(XHPROF_FLAGS_NO_BUILTINS | XHPROF_FLAGS_CPU |
// XHPROF_FLAGS_MEMORY, [
// 'ignored_functions' => [
// 'Drupal\Core\*'
// ]
// ]);
// TimerMonitoring::start("valueForm");
// if ($this->realField == "field_angle_de_vision")
// dump($this->realField, $this->options);
$vocabulary = $this->vocabularyStorage->load($this->options['vid']);
if (empty($vocabulary) && $this->options['limit']) {
$form['markup'] = [
'#markup' => '<div class="js-form-item form-item">' . $this->t('An invalid vocabulary is selected. Please change it in the options.') . '</div>'
];
return;
}
if ($this->options['type'] == 'textfield') {
$terms = $this->value ? Term::loadMultiple(($this->value)) : [];
$form['value'] = [
'#title' => $this->options['limit'] ? $this->t('Select terms from vocabulary @voc', [
'@voc' => $vocabulary->label()
]) : $this->t('Select terms'),
'#type' => 'textfield',
'#default_value' => EntityAutocomplete::getEntityLabels($terms)
];
if ($this->options['limit']) {
$form['value']['#type'] = 'entity_autocomplete';
$form['value']['#target_type'] = 'taxonomy_term';
$form['value']['#selection_settings']['target_bundles'] = [
$vocabulary->id()
];
$form['value']['#tags'] = TRUE;
$form['value']['#process_default_value'] = FALSE;
}
}
else {
// Add custom code.
$terms = [];
$tids = $this->FilterCountEntitiesHasterm();
// End custom code
if (!empty($this->options['hierarchy']) && $this->options['limit']) {
$tree = $this->termStorage->loadTree($vocabulary->id(), 0, NULL, TRUE);
$options = [];
if ($tree) {
foreach ($tree as $term) {
if (!$term->isPublished() && !$this->currentUser->hasPermission('administer taxonomy')) {
continue;
}
$tid = $term->id();
// verification de l'affichage du terme.
if (empty($tids[$tid])) {
continue;
}
$choice = new \stdClass();
$label = str_repeat('-', $term->depth) . \Drupal::service('entity.repository')->getTranslationFromContext($term)->label();
if (!empty($this->countsTerms[$tid])) {
// on doit configurer cela, afin de pouvoir l'ajouter ou pas.
// on peut faire cela avec before et after.
// $label .= ' <span> (' . $this->countsTerms[$tid] . ')</span> ';
$label .= ' <span> ' . $this->countsTerms[$tid] . '</span> ';
}
$choice->option = [
$tid => $label
];
$options[] = $choice;
}
}
}
else {
$options = [];
// Pas utile mais doit etre ajouter dans le filtre de taxo.
// $query = \Drupal::entityQuery('taxonomy_term')->accessCheck(TRUE)->
// // @todo Sorting on vocabulary properties -
// // https://www.drupal.org/node/1821274.
// sort('weight')->sort('name')->addTag('taxonomy_term_access');
// if (!$this->currentUser->hasPermission('administer taxonomy')) {
// $query->condition('status', 1);
// }
// if ($this->options['limit']) {
// $query->condition('vid', $vocabulary->id());
// }
if ($tids) {
$terms = Term::loadMultiple($tids);
}
foreach ($terms as $term) {
// On ajoute le nombre de valeur
if ($this->options['show_entities_numbers'] && $this->countsTerms) {
$tid = $term->id();
$label = \Drupal::service('entity.repository')->getTranslationFromContext($term)->label();
if (!empty($this->countsTerms[$tid])) {
// on doit configurer cela, afin de pouvoir l'ajouter ou pas.
// on peut faire cela avec before et after.
// $label .= ' <span> (' . $this->countsTerms[$tid] . ')</span> ';
$label .= ' <span> ' . $this->countsTerms[$tid] . '</span> ';
}
$options[$tid] = $label;
}
else
$options[$term->id()] = \Drupal::service('entity.repository')->getTranslationFromContext($term)->label();
}
}
$default_value = (array) $this->value;
if ($exposed = $form_state->get('exposed')) {
$identifier = $this->options['expose']['identifier'];
if (!empty($this->options['expose']['reduce'])) {
$options = $this->reduceValueOptions($options);
if (!empty($this->options['expose']['multiple']) && empty($this->options['expose']['required'])) {
$default_value = [];
}
}
if (empty($this->options['expose']['multiple'])) {
if (empty($this->options['expose']['required']) && (empty($default_value) || !empty($this->options['expose']['reduce']))) {
$default_value = 'All';
}
elseif (empty($default_value)) {
$keys = array_keys($options);
$default_value = array_shift($keys);
}
// Due to #1464174 there is a chance that array('') was saved in the
// admin ui.
// Let's choose a safe default value.
elseif ($default_value == [
''
]) {
$default_value = 'All';
}
else {
$copy = $default_value;
$default_value = array_shift($copy);
}
}
}
$form['value'] = [
'#type' => 'select',
'#title' => $this->options['limit'] ? $this->t('Select terms from vocabulary @voc', [
'@voc' => $vocabulary->label()
]) : $this->t('Select terms'),
'#multiple' => TRUE,
'#options' => $options,
'#size' => min(9, count($options)),
'#default_value' => $default_value
];
$user_input = $form_state->getUserInput();
if ($exposed && isset($identifier) && !isset($user_input[$identifier])) {
$user_input[$identifier] = $default_value;
$form_state->setUserInput($user_input);
}
}
if (!$form_state->get('exposed')) {
// Retain the helper option
$this->helper->buildOptionsForm($form, $form_state);
// Show help text if not exposed to end users.
$form['value']['#description'] = $this->t('Leave blank for all. Otherwise, the first selected term will be the default instead of "Any".');
}
// TimerMonitoring::stop("valueForm");
// $xhprof_data = xhprof_disable();
// asort($xhprof_data);
// dump($xhprof_data);
}
/**
*
* {@inheritdoc}
* @see \Drupal\more_fields\Plugin\views\filter\FilterCountInterface::FilterCountEntitiesHasterm()
*/
public function FilterCountEntitiesHasterm(): array {
// TimerMonitoring::start('FilterCountEntitiesHasterm');
$tids = [];
// Pour determiner si la configuration de la vue est ok.
if (!$this->view->inited || $this->view->preview) {
return $tids;
}
$old_code = false;
if ($old_code) {
/**
* Contient les informations sur chaque filtre.
* On va ajouter les filtres statiques et aussi ajouter les filtre passé
* en paramettre via les filtres exposés.
*
* @var array $filters
*/
$defaultFilters = $this->view->filter;
// dump($defaultFilters);
$filters = [];
if ($defaultFilters) {
// foreach ($defaultFilters as $currentFilter) {
// //
// if ($currentFilter->getPluginId() == 'search_api_term' ||
// empty($currentFilter->options['exposed'])) {
// $filters[$currentFilter->realField] = $currentFilter;
// }
// }
$select_query = $this->buildBaseQuery();
$this->buildAnothersQuery($select_query);
// dd($select_query, $select_query->__toString());
$entities = $select_query->execute()->fetchAll(\PDO::FETCH_ASSOC);
// dump($this->realField, $entities);
foreach ($entities as $value) {
$this->countsTerms[$value[$this->realField]] = $value[$this->alias_count];
$tids[$value[$this->realField]] = $value[$this->realField];
}
// dump(Timer::stop('FilterCountEntitiesHasterm'));
}
}
else {
/**
*
* @var \Drupal\search_api\Query\Query $select_query
*/
$select_query = $this->buildBaseSql();
$this->buildAnothersQuery($select_query);
$entities = $select_query->execute()->fetchAll(\PDO::FETCH_ASSOC);
// dump($this->realField, $entities);
foreach ($entities as $value) {
$this->countsTerms[$value[$this->realField]] = $value[$this->alias_count];
$tids[$value[$this->realField]] = $value[$this->realField];
}
}
return $tids;
}
protected function applyQueryByPlugin(Select $select_query, \Drupal\search_api\Plugin\views\filter\SearchApiFulltext $search_api_fulltext) {
$index = Index::load("telephones");
$options = [];
/**
*
* @var \Drupal\search_api\Query\Query $queryIndex
*/
$queryIndex = \Drupal::service('search_api.query_helper')->createQuery($index, $options);
// Change the parse mode for the search.
$parse_mode = \Drupal::service('plugin.manager.search_api.parse_mode')->createInstance('direct');
$parse_mode->setConjunction('OR');
$queryIndex->setParseMode($parse_mode);
// dump($queryIndex);
$search_api_fulltext->value = "itel";
// $search_api_fulltext->query = $this->loadCustomSearchApiQuery();
// $search_api_fulltext->query
dump('custom query run', $search_api_fulltext);
$search_api_fulltext->query();
// dd($search_api_fulltext->query);
}
/**
*
* @return \Drupal\search_api\Plugin\views\query\SearchApiQuery
*/
protected function loadCustomSearchApiQuery() {
/**
*
* @var \Drupal\views\Plugin\ViewsPluginManager $PluginManager
*/
$PluginManager = \Drupal::service('plugin.manager.views.query');
/**
*
* @var \Drupal\search_api\Plugin\views\query\SearchApiQuery $search_api_query
*/
$search_api_query = $PluginManager->createInstance("custom_search_api_query");
return $search_api_query;
}
/**
* // on surcharge afin de tenir compte de specificité de searchApi.
* Construit les requetes statiques.
* ( permet d'ajouter ce prendre en compte les filtres definie au niveau de la
* vue ).
*/
protected function buildStaticQueryByViewsJoin(&$select_query, array $filters, string $base_table) {
foreach ($filters as $currentFilter) {
/**
*
* @var \Drupal\views\Plugin\views\filter\FilterPluginBase $currentFilter
*/
if ($currentFilter->options['exposed'] === FALSE) {
$table = $this->getTableNameFromIndex($currentFilter->table);
// Le cas ou le champs est inclus dans la table principal.
if ($select_query->hasTag('more_fields_checkbox_list__' . $table)) {
$this->buildCondition($select_query, $table, $currentFilter->realField, $currentFilter->options['value'], $currentFilter->operator);
}
}
}
}
/**
* Cette fonction n'est pas automatique, elle fonctionnera au cas par cas en
* attandant de la rendre dynamique.
*
* @param \Drupal\Core\Database\Query\Select $select_query
* @param array $arguments
* @param string $base_table
* @param string $field_id
*/
protected function buildFilterArguments(\Drupal\Core\Database\Query\Select &$select_query, array $arguments, array $args, string $base_table, string $field_id) {
$position = 0;
// cas : $base_table == node_field_data et argument => taxonomy_index
if ($base_table == 'node_field_data') {
foreach ($arguments as $argument) {
if (isset($args[$position])) {
$arg = $args[$position];
$position++;
}
// s'il nya pas d'argument on continue.
if (!isset($arg))
continue;
$configuration = [
'type' => 'INNER',
'table' => $argument->table,
'field' => 'nid',
'left_table' => $base_table,
'left_field' => $field_id,
'extra_operator' => 'AND',
'adjusted' => true
];
$table = [
'table' => $argument->table,
'num' => 1,
'alias' => $argument->tableAlias ? $argument->tableAlias : $argument->table,
// 'join'=>
'relationship' => $base_table
];
/**
*
* @var \Drupal\views\Plugin\views\argument\ArgumentPluginBase $argument
*/
if ($argument->table == 'taxonomy_index') {
/**
*
* @var \Drupal\views\Plugin\views\join\Standard $instance
*/
if (!$select_query->hasTag('more_fields_checkbox_list__' . $argument->table)) {
$instance = $this->initViewsJoin()->createInstance("standard", $configuration);
$instance->buildJoin($select_query, $table, $this->view->query);
$select_query->addTag('more_fields_checkbox_list__' . $argument->table);
}
$this->buildCondition($select_query, $table['alias'], $argument->realField, $arg, $argument->operator);
}
}
}
}
protected function exposedTranslate(&$form, $type) {
parent::exposedTranslate($form, $type);
// les types radios et checkboxes ne fonctionnent pas correctement use
// better_exposed_filters.
}
/**
* Retrieves a list of all available fulltext fields.
*
* @return string[] An options list of fulltext field identifiers mapped to
* their prefixed
* labels.
*/
protected function getFulltextFields() {
$fields = [];
/** @var \Drupal\search_api\IndexInterface $index */
$index = Index::load(substr($this->table, 17));
$fields_info = $index->getFields();
foreach ($index->getFulltextFields() as $field_id) {
$fields[$field_id] = $fields_info[$field_id]->getPrefixedLabel();
}
return $fields;
}
}