Andreas Korthaus: PHP: Baum verändern, Veränderung wie speichern?

Beitrag lesen

Hi!

Innerhalb der Ebenen zu vershcieben ist noch relativ einfach. Da mußt DUbeim ausgewählten Element nur die Parent_ID (wenn es ein 'Ordner' ist), oder die 'Ordner'-ID(wenn es ein Produkt ist) verändern.

Die Reihenfolgen zu ändern ist dann schon etwas schwieriger. Du müßtest imho, wie Du auch schon angedacht hast, eine Positionsnummer einführen (am Besten je 'Ordner' eindeutig). Wenn Du nun die Position verschieben willst, dann mußt Du ermitteln, welche Positionsnummern des aktuellen Elements und des Elements vor bzw nach dem aktuellen ermitteln und diese dann vertauschen.

Mein Problem ist zur Zeit weniger die Datenhaltung, eher das was wzischen Datenhaltung und Ausgabe kommt. Ich sollte mich wohl man von dem PHP-Array verabschieden und das direkt aus der DB in die Ausgabe überführen. Ich speicher dann nur noch einen Array mit den "aufgeklappten" Parent_IDs in der Session, entsprechend muss ich dann für jede darin enthaltenen ID die Unterketegoriene mir Reihenfolge ID aus der DB lesen, halt mit "order by reihenfolge_ID". Wobei, ich brauche zusätzlich noch die Information ob es Unterketegorien oder produkte in einer Kategorie gibt, das werden dann doch ein par Mehr Abfragen, da ich das für jede Kategorie machen muss.

Nur mal so:

Lebensmittel
  Getränke
  Molkereiprodukte
    Milchprodukte
      1 Liter Frische Vollmilch
      1 Liter fettarme Milch
      0,5 Liter frische Vollmilch
    Quarkprodukte
  Backwaren

Das wird in der DB dann so abgebildet:

Tabelle "struktur":

ID | Parent_ID | Reihenfolge_ID | Titel
---+-----------+----------------+-------
1  | 0         | 1              | Lebensmittel
2  | 1         | 1              | Getränke
3  | 1         | 2              | Molkereiprodukte
4  | 3         | 1              | Milchprodukte
5  | 3         | 2              | Quarkprodukte
6  | 1         | 3              | Backwaren

Tabelle "produkte":

ID | Struktur_ID | Reihenfolge_ID | Titel                       | Beschreibung | Bild
---+-------------+----------------+-----------------------------+--------------+------------------------------
1  | 4           | 1              | 1 Liter Frische Vollmilch   | blabla1...   | schoene_milch_12345.jpg
2  | 4           | 2              | 1 Liter fettarme Milch      | blabla2...   | schoene_milch_12346.jpg
3  | 4           | 3              | 0,5 Liter frische Vollmilch | blabla3...   | schoene_milch_12347.jpg

Die "aktuelle Struktur", also welche Knoten des Baums aufgeklappt ist wird in der Session zwischengespeichert, und zwar so:

$aufgeplappte_Kategorien = array(0,1,3,4);

Dann frage ich das nacheinander ab:
SELECT ID,Titel FROM Struktur WHERE Parent_ID = 0 ORDER BY Reihenfolge_ID DESC
SELECT ID,Titel FROM Struktur WHERE Parent_ID = 1 ORDER BY Reihenfolge_ID DESC
SELECT ID,Titel FROM Struktur WHERE Parent_ID = 3 ORDER BY Reihenfolge_ID DESC
SELECT ID,Titel FROM Struktur WHERE Parent_ID = 4 ORDER BY Reihenfolge_ID DESC

Und jetzt wird es unschön, den ich muss ermitteln, in welchen Kategorien es Unterkategorien oder Produkte gibt:

Im Prinzip muss ich also nach jeder Abfrage oben in einer Schleife alle IDs der Ergebnisse durchegen so abfragen:

SELECT COUNT(*) FROM Struktur WHERE Parent_ID = $id
Und wenn das keine Ergebnisse liefert noch die Produkttabelle entsprechend abfragen. Das kommt mir jetzt auf einem wirder _sehr_ umständlich vor. Vielleicht mache ich das lieber mit einem Sub-Select und GROUP BY? Nur geht dann MYSQL nicht mehr, naja wäre auch nicht so schlimm...
Also da zweifele ich doch stark ob die Datenbank hier noch viel Sinn macht. Wobei natürlich auch über 100 Abfrageb ien einerm Script deutlich unter 1 Sekunde zu erledigen wären, naja.

Nochmal der Versuch das als PHP-Array zu halten:

Lebensmittel
  Getränke
  Molkereiprodukte
    Milchprodukte
      1 Liter Frische Vollmilch
      1 Liter fettarme Milch
      0,5 Liter frische Vollmilch
    Quarkprodukte
  Backwaren

Das Würde ich dann so machen

$struktur[1]['titel'] = 'Lebensmittel';
$struktur[1]['id'] = 0;
$struktur[1]['ukat'][1]['titel'] = 'Getränke';
$struktur[1]['ukat'][1]['id'] = 1;
$struktur[1]['ukat'][2]['titel'] = 'Molkereiprodukte';
$struktur[1]['ukat'][2]['id'] = 2;
$struktur[1]['ukat'][2]['ukat'][1]['titel'] = 'Milchprodukte';
$struktur[1]['ukat'][2]['ukat'][1]['id'] = 3;
$struktur[1]['ukat'][2]['ukat'][2]['titel'] = 'Quarkprodukte';
$struktur[1]['ukat'][2]['ukat'][2]['id'] = 3;
...

Aber das gefällt mir nicht wirklich. Ich habe das so gemachtn denn so kann ich einfach sehen ob in der Kategorie eine Unterkategorie kommt:

if($struktur[$id]['ukat']) {
  print "es gibt eine";
}

Außerdem kann ich die Untergruppen dann einfach abfragen:

foreach ($struktur[$id]['ukat'] as $tmp) {
  echo "<li>".$tmp['titel']."</li>";
}
Das ganze dann halt rekursiv, ja das brauche ich dann wohl doch, da hat ich mich anfangs doch verschätzt ;-)

PS: Vielleicht ist mein Lösungsansatz zu Deinen Aufgabe etwas zu stark von meiner aktuellen Arbeit geprägt, in der auch eine mehr oder weniger identische Teilaufgabe geforder ist. Die Begriffe sind zwar anders, aber es geht um das selbe Thema. Es geht dabei um einen generischen Client, wobei die einzelnen Informationsquellen (Shortcuts, Links oder wie auch immer) in mehreren Strukturbäumen eingehängt werden können. Der einzige wirkliche Unterschied ist der, daß bei dieser Lösung die 'Ordner' und die 'Shortcuts' in einer Tabelle verwaltet werden. Das erleichert die Sache mit den Positionsnummern doch etwas;-)

Das ist aber auch eine komplizierte Aufgabe, vor allem jetzt das ermitteln ob es Unterkategorien oder Produkte gibt, denn das hat Einfluss auf die verfügbaren Aktionen der HTML-Oberfläche(wenn es Unterkategorien gibt kann man nicht löschen, keine Produkte anlegen...)

Viele Grüße
Andreas