177 lines
5.0 KiB
PHP
177 lines
5.0 KiB
PHP
<?php
|
||
|
||
/**
|
||
* Единая функция для заливки файлов на сервер.
|
||
*
|
||
* @author Ivor Barhansky <me@lopar.space>
|
||
* @version 1
|
||
*/
|
||
|
||
class Uploader
|
||
{
|
||
private array $width = ['min' => 0, 'max' => 0];
|
||
private array $height = ['min' => 0, 'max' => 0];
|
||
private int $maxFileSizeMb;
|
||
private string $savePath;
|
||
private string $extensions = 'jpg|png|jpeg|gif';
|
||
private array $extMatches = [];
|
||
private array $FILE;
|
||
private $cnm;
|
||
public static string $error;
|
||
|
||
public function __construct($name, $cnm = null)
|
||
{
|
||
if (!isset($_FILES[$name])) {
|
||
return;
|
||
}
|
||
$this->FILE = $_FILES[$name];
|
||
$this->cnm = $cnm;
|
||
}
|
||
|
||
/**
|
||
* @param int $max
|
||
* @param int|null $min
|
||
* @return void
|
||
*/
|
||
public function setWidth(int $max, ?int $min = null)
|
||
{
|
||
$this->width['min'] = is_null($min) ? $max : $min;
|
||
$this->width['max'] = $max;
|
||
}
|
||
|
||
/**
|
||
* @param int $max
|
||
* @param int|null $min
|
||
* @return void
|
||
*/
|
||
public function setHeight(int $max, ?int $min = null)
|
||
{
|
||
$this->height['min'] = is_null($min) ? $max : $min;
|
||
$this->height['max'] = $max;
|
||
}
|
||
|
||
/**
|
||
* @param $megabytes
|
||
* @return void
|
||
*/
|
||
public function setMaxFileSize($megabytes)
|
||
{
|
||
$this->maxFileSizeMb = $megabytes;
|
||
}
|
||
|
||
/**
|
||
* @param string $path путь от корня до конечной папки без открывающего слеша.
|
||
* @return void
|
||
*/
|
||
public function setSavePath(string $path)
|
||
{
|
||
$this->savePath = $_SERVER['DOCUMENT_ROOT'] . '/' . $path;
|
||
}
|
||
|
||
/**
|
||
* @param string|array $ext
|
||
* @return void
|
||
*/
|
||
public function setExtentions($ext)
|
||
{
|
||
if (is_array($ext)) {
|
||
$arr = $ext;
|
||
} else {
|
||
$arr[] = $ext;
|
||
}
|
||
if (!$arr) {
|
||
return;
|
||
}
|
||
$this->extensions = implode('|', $arr);
|
||
}
|
||
|
||
/**
|
||
* @param int $width
|
||
* @param int $height
|
||
* @return void
|
||
*/
|
||
public function setDimensions(int $width, int $height)
|
||
{
|
||
$this->setWidth($width);
|
||
$this->setHeight($height);
|
||
}
|
||
|
||
private function hasNormalDimensions(): bool
|
||
{
|
||
[$width, $height] = getimagesize($this->FILE['tmp_name']);
|
||
if (!$width || !$height) {
|
||
self::$error = 'Не подтянулись размеры файла.';
|
||
return false;
|
||
}
|
||
if (
|
||
($width < $this->width['min'] || $width > $this->width['max']) ||
|
||
($height < $this->height['min'] || $height > $this->height['max'])
|
||
) {
|
||
self::$error = 'Требования к размеру: ';
|
||
if ($this->width['min'] !== $this->width['max'] || $this->height['min'] !== $this->height['max']) {
|
||
self::$error .= "от [{$this->width['min']} x {$this->height['min']}] до ";
|
||
}
|
||
self::$error .= "[{$this->width['max']} x {$this->height['max']}].";
|
||
self::$error .= " Текущий размер [$width x $height]";
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
private function hasNormalFileSize(): bool
|
||
{
|
||
if (!$this->maxFileSizeMb) {
|
||
$this->setMaxFileSize(2);
|
||
}
|
||
if ($this->FILE['size'] > $this->maxFileSizeMb * (1024 * 1024) || $this->FILE['size'] <= 0) {
|
||
self::$error = 'Неверный размер файла. Максимальный размер файла ' . $this->maxFileSizeMb . ' МБ';
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
private function hasNormalType(): bool
|
||
{
|
||
if (
|
||
!preg_match('/\.(' . $this->extensions . ')$/i', $this->FILE['name'], $this->extMatches) ||
|
||
!preg_match('/image/i', $this->FILE['type'])
|
||
) {
|
||
self::$error = 'Неверный тип файла. Допустимые типы : ' . $this->extensions;
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
private function hasNormalFilePath(): bool
|
||
{
|
||
if (!$this->savePath || !is_dir($this->savePath)) {
|
||
self::$error = 'Ошибка загрузки: нет такой папки.';
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
private function upload()
|
||
{
|
||
$this->extMatches[1] = strtolower($this->extMatches[1]);
|
||
$fn = uniqid('f_', true) . '.' . $this->extMatches[1];
|
||
$fn2 = uniqid('f_', true) . '.gif';
|
||
if ($this->cnm) {
|
||
$fn = $this->cnm;
|
||
$fn2 = $this->cnm;
|
||
}
|
||
if (!move_uploaded_file($this->FILE['tmp_name'], $this->savePath . $fn)) {
|
||
self::$error = 'Ошибка загрузки файла';
|
||
return false;
|
||
}
|
||
return [$fn2, $fn, $this->savePath . $fn];
|
||
}
|
||
|
||
public function saveimg()
|
||
{
|
||
return $this->hasNormalFilePath() &&
|
||
$this->hasNormalDimensions() &&
|
||
$this->hasNormalFileSize() &&
|
||
$this->hasNormalType() ? $this->upload() : false;
|
||
}
|
||
} |