/** * Функция проверки дерева на валидность * @param boolean с отчетом или без отчета * @return boolean прошло валидацию или нет, если отчет включен - развернутый ответ */ function validate($debug = true) { $i = 0; $aResult = array(0 => '', 1 => '', 2 => '', 3 => '', 4 => '', 5 => ''); do { switch ($i) { case 0: #Левый ключ ВСЕГДА меньше правого $aRes = $this->db->select_one_column('SELECT id FROM ' . $this->treeTable . ' WHERE numleft >= numright'); if (count($aRes) > 0) { if (!$debug) { return false; } $aResult[0] = 'id: ' . implode(', ', $aRes); } break; case 1: #Наибольший правый ключ ВСЕГДА равен двойному числу узлов; #Наименьший левый ключ ВСЕГДА равен 1 $aRes = $this->db->one_array('SELECT COUNT(id) as n, MIN(numleft) as min_left,MIN(id) as root_id, MAX(numright) as max_right FROM ' . $this->treeTable); if ($aRes['min_left'] != 1) { if (!$debug) { return false; } $aResult[1] = 'Наименьший левый ключ ' . $aRes['min_left'] . ' != 1<br />(id: ' . $aRes['root_id'] . ')'; } if ($aRes['max_right'] != 2 * $aRes['n']) { if (!$debug) { return false; } $aResult[2] = 'Наибольший правый ключ :' . $aRes['max_right'] . ' != ' . 2 * $aRes['n'] . ' <br />(id: ' . $aRes['root_id'] . ')'; } break; case 2: #Разница между правым и левым ключом ВСЕГДА нечетное число; $aRes = $this->db->select_one_column('SELECT mm.id FROM ' . $this->treeTable . ' as mm, (SELECT ' . $this->treeTable . '.id, MOD((numright - numleft) , 2) AS ostatok FROM ' . $this->treeTable . ') as m WHERE mm.id = m.id AND m.ostatok=0'); if ($aRes) { if (!$debug) { return false; } $aResult[3] = 'id: ' . implode(', ', $aRes); } break; case 3: #Если уровень узла нечетное число то тогда левый ключ ВСЕГДА четное число, то же $aRes = $this->db->select_one_column(' SELECT mm.id FROM ' . $this->treeTable . ' as mm, (SELECT ' . $this->treeTable . '.id, MOD( (' . $this->treeTable . '.numleft - ' . $this->treeTable . '.numlevel + 1) , 2) AS ostatok FROM ' . $this->treeTable . ')as m WHERE mm.id=m.id AND m.ostatok = 1'); if ($aRes) { if (!$debug) { return false; } $aResult[4] = 'id: ' . implode(', ', $aRes); } break; case 4: #Ключи ВСЕГДА уникальны, вне зависимости от того правый он или левый; + $aRes = $this->db->one_array('SELECT t1.id, COUNT(t1.id) AS rep, MAX(t3.numright) AS max_right FROM ' . $this->treeTable . ' AS t1, ' . $this->treeTable . ' AS t2, ' . $this->treeTable . ' AS t3 WHERE t1.numleft <> t2.numleft AND t1.numleft <> t2.numright AND t1.numright <> t2.numleft AND t1.numright <> t2.numright GROUP BY t1.id HAVING max_right <> SQRT(4 * rep + 1) + 1'); if ($aRes) { if (!$debug) { return false; } foreach ($aRes as $v) { $aResult[5] .= '[id:' . $v['id'] . ' max_right: ' . $v['max_right'] . ']<br/>'; } } break; } $i++; } while ($i < count($aResult) - 1); if ($debug) { return tpl::fetchPHP($aResult, PATH_CORE . 'database' . DIRECTORY_SEPARATOR . 'nestedsets' . DIRECTORY_SEPARATOR . 'validation.php'); } return true; }