data_pipelines-1.x-dev/src/Plugin/DatasetSource/JsonSource.php
src/Plugin/DatasetSource/JsonSource.php
<?php
declare(strict_types=1);
namespace Drupal\data_pipelines\Plugin\DatasetSource;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\data_pipelines\Attribute\DatasetSource;
use Drupal\data_pipelines\DatasetData;
use Drupal\data_pipelines\Entity\Dataset;
use Drupal\data_pipelines\Entity\DatasetInterface;
use Drupal\data_pipelines\Source\DatasetSourceBase;
use Drupal\data_pipelines\Traits\FieldValueTrait;
use Drupal\data_pipelines\Traits\JsonPathTrait;
/**
* A class for providing json as a source.
*/
#[DatasetSource(
id: 'json',
label: new TranslatableMarkup('JSON'),
deriver: SourceDeriver::class,
)]
class JsonSource extends DatasetSourceBase {
use FieldValueTrait;
use JsonPathTrait;
/**
* {@inheritdoc}
*/
public function extractDataFromDataSet(DatasetInterface $dataset): \Generator {
try {
$resource = $this->getResource($dataset);
$json = json_decode(stream_get_contents($resource), TRUE);
if (!empty($json_path_to_data = $this->getJsonPathToData($dataset))) {
$json = $this->createJsonPath($json)->find($json_path_to_data)->getData();
}
if (is_array($json) && array_values($json) === $json) {
foreach ($json as $record) {
if (!is_array($record)) {
$record = [$record];
}
yield new DatasetData($record);
}
}
else {
yield new DatasetData($json);
}
fclose($resource);
}
catch (\Exception $e) {
$this->loggerChannel->critical($e->getMessage());
yield from [];
}
}
/**
* A method to get the field value of the plugins path to the data.
*
* @param \Drupal\data_pipelines\Entity\Dataset $dataset
* The dataset.
*
* @return string|null
* The path to the data or null.
*/
private function getJsonPathToData(Dataset $dataset): ?string {
return self::getFieldValue($dataset, $this->getJsonPathToDataField());
}
/**
* A method the get the field name of the plugins path to the data.
*
* @return string
* The field name.
*/
private function getJsonPathToDataField(): string {
return sprintf('%s_path_to_data', $this->getBaseId());
}
/**
* {@inheritdoc}
*/
public function buildFieldDefinitions(): array {
$base_field_definitions = parent::buildFieldDefinitions();
$extra_field_definitions = [
$this->getJsonPathToDataField() => BaseFieldDefinition::create('string')
->setLabel(new TranslatableMarkup('Path to data'))
->setDescription(new TranslatableMarkup("This value must be a <a href='@link' target='_blank'>JSON path</a> query expression. Follow the link for examples.", ['@link' => 'https://github.com/SoftCreatR/JSONPath']))
->setSetting('max_length', 255)
->setDisplayOptions('form', [
'type' => 'string_textfield',
])
->setPropertyConstraints('value', ['JsonPath' => []]),
];
return $extra_field_definitions + $base_field_definitions;
}
}
