Я получаю сообщение об ошибке после написания кода с использованием 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_backend, Client $http_Client, ImmutableConfig $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->UAH, 2),
],
'usd' => [
'label' => $this->t('Dollar'),
'value' => round($data->rates->USD, 2),
],
'gbp' => [
'label' => $this->t('Pound sterling'),
'value' => round($data->rates->GBP, 2),
],
];
$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;
}
}
?>
В чем проблема? И как ее решить?
Комментарии
Это потому что в конструктор плагинов перед зависимостями ещё передаются дефинишн плагина, конфигурация и т.д. Поэтому проще инжектить зависмости прямо в create в обход конструктора:
https://druki.ru/wiki/9/services/dependency-injection#sovremennyy
Спасибо. А если все таки вот так делать:
Как должен выглядеть мой код в этом случае? Или подскажите как мой код должен выглядеть в предложенном вами варианте.
Когда написал вот так:
<?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_definition, CacheBackendInterface $cache_backend, Client $http_Client, ImmutableConfig $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')
);
}
Ошибка:
Может какой-то use нужен?