Index: trunk/core/units/categories/categories_event_handler.php =================================================================== diff -u -r5514 -r6093 --- trunk/core/units/categories/categories_event_handler.php (.../categories_event_handler.php) (revision 5514) +++ trunk/core/units/categories/categories_event_handler.php (.../categories_event_handler.php) (revision 6093) @@ -11,11 +11,62 @@ parent::mapPermissions(); $permissions = Array( 'OnRebuildCache' => Array('self' => 'add|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 = $this->Application->RecallVar($event->getPrefixSpecial().'_selected_ids'); + } + + $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField'); + $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); + + $perm_value = true; + $perm_helper =& $this->Application->recallObject('PermissionsHelper'); + 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); + } + + /** * Apply system filter to categories list * * @param kEvent $event @@ -51,7 +102,7 @@ } } - if ($parent_cat_id != 'any') { + 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.'%" '); @@ -62,10 +113,8 @@ } } - $object->addFilter('parent_filter', 'ParentId = '.$parent_cat_id); - $object->addFilter('perm_filter', 'PermId = 1'); // check for CATEGORY.VIEW permission - if ($this->Application->GetVar('u_id') > 0) { + if ($this->Application->GetVar('u_id') != -1) { // apply permission filters to all users except "root" $groups = explode(',',$this->Application->RecallVar('UserGroups')); foreach ($groups as $group) { @@ -79,7 +128,7 @@ // apply status filter only on front $object->addFilter('status_filter', $object->TableName.'.Status = 1'); } - + if(strpos($types, 'category_related') !== false) { $object->removeFilter('parent_filter'); @@ -237,9 +286,11 @@ if ($event->getEventParam('temp_id') == 0) { $object =& $this->Application->recallObject($event->Prefix.'.-item', null, Array('skip_autoload' => true, 'live_table' => true)); $object->Load($event->getEventParam('id')); - - $fields_hash = Array('ParentPath' => $object->buildParentPath()); - $this->Conn->doUpdate($fields_hash, $object->TableName, 'CategoryId = '.$object->GetID()); + 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()); + } } } @@ -251,20 +302,24 @@ 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) { - // new category -> update chache - $this->Application->StoreVar('PermCache_UpdateRequired', 1); + if ($temp_object->isLoaded()) { + // new category -> update chache (not loaded when "Home" category) + $this->Application->StoreVar('PermCache_UpdateRequired', 1); + } return ; } // existing category was edited, check if in-cache fields are modified - $temp_object =& $event->getObject( Array('skip_autoload' => true) ); - $temp_object->Load($id); - - $live_object =& $this->Application->recallObject($event->Prefix.'.-item', null, Array('live_table' => true)); + $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', 'ItemTemplate'); + $cached_fields = Array('Name', 'Filename', 'CategoryTemplate'); foreach ($cached_fields as $cached_field) { if ($live_object->GetDBField($cached_field) != $temp_object->GetDBField($cached_field)) { @@ -283,6 +338,11 @@ */ function OnSave(&$event) { + $object =& $event->getObject(); + if ($object->IsRoot()) { + $event->setEventParam('master_ids', Array(0)); + } + parent::OnSave($event); if ($event->status == erSUCCESS && $this->Application->RecallVar('PermCache_UpdateRequired')) { // "catalog" should be in opener stack by now @@ -317,6 +377,129 @@ } $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)); + } + + /** + * 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)); + } + + /** + * 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'); + 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); + } + } + + if ($clipboard_data['cut'] || $clipboard_data['copy']) { + $event->redirect = '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'); + } } ?> \ No newline at end of file