| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- <?php
- namespace Services;
- class DocumentStorageService
- {
- private string $rootDir;
- public function __construct(?string $rootDir = null)
- {
- $this->rootDir = $rootDir ?? ($_ENV['DOCUMENTS_ROOT'] ?? '/data/documents');
- }
- public function sanitizeDocumentType(string $documentType): string
- {
- $documentType = trim($documentType);
- $documentType = preg_replace('/[^a-zA-Z0-9._-]+/', '_', $documentType);
- $documentType = trim($documentType, '._-');
- if ($documentType === '') {
- throw new \RuntimeException('Invalid document_type');
- }
- return $documentType;
- }
- public function ensureDirectory(int $companyId, int $userId, string $documentType): string
- {
- $documentType = $this->sanitizeDocumentType($documentType);
- $dir = rtrim($this->rootDir, '/');
- $dir .= '/' . $companyId;
- $dir .= '/' . $userId;
- $dir .= '/' . $documentType;
- if (!is_dir($dir)) {
- if (!@mkdir($dir, 0775, true) && !is_dir($dir)) {
- $lastError = error_get_last();
- $root = rtrim($this->rootDir, '/');
- $rootParent = dirname($root);
- $debug = [
- 'root_dir' => $root,
- 'root_dir_exists' => is_dir($root),
- 'root_dir_writable' => is_writable($root),
- 'root_parent' => $rootParent,
- 'root_parent_exists' => is_dir($rootParent),
- 'root_parent_writable' => is_writable($rootParent),
- 'target_dir' => $dir,
- 'target_parent' => dirname($dir),
- 'target_parent_exists' => is_dir(dirname($dir)),
- 'target_parent_writable' => is_writable(dirname($dir)),
- 'php_user' => get_current_user(),
- 'euid' => function_exists('posix_geteuid') ? posix_geteuid() : null,
- 'last_error' => $lastError,
- ];
- throw new \RuntimeException('Failed to create documents directory: ' . json_encode($debug, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
- }
- }
- return $dir;
- }
- public function buildStoredFilename(string $originalFilename, ?string $contentType = null): string
- {
- $ext = pathinfo($originalFilename, PATHINFO_EXTENSION);
- $ext = $ext ? strtolower($ext) : '';
- if ($ext === '' && $contentType) {
- if (stripos($contentType, 'pdf') !== false) {
- $ext = 'pdf';
- }
- }
- $name = bin2hex(random_bytes(16));
- return $ext !== '' ? ($name . '.' . $ext) : $name;
- }
- public function writeFile(string $dir, string $filename, string $content): string
- {
- $dir = rtrim($dir, '/');
- $path = $dir . '/' . $filename;
- $bytes = @file_put_contents($path, $content, LOCK_EX);
- if ($bytes === false) {
- $lastError = error_get_last();
- $debug = [
- 'path' => $path,
- 'dir_exists' => is_dir($dir),
- 'dir_writable' => is_writable($dir),
- 'last_error' => $lastError,
- ];
- throw new \RuntimeException('Failed to write file: ' . json_encode($debug, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
- }
- return $path;
- }
- }
|