fetch(['isbnIssn' => str_replace(['-', ' '], '', $number)]); } public function findByDescription(string $title, string $author, string $publisher): array { return $this->fetch(array_filter( ['title' => $title, 'author' => $author, 'publisher' => $publisher], static fn(string $value): bool => $value !== '', )); } /** * @param array $query * * @return list */ private function fetch(array $query): array { try { $response = $this->bnClient->request('GET', '/api/networks/bibs.json', [ 'query' => $query + ['limit' => self::LIMIT, 'kind' => 'książka'], ]); $records = $response->toArray()['bibs'] ?? []; } catch (ExceptionInterface $exception) { throw new LookupFailedException('The catalogue request failed.', previous: $exception); } return array_map(self::toCandidate(...), $records); } /** * @param array $record */ private static function toCandidate(array $record): BookCandidate { $number = preg_replace('/[^\dX]/', '', strtoupper((string)($record['isbnIssn'] ?? ''))) ?: null; $isIssn = $number !== null && \strlen($number) === 8; $year = (string)($record['publicationYear'] ?? ''); return new BookCandidate( title: trim((string)($record['title'] ?? ''), " \t\n\r/:;,."), author: self::firstPerson((string)($record['author'] ?? '')), language: self::blankToNull((string)($record['language'] ?? '')), publisher: self::singlePublisher((string)($record['publisher'] ?? '')), publicationLoc: self::blankToNull(trim(explode(':', (string)($record['placeOfPublication'] ?? ''))[0])), publicationYear: preg_match('/\d{4}/', $year, $match) === 1 ? (int)$match[0] : null, isbn: $isIssn ? null : $number, issn: $isIssn ? $number : null, ); } /** * "MacLean, Alistair (1922-1987) Ginalski, Robert ..." becomes "Alistair MacLean". */ private static function firstPerson(string $authors): ?string { $first = preg_split('/\s*\(\d{4}/', $authors, 2)[0]; $parts = array_map(trim(...), explode(',', rtrim($first, " .\t\n\r"))); return self::blankToNull(\count($parts) === 2 ? $parts[1] . ' ' . $parts[0] : implode(', ', $parts)); } private static function singlePublisher(string $publisher): ?string { $publisher = trim($publisher, " \t\n\r\",;:."); return self::blankToNull(preg_replace('/^(.+)\s+\1$/u', '$1', $publisher) ?? $publisher); } private static function blankToNull(string $value): ?string { return trim($value) === '' ? null : trim($value); } }