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;
clasa MyArticle implementează ContainerInjectionInterface {
const MAX_RELATED_ARTICLES = 4;
protejat $nodeStorage;
funcția publică __construct(EntityTypeManagerInterface $entity_type_manager) {
$this->nodeStorage = $entity_type_manager->getStorage('nod');
}
funcția publică statică create(ContainerInterface $container) {
returnează static nou (
$container->get('entity_type.manager')
);
}
preprocesare a funcției publice (matrice &$variabile) {
if ('full' === $variables['view_mode']) {
$this->preprocessFull($variabile);
}
}
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?