Commit 46cd40b6 authored by Jordan Breton's avatar Jordan Breton

multi upload Ok

parent 76dd0c0e
......@@ -29,7 +29,8 @@
"uploader" : {
"dir" : "site/webroot/uploads",
"quotas" : "1Go",
"max_size" : "300Mo",
"max_size_by_file" : "300Mo",
"max_size_at_once" : "300Mo",
"accepted_mimes" : ["/^image\\/.*$/","/^video\\/mp4$/","/^audio\\/mp3$/","/^audio\\/mpeg$/"]
},
"modules" : {
......
......@@ -112,6 +112,8 @@
"INVALID_FILE_NAME" : "Invalid file name.\nA valid file name must contain less thant [$] characters and no /"
},
"STORAGE_QUOTA_EXCEED" : "Insufficient storage : quota exceeded !",
"UNKNOWN_FOLDER" : "The specified folder doesn't exists !",
"FILE_ALREADY_EXISTS" : "One of the below files already exists in this directory. Please rename it and try again : \n[$]",
"RENAME_LIST_ERROR" : "Elems to rename list doesn't match new name list !"
}
}
......
......@@ -112,6 +112,8 @@
"INVALID_FILE_NAME" : "Ce nom de fichier n'est pas valide.\nUn nom de fichier doit contenir moins de [$] caractères et aucun /"
},
"STORAGE_QUOTA_EXCEED" : "Vous n'avez plus assez d'espace disque disponible !",
"UNKNOWN_FOLDER" : "Le dossier spécifié n'existe pas !",
"FILE_ALREADY_EXISTS" : "Le(s) fichier(s) ci-dessous existe(nt) déjà dans ce dossier. Renommez le(s) puis réessayez : \n[$]",
"RENAME_LIST_ERROR" : "La liste d'éléments à renommer ne correspond pas à la liste des nouveaux noms !"
}
}
......
<?php
namespace wfw\engine\core\security\data\rules;
use wfw\engine\core\security\data\ForEachFieldRule;
/**
* Class IsFileArray
*
* @package wfw\engine\core\security\data\rules
*/
final class IsFileArray extends ForEachFieldRule {
/** @var IsFile $_rule */
private $_rule;
/**
* IsFileArray constructor.
*
* @param string $message Failure message
* @param int $maxSize Max file size
* @param int $totalMaxSize Total max size of all files
* @param array $acceptedMimes Accepted mime types
* @param string ...$fields List of fields
*/
public function __construct(
string $message,
int $maxSize = -1,
int $totalMaxSize = -1,
$acceptedMimes = [],
string ...$fields
) {
parent::__construct($message, ...$fields);
$this->_rule = new IsFile('',$maxSize,$acceptedMimes,'file');
}
/**
* @param mixed $data Donnée sur laquelle appliquer la règle
* @return bool
*/
protected function applyOn($data): bool {
if(!is_array($data)) return false;
$files = $this->extractFiles($data);
foreach($files as $file){
if(!$this->_rule->applyTo(["file"=>$file])->satisfied()) return false;
}
return true;
}
/**
* @param $data
* @return array
*/
private function extractFiles($data):array{
$keys = ["name","type","tmp_name","error"];
if(count(array_diff_key(array_flip($keys),$data)) === 0){
$res = [];
foreach($data as $k=>$values){
foreach($values as $i=>$value){
if(!isset($res[$i])) $res[$i] = [];
$res[$i][$k] = $value;
}
}
return $res;
}else return $data;
}
}
\ No newline at end of file
......@@ -44,8 +44,8 @@ final class UploadFileHandler extends UploadHandler {
$res = $this->_rule->applyTo($data);
if($res->satisfied()){
$totalSize = 0;
foreach($data["files"] as $file){
$totalSize += filesize($file["tmp_name"]);
foreach($data["files"]["size"] as $size){
$totalSize += $size;
}
$quotas = (new Byte($this->_conf->getString("server/uploader/quotas") ?? -1))->toInt();
$dirSize = $this->getUploadDirectorySize();
......@@ -58,18 +58,32 @@ final class UploadFileHandler extends UploadHandler {
}
try{
$res = [];
foreach($data["names"] as $name){
$alreadyExists = [];
foreach($data["names"] as $k=>$name){
$fname = $this->sanitize($name);
$name = $this->realPath($fname);
if(!is_dir(dirname($name)))
throw new \InvalidArgumentException("Unknown folder $name");
move_uploaded_file($data["file"]["tmp_name"],$name);
$res[] = $this->getUploadFolderName().$fname;
return new Response($this->getUploadFolderName().$fname);
if(is_file($name)) $alreadyExists[] = $fname;
else $res[$data["files"]["tmp_name"][$k]] = [
"new_name" => $name,
"return_value" => $this->getUploadFolderName().$fname,
"tmp_name" => $data["files"]["tmp_name"][$k]
];
}
return new Response($res);
if(count($alreadyExists) > 0) throw new \InvalidArgumentException(
$this->_translator->getAndReplace(
"server/engine/package/uploader/FILE_ALREADY_EXISTS",
implode("\n",$alreadyExists)
)
);
$toSend = [];
foreach($res as $k=>$v){
move_uploaded_file($v["tmp_name"],$v["new_name"]);
$toSend[] = $v["return_value"];
}
return new Response($toSend);
}catch (\Error | \Exception $e){
foreach($res as $file) if(file_exists($file)) unlink($file);
return new ErrorResponse(201,$e->getMessage());
}
}else return new ErrorResponse(201,$res->message(),$res->errors());
......
......@@ -7,7 +7,7 @@ use wfw\engine\core\security\data\AndRule;
use wfw\engine\core\security\data\IRule;
use wfw\engine\core\security\data\IRuleReport;
use wfw\engine\core\security\data\rules\IsArrayOf;
use wfw\engine\core\security\data\rules\IsFile;
use wfw\engine\core\security\data\rules\IsFileArray;
use wfw\engine\core\security\data\rules\RequiredFields;
use wfw\engine\lib\PHP\types\Byte;
......@@ -27,22 +27,21 @@ final class UploadFileRule implements IRule {
*/
public function __construct(IConf $conf,ITranslator $translator,int $maxFileNameLength = 512) {
$key = "server/engine/package/uploader/forms";
$maxFileSize = (new Byte($conf->getString("server/uploader/max_size") ?? -1))->toInt();
$isFileRule = new IsFile(
$translator->get("$key/INVALID_FILE"),
$maxFileSize,
$conf->getArray("server/uploader/accepted_mimes") ?? ["/^image\/.*$/","/^video\/.*"],
"file"
);
$maxFileSize = (new Byte($conf->getString("server/uploader/max_size_by_file") ?? -1))->toInt();
$totalMaxFileSize = (new Byte($conf->getString("server/uploader/max_size_at_once") ?? -1))->toInt();
$this->_rule = new AndRule(
$translator->get("$key/GENERAL_ERROR"),
new RequiredFields($translator->get("$key/REQUIRED"),"files","names"),
new IsArrayOf($translator->get("$key/INVALID_FILE_NAME"),function($fname)use($maxFileNameLength){
return is_string($fname) && preg_match("/^.{1,$maxFileNameLength}$/",$fname);
},"names"),
new IsArrayOf($translator->get("$key/INVALID_FILE"),function($file)use($isFileRule){
return $isFileRule->applyTo(["file"=>$file])->satisfied();
},"files")
new IsFileArray(
$translator->get("$key/INVALID_FILE"),
$maxFileSize,
$totalMaxFileSize,
$conf->getArray("server/uploader/accepted_mimes") ?? ["/^image\/.*$/","/^video\/.*"],
"files"
)
);
}
......
......@@ -293,7 +293,8 @@ wfw.define("ui/fileExplorer",function($params){
for(let $i =0; $i<$files.files.length; $i++){
if(!$files.files[$i].type.match(/^(video\/mp4|audio\/(mpeg|mp3)|image\/.*)$/)){
alert($lstr("WARN_MEDIA_TYPE_ACCEPTED"));
$filesForm.reset(); return;
$filesForm.reset();
return;
}
}
let $loader = $displayLoader($lstr("WAITING_SEND_FILE"),true);
......@@ -310,6 +311,7 @@ wfw.define("ui/fileExplorer",function($params){
})},
"001" : ($names)=>{
$loader.remove();
$names = JSON.parse($names);
$names.forEach(($name,$i)=>{
let $d = $getData($displayed); let $f={
name : $name.split('/').pop(),
......@@ -325,7 +327,7 @@ wfw.define("ui/fileExplorer",function($params){
$filesForm.reset();
$updateQuotas();
},
error : ()=>{ $loader.remove();alert($lstr("ERR_SERVER_REFUSES_FILE")); }
error : ($data)=>{ $loader.remove();alert($data);$filesForm.reset(); }
});
}
},name:"file"})),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment