ModuleMedia
Package | application.modules.media |
---|---|
Inheritance | class ModuleMedia » ModuleORM » Module » LsObject |
Since | 2.0 |
Source Code | /application/classes/modules/media/Media.class.php |
Protected Properties
Property | Type | Description | Defined By |
---|---|---|---|
_aBehaviors | Список поведений в виде готовых объектов, формируется автоматически | LsObject | |
aBehaviors | array | Список поведений | LsObject |
aMediaTypes | array | Список доступных типов медиа | ModuleMedia |
aTargetTypes | ModuleMedia | ||
bIsInit | bool | Указывает на то, была ли проведенна инициализация модуля | Module |
oMapper | ModuleMedia | ||
oMapperORM | MapperORM | Объект маппера ORM | ModuleORM |
oUserCurrent | ModuleUser_EntityUser|null | Объект текущего пользователя | ModuleMedia |
Public Methods
Method | Description | Defined By |
---|---|---|
AddBehaviorHook() | Добавляет хук поведения | LsObject |
AddTargetType() | Добавляет в разрешенные новый тип | ModuleMedia |
AttachBehavior() | Присоединяет поведение к объекту | LsObject |
BuildCodeForEditor() | ModuleMedia | |
CallbackParserTagGallery() | Обработка тега gallery в тексте | ModuleMedia |
CheckStandartMediaAllow() | Производит стандартнуе проверку на определенное действие с конкретным объектом Media | ModuleMedia |
CheckTarget() | Проверка объекта target - владелец медиа | ModuleMedia |
CheckTargetBlog() | Проверка владельца с типом "blog" | ModuleMedia |
CheckTargetComment() | Проверка владельца с типом "comment" | ModuleMedia |
CheckTargetTalk() | Проверка владельца с типом "talk" | ModuleMedia |
CheckTargetTopic() | Проверка владельца с типом "topic" | ModuleMedia |
CreateFilePreview() | Создает превью у файла для определенного типа | ModuleMedia |
DeleteFiles() | Выполняет удаление файлов медиа-объекта | ModuleMedia |
DeleteItemsByFilter() | Удаляет сущности по фильтру | ModuleORM |
DetachBehavior() | Отсоединяет поведение от объекта | LsObject |
GenerateImageBySizes() | Создает набор отресайзанных изображений | ModuleMedia |
GetAggregateFunctionByFilter() | Получить значение агрегирующей функции | ModuleORM |
GetAllowMediaItemsById() | Возвращает список media с учетов прав доступа текущего пользователя | ModuleMedia |
GetBehavior() | Возвращает объект поведения по его имени | LsObject |
GetBehaviors() | Возвращает все объекты поведения | LsObject |
GetByFilter() | Получить сущность по фильтру | ModuleORM |
GetConfigParam() | Возвращает параметр конфига с учетом текущего target_type | ModuleMedia |
GetCountItemsByFilter() | Получить количество сущностей по фильтру | ModuleORM |
GetCountItemsByJoinEntity() | ModuleORM | |
GetFileWebPath() | ModuleMedia | |
GetImagePathBySize() | Возвращает путь до изображения конкретного размера | ModuleMedia |
GetImageWebPath() | ModuleMedia | |
GetItemsByArray() | Возвращает список сущностей по фильтру | ModuleORM |
GetItemsByFilter() | Получить список сущностей по фильтру | ModuleORM |
GetItemsByJoinEntity() | ModuleORM | |
GetMediaByTarget() | ModuleMedia | |
GetMediaByTargetTmp() | ModuleMedia | |
GetSaveDir() | Возвращает каталог для сохранения контента медиа | ModuleMedia |
GetTargetTypeParam() | Возвращает конкретный парметры нужного типа | ModuleMedia |
GetTargetTypeParams() | Возвращает парметры нужного типа | ModuleMedia |
GetTargetTypes() | Возвращает список типов объектов | ModuleMedia |
Init() | Инициализация | ModuleMedia |
IsAllowMediaType() | Проверяет разрешен ли тип медиа | ModuleMedia |
IsAllowTargetType() | Проверяет разрешен ли данный тип | ModuleMedia |
LoadTree() | Для сущностей со связью RELATION_TYPE_TREE возвращает список сущностей в виде дерева | ModuleORM |
NotifyCreatePreviewTarget() | ModuleMedia | |
NotifyCreatePreviewTargetTopic() | Обработка создания превью для типа 'topic' | ModuleMedia |
NotifyRemovePreviewTarget() | ModuleMedia | |
NotifyRemovePreviewTargetTopic() | Обработка удаления превью для типа 'topic' | ModuleMedia |
ParsedImageSize() | Парсит строку с размером изображения | ModuleMedia |
ProcessingFile() | ModuleMedia | |
ProcessingFileImage() | ModuleMedia | |
RemoveAllPreviewByTarget() | Удаляет все превью у конкретного объекта | ModuleMedia |
RemoveBehaviorHook() | Удаляет хук поведения | LsObject |
RemoveFilePreview() | ModuleMedia | |
RemoveImageBySizes() | ModuleMedia | |
RemoveTarget() | Удаляет связь с медиа данными + при необходимости удаляет сами медиа данные | ModuleMedia |
RemoveTargetByTypeAndId() | ModuleMedia | |
ReplaceTargetTmpById() | Заменяет временный идентификатор на необходимый ID объекта | ModuleMedia |
RunBehaviorHook() | Запускает хук поведения на выполнение | LsObject |
SetInit() | Помечает модуль как инициализированный | Module |
Shutdown() | Метод срабатывает при завершении работы ядра | Module |
Upload() | ModuleMedia | |
UploadLocal() | ModuleMedia | |
UploadUrl() | ModuleMedia | |
__call() | Ставим хук на вызов неизвестного метода и считаем что хотели вызвать метод какого либо модуля. | ModuleORM |
__clone() | Блокируем копирование/клонирование объекта | Module |
__construct() | Конструктор, запускается автоматически при создании объекта | LsObject |
__get() | Обработка доступа к объекты поведения | LsObject |
buildTree() | Построение дерева | ModuleORM |
isInit() | Возвращает значение флага инициализации модуля | Module |
Protected Methods
Method | Description | Defined By |
---|---|---|
PrepareBehaviors() | Инициализация поведений | LsObject |
_AddEntity() | Добавление сущности в БД | ModuleORM |
_DeleteEntity() | Удаление сущности из БД | ModuleORM |
_GetAncestorsOfEntity() | Для сущности со связью RELATION_TYPE_TREE возвращает список всех предков | ModuleORM |
_GetChildrenOfEntity() | Для сущности со связью RELATION_TYPE_TREE возвращает список прямых потомков | ModuleORM |
_GetDescendantsOfEntity() | Для сущности со связью RELATION_TYPE_TREE возвращает список всех потомков | ModuleORM |
_GetParentOfEntity() | Для сущности со связью RELATION_TYPE_TREE возвращает предка | ModuleORM |
_LoadMapperORM() | Загрузка маппера ORM | ModuleORM |
_NormalizeEntityRootName() | Приводит название сущности к единому формату полного имени класса | ModuleORM |
_ReloadEntity() | Обновляет данные сущности из БД | ModuleORM |
_SaveEntity() | Сохранение сущности в БД | ModuleORM |
_ShowColumnsFrom() | Список полей сущности | ModuleORM |
_ShowPrimaryIndexFrom() | Primary индекс сущности | ModuleORM |
_UpdateEntity() | Обновление сущности в БД | ModuleORM |
_deleteManyToManyRelation() | Выполняет удаление всех связей many_to_many сущности | ModuleORM |
_setIndexesFromField() | Returns assotiative array, indexed by PRIMARY KEY or another field. | ModuleORM |
_setIndexesGroupField() | Возвращает сгруппированный массив по нужному полю | ModuleORM |
_setIndexesGroupJoinField() | Возвращает сгруппированный массив по нужному полю из данных таблицы связей | ModuleORM |
_updateManyToManyRelation() | Выполняет обновление связи many_to_many у сущности | ModuleORM |
Property Details
Список доступных типов медиа
Объект текущего пользователя
Method Details
public bool AddTargetType(string $sTargetType, array $aParams=array (
))
| ||
$sTargetType | string | Тип |
$aParams | array | Параметры |
{return} | bool |
public function AddTargetType($sTargetType, $aParams = array())
{
if (!array_key_exists($sTargetType, $this->aTargetTypes)) {
$this->aTargetTypes[$sTargetType] = $aParams;
return true;
}
return false;
}
Добавляет в разрешенные новый тип
public void BuildCodeForEditor($oMedia, $aParams)
| ||
$oMedia | ||
$aParams |
public function BuildCodeForEditor($oMedia, $aParams)
{
$sCode = '';
if ($oMedia->getType() == self::TYPE_IMAGE) {
$aSizes = (array)$oMedia->getDataOne('image_sizes');
$sSizeParam = isset($aParams['size']) ? (string)$aParams['size'] : '';
$sSize = 'original';
$bNeedHref = false;
/**
* Проверяем корректность размера
*/
foreach ($aSizes as $aSizeAllow) {
$sSizeKey = $aSizeAllow['w'] . 'x' . $aSizeAllow['h'] . ($aSizeAllow['crop'] ? 'crop' : '');
if ($sSizeKey == $sSizeParam) {
$sSize = $sSizeKey;
/**
* Необходимость лайтбокса
*/
if ($aSizeAllow['w'] < $oMedia->getWidth()) {
$bNeedHref = true;
}
}
}
$sPath = $oMedia->getFileWebPath($sSize == 'original' ? null : $sSize);
$sCode = '<img src="' . $sPath . '" ';
if (!isset($aParams['title'])) {
$aParams['title'] = $oMedia->getDataOne('title');
}
if (!isset($aParams['skip_title']) and $aParams['title']) {
$sCode .= ' title="' . htmlspecialchars($aParams['title']) . '" ';
$sCode .= ' alt="' . htmlspecialchars($aParams['title']) . '" ';
}
if (isset($aParams['align']) and in_array($aParams['align'], array('left', 'right', 'center'))) {
if ($aParams['align'] == 'center') {
$sCode .= ' class="image-center"';
} else {
$sCode .= ' align="' . htmlspecialchars($aParams['align']) . '" ';
}
}
$sDataParams = '';
if (isset($aParams['data']) and is_array($aParams['data'])) {
foreach ($aParams['data'] as $sDataName => $sDataValue) {
if ($sDataValue) {
$sDataParams .= ' data-' . $sDataName . '="' . htmlspecialchars($sDataValue) . '"';
}
}
}
if ($bNeedHref) {
$sCode .= ' />';
$sLbxGroup = '';
if (isset($aParams['lbx_group'])) {
$sLbxGroup = ' data-rel="' . htmlspecialchars($aParams['lbx_group']) . '"';
}
$sCode = '<a class="js-lbx" ' . $sLbxGroup . ' href="' . $oMedia->getFileWebPath() . '" ' . $sDataParams . '>' . $sCode . '</a>';
} else {
$sCode .= $sDataParams . ' />';
}
}
return $sCode;
}
public string CallbackParserTagGallery(string $sTag, array $aParams)
| ||
$sTag | string | Тег на ктором сработал колбэк |
$aParams | array | Список параметров тега |
{return} | string |
public function CallbackParserTagGallery($sTag, $aParams)
{
if (isset($aParams['items'])) {
$aItems = explode(',', $aParams['items']);
}
if (!(isset($aItems) and $aMediaItems = $this->Media_GetAllowMediaItemsById($aItems))) {
return '';
}
$aParamsMedia = array(
'size' => '100crop',
'skip_title' => true
);
$sProperties = '';
if (isset($aParams['nav']) and in_array($aParams['nav'], array('thumbs'))) {
$sProperties .= ' data-nav="' . $aParams['nav'] . '" ';
}
$sTextResult = '<div class="fotorama" ' . $sProperties . '>' . "\r\n";
foreach ($aMediaItems as $oMedia) {
if (isset($aParams['caption']) and $aParams['caption']) {
$aParamsMedia['data']['caption'] = htmlspecialchars($oMedia->getDataOne('title'));
}
$sTextResult .= "\t" . $this->Media_BuildCodeForEditor($oMedia, $aParamsMedia) . "\r\n";
}
$sTextResult .= "</div>\r\n";
return $sTextResult;
}
Обработка тега gallery в тексте
<gallery items="12,55,38" />
public bool CheckStandartMediaAllow($sAllowType $sAllowType, $aParams $aParams)
| ||
$sAllowType | $sAllowType | |
$aParams | $aParams | |
{return} | bool |
public function CheckStandartMediaAllow($sAllowType, $aParams)
{
if (!$oUser = $aParams['user']) {
return false;
}
$oMedia = isset($aParams['media']) ? $aParams['media'] : null;
if (!$oMedia) {
return false;
}
if (in_array($sAllowType, array(self::TYPE_CHECK_ALLOW_REMOVE, self::TYPE_CHECK_ALLOW_UPDATE))) {
if ($oMedia->getUserId() == $oUser->getId()) {
return true;
}
}
return false;
}
Производит стандартнуе проверку на определенное действие с конкретным объектом Media
public bool CheckTarget(string $sTargetType, int $iTargetId=NULL, string $sAllowType=NULL, array $aParams=array (
))
| ||
$sTargetType | string | Тип |
$iTargetId | int | ID владельца |
$sAllowType | string | |
$aParams | array | |
{return} | bool |
public function CheckTarget($sTargetType, $iTargetId = null, $sAllowType = null, $aParams = array())
{
if (!$this->IsAllowTargetType($sTargetType)) {
return false;
}
$sMethod = 'CheckTarget' . func_camelize($sTargetType);
if (method_exists($this, $sMethod)) {
if (!array_key_exists('user', $aParams)) {
$aParams['user'] = $this->oUserCurrent;
}
return $this->$sMethod($iTargetId, $sAllowType, $aParams);
}
return false;
}
Проверка объекта target - владелец медиа
public bool CheckTargetBlog(int|null $iTargetId, string $sAllowType, array $aParams)
| ||
$iTargetId | int|null | ID владельца, для новых объектов может быть не определен |
$sAllowType | string | Тип доступа, константа self::TYPE_CHECK_ALLOW_* |
$aParams | array | Дополнительные параметры, всегда есть ключ 'user' |
{return} | bool |
public function CheckTargetBlog($iTargetId, $sAllowType, $aParams)
{
if (!$oUser = $aParams['user']) {
return false;
}
if ($sAllowType == self::TYPE_CHECK_ALLOW_ADD) {
if (is_null($iTargetId)) {
/**
* Разрешаем для всех новых блогов
*/
return true;
}
if ($oBlog = $this->Blog_GetBlogById($iTargetId)) {
/**
* Проверяем права на редактирование блога
*/
if ($this->ACL_IsAllowEditBlog($oBlog, $oUser)) {
return true;
}
}
} else {
return $this->CheckStandartMediaAllow($sAllowType, $aParams);
}
return false;
}
Проверка владельца с типом "blog" Название метода формируется автоматически
public bool CheckTargetComment(int|null $iTargetId, string $sAllowType, array $aParams)
| ||
$iTargetId | int|null | ID владельца, для новых объектов может быть не определен |
$sAllowType | string | Тип доступа, константа self::TYPE_CHECK_ALLOW_* |
$aParams | array | Дополнительные параметры, всегда есть ключ 'user' |
{return} | bool |
public function CheckTargetComment($iTargetId, $sAllowType, $aParams)
{
if (!$oUser = $aParams['user']) {
return false;
}
if ($sAllowType == self::TYPE_CHECK_ALLOW_ADD) {
if (is_null($iTargetId)) {
/**
* Разрешаем для всех новых комментариев
*/
return true;
}
if ($oComment = $this->Comment_GetCommentById($iTargetId)) {
/**
* Проверяем права на редактирование комментария
*/
if ($this->ACL_IsAllowEditComment($oComment, $oUser)) {
return true;
}
}
} else {
return $this->CheckStandartMediaAllow($sAllowType, $aParams);
}
return false;
}
Проверка владельца с типом "comment" Название метода формируется автоматически
public bool CheckTargetTalk(int|null $iTargetId, string $sAllowType, array $aParams)
| ||
$iTargetId | int|null | ID владельца, для новых объектов может быть не определен |
$sAllowType | string | Тип доступа, константа self::TYPE_CHECK_ALLOW_* |
$aParams | array | Дополнительные параметры, всегда есть ключ 'user' |
{return} | bool |
public function CheckTargetTalk($iTargetId, $sAllowType, $aParams)
{
if (!$oUser = $aParams['user']) {
return false;
}
if ($sAllowType == self::TYPE_CHECK_ALLOW_ADD) {
if (is_null($iTargetId)) {
/**
* Разрешаем для всех новых блогов
*/
return true;
}
/**
* Редактировать сообщения нельзя
*/
return false;
} else {
return $this->CheckStandartMediaAllow($sAllowType, $aParams);
}
return false;
}
Проверка владельца с типом "talk" Название метода формируется автоматически
public bool CheckTargetTopic(int|null $iTargetId, string $sAllowType, array $aParams)
| ||
$iTargetId | int|null | ID владельца, для новых объектов может быть не определен |
$sAllowType | string | Тип доступа, константа self::TYPE_CHECK_ALLOW_* |
$aParams | array | Дополнительные параметры, всегда есть ключ 'user' |
{return} | bool |
public function CheckTargetTopic($iTargetId, $sAllowType, $aParams)
{
if (!$oUser = $aParams['user']) {
return false;
}
if (in_array($sAllowType, array(self::TYPE_CHECK_ALLOW_ADD, self::TYPE_CHECK_ALLOW_PREVIEW))) {
if (is_null($iTargetId)) {
/**
* Разрешаем для всех новых топиков
*/
return true;
}
if ($oTopic = $this->Topic_GetTopicById($iTargetId)) {
/**
* Проверяем права на редактирование топика
*/
if ($this->ACL_IsAllowEditTopic($oTopic, $oUser)) {
return true;
}
}
} else {
return $this->CheckStandartMediaAllow($sAllowType, $aParams);
}
return false;
}
Проверка владельца с типом "topic" Название метода формируется автоматически
public bool|string CreateFilePreview($oMedia $oMedia, $oTarget $oTarget)
| ||
$oMedia | $oMedia | |
$oTarget | $oTarget | |
{return} | bool|string |
public function CreateFilePreview($oMedia, $oTarget)
{
if (!$this->GetTargetTypeParam($oTarget->getTargetType(), 'allow_preview')) {
return false;
}
/**
* Нужно удалить прошлое превью (если оно есть)
*/
$this->RemoveFilePreview($oMedia, $oTarget);
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;
}
}
Создает превью у файла для определенного типа
public void DeleteFiles($oMedia $oMedia)
| ||
$oMedia | $oMedia |
public function DeleteFiles($oMedia)
{
/**
* Сначала удаляем все файлы
*/
if ($oMedia->getType() == self::TYPE_IMAGE) {
$aSizes = $oMedia->getDataOne('image_sizes');
$this->RemoveImageBySizes($oMedia->getFilePath(), $aSizes);
}
}
Выполняет удаление файлов медиа-объекта
public void GenerateImageBySizes($sFileSource $sFileSource, $sDirDist $sDirDist, $sFileName $sFileName, $aSizes $aSizes, null $aParams=NULL)
| ||
$sFileSource | $sFileSource | |
$sDirDist | $sDirDist | |
$sFileName | $sFileName | |
$aSizes | $aSizes | |
$aParams | null |
public function GenerateImageBySizes($sFileSource, $sDirDist, $sFileName, $aSizes, $aParams = null)
{
if (!$aSizes) {
return;
}
/**
* Преобразуем упрощенную запись списка размеров в полную
*/
foreach ($aSizes as $k => $v) {
if (!is_array($v)) {
$aSizes[$k] = $this->ParsedImageSize($v);
}
}
$sFileResult = null;
foreach ($aSizes as $aSize) {
/**
* Для каждого указанного в конфиге размера генерируем картинку
*/
$sNewFileName = $sFileName . '_' . $aSize['w'] . 'x' . $aSize['h'];
if ($oImage = $this->Image_Open($sFileSource, $aParams)) {
if ($aSize['crop']) {
$oImage->cropProportion($aSize['w'] / $aSize['h'], 'center');
$sNewFileName .= 'crop';
}
if (!$sFileResult = $oImage->resize($aSize['w'], $aSize['h'], true)->saveSmart($sDirDist,
$sNewFileName)
) {
// TODO: прерывать и возвращать false?
}
}
}
/**
* Возвращаем путь до последнего созданного файла
*/
return $sFileResult;
}
Создает набор отресайзанных изображений Варианты наименований результирующих файлов в зависимости от размеров: file_100x150 - w=100 h=150 crop=false file_100x150crop - w=100 h=150 crop=true file_x150 - w=null h=150 crop=false file_100x - w=100 h=null crop=false
public array GetAllowMediaItemsById(array $aId)
| ||
$aId | array | |
{return} | array |
public function GetAllowMediaItemsById($aId)
{
$aIdItems = array();
foreach ((array)$aId as $iId) {
$aIdItems[] = (int)$iId;
}
if (is_array($aIdItems) and count($aIdItems)) {
$iUserId = $this->oUserCurrent ? $this->oUserCurrent->getId() : null;
return $this->Media_GetMediaItemsByFilter(array(
'#where' => array(
'id in (?a) AND ( user_id is null OR user_id = ?d )' => array(
$aIdItems,
$iUserId
)
)
)
);
}
return array();
}
Возвращает список media с учетов прав доступа текущего пользователя
public mixed GetConfigParam(string $sParam, string $sTargetType)
| ||
$sParam | string | Ключ конфига относительно module.media |
$sTargetType | string | Тип |
{return} | mixed |
public function GetConfigParam($sParam, $sTargetType)
{
$mValue = Config::Get("module.media.type.{$sTargetType}.{$sParam}");
if (!$mValue) {
$mValue = Config::Get("module.media.{$sParam}");
}
return $mValue;
}
Возвращает параметр конфига с учетом текущего target_type
public void GetFileWebPath($oMedia, $sSize=NULL)
| ||
$oMedia | ||
$sSize |
public function GetFileWebPath($oMedia, $sSize = null)
{
if ($oMedia->getType() == self::TYPE_IMAGE) {
/**
* Проверяем необходимость автоматического создания превью нужного размера - если разрешено настройками и файл НЕ существует
*/
if ($this->GetConfigParam('image.autoresize',
$oMedia->getTargetType()) and !$this->Image_IsExistsFile($this->GetImagePathBySize($oMedia->getFilePath(),
$sSize))
) {
/**
* Запускаем генерацию изображения нужного размера
*/
$aSize = $this->ParsedImageSize($sSize);
$aParams = $this->Image_BuildParams('media.' . $oMedia->getTargetType());
$sNewFileName = $this->GetImagePathBySize($oMedia->getFilePath(), $sSize);
if ($oImage = $this->Image_OpenFrom($oMedia->getFilePath(), $aParams)) {
if ($aSize['crop']) {
$oImage->cropProportion($aSize['w'] / $aSize['h'], 'center');
}
$oImage->resize($aSize['w'], $aSize['h'], true)->save($sNewFileName);
/**
* Обновляем список размеров
*/
$aSizeOld = (array)$oMedia->getDataOne('image_sizes');
$aSizeOld[] = $aSize;
$oMedia->setDataOne('image_sizes', $aSizeOld);
$oMedia->Update();
}
}
return $this->GetImageWebPath($oMedia->getFilePath(), $sSize);
}
return null;
}
public string GetImagePathBySize(string $sPath, string $sSize)
| ||
$sPath | string | |
$sSize | string | |
{return} | string |
public function GetImagePathBySize($sPath, $sSize)
{
$aPathInfo = pathinfo($sPath);
if (is_array($sSize)) {
$aSize = $sSize;
$sSize = $aSize['w'] . 'x' . $aSize['h'];
if ($aSize['crop']) {
$sSize .= 'crop';
}
} else {
if (preg_match('#^(\d+)([a-z]{2,10})?$#i', $sSize, $aMatch)) {
$sSize = $aMatch[1] . 'x' . $aMatch[1];
if (isset($aMatch[2])) {
$sSize .= strtolower($aMatch[2]);
}
}
}
return $aPathInfo['dirname'] . '/' . $aPathInfo['filename'] . '_' . $sSize . '.' . $aPathInfo['extension'];
}
Возвращает путь до изображения конкретного размера Варианты преобразования размеров в имя файла: 100 - file_100x100 100crop - file_100x100crop 100x150 - file_100x150 100x150crop - file_100x150crop x150 - file_x150 100x - file_100x
public void GetImageWebPath($sPath, $sSize=NULL)
| ||
$sPath | ||
$sSize |
public function GetImageWebPath($sPath, $sSize = null)
{
$sPath = $this->Fs_GetPathWeb($sPath);
if ($sSize) {
return $this->GetImagePathBySize($sPath, $sSize);
} else {
return $sPath;
}
}
public void GetMediaByTarget($sTargetType, $iTargetId, $iUserId=NULL)
| ||
$sTargetType | ||
$iTargetId | ||
$iUserId |
public function GetMediaByTarget($sTargetType, $iTargetId, $iUserId = null)
{
return $this->oMapper->GetMediaByTarget($sTargetType, $iTargetId, $iUserId);
}
public void GetMediaByTargetTmp($sTargetTmp, $iUserId=NULL)
| ||
$sTargetTmp | ||
$iUserId |
public function GetMediaByTargetTmp($sTargetTmp, $iUserId = null)
{
return $this->oMapper->GetMediaByTargetTmp($sTargetTmp, $iUserId);
}
public string GetSaveDir(string $sTargetType, string|null $sTargetId=NULL, string $sPostfix='')
| ||
$sTargetType | string | |
$sTargetId | string|null | Желательно для одного типа при формировании каталога для загрузки выбрать что-то одно - использовать $sTargetId или нет |
$sPostfix | string | Дополнительный каталог для сохранения в конце цепочки |
{return} | string |
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 mixed|null GetTargetTypeParam(string $sTargetType, string $sName)
| ||
$sTargetType | string | |
$sName | string | |
{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;
}
Возвращает конкретный парметры нужного типа
public array|null GetTargetTypeParams(string $sTargetType)
| ||
$sTargetType | string | |
{return} | array|null |
public function GetTargetTypeParams($sTargetType)
{
if ($this->IsAllowTargetType($sTargetType)) {
return $this->aTargetTypes[$sTargetType];
}
return null;
}
Возвращает парметры нужного типа
public array GetTargetTypes()
| ||
{return} | array |
public function GetTargetTypes()
{
return $this->aTargetTypes;
}
Возвращает список типов объектов
public void Init()
|
public function Init()
{
parent::Init();
$this->oMapper = Engine::GetMapper(__CLASS__);
$this->oUserCurrent = $this->User_GetUserCurrent();
}
Инициализация
public bool IsAllowMediaType(string $sType)
| ||
$sType | string | |
{return} | bool |
public function IsAllowMediaType($sType)
{
return in_array($sType, $this->aMediaTypes);
}
Проверяет разрешен ли тип медиа
public bool IsAllowTargetType(string $sTargetType)
| ||
$sTargetType | string | Тип |
{return} | bool |
public function IsAllowTargetType($sTargetType)
{
return in_array($sTargetType, array_keys($this->aTargetTypes));
}
Проверяет разрешен ли данный тип
public void NotifyCreatePreviewTarget($sTargetType, $iTargetId, $oRelationTarget)
| ||
$sTargetType | ||
$iTargetId | ||
$oRelationTarget |
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;
}
public void NotifyCreatePreviewTargetTopic(int $iTargetId, ModuleMedia_EntityTarget $oRelationTarget)
| ||
$iTargetId | int | |
$oRelationTarget | ModuleMedia_EntityTarget |
public function NotifyCreatePreviewTargetTopic($iTargetId, $oRelationTarget)
{
if ($oTopic = $this->Topic_GetTopicById($iTargetId)) {
$oTopic->setPreviewImage($oRelationTarget->getDataOne('image_preview'));
$this->Topic_UpdateTopic($oTopic);
}
}
Обработка создания превью для типа 'topic' Название метода формируется автоматически
public void NotifyRemovePreviewTarget($sTargetType, $iTargetId, $oRelationTarget)
| ||
$sTargetType | ||
$iTargetId | ||
$oRelationTarget |
public function NotifyRemovePreviewTarget($sTargetType, $iTargetId, $oRelationTarget)
{
if (!$this->IsAllowTargetType($sTargetType)) {
return false;
}
$sMethod = 'NotifyRemovePreviewTarget' . func_camelize($sTargetType);
if (method_exists($this, $sMethod)) {
return $this->$sMethod($iTargetId, $oRelationTarget);
}
return false;
}
public void NotifyRemovePreviewTargetTopic(int $iTargetId, ModuleMedia_EntityTarget $oRelationTarget)
| ||
$iTargetId | int | |
$oRelationTarget | ModuleMedia_EntityTarget |
public function NotifyRemovePreviewTargetTopic($iTargetId, $oRelationTarget)
{
if ($oTopic = $this->Topic_GetTopicById($iTargetId)) {
$oTopic->setPreviewImage(null);
$this->Topic_UpdateTopic($oTopic);
}
}
Обработка удаления превью для типа 'topic' Название метода формируется автоматически
public array ParsedImageSize(string $sSize)
| ||
$sSize | string | |
{return} | array | Массив вида array('w'=>100,'h'=>150,'crop'=>true) |
public function ParsedImageSize($sSize)
{
$aSize = array(
'w' => null,
'h' => null,
'crop' => false,
);
if (preg_match('#^(\d+)?(x)?(\d+)?([a-z]{2,10})?$#Ui', $sSize, $aMatch)) {
$iW = (isset($aMatch[1]) and $aMatch[1]) ? $aMatch[1] : null;
$iH = (isset($aMatch[3]) and $aMatch[3]) ? $aMatch[3] : null;
$bDelim = (isset($aMatch[2]) and $aMatch[2]) ? true : false;
$sMod = (isset($aMatch[4]) and $aMatch[4]) ? $aMatch[4] : '';
if (!$bDelim) {
$iW = $iH;
}
$aSize['w'] = $iW;
$aSize['h'] = $iH;
if ($sMod) {
$aSize[$sMod] = true;
}
}
return $aSize;
}
Парсит строку с размером изображения Варианты входной строки: 100 100crop 100x150 100x150crop x150 100x
public void ProcessingFile($sFileTmp, $sTargetType, $sTargetId, $sTargetTmp=NULL)
| ||
$sFileTmp | ||
$sTargetType | ||
$sTargetId | ||
$sTargetTmp |
public function ProcessingFile($sFileTmp, $sTargetType, $sTargetId, $sTargetTmp = null)
{
/**
* Определяем тип файла по расширенияю и запускаем обработку
*/
$aPathInfo = pathinfo($sFileTmp);
$sExtension = @strtolower($aPathInfo['extension']);
if (in_array($sExtension, array('jpg', 'jpeg', 'gif', 'png'))) {
return $this->ProcessingFileImage($sFileTmp, $sTargetType, $sTargetId, $sTargetTmp);
}
return 'Неверный тип файла';
}
public void ProcessingFileImage($sFileTmp, $sTargetType, $sTargetId, $sTargetTmp=NULL)
| ||
$sFileTmp | ||
$sTargetType | ||
$sTargetId | ||
$sTargetTmp |
public function ProcessingFileImage($sFileTmp, $sTargetType, $sTargetId, $sTargetTmp = null)
{
$aPathInfo = pathinfo($sFileTmp);
$aParams = $this->Image_BuildParams('media.' . $sTargetType);
/**
* Если объект изображения не создан, возвращаем ошибку
*/
if (!$oImage = $this->Image_Open($sFileTmp, $aParams)) {
$this->Fs_RemoveFileLocal($sFileTmp);
return $this->Image_GetLastError();
}
$iWidth = $oImage->getWidth();
$iHeight = $oImage->getHeight();
$sPath = $this->GetSaveDir($sTargetType, $sTargetId);
/**
* Уникальное имя файла
*/
$sFileName = func_generator(20);
/**
* Сохраняем оригинальную копию
*/
if (!$sFileResult = $oImage->saveSmart($sPath, $sFileName)) {
$this->Fs_RemoveFileLocal($sFileTmp);
return $this->Image_GetLastError();
}
$aSizes = $this->GetConfigParam('image.sizes', $sTargetType);
/**
* Перед запуском генерации подчищаем память
*/
unset($oImage);
/**
* Генерируем варианты с необходимыми размерами
*/
$this->GenerateImageBySizes($sFileTmp, $sPath, $sFileName, $aSizes, $aParams);
/**
* Сохраняем медиа
*/
$oMedia = Engine::GetEntity('ModuleMedia_EntityMedia');
$oMedia->setUserId($this->oUserCurrent ? $this->oUserCurrent->getId() : null);
$oMedia->setType(self::TYPE_IMAGE);
$oMedia->setTargetType($sTargetType);
$oMedia->setFilePath($sFileResult);
$oMedia->setFileName($aPathInfo['filename']);
$oMedia->setFileSize(filesize($sFileTmp));
$oMedia->setWidth($iWidth);
$oMedia->setHeight($iHeight);
$oMedia->setDataOne('image_sizes', $aSizes);
/**
* Теперь можно удалить временный файл
*/
$this->Fs_RemoveFileLocal($sFileTmp);
/**
* Добавляем в БД
*/
if ($oMedia->Add()) {
/**
* Создаем связь с владельцем
*/
$oTarget = Engine::GetEntity('ModuleMedia_EntityTarget');
$oTarget->setMediaId($oMedia->getId());
$oTarget->setTargetType($sTargetType);
$oTarget->setTargetId($sTargetId ? $sTargetId : null);
$oTarget->setTargetTmp($sTargetTmp ? $sTargetTmp : null);
if ($oTarget->Add()) {
$oMedia->_setData(array('_relation_entity' => $oTarget));
return $oMedia;
}
}
return false;
}
public void RemoveAllPreviewByTarget($sTargetType $sTargetType, $sTargetId $sTargetId, null $sTargetTmp=NULL)
| ||
$sTargetType | $sTargetType | |
$sTargetId | $sTargetId | |
$sTargetTmp | null |
public function RemoveAllPreviewByTarget($sTargetType, $sTargetId, $sTargetTmp = null)
{
$aFilter = array(
'target_type' => $sTargetType,
'is_preview' => 1,
'#with' => array('media')
);
if ($sTargetId) {
$aFilter['target_id'] = $sTargetId;
} else {
$aFilter['target_tmp'] = $sTargetTmp;
}
$aTargetItems = $this->Media_GetTargetItemsByFilter($aFilter);
foreach ($aTargetItems as $oTarget) {
$this->RemoveFilePreview($oTarget->getMedia(), $oTarget);
}
}
Удаляет все превью у конкретного объекта
public void RemoveFilePreview($oMedia, $oTarget)
| ||
$oMedia | ||
$oTarget |
public function RemoveFilePreview($oMedia, $oTarget)
{
if ($oMedia->getType() == self::TYPE_IMAGE) {
if ($oTarget->getDataOne('image_preview')) {
/**
* Уведомляем объект о удалении превью
*/
if ($oTarget->getTargetId()) {
$this->NotifyRemovePreviewTarget($oTarget->getTargetType(), $oTarget->getTargetId(), $oTarget);
}
$this->RemoveImageBySizes($oTarget->getDataOne('image_preview'),
$oTarget->getDataOne('image_preview_sizes'));
$oTarget->setDataOne('image_preview', null);
$oTarget->setDataOne('image_preview_sizes', array());
$oTarget->setIsPreview(0);
$oTarget->Update();
return true;
}
}
}
public void RemoveImageBySizes($sPath, $aSizes, $bRemoveOriginal=true)
| ||
$sPath | ||
$aSizes | ||
$bRemoveOriginal |
public function RemoveImageBySizes($sPath, $aSizes, $bRemoveOriginal = true)
{
if ($aSizes) {
/**
* Преобразуем упрощенную запись списка размеров в полную
*/
foreach ($aSizes as $k => $v) {
if (!is_array($v)) {
$aSizes[$k] = $this->ParsedImageSize($v);
}
}
foreach ($aSizes as $aSize) {
$sSize = $aSize['w'] . 'x' . $aSize['h'];
if ($aSize['crop']) {
$sSize .= 'crop';
}
$this->Image_RemoveFile($this->GetImagePathBySize($sPath, $sSize));
}
}
/**
* Удаляем оригинал
*/
if ($bRemoveOriginal) {
$this->Image_RemoveFile($sPath);
}
}
public void RemoveTarget(string $sTargetType, int $sTargetId, bool $bMediaRemove=true)
| ||
$sTargetType | string | |
$sTargetId | int | |
$bMediaRemove | bool | Удалять медиа данные оставшиеся без связей |
public function RemoveTarget($sTargetType, $sTargetId, $bMediaRemove = true)
{
/**
* Получаем прикрепленные медиа
*/
$aMediaItems = $this->GetMediaByTarget($sTargetType, $sTargetId);
/**
* Удаляем все связи текущего таргета
*/
$this->RemoveTargetByTypeAndId($sTargetType, $sTargetId);
if ($bMediaRemove and $aMediaItems) {
/**
* Проверяем с какими медиа данными еще остались связи
*/
$aMediaIds = array();
foreach ($aMediaItems as $oMediaItem) {
$aMediaIds[] = $oMediaItem->getId();
}
$aTargetItems = $this->GetTargetItemsByFilter(array(
'media_id in' => $aMediaIds,
'#index-group' => 'media_id'
));
/**
* Удаляем медиа данные без оставшихся связей
*/
foreach ($aMediaItems as $oMediaItem) {
if (!isset($aTargetItems[$oMediaItem->getId()])) {
$oMediaItem->Delete();
}
}
}
}
Удаляет связь с медиа данными + при необходимости удаляет сами медиа данные
public void RemoveTargetByTypeAndId($sTargetType, $iTargetId)
| ||
$sTargetType | ||
$iTargetId |
public function RemoveTargetByTypeAndId($sTargetType, $iTargetId)
{
$bRes = $this->oMapper->RemoveTargetByTypeAndId($sTargetType, $iTargetId);
/**
* Сбрасываем кеши
*/
$this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, array(
'ModuleMedia_EntityTarget_delete'
));
return $bRes;
}
public void ReplaceTargetTmpById(string $sTargetType, string $sTargetId, null|string $sTargetTmp=NULL)
| ||
$sTargetType | string | |
$sTargetId | string | |
$sTargetTmp | null|string | Если не задан, то берется их куки "media_target_tmp_{$sTargetType}" |
public function ReplaceTargetTmpById($sTargetType, $sTargetId, $sTargetTmp = null)
{
$sCookieKey = 'media_target_tmp_' . $sTargetType;
if (is_null($sTargetTmp) and isset($_COOKIE[$sCookieKey])) {
$sTargetTmp = $_COOKIE[$sCookieKey];
setcookie($sCookieKey, null, -1, Config::Get('sys.cookie.path'), Config::Get('sys.cookie.host'));
}
if (is_string($sTargetTmp)) {
$aTargetItems = $this->Media_GetTargetItemsByTargetTmpAndTargetType($sTargetTmp, $sTargetType);
foreach ($aTargetItems as $oTarget) {
$oTarget->setTargetTmp(null);
$oTarget->setTargetId($sTargetId);
$oTarget->Update();
/**
* Уведомляем объект о создании превью
*/
if ($oTarget->getIsPreview()) {
$this->NotifyCreatePreviewTarget($oTarget->getTargetType(), $oTarget->getTargetId(), $oTarget);
}
}
}
}
Заменяет временный идентификатор на необходимый ID объекта
public void Upload($aFile, $sTargetType, $sTargetId, $sTargetTmp=NULL)
| ||
$aFile | ||
$sTargetType | ||
$sTargetId | ||
$sTargetTmp |
public function Upload($aFile, $sTargetType, $sTargetId, $sTargetTmp = null)
{
if (is_string($aFile)) {
return $this->UploadUrl($aFile, $sTargetType, $sTargetId, $sTargetTmp);
} else {
return $this->UploadLocal($aFile, $sTargetType, $sTargetId, $sTargetTmp);
}
}
public void UploadLocal($aFile, $sTargetType, $sTargetId, $sTargetTmp=NULL)
| ||
$aFile | ||
$sTargetType | ||
$sTargetId | ||
$sTargetTmp |
public function UploadLocal($aFile, $sTargetType, $sTargetId, $sTargetTmp = null)
{
if (!is_array($aFile) || !isset($aFile['tmp_name']) || !isset($aFile['name'])) {
return false;
}
$aPathInfo = pathinfo($aFile['name']);
$sExtension = isset($aPathInfo['extension']) ? $aPathInfo['extension'] : 'unknown';
$sFileName = $aPathInfo['filename'] . '.' . $sExtension;
/**
* Копируем загруженный файл
*/
$sDirTmp = Config::Get('path.tmp.server') . '/media/';
if (!is_dir($sDirTmp)) {
@mkdir($sDirTmp, 0777, true);
}
$sFileTmp = $sDirTmp . $sFileName;
if (!move_uploaded_file($aFile['tmp_name'], $sFileTmp)) {
return 'Не удалось загрузить файл';
}
/**
* TODO: проверить на размер файла в байтах
*/
return $this->ProcessingFile($sFileTmp, $sTargetType, $sTargetId, $sTargetTmp);
}
public void UploadUrl($sFileUrl, $sTargetType, $sTargetId, $sTargetTmp=NULL)
| ||
$sFileUrl | ||
$sTargetType | ||
$sTargetId | ||
$sTargetTmp |
public function UploadUrl($sFileUrl, $sTargetType, $sTargetId, $sTargetTmp = null)
{
/**
* Проверяем, является ли файл изображением
* TODO: файл может быть не только изображением, поэтому требуется рефакторинг
*/
if (!$aImageInfo = (@getimagesize($sFileUrl))) {
return 'Файл не является изображением';
}
$aTypeImage = array(
1 => 'gif',
2 => 'jpg',
3 => 'png'
); // see http://php.net/manual/en/function.exif-imagetype.php
$sExtension = isset($aTypeImage[$aImageInfo[2]]) ? $aTypeImage[$aImageInfo[2]] : 'jpg';
/**
* Открываем файловый поток и считываем файл поблочно,
* контролируя максимальный размер изображения
*/
$rFile = fopen($sFileUrl, 'r');
if (!$rFile) {
return 'Не удалось загрузить файл';
}
$iMaxSizeKb = $this->GetConfigParam('image.max_size_url', $sTargetType);
$iSizeKb = 0;
$sContent = '';
while (!feof($rFile) and $iSizeKb < $iMaxSizeKb) {
$sContent .= fread($rFile, 1024 * 2);
$iSizeKb++;
}
/**
* Если конец файла не достигнут,
* значит файл имеет недопустимый размер
*/
if (!feof($rFile)) {
return 'Превышен максимальный размер файла: ' . $this->GetConfigParam('image.max_size_url',
$sTargetType) . 'Kb';
}
fclose($rFile);
/**
* Копируем загруженный файл
*/
$sDirTmp = Config::Get('path.tmp.server') . '/media/';
if (!is_dir($sDirTmp)) {
@mkdir($sDirTmp, 0777, true);
}
$sFileTmp = $sDirTmp . func_generator() . '.' . $sExtension;
$rFile = fopen($sFileTmp, 'w');
fwrite($rFile, $sContent);
fclose($rFile);
return $this->ProcessingFile($sFileTmp, $sTargetType, $sTargetId, $sTargetTmp);
}