includes/framework/QApplicationBase.class.php
<?php
/**
* This abstract class should never be instantiated. It contains static methods,
* variables and constants to be used throughout the application.
*
* The static method "Initialize" should be called at the begin of the script by
* prepend.inc.
*/
abstract class QApplicationBase extends QBaseClass {
//////////////////////////
// Public Static Variables
//////////////////////////
/**
* The cache provider object used for caching ORM objects
* It is initialized below in Initialize(), based on the CACHE_PROVIDER and CACHE_PROVIDER_OPTIONS
* variables defined in configuration.inc.php
*
* @var QAbstractCacheProvider
*/
public static $objCacheProvider = null;
/**
* @var bool Set to true to turn on short-term caching. This is an in-memory cache that caches database
* objects only for as long as a single http request lasts. Depending on your application, this may speed
* up your database accesses. It DOES increase the amount of memory used in a request.
* */
public static $blnLocalCache = false;
/**
* Internal bitmask signifying which BrowserType the user is using
* Use the QApplication::IsBrowser() method to do browser checking
*
* @var integer BrowserType
*/
protected static $BrowserType = QBrowserType::Unsupported;
/**
* @var float Major version number of browser
*/
public static $BrowserVersion = null;
/**
* Definition of CacheControl for the HTTP header. In general, it is
* recommended to keep this as "private". But this can/should be overriden
* for file/scripts that have special caching requirements (e.g. dynamically
* created images like QImageLabel).
*
* @var string CacheControl
*/
public static $CacheControl = 'private';
/**
* @var #P#C\QCrossScripting.Purify|?
* Defines the default mode for controls that need protection against
* cross-site scripting. Can be overridden at the individual control level,
* or for all controls by overriding it in QApplication.
*
* Set to QCrossScripting::Legacy for backward compatibility reasons for legacy applications;
* For new applications the recommended setting is QCrossScripting::Purify.
*/
public static $DefaultCrossScriptingMode = QCrossScripting::Legacy;
/**
* Path of the "web root" or "document root" of the web server
* Like "/home/www/htdocs" on Linux/Unix or "c:\inetpub\wwwroot" on Windows
*
* @var string DocumentRoot
*/
public static $DocumentRoot;
/**
* Whether or not we are currently trying to Process the Output of the page.
* Used by the OutputPage PHP output_buffering handler. As of PHP 5.2,
* this gets called whenever ob_get_contents() is called. Because some
* classes like QFormBase utilizes ob_get_contents() to perform template
* evaluation without wanting to actually perform OutputPage, this flag
* can be set/modified by QFormBase::EvaluateTemplate accordingly to
* prevent OutputPage from executing.
*
* Also set this to false if you are outputting custom headers, especially
* if you send your own "Content-Type" header.
*
* @var boolean ProcessOutput
*/
public static $ProcessOutput = true;
/**
* Full path of the actual PHP script being run
* Like "/home/www/htdocs/folder/script.php" on Linux/Unix
* or "c:\inetpub\wwwroot" on Windows
*
* @var string ScriptFilename
*/
public static $ScriptFilename;
/**
* Web-relative path of the actual PHP script being run
* So for "http://www.domain.com/folder/script.php",
* QApplication::$ScriptName would be "/folder/script.php"
*
* @var string ScriptName
*/
public static $ScriptName;
/**
* Extended Path Information after the script URL (if applicable)
* So for "http://www.domain.com/folder/script.php/15/225"
* QApplication::$PathInfo would be "/15/255"
*
* @var string PathInfo
*/
public static $PathInfo;
/**
* Query String after the script URL (if applicable)
* So for "http://www.domain.com/folder/script.php?item=15&value=22"
* QApplication::$QueryString would be "item=15&value=22"
*
* @var string QueryString
*/
public static $QueryString;
/**
* The full Request URI that was requested
* So for "http://www.domain.com/folder/script.php/15/25/?item=15&value=22"
* QApplication::$RequestUri would be "/folder/script.php/15/25/?item=15&value=22"
*
* @var string RequestUri
*/
public static $RequestUri;
/**
* The IP address of the server running the script/PHP application
* This is either the LOCAL_ADDR or the SERVER_ADDR server constant, depending
* on the server type, OS and configuration.
*
* @var string ServerAddress
*/
public static $ServerAddress;
/**
* The encoding type for the application (e.g. UTF-8, ISO-8859-1, etc.). This is the encoding that will be
* used for internal variables, for web pages, and what will get stored in the database. This also affects
* how code generation is done, so if you change this, be sure to code generate again.
*
* @var string EncodingType
*/
public static $EncodingType = "UTF-8";
/**
* The content type to output.
*
* @var string ContentType
*/
public static $ContentType = "text/html";
/**
* An array of Database objects, as initialized by QApplication::InitializeDatabaseConnections()
*
* @var QDatabaseBase[] Database
*/
public static $Database;
/**
* A flag to indicate whether or not this script is run as a CLI (Command Line Interface)
*
* @var boolean CliMode
*/
public static $CliMode;
/**
* Class File Array - used by QApplication::AutoLoad to more quickly load
* core class objects without making a file_exists call.
*
* @var array ClassFile
*/
public static $ClassFile;
/**
* Preloaded Class File Array - used by QApplication::Initialize to load
* any core class objects during Initailize()
*
* @var array ClassFile
*/
public static $PreloadedClassFile;
/**
* The QRequestMode enumerated value for the current request mode
*
* @var string RequestMode
*/
public static $RequestMode;
/**
* 2-letter country code to set for internationalization and localization
* (e.g. us, uk, jp)
*
* @var string CountryCode
*/
public static $CountryCode;
/**
* 2-letter language code to set for internationalization and localization
* (e.g. en, jp, etc.)
*
* @var string LanguageCode
*/
public static $LanguageCode;
/**
* The instance of the active QI18n object (which contains translation strings), if any.
*
* @var QTranslationBase $LanguageObject
*/
public static $LanguageObject;
/**
* True to force drawing to be minimized.
*
* @var bool
*/
public static $Minimize = false;
////////////////////////
// Public Overrides
////////////////////////
/**
* This faux constructor method throws a caller exception.
* The Application object should never be instantiated, and this constructor
* override simply guarantees it.
*
* @throws QCallerException
*/
public final function __construct() {
throw new QCallerException('Application should never be instantiated. All methods and variables are publically statically accessible.');
}
////////////////////////
// Public Static Methods
////////////////////////
/**
* This should be the first call to initialize all the static variables
* The application object also has static methods that are miscellaneous web
* development utilities, etc.
*
* @throws Exception
* @return void
*/
public static function Initialize() {
self::$EncodingType = defined('__QAPPLICATION_ENCODING_TYPE__') ? __QAPPLICATION_ENCODING_TYPE__ : self::$EncodingType;
// Are we running as CLI?
if (PHP_SAPI == 'cli')
QApplication::$CliMode = true;
else
QApplication::$CliMode = false;
// Setup Server Address
if (array_key_exists('LOCAL_ADDR', $_SERVER))
QApplication::$ServerAddress = $_SERVER['LOCAL_ADDR'];
else if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER))
QApplication::$ServerAddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
else if (array_key_exists('SERVER_ADDR', $_SERVER))
QApplication::$ServerAddress = $_SERVER['SERVER_ADDR'];
// Setup ScriptFilename and ScriptName
QApplication::$ScriptFilename = $_SERVER['SCRIPT_FILENAME'];
QApplication::$ScriptName = $_SERVER['SCRIPT_NAME'];
// Ensure both are set, or we'll have to abort
if ((!QApplication::$ScriptFilename) || (!QApplication::$ScriptName)) {
throw new Exception('Error on QApplication::Initialize() - ScriptFilename or ScriptName was not set');
}
// Setup PathInfo and QueryString (if applicable)
QApplication::$PathInfo = null;
if(array_key_exists('PATH_INFO', $_SERVER)) {
QApplication::$PathInfo = urlencode(trim($_SERVER['PATH_INFO']));
QApplication::$PathInfo = str_ireplace('%2f', '/', QApplication::$PathInfo);
}
QApplication::$QueryString = array_key_exists('QUERY_STRING', $_SERVER) ? $_SERVER['QUERY_STRING'] : null;
// Setup RequestUri
if (defined('__URL_REWRITE__')) {
switch (strtolower(__URL_REWRITE__)) {
case 'apache':
QApplication::$RequestUri = $_SERVER['REQUEST_URI'];
break;
case 'none':
QApplication::$RequestUri = sprintf('%s%s%s',
QApplication::$ScriptName, QApplication::$PathInfo,
(QApplication::$QueryString) ? sprintf('?%s', QApplication::$QueryString) : null);
break;
default:
throw new Exception('Invalid URL Rewrite type: ' . __URL_REWRITE__);
}
} else {
QApplication::$RequestUri = sprintf('%s%s%s',
QApplication::$ScriptName, QApplication::$PathInfo,
(QApplication::$QueryString) ? sprintf('?%s', QApplication::$QueryString) : null);
}
// Setup DocumentRoot
QApplication::$DocumentRoot = trim(__DOCROOT__);
// Setup Browser Type
if (array_key_exists('HTTP_USER_AGENT', $_SERVER)) {
$strUserAgent = trim(strtolower($_SERVER['HTTP_USER_AGENT']));
QApplication::$BrowserType = 0;
// INTERNET EXPLORER (versions 6 through 10)
if (strpos($strUserAgent, 'msie') !== false) {
QApplication::$BrowserType = QApplication::$BrowserType | QBrowserType::InternetExplorer;
// just major version number. Will not see IE 10.6.
$matches = array();
preg_match ('#msie\s(.\d)#', $strUserAgent, $matches);
if ($matches) {
QApplication::$BrowserVersion = (int)$matches[1];
}
}
else if (strpos($strUserAgent, 'trident') !== false) {
// IE 11 significantly changes the user agent, and no longer includes 'MSIE'
QApplication::$BrowserType = QApplication::$BrowserType | QBrowserType::InternetExplorer;
$matches = array();
preg_match ('/rv:(.+)\)/', $strUserAgent, $matches);
if ($matches) {
QApplication::$BrowserVersion = (float)$matches[1];
}
// FIREFOX
} else if ((strpos($strUserAgent, 'firefox') !== false) || (strpos($strUserAgent, 'iceweasel') !== false)) {
QApplication::$BrowserType = QApplication::$BrowserType | QBrowserType::Firefox;
$strUserAgent = str_replace('iceweasel/', 'firefox/', $strUserAgent);
$matches = array();
preg_match ('#firefox/(.+)#', $strUserAgent, $matches);
if ($matches) {
QApplication::$BrowserVersion = (float)$matches[1];
}
}
// CHROME, must come before safari because it also includes a safari string
elseif (strpos($strUserAgent, 'chrome') !== false) {
QApplication::$BrowserType = QApplication::$BrowserType | QBrowserType::Chrome;
// find major version number only
$matches = array();
preg_match ('#chrome/(\d+)#', $strUserAgent, $matches);
if ($matches) {
QApplication::$BrowserVersion = (int)$matches[1];
}
}
// SAFARI
elseif (strpos($strUserAgent, 'safari') !== false) {
QApplication::$BrowserType = QApplication::$BrowserType | QBrowserType::Safari;
$matches = array();
preg_match ('#version/(.+)\s#', $strUserAgent, $matches);
if ($matches) {
QApplication::$BrowserVersion = (float)$matches[1];
}
}
// KONQUEROR
elseif (strpos($strUserAgent, 'konqueror') !== false) {
QApplication::$BrowserType = QApplication::$BrowserType | QBrowserType::Konqueror;
// only looking at major version number on this one
$matches = array();
preg_match ('#konqueror/(\d+)#', $strUserAgent, $matches);
if ($matches) {
QApplication::$BrowserVersion = (int)$matches[1];
}
}
// OPERA
elseif (strpos($strUserAgent, 'opera') !== false) {
QApplication::$BrowserType = QApplication::$BrowserType | QBrowserType::Opera;
// two different patterns;
$matches = array();
preg_match ('#version/(\d+)#', $strUserAgent, $matches);
if ($matches) {
QApplication::$BrowserVersion = (int)$matches[1];
} else {
preg_match ('#opera\s(.+)#', $strUserAgent, $matches);
if ($matches) {
QApplication::$BrowserVersion = (float)$matches[1];
}
}
}
// Unknown
if (QApplication::$BrowserType == 0)
QApplication::$BrowserType = QApplication::$BrowserType | QBrowserType::Unsupported;
// OS (supporting Windows, Linux and Mac)
if (strpos($strUserAgent, 'windows') !== false)
QApplication::$BrowserType = QApplication::$BrowserType | QBrowserType::Windows;
elseif (strpos($strUserAgent, 'linux') !== false)
QApplication::$BrowserType = QApplication::$BrowserType | QBrowserType::Linux;
elseif (strpos($strUserAgent, 'macintosh') !== false)
QApplication::$BrowserType = QApplication::$BrowserType | QBrowserType::Macintosh;
// Mobile version of one of the above browsers, or some other unknown browser
if (strpos($strUserAgent, 'mobi') !== false) // opera is just 'mobi', everyone else uses 'mobile'
QApplication::$BrowserType = QApplication::$BrowserType | QBrowserType::Mobile;
}
// Preload Class Files
foreach (QApplication::$PreloadedClassFile as $strClassFile) {
require($strClassFile);
}
// Initialize any classes that might call into the autoloader
$strCacheProviderClass = 'QCacheProviderNoCache';
if (defined('CACHE_PROVIDER_CLASS')) {
$strCacheProviderClass = CACHE_PROVIDER_CLASS;
}
if ($strCacheProviderClass) {
if (defined('CACHE_PROVIDER_OPTIONS')) {
QApplicationBase::$objCacheProvider = new $strCacheProviderClass(unserialize(CACHE_PROVIDER_OPTIONS));
} else {
QApplicationBase::$objCacheProvider = new $strCacheProviderClass();
}
}
if (defined('__MINIMIZE__') && __MINIMIZE__) {
QApplicationBase::$Minimize = true;
}
}
/**
* Checks for the type of browser in use by the client.
* @static
* @param int $intBrowserType
* @return int
*/
public static function IsBrowser($intBrowserType) {
return ($intBrowserType & QApplication::$BrowserType);
}
/**
* This call will initialize the database connection(s) as defined by
* the constants DB_CONNECTION_X, where "X" is the index number of a
* particular database connection.
*
* @throws Exception
* @return void
*/
public static function InitializeDatabaseConnections() {
// for backward compatibility, don't use MAX_DB_CONNECTION_INDEX directly,
// but check if MAX_DB_CONNECTION_INDEX is defined
$intMaxIndex = defined('MAX_DB_CONNECTION_INDEX') ? constant('MAX_DB_CONNECTION_INDEX') : 9;
if (defined('DB_CONNECTION_0')) {
// This causes a conflict with how DbBackedSessionHandler works.
throw new Exception('Do not define DB_CONNECTION_0. Start at DB_CONNECTION_1');
}
for ($intIndex = 1; $intIndex <= $intMaxIndex; $intIndex++) {
$strConstantName = sprintf('DB_CONNECTION_%s', $intIndex);
if (defined($strConstantName)) {
// Expected Keys to be Set
$strExpectedKeys = array(
'adapter', 'server', 'port', 'database',
'username', 'password', 'profiling', 'dateformat'
);
// Lookup the Serialized Array from the DB_CONFIG constants and unserialize it
$strSerialArray = constant($strConstantName);
$objConfigArray = unserialize($strSerialArray);
// Set All Expected Keys
foreach ($strExpectedKeys as $strExpectedKey)
if (!array_key_exists($strExpectedKey, $objConfigArray))
$objConfigArray[$strExpectedKey] = null;
if (!$objConfigArray['adapter'])
throw new Exception('No Adapter Defined for ' . $strConstantName . ': ' . var_export($objConfigArray, true));
if (!$objConfigArray['server'])
throw new Exception('No Server Defined for ' . $strConstantName . ': ' . constant($strConstantName));
$strDatabaseType = 'Q' . $objConfigArray['adapter'] . 'Database';
if (!class_exists($strDatabaseType)) {
$strDatabaseAdapter = sprintf('%s/database/%s.class.php', __QCUBED_CORE__, $strDatabaseType);
if (!file_exists($strDatabaseAdapter))
throw new Exception('Database Type is not valid: ' . $objConfigArray['adapter']);
require($strDatabaseAdapter);
}
QApplication::$Database[$intIndex] = new $strDatabaseType($intIndex, $objConfigArray);
}
}
}
public static function SessionOverride() {
// Are we using QDbBackedSessionHandler?
if (defined("DB_BACKED_SESSION_HANDLER_DB_INDEX") &&
constant("DB_BACKED_SESSION_HANDLER_DB_INDEX") != 0 && defined("DB_BACKED_SESSION_HANDLER_TABLE_NAME")) {
// Yes we are going to override PHP's default file based handlers.
QDbBackedSessionHandler::Initialize(DB_BACKED_SESSION_HANDLER_DB_INDEX, DB_BACKED_SESSION_HANDLER_TABLE_NAME);
}
}
/**
* This is called by the PHP5 Autoloader. This static method can be overridden.
*
* @param $strClassName
* @return boolean whether or not a class was found / included
*/
public static function Autoload($strClassName) {
if (isset(QApplication::$ClassFile[strtolower($strClassName)])) {
require_once (QApplication::$ClassFile[strtolower($strClassName)]);
return true;
} else if (file_exists($strFilePath = sprintf('%s/%s.class.php', __INCLUDES__, $strClassName))) {
require_once ($strFilePath);
return true;
} else if (file_exists($strFilePath = sprintf('%s/controls/%s.class.php', __INCLUDES__, $strClassName))) {
require_once ($strFilePath);
return true;
} else if (file_exists($strFilePath = sprintf('%s/plugins/%s.php', __INCLUDES__, $strClassName))) {
require_once ($strFilePath);
return true;
} else if (false !== ($intStart = strpos($strClassName, 'QCubed\\Plugin\\'))) {
$strClassName = substr($strClassName, $intStart + 14);
if (file_exists($strFilePath = sprintf('%s/plugins/%s.php', __INCLUDES__, $strClassName))) {
require_once ($strFilePath);
return true;
}
}
return false;
}
/**
* Temprorarily overrides the default error handling mechanism. Remember to call
* RestoreErrorHandler to restore the error handler back to the default.
*
* @param string $strName the name of the new error handler function, or NULL if none
* @param integer $intLevel if a error handler function is defined, then the new error reporting level (if any)
*
* @throws QCallerException
*/
public static function SetErrorHandler($strName, $intLevel = null) {
if (!is_null(QApplicationBase::$intStoredErrorLevel))
throw new QCallerException('Error handler is already currently overridden. Cannot override twice. Call RestoreErrorHandler before calling SetErrorHandler again.');
if (!$strName) {
// No Error Handling is wanted -- simulate a "On Error, Resume" type of functionality
set_error_handler('QcubedHandleError', 0);
QApplicationBase::$intStoredErrorLevel = error_reporting(0);
} else {
set_error_handler($strName, $intLevel);
QApplicationBase::$intStoredErrorLevel = -1;
}
}
/**
* Restores the temporarily overridden default error handling mechanism back to the default.
*/
public static function RestoreErrorHandler() {
if (is_null(QApplicationBase::$intStoredErrorLevel))
throw new QCallerException('Error handler is not currently overridden. Cannot reset something that was never overridden.');
if (QApplicationBase::$intStoredErrorLevel != -1)
error_reporting(QApplicationBase::$intStoredErrorLevel);
restore_error_handler();
QApplicationBase::$intStoredErrorLevel = null;
}
/** @var null|int Stored Error Level (used for Settings and Restoring error handler) */
private static $intStoredErrorLevel = null;
/**
* Create a directory on file system
*
* @param string $strPath Path of the directory to be created
* @param null|int $intMode Octal representation of permissions ('0755' style)
*
* @return bool
*/
public static function MakeDirectory($strPath, $intMode = null) {
return QFolder::MakeDirectory($strPath, $intMode);
}
/**
* This will redirect the user to a new web location. This can be a relative or absolute web path, or it
* can be an entire URL.
*
* TODO: break this into two routines, since the resulting UI behavior is really different. Redirect and LoadPage??
*
* @param string $strLocation target patch
* @param bool $blnAbortCurrentScript Whether to abort the current script, or finish it out so data gets saved.
* @return void
*/
public static function Redirect($strLocation, $blnAbortCurrentScript = true) {
if (!$blnAbortCurrentScript) {
// Use the javascript command mechanism
QApplication::$JavascriptCommandArray[QAjaxResponse::Location] = $strLocation;
}
else {
global $_FORM;
if ($_FORM) {
$_FORM->SaveControlState();
}
// Clear the output buffer (if any)
ob_clean();
if ((QApplication::$RequestMode == QRequestMode::Ajax) ||
(array_key_exists('Qform__FormCallType', $_POST) &&
($_POST['Qform__FormCallType'] == QCallType::Ajax))) {
QApplication::SendAjaxResponse(array(QAjaxResponse::Location => $strLocation));
} else {
// Was "DOCUMENT_ROOT" set?
if (array_key_exists('DOCUMENT_ROOT', $_SERVER) && ($_SERVER['DOCUMENT_ROOT'])) {
// If so, we're likely using PHP as a Plugin/Module
// Use 'header' to redirect
header(sprintf('Location: %s', $strLocation));
} else {
// We're likely using this as a CGI
// Use JavaScript to redirect
printf('<script type="text/javascript">document.location = "%s";</script>', $strLocation);
}
}
// End the Response Script
session_write_close();
exit();
}
}
/**
* This will close the window.
*
* @param bool $blnAbortCurrentScript Whether to abort the current script, or finish it out so data gets saved.
* @return void
*/
public static function CloseWindow($blnAbortCurrentScript = false) {
if (!$blnAbortCurrentScript) {
// Use the javascript command mechanism
QApplication::$JavascriptCommandArray[QAjaxResponse::Close] = true;
}
else {
// Clear the output buffer (if any)
ob_clean();
if (QApplication::$RequestMode == QRequestMode::Ajax) {
// AJAX-based Response
$aResponse[QAjaxResponse::Close] = 1;
QApplication::SendAjaxResponse($aResponse);
} else {
// Use JavaScript to close
_p('<script type="text/javascript">window.close();</script>', false);
}
// End the Response Script
exit();
}
}
/**
* Set a cookie. Allows setting of cookies in responses to ajax requests.
*
* @param string $strName
* @param sring $strValue
* @param QDatTime $dttTimeout
* @param string $strPath
* @param null|string $strDomain
* @param bool $blnSecure
*/
public static function SetCookie($strName, $strValue, QDateTime $dttTimeout, $strPath = '/', $strDomain = null, $blnSecure = false) {
if (QApplication::$RequestMode == QRequestMode::Ajax) {
self::ExecuteJsFunction ('qcubed.setCookie', $strName, $strValue, $dttTimeout, $strPath, $strDomain, $blnSecure);
}
else {
setcookie($strName, $strValue, $dttTimeout->Timestamp, $strPath, $strDomain, $blnSecure);
}
}
/**
* Delete's the given cookie IF its set. In other words, you cannot set a cookie and then delete a cookie right away before the
* cookie gets sent to the browser.
*
* @param $strName
*/
public static function DeleteCookie($strName) {
if (isset($_COOKIE[$strName])) { // don't post a cookie if its not set
$dttTimeout = QDateTime::Now();
$dttTimeout->AddYears(-5);
self::SetCookie($strName, "", $dttTimeout);
}
}
/**
* Gets the value of the QueryString item $strItem. Will return NULL if it doesn't exist.
*
* @param string $strItem the parameter name
*
* @return string value of the parameter
*/
public static function QueryString($strItem) {
if (array_key_exists($strItem, $_GET))
return $_GET[$strItem];
else
return null;
}
/**
* Generates a valid URL Query String based on values in the provided array. If no array is provided, it uses the global $_GET
* @param array $arr
* @return string
*/
public static function GenerateQueryString($arr = null) {
if(null === $arr)
$arr = $_GET;
if (count($arr)) {
$strToReturn = '';
foreach ($arr as $strKey => $mixValue)
$strToReturn .= QApplication::GenerateQueryStringHelper(urlencode($strKey), $mixValue);
return '?' . substr($strToReturn, 1);
} else
return '';
}
/**
* Generates part of query string (helps in generating the complete query string)
* @param string $strKey Key for the query string
* @param string|integer|array $mixValue Value we have to put as the value of the key
*
* @return null|string
*/
protected static function GenerateQueryStringHelper($strKey, $mixValue) {
if (is_array($mixValue)) {
$strToReturn = null;
foreach ($mixValue as $strSubKey => $mixSubValue) {
$strToReturn .= QApplication::GenerateQueryStringHelper($strKey . '[' . $strSubKey . ']', $mixSubValue);
}
return $strToReturn;
} else
return '&' . $strKey . '=' . urlencode($mixValue);
}
/**
* By default, this is used by the codegen and form drafts to do a quick check
* on the ALLOW_REMOTE_ADMIN constant (as defined in configuration.inc.php). If enabled,
* then anyone can access the page. If disabled, only "localhost" can access the page.
* If you want to run a script that should be accessible regardless of
* ALLOW_REMOTE_ADMIN, simply remove the CheckRemoteAdmin() method call from that script.
*
* @throws QRemoteAdminDeniedException
* @return void
*/
public static function CheckRemoteAdmin() {
if (!QApplication::IsRemoteAdminSession()) {
return;
}
// If we're here -- then we're not allowed to access. Present the Error/Issue.
header($_SERVER['SERVER_PROTOCOL'] . ' 401 Access Denied');
header('Status: 401 Access Denied', true);
throw new QRemoteAdminDeniedException();
}
/**
* Checks whether the current request was made by an ADMIN
* This does not refer to your Database admin or an Admin user defined in your application but an IP address
* (or IP address range) defined in configuration.inc.php.
*
* The function can be used to restrict access to sensitive pages to a list of IPs (or IP ranges), such as the LAN to which
* the server hosting the QCubed application is connected.
* @static
* @return bool
*/
public static function IsRemoteAdminSession() {
// Allow Remote?
if (ALLOW_REMOTE_ADMIN === true)
return false;
// Are we localhost?
if (substr($_SERVER['REMOTE_ADDR'],0,4) == '127.' || $_SERVER['REMOTE_ADDR'] == '::1')
return false;
// Are we the correct IP?
if (is_string(ALLOW_REMOTE_ADMIN))
foreach (explode(',', ALLOW_REMOTE_ADMIN) as $strIpAddress) {
if (QApplication::IsIPInRange($_SERVER['REMOTE_ADDR'], $strIpAddress) ||
(array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER) && (QApplication::IsIPInRange($_SERVER['HTTP_X_FORWARDED_FOR'], $strIpAddress)))) {
return false;
}
}
return true;
}
/**
* Checks whether the given IP falls into the given IP range
* @static
* @param string $ip the IP number to check
* @param string $range the IP number range. The range could be in 'IP/mask' or 'IP - IP' format. mask could be a simple
* integer or a dotted netmask.
* @return bool
*/
public static function IsIPInRange($ip, $range) {
$ip = trim($ip);
if (strpos($range, '/') !== false) {
// we are given a IP/mask
list($net, $mask) = explode('/', $range);
$net = ip2long(trim($net));
$mask = trim($mask);
//$ip_net = ip2long($net);
if (strpos($mask, '.') !== false) {
// mask has the dotted notation
$ip_mask = ip2long($mask);
} else {
// mask is an integer
$ip_mask = ~((1 << (32 - $mask)) - 1);
}
$ip = ip2long($ip);
return ($net & $ip_mask) == ($ip & $ip_mask);
}
if (strpos($range, '-') !== false) {
// we are given an IP - IP range
list($first, $last) = explode('-', $range);
$first = ip2long(trim($first));
$last = ip2long(trim($last));
$ip = ip2long($ip);
return $first <= $ip && $ip <= $last;
}
// $range is a simple IP
return $ip == trim($range);
}
/**
* Gets the value of the PathInfo item at index $intIndex. Will return NULL if it doesn't exist.
*
* The way PathInfo index is determined is, for example, given a URL '/folder/page.php/id/15/blue',
* QApplication::PathInfo(0) will return 'id'
* QApplication::PathInfo(1) will return '15'
* QApplication::PathInfo(2) will return 'blue'
*
* @param int $intIndex index
* @return string|null
*/
public static function PathInfo($intIndex) {
// TODO: Cache PathInfo
$strPathInfo = urldecode(QApplication::$PathInfo);
// Remove Starting '/'
if (QString::FirstCharacter($strPathInfo) == '/')
$strPathInfo = substr($strPathInfo, 1);
$strPathInfoArray = explode('/', $strPathInfo);
if (array_key_exists($intIndex, $strPathInfoArray))
return $strPathInfoArray[$intIndex];
else
return null;
}
/**
* If this particular item is set, we ensure that this command, and only this command will get invoked on the
* next response. The rest of the commands will wait until the next response.
*
* @var null|array;
*/
public static $JavascriptExclusiveCommand = null;
/** @var array A structured array of commands to be sent to either the ajax response, or page output.
* Replaces the AlertMessageArray, JavaScriptArray, JavaScriptArrayHighPriority, and JavaScriptArrayLowPriority.
*/
protected static $JavascriptCommandArray = array();
/** @var array JS files to be added to the list of files in front of the javascript commands. Should include jquery, etc. */
protected static $JavascriptFileArray = array();
/*
public static $AlertMessageArray = array();
public static $JavaScriptArray = array();
public static $JavaScriptArrayHighPriority = array();
public static $JavaScriptArrayLowPriority = array();
public static $ControlCommands = array();*/
/** @var bool Used to determine if an error has occurred */
public static $ErrorFlag = false;
/**
* Causes the browser to display a JavaScript alert() box with supplied message
* @param string $strMessage Message to be displayed
*/
public static function DisplayAlert($strMessage) {
QApplication::$JavascriptCommandArray[QAjaxResponse::Alert][] = $strMessage;
}
/**
* This class can be used to call a Javascript function in the client browser from the server side.
* Can be used inside event handlers to do something after verification on server side.
*
* TODO: Since this is implemented with an "eval" on the client side in ajax, we should phase this out in favor
* of specific commands sent to the client.
*
* @static
* @deprecated Will be eventually removed. If you need to do something in javascript, add it to QAjaxResponse.
* @param string $strJavaScript the javascript to execute
* @param string $strPriority
* @throws QCallerException
*/
public static function ExecuteJavaScript($strJavaScript, $strPriority = QJsPriority::Standard) {
if (is_bool($strPriority)) {
//we keep this codepath for backward compatibility
if ($strPriority === true) {
throw new QCallerException('Please specify a correct priority value');
}
} else {
switch ($strPriority) {
case QJsPriority::High:
QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsHigh][] = ['script'=>$strJavaScript];
break;
case QJsPriority::Low:
QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsLow][] = ['script'=>$strJavaScript];
break;
case QJsPriority::Exclusive:
QApplication::$JavascriptExclusiveCommand = ['script'=>$strJavaScript];
break;
default:
QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsMedium][] = ['script'=>$strJavaScript];
break;
}
}
}
/**
* Execute a function on a particular control. Many javascript widgets are structured this way, and this gives us
* a general purpose way of sending commands to widgets without an 'eval' on the client side.
*
* Commands will be executed in the order received, along with ExecuteJavaScript commands and ExecuteObjectCommands.
* If you want to force a command to execute first, give it high priority, or last, give it low priority.
*
* @param string $strControlId Id of control to direct the command to.
* @param string $strFunctionName Function name to call. For jQueryUI, this would be the widget name
* @param string $strFunctionName,... Unlimited OPTIONAL parameters to use as a parameter list to the function. List can
* end with a QJsPriority to prioritize the command.
*/
public static function ExecuteControlCommand ($strControlId, $strFunctionName /*, ..., QJsPriority */) {
$args = func_get_args();
$args[0] = '#' . $strControlId;
call_user_func_array('QApplication::ExecuteSelectorFunction', $args);
}
/**
* Call a function on a jQuery selector. The selector can be a single string, or an array where the first
* item is a selector specifying the items within the context of the second selector.
*
* @param array|string $mixSelector
* @param string $strFunctionName
* @param string $strFunctionName,... Unlimited OPTIONAL parameters to use as a parameter list to the function. List can
* end with a QJsPriority to prioritize the command.
* @throws QCallerException
*/
public static function ExecuteSelectorFunction ($mixSelector, $strFunctionName /*, ..., QJsPriority */) {
if (!(is_string($mixSelector) || (is_array($mixSelector) && count($mixSelector) == 2))) {
throw new QCallerException ('Selector must be a string or an array of two items');
}
$args = func_get_args();
array_shift ($args);
array_shift ($args);
if ($args && end($args) === QJsPriority::High) {
$code = QAjaxResponse::CommandsHigh;
array_pop($args);
}
elseif ($args && end($args) === QJsPriority::Low) {
$code = QAjaxResponse::CommandsLow;
array_pop($args);
}
elseif ($args && end($args) === QJsPriority::Exclusive) {
array_pop($args);
QApplication::$JavascriptExclusiveCommand = ['selector'=>$mixSelector, 'func'=>$strFunctionName, 'params'=>$args];
return;
}
elseif ($args && end($args) === QJsPriority::Last) {
array_pop($args);
QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsFinal][] = ['selector'=>$mixSelector, 'func'=>$strFunctionName, 'params'=>$args, 'final'=>true];
return;
}
else {
$code = QAjaxResponse::CommandsMedium;
}
if (empty($args)) {
$args = null;
}
QApplication::$JavascriptCommandArray[$code][] = ['selector'=>$mixSelector, 'func'=>$strFunctionName, 'params'=>$args];
}
/**
* Call the given function with the given arguments. If just a function name, then the window object is searched.
* The function can be inside an object accessible from the global namespace by separating with periods.
* @param string $strFunctionName Can be namespaced, as in "qcubed.func".
* @param string $strFunctionName,... Unlimited OPTIONAL parameters to use as a parameter list to the function. List can
* end with a QJsPriority to prioritize the command.
*/
public static function ExecuteJsFunction($strFunctionName /*, ... */) {
$args = func_get_args();
array_shift ($args);
if ($args && end($args) === QJsPriority::High) {
$code = QAjaxResponse::CommandsHigh;
array_pop($args);
}
elseif ($args && end($args) === QJsPriority::Low) {
$code = QAjaxResponse::CommandsLow;
array_pop($args);
}
elseif ($args && end($args) === QJsPriority::Exclusive) {
array_pop($args);
QApplication::$JavascriptExclusiveCommand = ['func'=>$strFunctionName, 'params'=>$args];
return;
}
else {
$code = QAjaxResponse::CommandsMedium;
}
if (empty($args)) {
$args = null;
}
QApplication::$JavascriptCommandArray[$code][] = ['func'=>$strFunctionName, 'params'=>$args];
}
/**
* One time add of style sheets, to be used by QForm only for last minute style sheet injection.
* @param string[] $strStyleSheetArray
*/
public static function AddStyleSheets (array $strStyleSheetArray) {
if (empty(QApplication::$JavascriptCommandArray[QAjaxResponse::StyleSheets])) {
QApplication::$JavascriptCommandArray[QAjaxResponse::StyleSheets] = $strStyleSheetArray;
}
else {
QApplication::$JavascriptCommandArray[QAjaxResponse::StyleSheets] =
array_merge (QApplication::$JavascriptCommandArray[QAjaxResponse::StyleSheets], $strStyleSheetArray);
}
}
/**
* Add an array of javascript files for one-time inclusion. Called by QForm. Do not call.
* @param string[] $strJavaScriptFileArray
*/
public static function AddJavaScriptFiles ($strJavaScriptFileArray) {
if (empty(QApplication::$JavascriptFileArray[QAjaxResponse::JavaScripts])) {
QApplication::$JavascriptFileArray[QAjaxResponse::JavaScripts] = $strJavaScriptFileArray;
}
else {
QApplication::$JavascriptFileArray[QAjaxResponse::JavaScripts] =
array_merge (QApplication::$JavascriptFileArray[QAjaxResponse::JavaScripts], $strJavaScriptFileArray);
}
}
/**
* Outputs the current page with the buffer data
* @param string $strBuffer Buffer data
*
* @return string
*/
public static function OutputPage($strBuffer) {
// If the ProcessOutput flag is set to false, simply return the buffer
// without processing anything.
if (!QApplication::$ProcessOutput)
return $strBuffer;
if (QApplication::$ErrorFlag) {
return $strBuffer;
} else {
if (QApplication::$RequestMode == QRequestMode::Ajax) {
return trim($strBuffer);
} else {
// Update Cache-Control setting
header('Cache-Control: ' . QApplication::$CacheControl);
// make sure the server does not override the character encoding value by explicitly sending it out as a header.
// some servers will use an internal default if not specified in the header, and that will override the "encoding" value sent in the text.
header(sprintf('Content-Type: %s; charset=%s', strtolower(QApplication::$ContentType), strtolower(QApplication::$EncodingType)));
/*
* Normally, FormBase->RenderEnd will render the javascripts. In the unusual case
* of not rendering with a QForm object, this will still output embedded javascript commands.
*/
$strScript = QApplicationBase::RenderJavascript();
if ($strScript) {
return $strBuffer . '<script type="text/javascript">' . $strScript . '</script>';
}
return $strBuffer;
}
}
}
public static function StartOutputBuffering() {
if (php_sapi_name() !== 'cli' && // Do not buffer the command line interface
!defined('__NO_OUTPUT_BUFFER__')) {
ob_start('QApplicationBase::EndOutputBuffering');
}
}
public static function EndOutputBuffering($strBuffer) {
return QApplication::OutputPage($strBuffer);
}
/**
* Render scripts for injecting files into the html output. This is for server only, not ajax.
* This list will appear ahead of the javascript commands rendered below.
*
* @static
* @return string
*/
public static function RenderFiles() {
$strScript = '';
// Javascript files should get processed before the commands.
if (!empty(QApplication::$JavascriptFileArray[QAjaxResponse::JavaScripts])) {
foreach (QApplication::$JavascriptFileArray[QAjaxResponse::JavaScripts] as $js) {
$strScript .= sprintf('<script type="text/javascript" src="%s"></script>', QApplication::GetJsFileUri($js)) . "\n";
}
}
QApplication::$JavascriptFileArray = array();
return $strScript;
}
/**
* Function renders all the Javascript commands as output to the client browser. This is a mirror of what
* occurs in the success function in the qcubed.js ajax code.
*
* @param $blnBeforeControls True to only render the javascripts that need to come before the controls are defined.
* This is used to break the commands issued into two groups.
* @static
* @return string
*/
public static function RenderJavascript($blnBeforeControls = false) {
$strScript = '';
// Style sheet injection by a control. Not very common, as other ways of adding style sheets would normally be done first.
if (!empty(QApplication::$JavascriptCommandArray[QAjaxResponse::StyleSheets])) {
$str = '';
foreach (QApplication::$JavascriptCommandArray[QAjaxResponse::StyleSheets] as $ss) {
$str .= 'qc.loadStyleSheetFile("' . $ss . '", "all"); ';
}
QApplication::$JavascriptCommandArray[QAjaxResponse::StyleSheets] = null;
}
if (!empty(QApplication::$JavascriptCommandArray[QAjaxResponse::Alert])) {
foreach (QApplication::$JavascriptCommandArray[QAjaxResponse::Alert] as $strAlert) {
$strAlert = json_encode($strAlert);
$strScript .= sprintf('alert(%s); ', $strAlert);
}
QApplication::$JavascriptCommandArray[QAjaxResponse::Alert] = null;
}
if (!empty(QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsHigh])) {
$strScript .= self::RenderCommandArray(QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsHigh]);
QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsHigh] = null;
}
if ($blnBeforeControls) return $strScript; // When we call again, everything above here will be skipped since we are emptying the arrays
if (!empty(QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsMedium])) {
$strScript .= self::RenderCommandArray(QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsMedium]);
QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsMedium] = null;
}
if (!empty(QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsLow])) {
$strScript .= self::RenderCommandArray(QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsLow]);
}
// A QApplication::Redirect
if (!empty(QApplication::$JavascriptCommandArray[QAjaxResponse::Location])) {
$strLocation = QApplication::$JavascriptCommandArray[QAjaxResponse::Location];
$strScript .= sprintf('document.location = "%s";', $strLocation);
}
if (!empty(QApplication::$JavascriptCommandArray[QAjaxResponse::Close])) {
$strScript .= 'window.close();';
}
QApplication::$JavascriptCommandArray = array();
return $strScript;
}
private static function RenderCommandArray(array $commandArray) {
$strScript = '';
foreach ($commandArray as $command) {
if (isset($command['script'])) { // a script to use eval on
$strScript .= sprintf('%s;', $command['script']) . _nl();
}
elseif (isset($command['selector'])) { // a control function
if (is_array($command['selector'])) {
$strSelector = sprintf('"%s", "%s"', $command['selector'][0], $command['selector'][1]);
}
else {
$strSelector = '"' . $command['selector'] . '"';
}
if ($params = $command['params']) {
$objParams = new QJsParameterList($params);
$strParams = $objParams->toJsObject();
} else {
$strParams = '';
}
$strScript .= sprintf ('jQuery(%s).%s(%s);', $strSelector, $command['func'], $strParams) . _nl();
}
elseif (isset($command['func'])) { // a function call
if ($params = $command['params']) {
$objParams = new QJsParameterList($params);
$strParams = $objParams->toJsObject();
}
else {
$strParams = '';
}
$strScript .= sprintf ('%s(%s);', $command['func'], $strParams) . _nl();
}
}
return $strScript;
}
/**
* Return the javascript command array, for use by form ajax response. Will erase the command array, so
* the form better use it.
* @static
* @return array
*/
public static function GetJavascriptCommandArray() {
if (QApplication::$JavascriptExclusiveCommand) {
// only render this one;
$a[QAjaxResponse::CommandsMedium] = [QApplication::$JavascriptExclusiveCommand];
QApplication::$JavascriptExclusiveCommand = null;
return $a;
}
// Combine the javascripts into one array item
$scripts = array();
if (!empty(QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsMedium])) {
$scripts = QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsMedium];
}
if (!empty(QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsHigh])) {
$scripts = array_merge (QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsHigh], $scripts);
unset (QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsHigh]);
}
if (!empty(QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsLow])) {
$scripts = array_merge ($scripts, QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsLow]);
unset (QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsLow]);
}
if (!empty(QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsFinal])) {
$scripts = array_merge ($scripts, QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsFinal]);
unset (QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsFinal]);
}
if ($scripts) {
QApplication::$JavascriptCommandArray[QAjaxResponse::CommandsMedium] = $scripts;
}
// add the file inclusion array onto the front of the command array
$a = array_merge(QApplication::$JavascriptFileArray, QApplication::$JavascriptCommandArray);
QApplication::$JavascriptFileArray = array();
QApplication::$JavascriptCommandArray = array();
return $a;
}
/**
* If LanguageCode is specified and QI18n::Initialize() has been called, then this
* will perform a translation of the given token for the specified Language Code and optional
* Country code.
*
* Otherwise, this will simply return the token as is.
* This method is also used by the global print-translated "_t" function.
*
* @static
* @param string $strToken
* @return string the Translated token (if applicable)
*/
public static function Translate($strToken) {
if (QApplication::$LanguageObject)
return QApplication::$LanguageObject->TranslateToken($strToken);
else
return $strToken;
}
/**
* Global/Central HtmlEntities command to perform the PHP equivalent of htmlentities.
* Feel free to override to specify encoding/quoting specific preferences (e.g. ENT_QUOTES/ENT_NOQUOTES, etc.)
*
* Be careful of one thing though. This now uses ENT_HTML5, to correspond with the default page DOCTYPE. This
* has the added benefit of encoding newlines in data sent to controls. In particular, a multi-line textbox
* needs to have newlines encoded to prevent problems when the output is formatted using _indent().
*
* This method is also used by the global print "_p" function.
*
* @param string $strText text string to perform html escaping
* @return string the html escaped string
*/
public static function HtmlEntities($strText) {
return htmlentities($strText, ENT_COMPAT | ENT_HTML5, QApplication::$EncodingType);
}
/**
* Print an ajax response to the browser.
*
* @param array $strResponseArray An array keyed with QAjaxResponse items. These items will be read by the qcubed.js
* ajax success function and operated on. The goals is to eventually have all possible response types represented
* in the QAjaxResponse so that we can remove the "eval" in qcubed.js.
*/
public static function SendAjaxResponse(array $strResponseArray) {
header('Content-Type: text/json'); // not application/json, as IE reportedly blows up on that, but jQuery knows what to do.
$strJSON = JavascriptHelper::toJSON($strResponseArray);
if (QApplication::$EncodingType && QApplication::$EncodingType != 'UTF-8') {
$strJSON = iconv(QApplication::$EncodingType, 'UTF-8', $strJSON); // json must be UTF-8 encoded
}
print ($strJSON);
}
/**
* Utility function to get the JS file URI, given a string input
* @param string $strFile File name to be tested
*
* @return string the final JS file URI
*/
public static function GetJsFileUri($strFile) {
if ((strpos($strFile, "http") === 0) || (strpos($strFile, "https") === 0))
return $strFile;
if (strpos($strFile, "/") === 0)
return __VIRTUAL_DIRECTORY__ . $strFile;
return __VIRTUAL_DIRECTORY__ . __JS_ASSETS__ . '/' . $strFile;
}
/**
* Utility function to get the CSS file URI, given a string input
* @param string $strFile File name to be tested
*
* @return string the final CSS URI
*/
public static function GetCssFileUri($strFile) {
if ((strpos($strFile, "http") === 0) || (strpos($strFile, "https") === 0))
return $strFile;
if (strpos($strFile, "/") === 0)
return __VIRTUAL_DIRECTORY__ . $strFile;
return __VIRTUAL_DIRECTORY__ . __CSS_ASSETS__ . '/' . $strFile;
}
/**
* For development purposes, this static method outputs all the Application static variables
*
* @return void
*/
public static function VarDump() {
_p('<div class="var-dump"><strong>QCubed Settings</strong><ul>', false);
$arrValidationErrors = QInstallationValidator::Validate();
foreach ($arrValidationErrors as $objResult) {
printf('<li><strong class="warning">WARNING:</strong> %s</li>', $objResult->strMessage);
}
printf('<li>QCUBED_VERSION = "%s"</li>', QCUBED_VERSION);
printf('<li>jQuery version = "%s"</li>', __JQUERY_CORE_VERSION__);
printf('<li>jQuery UI version = "%s"</li>', __JQUERY_UI_VERSION__);
printf('<li>__SUBDIRECTORY__ = "%s"</li>', __SUBDIRECTORY__);
printf('<li>__VIRTUAL_DIRECTORY__ = "%s"</li>', __VIRTUAL_DIRECTORY__);
printf('<li>__INCLUDES__ = "%s"</li>', __INCLUDES__);
printf('<li>__QCUBED_CORE__ = "%s"</li>', __QCUBED_CORE__);
printf('<li>ERROR_PAGE_PATH = "%s"</li>', ERROR_PAGE_PATH);
printf('<li>PHP Include Path = "%s"</li>', get_include_path());
printf('<li>QApplication::$DocumentRoot = "%s"</li>', QApplication::$DocumentRoot);
printf('<li>QApplication::$EncodingType = "%s"</li>', QApplication::$EncodingType);
printf('<li>QApplication::$PathInfo = "%s"</li>', QApplication::$PathInfo);
printf('<li>QApplication::$QueryString = "%s"</li>', QApplication::$QueryString);
printf('<li>QApplication::$RequestUri = "%s"</li>', QApplication::$RequestUri);
printf('<li>QApplication::$ScriptFilename = "%s"</li>', QApplication::$ScriptFilename);
printf('<li>QApplication::$ScriptName = "%s"</li>', QApplication::$ScriptName);
printf('<li>QApplication::$ServerAddress = "%s"</li>', QApplication::$ServerAddress);
if (QApplication::$Database) foreach (QApplication::$Database as $intKey => $objObject) {
printf('<li>QApplication::$Database[%s] settings:</li>', $intKey);
_p("<ul>", false);
foreach (unserialize(constant('DB_CONNECTION_' . $intKey)) as $key => $value) {
if ($key == "password") {
$value = "hidden for security purposes";
}
_p("<li>" . $key. " = " . var_export($value, true). "</li>", false);
}
_p("</ul>", false);
}
_p('</ul></div>', false);
}
}
/**
* Class for enumerating Javascript priority.
* These are taken out of a parameter list, and so are very unlikely strings to include normally.
*/
class QJsPriority {
/** Standard Priority */
const Standard = '*jsMed*';
/** High prioriy JS */
const High = '*jsHigh*';
/** Low Priority JS */
const Low = '*jsLow*';
/** Execute ONLY this command and exclude all others */
const Exclusive = '*jsExclusive*';
/** Execute this command after all ajax commands have been completely flushed */
const Last = '*jsFinal*';
}
/**
* This is an enumerator class for listing Request Modes
*/
class QRequestMode {
/** Normal request (initial request) */
const Standard = 'Standard';
/** Ajax Request (mostly calls triggered by events) */
const Ajax = 'Ajax';
}
/**
* Class QBrowserType: Type of browsers we can identify
*/
class QBrowserType {
/** IE */
const InternetExplorer = 1;
/* Deprecated. See QApplication::BrowserVersion **
const InternetExplorer_6_0 = 2;
const InternetExplorer_7_0 = 4;
const InternetExplorer_8_0 = 8;*/
/** Firefox */
const Firefox = 0x10;
/* Deprecated. See QApplication::BrowserVersion **
const Firefox_1_0 = 0x20;
const Firefox_1_5 = 0x40;
const Firefox_2_0 = 0x80;
const Firefox_3_0 = 0x100;*/
/** Apple's Safari */
const Safari = 0x200;
/* Deprecated. See QApplication::BrowserVersion **
const Safari_2_0 = 0x400;
const Safari_3_0 = 0x800;
const Safari_4_0 = 0x1000;*/
/** Browser */
const Opera = 0x2000;
/* Deprecated. See QApplication::BrowserVersion **
const Opera_7 = 0x4000;
const Opera_8 = 0x8000;
const Opera_9 = 0x10000;*/
/** KDE's failed rocket that never took off */
const Konqueror = 0x20000;
/* Deprecated. See QApplication::BrowserVersion **
const Konqueror_3 = 0x40000;
const Konqueror_4 = 0x80000;*/
/** Google Chrome (and chromium) */
const Chrome = 0x100000;
/* Deprecated. See QApplication::BrowserVersion **
const Chrome_0 = 0x200000;
const Chrome_1 = 0x400000;*/
/** Windows OS */
const Windows = 0x800000;
/** Linux based OS */
const Linux = 0x1000000;
/** Apple's OS X */
const Macintosh = 0x2000000;
/** Some kind of Mobile browser */
const Mobile = 0x4000000; // some kind of mobile browser
/** We don't know this gentleman...err...gentlebrowser */
const Unsupported = 0x8000000;
}