feat(documents) : filesystem storage, server-side pagination and PDF compression
- Add DocumentStorageService for file-based storage (replaces Base64 in DB) - Add DocumentServeController with /file and /download endpoints - Add DocumentUploadProcessor using FormData + filesystem storage - Add DocumentNormalizer exposing fileUrl/downloadUrl on all responses - Add DocumentFileCleanupListener for automatic file deletion - Add MigrateDocumentsToFilesystemCommand (Base64 → files, memory-safe) - Add ApiFilter (SearchFilter, ExistsFilter, OrderFilter) on Document entity - Add PdfCompressorService + refactor CompressPdfCommand for batch processing - Fix TypeMachine PUT: deserialize=false + validate=false to prevent UniqueEntity false positive and writableLink collection interference - Update CHANGELOG for v1.8.0 - Update frontend submodule Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,63 @@ namespace App\Service;
|
||||
|
||||
class PdfCompressorService
|
||||
{
|
||||
/**
|
||||
* Compress an actual PDF file on disk. Returns metadata or null if no gain.
|
||||
*
|
||||
* @return null|array{size: int, originalSize: int, saved: int}
|
||||
*/
|
||||
public function compressFile(string $absolutePath): ?array
|
||||
{
|
||||
exec('which qpdf', $qpdfPath, $returnCode);
|
||||
if (0 !== $returnCode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!file_exists($absolutePath)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$originalSize = filesize($absolutePath);
|
||||
if (false === $originalSize) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$tempOutput = tempnam(sys_get_temp_dir(), 'pdf_out_');
|
||||
|
||||
$command = sprintf(
|
||||
'qpdf --linearize --object-streams=generate %s %s 2>&1',
|
||||
escapeshellarg($absolutePath),
|
||||
escapeshellarg($tempOutput)
|
||||
);
|
||||
|
||||
exec($command, $cmdOutput, $returnCode);
|
||||
|
||||
if (0 !== $returnCode || !file_exists($tempOutput)) {
|
||||
@unlink($tempOutput);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$compressedSize = filesize($tempOutput);
|
||||
if (false === $compressedSize || $compressedSize >= $originalSize) {
|
||||
@unlink($tempOutput);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!rename($tempOutput, $absolutePath)) {
|
||||
@unlink($tempOutput);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'size' => $compressedSize,
|
||||
'originalSize' => $originalSize,
|
||||
'saved' => $originalSize - $compressedSize,
|
||||
];
|
||||
}
|
||||
|
||||
public function compressBase64Pdf(string $base64Data): ?array
|
||||
{
|
||||
// Check if qpdf is available
|
||||
|
||||
Reference in New Issue
Block a user