Update CoreLibs with phpstan level 8, add qqFileUploader implementation base, add base Test class for testing

This commit is contained in:
Clemens Schwaighofer
2021-10-26 16:35:26 +09:00
parent 736f822363
commit a6b42f243f
45 changed files with 1198 additions and 593 deletions

View File

@@ -0,0 +1,32 @@
<?php
namespace FileUpload\Core;
interface qqUploadedFile // phpcs:ignore Squiz.Classes.ValidClassName.NotCamelCaps
{
/**
* Save the file to the specified path
*
* @param string $path
* @return boolean TRUE on success
*/
public function save(string $path): bool;
/**
* get qqfile name from _GET array
*
* @return string
*/
public function getName(): string;
/**
* Get file size from _SERVERa array, throws an error if not possible
*
* @return int
*
* @throws \Exception
*/
public function getSize(): int;
}
// __END__

View File

@@ -5,26 +5,40 @@ namespace FileUpload\Core;
/**
* Handle file uploads via regular form post (uses the $_FILES array)
*/
class qqUploadedFileForm
class qqUploadedFileForm implements qqUploadedFile // phpcs:ignore Squiz.Classes.ValidClassName.NotCamelCaps
{
/**
* Save the file to the specified path
*
* @param string $path
* @return boolean TRUE on success
*/
public function save($path)
public function save(string $path): bool
{
if (!move_uploaded_file($_FILES['qqfile']['tmp_name'], $path)) {
return false;
}
return true;
}
public function getName()
/**
* get qqfile name from _FILES array
*
* @return string
*/
public function getName(): string
{
return $_FILES['qqfile']['name'];
return $_FILES['qqfile']['name'] ?? '';
}
public function getSize()
/**
* get files size from _FILES array
*
* @return int
*/
public function getSize(): int
{
return $_FILES['qqfile']['size'];
return (int)$_FILES['qqfile']['size'] ?? 0;
}
}

View File

@@ -5,16 +5,22 @@ namespace FileUpload\Core;
/**
* Handle file uploads via XMLHttpRequest
*/
class qqUploadedFileXhr
class qqUploadedFileXhr implements qqUploadedFile // phpcs:ignore Squiz.Classes.ValidClassName.NotCamelCaps
{
/**
* Save the file to the specified path
*
* @param string $path
* @return boolean TRUE on success
*/
public function save($path)
public function save(string $path): bool
{
$input = fopen("php://input", "r");
$temp = tmpfile();
// abort if not resources
if (!is_resource($input) || !is_resource($temp)) {
return false;
}
$realSize = stream_copy_to_stream($input, $temp);
fclose($input);
@@ -23,17 +29,34 @@ class qqUploadedFileXhr
}
$target = fopen($path, "w");
if (!is_resource($target)) {
return false;
}
fseek($temp, 0, SEEK_SET);
stream_copy_to_stream($temp, $target);
fclose($target);
return true;
}
public function getName()
/**
* get qqfile name from _GET array
*
* @return string
*/
public function getName(): string
{
return $_GET['qqfile'];
return $_GET['qqfile'] ?? '';
}
public function getSize()
/**
* Get file size from _SERVERa array, throws an error if not possible
*
* @return int
*
* @throws \Exception
*/
public function getSize(): int
{
if (isset($_SERVER['CONTENT_LENGTH'])) {
return (int)$_SERVER['CONTENT_LENGTH'];

View File

@@ -2,17 +2,29 @@
namespace FileUpload;
// use \FileUpload\Core;
use FileUpload\Core;
class qqFileUploader
// TODO: find all usages from qqFileUploader and name to Qq
class qqFileUploader // phpcs:ignore Squiz.Classes.ValidClassName.NotCamelCaps
{
private $allowedExtensions = array();
/** @var array<mixed> */
private $allowedExtensions = [];
/** @var int */
private $sizeLimit = 10485760;
/** @var null|Core\qqUploadedFileXhr|Core\qqUploadedFileForm */
private $file;
/** @var string */
public $uploadFileName;
/** @var string */
public $uploadFileExt;
public function __construct(array $allowedExtensions = array(), $sizeLimit = 10485760)
/**
* Undocumented function
*
* @param array<mixed> $allowedExtensions
* @param integer $sizeLimit
*/
public function __construct(array $allowedExtensions = [], int $sizeLimit = 10485760)
{
$allowedExtensions = array_map("strtolower", $allowedExtensions);
@@ -22,18 +34,23 @@ class qqFileUploader
$this->checkServerSettings();
if (isset($_GET['qqfile'])) {
$this->file = new \FileUpload\Core\qqUploadedFileXhr();
$this->file = new Core\qqUploadedFileXhr();
} elseif (isset($_FILES['qqfile'])) {
$this->file = new \FileUpload\Core\qqUploadedFileForm();
$this->file = new Core\qqUploadedFileForm();
} else {
$this->file = false;
$this->file = null;
}
}
private function checkServerSettings()
/**
* Undocumented function
*
* @return void
*/
private function checkServerSettings(): void
{
$postSize = $this->toBytes(ini_get('post_max_size'));
$uploadSize = $this->toBytes(ini_get('upload_max_filesize'));
$postSize = $this->toBytes(ini_get('post_max_size') ?: '');
$uploadSize = $this->toBytes(ini_get('upload_max_filesize') ?: '');
if ($postSize < $this->sizeLimit || $uploadSize < $this->sizeLimit) {
$size = max(1, $this->sizeLimit / 1024 / 1024) . 'M';
@@ -41,10 +58,16 @@ class qqFileUploader
}
}
private function toBytes($str)
/**
* Undocumented function
*
* @param string $str
* @return integer
*/
private function toBytes(string $str): int
{
$val = (int)trim($str);
$last = strtolower($str[strlen($str)-1]);
$last = strtolower($str[strlen($str) - 1]);
switch ($last) {
case 'g':
$val *= 1024;
@@ -59,36 +82,42 @@ class qqFileUploader
}
/**
* Returns array('success'=>true) or array('error'=>'error message')
* Undocumented function
*
* @param string $uploadDirectory
* @param boolean $replaceOldFile
* @return array<string,string|bool> Returns ['success'=>true] or
* ['error'=>'error message']
*/
public function handleUpload($uploadDirectory, $replaceOldFile = false)
public function handleUpload(string $uploadDirectory, bool $replaceOldFile = false): array
{
if (!is_writable($uploadDirectory)) {
return array('error' => "Server error. Upload directory isn't writable.");
return ['error' => "Server error. Upload directory isn't writable."];
}
if (!$this->file) {
return array('error' => 'No files were uploaded.');
if (!is_object($this->file)) {
return ['error' => 'No files were uploaded.'];
}
$size = 0;
$size = $this->file->getSize();
if ($size == 0) {
return array('error' => 'File is empty');
return ['error' => 'File is empty'];
}
if ($size > $this->sizeLimit) {
return array('error' => 'File is too large');
return ['error' => 'File is too large'];
}
$pathinfo = pathinfo($this->file->getName());
$filename = $pathinfo['filename'];
$filename = $pathinfo['filename'] ?? '';
//$filename = md5(uniqid());
$ext = $pathinfo['extension'] ?? '';
if ($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)) {
$these = implode(', ', $this->allowedExtensions);
return array('error' => 'File has an invalid extension, it should be one of '. $these . '.');
return ['error' => 'File has an invalid extension, it should be one of ' . $these . '.'];
}
if (!$replaceOldFile) {
@@ -102,10 +131,12 @@ class qqFileUploader
$this->uploadFileExt = $ext;
if ($this->file->save($uploadDirectory . $filename . '.' . $ext)) {
return array('success' => true);
return ['success' => true];
} else {
return array('error' => 'Could not save uploaded file.' .
'The upload was cancelled, or server error encountered');
return [
'error' => 'Could not save uploaded file.' .
'The upload was cancelled, or server error encountered'
];
}
}
}