* @license http://www.contenido.org/license/LIZENZ.txt * @link http://www.4fb.de * @link http://www.contenido.org * @since file available since contenido release <= 4.6 * * {@internal * created unknown * modified 2008-06-30, Dominik Ziegler, add security fix * modified 2008-07-08 Thorsten Granz, added option to disable menu hover effect. clicking is now possible again * modified 2009-12-17, Dominik Ziegler, added support for username fallback and fixed double quote * modified 2009-12-16 Corrected rendering of multiple apostrophes in anchors * modified 2010-01-15, Dominik Ziegler, added frontend url to client name * modified 2011-01-28, Dominik Ziegler, added check for client existance for link to frontend [#CON-378] * * $Id$: * }} * */ if (!defined('CON_FRAMEWORK')) { die('Illegal call'); } cInclude('includes', 'functions.api.string.php'); cInclude('includes', 'functions.api.images.php'); /** * Backend navigaton class. Renders the header navigation document containing the navigtion structure. * * @category Contenido * @package Backend * @subpackage Navigation */ class Contenido_Navigation { /** * Flag to debug this vlass * @var bool */ var $debug = 0; /** * Array storing all data * @var array */ var $data = array(); /** * Constructor. Loads the XML language file using XML_Doc. */ function __construct() { global $cfg, $belang; $this->xml = new XML_Doc(); $this->plugxml = new XML_Doc(); // Load language file if ($this->xml->load($cfg['path']['xml'] . $cfg['lang'][$belang]) == false) { if ($this->xml->load($cfg['path']['xml'] . 'lang_en_US.xml') == false) { die('Unable to load any XML language file'); } } } /** * Extracts caption from the XML language file including plugins extended multilang version. * * @param string $location The location of navigation item caption. Feasible values are * - "{xmlFilePath};{XPath}": Path to XML File and the XPath value * separated by semicolon. This type is used * to extract caption from a plugin XML file. * - "{XPath}": XPath value to extract caption from Contenido XML file * @return string The found caption */ function getName($location) { global $cfg, $belang; # If a ";" is found entry is from a plugin -> explode location, first is xml file path, # second is xpath location in xml file if (strstr($location, ';')) { $locs = explode(';', $location); $file = trim($locs[0]); $xpath = trim($locs[1]); $filepath = explode('/', $file); $counter = count($filepath) - 1; if ($filepath[$counter] == '') { unset($filepath[$counter]); $counter--; } if (strstr($filepath[$counter], '.xml')) { $filename = $filepath[$counter]; unset($filepath[$counter]); $counter--; } $filepath[($counter + 1)] = ''; $filepath = implode('/', $filepath); if ($this->plugxml->load($cfg['path']['plugins'] . $filepath . $cfg['lang'][$belang]) == false) { if (!isset($filename)) { $filename = 'lang_en_US.xml'; } if ($this->plugxml->load($cfg['path']['plugins'] . $filepath . $filename) == false) { die("Unable to load $filepath XML language file"); } } $caption = $this->plugxml->valueOf($xpath); } else { $caption = $this->xml->valueOf($location); } return $caption; } /** * Reads and fills the navigation structure data * * @return void */ function _buildHeaderData() { global $cfg, $perm, $belang; $db = new DB_ConLite(); $db2 = new DB_ConLite(); # Load main items $sql = "SELECT idnavm, location FROM " . $cfg['tab']['nav_main'] . " ORDER BY idnavm"; $db->query($sql); # Loop result and build array while ($db->next_record()) { # Extract names from the XML document. $main = $this->getName($db->f('location')); # Build data array $this->data[$db->f('idnavm')] = array($main); $sql = "SELECT a.location AS location, b.name AS area, b.relevant FROM " . $cfg['tab']['nav_sub'] . " AS a, " . $cfg['tab']['area'] . " AS b WHERE a.idnavm = '" . $db->f('idnavm') . "' AND a.level = '0' AND b.idarea = a.idarea AND a.online = '1' AND b.online = '1' ORDER BY a.idnavs"; $db2->query($sql); while ($db2->next_record()) { $area = $db2->f('area'); if ($perm->have_perm_area_action($area) || $db2->f('relevant') == 0) { # Extract names from the XML document. $name = $this->getName($db2->f('location')); $this->data[$db->f('idnavm')][] = array($name, $area); } } } # debugging information if ($this->debug) { echo '
' . print_r($this->data, true) . '
'; } } /** * Function to build the Contenido header document for backend * * @param int $lang The language to use for header doc creation */ function buildHeader($lang) { global $cfg, $sess, $client, $auth, $cfgClient; $this->_buildHeaderData(); $main = new Template(); $sub = new Template(); $cnt = 0; $t_sub = ''; $numSubMenus = 0; $properties = new PropertyCollection(); $clientImage = $properties->getValue('idclient', $client, 'backend', 'clientimage', false); $sJsEvents = ''; foreach ($this->data as $id => $item) { $sub->reset(); $genSubMenu = false; foreach ($item as $key => $value) { if (is_array($value)) { $sub->set('s', 'SUBID', 'sub_' . $id); // create sub menu link $link = new cHTMLLink(); $link->disableAutomaticParameterAppend(); $link->setClass('sub'); $link->setID('sub_' . $value[1]); $link->setLink($sess->url('frameset.php?area=' . $value[1])); $link->setTargetFrame('content'); $link->setContent($value[0]); if ($cfg['help'] == true) { $sJsEvents .= "\n\t" . '$("#sub_' . $value[1] . '").click(function(){ $("#help").attr("data", "' . $value[1] . '"); });'; } $sub->set('d', 'CAPTION', $link->render()); $sub->next(); $genSubMenu = true; } } if ($genSubMenu == true) { $link = new cHTMLLink(); $link->setClass('main'); $link->setID('main_' . $id); $link->setLink('javascript://'); $link->setAttribute('ident', 'sub_' . $id); $link->setContent($item[0]); $main->set('d', 'CAPTION', $link->render()); $main->next(); $numSubMenus++; } else { # first entry in array is a main menu item } # generate a sub menu item. $t_sub .= $sub->generate($cfg['path']['templates'] . $cfg['templates']['submenu'], true); $cnt ++; } if ($cfg['help'] == true) { $sJsEvents .= "\n\t" . 'help.setArea("mycontenido");'; } if ($numSubMenus == 0) { $main->set('d', 'CAPTION', ' '); $main->next(); } $main->set('s', 'SUBMENUS', $t_sub); // my contenido link $oMyConLink = new cHTMLLink(); $oMyConLink->setClass('main'); $oMyConLink->setTargetFrame('content'); $oMyConLink->attachEventDefinition('help_mycontenido', 'onclick', 'help.setArea("mycontenido")'); $oMyConLink->setLink($sess->url("frameset.php?area=mycontenido&frame=4")); $oMyConLink->setContent('MyConLite'); $main->set('s', 'MYCONLITE', $oMyConLink->render()); // info link $oInfoLink = new cHTMLLink(); $oInfoLink->setClass('main'); $oInfoLink->setTargetFrame('content'); $oInfoLink->attachEventDefinition('help_info', 'onclick', 'help.setArea("info")'); $oInfoLink->setLink($sess->url('frameset.php?area=info&frame=4')); $oInfoLink->setContent('Info'); $main->set('s', 'INFO', $oInfoLink->render()); $main->set('s', 'LOGOUT', $sess->url('logout.php')); if ($cfg['help'] == true) { // help link $oHelpLink = new cHTMLLink(); $oHelpLink->setID('help'); $oHelpLink->setClass('main'); $oHelpLink->setLink('javascript://'); $oHelpLink->setEvent('click', 'callHelp($(\'#help\').attr(\'data\'));'); $oHelpLink->setContent('Hilfe'); $main->set('s', 'HELP', $oHelpLink->render()); } else { $main->set('s', 'HELP', ''); } $classuser = new User(); $classclient = new Client(); if (getEffectiveSetting('system', 'clickmenu') == 'true') { // set click menu $main->set('s', 'HEADER_MENU_OBJ', 'HeaderClickMenu'); $main->set('s', 'HEADER_MENU_OPTIONS', '{menuId: "main_0", subMenuId: "sub_0"}'); } else { // set delay menu $mouseOver = getEffectiveSetting('system', 'delaymenu_mouseover', 300); $mouseOot = getEffectiveSetting('system', 'delaymenu_mouseout', 1000); $main->set('s', 'HEADER_MENU_OBJ', 'HeaderDelayMenu'); $main->set('s', 'HEADER_MENU_OPTIONS', '{menuId: "main_0", subMenuId: "sub_0", mouseOverDelay: ' . $mouseOver . ', mouseOutDelay: ' . $mouseOot . '}'); } $main->set('s', 'ACTION', $sess->url('index.php')); $main->set('s', 'LANG', $this->_renderLanguageSelect()); $main->set('s', 'WIDTH', ''); $sClientName = $classclient->getClientName($client); if (strlen($sClientName) > 25) { $sClientName = capiStrTrimHard($sClientName, 25); } $client = Contenido_Security::toInteger($client); if ($client == 0) { $sClientNameTemplate = '' . i18n("Client") . ': %s'; $main->set('s', 'CHOSENCLIENT', sprintf($sClientNameTemplate, $sClientName)); } else { $sClientNameTemplate = '' . i18n("Client") . ': %s'; $sClientName = $classclient->getClientName($client) . ' (' . $client . ')'; $sClientUrl = $cfgClient[$client]["path"]["htmlpath"]; if ($clientImage !== false && $clientImage != "" && file_exists($cfgClient[$client]['path']['frontend'] . $clientImage)) { $sClientImageTemplate = '%s'; $sThumbnailPath = capiImgScale($cfgClient[$client]['path']['frontend'] . $clientImage, 80, 25, 0, 1); $sClientImageTag = sprintf($sClientImageTemplate, $sThumbnailPath, $sClientName, $sClientName); $main->set('s', 'CHOSENCLIENT', sprintf($sClientNameTemplate, $sClientUrl, $sClientImageTag)); } else { $main->set('s', 'CHOSENCLIENT', sprintf($sClientNameTemplate, $sClientUrl, $sClientName)); } } $main->set('s', 'CHOSENUSER', "" . i18n("User") . ": " . $classuser->getRealname($auth->auth["uid"], true)); $main->set('s', 'SID', $sess->id); $main->set('s', 'MAINLOGINLINK', $sess->url("frameset.php?area=mycontenido&frame=4")); // additional footer javascript $footerJs = ''; if ($sJsEvents !== '') { $footerJs = '$(document).ready(function(){' . $sJsEvents . '});'; } $main->set('s', 'FOOTER_JS', $footerJs); $main->generate($cfg['path']['templates'] . $cfg['templates']['header']); } /** * Renders the language select box * * @todo recode and remove direct sql calls * * @return string */ function _renderLanguageSelect() { global $cfg, $client, $lang; $tpl = new Template(); $tpl->set('s', 'NAME', 'changelang'); $tpl->set('s', 'CLASS', 'text_medium'); $tpl->set('s', 'ID', 'cLanguageSelect'); $tpl->set('s', 'OPTIONS', 'onchange="changeContenidoLanguage(this.value)"'); $availableLanguages = new cApiLanguageCollection(); if (getEffectiveSetting('system', 'languageorder', 'name') == 'name') { $availableLanguages->select('', '', 'name ASC'); } else { $availableLanguages->select('', '', 'idlang ASC'); } $db = new DB_ConLite(); if ($availableLanguages->count() > 0) { while ($myLang = $availableLanguages->nextAccessible()) { $key = $myLang->get('idlang'); $value = $myLang->get('name'); // I want to get rid of such silly constructs very soon :) $sql = "SELECT idclient FROM " . $cfg['tab']['clients_lang'] . " WHERE idlang = '" . Contenido_Security::toInteger($key) . "'"; $db->query($sql); if ($db->next_record()) { if ($db->f('idclient') == $client) { if ($key == $lang) { $tpl->set('d', 'SELECTED', 'selected'); } else { $tpl->set('d', 'SELECTED', ''); } if (strlen($value) > 20) { $value = capiStrTrimHard($value, 20); } $tpl->set('d', 'VALUE', $key); $tpl->set('d', 'CAPTION', $value . ' (' . $key . ')'); $tpl->next(); } } } } else { $tpl->set('d', 'VALUE', 0); $tpl->set('d', 'CAPTION', i18n('-- No Language available --')); $tpl->next(); } return $tpl->generate($cfg['path']['templates'] . $cfg['templates']['generic_select'], true); } }