![]() |
|---|
| [ Index ] |
Source Code Reference for V1.00 |
[Summary view] [Print] [Text view]
1 <?php /* $Id: ui.class.php 174 2008-07-17 14:36:48Z pedroix $ $URL: https://web2project.svn.sourceforge.net/svnroot/web2project/trunk/classes/ui.class.php $ */ 2 /** 3 * @package web2project 4 * @subpackage core 5 * @license http://opensource.org/licenses/gpl-license.php GPL License Version 2 6 */ 7 8 if (!defined('W2P_BASE_DIR')) { 9 die('This file should not be called directly.'); 10 } 11 12 // Message No Constants 13 define('UI_MSG_OK', 1); 14 define('UI_MSG_ALERT', 2); 15 define('UI_MSG_WARNING', 3); 16 define('UI_MSG_ERROR', 4); 17 18 // global variable holding the translation array 19 $GLOBALS['translate'] = array(); 20 21 define('UI_CASE_MASK', 0x0F); 22 define('UI_CASE_UPPER', 1); 23 define('UI_CASE_LOWER', 2); 24 define('UI_CASE_UPPERFIRST', 3); 25 26 define('UI_OUTPUT_MASK', 0xF0); 27 define('UI_OUTPUT_HTML', 0); 28 define('UI_OUTPUT_JS', 0x10); 29 define('UI_OUTPUT_RAW', 0x20); 30 31 // W2P_BASE_DIR is set in base.php and fileviewer.php and is the base directory 32 // of the web2project installation. 33 require_once W2P_BASE_DIR . '/classes/permissions.class.php'; 34 /** 35 * The Application User Interface Class. 36 * 37 * @author Andrew Eddie <eddieajau@users.sourceforge.net> 38 * @version $Revision: 174 $ 39 */ 40 class CAppUI { 41 /** 42 @var array generic array for holding the state of anything */ 43 var $state = null; 44 /** 45 @var int */ 46 var $user_id = null; 47 /** 48 @var string */ 49 var $user_first_name = null; 50 /** 51 @var string */ 52 var $user_last_name = null; 53 /** 54 @var string */ 55 var $user_company = null; 56 /** 57 @var int */ 58 var $user_department = null; 59 /** 60 @var string */ 61 var $user_email = null; 62 /** 63 @var int */ 64 var $user_type = null; 65 /** 66 @var array */ 67 var $user_prefs = null; 68 /** 69 @var int Unix time stamp */ 70 var $day_selected = null; 71 72 // localisation 73 /** 74 @var string */ 75 var $user_locale = null; 76 /** 77 @var string */ 78 var $user_lang = null; 79 /** 80 @var string */ 81 var $base_locale = 'en'; // do not change - the base 'keys' will always be in english 82 83 /** 84 @var string Message string*/ 85 var $msg = ''; 86 /** 87 @var string */ 88 var $msgNo = ''; 89 /** 90 @var string Default page for a redirect call*/ 91 var $defaultRedirect = ''; 92 93 /** 94 @var array Configuration variable array*/ 95 var $cfg = null; 96 97 /** 98 @var integer Version major */ 99 var $version_major = null; 100 101 /** 102 @var integer Version minor */ 103 var $version_minor = null; 104 105 /** 106 @var integer Version patch level */ 107 var $version_patch = null; 108 109 /** 110 @var string Version string */ 111 var $version_string = null; 112 113 /** 114 @var integer for register log ID */ 115 var $last_insert_id = null; 116 117 /** 118 @var string */ 119 var $user_style = null; 120 121 /** 122 123 * CAppUI Constructor 124 */ 125 function CAppUI() { 126 $this->state = array(); 127 128 $this->user_id = -1; 129 $this->user_first_name = ''; 130 $this->user_last_name = ''; 131 $this->user_company = 0; 132 $this->user_department = 0; 133 $this->user_type = 0; 134 135 // cfg['locale_warn'] is the only cfgVariable stored in session data (for security reasons) 136 // this guarants the functionality of this->setWarning 137 $this->cfg['locale_warn'] = w2PgetConfig('locale_warn'); 138 139 $this->project_id = 0; 140 141 $this->defaultRedirect = ''; 142 // set up the default preferences 143 $this->setUserLocale($this->base_locale); 144 $this->user_prefs = array(); 145 } 146 /** 147 * Used to load a php class file from the system classes directory 148 * @param string $name The class root file name (excluding .class.php) 149 * @return string The path to the include file 150 */ 151 function getSystemClass($name = null) { 152 if ($name) { 153 return W2P_BASE_DIR . '/classes/' . $name . '.class.php'; 154 } 155 } 156 157 /** 158 * Used to load a php class file from the lib directory 159 * 160 * @param string $name The class root file name (excluding .class.php) 161 * @return string The path to the include file 162 */ 163 function getLibraryClass($name = null) { 164 if ($name) { 165 return W2P_BASE_DIR . '/lib/' . $name . '.php'; 166 } 167 } 168 169 /** 170 * Used to load a php class file from the module directory 171 * @param string $name The class root file name (excluding .class.php) 172 * @return string The path to the include file 173 */ 174 function getModuleClass($name = null) { 175 if ($name) { 176 return W2P_BASE_DIR . '/modules/' . $name . '/' . $name . '.class.php'; 177 } 178 } 179 180 /** 181 * Used to load a php class file from the module directory 182 * @param string $name The class root file name (excluding .ajax.php) 183 * @return string The path to the include file 184 */ 185 function getModuleAjax( $name=null ) { 186 if ($name) { 187 return W2P_BASE_DIR . '/modules/' . $name . '/' . $name . '.ajax.php'; 188 } 189 } 190 191 /** 192 * Determines the version. 193 * @return String value indicating the current web2project version 194 */ 195 function getVersion() { 196 global $w2Pconfig; 197 if (!isset($this->version_major)) { 198 include_once W2P_BASE_DIR . '/includes/version.php'; 199 $this->version_major = $w2p_version_major; 200 $this->version_minor = $w2p_version_minor; 201 $this->version_patch = $w2p_version_patch; 202 $this->version_string = $this->version_major . '.' . $this->version_minor; 203 if (isset($this->version_patch)) { 204 $this->version_string .= '.' . $this->version_patch; 205 } 206 if (isset($w2p_version_prepatch)) { 207 $this->version_string .= '-' . $w2p_version_prepatch; 208 } 209 } 210 return $this->version_string; 211 } 212 213 /** 214 * Checks that the current user preferred style is valid/exists. 215 */ 216 function checkStyle() { 217 // check if default user's uistyle is installed 218 $uistyle = $this->getPref('UISTYLE'); 219 220 if ($uistyle && !is_dir(W2P_BASE_DIR . '/style/' . $uistyle)) { 221 // fall back to host_style if user style is not installed 222 $this->setPref('UISTYLE', w2PgetConfig('host_style')); 223 } 224 } 225 226 /** 227 * Utility function to read the 'directories' under 'path' 228 * 229 * This function is used to read the modules or locales installed on the file system. 230 * @param string The path to read. 231 * @return array A named array of the directories (the key and value are identical). 232 */ 233 function readDirs($path) { 234 $dirs = array(); 235 $d = dir(W2P_BASE_DIR . '/' . $path); 236 while (false !== ($name = $d->read())) { 237 if (is_dir(W2P_BASE_DIR . '/' . $path . '/' . $name) && $name != '.' && $name != '..' && $name != 'CVS' && $name != '.svn') { 238 $dirs[$name] = $name; 239 } 240 } 241 $d->close(); 242 return $dirs; 243 } 244 245 /** 246 * Utility function to read the 'files' under 'path' 247 * @param string The path to read. 248 * @param string A regular expression to filter by. 249 * @return array A named array of the files (the key and value are identical). 250 */ 251 function readFiles($path, $filter = '.') { 252 $files = array(); 253 254 if (is_dir($path) && ($handle = opendir($path))) { 255 while (false !== ($file = readdir($handle))) { 256 if ($file != '.' && $file != '..' && preg_match('/' . $filter . '/', $file)) { 257 $files[$file] = $file; 258 } 259 } 260 closedir($handle); 261 } 262 return $files; 263 } 264 265 /** 266 * Utility function to check whether a file name is 'safe' 267 * 268 * Prevents from access to relative directories (eg ../../dealyfile.php); 269 * @param string The file name. 270 * @return array A named array of the files (the key and value are identical). 271 */ 272 function checkFileName($file) { 273 global $AppUI; 274 275 // define bad characters and their replacement 276 $bad_chars = ";/\\"; 277 $bad_replace = '....'; // Needs the same number of chars as $bad_chars 278 279 // check whether the filename contained bad characters 280 if (strpos(strtr($file, $bad_chars, $bad_replace), '.') !== false) { 281 $AppUI->redirect('m=public&a=access_denied'); 282 } else { 283 return $file; 284 } 285 286 } 287 288 /** 289 * Utility function to make a file name 'safe' 290 * 291 * Strips out mallicious insertion of relative directories (eg ../../dealyfile.php); 292 * @param string The file name. 293 * @return array A named array of the files (the key and value are identical). 294 */ 295 function makeFileNameSafe($file) { 296 $file = str_replace('../', '', $file); 297 $file = str_replace('..\\', '', $file); 298 return $file; 299 } 300 301 /** 302 * Sets the user locale. 303 * 304 * Looks in the user preferences first. If this value has not been set by the user it uses the system default set in config.php. 305 * @param string Locale abbreviation corresponding to the sub-directory name in the locales directory (usually the abbreviated language code). 306 */ 307 function setUserLocale($loc = '', $set = true) { 308 global $locale_char_set; 309 310 $LANGUAGES = $this->loadLanguages(); 311 312 if (!$loc) { 313 $loc = $this->user_prefs['LOCALE'] ? $this->user_prefs['LOCALE'] : w2PgetConfig('host_locale'); 314 } 315 316 if (isset($LANGUAGES[$loc])) 317 $lang = $LANGUAGES[$loc]; 318 else { 319 // Need to try and find the language the user is using, find the first one 320 // that has this as the language part 321 if (strlen($loc) > 2) { 322 list($l, $c) = explode('_', $loc); 323 $loc = $this->findLanguage($l, $c); 324 } else { 325 $loc = $this->findLanguage($loc); 326 } 327 $lang = $LANGUAGES[$loc]; 328 } 329 list($base_locale, $english_string, $native_string, $default_language, $lcs) = $lang; 330 if (!isset($lcs)) 331 $lcs = (isset($locale_char_set)) ? $locale_char_set : 'utf-8'; 332 333 if (version_compare(phpversion(), '4.3.0', 'ge')) { 334 $user_lang = array($loc . '.' . $lcs, $default_language, $loc, $base_locale); 335 } else { 336 if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') { 337 $user_lang = $default_language; 338 } else { 339 $user_lang = $loc . '.' . $lcs; 340 } 341 } 342 if ($set) { 343 $this->user_locale = $base_locale; 344 $this->user_lang = $user_lang; 345 $locale_char_set = $lcs; 346 } else { 347 return $user_lang; 348 } 349 } 350 351 function findLanguage($language, $country = false) { 352 $LANGUAGES = $this->loadLanguages(); 353 $language = strtolower($language); 354 if ($country) { 355 $country = strtoupper($country); 356 // Try constructing the code again 357 $code = $language . '_' . $country; 358 if (isset($LANGUAGES[$code])) { 359 return $code; 360 } 361 } 362 363 // Just use the country code and try and find it in the 364 // languages list. 365 $first_entry = null; 366 foreach ($LANGUAGES as $lang => $info) { 367 list($l, $c) = explode('_', $lang); 368 if ($l == $language) { 369 if (!$first_entry) { 370 $first_entry = $lang; 371 } 372 if ($country && $c == $country) { 373 return $lang; 374 } 375 } 376 } 377 return $first_entry; 378 } 379 380 /** 381 * Load the known language codes for loaded locales 382 * 383 */ 384 function loadLanguages() { 385 386 if (isset($_SESSION['LANGUAGES'])) { 387 $LANGUAGES = &$_SESSION['LANGUAGES']; 388 } else { 389 $LANGUAGES = array(); 390 $langs = $this->readDirs('locales'); 391 foreach ($langs as $lang) { 392 if (file_exists(W2P_BASE_DIR . '/locales/' . $lang . '/lang.php')) { 393 include_once W2P_BASE_DIR . '/locales/' . $lang . '/lang.php'; 394 } 395 } 396 $_SESSION['LANGUAGES'] = &$LANGUAGES; 397 } 398 return $LANGUAGES; 399 } 400 401 /** 402 * Translate string to the local language [same form as the gettext abbreviation] 403 * 404 * This is the order of precedence: 405 * <ul> 406 * <li>If the key exists in the lang array, return the value of the key 407 * <li>If no key exists and the base lang is the same as the local lang, just return the string 408 * <li>If this is not the base lang, then return string with a red star appended to show 409 * that a translation is required. 410 * </ul> 411 * @param string The string to translate 412 * @param int Option flags, can be case handling or'd with output styles 413 * @return string 414 */ 415 function _($str, $flags = 0) { 416 if (is_array($str)) { 417 $translated = array(); 418 foreach ($str as $s) { 419 $translated[] = $this->__($s, $flags); 420 } 421 return implode(' ', $translated); 422 } else { 423 return $this->__($str, $flags); 424 } 425 } 426 427 function __($str, $flags = 0) { 428 $str = trim($str); 429 if (empty($str)) { 430 return ''; 431 } 432 $x = $GLOBALS['translate'][$str]; 433 434 if ($x) { 435 $str = $x; 436 } elseif (w2PgetConfig('locale_warn')) { 437 if ($this->base_locale != $this->user_locale || ($this->base_locale == $this->user_locale && !in_array($str, $GLOBALS['translate']))) { 438 $str .= w2PgetConfig('locale_alert'); 439 } 440 } 441 switch ($flags & UI_CASE_MASK) { 442 case UI_CASE_UPPER: 443 $str = strtoupper($str); 444 break; 445 case UI_CASE_LOWER: 446 $str = strtolower($str); 447 break; 448 case UI_CASE_UPPERFIRST: 449 $str = ucwords($str); 450 break; 451 } 452 /* Altered to support multiple styles of output, to fix 453 * bugs where the same output style cannot be used succesfully 454 * for both javascript and HTML output. 455 * PLEASE NOTE: The default is currently UI_OUTPUT_HTML, 456 * which is different to the previous version (which was 457 * effectively UI_OUTPUT_RAW). If this causes problems, 458 * and they are localised, then use UI_OUTPUT_RAW in the 459 * offending call. If they are widespread, change the 460 * default to UI_OUTPUT_RAW and use the other options 461 * where appropriate. 462 * AJD - 2004-12-10 463 */ 464 global $locale_char_set; 465 466 if (!$locale_char_set) { 467 $locale_char_set = 'utf-8'; 468 } 469 470 switch ($flags & UI_OUTPUT_MASK) { 471 case UI_OUTPUT_HTML: 472 $str = htmlentities(stripslashes($str), ENT_COMPAT, $locale_char_set); 473 break; 474 case UI_OUTPUT_JS: 475 $str = addslashes(stripslashes($str)); //, ENT_COMPAT, $locale_char_set); 476 break; 477 case UI_OUTPUT_RAW: 478 $str = stripslashes($str); 479 break; 480 } 481 return $str; 482 } 483 /** 484 * Set the display of warning for untranslated strings 485 * @param string 486 */ 487 function setWarning($state = true) { 488 $temp = $this->cfg['locale_warn']; 489 $this->cfg['locale_warn'] = $state; 490 return $temp; 491 } 492 /** 493 * Save the url query string 494 * 495 * Also saves one level of history. This is useful for returning from a delete 496 * operation where the record more not now exist. Returning to a view page 497 * would be a nonsense in this case. 498 * @param string If not set then the current url query string is used 499 */ 500 function savePlace($query = '') { 501 if (!$query) { 502 $query = $_SERVER['QUERY_STRING']; 503 } 504 if ($query != $this->state['SAVEDPLACE']) { 505 $this->state['SAVEDPLACE-1'] = $this->state['SAVEDPLACE']; 506 $this->state['SAVEDPLACE'] = $query; 507 } 508 } 509 /** 510 * Resets the internal variable 511 */ 512 function resetPlace() { 513 $this->state['SAVEDPLACE'] = ''; 514 } 515 /** 516 * Get the saved place (usually one that could contain an edit button) 517 * @return string 518 */ 519 function getPlace() { 520 return $this->state['SAVEDPLACE']; 521 } 522 /** 523 * Redirects the browser to a new page. 524 * 525 * Mostly used in conjunction with the savePlace method. It is generally used 526 * to prevent nasties from doing a browser refresh after a db update. The 527 * method deliberately does not use javascript to effect the redirect. 528 * 529 * @param string The URL query string to append to the URL 530 * @param string A marker for a historic 'place, only -1 or an empty string is valid. 531 */ 532 function redirect($params = '', $hist = '') { 533 $session_id = SID; 534 535 session_write_close(); 536 // are the params empty 537 if (!$params) { 538 // has a place been saved 539 $params = !empty($this->state['SAVEDPLACE' . $hist]) ? $this->state['SAVEDPLACE' . $hist] : $this->defaultRedirect; 540 } 541 // Fix to handle cookieless sessions 542 if ($session_id != '') { 543 if (!$params) { 544 $params = $session_id; 545 } else { 546 $params .= '&' . $session_id; 547 } 548 } 549 ob_implicit_flush(); // Ensure any buffering is disabled. 550 header('Location: index.php?' . $params); 551 exit(); // stop the PHP execution 552 } 553 /** 554 * Set the page message. 555 * 556 * The page message is displayed above the title block and then again 557 * at the end of the page. 558 * 559 * IMPORTANT: Please note that append should not be used, since for some 560 * languagues atomic-wise translation doesn't work. Append should be 561 * deprecated. 562 * 563 * @param mixed The (untranslated) message 564 * @param int The type of message 565 * @param boolean If true, $msg is appended to the current string otherwise 566 * the existing message is overwritten with $msg. 567 */ 568 function setMsg($msg, $msgNo = 0, $append = false) { 569 $msg = $this->_($msg, UI_OUTPUT_RAW); 570 $this->msg = $append ? $this->msg . ' ' . $msg : $msg; 571 $this->msgNo = $msgNo; 572 } 573 /** 574 * Display the formatted message and icon 575 * @param boolean If true the current message state is cleared. 576 */ 577 function getMsg($reset = true) { 578 $img = ''; 579 $class = ''; 580 $msg = $this->msg; 581 582 switch ($this->msgNo) { 583 case UI_MSG_OK: 584 $img = w2PshowImage('stock_ok-16.png', 16, 16, ''); 585 $class = 'message'; 586 break; 587 case UI_MSG_ALERT: 588 $img = w2PshowImage('rc-gui-status-downgr.png', 16, 16, ''); 589 $class = 'message'; 590 break; 591 case UI_MSG_WARNING: 592 $img = w2PshowImage('rc-gui-status-downgr.png', 16, 16, ''); 593 $class = 'warning'; 594 break; 595 case UI_MSG_ERROR: 596 $img = w2PshowImage('stock_cancel-16.png', 16, 16, ''); 597 $class = 'error'; 598 break; 599 default: 600 $class = 'message'; 601 break; 602 } 603 if ($reset) { 604 $this->msg = ''; 605 $this->msgNo = 0; 606 } 607 return $msg ? '<table cellspacing="0" cellpadding="1" border="0"><tr>' . '<td>' . $img . '</td>' . '<td class="' . $class . '">' . $msg . '</td>' . '</tr></table>' : ''; 608 } 609 /** 610 * Set the value of a temporary state variable. 611 * 612 * The state is only held for the duration of a session. It is not stored in the database. 613 * Also do not set the value if it is unset. 614 * @param string The label or key of the state variable 615 * @param mixed Value to assign to the label/key 616 */ 617 function setState($label, $value = null) { 618 if (isset($value)) { 619 $this->state[$label] = $value; 620 } 621 } 622 /** 623 * Get the value of a temporary state variable. 624 * If a default value is supplied and no value is found, set the default. 625 * @return mixed 626 */ 627 function getState($label, $default_value = null) { 628 if (array_key_exists($label, $this->state)) { 629 return $this->state[$label]; 630 } else 631 if (isset($default_value)) { 632 $this->setState($label, $default_value); 633 return $default_value; 634 } else { 635 return null; 636 } 637 } 638 639 function checkPrefState($label, $value, $prefname, $default_value = null) { 640 // Check if we currently have it set 641 if (isset($value)) { 642 $result = $value; 643 $this->state[$label] = $value; 644 } else 645 if (array_key_exists($label, $this->state)) { 646 $result = $this->state[$label]; 647 } else 648 if (($pref = $this->getPref($prefname)) !== null) { 649 $this->state[$label] = $pref; 650 $result = $pref; 651 } else 652 if (isset($default_value)) { 653 $this->state[$label] = $default_value; 654 $result = $default_value; 655 } else { 656 $result = null; 657 } 658 return $result; 659 } 660 /** 661 * Login function 662 * 663 * A number of things are done in this method to prevent illegal entry: 664 * <ul> 665 * <li>The username and password are trimmed and escaped to prevent malicious 666 * SQL being executed 667 * </ul> 668 * The schema previously used the MySQL PASSWORD function for encryption. This 669 * Method has been deprecated in favour of PHP's MD5() function for database independance. 670 * The check_legacy_password option is no longer valid 671 * 672 * Upon a successful username and password match, several fields from the user 673 * table are loaded in this object for convenient reference. The style, localces 674 * and preferences are also loaded at this time. 675 * 676 * @param string The user login name 677 * @param string The user password 678 * @return boolean True if successful, false if not 679 */ 680 function login($username, $password) { 681 require_once W2P_BASE_DIR . '/classes/authenticator.class.php'; 682 683 $auth_method = w2PgetConfig('auth_method', 'sql'); 684 if ($_POST['login'] != 'login' && $_POST['login'] != $this->_('login', UI_OUTPUT_RAW) && $_REQUEST['login'] != $auth_method) { 685 die('You have chosen to log in using an unsupported or disabled login method'); 686 } 687 $auth = &getauth($auth_method); 688 689 $username = trim(db_escape($username)); 690 $password = trim($password); 691 692 if (!$auth->authenticate($username, $password)) { 693 return false; 694 } 695 696 $user_id = $auth->userId($username); 697 $username = $auth->username; // Some authentication schemes may collect username in various ways. 698 // Now that the password has been checked, see if they are allowed to 699 // access the system 700 if (!isset($GLOBALS['acl'])) { 701 $GLOBALS['acl'] = &new w2Pacl; 702 } 703 if (!$GLOBALS['acl']->checkLogin($user_id)) { 704 dprint(__file__, __line__, 1, 'Permission check failed'); 705 return false; 706 } 707 708 $q = new DBQuery; 709 $q->addTable('users'); 710 $q->addQuery('user_id, contact_first_name as user_first_name, contact_last_name as user_last_name, contact_company as user_company, contact_department as user_department, contact_email as user_email, user_type'); 711 $q->addJoin('contacts', 'con', 'contact_id = user_contact', 'inner'); 712 $q->addWhere('user_id = ' . (int)$user_id . ' AND user_username = \'' . $username . '\''); 713 $sql = $q->prepare(); 714 $q->loadObject($this); 715 $q->clear(); 716 dprint(__file__, __line__, 7, 'Login SQL: ' . $sql); 717 718 if (!$this) { 719 dprint(__file__, __line__, 1, 'Failed to load user information'); 720 return false; 721 } 722 723 // load the user preferences 724 $this->loadPrefs($this->user_id); 725 $this->setUserLocale(); 726 $this->checkStyle(); 727 return true; 728 } 729 /************************************************************************************************************************ 730 /** 731 *@Function for regiser log in dotprojet table "user_access_log" 732 */ 733 function registerLogin() { 734 $q = new DBQuery; 735 $q->addTable('user_access_log'); 736 $q->addInsert('user_id', '' . $this->user_id); 737 $q->addInsert('date_time_in', 'now()', false, true); 738 $q->addInsert('user_ip', $_SERVER['REMOTE_ADDR']); 739 $q->exec(); 740 $this->last_insert_id = db_insert_id(); 741 $q->clear(); 742 } 743 744 /** 745 *@Function for register log out in web2project table "user_acces_log" 746 */ 747 function registerLogout($user_id) { 748 $q = new DBQuery; 749 $q->addTable('user_access_log'); 750 $q->addUpdate('date_time_out', date('Y-m-d H:i:s')); 751 $q->addWhere('user_id = ' . (int)$user_id . ' AND (date_time_out = \'0000-00-00 00:00:00\' OR ISNULL(date_time_out)) '); 752 if ($user_id > 0) { 753 $q->exec(); 754 $q->clear(); 755 } 756 } 757 758 /** 759 *@Function for update table user_acces_log in field date_time_lost_action 760 */ 761 function updateLastAction($last_insert_id) { 762 $q = new DBQuery; 763 $q->addTable('user_access_log'); 764 $q->addUpdate('date_time_last_action', date('Y-m-d H:i:s')); 765 $q->addWhere('user_access_log_id = ' . $last_insert_id); 766 if ($last_insert_id > 0) { 767 $q->exec(); 768 $q->clear(); 769 } 770 } 771 /************************************************************************************************************************ 772 /** 773 * @deprecated 774 */ 775 function logout() { 776 } 777 /** 778 * Checks whether there is any user logged in. 779 */ 780 function doLogin() { 781 return ($this->user_id < 0) ? true : false; 782 } 783 /** 784 * Gets the value of the specified user preference 785 * @param string Name of the preference 786 */ 787 function getPref($name) { 788 return $this->user_prefs[$name]; 789 } 790 /** 791 * Sets the value of a user preference specified by name 792 * @param string Name of the preference 793 * @param mixed The value of the preference 794 */ 795 function setPref($name, $val) { 796 $this->user_prefs[$name] = $val; 797 } 798 /** 799 * Loads the stored user preferences from the database into the internal 800 * preferences variable. 801 * @param int User id number 802 */ 803 function loadPrefs($uid = 0) { 804 $q = new DBQuery; 805 $q->addTable('user_preferences'); 806 $q->addQuery('pref_name, pref_value'); 807 $q->addWhere('pref_user = ' . (int)$uid); 808 $prefs = $q->loadHashList(); 809 $this->user_prefs = array_merge($this->user_prefs, $prefs); 810 } 811 812 // --- Module connectors 813 814 /** 815 * Gets a list of the installed modules 816 * @return array Named array list in the form 'module directory'=>'module name' 817 */ 818 function getInstalledModules() { 819 $q = new DBQuery; 820 $q->addTable('modules'); 821 $q->addQuery('mod_directory, mod_ui_name'); 822 $q->addOrder('mod_directory'); 823 return ($q->loadHashList()); 824 } 825 /** 826 * Gets a list of the active modules 827 * @return array Named array list in the form 'module directory'=>'module name' 828 */ 829 function getActiveModules() { 830 $q = new DBQuery; 831 $q->addTable('modules'); 832 $q->addQuery('mod_directory, mod_ui_name'); 833 $q->addWhere('mod_active = 1'); 834 $q->addOrder('mod_directory'); 835 return ($q->loadHashList()); 836 } 837 /** 838 * Gets a list of the modules that should appear in the menu 839 * @return array Named array list in the form 840 * ['module directory', 'module name', 'module_icon'] 841 */ 842 function getMenuModules() { 843 $q = new DBQuery; 844 $q->addTable('modules'); 845 $q->addQuery('mod_directory, mod_ui_name, mod_ui_icon'); 846 $q->addWhere('mod_active > 0 AND mod_ui_active > 0 AND mod_directory <> \'public\''); 847 $q->addWhere('mod_type <> \'utility\''); 848 $q->addOrder('mod_ui_order'); 849 return ($q->loadList()); 850 } 851 852 function isActiveModule($module) { 853 $q = new DBQuery; 854 $q->addTable('modules'); 855 $q->addQuery('mod_active'); 856 $q->addWhere('mod_directory = \'' . $module . '\''); 857 $result = $q->loadResult(); 858 $q->clear(); 859 return $result; 860 } 861 862 /** 863 * Returns the global dpACL class or creates it as neccessary. 864 * @return object w2Pacl 865 */ 866 function &acl() { 867 if (!isset($GLOBALS['acl'])) { 868 $GLOBALS['acl'] = &new w2Pacl; 869 } 870 return $GLOBALS['acl']; 871 } 872 873 /** 874 * Find and add to output the file tags required to load module-specific 875 * javascript. 876 */ 877 function loadHeaderJS() { 878 global $m, $a; 879 880 // load the js base.php 881 include w2PgetConfig('root_dir') . '/js/base.php'; 882 883 // Search for the javascript files to load. 884 if (!isset($m)) { 885 return; 886 } 887 $root = W2P_BASE_DIR; 888 if (substr($root, -1) != '/') { 889 $root .= '/'; 890 } 891 892 $base = W2P_BASE_URL; 893 if (substr($base, -1) != '/') { 894 $base .= '/'; 895 } 896 // Load the basic javascript used by all modules. 897 echo '<script type="text/javascript" src="'.$base.'js/base.js"></script>'; 898 899 // additionally load mootools 900 echo '<script type="text/javascript" src="'.$base.'lib/mootools/mootools.js"></script>'; 901 902 $this->getModuleJS($m, $a, true); 903 } 904 905 function getModuleJS($module, $file = null, $load_all = false) { 906 $root = W2P_BASE_DIR; 907 if (substr($root, -1) != '/') { 908 $root .= '/'; 909 } 910 $base = W2P_BASE_URL; 911 if (substr($base, -1) != '/') { 912 $base .= '/'; 913 } 914 if ($load_all || !$file) { 915 if (file_exists($root . 'modules/' . $module . '/' . $module . '.module.js')) { 916 echo '<script type="text/javascript" src="' . $base . 'modules/' . $module . '/' . $module . '.module.js"></script>'; 917 } 918 } 919 if (isset($file) && file_exists($root . 'modules/' . $module . '/' . $file . '.js')) { 920 echo '<script type="text/javascript" src="' . $base . 'modules/' . $module . '/' . $file . '.js"></script>'; 921 } 922 } 923 924 function loadFooterJS() { 925 $s = '<script type="text/javascript">'; 926 $s .= 'window.addEvent(\'domready\', function(){'; 927 $s .= ' var as = [];'; 928 $s .= ' $$(\'span\').each(function(span){'; 929 $s .= ' if (span.getAttribute(\'title\')) as.push(span);'; 930 $s .= ' });'; 931 $s .= ' new Tips(as), {'; 932 $s .= ' }'; 933 $s .= '});'; 934 $s .= '</script>'; 935 echo $s; 936 } 937 938 function loadCalendarJS() { 939 global $AppUI; 940 //$s = '<style type="text/css">@import url('.w2PgetConfig('base_url').'/lib/jscalendar/calendar-win2k-1.css);</style>'; 941 $s = '<style type="text/css">@import url(' . w2PgetConfig('base_url') . '/lib/jscalendar/skins/aqua/theme.css);</style>'; 942 $s .= '<script type="text/javascript" src="' . w2PgetConfig('base_url') . '/js/calendar.js"></script>'; 943 $s .= '<script type="text/javascript" src="' . w2PgetConfig('base_url') . '/lib/jscalendar/calendar.js"></script>'; 944 if (file_exists(w2PgetConfig('root_dir') . '/lib/jscalendar/lang/calendar-' . $AppUI->user_locale . '.js')) { 945 $s .= '<script type="text/javascript" src="' . w2PgetConfig('base_url') . '/lib/jscalendar/lang/calendar-' . $AppUI->user_locale . '.js"></script>'; 946 } else { 947 $s .= '<script type="text/javascript" src="' . w2PgetConfig('base_url') . '/lib/jscalendar/lang/calendar-en.js"></script>'; 948 } 949 $s .= '<script type="text/javascript" src="' . w2PgetConfig('base_url') . '/lib/jscalendar/calendar-setup.js"></script>'; 950 echo $s; 951 include w2PgetConfig('root_dir') . '/js/calendar.php'; 952 } 953 } 954 955 /** 956 * Tabbed box abstract class 957 */ 958 class CTabBox_core { 959 /** 960 @var array */ 961 var $tabs = null; 962 /** 963 @var int The active tab */ 964 var $active = null; 965 /** 966 @var string The base URL query string to prefix tab links */ 967 var $baseHRef = null; 968 /** 969 @var string The base path to prefix the include file */ 970 var $baseInc; 971 /** 972 973 * the active tab, and the selected tab **/ 974 var $javascript = null; 975 976 /** 977 * Constructor 978 * @param string The base URL query string to prefix tab links 979 * @param string The base path to prefix the include file 980 * @param int The active tab 981 * @param string Optional javascript method to be used to execute tabs. 982 * Must support 2 arguments, currently active tab, new tab to activate. 983 */ 984 function CTabBox_core($baseHRef = '', $baseInc = '', $active = 0, $javascript = null) { 985 $this->tabs = array(); 986 $this->active = $active; 987 $this->baseHRef = ($baseHRef ? $baseHRef . '&' : '?'); 988 $this->javascript = $javascript; 989 $this->baseInc = $baseInc; 990 } 991 /** 992 * Gets the name of a tab 993 * @return string 994 */ 995 function getTabName($idx) { 996 return $this->tabs[$idx][1]; 997 } 998 /** 999 * Adds a tab to the object 1000 * @param string File to include 1001 * @param The display title/name of the tab 1002 */ 1003 function add($file, $title, $translated = false, $key = null) { 1004 $t = array($file, $title, $translated); 1005 if (isset($key)) { 1006 $this->tabs[$key] = $t; 1007 } else { 1008 $this->tabs[] = $t; 1009 } 1010 } 1011 1012 function isTabbed() { 1013 global $AppUI; 1014 if ($this->active < 0 || $AppUI->getPref('TABVIEW') == 2) { 1015 return false; 1016 } 1017 return true; 1018 } 1019 1020 /** 1021 * Displays the tabbed box 1022 * 1023 * This function may be overridden 1024 * 1025 * @param string Can't remember whether this was useful 1026 */ 1027 function show($extra = '', $js_tabs = false) { 1028 global $AppUI, $currentTabId, $currentTabName; 1029 $this->loadExtras($m, $a); 1030 reset($this->tabs); 1031 $s = ''; 1032 // tabbed / flat view options 1033 if ($AppUI->getPref('TABVIEW') == 0) { 1034 $s .= '<table border="0" cellpadding="2" cellspacing="0" width="100%"><tr><td nowrap="nowrap">'; 1035 $s .= '<a class="crumb" href="' . $this->baseHRef . 'tab=0"><span>' . $AppUI->_('tabbed') . '</span></a> '; 1036 $s .= '<a class="crumb" href="' . $this->baseHRef . 'tab=-1"><span>' . $AppUI->_('flat') . '</span></a>'; 1037 $s .= '</td>' . $extra . '</tr></table>'; 1038 echo $s; 1039 } else { 1040 if ($extra) { 1041 echo '<table border="0" cellpadding="2" cellspacing="0" width="100%"><tr>' . $extra . '</tr></table>'; 1042 } else { 1043 echo '<img src="' . w2PfindImage('shim.gif') . '" height="10" width="1" />'; 1044 } 1045 } 1046 1047 if ($this->active < 0 || $AppUI->getPref('TABVIEW') == 2) { 1048 // flat view, active = -1 1049 echo '<table border="0" cellpadding="2" cellspacing="0" width="100%">'; 1050 foreach ($this->tabs as $k => $v) { 1051 echo '<tr><td><strong>' . ($v[2] ? $v[1] : $AppUI->_($v[1])) . '</strong></td></tr>'; 1052 echo '<tr><td>'; 1053 $currentTabId = $k; 1054 $currentTabName = $v[1]; 1055 include $this->baseInc . $v[0] . '.php'; 1056 echo '</td></tr>'; 1057 } 1058 echo '</table>'; 1059 } else { 1060 // tabbed view 1061 $s = '<table width="100%" border="0" cellpadding="3" cellspacing="0"><tr>'; 1062 if (count($this->tabs) - 1 < $this->active) { 1063 //Last selected tab is not available in this view. eg. Child tasks 1064 $this->active = 0; 1065 } 1066 foreach ($this->tabs as $k => $v) { 1067 $class = ($k == $this->active) ? 'tabon' : 'taboff'; 1068 $s .= '<td width="1%" nowrap="nowrap" class="tabsp"><img src="' . w2PfindImage('shim.gif') . '" height="1" width="1" alt="" /></td>'; 1069 $s .= '<td id="toptab_' . $k . '" width="1%" nowrap="nowrap"'; 1070 if ($js_tabs) { 1071 $s .= ' class="' . $class . '"'; 1072 } 1073 $s .= '><a href="'; 1074 if ($this->javascript) { 1075 $s .= 'javascript:' . $this->javascript . '(' . $this->active . ', ' . $k . ')'; 1076 } elseif ($js_tabs) { 1077 $s .= 'javascript:show_tab(' . $k . ')'; 1078 } else { 1079 $s .= $this->baseHRef . "tab=$k"; 1080 } 1081 $s .= '">' . ($v[2] ? $v[1] : $AppUI->_($v[1])) . '</a></td>'; 1082 } 1083 $s .= '<td nowrap="nowrap" class="tabsp"> </td></tr>'; 1084 $s .= '<tr><td width="100%" colspan="' . (count($this->tabs) * 2 + 1) . '" class="tabox">'; 1085 echo $s; 1086 //Will be null if the previous selection tab is not available in the new window eg. Children tasks 1087 if ($this->baseInc . $this->tabs[$this->active][0] != '') { 1088 $currentTabId = $this->active; 1089 $currentTabName = $this->tabs[$this->active][1]; 1090 if (!$js_tabs) { 1091 require $this->baseInc . $this->tabs[$this->active][0] . '.php'; 1092 } 1093 } 1094 if ($js_tabs) { 1095 foreach ($this->tabs as $k => $v) { 1096 echo '<div class="tab" id="tab_' . $k . '">'; 1097 require $this->baseInc . $v[0] . '.php'; 1098 echo '</div>'; 1099 } 1100 } 1101 echo '</td></tr></table>'; 1102 } 1103 } 1104 1105 function loadExtras($module, $file = null) { 1106 global $AppUI; 1107 if (!isset($_SESSION['all_tabs']) || !isset($_SESSION['all_tabs'][$module])) { 1108 return false; 1109 } 1110 1111 if ($file) { 1112 if (isset($_SESSION['all_tabs'][$module][$file]) && is_array($_SESSION['all_tabs'][$module][$file])) { 1113 $tab_array = &$_SESSION['all_tabs'][$module][$file]; 1114 } else { 1115 return false; 1116 } 1117 } else { 1118 $tab_array = &$_SESSION['all_tabs'][$module]; 1119 } 1120 $tab_count = 0; 1121 foreach ($tab_array as $tab_elem) { 1122 if (isset($tab_elem['module']) && $AppUI->isActiveModule($tab_elem['module'])) { 1123 $tab_count++; 1124 $this->add($tab_elem['file'], $tab_elem['name']); 1125 } 1126 } 1127 return $tab_count; 1128 } 1129 1130 function findTabModule($tab) { 1131 global $AppUI, $m, $a; 1132 1133 if (!isset($_SESSION['all_tabs']) || !isset($_SESSION['all_tabs'][$m])) { 1134 return false; 1135 } 1136 1137 if (isset($a)) { 1138 if (isset($_SESSION['all_tabs'][$m][$a]) && is_array($_SESSION['all_tabs'][$m][$a])) { 1139 $tab_array = &$_SESSION['all_tabs'][$m][$a]; 1140 } else { 1141 $tab_array = &$_SESSION['all_tabs'][$m]; 1142 } 1143 } else { 1144 $tab_array = &$_SESSION['all_tabs'][$m]; 1145 } 1146 1147 list($file, $name) = $this->tabs[$tab]; 1148 foreach ($tab_array as $tab_elem) { 1149 if (isset($tab_elem['name']) && $tab_elem['name'] == $name && $tab_elem['file'] == $file) { 1150 return $tab_elem['module']; 1151 } 1152 } 1153 return false; 1154 } 1155 } 1156 1157 /** 1158 * CInfoTabBox 1159 * This class is used to do second level tabs or subtabs aligned to the right by default 1160 * @package 1161 * @author Pedro Azevedo 1162 * @copyright 2007 1163 * @version $Id: ui.class.php 174 2008-07-17 14:36:48Z pedroix $ 1164 * @access public 1165 */ 1166 class CInfoTabBox extends CTabBox_core { 1167 function show($extra = '', $js_tabs = false, $alignment = 'left') { 1168 global $AppUI, $w2Pconfig, $currentInfoTabId, $currentInfoTabName, $m, $a; 1169 $uistyle = $AppUI->getPref('UISTYLE') ? $AppUI->getPref('UISTYLE') : $w2Pconfig['host_style']; 1170 if (!$uistyle) { 1171 $uistyle = 'web2project'; 1172 } 1173 reset($this->tabs); 1174 $s = ''; 1175 if ($extra) { 1176 echo '<table border="0" cellpadding="2" cellspacing="0" width="100%"><tr>' . $extra . '</tr></table>'; 1177 } 1178 1179 if ($this->active < 0 || $AppUI->getPref('TABVIEW') == 2) { 1180 // flat view, active = -1 1181 echo '<table border="0" cellpadding="2" cellspacing="0" width="100%">'; 1182 foreach ($this->tabs as $k => $v) { 1183 echo '<tr><td><strong>' . ($v[2] ? $v[1] : $AppUI->_($v[1])) . '</strong></td></tr>'; 1184 echo '<tr><td>'; 1185 $currentInfoTabId = $k; 1186 $currentInfoTabName = $v[1]; 1187 include $this->baseInc . $v[0] . '.php'; 1188 echo '</td></tr>'; 1189 } 1190 echo '</table>'; 1191 } else { 1192 // tabbed view 1193 $s = '<table width="100%" border="0" cellpadding="0" cellspacing="0">'; 1194 $s .= '<tr><td><table align="' . $alignment . '" border="0" cellpadding="0" cellspacing="0">'; 1195 1196 if (count($this->tabs) - 1 < $this->active) { 1197 //Last selected tab is not available in this view. eg. Child tasks 1198 $this->active = 0; 1199 } 1200 foreach ($this->tabs as $k => $v) { 1201 $class = ($k == $this->active) ? 'tabon' : 'taboff'; 1202 $sel = ($k == $this->active) ? 'Selected' : ''; 1203 $s .= '<td valign="middle"><img src="./style/' . $uistyle . '/bar_top_' . $sel . 'left.gif" id="lefttab_' . $k . '" border="0" alt="" /></td>'; 1204 $s .= '<td id="toptab_' . $k . '" valign="middle" nowrap="nowrap"'; 1205 // if ($js_tabs) 1206 $s .= ' class="' . $class . '"'; 1207 // else 1208 // $s .= ' background="./style/'.$uistyle.'/bar_top_'.$sel.'middle.gif"'; 1209 $s .= '> <a href="'; 1210 if ($this->javascript) 1211 $s .= 'javascript:' . $this->javascript . '(' . $this->active . ', ' . $k . ')'; 1212 else 1213 if ($js_tabs) { 1214 $s .= 'javascript:show_tab(' . $k . ')'; 1215 } else { 1216 if ($m == 'projectdesigner' && strpos($v[1], 'Invoices') === false) { 1217 $s .= $this->baseHRef . 'infotab_bil=' . $k . '#billings'; 1218 } elseif ($m == 'projectdesigner') { 1219 $s .= $this->baseHRef . 'infotab_inv=' . $k . '#invoices'; 1220 } else { 1221 $s .= $this->baseHRef . 'infotab=' . $k; 1222 } 1223 } 1224 $s .= '">' . ($v[2] ? $v[1] : $AppUI->_($v[1])) . '</a> </td>'; 1225 $s .= '<td valign="middle" ><img id="righttab_' . $k . '" src="./style/' . $uistyle . '/bar_top_' . $sel . 'right.gif" border="0" alt="" /></td>'; 1226 $s .= '<td class="tabsp"><img src="' . w2PfindImage('shim.gif') . '"/></td>'; 1227 } 1228 $s .= '</table></td></tr>'; 1229 $s .= '<tr><td width="100%" colspan="' . (count($this->tabs) * 4 + 1) . '" class="tabox">'; 1230 echo $s; 1231 //Will be null if the previous selection tab is not available in the new window eg. Children tasks 1232 if ($this->tabs[$this->active][0] != '') { 1233 $currentInfoTabId = $this->active; 1234 $currentInfoTabName = $this->tabs[$this->active][1]; 1235 if (!$js_tabs) { 1236 require $this->baseInc . $this->tabs[$this->active][0] . '.php'; 1237 } 1238 } 1239 if ($js_tabs) { 1240 foreach ($this->tabs as $k => $v) { 1241 echo '<div class="tab" id="infotab_' . $k . '">'; 1242 $currentInfoTabId = $k; 1243 $currentInfoTabName = $v[1]; 1244 require $this->baseInc . $v[0] . '.php'; 1245 echo '</div>'; 1246 echo '<script language="JavaScript" type="text/javascript"> 1247 <!-- 1248 show_tab(' . $this->active . '); 1249 //--> 1250 </script>'; 1251 1252 } 1253 } 1254 echo '</td></tr></table>'; 1255 } 1256 } 1257 } 1258 /** 1259 * Title box abstract class 1260 */ 1261 class CTitleBlock_core { 1262 /** 1263 @var string The main title of the page */ 1264 var $title = ''; 1265 /** 1266 @var string The name of the icon used to the left of the title */ 1267 var $icon = ''; 1268 /** 1269 @var string The name of the module that this title block is displaying in */ 1270 var $module = ''; 1271 /** 1272 @var array An array of the table 'cells' to the right of the title block and for bread-crumbs */ 1273 var $cells = null; 1274 /** 1275 @var string The reference for the context help system */ 1276 var $helpref = ''; 1277 /** 1278 * The constructor 1279 * 1280 * Assigns the title, icon, module and help reference. If the user does not 1281 * have permission to view the help module, then the context help icon is 1282 * not displayed. 1283 */ 1284 function CTitleBlock_core($title, $icon = '', $module = '', $helpref = '') { 1285 $this->title = $title; 1286 $this->icon = $icon; 1287 $this->module = $module; 1288 $this->helpref = $helpref; 1289 $this->cells1 = array(); 1290 $this->cells2 = array(); 1291 $this->crumbs = array(); 1292 $this->showhelp = !getDenyRead('help'); 1293 } 1294 /** 1295 * Adds a table 'cell' beside the Title string 1296 * 1297 * Cells are added from left to right. 1298 */ 1299 function addCell($data = '', $attribs = '', $prefix = '', $suffix = '') { 1300 $this->cells1[] = array($attribs, $data, $prefix, $suffix); 1301 } 1302 /** 1303 * Adds a table 'cell' to left-aligned bread-crumbs 1304 * 1305 * Cells are added from left to right. 1306 */ 1307 function addCrumb($link, $label, $icon = '') { 1308 $this->crumbs[$link] = array($label, $icon); 1309 } 1310 /** 1311 * Adds a table 'cell' to the right-aligned bread-crumbs 1312 * 1313 * Cells are added from left to right. 1314 */ 1315 function addCrumbRight($data = '', $attribs = '', $prefix = '', $suffix = '') { 1316 $this->cells2[] = array($attribs, $data, $prefix, $suffix); 1317 } 1318 /** 1319 * Creates a standarised, right-aligned delete bread-crumb and icon. 1320 */ 1321 function addCrumbDelete($title, $canDelete = '', $msg = '') { 1322 global $AppUI; 1323 $this->addCrumbRight('<table cellspacing="0" cellpadding="0" border="0"><tr><td>' . '<a class="delete" href="javascript:delIt()" title="' . ($canDelete ? '' : $msg) . '"><span>' . $AppUI->_($title) . '</span></a>' . '</td></tr></table>'); 1324 } 1325 /** 1326 * The drawing function 1327 */ 1328 function show() { 1329 global $AppUI, $a, $m, $tab, $infotab; 1330 $this->loadExtraCrumbs($m, $a); 1331 $uistyle = $AppUI->getPref('UISTYLE') ? $AppUI->getPref('UISTYLE') : $w2Pconfig['host_style']; 1332 if (!$uistyle) { 1333 $uistyle = 'web2project'; 1334 } 1335 $s = '<table width="100%" border="0" cellpadding="1" cellspacing="1"><tr>'; 1336 if ($this->icon) { 1337 $s .= '<td width="42">'; 1338 $s .= w2PshowImage($this->icon, '', '', '', '', $this->module); 1339 $s .= '</td>'; 1340 } 1341 $s .= '<td align="left" width="100%" nowrap="nowrap"><h1>' . $AppUI->_($this->title) . '</h1></td>'; 1342 foreach ($this->cells1 as $c) { 1343 $s .= $c[2] ? $c[2] : ''; 1344 $s .= '<td align="right" nowrap="nowrap"' . ($c[0] ? (' ' . $c[0]) : '') . '>'; 1345 $s .= $c[1] ? $c[1] : ' '; 1346 $s .= '</td>'; 1347 $s .= $c[3] ? $c[3] : ''; 1348 } 1349 $s .= '</tr></table>'; 1350 1351 if (count($this->crumbs) || count($this->cells2)) { 1352 $crumbs = array(); 1353 $class = 'crumb'; 1354 foreach ($this->crumbs as $k => $v) { 1355 $t = $v[1] ? '<img src="' . w2PfindImage($v[1], $this->module) . '" border="" alt="" /> ' : ''; 1356 $t .= $AppUI->_($v[0]); 1357 // $crumbs[] = "<a href=\"$k\">$t</a>"; 1358 $crumbs[] = '<li><a href="'.$k.'"><span>'.$t.'</span></a></li>'; 1359 } 1360 $s .= '<table border="0" cellpadding="0" cellspacing="0" width="100%"><tr>'; 1361 // $s .= "\n\t<td nowrap=\"nowrap\">"; 1362 $s .= '<td height="20" nowrap="nowrap"><div class="'.$class.'"><ul>'; 1363 // $s .= "\n\t\t" . implode( ' <strong>:</strong> ', $crumbs ); 1364 $s .= implode('', $crumbs); 1365 // $s .= "\n\t</td>"; 1366 $s .= '</ul></div></td>'; 1367 1368 foreach ($this->cells2 as $c) { 1369 $s .= $c[2] ? $c[2] : ''; 1370 $s .= '<td align="right" nowrap="nowrap" ' . ($c[0] ? " $c[0]" : '') . '>'; 1371 $s .= $c[1] ? $c[1] : ' '; 1372 $s .= '</td>'; 1373 $s .= $c[3] ? $c[3] : ''; 1374 } 1375 $s .= '</tr></table>'; 1376 } 1377 echo '' . $s; 1378 if (($a != 'index' || $m == 'system' || $m == 'calendar' || $m == 'smartsearch') && !$AppUI->boxTopRendered && function_exists('styleRenderBoxTop')) { 1379 echo styleRenderBoxTop(); 1380 $AppUI->boxTopRendered = true; 1381 } 1382 } 1383 1384 function loadExtraCrumbs($module, $file = null) { 1385 global $AppUI; 1386 if (!isset($_SESSION['all_crumbs']) || !isset($_SESSION['all_crumbs'][$module])) { 1387 return false; 1388 } 1389 1390 if ($file) { 1391 if (isset($_SESSION['all_crumbs'][$module][$file]) && is_array($_SESSION['all_crumbs'][$module][$file])) { 1392 $crumb_array = &$_SESSION['all_crumbs'][$module][$file]; 1393 } else { 1394 return false; 1395 } 1396 } else { 1397 $crumb_array = &$_SESSION['all_crumbs'][$module]; 1398 } 1399 $crumb_count = 0; 1400 foreach ($crumb_array as $crumb_elem) { 1401 if (isset($crumb_elem['module']) && $AppUI->isActiveModule($crumb_elem['module'])) { 1402 $crumb_count++; 1403 include_once ($crumb_elem['file'] . '.php'); 1404 } 1405 } 1406 return $crumb_count; 1407 } 1408 1409 function findCrumbModule($crumb) { 1410 global $AppUI, $m, $a; 1411 1412 if (!isset($_SESSION['all_crumbs']) || !isset($_SESSION['all_crumbs'][$m])) { 1413 return false; 1414 } 1415 1416 if (isset($a)) { 1417 if (isset($_SESSION['all_crumbs'][$m][$a]) && is_array($_SESSION['all_crumbs'][$m][$a])) { 1418 $crumb_array = &$_SESSION['all_crumbs'][$m][$a]; 1419 } else { 1420 $crumb_array = &$_SESSION['all_crumbs'][$m]; 1421 } 1422 } else { 1423 $crumb_array = &$_SESSION['all_crumbs'][$m]; 1424 } 1425 1426 list($file, $name) = $this->crumbs[$crumb]; 1427 foreach ($crumb_array as $crumb_elem) { 1428 if (isset($crumb_elem['name']) && $crumb_elem['name'] == $name && $crumb_elem['file'] == $file) { 1429 return $crumb_elem['module']; 1430 } 1431 } 1432 return false; 1433 } 1434 } 1435 // !! Ensure there is no white space after this close php tag. 1436 1437 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Sat Jul 17 03:00:04 2010 | Cross-referenced by PHPXref 0.7 |