fh) { $this->fh = clone $this->fh; } } public function __construct(string $separator = ";", string $encoding = "UTF-8", $enclosure = '"', bool $readHeaderFields = true) { $this->separator = $separator; $this->encoding = $encoding; $this->enclosure = $enclosure; $this->readHeaderFields = $readHeaderFields; } public function __destruct() { $this->close(); } public function getFiletypeExtension(): string { return 'csv'; } public function open(string $file): bool { $this->fh = fopen($file, "r"); return false !== $this->fh; } public function isValid(): bool { try { $result = $this->read(function() {}); } catch (stTaskSchedulerImportReaderException $e) { $result = false; } $this->rewind(); return $result; } public function rewind(): void { rewind($this->fh); } public function count(): int { if (null === $this->count) { fseek($this->fh, 0, SEEK_END); $this->count = $this->getOffset(); $this->rewind(); } return $this->count; } public function setOffset(int $offset): void { fseek($this->fh, $offset); } public function getOffset(): int { return ftell($this->fh); } public function read(\Closure $callback): bool { if ($this->readHeaderFields) { $fields = $this->getFields(); if (!$this->getOffset() && $this->dataOffset) { $this->setOffset($this->dataOffset); } } $data = $this->getNextLine(); if ($data && $this->readHeaderFields) { $data = array_slice($data, 0, count($fields)); $combinedData = array_combine($fields, $data); if (false === $combinedData) { throw new stTaskSchedulerImportReaderException(sprintf("The number of header fields is not equal to the number of read data fields (fields: \"%s\", data: \"%s\")", implode('", "', $fields), implode('", "', $data) )); } $data = $combinedData; } if ($data) { if ("UTF-8" != $this->encoding) { $data = array_map(function($value) { return iconv($this->encoding, "UTF-8//TRANSLIT", $value); }, $data); } $callback($data); } return !empty($data); } public function close(): void { if ($this->fh) { fclose($this->fh); $this->fh = null; } } /** * Czyta i zwraca następna linię z pliku csv * * @return array|null */ private function getNextLine(): ?array { $data = fgetcsv($this->fh, null, $this->separator, $this->enclosure, "\0"); return false !== $data ? array_map('trim', $data) : null; } /** * Odczytuje nazwy pól * * @return array|null */ private function getFields(): ?array { $offset = $this->getOffset(); if (null === $this->fields) { if ($offset > 0) { $this->rewind(); } $this->fields = $this->getNextLine(); $this->dataOffset = $this->getOffset(); if ($offset > 0) { $this->setOffset($offset); } } return $this->fields; } }