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