<?php


/**
 * navigationUniversell (aQnavigation)
 * 
 * @version 1.2.2
 * @since 1.2.2 - 15.10.2007
 * @since 1.2.1 - 15.10.2007
 * @author Andreas Kummer
 * @copyright Copyright &copy; 2007 atelierQ
 */

class aQnavigation {

	/**
	 * Konstruktor der Klasse.
	 * @param Integer  Prim?rschl?ssel der Startkategorie.
	 */
	function aQnavigation($startId) {

		global $client, $lang, $idcat, $db;

		$this->startId = $startId;

		$this->client = $client;
		$this->lang = $lang;

		$this->idcat = (isset ($_GET['pretend'])) ? ($_GET['pretend']) : ($idcat);

		$this->before = '';
		$this->beforeEach = '';
		$this->between = '';
		$this->after = '';

		$this->excludeItemsStartingWith = '__';

		$this->db = $db;

		$this->setStartIds();

		$this->getNavigation();
	}

	/**
	 * Auslesen der Navigationsstruktur aus der Datenbank.
	 */
	function getNavigation() {

		global $cfg, $auth;

		if ($this->startId != $this->id[0]) {
			/*
			 * Wenn die StartId nicht identisch ist mit der h?chsten Ebene der
			 * aktuell selektierten Kategorie, dann liegt die gew?hlte Kategorie
			 * folgerichtig ausserhalb des f?r die Navigation gew?hlten Baumes.
			 * In diesem Fall ist nur die Hauptnavigation einzublenden.
			 */
			$this->id[0] = $this->startId;
			for ($i = 1; $i <= 3; $i++) {
				$this->id[$i] = -1;
			}
		}

		if ($auth->auth['uid'] == '' || !$this->isNumeric($auth->auth['uid'])) {
			/*
			 * Login nicht erfolgt
			 */
			$user = 0;
		} else {
			/*
			 * Benutzer ist eingeloggt
			 */
			$user = $auth->auth['uid'];
		}

		$this->db->query("" .
		"SELECT DISTINCT " .
		"a.idcat, " .
		"a.parentid, " .
		"a.preid, " .
		"a.postid, " .
		"a.parentid, " .
		"b.name, " .
		"b.idlang, " .
		"IF (b.visible = 1 && (b.public = 1 || d.idfrontenduser IS NOT NULL), 1, 0) AS visible " .
		"FROM {$cfg['tab']['cat']} AS a " .
		"LEFT JOIN {$cfg['tab']['cat_lang']} AS b ON a.idcat = b.idcat " .
		"LEFT JOIN {$cfg['tab']['frontendpermissions']} AS c ON ((c.item = b.idcatlang OR c.item = '__GLOBAL__') AND c.idlang = b.idlang AND plugin ='category') " .
		"LEFT JOIN {$cfg['tab']['frontendgroupmembers']} AS d ON c.idfrontendgroup = d.idfrontendgroup AND d.idfrontenduser = {$user} " .
		"WHERE " .
		"   a.idclient = {$this->client} " .
		"   AND (" .
		"      a.parentid = {$this->id[0]} " .
		"      OR a.parentid = {$this->id[1]} " .
		"      OR a.parentid = {$this->id[2]} " .
		"      OR a.parentid = {$this->id[3]} " .
		"   ) " .
		"");

		$this->navigationTree = array ();

		$this->firstId[0] = 0;
		$this->firstId[1] = 0;
		$this->firstId[2] = 0;
		$this->firstId[3] = 0;

		while ($this->db->next_record()) {

			for ($i = 0; $i <= 3; $i++) {
				if (($this->firstId[$i] == 0 && $this->db->f('parentid') == $this->id[$i] && $this->db->f('preid') == 0 && $this->db->f('idlang') == $this->lang) || ($this->firstId[$i] == 0 && $this->db->f('parentid') == $this->id[$i] && $this->db->f('preid') == 0 && $this->db->f('idlang') == null)) {
					$this->firstId[$i] = $this->db->f('idcat');
				}
			}
			/*
			 * Das Einf?gen in den Navigationsbaum darf nur erfolgen, wenn noch kein Eintrag existiert
			 * oder - wenn bereits einer existiert - der neue Eintrag der aktuell gew?hlten Sprache
			 * entspricht.
			 */
			if (!isset ($this->navigationTree[$this->db->f('parentid')][$this->db->f('idcat')]) || $this->db->f('idlang') == $this->lang) {
				$this->navigationTree[$this->db->f('parentid')][$this->db->f('idcat')] = array (
					'preid' => $this->db->f('preid'
				), 'postid' => $this->db->f('postid'), 'visible' => $this->db->f('visible'), 'name' => $this->db->f('name'), 'idlang' => $this->db->f('idlang'));
			}
		}

	}

	/**
	 * Ausgabe der Navigation an die Standardausgabe.
	 * @param String  Navigationstyp
	 */
	function showNavigation($type, $next = -1) {

		static $first;
		static $output = array (
			false,
			false,
			false,
			false,
			false,
			false,
			false
		);

		$returnValue = "";

		if ($next == 0) {
			if ($output[$type]) {
				return $this->after[$type];
			} else {
				return false;
			}
		}

		if ($next == -1) {
			$returnValue .= $this->before[$type];
			$next = $this->firstId[$type];
			$first[$type] = true;
		}

		$parentId = $this->id[$type];

		$link = 'front_content.php?idcat=' . $next;

		if ($this->navigationTree[$parentId][$next]['visible'] == 1 && $this->navigationTree[$parentId][$next]['idlang'] == $this->lang && $this->isVisble($this->navigationTree[$parentId][$next]['name'])) {
			if (!$first[$type]) {
				$returnValue .= $this->between[$type];
			}

			if (strstr($this->navigationTree[$parentId][$next]['name'], '$$$') == true) {
				$name = explode('$$$', $this->navigationTree[$parentId][$next]['name']);
				$name1 = $name[0];
				$name2 = $name[1];
			} else {
				$name1 = $this->navigationTree[$parentId][$next]['name'];
				$name2 = '';
			}

			$sub = (isset ($this->sub[$type])) ? ($this->sub[$type]) : ('');

			if ($this->isActive($next) & !empty ($this->maskActive[$type]) & !empty ($this->maskActive[$type])) {
				$returnValue .= $this->beforeSelected[$type];
				$returnValue .= str_replace('{sub}', $sub, str_replace('{name2}', $name2, str_replace('{name1}', $name1, str_replace('{link}', $link, ($sub == '') ? ($this->maskActive[$type]) : ($this->maskActiveSub[$type])))));
			}
			elseif ($this->isSelected($next)) {
				$returnValue .= $this->beforeSelected[$type];
				$returnValue .= str_replace('{sub}', $sub, str_replace('{name2}', $name2, str_replace('{name1}', $name1, str_replace('{link}', $link, ($sub == '') ? ($this->maskSelected[$type]) : ($this->maskSelectedSub[$type])))));
			} else {
				$returnValue .= $this->beforeEach[$type];
				$returnValue .= str_replace('{sub}', $sub, str_replace('{name2}', $name2, str_replace('{name1}', $name1, str_replace('{link}', $link, $this->maskNormal[$type]))));
			}

			$first[$type] = false;
			$output[$type] = true;
		}
		elseif (!$output && $this->navigationTree[$parentId][$next]['postid'] == 0) {
			/*
			 * Die Navigation enth?lt nichts.
			 */
		}

		return $returnValue . $this->showNavigation($type, $this->navigationTree[$parentId][$next]['postid']);
	}

	function setExcludeStart($start) {
		$this->excludeItemsStartingWith = $start;
	}

	function isVisble($name) {
		if (substr($name, 0, strlen($this->excludeItemsStartingWith)) == $this->excludeItemsStartingWith) {
			return false;
		}
		return true;
	}

	/**
	 * Ausgabe vor der Navigation
	 * @param String  Ausgabe vor der Navigation.
	 */
	function before($level, $text) {
		$this->before[$level] = $text;
	}

	/**
	 * Ausgabe vor jedem Eintrag
	 * @param String  Ausgabe vor jedem Eintrag.
	 */
	function beforeEach($level, $text) {
		$this->beforeEach[$level] = $text;
	}

	/**
	 * Ausgabe vor jedem selektierten Menueintrag
	 * @param String  Ausgabe vor jedem selektierten Menueintrag.
	 */
	function beforeSelected($level, $text) {
		$this->beforeSelected[$level] = $text;
	}

	/**
	 * Ausgabe zwischen zwei Hauptmenupunkten
	 * @param String  Ausgabe zwischen zwei Hauptmenupunkten.
	 */
	function between($level, $text) {
		$this->between[$level] = $text;
	}

	/**
	 * Ausgabe nach der Navigation
	 * @param String  Ausgabe nach der Navigation.
	 */
	function after($level, $text) {
		$this->after[$level] = $text;
	}

	function maskNormal($level, $text) {
		$this->maskNormal[$level] = $text;
	}

	function maskNormalSub($level, $text) {
		$this->maskNormalSub[$level] = $text;
	}

	function maskSelected($level, $text) {
		$this->maskSelected[$level] = $text;
	}

	function maskSelectedSub($level, $text) {
		$this->maskSelectedSub[$level] = $text;
	}

	function maskActive($level, $text) {
		$this->maskActive[$level] = $text;
	}

	function maskActiveSub($level, $text) {
		$this->maskActiveSub[$level] = $text;
	}

	function setSub($level, $content) {
		$this->sub[$level] = $content;
	}

	/**
	 * Gibt das Level der Kategorie zur?ck.
	 * @param Integer  Prim?rschl?ssel der Kategorie.
	 * @return Integer Level der spezifizierten Kategorie.
	 */
	function getLevel($idcat) {

		global $cfg;

		if (empty ($idcat)) {
			return 0;
		}

		$this->db->query("" .
		"SELECT level FROM {$cfg['tab']['cat_tree']} " .
		"WHERE " .
		"   idcat = $idcat" .
		"");
		if ($this->db->next_record()) {
			return $this->db->f('level');
		} else {
			return 0;
		}
	}

	/**
	 * Gib die Tiefe relativ zum Hauptmenu an.
	 * @param Integer  Prim?rschl?ssel der Kategorie
	 * @return Integer Level relativ zum Hauptmenu
	 */
	function getNetLevel($idcat) {

		return $this->getLevel($idcat) - $this->getLevel($this->startId);
	}

	/**
	 * Ermittlung des jeweils ersten Kategorieeintrages jeder Ebene. Die
	 * Speicherung dieser Daten erfolgt in das Klassenattribut id.
	 */
	function setStartIds() {

		$id = $this->idcat;

		$level = $this->getNetLevel($id);
		$this->id[$level] = $id;

		while ($level > 0) {
			$this->id[$level -1] = $this->getParentId($id);
			$id = $this->id[$level -1];
			$level = $this->getNetLevel($id);
		}

		if (empty ($this->id)) {
			$this->id[0] = $this->startId;
		}
		for ($i = 1; $i <= 3; $i++) {
			if (empty ($this->id[$i])) {
				$this->id[$i] = -1;
			}
		}
		ksort($this->id);
	}

	/**
	 * Ermittlung des Elternelementes der Kategorie mit dem Prim?rschl?ssel
	 * idcat
	 * @param Integer  Prim?rschl?ssel des Kindelementes, dessen Elternelement
	 * ermittelt werden soll.
	 * @return Integer Prim?rschl?ssel des Elternelementes.
	 */
	function getParentId($idcat) {

		global $cfg;

		$this->db->query("" .
		"SELECT parentid FROM {$cfg['tab']['cat']} " .
		"WHERE " .
		"   idcat = $idcat " .
		"");
		if ($this->db->next_record()) {
			return $this->db->f('parentid');
		} else {
			return 0;
		}
	}

	/**
	 * Anzeige, ob eine Navigationsebene Elemente enth?lt oder nicht.
	 * @param Integer  Navigationsstufe.
	 * @return Boolean True, wenn die Navigationsstufe leer ist (keine Elemente
	 * enh?lt). Sonst false.
	 */
	function navigationEmpty($level) {

		if ($this->firstId[$level] == 0) {
			return true;
		}

		return false;
	}

	/**
	 * Anzeige, ob eine Kategorie selektiert ist oder nicht. Eine Kategorie gilt
	 * als selektiert, wenn sie die aktuelle Kategorie ist oder ein direktes
	 * oder indirektes Elternelement der aktuellen Kategorie.
	 * @param Integer  Prim?rschl?ssel der Kategorie, deren Status gefragt ist.
	 * @return Boolean True, wenn die gefragte Kategorie mit der aktuellen
	 * Kategorie ?bereinstimmt oder ein direktes oder indirektes Elternelement
	 * der aktuellen Kategorie darstellt.
	 */
	function isSelected($idcat) {

		return in_array($idcat, $this->id);
	}

	/**
	 * Anzeige, ob es sich bei der Kategorie um die aktive Kategorie handelt oder nicht.
	 * @param Integer Prim?rschl?ssel der Kategorie, deren Status gefragt ist.
	 * @return Boolean True, wenn die gefragte Kategorie aktiv ist.
	 */
	function isActive($idcat) {

		return $idcat == $GLOBALS['idcat'];
	}

	/**
	 * Die Funktion gibt true zur?ck, wenn der ?bergene String ausschliesslich aus nummerischen Ziffern besteht.
	 * @param String parameter String, der gepr?ft werden soll.
	 * @return Boolean True, wenn der ?bergebene String ausschliesslich aus nummerischen Ziffern besteht.
	 */
	function isNumeric($parameter) {
		return !preg_match("/[^0-9]/", $parameter);
	}
}
?>