Am un tip de nod articol cu un câmp care face referire la articole legate.
Dacă un articol are mai puțin de 4 referințe pentru acel câmp, trebuie să caut alte articole care
- nu sunt nodul curent
- au fost actualizate cu mai puțin de 2 ani în urmă
- bifați o casetă de selectare „favorită”.
- partajați cel puțin un id de cultură (referință taxonomie) ȘI cel puțin un id de temă (referință taxonomie)
Și de fapt mă întreb cum să îndeplinesc această ultimă nevoie...
Bazat pe Efectuați o interogare cu o condiție de câmp de entitate cu mai multe valori, am scris urmatorul cod:
<?php
spațiu de nume Drupal\modulul_meu\Preproces;
utilizați Drupal\Core\DependencyInjection\ContainerInjectionInterface;
utilizați Drupal\Core\Entity\EntityTypeManagerInterface;
utilizați Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Tipul de nod de preprocesare Articol.
*/
clasa MyArticle implementează ContainerInjectionInterface {
const MAX_RELATED_ARTICLES = 4;
/**
* Taxonomie termen de stocare.
*
* @var \Drupal\node\NodeStorage
*/
protejat $nodeStorage;
/**
* Constructor de clasă.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* Managerul de tip de entitate.
*/
funcția publică __construct(EntityTypeManagerInterface $entity_type_manager) {
$this->nodeStorage = $entity_type_manager->getStorage('nod');
}
/**
* {@inheritdoc}
*/
funcția publică statică create(ContainerInterface $container) {
returnează static nou (
$container->get('entity_type.manager')
);
}
/**
* Preprocesare articol tip nod.
*
* @param matrice $variabile
* O serie de variabile utilizate pentru a reda nodul.
*/
preprocesare a funcției publice (matrice &$variabile) {
if ('full' === $variables['view_mode']) {
$this->preprocessFull($variabile);
}
}
/**
* Preprocesează articolul de tip nod în modul de vizualizare complet.
*
* @param matrice $variabile
* O serie de variabile utilizate pentru a reda nodul.
*/
funcția protejată preprocessFull(array &$variables) {
$nod = $variabile['nod'];
$related_articles = $node->get('related_articles')->referencedEntities();
$themes = $node->get('themes')->referencedEntities();
$culture = $node->get('culturi')->referencedEntities();
$teme_ids = $culturi_ids = [];
foreach ($teme ca $term) {
$themes_ids[] = $term->id();
}
foreach ($culturi ca $term) {
$culturi_ids[] = $term->id();
}
$nb_related_articles = count($related_articles);
dacă ($nb_related_articles < self::MAX_RELATED_ARTICLES) {
$limit = self::MAX_RELATED_ARTICLES - $nb_related_articles;
$changed_boundary = strtotime('-2 ani');
$query = $this->nodeStorage->getQuery()
->condition('tip', 'articol')
->condition('status', 1)
->condition('nid', $node->id(), '<>')
->condition('favorit', 1)
->condition('schimbat', $changed_boundary, '>=')
->interval(0, $limit);
$sau_teme = $sau_culturi = $interogare->orConditionGroup();
foreach ($themes_ids ca $tid) {
$sau_teme->condition('culturi', $tid);
}
foreach ($cultures_ids ca $tid) {
$sau_culturi->condition('teme', $tid);
}
$și = $interogare->andConditionGroup()
->condition($or_themes);
$interogare->condiție($și);
$și = $interogare->andConditionGroup()
->condition($or_cultures);
$interogare->condiție($și);
$node_ids = $query->execute();
}
}
}
care îmi dă următoarea întrebare:
SELECTAȚI „base_table”. „vid” AS „vid”, „base_table”. „nid” AS „nid”
DIN „nod” „base_table”
INNER JOIN "node_field_data" "node_field_data" ON "node_field_data"."nid" = "base_table"."nid"
INNER JOIN "node__favorite" "node__favorite" ON "node__favorite"."entity_id" = "base_table"."nid"
LEFT JOIN "node__cultures" "node__cultures" ON "node__cultures"."entity_id" = "base_table"."nid"
LEFT JOIN "node__themes" "node__themes" ON "node__themes"."entity_id" = "base_table"."nid"
LEFT JOIN "node__cultures" "node__cultures_2" ON "node__cultures_2"."entity_id" = "base_table"."nid"
LEFT JOIN "node__themes" "node__themes_2" ON "node__themes_2"."entity_id" = "base_table"."nid"
WHERE ("node_field_data"."tip" = "articol")
ȘI ("node_field_data"."status" = "NODE_PUBLISHED")
ȘI ("node_field_data"."nid" <> '19533')
ȘI ("nod__favorite"."favorite_value" = "1")
ȘI ("node_field_data"."schimbat" >= '1583280325')
ȘI ("node__cultures"."cultures_target_id" = '5077') sau ("node__themes"."themes_target_id" = '42') sau ("node__themes"."themes_target_id" = '38'))
ȘI (("node__cultures_2"."cultures_target_id" = '5077') sau ("node__themes_2"."themes_target_id" = '42') sau ("node__themes_2"."themes_target_id" = '38'))
GROUP BY base_table.vid, base_table.nid
LIMITA 4 OFFSET 0
Și nu este ceea ce mă așteptam, deoarece am nevoie de o condiție AND între ID-urile culturii și ID-urile temei.
As avea nevoie de ceva de genul:
AND ("node__cultures"."cultures_target_id" = '5077') AND ("node__themes"."themes_target_id" = '42') sau ("node__themes"."themes_target_id" = '38')))
în loc de
ȘI ("node__cultures"."cultures_target_id" = '5077') sau ("node__themes"."themes_target_id" = '42') sau ("node__themes"."themes_target_id" = '38'))
Deci întrebarea mea este: există o modalitate de a realiza acest lucru cu And/OrConditionGroup sau ar trebui să folosesc subinterogări pentru a potrivi niște ID-uri specifice atât pentru teme, cât și pentru culturi?