Index: trunk/core/units/general/helpers/recursive_helper.php =================================================================== diff -u -N -r5178 -r6093 --- trunk/core/units/general/helpers/recursive_helper.php (.../recursive_helper.php) (revision 5178) +++ trunk/core/units/general/helpers/recursive_helper.php (.../recursive_helper.php) (revision 6093) @@ -18,20 +18,154 @@ } } + $ci_table = $this->Application->getUnitOption('ci', 'TableName'); // 1. remove category items from this category if it is supplemental (non-primary) category to them - $sql = 'DELETE FROM '.TABLE_PREFIX.'CategoryItems + $sql = 'DELETE FROM '.$ci_table.' WHERE ('.$id_field.' = '.$category_id.') AND (PrimaryCat = 0)'; $this->Conn->Query($sql); $temp_handler =& $this->Application->recallObject('c_TempHandler', 'kTempTablesHandler'); // 2. delete items this have this category as primary -// $temp_handler->DeleteItems($item_prefix, '', $item_ids); + $delete_ids = $this->getCategoryItems($category_id, true); + foreach ($delete_ids as $item_prefix => $resource_ids) { + if (!$item_prefix) { + // not ItemPrefix filled -> old categoryitem linking + continue; + } + $item_ids = $this->GetItemIDs($item_prefix, $resource_ids); + $temp_handler->BuildTables($item_prefix, $item_ids); + $temp_handler->DeleteItems($item_prefix, '', $item_ids); + } + // 3. delete this category + $temp_handler->BuildTables('c', Array($category_id)); $temp_handler->DeleteItems('c', '', Array($category_id)); + } + + /** + * Converts resource ids list to id field list for given prefix + * + * @param string $prefix + * @param Array $resource_ids + * @return Array + */ + function GetItemIDs($prefix, $resource_ids) + { + if (!$resource_ids) { + return Array(); + } + $id_field = $this->Application->getUnitOption($prefix, 'IDField'); + $table_name = $this->Application->getUnitOption($prefix, 'TableName'); + + $sql = 'SELECT '.$id_field.' + FROM '.$table_name.' + WHERE ResourceId IN ('.implode(',', $resource_ids).')'; + return $this->Conn->GetCol($sql); } + + // moves selected categories to destination category + function MoveCategories($category_ids, $dest_category_id) + { + if (!$category_ids) return ; + + $id_field = $this->Application->getUnitOption('c', 'IDField'); + $table_name = $this->Application->getUnitOption('c', 'TableName'); + + $sql = 'UPDATE '.$table_name.' + SET ParentId = '.$dest_category_id.' + WHERE '.$id_field.' IN ('.implode(',', $category_ids).')'; + $this->Conn->Query($sql); + } + + /** + * Complete cloning or category with subcategories and subitems + * + * @param int $category_id + */ + function PasteCategory($category_id) + { + $backup_category_id = $this->Application->GetVar('m_cat_id'); + + // 1. clone category + $temp_handler =& $this->Application->recallObject('c_TempHandler', 'kTempTablesHandler'); + $temp_handler->BuildTables('c', Array($category_id)); + $new_category_id = array_pop( $temp_handler->CloneItems('c', '', Array($category_id)) ); + $this->Application->SetVar('m_cat_id', $new_category_id); + + $id_field = $this->Application->getUnitOption('c', 'IDField'); + $table_name = $this->Application->getUnitOption('c', 'TableName'); + + // 2. assign supplemental items to current category to new category + $paste_ids = $this->getCategoryItems($category_id, false); + + foreach ($paste_ids as $item_prefix => $resource_ids) { + if (!$item_prefix) { + // not ItemPrefix filled -> old categoryitem linking + continue; + } + + $item_object =& $this->Application->recallObject($item_prefix.'.-item', null, Array('skip_autoload' => true)); + foreach ($resource_ids as $item_resource_id) { + $item_object->Load($item_resource_id, 'ResourceId'); + $item_object->assignToCategory($new_category_id, false); + } + } + + // 3. clone items that have current category as primary + $paste_ids = $this->getCategoryItems($category_id, true); + + foreach ($paste_ids as $item_prefix => $resource_ids) { + if (!$item_prefix) { + // not ItemPrefix filled -> old categoryitem linking + continue; + } + + // 2. clone items from current category (for each prefix separately) + $item_ids = $this->GetItemIDs($item_prefix, $resource_ids); + $temp_handler->BuildTables($item_prefix, $item_ids); + $temp_handler->CloneItems($item_prefix, '', $item_ids); + } + + // 4. do same stuff for each subcategory + $sql = 'SELECT '.$id_field.' + FROM '.$table_name.' + WHERE ParentId = '.$category_id; + + $sub_categories = $this->Conn->GetCol($sql); + if ($sub_categories) { + foreach ($sub_categories as $sub_category_id) { + $this->PasteCategory($sub_category_id); + } + } + + $this->Application->SetVar('m_cat_id', $backup_category_id); + } + + /** + * Returns grouped category items + * + * @param int $category_id + * @param bool $item_primary_category + * @return Array + */ + function getCategoryItems($category_id, $item_primary_category = true) + { + $ci_table = $this->Application->getUnitOption('ci', 'TableName'); + + $sql = 'SELECT ItemPrefix, ItemResourceId + FROM '.$ci_table.' + WHERE (CategoryId = '.$category_id.') AND (PrimaryCat = '.($item_primary_category ? 1 : 0).')'; + $category_items = $this->Conn->GetCol($sql, 'ItemResourceId'); + + $item_ids = Array(); + foreach ($category_items as $resource_id => $item_prefix) { + $item_ids[$item_prefix][] = $resource_id; + } + return $item_ids; + } } ?> \ No newline at end of file