for finding and solving bugs into the MoveNode () method. Modified by Vladimir Obukhov for InstantCMS project. Members $TableName => Table name that contains nasted sets $FieldID => Field name for table ID $FieldIDParent => Field name for table IDParent $FieldLeft => Field name for table nasted set left field $FieldRight => Field name for table nasted set right field $FieldDiffer => Field name used to manage more than one type of nasted set in the same table $FieldLevel => Field name for table nasted set level field (0 = root node) $FieldOrder => Field name for table nasted set order field $FieldIgnore => Field name for tablr nested set ignore field $TransactionTable => Name for table used to manage transactions $MyLink => MySQL database link resource Methods SelectSubNodes () => Returns all the sub node of IDNode fo Level number of level. SelectPath () => Returns the path from the IDNode to the root node. MoveNode () => Method used to move the node IDNode to IDParent. AddRootNode () => Method used to add the root node for a nested set AddNode () => Method used to add a node to IDParent. Return the new IDNode. DeleteNode () => Method used to delete the node identified by IDNode and all his children. ClearNodes () => Method used to clear the nasted set table BeginTransaction () => Method that start the transaction. Returns true or false. EndTransaction () => Method that stop the transaction. IsInTransaction () => Method to check the transaction state. Returns true or false. */ class CCelkoNastedSet { public $TableName; private $FieldID; private $FieldIDParent; private $FieldLeft; private $FieldRight; private $FieldDiffer; private $FieldLevel; private $FieldOrder; private $FieldIgnore; public $TransactionTable; private $_IsInTransaction; private $_TransactionTStamp; public $MyLink; public function __construct () { $this->TableName = "tblCelkoTree"; $this->FieldID = "id"; $this->FieldIDParent = "parent_id"; $this->FieldLeft = "NSLeft"; $this->FieldRight = "NSRight"; $this->FieldDiffer = "NSDiffer"; $this->FieldLevel = "NSLevel"; $this->FieldOrder = "ordering"; $this->FieldIgnore = "NSIgnore"; $this->TransactionTable = "cms_ns_transactions"; $this->_IsInTransaction = false; $this->_TransactionTStamp = 0; $this->MyLink = null; } // Begin private functions // private function _safe_set (&$var_true, $var_false = "") { if (!isset ($var_true)) { $var_true = $var_false; } } private function _safe_query ($query, $link) { if (empty($query)) { return false; } $inDB = cmsDatabase::getInstance(); $result = $inDB->query($query) or die("Nested sets error: $query"); return $result; } // End private functions // // Begin transaction functions // private function InitializeTransaction ($Differ = "") { $sql_verify = "SELECT * FROM " . $this->TransactionTable . " WHERE TableName = '" . $this->TableName . "' " . " AND Differ = '" . $Differ . "'"; $rs_verify = $this->_safe_query ($sql_verify, $this->MyLink); if (($rs_verify) && (mysql_num_rows ($rs_verify) == 0)) { mysql_free_result ($rs_verify); $sql_insert = "INSERT INTO " . $this->TransactionTable . " (TableName, Differ, InTransaction) " . " VALUES ('" . $this->TableName . "', '" . $Differ . "', 0)"; $this->_safe_query ($sql_insert, $this->MyLink); return true; } else { return false; } } private function BeginTransaction ($Differ = "") { //r2: здесь нужно будет разбираться с транзакциями $this->_IsInTransaction = true; return true; $this->InitializeTransaction($Differ); $TStamp = date ("YmdHis"); $sql_update = "UPDATE " . $this->TransactionTable . " SET TStamp = " . $TStamp . ", " . " InTransaction = 1 " . " WHERE InTransaction = 0 " . " AND TableName = '" . $this->TableName . "' " . " AND Differ = '" . $Differ . "'"; $this->_safe_query ($sql_update, $this->MyLink); $sql_verify = "SELECT * FROM " . $this->TransactionTable . " WHERE TableName = '" . $this->TableName . "' " . " AND InTransaction = 1 " . " AND TStamp = " . $TStamp . " AND Differ = '" . $Differ . "'"; $rs_verify = $this->_safe_query ($sql_verify, $this->MyLink); if (($rs_verify) && (mysql_num_rows ($rs_verify) == 1)) { mysql_free_result ($rs_verify); $this->_IsInTransaction = true; $this->_TransactionTStamp = $TStamp; return true; } else { $this->_IsInTransaction = false; $this->_TransactionTStamp = 0; return false; } } public function EndTransaction ($Differ = "") { $sql_update = "UPDATE " . $this->TransactionTable . " SET InTransaction = 0 " . " WHERE TableName = '" . $this->TableName . "' " . " AND TStamp = " . $this->_TransactionTStamp . " AND Differ = '" . $Differ . "'"; $this->_safe_query ($sql_update, $this->MyLink); $this->_IsInTransaction = false; } public function IsInTransaction () { return $this->_IsInTransaction; } // End transaction functions // // Begin nasted set functions // public function ClearNodes ($Differ = "") { $this->BeginTransaction($Differ); $sql_delete = "DELETE FROM " . $this->TableName . " WHERE " . $this->FieldDiffer . " = '" . $Differ . "'"; $this->_safe_query ($sql_delete, $this->MyLink); $this->EndTransaction($Differ); } public function DeleteNode ($IDNode = -1, $Differ = "") { $this->BeginTransaction($Differ); if (!$this->_IsInTransaction) { return false; } $sql_select = "SELECT * FROM " . $this->TableName . " WHERE " . $this->FieldID . " = " . $IDNode . " AND " . $this->FieldDiffer . " = '" . $Differ . "'"; $rs_select = $this->_safe_query ($sql_select, $this->MyLink); if (($rs_select) && ($row_select = mysql_fetch_assoc ($rs_select))) { $this->_safe_set ($row_select[$this->FieldID], -1); $this->_safe_set ($row_select[$this->FieldLeft], -1); $this->_safe_set ($row_select[$this->FieldRight], -1); $delete_offset = $row_select[$this->FieldRight] - $row_select[$this->FieldLeft]; // Delete sub nodes $sql_delete = "DELETE FROM " . $this->TableName . " WHERE " . $this->FieldLeft . " >= " . $row_select[$this->FieldLeft] . " AND " . $this->FieldLeft . " <= " . $row_select[$this->FieldRight] . " AND " . $this->FieldDiffer . " = '" . $Differ . "'"; $this->_safe_query ($sql_delete, $this->MyLink); // Update FieldLeft $sql_update = "UPDATE " . $this->TableName . " SET " . $this->FieldLeft . " = " . $this->FieldLeft . " - " . ($delete_offset + 1) . " WHERE " . $this->FieldLeft . " > " . $row_select[$this->FieldRight] . " AND " . $this->FieldDiffer . " = '" . $Differ . "'"; $this->_safe_query ($sql_update, $this->MyLink); // Update FieldRight $sql_update = "UPDATE " . $this->TableName . " SET " . $this->FieldRight . " = " . $this->FieldRight . " - " . ($delete_offset + 1) . " WHERE " . $this->FieldRight . " > " . $row_select[$this->FieldRight] . " AND " . $this->FieldDiffer . " = '" . $Differ . "'"; $this->_safe_query ($sql_update, $this->MyLink); mysql_free_result ($rs_select); $this->EndTransaction($Differ); return true; } else { $this->EndTransaction($Differ); return false; } } public function AddRootNode ($Differ = "") { $this->BeginTransaction($Differ); if (!$this->_IsInTransaction) { return false; } $sql_insert = "INSERT INTO " . $this->TableName . " (" . $this->FieldIDParent . ", " . $this->FieldLeft . ", " . $this->FieldRight . ", " . $this->FieldLevel . ", " . $this->FieldOrder . ", " . $this->FieldDiffer . ") " . " VALUES (0, 1, 2, 0, 1, '" . $Differ . "')"; $this->_safe_query ($sql_insert, $this->MyLink); $new_id = mysql_insert_id ($this->MyLink); $this->EndTransaction($Differ); return $new_id; } public function AddNode ($IDParent = -1, $Order = -1, $Differ = "") { $this->BeginTransaction($Differ); if (!$this->_IsInTransaction) { return false; } $sql_select = "SELECT * FROM " . $this->TableName . " WHERE " . $this->FieldID . " = " . $IDParent . " AND " . $this->FieldDiffer . " = '" . $Differ . "'"; $rs_select = $this->_safe_query ($sql_select, $this->MyLink); if (($rs_select) && ($row_select = mysql_fetch_assoc ($rs_select))) { $this->_safe_set ($row_select[$this->FieldID], -1); $this->_safe_set ($row_select[$this->FieldLeft], -1); $this->_safe_set ($row_select[$this->FieldRight], -1); $this->_safe_set ($row_select[$this->FieldLevel], -1); $left = $row_select[$this->FieldLeft] + 1; // Update Order (set order = order +1 where order>$Order) if ($Order == -1) { $sql_order = "SELECT * FROM " . $this->TableName . " WHERE " . $this->FieldIDParent . " = " . $IDParent . " AND " . $this->FieldDiffer . " = '" . $Differ . "'" . " ORDER BY " . $this->FieldOrder . " DESC " . " LIMIT 0,1"; $rs_order = $this->_safe_query ($sql_order, $this->MyLink); if (($rs_order) && ($row_order = mysql_fetch_assoc ($rs_order))) { $this->_safe_set ($row_order[$this->FieldOrder], 0); $Order = $row_order[$this->FieldOrder] + 1; mysql_free_result ($rs_order); } else { $Order = 1; } } $sql_update = "UPDATE " . $this->TableName . " SET " . $this->FieldOrder . " = " . $this->FieldOrder . " + 1" . " WHERE " . $this->FieldIDParent . " = " . $IDParent . " AND " . $this->FieldOrder . " >= " . $Order . " AND " . $this->FieldDiffer . " = '" . $Differ . "'"; $this->_safe_query ($sql_update, $this->MyLink); $sql_order = "SELECT * FROM " . $this->TableName . " WHERE " . $this->FieldIDParent . " = " . $IDParent . " AND " . $this->FieldOrder . " <= " . $Order . " AND " . $this->FieldDiffer . " = '" . $Differ . "'" . " ORDER BY " . $this->FieldOrder . " DESC " . " LIMIT 0,1"; $rs_order = $this->_safe_query ($sql_order, $this->MyLink); if (($rs_order) && ($row_order = mysql_fetch_assoc ($rs_order))) { $this->_safe_set ($row_order[$this->FieldRight], -1); $left = $row_order[$this->FieldRight] + 1; mysql_free_result ($rs_order); } $right = $left + 1; // Update FieldLeft $sql_update = "UPDATE " . $this->TableName . " SET " . $this->FieldLeft . " = " . $this->FieldLeft . " + 2" . " WHERE " . $this->FieldLeft . " >= " . $left . " AND " . $this->FieldDiffer . " = '" . $Differ . "'"; $this->_safe_query ($sql_update, $this->MyLink); // Update FieldRight $sql_update = "UPDATE " . $this->TableName . " SET " . $this->FieldRight . " = " . $this->FieldRight . " + 2" . " WHERE " . $this->FieldRight . " >= " . $left . " AND " . $this->FieldDiffer . " = '" . $Differ . "'"; $this->_safe_query ($sql_update, $this->MyLink); // Insert $sql_insert = "INSERT INTO " . $this->TableName . " (" . $this->FieldIDParent . ", " . $this->FieldLeft . ", " . $this->FieldRight . ", " . $this->FieldLevel . ", " . $this->FieldOrder . ", " . $this->FieldDiffer . ") " . " VALUES (" . $IDParent . ", " . $left . ", " . $right . ", " . ($row_select[$this->FieldLevel] + 1) . ", " . $Order . ", '" . $Differ . "')"; $this->_safe_query ($sql_insert, $this->MyLink); mysql_free_result ($rs_select); $new_id = mysql_insert_id ($this->MyLink); $this->EndTransaction($Differ); return $new_id; } else { return false; } } public function MoveOrdering($IDNode, $dir = 1){ $this->BeginTransaction(); if (!$this->_IsInTransaction) { return false; } $sql = "SELECT * FROM {$this->TableName} WHERE {$this->FieldID}='{$IDNode}'"; $res = $this->_safe_query ($sql, $this->MyLink); $move_row = mysql_fetch_assoc($res); mysql_free_result($res); if ($move_row[$this->FieldDiffer]) $Differ = 'AND ' . $this->FieldDiffer . ' = ' . $move_row[$this->FieldDiffer]; else $Differ = ''; // максимальное значение сортировки $sql = "SELECT MAX({$this->FieldOrder}) FROM {$this->TableName} WHERE {$this->FieldIDParent}={$move_row[$this->FieldIDParent]}"; $res = $this->_safe_query ($sql, $this->MyLink); list($maxordering) = mysql_fetch_row($res); if (!$maxordering) $maxordering = 1; // минимальное значение сортировки $sql_min = "SELECT MIN({$this->FieldOrder}) FROM {$this->TableName} WHERE {$this->FieldIDParent}={$move_row[$this->FieldIDParent]}"; $res_min = $this->_safe_query ($sql_min, $this->MyLink); list($minordering) = mysql_fetch_row($res_min); if (!$minordering) $minordering = 1; mysql_free_result($res); if ($dir == -1 && $move_row[$this->FieldOrder] == $minordering) return; if ($dir == 1 && $move_row[$this->FieldOrder] == $maxordering) return; if ($dir == -1){ $sql = "UPDATE {$this->TableName} SET {$this->FieldIgnore} = 1 WHERE {$this->FieldLeft} >= {$move_row[$this->FieldLeft]} AND {$this->FieldRight} <= {$move_row[$this->FieldRight]} {$Differ}"; $this->_safe_query ($sql, $this->MyLink); $count = mysql_affected_rows($this->MyLink) * 2; $sql = "SELECT * FROM {$this->TableName} WHERE {$this->FieldIDParent} = {$move_row[$this->FieldIDParent]} AND {$this->FieldOrder} = ".($move_row[$this->FieldOrder]-1); $res = $this->_safe_query ($sql, $this->MyLink); $near = mysql_fetch_assoc($res); mysql_free_result($res); $sql = "UPDATE {$this->TableName} SET {$this->FieldLeft} = {$this->FieldLeft} + {$count}, {$this->FieldRight} = {$this->FieldRight} + {$count} WHERE {$this->FieldLeft} >= {$near[$this->FieldLeft]} AND {$this->FieldRight} <= {$near[$this->FieldRight]} {$Differ}"; $this->_safe_query ($sql, $this->MyLink); $count2 = mysql_affected_rows($this->MyLink) * 2; $sql = "UPDATE {$this->TableName} SET {$this->FieldLeft} = {$this->FieldLeft} - {$count2}, {$this->FieldRight} = {$this->FieldRight} - {$count2}, {$this->FieldIgnore} = 0 WHERE {$this->FieldIgnore} = 1 {$Differ}"; $this->_safe_query ($sql, $this->MyLink); $sql = "UPDATE {$this->TableName} SET {$this->FieldOrder} = {$this->FieldOrder} - 1 WHERE {$this->FieldID} = {$IDNode}"; $this->_safe_query ($sql, $this->MyLink); $sql = "UPDATE {$this->TableName} SET {$this->FieldOrder} = {$this->FieldOrder} + 1 WHERE {$this->FieldID} = {$near[$this->FieldID]}"; $this->_safe_query ($sql, $this->MyLink); } if ($dir == 1){ $sql = "UPDATE {$this->TableName} SET {$this->FieldIgnore} = 1 WHERE {$this->FieldLeft} >= {$move_row[$this->FieldLeft]} AND {$this->FieldRight} <= {$move_row[$this->FieldRight]} {$Differ}"; $this->_safe_query ($sql, $this->MyLink); $count = mysql_affected_rows($this->MyLink) * 2; $sql = "SELECT * FROM {$this->TableName} WHERE {$this->FieldIDParent} = {$move_row[$this->FieldIDParent]} AND {$this->FieldOrder} = ".($move_row[$this->FieldOrder]+1); $res = $this->_safe_query ($sql, $this->MyLink); $near = mysql_fetch_assoc($res); mysql_free_result($res); $sql = "UPDATE {$this->TableName} SET {$this->FieldLeft} = {$this->FieldLeft} - {$count}, {$this->FieldRight} = {$this->FieldRight} - {$count} WHERE {$this->FieldLeft} >= {$near[$this->FieldLeft]} AND {$this->FieldRight} <= {$near[$this->FieldRight]} {$Differ}"; $this->_safe_query ($sql, $this->MyLink); $count2 = mysql_affected_rows($this->MyLink) * 2; $sql = "UPDATE {$this->TableName} SET {$this->FieldLeft} = {$this->FieldLeft} + {$count2}, {$this->FieldRight} = {$this->FieldRight} + {$count2}, {$this->FieldIgnore} = 0 WHERE {$this->FieldIgnore} = 1 {$Differ}"; $this->_safe_query ($sql, $this->MyLink); $sql = "UPDATE {$this->TableName} SET {$this->FieldOrder} = {$this->FieldOrder} + 1 WHERE {$this->FieldID} = {$IDNode}"; $this->_safe_query ($sql, $this->MyLink); $sql = "UPDATE {$this->TableName} SET {$this->FieldOrder} = {$this->FieldOrder} - 1 WHERE {$this->FieldID} = {$near[$this->FieldID]}"; $this->_safe_query ($sql, $this->MyLink); } $this->EndTransaction($Differ); return true; } public function MoveNode ($IDNode = -1, $IDParent = -1, $Order = -1, $Differ = "") { $this->BeginTransaction($Differ); if (!$this->_IsInTransaction) { return false; } $sql_select = "SELECT * FROM " . $this->TableName . " WHERE " . $this->FieldID . " = " . $IDNode . " AND " . $this->FieldDiffer . " = '" . $Differ . "'"; $rs_select = $this->_safe_query ($sql_select, $this->MyLink); if (($rs_select) && ($row_select = mysql_fetch_assoc ($rs_select))) { $this->_safe_set ($row_select[$this->FieldID], -1); $this->_safe_set ($row_select[$this->FieldLeft], -1); $this->_safe_set ($row_select[$this->FieldRight], -1); $this->_safe_set ($row_select[$this->FieldLevel], -1); $delete_offset = $row_select[$this->FieldRight] - $row_select[$this->FieldLeft]; $sql_select_parent = "SELECT * FROM " . $this->TableName . " WHERE " . $this->FieldID . " = " . $IDParent . " AND " . $this->FieldDiffer . " = '" . $Differ . "'"; $rs_select_parent = $this->_safe_query ($sql_select_parent, $this->MyLink); if (($rs_select_parent) && ($row_select_parent = mysql_fetch_assoc ($rs_select_parent))) { $this->_safe_set ($row_select_parent[$this->FieldID], -1); $this->_safe_set ($row_select_parent[$this->FieldLeft], -1); $this->_safe_set ($row_select_parent[$this->FieldRight], -1); $this->_safe_set ($row_select_parent[$this->FieldLevel], -1); $left = $row_select_parent[$this->FieldLeft] + 1; //Set node tree as ignore $sql_ignore = "UPDATE " . $this->TableName . " SET " . $this->FieldIgnore . " = 1" . " WHERE " . $this->FieldLeft . " >= " . $row_select[$this->FieldLeft] . " AND " . $this->FieldRight . " <= " . $row_select[$this->FieldRight] . " AND " . $this->FieldDiffer . " = '" . $Differ . "'"; $this->_safe_query ($sql_ignore, $this->MyLink); // Update Order (set order = order +1 where order>$Order) if ($Order == -1) { $sql_order = "SELECT * FROM " . $this->TableName . " WHERE " . $this->FieldIDParent . " = " . $IDParent . " AND " . $this->FieldDiffer . " = '" . $Differ . "'" . " ORDER BY " . $this->FieldOrder . " DESC " . " LIMIT 0,1"; $rs_order = $this->_safe_query ($sql_order, $this->MyLink); if (($rs_order) && ($row_order = mysql_fetch_assoc ($rs_order))) { $this->_safe_set ($row_order[$this->FieldOrder], 0); $Order = $row_order[$this->FieldOrder] + 1; mysql_free_result ($rs_order); } else { $Order = 1; } } $sql_update = "UPDATE " . $this->TableName . " SET " . $this->FieldOrder . " = " . $this->FieldOrder . " + 1" . " WHERE " . $this->FieldIDParent . " = " . $IDParent . " AND " . $this->FieldOrder . " >= " . $Order . " AND " . $this->FieldDiffer . " = '" . $Differ . "'"; $this->_safe_query ($sql_update, $this->MyLink); $sql_order = "SELECT * FROM " . $this->TableName . " WHERE " . $this->FieldIDParent . " = " . $IDParent . " AND " . $this->FieldOrder . " <= " . $Order . " AND " . $this->FieldDiffer . " = '" . $Differ . "'" . " ORDER BY " . $this->FieldOrder . " DESC " . " LIMIT 0,1"; $rs_order = $this->_safe_query ($sql_order, $this->MyLink); if (($rs_order) && ($row_order = mysql_fetch_assoc ($rs_order))) { $this->_safe_set ($row_order[$this->FieldRight], -1); $left = $row_order[$this->FieldRight] + 1; mysql_free_result ($rs_order); } $child_offset = $row_select[$this->FieldRight] - $row_select[$this->FieldLeft] + 1; // Update FieldLeft if ($left < $row_select[$this->FieldLeft]) // Move to left { $sql_update = "UPDATE " . $this->TableName . " SET " . $this->FieldLeft . " = " . $this->FieldLeft . " + (" . $child_offset . ")" . " WHERE " . $this->FieldLeft . " >= " . $left . " AND " . $this->FieldLeft . " <= " . $row_select[$this->FieldLeft] . " AND " . $this->FieldIgnore . " = 0" . " AND " . $this->FieldDiffer . " = '" . $Differ . "'"; } else // Move to right { $sql_update = "UPDATE " . $this->TableName . " SET " . $this->FieldLeft . " = " . $this->FieldLeft . " - " . $child_offset . " WHERE " . $this->FieldLeft . " <= " . $left . " AND " . $this->FieldLeft . " >= " . $row_select[$this->FieldLeft] . " AND " . $this->FieldIgnore . " = 0" . " AND " . $this->FieldDiffer . " = '" . $Differ . "'"; } $this->_safe_query ($sql_update, $this->MyLink); // Update FieldRight if ($left < $row_select[$this->FieldLeft]) // Move to left { $sql_update = "UPDATE " . $this->TableName . " SET " . $this->FieldRight . " = " . $this->FieldRight . " + (" . $child_offset . ")" . " WHERE " . $this->FieldRight . " >= " . $left . " AND " . $this->FieldRight . " <= " . $row_select[$this->FieldRight] . " AND " . $this->FieldIgnore . " = 0" . " AND " . $this->FieldDiffer . " = '" . $Differ . "'"; } else // Move to right { $sql_update = "UPDATE " . $this->TableName . " SET " . $this->FieldRight . " = " . $this->FieldRight . " - " . $child_offset . " WHERE " . $this->FieldRight . " < " . $left . " AND " . $this->FieldRight . " >= " . $row_select[$this->FieldRight] . " AND " . $this->FieldIgnore . " = 0" . " AND " . $this->FieldDiffer . " = '" . $Differ . "'"; } $this->_safe_query ($sql_update, $this->MyLink); $level_difference = $row_select_parent[$this->FieldLevel] - $row_select[$this->FieldLevel] + 1; $new_offset = $row_select[$this->FieldLeft] - $left; if ($left > $row_select[$this->FieldLeft]) // i.e. move to right { $new_offset += $child_offset; } //Update new tree left $sql_update = "UPDATE " . $this->TableName . " SET " . $this->FieldLeft . " = " . $this->FieldLeft . " - (" . $new_offset . "), " . $this->FieldRight . " = " . $this->FieldRight . " - (" . $new_offset . ")," . "$this->FieldLevel = $this->FieldLevel + $level_difference" . " WHERE " . $this->FieldLeft . " >= " . $row_select[$this->FieldLeft] . " AND " . $this->FieldRight . " <= " . $row_select[$this->FieldRight] . " AND " . $this->FieldIgnore . " = 1" . " AND " . $this->FieldDiffer . " = '" . $Differ . "'"; $this->_safe_query ($sql_update, $this->MyLink); //Remove ignore statis from node tree $sql_ignore = "UPDATE " . $this->TableName . " SET " . $this->FieldIgnore . " = 0" . " WHERE " . $this->FieldLeft . " >= " . ($row_select[$this->FieldLeft] - $new_offset) . " AND " . $this->FieldRight . " <= " . ($row_select[$this->FieldRight] - $new_offset) . " AND " . $this->FieldIgnore . " = 1" . " AND " . $this->FieldDiffer . " = '" . $Differ . "'"; $this->_safe_query ($sql_ignore, $this->MyLink); //Update insert root field $sql_update = "UPDATE " . $this->TableName . " SET " . $this->FieldIDParent . " = " . $IDParent . ", " . $this->FieldOrder . " = " . $Order . " WHERE " . $this->FieldID . " = " . $IDNode; $this->_safe_query ($sql_update, $this->MyLink); mysql_free_result ($rs_select_parent); $this->EndTransaction($Differ); return true; } else { $this->EndTransaction($Differ); return false; } mysql_free_result ($rs_select); $this->EndTransaction($Differ); return true; } else { $this->EndTransaction($Differ); return false; } } public function SelectPath ($IDNode = -1, $Differ = "") { $sql_select = "SELECT * FROM " . $this->TableName . " WHERE " . $this->FieldID . " = " . $IDNode . " AND " . $this->FieldDiffer . " = '" . $Differ . "'"; $rs_select = $this->_safe_query ($sql_select, $this->MyLink); if (($rs_select) && ($row_select = mysql_fetch_assoc ($rs_select))) { $this->_safe_set ($row_select[$this->FieldID], -1); $this->_safe_set ($row_select[$this->FieldLeft], -1); $this->_safe_set ($row_select[$this->FieldRight], -1); $sql_result = "SELECT * FROM " . $this->TableName . " WHERE " . $this->FieldLeft . " <= " . $row_select[$this->FieldLeft] . " AND " . $this->FieldRight . " >= " . $row_select[$this->FieldRight] . " AND " . $this->FieldDiffer . " = '" . $Differ . "'" . " ORDER BY " . $this->FieldLeft; mysql_free_result ($rs_select); return $this->_safe_query ($sql_result, $this->MyLink); // Remember to free result } else { return false; } } public function SelectSubNodes ($IDNode = -1, $Level = -1, $Differ = "") { $sql_select = "SELECT * FROM " . $this->TableName . " WHERE " . $this->FieldID . " = " . $IDNode . " AND " . $this->FieldDiffer . " = '" . $Differ . "'"; $rs_select = $this->_safe_query ($sql_select, $this->MyLink); if (($rs_select) && ($row_select = mysql_fetch_assoc ($rs_select))) { $this->_safe_set ($row_select[$this->FieldID], -1); $this->_safe_set ($row_select[$this->FieldLeft], -1); $this->_safe_set ($row_select[$this->FieldRight], -1); $this->_safe_set ($row_select[$this->FieldLevel], -1); if ($Level == -1) // All child nodes { $sql_result = "SELECT * FROM " . $this->TableName . " WHERE " . $this->FieldLeft . " > " . $row_select[$this->FieldLeft] . " AND " . $this->FieldRight . " < " . $row_select[$this->FieldRight] . " AND " . $this->FieldDiffer . " = '" . $Differ . "'" . " ORDER BY " . $this->FieldLeft . "," . $this->FieldOrder; } else // Only $Level child nodes { $sql_result = "SELECT * FROM " . $this->TableName . " WHERE " . $this->FieldLeft . " >= " . $row_select[$this->FieldLeft] . " AND " . $this->FieldRight . " <= " . $row_select[$this->FieldRight] . " AND " . $this->FieldLevel . " <= " . ($Level + $row_select[$this->FieldLevel]) . " AND " . $this->FieldDiffer . " = '" . $Differ . "'" . " ORDER BY " . $this->FieldLeft . "," . $this->FieldOrder; } mysql_free_result ($rs_select); return $this->_safe_query ($sql_result, $this->MyLink); // Remember to free result } else { return false; } } public function SelectCountSubNodes ($IDNode = -1, $Level = -1, $Differ = "") { $sql_select = "SELECT * FROM " . $this->TableName . " WHERE " . $this->FieldID . " = " . $IDNode . " AND " . $this->FieldDiffer . " = '" . $Differ . "'"; $rs_select = $this->_safe_query ($sql_select, $this->MyLink); if (($rs_select) && ($row_select = mysql_fetch_assoc ($rs_select))) { $this->_safe_set ($row_select[$this->FieldID], -1); $this->_safe_set ($row_select[$this->FieldLeft], -1); $this->_safe_set ($row_select[$this->FieldRight], -1); $this->_safe_set ($row_select[$this->FieldLevel], -1); if ($Level == -1) // All child nodes { $sql_result = "SELECT count(" . $this->FieldID . ") FROM " . $this->TableName . " WHERE " . $this->FieldLeft . " > " . $row_select[$this->FieldLeft] . " AND " . $this->FieldRight . " < " . $row_select[$this->FieldRight] . " AND " . $this->FieldDiffer . " = '" . $Differ . "'" . " ORDER BY " . $this->FieldLeft . "," . $this->FieldOrder; } else // Only $Level child nodes { $sql_result = "SELECT count(" . $this->FieldID . ") FROM " . $this->TableName . " WHERE " . $this->FieldLeft . " > " . $row_select[$this->FieldLeft] . " AND " . $this->FieldRight . " < " . $row_select[$this->FieldRight] . " AND " . $this->FieldLevel . " <= " . ($Level + $row_select[$this->FieldLevel]) . " AND " . $this->FieldDiffer . " = '" . $Differ . "'" . " ORDER BY " . $this->FieldLeft . "," . $this->FieldOrder; } mysql_free_result ($rs_select); $res = $this->_safe_query ($sql_result, $this->MyLink); // Remember to free result list($count) = mysql_fetch_row($res); mysql_free_result ($res); return $count; } else { return false; } } // End nasted set functions // } ?>