<?php
/**
* @property \modelBackendContent $model_backend_content
*/
class actionAdminContentCatsOrder extends cmsAction {
private $total_nodes = 0;
public function run($ctype_id) {
$ctype = $this->model_backend_content->getContentType($ctype_id);
if (!$ctype) {
return cmsCore::error404();
}
$categories = $this->model_backend_content->getCategoriesTree($ctype['name'], false);
$this->model_backend_content->localizedRestore();
if ($this->request->has('submit')) {
$csrf_token = $this->request->get('csrf_token', '');
if (!cmsForm::validateCSRFToken($csrf_token)) {
cmsUser::addSessionMessage(LANG_FORM_ERRORS, 'error');
return $this->redirectToAction('content');
}
$hash = $this->request->get('hash', '');
cmsUser::setCookiePublic('content_tree_path', "{$ctype_id}.1");
if (!$this->reorderCategoriesTree($ctype, $categories, $hash)) {
cmsUser::addSessionMessage(LANG_FORM_ERRORS, 'error');
} else {
cmsUser::addSessionMessage(LANG_CP_ORDER_SUCCESS, 'success');
}
return $this->redirectToAction('content');
}
return $this->cms_template->render('content_cats_order', [
'ctype' => $ctype,
'categories' => $categories
]);
}
private function reorderCategoriesTree($ctype, $categories, $hash) {
$hash = json_decode($hash, true);
if (!$hash) {
return false;
}
$this->total_nodes = 0;
$tree = $this->prepareTree($hash);
$tree = $this->buildNestedSet($tree);
return $this->model_backend_content->updateCategoryTree(
$ctype['name'],
$tree,
$this->total_nodes,
!empty($ctype['options']['is_cats_first_level_slug'])
);
}
private function countChilds($tree, $count) {
foreach ($tree as $idx => $node) {
if (!empty($node['children'])) {
$my_count = count($node['children']);
$count = $my_count + $this->countChilds($node['children'], $count);
}
}
return $count;
}
private function prepareTree($tree, $parent_key = 1) {
foreach ($tree as $idx => $node) {
unset($node['expand']);
unset($node['activate']);
unset($node['isFolder']);
$node['parent_key'] = $parent_key;
if (!empty($node['children']) && is_array($node['children'])) {
$count = count($node['children']);
$node['children'] = $this->prepareTree($node['children'], $node['key']);
$node['children_count'] = $this->countChilds($node['children'], $count);
} else {
$node['children_count'] = 0;
}
$tree[$idx] = $node;
$this->total_nodes++;
}
return $tree;
}
private function buildNestedSet($tree, $left = 1, $level = 1) {
foreach ($tree as $idx => $node) {
$left++;
$node['left'] = $left;
$node['level'] = $level;
if (!empty($node['children'])) {
$node['right'] = $left + ($node['children_count'] * 2) + 1;
$child_level = $level + 1;
$node['children'] = $this->buildNestedSet($node['children'], $left, $child_level);
} else {
$node['right'] = $node['left'] + 1;
}
$left = $node['right'];
$tree[$idx] = $node;
}
return $tree;
}
}