<?php
/**
 * ==================================================
 * Template: Universelle <ul>-Navigation (YAML)
 *       YAML-Navigationstemplate
 *
 * Version: 1.3
 * Redaxo Version: 4.2
 * HTML-/XHTML-Version: XHTML 1.0
 *
 * Hinweise:
 * YAML3.1-konformes universelles Navigations-Template
 * fuer Redaxo 4.2.x
 *
 * Navigationstemplate zur Gestaltung von Seitennavigationen/-menues auf der
 * Grundlage unsortierter Listen (<ul></ul>) mit folgenden Funktionen:
 * - Durch eine Meta-Info cat_styleclass kann jeder beliebigen Kategorie eine
 *   individuelle Style-Klasse hinzugefuegt werden
 * - An YAML CSS-Framework angepasst, funktioniert aber auch eigenstaendig
 * - beliebige Verschachtelungstiefe
 * - Veroeffentlichungszeitraum (Online vom/bis) wird beachtet
 * - individuelle Benutzerbereiche des Community-Basis-Addon werden ausgewertet
 * - Verschachtelung der unsortierten Listen wahlweise mit w3c-konformer
 *   <ul>-Gliederung im jeweils uebergeordnetern <li>-Element oder als
 *   "Pseudo"-Verschachtelung in nur einem <ul>-Element
 * - Wahlweise Anzeige der Untermenuepunkte nur der aktuellen Kategorie oder
 *   Anzeige aller Untermenuepunkte
 * - Wahlweise getrennte Anzeige von Haupt- und Untermenue
 * - Generierung eines Breadcrumb-Menues
 * - zusaetzliches Navigationsmenue aus root-Artikeln moeglich
 *
 * weitere ausfuehrliche Erlaeuterungen zu diesem Template neben den
 * Hinweisen im Quelltext auch unter:
 *
 * http://www.raybeam.de/20-0-Optionen-des-Navigationsmenues.html
 * http://www.raybeam.de/35-0-Breadcrumbmenue-und-Zusatzmenue-mit-root-Artikeln.html
 *
 *
 * Bearbeitung: Peter Reiche
 *        www.raybeam.de
 * Datum: 15.02.2010
 * $oStyleClass angepasst, um doppelte class-Zuweisung
 * zu verhindern
 *
 * Datum: 24.01.2010
 * Breadcrumb-Voreinstellungen angepasst
 * $bcServerLink='on|off|no'
 * mit "no" kann Servername ausgeblendet werden
 *
 * Datum: 16.12.2009
 * Anpassung an redaxo-community-basis-addon
 * einsetzbar ab redaxo 4.2.x
 * Das simple-user-addon wird nicht mehr berücksichtigt
 *
 * Ursprung-Datum: 09.05.2009
 * ================================================== */


function build_navigation($nav, $path, $subUl='on',$pathIndex=1)
{
  /* Wenn der Veroeffentlichungszeitraum "Online von / bis zum" nicht zutrifft, wird der
   * Navigationslink nicht angezeigt. Artikel die direkt ueber den URL aufgerufen
   * wurden, werden jedoch immer noch angezeigt. Das entsprechende Seiten-Template
   * muss also bezuegl. des Veroeffentlichungszeitraums ebenfalls angepasst werden. */

  $time = time();

  /* online_from und online_to werden ueber Metainformationen der Artikel zur Verfuegung gestellt.
   * Folgende Felder muessen, fall nicht vorhanden, ueber "Metainformationen erweitern/Artikel"
   * angelegt werden
   * /////////////////////////////////
   * Prefix:      art_
   * Spaltenname:   online_from
   * Feldposition:  [nach belieben]
   * Feldbezeichnung: [nach belieben]
   * Feldtyp:     date
   * Parameter:   [kein Eintrag]
   * Feldattribute:   [kein Eintrag]
   * Standardwert:  [kein Eintrag]
   * /////////////////////////////////
   * und
   * ////////////////////////////////
   * Prefix:    art_
   * Spaltenname: online_to
   * ... wie oben

   * Werden die Metadaten im Backend gespeichert, so wird das aktuelle Datum in art_online_from
   * und art_online_to gespeichert, wenn dort zuvor keine Werte eingetragen waren. Um eine un-
   * beabsichtigte Sperrung der Artikel zu vermeiden, wird das Onlinedatum nur in die Pruefung
   * einbezogen, wenn sich art_online_from und art_online_to unterscheiden. */


  if($nav->getValue('online_from') != $nav->getValue('online_to'))
  {
    if($nav->getValue('online_from') > $time || $nav->getValue('online_to') < $time)
    {
      return;
    }
  }
 
    /* Der Artikel-Typ wird ueber die Metainformationen der Artikel zur Verfuegung gestellt
     * Folgendes Feld muss, falls nicht vorhanden, ueber "Metainformationen erweitern/Artikel" angelegt werden
     * /////////////////////////////////
   * Prefix:      art_
   * Spaltenname:   com_perm
   * Feldposition:  [nach belieben]
   * Feldbezeichnung: [nach belieben] z. B. Artikel-Typ
   * Feldtyp:     select
   * Parameter:     0:Standard|-1:nicht eingeloggt|1:eingeloggt|2:Admin
   * Feldattribute:   [kein Eintrag]
   * Standardwert:  [kein Eintrag]
   */
////////////////////////////////

  /* Individuelle Userbereiche koennen ueber die Metainformationen der Artikel zur Verfuegung gestellt werden
   * Folgendes Feld muss, falls nicht vorhanden, ueber "Metainformationen erweitern/Artikel" angelegt werden
   * /////////////////////////////////
   * Prefix:      art_
   * Spaltenname:   com_user
   * Feldposition:  [nach belieben]
   * Feldbezeichnung: [nach belieben] z. B. Community User
   * Feldtyp:     select
   * Parameter:     SELECT "angemeldet" AS name,"-1" AS id
   *          UNION SELECT name,id FROM rex_com_user WHERE status = 1
   * Feldattribute:   [kein Eintrag]
   * Standardwert:  [kein Eintrag]
   */
////////////////////////////////

  global $REX;

  // Zugriffsberechtigung fuer redaxo-community pruefen
  if(OOAddon::isAvailable('community'))
  {
    if($nav->getValue('art_com_perm')=="") $chkUsrPerm = true; // Zugriff fuer alle
    if($nav->getValue('art_com_perm')==0) $chkUsrPerm = true; // Zugriff fuer alle

    if(isset($REX['COM_USER']) && is_object($REX['COM_USER']))
    {
      // Eigene Bereiche fuer jeden angemeldeten Community-User einrichten
      // Dazu wird die MetaInfo art_com_user bei den Artikeln genutzt, Admins sehen alles
      if($nav->getValue('art_com_user'))
      {
      if(($nav->getValue('art_com_perm')==1 && $REX['COM_USER']->getValue('id')==$nav->getValue('art_com_user')) || $REX['COM_USER']->getValue("admin")==1)$chkUsrPerm = true;
      elseif($nav->getValue('art_com_perm')==1 && $nav->getValue('art_com_user')=='-1')$chkUsrPerm = true;
      }
      else
      {
      // oder die Standardvariante ueber die MetaInfo art_com_perm
      if($nav->getValue('art_com_perm')==1) $chkUsrPerm = true;
      }
      if($nav->getValue('art_com_perm')==2 && $REX['COM_USER']->getValue("admin")==1) $chkUsrPerm = true;
    }
    if(!isset($REX['COM_USER']) || !is_object($REX['COM_USER']))
    {
      // Zugriff fuer nicht eingeloggte User
      if($nav->getValue('art_com_perm')=="-1") $chkUsrPerm = true;
    }
  }
  else
  {
    // permisson-Check fuer redaxo-community umgehen
    $chkUsrPerm = true;
  }

    if($chkUsrPerm)
    {
      // Falls MetaInfo cat_styleclass vorhanden ist, Klasseneintrag
      // 'class="cat_styleclass-Wert" ' generieren
      if($nav->getValue($REX['csMetaInfo']))
      {
        $oStyleClass = $nav->getValue($REX['csMetaInfo']);
      $sStyleClass = " class=\"$oStyleClass\"";
      }

      // "geoeffnete" Rootkategorie durch css-Klasse 'current' markieren
        if($pathIndex==1 || ($pathIndex==2 && $subUl=='extra'))
        {
          if($pathIndex==1)
          {
            $oStyleID=" class=\"current $oStyleClass\"";
          }
          else
          {
            $oStyleID=" class=\"current{$pathIndex} $oStyleClass\"";
          }
        }
    else
    {
          $oStyleID=" class=\"active $oStyleClass\"";
    }

        // Nur Submenue des aktuellen Root anzeigen
        if($subUl=='on' || $subUl=='off' || $subUl=='extra')
        {
          if($nav->getId()==$path[$pathIndex])
          {
            // Namen der aktuellen root-Kategorie als Titel fuer
            // das Submenue uebernehmen
            if($pathIndex==1)
            {
              $subNavigation='<li id="title"'.$oStyleClass.'>'.$nav->getName()."</li>\n";
            }

            // Durch ...->getChildren(1) anstatt ...->getChildren() werden
            // nur Kategorien durchlaufen die "online" sind
            if($nav->getChildren(1))
            {
              if((count($path) > $pathIndex) && ($path[$pathIndex + 1] > 0))
                {
              if(preg_match('/ class="active.*"/',$oStyleID))$oStyleID=$sStyleClass;
                 
            if($pathIndex>1 && $subUl=='extra')
                  {
                    $subNavigation.='<li'.$oStyleID.'><a href="'.$nav->getUrl().'">'.$nav->getName().'</a>';
                  }
                  else
                  {
                    $navigation.='<li'.$oStyleID.'><a href="'.$nav->getUrl().'">'.$nav->getName().'</a>';
                  }
                }
                else
                {
                  // bei 'extra' wuerde der root-Navigationspunkt ins submenue verschoben, soll er aber nicht
                  if($pathIndex>1 && $subUl=='extra')
                  {
                    $subNavigation.='<li'.$oStyleID.'><a  href="'.$nav->getUrl().'">'.$nav->getName().'</a>';
                  }
                  else
                  {
                    $navigation.='<li'.$oStyleID.'><a href="'.$nav->getUrl().'">'.$nav->getName().'</a>';
                  }
                }
                // Wenn keine untergeordneten <ul>-Tags im Menue verwendet
                // werden sollen ($subUl='off'), wird der <li>-Tag geschlossen
          if($subUl=='off')
                {
                  $navigation.= '</li>'."\n";
                }
                // Wenn untergeordnete <ul>-Tags im Menue verwendet
                // werden sollen ($subUl='on'), wird in dem noch offenen
                // <li>-Tag der <ul>-Tag geoeffnet
                else
                {
                  if($pathIndex>1 && $subUl=='extra')
                  {
                    $subNavigation.= "\n<ul class=\"subnav".$pathIndex."\">\n";
                  }
                  else
                  {
                    $navigation.= "\n<ul class=\"subnav".$pathIndex."\">\n";
                  }
                }
                // Durch ...->getChildren(1) anstatt ...->getChildren() werden
                // nur Kategorien durchlaufen die "online" sind - dazu wird die
                // Funktion erneut aufgegrufen
                foreach($nav->getChildren(1) as $sub)
                {
                  $tmpNav=build_navigation($sub, $path,$subUl, $pathIndex+1);
                  $navigation.=$tmpNav[0];
                  $subNavigation.=$tmpNav[1];
                }
                // Wenn untergeordnete <ul>-Tags im Menue verwendet
                // werden sollen ($subUl='on'), wird der <ul>-Tag hier wieder geschlossen
                if($subUl=='on' || $subUl=='extra')
                {
                  if($pathIndex>1 && $subUl=='extra')
                  {
                    $subNavigation.="</ul>\n";
                  }
                  else
                  {
                    $navigation.="</ul>\n";
                  }
                }
              }
              else
              {
          if($pathIndex>1 && $subUl=='extra')
          {
                $subNavigation.='<li'.$oStyleID.'><a class="level'.$pathIndex.' active" href="'.$nav->getUrl().'">'.$nav->getName().'</a>';
              }
              else
              {
                $navigation.='<li'.$oStyleID.'><a href="'.$nav->getUrl().'">'.$nav->getName().'</a>';
              }

          if($subUl=='off')
              {
                $navigation.= '</li>'."\n";
              }
              }
            }
            else
        {
        if($pathIndex>1 && $subUl=='extra')
        {
          $subNavigation.='<li'.$sStyleClass.'><a href="'.$nav->getUrl().'">'.$nav->getName().'</a>';
        }
        else
        {
          $navigation.='<li'.$sStyleClass.'><a href="'.$nav->getUrl().'">'.$nav->getName().'</a>';
        }

        if($subUl=='off')
            {
              $navigation.= '</li>'."\n";
              }
            }
      if($subUl=='on' || $subUl=='extra')
          {
            if($pathIndex>1 && $subUl=='extra')
            {
              $subNavigation.= '</li>'."\n";
            }
            else
            {
              $navigation.= '</li>'."\n";
            }
          }
        }
        // Submenues aller Kategorien anzeigen
        elseif($subUl=='allOn' || $subUl=='allOff')
        {
          if($nav->getChildren(1))
          {
            // class="active" bei aktiver Unterkategorie wieder loeschen
            if((count($path) > $pathIndex) && ($path[$pathIndex + 1] > 0))
            {
            if(preg_match('/ class="active.*"/',$oStyleID))$oStyleID=$sStyleClass;
            }

            if($nav->getId()==$path[$pathIndex])
              {
                $navigation.='<li'.$oStyleID.' ><a href="'.$nav->getUrl().'">'.$nav->getName().'</a>';
              }
              else
              {
                $navigation.='<li'.$sStyleClass.'><a href="'.$nav->getUrl().'">'.$nav->getName().'</a>';
              }
              // Wenn keine untergeordneten <ul>-Tags im Menue verwendet
              // werden sollen ($subUl='allOff'), wird der <li>-Tag geschlossen
        if($subUl=='allOff')
              {
                $navigation.= '</li>'."\n";
              }
              // Wenn untergeordnete <ul>-Tags im Menue verwendet
              // werden sollen ($subUl='allOn'), wird in dem noch offenen
              // <li>-Tag der <ul>-Tag geoeffnet
              else
              {
                $navigation.= "\n<ul class=\"subnav".$pathIndex."\">\n";
              }
              foreach($nav->getChildren(1) as $sub)
              {
                $tmpNav=build_navigation($sub, $path,$subUl, $pathIndex+1);
                $navigation.=$tmpNav[0];
              }
              // Wenn untergeordnete <ul>-Tags im Menue verwendet
              // werden sollen ($subUl='allOn'), wird der <ul>-Tag hier wieder geschlossen
              if($subUl=='allOn')
              {
                $navigation.="</ul>\n";
              }
          }
          else
          {
            if($nav->getId()==$path[$pathIndex])
            {
              $navigation.='<li'.$oStyleID.'><a href="'.$nav->getUrl().'">'.$nav->getName().'</a>';
            }
            else
            {
              $navigation.='<li'.$sStyleClass.'><a href="'.$nav->getUrl().'">'.$nav->getName().'</a>';
            }
              if($subUl=='allOff')
            {
              $navigation.= '</li>'."\n";
            }
          }
        }
      if($subUl=='allOn')
        {
        $navigation.= '</li>'."\n";
      }
    }
  // Kleiner Trick, falls ausser der root-Kategorie alle weiteren aufgrund
    // der Rechtevergabe ausgeblendet sind. Um validen HTML-Code zu erhalten
    // muss am Ende des $navigations-String "<ul class=\"subnav1\">\n</ul>"
    // geloescht werden
    if(strstr($navigation,"<ul class=\"subnav1\">\n</ul>"))
    {
      $navigation = str_replace("\n<ul class=\"subnav1\">\n</ul>","\n",$navigation);
    }
    $navArray=array();
    $navArray[0].=$navigation;
    $navArray[1].=$subNavigation;
    return $navArray;
}  // ------------------ Ende der function build_navigation ------------------

//////////////////////////////////////////////
//  " M E N U E - U M S C H A L T E R "
//////////////////////////////////////////////
//  Menue mit <ul></ul> Auszeichnung
//  auch in den Unter-Menuepunkten oder
//  alle Untermenuepunkte staendig anzeigen
//  <ul> einschalten:.................. on
//  <ul> ausschalten:.................. off
//  alle mit <ul> staendig anzeigen:.... allOn
//  alle ohne <ul> staendig anzeigen:... allOff
//  Untermenue extra:................... extra
//////////////////////////////////////////////
// Standardparameter fuer $subUl setzen, falls
// yaml-Layout-Template nicht benutzt wird
// (Bei Einsatz des yaml-templates werden diese
//  Werte dort gesetzt)
//////////////////////////////////////////////
if($subUl=='')$subUl='on';
//////////////////////////////////////////////
// Ein Zusaetzliches Menue (z. B. als topnav-Menue) kann auf Basis von root-Artikeln,
// die ueber eine Meta Info selektiert werden koennen, oder ohne eine Meta Info
// komplett in die Variable $raNavigation uebergeben werden.
// $raNav = 'on|off' (Bei Einsatz des yaml-templates wird dieser Wert dort gesetzt)
if($raNav=='')$raNav = 'off';
//////////////////////////////////////////////
// Standardwert fuer individuelle StyleKlassen der Kategorien ueber MetaInfo setzen
// ueber $REX['csMetaInfo'] ist der Wert automatisch global, also auch in der
// Funktion build_navigation sofort abrufbar (Bei Einsatz des yaml-templates wird
// dieser Wert dort gesetzt)
if($REX['csMetaInfo']=='')$REX['csMetaInfo']= 'cat_styleclass';
// Den Meta Infos wird unter *KATEGORIEN* folgendes hinzugefuegt:
// ---------------------------------
// Spaltenname: styleclass
// Feldposition: beliebiger Wert
// Feldbezeichnung: styleclass
// Feldtyp: select
// Parameter (z.B.): |rot|gruen|blau          (durch das erste Pipezeichen kann ein Eintrag spaeter wieder geleert werden)
// Feldattribute: size=1
// ---------------------------------
// Über Kategorie editieren/löschen im Strukturmenue kann man jetzt
// jeder Kategorie eine css-Klassenbezeichnung zufuegen, die dann im
// Quelltext z. B. aus <li> <li class="rot"> macht.

// ------------------ Navigation erstellen ------------------

// Voreinstellungen:
$path = explode("|",$this->getValue("path").$this->getValue("article_id")."|");

$navi=array();
foreach (OOCategory::getRootCategories(1) as $nav)
{
  $navi=build_navigation($nav, $path, $subUl);
  $navMain.=$navi[0];
  $navSub.=$navi[1];
}

$cssClsV = 'class="vlist"';
$cssClsH = 'class="hlist"';

if($subUl=='extra')
{
  $navigation= "<div ".$cssClsH.">\n  <ul> \n".$navMain."</ul>\n</div>\n";
}
else
{
  $navigation= "<div ".$cssClsV.">\n  <ul> \n".$navMain."</ul>\n</div>\n";
}

if($navSub)
{
  $subNavigation= "<div ".$cssClsV.">\n  <ul>\n".$navSub."</ul>\n</div>\n";
}

// ------------------ Breadcrumb erstellen ------------------

$aktArticle = OOArticle::getArticleById($this->getValue('article_id'));
$tree = $aktArticle->getParentTree();

//////////////////////////////////////////////
//  Standardwerte fuer Titel und Trennzeichen
//  fuer die Breadcrumb-Links festlegen, falls
//  yaml-Layout-Template nicht benutzt wird
//  (Bei Einsatz des yaml-templates werden diese
//  Werte dort gesetzt)
//////////////////////////////////////////////
if($bcTitle=='')$bcTitle = 'Sie befinden sich hier: ';
if($bcDivi =='')$bcDivi  = ' > ';
//  Startartikel im Breadcrumbmenue verlinken (Dank an rudoo fuer die Idee!)
//  $bcServerLink='on|off|no'
if($bcServerLink=='')$bcServerLink='no';
//////////////////////////////////////////////

if(is_array($path))
{
  $divi = $bcDivi;
  if($bcServerLink=='on')
  {
    $startArticle = OOArticle::getArticleByID($REX['START_ARTICLE_ID']);
    $breadcrumb = '<div id="breadcrumb">'."\n".'<span class="bcTitle">'.$bcTitle.'<a href="'.$startArticle->getUrl().'">'.$REX ['SERVERNAME'].'</a>'.'</span>';
  }
  elseif($bcServerLink=='off')
  {
    $breadcrumb = '<div id="breadcrumb">'."\n".'<span class="bcTitle">'.$bcTitle.$REX ['SERVERNAME'].'</span>';
  }
  else
  {
    $breadcrumb = '<div id="breadcrumb">'."\n".'<span class="bcTitle">'.$bcTitle.'</span>';
    $divi = '';
  }

    foreach($path as $bcNr)
    {
      if($bcNr!='')
      {
        $art = OOArticle::getArticleByID($bcNr);
        if($art->getValue('id')!=$this->getValue('article_id'))
        {
          // Pfad-Eintraege des Artikels verlinken
          $breadcrumb .= $divi.$art->toLink();
        }
        else
        {
          // Artikelname der aktuellen Seite nicht verlinken
          $breadcrumb .= $divi.'<span class="bcActive">'.$this->getValue("name")."</span>\n";
        }
        if(!$divi)$divi=$bcDivi;
      }
    }
    $breadcrumb .='</div>'."\n";
}

// ------------------ Navigationsmenue anhand von root-Artikeln erstellen ------------------
if($raNav=='on')
{
  $rootArticles = OOArticle::getRootArticles($ignore_offlines = true, $clang = false);
  $raNavigation='';
  $raCnt = 1;

  foreach($rootArticles as $rootArticle)
  {
    // ab redaxo 4.x
    // mit MetaInfo ob der root-Artikel im Menue erscheinen soll
    if($rootArticle->hasValue($raMetaInfo))
    {
      if($rootArticle->getValue($raMetaInfo)=='|true|')
      {
        if($raCnt>1)
        {
          $raNavigation=$raNavigation.$raDivi;
        }
        $raCnt++;
        $raNavigation = $raNavigation.$rootArticle->toLink($params='', $attributes=null, $sorround_tag=null, $sorround_attributes=null);
      }
    }
    // ohne MetaInfo-Nutzung
    else
    {
      if($raCnt>1)
      {
        $raNavigation=$raNavigation.$raDivi;
      }
      $raCnt++;
      $raNavigation = $raNavigation.$rootArticle->toLink($params='', $attributes=null, $sorround_tag=null, $sorround_attributes=null);
    }
  }
}
?>