Source for file web.php
Documentation is available at web.php
* @package Joomla.Platform
* @subpackage Application
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
* Base class for a Joomla! Web application.
* @package Joomla.Platform
* @subpackage Application
* @var string Character encoding string.
* @var string Response mime type.
* @var JDate The body modified date for response headers.
* @var JApplicationWebClient The application client object.
* @var JRegistry The application configuration object.
* @var JDocument The application document object.
* @var JLanguage The application language object.
* @var JSession The application session object.
* @var object The application response object.
* @var JApplicationWeb The application instance.
protected static $instance;
* @param mixed $input An optional argument to provide dependency injection for the application's
* input object. If the argument is a JInput object that object will become
* the application's input object, otherwise a default input object is created.
* @param mixed $config An optional argument to provide dependency injection for the application's
* config object. If the argument is a JRegistry object that object will become
* the application's config object, otherwise a default config object is created.
* @param mixed $client An optional argument to provide dependency injection for the application's
* client object. If the argument is a JApplicationWebClient object that object will become
* the application's client object, otherwise a default client object is created.
public function __construct(JInput $input =
null, JRegistry $config =
null, JApplicationWebClient $client =
null)
// If a input object is given use it.
// Create the input based on the application logic.
// If a config object is given use it.
// Instantiate a new configuration object.
// If a client object is given use it.
// Instantiate a new web client object.
// Load the configuration object.
// Set the execution datetime and timestamp;
$this->set('execution.datetime', gmdate('Y-m-d H:i:s'));
$this->set('execution.timestamp', time());
// Setup the response object.
* Returns a reference to the global JApplicationWeb object, only creating it if it doesn't already exist.
* This method must be invoked as: $web = JApplicationWeb::getInstance();
* @param string $name The name (optional) of the JApplicationWeb class to instantiate.
* @return JApplicationWeb
// Only create the object if it doesn't exist.
if (empty(self::$instance))
if (class_exists($name) &&
(is_subclass_of($name, 'JApplicationWeb')))
self::$instance =
new $name;
self::$instance =
new JApplicationWeb;
* Initialise the application.
* @param mixed $session An optional argument to provide dependency injection for the application's
* session object. If the argument is a JSession object that object will become
* the application's session object, if it is false then there will be no session
* object, and if it is null then the default session object will be created based
* on the application's loadSession() method.
* @param mixed $document An optional argument to provide dependency injection for the application's
* document object. If the argument is a JDocument object that object will become
* the application's document object, if it is false then there will be no document
* object, and if it is null then the default document object will be created based
* on the application's loadDocument() method.
* @param mixed $language An optional argument to provide dependency injection for the application's
* language object. If the argument is a JLanguage object that object will become
* the application's language object, if it is false then there will be no language
* object, and if it is null then the default language object will be created based
* on the application's loadLanguage() method.
* @param mixed $dispatcher An optional argument to provide dependency injection for the application's
* event dispatcher. If the argument is a JEventDispatcher object that object will become
* the application's event dispatcher, if it is null then the default event dispatcher
* will be created based on the application's loadDispatcher() method.
* @return JApplicationWeb Instance of $this to allow chaining.
* @deprecated 13.1 (Platform) & 4.0 (CMS)
* @see JApplicationWeb::loadSession()
* @see JApplicationWeb::loadDocument()
* @see JApplicationWeb::loadLanguage()
* @see JApplicationBase::loadDispatcher()
public function initialise($session =
null, $document =
null, $language =
null, $dispatcher =
null)
// Create the session based on the application logic.
// Create the document based on the application logic.
// Create the language based on the application logic.
* Execute the application.
// Trigger the onBeforeExecute event.
// Perform application routines.
// Trigger the onAfterExecute event.
// If we have an application document object, render it.
// Trigger the onBeforeRender event.
// Render the application output.
// Trigger the onAfterRender event.
// If gzip compression is enabled in configuration and the server is compliant, compress the output.
if ($this->get('gzip') &&
!ini_get('zlib.output_compression') &&
(ini_get('output_handler') !=
'ob_gzhandler'))
// Trigger the onBeforeRespond event.
// Send the application response.
// Trigger the onAfterRespond event.
* Method to run the Web application routines. Most likely you will want to instantiate a controller
* and execute it, or perform some sort of action that populates a JDocument object so that output
* can be rendered to the client.
// Your application routines go here.
* Rendering is the process of pushing the document buffers into the template
* placeholders, retrieving data from the document and pushing it into
* the application response buffer.
// Setup the document options.
'template' =>
$this->get('theme'),
'file' =>
$this->get('themeFile', 'index.php'),
'params' =>
$this->get('themeParams')
if ($this->get('themes.base'))
$options['directory'] =
$this->get('themes.base');
// Fall back to constants.
// Set the application output data.
* Checks the accept encoding of the browser and compresses the data before
* sending it to the client if possible.
// Supported compression encodings.
// Get the supported encoding.
// If no supported encoding is detected do nothing and return.
// Verify that headers have not yet been sent, and that our connection is still alive.
// Iterate through the encodings and attempt to compress the data using any found supported encodings.
foreach ($encodings as $encoding)
if (($supported[$encoding] ==
'gz') ||
($supported[$encoding] ==
'deflate'))
// Verify that the server supports gzip compression before we attempt to gzip encode the data.
// @codeCoverageIgnoreStart
// @codeCoverageIgnoreEnd
// Attempt to gzip encode the data with an optimal level 4.
$gzdata =
gzencode($data, 4, ($supported[$encoding] ==
'gz') ?
FORCE_GZIP :
FORCE_DEFLATE);
// If there was a problem encoding the data just try the next encoding scheme.
// @codeCoverageIgnoreStart
// @codeCoverageIgnoreEnd
// Set the encoding headers.
$this->setHeader('Content-Encoding', $encoding);
// Header will be removed at 4.0
if ($this->get('MetaVersion'))
$this->setHeader('X-Content-Encoded-By', 'Joomla');
// Replace the output with the encoded data.
// Compression complete, let's break out of the loop.
* Method to send the application response to the client. All headers will be sent prior to the main
* application output data.
// Send the content-type header.
// If the response is set to uncachable, we need to set some appropriate headers so browsers don't cache the response.
$this->setHeader('Expires', 'Mon, 1 Jan 2001 00:00:00 GMT', true);
$this->setHeader('Last-Modified', gmdate('D, d M Y H:i:s') .
' GMT', true);
$this->setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0', false);
* Redirect to another URL.
* If the headers have not been sent the redirect will be accomplished using a "301 Moved Permanently"
* or "303 See Other" code in the header pointing to the new location. If the headers have already been
* sent this will be accomplished using a JavaScript statement.
* @param string $url The URL to redirect to. Can only be http/https URL
* @param boolean $moved True if the page is 301 Permanently Moved, otherwise 303 See Other is assumed.
public function redirect($url, $moved =
false)
// Import library dependencies.
// Check for relative internal links.
// We changed this from "$this->get('uri.base.full') . $url" due to the inability to run the system tests with the original code
// Perform a basic sanity check to make sure we don't have any CRLF garbage.
* Here we need to check and see if the URL is relative or absolute. Essentially, do we need to
* prepend the URL with our base URL for a proper redirect. The rudimentary way we are looking
* at this is to simply check whether or not the URL string has a valid scheme or not.
// Get a JUri instance for the requested URI.
// Get a base URL to prepend from the requested URI.
$prefix =
$uri->toString(array('scheme', 'user', 'pass', 'host', 'port'));
// We just need the prefix since we have a path relative to the root.
// It's relative to where we are now, so lets add that.
$parts =
explode('/', $uri->toString(array('path')));
$path =
implode('/', $parts) .
'/';
$url =
$prefix .
$path .
$url;
// If the headers have already been sent we need to send the redirect statement via JavaScript.
echo
"<script>document.location.href='" .
str_replace("'", "'", $url) .
"';</script>\n";
// We have to use a JavaScript redirect here because MSIE doesn't play nice with utf-8 URLs.
$html .=
'<meta http-equiv="content-type" content="text/html; charset=' .
$this->charSet .
'" />';
$html .=
'<script>document.location.href=\'' .
str_replace("'", "'", $url) .
'\';</script>';
$html .=
'</head><body></body></html>';
// All other cases use the more efficient HTTP header for redirection.
$this->header($moved ?
'HTTP/1.1 301 Moved Permanently' :
'HTTP/1.1 303 See other');
$this->header('Location: ' .
$url);
$this->header('Content-Type: text/html; charset=' .
$this->charSet);
// Close the application after the redirect.
* Load an object or array into the application configuration object.
* @param mixed $data Either an array or object to be loaded into the configuration object.
* @return JApplicationWeb Instance of $this to allow chaining.
// Load the data into the configuration object.
* Returns a property of the object or the default value if the property is not set.
* @param string $key The name of the property.
* @param mixed $default The default value (optional) if none is set.
* @return mixed The value of the configuration.
public function get($key, $default =
null)
* Modifies a property of the object, creating it if it does not already exist.
* @param string $key The name of the property.
* @param mixed $value The value of the property to set (optional).
* @return mixed Previous value of the property
public function set($key, $value =
null)
* Set/get cachable state for the response. If $allow is set, sets the cachable state of the
* response. Always returns the current state.
* @param boolean $allow True to allow browser caching.
$this->response->cachable = (bool)
$allow;
* Method to set a response header. If the replace flag is set then all headers
* with the given name will be replaced by the new one. The headers are stored
* in an internal array to be sent when the site is sent to the browser.
* @param string $name The name of the header to set.
* @param string $value The value of the header to set.
* @param boolean $replace True to replace any headers with the same name.
* @return JApplicationWeb Instance of $this to allow chaining.
public function setHeader($name, $value, $replace =
false)
// Sanitize the input values.
$value = (string)
$value;
// If the replace flag is set, unset all known headers with the given name.
foreach ($this->response->headers as $key =>
$header)
if ($name ==
$header['name'])
// Clean up the array as unsetting nested arrays leaves some junk.
// Add the header to the internal array.
$this->response->headers[] =
array('name' =>
$name, 'value' =>
$value);
* Method to get the array of response headers to be sent when the response is sent
* Method to clear any set response headers.
* @return JApplicationWeb Instance of $this to allow chaining.
* Send the response headers.
* @return JApplicationWeb Instance of $this to allow chaining.
foreach ($this->response->headers as $header)
// 'status' headers indicate an HTTP status, and need to be handled slightly differently
$this->header($header['name'] .
': ' .
$header['value']);
* Set body content. If body content already defined, this will replace it.
* @param string $content The content to set as the response body.
* @return JApplicationWeb Instance of $this to allow chaining.
$this->response->body =
array((string)
$content);
* Prepend content to the body content
* @param string $content The content to prepend to the response body.
* @return JApplicationWeb Instance of $this to allow chaining.
* Append content to the body content
* @param string $content The content to append to the response body.
* @return JApplicationWeb Instance of $this to allow chaining.
* Return the body content
* @param boolean $asArray True to return the body as an array of strings.
* @return mixed The response body either as an array or concatenated string.
public function getBody($asArray =
false)
* Method to get the application document object.
* @return JDocument The document object
* Method to get the application language object.
* @return JLanguage The language object
* Method to get the application session object.
* @return JSession The session object
* Method to check the current client connnection status to ensure that it is alive. We are
* wrapping this to isolate the connection_status() function from our code base for testing reasons.
* @return boolean True if the connection is valid and normal.
* @see connection_status()
* Method to check to see if headers have already been sent. We are wrapping this to isolate the
* headers_sent() function from our code base for testing reasons.
* @return boolean True if the headers have already been sent.
* Method to detect the requested URI from server environment variables.
* @return string The requested URI
// First we need to detect the URI scheme.
if (isset
($_SERVER['HTTPS']) &&
!empty($_SERVER['HTTPS']) &&
(strtolower($_SERVER['HTTPS']) !=
'off'))
* There are some differences in the way that Apache and IIS populate server environment variables. To
* properly detect the requested URI we need to adjust our algorithm based on whether or not we are getting
* information from Apache or IIS.
// If PHP_SELF and REQUEST_URI are both populated then we will assume "Apache Mode".
if (!empty($_SERVER['PHP_SELF']) &&
!empty($_SERVER['REQUEST_URI']))
// The URI is built from the HTTP_HOST and REQUEST_URI environment variables in an Apache environment.
$uri =
$scheme .
$_SERVER['HTTP_HOST'] .
$_SERVER['REQUEST_URI'];
// If not in "Apache Mode" we will assume that we are in an IIS environment and proceed.
// IIS uses the SCRIPT_NAME variable instead of a REQUEST_URI variable... thanks, MS
$uri =
$scheme .
$_SERVER['HTTP_HOST'] .
$_SERVER['SCRIPT_NAME'];
// If the QUERY_STRING variable exists append it to the URI string.
if (isset
($_SERVER['QUERY_STRING']) &&
!empty($_SERVER['QUERY_STRING']))
$uri .=
'?' .
$_SERVER['QUERY_STRING'];
* Method to load a PHP configuration class file based on convention and return the instantiated data object. You
* will extend this method in child classes to provide configuration data from whatever data source is relevant
* for your specific application.
* @param string $file The path and filename of the configuration file. If not provided, configuration.php
* in JPATH_BASE will be used.
* @param string $class The class name to instantiate.
* @return mixed Either an array or object to be loaded into the configuration object.
* @throws RuntimeException
// Instantiate variables.
if (empty($file) &&
defined('JPATH_ROOT'))
// Applications can choose not to have any configuration data
// by not implementing this method and not having a config file.
throw
new RuntimeException('Configuration class does not exist.');
* Flush the media version to refresh versionable assets
$version->refreshMediaVersion();
* Method to send a header to the client. We are wrapping this to isolate the header() function
* from our code base for testing reasons.
* @param string $string The header string.
* @param boolean $replace The optional replace parameter indicates whether the header should
* replace a previous similar header, or add a second header of the same type.
* @param integer $code Forces the HTTP response code to the specified value. Note that
* this parameter only has an effect if the string is not empty.
protected function header($string, $replace =
true, $code =
null)
header($string, $replace, $code);
* Determine if we are using a secure (SSL) connection.
* @return boolean True if using SSL, false if not.
return ((isset
($_SERVER['HTTPS']) &&
($_SERVER['HTTPS'] ==
'on')) ||
getenv('SSL_PROTOCOL_VERSION'));
* Allows the application to load a custom or default document.
* The logic and options for creating this object are adequately generic for default cases
* but for many applications it will make sense to override this method and create a document,
* if required, based on more specific needs.
* @param JDocument $document An optional document object. If omitted, the factory document is created.
* @return JApplicationWeb This method is chainable.
* Allows the application to load a custom or default language.
* The logic and options for creating this object are adequately generic for default cases
* but for many applications it will make sense to override this method and create a language,
* if required, based on more specific needs.
* @param JLanguage $language An optional language object. If omitted, the factory language is created.
* @return JApplicationWeb This method is chainable.
* Allows the application to load a custom or default session.
* The logic and options for creating this object are adequately generic for default cases
* but for many applications it will make sense to override this method and create a session,
* if required, based on more specific needs.
* @param JSession $session An optional session object. If omitted, the session is created.
* @return JApplicationWeb This method is chainable.
// Generate a session name.
// Calculate the session lifetime.
$lifetime =
(($this->get('sess_lifetime')) ?
$this->get('sess_lifetime') *
60 :
900);
// Get the session handler from the configuration.
$handler =
$this->get('sess_handler', 'none');
// Initialize the options for JSession.
'force_ssl' =>
$this->get('force_ssl')
$this->registerEvent('onAfterSessionStart', array($this, 'afterSessionStart'));
// Instantiate the session object.
if ($session->getState() ==
'expired')
// Set the session object.
* After the session has been started we need to populate it with some default values.
$session->set('registry', new JRegistry('session'));
$session->set('user', new JUser);
* Method to load the system URI strings for the application.
* @param string $requestUri An optional request URI to use instead of detecting one from the
* server environment variables.
// @codeCoverageIgnoreStart
$this->set('uri.request', $requestUri);
// @codeCoverageIgnoreEnd
// Check to see if an explicit base URI has been set.
$siteUri =
trim($this->get('site_uri'));
// No explicit base URI was set so we need to detect it.
// Start with the requested URI.
// If we are working from a CGI SAPI with the 'cgi.fix_pathinfo' directive disabled we use PHP_SELF.
// We aren't expecting PATH_INFO within PHP_SELF so this should work.
// Pretty much everything else should be handled with SCRIPT_NAME.
$uri->setPath(rtrim(dirname($_SERVER['SCRIPT_NAME']), '/\\'));
// Clear the unused parts of the requested URI.
// Get the host and path from the URI.
$host =
$uri->toString(array('scheme', 'user', 'pass', 'host', 'port'));
$path =
rtrim($uri->toString(array('path')), '/\\');
// Check if the path includes "index.php".
if (strpos($path, 'index.php') !==
false)
// Remove the index.php portion of the path.
$path =
rtrim($path, '/\\');
// Set the base URI both as just a path and as the full URI.
$this->set('uri.base.full', $host .
$path .
'/');
$this->set('uri.base.host', $host);
$this->set('uri.base.path', $path .
'/');
// Set the extended (non-base) part of the request URI as the route.
// Get an explicitly set media URI is present.
$mediaURI =
trim($this->get('media_uri'));
if (strpos($mediaURI, '://') !==
false)
$this->set('uri.media.full', $mediaURI);
$this->set('uri.media.path', $mediaURI);
$mediaURI =
trim($mediaURI, '/\\');
$mediaURI =
!empty($mediaURI) ?
'/' .
$mediaURI .
'/' :
'/';
$this->set('uri.media.full', $this->get('uri.base.host') .
$mediaURI);
$this->set('uri.media.path', $mediaURI);
// No explicit media URI was set, build it dynamically from the base uri.
$this->set('uri.media.full', $this->get('uri.base.full') .
'media/');
$this->set('uri.media.path', $this->get('uri.base.path') .
'media/');
Documentation generated on Tue, 19 Nov 2013 15:18:21 +0100 by phpDocumentor 1.4.3