AutorÃa | Ultima modificación | Ver Log |
<?phpdeclare(strict_types=1);namespace OpenSpout\Reader;use OpenSpout\Common\Exception\IOException;use OpenSpout\Reader\Exception\ReaderException;use OpenSpout\Reader\Exception\ReaderNotOpenedException;/*** @template T of SheetIteratorInterface** @implements ReaderInterface<T>*/abstract class AbstractReader implements ReaderInterface{/** @var bool Indicates whether the stream is currently open */private bool $isStreamOpened = false;/*** Prepares the reader to read the given file. It also makes sure* that the file exists and is readable.** @param string $filePath Path of the file to be read** @throws IOException If the file at the given path does not exist, is not readable or is corrupted*/public function open(string $filePath): void{if ($this->isStreamWrapper($filePath) && (!$this->doesSupportStreamWrapper() || !$this->isSupportedStreamWrapper($filePath))) {throw new IOException("Could not open {$filePath} for reading! Stream wrapper used is not supported for this type of file.");}if (!$this->isPhpStream($filePath)) {// we skip the checks if the provided file path points to a PHP streamif (!file_exists($filePath)) {throw new IOException("Could not open {$filePath} for reading! File does not exist.");}if (!is_readable($filePath)) {throw new IOException("Could not open {$filePath} for reading! File is not readable.");}}try {$fileRealPath = $this->getFileRealPath($filePath);$this->openReader($fileRealPath);$this->isStreamOpened = true;} catch (ReaderException $exception) {throw new IOException("Could not open {$filePath} for reading!",0,$exception);}}/*** Closes the reader, preventing any additional reading.*/final public function close(): void{if ($this->isStreamOpened) {$this->closeReader();$this->isStreamOpened = false;}}/*** Returns whether stream wrappers are supported.*/abstract protected function doesSupportStreamWrapper(): bool;/*** Opens the file at the given file path to make it ready to be read.** @param string $filePath Path of the file to be read*/abstract protected function openReader(string $filePath): void;/*** Closes the reader. To be used after reading the file.*/abstract protected function closeReader(): void;final protected function ensureStreamOpened(): void{if (!$this->isStreamOpened) {throw new ReaderNotOpenedException('Reader should be opened first.');}}/*** Returns the real path of the given path.* If the given path is a valid stream wrapper, returns the path unchanged.*/private function getFileRealPath(string $filePath): string{if ($this->isSupportedStreamWrapper($filePath)) {return $filePath;}// Need to use realpath to fix "Can't open file" on some Windows setup$realpath = realpath($filePath);\assert(false !== $realpath);return $realpath;}/*** Returns the scheme of the custom stream wrapper, if the path indicates a stream wrapper is used.* For example, php://temp => php, s3://path/to/file => s3...** @param string $filePath Path of the file to be read** @return null|string The stream wrapper scheme or NULL if not a stream wrapper*/private function getStreamWrapperScheme(string $filePath): ?string{$streamScheme = null;if (1 === preg_match('/^(\w+):\/\//', $filePath, $matches)) {$streamScheme = $matches[1];}return $streamScheme;}/*** Checks if the given path is an unsupported stream wrapper* (like local path, php://temp, mystream://foo/bar...).** @param string $filePath Path of the file to be read** @return bool Whether the given path is an unsupported stream wrapper*/private function isStreamWrapper(string $filePath): bool{return null !== $this->getStreamWrapperScheme($filePath);}/*** Checks if the given path is an supported stream wrapper* (like php://temp, mystream://foo/bar...).* If the given path is a local path, returns true.** @param string $filePath Path of the file to be read** @return bool Whether the given path is an supported stream wrapper*/private function isSupportedStreamWrapper(string $filePath): bool{$streamScheme = $this->getStreamWrapperScheme($filePath);return null === $streamScheme || \in_array($streamScheme, stream_get_wrappers(), true);}/*** Checks if a path is a PHP stream (like php://output, php://memory, ...).** @param string $filePath Path of the file to be read** @return bool Whether the given path maps to a PHP stream*/private function isPhpStream(string $filePath): bool{$streamScheme = $this->getStreamWrapperScheme($filePath);return 'php' === $streamScheme;}}