Index: branches/RC/core/units/categories/categories_event_handler.php =================================================================== diff -u -N --- branches/RC/core/units/categories/categories_event_handler.php (revision 11897) +++ branches/RC/core/units/categories/categories_event_handler.php (revision 0) @@ -1,1893 +0,0 @@ - Array ('self' => 'add|edit'), - 'OnCopy' => Array ('self' => true), - 'OnCut' => Array ('self' => 'edit'), - 'OnPasteClipboard' => Array ('self' => true), - 'OnPaste' => Array ('self' => 'add|edit', 'subitem' => 'edit'), - - 'OnRecalculatePriorities' => Array ('self' => 'add|edit'), // category ordering - 'OnItemBuild' => Array ('self' => true), // always allow to view individual categories (regardless of CATEGORY.VIEW right) - 'OnUpdatePreviewBlock' => Array ('self' => true), // for FCKEditor integration - ); - - $this->permMapping = array_merge($this->permMapping, $permissions); - } - - /** - * Categories are sorted using special sorting event - * - */ - function mapEvents() - { - parent::mapEvents(); - - $events_map = Array ( - 'OnMassMoveUp' => 'OnChangePriority', - 'OnMassMoveDown' => 'OnChangePriority', - ); - - $this->eventMethods = array_merge($this->eventMethods, $events_map); - } - - /** - * Checks permissions of user - * - * @param kEvent $event - */ - function CheckPermission(&$event) - { - if (!$this->Application->IsAdmin()) { - if ($event->Name == 'OnSetSortingDirect') { - // allow sorting on front event without view permission - return true; - } - - if ($event->Name == 'OnItemBuild') { - $category_id = $this->getPassedID($event); - if ($category_id == 0) { - return true; - } - } - } - - if (in_array($event->Name, $this->_getMassPermissionEvents())) { - $items = $this->_getPermissionCheckInfo($event); - - $perm_helper =& $this->Application->recallObject('PermissionsHelper'); - /* @var $perm_helper kPermissionsHelper */ - - if (($event->Name == 'OnSave') && array_key_exists(0, $items)) { - // adding new item (ID = 0) - $perm_value = $perm_helper->AddCheckPermission($items[0]['ParentId'], $event->Prefix) > 0; - } - else { - // leave only items, that can be edited - $ids = Array (); - $check_method = in_array($event->Name, Array ('OnMassDelete', 'OnCut')) ? 'DeleteCheckPermission' : 'ModifyCheckPermission'; - foreach ($items as $item_id => $item_data) { - if ($perm_helper->$check_method($item_data['CreatedById'], $item_data['ParentId'], $event->Prefix) > 0) { - $ids[] = $item_id; - } - } - - if (!$ids) { - // no items left for editing -> no permission - return $perm_helper->finalizePermissionCheck($event, false); - } - - $perm_value = true; - $event->setEventParam('ids', $ids); // will be used later by "kDBEventHandler::StoreSelectedIDs" method - } - - return $perm_helper->finalizePermissionCheck($event, $perm_value); - } - - if ($event->Name == 'OnPasteClipboard') { - // forces permission check to work by current category for "Paste In Category" operation - $category_id = $this->Application->GetVar('m_cat_id'); - $this->Application->SetVar('c_id', $category_id); - } - - return parent::CheckPermission($event); - } - - /** - * Returns events, that require item-based (not just event-name based) permission check - * - * @return Array - */ - function _getMassPermissionEvents() - { - return Array ( - 'OnEdit', 'OnSave', 'OnMassDelete', 'OnMassApprove', - 'OnMassDecline', 'OnMassMoveUp', 'OnMassMoveDown', - 'OnCut', - ); - } - - /** - * Returns category item IDs, that require permission checking - * - * @param kEvent $event - * @return string - */ - function _getPermissionCheckIDs(&$event) - { - if ($event->Name == 'OnSave') { - $selected_ids = implode(',', $this->getSelectedIDs($event, true)); - if (!$selected_ids) { - $selected_ids = 0; // when saving newly created item (OnPreCreate -> OnPreSave -> OnSave) - } - } - else { - // OnEdit, OnMassDelete events, when items are checked in grid - $selected_ids = implode(',', $this->StoreSelectedIDs($event)); - } - - return $selected_ids; - } - - /** - * Returns information used in permission checking - * - * @param kEvent $event - * @return Array - */ - function _getPermissionCheckInfo(&$event) - { - // when saving data from temp table to live table check by data from temp table - $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField'); - $table_name = $this->Application->getUnitOption($event->Prefix, 'TableName'); - - if ($event->Name == 'OnSave') { - $table_name = $this->Application->GetTempName($table_name, 'prefix:' . $event->Prefix); - } - - $sql = 'SELECT ' . $id_field . ', CreatedById, ParentId - FROM ' . $table_name . ' - WHERE ' . $id_field . ' IN (' . $this->_getPermissionCheckIDs($event) . ')'; - $items = $this->Conn->Query($sql, $id_field); - - if (!$items) { - // when creating new category, then no IDs are stored in session - $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); - list ($id, $fields_hash) = each($items_info); - - if (array_key_exists('ParentId', $fields_hash)) { - $item_category = $fields_hash['ParentId']; - } - else { - $item_category = $this->Application->RecallVar('m_cat_id'); // saved in c:OnPreCreate event permission checking - } - - $items[$id] = Array ( - 'CreatedById' => $this->Application->RecallVar('user_id'), - 'ParentId' => $item_category, - ); - } - - return $items; - } - - /** - * Set's mark, that root category is edited - * - * @param kEvent $event - */ - function OnEdit(&$event) - { - $category_id = $this->Application->GetVar($event->getPrefixSpecial().'_id'); - $this->Application->StoreVar('IsRootCategory_'.$this->Application->GetVar('m_wid'), $category_id === '0'); - - parent::OnEdit($event); - } - - /** - * Adds selected link to listing - * - * @param kEvent $event - */ - function OnProcessSelected(&$event) - { - $object =& $event->getObject(); - /* @var $object kDBItem */ - - $selected_ids = $this->Application->GetVar('selected_ids'); - - $this->RemoveRequiredFields($object); - $object->SetDBField($this->Application->RecallVar('dst_field'), $selected_ids['c']); - $object->Update(); - - $this->finalizePopup($event); - } - - /** - * Apply system filter to categories list - * - * @param kEvent $event - */ - function SetCustomQuery(&$event) - { - parent::SetCustomQuery($event); - - $object =& $event->getObject(); - /* @var $object kDBList */ - - // don't show "Content" category in advanced view - $object->addFilter('system_categories', '%1$s.Status <> 4'); - - // show system templates from current theme only + all virtual templates - $object->addFilter('theme_filter', '%1$s.ThemeId = ' . $this->_getCurrentThemeId() . ' OR %1$s.ThemeId = 0'); - - if ($event->Special == 'showall') { - // if using recycle bin don't show categories from there - $recycle_bin = $this->Application->ConfigValue('RecycleBinFolder'); - if ($recycle_bin) { - $sql = 'SELECT TreeLeft, TreeRight - FROM '.TABLE_PREFIX.'Category - WHERE CategoryId = '.$recycle_bin; - $tree_indexes = $this->Conn->GetRow($sql); - - $object->addFilter('recyclebin_filter', '%1$s.TreeLeft < '.$tree_indexes['TreeLeft'].' OR %1$s.TreeLeft > '.$tree_indexes['TreeRight']); - } - } - - if ($event->getEventParam('parent_cat_id') !== false) { - $parent_cat_id = $event->getEventParam('parent_cat_id'); - - if ("$parent_cat_id" == 'Root') { - $module_name = $event->getEventParam('module') ? $event->getEventParam('module') : 'In-Commerce'; - $parent_cat_id = $this->Application->findModule('Name', $module_name, 'RootCat'); - } - } - else { - $parent_cat_id = $this->Application->GetVar('c_id'); - if (!$parent_cat_id) { - $parent_cat_id = $this->Application->GetVar('m_cat_id'); - } - if (!$parent_cat_id) { - $parent_cat_id = 0; - } - } - - if ("$parent_cat_id" == '0') { - // replace "0" category with "Content" category id (this way template - $parent_cat_id = $this->Application->findModule('Name', 'Core', 'RootCat'); - } - - if ("$parent_cat_id" != 'any') { - if ($event->getEventParam('recursive')) { - if ($parent_cat_id > 0) { - // not "Home" category - $tree_indexes = $this->Application->getTreeIndex($parent_cat_id); - - $object->addFilter('parent_filter', TABLE_PREFIX.'Category.TreeLeft BETWEEN '.$tree_indexes['TreeLeft'].' AND '.$tree_indexes['TreeRight']); - } - } - else { - $object->addFilter('parent_filter', 'ParentId = '.$parent_cat_id); - } - } - - $object->addFilter('perm_filter', 'PermId = 1'); // check for CATEGORY.VIEW permission - if ($this->Application->RecallVar('user_id') != -1) { - // apply permission filters to all users except "root" - $groups = explode(',',$this->Application->RecallVar('UserGroups')); - foreach ($groups as $group) { - $view_filters[] = 'FIND_IN_SET('.$group.', acl)'; - } - $view_filter = implode(' OR ', $view_filters); - $object->addFilter('perm_filter2', $view_filter); - } - - if (!$this->Application->IsAdmin()) { - // apply status filter only on front - $object->addFilter('status_filter', $object->TableName.'.Status = 1'); - } - - // process "types" and "except" parameters - $type_clauses = Array(); - - $types = $event->getEventParam('types'); - $types = $types ? explode(',', $types) : Array (); - - $except_types = $event->getEventParam('except'); - $except_types = $except_types ? explode(',', $except_types) : Array (); - - if (in_array('related', $types) || in_array('related', $except_types)) { - $related_to = $event->getEventParam('related_to'); - if (!$related_to) { - $related_prefix = $event->Prefix; - } - else { - $sql = 'SELECT Prefix - FROM '.TABLE_PREFIX.'ItemTypes - WHERE ItemName = '.$this->Conn->qstr($related_to); - $related_prefix = $this->Conn->GetOne($sql); - } - - $rel_table = $this->Application->getUnitOption('rel', 'TableName'); - $item_type = (int)$this->Application->getUnitOption($event->Prefix, 'ItemType'); - - if ($item_type == 0) { - trigger_error('ItemType not defined for prefix ' . $event->Prefix . '', E_USER_WARNING); - } - - // process case, then this list is called inside another list - $prefix_special = $event->getEventParam('PrefixSpecial'); - if (!$prefix_special) { - $prefix_special = $this->Application->Parser->GetParam('PrefixSpecial'); - } - - $id = false; - if ($prefix_special !== false) { - $processed_prefix = $this->Application->processPrefix($prefix_special); - if ($processed_prefix['prefix'] == $related_prefix) { - // printing related categories within list of items (not on details page) - $list =& $this->Application->recallObject($prefix_special); - /* @var $list kDBList */ - - $id = $list->GetID(); - } - } - - if ($id === false) { - // printing related categories for single item (possibly on details page) - if ($related_prefix == 'c') { - $id = $this->Application->GetVar('m_cat_id'); - } - else { - $id = $this->Application->GetVar($related_prefix . '_id'); - } - } - - $p_item =& $this->Application->recallObject($related_prefix . '.current', null, Array('skip_autoload' => true)); - $p_item->Load( (int)$id ); - - $p_resource_id = $p_item->GetDBField('ResourceId'); - - $sql = 'SELECT SourceId, TargetId FROM '.$rel_table.' - WHERE - (Enabled = 1) - AND ( - (Type = 0 AND SourceId = '.$p_resource_id.' AND TargetType = '.$item_type.') - OR - (Type = 1 - AND ( - (SourceId = '.$p_resource_id.' AND TargetType = '.$item_type.') - OR - (TargetId = '.$p_resource_id.' AND SourceType = '.$item_type.') - ) - ) - )'; - - $related_ids_array = $this->Conn->Query($sql); - $related_ids = Array(); - - foreach ($related_ids_array as $key => $record) { - $related_ids[] = $record[ $record['SourceId'] == $p_resource_id ? 'TargetId' : 'SourceId' ]; - } - - if (count($related_ids) > 0) { - $type_clauses['related']['include'] = '%1$s.ResourceId IN ('.implode(',', $related_ids).')'; - $type_clauses['related']['except'] = '%1$s.ResourceId NOT IN ('.implode(',', $related_ids).')'; - } - else { - $type_clauses['related']['include'] = '0'; - $type_clauses['related']['except'] = '1'; - } - - $type_clauses['related']['having_filter'] = false; - } - - if (in_array('category_related', $type_clauses)) { - $object->removeFilter('parent_filter'); - $resource_id = $this->Conn->GetOne(' - SELECT ResourceId FROM '.$this->Application->getUnitOption($event->Prefix, 'TableName').' - WHERE CategoryId = '.$parent_cat_id - ); - - $sql = 'SELECT DISTINCT(TargetId) FROM '.TABLE_PREFIX.'Relationship - WHERE SourceId = '.$resource_id.' AND SourceType = 1'; - $related_cats = $this->Conn->GetCol($sql); - $related_cats = is_array($related_cats) ? $related_cats : Array(); - - $sql = 'SELECT DISTINCT(SourceId) FROM '.TABLE_PREFIX.'Relationship - WHERE TargetId = '.$resource_id.' AND TargetType = 1 AND Type = 1'; - $related_cats2 = $this->Conn->GetCol($sql); - $related_cats2 = is_array($related_cats2) ? $related_cats2 : Array(); - $related_cats = array_unique( array_merge( $related_cats2, $related_cats ) ); - - if ($related_cats) { - $type_clauses['category_related']['include'] = '%1$s.ResourceId IN ('.implode(',', $related_cats).')'; - $type_clauses['category_related']['except'] = '%1$s.ResourceId NOT IN ('.implode(',', $related_cats).')'; - } - else - { - $type_clauses['category_related']['include'] = '0'; - $type_clauses['category_related']['except'] = '1'; - } - $type_clauses['category_related']['having_filter'] = false; - } - - if (in_array('product_related', $types)) { - $object->removeFilter('parent_filter'); - - $product_id = $event->getEventParam('product_id') ? $event->getEventParam('product_id') : $this->Application->GetVar('p_id'); - $resource_id = $this->Conn->GetOne(' - SELECT ResourceId FROM '.$this->Application->getUnitOption('p', 'TableName').' - WHERE ProductId = '.$product_id - ); - - $sql = 'SELECT DISTINCT(TargetId) FROM '.TABLE_PREFIX.'Relationship - WHERE SourceId = '.$resource_id.' AND TargetType = 1'; - $related_cats = $this->Conn->GetCol($sql); - $related_cats = is_array($related_cats) ? $related_cats : Array(); - $sql = 'SELECT DISTINCT(SourceId) FROM '.TABLE_PREFIX.'Relationship - WHERE TargetId = '.$resource_id.' AND SourceType = 1 AND Type = 1'; - $related_cats2 = $this->Conn->GetCol($sql); - $related_cats2 = is_array($related_cats2) ? $related_cats2 : Array(); - $related_cats = array_unique( array_merge( $related_cats2, $related_cats ) ); - - if ($related_cats) { - $type_clauses['product_related']['include'] = '%1$s.ResourceId IN ('.implode(',', $related_cats).')'; - $type_clauses['product_related']['except'] = '%1$s.ResourceId NOT IN ('.implode(',', $related_cats).')'; - } - else { - $type_clauses['product_related']['include'] = '0'; - $type_clauses['product_related']['except'] = '1'; - } - - $type_clauses['product_related']['having_filter'] = false; - } - - $type_clauses['menu']['include'] = '%1$s.IsMenu = 1'; - $type_clauses['menu']['except'] = '%1$s.IsMenu = 0'; - - $search_helper =& $this->Application->recallObject('SearchHelper'); - /* @var $search_helper kSearchHelper */ - - $search_helper->SetComplexFilter($event, $type_clauses, implode(',', $types), implode(',', $except_types)); - } - - /** - * Returns current theme id - * - * @return int - */ - function _getCurrentThemeId() - { - $themes_helper =& $this->Application->recallObject('ThemesHelper'); - /* @var $themes_helper kThemesHelper */ - - return (int)$themes_helper->getCurrentThemeId(); - } - - /** - * Enter description here... - * - * @param kEvent $event - * @return int - */ - function getPassedID(&$event) - { - if (($event->Special == 'page') || ($event->Special == '-virtual') || ($event->Prefix == 'st')) { - return $this->_getPassedStructureID($event); - } - - if ($this->Application->IsAdmin()) { - return parent::getPassedID($event); - } - - return $this->Application->GetVar('m_cat_id'); - } - - /** - * Enter description here... - * - * @param kEvent $event - * @return int - */ - function _getPassedStructureID(&$event) - { - static $page_by_template = Array (); - - if ($event->Special == 'current') { - return $this->Application->GetVar('m_cat_id'); - } - - $event->setEventParam('raise_warnings', 0); - - $page_id = parent::getPassedID($event); - - if ($page_id === false) { - $template = $event->getEventParam('page'); - if (!$template) { - $template = $this->Application->GetVar('t'); - } - - // bug: when template contains "-" symbols (or others, that stripDisallowed will replace) it's not found - if (!array_key_exists($template, $page_by_template)) { - $sql = 'SELECT ' . $this->Application->getUnitOption($event->Prefix, 'IDField') . ' - FROM ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . ' - WHERE - ( - (NamedParentPath = ' . $this->Conn->qstr($template) . ') OR - (NamedParentPath = ' . $this->Conn->qstr('Content/' . $template) . ') OR - (IsSystem = 1 AND CachedTemplate = ' . $this->Conn->qstr($template) . ') - ) AND (ThemeId = ' . $this->_getCurrentThemeId() . ' OR ThemeId = 0)'; - - $page_id = $this->Conn->GetOne($sql); - } - else { - $page_id = $page_by_template[$template]; - } - - if ($page_id === false && EDITING_MODE) { - // create missing pages, when in editing mode - $object =& $this->Application->recallObject($this->Prefix . '.-new', null, Array('skip_autoload' => true)); - /* @var $object kDBItem */ - - $created = $this->_prepareAutoPage($object, $template, null, SMS_MODE_AUTO, false); // create virtual (not system!) page - if ($created) { - if ($this->Application->ConfigValue('QuickCategoryPermissionRebuild') || !$this->Application->IsAdmin()) { - $updater =& $this->Application->recallObject('kPermCacheUpdater'); - /* @var $updater kPermCacheUpdater */ - - $updater->OneStepRun(); - } - - $event->CallSubEvent('OnResetMenuCache'); - - $this->Application->RemoveVar('PermCache_UpdateRequired'); - - $page_id = $object->GetID(); - $this->Application->SetVar('m_cat_id', $page_id); - } - } - - if ($page_id) { - $page_by_template[$template] = $page_id; - } - } - - if (!$page_id && !$this->Application->IsAdmin()) { - $page_id = $this->Application->GetVar('m_cat_id'); - } - - return $page_id; - } - - function ParentGetPassedId(&$event) - { - return parent::GetPassedId($event); - } - - /** - * Adds calculates fields for item statuses - * - * @param kCatDBItem $object - * @param kEvent $event - */ - function prepareObject(&$object, &$event) - { - $object =& $event->getObject( Array('skip_autoload' => true) ); - - $object->addCalculatedField( - 'IsNew', - ' IF(%1$s.NewItem = 2, - IF(%1$s.CreatedOn >= (UNIX_TIMESTAMP() - '. - $this->Application->ConfigValue('Category_DaysNew'). - '*3600*24), 1, 0), - %1$s.NewItem - )'); - } - - /** - * Set correct parent path for newly created categories - * - * @param kEvent $event - */ - function OnAfterCopyToLive(&$event) - { - $parent_path = false; - $object =& $this->Application->recallObject($event->Prefix.'.-item', null, Array('skip_autoload' => true, 'live_table' => true)); - $object->Load($event->getEventParam('id')); - if ($event->getEventParam('temp_id') == 0) { - if ($object->isLoaded()) { - // update path only for real categories (not including "Home" root category) - $fields_hash = Array('ParentPath' => $object->buildParentPath()); - $this->Conn->doUpdate($fields_hash, $object->TableName, 'CategoryId = '.$object->GetID()); - $parent_path = $fields_hash['ParentPath']; - } - } - else { - $parent_path = $object->GetDBField('ParentPath'); - } - - if ($parent_path) { - $cache_updater =& $this->Application->recallObject('kPermCacheUpdater', null, array('strict_path' => $parent_path)); - $cache_updater->OneStepRun(); - $cache_updater->StrictPath = false; - } - } - - /** - * Set cache modification mark if needed - * - * @param kEvent $event - */ - function OnBeforeDeleteFromLive(&$event) - { - $id = $event->getEventParam('id'); - - // loding anyway, because this object is needed by "c-perm:OnBeforeDeleteFromLive" event - $temp_object =& $event->getObject( Array('skip_autoload' => true) ); - $temp_object->Load($id); - - if ($id == 0) { - if ($temp_object->isLoaded()) { - // new category -> update cache (not loaded when "Home" category) - $this->Application->StoreVar('PermCache_UpdateRequired', 1); - } - return ; - } - - // existing category was edited, check if in-cache fields are modified - $live_object =& $this->Application->recallObject($event->Prefix.'.-item', null, Array('live_table' => true, 'skip_autoload' => true)); - $live_object->Load($id); - - $cached_fields = Array('Name', 'Filename', 'Template', 'ParentId', 'Priority'); - - foreach ($cached_fields as $cached_field) { - if ($live_object->GetDBField($cached_field) != $temp_object->GetDBField($cached_field)) { - // use session instead of REQUEST because of permission editing in category can contain - // multiple submits, that changes data before OnSave event occurs - $this->Application->StoreVar('PermCache_UpdateRequired', 1); - break; - } - } - } - - /** - * Calls kDBEventHandler::OnSave original event - * Used in proj-cms:StructureEventHandler->OnSave - * - * @param kEvent $event - */ - function parentOnSave(&$event) - { - parent::OnSave($event); - } - - /** - * Reset root-category flag when new category is created - * - * @param kEvent $event - */ - function OnPreCreate(&$event) - { - // 1. for permission editing of Home category - $this->Application->RemoveVar('IsRootCategory_' . $this->Application->GetVar('m_wid')); - - parent::OnPreCreate($event); - - $object =& $event->getObject(); - - // 2. preset template -// $object->SetDBField('Template', $this->_getDefaultDesign()); - - $priority_helper =& $this->Application->recallObject('PriorityHelper'); - /* @var $priority_helper kPriorityHelper */ - - // 3. prepare priorities dropdown - $category_id = $this->Application->GetVar('m_cat_id'); - $priority_helper->preparePriorities($event, true, 'ParentId = ' . $category_id); - } - - /** - * Checks cache update mark and redirect to cache if needed - * - * @param kEvent $event - */ - function OnSave(&$event) - { - $object =& $event->getObject(); - if ($object->IsRoot()) { - $event->setEventParam('master_ids', Array(0)); - $this->RemoveRequiredFields($object); - } - - parent::OnSave($event); - - if ($event->status != erSUCCESS) { - return ; - } - - // 1. update priorities - $tmp = $this->Application->RecallVar('priority_changes'.$this->Application->GetVar('m_wid')); - $changes = $tmp ? unserialize($tmp) : Array (); - $changed_ids = array_keys($changes); - - $priority_helper =& $this->Application->recallObject('PriorityHelper'); - /* @var $priority_helper kPriorityHelper */ - - $priority_helper->updatePriorities($event, $changes, Array (0 => $event->getEventParam('ids'))); - - if ($this->Application->RecallVar('PermCache_UpdateRequired')) { - $this->Application->RemoveVar('IsRootCategory_' . $this->Application->GetVar('m_wid')); - } - - $this->Application->StoreVar('RefreshStructureTree', 1); - $event->CallSubEvent('OnResetMenuCache'); - } - - /** - * Creates a new item in temp table and - * stores item id in App vars and Session on succsess - * - * @param kEvent $event - */ - function OnPreSaveCreated(&$event) - { - $object =& $event->getObject( Array('skip_autoload' => true) ); - /* @var $object CategoriesItem */ - - if ($object->IsRoot()) { - // don't create root category while saving permissions - return ; - } - - $priority_helper =& $this->Application->recallObject('PriorityHelper'); - /* @var $priority_helper kPriorityHelper */ - - $category_id = $this->Application->GetVar('m_cat_id'); - $priority_helper->preparePriorities($event, true, 'ParentId = ' . $category_id); - - parent::OnPreSaveCreated($event); - } - - /** - * Deletes sym link to other category - * - * @param kEvent $event - */ - function OnAfterItemDelete(&$event) - { - parent::OnAfterItemDelete($event); - - $object =& $event->getObject(); - /* @var $object kDBItem */ - - $sql = 'UPDATE '.$object->TableName.' - SET SymLinkCategoryId = NULL - WHERE SymLinkCategoryId = '.$object->GetID(); - - $this->Conn->Query($sql); - } - - - /** - * Exclude root categories from deleting - * - * @param kEvent $event - */ - function customProcessing(&$event, $type) - { - if ($event->Name == 'OnMassDelete' && $type == 'before') { - $ids = $event->getEventParam('ids'); - if (!$ids || $this->Application->ConfigValue('AllowDeleteRootCats')) { - return ; - } - - // get module root categories and exclude them - foreach ($this->Application->ModuleInfo as $module_info) { - $root_categories[] = $module_info['RootCat']; - } - $root_categories = array_unique($root_categories); - - if ($root_categories && array_intersect($ids, $root_categories)) { - $event->setEventParam('ids', array_diff($ids, $root_categories)); - $this->Application->StoreVar('root_delete_error', 1); - } - } - - $change_events = Array ('OnPreSave', 'OnPreSaveCreated', 'OnUpdate', 'OnSave'); - if ($type == 'after' && in_array($event->Name, $change_events)) { - $object =& $event->getObject(); - - $tmp = $this->Application->RecallVar('priority_changes'.$this->Application->GetVar('m_wid')); - $changes = $tmp ? unserialize($tmp) : array(); - - if (!isset($changes[$object->GetID()])) { - $changes[$object->GetId()]['old'] = $object->GetID() == 0 ? 'new' : $object->GetDBField('OldPriority'); - } - - if ($changes[$object->GetId()]['old'] == $object->GetDBField('Priority')) return ; - - $changes[$object->GetId()]['new'] = $object->GetDBField('Priority'); - $changes[$object->GetId()]['parent'] = $object->GetDBField('ParentId'); - - $this->Application->StoreVar('priority_changes'.$this->Application->GetVar('m_wid'), serialize($changes)); - } - } - - /** - * Checks, that given template exists (physically) in given theme - * - * @param string $template - * @param int $theme_id - * @return bool - */ - function _templateFound($template, $theme_id = null) - { - static $init_made = false; - - if (!$init_made) { - $this->Application->InitParser(true); - $init_made = true; - } - - if (!isset($theme_id)) { - $theme_id = $this->_getCurrentThemeId(); - } - - $theme_name = $this->_getThemeName($theme_id); - - return $this->Application->TemplatesCache->TemplateExists('theme:' . $theme_name . '/' . $template); - } - - /** - * Removes ".tpl" in template path - * - * @param string $template - * @return string - */ - function _stripTemplateExtension($template) - { -// return preg_replace('/\.[^.\\\\\\/]*$/', '', $template); - - return preg_replace('/^[\\/]{0,1}(.*)\.tpl$/', "$1", $template); - } - - /** - * Deletes all selected items. - * Automatically recurse into sub-items using temp handler, and deletes sub-items - * by calling its Delete method if sub-item has AutoDelete set to true in its config file - * - * @param kEvent $event - */ - function OnMassDelete(&$event) - { - if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) { - return; - } - - $ids = $this->StoreSelectedIDs($event); - $to_delete = array(); - if ($recycle_bin = $this->Application->ConfigValue('RecycleBinFolder')) { - $rb =& $this->Application->recallObject('c.recycle', null, Array ('skip_autoload' => true)); - $rb->Load($recycle_bin); - $cat =& $event->getObject(Array('skip_autoload' => true)); - foreach ($ids as $id) { - $cat->Load($id); - if (preg_match('/^'.preg_quote($rb->GetDBField('ParentPath'),'/').'/', $cat->GetDBField('ParentPath'))) { - $to_delete[] = $id; - continue; - } - $cat->SetDBField('ParentId', $recycle_bin); - $cat->Update(); - } - $ids = $to_delete; - $event->redirect = 'categories/cache_updater'; - } - - $event->setEventParam('ids', $ids); - $this->customProcessing($event, 'before'); - $ids = $event->getEventParam('ids'); - - if ($ids) { - $recursive_helper =& $this->Application->recallObject('RecursiveHelper'); - /* @var $recursive_helper kRecursiveHelper */ - - foreach ($ids as $id) { - $recursive_helper->DeleteCategory($id, $event->Prefix); - } - } - $this->clearSelectedIDs($event); - - // update priorities - $priority_helper =& $this->Application->recallObject('PriorityHelper'); - /* @var $priority_helper kPriorityHelper */ - - // after deleting categories, all priorities should be recalculated - $parent_id = $this->Application->GetVar('m_cat_id'); - $priority_helper->recalculatePriorities($event, 'ParentId = ' . $parent_id); - - $this->Application->StoreVar('RefreshStructureTree', 1); - $event->CallSubEvent('OnResetMenuCache'); - } - - /** - * Add selected items to clipboard with mode = COPY (CLONE) - * - * @param kEvent $event - */ - function OnCopy(&$event) - { - $this->Application->RemoveVar('clipboard'); - $clipboard_helper =& $this->Application->recallObject('ClipboardHelper'); - $clipboard_helper->setClipboard($event, 'copy', $this->StoreSelectedIDs($event)); - $this->clearSelectedIDs($event); - } - - /** - * Add selected items to clipboard with mode = CUT - * - * @param kEvent $event - */ - function OnCut(&$event) - { - $this->Application->RemoveVar('clipboard'); - $clipboard_helper =& $this->Application->recallObject('ClipboardHelper'); - $clipboard_helper->setClipboard($event, 'cut', $this->StoreSelectedIDs($event)); - $this->clearSelectedIDs($event); - } - - /** - * Controls all item paste operations. Can occur only with filled clipbord. - * - * @param kEvent $event - */ - function OnPasteClipboard(&$event) - { - $clipboard = unserialize( $this->Application->RecallVar('clipboard') ); - foreach ($clipboard as $prefix => $clipboard_data) { - $paste_event = new kEvent($prefix.':OnPaste', Array('clipboard_data' => $clipboard_data)); - $this->Application->HandleEvent($paste_event); - - $event->redirect = $paste_event->redirect; - $event->redirect_params = $paste_event->redirect_params; - $event->status = $paste_event->status; - } - } - - /** - * Checks permission for OnPaste event - * - * @param kEvent $event - * @return bool - */ - function _checkPastePermission(&$event) - { - $perm_helper =& $this->Application->recallObject('PermissionsHelper'); - /* @var $perm_helper kPermissionsHelper */ - - $category_id = $this->Application->GetVar('m_cat_id'); - if ($perm_helper->AddCheckPermission($category_id, $event->Prefix) == 0) { - // no items left for editing -> no permission - return $perm_helper->finalizePermissionCheck($event, false); - } - - return true; - } - - /** - * Paste categories with subitems from clipboard - * - * @param kEvent $event - */ - function OnPaste(&$event) - { - if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1) || !$this->_checkPastePermission($event)) { - return ; - } - - $clipboard_data = $event->getEventParam('clipboard_data'); - - if (!$clipboard_data['cut'] && !$clipboard_data['copy']) { - return false; - } - - // 1. get ParentId of moved category(-es) before it gets updated!!!) - $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField'); - - if ($clipboard_data['cut']) { - $sql = 'SELECT ParentId - FROM ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . ' - WHERE ' . $id_field . ' = ' . $clipboard_data['cut'][0]; - $source_category_id = $this->Conn->GetOne($sql); - } - - $recursive_helper =& $this->Application->recallObject('RecursiveHelper'); - /* @var $recursive_helper kRecursiveHelper */ - - if ($clipboard_data['cut']) { - $recursive_helper->MoveCategories($clipboard_data['cut'], $this->Application->GetVar('m_cat_id')); - } - - if ($clipboard_data['copy']) { - foreach ($clipboard_data['copy'] as $id) { - $recursive_helper->PasteCategory($id, $event->Prefix); - } - } - - $priority_helper =& $this->Application->recallObject('PriorityHelper'); - /* @var $priority_helper kPriorityHelper */ - - - if ($clipboard_data['cut']) { - $priority_helper->recalculatePriorities($event, 'ParentId = '.$source_category_id); - } - - // recalculate priorities of newly pasted categories in destination category - $parent_id = $this->Application->GetVar('m_cat_id'); - $priority_helper->recalculatePriorities($event, 'ParentId = ' . $parent_id); - - if ($clipboard_data['cut'] || $clipboard_data['copy']) { - // rebuild with progress bar - if ($this->Application->ConfigValue('QuickCategoryPermissionRebuild')) { - $updater =& $this->Application->recallObject('kPermCacheUpdater'); - /* @var $updater kPermCacheUpdater */ - - $updater->OneStepRun(); - } - else { - $event->redirect = 'categories/cache_updater'; - } - - $event->CallSubEvent('OnResetMenuCache'); - $this->Application->StoreVar('RefreshStructureTree', 1); - } - } - - /** - * Occurs when pasting category - * - * @param kEvent $event - */ - /*function OnCatPaste(&$event) - { - $inp_clipboard = $this->Application->RecallVar('ClipBoard'); - $inp_clipboard = explode('-', $inp_clipboard, 2); - - if($inp_clipboard[0] == 'COPY') - { - $saved_cat_id = $this->Application->GetVar('m_cat_id'); - $cat_ids = $event->getEventParam('cat_ids'); - - $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField'); - $table = $this->Application->getUnitOption($event->Prefix, 'TableName'); - $ids_sql = 'SELECT '.$id_field.' FROM '.$table.' WHERE ResourceId IN (%s)'; - $resource_ids_sql = 'SELECT ItemResourceId FROM '.TABLE_PREFIX.'CategoryItems WHERE CategoryId = %s AND PrimaryCat = 1'; - - $object =& $this->Application->recallObject($event->Prefix.'.item', $event->Prefix, Array('skip_autoload' => true)); - - foreach($cat_ids as $source_cat => $dest_cat) - { - $item_resource_ids = $this->Conn->GetCol( sprintf($resource_ids_sql, $source_cat) ); - if(!$item_resource_ids) continue; - - $this->Application->SetVar('m_cat_id', $dest_cat); - $item_ids = $this->Conn->GetCol( sprintf($ids_sql, implode(',', $item_resource_ids) ) ); - - $temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler'); - if($item_ids) $temp->CloneItems($event->Prefix, $event->Special, $item_ids); - } - - $this->Application->SetVar('m_cat_id', $saved_cat_id); - } - }*/ - - /** - * Cleares clipboard content - * - * @param kEvent $event - */ - function OnClearClipboard(&$event) - { - $this->Application->RemoveVar('clipboard'); - } - - /** - * Sets correct status for new categories created on front-end - * - * @param kEvent $event - */ - function OnBeforeItemCreate(&$event) - { - $this->_beforeItemChange($event); - - if ($this->Application->IsAdmin() || $event->Prefix == 'st') { - // don't check category permissions when auto-creating structure pages - return ; - } - - $perm_helper =& $this->Application->recallObject('PermissionsHelper'); - /* @var $perm_helper kPermissionsHelper */ - - $new_status = false; - $category_id = $this->Application->GetVar('m_cat_id'); - if ($perm_helper->CheckPermission('CATEGORY.ADD', 0, $category_id)) { - $new_status = STATUS_ACTIVE; - } - else if ($perm_helper->CheckPermission('CATEGORY.ADD.PENDING', 0, $category_id)) { - $new_status = STATUS_PENDING; - } - - if ($new_status) { - $object =& $event->getObject(); - /* @var $object kDBItem */ - - $object->SetDBField('Status', $new_status); - - /* - if (!$this->Application->IsAdmin()) { - $object->SetDBField('IsMenu', 0); // add all suggested categories as non-menu - } - */ - } - else { - $event->status = erPERM_FAIL; - return ; - } - } - - /** - * Sets correct status for new categories created on front-end - * - * @param kEvent $event - */ - function OnBeforeItemUpdate(&$event) - { - parent::OnBeforeItemUpdate($event); - - $this->_beforeItemChange($event); - } - - /** - * Performs redirect to correct suggest confirmation template - * - * @param kEvent $event - */ - function OnCreate(&$event) - { - parent::OnCreate($event); - - if ($this->Application->IsAdmin() || $event->status != erSUCCESS) { - return ; - } - - $object =& $event->getObject(); - - $cache_updater =& $this->Application->recallObject('kPermCacheUpdater', null, array('strict_path' => $object->GetDBField('ParentPath'))); - $cache_updater->OneStepRun(); - $cache_updater->StrictPath = false; - - $is_active = ($object->GetDBField('Status') == STATUS_ACTIVE); - - $next_template = $is_active ? 'suggest_confirm_template' : 'suggest_pending_confirm_template'; - $event->redirect = $this->Application->GetVar($next_template); - $event->SetRedirectParam('opener', 's'); - - // send email events - $perm_prefix = $this->Application->getUnitOption($event->Prefix, 'PermItemPrefix'); - - $event_suffix = $is_active ? 'ADD' : 'ADD.PENDING'; - $this->Application->EmailEventAdmin($perm_prefix.'.'.$event_suffix); - $this->Application->EmailEventUser($perm_prefix.'.'.$event_suffix, $object->GetDBField('CreatedById')); - } - - /** - * Returns current per-page setting for list - * - * @param kEvent $event - * @return int - */ - function getPerPage(&$event) - { - if (!$this->Application->IsAdmin()) { - $event->setEventParam('same_special', true); - } - - return parent::getPerPage($event); - } - - /** - * Set's correct page for list - * based on data provided with event - * - * @param kEvent $event - * @access private - * @see OnListBuild - */ - function SetPagination(&$event) - { - parent::SetPagination($event); - - if (!$this->Application->IsAdmin()) { - $page_var = $event->getEventParam('page_var'); - if ($page_var !== false) { - $page = $this->Application->GetVar($page_var); - if (is_numeric($page)) { - $object =& $event->getObject(); - $object->SetPage($page); - } - } - } - } - - /** - * Apply same processing to each item beeing selected in grid - * - * @param kEvent $event - * @access private - */ - function iterateItems(&$event) - { - if ($event->Name != 'OnMassApprove' && $event->Name != 'OnMassDecline') { - return parent::iterateItems($event); - } - - if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) { - return; - } - - $object =& $event->getObject( Array('skip_autoload' => true) ); - $ids = $this->StoreSelectedIDs($event); - - if ($ids) { - $status_field = array_shift( $this->Application->getUnitOption($event->Prefix,'StatusField') ); - - foreach ($ids as $id) { - $object->Load($id); - - switch ($event->Name) { - case 'OnMassApprove': - $object->SetDBField($status_field, 1); - break; - - case 'OnMassDecline': - $object->SetDBField($status_field, 0); - break; - } - - if ($this->Application->GetVar('propagate_category_status')) { - $sql = 'UPDATE '.$object->TableName.' - SET '.$status_field.' = '.$object->GetDBField($status_field).' - WHERE TreeLeft BETWEEN '.$object->GetDBField('TreeLeft').' AND '.$object->GetDBField('TreeRight'); - $this->Conn->Query($sql); - } - - if ($object->Update()) { - $event->status = erSUCCESS; - } - else { - $event->status = erFAIL; - $event->redirect = false; - break; - } - } - } - - $this->clearSelectedIDs($event); - $this->Application->StoreVar('RefreshStructureTree', 1); - } - - /** - * Checks, that currently loaded item is allowed for viewing (non permission-based) - * - * @param kEvent $event - * @return bool - */ - function checkItemStatus(&$event) - { - $status_fields = $this->Application->getUnitOption($event->Prefix,'StatusField'); - if (!$status_fields) { - return true; - } - - $status_field = array_shift($status_fields); - if ($status_field == 'Status' || $status_field == 'Enabled') { - $object =& $event->getObject(); - if (!$object->isLoaded()) { - return true; - } - - return $object->GetDBField($status_field) == STATUS_ACTIVE || $object->GetDBField($status_field) == 4; - } - return true; - } - - // ============= for cms page processing ======================= - - /** - * Returns default design template - * - * @return string - */ - function _getDefaultDesign() - { - $default_design = $this->Application->ConfigValue('cms_DefaultDesign'); - return '/' . trim($default_design ? $default_design : 'designs/default_design', '/'); - } - - /** - * Returns default design based on given virtual template (used from kApplication::Run) - * - * @return string - */ - function GetDesignTemplate($t = null) - { - if (!isset($t)) { - $t = $this->Application->GetVar('t'); - } - - $page =& $this->Application->recallObject($this->Prefix . '.-virtual', null, Array ('page' => $t)); - if($page->isLoaded()) { - $real_t = $page->GetDBField('CachedTemplate'); - $this->Application->SetVar('m_cat_id', $page->GetDBField('CategoryId') ); - if ($page->GetDBField('FormId')) { - $this->Application->SetVar('form_id', $page->GetDBField('FormId')); - } - } - else { - $real_t = $this->_getDefaultDesign(); - } - -// $this->Application->SetVar('t', $t); - - return $real_t; - } - - /** - * Sets category id based on found template (used from kApplication::Run) - * - * @deprecated - */ - /*function SetCatByTemplate() - { - $t = $this->Application->GetVar('t'); - $page =& $this->Application->recallObject($this->Prefix . '.-virtual'); - - if ($page->isLoaded()) { - $this->Application->SetVar('m_cat_id', $page->GetDBField('CategoryId') ); - } - }*/ - - /** - * Prepares template paths - * - * @param kEvent $event - */ - function _beforeItemChange(&$event) - { - $object =& $event->getObject(); - /* @var $object kDBItem */ - - $object->SetDBField('Template', $this->_stripTemplateExtension( $object->GetDBField('Template') )); - - if ($object->GetDBField('IsSystem') == 1) { - if (!$this->_templateFound($object->GetDBField('Template'), $object->GetDBField('ThemeId'))) { - $object->SetError('Template', 'template_file_missing', 'la_error_TemplateFileMissing'); - } - } - - $this->_saveTitleField($object, 'Title'); - $this->_saveTitleField($object, 'MenuTitle'); - } - - /** - * Sets page name to requested field in case when: - * 1. page was auto created (through theme file rebuld) - * 2. requested field is emtpy - * - * @param kDBItem $object - * @param string $field - * @author Alex - */ - function _saveTitleField(&$object, $field) - { - $value = $object->GetField($field, 'no_default'); - if ($value == '' || preg_match('/^_Auto: (.*)/', $value)) { - $ml_formatter =& $this->Application->recallObject('kMultiLanguage'); - /* @var $ml_formatter kMultiLanguage */ - - $object->SetField( - $ml_formatter->LangFieldName($field), - $object->GetField( $ml_formatter->LangFieldName('Name') ) - ); - } - } - - /** - * Don't allow to delete system pages, when not in debug mode - * - * @param kEvent $event - */ - function OnBeforeItemDelete(&$event) - { - $object =& $event->getObject(); - if ($object->GetDBField('IsSystem') && !$this->Application->isDebugMode()) { - $event->status = erFAIL; - } - } - - /** - * Enter description here... - * - * @param StructureItem $object - * @param string $template - */ - function _prepareAutoPage(&$object, $template, $theme_id = null, $system_mode = SMS_MODE_AUTO, $template_info = Array ()) - { - $template = $this->_stripTemplateExtension($template); - - if ($system_mode == SMS_MODE_AUTO) { - $system = $this->_templateFound($template, $theme_id) ? 1 : 0; - } - else { - $system = $system_mode == SMS_MODE_FORCE ? 1 : 0; - } - - if ($system && $template_info === false) { - // do not autocreate system pages, when browsing through site - return false; - } - - if (!isset($theme_id)) { - $theme_id = $this->_getCurrentThemeId(); - } - - $root_category = $this->Application->findModule('Name', 'Core', 'RootCat'); - $page_category = $this->Application->GetVar('m_cat_id'); - if (!$page_category) { - $page_category = $root_category; - $this->Application->SetVar('m_cat_id', $page_category); - } - - if (!$system && strpos($template, '/') !== false) { - // virtual page, but have "/" in template path -> create it's path - $category_path = explode('/', $template); - $template = array_pop($category_path); - - $page_category = $this->_getParentCategoryFromPath($category_path, $root_category, $theme_id); - } - - $page_name = $system ? '_Auto: ' . $template : $template; - $page_description = ''; - - if ($system) { - $design_template = strtolower($template); // leading "/" not added ! - if ($template_info) { - if (array_key_exists('name', $template_info) && $template_info['name']) { - $page_name = $template_info['name']; - } - - if (array_key_exists('desc', $template_info) && $template_info['desc']) { - $page_description = $template_info['desc']; - } - - if (array_key_exists('section', $template_info) && $template_info['section']) { - // this will override any global "m_cat_id" - $page_category = $this->_getParentCategoryFromPath(explode('||', $template_info['section']), $root_category, $theme_id); - } - } - } - else { - $design_template = $this->_getDefaultDesign(); // leading "/" added ! - } - - // put all templates to then end of list (in their category) - $sql = 'SELECT MIN(Priority) - FROM ' . $object->TableName . ' - WHERE ParentId = ' . $page_category; - $min_priority = (int)$this->Conn->GetOne($sql); - - $object->Clear(); - $object->SetDBField('ParentId', $page_category); - $object->SetDBField('IsSystem', $system); - - - // system templates don't build their NamedParentPath based on their location because they are all added under - // "Content" when theme file structure is rebuilded and for ex. file "in-edit/designs/general" will have filename - // (after stripDisallowed) like "in_edit_designs_general" witch is less readable like "in-edit/designs/general" - // as for now. - - // TODO: 1. make system template NamedParentPath dependent on their location in structure. - // 2. load cms-page not only by NamedParentPath, but also by 'OR (Template = "$template" AND IsSystem = 1)' - // This way we can store CMS-blocks based on system template name on HDD no matter where it's location is - // and we can address him from template using his system path OR structure path (CMS-blocks should work too). - - $object->SetDBField('IsMenu', 0); - $object->SetDBField('ThemeId', $system ? $theme_id : 0); - $object->SetDBField('Priority', $min_priority - 1); - $object->SetDBField('Template', $design_template); - $object->SetDBField('CachedTemplate', $design_template); - - $primary_language = $this->Application->GetDefaultLanguageId(); - $current_language = $this->Application->GetVar('m_lang'); - $object->SetDBField('l' . $primary_language . '_Name', $page_name); - $object->SetDBField('l' . $current_language . '_Name', $page_name); - $object->SetDBField('l' . $primary_language . '_Description', $page_description); - $object->SetDBField('l' . $current_language . '_Description', $page_description); - - return $object->Create(); - } - - function _getParentCategoryFromPath($category_path, $base_category, $theme_id = null) - { - static $category_ids = Array (); - - if (!$category_path) { - return $base_category; - } - - if (array_key_exists(implode('||', $category_path), $category_ids)) { - return $category_ids[ implode('||', $category_path) ]; - } - - $backup_category_id = $this->Application->GetVar('m_cat_id'); - - $object =& $this->Application->recallObject($this->Prefix . '.-item', null, Array ('skip_autoload' => true)); - /* @var $object kDBItem */ - - $parent_id = $base_category; - - $filenames_helper =& $this->Application->recallObject('FilenamesHelper'); - /* @var $filenames_helper kFilenamesHelper */ - - $safe_category_path = array_map(Array (&$filenames_helper, 'replaceSequences'), $category_path); - - foreach ($category_path as $category_order => $category_name) { - $this->Application->SetVar('m_cat_id', $parent_id); - - // get virtual category first, when possible - $sql = 'SELECT ' . $object->IDField . ' - FROM ' . $object->TableName . ' - WHERE - ( - Filename = ' . $this->Conn->qstr($safe_category_path[$category_order]) . ' OR - Filename = ' . $this->Conn->qstr( $filenames_helper->replaceSequences('_Auto: ' . $category_name) ) . ' - ) AND - (ParentId = ' . $parent_id . ') AND - (ThemeId = 0 OR ThemeId = ' . $theme_id . ') - ORDER BY ThemeId ASC'; - $parent_id = $this->Conn->GetOne($sql); - - if ($parent_id === false) { - // page not found - $template = implode('/', array_slice($safe_category_path, 0, $category_order + 1)); - - // don't process system templates in sub-categories - $system = $this->_templateFound($template, $theme_id) && (strpos($template, '/') === false); - - if (!$this->_prepareAutoPage($object, $category_name, $theme_id, $system ? SMS_MODE_FORCE : false)) { - // page was not created - break; - } - - $parent_id = $object->GetID(); - } - } - - $this->Application->SetVar('m_cat_id', $backup_category_id); - $category_ids[ implode('||', $category_path) ] = $parent_id; - - return $parent_id; - } - - /** - * Returns theme name by it's id. Used in structure page creation. - * - * @param int $theme_id - * @return string - */ - function _getThemeName($theme_id) - { - static $themes = null; - - if (!isset($themes)) { - $id_field = $this->Application->getUnitOption('theme', 'IDField'); - $table_name = $this->Application->getUnitOption('theme', 'TableName'); - - $sql = 'SELECT Name, ' . $id_field . ' - FROM ' . $table_name . ' - WHERE Enabled = 1'; - $themes = $this->Conn->GetCol($sql, $id_field); - } - - return array_key_exists($theme_id, $themes) ? $themes[$theme_id] : false; - } - - /** - * Resets SMS-menu cache - * - * @param kEvent $event - */ - function OnResetMenuCache(&$event) - { - $this->Conn->Query('DELETE FROM '.TABLE_PREFIX.'Cache WHERE VarName IN ("cms_menu", "StructureTree")'); - } - - /** - * Updates structure config - * - * @param kEvent $event - */ - function OnAfterConfigRead(&$event) - { - parent::OnAfterConfigRead($event); - - if (defined('IS_INSTALL') && IS_INSTALL) { - // skip any processing, because Category table doesn't exists until install is finished - return ; - } - - $root_category = $this->Application->findModule('Name', 'Core', 'RootCat'); - - // set root category - $section_ajustments = $this->Application->getUnitOption($event->Prefix, 'SectionAdjustments'); - - $section_ajustments['in-portal:browse'] = Array ( - 'url' => Array ('m_cat_id' => $root_category), - 'late_load' => Array ('m_cat_id' => $root_category), - 'onclick' => 'checkCatalog(' . $root_category . ')', - ); - - $this->Application->setUnitOption($event->Prefix, 'SectionAdjustments', $section_ajustments); - - // prepare structure dropdown - $category_helper =& $this->Application->recallObject('CategoryHelper'); - /* @var $category_helper CategoryHelper */ - - $fields = $this->Application->getUnitOption($event->Prefix, 'Fields'); - - $fields['ParentId']['default'] = (int)$this->Application->GetVar('m_cat_id'); - $fields['ParentId']['options'] = $category_helper->getStructureTreeAsOptions(); - - // limit design list by theme - $design_folders = Array ('tf.FilePath = "/designs"', 'tf.FilePath = "/platform/designs"'); - foreach ($this->Application->ModuleInfo as $module_name => $module_info) { - $design_folders[] = 'tf.FilePath = "/' . $module_info['TemplatePath'] . 'designs"'; - } - $design_folders = array_unique($design_folders); - - $theme_id = $this->_getCurrentThemeId(); - $design_sql = $fields['Template']['options_sql']; - $design_sql = str_replace('(tf.FilePath = "/designs")', '(' . implode(' OR ', $design_folders) . ')' . ' AND (t.ThemeId = ' . $theme_id . ')', $design_sql); - $fields['Template']['options_sql'] = $design_sql; - - $this->Application->setUnitOption($event->Prefix, 'Fields', $fields); - - if ($this->Application->IsAdmin()) { - // don't sort by Front-End sorting fields - $config_mapping = $this->Application->getUnitOption($event->Prefix, 'ConfigMapping'); - $remove_keys = Array ('DefaultSorting1Field', 'DefaultSorting2Field', 'DefaultSorting1Dir', 'DefaultSorting2Dir'); - foreach ($remove_keys as $remove_key) { - unset($config_mapping[$remove_key]); - } - $this->Application->setUnitOption($event->Prefix, 'ConfigMapping', $config_mapping); - } - else { - // sort by parent path on Front-End only - $list_sortings = $this->Application->getUnitOption($event->Prefix, 'ListSortings'); - $list_sortings['']['ForcedSorting'] = Array ("CurrentSort" => 'asc'); - $this->Application->setUnitOption($event->Prefix, 'ListSortings', $list_sortings); - } - - // add grids for advanced view (with primary category column) - $grids = $this->Application->getUnitOption($this->Prefix, 'Grids'); - $process_grids = Array ('Default', 'Radio'); - foreach ($process_grids as $process_grid) { - $grid_data = $grids[$process_grid]; - $grid_data['Fields']['CachedNavbar'] = Array ('title' => 'la_col_Path', 'data_block' => 'grid_parent_category_td', 'filter_block' => 'grid_like_filter'); - $grids[$process_grid . 'ShowAll'] = $grid_data; - } - $this->Application->setUnitOption($this->Prefix, 'Grids', $grids); - } - - /** - * Removes this item and it's children (recursive) from structure dropdown - * - * @param kEvent $event - */ - function OnAfterItemLoad(&$event) - { - parent::OnAfterItemLoad($event); - - if (!$this->Application->IsAdmin()) { - return ; - } - - $object =& $event->getObject(); - - // remove this category & it's children from dropdown - $sql = 'SELECT '.$object->IDField.' - FROM '.$this->Application->getUnitOption($event->Prefix, 'TableName').' - WHERE ParentPath LIKE "'.$object->GetDBField('ParentPath').'%"'; - $remove_categories = $this->Conn->GetCol($sql); - - $field_options = $object->GetFieldOptions('ParentId'); - foreach ($remove_categories as $remove_category) { - unset($field_options['options'][$remove_category]); - } - $object->SetFieldOptions('ParentId', $field_options); - - $priority_helper =& $this->Application->recallObject('PriorityHelper'); - /* @var $priority_helper kPriorityHelper */ - - $priority_helper->preparePriorities($event, false, 'ParentId = '.$object->GetDBField('ParentId')); - - // storing prioriry right after load for comparing when updating - $object->SetDBField('OldPriority', $object->GetDBField('Priority')); - } - - /** - * Builds list - * - * @param kEvent $event - * @access protected - */ - function OnListBuild(&$event) - { - parent::OnListBuild($event); - - $priority_helper =& $this->Application->recallObject('PriorityHelper'); - /* @var $priority_helper kPriorityHelper */ - - $priority_helper->preparePriorities($event, false, 'ParentId = '.$this->Application->GetVar('m_cat_id')); - } - - /** - * Enter description here... - * - * @param kEvent $event - */ - function OnAfterRebuildThemes(&$event) - { - $sql = 'SELECT t.ThemeId, CONCAT( tf.FilePath, \'/\', tf.FileName ) AS Path, tf.FileMetaInfo - FROM '.TABLE_PREFIX.'ThemeFiles AS tf - LEFT JOIN '.TABLE_PREFIX.'Theme AS t ON t.ThemeId = tf.ThemeId - WHERE t.Enabled = 1 AND tf.FileType = 1 - AND ( - SELECT COUNT(CategoryId) - FROM ' . TABLE_PREFIX . 'Category - WHERE CONCAT(\'/\', ' . TABLE_PREFIX . 'Category.Template, \'.tpl\') = CONCAT( tf.FilePath, \'/\', tf.FileName ) - ) = 0 '; - $files = $this->Conn->Query($sql, 'Path'); - if (!$files) { - // all possible pages are already created - return ; - } - - set_time_limit(0); - ini_set('memory_limit', -1); - - $dummy =& $this->Application->recallObject($event->Prefix . '.-dummy', null, Array ('skip_autoload' => true)); - /* @var $dummy kDBItem */ - - $error_count = 0; - foreach ($files as $a_file => $file_info) { - $status = $this->_prepareAutoPage($dummy, $a_file, $file_info['ThemeId'], SMS_MODE_FORCE, unserialize($file_info['FileMetaInfo'])); // create system page - if (!$status) { - $error_count++; - } - } - - if ($this->Application->ConfigValue('QuickCategoryPermissionRebuild')) { - $updater =& $this->Application->recallObject('kPermCacheUpdater'); - /* @var $updater kPermCacheUpdater */ - - $updater->OneStepRun(); - } - - $event->CallSubEvent('OnResetMenuCache'); - - if ($error_count) { - // allow user to review error after structure page creation - $event->MasterEvent->redirect = false; - } - } - - /** - * Processes OnMassMoveUp, OnMassMoveDown events - * - * @param kEvent $event - */ - function OnChangePriority(&$event) - { - $object =& $event->getObject( Array('skip_autoload' => true) ); - $ids = $this->StoreSelectedIDs($event); - - if ($ids) { - $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField'); - $table_name = $this->Application->getUnitOption($event->Prefix, 'TableName'); - $parent_id = $this->Application->GetVar('m_cat_id'); - - $sql = 'SELECT Priority, '.$id_field.' - FROM '.$table_name.' - WHERE '.$id_field.' IN ('.implode(',', $ids).')'; - $priorities = $this->Conn->GetCol($sql, $id_field); - - $priority_helper =& $this->Application->recallObject('PriorityHelper'); - /* @var $priority_helper kPriorityHelper */ - - foreach ($ids as $id) { - $new_priority = $priorities[$id] + ($event->Name == 'OnMassMoveUp' ? +1 : -1); - - $changes = Array ( - $id => Array ('old' => $priorities[$id], 'new' => $new_priority, 'parent' => $parent_id), - ); - - $sql = 'UPDATE '.$table_name.' - SET Priority = '.$new_priority.' - WHERE '.$id_field.' = '.$id; - $this->Conn->Query($sql); - - $priority_helper->updatePriorities($event, $changes, Array ($id => $id)); - } - } - - $this->clearSelectedIDs($event); - $this->Application->StoreVar('RefreshStructureTree', 1); - } - - /** - * Completely recalculates priorities in current category - * - * @param kEvent $event - */ - function OnRecalculatePriorities(&$event) - { - $priority_helper =& $this->Application->recallObject('PriorityHelper'); - /* @var $priority_helper kPriorityHelper */ - - $parent_id = $this->Application->GetVar('m_cat_id'); - $priority_helper->recalculatePriorities($event, 'ParentId = ' . $parent_id); - } - - /** - * Update Preview Block for FCKEditor - * - * @param kEvent $event - */ - function OnUpdatePreviewBlock(&$event) - { - $event->status = erSTOP; - $string = unhtmlentities($this->Application->GetVar('preview_content')); - - $category_helper =& $this->Application->recallObject('CategoryHelper'); - /* @var $category_helper CategoryHelper */ - - $string = $category_helper->replacePageIds($string); - - $this->Application->StoreVar('_editor_preview_content_', $string); - } -} - -?> \ No newline at end of file