Ошибка: TypeError: Argument 1 passed to ........ ::__construct() must implement interface Drupal\Core\Cache\CacheBackendInterface, array given, called in ....

Аватар пользователя Joseph Joseph 1 апреля в 12:44

Я получаю сообщение об ошибке после написания кода с использованием dependency injection:

TypeError: Argument 1 passed to Drupal\sydneypro_exchange_rates_block\Plugin\Block\ExchangeRatesBlock::__construct() must implement interface Drupal\Core\Cache\CacheBackendInterface, array given, called in /var/www/web/core/lib/Drupal/Core/Plugin/Factory/ContainerFactory.php on line 25 in Drupal\sydneypro_exchange_rates_block\Plugin\Block\ExchangeRatesBlock->__construct() (line 55 of modules/custom/sydneypro_exchange_rates_block/src/Plugin/Block/ExchangeRatesBlock.php).

ExchangeRatesBlock.php:

<?php

namespace Drupal\sydneypro_exchange_rates_block\Plugin\Block;

use 

Drupal\Core\Block\BlockBase;
use 
Drupal\Core\Cache\CacheBackendInterface;
use 
Drupal\Core\Config\ImmutableConfig;
use 
Drupal\Core\Render\Markup;
use 
GuzzleHttp\Client;
use 
GuzzleHttp\Exception\ConnectException;
use 
GuzzleHttp\Exception\RequestException;
use 
Psr\Container\ContainerInterface;

/**
 * Provides a block with Exchange Rates.
 *
 * @block(
 *   id = "block_exchange_rates",
 *   admin_label = @Translation("Exchange rates block"),
 * )
 */
class ExchangeRatesBlock extends BlockBase {

  

/**
   * Cache for Data.
   *
   * @var \Drupal\Core\Cache\CacheBackendInterface
   */
  
protected $cacheBackend;

  

/**
   * Guzzle Http Client.
   *
   * @var \GuzzleHttp\Client
   */
  
protected $httpClient;

  

/**
   * Configuration for module.
   *
   * @var \Drupal\Core\Config\ImmutableConfig
   */
  
protected $config;

  

/**
   * ExchangeRatesBlock constructor.
   *
   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
   *   The cacheBackendInterface.
   * @param \GuzzleHttp\Client $http_Client
   *   The httpclient.
   * @param \Drupal\Core\Config\ImmutableConfig $immutable_config
   *   The configuration.
   */
  
public function __construct(CacheBackendInterface $cache_backendClient $http_ClientImmutableConfig $immutable_config) {
    
$this->cacheBackend $cache_backend;
    
$this->httpClient $http_Client;
    
$this->config $immutable_config;
  }

  

/**
   * {@inheritdoc}
   */
  
public static function create(ContainerInterface $container) {
    return new static(
      
$container->get('cache.default'),
      
$container->get('http_client'),
      
$container->get('config.factory')
    );
  }

  

/**
   * {@inheritdoc}
   */
  
public function build() {
    
$client $this->httpClient;
    
$access_key $this->config->get('exchange.settings')->get('exchange_access_key');
    
$cid 'sydneypro_exchange_rates_block';

    try {
      if (

$cache $this->cacheBackend->get($cid)) {
        
$data $cache->data;
      }
      else {
        
$response $client->get('http://api.exchangeratesapi.io/v1/latest?access_key=' $access_key);
        
$response_data $response->getBody();
        
$data json_decode($response_data);
        
$this->cacheBackend->set($cid$data);
      }

      

$properties = [
        
'uah' => [
          
'label' => $this->t('Hryvnia'),
          
'value' => round($data->rates->UAH2),
        ],
        
'usd' => [
          
'label' => $this->t('Dollar'),
          
'value' => round($data->rates->USD2),
        ],
        
'gbp' => [
          
'label' => $this->t('Pound sterling'),
          
'value' => round($data->rates->GBP2),
        ],
      ];

      

$build = [];

      foreach (

$properties as $exchange_property => $data) {
        
$build[$exchange_property] = ['#type' => 'container'];
        
$build[$exchange_property]['label'] = ['#markup' => $data['label']];
        
$build[$exchange_property]['separator'] = ['#markup' => ': '];
        
$build[$exchange_property]['value'] = ['#markup' => $data['value']];
      }
      
$build[] = [
        
'#attached' => [
          
'library' => [
            
'sydneypro_exchange_rates_block/sydneypro_exchange_rates_block',
          ],
        ],
      ];

      return 

$build;
    }
    catch (
ConnectException $e) {
      return [
        
'#markup' => Markup::create('<h1>Internet, DNS, or other connection error</h1>'),
      ];
    }
    catch (
RequestException $e) {
      return [
        
'#markup' => Markup::create('<h1>Sorry, no data available</h1>'),
      ];
    }
  }

  

/**
   * Disable cache for a block because my own cache doesn't work with it.
   *
   * @return int
   *   return cacheMaxAge 0
   */
  
public function getCacheMaxAge() {
    return 
0;
  }

}

?>

В чем проблема? И как ее решить?

Лучший ответ

Аватар пользователя gun_dose gun_dose 1 апреля в 13:51
1

Это потому что в конструктор плагинов перед зависимостями ещё передаются дефинишн плагина, конфигурация и т.д. Поэтому проще инжектить зависмости прямо в create в обход конструктора:
https://druki.ru/wiki/9/services/dependency-injection#sovremennyy

Комментарии

Аватар пользователя gun_dose gun_dose 1 апреля в 13:51
1

Это потому что в конструктор плагинов перед зависимостями ещё передаются дефинишн плагина, конфигурация и т.д. Поэтому проще инжектить зависмости прямо в create в обход конструктора:
https://druki.ru/wiki/9/services/dependency-injection#sovremennyy

Аватар пользователя Joseph Joseph 1 апреля в 14:37

Спасибо. А если все таки вот так делать:

в конструктор плагинов перед зависимостями ещё передаются дефинишн плагина

Как должен выглядеть мой код в этом случае? Или подскажите как мой код должен выглядеть в предложенном вами варианте.

Когда написал вот так:

<?php  
  
/**
   * ExchangeRatesBlock constructor.
   * @param array $configuration
   *   The plugin configuration.
   * @param $plugin_id
   *   The plugin ID.
   * @param $plugin_definition
   *   The plugin definition.
   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
   *   The cacheBackendInterface.
   * @param \GuzzleHttp\Client $http_Client
   *   The httpclient.
   * @param \Drupal\Core\Config\ImmutableConfig $immutable_config
   *   The configuration.
   */
  
public function __construct(array $configuration$plugin_id$plugin_definitionCacheBackendInterface $cache_backendClient $http_ClientImmutableConfig $immutable_config) {
    
parent::__construct($configuration$plugin_id$plugin_definition);
    
$this->cacheBackend $cache_backend;
    
$this->httpClient $http_Client;
    
$this->config $immutable_config;
  }

  

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

 

?>

Ошибка:

The website encountered an unexpected error. Please try again later.
ArgumentCountError: Too few arguments to function Drupal\sydneypro_exchange_rates_block\Plugin\Block\ExchangeRatesBlock::__construct(), 3 passed in /var/www/web/core/lib/Drupal/Core/Plugin/Factory/ContainerFactory.php on line 25 and exactly 6 expected in Drupal\sydneypro_exchange_rates_block\Plugin\Block\ExchangeRatesBlock->__construct() (line 60 of modules/custom/sydneypro_exchange_rates_block/src/Plugin/Block/ExchangeRatesBlock.php).

Может какой-то use нужен?