+ Antworten
Seite 3 von 8 ErsteErste 1 2 3 4 5 6 ... LetzteLetzte
Ergebnis 31 bis 45 von 120

Thema: [Workshop] Nested Sets

  1. #31
    TP-Specialist theo bringt sich richtig ein Avatar von theo
    Registriert seit
    Apr 2002
    Ort
    743, evergreen terrace
    Beiträge
    2.343
    hi kworth,

    fuer ein forum ansich duerfte der einsatz der nested sets schon eine gute idee sein. nur wuerde ich nicht nur den grossen zeitlichen aufwand beim einbinden der posts fuer unsinnig halten. nach den foren, in denen ich mich normalerweise aufhalte zu urteilen, ist die loesung wie hier im tp am sinnvollsten: ein aktualisierter thread wandert nach oben. in foren, wie z.b. www.3dmax.de, wo das nicht der fall ist, verliert man schnell die uebersicht und vor allem geraten themen, in denen noch geschrieben wird, immer weiter "nach hinten" und damit in vergessenheit oder werden einfach uebersehen.
    aber was deine frage nach den querys angeht, so wirst du nicht um das immer wieder erneute senden der anfragen an die db herumkommen. ganz einfach schon aus dem grunde nicht, weil es sich um ein forum handelt! d.h. die leute sollen ja schreiben und der inhalt der db aendert sich permanent. also musst du auch staendig eine aktualisierte abfrage holen.

    gruss
    hardy
    /b{2}|[^(bb)]/

    [Workshop] Nested sets

  2. #32
    TP-Senior mat81 macht alles soweit korrekt Avatar von mat81
    Registriert seit
    Jun 2005
    Ort
    Köln
    Beiträge
    241

    Fortschritte?

    Hallo Theo und Fans dieses Tutorials,

    ich bin froh, dieses Tutorial gefunden zu haben und versuche die SQL-Anweisungen Stück für Stück zu verstehen. Das Prinzip hab ich im Grunde verstanden. Ich hab, wie die meisten, die sich den Code mal genauer angesehen haben, gesehen, dass du, Theo, schonmal nen Link fürs Abwärtsverschieben eingebaut hast.

    Daher nun auch die Frage: Hattest du schon die Möglichkeit Fortschritte zu machen?

    Es geht um die Punkte
    1. Abwärtsverschieben von Blättern/Teilbäumen
    2. Verschieben in eine andere Ebene

    Die Punkte wurden ja vor einiger Zeit schon angesprochen, doch leider hab ich noch keine Antworten darauf gefunden.

    Ich versuche auch selbst nen Ansatz zu finden, aber bin noch nicht sehr zuversichtlich.



    Viele Grüße

    von mir aus hier ;-)
    Geändert von mat81 (19.09.2005 um 17:22 Uhr)

  3. #33
    TP-Specialist theo bringt sich richtig ein Avatar von theo
    Registriert seit
    Apr 2002
    Ort
    743, evergreen terrace
    Beiträge
    2.343

    Talking seid mein schlechtes gewissen!

    hallo mat81,

    schoen, wenn ich immer wieder an meine versprechen erinnert werde. ich hab sie auch wirklich nicht vergessen. es ist nur so, dass ich im real life derzeit etwas mit arbeit zugeschuettet wurde und daher wenig zum probieren und testen kam.
    aber ich bleibe dran und werde neue erkenntnisse sofort posten.

    gruss
    hardy (der demnaechst auch noch umziehen wird)
    /b{2}|[^(bb)]/

    [Workshop] Nested sets

  4. #34
    TP-Senior mat81 macht alles soweit korrekt Avatar von mat81
    Registriert seit
    Jun 2005
    Ort
    Köln
    Beiträge
    241

    Denkanstoß

    Kein Thema, Theo.
    Ich versuch ja auch selbst die Lösung zu finden. Im Moment hab ich mir mal ein paar Skizzen als Denkanstoß (evtl. auch für alle Interessierten) gemacht. Sie sind nicht sehr schön, aber darum gehts auch nicht.
    Hoffentlich sind diese Hilfreich. Ich grübel noch...



    Die orange gefärbten Rechtecke markieren die veränderten Elemente.
    Offensichtlich stehen die rot markierten Zahlen für die veränderten L- bzw R-Werte.


    Aus der Skizze folgt:

    B.R (neu) = B.R - (B2_1.R - B2_1.L + 1)


    für alle L und R von B2_1.L bis B.R (neu):

    L (neu) = L-1
    R (neu) = R-1

    für alle L und R von B2_1.R bis B2_1.L:

    L (neu) = L - (B2_1.R - B2_1.L + 1)
    R (neu) = R - (B2_1.R - B2_1.L + 1) = L (neu) + 1


    Wie man dies nun allerdings gescheit in SQL umsetzt, kann ich noch nicht sagen. Ich hoffe, dass die Folgerungsterme halbwegs verständlich sind.


    Zusatz:

    Theo, könntest du mir den SET-Part aus dem MoveUp-Teil mal erklären?
    Ich hab schon oft mit MySQL zu tun gehabt, aber diese seltsame IF-Anweisung ist mir etwas suspekt. Ich wollte mich nämlich mal um die MoveDown-Variante kümmern. Dazu müßte ich aber erstmal den MoveUp-Teil beherrschen.

    PHP-Code:
        $sql "UPDATE node
             SET lft = lft + IF(lft<"
    .$nodes[2].",".$inc.",-".$desc."),
             rgt = rgt + IF(rgt<"
    .$nodes[2].",".$inc.",-".$desc.")
             WHERE root_id = "
    .$nodes[0]."
             AND lft >= "
    .$nodes[5]."
             AND rgt <= "
    .$nodes[3].""
    Danke schonmal :-)
    Geändert von mat81 (20.09.2005 um 19:54 Uhr)

  5. #35
    TP-Specialist theo bringt sich richtig ein Avatar von theo
    Registriert seit
    Apr 2002
    Ort
    743, evergreen terrace
    Beiträge
    2.343
    So ... also mal ganz kurz zwischendurch, weil es Dich ja wirklich stark zu beschäftigen scheint. Ist aber nur etwas Theo-rie.

    Wenn ich einen Zweig oder Knoten verschieben will, dann muss ich, egal in welche Richtung geschoben wird, wie folgt vorgehen:
    Zunächst brauche ich die beiden Kanditaten, die getauscht werden sollen (wir reden ja immer von einem schrittweisen Verschieben). Das geht am besten über die ID der beiden.
    Dann brauchen wir die linken und rechten Seiten der beiden Knoten. Aus denen bekommen wir die Anzahl der Knoten im Zweig. Im einfachsten Fall werden nur zwei Knoten gegeneinander getauscht.
    Da beide Knoten die Plätze wechseln, bekommt der Knoten, der an die Stelle des anderen wandert, die linke Seite des ersteren zugewiesen.
    Jetzt wissen wir aber schon, wieviele Kinder im Zweig sind und nach dem Preorder-Walk werden sie alle neu durchnumeriert. Damit kommen wir zur rechten Seite des neu positionierten Knotens. Diese plus eins ist die linke Seite des zweiten Knotens. Da wir von dem auch wissen, wieviele Kinder im Zweig sind, können wir nun auch diese durchnumerieren lassen.

    Nach diesem System sind die Anweisungen für das Verschieben von Zweigen und Knoten in beide Richtungen prinzipell identisch. Die Vorzeichen ändern sich, da sich die Richtung der Änderung ändert.

    Grundprinzip bleibt: beide Knoten mit ihren linken und rechten Seiten ermitteln, jeweilige Anzahl der Knoten errechnen und beim Tausch der Plätze beide Zweige neu numerieren lassen.

    Zum besseren Verständnis werde ich, sobald ich etwas mehr Luft habe, noch eine Grafik nachliefern, die das Ganze besser erklären wird, als ich das mit Worten kann.
    Und dann folgen sicher auch bald die fehlenden Statements. Die werd ich dann auch noch mal im Detail erläutern.

    Dank für Deine Hartnäckigkeit und Deine Mühe mit dem grafischen Denkanstoß. Ich hoffe ich kann mich bald mit einem ausfühlicheren Kapitel für diesen Workshop revanchieren.

    Gruss
    Hardy
    /b{2}|[^(bb)]/

    [Workshop] Nested sets

  6. #36
    TP-Specialist theo bringt sich richtig ein Avatar von theo
    Registriert seit
    Apr 2002
    Ort
    743, evergreen terrace
    Beiträge
    2.343
    Kleiner Nachtrag zu der "suspekten IF-Anweisung" (hatte ich völlig vergessen)

    Die Anweisung sieht wie folgt aus;
    IF(ausdruck,wert1,wert2)

    Wenn der Ausdruck wahr ist, wird der Wert1 zurückgegeben, ansonsten Wert2.
    /b{2}|[^(bb)]/

    [Workshop] Nested sets

  7. #37
    TP-Senior mat81 macht alles soweit korrekt Avatar von mat81
    Registriert seit
    Jun 2005
    Ort
    Köln
    Beiträge
    241

    Lightbulb runterschieben = hochschieben

    hey theo und nestsetters

    ich hab mal die Funktion nodeMove etwas umgestrickt, sodass auch das Verschieben nach unten möglich ist. Nach meinen bisherigen Tests gabs keine Probleme. *erfolgbautauf*

    Hier erstmal der alte Code:

    PHP-Code:
    function nodeMove($id,$direction) {
             
    // gibt den selektierten knoten + vorgänger in gleicher ebene mit infos aus
            
    $sql "SELECT    n1.root_id,
                    n1.payload n1payload, n1.lft n1lft, n1.rgt n1rgt,
                    n2.payload n2payload, n2.lft n2lft, n2.rgt n2rgt
                    FROM node AS n1
                    LEFT OUTER JOIN
                    node AS n2
                    ON (n1.lft = (n2.rgt+1) 
                        AND    n1.rgt > n2.rgt
                        AND n1.root_id = n2.root_id)
                    WHERE n1.node_id="
    .$id."";
            
            
    $result mysql_query($sqlconnectDB());
            
            
    $nodes mysql_fetch_row($result);
            
    $result mysql_query($sqlconnectDB());

            if (!
    $nodes[5]) $error "<p>Kein übergeordneter Knoten vorhanden!</p>";

            
    $desc = (($nodes[2]-$nodes[5])); // left-differenz von nachfolger und vorgänger
            
    $inc = (($nodes[3]-$nodes[6])); // right-differenz von nachfolger und vorgänger
            
            
    if ($direction == "down"):
                
    $sql "UPDATE node
                        SET    lft = lft - IF(lft<"
    .$nodes[2].",".$inc.",-".$desc."),
                        rgt = rgt - IF(rgt<"
    .$nodes[2].",".$inc.",-".$desc.")
                        WHERE root_id = "
    .$nodes[0]."
                        AND    lft >= "
    .$nodes[5]."
                        AND    rgt <= "
    .$nodes[3]."";            
            else:
                
    $sql "UPDATE node
                        SET    lft = lft + IF(lft<"
    .$nodes[2].",".$inc.",-".$desc."),
                        rgt = rgt + IF(rgt<"
    .$nodes[2].",".$inc.",-".$desc.")
                        WHERE root_id = "
    .$nodes[0]."
                        AND lft >= "
    .$nodes[5]."
                        AND rgt <= "
    .$nodes[3]."";
            endif;
            
    $result mysql_query($sqlconnectDB());
            
            return 
    $error;

    Und hier nun der neue Code:

    PHP-Code:
    function nodeMove($id,$direction) {
     
    // --> neu
    // hier geh ich vor wie bei up. jedoch brauch ich hierfür die id des nachfolgers,
    // sodass ein up des nachfolgers erfolgen kann        
    if ($direction == "down"):
                
    $sql "SELECT n2.node_id
                        FROM node AS n1
                        LEFT OUTER JOIN
                            node AS n2
                        ON (n2.lft = (n1.rgt+1))
                        WHERE n1.node_id="
    .$id."
                        AND n1.root_id = n2.root_id"
    ;
                
                
    $result mysql_query($sqlconnectDB());
                
    $nachfolger mysql_fetch_row($result);            
                
    $id $nachfolger [0];
            endif; 
     

    // unverändert
             // gibt den selektierten knoten + vorgänger in gleicher ebene mit infos aus
            
    $sql "SELECT    n1.root_id,
                        n1.payload n1payload, n1.lft n1lft, n1.rgt n1rgt,
                        n2.payload n2payload, n2.lft n2lft, n2.rgt n2rgt
                    FROM node AS n1
                    LEFT OUTER JOIN
                        node AS n2
                    ON (n1.lft = (n2.rgt+1) 
                        AND    n1.rgt > n2.rgt
                        AND n1.root_id = n2.root_id)
                    WHERE n1.node_id="
    .$id."";
            
            
    $result mysql_query($sqlconnectDB());
            
            
    $nodes mysql_fetch_row($result);
            
    $result mysql_query($sqlconnectDB());

            if (!
    $nodes[5]) $error "<p>Kein übergeordneter Knoten vorhanden!</p>";

            
    $desc = (($nodes[2]-$nodes[5])); // left-differenz von nachfolger und vorgänger
            
    $inc = (($nodes[3]-$nodes[6])); // right-differenz von nachfolger und vorgänger

    // und hier ist nur noch der else-zweig übrig geblieben, das wars

            
    $sql "UPDATE node
                    SET    lft = lft + IF(lft<"
    .$nodes[2].",".$inc.",-".$desc."),
                    rgt = rgt + IF(rgt<"
    .$nodes[2].",".$inc.",-".$desc.")
                    WHERE root_id = "
    .$nodes[0]."
                    AND lft >= "
    .$nodes[5]."
                    AND rgt <= "
    .$nodes[3]."";
            
            
    $result mysql_query($sqlconnectDB());
            
            return 
    $error;

    Also für die, die die Frau in rot nicht in dem Matrix-Code erkennen können. ;-)

    Im Prinzip funktioniert hier das Runterschieben (bzw. das Verschieben nach rechts) genauso, als ob man stattdessen den Nachfolger nach oben (bzw. links) verschiebt. Denn es wird einfach nur die entsprechende ID des Nachfolgers ausgelesen und der Rest läuft wie gehabt ab, nur eben mit der Nachfolger-ID.

    Natürlich gibts nen Fehler, wenn man den letzten Knoten des entsprechenden Teilbaumes nach unten verschieben möchte. Ich hab mir die Fehlerbehandlung geschenkt, da ich lieber vorher schon den Fehler abfangen, sprich den entsprechenden Button an der Stelle weglassen möchte.

    Meiner Meinung nach ist die Idee gar nicht schlecht. Zwar beim 1. Durchblicken etwas unsauber, im nachhinein aber elegant. Oder bin ich aufm Holzweg?

    Danke Theo, für die Erklärungen bis hier hin. Weiter so
    Geändert von mat81 (22.09.2005 um 18:14 Uhr)

  8. #38
    TP-Specialist theo bringt sich richtig ein Avatar von theo
    Registriert seit
    Apr 2002
    Ort
    743, evergreen terrace
    Beiträge
    2.343
    Glückwunsch!

    Heute Abend werde ich Dein Script mal testen. Wenn es wirklich läuft, dann wäre das ein wirklich schöner Erfolg für diesen Workshop.

    Hardy
    /b{2}|[^(bb)]/

    [Workshop] Nested sets

  9. #39
    TP-Senior mat81 macht alles soweit korrekt Avatar von mat81
    Registriert seit
    Jun 2005
    Ort
    Köln
    Beiträge
    241

    Exclamation the show must go on oder so ;-)

    Zitat Zitat von theo
    Glückwunsch!

    Heute Abend werde ich Dein Script mal testen. Wenn es wirklich läuft, dann wäre das ein wirklich schöner Erfolg für diesen Workshop.

    Hardy
    Hey Theo, ich hoffe du kamst schon zum Testen, denn es funktioniert bei mir immernoch tadellos!

    Ich hab auch noch eine wichtige Erweiterung gebastelt: Wurzeln verschieben

    Zudem hab ich den Adminbereich an die Baumstruktur angepasst, wie man hier sieht:



    Die ganzen Buttons häufen sich zwar, dafür hat man IMHO eine bessere Übersicht und erkennt sofort was passiert.

    Nun aber zu den Änderungen:


    1. Es muss eine neue Spalte in der Datenbank - am Ende der Tabelle node - angelegt werden.

    Die Spalte heißt in meinem Beispiel einfach root_seq (abgeleitet von sequence und bedeutet soviel, dass dort die Reihenfolge der Knoten gespeichert wird).

    Eigentlich geschiet dies ja schon in der root_id. Doch hatte ich Probleme als ich mit dieser arbeitete, also hab ich ne zusätzliche Spalte eingefügt.

    Der Sinn liegt einfach darin, dass hier eine lückenlose Aufreihung der Wurzeln inkl. Blättern usw. erfolgt.

    Praktisches Beispiel:

    Wir nehmen eine Tabelle an wie wir sie kennen (lft und rgt lass ich der übersicht halber einfach mal weg)
    Code:
    root_id  payload
    
    1         root1
    2         root2
    3         root3
    4         root4
    5         root5
    Löscht man hier z.B. root3 entsteht eine Lücke bei den root_id's.

    Code:
    root_id  payload
    
    1         root1
    2         root2
    4         root4
    5         root5
    Hier kommt die root_seq ins Spiel. Die Tabelle vor dem Löschen von root3

    Code:
    root_id  payload  root_seq
    
    1         root1      1
    2         root2      2
    3         root3      3
    4         root4      4
    5         root5      5
    Und jetzt nach dem Löschen von root3

    Code:
    root_id  payload  root_seq
    
    1         root1      1
    2         root2      2
    4         root4      3
    5         root5      4
    Die Anpassung der root_seq's ab root4 erfolgt natürlich irgendwo im Skript (das zeig ich dir/euch auch gleich).

    Dank dieser lückenlosen Abfolge kann man dann relativ einfach eine Wurzel verschieben, indem man deren root_seq einfach mit dem nachfolger bzw. vorgänger tauscht.

    Mir kam (auch) der Gedanke, dass die Spalte überflüssig ist und dass man es auch mit der root_id lösen könnte. Wie gesagt scheiterte ich daran, denn die Blätter der Wurzeln wurden bei mir auf diesem Wege immer zu Waisen.

    Nu gehts aber los!


    Hier suchen wir uns die größte ODER die kleinste root_seq raus.
    Wozu das ganze? Das sag ich euch gleich. ;-)
    PHP-Code:
     /** min und max root_seq - dient später zum benutzen der verschiebefunktion von roots **/
     
    function getRootExtremes($welches) {    
        if (
    $welches == 'min'):
            
    $sql "SELECT min(root_seq) AS min FROM node";
            
    $result mysql_query($sqlconnectDB());
            
    $row mysql_fetch_array($result);
            return 
    $row['min'];
        else:
            
    $sql "SELECT max(root_seq) AS max FROM node";
            
    $result mysql_query($sqlconnectDB());
            
    $row mysql_fetch_array($result);
            return 
    $row['max'];
        endif;
     } 
    Wozu diese Funktion? Ganz einfach, im Adminbereich soll ein Hochschieben von Wurzeln doch nur möglich sein, wenn die Wurzel nicht eh schon ganz oben steht. Dasselbe gilt fürs Abwärtsschieben.

    Im folgenden müßt ihr den 1. Zweig von showNavi()
    also alles zwischen
    PHP-Code:
    if ($_REQUEST['site'] == "admin"): 
    und
    PHP-Code:
    else 
    gegen das hier austauschen:

    PHP-Code:
            $level 1;
            
    $tree.= '<ul id="NewTree">';
            
            
            while(
    $row mysql_fetch_array($result)) {
                    
                if (
    $row['level'] > $level// wenn neuer level
                    
    $tree.= '<ul>';
                else if (
    $row['level'] < $level)
                    
    $tree.= str_repeat('</li></ul>'$level-$row['level']);
                else if (
    $level 1)
                    
    $tree.= '</li>';
                
                
    $tree.= '<li value_id="'.$row['node_id'].'" level="'.$row['level'].'" input_id="'.$row['root_id'].'" productgroupname="" input_type="">';
                
    $tree.= '<span>'.$row['payload']; // name
                // die nächsten beiden ifs werden leider nicht für roots berücksichtigt
                // hochrutschen nur wenn vorgänger vorhanden
                
    if (($row['upper'] == 1)):
                    
    $tree.= ' <a href="'.$PHP_SELF.'?site=admin&action=moveup&id='.$row[0].'"><img src="img/up.png" border="0"></a> ';        // hochschieben
                
    endif;                        
                
    // runterrutschen nur wenn nachfolger vorhanden
                
    if ($row['lower'] == 1):
                    
    $tree.= ' <a href="'.$PHP_SELF.'?site=admin&action=movedown&id='.$row[0].'"><img src="img/down.png" border="0"></a> ';        // hochschieben
                
    endif;
        
    // root-verschiebebuttons    
                // die nächsten beiden ifs werden NUR für roots berücksichtigt
                // hochrutschen nur wenn es ein root ist (also lft = 1) und größer als minimalwert
                
    if (($row['root_seq'] > getRootExtremes('min')) && ($row['lft'] == 1)):
                    
    $tree.= ' <a href="'.$PHP_SELF.'?site=admin&action=rootmoveup&id='.$row[0].'"><img src="img/up.png" border="0"></a> ';        // hochschieben
                
    endif;                        
                
    // runterrutschen nur wenn es ein root ist (also lft = 1) und kleiner als der maximalwert
                
    if (($row['root_seq'] < getRootExtremes('max')) && ($row['lft'] == 1)):
                    
    $tree.= ' <a href="'.$PHP_SELF.'?site=admin&action=rootmovedown&id='.$row[0].'"><img src="img/down.png" border="0"></a> ';        // hochschieben
                
    endif;
                
                
    $tree.= '<a href="'.$PHP_SELF.'?site=admin&action=edit&id='.$row[0].'"><img src="img/edit.png" border="0"></a> ';        // umbenennen
                
    $tree.= '<a href="'.$PHP_SELF.'?site=admin&action=insert&id='.$row[0].'"><img src="img/insert.png" border="0"></a> ';    // unterhalb einfügen
                
    $tree.= '<a href="'.$PHP_SELF.'?site=admin&action=del&id='.$row[0].'"><img src="img/del.png" border="0"></a></span>';    // löschen
                
    $level $row['level'];
            } 
    // while
            
    $tree.= str_repeat('</ul>'$level-1); 
    Ihr seht schon: Auch die Einträge, die keine Wurzel sind (also alles innerhalb einer Wurzel), bekommen den hoch- und runterschiebebutten nur, wenn sie nicht erstes bzw. letztes Element im Teilbaum sind. Guckt euch dazu am besten einfach nochmal die obere Grafik (in diesem Posting) an.

    Im in der getNavi() müßt ihr nur die Zeile (kommt 2x vor)
    PHP-Code:
    ORDER BY n.root_id,n.lft"; 
    mit root_seq erweitern, also so
    PHP-Code:
    ORDER BY n.root_seq,n.root_id,n.lft"; 
    Doch damit das alles funktioniert, fehlt noch was: rootMove() ;-)

    Ich geh dabei nach folgendem, typischen Tauschschema vor:

    Beispiel:

    Code:
    a = 1
    b = 2
    c = 3
    
    nun möchte ich b und c tauschen:
    
    b = 0 // da 0 ja eh nie auftaucht, ist das hier ne temporäre zuweisung
    c = 2
    b = 3
    Ich bin mir nicht sicher, obs in sql geschicktere Lösungen gibt. Da wärs nett, wenn mich jemand verbessert.

    PHP-Code:
     /** wurzeln verschieben **/
     
    function rootMove($id,$direction) {
             
            
    $node getNode($id);
                     
            if (
    $direction == "down"):
                
    // erstmal die auszutauschenden werte auf 0 setzen
                
    $sql "UPDATE node
                        SET root_seq = 0
                        WHERE root_seq = "
    .$node[5];
                
    $result mysql_query($sqlconnectDB());
                
                
    // root_seq anpassen - sprich die nachfolger um 1 vermindern
                
    $sql "UPDATE node
                        SET root_seq = root_seq - 1
                        WHERE root_seq = "
    .$node[5]." + 1";
                
    $result mysql_query($sqlconnectDB());
                
                
    // die soeben genullten werte auf das ursprüngliche + 1 erhöhen
                
    $sql "UPDATE node
                        SET root_seq = "
    .$node[5]." + 1
                        WHERE root_seq = 0"
    ;
                
    $result mysql_query($sqlconnectDB());            
            else:
                
    // erstmal die auszutauschenden werte auf 0 setzen
                
    $sql "UPDATE node
                        SET root_seq = 0
                        WHERE root_seq = "
    .$node[5];
                
    $result mysql_query($sqlconnectDB());
                
                
    // root_seq anpassen - sprich die vorgänger um 1 erhöhen
                
    $sql "UPDATE node
                        SET root_seq = root_seq + 1
                        WHERE root_seq = "
    .$node[5]." - 1";
                
    $result mysql_query($sqlconnectDB());
                
                
    // die soeben genullten werte auf das ursprüngliche um 1 vermindern
                
    $sql "UPDATE node
                        SET root_seq = "
    .$node[5]." - 1
                        WHERE root_seq = 0"
    ;
                
    $result mysql_query($sqlconnectDB());
            endif;
     } 
    Nun sind die root_seq-Werte vertauscht. Entweder getauscht mit dem Vorgänger oder mit dem Nachfolger, je nachdem welchen Pfeil man klickt.

    Doch damit das ganze aufgerufen wird, brauchen wir noch einen Zusatz in der index.php

    Dort fügt ihr das
    PHP-Code:
    case "rootmoveup"
             
    $error rootMove($_REQUEST['id'],"up");
             break;
         case 
    "rootmovedown"
             
    $error rootMove($_REQUEST['id'],"down");
             break; 
    direkt unter der Zeile
    PHP-Code:
    switch($_REQUEST['action']){ 
    oder wo auch immer (hauptsache anständig im switch-konstrukt) ein.

    Jetzt sind wir auch schon fast fertig. 2 Schritte fehlen noch auf dem Weg zur Wurzelbehandlung *ha der war gut*

    Zunächst gehts noch ums Löschen der Wurzeln. Wenn eine Wurzel gelöscht wird, müssen die Werte für root_seq der nachfolgenden Wurzeln um 1 vermindert werden, um die Lücke zu schließen.

    Dazu fügt ihr in der Funktion nodeDel()
    einfach das hier ein:
    PHP-Code:
    $sql "UPDATE node
                SET root_seq = root_seq - 1
                WHERE root_seq > "
    .$node[5];
        
    $result mysql_query($sqlconnectDB()); 
    Nun gehts an die letzte Funktion nodeIns():

    Um beim Einfügen der Knoten auch brav die zugehörige root_seq einzufügen, muss beim INSERT auch root_seq angegeben werden. Also aus
    PHP-Code:
    $sql "INSERT INTO node (root_id,payload,lft,rgt)
                            VALUES ("
    .$node[1].",'".$name."',".$node[3].",".($node[3]+2).")"
    wird
    PHP-Code:
    $sql "INSERT INTO node (root_id,payload,lft,rgt,root_seq)
                            VALUES ("
    .$node[1].",'".$name."',".$node[3].",".($node[3]+2).",".$node[5].")"
    Tauscht das eben genannte bitte nicht einfach blind aus. Erweitert die letzte Spalte lieber, um auf Nr. sicher zu gehen. Denn es handelt sich um 2 unterschiedliche Statements, die erweitert werden müssen.

    Ich hab bei mir der Übersicht halber mysql_fetch_array, statt mysql_fetch_row benutzt. Angeblich ist es verschwindend langsamer, man kann jedoch mehr mit dem fremden Code anfangen, als mit bloßen Zahlen (ich zumindest).
    Doch keine Sorge, hier im Posting bleibt alles bei Zahlen - ihr brauch kein row gegen array tauschen.


    Den letzten else-zweig dieser Funktion (nodeIns) könnt ihr nun doch noch getrost gegen diesen Inhalt austauschen:

    PHP-Code:
    $sql "SELECT     max(root_id) as maxroot, max(root_seq) as maxrootseq
                    FROM node"
    ;
            
    $result mysql_query($sqlconnectDB());

            
    $row mysql_fetch_row($result);
            
    $root_id $row[0];
            
    $root_seq $row[1];
            
            
    $sql "INSERT INTO node (root_id,payload,lft,rgt,root_seq)
                    VALUES ("
    .($root_id+1).",'".$name."',1,2,".($root_seq+1).")";
                    
            
    $result mysql_query($sqlconnectDB()); 
    Das muss es gewesen sein. :-)
    Hoffentlich hab ich dem Tutorial, welches mir bis jetzt enorm geholfen hat, auch ein wenig geholfen.
    Geändert von mat81 (23.09.2005 um 11:15 Uhr)

  10. #40
    TP-Senior mat81 macht alles soweit korrekt Avatar von mat81
    Registriert seit
    Jun 2005
    Ort
    Köln
    Beiträge
    241

    Exclamation auweija

    Ich muss einen Fehler eingestehen.
    Zwar funktioniert die Abwärtsverschiebung von Knoten meistens, jedoch nicht immer, da mit dieser Abfrage, die ich an den Anfang von nodeMove() gesetzt habe, etwas nicht ganz stimmt.
    PHP-Code:
    if ($direction == "down"):
                
    $sql "SELECT n2.node_id
                        FROM node AS n1
                        LEFT OUTER JOIN
                            node AS n2
                        ON (n2.lft = (n1.rgt+1))
                        WHERE n1.node_id="
    .$id."";
                
                
    $result mysql_query($sqlconnectDB());
                
    $nachfolger mysql_fetch_row($result);            
                
    $id $nachfolger [0];
            endif; 
    Dort soll die ID des Nachfolgers in gleicher Ebene ausgegeben werden. Mitunter werden dort mehrere ID's ausgegeben. So ein Blödsinn.

    Die hat aber keine Auswirkungen auf das Verschieben von Wurzeln.
    Geändert von mat81 (22.09.2005 um 18:13 Uhr)

    The difference between theory and practice is
    that in theory there is no
    difference between theory and practice
    but in practice there is

  11. #41
    TP-Senior mat81 macht alles soweit korrekt Avatar von mat81
    Registriert seit
    Jun 2005
    Ort
    Köln
    Beiträge
    241

    Exclamation

    ACHTUNG:

    Habe den Fehler entdeckt:

    Es fehlt der Vergleich mit der root_id beim Runterverschieben von Knoten

    also muss es in der nodeMove() am Anfang so aussehen (habe den Fehler nun auch in der Anleitung - 3 posts drüber - ausgebessert)

    PHP-Code:
    if ($direction == "down"):
                
    $sql "SELECT n2.node_id
                        FROM node AS n1
                        LEFT OUTER JOIN
                            node AS n2
                        ON (n2.lft = (n1.rgt+1))
                        WHERE n1.node_id="
    .$id."
                        AND n1.root_id = n2.root_id"
    ;
                
                
    $result mysql_query($sqlconnectDB());
                
    $nachfolger mysql_fetch_row($result);            
                
    $id $nachfolger [0];
            endif; 
    PS: Sorry fürs 2malige Posting, habe mich verdrückt.
    Geändert von mat81 (22.09.2005 um 18:17 Uhr)

    The difference between theory and practice is
    that in theory there is no
    difference between theory and practice
    but in practice there is

  12. #42
    TP-Senior mat81 macht alles soweit korrekt Avatar von mat81
    Registriert seit
    Jun 2005
    Ort
    Köln
    Beiträge
    241
    Hi tommes und willkommen im Fourm (ok, bin ebenfalls recht neu hier).

    Zu dem Fehler, der auftauchte:

    Deshalb schrieb ich ja noch die warnenden Worte, dass man an dieser Stelle nicht einfach copy-pasten soll
    Ich wollt die eh schon zu lange Tutorial-Erweiterung von mir so kurz wie möglich halten und die Leute auch noch ein wenig mehr mitdenken lassen (sonst hätte ich einfach den ganzen Code angeboten). Aber ich werde die Warnung an entsprechender Stelle sofort hervorheben.

    Schön, dass es auch bei dir klappt. Je mehr Tester, desto besser. Und schön, dass meine Erweiterung verständlich war. *aufdieschulterklopf*

    Ich hoffe, dass dieses Tutorial jetzt wieder mehr Aufmerksamkeit bekommt und die Leute (gerade die Gründer des Tutorials) wieder mehr Antrieb erhalten, weiter zu machen.
    Geändert von mat81 (23.09.2005 um 11:19 Uhr)

    The difference between theory and practice is
    that in theory there is no
    difference between theory and practice
    but in practice there is

  13. #43
    TP-Specialist theo bringt sich richtig ein Avatar von theo
    Registriert seit
    Apr 2002
    Ort
    743, evergreen terrace
    Beiträge
    2.343
    Zitat Zitat von mat81
    Ich hoffe, dass dieses Tutorial jetzt wieder mehr Aufmerksamkeit bekommt und die Leute (gerade die Gründer des Tutorials) wieder mehr Antrieb erhalten, weiter zu machen.
    Daran soll es nicht mangeln. Gerade die Aktivitäten der letzten Tage freuen mich besonders!
    Wenn mir jetzt noch jemand etwas Zeit schenken könnte, dann würde ich mich auch liebend gern wieder an dem Spiel beteiligen.
    /b{2}|[^(bb)]/

    [Workshop] Nested sets

  14. #44
    TP-Senior mat81 macht alles soweit korrekt Avatar von mat81
    Registriert seit
    Jun 2005
    Ort
    Köln
    Beiträge
    241

    Thumbs up

    Zitat Zitat von theo
    Wenn mir jetzt noch jemand etwas Zeit schenken könnte, dann würde ich mich auch liebend gern wieder an dem Spiel beteiligen.
    *zeitschenk*

    The difference between theory and practice is
    that in theory there is no
    difference between theory and practice
    but in practice there is

  15. #45
    TP-Senior mat81 macht alles soweit korrekt Avatar von mat81
    Registriert seit
    Jun 2005
    Ort
    Köln
    Beiträge
    241

    Question Daddy

    Das sieht doch schonmal sehr schön aus!

    Mir brennt zur Zeit eine Frage unter den Nägeln.

    Wie kann ich beim auslesen der Navi (also dem Statement aus der getNavi() - Funktion) die jeweilige Vater-ID mit ausgeben lassen?

    Ein Beispiel aus der Funktion sieht ja wie folgt aus:

    PHP-Code:
    SELECT n.*,
        
    floor((n.rgt-n.lft-1)/2) AS childs,
        
    count(*)+(n.lft>1) AS level,
        ((
    min(p.rgt)-n.rgt-(n.lft>1))/2) > AS lower,
        (((
    n.lft-max(p.lft)>1))) AS upper
        FROM node n
    node p
    WHERE n
    .lft BETWEEN p.lft AND p.rgt
        
    AND (p.root_id n.root_id)
        AND (
    p.node_id != n.node_id OR n.lft 1)
        
    GROUP BY n.root_id,n.node_id
        ORDER BY n
    .root_seq,n.root_id,n.lft 
    Da fehlt mir aber noch der Vater jedes Knotens.

    The difference between theory and practice is
    that in theory there is no
    difference between theory and practice
    but in practice there is

+ Antworten
Seite 3 von 8 ErsteErste 1 2 3 4 5 6 ... LetzteLetzte

Ähnliche Themen

  1. [Workshop] Formmailer
    Von mike im Forum Workshops und Tutorials
    Antworten: 93
    Letzter Beitrag: 29.01.2009, 12:34
  2. [Workshop] Objektorientierte Programmierung in PHP
    Von Lars im Forum Workshops und Tutorials
    Antworten: 114
    Letzter Beitrag: 29.05.2007, 17:55
  3. Nested Sets und SQL-Querys
    Von martinR im Forum Traum-Dynamik
    Antworten: 0
    Letzter Beitrag: 17.11.2004, 11:15
  4. Nested Templates bei DW MX
    Von Haretürk im Forum Dreamweaver & andere Webeditoren
    Antworten: 3
    Letzter Beitrag: 19.01.2003, 22:29

Stichworte


Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

     

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51