baseBatchSize = $baseBatchSize; $this->directoryList = $directoryList; $this->fileDriver = $fileDriver; } /** * Save to csv data with batches. * * @param string $file * @param array $data * @return $this */ public function save($file, array $data) { $file = $this->prepareFile($file); if (!count($data) || !$file) { return $this; } if (!file_exists($file)) { array_unshift($data, array_keys($data[0])); } $fh = fopen($file, 'a'); foreach ($data as $dataRow) { fputcsv($fh, $dataRow); } fclose($fh); return $this; } /** * Prepare CSV file name * * @param string $file * @return string | bool */ private function prepareFile($file) { $absolutePath = $this->directoryList->getPath(DirectoryList::VAR_DIR); if (!$this->fileDriver->isWritable($absolutePath)) { return false; } $dumpsPath = $absolutePath . DIRECTORY_SEPARATOR . self::DUMP_FOLDER; $this->ensureDirExists($dumpsPath); $filePath = $dumpsPath . DIRECTORY_SEPARATOR . $file . '.csv'; return $filePath; } /** * Create directory if not exists * * @param string $dir */ private function ensureDirExists($dir) { if (!$this->fileDriver->isExists($dir)) { $this->fileDriver->createDirectory($dir); } } /** * File read generator. * * This generator allows to load to memory only batch, with which we need to work at the moment * * @param string $file * @return \Generator */ public function read($file) { $file = $this->prepareFile($file); if (!$this->fileDriver->isReadable($file)) { return []; } $data = []; $iterator = 0; $fh = fopen($file, 'r'); $headers = fgetcsv($fh); $rowData = fgetcsv($fh); while ($rowData) { if ($iterator++ > $this->baseBatchSize) { $iterator = 0; $finalData = $data; $data = []; yield $this->processCsvData($finalData, $headers); } $data[] = $rowData; $rowData = fgetcsv($fh); } fclose($fh); yield $this->processCsvData($data, $headers); } /** * @param array $csvData * @param array $headers * @return array */ private function processCsvData(array $csvData, array $headers) { $result = []; foreach ($csvData as $rowIndex => $csvRow) { foreach ($csvRow as $index => $item) { $result[$rowIndex][$headers[$index]] = $item; } } return $result; } /** * @inheritdoc */ public function destruct($resource) { $file = $this->prepareFile($resource); if ($this->fileDriver->isExists($file)) { $this->fileDriver->deleteFile($file); } } }