get('token'); if ($token != env('TOKEN_DEPOT', "c8c4613a-236c-4b06-95f6-a9c9c6c18861")) { return abort(404); } $sites = Site::orderBy('libelle')->get(); return view('upload.show')->with( [ 'sites' => $sites, ] ); } public function storeMedia(Request $request) { $uid = $request->input('uid'); $sujet_id = $request->input('sujet_id'); $dossier_id = $request->input('dossier_id'); $replaceMediaId = $request->input('replaceMediaId'); if ($dossier_id == 0) { $dossier_id = null; } $headers = $request->headers->all(); $acceptFileTypes = array('gif','jpeg', 'jpg','png','mp4','mp3','psd','ai','svg','pdf'); if ($request->hasFile('files')) { $filesa = []; /** @var array<\Illuminate\Http\UploadedFile> */ $files = $request->file('files'); foreach ($files as $file) { $is_last_chunk = false; $is_chunked_upload = !empty($headers['content-range']); if ($is_chunked_upload) { if (preg_match('|(\d+)/(\d+)|', $headers['content-range'][0], $range)) { if ($range[1] == $range[2] - 1) { $is_last_chunk = true; } } } $extension = strtolower($file->getClientOriginalExtension()); $originalName = str_replace("." . $extension, "", $file->getClientOriginalName()); if (!in_array($extension, $acceptFileTypes)) { return array("false"); } if ($is_chunked_upload) { $filename = $uid . "_" . $range[1] . "." . $extension; } else { $filename = $uid . '.' . $extension; } $uploadPath = public_path() . '/uploads/'; $file->move($uploadPath, $filename); // * si c'est le dernier morceux d'un fichier if ($is_last_chunk) { if ($dossier = opendir($uploadPath)) { $dirFiles = array(); // * on compile tous les chunk du fichier while (false !== ($fichier = readdir($dossier))) { if ($fichier != '.' && $fichier != '..') { if (strpos($fichier, $uid) !== false) { $dirFiles[$fichier] = str_replace( ".{$extension}", "", str_replace("{$uid}_", "", $fichier) ); } } } closedir($dossier); // * on les trie pour les assembler dans le bon ordre asort($dirFiles, SORT_NUMERIC); // * on les assemble dans un fichier final $filename = $uid . '.' . $extension; foreach ($dirFiles as $key => $fichier) { $file = fopen($uploadPath . $key, 'rb'); $buff = fread($file, filesize($uploadPath . $key)); fclose($file); $final = fopen($uploadPath . $filename, 'a'); $write = fwrite($final, $buff); fclose($final); unlink($uploadPath . $key); } }//end if }//end if // * si c'est le dernier morceau d'un fichier ou que c'est un envoi simple if ($is_last_chunk || !$is_chunked_upload) { $destinationPath = $this->getMediaFolder() . "/"; // * si on upload un média pour remplacer un fichier par un autre if ($replaceMediaId != 0) { // * on récupère le média à modifier /** @var \App\Models\Media|null */ $media = Media::where('id', $replaceMediaId)->first(); // * On déplace le fichier dans le répertoire des médias if (!Storage::move("uploads/{$filename}", $destinationPath . $filename)) { throw new \ErrorException( "Could not move uploaded file $filename into {$destinationPath}{$filename}" ); } // * supprime les fichiers médias stockés sur disque $filesfF = Storage::files($media->folder . "/"); $filepath = preg_quote($media->folder . $media->uid, '/'); $matchingFiles = preg_grep('/^' . $filepath . '/', $filesfF); Storage::delete($matchingFiles); $media->isDefault = 0; $media->save(); } else { // * On déplace le fichier dans le répertoire des médias if (!Storage::move("uploads/{$filename}", $destinationPath . $filename)) { throw new \ErrorException( "Could not move uploaded file $filename into {$destinationPath}{$filename}" ); } // * on créé un média en bdd $media = new Media(); $media->dossier_id = $dossier_id; $media->sujet_id = $sujet_id; // * Par défaut FR $media->langue_id = 1; // * Par défaut propriété de la marque $media->copyright_id = 3; }//end if $media->extension = $extension; $media->folder = $destinationPath; if ($replaceMediaId == 0) { $media->libelle = mb_substr($originalName, 0, 50, "UTF-8"); $media->created_by = Auth::user()->id; } $media->uid = $uid; $media->taille = $this->formatBytes(Storage::size($destinationPath . $filename)); switch ($extension) { // * Photo (1) case 'gif': case 'jpeg': case 'jpg': case 'png': case 'ai': case 'pdf': case 'psd': $media->typemedia_id = 1; $im = new \Imagick($destinationPath . $filename); if (in_array($extension, array("pdf", "ai", "psd", "gif"))) { $im->setIteratorIndex(0); } $resolutions = $im->getImageResolution(); $media->resolution = round($resolutions['x'] * 2.54); $imageprops = $im->getImageGeometry(); $media->largeur = $imageprops['width']; $media->hauteur = $imageprops['height']; if ($media->resolution != 0) { $media->largeur_mm = ceil(($media->largeur * 2.54 / $media->resolution) * 10); $media->hauteur_mm = ceil(($media->hauteur * 2.54 / $media->resolution) * 10); } else { $media->largeur_mm = ""; $media->hauteur_mm = ""; } $media->save(); $im->destroy(); // ---- Creation des vignettes de base $this->createSysThumb($media); // ---- Creation des vignettes en lien avec le sujet du média if (isset($sujet_id)) { $this->createThumb($media); } break; // * Illustration/Vectorielle (2) case 'svg': $media->typemedia_id = 2; $media->save(); break; // * Vidéo (3) case 'mp4': $media->typemedia_id = 3; $getID3 = new \getID3(); if ($fileInfo = $getID3->analyze($destinationPath . $filename)) { $media->largeur = $fileInfo['video']['resolution_x']; $media->hauteur = $fileInfo['video']['resolution_y']; $media->duree = $fileInfo['playtime_string']; } $media->save(); break; // * Audio (4) case 'mp3': $media->typemedia_id = 4; $getID3 = new \getID3(); if ($fileInfo = $getID3->analyze($destinationPath . $filename)) { $media->duree = $fileInfo['playtime_string']; } $media->save(); break; }//end switch $id = $media->id; $media = Media::find($id); // ---- Index dans Elasticsearch $media = Media::where('id', $media->id)->first(); $media->addToIndex(); // ---- Historique des actions $historique = new Historique(); if ($user = Auth::user()) { $historique->user_id = $user->id; } $historique->media_id = $media->id; if ($replaceMediaId == 0) { $historique->type = "Création"; $historique->description = "Média ajouté"; } else { $historique->type = "Modification"; $historique->description = "Le média a été remplacé"; } $historique->save(); $filest = array(); $filest['name'] = $filename; $filest['uid'] = $uid; $filest['libelle'] = $media->libelle; $filest['id'] = $media->id; $filest['folder'] = $media->folder; $filest['extension'] = $media->extension; $filest['typemedia_id'] = $media->typemedia_id; $filesa['files'][] = $filest; }//end if }//end foreach return $filesa; }//end if } public function storeMediaV2(Request $request) { $uid = $request->input('uid'); $sujet_id = $request->input('sujet_id'); $dossier_id = $request->input('dossier_id'); $replaceMediaId = $request->input('replaceMediaId'); if ($dossier_id == 0) { $dossier_id = null; } $filesa = []; $acceptFileTypes = array('gif','jpeg', 'jpg','png','mp4','mp3','psd','ai','svg','pdf'); if (!$uid) { $uid = Str::uuid(); } $file = $request->file('files'); if (!empty($file)) { $extension = strtolower($file->getClientOriginalExtension()); $originalName = str_replace("." . $extension, "", $file->getClientOriginalName()); if (!in_array($extension, $acceptFileTypes)) { return array("false"); } if (!in_array($extension, $acceptFileTypes)) { return array("error" => "Ce type de fichier n'est pas accepté."); } // * check the error status if ($file->getError() != 0) { Log::error('error ' . $file->getError() . ' in file ' . $request->resumableFilename); } $temp_dir = 'uploads'; /** * init the destination file (format .part<#chunk> * the file is stored in a temporary directory */ if (isset($request->resumableIdentifier) && trim($request->resumableIdentifier) != '') { $temp_dir .= "/{$request->resumableIdentifier}"; } $dest_file = "{$temp_dir}/{$request->resumableFilename}.part{$request->resumableChunkNumber}"; // * create the temporary directory if (!is_dir($temp_dir)) { mkdir($temp_dir, 0777, true); } // * move the temporary file if (!move_uploaded_file($file->getPathname(), $dest_file)) { Log::error( //phpcs:ignore Generic.Files.LineLength.TooLong "Error saving (move_uploaded_file) chunk $request->resumableChunkNumber for file $request->resumableFilename" ); } else { $filename = $uid . '.' . $extension; // * check if all the parts present, and create the final destination file $isLast = $this->createFileFromChunks( $temp_dir, $request->resumableFilename, $request->resumableChunkSize, $request->resumableTotalSize, $request->resumableTotalChunks, $filename ); if ($isLast) { $destinationPath = $this->getMediaFolder() . "/"; // * si on upload un média pour remplacer un fichier par un autre if ($replaceMediaId != 0) { // * on récupère le média à modifier /** @var \App\Models\Media $media */ $media = Media::where('id', $replaceMediaId)->firstOrFail(); // * On déplace le fichier dans le répertoire des médias Storage::move("uploads/" . $filename, $destinationPath . $filename); // * supprime les fichiers médias stockés sur disque $filesfF = Storage::files($media->folder . "/"); $filepath = preg_quote($media->folder . $media->uid, '/'); $matchingFiles = preg_grep('/^' . $filepath . '/', $filesfF); Storage::delete($matchingFiles); $media->isDefault = 0; $media->save(); } else { // * On déplace le fichier dans le répertoire des médias Storage::move("uploads/" . $filename, $destinationPath . $filename); // * on créé un média en bdd $media = new Media(); $media->dossier_id = $dossier_id; $media->sujet_id = $sujet_id; // * Par défaut FR $media->langue_id = 1; // * Par défaut propriété de la marque $media->copyright_id = 3; }//end if $media->extension = $extension; $media->folder = $destinationPath; if ($replaceMediaId == 0) { $media->libelle = mb_substr($originalName, 0, 50, "UTF-8"); $media->created_by = Auth::user()->id; } $media->uid = $uid; $media->taille = $this->formatBytes($this->getFileSize($destinationPath . $filename)); switch ($extension) { // * Photo (1) case 'gif': case 'jpeg': case 'jpg': case 'png': case 'ai': case 'pdf': case 'psd': $media->typemedia_id = 1; $im = new \imagick($destinationPath . $filename); if (in_array($extension, array("pdf", "ai", "psd", "gif"))) { $im->setIteratorIndex(0); } $resolutions = $im->getImageResolution(); $media->resolution = round($resolutions['x'] * 2.54); $imageprops = $im->getImageGeometry(); $media->largeur = $imageprops['width']; $media->hauteur = $imageprops['height']; if ($media->resolution != 0) { $media->largeur_mm = ceil(($media->largeur * 2.54 / $media->resolution) * 10); $media->hauteur_mm = ceil(($media->hauteur * 2.54 / $media->resolution) * 10); } else { $media->largeur_mm = ""; $media->hauteur_mm = ""; } $media->save(); $im->destroy(); // ---- Creation des vignettes de base $this->createSysThumb($media); // ---- Creation des vignettes en lien avec le sujet du média if (isset($sujet_id)) { $this->createThumb($media); } break; // * Illustration/Vectorielle (2) case 'svg': $media->typemedia_id = 2; $media->save(); break; // * Vidéo (3) case 'mp4': $media->typemedia_id = 3; $getID3 = new \getID3(); if ($fileInfo = $getID3->analyze($destinationPath . $filename)) { $media->largeur = $fileInfo['video']['resolution_x']; $media->hauteur = $fileInfo['video']['resolution_y']; $media->duree = $fileInfo['playtime_string']; } $media->save(); break; // * Audio (4) case 'mp3': $media->typemedia_id = 4; $getID3 = new \getID3(); if ($fileInfo = $getID3->analyze($destinationPath . $filename)) { $media->duree = $fileInfo['playtime_string']; } $media->save(); break; }//end switch $id = $media->id; $media = Media::find($id); // ---- Index dans Elasticsearch $media = Media::where('id', $media->id)->first(); $media->addToIndex(); // ---- Historique des actions $historique = new Historique(); if ($user = Auth::user()) { $historique->user_id = $user->id; } $historique->media_id = $media->id; if ($replaceMediaId == 0) { $historique->type = "Création"; $historique->description = "Média ajouté"; } else { $historique->type = "Modification"; $historique->description = "Le média a été remplacé"; } $historique->save(); return response()->json($media); }//end if }//end if }//end if } /** * Check if all the parts exist, and * gather all the parts of the file together * * @param string $temp_dir The temporary directory holding all the parts of the file. * @param string $fileName The original file name. * @param integer $chunkSize Each chunk size (in bytes). * @param integer $totalSize Original file size (in bytes). * @param integer $total_files * @param string $finalName * @return boolean */ private function createFileFromChunks( string $temp_dir, string $fileName, int $chunkSize, int $totalSize, int $total_files, string $finalName ): bool { // * count all the parts of this file $total_files_on_server_size = 0; $temp_total = 0; foreach (scandir($temp_dir) as $file) { $temp_total = $total_files_on_server_size; $tempfilesize = filesize($temp_dir . '/' . $file); $total_files_on_server_size = $temp_total + $tempfilesize; } // * check that all the parts are present // * If the Size of all the chunks on the server is equal to the size of the file uploaded. if ($total_files_on_server_size >= $totalSize) { // * create the final destination file if (($fp = fopen("uploads/{$finalName}", 'w')) !== false) { for ($i = 1; $i <= $total_files; $i++) { fwrite($fp, file_get_contents("{$temp_dir}/{$fileName}.part{$i}")); } fclose($fp); } else { Log::error('cannot create the destination file'); return false; } // * rename the temporary directory (to avoid access from other // * concurrent chunks uploads) and than delete it if (rename($temp_dir, $temp_dir . '_UNUSED')) { $this->rrmdir($temp_dir . '_UNUSED'); } else { $this->rrmdir($temp_dir); } return true; }//end if return false; } /** * Delete a directory RECURSIVELY * * @param string $dir Directory path. * @return void * @link http://php.net/manual/en/function.rmdir.php */ private function rrmdir(string $dir): void { if (is_dir($dir)) { $objects = scandir($dir); foreach ($objects as $object) { if ($object != "." && $object != "..") { if (filetype($dir . "/" . $object) == "dir") { $this->rrmdir($dir . "/" . $object); } else { unlink($dir . "/" . $object); } } } reset($objects); rmdir($dir); } } }