prepareRaw($fetcher_result); $parsed = FeedsExJsonUtility::decodeJsonArray($raw); $parsed = $this->getParser()->search($parsed, $this->config['context']['value']); if (!is_array($parsed) || empty($parsed)) { throw new RuntimeException(t('The context expression must return an object or array.')); } $state = $source->state(FEEDS_PARSE); if (!$state->total) { $state->total = count($parsed); } $start = (int) $state->pointer; $state->pointer = $start + $source->importer->getLimit(); return array_slice($parsed, $start, $source->importer->getLimit()); } /** * {@inheritdoc} */ protected function cleanUp(FeedsSource $source, FeedsParserResult $result) { unset($this->parser); // Calculate progress. $state = $source->state(FEEDS_PARSE); $state->progress($state->total, $state->pointer); } /** * {@inheritdoc} */ protected function executeSourceExpression($machine_name, $expression, $row) { $result = $this->getParser()->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 { // Use class as string for PHP 5.2 compat. $class = 'Flow\JSONPath\JSONPathLexer'; $lexer = new $class($expression); $lexer->parseExpression(); } catch (Exception $e) { return check_plain($e->getMessage()); } } /** * {@inheritdoc} */ protected function startErrorHandling() { // Clear the json errors from previous parsing. json_decode('{}'); } /** * {@inheritdoc} */ protected function getErrors() { if (!function_exists('json_last_error')) { return array(); } if (!$error = json_last_error()) { return array(); } $message = array( 'message' => FeedsExJsonUtility::translateError($error), 'variables' => array(), 'severity' => WATCHDOG_ERROR, ); return array($message); } /** * {@inheritdoc} */ protected function loadLibrary() { if (!FeedsExJsonUtility::jsonPathParserInstalled()) { if (user_access('administer site configuration')) { $link = l(t('status report'), 'admin/reports/status'); } else { $link = t('status report'); } throw new RuntimeException(t('The JSONPath library is not installed. Check the !status_report_link for more info.', array( '!status_report_link' => $link, ))); } } /** * Returns the JSONPath parser. * * @return FeedsExJsonPathParserInterface * The JSONPath parser. */ protected function getParser() { if (!isset($this->parser)) { if (class_exists('Flow\JSONPath\JSONPath')) { $this->parser = new FeedsExJsonPathParserFlow(); } } if (!isset($this->parser)) { throw new RuntimeException(t('Could not load the JSONPath library.')); } return $this->parser; } } /** * Normalizes various JSONPath implementations. */ interface FeedsExJsonPathParserInterface { /** * Searches an array via JSONPath. * * @param array $data * The array to search. * @param string $expression * The JSONPath expression. * * @return mixed * The search results. */ public function search(array $data, $expression); } /** * Wraps the Flow JSONPath implementation. */ class FeedsExJsonPathParserFlow implements FeedsExJsonPathParserInterface { /** * {@inheritdoc} */ public function search(array $data, $expression) { // Use class string so that PHP 5.2 doesn't complain. $class = 'Flow\JSONPath\JSONPath'; $json_path = new $class($data); return $json_path->find($expression)->data(); } }