
| Current Path : /var/www/html1/bbp/web/modules/contrib/migrate_plus/src/Plugin/migrate_plus/data_parser/ |
Linux ift1.ift-informatik.de 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64 |
| Current File : /var/www/html1/bbp/web/modules/contrib/migrate_plus/src/Plugin/migrate_plus/data_parser/Json.php |
<?php
namespace Drupal\migrate_plus\Plugin\migrate_plus\data_parser;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\migrate_plus\DataParserPluginBase;
/**
* Obtain JSON data for migration.
*
* @DataParser(
* id = "json",
* title = @Translation("JSON")
* )
*/
class Json extends DataParserPluginBase implements ContainerFactoryPluginInterface {
/**
* Iterator over the JSON data.
*
* @var \Iterator
*/
protected $iterator;
/**
* Retrieves the JSON data and returns it as an array.
*
* @param string $url
* URL of a JSON feed.
*
* @return array
* The selected data to be iterated.
*
* @throws \GuzzleHttp\Exception\RequestException
*/
protected function getSourceData($url) {
$response = $this->getDataFetcherPlugin()->getResponseContent($url);
// Convert objects to associative arrays.
$source_data = json_decode($response, TRUE);
// If json_decode() has returned NULL, it might be that the data isn't
// valid utf8 - see http://php.net/manual/en/function.json-decode.php#86997.
if (is_null($source_data)) {
$utf8response = utf8_encode($response);
$source_data = json_decode($utf8response, TRUE);
}
// Backwards-compatibility for depth selection.
if (is_int($this->itemSelector)) {
return $this->selectByDepth($source_data);
}
// Otherwise, we're using xpath-like selectors.
$selectors = explode('/', trim($this->itemSelector, '/'));
foreach ($selectors as $selector) {
if (!empty($selector)) {
$source_data = $source_data[$selector];
}
}
return $source_data;
}
/**
* Get the source data for reading.
*
* @param array $raw_data
* Raw data from the JSON feed.
*
* @return array
* Selected items at the requested depth of the JSON feed.
*/
protected function selectByDepth(array $raw_data) {
// Return the results in a recursive iterator that can traverse
// multidimensional arrays.
$iterator = new \RecursiveIteratorIterator(
new \RecursiveArrayIterator($raw_data),
\RecursiveIteratorIterator::SELF_FIRST);
$items = [];
// Backwards-compatibility - an integer item_selector is interpreted as a
// depth. When there is an array of items at the expected depth, pull that
// array out as a distinct item.
$identifierDepth = $this->itemSelector;
$iterator->rewind();
while ($iterator->valid()) {
$item = $iterator->current();
if (is_array($item) && $iterator->getDepth() == $identifierDepth) {
$items[] = $item;
}
$iterator->next();
}
return $items;
}
/**
* {@inheritdoc}
*/
protected function openSourceUrl($url) {
// (Re)open the provided URL.
$source_data = $this->getSourceData($url);
$this->iterator = new \ArrayIterator($source_data);
return TRUE;
}
/**
* {@inheritdoc}
*/
protected function fetchNextRow() {
$current = $this->iterator->current();
if ($current) {
foreach ($this->fieldSelectors() as $field_name => $selector) {
$field_data = $current;
$field_selectors = explode('/', trim($selector, '/'));
foreach ($field_selectors as $field_selector) {
if (is_array($field_data) && array_key_exists($field_selector, $field_data)) {
$field_data = $field_data[$field_selector];
}
else {
$field_data = '';
}
}
$this->currentItem[$field_name] = $field_data;
}
if (!empty($this->configuration['include_raw_data'])) {
$this->currentItem['raw'] = $current;
}
$this->iterator->next();
}
}
}