27

I would like to get all nodes that are of my_custom_type type in Drupal 8.

I know I can get all the nodes (of any type) with \Drupal\node\Entity\Node::loadMultiple() and the list of all types by \Drupal\node\Entity\NodeType::loadMultiple().

But how to get only the nodes of given node type?

I really don't want to use specialized module for it (if it's possible), just keep it as simple as possible. I will use the solution in my custom module.

And loading all the nodes with \Drupal\node\Entity\Node::loadMultiple() and then check their type in foreach would hit the performance too much.

  • 1
    What do you mean filter by name? Why not build a Views page for that through the interface? It will construct the query for you, and you can add a filter where users can enter text to search. – prkos Jun 27 at 19:42
  • Because i want it inside a method, so can get them all without filter? i do filter later – David montera Jun 27 at 19:55
46

You can use Drupal::entityQuery() & Node::loadMultiple() to load all the nodes of your given type:

$nids = \Drupal::entityQuery('node')->condition('type','my_custom_type')->execute();
$nodes =  \Drupal\node\Entity\Node::loadMultiple($nids);
| improve this answer | |
  • 1
    Any way to do this generically for any entity type? You would think \Drupal::entityQuery($type)->condition('type',$bundle)>execute(); would work, but sadly no. – liquidcms Apr 14 '19 at 19:47
  • 1
    This answer is specific to node entities. Details will change for other entities. You should ask another question for a general case. – Shawn Conn Apr 14 '19 at 21:04
  • 6
    In OOP code this now is $nids = $this->entityTypeManager->getStorage('node')->getQuery()->condition('type','my_custom_type')->execute();. See drupal.org/node/2849874. – leymannx Oct 9 '19 at 19:19
23

Another way to do this would be using this snippet of code:

// Set properties to filter.
$values = [
  'type' => 'page',
];

// Get the nodes.
$nodes = \Drupal::entityTypeManager()
  ->getStorage('node')
  ->loadByProperties($values);
| improve this answer | |
8

Usually you need published nodes, not all.

$nids = \Drupal::entityQuery('node')
  ->condition('status', 1)
  ->condition('type', 'YOUR-NODE-TYPE')
  ->execute();
$nodes = \Drupal\node\Entity\Node::loadMultiple($nids);
| improve this answer | |
8

Its actually very easy,

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

If you would like all nodes also unpublished just use:

\Drupal::entityTypeManager()->getStorage('node')
  ->loadByProperties(['type' => 'content_type'])
| improve this answer | |
2

You want to use entity storage.

$storage = \Drupal::service('entity_type.manager')->getStorage('node');

There are two main ways to query for entities:

  1. Using entity storage's getQuery() method
$my_entity_ids = $storage->getQuery()
  ->condition('type', 'article')
  ->condition('status', 1)
  ->execute();

$my_entities = $storage->loadMultiple($my_entity_ids);
  1. Using entity_storage's loadByProperties() method
$my_entities = $storage->loadByProperties([
  'type' => 'article',
  'status' => 1,
]);

Either one is perfectly acceptable and just use whichever makes more sense in your situation.

Additionally, since it looks like you're doing this in a class of some sort, you can use Dependency Injection to inject the entity_type.manager service. This is well documented in this related post: How to inject a service in another service?

| improve this answer | |
1

Something that was, at one time, fairly simple to figure out and find documentation for has become quite a bit more confusing and hard to find. This is one of the top search results for this topic, so I want to take the time to post a solution I was able to put together using the new Methods.

My use case is getting a list of published nodes of a certain content type and publishing them to a page as XML to be consumed by a third party.

Here are my declarations. Some of them might be superfluous at this point, but I'm not done upgrading the code as of yet.

<?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;

Here's the code to just feed the object into the 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;
  }
}

If you need to massage the data, then you'll have to fill an array and make edits there. Of course, you can still serialize a standard library array.

/**
 * 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;
  }
}

Hope this helps.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.