Index: branches/RC/core/units/categories/categories_event_handler.php =================================================================== diff -u -N -r11693 -r11724 --- branches/RC/core/units/categories/categories_event_handler.php (.../categories_event_handler.php) (revision 11693) +++ branches/RC/core/units/categories/categories_event_handler.php (.../categories_event_handler.php) (revision 11724) @@ -62,49 +62,40 @@ } } - 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)); - } + $check_events = Array ( + 'OnEdit', 'OnSave', 'OnMassDelete', 'OnMassApprove', + 'OnMassDecline', 'OnMassMoveUp', 'OnMassMoveDown' + ); + if (in_array($event->Name, $check_events)) { + $items = $this->_getPermissionCheckInfo($event); - $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField'); + $perm_helper =& $this->Application->recallObject('PermissionsHelper'); + /* @var $perm_helper kPermissionsHelper */ - 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); + 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 { - // 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 */ + // leave only items, that can be edited + $ids = Array (); + $check_method = ($event->Name == 'OnMassDelete') ? '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; + } + } - 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 (!$ids) { + // no items left for editing -> no permission + return $perm_helper->finalizePermissionCheck($event, false); } - } - if (!$perm_value) { - $event->status = erPERM_FAIL; + $perm_value = true; + $event->setEventParam('ids', $ids); // will be used later by "kDBEventHandler::StoreSelectedIDs" method } - return $perm_value; + return $perm_helper->finalizePermissionCheck($event, $perm_value); } if ($event->Name == 'OnPasteClipboard') { @@ -117,6 +108,70 @@ } /** + * 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 @@ -1536,30 +1591,13 @@ $this->Application->setUnitOption($event->Prefix, 'SectionAdjustments', $section_ajustments); // prepare structure dropdown - $sql = 'SELECT Data - FROM ' . TABLE_PREFIX . 'Cache - WHERE VarName = "StructureTree"'; - $data = $this->Conn->GetOne($sql); - if ($data) { - $data = unserialize($data); - } - else { - $data = $this->_getChildren($event, $root_category); + $category_helper =& $this->Application->recallObject('CategoryHelper'); + /* @var $category_helper CategoryHelper */ - $fields_hash = Array ( - 'VarName' => 'StructureTree', - 'Data' => serialize($data), - 'Cached' => adodb_mktime(), - ); - - $this->Conn->doInsert($fields_hash, TABLE_PREFIX.'Cache', 'REPLACE'); - } - - $fields = $this->Application->getUnitOption($event->Prefix, 'Fields'); - $theme_id = $this->_getCurrentThemeId(); + $fields['ParentId']['default'] = (int)$this->Application->GetVar('m_cat_id'); - $fields['ParentId']['options'] = $this->_printChildren($data, $root_category, $this->Application->GetVar('m_lang'), $theme_id); + $fields['ParentId']['options'] = $category_helper->getStructureTreeAsOptions(); // limit design list by theme $design_folders = Array ('tf.FilePath = "/designs"', 'tf.FilePath = "/platform/designs"'); @@ -1568,6 +1606,7 @@ } $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; @@ -1601,74 +1640,7 @@ $this->Application->setUnitOption($this->Prefix, 'Grids', $grids); } - function _printChildren(&$data, $parent_category_id, $language_id, $theme_id, $level = 0) - { - if ($data['ThemeId'] != $theme_id && $data['ThemeId'] != 0) { - // don't show system templates from different themes - return Array (); - } - - $ret = Array($parent_category_id => str_repeat('-', $level).' '.$data['l'.$language_id.'_Name']); - - if ($data['children']) { - $level++; - foreach ($data['children'] as $category_id => $category_data) { - $ret = array_merge_recursive2($ret, $this->_printChildren($data['children'][$category_id], $category_id, $language_id, $theme_id, $level)); - } - } - - return $ret; - } - /** - * Returns information about children under parent path (recursive) - * - * @param kEvent $event - * @param int $parent_category_id - * @param int $language_count - */ - function _getChildren(&$event, $parent_category_id) - { - static $language_count = null; - if (!isset($language_count)) { - $ml_helper =& $this->Application->recallObject('kMultiLanguageHelper'); - /* @var $ml_helper kMultiLanguageHelper */ - - $language_count = $ml_helper->getLanguageCount(); - } - - $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField'); - $table_name = $this->Application->getUnitOption($event->Prefix, 'TableName'); - - // get category children + parent category - $sql = 'SELECT * - FROM '.$table_name.' - WHERE ParentId = '.$parent_category_id.' OR '.$id_field.' = '.$parent_category_id.' - ORDER BY Priority DESC'; - $categories = $this->Conn->Query($sql, $id_field); - - $parent_data = $categories[$parent_category_id]; - unset($categories[$parent_category_id]); - - // no children for this category - $data = Array ('id' => $parent_data[$id_field], 'children' => false, 'ThemeId' => $parent_data['ThemeId']); - for ($i = 1; $i <= $language_count; $i++) { - $data['l'.$i.'_Name'] = $parent_data['l'.$i.'_Name']; - } - - if (!$categories) { - // no children - return $data; - } - - // category has children - foreach ($categories as $category_id => $category_data) { - $data['children'][$category_id] = $this->_getChildren($event, $category_id); - } - return $data; - } - - /** * Removes this item and it's children (recursive) from structure dropdown * * @param kEvent $event @@ -1742,6 +1714,9 @@ 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 */