265 lines
7.7 KiB
PHP
265 lines
7.7 KiB
PHP
<?php
|
|
|
|
class stAdminFileUpload
|
|
{
|
|
/**
|
|
* Kontekst aplikacji
|
|
*
|
|
* @var sfContext
|
|
*/
|
|
private $context;
|
|
|
|
/**
|
|
* Dodatkowe opcje
|
|
* @var array
|
|
*/
|
|
private $options;
|
|
private $fieldName;
|
|
private $removeFieldName;
|
|
private $moveFiles = array();
|
|
private $cleanupFiles = array();
|
|
private $uploadDir = null;
|
|
/**
|
|
*
|
|
* @var string|null|array
|
|
*/
|
|
private $currentFieldValue;
|
|
private $multiple = false;
|
|
private $systemUploadDir = null;
|
|
|
|
/**
|
|
* Konstruktor
|
|
*
|
|
* @param string $fieldName
|
|
* @param string $currentFieldValue
|
|
* @param array $options opcjonalne parametry multiple, upload_dir,
|
|
*/
|
|
public function __construct($fieldName, $currentFieldValue = null, array $options = array())
|
|
{
|
|
$this->context = sfContext::getInstance();
|
|
$this->fieldName = $fieldName;
|
|
$this->currentFieldValue = $currentFieldValue;
|
|
$this->options = $options;
|
|
|
|
$this->removeFieldName = false !== strpos($fieldName, ']') ? substr($fieldName, 0, -1) . '_remove]' : $fieldName . '_remove';
|
|
$this->multiple = isset($options['multiple']);
|
|
|
|
if (!isset($this->options['upload_dir']) || false !== $this->options['upload_dir'])
|
|
{
|
|
$this->uploadDir = isset($this->options['upload_dir']) ? sfConfig::get('sf_upload_dir_name') . '/' . trim($this->options['upload_dir'], '/') : sfConfig::get('sf_upload_dir_name') . '/' . sfInflector::underscore($this->context->getModuleName());
|
|
$this->systemUploadDir = sfConfig::get('sf_web_dir') . '/' . $this->uploadDir;
|
|
}
|
|
else
|
|
{
|
|
$this->options['with_upload_dir'] = false;
|
|
}
|
|
|
|
}
|
|
|
|
public function __destruct()
|
|
{
|
|
if (!$this->getRequest()->hasErrors() && $this->systemUploadDir)
|
|
{
|
|
$this->doCleanupFiles();
|
|
$this->doMoveFiles();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Przetwarza uploadowane pliki
|
|
*
|
|
* @param array $errors Komunikaty błędów
|
|
* @return bool|string|array Zwraca listę lub nazwę jednego pliku w przypadku powodzenia lub false w przypadku wystąpienia błędu
|
|
*/
|
|
public function process(array &$errors = null)
|
|
{
|
|
if (null === $errors)
|
|
{
|
|
$errors = array();
|
|
}
|
|
|
|
$fileUploadError = null;
|
|
$cleanupFiles = $this->getRequest()->getParameter($this->removeFieldName);
|
|
$fileData = $this->getRequest()->getFile($this->fieldName);
|
|
|
|
$fileValidator = new sfFileValidator();
|
|
|
|
$fileValidator->initialize($this->context, array('required' => isset($this->options['required']) && $this->options['required']));
|
|
|
|
if (isset($this->options['accept']))
|
|
{
|
|
$fileValidator->setParameter('mime_types', is_string($this->options['accept']) ? array_map('trim', explode(',', $this->options['accept'])) : $this->options['accept']);
|
|
}
|
|
elseif (isset($this->options['image']) && $this->options['image'])
|
|
{
|
|
$fileValidator->setParameter('mime_types', array(
|
|
'image/jpeg',
|
|
'image/png',
|
|
'image/gif',
|
|
'image/webp',
|
|
'image/apng',
|
|
));
|
|
}
|
|
|
|
if (!$this->multiple || !isset($fileData[0]))
|
|
{
|
|
$files = array($fileData);
|
|
}
|
|
else
|
|
{
|
|
$files = $fileData;
|
|
}
|
|
|
|
if ($cleanupFiles)
|
|
{
|
|
if ($this->multiple)
|
|
{
|
|
$this->currentFieldValue = $this->currentFieldValue ? array_diff($this->currentFieldValue, $cleanupFiles) : [];
|
|
}
|
|
else
|
|
{
|
|
$this->currentFieldValue = null;
|
|
}
|
|
|
|
$this->cleanupFiles = $cleanupFiles;
|
|
}
|
|
|
|
foreach ($files as $file)
|
|
{
|
|
if ($fileValidator->execute($file, $fileUploadError) && $file['error'] != UPLOAD_ERR_NO_FILE)
|
|
{
|
|
$pathInfo = pathinfo($file['name']);
|
|
|
|
if (isset($this->options['filename']))
|
|
{
|
|
$fileName = $this->options['filename'] . '-' . uniqid() . '.' . $pathInfo['extension'];
|
|
}
|
|
else
|
|
{
|
|
$fileName = $pathInfo['filename'] . '-' . uniqid() . '.' . $pathInfo['extension'];
|
|
}
|
|
|
|
if (is_uploaded_file($file['tmp_name']))
|
|
{
|
|
if ($this->currentFieldValue && !$this->multiple)
|
|
{
|
|
$this->cleanupFiles[] = $this->currentFieldValue;
|
|
}
|
|
|
|
$this->moveFiles[$file['tmp_name']] = $fileName;
|
|
|
|
$valueFileName = isset($this->options['with_upload_dir']) && $this->options['with_upload_dir'] ? $this->uploadDir . '/' . $fileName : $fileName;
|
|
|
|
if ($this->multiple)
|
|
{
|
|
$this->currentFieldValue[] = $valueFileName;
|
|
}
|
|
else
|
|
{
|
|
$this->currentFieldValue = $valueFileName;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$errors[] = $this->composeFileError($file['name'], $this->getI18N()->__("Wystąpił błąd podczas wgrywania pliku"));
|
|
}
|
|
}
|
|
elseif ($fileValidator->getParameter('required') || $file['error'] != UPLOAD_ERR_NO_FILE)
|
|
{
|
|
$errors[] = $this->composeFileError($file['name'], $fileUploadError);
|
|
}
|
|
}
|
|
|
|
return empty($errors) ? $this->currentFieldValue : false;
|
|
}
|
|
|
|
/**
|
|
* Przenosi pliki do miejsca docelowego
|
|
* @return void
|
|
* @throws sfFileException
|
|
*/
|
|
public function doMoveFiles(?string $targetDir = null)
|
|
{
|
|
if (null === $targetDir)
|
|
{
|
|
$targetDir = $this->systemUploadDir;
|
|
}
|
|
|
|
if (null === $targetDir)
|
|
{
|
|
throw new sfFileException($this->getI18N()->__("Parameter targetDir jest obowiązkowy", null, 'stAdminGeneratorPlugin'));
|
|
}
|
|
|
|
if (!is_dir($targetDir))
|
|
{
|
|
mkdir($targetDir, 0755, true);
|
|
}
|
|
|
|
foreach ($this->moveFiles as $source => $fileName)
|
|
{
|
|
$target = $targetDir . '/' . $fileName;
|
|
|
|
if (!move_uploaded_file($source, $target))
|
|
{
|
|
throw new sfFileException($this->getI18N()->__("Wystąpił błąd podczas wgrywania pliku", null, 'stAdminGeneratorPlugin'));
|
|
}
|
|
}
|
|
|
|
$this->moveFiles = array();
|
|
}
|
|
|
|
/**
|
|
* Usuwa pliki oznaczone do usunięcia
|
|
*
|
|
* @return void
|
|
*/
|
|
public function doCleanupFiles()
|
|
{
|
|
if ($this->systemUploadDir)
|
|
{
|
|
foreach ($this->cleanupFiles as $file)
|
|
{
|
|
$file = str_replace(array('/', '\\'), '', $file);
|
|
|
|
$filepath = $this->systemUploadDir . '/' . $file;
|
|
|
|
if (is_file($filepath))
|
|
{
|
|
unlink($filepath);
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->cleanupFiles = [];
|
|
}
|
|
|
|
private function composeFileError($name, $error)
|
|
{
|
|
return !empty($name) ? $name . ' - ' . $error : $error;
|
|
}
|
|
|
|
/**
|
|
* Zwraca ządanie
|
|
*
|
|
* @return sfWebRequest
|
|
*/
|
|
public function getRequest()
|
|
{
|
|
return $this->context->getRequest();
|
|
}
|
|
|
|
public function getI18N()
|
|
{
|
|
return $this->context->getI18N();
|
|
}
|
|
|
|
/**
|
|
* Zwraca dodatkowe opcje
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getOptions(): array
|
|
{
|
|
return $this->options;
|
|
}
|
|
} |