public static function add($pid, $type, $name, $title, $show = 1, $ord = 0) { $treeTable = new K_Tree_Model(); if (preg_match('/[^a-z0-9-]/i', $name)) { die('node name not match' . $name); } // Получаем родительский элемент $result = self::getNode($pid); $pid = $result['tree_id']; if (count($result) == 0) { die('no such parent node'); } list($lKey, $rKey, $level, $url) = array($result['tree_lkey'], $result['tree_rkey'], $result['tree_level'], $result['tree_link']); // Проверяем, есть ли элемент с таким же именем $cnt = $treeTable->count(K_Db_Select::create()->where('`tree_pid` = ' . (int) $pid . ' AND `tree_name` = ' . K_Db_Quote::quoteKey($name))); // Если есть, варьируем число в конце if ($cnt > 0) { $result = $treeTable->select()->where('`tree_pid`=' . (int) $pid)->fetchArray(); $eNames = array(); while (list($k, $f) = each($result)) { $eNames[] = $f['tree_name']; } if (preg_match('@(\\d+)$@', $name, $subp)) { // Имя заканчивается числом $newNum = intval($subp[1]); $newPart = substr($name, 0, strlen($name) - strlen($newNum)); } else { // Имя не заканчивается числом, берем его целиком за основу $newNum = 1; $newPart = $name; } while (in_array($newPart . $newNum, $eNames)) { $newNum++; } $name = $newPart . $newNum; } // Формируем ссылку для вставляемого элемента $url = $url[0] == '.' ? ($url[1] != '1' ? $url : '') . '/' . $name . '/' : $url . $name . '/'; // Подготовка к сдвигу if ($ord == 0) { // По умолчанию вставляем в конец родительского элемента $result = $treeTable->select('MAX(`tree_rkey`) as `mkey`')->where('`tree_pid`=' . (int) $pid)->fetchArray(); $mKey = $result[0]['mkey']; } else { // Вставляем в определенную позицию $result = $treeTable->select('`tree_lkey`-1 as `tree_lkey`')->where('`tree_pid`=' . (int) $pid)->order('`tree_lkey`')->fetchAssoc('tree_name'); $childs = array(); while (list($k, $f) = each($r)) { $childs[] = $f['tree_lkey']; } if ($ord > count($childs)) { $mKey = $rKey - 1; } else { $mKey = $childs[$ord - 1]; } } if ($mKey == 0) { $newLeft = $rKey; $newRight = $rKey + 1; // Это первый элемент } else { $newLeft = $mKey + 1; $newRight = $mKey + 2; // Нормальная вставка } $treeTable->update(array('tree_rkey' => new K_Db_Expr('IF(`tree_rkey` >= ' . $newLeft . ', `tree_rkey` + 2, `tree_rkey`)'), 'tree_lkey' => new K_Db_Expr('IF(`tree_lkey` >= ' . $newLeft . ', `tree_lkey` + 2, `tree_lkey`) ')), '`tree_rkey` >= ' . $newLeft); $time = time(); $insertIntoTreeData = array('tree_lkey' => $newLeft, 'tree_rkey' => $newRight, 'tree_level' => $level + 1, 'tree_pid' => $pid, 'tree_type' => $type, 'tree_name' => $name, 'tree_link' => $url, 'tree_title' => $title, 'tree_added' => $time, 'tree_modified' => $time); $insertId = $treeTable->save($insertIntoTreeData); $typeModelName = 'Type_Model_' . ucfirst($type); $typeTable = new $typeModelName(); $typeTable->save(array('type_' . $type . '_id' => $insertId)); // Возвращает ID созданного элемента. return $insertId; }