feeds_ex-8.x-1.0-alpha4/src/Feeds/Parser/JsonPathParser.php
src/Feeds/Parser/JsonPathParser.php
<?php
namespace Drupal\feeds_ex\Feeds\Parser;
use Drupal\Core\Logger\RfcLogLevel;
use Drupal\feeds\FeedInterface;
use Drupal\feeds\Result\FetcherResultInterface;
use Drupal\feeds\Result\ParserResultInterface;
use Drupal\feeds\StateInterface;
use Flow\JSONPath\JSONPath;
use Flow\JSONPath\JSONPathLexer;
/**
* Defines a JSON parser using JSONPath.
*
* @FeedsParser(
* id = "jsonpath",
* title = @Translation("JsonPath"),
* description = @Translation("Parse JSON with JSONPath.")
* )
*/
class JsonPathParser extends JsonParserBase {
/**
* {@inheritdoc}
*/
protected function executeContext(FeedInterface $feed, FetcherResultInterface $fetcher_result, StateInterface $state) {
$raw = $this->prepareRaw($fetcher_result);
$parsed = $this->utility->decodeJsonArray($raw);
$parsed = $this->search($parsed, $this->configuration['context']['value']);
if (!$state->total) {
$state->total = count($parsed);
}
$start = (int) $state->pointer;
$state->pointer = $start + $this->configuration['line_limit'];
return array_slice($parsed, $start, $this->configuration['line_limit']);
}
/**
* {@inheritdoc}
*/
protected function cleanUp(FeedInterface $feed, ParserResultInterface $result, StateInterface $state) {
// Calculate progress.
$state->progress($state->total, $state->pointer);
}
/**
* {@inheritdoc}
*/
protected function executeSourceExpression($machine_name, $expression, $row) {
$result = $this->search($row, $expression);
if (is_scalar($result)) {
return $result;
}
// Return a single value if there's only one value.
return count($result) === 1 ? reset($result) : $result;
}
/**
* {@inheritdoc}
*/
protected function validateExpression(&$expression) {
$expression = trim($expression);
// Try to validate if possible.
if (!class_exists('Flow\JSONPath\JSONPathLexer')) {
return;
}
try {
$lexer = new JSONPathLexer($expression);
$lexer->parseExpression();
}
catch (\Exception $e) {
return $e->getMessage();
}
}
/**
* {@inheritdoc}
*/
protected function getErrors() {
if (!function_exists('json_last_error')) {
return [];
}
if (!$error = json_last_error()) {
return [];
}
$message = [
'message' => $this->utility->translateError($error),
'variables' => [],
'severity' => RfcLogLevel::ERROR,
];
return [$message];
}
/**
* Searches an array via JSONPath.
*
* @param array $data
* The array to search.
* @param string $expression
* The JSONPath expression.
*
* @return mixed
* The search results.
*/
protected function search(array $data, $expression) {
$json_path = new JSONPath($data);
return $json_path->find($expression)->getData();
}
/**
* {@inheritdoc}
*/
protected function loadLibrary() {
if (!class_exists('Flow\JSONPath\JSONPath')) {
throw new \RuntimeException('The JSONPath library is not installed.');
}
}
}
