diff --git a/src/Constrict/ConstrictRequest.php b/src/Constrict/ConstrictRequest.php index adcc476..a3dc963 100644 --- a/src/Constrict/ConstrictRequest.php +++ b/src/Constrict/ConstrictRequest.php @@ -64,19 +64,22 @@ class ConstrictRequest extends Message implements RequestInterface, ServerReques /** * @param string $name - * @return array|null + * @return File|null */ - #[ArrayShape(['name' => 'string', 'type' => 'string', 'tmp_name' => 'string', 'error' => 'int', 'size' => 'int'])] - public function file(string $name): ?array + public function file(string $name): ?File { - return $this->files[$name] ?? null; + if (isset($this->files[$name])) { + return new File($this->files[$name]); + } else { + return null; + } } /** * @return bool */ - public function getIsPost(): bool + public function isPost(): bool { return $this->method === 'POST'; } diff --git a/src/Constrict/File.php b/src/Constrict/File.php new file mode 100644 index 0000000..7a291c4 --- /dev/null +++ b/src/Constrict/File.php @@ -0,0 +1,154 @@ +name = $array['name']; + $this->tmp_name = $array['tmp_name']; + $this->error = $array['error']; + $this->type = $array['type']; + $this->size = $array['size']; + } + + const array errorInfo = [ + 0 => 'UPLOAD_ERR_OK.', + 1 => 'The uploaded file exceeds the upload_max_filesize directive in php.ini.', + 2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.', + 3 => 'The uploaded file was only partially uploaded.', + 4 => 'No file was uploaded.', + 6 => 'Missing a temporary folder.', + 7 => 'Failed to write file to disk.', + 8 => 'A PHP extension stopped the file upload.' + ]; + + /** + * @param string $path + * @return bool + * @throws + */ + public function saveTo(string $path): bool + { + if ($this->hasError()) { + throw new Exception($this->getErrorInfo()); + } + + @move_uploaded_file($this->tmp_name, $path); + if (!file_exists($path)) { + return false; + } + return true; + } + + /** + * @return string + * @throws + */ + public function rename(): string + { + if (!empty($this->newName)) return $this->newName; + if (!file_exists($this->getTmpPath())) { + throw new Exception('(' . $this->name . ')Failed to open stream: No such file or directory'); + } + + $hash = md5_file($this->getTmpPath()); + + $later = '.' . exif_imagetype($this->getTmpPath()); + + $match = '/(\w{12})(\w{5})(\w{9})(\w{6})/'; + $tmp = preg_replace($match, '$1-$2-$3-$4', $hash); + + return $this->name = strtoupper($tmp) . $later; + } + + /** + * @return string + */ + public function getType(): string + { + return $this->type; + } + + + /** + * @return int + */ + public function getSize(): int + { + return $this->size; + } + + + /** + * @return string + * @throws + */ + public function getContent(): string + { + $open = fopen($this->getTmpPath(), 'r'); + $content = ''; + while ($file = fread($open, $this->limit)) { + $content .= $file; + fseek($open, $this->offset); + if ($this->offset >= $this->getSize()) { + break; + } + $this->offset += $this->limit; + } + fclose($open); + $this->offset = 0; + return $content; + } + + + /** + * @return string + */ + public function getTmpPath(): string + { + return $this->tmp_name; + } + + /** + * @return bool + * + * check file have error + */ + public function hasError(): bool + { + return $this->error !== 0; + } + + /** + * @return mixed + * + * get upload error info + */ + public function getErrorInfo(): mixed + { + if (!isset(self::errorInfo[$this->error])) { + return 'Unknown upload error.'; + } + return self::errorInfo[$this->error]; + } + +} \ No newline at end of file diff --git a/src/Request.php b/src/Request.php index 295bb84..ce1808b 100644 --- a/src/Request.php +++ b/src/Request.php @@ -3,9 +3,9 @@ declare(strict_types=1); namespace Kiri\Router; -use JetBrains\PhpStorm\ArrayShape; use Kiri\Router\Base\AuthorizationInterface; use Kiri\Router\Base\ExceptionHandlerDispatcher; +use Kiri\Router\Constrict\File; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\StreamInterface; @@ -647,10 +647,9 @@ class Request implements ServerRequestInterface /** * @param string $name - * @return array|null + * @return File|null */ - #[ArrayShape(['name' => 'string', 'type' => 'string', 'tmp_name' => 'string', 'error' => 'int', 'size' => 'int'])] - public function file(string $name): ?array + public function file(string $name): ?File { return $this->__call__(__FUNCTION__, $name); } @@ -659,7 +658,7 @@ class Request implements ServerRequestInterface /** * @return bool */ - public function getIsPost(): bool + public function isPost(): bool { return $this->getMethod() == 'POST'; } diff --git a/src/Validator/Validator.php b/src/Validator/Validator.php index d6412c5..dffba00 100644 --- a/src/Validator/Validator.php +++ b/src/Validator/Validator.php @@ -97,7 +97,7 @@ class Validator if (!empty($this->message)) { return false; } - $params = !$request->getIsPost() ? $request->getQueryParams() : $request->getParsedBody(); + $params = !$request->isPost() ? $request->getQueryParams() : $request->getParsedBody(); foreach ($params as $name => $value) { if (!isset($this->types[$name])) {