Files
grzanieplus.pl/plugins/stAdminGeneratorPlugin/lib/stAdminFileUpload.class.php
2025-03-12 17:06:23 +01:00

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;
}
}