Page MenuHomeIn-Portal Phabricator

D256.id611.diff
No OneTemporary

File Metadata

Created
Sun, Jun 29, 3:25 PM

D256.id611.diff

Index: core/install/install_data.sql
===================================================================
--- core/install/install_data.sql
+++ core/install/install_data.sql
@@ -12,7 +12,7 @@
INSERT INTO SystemSettings VALUES(DEFAULT, 'Catalog_PreselectModuleTab', '1', 'In-Portal', 'in-portal:configure_categories', 'la_title_General', 'la_config_CatalogPreselectModuleTab', 'checkbox', NULL, NULL, 10.09, 0, 0, NULL);
INSERT INTO SystemSettings VALUES(DEFAULT, 'RecycleBinFolder', '', 'In-Portal', 'in-portal:configure_categories', 'la_title_General', 'la_config_RecycleBinFolder', 'text', NULL, NULL, 10.10, 0, 0, NULL);
INSERT INTO SystemSettings VALUES(DEFAULT, 'CheckViewPermissionsInCatalog', '0', 'In-Portal', 'in-portal:configure_categories', 'la_title_General', 'la_config_CheckViewPermissionsInCatalog', 'radio', NULL, '1=la_Yes||0=la_No', 10.11, 0, 1, 'hint:la_config_CheckViewPermissionsInCatalog');
-INSERT INTO SystemSettings VALUES(DEFAULT, 'CategoryPermissionRebuildMode', '3', 'In-Portal', 'in-portal:configure_categories', 'la_title_General', 'la_config_CategoryPermissionRebuildMode', 'select', NULL, '1=la_opt_Manual||2=la_opt_Silent||3=la_opt_Automatic', 10.12, 0, 0, 'hint:la_config_CategoryPermissionRebuildMode');
+INSERT INTO SystemSettings VALUES(DEFAULT, 'CategoryPermissionRebuildMode', '1', 'In-Portal', 'in-portal:configure_categories', 'la_title_General', 'la_config_CategoryPermissionRebuildMode', 'select', NULL, '1=la_opt_Manual||2=la_opt_Silent||3=la_opt_Automatic', 10.12, 0, 0, 'hint:la_config_CategoryPermissionRebuildMode');
INSERT INTO SystemSettings VALUES(DEFAULT, 'FilenameSpecialCharReplacement', '-', 'In-Portal', 'in-portal:configure_categories', 'la_title_General', 'la_config_FilenameSpecialCharReplacement', 'select', NULL, '_=+_||-=+-', 10.13, 0, 0, NULL);
INSERT INTO SystemSettings VALUES(DEFAULT, 'Search_MinKeyword_Length', '3', 'In-Portal', 'in-portal:configure_categories', 'la_title_General', 'la_config_Search_MinKeyword_Length', 'text', NULL, NULL, 10.14, 0, 0, NULL);
INSERT INTO SystemSettings VALUES(DEFAULT, 'ExcludeTemplateSectionsFromSearch', '0', 'In-Portal', 'in-portal:configure_categories', 'la_title_General', 'la_config_ExcludeTemplateSectionsFromSearch', 'checkbox', '', '', 10.15, 0, 0, NULL);
Index: core/install/install_schema.sql
===================================================================
--- core/install/install_schema.sql
+++ core/install/install_schema.sql
@@ -518,6 +518,7 @@
ParentPath text,
TreeLeft bigint(20) NOT NULL DEFAULT '0',
TreeRight bigint(20) NOT NULL DEFAULT '0',
+ TreeLocked tinyint(4) NOT NULL DEFAULT '0',
NamedParentPath text,
NamedParentPathHash int(10) unsigned NOT NULL DEFAULT '0',
MetaDescription text,
@@ -592,7 +593,8 @@
KEY LiveRevisionNumber (LiveRevisionNumber),
KEY PromoBlockGroupId (PromoBlockGroupId),
KEY NamedParentPathHash (NamedParentPathHash),
- KEY CachedTemplateHash (CachedTemplateHash)
+ KEY CachedTemplateHash (CachedTemplateHash),
+ KEY IDX_TREELOCKED (TreeLocked)
);
CREATE TABLE CategoryCustomData (
Index: core/install/upgrades.sql
===================================================================
--- core/install/upgrades.sql
+++ core/install/upgrades.sql
@@ -2934,3 +2934,7 @@
WHERE TemplateName LIKE 'USER%';
UPDATE SystemSettings SET VariableValue = 1 WHERE VariableName = 'CSVExportEncoding';
+
+ALTER TABLE Categories ADD TreeLocked TINYINT(4) NOT NULL DEFAULT '0' AFTER TreeRight;
+ALTER TABLE Categories ADD INDEX IDX_TREELOCKED (TreeLocked);
+UPDATE SystemSettings SET VariableValue = 1 WHERE VariableName = 'CategoryPermissionRebuildMode';
Index: core/units/admin/admin_tag_processor.php
===================================================================
--- core/units/admin/admin_tag_processor.php
+++ core/units/admin/admin_tag_processor.php
@@ -582,7 +582,10 @@
if ( $global_mark || $local_mark ) {
$this->Application->RemoveVar('PermCache_UpdateRequired');
- $rebuild_mode = $this->Application->ConfigValue('CategoryPermissionRebuildMode');
+
+ /** @var CategoryHelper $category_helper */
+ $category_helper = $this->Application->recallObject('CategoryHelper');
+ $rebuild_mode = $category_helper->getCategoryPermissionRebuildMode();
if ( $rebuild_mode == CategoryPermissionRebuild::SILENT ) {
$updater = $this->Application->makeClass('kPermCacheUpdater');
Index: core/units/categories/cache_updater.php
===================================================================
--- core/units/categories/cache_updater.php
+++ core/units/categories/cache_updater.php
@@ -206,12 +206,20 @@
var $StrictPath = false;
/**
+ * Previous parent of strict category.
+ *
+ * @var integer
+ */
+ protected $StrictPathOldParentId;
+
+ /**
* Returns instance of perm cache updater
*
- * @param int $continuing
- * @param mixed $strict_path
+ * @param integer $continuing Continuing previous operation.
+ * @param string $strict_path Strict path limitation.
+ * @param integer $strict_path_old_parent_id Previous parent of strict category.
*/
- public function __construct($continuing = null, $strict_path = null)
+ public function __construct($continuing = null, $strict_path = null, $strict_path_old_parent_id = null)
{
parent::__construct();
@@ -221,6 +229,7 @@
}
$this->StrictPath = $strict_path;
+ $this->StrictPathOldParentId = $strict_path_old_parent_id;
}
// cache widely used values to speed up process
@@ -343,6 +352,11 @@
$this->Conn->Query($sql);
$this->clearData();
+ // Don't delete override, that is set exactly, during strict path processing.
+ if ( !$this->StrictPath ) {
+ $this->Application->RemoveVar('CategoryPermissionRebuildModeOverride');
+ }
+
$this->Application->incrementCacheSerial('c');
}
@@ -381,19 +395,22 @@
$this->iteration++;
}
- // start with first child if we haven't started yet
- if (!isset($data['current_child'])) $data['current_child'] = 0;
+ // Start with first child if we haven't started yet.
+ if ( !isset($data['current_child']) ) {
+ $data['current_child'] = 0;
+ }
- // if we have more children on CURRENT LEVEL
- if (isset($data['children'][$data['current_child']])) {
- if ($this->StrictPath) {
- while ( isset($data['children'][ $data['current_child'] ]) && !in_array($data['children'][ $data['current_child'] ], $this->StrictPath) ) {
- $data['current_child']++;
- continue;
- }
- if (!isset($data['children'][ $data['current_child'] ])) return false; //error
+ // Skip all children on CURRENT LEVEL that are not within StrictPath.
+ if ( $this->StrictPath && isset($data['children'][$data['current_child']]) ) {
+ while ( isset($data['children'][$data['current_child']]) && !in_array($data['children'][$data['current_child']], $this->StrictPath) ) {
+ $data['current_child']++;
+ continue;
}
- $next_data = Array();
+ }
+
+ // If we have more children on CURRENT LEVEL.
+ if ( isset($data['children'][$data['current_child']]) ) {
+ $next_data = array();
$next_data['titles'] = $data['titles'];
$next_data['parent_path'] = $data['parent_path'];
$next_data['named_path'] = $data['named_path'];
@@ -444,11 +461,77 @@
'CachedTemplate' => $data['template'], // actual template to use when category is visited
'CachedTemplateHash' => kUtil::crc32(mb_strtolower($data['template'])),
'CachedDescendantCatsQty' => $data['children_count'],
- 'TreeLeft' => $data['left'],
- 'TreeRight' => $data['right'],
);
- foreach ($this->languages as $language_id) {
+ if ( $this->StrictPath ) {
+ // Only do once per whole strict path.
+ $category_id = $data['current_id'];
+
+ if ( $category_id == end($this->StrictPath)
+ && is_numeric($this->StrictPathOldParentId)
+ && $this->StrictPathOldParentId > 0
+ ) {
+ $this->Conn->doUpdate(array('TreeLocked' => 0), TABLE_PREFIX . 'Categories', 'TRUE');
+
+ $new_parent_id = $this->StrictPath[count($this->StrictPath) - 2];
+
+ if ( $this->StrictPathOldParentId == 0 ) {
+ // New category.
+ $this->Conn->doUpdate(
+ array('TreeLocked' => 1),
+ TABLE_PREFIX . 'Categories',
+ 'CategoryId = ' . $category_id
+ );
+ $parent_tree_indexes = $this->Application->getTreeIndex($new_parent_id);
+ $this->addCreateTreeWindow($parent_tree_indexes['TreeLeft'], 1);
+ }
+ elseif ( $new_parent_id != $this->StrictPathOldParentId ) {
+ // Moved categories.
+ $tree_indexes = $this->Application->getTreeIndex($category_id);
+ $this->Conn->doUpdate(
+ array('TreeLocked' => 1),
+ TABLE_PREFIX . 'Categories',
+ 'TreeLeft BETWEEN ' . $tree_indexes['TreeLeft'] . ' AND ' . $tree_indexes['TreeRight']
+ );
+ $parent_tree_indexes = $this->Application->getTreeIndex($new_parent_id);
+ $this->addCreateTreeWindow($parent_tree_indexes['TreeLeft'], $data['children_count'] + 1);
+
+ // Increase/decrease moved tree indexes to fit within new parent tree indexes.
+ $tree_diff = ($parent_tree_indexes['TreeLeft'] + 1) - $tree_indexes['TreeLeft'];
+ $tree_diff_clause = ($tree_diff >= 0 ? '+' : '-') . ' ' . abs($tree_diff);
+
+ $sql = 'UPDATE ' . TABLE_PREFIX . 'Categories
+ SET TreeLeft = TreeLeft ' . $tree_diff_clause . ',
+ TreeRight = TreeRight ' . $tree_diff_clause . '
+ WHERE TreeLocked = 1';
+ $this->Conn->Query($sql);
+
+ $sql = 'SELECT CategoryId
+ FROM ' . TABLE_PREFIX . 'Categories
+ WHERE TreeLocked = 1';
+ $moved_categories = $this->Conn->GetColIterator($sql);
+
+ foreach ( $moved_categories as $moved_category_id ) {
+ $this->Application->incrementCacheSerial('c', $moved_category_id);
+ }
+
+ // Moved category has sub-categories.
+ if ( count($moved_categories) > 1 ) {
+ $this->Application->StoreVar(
+ 'CategoryPermissionRebuildModeOverride',
+ CategoryPermissionRebuild::AUTOMATIC
+ );
+ }
+ }
+ }
+ }
+ else {
+ // Is calculated correctly, only when doing full cache rebuild.
+ $fields_hash['TreeLeft'] = $data['left'];
+ $fields_hash['TreeRight'] = $data['right'];
+ }
+
+ foreach ( $this->languages as $language_id ) {
$fields_hash['l' . $language_id . '_CachedNavbar'] = implode('&|&', $data['titles'][$language_id]);
}
@@ -459,6 +542,43 @@
}
}
+ /**
+ * Creates window in TreeLeft/TreeRight for X categories.
+ *
+ * @param integer $tree_left Tree left.
+ * @param integer $sub_category_count Sub category count.
+ *
+ * @return void
+ */
+ protected function addCreateTreeWindow($tree_left, $sub_category_count)
+ {
+ // Use ">" in WHERE to avoid affecting direct parent.
+ $sql = 'SELECT CategoryId
+ FROM ' . TABLE_PREFIX . 'Categories
+ WHERE TreeLeft > ' . $tree_left . ' AND TreeLocked = 0';
+ $updated_categories = $this->Conn->GetCol($sql);
+
+ $sql = 'UPDATE ' . TABLE_PREFIX . 'Categories
+ SET TreeLeft = TreeLeft + ' . ($sub_category_count * 2) . '
+ WHERE TreeLeft > ' . $tree_left . ' AND TreeLocked = 0';
+ $this->Conn->Query($sql);
+
+ // Use ">=" in WHERE to affect direct parent.
+ $sql = 'SELECT CategoryId
+ FROM ' . TABLE_PREFIX . 'Categories
+ WHERE TreeRight >= ' . $tree_left . ' AND TreeLocked = 0';
+ $updated_categories = array_unique(array_merge($updated_categories, $this->Conn->GetCol($sql)));
+
+ $sql = 'UPDATE ' . TABLE_PREFIX . 'Categories
+ SET TreeRight = TreeRight + ' . ($sub_category_count * 2) . '
+ WHERE TreeRight >= ' . $tree_left . ' AND TreeLocked = 0';
+ $this->Conn->Query($sql);
+
+ foreach ( $updated_categories as $updated_category_id ) {
+ $this->Application->incrementCacheSerial('c', $updated_category_id);
+ }
+ }
+
function QueryTitle(&$data)
{
$category_id = $data['current_id'];
Index: core/units/categories/categories_event_handler.php
===================================================================
--- core/units/categories/categories_event_handler.php
+++ core/units/categories/categories_event_handler.php
@@ -739,24 +739,34 @@
$parent_path = false;
$object->Load($event->getEventParam('id'));
+ $old_parent_id = $object->GetDBField('ParentId');
+ $old_parent_path = $object->GetDBField('ParentPath');
if ( $event->getEventParam('temp_id') == 0 ) {
+ // Update path only for real categories (not including "Home" root category).
if ( $object->isLoaded() ) {
- // update path only for real categories (not including "Home" root category)
- $fields_hash = $object->buildParentBasedFields();
- $this->Conn->doUpdate($fields_hash, $object->TableName, 'CategoryId = ' . $object->GetID());
- $parent_path = $fields_hash['ParentPath'];
+ $old_parent_id = 0;
+ $this->refreshHierarchyFields($object, true);
+ $parent_path = $object->GetDBField('ParentPath');
}
}
else {
+ $parent_changed = $this->Application->GetVar($event->Prefix . '_parent_changed', array());
+
+ if ( isset($parent_changed[$object->GetID()]) ) {
+ $this->refreshHierarchyFields($object);
+ $old_parent_id = $parent_changed[$object->GetID()];
+ }
+
$parent_path = $object->GetDBField('ParentPath');
}
if ( $parent_path ) {
- $cache_updater = $this->Application->makeClass('kPermCacheUpdater', Array (null, $parent_path));
- /* @var $cache_updater kPermCacheUpdater */
+ $this->quickCategoryCacheRebuild($parent_path, $old_parent_id);
- $cache_updater->OneStepRun();
+ if ( strlen($old_parent_path) && $old_parent_path != $parent_path ) {
+ $this->quickCategoryCacheRebuild($this->removeLastFromPath($old_parent_path), null);
+ }
}
}
@@ -804,7 +814,18 @@
}
}
- // remember category filename change between temp and live records
+ // Change in these fields require full category cache rebuilding.
+ foreach ( array('Filename', 'Template') as $cached_field ) {
+ if ( $live_object->GetDBField($cached_field) != $temp_object->GetDBField($cached_field) ) {
+ $this->Application->StoreVar(
+ 'CategoryPermissionRebuildModeOverride',
+ CategoryPermissionRebuild::AUTOMATIC
+ );
+ break;
+ }
+ }
+
+ // Remember category filename change between temp and live records.
if ( $temp_object->GetDBField('Filename') != $live_object->GetDBField('Filename') ) {
$filename_changes = $this->Application->GetVar($event->Prefix . '_filename_changes', Array ());
@@ -815,6 +836,13 @@
$this->Application->SetVar($event->Prefix . '_filename_changes', $filename_changes);
}
+
+ // Remember category parent change between temp and live records.
+ if ( $temp_object->GetDBField('ParentId') != $live_object->GetDBField('ParentId') ) {
+ $parent_changed = $this->Application->GetVar($event->Prefix . '_parent_changed', array());
+ $parent_changed[$live_object->GetID()] = $live_object->GetDBField('ParentId');
+ $this->Application->SetVar($event->Prefix . '_parent_changed', $parent_changed);
+ }
}
/**
@@ -989,6 +1017,8 @@
$temp_handler->DeleteItems('system-event-subscription', '', $ids);
}
+
+ $this->quickCategoryCacheRebuild($this->removeLastFromPath($object->GetDBField('ParentPath')), null);
}
/**
@@ -1284,6 +1314,7 @@
{
$this->Application->StoreVar('PermCache_UpdateRequired', 1);
$this->Application->StoreVar('RefreshStructureTree', 1);
+ $this->_resetMenuCache();
}
/**
@@ -1487,11 +1518,6 @@
$object = $event->getObject();
/* @var $object kDBItem */
- $cache_updater = $this->Application->makeClass('kPermCacheUpdater', Array (null, $object->GetDBField('ParentPath')));
- /* @var $cache_updater kPermCacheUpdater */
-
- $cache_updater->OneStepRun();
-
$is_active = ($object->GetDBField('Status') == STATUS_ACTIVE);
$next_template = $is_active ? 'suggest_confirm_template' : 'suggest_pending_confirm_template';
@@ -2335,13 +2361,93 @@
{
parent::OnAfterItemCreate($event);
+ /** @var CategoriesItem $object */
$object = $event->getObject();
- /* @var $object CategoriesItem */
- // need to update path after category is created, so category is included in that path
- $fields_hash = $object->buildParentBasedFields();
- $this->Conn->doUpdate($fields_hash, $object->TableName, $object->IDField . ' = ' . $object->GetID());
- $object->SetDBFieldsFromHash($fields_hash);
+ // The hierarchy fields would be updated in "OnAfterCopyToLive" event.
+ if ( $object->IsTempTable() ) {
+ return;
+ }
+
+ $this->refreshHierarchyFields($object, true);
+ $this->quickCategoryCacheRebuild($object->GetDBField('ParentPath'), 0);
+ }
+
+ /**
+ * Occurs after updating item
+ *
+ * @param kEvent $event Event.
+ *
+ * @return void
+ */
+ protected function OnAfterItemUpdate(kEvent $event)
+ {
+ parent::OnAfterItemUpdate($event);
+
+ /** @var CategoriesItem $object */
+ $object = $event->getObject();
+
+ // The hierarchy fields would be updated in "OnAfterCopyToLive" event.
+ if ( $object->IsTempTable() || $object->GetDBField('ParentId') == $object->GetOriginalField('ParentId') ) {
+ return;
+ }
+
+ $this->refreshHierarchyFields($object);
+
+ $this->quickCategoryCacheRebuild($object->GetDBField('ParentPath'), $object->GetOriginalField('ParentId'));
+ $this->quickCategoryCacheRebuild($this->removeLastFromPath($object->GetOriginalField('ParentPath')), null);
+ }
+
+ /**
+ * Refreshes category hierarchy fields.
+ *
+ * @param CategoriesItem $category Category.
+ * @param boolean $including_tree_indexes Also calculate values for tree indexes.
+ *
+ * @return void
+ */
+ protected function refreshHierarchyFields(CategoriesItem $category, $including_tree_indexes = false)
+ {
+ $fields_hash = $category->buildParentBasedFields($including_tree_indexes);
+ $this->Conn->doUpdate(
+ $fields_hash,
+ $category->TableName,
+ $category->IDField . ' = ' . $category->GetID()
+ );
+ $category->SetDBFieldsFromHash($fields_hash);
+ }
+
+ /**
+ * Quickly rebuilds category cache for given path only.
+ *
+ * @param string $strict_path Strict path limitation.
+ * @param integer $strict_path_old_parent_id Previous parent of strict category.
+ *
+ * @return void
+ */
+ protected function quickCategoryCacheRebuild($strict_path, $strict_path_old_parent_id)
+ {
+ /** @var kPermCacheUpdater $cache_updater */
+ $cache_updater = $this->Application->makeClass(
+ 'kPermCacheUpdater',
+ array(null, $strict_path, $strict_path_old_parent_id)
+ );
+ $cache_updater->OneStepRun();
+ }
+
+ /**
+ * Removes last category from path.
+ *
+ * @param string $parent_path Parent path.
+ *
+ * @return string
+ */
+ protected function removeLastFromPath($parent_path)
+ {
+ $parent_path = explode('|', trim($parent_path, '|'));
+ array_pop($parent_path);
+
+ return '|' . implode('|', $parent_path) . '|';
}
/**
@@ -2379,7 +2485,10 @@
}
}
- if ( $this->Application->ConfigValue('CategoryPermissionRebuildMode') == CategoryPermissionRebuild::SILENT ) {
+ /** @var CategoryHelper $category_helper */
+ $category_helper = $this->Application->recallObject('CategoryHelper');
+
+ if ( $category_helper->getCategoryPermissionRebuildMode() == CategoryPermissionRebuild::SILENT ) {
$updater = $this->Application->makeClass('kPermCacheUpdater');
/* @var $updater kPermCacheUpdater */
Index: core/units/categories/categories_item.php
===================================================================
--- core/units/categories/categories_item.php
+++ core/units/categories/categories_item.php
@@ -16,13 +16,15 @@
class CategoriesItem extends kDBItem
{
+
/**
* Builds parent path for this category
*
- * @return Array
- * @access public
+ * @param boolean $including_tree_indexes Also calculate values for tree indexes.
+ *
+ * @return array
*/
- public function buildParentBasedFields()
+ public function buildParentBasedFields($including_tree_indexes = false)
{
static $parent_cache = Array (
0 => Array ('ParentPath' => '|', 'NamedParentPath' => '', 'CachedTemplate' => ''),
@@ -60,6 +62,12 @@
'CachedTemplateHash' => kUtil::crc32(mb_strtolower($cached_template)),
);
+ if ( $including_tree_indexes ) {
+ $tree_indexes = $this->Application->getTreeIndex($parent_id);
+ $ret['TreeLeft'] = $tree_indexes['TreeLeft'] + 1;
+ $ret['TreeRight'] = $tree_indexes['TreeLeft'] + 2;
+ }
+
$primary_language = $this->Application->GetDefaultLanguageId();
foreach ($languages as $language_id) {
@@ -286,4 +294,4 @@
} while ($res !== false);
$this->SetDBField($title_field, $new_name);
}
- }
\ No newline at end of file
+ }
Index: core/units/categories/categories_tag_processor.php
===================================================================
--- core/units/categories/categories_tag_processor.php
+++ core/units/categories/categories_tag_processor.php
@@ -512,10 +512,13 @@
$total_cats = (int)$this->Conn->GetOne('SELECT COUNT(*) FROM ' . TABLE_PREFIX . 'Categories');
if ( $continue === false ) {
- $rebuild_mode = $this->Application->ConfigValue('CategoryPermissionRebuildMode');
+ /** @var CategoryHelper $category_helper */
+ $category_helper = $this->Application->recallObject('CategoryHelper');
- if ( $rebuild_mode == CategoryPermissionRebuild::AUTOMATIC && $total_cats > CACHE_PERM_CHUNK_SIZE ) {
- // first step, if category count > CACHE_PERM_CHUNK_SIZE, then ask for cache update
+ if ( $category_helper->getCategoryPermissionRebuildMode() == CategoryPermissionRebuild::AUTOMATIC
+ && $total_cats > CACHE_PERM_CHUNK_SIZE
+ ) {
+ // First step, if category count > CACHE_PERM_CHUNK_SIZE, then ask for cache update.
return true;
}
Index: core/units/helpers/category_helper.php
===================================================================
--- core/units/helpers/category_helper.php
+++ core/units/helpers/category_helper.php
@@ -358,4 +358,21 @@
return $text;
}
+
+ /**
+ * Tells how category cache needs to be rebuilt.
+ *
+ * @return integer
+ */
+ public function getCategoryPermissionRebuildMode()
+ {
+ $rebuild_mode = $this->Application->RecallVar('CategoryPermissionRebuildModeOverride');
+
+ if ( $rebuild_mode !== false ) {
+ return $rebuild_mode;
+ }
+
+ return $this->Application->ConfigValue('CategoryPermissionRebuildMode');
+ }
+
}
Index: core/units/helpers/recursive_helper.php
===================================================================
--- core/units/helpers/recursive_helper.php
+++ core/units/helpers/recursive_helper.php
@@ -98,11 +98,18 @@
$child_categories = array_intersect($dest_parent_path, $category_ids); // get categories, then can't be moved
$category_ids = array_diff($category_ids, $child_categories); // remove them from movable categories list
- if ($category_ids) {
- $sql = 'UPDATE '.$table_name.'
- SET ParentId = '.$dest_category_id.'
- WHERE '.$id_field.' IN ('.implode(',', $category_ids).')';
- $this->Conn->Query($sql);
+ if ( $category_ids ) {
+ /** @var CategoriesItem $move_category */
+ $move_category = $this->Application->recallObject('c.move', null, array('skip_autoload' => true));
+
+ foreach ( $category_ids as $move_category_id ) {
+ $move_category->Load($move_category_id);
+
+ if ( $move_category->GetDBField('ParentId') != $dest_category_id ) {
+ $move_category->SetDBField('ParentId', $dest_category_id);
+ $move_category->Update();
+ }
+ }
}
}
@@ -224,4 +231,4 @@
return $cache[$category_id];
}
- }
\ No newline at end of file
+ }

Event Timeline