2014-04-01 15:43:38 +03:00
|
|
|
|
<?php
|
2014-10-08 08:20:29 +03:00
|
|
|
|
/*
|
2014-04-01 15:43:38 +03:00
|
|
|
|
* LiveStreet CMS
|
|
|
|
|
* Copyright © 2013 OOO "ЛС-СОФТ"
|
|
|
|
|
*
|
|
|
|
|
* ------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* Official site: www.livestreetcms.com
|
|
|
|
|
* Contact e-mail: office@livestreetcms.com
|
|
|
|
|
*
|
|
|
|
|
* GNU General Public License, version 2:
|
|
|
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
|
|
|
*
|
|
|
|
|
* ------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* @link http://www.livestreetcms.com
|
|
|
|
|
* @copyright 2013 OOO "ЛС-СОФТ"
|
|
|
|
|
* @author Maxim Mzhelskiy <rus.engine@gmail.com>
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
2014-10-08 08:20:29 +03:00
|
|
|
|
/**
|
|
|
|
|
* Объект управления типом file
|
|
|
|
|
*
|
|
|
|
|
* @package application.modules.property
|
|
|
|
|
* @since 2.0
|
|
|
|
|
*/
|
2014-10-08 11:49:34 +03:00
|
|
|
|
class ModuleProperty_EntityValueTypeFile extends ModuleProperty_EntityValueType
|
|
|
|
|
{
|
2014-04-01 15:43:38 +03:00
|
|
|
|
|
2014-10-08 11:49:34 +03:00
|
|
|
|
public function getValueForDisplay()
|
|
|
|
|
{
|
|
|
|
|
return $this->getFileFullName();
|
|
|
|
|
}
|
2014-04-01 15:43:38 +03:00
|
|
|
|
|
2014-10-08 11:49:34 +03:00
|
|
|
|
public function validate()
|
|
|
|
|
{
|
|
|
|
|
$oValue = $this->getValueObject();
|
|
|
|
|
$oProperty = $oValue->getProperty();
|
|
|
|
|
$iPropertyId = $oProperty->getId();
|
2014-04-01 15:43:38 +03:00
|
|
|
|
|
2014-11-20 06:57:37 +02:00
|
|
|
|
$bNeedRemove=false;
|
2014-10-08 11:49:34 +03:00
|
|
|
|
$mValue = $this->getValueForValidate();
|
|
|
|
|
if (isset($mValue['remove']) and $mValue['remove']) {
|
2014-11-20 06:57:37 +02:00
|
|
|
|
$bNeedRemove=true;
|
2014-10-08 11:49:34 +03:00
|
|
|
|
$this->setValueForValidate(array('remove' => true));
|
|
|
|
|
}
|
2014-04-01 15:43:38 +03:00
|
|
|
|
|
2014-10-08 11:49:34 +03:00
|
|
|
|
$sFileName = $this->_getValueFromFiles($iPropertyId, 'name');
|
|
|
|
|
$sFileTmpName = $this->_getValueFromFiles($iPropertyId, 'tmp_name');
|
|
|
|
|
$sFileError = $this->_getValueFromFiles($iPropertyId, 'error');
|
|
|
|
|
$sFileSize = $this->_getValueFromFiles($iPropertyId, 'size');
|
2014-04-01 15:43:38 +03:00
|
|
|
|
|
2014-10-08 11:49:34 +03:00
|
|
|
|
if (!$sFileTmpName) {
|
|
|
|
|
if ($oProperty->getValidateRuleOne('allowEmpty')) {
|
|
|
|
|
return true;
|
2014-11-20 06:57:37 +02:00
|
|
|
|
} elseif ($aFilePrev = $oValue->getDataOne('file') and isset($aFilePrev['path']) and !$bNeedRemove) {
|
2014-10-08 11:49:34 +03:00
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
return 'Необходимо выбрать файл';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Проверяем на ошибки
|
|
|
|
|
*/
|
|
|
|
|
if ($sFileError and $sFileError != UPLOAD_ERR_NO_FILE) {
|
|
|
|
|
return "При загрузке файла возникла ошибка - {$sFileError}";
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* На корректность загрузки
|
|
|
|
|
*/
|
|
|
|
|
if (!$sFileName or !$sFileTmpName) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* На ограниечение по размеру файла
|
|
|
|
|
*/
|
|
|
|
|
if ($iSizeKb = $oProperty->getValidateRuleOne('size_max') and $iSizeKb * 1025 < $sFileSize) {
|
|
|
|
|
return "Превышен размер файла, максимальный {$iSizeKb}Kb";
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* На допустимые типы файлов
|
|
|
|
|
*/
|
|
|
|
|
$aPath = pathinfo($sFileName);
|
|
|
|
|
if (!isset($aPath['extension']) or !$aPath['extension']) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if ($aTypes = $oProperty->getParam('types') and !in_array($aPath['extension'], $aTypes)) {
|
|
|
|
|
return 'Неверный тип файла, допустимы ' . join(', ', $aTypes);
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Пробрасываем данные по файлу
|
|
|
|
|
*/
|
|
|
|
|
$this->setValueForValidate(array(
|
|
|
|
|
'name' => $sFileName,
|
|
|
|
|
'tmp_name' => $sFileTmpName,
|
|
|
|
|
'error' => $sFileError,
|
|
|
|
|
'size' => $sFileSize,
|
|
|
|
|
));
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2014-04-01 15:43:38 +03:00
|
|
|
|
|
2014-10-08 11:49:34 +03:00
|
|
|
|
protected function _getValueFromFiles($iId, $sName)
|
|
|
|
|
{
|
|
|
|
|
if (isset($_FILES['property'][$sName][$iId]['file'])) {
|
|
|
|
|
return $_FILES['property'][$sName][$iId]['file'];
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2014-04-01 15:43:38 +03:00
|
|
|
|
|
2014-10-08 11:49:34 +03:00
|
|
|
|
/**
|
|
|
|
|
* Устанавливает значение после валидации конкретного поля, а не всех полей
|
|
|
|
|
* Поэтому здесь нельзя сохранять файл, это нужно делать в beforeSaveValue()
|
|
|
|
|
*
|
|
|
|
|
* @param $aValue
|
|
|
|
|
*/
|
|
|
|
|
public function setValue($aValue)
|
|
|
|
|
{
|
|
|
|
|
$oValue = $this->getValueObject();
|
|
|
|
|
/**
|
|
|
|
|
* Просто пробрасываем данные
|
|
|
|
|
*/
|
|
|
|
|
if ($aValue) {
|
|
|
|
|
$oValue->setDataOne('file_raw', $aValue);
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-04-01 15:43:38 +03:00
|
|
|
|
|
2014-10-08 11:49:34 +03:00
|
|
|
|
/**
|
|
|
|
|
* Дополнительная обработка перед сохранением значения
|
|
|
|
|
* Здесь нужно выполнять основную загрузку файла
|
|
|
|
|
*/
|
|
|
|
|
public function beforeSaveValue()
|
|
|
|
|
{
|
|
|
|
|
$oValue = $this->getValueObject();
|
|
|
|
|
$oProperty = $oValue->getProperty();
|
|
|
|
|
if (!$aFile = $oValue->getDataOne('file_raw')) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
$oValue->setDataOne('file_raw', null);
|
|
|
|
|
/**
|
|
|
|
|
* Удаляем предыдущий файл
|
|
|
|
|
*/
|
|
|
|
|
if (isset($aFile['remove']) or isset($aFile['name'])) {
|
|
|
|
|
if ($aFilePrev = $oValue->getDataOne('file')) {
|
|
|
|
|
$this->RemoveFile($aFilePrev['path']);
|
|
|
|
|
$oValue->setDataOne('file', array());
|
|
|
|
|
$oValue->setValueVarchar(null);
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-04-01 15:43:38 +03:00
|
|
|
|
|
2014-10-08 11:49:34 +03:00
|
|
|
|
if (isset($aFile['name'])) {
|
|
|
|
|
/**
|
|
|
|
|
* Выполняем загрузку файла
|
|
|
|
|
*/
|
|
|
|
|
$aPathInfo = pathinfo($aFile['name']);
|
|
|
|
|
$sExtension = isset($aPathInfo['extension']) ? $aPathInfo['extension'] : 'unknown';
|
|
|
|
|
$sFileName = func_generator(20) . '.' . $sExtension;
|
|
|
|
|
/**
|
|
|
|
|
* Копируем загруженный файл
|
|
|
|
|
*/
|
|
|
|
|
$sDirTmp = Config::Get('path.tmp.server') . '/property/';
|
|
|
|
|
if (!is_dir($sDirTmp)) {
|
|
|
|
|
@mkdir($sDirTmp, 0777, true);
|
|
|
|
|
}
|
|
|
|
|
$sFileTmp = $sDirTmp . $sFileName;
|
2014-04-01 15:43:38 +03:00
|
|
|
|
|
2014-10-08 11:49:34 +03:00
|
|
|
|
if (move_uploaded_file($aFile['tmp_name'], $sFileTmp)) {
|
|
|
|
|
$sDirSave = Config::Get('path.root.server') . $oProperty->getSaveFileDir();
|
|
|
|
|
if (!is_dir($sDirSave)) {
|
|
|
|
|
@mkdir($sDirSave, 0777, true);
|
|
|
|
|
}
|
|
|
|
|
$sFilePath = $sDirSave . $sFileName;
|
|
|
|
|
/**
|
|
|
|
|
* Сохраняем файл
|
|
|
|
|
*/
|
|
|
|
|
if ($sFilePathNew = $this->SaveFile($sFileTmp, $sFilePath, null, true)) {
|
|
|
|
|
/**
|
|
|
|
|
* Сохраняем данные о файле
|
|
|
|
|
*/
|
|
|
|
|
$oValue->setDataOne('file', array(
|
|
|
|
|
'path' => $sFilePathNew,
|
|
|
|
|
'size' => filesize($sFilePath),
|
|
|
|
|
'name' => htmlspecialchars($aPathInfo['filename']),
|
|
|
|
|
'extension' => htmlspecialchars($aPathInfo['extension']),
|
|
|
|
|
));
|
|
|
|
|
/**
|
|
|
|
|
* Сохраняем уникальный ключ для доступа к файлу
|
|
|
|
|
*/
|
|
|
|
|
$oValue->setValueVarchar(func_generator(32));
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-04-01 15:43:38 +03:00
|
|
|
|
|
2014-10-08 11:49:34 +03:00
|
|
|
|
public function prepareValidateRulesRaw($aRulesRaw)
|
|
|
|
|
{
|
|
|
|
|
$aRules = array();
|
|
|
|
|
$aRules['allowEmpty'] = isset($aRulesRaw['allowEmpty']) ? false : true;
|
2014-04-01 15:43:38 +03:00
|
|
|
|
|
2014-10-08 11:49:34 +03:00
|
|
|
|
if (isset($aRulesRaw['size_max']) and is_numeric($aRulesRaw['size_max'])) {
|
|
|
|
|
$aRules['size_max'] = (int)$aRulesRaw['size_max'];
|
|
|
|
|
}
|
|
|
|
|
return $aRules;
|
|
|
|
|
}
|
2014-04-01 15:43:38 +03:00
|
|
|
|
|
2014-10-08 11:49:34 +03:00
|
|
|
|
public function prepareParamsRaw($aParamsRaw)
|
|
|
|
|
{
|
|
|
|
|
$aParams = array();
|
2014-04-01 15:43:38 +03:00
|
|
|
|
|
2014-10-08 11:49:34 +03:00
|
|
|
|
$aParams['types'] = array();
|
|
|
|
|
if (isset($aParamsRaw['types']) and is_array($aParamsRaw['types'])) {
|
|
|
|
|
foreach ($aParamsRaw['types'] as $sType) {
|
|
|
|
|
if ($sType) {
|
|
|
|
|
$aParams['types'][] = htmlspecialchars($sType);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$aParams['access_only_auth'] = isset($aParamsRaw['access_only_auth']) ? true : false;
|
2014-04-01 15:43:38 +03:00
|
|
|
|
|
2014-10-08 11:49:34 +03:00
|
|
|
|
return $aParams;
|
|
|
|
|
}
|
2014-04-01 15:43:38 +03:00
|
|
|
|
|
2014-10-08 11:49:34 +03:00
|
|
|
|
public function getParamsDefault()
|
|
|
|
|
{
|
|
|
|
|
return array(
|
|
|
|
|
'types' => array(
|
|
|
|
|
'zip'
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
2014-04-01 15:43:38 +03:00
|
|
|
|
|
2014-10-08 11:49:34 +03:00
|
|
|
|
public function removeValue()
|
|
|
|
|
{
|
|
|
|
|
$oValue = $this->getValueObject();
|
|
|
|
|
/**
|
|
|
|
|
* Удаляем файл
|
|
|
|
|
*/
|
|
|
|
|
if ($aFilePrev = $oValue->getDataOne('file')) {
|
|
|
|
|
$this->RemoveFile($aFilePrev['path']);
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-04-01 15:43:38 +03:00
|
|
|
|
|
2014-10-08 11:49:34 +03:00
|
|
|
|
public function getFileFullName()
|
|
|
|
|
{
|
|
|
|
|
$oValue = $this->getValueObject();
|
|
|
|
|
if ($aFilePrev = $oValue->getDataOne('file')) {
|
|
|
|
|
return $aFilePrev['name'] . '.' . $aFilePrev['extension'];
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2014-04-02 15:21:58 +03:00
|
|
|
|
|
2014-10-08 11:49:34 +03:00
|
|
|
|
/**
|
|
|
|
|
* Сохраняет(копирует) файл на сервер
|
|
|
|
|
* Если переопределить данный метод, то можно сохранять файл, например, на Amazon S3
|
|
|
|
|
*
|
|
|
|
|
* @param string $sFileSource Полный путь до исходного файла
|
|
|
|
|
* @param string $sFileDest Полный путь до файла для сохранения с типом, например, [server]/home/var/site.ru/book.pdf
|
|
|
|
|
* @param int|null $iMode Права chmod для файла, например, 0777
|
|
|
|
|
* @param bool $bRemoveSource Удалять исходный файл или нет
|
|
|
|
|
* @return bool | string При успешном сохранении возвращает относительный путь до файла с типом, например, [relative]/image.jpg
|
|
|
|
|
*/
|
|
|
|
|
protected function SaveFile($sFileSource, $sFileDest, $iMode = null, $bRemoveSource = false)
|
|
|
|
|
{
|
|
|
|
|
if ($this->Fs_SaveFileLocal($sFileSource, $this->Fs_GetPathServer($sFileDest), $iMode, $bRemoveSource)) {
|
|
|
|
|
return $this->Fs_MakePath($this->Fs_GetPathRelativeFromServer($sFileDest), ModuleFs::PATH_TYPE_RELATIVE);
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2014-04-02 15:21:58 +03:00
|
|
|
|
|
2014-10-08 11:49:34 +03:00
|
|
|
|
/**
|
|
|
|
|
* Удаляет файл
|
|
|
|
|
* Если переопределить данный метод, то можно удалять файл, например, с Amazon S3
|
|
|
|
|
*
|
|
|
|
|
* @param string $sPathFile Полный путь до файла с типом, например, [relative]/book.pdf
|
|
|
|
|
*
|
|
|
|
|
* @return mixed
|
|
|
|
|
*/
|
|
|
|
|
protected function RemoveFile($sPathFile)
|
|
|
|
|
{
|
|
|
|
|
$sPathFile = $this->Fs_GetPathServer($sPathFile);
|
|
|
|
|
return $this->Fs_RemoveFileLocal($sPathFile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function DownloadFile()
|
|
|
|
|
{
|
|
|
|
|
$oValue = $this->getValueObject();
|
|
|
|
|
if ($aFilePrev = $oValue->getDataOne('file')) {
|
|
|
|
|
$this->Tools_DownloadFile($this->Fs_GetPathServer($aFilePrev['path']),
|
|
|
|
|
$aFilePrev['name'] . '.' . $aFilePrev['extension'], $aFilePrev['size']);
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2014-04-01 15:43:38 +03:00
|
|
|
|
}
|