Peter L.: Array mit Nested Set Werten zu Html-Liste/Menu verarbeiten

Beitrag lesen

Ich würde die erste Bedingung so umschreiben, dass sie zunächst nur prüft, ob ein Elternelement vorliegt (L+1<R). Auch dann musst du ja eine Ausgabe vornehmen. Aber nun muss anhand von Kindern entschieden werden, ob abgestiegen werden soll, oder ob man sich das sparen kann. Das heißt, innerhalb des if(Elter)-Blocks kommt nun die Abfrage, ob das nächste Element ein Kind ist.

Jetzt habe ich alle Elemente auf Level 0!? Ähm...

Mein Test-Array:

$this->arrMenuItems = array(  
    array('leftkey'=> '0',  
          'rightkey'=> '5',  
          'name'=> 'foobar'),  
    array('leftkey'=> '6',  
          'rightkey'=> '7',  
          'name'=>'hauptmenu punkt1'),  
    array('leftkey'=> '8',  
          'rightkey'=> '9',  
          'name'=>'submenu2 punkt1'),  
    array('leftkey'=> '10',  
          'rightkey'=> '11',  
          'name'=>'submenu2 punkt2'),  
    array('leftkey'=> '12',  
          'rightkey'=> '14',  
          'name'=>'hauptmenu punkt2')  
);

Und die Schleife:

$counter = count($this->arrMenuItems);  
for($i = 0; $i < $counter; $i++){  
    echo 'Name: '.$this->arrMenuItems[$i]['name']." - Level: ";  
    $arrParent = array_pop($this->arrStack);  
  
    // Elter gefunden  
    if($this->arrMenuItems[$i]['leftkey']+1 < $this->arrMenuItems[$i]['rightkey']){  
        // Elter hat Kind  
        if(isset($this->arrMenuItems[$i+1]) && $this->arrMenuItems[$i+1]['rightkey'] < $this->arrMenuItems[$i]['rightkey']){  
            echo count($this->arrStack)." \n";  
            $this->arrStack[] = $arrParent;  
            $this->arrStack[] = $this->arrMenuItems[$i];  
        // Elter hat kein Kind mehr ;(  
        }else{  
            echo count($this->arrStack)." \n";  
            $this->arrStack[] = $arrParent;  
        }  
        continue;  
    }  
  
    // Element ein Blatt?  
    if($this->arrMenuItems[$i]['leftkey']+1 == $this->arrMenuItems[$i]['rightkey'] && $this->arrMenuItems[$i]['rightkey'] < $arrParent['rightkey']){  
        echo count($this->arrStack)." \n";  
        $this->arrStack[] = $arrParent;  
        continue;  
    }  
  
    // Element höher oder neben des letzten Elter?  
    if($this->arrMenuItems[$i]['leftkey'] > $arrParent['rightkey']){  
        $this->arrStack[] = $arrParent;  
	// Array abbauen			  
        while($this->arrMenuItems[$i]['rightkey'] > $arrParent['rightkey'] && count($this->arrStack) != 0){  
            $arrParent = array_pop($this->arrStack);  
        }  
        echo count($this->arrStack)." \n";  
        continue;  
    }  
    // irgendwas vergessen?  
    echo 'hund';  
}

Du hast eine Menge Zugriffe auf das aktuelle Element. Es empfiehlt sich, $this->arrMenuItems[$i] in einer lokalen Variable ($current) abzulegen und die zu verwenden.

Ist das in dem Fall nicht egal? Und wenn nicht wo liegt der Unterschied beim Zugriff auf ein "lokales" 2 dimensionales Array und dem auf ein 3 dimensionales Klassenweites?

// letzten Elter suchen
    $arrParent = array_pop($this->arrStack);

Damit nimmst du den Elter auch vom Stack, was aber nur beim Aufsteigen passieren soll. Nimm an dieser Stelle end() und spar dir das Wiederdrauflegen. Beachte auch, dass array_pop() null und end() false liefert, wenn das Array leer ist.

Aber ich lege ihn ja auch immer wieder drauf. Und beim Vergleich als "Blatt" brauch ich ja auch das Elter. Deshalb habe ich es erstmal grundsätzlich abgezogen und immer wieder drauf gelegt. Wie gesagt, der Code ist noch nicht sehr elegant. Ich bin mir grad nicht sicher was du mit "beim Aufsteigen" meinst.
Meinst du meine while-Schleife?

Es geht nicht darum, die Variable aufzuräumen, sondern dass wenn da nochwas drinliegt, du noch abgestiegen bist. Für jedes Element, das da noch liegt, muss noch eine ul/li-Liste geschlossen werden.

Die Geschichte mit dem abbauen des Stacks muss ich mir nochmal durch den Kopf gehen lassen. Ich dachte, das würde ich in der while-Schleife schaffen. Um die Liste würde ich mir auch erst Gedanken machen wenn ich die Level zuverlässig ermitteln kann.

Aber was hab ich denn kaputt gemacht, dass jetzt jedes Level 0 ist? ôO