src/Service/FileUploader.php line 53

Open in your IDE?
  1. <?php
  2. namespace App\Service;
  3. use App\Entity\DeliveryMan;
  4. use App\Entity\Document;
  5. use App\Entity\Rib;
  6. use App\Entity\TypeDocument;
  7. use App\Entity\Variables\DelivererDocumentStatus;
  8. use App\Enum\TypeDocumentEnum;
  9. use App\Repository\DocumentRepository;
  10. use Doctrine\ORM\EntityManagerInterface;
  11. use Doctrine\Persistence\ManagerRegistry;
  12. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  13. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  14. use Symfony\Component\Filesystem\Filesystem;
  15. use Symfony\Component\Form\FormInterface;
  16. use Symfony\Component\HttpFoundation\File\Exception\FileException;
  17. use Symfony\Component\HttpFoundation\File\UploadedFile;
  18. use Symfony\Component\HttpFoundation\Request;
  19. use Symfony\Component\HttpFoundation\Response;
  20. use Symfony\Component\Security\Core\User\UserInterface;
  21. use Symfony\Component\String\Slugger\SluggerInterface;
  22. class FileUploader
  23. {
  24. public function __construct(
  25. private string $targetDirectory,
  26. private SluggerInterface $slugger,
  27. private ManagerRegistry $doctrine,
  28. private DocumentRepository $documentRepository,
  29. private EntityManagerInterface $entityManager,
  30. private Filesystem $fileSystem,
  31. ) {
  32. }
  33. /**
  34. * @return string
  35. */
  36. public function getOriginalFileName(UploadedFile $file)
  37. {
  38. return pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
  39. }
  40. public function getUniqueFileName(UploadedFile $file): string
  41. {
  42. $originalFilename = $this->getOriginalFileName($file);
  43. $safeFilename = $this->slugger->slug($originalFilename);
  44. return $safeFilename.'-'.uniqid().'.'.$file->guessExtension();
  45. }
  46. public function upload(UploadedFile $file, string $fileName = null): string
  47. {
  48. if (!$fileName) {
  49. $fileName = $this->getUniqueFileName($file);
  50. }
  51. try {
  52. $file->move($this->getTargetDirectory(), $fileName);
  53. } catch (FileException $e) {
  54. // ... handle exception if something happens during file upload
  55. throw new \Exception('File upload error : '.$e->getMessage());
  56. }
  57. return $fileName;
  58. }
  59. /**
  60. * update and upload Document.
  61. *
  62. * @throws \Exception
  63. */
  64. public function updateDocument(Document $document, UploadedFile $file, string $documentType = ''): Document
  65. {
  66. if ('' == $documentType) {
  67. $documentType = TypeDocumentEnum::getLabel(TypeDocumentEnum::PDF);
  68. }
  69. $originalFileName = $this->getOriginalFileName($file);
  70. $uniqueFileName = $this->getUniqueFileName($file);
  71. $documentFileName = $this->upload($file, $uniqueFileName);
  72. $document->setDisplayName($originalFileName);
  73. $document->setRealName($documentFileName);
  74. $type = $this->doctrine->getRepository(TypeDocument::class)->findOneBy(['name' => $documentType]);
  75. if (!$type) {
  76. throw new \Exception('Type not found', Response::HTTP_NOT_FOUND);
  77. }
  78. $document->setType($type);
  79. return $document;
  80. }
  81. public function getTargetDirectory(): string
  82. {
  83. return $this->targetDirectory;
  84. }
  85. public function getTempFile(string $fileName, Spreadsheet $spreadsheet): string
  86. {
  87. // Create Office 2007 Excel (XLSX Format)
  88. $writer = new Xlsx($spreadsheet);
  89. $temp_file = tempnam(sys_get_temp_dir(), $fileName);
  90. if (!$temp_file) {
  91. throw new \Exception('Temp file undefined', Response::HTTP_NOT_FOUND);
  92. }
  93. // Create the excel file in the tmp directory of the system
  94. $writer->save($temp_file);
  95. return $temp_file;
  96. }
  97. public function uploadFile(TypeDocumentEnum $docType, FormInterface $formDocuments, DeliveryMan $deliveryMan, ?string $directory): void
  98. {
  99. $idFile = $formDocuments->get($docType->formName())->getData();
  100. $document = $this->documentRepository->findOneBy(['deliveryMan' => $deliveryMan, 'type' => $docType->value]);
  101. if ($idFile && $formDocuments[$docType->formName()]) {
  102. $uploadedFile = $formDocuments[$docType->formName()]->getData() instanceof UploadedFile
  103. ? $formDocuments[$docType->formName()]->getData()
  104. : ($formDocuments[$docType->formName()]->get('realName') ? $formDocuments[$docType->formName()]->get('realName')->getData() : null);
  105. if (!$uploadedFile) {
  106. throw new \Exception('File not found in Form', Response::HTTP_INTERNAL_SERVER_ERROR);
  107. }
  108. $documentUploader = new DocumentUploader($directory ?? '', $uploadedFile);
  109. $documentUploader->setTargetDirectory($directory ?? '');
  110. $documentUploader->upload();
  111. $fileName = $documentUploader->getFileName();
  112. if ($document) {
  113. $unlink = unlink($directory.'/'.$document->getRealName());
  114. if (!$unlink) {
  115. throw new \Exception('Cannot be unlink', Response::HTTP_FORBIDDEN);
  116. }
  117. $document->setRealName($fileName);
  118. } else {
  119. $document = new Document();
  120. $document->setRealName($fileName);
  121. $document->setDeliveryMan($deliveryMan);
  122. $document->setDisplayName($docType->label());
  123. $type = $this->doctrine->getRepository(TypeDocument::class)->findOneBy(['name' => $docType->label()]);
  124. if (!$type) {
  125. throw new \Exception('Type not found', Response::HTTP_NOT_FOUND);
  126. }
  127. $document->setType($type);
  128. $documentStatus = $this->doctrine->getRepository(DelivererDocumentStatus::class)->findOneBy(['status' => 'En attente']);
  129. if (!$documentStatus) {
  130. throw new \Exception('DocumentStatus not found', Response::HTTP_NOT_FOUND);
  131. }
  132. $document->setDocumentStatus($documentStatus);
  133. }
  134. $this->entityManager->persist($document);
  135. $this->entityManager->flush();
  136. } elseif ($formDocuments->has('suppr'.$docType->formName()) && '' != $formDocuments->get('suppr'.$docType->formName())->getData() && $document) {
  137. $this->deleteFile($directory, $document);
  138. }
  139. }
  140. private function deleteFile(?string $directory, ?Document $document): void
  141. {
  142. if (!$document) {
  143. return;
  144. }
  145. $filePath = $directory.'/'.$document->getRealName();
  146. if ($this->fileSystem->exists($filePath)) {
  147. $this->fileSystem->remove($filePath);
  148. }
  149. $this->entityManager->remove($document);
  150. $this->entityManager->flush();
  151. }
  152. /**
  153. * @todo A refacto
  154. */
  155. /**public function uploadFile(
  156. string $doc,
  157. FormInterface $formDocuments,
  158. DeliveryMan $deliveryMan,
  159. ?string $directory
  160. ): void {
  161. /** @var ?string $idFile
  162. $idFile = $formDocuments->get($doc)->getData();
  163. // get previous file if exists
  164. $document = $this->documentRepository->findOneBy(['deliveryMan' => $deliveryMan, 'displayName' => $doc]);
  165. // if new file
  166. if ($idFile && $formDocuments[$doc]) {
  167. $documentUploader = new DocumentUploader($directory ?? '', $formDocuments[$doc]);
  168. // upload file
  169. $documentUploader->upload();
  170. // get file name
  171. $fileName = $documentUploader->getFileName();
  172. // if we have to delete previous file
  173. if (isset($document) && $fileName != $document->getRealName()) {
  174. // unlink old file
  175. $unlink = unlink($directory . '/' . $document->getRealName());
  176. if (!$unlink) {
  177. throw new \Exception('Cannot be unlink', Response::HTTP_FORBIDDEN);
  178. }
  179. // set new file name
  180. $document->setRealName($fileName);
  181. }
  182. // if no previous file
  183. else {
  184. // create new document
  185. $document = new Document();
  186. $document->setRealName($fileName);
  187. $document->setDeliveryMan($deliveryMan);
  188. $document->setDisplayName($doc);
  189. $type = $this->doctrine->getRepository(TypeDocument::class)->findOneBy(['name' => $doc]);
  190. if (!$type) {
  191. throw new \Exception('Type not found', Response::HTTP_NOT_FOUND);
  192. }
  193. $documentStatus = $this->doctrine->getRepository(DelivererDocumentStatus::class)->findOneBy(['status' => 'En attente']);
  194. if (!$documentStatus) {
  195. throw new \Exception('DocumentStatus not found', Response::HTTP_NOT_FOUND);
  196. }
  197. $document->setDocumentStatus($documentStatus);
  198. }
  199. // add to DB
  200. $this->entityManager->persist($document);
  201. $this->entityManager->flush();
  202. }
  203. // else if we want to drop the old file
  204. elseif ('' != $formDocuments->get('suppr' . $doc)->getData()) {
  205. // unlink old file
  206. $unlink = unlink($directory ?? '/' . $document->getRealName());
  207. if (!$unlink) {
  208. throw new \Exception('Cannot be unlink', Response::HTTP_FORBIDDEN);
  209. }
  210. $document->setDeliveryMan(null);
  211. $this->entityManager->remove($document);
  212. $this->entityManager->flush();
  213. }
  214. }*/
  215. /**
  216. * @todo A refacto
  217. */
  218. public function uploadRib(?UserInterface $user, Request $request, FormInterface $form, string $directory, ?Rib $rib): bool
  219. {
  220. $session = $request->getSession();
  221. $ribStatus = $this->doctrine->getRepository(DelivererDocumentStatus::class)->findOneBy(['status' => 'En attente']);
  222. if (!$ribStatus) {
  223. throw new \Exception('RibStatus not found', Response::HTTP_NOT_FOUND);
  224. }
  225. if (!$rib && $user) {
  226. $rib = new Rib();
  227. $rib->setUser($user);
  228. $rib->setRibStatus($ribStatus);
  229. } elseif ($rib && $rib->getDocument()) {
  230. $session->set('rib_document', $rib->getDocument());
  231. }
  232. $form->handleRequest($request);
  233. if ($form->isSubmitted() && $form->isValid()) {
  234. if (!$rib) {
  235. throw new \Exception('Rib not found', Response::HTTP_NOT_FOUND);
  236. }
  237. /** @var string $rib_document */
  238. $rib_document = $session->get('rib_document');
  239. if ('' != $rib->getDocument()) {
  240. $documentUploader = new DocumentUploader($directory, $form->get('document'));
  241. $documentUploader->upload();
  242. $rib->setDocument($documentUploader->getFileName());
  243. // suppression de l'ancier fichier sur le serveur si il y en avait un
  244. if ('' != $rib_document) {
  245. unlink($directory.'/'.$rib_document);
  246. }
  247. }
  248. // si on veut garder l'ancien fichier
  249. elseif ('' == $form->get('supprRIB')->getData()) {
  250. $rib->setDocument($rib_document);
  251. }
  252. // si on veut supprimer l'ancien fichier
  253. elseif ('' != $rib_document) {
  254. unlink($directory.'/'.$rib_document);
  255. $rib->setRibStatus($ribStatus);
  256. }
  257. $session->remove('rib_document');
  258. $this->entityManager->persist($rib);
  259. $this->entityManager->flush();
  260. return true;
  261. }
  262. return false;
  263. }
  264. public function delete(string $directory, string $fileName): void
  265. {
  266. $filePath = $directory.'/'.$fileName;
  267. if (file_exists($filePath) && !unlink($filePath)) {
  268. throw new \Exception('Cannot unlink file', Response::HTTP_FORBIDDEN);
  269. }
  270. }
  271. }