1

So I was making a custom block, and implemented the build() method.

public function build() {
    $result = $connection->db_query("SELECT n.title, u.uid, n.created    FROM node_field_data n, users u WHERE u.uid = n.uid AND n.type = :type ORDER BY n.created DESC LIMIT 5", array(
        'type' => 'article',
    ));
    $content = '';
    if ($result) {
        while ($row = $result->fetchAssoc()) {
            $content .= '<li>' . $row['title'] . '</li>';
        }
    } else {
        $content .= 'No blog posts to show';
    }

    return array(
        '#markup' => '<ul>' . $content . '</ul>',
    );
}

So this is a pretty basic helloworld kind of example calling the database. But db_query is deprecated with the following surgestion:

     * @deprecated as of Drupal 8.0.x, will be removed in Drupal 9.0.0. Instead, get
     *   a database connection injected into your service from the container and
     *   call query() on it. E.g.
     *   $injected_database->query($query, $args, $options);

The surgestion seemed kind of spacey not entirely knowing all of the expressions but i eventually fixed it with the following code:

    $connection = \Drupal::database();
    $result = $connection->query("SELECT n.title, u.uid, n.created FROM node_field_data n, users u WHERE u.uid = n.uid AND n.type = :type ORDER BY n.created DESC LIMIT 5", array(
        'type' => 'article',
    ));

to call the database.

My question is, \Drupal::database() is a static method, and i call it from inside of my own block, am i doing it wrong? or am i misunderstanding their meaning of dependency injection? if i had to do DI in other web programming i would find the DI container and configure it to give the database into my constructor or via a accessor method right?

Follow up questions is

  1. What exactly constitutes my container?

  2. What is "my service" referring to? my module maybe?

3

Yes, you are doing it wrong by calling \Drupal::database.

Look at Drupal\block_content\Plugin\Block\BlockContentBlock in core as an example. The create() method gets the services and passes them to the __construct() method. That is the proper way.

  • Okay, so i guess that the static create method are being called by the DI container? i then register the dependencies my block will need, and i accept them chronologically in the constructor, allright. But the example you linked uses the entityManagers loadEntityByUuid method, which is deprecated. I think the entity manager was the only dependency that looked like a "database thing". What object to do surgest i subscribe to in the create method? :). thanks for the answer btw. – DenLilleMand Dec 15 '15 at 15:28
  • Which service to inject? Probably entity.query and do this with an entity query (google it) instead of a direct database query. But looking at the query you wrote, this may be possible with a View that creates a block. – cilefen Dec 15 '15 at 15:55
  • Here is a video of a similar example, in a controller, not a block, with usage of the create() method (which by the way you seem to grasp, others may benefit): knpuniversity.com/screencast/drupal8-under-the-hood/… – cilefen Dec 15 '15 at 19:46

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.