FileUtils.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Service\Utils;
  4. use App\Entity\Core\File;
  5. use Mimey\MimeTypes;
  6. use Path\Exception\FileExistsException;
  7. use Path\Exception\FileNotFoundException;
  8. use Path\Exception\IOException;
  9. use Path\Path;
  10. use Symfony\Component\Config\FileLocator;
  11. class FileUtils
  12. {
  13. public function __construct()
  14. {
  15. }
  16. /**
  17. * Return a Path object
  18. * > Method is for testing purposes.
  19. *
  20. * @see https://path-php.net/api
  21. */
  22. protected function makePath(string $path): Path
  23. {
  24. return new Path($path);
  25. }
  26. /**
  27. * Return a FileLocator object
  28. * > Method is for testing purposes.
  29. *
  30. * @param array<string> $directories
  31. */
  32. protected function makeFileLocator(array $directories): FileLocator
  33. {
  34. return new FileLocator($directories);
  35. }
  36. /**
  37. * Return the mimetype corresponding to the given file extension.
  38. */
  39. public function getMimeTypeFromExt(string $ext): ?string
  40. {
  41. return (new MimeTypes())->getMimeType(ltrim($ext, '.'));
  42. }
  43. /**
  44. * Try to guess the mimetype from the filename.
  45. *
  46. * Return null if it did not manage to guess it.
  47. */
  48. public function guessMimeTypeFromFilename(string $filename): ?string
  49. {
  50. $ext = pathinfo($filename, PATHINFO_EXTENSION);
  51. if (empty($ext)) {
  52. return null;
  53. }
  54. return $this->getMimeTypeFromExt($ext);
  55. }
  56. /**
  57. * Test si le fichier passé en paramètre est une image.
  58. */
  59. public function isImage(File $file): bool
  60. {
  61. $mimetype = $file->getMimeType() ?? $this->guessMimeTypeFromFilename($file->getName());
  62. return boolval(preg_match('#^image#', $mimetype ?? ''));
  63. }
  64. /**
  65. * Génère un nom de fichier temporaire situé dans le répertoire var/tmp,
  66. * avec l'extension et le préfixe donnés.
  67. *
  68. * @throws \RuntimeException
  69. */
  70. public function getTempFilename(string $ext = 'tmp', string $prefix = ''): string
  71. {
  72. if (empty($ext)) {
  73. throw new \RuntimeException('Extension can not be empty');
  74. }
  75. $tempDir = PathUtils::getProjectDir().'/var/tmp';
  76. $this->makePath($tempDir)->mkdir(0777, true);
  77. return PathUtils::join($tempDir, uniqid($prefix).'.'.$ext);
  78. }
  79. /**
  80. * @throws IOException
  81. * @throws FileNotFoundException
  82. * @throws FileExistsException
  83. */
  84. public function rmIfExist(string $path): void
  85. {
  86. $this->makePath($path)->remove_p();
  87. }
  88. /**
  89. * Reads the content of a file.
  90. *
  91. * @param string $path the path to the file to be read
  92. *
  93. * @return string the content of the file
  94. *
  95. * @throws FileNotFoundException
  96. * @throws IOException
  97. */
  98. public function getFileContent(string $path): string
  99. {
  100. return $this->makePath($path)->getContent();
  101. }
  102. /**
  103. * Locate a file in the given directories and return its absolute path, or
  104. * null if no file were found.
  105. *
  106. * @param array<string> $directories
  107. */
  108. public function locate(array $directories, string $filename): ?string
  109. {
  110. $fileLocator = $this->makeFileLocator($directories);
  111. return $fileLocator->locate($filename, null, false)[0] ?? null;
  112. }
  113. /**
  114. * Recursively removes a directory and all its contents.
  115. *
  116. * @param string $path the path to the directory to be removed
  117. *
  118. * @throws FileNotFoundException
  119. * @throws IOException
  120. */
  121. public function rmTree(string $path): void
  122. {
  123. $this->makePath($path)->rmdir(true);
  124. }
  125. /**
  126. * List the files located in the given directory.
  127. *
  128. * @return list<string>
  129. *
  130. * @throws FileNotFoundException
  131. * @throws IOException
  132. */
  133. public function list(string $path, string $glob = '*'): array
  134. {
  135. $paths = $this->makePath($path)->glob($glob);
  136. return array_map('strval', $paths);
  137. }
  138. /**
  139. * Recursively remove a directory.
  140. */
  141. public static function rrmDir(string $path): void
  142. {
  143. if (!is_dir($path)) {
  144. throw new \RuntimeException(sprintf('Path %s is not a directory', $path));
  145. }
  146. $files = glob($path.'/*');
  147. foreach ($files as $file) {
  148. is_dir($file) ? self::rrmDir($file) : unlink($file);
  149. }
  150. rmdir($path);
  151. }
  152. }