DocumentStorageService.php 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. <?php
  2. namespace Services;
  3. class DocumentStorageService
  4. {
  5. private string $rootDir;
  6. public function __construct(?string $rootDir = null)
  7. {
  8. $this->rootDir = $rootDir ?? ($_ENV['DOCUMENTS_ROOT'] ?? '/data/documents');
  9. }
  10. public function sanitizeDocumentType(string $documentType): string
  11. {
  12. $documentType = trim($documentType);
  13. $documentType = preg_replace('/[^a-zA-Z0-9._-]+/', '_', $documentType);
  14. $documentType = trim($documentType, '._-');
  15. if ($documentType === '') {
  16. throw new \RuntimeException('Invalid document_type');
  17. }
  18. return $documentType;
  19. }
  20. public function ensureDirectory(int $companyId, int $userId, string $documentType): string
  21. {
  22. $documentType = $this->sanitizeDocumentType($documentType);
  23. $dir = rtrim($this->rootDir, '/');
  24. $dir .= '/' . $companyId;
  25. $dir .= '/' . $userId;
  26. $dir .= '/' . $documentType;
  27. if (!is_dir($dir)) {
  28. if (!@mkdir($dir, 0775, true) && !is_dir($dir)) {
  29. throw new \RuntimeException('Failed to create documents directory');
  30. }
  31. }
  32. return $dir;
  33. }
  34. public function buildStoredFilename(string $originalFilename, ?string $contentType = null): string
  35. {
  36. $ext = pathinfo($originalFilename, PATHINFO_EXTENSION);
  37. $ext = $ext ? strtolower($ext) : '';
  38. if ($ext === '' && $contentType) {
  39. if (stripos($contentType, 'pdf') !== false) {
  40. $ext = 'pdf';
  41. }
  42. }
  43. $name = bin2hex(random_bytes(16));
  44. return $ext !== '' ? ($name . '.' . $ext) : $name;
  45. }
  46. public function writeFile(string $dir, string $filename, string $content): string
  47. {
  48. $dir = rtrim($dir, '/');
  49. $path = $dir . '/' . $filename;
  50. $bytes = @file_put_contents($path, $content, LOCK_EX);
  51. if ($bytes === false) {
  52. throw new \RuntimeException('Failed to write file');
  53. }
  54. return $path;
  55. }
  56. }