예제 #1
0
 /**
  * Функция проверки дерева на валидность
  * @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;
 }