data_pipelines-1.x-dev/src/Source/Resource/Uri.php
src/Source/Resource/Uri.php
<?php
declare(strict_types=1);
namespace Drupal\data_pipelines\Source\Resource;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\data_pipelines\Entity\DatasetInterface;
use Drupal\link\LinkItemInterface;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Exception\GuzzleException;
/**
* A class for the uri resource.
*/
final class Uri extends SourceResourceBase {
/**
* The http client.
*
* @var \GuzzleHttp\ClientInterface
*/
protected $client;
/**
* The cache backend service.
*
* @var \Drupal\Core\Cache\CacheBackendInterface
*/
protected $cacheBackend;
/**
* The time service.
*
* @var \Drupal\Component\Datetime\TimeInterface
*/
protected $time;
/**
* The cache lifetime.
*
* @var int
*/
protected $cacheLifetime;
/**
* UriBase constructor.
*
* @param \GuzzleHttp\ClientInterface $client
* The http client service.
* @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
* The cache backend service.
* @param \Drupal\Component\Datetime\TimeInterface $time
* The time service.
* @param int $cache_lifetime
* The cache lifetime.
*/
public function __construct(ClientInterface $client, CacheBackendInterface $cache_backend, TimeInterface $time, int $cache_lifetime) {
$this->client = $client;
$this->cacheBackend = $cache_backend;
$this->time = $time;
$this->cacheLifetime = $cache_lifetime;
}
/**
* {@inheritdoc}
*/
public function getResourceBaseFieldDefinition(array $source_plugin_definition): BaseFieldDefinition {
return BaseFieldDefinition::create('link')
->setLabel(new TranslatableMarkup('Remote URL'))
->setDescription(new TranslatableMarkup('The URL of the remote dataset.'))
->setRequired(TRUE)
->setSettings([
'link_type' => LinkItemInterface::LINK_EXTERNAL,
'title' => DRUPAL_DISABLED,
])
->setDisplayOptions('form', [
'type' => 'link_default',
]);
}
/**
* {@inheritdoc}
*/
public function getResource(DatasetInterface $dataset, string $field_name): mixed {
if (!empty($uri = self::getFieldValue($dataset, $field_name))) {
$cid = sprintf('dataset:%s', $dataset->getMachineName());
if ($cached = $this->cacheBackend->get($cid)) {
return $this->getResourceFromData($cached->data);
}
try {
$response = $this->client->request('GET', $uri);
$data = (string) $response->getBody();
$this->cacheBackend->set($cid, $data, $this->time->getCurrentTime() + $this->cacheLifetime, $dataset->getCacheTags());
return $this->getResourceFromData($data);
}
catch (BadResponseException $e) {
$response = $e->getResponse();
$dataset->addLogMessage(sprintf('Error fetching %s: %s - %s', $uri, $response->getStatusCode(), $response->getReasonPhrase()));
}
catch (GuzzleException $e) {
$dataset->addLogMessage(sprintf('Error fetching %s: %s', $uri, $e->getMessage()));
}
}
return NULL;
}
/**
* Gets a resource from data.
*
* @param string $data
* Data to convert into a resource.
*
* @return resource|null
* Resource, or NULL on failure.
*/
protected function getResourceFromData(string $data) {
if ($resource = fopen('php://temp', 'r+')) {
fwrite($resource, $data);
rewind($resource);
return $resource;
}
return NULL;
}
}
