# PHP Navigation aus Array



## bertiSR (28. August 2009)

Hallo zusammen, mich plagt im Moment die Erstellung eines Menüs mit PHP.

Bisher lasse ich das Menü wie folgt erstellen.


```
$pages = array ( 'home' => 'Startseite', 'register' => 'Anmelden', 'help' => 'Hilfe', 'contact' => 'Kontakt' );

	function get_nav ( $class_id = '' )
	{
		global $sys, $pages;

		echo '<ul';
		if ( $class_id )
		{
			if ( $class_id[0] == '.' ) echo ' class="' . substr ( $class_id, 1 ) . '"';
			elseif ( $class_id[0] == '#' ) echo ' id="' . substr ( $class_id, 1 ) . '"';
		}
		echo '>';
		foreach ( $pages as $l => $t )
		{
			$class = '';
			if ( $l == $sys->_page ) $class = ' class="active"';

			if ( @$sys->get_config ( 'rewrite_url' ) ) echo '<li' . $class . '><a href="' . URL . $l . '/">' . $t . '</a></li>';
			else echo '<li' . $class . '><a href="' . URL . 'index.php?page=' . $l . '">' . $t . '</a></li>';
		}
		echo '</ul>' . "\n";

		return true;
	}
```

Soweit sogut. Der erzeugte HTML CODE sieht also so aus:

```
<!-- Main Navigation -->
<ul id="main-nav">
	<li class="active"><a href="http://school.arob-media.de/index.php?page=home">Startseite</a></li>
	<li><a href="http://school.arob-media.de/index.php?page=register">Anmelden</a></li>
	<li><a href="http://school.arob-media.de/index.php?page=help">Hilfe</a></li>
	<li><a href="http://school.arob-media.de/index.php?page=contact">Kontakt</a></li>
</ul><!-- // end #main-nav -->
```
Bei einem Klick auf den Link wird er "active". Ich würde gerne auf die selbe Art und Weise ein etwas komplizierteres Menü erstellen, dessen HTML Code aussehen muss wie folgt.

```
<!-- Main Navigation -->
<ul id="main-nav">
	<li><a href="#" class="nav-top-item no-submenu">Dashboard</a></li>

	<li><a href="#" class="nav-top-item current">Anmeldungen</a>
		<ul>
			<li><a class="current" href="#">Anmeldungen einsehen</a></li>
			<li><a href="#">Anmeldungen bearbeiten</a></li>
		</ul>
	</li>

	<li><a href="#" class="nav-top-item">Verwaltung</a>
		<ul>
			<li><a href="#">Termine</a></li>
			<li><a href="#">Neuen Termin erstellen</a>
			<li><a href="#">Benutzer</a></li>
			<li><a href="#">Neuen Benutzer erstellen</a></li>
			<li><a href="#">Klassen verwalten</a></li>
			<li><a href="#">F&auml;cher verwalten</a></li>
		</ul>
	</li>

	<li><a href="#" class="nav-top-item">Einstellungen</a>
		<ul>
			<li><a href="#">Allgemein</a></li>
			<li><a href="#">Design</a></li>
			<li><a href="#">Ihr Profil</a></li>
		</ul>
	</li>
</ul><!-- // end #main-nav -->
```

Mir ergeben sich im Moment folgende Probleme:
1. Ich würde die Links gerne in einem array speichern so wie oben, jedoch soll zu jedem Link noch die Information mit welches "Recht" man braucht um die Seite aufrufen zu können.
2. Das Menü ist mit jQuery animiert. Das heißt, dass das Untermenü erst mit einem Klick aufgeht. Bei einem Klick auf ein Element aus dem Untermenü muss diess Element "active" werden und das dazugehörige Hauptelement ebenfalls "active".


----------



## tobee (28. August 2009)

Was genau ist die Frage?
Wie du das mehrdimensionale Array gestalten musst?
Oder wie du Dieses verarbeitest?


----------



## BadMatt (28. August 2009)

Ich würde dir ne rekursive Funktion empfehlen


----------



## bertiSR (28. August 2009)

tobee hat gesagt.:


> Was genau ist die Frage?



Vorerst mal nur wie ich das Array gestallten muss!


----------



## Abro (28. August 2009)

Du solltest gucken ob man da nicht anders rangehen kann , du machst dich nur unglücklich. Da ist  PHP und HTML null getrennt ... 
Mein Tipp: Guck in die entsprechende Funktion in so ziemlich jedem CMS (z.B. WordPress) *zwinker* 

Ausnahmsweise muss ich aber BadMatt recht geben und sagen "machs rekursiv".


----------



## bertiSR (28. August 2009)

Abro hat gesagt.:


> Mein Tipp: Guck in die entsprechende Funktion in so ziemlich jedem CMS (z.B. WordPress) *zwinker*



Die WordPress-Navigation wäre genau mein Ding aber ich durchschau das PHP-Zeugs nicht^^


----------



## Abro (28. August 2009)

Mh ok, wie wärs mit der Klasse von Corey Worrell - sieht ganz brauchbar aus 

Bsp. & Download:
http://coreyworrell.com/demo/php_menu_builder#how
Blogpost:
http://coreyworrell.com/blog/article/php-menu-builder


----------



## bertiSR (28. August 2009)

Also des Rätsels Lösung sieht bislang so aus und funktioniert auch bis auf ein kleines aber feines Problem:


```
<?php

	if ( isset ( $_GET["page"] ) ) $page = $_GET["page"];
	else $page = 'dashboard';

	$menu[] = array ( 'Dashboard', 'dashboard', 1 );

	$menu[] = array ( 'Anmeldungen', 'registrations', 1 );
	$submenu['registrations'][5] = array ( 'Anmeldungen einsehen', 'registrations_view', 1 );
	$submenu['registrations'][10] = array ( 'Anmeldungen bearbeiten', 'registrations_edit', 1 );

	$menu[] = array ( 'Verwaltung', 'administration', 3 );
	$submenu['administration'][5] = array ( 'Termine', 'meetings', 3 );
	$submenu['administration'][10] = array ( 'Neuen Termin erstellen', 'meetings_add', 3 );
	$submenu['administration'][15] = array ( 'Benutzer', 'users', 3 );
	$submenu['administration'][20] = array ( 'Neuen Benutzer erstellen', 'users_add', 3 );
	$submenu['administration'][25] = array ( 'Klassen verwalten', 'classes', 3 );
	$submenu['administration'][30] = array ( 'F&auml;cher verwalten', 'subjects', 3 );

	$menu[] = array ( 'Einstellungen', 'adjustments', 1 );
	$submenu['adjustments'][5] = array ( 'Allgemein', 'adjustments', 3 );
	$submenu['adjustments'][10] = array ( 'Design', 'adjustments_design', 3 );
	$submenu['adjustments'][15] = array ( 'Mein Profil', 'adjustments_profile', 1 );

	foreach ( $menu as $key => $values )
	{
		$class = '';
		if ( !isset ( $submenu[$values[1]] ) ) $class .= ' no-submenu';
		if ( $page == $values[1] ) $class .= ' active';

		print '<li><a href="menu.php?page=' . $values[1] . '" class="nav-top-item' . $class . '">' . $values[0] . '</a>';

		if ( isset ( $submenu[$values[1]] ) )
		{
			print '<ul>';
			foreach ( $submenu[$values[1]] as $key => $sub )
			{
				$sub_class = '';
				if ( $page == $sub[1] ) $sub_class = ' class="active"';
				print '<li><a href="menu.php?page=' . $sub[1] . '"' . $sub_class . '>' . $sub[0] . '</a></li>';
			}
			print '</ul>';
		}
		print '</li>';
	}

?>
```

Wenn ein Link aus dem Untermenü "active" ist soll auch der dazugehörige Link aus dem Hauptmenü "active" sein. 

Ich habs schon so versucht aber so gehts leider auch nicht ...

```
foreach ( $menu as $key => $values )
	{
		$class = '';
		if ( !isset ( $submenu[$values[1]] ) ) $class .= ' no-submenu';
		if ( $page == $values[1] ) $class .= ' active';
		elseif ( $page === $submenu[$values[1][][1]] ) $class .= ' active'; ### MEIN VERSUCH
```


----------



## Abro (28. August 2009)

Also des Rätsels Lösung ist ja schon was pervers *zwinker*
Ich mach das jetzt mal kurz und dreckig, ja ?

- Ich glaube am Anfang fehlt ein <ul> und am Ende ist ein </li> zu viel (korregier mich wenn ich Blödsinn rede).
- Des weiteren weiss ich nicht warum du die Elemente in 5er Schritten einfügst, statt einfach $var[]=array('foo','bar',123) zu benutzen.
- Braucht man wirklich so viele Selektoren? Ich bin mir ziemlich sicher, dass man im vorliegenden fall alles per CSS stylen kann ohne ".active-parent" o.ä., aber das ist ja ein normaler usecase...

Vielleicht geht's noch einfacher, aber das kannste benutzen, schreib einfach mal nen Kommentar in mein Blog dann passt das *zwinker*

```
/**
  * php's default "in_array"-function for multi-dimensional arrays
  * @version  2009-08-11 05:45h
  * @author   d.abromeit, http://lucido-media.de/
  * 
  * @param    string  $needle
  * @param    mixed   &$haystack      
  * @param    bool    $case_sensitive (optional)
  *
  * @return   bool
  */
  function in_array_recursive($needle, &$haystack, $case_sensitive=true)
  {
    if( !$case_sensitive )
      $needle = strtolower($needle);

    foreach($haystack as $v)
    {
        if( !is_array($v) )
        {
          if( !$case_sensitive )
            $v = strtolower($v);

          if( $needle == $v )
            return true;
        }
        else
        {
          if( in_array_recursive($needle, $v, $case_sensitive) === true )
            return true;
        }
    }
    return false;
  }
```

Einfach den Entsprechenden Abschnitt in deinem Source ersetzen mit folgendem, wenn ich nichts vergessen hab funktioniert's dann hoffentlich ;o)

```
foreach ( $menu as $key => $values )
    {
        $class = '';
        if( $page == $values[1] )
        {
          $class .= ' active';
        }
        else
        {
          if( !isset ( $submenu[$values[1]] ) )
            $class .= ' no-submenu';
          elseif( in_array_recursive($page,$submenu[$values[1]],true) )
            $class .= ' active';
        }

        print '<li><a href="menu.php?page=' . $values[1] . '" class="nav-top-item' . $class . '">' . $values[0] . '</a>';
```

Viel Spass!


----------

