0

I am trying to make a plugin that connects to a json endpoint on another drupal site. But im getting an error in my service class. Please help me understand what im doing wrong.

This is my service declaration in services.yml inside the module folder:

services:
  letter_query_client:
    class: Drupal\******\Plugin\views\LetterQueryClient
    argument: ['@http_client_factory']

This is my service class:

namespace Drupal\*******\Plugin\Views;

use Drupal\Component\Serialization\Json;


class LetterQueryClient {

  /**
   * @var \GuzzleHttp\Client
   */
  protected $client;

  /**
   * LetterQueryClient constructor.
   *
   * @param $http_client_factory
   */
  public function __construct($http_client_factory) {
    $this->http_client_factory = $http_client_factory;
    $this->client = $http_client_factory->fromOptions([
      'base_uri' => '**********',
    ]);
  }


  public function getLetters() {
    $response = $this->client->get('********');
    $data = Json::decode($response->getBody());
    return $data;
}

}

This is my views query:

<?php

namespace Drupal\*****\Plugin\views\Query;

use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\views\ResultRow;
use Drupal\views\ViewExecutable;
use Drupal\views\Plugin\views\query\QueryPluginBase;
use Drupal\views\Annotation\ViewsQuery;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Views query plugin
 *
 * @ViewsQuery(
 *   id = "views_*****",
 *   title = @Translation("Letter Query"),
 *   help = @Translation("Query against the API.")
 * )
 */

class ViewsLetterQuery extends QueryPluginBase implements ContainerFactoryPluginInterface {

  public function ensureTable($table, $relationship = NULL) {
    return '';
  }

  public function addField($table, $field, $alias = '', $params = []) {
    return $field;
  }

  /**
   * @var \Drupal\******\Plugin\views\LetterQueryClient
   */
  protected $LetterQueryClient;


  /**
   * ViewsLetterQuery constructor.
   *
   * @param array $configuration
   * @param $plugin_id
   * @param $plugin_definition
   * @param $LetterQueryClient
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, $LetterQueryClient) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->letter_query_client = $LetterQueryClient;

  }

  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('letter_query_client')

    );
  }

  public function execute(ViewExecutable $view) {
    $index = 0;
    if ($letter_items = $this->LetterQueryClient->getLetters()) {
      foreach ($letter_items as $letter_item) {
        $row['title'] = $letter_item['title'];
        $row['field_note'] = $letter_item['field_note'];
        $row['index'] = $index++;
        $view->result[] = new ResultRow($row);

      }

    }


  }

}
6
  • Sounds like you did not define the service in services.yml with an argument to construct it with.
    – Kevin
    Jun 5 at 20:16
  • How are you invoking this class? You've put it in a Plugin namespace, but I'm not sure if you intended to use Drupal's plugin system (typically a Drupal plugin has an annotation, for one; for another, I'm not sure that "Plugin\Views" is a namespace that Views module uses).
    – Les Lim
    Jun 5 at 21:29
  • Kevin I added the code to my declaration of the service in the service.yml file.
    – mfv
    Jun 6 at 13:55
  • Les I am trying to make a views plugin. I tweaked the namespace a bit to match the namespace of the view per your suggestions. Also i added the rest of my code.
    – mfv
    Jun 6 at 13:56
  • You just have a typo - argument should be arguments in .services.yml
    – Clive
    Jun 6 at 18:34
1

You must type-hint the parameters of your service's constructor, otherwise Symfony's auto-wire will not work:

namespace Drupal\*******\Plugin\Views;

use Drupal\Component\Serialization\Json;


class LetterQueryClient {

  /**
   * @var \GuzzleHttp\Client
   */
  protected $client;

  /**
   * LetterQueryClient constructor.
   *
   * @param $http_client_factory
   */
  public function __construct(Drupal\Core\Http\ClientFactory $http_client_factory) { // type-hint here
    $this->http_client_factory = $http_client_factory; // side note: this member variable is not defined
    $this->client = $http_client_factory->fromOptions([
      'base_uri' => '**********',
    ]);
  }

see https://symfony.com/doc/current/service_container.html#injecting-services-config-into-a-service

3
  • Thank you for the answer, I tried the type hint approach. Still getting the same error.
    – mfv
    Jun 6 at 15:15
  • Same for the views plugin (after the first three Drupal-plugin-specific parameters)
    – Hudri
    Jun 6 at 15:51
  • So I added the namespace for http_client_factory in the parameter annotation and that worked. Is that what you meant? I couldn't find anything in the documentation as to why it works that way.
    – mfv
    Jun 6 at 20:55

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.