http = $httpClient; $this->generator = $generator; $this->objectWrapper = $objectWrapper; $this->parser = new Parser(); $this->feedReader = new XMLFeedReader(); $this->setFeedGenerator($generator); } private function initParser(array $feedRow): void { $cache = new ExternalFeedCache($feedRow); $this->parser->loadFile($cache->getDescriptionUrl()); } /** * @throws UnreadableXMLException */ private function initReader(array $feedRow, ?array $basePath = null): void { $cache = new ExternalFeedCache($feedRow, $basePath); $this->feedReader->openFile($cache->getSourceUrl()); } /** * Called from template, shows in data tab in feed configuration. */ public function fetchDataDescription(array $feedRow): array { if (is_string($feedRow['data'])) { $feedRow['data'] = json_decode($feedRow['data'], true); } $this->initParser($feedRow); $data = $this->parser->getFeedRootElement()->serialize(); $data['children'] = $data['children'] ?? []; $data['children'][] = ['type' => 'xs:string', 'name' => '__search', 'minOccurs' => '0']; usort($data['children'], function ($a, $b) { return strcmp($a['name'], $b['name']); }); return $data; } private function doSearch(string $searchQuery): ?array { try { return $this->feedReader->findElementBySearchAttribute($searchQuery); } catch (XMLFeedReaderException $e) { } return null; } /** * @throws XSDParsingException|XMLFeedReaderException */ public function getData(array $feedRow, ?int $limit = null): \Generator { if (is_string($feedRow['data'])) { $feedRow['data'] = json_decode($feedRow['data'], true); } $this->initParser($feedRow); $feedElementPath = $this->parser->getFeedRootElementPath(); $types = $this->parser->getTypeConstraints(); $this->initReader($feedRow, $feedElementPath); $this->feedReader->setBasePath($feedElementPath); $this->feedReader->setTypeCorrectionMap($types); if ($this->searchValue !== null) { $cache = new ExternalFeedCache($feedRow, $feedElementPath); $res = $cache->getCacheItem($this->searchValue); if ($res !== null) { return yield $this->prepareSingleObject($res); } $found = $this->doSearch($this->searchValue); if ($found === null) { return new \EmptyIterator(); } else { $res = $found; $cache->setCacheItem($this->searchValue, $res); } return yield $this->prepareSingleObject($res); } $counter = 0; foreach ($this->feedReader->read() as $feedItem) { if ($limit !== null && $counter >= $limit) { break; } yield $this->prepareSingleObject($feedItem); $counter++; } } public function getDataNoThrow(array $feedRow, ?int $limit = null): \Generator { try { $data = $this->getData($feedRow, $limit); foreach ($data as $elem) { yield $elem; } } catch (\Throwable $ignore) { return new \EmptyIterator(); } } public function fetchDataDescriptionNoThrow(array $feedRow): array { try { return $this->fetchDataDescription($feedRow); } catch (\Throwable $ignore) { return []; } } public function filterByObjectID($objectID): void { $this->searchValue = trim($objectID); } }