Array('self' => 'add|edit'), 'OnPasteClipboard' => Array('self' => 'add|edit'), 'OnPaste' => array('self'=>'add|edit', 'subitem' => 'edit'), // 'OnSave' => Array('self' => 'add|edit') ); $this->permMapping = array_merge($this->permMapping, $permissions); } /** * 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 == 'OnEdit' || $event->Name == 'OnSave') { // check each id from selected individually and only if all are allowed proceed next if ($event->Name == 'OnEdit') { $selected_ids = implode(',', $this->StoreSelectedIDs($event)); } else { $selected_ids = implode(',', $this->getSelectedIDs($event, true)); } $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField'); if (strlen($selected_ids) > 0) { $table_name = $this->Application->getUnitOption($event->Prefix, 'TableName'); $sql = 'SELECT '.$id_field.', CreatedById FROM '.$table_name.' item_table WHERE '.$id_field.' IN ('.$selected_ids.')'; $items = $this->Conn->Query($sql, $id_field); } else { // when creating new category, then no IDs are stored in session $parent_cat = $this->Application->RecallVar('m_cat_id'); $items[$parent_cat] = Array ( $id_field => $parent_cat, 'CreatedById' => $this->Application->RecallVar('user_id'), ); } $perm_value = true; $perm_helper =& $this->Application->recallObject('PermissionsHelper'); /* @var $perm_helper kPermissionsHelper */ foreach ($items as $item_id => $item_data) { if ($perm_helper->ModifyCheckPermission($item_data['CreatedById'], $item_data[$id_field], $event->Prefix) == 0) { // one of items selected has no permission $perm_value = false; break; } } if (!$perm_value) { $event->status = erPERM_FAIL; } return $perm_value; } return parent::CheckPermission($event); } /** * 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); } /** * Apply system filter to categories list * * @param kEvent $event */ function SetCustomQuery(&$event) { parent::SetCustomQuery($event); $types=$event->getEventParam('types'); $except_types=$event->getEventParam('except'); $object =& $event->getObject(); $type_clauses = Array(); $object =& $event->getObject(); /* @var $object kDBList */ // hide categories with status = 4 (system categories) $object->addFilter('system_categories', '%1$s.Status <> 4'); 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" != 'any') { if ($event->getEventParam('recursive')) { $current_path = $this->Conn->GetOne('SELECT ParentPath FROM '.TABLE_PREFIX.'Category WHERE CategoryId='.$parent_cat_id); $subcats = $this->Conn->GetCol('SELECT CategoryId FROM '.TABLE_PREFIX.'Category WHERE ParentPath LIKE "'.$current_path.'%" '); $object->addFilter('parent_filter', 'ParentId IN ('.implode(', ', $subcats).')'); } 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'); } if(strpos($types, 'category_related') !== false) { $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(strpos($types, 'product_related') !== false) { $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; } /********************************************/ $includes_or_filter =& $this->Application->makeClass('kMultipleFilter'); $includes_or_filter->setType(FLT_TYPE_OR); $excepts_and_filter =& $this->Application->makeClass('kMultipleFilter'); $excepts_and_filter->setType(FLT_TYPE_AND); $includes_or_filter_h =& $this->Application->makeClass('kMultipleFilter'); $includes_or_filter_h->setType(FLT_TYPE_OR); $excepts_and_filter_h =& $this->Application->makeClass('kMultipleFilter'); $excepts_and_filter_h->setType(FLT_TYPE_AND); $except_types_array=explode(',', $types); if ($types){ $types_array=explode(',', $types); for ($i=0; $iremoveFilter('filter_'.$type); $includes_or_filter_h->addFilter('filter_'.$type, $type_clauses[$type]['include']); }else{ $includes_or_filter->removeFilter('filter_'.$type); $includes_or_filter->addFilter('filter_'.$type, $type_clauses[$type]['include']); } } } } if ($except_types){ $except_types_array=explode(',', $except_types); for ($i=0; $iremoveFilter('filter_'.$type); $excepts_and_filter_h->addFilter('filter_'.$type, $type_clauses[$type]['except']); }else{ $excepts_and_filter->removeFilter('filter_'.$type); $excepts_and_filter->addFilter('filter_'.$type, $type_clauses[$type]['except']); } } } } $object->addFilter('includes_filter', $includes_or_filter); $object->addFilter('excepts_filter', $excepts_and_filter); $object->addFilter('includes_filter_h', $includes_or_filter_h, HAVING_FILTER); $object->addFilter('excepts_filter_h', $excepts_and_filter_h, HAVING_FILTER); } /** * Enter description here... * * @param kEvent $event * @return int */ function GetPassedId(&$event) { if ( $this->Application->IsAdmin()) { return parent::getPassedID($event); } return $this->Application->GetVar('m_cat_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', 'CategoryTemplate', '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) { $this->Application->RemoveVar('IsRootCategory_'.$this->Application->GetVar('m_wid')); parent::OnPreCreate($event); } /** * 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 && $this->Application->RecallVar('PermCache_UpdateRequired')) { // "catalog" should be in opener stack by now $wid = $this->Application->GetVar('m_wid'); $stack_name = rtrim('opener_stack_'.$wid, '_'); $this->Application->RemoveVar('IsRootCategory_'.$wid); $opener_stack = unserialize($this->Application->RecallVar($stack_name)); $opener_stack[0] = str_replace('catalog', 'categories/cache_updater', $opener_stack[0]); $this->Application->StoreVar($stack_name, serialize($opener_stack)); $this->Application->RemoveVar('PermCache_UpdateRequired'); } } /** * 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 ; } parent::OnPreSaveCreated($event); } /** * 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; } // $event->status = erSUCCESS; $ids = $this->StoreSelectedIDs($event); 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); } /** * 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; } } /** * Paste categories with subitems from clipboard * * @param kEvent $event */ function OnPaste(&$event) { if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) { return; } $clipboard_data = $event->getEventParam('clipboard_data'); if (!$clipboard_data['cut'] && !$clipboard_data['copy']) { return false; } $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); } } if ($clipboard_data['cut'] || $clipboard_data['copy']) { $event->redirect = 'in-portal/categories/cache_updater'; } } /** * 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'); } } ?>