Changeset 42 for trunk/lib/App.inc.php
- Timestamp:
- Dec 18, 2005 12:16:03 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/lib/App.inc.php
r41 r42 9 9 * @version 1.0 10 10 */ 11 11 12 12 // Message Types. 13 13 define('MSG_ERR', 1); … … 20 20 21 21 class App { 22 22 23 23 // Name of this application. 24 24 var $app = '_app_'; … … 29 29 // Instance of database object. 30 30 var $db; 31 31 32 32 // Array of query arguments will be carried persistently between requests. 33 33 var $_carry_queries = array(); … … 46 46 // The location the user will go if the system doesn't knew where else to send them. 47 47 'redirect_home_url' => '/', 48 48 49 49 // SSL URL used when redirecting with App::sslOn(). 50 50 'ssl_domain' => null, 51 51 'ssl_enabled' => false, 52 52 53 53 // Character set for page output. Used in the Content-Type header and the HTML <meta content-type> tag. 54 54 'character_set' => 'utf-8', … … 63 63 'session_name' => 'Strangecode', 64 64 'session_use_cookies' => true, 65 65 66 66 // Use database? 67 67 'enable_db' => false, … … 69 69 // Use db-based sessions? 70 70 'enable_db_session_handler' => false, 71 71 72 72 // DB passwords should be set as apache environment variables in httpd.conf, readable only by root. 73 73 'db_server' => 'localhost', … … 80 80 'db_debug' => false, // TRUE = display db errors. 81 81 'db_die_on_failure' => false, // TRUE = script stops on db error. 82 82 83 83 // For classes that require db tables, do we check that a table exists and create if missing? 84 84 'db_create_tables' => true, … … 89 89 // Don't display errors by default; it is preferable to log them to a file. 90 90 'display_errors' => false, 91 91 92 92 // Directory in which to store log files. 93 93 'log_directory' => '', … … 112 112 'log_sms_priority' => false, 113 113 'log_screen_priority' => false, 114 114 115 115 // Email address to receive log event emails. 116 116 'log_to_email_address' => null, 117 117 118 118 // SMS Email address to receive log event SMS messages. 119 119 'log_to_sms_address' => null, 120 120 121 121 // A key for calculating simple cryptographic signatures. Set using as an environment variables in the httpd.conf with 'SetEnv SIGNING_KEY <key>'. 122 122 'signing_key' => 'aae6abd6209d82a691a9f96384a7634a', 123 123 ); 124 124 125 125 /** 126 126 * This method enforces the singleton pattern for this class. Only one application is running at a time. … … 140 140 return $instance; 141 141 } 142 142 143 143 /** 144 144 * Constructor. … … 149 149 $this->app .= $app; 150 150 } 151 151 152 152 // Initialize default parameters. 153 153 $this->_params = array_merge($this->_params, $this->_param_defaults); … … 184 184 $this =& App::getInstance(); 185 185 } 186 186 187 187 if ($param === null) { 188 188 return $this->_params; … … 194 194 } 195 195 } 196 196 197 197 /** 198 198 * Begin running this application. … … 207 207 return false; 208 208 } 209 209 210 210 // Error reporting. 211 211 ini_set('error_reporting', $this->getParam('error_reporting')); … … 215 215 ini_set('error_log', $this->getParam('log_directory') . '/' . $this->getParam('php_error_log')); 216 216 } 217 218 217 218 219 219 /** 220 220 * 1. Start Database. 221 221 */ 222 222 223 223 if ($this->getParam('enable_db')) { 224 224 225 225 // DB connection parameters taken from environment variables in the httpd.conf file, readable only by root. 226 226 if (!empty($_SERVER['DB_SERVER'])) { … … 236 236 $this->setParam(array('db_pass' => $_SERVER['DB_PASS'])); 237 237 } 238 238 239 239 // The only instance of the DB object. 240 240 require_once dirname(__FILE__) . '/DB.inc.php'; 241 241 242 242 $this->db =& DB::getInstance(); 243 243 244 244 $this->db->setParam(array( 245 245 'db_server' => $this->getParam('db_server'), … … 255 255 $this->db->connect(); 256 256 } 257 258 257 258 259 259 /** 260 260 * 2. Start PHP session. 261 261 */ 262 262 263 263 // Skip session for some user agents. 264 264 if (preg_match('/Atomz|ApacheBench|Wget/i', getenv('HTTP_USER_AGENT'))) { 265 265 $this->setParam(array('enable_session' => false)); 266 266 } 267 267 268 268 if (true === $this->getParam('enable_session')) { 269 269 270 270 // Set the session ID to one provided in GET/POST. This is necessary for linking 271 271 // between domains and keeping the same session. … … 273 273 session_id($ses); 274 274 } 275 275 276 276 if (true === $this->getParam('enable_db_session_handler') && true === $this->getParam('enable_db')) { 277 277 // Database session handling. … … 282 282 )); 283 283 } 284 284 285 285 // Session parameters. 286 286 ini_set('session.use_cookies', $this->getParam('session_use_cookies')); … … 289 289 ini_set('session.entropy_length', '512'); 290 290 session_name($this->getParam('session_name')); 291 291 292 292 // Start the session. 293 293 session_start(); 294 294 295 295 if (!isset($_SESSION[$this->app])) { 296 296 // Access session data using: $_SESSION['...']. … … 302 302 } 303 303 } 304 305 304 305 306 306 /** 307 307 * 3. Misc setup. … … 319 319 $this->setParam(array('signing_key' => $_SERVER['SIGNING_KEY'])); 320 320 } 321 321 322 322 // Character set. This should also be printed in the html header template. 323 323 header('Content-type: text/html; charset=' . $this->getParam('character_set')); 324 324 325 325 $this->running = true; 326 326 } 327 327 328 328 /** 329 329 * Stop running this application. … … 340 340 $this->running = false; 341 341 } 342 343 342 343 344 344 /** 345 345 * Add a message to the string globalmessage, which is printed in the header. … … 359 359 $this =& App::getInstance(); 360 360 } 361 361 362 362 $message = trim($message); 363 363 … … 365 365 return false; 366 366 } 367 367 368 368 // Save message in session under unique key to avoid duplicate messages. 369 369 $_SESSION[$this->app]['messages'][md5($type . $message . $file . $line)] = array( 370 'type' => $type, 370 'type' => $type, 371 371 'message' => $message, 372 372 'file' => $file, 373 373 'line' => $line 374 374 ); 375 375 376 376 if (!in_array($type, array(MSG_NOTICE, MSG_SUCCESS, MSG_WARNING, MSG_ERR))) { 377 378 } 379 } 380 377 $this->logMsg(sprintf('Invalid MSG_* type: %s', $type), LOG_DEBUG, __FILE__, __LINE__); 378 } 379 } 380 381 381 /** 382 382 * Prints the HTML for displaying raised messages. … … 405 405 echo '<div class="error">' . $message['message'] . '</div>'; 406 406 break; 407 407 408 408 case MSG_WARNING: 409 409 echo '<div class="warning">' . $message['message'] . '</div>'; 410 410 break; 411 411 412 412 case MSG_SUCCESS: 413 413 echo '<div class="success">' . $message['message'] . '</div>'; 414 414 break; 415 415 416 416 case MSG_NOTICE: 417 417 default: 418 418 echo '<div class="notice">' . $message['message'] . '</div>'; 419 419 break; 420 420 421 421 } 422 422 ?></div><?php 423 423 } 424 424 } 425 425 426 426 /** 427 427 * Logs a message to a user defined log file. Additional actions to take for … … 448 448 $this =& App::getInstance(); 449 449 } 450 450 451 451 // If priority is not specified, assume the worst. 452 452 if (!$this->logPriorityToString($priority)) { … … 454 454 $priority = LOG_EMERG; 455 455 } 456 456 457 457 // If log file is not specified, don't log to a file. 458 458 if (!$this->getParam('log_directory') || !$this->getParam('log_filename') || !is_dir($this->getParam('log_directory')) || !is_writable($this->getParam('log_directory'))) { … … 461 461 trigger_error(sprintf('Codebase error: log directory (%s) not found or writable.', $this->getParam('log_directory')), E_USER_NOTICE); 462 462 } 463 463 464 464 // Make sure to log in the system's locale. 465 465 $locale = setlocale(LC_TIME, 0); 466 466 setlocale(LC_TIME, 'C'); 467 467 468 468 // Data to be stored for a log event. 469 469 $event = array(); … … 478 478 $event['message'] = strip_tags(preg_replace('/\s+/', ' ', $message), (!empty($strip_tags_allow[1]) ? join('> ', $strip_tags_allow[1]) . '>' : null)); 479 479 $event_str = '[' . join('] [', $event) . ']'; 480 480 481 481 // FILE ACTION 482 482 if ($this->getParam('log_file_priority') && $priority <= $this->getParam('log_file_priority')) { 483 483 error_log($event_str . "\n", 3, $this->getParam('log_directory') . '/' . $this->getParam('log_filename')); 484 484 } 485 485 486 486 // EMAIL ACTION 487 487 if ($this->getParam('log_email_priority') && $priority <= $this->getParam('log_email_priority')) { … … 494 494 mail($this->getParam('log_to_email_address'), $subject, $email_msg, $headers, '-f codebase@strangecode.com'); 495 495 } 496 496 497 497 // SMS ACTION 498 498 if ($this->getParam('log_sms_priority') && $priority <= $this->getParam('log_sms_priority')) { … … 502 502 mail($this->getParam('log_to_sms_address'), $subject, $sms_msg, $headers, '-f codebase@strangecode.com'); 503 503 } 504 504 505 505 // SCREEN ACTION 506 506 if ($this->getParam('log_screen_priority') && $priority <= $this->getParam('log_screen_priority')) { 507 507 echo "[{$event['date']}] [{$event['type']}] [{$event['file:line']}] [{$event['message']}]\n"; 508 508 } 509 509 510 510 // Restore original locale. 511 511 setlocale(LC_TIME, $locale); 512 512 } 513 513 514 514 /** 515 515 * Returns the string representation of a LOG_* integer constant. … … 536 536 } 537 537 } 538 538 539 539 /** 540 540 * Sets which query arguments will be carried persistently between requests. 541 * Values in the _carry_queries array will be copied to URLs (via App::url()) and 541 * Values in the _carry_queries array will be copied to URLs (via App::url()) and 542 542 * to hidden input values (via printHiddenSession()). 543 543 * 544 544 * @access public 545 * @param string $query_key The key of the query argument to save. 545 * @param string $query_key The key of the query argument to save. 546 546 * @author Quinn Comendant <quinn@strangecode.com> 547 547 * @since 14 Nov 2005 19:24:52 … … 552 552 $this =& App::getInstance(); 553 553 } 554 554 555 555 // If not already set, and there is a non-empty value provided in the request... 556 556 if (!isset($this->_carry_queries[$query_key]) && getFormData($query_key, false)) { 557 557 // Copy the value of the specified query argument into the _carry_queries array. 558 559 } 560 } 561 558 $this->_carry_queries[$query_key] = getFormData($query_key); 559 } 560 } 561 562 562 /** 563 563 * Outputs a fully qualified URL with a query of all the used (ie: not empty) 564 * keys and values, including optional queries. This allows mindless retention 564 * keys and values, including optional queries. This allows mindless retention 565 565 * of query arguments across page requests. If cookies are not 566 566 * used, the session id will be propogated in the URL. … … 588 588 return false; 589 589 } 590 590 591 591 // Get any provided query arguments to include in the final URL. 592 592 // If FALSE is a provided here, DO NOT carry the queries. … … 611 611 } 612 612 } 613 613 614 614 // Get the first delimiter that is needed in the url. 615 615 $delim = strpos($url, '?') !== false ? ini_get('arg_separator.output') : '?'; 616 616 617 617 618 618 $q = ''; 619 619 if ($do_carry_queries) { … … 628 628 } 629 629 } 630 630 631 631 // Include the necessary SID if the following is true: 632 632 // - no cookie in http request OR cookies disabled in App … … 634 634 // - the link stays on our site 635 635 // - transparent SID propogation with session.use_trans_sid is not being used OR url begins with protocol (using_trans_sid has no effect here) 636 // OR 636 // OR 637 637 // - we must include the SID because we say so (it's used in a context where cookies will not be effective, ie. moving from http to https) 638 638 // AND … … 642 642 ( 643 643 ( 644 !isset($_COOKIE[session_name()]) 644 !isset($_COOKIE[session_name()]) 645 645 || !$this->getParam('session_use_cookies') 646 ) 646 ) 647 647 && $this->getParam('enable_session') 648 && isMyDomain($url) 649 && 648 && isMyDomain($url) 649 && 650 650 ( 651 651 !ini_get('session.use_trans_sid') 652 652 || preg_match('!^(http|https)://!i', $url) 653 653 ) 654 ) 654 ) 655 655 || $always_include_sid 656 656 ) … … 679 679 $this =& App::getInstance(); 680 680 } 681 681 682 682 $url = $this->url($url, $carry_args, $always_include_sid); 683 683 684 684 // Replace any & not followed by an html or unicode entity with it's & equivalent. 685 685 $url = preg_replace('/&(?![\w\d#]{1,10};)/', '&', $url); 686 686 687 687 return $url; 688 688 } 689 689 690 690 /** 691 691 * Prints a hidden form element with the PHPSESSID when cookies are not used, as well 692 * as hidden form elements for GET_VARS that might be in use. 692 * as hidden form elements for GET_VARS that might be in use. 693 693 * 694 694 * @param mixed $carry_args Additional url arguments to carry in the query, … … 707 707 return false; 708 708 } 709 709 710 710 // Get any provided query arguments to include in the final hidden form data. 711 711 // If FALSE is a provided here, DO NOT carry the queries. … … 730 730 } 731 731 } 732 732 733 733 // For each existing POST value, we create a hidden input to carry it through a form. 734 734 if ($do_carry_queries) { … … 740 740 } 741 741 } 742 742 743 743 // Include the SID if cookies are disabled. 744 744 if (!isset($_COOKIE[session_name()]) && !ini_get('session.use_trans_sid')) { … … 746 746 } 747 747 } 748 748 749 749 /** 750 750 * Uses an http header to redirect the client to the given $url. If sessions are not used … … 769 769 return false; 770 770 } 771 771 772 772 if ('' == $url) { 773 773 // If URL is not specified, use the redirect_home_url. 774 774 $url = $this->getParam('redirect_home_url'); 775 775 } 776 776 777 777 if (preg_match('!^/!', $url)) { 778 778 // If relative URL is given, prepend correct local hostname. … … 783 783 784 784 $url = $this->url($url, $carry_args, $always_include_sid); 785 785 786 786 header(sprintf('Location: %s', $url)); 787 787 $this->logMsg(sprintf('dieURL: %s', $url), LOG_DEBUG, __FILE__, __LINE__); 788 788 789 789 // End this application. 790 790 // Recommended, although I'm not sure it's necessary: http://cn2.php.net/session_write_close … … 792 792 die; 793 793 } 794 794 795 795 /** 796 796 * Redirects a user by calling the App::dieURL(). It will use: … … 808 808 return false; 809 809 } 810 810 811 811 // Get URL from stored boomerang. Allow non specific URL if ID not valid. 812 812 if ($this->validBoomerangURL($id, true)) { … … 829 829 $this->logMsg(sprintf('dieBoomerangURL(%s) not found, using redirect_home_url: %s', $id, $url), LOG_DEBUG, __FILE__, __LINE__); 830 830 } 831 832 831 832 833 833 // A redirection will never happen immediatly twice. 834 834 // Set the time so ensure this doesn't happen. … … 836 836 $this->dieURL($url, $carry_args); 837 837 } 838 838 839 839 /** 840 840 * Set the URL to return to when App::dieBoomerangURL() is called. … … 855 855 // A redirection will never happen immediatly after setting the boomerangURL. 856 856 // Set the time so ensure this doesn't happen. See App::validBoomerangURL for more. 857 857 858 858 if ('' != $url && is_string($url)) { 859 859 // Delete any boomerang request keys in the query string. 860 860 $url = preg_replace('/boomerang=[\w]+/', '', $url); 861 861 862 862 if (isset($_SESSION[$this->app]['boomerang']['url']) && is_array($_SESSION[$this->app]['boomerang']['url']) && !empty($_SESSION[$this->app]['boomerang']['url'])) { 863 863 // If the URL currently exists in the boomerang array, delete. … … 866 866 } 867 867 } 868 868 869 869 if (isset($id)) { 870 870 $_SESSION[$this->app]['boomerang']['url'][$id] = $url; … … 879 879 } 880 880 } 881 881 882 882 /** 883 883 * Return the URL set for the specified $id. … … 894 894 return false; 895 895 } 896 896 897 897 if (isset($id)) { 898 898 if (isset($_SESSION[$this->app]['boomerang']['url'][$id])) { … … 907 907 } 908 908 } 909 909 910 910 /** 911 911 * Delete the URL set for the specified $id. … … 922 922 return false; 923 923 } 924 924 925 925 $this->logMsg(sprintf('deleteBoomerangURL(%s): %s', $id, $this->getBoomerangURL($id)), LOG_DEBUG, __FILE__, __LINE__); 926 926 … … 931 931 } 932 932 } 933 933 934 934 /** 935 935 * Check if a valid boomerang URL value has been set. … … 947 947 return false; 948 948 } 949 949 950 950 if (!isset($_SESSION[$this->app]['boomerang']['url'])) { 951 951 return false; 952 952 } 953 953 954 954 // Time is the timestamp of a boomerangURL redirection, or setting of a boomerangURL. 955 955 // a boomerang redirection will always occur at least several seconds after the last boomerang redirect 956 956 // or a boomerang being set. 957 957 $boomerang_time = isset($_SESSION[$this->app]['boomerang']['time']) ? $_SESSION[$this->app]['boomerang']['time'] : 0; 958 958 959 959 $url = ''; 960 960 if (isset($id) && isset($_SESSION[$this->app]['boomerang']['url'][$id])) { … … 964 964 $url = end($_SESSION[$this->app]['boomerang']['url']); 965 965 } 966 966 967 967 $this->logMsg(sprintf('validBoomerangURL(%s) testing: %s', $id, $url), LOG_DEBUG, __FILE__, __LINE__); 968 968 … … 981 981 return false; 982 982 } 983 983 984 984 $this->logMsg(sprintf('validBoomerangURL(%s) is valid: %s', $id, $url), LOG_DEBUG, __FILE__, __LINE__); 985 985 return true; … … 995 995 $this =& App::getInstance(); 996 996 } 997 997 998 998 if (function_exists('apache_get_modules')) { 999 999 $modules = apache_get_modules(); 1000 1000 } else { 1001 1001 // It's safe to assume we have mod_ssl if we can't determine otherwise. 1002 1002 $modules = array('mod_ssl'); 1003 1003 } 1004 1004 1005 1005 if ('on' != getenv('HTTPS') && $this->getParam('ssl_enabled') && in_array('mod_ssl', $modules)) { 1006 1006 $this->raiseMsg(sprintf(_("Secure SSL connection made to %s"), $this->getParam('ssl_domain')), MSG_NOTICE, __FILE__, __LINE__); … … 1009 1009 } 1010 1010 } 1011 1012 1011 1012 1013 1013 /** 1014 1014 * to enforce the user to connect via http (port 80) by redirecting them to … … 1022 1022 } 1023 1023 1024 1024 1025 1025 } // End. 1026 1026
Note: See TracChangeset
for help on using the changeset viewer.