mirror of
https://github.com/OpenXE-org/OpenXE.git
synced 2024-12-27 07:00:29 +01:00
266 lines
7.5 KiB
PHP
266 lines
7.5 KiB
PHP
|
<?php
|
||
|
|
||
|
namespace Xentral\Modules\DownloadSpooler;
|
||
|
|
||
|
use erpAPI;
|
||
|
use Xentral\Components\Database\Database;
|
||
|
use Xentral\Modules\DownloadSpooler\Exception\InvalidArgumentException;
|
||
|
use Xentral\Modules\DownloadSpooler\Exception\RuntimeException;
|
||
|
use ZipArchive;
|
||
|
|
||
|
final class DownloadSpoolerService
|
||
|
{
|
||
|
/** @var Database $db */
|
||
|
private $db;
|
||
|
|
||
|
/**
|
||
|
* @deprecated
|
||
|
* @var erpAPI $erp
|
||
|
*/
|
||
|
private $erp;
|
||
|
|
||
|
/**
|
||
|
* @param Database $database
|
||
|
* @param erpAPI $erpApi
|
||
|
*/
|
||
|
public function __construct(Database $database, erpAPI $erpApi)
|
||
|
{
|
||
|
$this->db = $database;
|
||
|
$this->erp = $erpApi;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @example makeZipCompilation([3, 4, 5], 1)
|
||
|
*
|
||
|
* @param array $spoolerIds
|
||
|
* @param int $userId
|
||
|
* @param int|null $printerId
|
||
|
*
|
||
|
* @throws RuntimeException|InvalidArgumentException
|
||
|
*
|
||
|
* @return string Absolute path to zip file
|
||
|
*/
|
||
|
public function createZipCompilation($spoolerIds, $userId, $printerId = null)
|
||
|
{
|
||
|
$userId = $this->ensureUserId($userId);
|
||
|
if (empty($spoolerIds)) {
|
||
|
throw new InvalidArgumentException('Required argument "$spoolerIds" is empty.');
|
||
|
}
|
||
|
|
||
|
$select = $this->db
|
||
|
->select()
|
||
|
->cols(['ds.id', 'ds.zeitstempel', 'ds.filename', 'ds.content'])
|
||
|
->from('drucker_spooler AS ds')
|
||
|
->where('ds.id IN (?)', $spoolerIds)
|
||
|
->where('ds.user = ?', $userId);
|
||
|
|
||
|
if ($printerId !== null) {
|
||
|
$select->where('ds.drucker = ?', (int)$printerId);
|
||
|
}
|
||
|
|
||
|
$data = $this->db->fetchAll(
|
||
|
$select->getStatement(),
|
||
|
$select->getBindValues()
|
||
|
);
|
||
|
if (empty($data)) {
|
||
|
throw new RuntimeException('Data not found.');
|
||
|
}
|
||
|
|
||
|
$filePath = tempnam(sys_get_temp_dir(), 'spooler_zip');
|
||
|
$zip = new ZipArchive();
|
||
|
$zip->open($filePath, ZipArchive::CREATE);
|
||
|
foreach ($data as $row) {
|
||
|
$zip->addFromString(
|
||
|
"{$row['id']} {$row['zeitstempel']} {$row['filename']}",
|
||
|
base64_decode($row['content'])
|
||
|
);
|
||
|
}
|
||
|
$zip->close();
|
||
|
|
||
|
// Mark processed files as printed
|
||
|
$this->markFilesAsPrinted(array_column($data, 'id'), $printerId);
|
||
|
|
||
|
return $filePath;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @example makePdfCompilation([3, 4, 5], 1)
|
||
|
*
|
||
|
* @param array $spoolerIds
|
||
|
* @param int $userId
|
||
|
* @param int|null $printerId
|
||
|
*
|
||
|
* @throws RuntimeException|InvalidArgumentException
|
||
|
*
|
||
|
* @return string Absolute path to pdf compilation file
|
||
|
*/
|
||
|
public function createPdfCompilation($spoolerIds, $userId, $printerId = null)
|
||
|
{
|
||
|
$userId = $this->ensureUserId($userId);
|
||
|
if (empty($spoolerIds)) {
|
||
|
throw new InvalidArgumentException('Required argument "$spoolerIds" is empty.');
|
||
|
}
|
||
|
|
||
|
$select = $this->db
|
||
|
->select()
|
||
|
->cols(['ds.id', 'ds.content'])
|
||
|
->from('drucker_spooler AS ds')
|
||
|
->where('ds.id IN (?)', $spoolerIds)
|
||
|
->where('ds.user = ?', $userId);
|
||
|
|
||
|
if ($printerId !== null) {
|
||
|
$select->where('ds.drucker = ?', (int)$printerId);
|
||
|
}
|
||
|
|
||
|
$data = $this->db->fetchAll(
|
||
|
$select->getStatement(),
|
||
|
$select->getBindValues()
|
||
|
);
|
||
|
if (empty($data)) {
|
||
|
throw new RuntimeException('Data not found.');
|
||
|
}
|
||
|
|
||
|
// Save each file to temp dir
|
||
|
$tempPdfFiles = [];
|
||
|
foreach ($data as $row) {
|
||
|
$tempPdf = tempnam(sys_get_temp_dir(), 'spooler_pdf');
|
||
|
file_put_contents($tempPdf, base64_decode($row['content']));
|
||
|
$tempPdfFiles[] = $tempPdf;
|
||
|
}
|
||
|
|
||
|
// Create compilation from temporary files
|
||
|
$compilationPdf = $this->erp->MergePDF($tempPdfFiles); // @todo Refactor erpAPI out
|
||
|
$compilationPdfPath = tempnam(sys_get_temp_dir(), 'spooler_pdf');
|
||
|
file_put_contents($compilationPdfPath, $compilationPdf);
|
||
|
|
||
|
// Delete temporary files
|
||
|
foreach ($tempPdfFiles as $tempPdfFile) {
|
||
|
unlink($tempPdfFile);
|
||
|
}
|
||
|
|
||
|
// Mark processed files as printed
|
||
|
$this->markFilesAsPrinted(array_column($data, 'id'), $printerId);
|
||
|
|
||
|
return $compilationPdfPath;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get single spooler file as array
|
||
|
*
|
||
|
* @param int $fileId
|
||
|
* @param int $userId
|
||
|
*
|
||
|
* @throws RuntimeException If file id not exists
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function fetchFile($fileId, $userId)
|
||
|
{
|
||
|
$userId = $this->ensureUserId($userId);
|
||
|
|
||
|
$data = $this->db->fetchRow(
|
||
|
'SELECT d.filename, d.zeitstempel, d.content
|
||
|
FROM drucker_spooler AS d
|
||
|
WHERE d.id = :file_id AND d.user = :user_id',
|
||
|
['user_id' => $userId, 'file_id' => (int)$fileId]
|
||
|
);
|
||
|
if (empty($data)) {
|
||
|
throw new RuntimeException(sprintf('File ID%s not found.', $fileId));
|
||
|
}
|
||
|
|
||
|
$result = [
|
||
|
'filedate' => $data['zeitstempel'],
|
||
|
'filename' => $data['filename'],
|
||
|
'content' => $data['content'],
|
||
|
];
|
||
|
|
||
|
$this->markFilesAsPrinted([$fileId], $userId);
|
||
|
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param int $fileId
|
||
|
* @param int $printerId
|
||
|
*
|
||
|
* @return bool
|
||
|
*/
|
||
|
public function deleteFile($fileId, $printerId)
|
||
|
{
|
||
|
$fileId = (int)$fileId;
|
||
|
$printerId = (int)$printerId;
|
||
|
if ($fileId === 0 || $printerId === 0) {
|
||
|
throw new InvalidArgumentException('Required parameter "fileId" or "printerId" is empty.');
|
||
|
}
|
||
|
|
||
|
// Check that printer id and file id are joining
|
||
|
$checkPrinterId = (int)$this->db->fetchValue(
|
||
|
'SELECT d.drucker FROM drucker_spooler AS d WHERE d.id = :file_id',
|
||
|
['file_id' => $fileId]
|
||
|
);
|
||
|
if ($checkPrinterId !== $printerId) {
|
||
|
throw new InvalidArgumentException(sprintf(
|
||
|
'Parameter "fileId":"%s" and "printerId":"%s" are not joining.',
|
||
|
$fileId,
|
||
|
$printerId
|
||
|
));
|
||
|
}
|
||
|
|
||
|
$numRows = (int)$this->db->fetchAffected(
|
||
|
'DELETE FROM drucker_spooler WHERE id = :file_id AND drucker = :printer_id LIMIT 1',
|
||
|
['file_id' => $fileId, 'printer_id' => $printerId]
|
||
|
);
|
||
|
|
||
|
return $numRows === 1;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param array $spoolerIds
|
||
|
* @param int $userId
|
||
|
* @param int|null $printerId
|
||
|
*
|
||
|
* @throws InvalidArgumentException
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public function markFilesAsPrinted($spoolerIds, $userId, $printerId = null)
|
||
|
{
|
||
|
$userId = $this->ensureUserId($userId);
|
||
|
if (empty($spoolerIds)) {
|
||
|
throw new InvalidArgumentException('Required argument "$spoolerIds" is empty.');
|
||
|
}
|
||
|
|
||
|
$query = $this->db
|
||
|
->update()
|
||
|
->table('drucker_spooler')
|
||
|
->set('gedruckt', 1)
|
||
|
->where('id IN (?)', $spoolerIds)
|
||
|
->where('user = ?', $userId);
|
||
|
|
||
|
if ($printerId !== null) {
|
||
|
$query->where('drucker = ?', (int)$printerId);
|
||
|
}
|
||
|
|
||
|
$this->db->perform(
|
||
|
$query->getStatement(),
|
||
|
$query->getBindValues()
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param int $userId
|
||
|
*
|
||
|
* @throws InvalidArgumentException
|
||
|
*
|
||
|
* @return int
|
||
|
*/
|
||
|
private function ensureUserId($userId)
|
||
|
{
|
||
|
if (empty($userId) || (int)$userId < 0) {
|
||
|
throw new InvalidArgumentException('Required argument "userId" is empty or invalid.');
|
||
|
}
|
||
|
|
||
|
return (int)$userId;
|
||
|
}
|
||
|
}
|