Tobias Hahner: Philosophieproblem zum Thema "Verschieben"

Beitrag lesen

Hallihallo!

Für mich sieht das Konstrukt gewaltig nach einer Anwendung für das nested sets Modell aus.
Selbst, wenn Deine bisherige Arbeit das so nicht vorgesehen hatte, lässt es sich ja relativ einfach nachrüsten, indem Du die Zuordnungen einfach in einer Extratabelle auslagerst und mit der Payload-Tabelle verknüpfst.

Ich hatte vor einer gefühlten Ewigkeit mal ein paar Funktionen gebastelt, mit deren Hilfe ich problemlos einzelne Äste ausschneiden und einfügen konnte. Hier mal der entsprechende Auszug aus meinem Testskript (Vorsicht: in meinem Test ist nur die reine Funktionalität abgebildet, um das Escaping müsste man sich noch kümmern. Ausserdem wird noch die Mysql- Version genutzt, mysqli hatte ich da noch nicht zur Verfügung...)

  
// Für die bessere Lesbarkeit der eigentlichen Funktionalität sind die MySQL- Zugriffsfunktionen hier stark abgekürzt:  
  
function g($r) {  
                // g wie "get"  
		return mysql_fetch_assoc($r);  
	}  
  
function m($q) {  
                // m wie "mysql_query"  
		return mysql_query($q);  
	}  
  
function AddToBranch($was,$worin) {  
                // hängt ein Blatt an einen Ast an  
		$q = "SELECT * FROM settest WHERE name='$worin';";  
		$r = m($q);  
		$s = g($r);	// s['id'], s['name'], ...  
		//echo '<pre>'; var_dump($s); echo '</pre>';  
		  
		$LFT = $s['lft']; $RGT = $s['rgt'];  
		$q = "UPDATE settest SET rgt=rgt+2 WHERE rgt>=$RGT;";  
		$r = m($q);  
		  
		$q = "UPDATE settest SET lft=lft+2 WHERE lft>$RGT;";  
		$r = m($q);  
		  
		$lft = $RGT; $rgt = $RGT+1;  
		$q = 'INSERT INTO settest (name,lft,rgt) VALUES (\''.$was.'\','.$lft.','.$rgt.');';  
		$r = m($q);  
		//echo mysql_insert_id();  
	}  
  
function InsertBefore($was, $wovor) {  
		$q = "SELECT * FROM settest WHERE name='$wovor';";  
		$r = m($q);  
		$s = g($r);  
		$LFT = $s['lft']; $RGT = $LFT+1;  
		  
		$q = "UPDATE settest SET lft=lft+2 WHERE lft>=$LFT;";  
		$r = m($q);  
		  
		$q = "UPDATE settest SET rgt=rgt+2 WHERE rgt>=$LFT;";  
		$r = m($q);  
		  
		$q = "INSERT INTO settest (name,lft,rgt) VALUES ('$was',$LFT,$RGT);";  
		$r = m($q);  
	}  
	  
	function DeleteItem($was) {  
		// lft und rgt ermitteln  
		$q = 'SELECT lft,rgt FROM settest WHERE name=\''.$was.'\';';  
		$s = g(m($q));  
		$LFT = $s['lft']; $RGT = $s['rgt'];  
		$q = "DELETE FROM settest WHERE lft BETWEEN $LFT AND $RGT;";  
		$r = m($q);  
		$minus = $RGT-$LFT+1;  
		$q = "UPDATE settest SET lft=lft-$minus WHERE lft>$RGT;";  
		$r = m($q);  
		$q = "UPDATE settest SET rgt=rgt-$minus WHERE rgt>$RGT;";  
		$r = m($q);  
	}  
	  
	function AppendItem ($was,$wohin) {  
		// hängt ein bereits bestehendes Item (Blatt oder Ast) an ein anderes (auch Blatt oder Ast) an  
		// und löscht es von seiner ursprünglichen Position  
		  
		// lft und rgt vom zu verschiebenden Element holen  
		$r=m("SELECT lft,rgt FROM settest WHERE name='$was';");  
		$set=g($r); $BaumLft=$set['lft']; $BaumRgt=$set['rgt'];  
		  
		// GRösse des zu verschiebenden Elements  
		$gr=$BaumRgt-$BaumLft+1;  
		  
		// lft und rgt vom Zielelement holen  
		$r=m("SELECT lft,rgt FROM settest WHERE name='$wohin';");  
		$set=g($r); $TargetLft=$set['lft']; $TargetRgt=$set['rgt'];  
		  
		// im Zielelement Platz schaffen  
		m("UPDATE settest SET lft=lft+$gr WHERE lft>=$TargetRgt;");  
		m("UPDATE settest SET rgt=rgt+$gr WHERE rgt>=$TargetRgt;");  
		  
		// Korrektur für den Fall, dass der Baum an eine Position VOR seiner alten verschoben wird. Dann ist nämlich der Baum selbst beim Lückeschaffen betroffen gewesen  
		if (($BaumLft > $TargetLft)&&($BaumRgt > $TargetRgt)) {  
			$BaumLft = $BaumLft+$gr; $BaumRgt = $BaumRgt+$gr;  
		}  
		  
		// Element an seine neue Position verschieben  
		m("UPDATE settest SET lft=$TargetRgt+lft-$BaumLft, rgt=$TargetRgt+rgt-$BaumLft WHERE lft BETWEEN $BaumLft AND $BaumRgt;");  
		  
		// entstandene Lücke wieder schliessen  
		m("UPDATE settest SET lft=lft-$gr WHERE lft>$BaumLft;");  
		m("UPDATE settest SET rgt=rgt-$gr WHERE rgt>$BaumRgt;");  
	}  
	  
	function MoveItemBefore($was, $wohin) {  
		// verschiebt ein Blatt oder einen Ast von seiner ursprünglichen Position VOR das Target  
		  
		// lft und rgt vom zu verschiebenden Baum bestimmen  
		$r=m("SELECT lft,rgt FROM settest WHERE name='$was';");  
		$set=g($r); $BaumLft=$set['lft']; $BaumRgt=$set['rgt'];  
		// lft und rgt vom Target bestimmen  
		$r=m("SELECT lft,rgt FROM settest WHERE name='$wohin';");  
		$set=g($r); $TargetLft=$set['lft']; $TargetRgt=$set['rgt'];  
		//Grösse des Baums bestimmen  
		$gr=$BaumRgt-$BaumLft+1;  
		// vor dem Target eine Lücke schaffen:  
		m("UPDATE settest SET lft=lft+$gr WHERE lft>=$TargetLft;");  
		m("UPDATE settest SET rgt=rgt+$gr WHERE rgt>=$TargetLft;");  
		  
		// Korrektur für den Fall, dass der Baum an eine Position VOR seiner alten verschoben wird. Dann ist nämlich der Baum selbst beim Lückeschaffen betroffen gewesen  
		if ($BaumLft > $TargetLft) {  
			$BaumLft = $BaumLft+$gr; $BaumRgt = $BaumRgt+$gr;  
		}  
		  
		// den zu verschiebenden Baum an seine neue jetzt freie Position verschieben  
		m("UPDATE settest SET lft=$TargetLft+lft-$BaumLft, rgt=$TargetLft+rgt-$BaumLft WHERE lft BETWEEN $BaumLft AND $BaumRgt;");  
		// die entstandene Lücke an der ursprünglichen Position des Baums wieder schliessen  
		m("UPDATE settest SET lft=lft-$gr WHERE lft>$BaumLft;");  
		m("UPDATE settest SET rgt=rgt-$gr WHERE rgt>$BaumRgt;");  
		// das sollte es gewesen sein.  
	}  

Vielleicht kannst Du damit ja was anfangen. Falls nicht, bitte einfach ignorieren ;-)

Beste Grüsse,
    Tobias Hahner