mirror of
https://github.com/Oreolek/ifhub.club.git
synced 2024-06-16 23:00:51 +03:00
Новый модуль для управления универсальными категориями
This commit is contained in:
parent
d2c30497be
commit
e58391812f
395
application/classes/modules/category/Category.class.php
Normal file
395
application/classes/modules/category/Category.class.php
Normal file
|
@ -0,0 +1,395 @@
|
|||
<?php
|
||||
/**
|
||||
* 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>
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Модуль управления универсальными категориями
|
||||
*/
|
||||
class ModuleCategory extends ModuleORM {
|
||||
/**
|
||||
* Список состояний типов объектов
|
||||
*/
|
||||
const TARGET_STATE_ACTIVE=1;
|
||||
const TARGET_STATE_NOT_ACTIVE=2;
|
||||
const TARGET_STATE_REMOVE=3;
|
||||
|
||||
protected $oMapper=null;
|
||||
|
||||
/**
|
||||
* Инициализация
|
||||
*/
|
||||
public function Init() {
|
||||
parent::Init();
|
||||
$this->oMapper=Engine::GetMapper(__CLASS__);
|
||||
}
|
||||
/**
|
||||
* Возвращает список категорий сущности
|
||||
*
|
||||
* @param $oTarget
|
||||
* @param $sTargetType
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetEntityCategories($oTarget,$sTargetType) {
|
||||
$aCategories=$oTarget->_getDataOne('_categories');
|
||||
if (is_null($aCategories)) {
|
||||
$this->AttachCategoriesForTargetItems($oTarget,$sTargetType);
|
||||
return $oTarget->_getDataOne('_categories');
|
||||
}
|
||||
return $aCategories;
|
||||
}
|
||||
/**
|
||||
* Обработка фильтра ORM запросов
|
||||
*
|
||||
* @param array $aFilter
|
||||
* @param array $sEntityFull
|
||||
* @param string $sTargetType
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function RewriteFilter($aFilter,$sEntityFull,$sTargetType) {
|
||||
$oEntitySample=Engine::GetEntity($sEntityFull);
|
||||
|
||||
if (!isset($aFilter['#join'])) {
|
||||
$aFilter['#join']=array();
|
||||
}
|
||||
|
||||
if (!isset($aFilter['#select'])) {
|
||||
$aFilter['#select']=array();
|
||||
}
|
||||
|
||||
if (array_key_exists('#category',$aFilter)) {
|
||||
$aCategoryId=$aFilter['#category'];
|
||||
if (!is_array($aCategoryId)) {
|
||||
$aCategoryId=array($aCategoryId);
|
||||
}
|
||||
$sJoin="JOIN ".Config::Get('db.table.category_target')." category ON
|
||||
t.`{$oEntitySample->_getPrimaryKey()}` = category.target_id and
|
||||
category.target_type = '{$sTargetType}' and
|
||||
category.category_id IN ( ?a ) ";
|
||||
$aFilter['#join'][$sJoin]=array($aCategoryId);
|
||||
if (count($aFilter['#select'])) {
|
||||
$aFilter['#select'][]="distinct t.`{$oEntitySample->_getPrimaryKey()}`";
|
||||
} else {
|
||||
$aFilter['#select'][]="distinct t.`{$oEntitySample->_getPrimaryKey()}`";
|
||||
$aFilter['#select'][]='t.*';
|
||||
}
|
||||
}
|
||||
return $aFilter;
|
||||
}
|
||||
/**
|
||||
* Переопределяем метод для возможности цеплять свои кастомные данные при ORM запросах - свойства
|
||||
*
|
||||
* @param array $aResult
|
||||
* @param array $aFilter
|
||||
* @param string $sTargetType
|
||||
*/
|
||||
public function RewriteGetItemsByFilter($aResult,$aFilter,$sTargetType) {
|
||||
if (!$aResult) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Список на входе может быть двух видов:
|
||||
* 1 - одномерный массив
|
||||
* 2 - двумерный, если применялась группировка (использование '#index-group')
|
||||
*
|
||||
* Поэтому сначала сформируем линейный список
|
||||
*/
|
||||
if (isset($aFilter['#index-group']) and $aFilter['#index-group']) {
|
||||
$aEntitiesWork=array();
|
||||
foreach($aResult as $aItems) {
|
||||
foreach($aItems as $oItem) {
|
||||
$aEntitiesWork[]=$oItem;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$aEntitiesWork=$aResult;
|
||||
}
|
||||
|
||||
if (!$aEntitiesWork) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Проверяем необходимость цеплять категории
|
||||
*/
|
||||
if (isset($aFilter['#with']['#category'])) {
|
||||
$this->AttachCategoriesForTargetItems($aEntitiesWork,$sTargetType);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Цепляет для списка объектов категории
|
||||
*
|
||||
* @param array $aEntityItems
|
||||
* @param string $sTargetType
|
||||
*/
|
||||
public function AttachCategoriesForTargetItems($aEntityItems,$sTargetType) {
|
||||
if (!is_array($aEntityItems)) {
|
||||
$aEntityItems=array($aEntityItems);
|
||||
}
|
||||
$aEntitiesId=array();
|
||||
foreach($aEntityItems as $oEntity) {
|
||||
$aEntitiesId[]=$oEntity->getId();
|
||||
}
|
||||
/**
|
||||
* Получаем категории для всех объектов
|
||||
*/
|
||||
$sEntityCategory=$this->_NormalizeEntityRootName('Category');
|
||||
$sEntityTarget=$this->_NormalizeEntityRootName('Target');
|
||||
$aCategories=$this->GetCategoryItemsByFilter(array(
|
||||
'#join'=>array(
|
||||
"JOIN ".Config::Get('db.table.category_target')." category_target ON
|
||||
t.id = category_target.category_id and
|
||||
category_target.target_type = '{$sTargetType}' and
|
||||
category_target.target_id IN ( ?a )
|
||||
"=>array($aEntitiesId)
|
||||
),
|
||||
'#select'=>array(
|
||||
't.*',
|
||||
'category_target.target_id'
|
||||
),
|
||||
'#index-group'=>'target_id',
|
||||
'#cache'=>array(
|
||||
null,
|
||||
array($sEntityCategory.'_save',$sEntityCategory.'_delete',$sEntityTarget.'_save',$sEntityTarget.'_delete')
|
||||
)
|
||||
));
|
||||
/**
|
||||
* Собираем данные
|
||||
*/
|
||||
foreach($aEntityItems as $oEntity) {
|
||||
if (isset($aCategories[$oEntity->_getPrimaryKeyValue()])) {
|
||||
$oEntity->_setData(array('_categories'=>$aCategories[$oEntity->_getPrimaryKeyValue()]));
|
||||
} else {
|
||||
$oEntity->_setData(array('_categories'=>array()));
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Возвращает дерево категорий
|
||||
*
|
||||
* @param int $sId Type ID
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetCategoriesTreeByType($sId) {
|
||||
$aRow=$this->oMapper->GetCategoriesByType($sId);
|
||||
if (count($aRow)) {
|
||||
$aRec=$this->Tools_BuildEntityRecursive($aRow);
|
||||
}
|
||||
if (!isset($aRec['collection'])) {
|
||||
return array();
|
||||
}
|
||||
$aResult=$this->Category_GetCategoryItemsByFilter(array('id in'=>array_keys($aRec['collection']),'#index-from-primary','#order'=>array('FIELD:id'=>array_keys($aRec['collection']))));
|
||||
foreach ($aResult as $oCategory) {
|
||||
$oCategory->setLevel($aRec['collection'][$oCategory->getId()]);
|
||||
}
|
||||
return $aResult;
|
||||
}
|
||||
/**
|
||||
* Возвращает дерево категорий
|
||||
*
|
||||
* @param string $sCode Type code
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetCategoriesTreeByTargetType($sCode) {
|
||||
if ($oType=$this->Category_GetTypeByTargetType($sCode)) {
|
||||
return $this->GetCategoriesTreeByType($oType->getId());
|
||||
}
|
||||
return array();
|
||||
}
|
||||
/**
|
||||
* Валидирует список категория
|
||||
*
|
||||
* @param array $aCategoryId
|
||||
* @param int $iType
|
||||
*
|
||||
* @return array|bool
|
||||
*/
|
||||
public function ValidateCategoryArray($aCategoryId,$iType) {
|
||||
if (!is_array($aCategoryId)) {
|
||||
return false;
|
||||
}
|
||||
$aIds=array();
|
||||
foreach($aCategoryId as $iId) {
|
||||
$aIds[]=(int)$iId;
|
||||
}
|
||||
if ($aIds and $aCategories=$this->GetCategoryItemsByFilter(array('id in'=>$aIds,'type_id'=>$iType))) {
|
||||
$aResultId=array();
|
||||
foreach($aCategories as $oCategory) {
|
||||
$aResultId[]=$oCategory->getId();
|
||||
}
|
||||
return $aResultId;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Сохраняет категории для объекта
|
||||
*
|
||||
* @param $oTarget
|
||||
* @param $sTargetType
|
||||
*/
|
||||
public function SaveCategories($oTarget,$sTargetType) {
|
||||
$aCategoriesId=$oTarget->_getDataOne('_categories_for_save');
|
||||
if (!is_array($aCategoriesId)) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Удаляем текущие связи
|
||||
*/
|
||||
$this->RemoveRelation($oTarget->_getPrimaryKeyValue(),$sTargetType);
|
||||
/**
|
||||
* Создаем
|
||||
*/
|
||||
$this->CreateRelation($aCategoriesId,$oTarget->_getPrimaryKeyValue(),$sTargetType);
|
||||
|
||||
$oTarget->_setData(array('_categories_for_save'=>null));
|
||||
}
|
||||
/**
|
||||
* Удаляет категории у объекта
|
||||
*
|
||||
* @param $oTarget
|
||||
* @param $sTargetType
|
||||
*/
|
||||
public function RemoveCategories($oTarget,$sTargetType) {
|
||||
$this->RemoveRelation($oTarget->_getPrimaryKeyValue(),$sTargetType);
|
||||
}
|
||||
/**
|
||||
* Создает новую связь конкретного объекта с категориями
|
||||
*
|
||||
* @param array $aCategoryId
|
||||
* @param int $iTargetId
|
||||
* @param int|string $iType type_id или target_type
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function CreateRelation($aCategoryId,$iTargetId,$iType) {
|
||||
if (!$aCategoryId or (is_array($aCategoryId) and !count($aCategoryId))) {
|
||||
return false;
|
||||
}
|
||||
if (!is_array($aCategoryId)) {
|
||||
$aCategoryId=array($aCategoryId);
|
||||
}
|
||||
if (is_numeric($iType)) {
|
||||
$oType=$this->GetTypeById($iType);
|
||||
} else {
|
||||
$oType=$this->GetTypeByTargetType($iType);
|
||||
}
|
||||
if (!$oType) {
|
||||
return false;
|
||||
}
|
||||
foreach($aCategoryId as $iCategoryId){
|
||||
if (!$this->GetTargetByCategoryIdAndTargetIdAndTypeId($iCategoryId,$iTargetId,$oType->getId())) {
|
||||
$oTarget=Engine::GetEntity('ModuleCategory_EntityTarget');
|
||||
$oTarget->setCategoryId($iCategoryId);
|
||||
$oTarget->setTargetId($iTargetId);
|
||||
$oTarget->setTargetType($oType->getTargetType());
|
||||
$oTarget->setTypeId($oType->getId());
|
||||
$oTarget->Add();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Удаляет связь конкретного объекта с категориями
|
||||
*
|
||||
* @param int $iTargetId
|
||||
* @param int|string $iType type_id или target_type
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function RemoveRelation($iTargetId,$iType) {
|
||||
if (!is_numeric($iType)) {
|
||||
if ($oType=$this->GetTypeByTargetType($iType)) {
|
||||
$iType=$oType->getId();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$aTargets=$this->GetTargetItemsByTargetIdAndTypeId($iTargetId,$iType);
|
||||
foreach($aTargets as $oTarget) {
|
||||
$oTarget->Delete();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Возвращает список категорий по категории
|
||||
*
|
||||
* @param $oCategory
|
||||
* @param bool $bIncludeChild Возвращать все дочернии категории
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function GetCategoriesIdByCategory($oCategory,$bIncludeChild=false) {
|
||||
if (is_object($oCategory)) {
|
||||
$iCategoryId=$oCategory->getId();
|
||||
} else {
|
||||
$iCategoryId=$oCategory;
|
||||
}
|
||||
if ($bIncludeChild) {
|
||||
/**
|
||||
* Сначала получаем полный список категорий текущего типа
|
||||
*/
|
||||
if (!is_object($oCategory)) {
|
||||
$oCategory=$this->GetCategoryById($iCategoryId);
|
||||
}
|
||||
if ($oCategory) {
|
||||
$aCategories=$this->oMapper->GetCategoriesByType($oCategory->getTypeId());
|
||||
$aCategoriesChild=$this->GetChildItemsFromCategories($aCategories,$iCategoryId);
|
||||
$aCategoryId=array_merge(array((int)$iCategoryId),array_keys($aCategoriesChild));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
$aCategoryId=array($iCategoryId);
|
||||
}
|
||||
return $aCategoryId;
|
||||
}
|
||||
/**
|
||||
* Обрабатывает дочерние категории
|
||||
*
|
||||
* @param $aCategories
|
||||
* @param null $iCategoryId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function GetChildItemsFromCategories($aCategories,$iCategoryId=null) {
|
||||
static $aResult;
|
||||
static $bIsChild;
|
||||
|
||||
foreach($aCategories as $aCategory) {
|
||||
if ($aCategory['id']==$iCategoryId) {
|
||||
$bIsChild=true;
|
||||
$this->GetChildItemsFromCategories($aCategory['childNodes'],$iCategoryId);
|
||||
return $aResult ? $aResult : array();
|
||||
}
|
||||
if ($bIsChild) {
|
||||
$aCat=$aCategory;
|
||||
unset($aCat['childNodes']);
|
||||
$aResult[$aCat['id']]=$aCat;
|
||||
}
|
||||
if ($aCategory['childNodes']) {
|
||||
$this->GetChildItemsFromCategories($aCategory['childNodes'],$iCategoryId);
|
||||
}
|
||||
}
|
||||
return $aResult ? $aResult : array();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
<?php
|
||||
/**
|
||||
* 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>
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Поведение, которое необходимо добавлять к сущности (entity) у которой добавляются категории
|
||||
*/
|
||||
class ModuleCategory_BehaviorEntity extends Behavior {
|
||||
/**
|
||||
* Дефолтные параметры
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $aParams=array(
|
||||
'target_type'=>'',
|
||||
'form_field'=>'categories',
|
||||
'multiple'=>false,
|
||||
|
||||
'validate_enable'=>true,
|
||||
'validate_field'=>null,
|
||||
'validate_require'=>false,
|
||||
'validate_from_request'=>true,
|
||||
'validate_min'=>1,
|
||||
'validate_max'=>5,
|
||||
);
|
||||
/**
|
||||
* Список хуков
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $aHooks=array(
|
||||
'validate_after'=>'CallbackValidateAfter',
|
||||
'after_save'=>'CallbackAfterSave',
|
||||
'after_delete'=>'CallbackAfterDelete',
|
||||
);
|
||||
/**
|
||||
* Инициализация
|
||||
*/
|
||||
protected function Init() {
|
||||
parent::Init();
|
||||
if (!$this->getParam('validate_field')) {
|
||||
$this->aParams['validate_field']=$this->getParam('form_field');
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Коллбэк
|
||||
* Выполняется при инициализации сущности
|
||||
*
|
||||
* @param $aParams
|
||||
*/
|
||||
public function CallbackValidateAfter($aParams) {
|
||||
if ($aParams['bResult'] and $this->getParam('validate_enable')) {
|
||||
$aFields=$aParams['aFields'];
|
||||
if (is_null($aFields) or in_array($this->getParam('validate_field'),$aFields)) {
|
||||
$oValidator=$this->Validate_CreateValidator('categories_check',$this,$this->getParam('validate_field'));
|
||||
$oValidator->validateEntity($this->oObject,$aFields);
|
||||
$aParams['bResult']=!$this->oObject->_hasValidateErrors();
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Коллбэк
|
||||
* Выполняется после сохранения сущности
|
||||
*/
|
||||
public function CallbackAfterSave() {
|
||||
$this->Category_SaveCategories($this->oObject,$this->getParam('target_type'));
|
||||
}
|
||||
/**
|
||||
* Коллбэк
|
||||
* Выполняется после удаления сущности
|
||||
*/
|
||||
public function CallbackAfterDelete() {
|
||||
$this->Category_RemoveCategories($this->oObject,$this->getParam('target_type'));
|
||||
}
|
||||
/**
|
||||
* Дополнительный метод для сущности
|
||||
* Запускает валидацию дополнительных полей
|
||||
*
|
||||
* @param $mValue
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
public function ValidateCategoriesCheck($mValue) {
|
||||
/**
|
||||
* Проверяем тип категрий
|
||||
*/
|
||||
if (!$oTypeCategory=$this->Category_GetTypeByTargetType($this->getParam('target_type'))) {
|
||||
return 'Неверный тип категорий';
|
||||
}
|
||||
|
||||
if ($this->getParam('validate_from_request')) {
|
||||
$mValue=getRequest($this->getParam('form_field'));
|
||||
}
|
||||
/**
|
||||
* Значение может быть числом, массивом, строкой с разделением через запятую
|
||||
*/
|
||||
if (!is_array($mValue)) {
|
||||
if ($this->getParam('multiple')) {
|
||||
$mValue=explode(',',$mValue);
|
||||
} else {
|
||||
$mValue=array($mValue);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Проверяем наличие категорий в БД
|
||||
*/
|
||||
$aCategoriesId=$this->Category_ValidateCategoryArray($mValue,$oTypeCategory->getId());
|
||||
if (!$aCategoriesId) {
|
||||
$aCategoriesId=array();
|
||||
}
|
||||
|
||||
if ($this->getParam('validate_require') and !$aCategoriesId) {
|
||||
return 'Необходимо выбрать категорию';
|
||||
}
|
||||
if (!$this->getParam('multiple') and count($aCategoriesId)>1) {
|
||||
$aCategoriesId=array_slice($aCategoriesId,0,1);
|
||||
}
|
||||
if ($this->getParam('multiple') and $aCategoriesId and ( count($aCategoriesId)<$this->getParam('validate_min') or count($aCategoriesId)>$this->getParam('validate_max'))) {
|
||||
return 'Количество категорий должно быть от '.$this->getParam('validate_min').' до '.$this->getParam('validate_max');
|
||||
}
|
||||
/**
|
||||
* Сохраняем необходимый список категорий для последующего сохранения в БД
|
||||
*/
|
||||
$this->oObject->_setData(array('_categories_for_save'=>$aCategoriesId));
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Возвращает список категорий сущности
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCategories() {
|
||||
return $this->Category_GetEntityCategories($this->oObject,$this->getCategoryTargetType());
|
||||
}
|
||||
/**
|
||||
* Возвращает количество категорий
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCountCategories() {
|
||||
return count($this->getCategories());
|
||||
}
|
||||
/**
|
||||
* Возвращает одну категорию сущности
|
||||
* Если объект может иметь несколько категорий, то вернется первая
|
||||
*
|
||||
* @return ModuleCategory_EntityCategory|null
|
||||
*/
|
||||
public function getCategory() {
|
||||
$aCategories=$this->getCategories();
|
||||
$oCategory=reset($aCategories);
|
||||
return $oCategory ? $oCategory : null;
|
||||
}
|
||||
/**
|
||||
* Возвращает тип объекта для категорий
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCategoryTargetType() {
|
||||
if ($sType=$this->getParam('target_type')) {
|
||||
return $sType;
|
||||
}
|
||||
/**
|
||||
* Иначе дополнительно смотрим на наличие данного метода у сущности
|
||||
* Это необходимо, если тип вычисляется динамически по какой-то своей логике
|
||||
*/
|
||||
if (func_method_exists($this->oObject,'getCategoryTargetType','public')) {
|
||||
return call_user_func(array($this->oObject,'getCategoryTargetType'));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
/**
|
||||
* 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>
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Поведение, которое необходимо добавлять к ORM модулю сущности у которой добавляются категории
|
||||
*/
|
||||
class ModuleCategory_BehaviorModule extends Behavior {
|
||||
/**
|
||||
* Список хуков
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $aHooks=array(
|
||||
'module_orm_GetItemsByFilter_after'=>array(
|
||||
'CallbackGetItemsByFilterAfter',1000
|
||||
),
|
||||
'module_orm_GetItemsByFilter_before'=>array(
|
||||
'CallbackGetItemsByFilterBefore',1000
|
||||
),
|
||||
'module_orm_GetByFilter_before'=>array(
|
||||
'CallbackGetItemsByFilterBefore',1000
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Модифицирует фильтр в ORM запросе
|
||||
*
|
||||
* @param $aParams
|
||||
*/
|
||||
public function CallbackGetItemsByFilterAfter($aParams) {
|
||||
$aEntities=$aParams['aEntities'];
|
||||
$aFilter=$aParams['aFilter'];
|
||||
$this->Category_RewriteGetItemsByFilter($aEntities,$aFilter,'test');
|
||||
}
|
||||
/**
|
||||
* Модифицирует результат ORM запроса
|
||||
*
|
||||
* @param $aParams
|
||||
*/
|
||||
public function CallbackGetItemsByFilterBefore($aParams) {
|
||||
$aFilter=$this->Category_RewriteFilter($aParams['aFilter'],$aParams['sEntityFull'],'test');
|
||||
$aParams['aFilter']=$aFilter;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
/**
|
||||
* 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>
|
||||
*
|
||||
*/
|
||||
class ModuleCategory_EntityCategory extends EntityORM {
|
||||
|
||||
protected $aRelations=array(
|
||||
'type' => array(self::RELATION_TYPE_BELONGS_TO,'ModuleCategory_EntityType','type_id'),
|
||||
);
|
||||
|
||||
/**
|
||||
* Выполняется перед сохранением
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function beforeSave() {
|
||||
if ($bResult=parent::beforeSave()) {
|
||||
if ($this->_isNew()) {
|
||||
$this->setDateCreate(date("Y-m-d H:i:s"));
|
||||
}
|
||||
}
|
||||
return $bResult;
|
||||
}
|
||||
/**
|
||||
* Возвращает URL категории
|
||||
* Этот метод можно переопределить из плагина и возвращать свой URL для нужного типа категорий
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getWebUrl() {
|
||||
return Router::GetPath('category').$this->getUrlFull().'/';
|
||||
}
|
||||
/**
|
||||
* Возвращает объект типа категории с использованием кеширования на время сессии
|
||||
*
|
||||
* @return ModuleCategory_EntityType
|
||||
*/
|
||||
public function getTypeByCacheLife() {
|
||||
$sKey='category_type_'.(string)$this->getTypeId();
|
||||
if (false===($oType=$this->Cache_GetLife($sKey))) {
|
||||
$oType=$this->getType();
|
||||
$this->Cache_SetLife($oType,$sKey);
|
||||
}
|
||||
return $oType;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
/**
|
||||
* 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>
|
||||
*
|
||||
*/
|
||||
class ModuleCategory_EntityTarget extends EntityORM {
|
||||
|
||||
protected $aRelations=array(
|
||||
|
||||
);
|
||||
|
||||
/**
|
||||
* Выполняется перед сохранением
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function beforeSave() {
|
||||
if ($bResult=parent::beforeSave()) {
|
||||
if ($this->_isNew()) {
|
||||
$this->setDateCreate(date("Y-m-d H:i:s"));
|
||||
}
|
||||
}
|
||||
return $bResult;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
/**
|
||||
* 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>
|
||||
*
|
||||
*/
|
||||
class ModuleCategory_EntityType extends EntityORM {
|
||||
|
||||
protected $aRelations=array(
|
||||
|
||||
);
|
||||
|
||||
/**
|
||||
* Выполняется перед сохранением
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function beforeSave() {
|
||||
if ($bResult=parent::beforeSave()) {
|
||||
if ($this->_isNew()) {
|
||||
$this->setDateCreate(date("Y-m-d H:i:s"));
|
||||
} else {
|
||||
$this->setDateUpdate(date("Y-m-d H:i:s"));
|
||||
}
|
||||
}
|
||||
return $bResult;
|
||||
}
|
||||
/**
|
||||
* Возвращает список дополнительных параметров
|
||||
*
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function getParams() {
|
||||
$aData=@unserialize($this->_getDataOne('params'));
|
||||
if (!$aData) {
|
||||
$aData=array();
|
||||
}
|
||||
return $aData;
|
||||
}
|
||||
/**
|
||||
* Устанавливает список дополнительных параметров
|
||||
*
|
||||
* @param $aParams
|
||||
*/
|
||||
public function setParams($aParams) {
|
||||
$this->_aData['params']=@serialize($aParams);
|
||||
}
|
||||
/**
|
||||
* Возвращает конкретный параметр
|
||||
*
|
||||
* @param $sName
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function getParam($sName) {
|
||||
$aParams=$this->getParams();
|
||||
return isset($aParams[$sName]) ? $aParams[$sName] : null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
/**
|
||||
* 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>
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Маппер для работы с БД
|
||||
*
|
||||
* @package modules.category
|
||||
* @since 1.0
|
||||
*/
|
||||
class ModuleCategory_MapperCategory extends Mapper {
|
||||
|
||||
public function GetCategoriesByType($sId) {
|
||||
$sql = "SELECT
|
||||
id,
|
||||
id as ARRAY_KEY,
|
||||
pid as PARENT_KEY
|
||||
FROM
|
||||
".Config::Get('db.table.category')."
|
||||
WHERE
|
||||
type_id = ?d
|
||||
ORDER by `order` desc;
|
||||
";
|
||||
if ($aRows=$this->oDb->select($sql,$sId)) {
|
||||
return $aRows;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -66,7 +66,39 @@ class ModuleTools extends Module {
|
|||
}
|
||||
return $aCollection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает дерево объектов
|
||||
*
|
||||
* @param array $aEntities Массив данных сущностей с заполнеными полями 'childNodes'
|
||||
* @param bool $bBegin
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function BuildEntityRecursive($aEntities,$bBegin=true) {
|
||||
static $aResultEntities;
|
||||
static $iLevel;
|
||||
static $iMaxIdEntity;
|
||||
if ($bBegin) {
|
||||
$aResultEntities=array();
|
||||
$iLevel=0;
|
||||
$iMaxIdEntity=0;
|
||||
}
|
||||
foreach ($aEntities as $aEntity) {
|
||||
$aTemp=$aEntity;
|
||||
if ($aEntity['id']>$iMaxIdEntity) {
|
||||
$iMaxIdEntity=$aEntity['id'];
|
||||
}
|
||||
$aTemp['level']=$iLevel;
|
||||
unset($aTemp['childNodes']);
|
||||
$aResultEntities[$aTemp['id']]=$aTemp['level'];
|
||||
if (isset($aEntity['childNodes']) and count($aEntity['childNodes'])>0) {
|
||||
$iLevel++;
|
||||
$this->BuildEntityRecursive($aEntity['childNodes'],false);
|
||||
}
|
||||
}
|
||||
$iLevel--;
|
||||
return array('collection'=>$aResultEntities,'iMaxId'=>$iMaxIdEntity);
|
||||
}
|
||||
/**
|
||||
* Преобразует спец символы в html последовательнось, поведение аналогично htmlspecialchars, кроме преобразования амперсанта "&"
|
||||
*
|
||||
|
|
|
@ -315,6 +315,9 @@ $config['db']['table']['storage'] = '___db.table.prefix___storage';
|
|||
$config['db']['table']['poll'] = '___db.table.prefix___poll';
|
||||
$config['db']['table']['poll_answer'] = '___db.table.prefix___poll_answer';
|
||||
$config['db']['table']['poll_vote'] = '___db.table.prefix___poll_vote';
|
||||
$config['db']['table']['category'] = '___db.table.prefix___category';
|
||||
$config['db']['table']['category_type'] = '___db.table.prefix___category_type';
|
||||
$config['db']['table']['category_target'] = '___db.table.prefix___category_target';
|
||||
|
||||
$config['db']['tables']['engine'] = 'InnoDB'; // InnoDB или MyISAM
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit f3e123a8a77ed89ec0cdac74efdec1f8fd76f20e
|
||||
Subproject commit fcf92c128844ed9d9c2e5fb5f5877b1f0c1592ed
|
|
@ -510,6 +510,73 @@ ALTER TABLE `prefix_comment` ADD `comment_count_edit` INT NOT NULL DEFAULT '0' A
|
|||
ADD INDEX ( `comment_count_edit` ) ;
|
||||
|
||||
|
||||
--29.05.2014
|
||||
-- 29.05.2014
|
||||
UPDATE `prefix_stream_user_type` set `event_type`='vote_comment_topic' WHERE `event_type`='vote_comment';
|
||||
UPDATE `prefix_stream_event` set `event_type`='vote_comment_topic' WHERE `event_type`='vote_comment';
|
||||
UPDATE `prefix_stream_event` set `event_type`='vote_comment_topic' WHERE `event_type`='vote_comment';
|
||||
|
||||
|
||||
-- 26.05.2014
|
||||
--
|
||||
-- Структура таблицы `prefix_category`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `prefix_category` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`pid` int(11) DEFAULT NULL,
|
||||
`type_id` int(11) NOT NULL,
|
||||
`title` varchar(250) NOT NULL,
|
||||
`description` text NOT NULL,
|
||||
`url` varchar(250) NOT NULL,
|
||||
`url_full` varchar(250) NOT NULL,
|
||||
`date_create` datetime NOT NULL,
|
||||
`order` int(11) NOT NULL,
|
||||
`state` tinyint(1) NOT NULL DEFAULT '1',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `pid` (`pid`),
|
||||
KEY `title` (`title`),
|
||||
KEY `order` (`order`),
|
||||
KEY `state` (`state`),
|
||||
KEY `url` (`url`),
|
||||
KEY `url_full` (`url_full`),
|
||||
KEY `type_id` (`type_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Структура таблицы `prefix_category_target`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `prefix_category_target` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`category_id` int(11) NOT NULL,
|
||||
`type_id` int(11) NOT NULL,
|
||||
`target_type` varchar(50) NOT NULL,
|
||||
`target_id` int(11) NOT NULL,
|
||||
`date_create` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `target_type` (`target_type`),
|
||||
KEY `target_id` (`target_id`),
|
||||
KEY `category_id` (`category_id`),
|
||||
KEY `type_id` (`type_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Структура таблицы `prefix_category_type`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `prefix_category_type` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`target_type` varchar(50) NOT NULL,
|
||||
`title` varchar(200) NOT NULL,
|
||||
`state` tinyint(1) NOT NULL DEFAULT '1',
|
||||
`date_create` datetime NOT NULL,
|
||||
`date_update` datetime DEFAULT NULL,
|
||||
`params` text NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `title` (`title`),
|
||||
KEY `state` (`state`),
|
||||
KEY `target_type` (`target_type`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
|
Loading…
Reference in a new issue