OpenXE/classes/Components/Http/File/FileUpload.php
2021-05-21 08:49:41 +02:00

268 lines
7.3 KiB
PHP

<?php
namespace Xentral\Components\Http\File;
use Xentral\Components\Http\Exception\FileExistsException;
use Xentral\Components\Http\Exception\InvalidArgumentException;
use Xentral\Components\Http\Exception\NoUploadErrorException;
use Xentral\Components\Util\StringUtil;
class FileUpload extends FileInfo
{
/** @var string $clientFileName Original file name on client side (without path) */
protected $clientFileName;
/** @var string $clientMimeType Mime type on client side */
protected $clientMimeType;
/** @var int|null $clientSize */
protected $clientSize;
/** @var int $errorCode Error code */
protected $errorCode;
/**
* @param string $filePath
* @param string $clientName
* @param string|null $mimeType
* @param int|null $fileSize
* @param int|null $errorCode
*
* @throws InvalidArgumentException
*/
public function __construct(
$filePath,
$clientName,
$mimeType = null,
$fileSize = null,
$errorCode = null
) {
if (empty($filePath)) {
throw new InvalidArgumentException('File upload information is invalid. File path is missing.');
}
if (empty($clientName)) {
throw new InvalidArgumentException('File upload information is invalid. Original file name is missing.');
}
parent::__construct((string)$filePath);
$this->clientFileName = (string)$clientName;
$this->clientMimeType = $mimeType !== null ? $mimeType : 'application/octet-stream';
$this->clientSize = $fileSize;
$this->errorCode = $errorCode !== null ? (int)$errorCode : UPLOAD_ERR_OK;
}
/**
* @param array $file
*
* @return FileUpload
*/
public static function fromFilesArray(array $file)
{
foreach (['tmp_name', 'name', 'type', 'size', 'error'] as $key) {
if (!array_key_exists($key, $file)) {
$file[$key] = null;
}
}
return new self($file['tmp_name'], $file['name'], $file['type'], $file['size'], $file['error']);
}
/**
* Client file size may not be set. Use self::getSize()
*
* @return int|null File size
*/
public function getClientSize()
{
return $this->clientSize;
}
/**
* Client mime type may not correct. Use self::getMimeType()
*
* @return string 'application/octet-stream' if not set
*/
public function getClientMimeType()
{
return $this->clientMimeType;
}
/**
* Returns true if an error other than 0 exists.
*
* @return bool
*/
public function hasError()
{
return $this->errorCode !== UPLOAD_ERR_OK;
}
/**
* Returns error message.
*
* @throws NoUploadErrorException
*
* @return string error message
*/
public function getErrorMessage()
{
if (!$this->hasError()) {
throw new NoUploadErrorException('There is no error message. Please call first hasError()');
}
switch ($this->getErrorCode()) {
case UPLOAD_ERR_INI_SIZE:
$message = sprintf(
'Die Datei "%s" überschreitet die \'upload_max_filesize\' Einstellung (%s) der in php.ini.',
$this->getClientFileName(),
ini_get('upload_max_filesize')// @todo format using Stringutils
);
break;
case UPLOAD_ERR_FORM_SIZE:
$message = sprintf(
'Der Datei "%s" überschreitet die MAX_FILE_SIZE Einstellung des HTML-Formulars.',
$this->getClientFileName()
);
break;
case UPLOAD_ERR_PARTIAL:
$message = sprintf(
'Die Datei "%s" wurde nicht vollständig übertragen.',
$this->getClientFileName()
);
break;
case UPLOAD_ERR_NO_FILE:
$message = 'Es wurde keine Datei ausgewählt.';
break;
case UPLOAD_ERR_NO_TMP_DIR:
$message = 'Temporärer Ordner fehlt.';
break;
case UPLOAD_ERR_CANT_WRITE:
$message = sprintf(
'Die Datei "%s" konnte nicht abgespeichert werden.',
$this->getClientFileName()
);
break;
case UPLOAD_ERR_EXTENSION:
$message = 'Der Upload wurde durch eine PHP-Erweiterung gestoppt.';
break;
default:
$message = 'Unbekannter Upload-Fehler.';
break;
}
return $message;
}
/**
* Returns file upload error code.
*
* @see http://php.net/manual/de/features.file-upload.errors.php
*
* @return int File upload error code
*/
public function getErrorCode()
{
return $this->errorCode;
}
/**
* Returns the client's file name
*
* @return string file name on client side
*/
public function getClientFileName()
{
return $this->clientFileName;
}
/**
* Returns the content of the file.
*
* @return string file contents
*/
public function getContent()
{
return file_get_contents($this->getRealPath());
}
/**
* Opens a readonly stream to the file.
*
* @return resource file contents as stream
*/
public function createContentStream()
{
return fopen($this->getRealPath(), 'rb');
}
/**
* Returns true if the file is an image.
*
* @return bool
*/
public function isImage()
{
return in_array(
$this->getMimeType(),
['image/jpg', 'image/jpeg', 'image/png', 'image/gif', 'image/tiff', 'image/tif'],
true
);
}
/**
* Returns true if the file is a Pdf file.
*
* @return bool
*/
public function isPdf()
{
return $this->getMimeType() === 'application/pdf';
}
/**
* Return true if file is valid
*
* @return bool
*/
public function isValid()
{
return is_uploaded_file($this->getRealPath());
}
/**
* Moves file to specific location.
*
* @param string $targetDir
* @param string|null $targetName
*
* @return FileInfo file at new location
*/
public function move($targetDir, $targetName = null)
{
if (!is_dir($targetDir)) {
throw new InvalidArgumentException(
sprintf('The target directory "%s" does not exist or is no directory.', $targetDir)
);
}
if ($targetName === '') {
throw new InvalidArgumentException('The target file name can not be empty.');
}
if ($targetName === null) {
$targetName = StringUtil::toFilename( $this->getClientFileName());
}
$targetFilePath = $targetDir . '/' . $targetName;
if (file_exists($targetFilePath)) {
throw new FileExistsException(
sprintf('Cannot move file. Target file "%s" already exists', $targetFilePath)
);
}
move_uploaded_file($this->getRealPath(), $targetFilePath);
return new FileInfo($targetFilePath);
}
}