5

When i checked DrupalPractice standard using phpcs (phpcs --standard=DrupalPractice /path/to/myController ) for a controller file am getting the following warning

WARNING | Node::load calls should be avoided in classes, use dependency injection instead

Am loading the node data as follows :

use Drupal\node\Entity\Node;

public function content_load($node = NULL) {
 $noad_data = Node::load($node, NULL, TRUE);
}

How do i use dependancy Injection to load the node data instead ?

  • Use entity_type.manager in your constructor(potentially use create() method if you are using DI directly as service for example) and in there use something like $this->storage = $entity_type_manager->getStorage('node') and in your method just call $this->storage->load($id) – user21641 Mar 31 '17 at 10:08
  • can u add it as a code sample , its bit unclear – Crazyrubixfan Mar 31 '17 at 10:11
  • See 4k4's answer, it is correct. – Kevin Mar 31 '17 at 13:14
12

The controller base class provides the method entityTypeManager() which gets the service with the same name from the container the first time you use it. You can use this service to get the node storage:

  $node_storage = $this->entityTypeManager()->getStorage('node');

and then load the node:

  $node = $node_storage->load($nid);
  • Shouldn't this be $node_storage = $this->entityTypeManager->getStorage('node');? Without the parenthesis after entityTypeManager? – leymannx Nov 5 at 12:55
  • 1
    No, not if you use the utility base class for thin controllers ControllerBase. This class exists so that the average user doesn't need to write that ugly pair of factory method and constructor, which you can avoid also by simply putting the controller method in a normal service and inject via container arguments. – 4k4 Nov 5 at 13:33
7

I'm not a 100% sure but this is how I got it working for a block (the node(s) didn't come from context):

<?php

namespace Drupal\MYMODULE\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;

/**
 * Provides a 'My Block' Block.
 *
 * @Block(
 *   id = "my_block",
 *   admin_label = @Translation("My Block"),
 * )
 */
class MyBlock extends BlockBase implements ContainerFactoryPluginInterface {

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Constructs a new MyBlock.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param array $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager service.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->entityTypeManager = $entity_type_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('entity_type.manager')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function build() {

    $node_storage = $this->entityTypeManager->getStorage('node');

    $node = $node_storage->load(1);

    return [
      '#markup' => $node->getTitle(),
    ];
  }

}
  • I don't really see how it's relevant to the original question: - why context should provide nodes? And what does it have to do that you then loaded node id:1? - Mentioning ContainerFactoryPluginInterface in general has nothing to do that you should always use storage injection loading entities. It's a different topic. – ssibal Mar 1 at 16:31
  • @ssibal – Normally, in a block, you can simply get the current node from the block context. In my case, I got some entity IDs from a database query, and then needed to load them. No context. That's why I called in entityTypeManager. ->load(1) is a placeholder. How you get your entity IDs depends on your own logic. I just extended the accepted answer to have a fully working code snippet. How would you have solved that challenge? What's your fully working code answer to the asked question? – leymannx Mar 1 at 17:18
  • 2
    While the context is slightly different, the answer still shows how to load an entity using dependency injection without using a static method of a class. This answer is not about block context. I take it as saying I would do it in the same way I would do it in a block plugin. – kiamlaluno Mar 6 at 10:57

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.