* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development Wiki */ namespace VuFind\Marc; /** * MARC collection class for streaming a file. * * @category VuFind * @package MARC * @author Ere Maijala * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development Wiki */ class MarcCollectionFile implements \Iterator { /** * Supported serialization formats * * @var array */ protected $serializations = [ 'ISO2709' => Serialization\Iso2709::class, 'MARCXML' => Serialization\MarcXml::class, 'JSON' => Serialization\MarcInJson::class, ]; /** * Serialized format stream * * @var Serialization\SerializationFileInterface */ protected $stream; /** * Iteration position * * @var int */ protected $position = 0; /** * Current record * * @var string */ protected $record = ''; /** * Message callback * * @var callable */ protected $messageCallback; /** * Constructor * * @param string $file MARC record collection file in MARCXML or * ISO2709 format * @param callable $messageCallback Callback triggered for any messages with * message string and error level (similar to * https://www.php.net/manual/en/function.error-reporting.php) */ public function __construct(string $file = '', ?callable $messageCallback = null) { $this->messageCallback = $messageCallback; $this->setFile($file); } /** * Set MARC record file * * @param string $file MARC record collection file in MARCXML or ISO2709 format * * @throws \Exception * @return void */ public function setFile(string $file): void { if (!file_exists($file)) { throw new \Exception("File '$file' does not exist"); } $this->position = 0; $this->record = null; foreach ($this->serializations as $serialization) { if ($serialization::canParseCollectionFile($file)) { $this->stream = new $serialization(); if ( $this->stream instanceof Serialization\MessageCallbackInterface ) { $this->stream->setMessageCallback($this->messageCallback); } $this->stream->openCollectionFile($file); return; } } throw new \Exception('MARC collection file format not recognized'); } /** * Iterator: Rewind to the beginning. * * @return void */ public function rewind(): void { $this->stream->rewind(); $this->position = 0; $this->record = null; } /** * Iterator: Return current record. * * @return mixed */ #[\ReturnTypeWillChange] public function current() { if (null === $this->record) { $this->record = $this->stream->getNextRecord(); } return $this->record ? new MarcReader($this->record) : null; } /** * Iterator: Return current key. * * @return mixed */ #[\ReturnTypeWillChange] public function key() { return $this->position; } /** * Iterator: Advance to the next record. * * @return void */ public function next(): void { ++$this->position; $this->record = null; } /** * Iterator: Check if current position is valid. * * @return bool */ public function valid(): bool { if (null === $this->record) { $this->record = $this->stream->getNextRecord(); } return '' !== $this->record; } }