Получить все узлы данного типа

21

Я хотел бы получить все узлы, которые имеют my_custom_typeтип в Drupal 8 .

Я знаю, что могу получить все узлы (любого типа) \Drupal\node\Entity\Node::loadMultiple()и список всех типов \Drupal\node\Entity\NodeType::loadMultiple().

Но как получить только узлы данного типа узла?

Я действительно не хочу использовать специализированный модуль для него (если это возможно), просто держите его как можно более простым. Я буду использовать решение в моем пользовательском модуле.

Загрузка всех узлов с \Drupal\node\Entity\Node::loadMultiple()последующим проверкой их типа foreachслишком сильно снизит производительность.

PolGraphic
источник

Ответы:

39

Вы можете использовать Drupal::entityQuery()& Node::loadMultiple()для загрузки всех узлов данного типа:

$nids = \Drupal::entityQuery('node')->condition('type','my_custom_type')->execute();
$nodes =  \Drupal\node\Entity\Node::loadMultiple($nids);
Шон Конн
источник
1
Любой способ сделать это в общем для любого типа объекта? Вы могли бы подумать, что \ Drupal :: entityQuery ($ type) -> условие ('type', $ bundle)> execute (); будет работать, но, к сожалению, нет.
liquidcms
1
Этот ответ специфичен для узловых объектов. Детали будут изменены для других лиц. Вы должны задать еще один вопрос для общего случая.
Шон Конн
3
В ООП-коде это сейчас есть $nids = $this->entityTypeManager->getStorage('node')->getQuery()->condition('type','my_custom_type')->execute();. См. Drupal.org/node/2849874 .
Leymannx
17

Другой способ сделать это - использовать этот фрагмент кода:

$values = [
  'type' => 'page'
];
$nodes = \Drupal::entityTypeManager()
  ->getStorage('node')
  ->loadByProperties($values);
MrD
источник
7

Обычно вам нужны опубликованные узлы, а не все.

$nids = \Drupal::entityQuery('node')
  ->condition('status', 1)
  ->condition('type', 'YOUR-NODE-TYPE')
  ->execute();
$nodes = \Drupal\node\Entity\Node::loadMultiple($nids);
Ориол Роселло
источник
7

На самом деле это очень легко,

\Drupal::entityTypeManager()->getStorage('node')
  ->loadByProperties(['type' => 'content_type', 'status' => 1])

Если вы хотите, чтобы все узлы также не публиковались, просто используйте:

\Drupal::entityTypeManager()->getStorage('node')
  ->loadByProperties(['type' => 'content_type'])
Ремко Хеневельд
источник
0

То, что когда-то было довольно просто выяснить и найти документацию, стало немного более запутанным и трудным для поиска. Это один из лучших результатов поиска по этой теме, поэтому я хочу выделить время, чтобы опубликовать решение, которое я смог собрать, используя новые методы.

Мой вариант использования - получить список опубликованных узлов определенного типа контента и опубликовать их на странице в виде XML для использования третьей стороной.

Вот мои заявления. Некоторые из них могут быть излишними на данный момент, но я еще не закончил обновление кода.

<?php
namespace Drupal\my_events_feed\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Component\Serialization;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\HttpFoundation\Response;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Entity\EntityTypeManager;

Вот код, чтобы просто передать объект в XML

/**
 * Class BuildXmlController.
 */
class BuildXmlController extends ControllerBase {
  /**
   * Builds the xml from an object
   */
  public function build() {
    $my_events = \Drupal::entityTypeManager()
    ->getStorage('node')
    ->loadByProperties([
      'status' => '1',
      'type' => 'submit_an_event',
    ]);

    $thisSerializer = \Drupal::service('serializer');
    $serializedData = $thisSerializer->serialize($my_events, 'xml', ['plugin_id' => 'entity']);

    $response = new Response();
    $response->headers->set('Content-Type', 'text/xml');
    $response->setContent($serializedData);
    return $response;
  }
}

Если вам нужно обработать данные, вам нужно будет заполнить массив и внести в него изменения. Конечно, вы все еще можете сериализовать стандартный библиотечный массив.

/**
 * Class BuildXmlController.
 */
class BuildXmlController extends ControllerBase {
  /**
   * Builds the xml from an array
   */
  public function build() {

    $my_events = \Drupal::entityTypeManager()
    ->getStorage('node')
    ->loadByProperties([
      'status' => '1',
      'type' => 'submit_an_event',
    ]);

    $nodedata = [];
    if ($my_events) {
      /*
      Get the details of each node and
      put it in an array.
      We have to do this because we need to manipulate the array so that it will spit out exactly the XML we want
       */
      foreach ($my_events as $node) {
        $nodedata[] = $node->toArray();
      }
    }

    foreach ($nodedata as &$nodedata_row) {
      /* LOGIC TO MESS WITH THE ARRAY GOES HERE */
    }

    $thisSerializer = \Drupal::service('serializer');
    $serializedData = $thisSerializer->serialize($nodedata, 'xml', ['plugin_id' => 'entity']);

    $response = new Response();
    $response->headers->set('Content-Type', 'text/xml');
    $response->setContent($serializedData);
    return $response;
  }
}

Надеюсь это поможет.

чокнутый
источник