nulib-base/php/src/file/web/Upload.php

124 lines
3.2 KiB
PHP

<?php
namespace nulib\file\web;
use nulib\cl;
use nulib\file\FileReader;
use nulib\os\path;
use nulib\os\sh;
use nulib\php\coll\BaseArray;
use nulib\ValueException;
/**
* Class Upload: un fichier téléversé
*
* @property-read string $name
* @property-read string $type
* @property-read string $tmpName
* @property-read int $error
* @property-read int $size
* @property-read string $fullPath
*/
class Upload extends BaseArray {
const MESSAGES = [
"invalid" => "Ceci n'est pas un fichier téléversé",
"nofile" => "Aucun fichier n'a été fourni",
"toobig" => "Le fichier que vous avez fourni est trop volumineux.",
"unknown" => "Une erreur s'est produite pendant le transfert du fichier. Veuillez réessayer.",
];
protected static function error(string $message) {
return new ValueException(static::MESSAGES[$message]);
}
function __construct(?array $file, bool $required=true, bool $check=true) {
parent::__construct($file);
if ($check) $this->check($required);
}
function check(bool $required=true, bool $throw=true): bool {
$file = $this->data;
if ($file) {
$name = $file["name"] ?? null;
$type = $file["type"] ?? null;
$error = $file["error"] ?? null;
if (!is_scalar($name) || !is_scalar($type) || !is_scalar($error)) {
if ($throw) throw static::error("invalid");
else return false;
}
switch ($error) {
case UPLOAD_ERR_OK:
break;
case UPLOAD_ERR_NO_FILE:
if ($required) {
if ($throw) throw self::error("nofile");
else return false;
}
break;
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
if ($throw) throw self::error("toobig");
else return false;
default:
if ($throw) self::error("unknown");
else return false;
}
} elseif ($required) {
if ($throw) throw static::error("nofile");
else return false;
}
return true;
}
const _AUTO_PROPERTIES = [
"tmpName" => "tmp_name",
"fullPath" => "full_path",
];
function &__get($name) {
$name = static::_AUTO_PROPERTIES[$name] ?? $name;
return parent::__get($name);
}
function isError(): bool {
$error = $this->error;
return $error !== UPLOAD_ERR_OK && $error !== UPLOAD_ERR_NO_FILE;
}
function isValid(): bool {
return $this->error === UPLOAD_ERR_OK;
}
/**
* retourner true si le nom du fichier a une des extensions de $exts
*
* @param string|array $exts une ou plusieurs extensions qui sont vérifiées
*/
function isExt($exts): bool {
if ($exts === null) return false;
$ext = path::ext($this->name);
$exts = cl::with($exts);
return in_array($ext, $exts);
}
/** @var ?string chemin du fichier, s'il a été déplacé */
protected $file;
function moveTo(string $dest): bool {
if ($this->file === null) {
sh::mkdirof($dest);
$moved = move_uploaded_file($this->tmpName, $dest);
if ($moved) $this->file = $dest;
} else {
$moved = false;
}
return $moved;
}
function getFile(): string {
return $this->file ?? $this->tmpName;
}
function getReader(): FileReader {
return new FileReader($this->getFile(), "r+b");
}
}