mirror of
https://github.com/OpenXE-org/OpenXE.git
synced 2024-11-15 20:47:15 +01:00
268 lines
7.3 KiB
PHP
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);
|
||
|
}
|
||
|
}
|