dateiService = $dateiService; $this->cleanerService = $cleanerService; $this->tmpDir = $dateiService->getTmpPath(); $this->db = $db; $this->configurationService = $configurationService; $this->backupService = $backupService; $this->gateway = $gateway; $this->logger = $logger; } /** * @param array $options * * @throws DemoExporterException * @return void */ public function setDumpOptions($options = []) { try { $default = [ 'artikel' => 'artikel.geloescht !=1', ]; $options = array_merge($default, $options); foreach ($options as $table => $where) { $tableCleaned = $this->cleanerService->tryXssClean($table); $whereCleaned = ''; if (trim($where) !== '') { $whereCleaned = $this->cleanerService->tryXssClean($where); } $this->customDemoExporter[$tableCleaned] = $whereCleaned; } } catch (DemoExporterCleanerException $exception) { throw new DemoExporterException($exception->getMessage()); } $value = $this->valueToDB($this->customDemoExporter); $this->configurationService->trySetConfiguration(static::DEMO_EXPORTER_CONFIG_NAME, $value); } /** * @param array $value * * @return string */ private function valueToDB($value) { return base64_encode(serialize($value)); } /** * @param stdClass $config * * @return void */ public function export(stdClass $config) { $this->logger->write('--Begin--'); $customDemoExporter = $this->valueFromDB($config->demo_exporter_config); $this->zipFile = $config->options->zip_file; $tmpDirectory = $this->tmpDir . uniqid('', true) . DIRECTORY_SEPARATOR; if (!@mkdir($tmpDirectory, 0777, true) && !is_dir($tmpDirectory)) { throw new DemoExporterException(sprintf('Failed to create tmp Dir %s', $tmpDirectory)); } $this->db->perform("SET SESSION SQL_MODE='ALLOW_INVALID_DATES'"); $this->logger->write('Export DB data'); try { foreach ($customDemoExporter as $table => $where) { $tableTmpName = $table . '_' . time(); $sqlTableAndWhere = empty($where) ? $table : $table . ' WHERE ' . stripslashes($where); $sqlFrom = 'SELECT * FROM ' . $sqlTableAndWhere; if ($table === 'artikel') { $articleWhere = !empty($where) ? 'WHERE ' . stripslashes($where) . ' AND ' : 'WHERE '; $articleWhere .= '(v.gueltig_bis ="0000-00-00" OR v.gueltig_bis >NOW()) AND v.adresse IN(0,NULL) AND v.gruppe IN(0,NULL) AND artikel.geloescht !=1'; $sqlFrom = 'SELECT artikel.* FROM artikel AS `artikel` INNER JOIN verkaufspreise AS `v` ON(artikel.id=v.artikel) ' . $articleWhere . ' ORDER BY v.ab_menge'; $tmpSQL = 'CREATE TEMPORARY TABLE IF NOT EXISTS ' . $tableTmpName . ' ' . $sqlFrom; $this->db->perform($tmpSQL); $this->sqlTmpArticle = $tableTmpName; } $this->sqlToCSV($sqlFrom, $tmpDirectory, $table); } } catch (QueryFailureException $exception) { $this->logger->write('ERROR'); throw new DemoExporterException($exception->getMessage()); } catch (ExporterExceptionInterface $exception) { $this->logger->write('ERROR'); throw new DemoExporterException($exception->getMessage()); } $this->logger->write('Grab Data and files'); if (!empty($this->sqlTmpArticle)) { $this->grabArticleData($this->sqlTmpArticle, $tmpDirectory); } if ($this->zipExport($tmpDirectory)) { $this->logger->write('Create achieve'); $this->deleteDir($tmpDirectory); } $this->logger->write('--END--'); } /** * @param string $value * * @return mixed */ private function valueFromDB($value) { return unserialize(base64_decode($value)); } protected function sqlToCSV($sqlFrom, $tmpDirectory, $tableName) { $tableName = $tmpDirectory . $tableName . '.csv'; $data = $this->db->yieldAll($sqlFrom); $exporter = new CsvExporter(); $exporter->export($tableName, $data); } /** * @param $tableTmpName * @param $tmpDirectory */ private function grabArticleData($tableTmpName, $tmpDirectory) { if (empty($tableTmpName)) { throw new DemoExporterException('Table for grabbing is missing'); } $sql = 'SELECT a.id, dv.dateiname, dv.version, a.nummer FROM ' . $tableTmpName . ' AS `a` LEFT JOIN datei_stichwoerter AS `ds` ON (a.id=ds.parameter) INNER JOIN datei AS `d` ON (ds.datei=d.id) LEFT JOIN datei_version AS `dv` ON (d.id=dv.datei) WHERE LOWER(ds.objekt) =:object AND d.geloescht !=:deleted AND a.geloescht !=:deleted'; // SQL verkaufpreise $salePrices = 'SELECT v.* FROM ' . $tableTmpName . ' AS `a` INNER JOIN verkaufspreise AS `v` ON(a.id=v.artikel) WHERE (v.gueltig_bis ="0000-00-00" OR v.gueltig_bis >NOW()) AND v.adresse IN(0,NULL) AND v.gruppe IN(0,NULL) ORDER BY v.ab_menge'; $this->sqlToCSV($salePrices, $tmpDirectory, 'verkaufspreise'); try { $rows = $this->db->fetchAll($sql, ['object' => 'artikel', 'deleted' => 1]); } catch (DatabaseExceptionInterface $exception) { throw new DemoExporterException($exception->getMessage()); } $filesDir = $tmpDirectory . 'files' . DIRECTORY_SEPARATOR; if (!@mkdir($filesDir, 0777, true) && !is_dir($filesDir)) { throw new DemoExporterException(sprintf('Failed to create tmp Dir %s', $filesDir)); } foreach ($rows as $row) { $id = $row['id']; $articleNumber = $row['nummer']; $fileName = $row['dateiname']; $pathFile = $this->dateiService->tryGetDateiPfad($id); $finalName = $filesDir . $articleNumber . '_' . $fileName; if (file_exists($pathFile) && !copy($pathFile, $finalName)) { $this->logger->write('ERROR'); throw new DemoExporterException(sprintf('Failed to copy %s into tmp Dir %s', $pathFile, $finalName)); } } $this->db->perform('DROP TABLE IF EXISTS ' . $tableTmpName); } /** * @param string $tmpDirectory * * @throws DemoExporterException * * @return bool */ private function zipExport($tmpDirectory) { $rootPath = realpath($tmpDirectory); $oZip = new ZipArchive(); $zipFile = $this->tmpDir . $this->zipFile; if ($this->openZipObject($oZip, $zipFile, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) { $this->logger->write('ERROR'); throw new DemoExporterException(sprintf('Failure to create temporary file in "%s"', $this->tmpDir)); } try { /** @var RecursiveIteratorIterator $oFiles */ $oFiles = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($rootPath), RecursiveIteratorIterator::LEAVES_ONLY ); foreach ($oFiles as $name => $oFile) { /** @var SplFileInfo $oFile */ if (!$oFile->isDir()) { $filePath = $oFile->getRealPath(); $relativePath = substr($filePath, strlen($rootPath) + 1); $oZip->addFile($filePath, $relativePath); } } return $oZip->close(); } catch (Throwable $exception) { $this->logger->write('ERROR'); throw new DemoExporterException($exception->getMessage()); } } /** * @param ZipArchive $oZip * @param string $fileName * @param int $flags * * @return mixed */ protected function openZipObject($oZip, $fileName, $flags = 0) { return $oZip->open($fileName, $flags); } /** * @param string $dirPath * * @return bool */ private function deleteDir($dirPath) { if (is_dir($dirPath)) { if (substr($dirPath, strlen($dirPath) - 1, 1) !== '/') { $dirPath .= '/'; } $files = glob($dirPath . '*', GLOB_MARK); foreach ($files as $file) { if (is_dir($file)) { $this->deleteDir($file); } else { unlink($file); } } return rmdir($dirPath); } $this->logger->write('ERROR'); throw new DemoExporterException(sprintf('Deleted DIR %s failed', $dirPath)); } /** * @param string $zipFileName * * @throws DemoExporterException * * @return string */ public function getZippedFile($zipFileName) { $zippedFile = $this->tmpDir . $zipFileName; if (!file_exists($zippedFile)) { $this->logger->write('ERROR'); throw new DemoExporterException(sprintf('Zipped file %s cannot be found!', $zipFileName)); } return $zippedFile; } /** * @param array $xConfig * @param string $identifier * @param string $sParam * @param string $cronFile * * @throws Exception */ public function addToProcessStarter( $xConfig, $identifier = 'Demo Exporter Konfigurartion', $sParam = 'demo_exporter_cron', $cronFile = 'demo_exporter' ) { try { $rowDemoExporter = $this->gateway->getDemoExporterConfigurationValue(static::DEMO_EXPORTER_CONFIG_NAME); if (empty($rowDemoExporter)) { $this->logger->write('ERROR'); throw new DemoExporterException( sprintf('configuration value %s cannot be found !', static::DEMO_EXPORTER_CONFIG_NAME) ); } $xConfig['demo_exporter_config'] = $rowDemoExporter['wert']; $value = json_encode($xConfig); $this->backupService->addToProcessStarter($value, $identifier, $sParam, $cronFile); } catch (BackupModuleRuntimeException $exception) { $this->logger->write('ERROR'); throw new DemoExporterException($exception->getMessage()); } } }