Warnung: file_put_contents(/home/www/web1/html/php_dev/test.txt) [function.file-put-contents]: failed to open stream: Permission denied in /home/www/web1/html/php_dev/sys/lib.activity.php (Zeile 58)
Menü aus XML erzeugen, Syntax-Problem Array-Aufbau [Archiv] - PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr

- Ad -
php-resource




Archiv verlassen und diese Seite im Standarddesign anzeigen :
Menü aus XML erzeugen, Syntax-Problem Array-Aufbau


 
creative-w3
20-10-2005, 09:42 
 
Hallo allerseits,

ich möchte aus einer XML-Datei (1) über eine php-Klasse (2) ein Array (3) erzeugen. In einen Array bekomme ich auch alles ganz gut, jedoch weiß ich nicht, wie ich in der Methode "buildMenuStructure" für die Kinder in eine tiefere Ebene des Array komme, so dass das Modell wie in 3 entsteht. Ich habe immer alle Menüelemente auf einer Ebene - die SubElemente sind also nicht als Children zugeordnet...

Ich hoffe, dass mich der eine oder andere verstanden hat und mir helfen kann! Wäre sehr geil ;)

Viele Grüße,
André


1. XML-Datei
<?xml version="1.0"?>
<menu>
<menuElement view="defaultview" url=""/>
<menuElement view="systems" url="?op=systems">
<menuSubElement view="systemgroups" url="?op=systemgroups"/>
<menuSubElement view="systemoverview" url="?op=systemOverview"/>
<menuSubElement view="addsystem" url="?op=addSystem"/>
<menuSubElement view="import" url="?op=import"/>
</menuElement>
<menuElement view="mylandscape" url="?op=mylandscape">
<menuSubElement view="personaldata" url="?op=personaldata"/>
<menuSubElement view="responsibilities" url="?op=responsibilities"/>
<menuSubElement view="subscriptions" url="?op=subscriptions"/>
</menuElement>
</menu>

2. Ausschnitt der php-Klasse
public function buildMenuAsArray($whichMenu, $activeView) {

// Menueexistenz feststellen
if(!array_key_exists($whichMenu, $this->map)) {
die("The selected menu doesn't exist in the menuMap.");
}

// XML-Datei als DOM-Objekt einlesen
// :TODO: Datei-Existenz pruefen...
$this->menuDom = new domDocument();
$this->menuDom->preserveWhiteSpace = false;
$this->menuDom->load($this->map[$whichMenu]);

// Mit der ersten Menue-Ebene starten...
$highestElements = $this->menuDom->getElementsByTagName('menuElement');
foreach($highestElements as $highestElement) {
$this->buildMenuStructure($highestElement, $this->menu, $activeView);
}
}

private function buildMenuStructure($menuElement, $menu, $activeView) {
$active = ($menuElement->getAttribute("view") ==
strtolower($activeView)) ? true : false;
$gotChildren = $menuElement->hasChildNodes();
$this->menu[] = array('view' => $menuElement->getAttribute("view"),
'url' => $menuElement->getAttribute("url"),
'active' => $active,
'gotChildren' => $gotChildren);
if($gotChildren) {
$childElements = $menuElement->childNodes;
foreach($childElements as $childElement) {
$this->buildMenuStructure($childElement, $menu, $activeView);
}
}
}

3. gewünschter Aufbau des Array
$menu[menuItem][url] = "bla..."
[view] = "blubb..."
[active] = 1
[gotChildren] = 1
[childActive] = 1
[children][menuItem] ... usw. (alle SubElemente, Struktur wie oben) ...

 
creative-w3
20-10-2005, 21:11 
 
Ich habe es inzwischen ganz anders gelöst (und es funktioniert auch...).
Falls es jemanden interessiert (Kritik ist ausdrücklich erwünscht):

XML-Datei:<?xml version="1.0"?>
<menu>
<menuElement view="defaultview" url=""/>
<menuElement view="systems" url="?op=systems">
<menuElement view="systemgroups" url="?op=systemgroups"/>
<menuElement view="systemoverview" url="?op=systemOverview">
<menuElement view="systemgroups2" url="?op=systemgroups2"/>
<menuElement view="systemgroups3" url="?op=systemgroups3"/>
</menuElement>
<menuElement view="addsystem" url="?op=addSystem"/>
<menuElement view="import" url="?op=import"/>
</menuElement>
<menuElement view="mylandscape" url="?op=mylandscape">
<menuElement view="personaldata" url="?op=personaldata"/>
<menuElement view="responsibilities" url="?op=responsibilities"/>
<menuElement view="subscriptions" url="?op=subscriptions"/>
</menuElement>
</menu>


Menü-Klasse (die menuMap ist ja klar...):<?php
/*
* Systemlandschaft: class/template/menu.class.php
* Autor: Andre Kolell
* Erstellt: 19.10.2005, 20:54
*
* Kurzbeschreibung:
* Diese Klasse liest eine XML-Menuestruktur ein und stellt diese dann in der
* gewuenschten Form (bisher ist lediglich "Array" implementiert) bereit.
*/

class Menu {

// Zuordnungen zwischen Menues und einzubindenden XML-Dateien
// (jedes Menue, z.B. Hauptmenue, Shortcuts, etc. hat seine eigene Datei)
private $map;

// Das "fertige" Menue (bisher ist lediglich "Array" implementiert)
private $menu;

// Aktueller View
private $activeView; // als String, z.B. "defaultView"
private $activeViewKey; // als Key in einem Array, z.B. "4"



// Konstruktor. $activeView entspricht der aus vielen Webprojekten bekannten
// "$display"-Variable. Zum Zeitpunkt der Erstellung dieses Menues muss also
// der aktuelle View bereits bekannt sein.
function __construct($activeView) {

// Zuordnungen zwischen Menues und einzubindenden XML-Dateien bereitstellen
include_once("class/template/menu/menumap.properties.php");
$this->map = $menuMap;

// Aktiven View belegen
$this->activeView = $activeView;
}



// Erzeugt das Menue ($whichMenu) als Array aus der XML-Datei
public function buildMenuAsArray($whichMenu) {

// Menueexistenz feststellen
if(!array_key_exists($whichMenu, $this->map)) {
die("The selected menu doesn't exist in the menuMap.");
}

// XML-Datei als DOM-Objekt einlesen
// :TODO: Datei-Existenz pruefen...
$menuDom = new domDocument();
$menuDom->preserveWhiteSpace = false;
$menuDom->load($this->map[$whichMenu]);

// Wurzelelement "menu" und dessen Kinder (erste Menueebene) holen
$rootElementNodeList = $menuDom->getElementsByTagName('menu');
$rootElement = $rootElementNodeList->item(0);
$firstMenuLevel = $rootElement->childNodes;

// Komplette Baumstruktur erzeugen, aktives Element kennzeichnen (und merken)
foreach($firstMenuLevel as $menuElement) {
$this->buildMenuAsArrayAddElement($menuElement, 0, 0);
}

// Ist ein Menuepunkt (View) aktiv, und ist dieser Menuepunkt in einer
// tieferen Ebene als der Ersten, muss die Baumstruktur geoffnet werden
if(isset($this->activeViewKey) &&
$this->menu[$this->activeViewKey]['hierachy'] > 0) {
$this->buildMenuAsArrayOpenRelevantItems($this->activeViewKey);
}
}

// Fuegt dem Array-Menue ein Menueelement hinzu
private function buildMenuAsArrayAddElement($menuElement, $crntLevel, $parentKey) {
if($menuElement->getAttribute("view") == strtolower($this->activeView)) {
$activeView = true;
$this->activeViewKey = count($this->menu);
} else {
$activeView = false;
}
$gotChildren = $menuElement->hasChildNodes();
$this->menu[] = array('view' => $menuElement->getAttribute("view"),
'url' => $menuElement->getAttribute("url"),
'hierachy' => $crntLevel,
'parent' => $parentKey,
'activeView' => $activeView,
'open' => false);
if($gotChildren) {
$crntLevel++;
$thisElementsKey = (count($this->menu)-1);
$childElements = $menuElement->childNodes;
foreach($childElements as $childElement) {
$this->buildMenuAsArrayAddElement($childElement, $crntLevel, $thisElementsKey);
}
}
}

// Oeffnet die gleich- und uebergeordnete Struktur eines Menueelementes
private function buildMenuAsArrayOpenRelevantItems($parentKey) {

// Aktuelles Menueelement und Elemente gleicher Ebene oeffnen
// :TODO: Es geht sicherlich einfacher!?
for($i = 0; $i < count($this->menu); $i++) {
if($this->menu[$i]['parent'] == $parentKey) {
$this->menu[$i]['open'] = true;
}
}

// Sofern es sich bei dem aktuellen Menueelement nicht um eines der ersten
// Ebene handelt, wird die Methode nun mit dem Elternelement aufgerufen
if($this->menu[$parentKey]['hierachy'] > 0) {
$this->buildMenuAsArrayOpenRelevantItems($this->menu[$parentKey]['parent']);
}
}

// Gibt das Menue zurueck
public function getMenu() {
return $this->menu;
}
}
?>


Folgendes Array entsteht ($activeView = "responsibilities"):Array
(
[0] => Array
(
[view] => defaultview
[url] =>
[hierachy] => 0
[parent] => 0
[activeView] =>
[open] =>
)

[1] => Array
(
[view] => systems
[url] => ?op=systems
[hierachy] => 0
[parent] => 0
[activeView] =>
[open] =>
)

[2] => Array
(
[view] => systemgroups
[url] => ?op=systemgroups
[hierachy] => 1
[parent] => 1
[activeView] =>
[open] =>
)

[3] => Array
(
[view] => systemoverview
[url] => ?op=systemOverview
[hierachy] => 1
[parent] => 1
[activeView] =>
[open] =>
)

[4] => Array
(
[view] => systemgroups2
[url] => ?op=systemgroups2
[hierachy] => 2
[parent] => 3
[activeView] =>
[open] =>
)

[5] => Array
(
[view] => systemgroups3
[url] => ?op=systemgroups3
[hierachy] => 2
[parent] => 3
[activeView] =>
[open] =>
)

[6] => Array
(
[view] => addsystem
[url] => ?op=addSystem
[hierachy] => 1
[parent] => 1
[activeView] =>
[open] =>
)

[7] => Array
(
[view] => import
[url] => ?op=import
[hierachy] => 1
[parent] => 1
[activeView] =>
[open] =>
)

[8] => Array
(
[view] => mylandscape
[url] => ?op=mylandscape
[hierachy] => 0
[parent] => 0
[activeView] =>
[open] =>
)

[9] => Array
(
[view] => personaldata
[url] => ?op=personaldata
[hierachy] => 1
[parent] => 8
[activeView] =>
[open] => 1
)

[10] => Array
(
[view] => responsibilities
[url] => ?op=responsibilities
[hierachy] => 1
[parent] => 8
[activeView] => 1
[open] => 1
)

[11] => Array
(
[view] => subscriptions
[url] => ?op=subscriptions
[hierachy] => 1
[parent] => 8
[activeView] =>
[open] => 1
)

)

Dieses kann dann z.B. an Smarty übergeben und dort weiterverarbeitet werden... ;)

Hoffe auf Feedback!

Viele Grüße,
André

- -

Alle Zeitangaben in WEZ +2. Es ist jetzt 11:33 Uhr.