Skip to content

Commit

Permalink
Наброски функционала создания превью для медиа-файлов
Browse files Browse the repository at this point in the history
  • Loading branch information
mzhelskiy committed Mar 21, 2014
1 parent 5bdb392 commit 2de215a
Show file tree
Hide file tree
Showing 13 changed files with 405 additions and 17 deletions.
47 changes: 47 additions & 0 deletions application/classes/actions/ActionAjax.class.php
Expand Up @@ -84,6 +84,7 @@ protected function RegisterEvent() {
$this->AddEventPreg('/^media$/i','/^submit-create-photoset$/','/^$/','EventMediaSubmitCreatePhotoset');
$this->AddEventPreg('/^media$/i','/^load-gallery$/','/^$/','EventMediaLoadGallery');
$this->AddEventPreg('/^media$/i','/^remove-file$/','/^$/','EventMediaRemoveFile');
$this->AddEventPreg('/^media$/i','/^create-preview-file$/','/^$/','EventMediaCreatePreviewFile');
$this->AddEventPreg('/^media$/i','/^save-data-file$/','/^$/','EventMediaSaveDataFile');

$this->AddEventPreg('/^property$/i','/^tags$/','/^autocompleter$/','/^$/','EventPropertyTagsAutocompleter');
Expand Down Expand Up @@ -532,6 +533,52 @@ protected function EventMediaRemoveFile() {
}
}

protected function EventMediaCreatePreviewFile() {
/**
* Пользователь авторизован?
*/
if (!$this->oUserCurrent) {
$this->Message_AddErrorSingle($this->Lang_Get('need_authorization'),$this->Lang_Get('error'));
return;
}
$sId=getRequestStr('id');
if (!$oMedia=$this->Media_GetMediaById($sId)) {
return $this->EventErrorDebug();
}

$sTargetType=getRequestStr('target_type');
$sTargetId=getRequestStr('target_id');
$sTargetTmp=getRequestStr('target_tmp');

/**
* Получаем объект связи
*/
$aFilter=array('media_id'=>$oMedia->getId(),'target_type'=>$sTargetType);
if ($sTargetTmp) {
$aFilter['target_tmp']=$sTargetTmp;
} else {
$aFilter['target_id']=$sTargetId;
}
if (!$oTarget=$this->Media_GetTargetByFilter($aFilter)) {
return $this->EventErrorDebug();
}
if ($oTarget->getIsPreview()) {
return $this->EventErrorDebug();
}


/**
* Проверяем доступ к этому медиа
*/
if (true===$res=$this->Media_CheckTarget($oTarget->getTargetType(),$oTarget->getTargetId(),ModuleMedia::TYPE_CHECK_ALLOW_PREVIEW,array('media'=>$oMedia,'user'=>$this->oUserCurrent))) {
$this->Media_CreateFilePreview($oMedia,$oTarget);

$this->Viewer_AssignAjax('bUnsetOther',true);
} else {
$this->Message_AddErrorSingle(is_string($res) ? $res : $this->Lang_Get('system_error'));
}
}

protected function EventMediaLoadGallery() {
/**
* Пользователь авторизован?
Expand Down
145 changes: 138 additions & 7 deletions application/classes/modules/media/Media.class.php
Expand Up @@ -35,6 +35,7 @@ class ModuleMedia extends ModuleORM {
const TYPE_CHECK_ALLOW_ADD='add';
const TYPE_CHECK_ALLOW_REMOVE='remove';
const TYPE_CHECK_ALLOW_UPDATE='update';
const TYPE_CHECK_ALLOW_PREVIEW='preview';
/**
* Объект текущего пользователя
*
Expand All @@ -45,7 +46,9 @@ class ModuleMedia extends ModuleORM {
protected $oMapper=null;

protected $aTargetTypes=array(
'topic'=>array(),
'topic'=>array(
'allow_preview'=>true,
),
'comment'=>array(),
'blog'=>array(),
'talk'=>array(),
Expand Down Expand Up @@ -105,12 +108,29 @@ public function IsAllowTargetType($sTargetType) {
*
* @param string $sTargetType
*
* @return mixed
* @return array|null
*/
public function GetTargetTypeParams($sTargetType) {
if ($this->IsAllowTargetType($sTargetType)) {
return $this->aTargetTypes[$sTargetType];
}
return null;
}

/**
* Возвращает конкретный парметры нужного типа
*
* @param string $sTargetType
* @param string $sName
*
* @return mixed|null
*/
public function GetTargetTypeParam($sTargetType,$sName) {
$aParams=$this->GetTargetTypeParams($sTargetType);
if ($aParams and array_key_exists($sName,$aParams)) {
return $aParams[$sName];
}
return null;
}
/**
* Проверяет разрешен ли тип медиа
Expand Down Expand Up @@ -144,6 +164,17 @@ public function CheckTarget($sTargetType,$iTargetId=null,$sAllowType=null,$aPara
}
return false;
}

public function NotifyCreatePreviewTarget($sTargetType,$iTargetId,$oRelationTarget) {
if (!$this->IsAllowTargetType($sTargetType)) {
return false;
}
$sMethod = 'NotifyCreatePreviewTarget'.func_camelize($sTargetType);
if (method_exists($this,$sMethod)) {
return $this->$sMethod($iTargetId,$oRelationTarget);
}
return false;
}
/**
* Возвращает параметр конфига с учетом текущего target_type
*
Expand Down Expand Up @@ -351,7 +382,7 @@ public function GenerateImageBySizes($sFileSource,$sDirDist,$sFileName,$aSizes,$
$aSizes[$k]=$this->ParsedImageSize($v);
}
}

$sFileResult=null;
foreach ($aSizes as $aSize) {
/**
* Для каждого указанного в конфиге размера генерируем картинку
Expand All @@ -362,11 +393,15 @@ public function GenerateImageBySizes($sFileSource,$sDirDist,$sFileName,$aSizes,$
$oImage->cropProportion($aSize['w']/$aSize['h'],'center');
$sNewFileName .= 'crop';
}
if (!$oImage->resize($aSize['w'],$aSize['h'],true)->saveSmart($sDirDist,$sNewFileName)) {
if (!$sFileResult=$oImage->resize($aSize['w'],$aSize['h'],true)->saveSmart($sDirDist,$sNewFileName)) {
// TODO: прерывать и возвращать false?
}
}
}
/**
* Возвращаем путь до последнего созданного файла
*/
return $sFileResult;
}
public function RemoveImageBySizes($sPath,$aSizes,$bRemoveOriginal=true) {
if ($aSizes) {
Expand Down Expand Up @@ -398,11 +433,13 @@ public function RemoveImageBySizes($sPath,$aSizes,$bRemoveOriginal=true) {
*
* @param string $sTargetType
* @param string|null $sTargetId Желательно для одного типа при формировании каталога для загрузки выбрать что-то одно - использовать $sTargetId или нет
* @param string $sPostfix Дополнительный каталог для сохранения в конце цепочки
*
* @return string
*/
public function GetSaveDir($sTargetType,$sTargetId=null) {
return Config::Get('path.uploads.base')."/media/{$sTargetType}/".date('Y/m/d/H/');
public function GetSaveDir($sTargetType,$sTargetId=null,$sPostfix='') {
$sPostfix=trim($sPostfix,'/');
return Config::Get('path.uploads.base')."/media/{$sTargetType}/".date('Y/m/d/H/').($sPostfix ? "{$sPostfix}/" : '');
}

public function BuildCodeForEditor($oMedia,$aParams) {
Expand Down Expand Up @@ -569,6 +606,12 @@ public function ReplaceTargetTmpById($sTargetType,$sTargetId,$sTargetTmp=null) {
$oTarget->setTargetTmp(null);
$oTarget->setTargetId($sTargetId);
$oTarget->Update();
/**
* TODO: Уведомляем объект о создании превью
*/
if ($oTarget->getIsPreview()) {

}
}
}
}
Expand Down Expand Up @@ -745,11 +788,99 @@ public function CheckStandartMediaAllow($sAllowType,$aParams) {
}
return false;
}
/**
* Создает превью у файла для определенного типа
*
* @param $oMedia
* @param $oTarget
*
* @return bool|string
*/
public function CreateFilePreview($oMedia,$oTarget) {
if (!$this->GetTargetTypeParam($oTarget->getTargetType(),'allow_preview')) {
return false;
}

/**
* TODO: нужно удалить прошлое превью
*/

if ($oMedia->getType()==self::TYPE_IMAGE) {
$aParams=$this->Image_BuildParams('media.preview_'.$oTarget->getTargetType());

if(!$oImage=$this->Image_OpenFrom($oMedia->getFilePath(),$aParams)) {
return $this->Image_GetLastError();
}
/**
* Сохраняем во временный файл
*/
if (!$sFileTmp=$oImage->saveTmp()) {
return $this->Image_GetLastError();
}
unset($oImage);
/**
* Получаем список необходимых размеров превью
*/
$aSizes=$this->GetConfigParam('image.preview.sizes',$oTarget->getTargetType());
/**
* Каталог для сохранения превью
*/
$sPath=$this->GetSaveDir($oTarget->getTargetType(),$oTarget->getTargetId(),'preview');
/**
* Уникальное имя файла
*/
$sFileName=func_generator(20);
/**
* Генерируем варианты с необходимыми размерами
*/
$sFileLast=$this->GenerateImageBySizes($sFileTmp,$sPath,$sFileName,$aSizes,$aParams);
$aSizeLast=end($aSizes);
$sReplaceSize='_'.$aSizeLast['w'].'x'.$aSizeLast['h'];
if ($aSizeLast['crop']) {
$sReplaceSize.='crop';
}
$sFileLast=str_replace($sReplaceSize,'',$sFileLast);
/**
* Теперь можно удалить временный файл
*/
$this->Fs_RemoveFileLocal($sFileTmp);
/**
* Сохраняем данные во связи
*/
$oTarget->setDataOne('image_preview_sizes',$aSizes);
$oTarget->setDataOne('image_preview',$sFileLast);
$oTarget->setIsPreview(1);
$oTarget->Update();

/**
* Уведомляем объект о создании нового превью
*/
if ($oTarget->getTargetId()) {
$this->NotifyCreatePreviewTarget($oTarget->getTargetType(),$oTarget->getTargetId(),$oTarget);
}

return true;
}
}






/**
* Обработка создания превью для типа 'topic'
* Название метода формируется автоматически
*
* @param int $iTargetId
* @param ModuleMedia_EntityTarget $oRelationTarget
*/
public function NotifyCreatePreviewTargetTopic($iTargetId,$oRelationTarget) {
if ($oTopic=$this->Topic_GetTopicById($iTargetId)) {
$oTopic->setPreviewImage($oRelationTarget->getDataOne('image_preview'));
$this->Topic_UpdateTopic($oTopic);
}
}
/**
* Проверка владельца с типом "topic"
* Название метода формируется автоматически
Expand All @@ -764,7 +895,7 @@ public function CheckTargetTopic($iTargetId,$sAllowType,$aParams) {
if (!$oUser=$aParams['user']) {
return false;
}
if ($sAllowType==self::TYPE_CHECK_ALLOW_ADD) {
if (in_array($sAllowType,array(self::TYPE_CHECK_ALLOW_ADD,self::TYPE_CHECK_ALLOW_PREVIEW))) {
if (is_null($iTargetId)) {
/**
* Разрешаем для всех новых топиков
Expand Down
Expand Up @@ -91,4 +91,8 @@ public function setDataOne($sKey,$mValue) {
$aData[$sKey]=$mValue;
$this->setData($aData);
}

public function getRelationTarget() {
return $this->_getDataOne('_relation_entity');
}
}
27 changes: 27 additions & 0 deletions application/classes/modules/media/entity/Target.entity.class.php
Expand Up @@ -35,4 +35,31 @@ protected function beforeSave() {
}
return true;
}


public function getData() {
$aData=@unserialize($this->_getDataOne('data'));
if (!$aData) {
$aData=array();
}
return $aData;
}

public function setData($aRules) {
$this->_aData['data']=@serialize($aRules);
}

public function getDataOne($sKey) {
$aData=$this->getData();
if (isset($aData[$sKey])) {
return $aData[$sKey];
}
return null;
}

public function setDataOne($sKey,$mValue) {
$aData=$this->getData();
$aData[$sKey]=$mValue;
$this->setData($aData);
}
}

0 comments on commit 2de215a

Please sign in to comment.