HTML - PHP - MySQL - SVG

KERNI's SEITE

Das Nested Set Model

Veröffentlicht am


Eintrag heben / senken

 

Die Funktion zum heben oder Senken eines Eintrages ist eigentlich die gleiche. Ausschlaggebend ist nur welchen Ausgangswert man sucht.

Einen Eintrag nach oben verschieben: lft Wert des auslösenden Elements ermittelt. Dann der in der Liste darüberligende mittels lft=@lt-1 OR rgt=@lt-1. Da jede Zahl in beiden Spalten, sowohl lft als auch rgt nur einmal vorkommt wird dadurch auch nur ein Datensatz zurückgegeben. Zusätzlich brauchen wir noch den auslösenden Datensatz. Diesen können wir mit seiner ID ermitteln.

Beim darunterliegenden dementsprechend den rgt Wert plus 1. lft=@rt+1 OR rgt=@rt+1

Für die UPDATE Anweisungen benötigen wir die IDs der einzelnen Elemente. Mit zwei UPDATE Anweisungen die in der WHERE Klausel nach den lft oder rgt suchen, wird man schnell feststellen das dies nur ein Chaos in der Struktur verursacht. 

 

		$id = $_REQUEST["id"];
		$ud = $_REQUEST["ud"];
		$erg = "";
		 
		if($ud=="u"){
		  // Eintrag und darüberliegenden suchen
		  // ( lft / rgt -1 )
		  $sql = "SET @lt = (SELECT `lft` FROM `tree` WHERE `id`=$id); 
		  SELECT `id`, `lft`, `rgt` 
		  FROM `tree` 
		  WHERE `lft` = @lt-1 OR `rgt` = @lt-1 OR `id`=$id 
		  ORDER BY `lft`;";
		}elseif($ud=="d"){
		  // Eintrag und darunterliegenden suchen
		  // ( lft / rgt +1 )
		  $sql = "SET @rt = (SELECT `rgt` FROM `tree` WHERE `id`=$id); 
		  SELECT `id`, `lft`, `rgt` 
		  FROM `tree` 
		  WHERE `lft` = @rt+1 OR `rgt` = @rt+1 OR `id`=$id 
		  ORDER BY `lft`;";
		}
		 
		$rst = $pdo->prepare($sql);
		$rst->execute();
		$arr = array();
		 
		$result = 0;
		 
		$rst->fetch();
		$rst->nextRowset();
		 
		while($row = $rst->fetch(PDO::FETCH_ASSOC)){
		  array_push($arr,$row);
		}
		// Wurde nur ein Eintrag gefunden kann dieser auch nicht verschoben werden
		if(count($arr)==1){die("Ende");}
		 
		// liegt der Eintrag auf der gleichen Ebene ale der darüber?
		if($arr[1]["lft"]-$arr[0]["lft"]==1){
		  // Vom Sohn und Enkel die IDs ermitteln
		  $sql = "SELECT `id` FROM `tree` WHERE `rgt` BETWEEN ".$arr[1]["lft"]." AND ".$arr[1]["rgt"].";";
		  $res = $pdo->prepare($sql);
		  $res->execute();
		  $id1 = array();
		 
		  while($row=$res->fetch(PDO::FETCH_ASSOC)){
		    array_push($id1,$row["id"]);
		  }
		 
		  // IDs zusammenfassen
		  $ids1 = implode(", ",$id1);
		 
		  // lft und rgt um 1 veringern
		  $sql = "UPDATE `tree` SET `lft`=`lft`-1, `rgt`=`rgt`-1 WHERE `id` IN (".$ids1.");";
		  // Offset1
		  $offset1 = $arr[1]["rgt"]-$arr[1]["lft"]+1;
		 
		  // lft des Vaters um das Offset erhöhen. rgt bleibt unberührt
		  $sql .= "UPDATE `tree` SET `lft`=`lft`+".$offset1." WHERE `id` = ".$arr[0]["id"].";";
		 
		  $res = $pdo->prepare($sql);
		  $res->execute();
		 
		  do {
		    $erg.= $res->rowCount().", ";
		  } while ($res->nextRowset());
		// Der Eintrag ist ein Kind Element dann ...
		}elseif($arr[1]["lft"]-$arr[0]["rgt"]==1){
		  // Offset des Auslösers (darunterliegend) ermitteln
		  $offset1 = $arr[1]["rgt"]-$arr[1]["lft"]+1;
		 
		  // IDs der darüberliegenden ermitteln
		  $sql = "SELECT `id` FROM `tree` WHERE `rgt` BETWEEN ".$arr[0]["lft"]." AND ".$arr[0]["rgt"];
		 
		  $res = $pdo->prepare($sql);
		  $res->execute();
		  $id0 = array();
		 
		  while($row=$res->fetch(PDO::FETCH_ASSOC)){
		    array_push($id0,$row["id"]);
		  }
		 
		  // IDs zusammenfassen
		  $ids0 = implode(", ",$id0);
		 
		  // Offset des Auslösers ermitteln
		  $offset0 = $arr[0]["rgt"]-$arr[0]["lft"]+1;
		 
		  // IDs des Auslösers ermitteln
		  $sql = "SELECT `id` FROM `tree` WHERE `rgt` BETWEEN ".$arr[1]["lft"]." AND ".$arr[1]["rgt"];
		 
		  $res = $pdo->prepare($sql);
		  $res->execute();
		  $id1 = array();
		 
		  while($row=$res->fetch(PDO::FETCH_ASSOC)){
		    array_push($id1,$row["id"]);
		  }
		  // IDs zusammenfassen
		  $ids1 = implode(", ",$id1);
		 
		  // lft und rgt des darüberliegenden Elements um das Offset1 ergöhen
		  // ( rgt Auslöser - lft Auslöser + 1 )
		  $sql = "UPDATE `tree` SET `lft`=`lft`+".$offset1.", `rgt`=`rgt`+".$offset1." WHERE `id` IN (".$ids0.");";
		  // lft und rgt um das Offset des Auslösers veringern
		  $sql .= "UPDATE `tree` SET `lft`=`lft`-".$offset0.", `rgt`=`rgt`-".$offset0." WHERE `id` IN (".$ids1.");";
		 
		  $res = $pdo->prepare($sql);
		  $res->execute();
		 
		  do {
		    $erg .= $res->rowCount().", ";
		  } while ($res->nextRowset());
		 
		}
		 
		echo $erg;
	

 

JavaScript für die Buttons Up / Down

	function nodeUP(id){
	  $.ajax({
	    type: "POST",
	    url: "php/up_down.php",
	    data: {id:id,ud:"u"}
	  })
	  .done(function(data){
	    laden();
	  });
	  $("#mid").combobox("reload");
	}
	 
	function nodeDOWN(id){
	  $.ajax({
	    type: "POST",
	    url: "php/up_down.php",
	    data: {id:id,ud:"d"}
	  })
	  .done(function(data){
	    if(data=="Ende"){
	      alert("Weiter nach unten geht es nicht");
	    }else{
	      laden();
	    }
	  });
	  $("#mid").combobox("reload");
	}