<?php
// +----------------------------------------------------------------------+
// | CB_NestedSet |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The C*B Development Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 1.0 of the CB license, |
// | that is bundled with this package in the file license.txt |
// | If you did not receive a copy of the CB license please send a |
// | note to hide@address.com so we can mail you |
// | a copy immediately. |
// +----------------------------------------------------------------------+
// | Author: Joerg Stoeber <hide@address.com> |
// +----------------------------------------------------------------------+
/*
* Konstante für Move Methoden. Gibt an das ein Zweig in der Hierarchie
* unter einem anderen Zweig stehen soll
*/
define("CB_NESE_MOVEBELOW", 1);
/*
* Konstante für Move Methoden. Gibt an das ein Zweig in der selben Hierarchie
* vor einem anderen stehen soll
*/
define("CB_NESE_MOVEBEFORE", 2);
/*
* Konstante für Move Methoden. Gibt an das ein Zweig in der selben Hierarchie
* nach einem anderen stehen soll
*/
define("CB_NESE_MOVEAFTER", 3);
/**
* CB_NestedSet
*
* @package CB_NestedSet
* @author Joerg Stoeber <hide@address.com>
* @copyright Copyright (c) 2003 The C*B Development Group
* @version $Id: CB_NestedSet.class.php,v 1.6 2004/09/03 20:17:20 cb_fog Exp $
* @access public
*/
class CB_NestedSet {
function CB_NestedSet($params, $otherFields)
{
$this->params = $params;
$this->additional = $otherFields;
}
/**
* CB_NestedSet::factory()
*
* @param array $params Array mit folgenden zwingenden Werten:
* table -> Tabellenname
* id -> Feldname des ID Feldes
* parent -> Feldname der ElternID
* root -> Feldname der Root ID
* l -> Feldname der leftID
* r -> Feldname der rightID
* norder -> Feldname des order Wertes
* @param array $otherFields Alle anderen Felder, die es noch in der
* Tabelle gibt und die bearbeitbar sein sollen
* @return mixed Entweder angefordertes Objekt oder false, wenn Fehler auftrat
*/
function &factory($params, $otherFields = array())
{
if (is_array($params)) {
return new CB_NestedSet($params, $otherFields);
} else {
return false;
}
}
/*
* getNode()
* liefert ein Blatt des Baumes zurueck
*
* @access public
* @param int $id ID des Blattes
* @param boolean $aliasFields Stellt bei true fuer alle Felder die
* Aliasnamen ein, die in den Parameter Tabellen auf der
* linken Seite stehen. Bei false werden die realen Felder
* der rechten Seite zurueck geliefert
* @return mixed $result entweder Array mit Node Werten oder false falls Abfrage fehl schlug
*/
function getNode($id, $aliasFields = false, $additionalSQL = array())
{
$this->_setActualFieldNames();
if (count($additionalSQL) > 0) {
$joinParameters = $additionalSQL['join'];
$fieldParameters = $additionalSQL['field'];
$whereParameters = $additionalSQL['where'];
$appendParameters = $additionalSQL['append'];
}
$nodeSQL = sprintf("SELECT %s %s FROM %s AS n %s WHERE n.%s = '$id' %s %s",
$this->_queryFieldNameConvert('n', $aliasFields),
$fieldParameters,
$this->params['table'],
$joinParameters,
$this->params['id'],
$whereParameters,
$appendParameters
);
$nodeQuery = mysql_query($nodeSQL);
if (mysql_num_rows($nodeQuery) > 0) {
return mysql_fetch_array($nodeQuery);
} else {
return false;
}
}
/*
* getRootNodes()
* Liefert alle Wurzelknoten zurueck
* Rueckgabe eines Array's mit Werten, erstes Array Level = ID des Nodes, 2. Level = alle Werte
*
* @access public
* @param boolean $aliasFields Stellt bei true fuer alle Felder die
* Aliasnamen ein, die in den Parameter Tabellen auf der
* linken Seite stehen. Bei false werden die realen Felder
* der rechten Seite zurueck geliefert
* @return mixed $result entweder Array mit Node Werten oder false falls Abfrage fehl schlug
*/
function getRootNodes($aliasFields = false, $additionalSQL = array())
{
$this->_setActualFieldNames();
if (count($additionalSQL) > 0) {
$joinParameters = $additionalSQL['join'];
$fieldParameters = $additionalSQL['field'];
$whereParameters = $additionalSQL['where'];
$appendParameters = $additionalSQL['append'];
$orderByParameters = $additionalSQL['orderby'];
}
if ($orderByParameters == "") {
$orderByParameters = "ORDER BY n." . $this->params['norder'] . " ASC";
}
$nodesSQL = sprintf("SELECT %s %s FROM %s AS n %s WHERE n.%s = n.%s %s %s %s",
$this->_queryFieldNameConvert('n', $aliasFields),
$fieldParameters,
$this->params['table'],
$joinParameters,
$this->params['id'],
$this->params['root'],
$whereParameters,
$orderByParameters,
$appendParameters
);
$nodesQuery = mysql_query($nodesSQL);
if ($nodesQuery) {
while ($nodesRow = mysql_fetch_array($nodesQuery)) {
$branch[$nodesRow[$this->actualFieldNames['id']]] = $nodesRow;
}
return $branch;
} else {
return false;
}
}
/*
* getBranch()
* einen ganzen Zweig eines Baumes zurueck
* Rueckgabe eines Array's mit Werten, erstes Array Level = ID des Nodes, 2. Level = alle Werte
*
* @access public
* @param int $id ID des Blattes
* @param boolean $aliasFields Stellt bei true fuer alle Felder die
* Aliasnamen ein, die in den Parameter Tabellen auf der
* linken Seite stehen. Bei false werden die realen Felder
* der rechten Seite zurueck geliefert
* @return mixed $result entweder Array mit Node Werten oder false falls Abfrage fehl schlug
*/
function getBranch($id, $aliasFields = false, $additionalSQL = array())
{
$this->_setActualFieldNames();
if (count($additionalSQL) > 0) {
$joinParameters = $additionalSQL['join'];
$fieldParameters = $additionalSQL['field'];
$whereParameters = $additionalSQL['where'];
$appendParameters = $additionalSQL['append'];
$orderByParameters = $additionalSQL['orderby'];
}
if ($orderByParameters == "") {
$orderByParameters = "ORDER BY n." . $this->params['l'] . " ASC";
}
$node = $this->getNode($id);
$nodesSQL = sprintf("SELECT %s %s FROM %s AS n %s WHERE n.%s BETWEEN %s AND %s AND n.%s = '%s' %s GROUP BY n.%s %s %s",
$this->_queryFieldNameConvert('n', $aliasFields),
$fieldParameters,
$this->params['table'],
$joinParameters,
$this->params['l'],
$node[$this->params['l']],
$node[$this->params['r']],
$this->params['root'],
$node[$this->params['root']],
$whereParameters,
$this->params['l'],
$orderByParameters,
$appendParameters
);
$nodesQuery = mysql_query($nodesSQL);
if ($nodesQuery) {
while ($nodesRow = mysql_fetch_array($nodesQuery)) {
$branch[$nodesRow[$this->actualFieldNames['id']]] = $nodesRow;
}
return $branch;
} else {
return false;
}
}
/*
* getAllNodes()
* Methode gibt den ganzen Baum zurueck. Alle Root Nodes mit Subnodes
* Rueckgabe eines Array's mit Werten, erstes Array Level = ID des Nodes, 2. Level = alle Werte
*
* @access public
* @param boolean $aliasFields Stellt bei true fuer alle Felder die
* Aliasnamen ein, die in den Parameter Tabellen auf der
* linken Seite stehen. Bei false werden die realen Felder
* der rechten Seite zurueck geliefert
* @return mixed $result entweder Array mit Node Werten oder false falls Abfrage fehl schlug
*/
function getAllNodes($aliasFields = false, $additionalSQL = array())
{
$this->_setActualFieldNames();
if (count($additionalSQL) > 0) {
$joinParameters = $additionalSQL['join'];
$fieldParameters = $additionalSQL['field'];
$whereParameters = $additionalSQL['where'];
$appendParameters = $additionalSQL['append'];
$orderByParameters = $additionalSQL['orderby'];
}
if ($orderByParameters == "") {
$orderByParameters = "ORDER BY n." . $this->params['norder'] . ", n." . $this->params['l'] . " ASC";
}
$nodesSQL = sprintf("SELECT %s %s FROM %s AS n, %s AS p %s WHERE n.%s BETWEEN p.%s AND p.%s %s GROUP BY n.%s, n.%s %s %s",
$this->_queryFieldNameConvert('n', $aliasFields),
$fieldParameters,
$this->params['table'],
$this->params['table'],
$joinParameters,
$this->params['l'],
$this->params['l'],
$this->params['r'],
$whereParameters,
$this->params['root'],
$this->params['l'],
$orderByParameters,
$appendParameters
);
$nodesQuery = mysql_query($nodesSQL);
if ($nodesQuery) {
while ($nodesRow = mysql_fetch_array($nodesQuery)) {
$branch[$nodesRow[$this->actualFieldNames['id']]] = $nodesRow;
}
return $branch;
} else {
return false;
}
}
/*
* getParent()
* Liefert den Elternknoten
*
* @access public
* @param int $id ID von dem Knoten, dessen Eltern Knoten ermittelt wird
* @param boolean $aliasFields Stellt bei true fuer alle Felder die
* Aliasnamen ein, die in den Parameter Tabellen auf der
* linken Seite stehen. Bei false werden die realen Felder
* der rechten Seite zurueck geliefert
* @return mixed $result entweder Array mit Node Werten oder false falls Abfrage fehl schlug
*/
function getParent($id, $aliasFields = false, $additionalSQL = array())
{
$this->_setActualFieldNames();
$node = $this->getNode($id);
$parent = false;
if ($node != false) {
$parent = $this->getNode($node[$this->params['parent']], $aliasFields, $additionalSQL);
}
if ($parent != false) {
return $parent;
} else {
return false;
}
}
/*
* getParents()
* Liefert alle Eltern des angebenen Knotens
*
* @access public
* @param int $id ID zu dem der Pfad gefuehrt werden soll
* @param boolean $aliasFields Stellt bei true fuer alle Felder die
* Aliasnamen ein, die in den Parameter Tabellen auf der
* linken Seite stehen. Bei false werden die realen Felder
* der rechten Seite zurueck geliefert
* @return mixed $result entweder Array mit Node Werten oder false falls Abfrage fehl schlug
*/
function getParents($id, $aliasFields = false, $additionalSQL = array())
{
$this->_setActualFieldNames();
if (count($additionalSQL) > 0) {
$joinParameters = $additionalSQL['join'];
$fieldParameters = $additionalSQL['field'];
$whereParameters = $additionalSQL['where'];
$appendParameters = $additionalSQL['append'];
$orderByParameters = $additionalSQL['orderby'];
}
if ($orderByParameters == "") {
$orderByParameters = "ORDER BY n." . $this->params['l'] . " ASC";
}
$nodesSQL = sprintf("SELECT %s %s FROM %s AS n, %s AS p %s WHERE n.%s BETWEEN p.%s AND p.%s AND n.%s = '$id' AND p.%s != '$id' AND n.%s = p.%s %s ORDER BY n.%s ASC %s",
$this->_queryFieldNameConvert('p', $aliasFields),
$fieldParameters,
$this->params['table'],
$this->params['table'],
$joinParameters,
$this->params['l'],
$this->params['l'],
$this->params['r'],
$this->params['id'],
$this->params['id'],
$this->params['root'],
$this->params['root'],
$whereParameters,
$orderByParameters,
$appendParameters
);
$nodesQuery = mysql_query($nodesSQL);
if ($nodesQuery) {
while ($nodesRow = mysql_fetch_array($nodesQuery)) {
$branch[$nodesRow[$this->actualFieldNames['id']]] = $nodesRow;
}
return $branch;
} else {
return false;
}
}
/*
* getPath()
* Liefert den Pfad von der Wurzel bis zum angegebenen Knoten
*
* @access public
* @param int $id ID zu dem der Pfad gefuehrt werden soll
* @param boolean $aliasFields Stellt bei true fuer alle Felder die
* Aliasnamen ein, die in den Parameter Tabellen auf der
* linken Seite stehen. Bei false werden die realen Felder
* der rechten Seite zurueck geliefert
* @return mixed $result entweder Array mit Node Werten oder false falls Abfrage fehl schlug
*/
function getPath($id, $aliasFields = false, $additionalSQL = array())
{
$this->_setActualFieldNames();
if (count($additionalSQL) > 0) {
$joinParameters = $additionalSQL['join'];
$fieldParameters = $additionalSQL['field'];
$whereParameters = $additionalSQL['where'];
$appendParameters = $additionalSQL['append'];
$orderByParameters = $additionalSQL['orderby'];
}
if ($orderByParameters == "") {
$orderByParameters = "ORDER BY n." . $this->params['l'] . " ASC";
}
$nodesSQL = sprintf("SELECT %s %s FROM %s AS n, %s AS p %s WHERE n.%s BETWEEN p.%s AND p.%s AND n.%s = '$id' AND n.%s = p.%s %s %s %s",
$this->_queryFieldNameConvert('p', $aliasFields),
$fieldParameters,
$this->params['table'],
$this->params['table'],
$joinParameters,
$this->params['l'],
$this->params['l'],
$this->params['r'],
$this->params['id'],
$this->params['root'],
$this->params['root'],
$whereParameters,
$orderByParameters,
$appendParameters
);
$nodesQuery = mysql_query($nodesSQL);
if ($nodesQuery) {
while ($nodesRow = mysql_fetch_array($nodesQuery)) {
$branch[$nodesRow[$this->actualFieldNames['id']]] = $nodesRow;
}
return $branch;
} else {
return false;
}
}
function getPrecedents($id, $aliasFields = false, $additionalSQL = array())
{
$this->_setActualFieldNames();
if (count($additionalSQL) > 0) {
$joinParameters = $additionalSQL['join'];
$fieldParameters = $additionalSQL['field'];
$whereParameters = $additionalSQL['where'];
$appendParameters = $additionalSQL['append'];
$orderByParameters = $additionalSQL['orderby'];
}
if ($orderByParameters == "") {
$orderByParameters = "ORDER BY n." . $this->params['l'] . " ASC";
}
$nodesSQL = sprintf("SELECT %s %s FROM %s AS n, %s AS p %s WHERE n.%s BETWEEN p.%s AND p.%s AND n.%s = '$id' %s %s %s",
$this->_queryFieldNameConvert('p', $aliasFields),
$fieldParameters,
$this->params['table'],
$this->params['table'],
$joinParameters,
$this->params['l'],
$this->params['l'],
$this->params['r'],
$this->params['id'],
$whereParameters,
$orderByParameters,
$appendParameters
);
$nodesQuery = mysql_query($nodesSQL);
if ($nodesQuery) {
while ($nodesRow = mysql_fetch_array($nodesQuery)) {
$branch[$nodesRow[$this->actualFieldNames['id']]] = $nodesRow;
}
return $branch;
} else {
return false;
}
}
/*
* getDescendants()
* liefert alle Nachkommen eines Zweiges
* Rueckgabe eines Array's mit Werten, erstes Array Level = ID des Nodes, 2. Level = alle Werte
*
* @access public
* @param int $id ID des Knotens dessen Nachfahren ermittelt werden
* sollen
* @param boolean $aliasFields Stellt bei true fuer alle Felder die
* Aliasnamen ein, die in den Parameter Tabellen auf der
* linken Seite stehen. Bei false werden die realen Felder
* der rechten Seite zurueck geliefert
* @return mixed $result entweder Array mit Node Werten oder false falls Abfrage fehl schlug
*/
function getDescendants($id, $aliasFields = false, $additionalSQL = array())
{
$this->_setActualFieldNames();
if (count($additionalSQL) > 0) {
$joinParameters = $additionalSQL['join'];
$fieldParameters = $additionalSQL['field'];
$whereParameters = $additionalSQL['where'];
$appendParameters = $additionalSQL['append'];
$orderByParameters = $additionalSQL['orderby'];
}
if ($orderByParameters == "") {
$orderByParameters = "ORDER BY n." . $this->params['l'] . " ASC";
}
$node = $this->getNode($id);
$nodesSQL = sprintf("SELECT %s %s FROM %s AS n %s WHERE n.%s BETWEEN %s AND %s AND n.%s = '%s' %s GROUP BY n.%s %s %s",
$this->_queryFieldNameConvert('n', $aliasFields),
$fieldParameters,
$this->params['table'],
$joinParameters,
$this->params['l'],
$node[$this->params['l']] + 1,
$node[$this->params['r']] - 1,
$this->params['root'],
$node[$this->params['root']],
$whereParameters,
$this->params['l'],
$orderByParameters,
$appendParameters
);
$nodesQuery = mysql_query($nodesSQL);
if ($nodesQuery) {
while ($nodesRow = mysql_fetch_array($nodesQuery)) {
$branch[$nodesRow[$this->actualFieldNames['id']]] = $nodesRow;
}
return $branch;
} else {
return false;
}
}
/*
* getChildren()
* liefert die direkten Nachkommen eines Zweiges
* Rueckgabe eines Array's mit Werten, erstes Array Level = ID des Nodes, 2. Level = alle Werte
*
* @access public
* @param int $id ID des Knotens dessen Nachfahren ermittelt werden
* sollen
* @param boolean $aliasFields Stellt bei true fuer alle Felder die
* Aliasnamen ein, die in den Parameter Tabellen auf der
* linken Seite stehen. Bei false werden die realen Felder
* der rechten Seite zurueck geliefert
* @return mixed $result entweder Array mit Node Werten oder false falls Abfrage fehl schlug
*/
function getChildren($id, $aliasFields = false, $additionalSQL = array())
{
$this->_setActualFieldNames();
if (count($additionalSQL) > 0) {
$joinParameters = $additionalSQL['join'];
$fieldParameters = $additionalSQL['field'];
$whereParameters = $additionalSQL['where'];
$appendParameters = $additionalSQL['append'];
$orderByParameters = $additionalSQL['orderby'];
}
if ($orderByParameters == "") {
$orderByParameters = "ORDER BY n." . $this->params['l'] . " ASC";
}
$nodesSQL = sprintf("SELECT %s %s FROM %s AS n %s WHERE n.%s = '%s' %s %s %s",
$this->_queryFieldNameConvert('n', $aliasFields),
$fieldParameters,
$this->params['table'],
$joinParameters,
$this->params['parent'],
$id,
$whereParameters,
$orderByParameters,
$appendParameters
);
$nodesQuery = mysql_query($nodesSQL);
if ($nodesQuery) {
while ($nodesRow = mysql_fetch_array($nodesQuery)) {
$children[$nodesRow[$this->actualFieldNames['id']]] = $nodesRow;
}
return $children;
} else {
return false;
}
}
/*
* getSiblings()
* Liefert alle Geschwister eines Knotens
*
* @access public
* @param int $id ID von dem Knoten, dessen Geschwister ermittelt werden sollen
* @param boolean $aliasFields Stellt bei true fuer alle Felder die
* Aliasnamen ein, die in den Parameter Tabellen auf der
* linken Seite stehen. Bei false werden die realen Felder
* der rechten Seite zurueck geliefert
* @return mixed $result entweder Array mit Node Werten oder false falls Abfrage fehl schlug
*/
function getSiblings($id, $aliasFields = false, $additionalSQL = array())
{
$this->_setActualFieldNames();
if (count($additionalSQL) > 0) {
$joinParameters = $additionalSQL['join'];
$fieldParameters = $additionalSQL['field'];
$whereParameters = $additionalSQL['where'];
$appendParameters = $additionalSQL['append'];
$orderByParameters = $additionalSQL['orderby'];
}
$actualNode = $this->getNode($id);
if ($actualNode[$this->params['root']] != $actualNode[$this->params['id']]) {
if ($orderByParameters == "") {
$orderByParameters = "ORDER BY n." . $this->params['l'] . " ASC";
}
$nodesSQL = sprintf("SELECT %s %s FROM %s AS n %s WHERE n.%s = '%s' %s %s %s",
$this->_queryFieldNameConvert('n', $aliasFields),
$fieldParameters,
$this->params['table'],
$joinParameters,
$this->params['parent'],
$actualNode[$this->params['parent']],
$whereParameters,
$orderByParameters,
$appendParameters
);
} else {
if ($orderByParameters == "") {
$orderByParameters = "ORDER BY n." . $this->params['norder'] . " ASC";
}
$nodesSQL = sprintf("SELECT %s %s FROM %s AS n %s WHERE n.%s = n.%s %s %s %s",
$this->_queryFieldNameConvert('n', $aliasFields),
$fieldParameters,
$this->params['table'],
$joinParameters,
$this->params['root'],
$this->params['id'],
$whereParameters,
$orderByParameters,
$appendParameters
);
}
$nodesQuery = mysql_query($nodesSQL);
if ($nodesQuery) {
while ($nodesRow = mysql_fetch_array($nodesQuery)) {
$branch[$nodesRow[$this->actualFieldNames['id']]] = $nodesRow;
}
return $branch;
} else {
return false;
}
}
/*
* createRootNode()
* Erzeugt einen Wurzeleintrag
*
* @access public
* @param array $values Zusatzinformation zum Wurzelknoten
* Hier koennen Werte fuer die Felder uebergeben werden, die als
* Zusatzfeldarray an die Factory uebergeben wurden. Als Key gilt
* der Aliasname (linke Seite des Array's)
* Keine Ueberpruefung ob diese Felder korrekt sind.
* @return int $id ID des erzeugten Eintrags
*/
function createRootNode($values)
{
mysql_query("LOCK TABLES " . $this->params['table'] . " WRITE");
/*
* Eindeutige letzte ID bekommen
*/
$idQuery = mysql_fetch_array(mysql_query("SELECT " . $this->params['id'] . " FROM " . $this->params['table'] . " ORDER BY " . $this->params['id'] . " DESC LIMIT 1"));
$id = $idQuery[$this->params['id']] + 1;
$orderQuery = mysql_query("SELECT " . $this->params['norder'] . " FROM " . $this->params['table'] . " WHERE " . $this->params['root'] . " = " . $this->params['id'] . " ORDER BY " . $this->params['norder'] . " DESC LIMIT 1");
if ($orderQuery) {
$orderRow = mysql_fetch_array($orderQuery);
$order = $orderRow[$this->params['norder']] + 1;
} else {
$order = 1;
}
$sql = sprintf("INSERT INTO %s %s",
$this->params['table'],
$this->_insertFields($values, array ('id' => $id, 'norder' => $order))
);
mysql_query($sql);
mysql_query("UNLOCK TABLES");
return $id;
}
/**
* CB_NestedSet::updateNode()
* Methode zum Aktualisieren von Knoten
*
* @param int $id ID des Knotens der upgedated werden soll
* @param array $values Array mit Werten die erneuert werden sollen
* @return boolean $error
*/
function updateNode($id, $values)
{
$checkQuery = $this->getNode($id, true);
mysql_query("LOCK TABLES " . $this->params['table'] . " WRITE");
$error = false;
/*
* Eindeutige letzte ID bekommen
*/
if ($checkQuery === false) {
$error = true;
}
if (!is_array($values)) {
$error = true;
}
if (count($values) == 0) {
$error = true;
}
if (!$error) {
$sql = sprintf("UPDATE %s SET %s WHERE %s = '%s'",
$this->params['table'],
$this->_updateFields($values),
$this->params['id'],
$id
);
mysql_query($sql);
}
mysql_query("UNLOCK TABLES");
return $error;
}
/*
* createRootNode()
* Erzeugt einen Kindknoten, Kind wird ans Ende auf dieser Ebene gesetzt
*
* @access public
* @param int $parent ID des Elternknotens
* @param array $values Zusatzinformation zum Kindknoten
* Hier koennen Werte fuer die Felder uebergeben werden, die als
* Zusatzfeldarray an die Factory uebergeben wurden. Als Key gilt
* der Aliasname (linke Seite des Array's)
* Keine Ueberpruefung ob diese Felder korrekt sind.
* @return int $id ID des erzeugten Eintrags
*/
function createSubNode($parent, $values)
{
/*
* Eltern Infos bekommen
* SubNode muss zwingend Eltern haben. Diese haben dann weitere benoetigte Infos
*/
$parentQuery = $this->getNode($parent);
if ($parentQuery != false) {
/*
* Wurzel Infos bekommen
*/
$rootQuery = $this->getNode($parentQuery[$this->params['root']], true);
mysql_query("LOCK TABLES " . $this->params['table'] . " WRITE");
/*
* Eindeutige letzte ID bekommen
*/
$idQuery = mysql_fetch_array(mysql_query("SELECT " . $this->params['id'] . " FROM " . $this->params['table'] . " ORDER BY " . $this->params['id'] . " DESC LIMIT 1"));
$id = $idQuery[$this->params['id']] + 1;
/*
* Order Wert der Rootnodes übernehmen
*/
$order = $rootQuery[norder];
/*
* Standard Daten Array aufbauen.
*/
$standardFields = array ('id' => $id,
'norder' => $order,
'parent' => $parent,
'l' => $parentQuery[$this->params['r']],
'r' => $parentQuery[$this->params['r']] + 1,
'level' => $parentQuery[$this->params['level']] + 1,
'root' => $parentQuery[$this->params['root']]
);
/*
* Luecke schaffen. Es wird anhand der rechten ID der Mutter
* (right der Mutter = right + 1 des letzten Geschisterchens)
* der Baum um 2 ID Werte vergroeßert
*/
$sql = sprintf("UPDATE %s SET %s = %s + 2 WHERE %s >= '%s' AND %s = '%s'",
$this->params['table'],
$this->params['r'],
$this->params['r'],
$this->params['r'],
$parentQuery[$this->params['r']],
$this->params['root'],
$parentQuery[$this->params['root']]
);
mysql_query($sql);
/*
* Luecke schaffen. Das gleiche noch mal fuer die linke ID
*/
$sql = sprintf("UPDATE %s SET %s = %s + 2 WHERE %s > '%s' AND %s = '%s'",
$this->params['table'],
$this->params['l'],
$this->params['l'],
$this->params['l'],
$parentQuery[$this->params['r']],
$this->params['root'],
$parentQuery[$this->params['root']]
);
mysql_query($sql);
/*
* Einfuegen des neuen Nodes
*/
$sql = sprintf("INSERT INTO %s %s",
$this->params['table'],
$this->_insertFields($values, $standardFields)
);
mysql_query($sql);
$result = $id;
mysql_query("UNLOCK TABLES");
} else {
$result = false;
}
return $result;
}
/*
* sortNodeUp()
* Methode ermittelt den vorhergehenden Knoten und gibt das ganze an
* moveBranch weiter, mit der Option CB_NESE_MOVEBEFORE
*
* @access public
* @param int $nodeID ID des zu sortierenden Knoten
*/
function sortNodeUp($nodeID)
{
$nodeRow = $this->getNode($nodeID, true);
if ($nodeRow != false) {
// SQL erzeugen, um den Vorgänger zu bekommen
if ($nodeRow[root] == $nodeRow[id]) {
// Wenn der Node Wurzel ist, dann per norder sortieren
$sql = sprintf("SELECT %s FROM %s WHERE %s = %s AND %s < %s ORDER BY %s DESC LIMIT 0,1",
$this->params['id'],
$this->params['table'],
$this->params['id'],
$this->params['root'],
$this->params['norder'],
$nodeRow[norder],
$this->params['norder']
);
} else {
// wenn der Node keine Wurzel ist, per leftID sortieren
$sql = sprintf("SELECT %s FROM %s WHERE %s = %s AND %s < %s AND %s = %s ORDER BY %s DESC LIMIT 0,1",
$this->params['id'],
$this->params['table'],
$this->params['level'],
$nodeRow[level],
$this->params['l'],
$nodeRow['l'],
$this->params['root'],
$nodeRow['root'],
$this->params['l']
);
}
$result = mysql_query($sql);
if ($result) {
$targetNodeID = mysql_fetch_array($result);
$this->moveBranch($nodeID, $targetNodeID[$this->params['id']], CB_NESE_MOVEBEFORE);
}
}
}
/*
* sortNodeDown()
* Methode ermittelt den vorhergehenden Knoten und gibt das ganze an
* moveBranch weiter, mit der Option CB_NESE_MOVEAFTER
*
* @access public
* @param int $nodeID ID des zu sortierenden Knoten
*/
function sortNodeDown($nodeID)
{
$nodeRow = $this->getNode($nodeID, true);
if ($nodeRow != false) {
if ($nodeRow[root] == $nodeRow[id]) {
$sql = sprintf("SELECT %s FROM %s WHERE %s = %s AND %s > %s ORDER BY %s ASC LIMIT 0,1",
$this->params['id'],
$this->params['table'],
$this->params['id'],
$this->params['root'],
$this->params['norder'],
$nodeRow[norder],
$this->params['norder']
);
} else {
$sql = sprintf("SELECT %s FROM %s WHERE %s = %s AND %s > %s AND %s = %s ORDER BY %s ASC LIMIT 0,1",
$this->params['id'],
$this->params['table'],
$this->params['level'],
$nodeRow[level],
$this->params['l'],
$nodeRow['r'],
$this->params['root'],
$nodeRow['root'],
$this->params['l']
);
}
$result = mysql_query($sql);
if ($result) {
$targetNodeID = mysql_fetch_array($result);
$this->moveBranch($nodeID, $targetNodeID[$this->params['id']], CB_NESE_MOVEAFTER);
}
}
}
/*
* moveBranch()
* Verschiebt einen Zweig
*
* @access public
* @param int $nodeID ID des zu verschiebenden Zweiges
* @param int $targetID ID des Zielzweiges
* @param int $moveAction 1 für verschieben des Zweiges unter den
* anderen, 2 für verschieben und einsortieren in der
* selben Hierarchie vor dem Zielzweig, 3 für verschieben
* und einsortieren in der selben Hierarchie nach dem Zielzweig
*/
function moveBranch($nodeID, $targetID, $moveAction = CB_NESE_MOVEBELOW)
{
/*
* zu verschiebenden Zweig abfragen und testen
*/
$moveNode = $this->getNode($nodeID, true);
if ($moveNode == false) {
$error[] = "node not found";
}
/*
* Zielzweig abfragen und testen
*/
$targetNode = $this->getNode($targetID, true);
if ($targetNode == false) {
$error[] = "targetnode not found";
}
/*
* Check auf Rekursion
*/
if (($targetNode['root'] == $moveNode['root']) && (($moveNode['l'] <= $targetNode['l']) && ($moveNode['r'] >= $targetNode['r']))) {
$error[] = "recursion error";
}
/*
* wenn keine Fehler auftraten, dann weiter
*/
if (!isset($error)) {
if ($moveAction != CB_NESE_MOVEBELOW) {
if (($targetNode[root] == $targetNode[id]) && ($moveNode[root] == $moveNode[id])) {
/*
* wenn beide Nodes RootNodes sind, muss man anhand norder sortieren.
*/
$this->_moveBetweenRootNodes($moveNode, $targetNode, $moveAction);
} else {
/*
* der Einfachheit halber wird der zu verschiebende Zweig als RootNode zwischengespeichert
*/
$this->_moveToRoot($nodeID);
if ($targetNode[root] == $targetNode[id]) {
/*
* wenn target auch Root ist, sinds JETZT beide....also sortieren über norder.
*/
$this->_moveBetweenRootNodes($moveNode, $targetNode, $moveAction);
} else {
/*
* Ansonsten müssen Löcher gebohrt werden, wo der Zweig
* rein passt
*/
if ($moveAction == CB_NESE_MOVEBEFORE) {
$this->_moveRootBeforeTarget($nodeID, $targetID);
} elseif ($moveAction == CB_NESE_MOVEAFTER) {
$this->_moveRootAfterTarget($nodeID, $targetID);
}
}
}
} else {
if ($moveNode[root] != $moveNode[id]) {
/*
* der Einfachheit halber wird der zu verschiebende Zweig als RootNode zwischengespeichert
*/
$this->_moveToRoot($nodeID);
}
$this->_moveRootBelowTarget($nodeID, $targetID);
/*
* Dem alten Node noch neue ParentID geben
*/
$sql = mysql_query("UPDATE " . $this->params['table'] . " SET " . $this->params['parent'] . " = '$targetID' WHERE " . $this->params['id'] . " = '$nodeID'");
}
$this->setOrderIntegrity();
}
}
/**
* CB_NestedSet::setOrderIntegrity()
* Methode stellt sicher, dass die Kinder von Wurzeln immer den selben norder Wert haben
* wie die Wurzeln. Des weiteren werden Löcher in den norder Werten gestopft.
* Wichtig für die Methode getAllNodes, damit bei der Ausgabe des Baumes die Reihenfolge stimmt
*
* @return
**/
function setOrderIntegrity() {
$roots = $this->getRootNodes(true);
if($roots != false) {
$counter = 1;
foreach($roots as $v) {
mysql_query("UPDATE " . $this->params['table'] . " SET " . $this->params['norder'] . " = '$counter' WHERE " . $this->params['root'] . " = '".$v[id]."'");
++$counter;
}
}
}
/*
* deleteNode()
* Loescht einen Zweig
*
* @access public
* @param int $nodeID ID des zu loeschenden Zweiges
* @param int $children Was soll mit den Kindern passieren? 1 = loeschen, 2 = verschieben auf die Ebene der jeweiligen Mutter
* @return array $result ID's aller zu loeschenden Nodes ... zur Weiterverarbeitung
*/
function deleteNode($nodeID, $children = '1')
{
$nodeQuery = $this->getNode($nodeID);
mysql_query("LOCK TABLES " . $this->params['table'] . " WRITE");
if ($nodeQuery != false) {
/*
* alle Nodes auswählen, die nach dem zu löschenden Node kommen,
* einschließlich dem zu löschenden Node
*/
$deleteIDSQL = sprintf("SELECT %s FROM %s WHERE %s BETWEEN %s AND %s AND %s = %s",
$this->params['id'],
$this->params['table'],
$this->params['l'],
$nodeQuery[$this->params['l']],
$nodeQuery[$this->params['r']],
$this->params['root'],
$nodeQuery[$this->params['root']]
);
/*
* Array mit allen zu löschenden Nodes aufbauen
*/
$deleteIDQuery = mysql_query($deleteIDSQL);
while ($deleteIDRow = mysql_fetch_array($deleteIDQuery)) {
$resultSet[] = $deleteIDRow[$this->params['id']];
}
/*
* Alle Nodes löschen, die nach $nodeID kommen, einschließlich
* $nodeID
*/
$sql = sprintf("DELETE FROM %s WHERE %s BETWEEN %s AND %s AND %s = %s",
$this->params['table'],
$this->params['l'],
$nodeQuery[$this->params['l']],
$nodeQuery[$this->params['r']],
$this->params['root'],
$nodeQuery[$this->params['root']]
);
mysql_query($sql);
/*
* Enstandenes Loch bei den leftIDs schließen
*/
$sql = sprintf("UPDATE %s SET %s = %s - ROUND((%s - %s + 1)) WHERE %s > %s AND %s = %s",
$this->params['table'],
$this->params['l'],
$this->params['l'],
$nodeQuery[$this->params['r']],
$nodeQuery[$this->params['l']],
$this->params['l'],
$nodeQuery[$this->params['r']],
$this->params['root'],
$nodeQuery[$this->params['root']]
);
mysql_query($sql);
/*
* Enstandenes Loch bei den rightIDs schließen
*/
$sql = sprintf("UPDATE %s SET %s = %s - ROUND((%s - %s + 1)) WHERE %s > %s AND %s = %s",
$this->params['table'],
$this->params['r'],
$this->params['r'],
$nodeQuery[$this->params['r']],
$nodeQuery[$this->params['l']],
$this->params['r'],
$nodeQuery[$this->params['r']],
$this->params['root'],
$nodeQuery[$this->params['root']]
);
mysql_query($sql);
}
mysql_query("UNLOCK TABLES");
/*
* zurücklieferung aller gelöschten ID's zur Weiterverarbeitung
* bestimmte Elemente, die zu diesen ID's eine Beziehung haben, können
* dadurch auch gelöscht werden
*/
return $resultSet;
}
/*
* _insertFields()
* Erzeugt den Feld und Werte Teil des Insert Query's
*
* @access private
* @param array $values Zusatzinformation zum Knoten (alles was nicht zum Nested Set gehoert)
* @param array $standard Array mit Standard Infos, 'id' und 'order' sind zwingende Array Eintraege, alle anderen ('left', 'right', 'level', 'parent') nicht, werden aber auf Standardwerte gesetzt
* @return string $insertFields Insert String fuer's Query
*/
function _insertFields($values, $standard)
{
/*
* Bei den INSERT Werten werden die Grundwerte von CB_NestedSet bestimmt
*/
$insertFields = sprintf("(%s, %s, %s, %s, %s, %s, %s",
$this->params['id'],
$this->params['parent'],
$this->params['root'],
$this->params['l'],
$this->params['r'],
$this->params['level'],
$this->params['norder']
);
/*
* individuelle Felder, die an die Methode übergeben wurden, werden als
* zusätzliche INSERT Felder in den String gesetzt
* $values enthält im Schlüssel die zusätzlichen Felder
*/
foreach($values as $k => $v) {
$insertFields .= sprintf(", %s",
$this->additional[$k]
);
}
/*
* wenn im Standard Feld Array bestimmte wichtige Elemente leer sin, werden
* Standard Werte gesetzt
*/
if ($standard['parent'] == "") {
$standard['parent'] = '0';
}
if ($standard['root'] == "") {
$standard['root'] = $standard['id'];
}
if ($standard['l'] == "") {
$standard['l'] = '1';
}
if ($standard['r'] == "") {
$standard['r'] = '2';
}
if ($standard['level'] == "") {
$standard['level'] = '1';
}
if ($standard['norder'] == "") {
$standard['norder'] = '1';
}
/*
* die Werte aus dem Standard Array mit den Grundwerten werden ins
* INSERT Statement geschrieben
*/
$insertFields .= sprintf(") VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s'",
$standard['id'],
$standard['parent'],
$standard['root'],
$standard['l'],
$standard['r'],
$standard['level'],
$standard['norder']
);
/*
* Nun werden alle Werte der zusätzlichen Felder aus dem $values
* Array an den String angefügt
*/
foreach($values as $v) {
$insertFields .= ", '$v'";
}
/*
* INSERT Statement abschließen
*/
$insertFields .= ")";
/*
* fertig iss
*/
return $insertFields;
}
/**
* CB_NestedSet::_updateFields()
*
* @param array $values Array mit Additional Werten die erneuert werden sollen
* @return string $updateFields alle Felder mit neuen Werten
*/
function _updateFields($values)
{
/*
* individuelle UPDATE Felder
*/
$multiple = false;
foreach($values as $k => $v) {
if ($multiple == true) {
$updateFields .= ", ";
}
$updateFields .= sprintf("%s = '%s'",
$this->additional[$k],
$v
);
$multiple = true;
}
/*
* fertig iss
*/
return $updateFields;
}
/**
* CB_NestedSet::_queryFieldNameConvert()
* Konvertiert die real existierenden Spaltennamen in die im Parameter
* Array angegebenen Arbeitsnamen.
*
* @access private
* @param array $tableIdent Alias Name der Tabelle im Query, da in
* den einzelnen Get Funktionen teilweise mehrere Versionen
* der selben Tabelle gehalten werden.
* @param array $getArray Array mit Feldern, die im Select String
* auftauchen sollen. Dadurch soll der Query String so klein
* wie moeglich gehalten werden koennen.
* @return
*/
function _queryFieldNameConvert($tableIdent = false, $aliasFields = false, $getArray = false)
{
$convertFields = array_merge($this->params, $this->additional);
if (!$tableIdent) {
$tableIdent = "";
} else {
$tableIdent = $tableIdent . ".";
}
foreach($convertFields as $k => $v) {
if ($v != "" && $k != "table") {
if (($v == $k) || ($aliasFields == false)) {
$tempField = $tableIdent . $v;
} else {
$tempField = $tableIdent . $v . " AS " . $k;
$this->actualFieldNames[$k] = $k;
}
$queryFields[] = $tempField;
}
}
return implode(', ', $queryFields);
}
/**
* CB_NestedSet::_setActualFieldNames()
* Initialisiert ein Array in dem das param Array und das Additional
* Array zusammengefasst sind. Die Werte werden dann gegebenfalls
* ueberschrieben (fuer Alias Funktion)
*
* @access private
*/
function _setActualFieldNames()
{
$this->actualFieldNames = array_merge($this->params, $this->additional);
}
/**
* CB_NestedSet::_moveBetweenRootNodes()
* Verschieben von Rootnodes untereinander. RootNodes werden nur anhand der $oder Werte sortiert, stehen also ausserhalb der left - right Regeln
*
* @access private
* @param array $moveNode ResultSet von $this->getNode() mit Aliasflag
* @param array $targetNode ResultSet von $this->getNode() mit Aliasflag
* @param int $moveAction Was soll gemacht werden?
*/
function _moveBetweenRootNodes($moveNode, $targetNode, $moveAction)
{
mysql_query("LOCK TABLES " . $this->params['table'] . " WRITE");
/*
* Alle Root Nodes nach $moveNode müssen einen vorrücken, weil $moveNode
* ja wegzieht
*/
$sql = sprintf("UPDATE %s SET %s = (%s - 1) WHERE %s > %s AND %s != '%s' AND %s = %s",
$this->params['table'],
$this->params['norder'],
$this->params['norder'],
$this->params['norder'],
$moveNode[norder] + 1,
$this->params['id'],
$moveNode[id],
$this->params['root'],
$this->params['id']
);
mysql_query($sql);
mysql_query("UNLOCK TABLES");
/*
* $targetNode könnte auch gewandert sein, also aktuelle Werte
* ermitteln
*/
$targetNode = $this->getNode($targetNode[id], true);
mysql_query("LOCK TABLES " . $this->params['table'] . " WRITE");
if ($moveAction == CB_NESE_MOVEBEFORE) {
/*
* Loch vor $targetNode einbauen
*/
$sql = sprintf("UPDATE %s SET %s = (%s + 1) WHERE %s >= %s AND %s != '%s' AND %s = %s",
$this->params['table'],
$this->params['norder'],
$this->params['norder'],
$this->params['norder'],
$targetNode[norder],
$this->params['id'],
$moveNode[id],
$this->params['root'],
$this->params['id']
);
mysql_query($sql);
/*
* $moveNode ins Loch setzen
*/
$sql = sprintf("UPDATE %s SET %s = '%s' WHERE %s = '%s'",
$this->params['table'],
$this->params['norder'],
$targetNode[norder],
$this->params['id'],
$moveNode['id']
);
mysql_query($sql);
}
if ($moveAction == CB_NESE_MOVEAFTER) {
/*
* Loch hinter $targetNode einbauen
*/
$sql = sprintf("UPDATE %s SET %s = %s + 1 WHERE %s >= %s AND %s != '%s' AND %s != '%s' AND %s = %s",
$this->params['table'],
$this->params['norder'],
$this->params['norder'],
$this->params['norder'],
$targetNode[norder],
$this->params['id'],
$moveNode[id],
$this->params['id'],
$targetNode[id],
$this->params['root'],
$this->params['id']
);
mysql_query($sql);
/*
* $moveNode ins Loch setzen
*/
$sql = sprintf("UPDATE %s SET %s = '%s' WHERE %s = '%s'",
$this->params['table'],
$this->params['norder'],
$targetNode[norder] + 1,
$this->params['id'],
$moveNode['id']
);
mysql_query($sql);
}
/*
* Neue norder Werte auf alle Kinder übertragen
*/
// Wurzelknoten abfragen
$rootNodes = $this->getRootNodes(true);
if ($rootNodes != false) {
foreach($rootNodes as $v) {
mysql_query("UPDATE " . $this->params['table'] . " SET " . $this->params['norder'] . " = '" . $v['norder'] . "' WHERE " . $this->params['root'] . " = '" . $v[id] . "'");
}
}
mysql_query("UNLOCK TABLES");
}
/**
* CB_NestedSet::_moveToRoot()
* Verschiebt einen Node und dessen Kinder und macht aus dem Node
* eine Wurzel
*
* @access private
* @param array $nodeID ID des zu verschiebenden Zweiges
*/
function _moveToRoot($nodeID)
{
$orderQuery = mysql_fetch_array(mysql_query("SELECT " . $this->params['norder'] . " FROM " . $this->params['table'] . " ORDER BY " . $this->params['norder'] . " DESC LIMIT 0,1"));
/*
* Daten herausfinden. Ist wegen der Left / Right Berechnungen
* wichtig, um alle Kinder mit zu verschieben
*/
$moveNode = $this->getNode($nodeID, true);
mysql_query("LOCK TABLES " . $this->params['table'] . " WRITE");
if ($moveNode != false) {
/*
* Verschieben des Nodes und aller Kinder zur Wurzel
*/
$sql = sprintf("UPDATE %s SET %s = %s - %s + 1, %s = %s - %s + 1, %s = '%s', %s = %s - %s + 1, %s = '%s' WHERE %s BETWEEN %s AND %s AND %s = '%s'",
$this->params['table'],
$this->params['l'],
$this->params['l'],
$moveNode[l],
$this->params['r'],
$this->params['r'],
$moveNode[l],
$this->params['root'],
$moveNode[id],
$this->params['level'],
$this->params['level'],
$moveNode[level],
$this->params['norder'],
$orderQuery[$this->params['norder']] + 1,
$this->params['l'],
$moveNode['l'],
$moveNode['r'],
$this->params['root'],
$moveNode['root']
);
mysql_query($sql);
/*
* Jetzt ist im alten Zweig ein Loch in den Left / Right Werten
* Enstandenes Loch bei den leftIDs schließen
*/
$sql = sprintf("UPDATE %s SET %s = %s - ROUND((%s - %s + 1)) WHERE %s > %s AND %s = %s",
$this->params['table'],
$this->params['l'],
$this->params['l'],
$moveNode['r'],
$moveNode['l'],
$this->params['l'],
$moveNode['r'],
$this->params['root'],
$moveNode['root']
);
mysql_query($sql);
/*
* Jetzt ist im alten Zweig ein Loch in den Left / Right Werten
* Enstandenes Loch bei den rightIDs schließen
*/
$sql = sprintf("UPDATE %s SET %s = %s - ROUND((%s - %s + 1)) WHERE %s > %s AND %s = %s",
$this->params['table'],
$this->params['r'],
$this->params['r'],
$moveNode['r'],
$moveNode['l'],
$this->params['r'],
$moveNode['r'],
$this->params['root'],
$moveNode['root']
);
mysql_query($sql);
}
mysql_query("UPDATE " . $this->params['table'] . " SET " . $this->params['parent'] . " = '0' WHERE " . $this->params['id'] . " = '$nodeID'");
mysql_query("UNLOCK TABLES");
}
/**
* CB_NestedSet::_moveRootBelowTarget()
* Verschiebt einen Node und dessen Kinder und setzt den Zweig in
* der Hierarchie unter einen bestimmten Zielknoten
*
* @access private
* @param array $nodeID ID des zu verschiebenden Zweiges
* @param array $targetID ID des Zielknotens
*/
function _moveRootBelowTarget($nodeID, $targetID)
{
$targetNode = $this->getNode($targetID, true);
$rootNode = $this->getNode($targetNode['root'], true);
$moveNode = $this->getNode($nodeID, true);
/*
* Loch in die LeftID's reissen
*/
$sql = sprintf("UPDATE %s SET %s = %s + ROUND((%s - %s + 1)) WHERE %s > %s AND %s = %s",
$this->params['table'],
$this->params['l'],
$this->params['l'],
$moveNode['r'],
$moveNode['l'],
$this->params['l'],
$targetNode['l'],
$this->params['root'],
$targetNode['root']
);
mysql_query($sql);
/*
* Loch in die RightID's reissen
*/
$sql = sprintf("UPDATE %s SET %s = %s + ROUND((%s - %s + 1)) WHERE %s > %s AND %s = %s",
$this->params['table'],
$this->params['r'],
$this->params['r'],
$moveNode['r'],
$moveNode['l'],
$this->params['r'],
$targetNode['l'],
$this->params['root'],
$targetNode['root']
);
mysql_query($sql);
/*
* Verschieben des Nodes in das entstandene Loch unter target
*/
$sql = sprintf("UPDATE %s SET %s = %s + %s, %s = %s + %s, %s = '%s', %s = %s + %s, %s = '%s' WHERE %s BETWEEN %s AND %s AND %s = '%s'",
$this->params['table'],
$this->params['l'],
$this->params['l'],
$targetNode[l],
$this->params['r'],
$this->params['r'],
$targetNode[l],
$this->params['root'],
$targetNode[root],
$this->params['level'],
$this->params['level'],
$targetNode[level],
$this->params['norder'],
$rootNode['norder'],
$this->params['l'],
$moveNode['l'],
$moveNode['r'],
$this->params['root'],
$moveNode['root']
);
mysql_query($sql);
}
/**
* CB_NestedSet::_moveRootBeforeTarget()
* Verschiebt einen Node und dessen Kinder und setzt den Zweig in
* der gleichen Hierarchiestufe vor einen bestimmten Zielknoten
*
* @access private
* @param array $nodeID ID des zu verschiebenden Zweiges
* @param array $targetID ID des Zielknotens
*/
function _moveRootBeforeTarget($nodeID, $targetID)
{
$targetNode = $this->getNode($targetID, true);
$rootNode = $this->getNode($targetNode['root'], true);
$moveNode = $this->getNode($nodeID, true);
/*
* Loch in die LeftID's reissen
*/
$sql = sprintf("UPDATE %s SET %s = %s + ROUND((%s - %s + 1)) WHERE %s >= %s AND %s = %s",
$this->params['table'],
$this->params['l'],
$this->params['l'],
$moveNode['r'],
$moveNode['l'],
$this->params['l'],
$targetNode['l'],
$this->params['root'],
$targetNode['root']
);
mysql_query($sql);
/*
* Loch in die RightID's reissen
*/
$sql = sprintf("UPDATE %s SET %s = %s + ROUND((%s - %s + 1)) WHERE %s >= %s AND %s = %s",
$this->params['table'],
$this->params['r'],
$this->params['r'],
$moveNode['r'],
$moveNode['l'],
$this->params['r'],
$targetNode['l'],
$this->params['root'],
$targetNode['root']
);
mysql_query($sql);
/*
* Füllen des Loches mit dem Zweig
*/
$sql = sprintf("UPDATE %s SET %s = %s + %s - 1, %s = %s + %s - 1, %s = '%s', %s = %s + %s - 1, %s = '%s' WHERE %s BETWEEN %s AND %s AND %s = '%s'",
$this->params['table'],
$this->params['l'],
$this->params['l'],
$targetNode[l],
$this->params['r'],
$this->params['r'],
$targetNode[l],
$this->params['root'],
$targetNode[root],
$this->params['level'],
$this->params['level'],
$targetNode[level],
$this->params['norder'],
$rootNode['norder'],
$this->params['l'],
$moveNode['l'],
$moveNode['r'],
$this->params['root'],
$moveNode['root']
);
mysql_query($sql);
/*
* Dem alten Node noch neue ParentID geben
*/
$sql = mysql_query("UPDATE " . $this->params['table'] . " SET " . $this->params['parent'] . " = '" . $targetNode['parent'] . "' WHERE " . $this->params['id'] . " = '$nodeID'");
}
/**
* CB_NestedSet::_moveRootBeforeTarget()
* Verschiebt einen Node und dessen Kinder und setzt den Zweig in
* der gleichen Hierarchiestufe hinter einen bestimmten Zielknoten
*
* @access private
* @param array $nodeID ID des zu verschiebenden Zweiges
* @param array $targetID ID des Zielknotens
*/
function _moveRootAfterTarget($nodeID, $targetID)
{
$targetNode = $this->getNode($targetID, true);
$rootNode = $this->getNode($targetNode['root'], true);
$moveNode = $this->getNode($nodeID, true);
/*
* Loch in die LeftID's reissen
*/
$sql = sprintf("UPDATE %s SET %s = %s + ROUND((%s - %s + 1)) WHERE %s > %s AND %s = %s",
$this->params['table'],
$this->params['l'],
$this->params['l'],
$moveNode['r'],
$moveNode['l'],
$this->params['l'],
$targetNode['r'],
$this->params['root'],
$targetNode['root']
);
mysql_query($sql);
/*
* Loch in die RightID's reissen
*/
$sql = sprintf("UPDATE %s SET %s = %s + ROUND((%s - %s + 1)) WHERE %s > %s AND %s = %s",
$this->params['table'],
$this->params['r'],
$this->params['r'],
$moveNode['r'],
$moveNode['l'],
$this->params['r'],
$targetNode['r'],
$this->params['root'],
$targetNode['root']
);
mysql_query($sql);
/*
* Füllen des Loches mit dem Zweig
*/
$sql = sprintf("UPDATE %s SET %s = %s + %s, %s = %s + %s, %s = '%s', %s = %s + %s - 1, %s = '%s' WHERE %s BETWEEN %s AND %s AND %s = '%s'",
$this->params['table'],
$this->params['l'],
$this->params['l'],
$targetNode[r],
$this->params['r'],
$this->params['r'],
$targetNode[r],
$this->params['root'],
$targetNode[root],
$this->params['level'],
$this->params['level'],
$targetNode[level],
$this->params['norder'],
$rootNode['norder'],
$this->params['l'],
$moveNode['l'],
$moveNode['r'],
$this->params['root'],
$moveNode['root']
);
mysql_query($sql);
/*
* Dem alten Node noch neue ParentID geben
*/
$sql = mysql_query("UPDATE " . $this->params['table'] . " SET " . $this->params['parent'] . " = '" . $targetNode['parent'] . "' WHERE " . $this->params['id'] . " = '$nodeID'");
}
}
?>