PageRenderTime 40ms CodeModel.GetById 17ms app.highlight 17ms RepoModel.GetById 0ms app.codeStats 0ms

/libraries/legacy/application/application.php

https://bitbucket.org/eternaware/joomus
PHP | 1154 lines | 536 code | 142 blank | 476 comment | 68 complexity | 2c3cd123d82844084c66708690b9fc7b MD5 | raw file
Possible License(s): LGPL-2.1
   1<?php
   2/**
   3 * @package     Joomla.Legacy
   4 * @subpackage  Application
   5 *
   6 * @copyright   Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
   7 * @license     GNU General Public License version 2 or later; see LICENSE
   8 */
   9
  10defined('JPATH_PLATFORM') or die;
  11
  12jimport('joomla.environment.response');
  13
  14/**
  15 * Base class for a Joomla! application.
  16 *
  17 * Acts as a Factory class for application specific objects and provides many
  18 * supporting API functions. Derived clases should supply the route(), dispatch()
  19 * and render() functions.
  20 *
  21 * @package     Joomla.Legacy
  22 * @subpackage  Application
  23 * @since       11.1
  24 */
  25class JApplication extends JApplicationBase
  26{
  27	/**
  28	 * The client identifier.
  29	 *
  30	 * @var    integer
  31	 * @since  11.1
  32	 */
  33	protected $_clientId = null;
  34
  35	/**
  36	 * The application message queue.
  37	 *
  38	 * @var    array
  39	 * @since  11.1
  40	 */
  41	protected $_messageQueue = array();
  42
  43	/**
  44	 * The name of the application.
  45	 *
  46	 * @var    array
  47	 * @since  11.1
  48	 */
  49	protected $_name = null;
  50
  51	/**
  52	 * The scope of the application.
  53	 *
  54	 * @var    string
  55	 * @since  11.1
  56	 */
  57	public $scope = null;
  58
  59	/**
  60	 * The time the request was made.
  61	 *
  62	 * @var    date
  63	 * @since  11.1
  64	 */
  65	public $requestTime = null;
  66
  67	/**
  68	 * The time the request was made as Unix timestamp.
  69	 *
  70	 * @var    integer
  71	 * @since  11.1
  72	 */
  73	public $startTime = null;
  74
  75	/**
  76	 * @var    JApplicationWebClient  The application client object.
  77	 * @since  12.2
  78	 */
  79	public $client;
  80
  81	/**
  82	 * @var    array  JApplication instances container.
  83	 * @since  11.3
  84	 */
  85	protected static $instances = array();
  86
  87	/**
  88	 * Class constructor.
  89	 *
  90	 * @param   array  $config  A configuration array including optional elements such as session
  91	 * session_name, clientId and others. This is not exhaustive.
  92	 *
  93	 * @since   11.1
  94	 */
  95	public function __construct($config = array())
  96	{
  97		// Set the view name.
  98		$this->_name = $this->getName();
  99
 100		// Only set the clientId if available.
 101		if (isset($config['clientId']))
 102		{
 103			$this->_clientId = $config['clientId'];
 104		}
 105
 106		// Enable sessions by default.
 107		if (!isset($config['session']))
 108		{
 109			$config['session'] = true;
 110		}
 111
 112		// Create the input object
 113		$this->input = new JInput;
 114
 115		$this->client = new JApplicationWebClient;
 116
 117		$this->loadDispatcher();
 118
 119		// Set the session default name.
 120		if (!isset($config['session_name']))
 121		{
 122			$config['session_name'] = $this->_name;
 123		}
 124
 125		// Set the default configuration file.
 126		if (!isset($config['config_file']))
 127		{
 128			$config['config_file'] = 'configuration.php';
 129		}
 130
 131		// Create the configuration object.
 132		if (file_exists(JPATH_CONFIGURATION . '/' . $config['config_file']))
 133		{
 134			$this->_createConfiguration(JPATH_CONFIGURATION . '/' . $config['config_file']);
 135		}
 136
 137		// Create the session if a session name is passed.
 138		if ($config['session'] !== false)
 139		{
 140			$this->_createSession(self::getHash($config['session_name']));
 141		}
 142
 143		$this->requestTime = gmdate('Y-m-d H:i');
 144
 145		// Used by task system to ensure that the system doesn't go over time.
 146		$this->startTime = JProfiler::getmicrotime();
 147	}
 148
 149	/**
 150	 * Returns the global JApplication object, only creating it if it
 151	 * doesn't already exist.
 152	 *
 153	 * @param   mixed   $client  A client identifier or name.
 154	 * @param   array   $config  An optional associative array of configuration settings.
 155	 * @param   string  $prefix  A prefix for class names
 156	 *
 157	 * @return  JApplication A JApplication object.
 158	 *
 159	 * @since   11.1
 160	 */
 161	public static function getInstance($client, $config = array(), $prefix = 'J')
 162	{
 163		if (empty(self::$instances[$client]))
 164		{
 165			// Load the router object.
 166			$info = JApplicationHelper::getClientInfo($client, true);
 167
 168			$path = $info->path . '/includes/application.php';
 169			if (file_exists($path))
 170			{
 171				include_once $path;
 172
 173				// Create a JApplication object.
 174				$classname = $prefix . ucfirst($client);
 175				$instance = new $classname($config);
 176			}
 177			else
 178			{
 179				$error = JError::raiseError(500, JText::sprintf('JLIB_APPLICATION_ERROR_APPLICATION_LOAD', $client));
 180				return $error;
 181			}
 182
 183			self::$instances[$client] = $instance;
 184		}
 185
 186		return self::$instances[$client];
 187	}
 188
 189	/**
 190	 * Initialise the application.
 191	 *
 192	 * @param   array  $options  An optional associative array of configuration settings.
 193	 *
 194	 * @return  void
 195	 *
 196	 * @since   11.1
 197	 */
 198	public function initialise($options = array())
 199	{
 200		// Set the language in the class.
 201		$config = JFactory::getConfig();
 202
 203		// Check that we were given a language in the array (since by default may be blank).
 204		if (isset($options['language']))
 205		{
 206			$config->set('language', $options['language']);
 207		}
 208
 209		// Set user specific editor.
 210		$user = JFactory::getUser();
 211		$editor = $user->getParam('editor', $this->getCfg('editor'));
 212		if (!JPluginHelper::isEnabled('editors', $editor))
 213		{
 214			$editor = $this->getCfg('editor');
 215			if (!JPluginHelper::isEnabled('editors', $editor))
 216			{
 217				$editor = 'none';
 218			}
 219		}
 220
 221		$config->set('editor', $editor);
 222
 223		// Trigger the onAfterInitialise event.
 224		JPluginHelper::importPlugin('system');
 225		$this->triggerEvent('onAfterInitialise');
 226	}
 227
 228	/**
 229	 * Route the application.
 230	 *
 231	 * Routing is the process of examining the request environment to determine which
 232	 * component should receive the request. The component optional parameters
 233	 * are then set in the request object to be processed when the application is being
 234	 * dispatched.
 235	 *
 236	 * @return  void
 237	 *
 238	 * @since   11.1
 239	 */
 240	public function route()
 241	{
 242		// Get the full request URI.
 243		$uri = clone JURI::getInstance();
 244
 245		$router = $this->getRouter();
 246		$result = $router->parse($uri);
 247
 248		foreach ($result as $key => $value)
 249		{
 250			$this->input->def($key, $value);
 251		}
 252
 253		// Trigger the onAfterRoute event.
 254		JPluginHelper::importPlugin('system');
 255		$this->triggerEvent('onAfterRoute');
 256	}
 257
 258	/**
 259	 * Dispatch the application.
 260	 *
 261	 * Dispatching is the process of pulling the option from the request object and
 262	 * mapping them to a component. If the component does not exist, it handles
 263	 * determining a default component to dispatch.
 264	 *
 265	 * @param   string  $component  The component to dispatch.
 266	 *
 267	 * @return  void
 268	 *
 269	 * @since   11.1
 270	 */
 271	public function dispatch($component = null)
 272	{
 273		$document = JFactory::getDocument();
 274
 275		$contents = JComponentHelper::renderComponent($component);
 276		$document->setBuffer($contents, 'component');
 277
 278		// Trigger the onAfterDispatch event.
 279		JPluginHelper::importPlugin('system');
 280		$this->triggerEvent('onAfterDispatch');
 281	}
 282
 283	/**
 284	 * Render the application.
 285	 *
 286	 * Rendering is the process of pushing the document buffers into the template
 287	 * placeholders, retrieving data from the document and pushing it into
 288	 * the JResponse buffer.
 289	 *
 290	 * @return  void
 291	 *
 292	 * @since   11.1
 293	 */
 294	public function render()
 295	{
 296		$params = array('template' => $this->getTemplate(), 'file' => 'index.php', 'directory' => JPATH_THEMES, 'params' => $template->params);
 297
 298		// Parse the document.
 299		$document = JFactory::getDocument();
 300		$document->parse($params);
 301
 302		// Trigger the onBeforeRender event.
 303		JPluginHelper::importPlugin('system');
 304		$this->triggerEvent('onBeforeRender');
 305
 306		// Render the document.
 307		$caching = ($this->getCfg('caching') >= 2) ? true : false;
 308		JResponse::setBody($document->render($caching, $params));
 309
 310		// Trigger the onAfterRender event.
 311		$this->triggerEvent('onAfterRender');
 312	}
 313
 314	/**
 315	 * Redirect to another URL.
 316	 *
 317	 * Optionally enqueues a message in the system message queue (which will be displayed
 318	 * the next time a page is loaded) using the enqueueMessage method. If the headers have
 319	 * not been sent the redirect will be accomplished using a "301 Moved Permanently"
 320	 * code in the header pointing to the new location. If the headers have already been
 321	 * sent this will be accomplished using a JavaScript statement.
 322	 *
 323	 * @param   string   $url      The URL to redirect to. Can only be http/https URL
 324	 * @param   string   $msg      An optional message to display on redirect.
 325	 * @param   string   $msgType  An optional message type. Defaults to message.
 326	 * @param   boolean  $moved    True if the page is 301 Permanently Moved, otherwise 303 See Other is assumed.
 327	 *
 328	 * @return  void  Calls exit().
 329	 *
 330	 * @since   11.1
 331	 *
 332	 * @see     JApplication::enqueueMessage()
 333	 */
 334	public function redirect($url, $msg = '', $msgType = 'message', $moved = false)
 335	{
 336		// Check for relative internal links.
 337		if (preg_match('#^index2?\.php#', $url))
 338		{
 339			$url = JURI::base() . $url;
 340		}
 341
 342		// Strip out any line breaks.
 343		$url = preg_split("/[\r\n]/", $url);
 344		$url = $url[0];
 345
 346		/*
 347		 * If we don't start with a http we need to fix this before we proceed.
 348		 * We could validly start with something else (e.g. ftp), though this would
 349		 * be unlikely and isn't supported by this API.
 350		 */
 351		if (!preg_match('#^http#i', $url))
 352		{
 353			$uri = JURI::getInstance();
 354			$prefix = $uri->toString(array('scheme', 'user', 'pass', 'host', 'port'));
 355
 356			if ($url[0] == '/')
 357			{
 358				// We just need the prefix since we have a path relative to the root.
 359				$url = $prefix . $url;
 360			}
 361			else
 362			{
 363				// It's relative to where we are now, so lets add that.
 364				$parts = explode('/', $uri->toString(array('path')));
 365				array_pop($parts);
 366				$path = implode('/', $parts) . '/';
 367				$url = $prefix . $path . $url;
 368			}
 369		}
 370
 371		// If the message exists, enqueue it.
 372		if (trim($msg))
 373		{
 374			$this->enqueueMessage($msg, $msgType);
 375		}
 376
 377		// Persist messages if they exist.
 378		if (count($this->_messageQueue))
 379		{
 380			$session = JFactory::getSession();
 381			$session->set('application.queue', $this->_messageQueue);
 382		}
 383
 384		// If the headers have been sent, then we cannot send an additional location header
 385		// so we will output a javascript redirect statement.
 386		if (headers_sent())
 387		{
 388			echo "<script>document.location.href='" . htmlspecialchars($url) . "';</script>\n";
 389		}
 390		else
 391		{
 392			$document = JFactory::getDocument();
 393
 394			jimport('phputf8.utils.ascii');
 395			if (($this->client->engine == JApplicationWebClient::TRIDENT) && !utf8_is_ascii($url))
 396			{
 397				// MSIE type browser and/or server cause issues when url contains utf8 character,so use a javascript redirect method
 398				echo '<html><head><meta http-equiv="content-type" content="text/html; charset=' . $document->getCharset() . '" />'
 399					. '<script>document.location.href=\'' . htmlspecialchars($url) . '\';</script></head></html>';
 400			}
 401			else
 402			{
 403				// All other browsers, use the more efficient HTTP header method
 404				header($moved ? 'HTTP/1.1 301 Moved Permanently' : 'HTTP/1.1 303 See other');
 405				header('Location: ' . $url);
 406				header('Content-Type: text/html; charset=' . $document->getCharset());
 407			}
 408		}
 409		$this->close();
 410	}
 411
 412	/**
 413	 * Enqueue a system message.
 414	 *
 415	 * @param   string  $msg   The message to enqueue.
 416	 * @param   string  $type  The message type. Default is message.
 417	 *
 418	 * @return  void
 419	 *
 420	 * @since   11.1
 421	 */
 422	public function enqueueMessage($msg, $type = 'message')
 423	{
 424		// For empty queue, if messages exists in the session, enqueue them first.
 425		if (!count($this->_messageQueue))
 426		{
 427			$session = JFactory::getSession();
 428			$sessionQueue = $session->get('application.queue');
 429
 430			if (count($sessionQueue))
 431			{
 432				$this->_messageQueue = $sessionQueue;
 433				$session->set('application.queue', null);
 434			}
 435		}
 436
 437		// Enqueue the message.
 438		$this->_messageQueue[] = array('message' => $msg, 'type' => strtolower($type));
 439	}
 440
 441	/**
 442	 * Get the system message queue.
 443	 *
 444	 * @return  array  The system message queue.
 445	 *
 446	 * @since   11.1
 447	 */
 448	public function getMessageQueue()
 449	{
 450		// For empty queue, if messages exists in the session, enqueue them.
 451		if (!count($this->_messageQueue))
 452		{
 453			$session = JFactory::getSession();
 454			$sessionQueue = $session->get('application.queue');
 455
 456			if (count($sessionQueue))
 457			{
 458				$this->_messageQueue = $sessionQueue;
 459				$session->set('application.queue', null);
 460			}
 461		}
 462
 463		return $this->_messageQueue;
 464	}
 465
 466	/**
 467	 * Gets a configuration value.
 468	 *
 469	 * An example is in application/japplication-getcfg.php Getting a configuration
 470	 *
 471	 * @param   string  $varname  The name of the value to get.
 472	 * @param   string  $default  Default value to return
 473	 *
 474	 * @return  mixed  The user state.
 475	 *
 476	 * @since   11.1
 477	 */
 478	public function getCfg($varname, $default = null)
 479	{
 480		$config = JFactory::getConfig();
 481		return $config->get('' . $varname, $default);
 482	}
 483
 484	/**
 485	 * Method to get the application name.
 486	 *
 487	 * The dispatcher name is by default parsed using the classname, or it can be set
 488	 * by passing a $config['name'] in the class constructor.
 489	 *
 490	 * @return  string  The name of the dispatcher.
 491	 *
 492	 * @since   11.1
 493	 */
 494	public function getName()
 495	{
 496		$name = $this->_name;
 497
 498		if (empty($name))
 499		{
 500			$r = null;
 501			if (!preg_match('/J(.*)/i', get_class($this), $r))
 502			{
 503				JLog::add(JText::_('JLIB_APPLICATION_ERROR_APPLICATION_GET_NAME'), JLog::WARNING, 'jerror');
 504			}
 505			$name = strtolower($r[1]);
 506		}
 507
 508		return $name;
 509	}
 510
 511	/**
 512	 * Gets a user state.
 513	 *
 514	 * @param   string  $key      The path of the state.
 515	 * @param   mixed   $default  Optional default value, returned if the internal value is null.
 516	 *
 517	 * @return  mixed  The user state or null.
 518	 *
 519	 * @since   11.1
 520	 */
 521	public function getUserState($key, $default = null)
 522	{
 523		$session = JFactory::getSession();
 524		$registry = $session->get('registry');
 525
 526		if (!is_null($registry))
 527		{
 528			return $registry->get($key, $default);
 529		}
 530
 531		return $default;
 532	}
 533
 534	/**
 535	 * Sets the value of a user state variable.
 536	 *
 537	 * @param   string  $key    The path of the state.
 538	 * @param   string  $value  The value of the variable.
 539	 *
 540	 * @return  mixed  The previous state, if one existed.
 541	 *
 542	 * @since   11.1
 543	 */
 544	public function setUserState($key, $value)
 545	{
 546		$session = JFactory::getSession();
 547		$registry = $session->get('registry');
 548
 549		if (!is_null($registry))
 550		{
 551			return $registry->set($key, $value);
 552		}
 553
 554		return null;
 555	}
 556
 557	/**
 558	 * Gets the value of a user state variable.
 559	 *
 560	 * @param   string  $key      The key of the user state variable.
 561	 * @param   string  $request  The name of the variable passed in a request.
 562	 * @param   string  $default  The default value for the variable if not found. Optional.
 563	 * @param   string  $type     Filter for the variable, for valid values see {@link JFilterInput::clean()}. Optional.
 564	 *
 565	 * @return  The request user state.
 566	 *
 567	 * @since   11.1
 568	 */
 569	public function getUserStateFromRequest($key, $request, $default = null, $type = 'none')
 570	{
 571		$cur_state = $this->getUserState($key, $default);
 572		$new_state = $this->input->get($request, null, $type);
 573
 574		// Save the new value only if it was set in this request.
 575		if ($new_state !== null)
 576		{
 577			$this->setUserState($key, $new_state);
 578		}
 579		else
 580		{
 581			$new_state = $cur_state;
 582		}
 583
 584		return $new_state;
 585	}
 586
 587	/**
 588	 * Login authentication function.
 589	 *
 590	 * Username and encoded password are passed the onUserLogin event which
 591	 * is responsible for the user validation. A successful validation updates
 592	 * the current session record with the user's details.
 593	 *
 594	 * Username and encoded password are sent as credentials (along with other
 595	 * possibilities) to each observer (authentication plugin) for user
 596	 * validation.  Successful validation will update the current session with
 597	 * the user details.
 598	 *
 599	 * @param   array  $credentials  Array('username' => string, 'password' => string)
 600	 * @param   array  $options      Array('remember' => boolean)
 601	 *
 602	 * @return  boolean  True on success.
 603	 *
 604	 * @since   11.1
 605	 */
 606	public function login($credentials, $options = array())
 607	{
 608		// Get the global JAuthentication object.
 609		jimport('joomla.user.authentication');
 610
 611		$authenticate = JAuthentication::getInstance();
 612		$response = $authenticate->authenticate($credentials, $options);
 613
 614		if ($response->status === JAuthentication::STATUS_SUCCESS)
 615		{
 616			// Validate that the user should be able to login (different to being authenticated).
 617			// This permits authentication plugins blocking the user
 618			$authorisations = $authenticate->authorise($response, $options);
 619			foreach ($authorisations as $authorisation)
 620			{
 621				$denied_states = array(JAuthentication::STATUS_EXPIRED, JAuthentication::STATUS_DENIED);
 622				if (in_array($authorisation->status, $denied_states))
 623				{
 624					// Trigger onUserAuthorisationFailure Event.
 625					$this->triggerEvent('onUserAuthorisationFailure', array((array) $authorisation));
 626
 627					// If silent is set, just return false.
 628					if (isset($options['silent']) && $options['silent'])
 629					{
 630						return false;
 631					}
 632
 633					// Return the error.
 634					switch ($authorisation->status)
 635					{
 636						case JAuthentication::STATUS_EXPIRED:
 637							return JError::raiseWarning('102002', JText::_('JLIB_LOGIN_EXPIRED'));
 638							break;
 639						case JAuthentication::STATUS_DENIED:
 640							return JError::raiseWarning('102003', JText::_('JLIB_LOGIN_DENIED'));
 641							break;
 642						default:
 643							return JError::raiseWarning('102004', JText::_('JLIB_LOGIN_AUTHORISATION'));
 644							break;
 645					}
 646				}
 647			}
 648
 649			// Import the user plugin group.
 650			JPluginHelper::importPlugin('user');
 651
 652			// OK, the credentials are authenticated and user is authorised.  Lets fire the onLogin event.
 653			$results = $this->triggerEvent('onUserLogin', array((array) $response, $options));
 654
 655			/*
 656			 * If any of the user plugins did not successfully complete the login routine
 657			 * then the whole method fails.
 658			 *
 659			 * Any errors raised should be done in the plugin as this provides the ability
 660			 * to provide much more information about why the routine may have failed.
 661			 */
 662
 663			if (!in_array(false, $results, true))
 664			{
 665				// Set the remember me cookie if enabled.
 666				if (isset($options['remember']) && $options['remember'])
 667				{
 668					// Create the encryption key, apply extra hardening using the user agent string.
 669					$privateKey = self::getHash(@$_SERVER['HTTP_USER_AGENT']);
 670
 671					$key = new JCryptKey('simple', $privateKey, $privateKey);
 672					$crypt = new JCrypt(new JCryptCipherSimple, $key);
 673					$rcookie = $crypt->encrypt(serialize($credentials));
 674					$lifetime = time() + 365 * 24 * 60 * 60;
 675
 676					// Use domain and path set in config for cookie if it exists.
 677					$cookie_domain = $this->getCfg('cookie_domain', '');
 678					$cookie_path = $this->getCfg('cookie_path', '/');
 679					setcookie(self::getHash('JLOGIN_REMEMBER'), $rcookie, $lifetime, $cookie_path, $cookie_domain);
 680				}
 681
 682				return true;
 683			}
 684		}
 685
 686		// Trigger onUserLoginFailure Event.
 687		$this->triggerEvent('onUserLoginFailure', array((array) $response));
 688
 689		// If silent is set, just return false.
 690		if (isset($options['silent']) && $options['silent'])
 691		{
 692			return false;
 693		}
 694
 695		// If status is success, any error will have been raised by the user plugin
 696		if ($response->status !== JAuthentication::STATUS_SUCCESS)
 697		{
 698			JLog::add($response->error_message, JLog::WARNING, 'jerror');
 699		}
 700
 701		return false;
 702	}
 703
 704	/**
 705	 * Logout authentication function.
 706	 *
 707	 * Passed the current user information to the onUserLogout event and reverts the current
 708	 * session record back to 'anonymous' parameters.
 709	 * If any of the authentication plugins did not successfully complete
 710	 * the logout routine then the whole method fails. Any errors raised
 711	 * should be done in the plugin as this provides the ability to give
 712	 * much more information about why the routine may have failed.
 713	 *
 714	 * @param   integer  $userid   The user to load - Can be an integer or string - If string, it is converted to ID automatically
 715	 * @param   array    $options  Array('clientid' => array of client id's)
 716	 *
 717	 * @return  boolean  True on success
 718	 *
 719	 * @since   11.1
 720	 */
 721	public function logout($userid = null, $options = array())
 722	{
 723		// Get a user object from the JApplication.
 724		$user = JFactory::getUser($userid);
 725
 726		// Build the credentials array.
 727		$parameters['username'] = $user->get('username');
 728		$parameters['id'] = $user->get('id');
 729
 730		// Set clientid in the options array if it hasn't been set already.
 731		if (!isset($options['clientid']))
 732		{
 733			$options['clientid'] = $this->getClientId();
 734		}
 735
 736		// Import the user plugin group.
 737		JPluginHelper::importPlugin('user');
 738
 739		// OK, the credentials are built. Lets fire the onLogout event.
 740		$results = $this->triggerEvent('onUserLogout', array($parameters, $options));
 741
 742		// Check if any of the plugins failed. If none did, success.
 743
 744		if (!in_array(false, $results, true))
 745		{
 746			// Use domain and path set in config for cookie if it exists.
 747			$cookie_domain = $this->getCfg('cookie_domain', '');
 748			$cookie_path = $this->getCfg('cookie_path', '/');
 749			setcookie(self::getHash('JLOGIN_REMEMBER'), false, time() - 86400, $cookie_path, $cookie_domain);
 750
 751			return true;
 752		}
 753
 754		// Trigger onUserLoginFailure Event.
 755		$this->triggerEvent('onUserLogoutFailure', array($parameters));
 756
 757		return false;
 758	}
 759
 760	/**
 761	 * Gets the name of the current template.
 762	 *
 763	 * @param   array  $params  An optional associative array of configuration settings
 764	 *
 765	 * @return  string  System is the fallback.
 766	 *
 767	 * @since   11.1
 768	 */
 769	public function getTemplate($params = array())
 770	{
 771		return 'system';
 772	}
 773
 774	/**
 775	 * Returns the application JRouter object.
 776	 *
 777	 * @param   string  $name     The name of the application.
 778	 * @param   array   $options  An optional associative array of configuration settings.
 779	 *
 780	 * @return  JRouter  A JRouter object
 781	 *
 782	 * @since   11.1
 783	 */
 784	static public function getRouter($name = null, array $options = array())
 785	{
 786		if (!isset($name))
 787		{
 788			$app = JFactory::getApplication();
 789			$name = $app->getName();
 790		}
 791
 792		jimport('joomla.application.router');
 793
 794		try
 795		{
 796			$router = JRouter::getInstance($name, $options);
 797		}
 798		catch (Exception $e)
 799		{
 800			return null;
 801		}
 802
 803		return $router;
 804	}
 805
 806	/**
 807	 * This method transliterates a string into an URL
 808	 * safe string or returns a URL safe UTF-8 string
 809	 * based on the global configuration
 810	 *
 811	 * @param   string  $string  String to process
 812	 *
 813	 * @return  string  Processed string
 814	 *
 815	 * @since   11.1
 816	 */
 817	static public function stringURLSafe($string)
 818	{
 819		if (JFactory::getConfig()->get('unicodeslugs') == 1)
 820		{
 821			$output = JFilterOutput::stringURLUnicodeSlug($string);
 822		}
 823		else
 824		{
 825			$output = JFilterOutput::stringURLSafe($string);
 826		}
 827
 828		return $output;
 829	}
 830
 831	/**
 832	 * Returns the application JPathway object.
 833	 *
 834	 * @param   string  $name     The name of the application.
 835	 * @param   array   $options  An optional associative array of configuration settings.
 836	 *
 837	 * @return  JPathway  A JPathway object
 838	 *
 839	 * @since   11.1
 840	 */
 841	public function getPathway($name = null, $options = array())
 842	{
 843		if (!isset($name))
 844		{
 845			$name = $this->_name;
 846		}
 847
 848		try
 849		{
 850			$pathway = JPathway::getInstance($name, $options);
 851		}
 852		catch (Exception $e)
 853		{
 854			return null;
 855		}
 856
 857		return $pathway;
 858	}
 859
 860	/**
 861	 * Returns the application JPathway object.
 862	 *
 863	 * @param   string  $name     The name of the application/client.
 864	 * @param   array   $options  An optional associative array of configuration settings.
 865	 *
 866	 * @return  JMenu  JMenu object.
 867	 *
 868	 * @since   11.1
 869	 */
 870	public function getMenu($name = null, $options = array())
 871	{
 872		if (!isset($name))
 873		{
 874			$name = $this->_name;
 875		}
 876
 877		try
 878		{
 879			$menu = JMenu::getInstance($name, $options);
 880		}
 881		catch (Exception $e)
 882		{
 883			return null;
 884		}
 885
 886		return $menu;
 887	}
 888
 889	/**
 890	 * Provides a secure hash based on a seed
 891	 *
 892	 * @param   string  $seed  Seed string.
 893	 *
 894	 * @return  string  A secure hash
 895	 *
 896	 * @since   11.1
 897	 */
 898	public static function getHash($seed)
 899	{
 900		return md5(JFactory::getConfig()->get('secret') . $seed);
 901	}
 902
 903	/**
 904	 * Create the configuration registry.
 905	 *
 906	 * @param   string  $file  The path to the configuration file
 907	 *
 908	 * @return  JConfig  A JConfig object
 909	 *
 910	 * @since   11.1
 911	 */
 912	protected function _createConfiguration($file)
 913	{
 914		JLoader::register('JConfig', $file);
 915
 916		// Create the JConfig object.
 917		$config = new JConfig;
 918
 919		// Get the global configuration object.
 920		$registry = JFactory::getConfig();
 921
 922		// Load the configuration values into the registry.
 923		$registry->loadObject($config);
 924
 925		return $config;
 926	}
 927
 928	/**
 929	 * Create the user session.
 930	 *
 931	 * Old sessions are flushed based on the configuration value for the cookie
 932	 * lifetime. If an existing session, then the last access time is updated.
 933	 * If a new session, a session id is generated and a record is created in
 934	 * the #__sessions table.
 935	 *
 936	 * @param   string  $name  The sessions name.
 937	 *
 938	 * @return  JSession  JSession on success. May call exit() on database error.
 939	 *
 940	 * @since   11.1
 941	 */
 942	protected function _createSession($name)
 943	{
 944		$options = array();
 945		$options['name'] = $name;
 946
 947		switch ($this->_clientId)
 948		{
 949			case 0:
 950				if ($this->getCfg('force_ssl') == 2)
 951				{
 952					$options['force_ssl'] = true;
 953				}
 954				break;
 955
 956			case 1:
 957				if ($this->getCfg('force_ssl') >= 1)
 958				{
 959					$options['force_ssl'] = true;
 960				}
 961				break;
 962		}
 963
 964		$this->registerEvent('onAfterSessionStart', array($this, 'afterSessionStart'));
 965
 966		$session = JFactory::getSession($options);
 967		$session->initialise($this->input, $this->dispatcher);
 968		$session->start();
 969
 970		// TODO: At some point we need to get away from having session data always in the db.
 971
 972		$db = JFactory::getDBO();
 973
 974		// Remove expired sessions from the database.
 975		$time = time();
 976		if ($time % 2)
 977		{
 978			// The modulus introduces a little entropy, making the flushing less accurate
 979			// but fires the query less than half the time.
 980			$query = $db->getQuery(true);
 981			$query->delete($query->qn('#__session'))
 982				->where($query->qn('time') . ' < ' . $query->q((int) ($time - $session->getExpire())));
 983
 984			$db->setQuery($query);
 985			$db->execute();
 986		}
 987
 988		// Check to see the the session already exists.
 989		$handler = $this->getCfg('session_handler');
 990		if (($handler != 'database' && ($time % 2 || $session->isNew()))
 991			|| ($handler == 'database' && $session->isNew()))
 992		{
 993			$this->checkSession();
 994		}
 995
 996		return $session;
 997	}
 998
 999	/**
1000	 * Checks the user session.
1001	 *
1002	 * If the session record doesn't exist, initialise it.
1003	 * If session is new, create session variables
1004	 *
1005	 * @return  void
1006	 *
1007	 * @since   11.1
1008	 */
1009	public function checkSession()
1010	{
1011		$db = JFactory::getDBO();
1012		$session = JFactory::getSession();
1013		$user = JFactory::getUser();
1014
1015		$query = $db->getQuery(true);
1016		$query->select($query->qn('session_id'))
1017			->from($query->qn('#__session'))
1018			->where($query->qn('session_id') . ' = ' . $query->q($session->getId()));
1019
1020		$db->setQuery($query, 0, 1);
1021		$exists = $db->loadResult();
1022
1023		// If the session record doesn't exist initialise it.
1024		if (!$exists)
1025		{
1026			$query->clear();
1027			if ($session->isNew())
1028			{
1029				$query->insert($query->qn('#__session'))
1030					->columns($query->qn('session_id') . ', ' . $query->qn('client_id') . ', ' . $query->qn('time'))
1031					->values($query->q($session->getId()) . ', ' . (int) $this->getClientId() . ', ' . $query->q((int) time()));
1032				$db->setQuery($query);
1033			}
1034			else
1035			{
1036				$query->insert($query->qn('#__session'))
1037					->columns(
1038						$query->qn('session_id') . ', ' . $query->qn('client_id') . ', ' . $query->qn('guest') . ', ' .
1039						$query->qn('time') . ', ' . $query->qn('userid') . ', ' . $query->qn('username')
1040					)
1041					->values(
1042						$query->q($session->getId()) . ', ' . (int) $this->getClientId() . ', ' . (int) $user->get('guest') . ', ' .
1043						$query->q((int) $session->get('session.timer.start')) . ', ' . (int) $user->get('id') . ', ' . $query->q($user->get('username'))
1044					);
1045
1046				$db->setQuery($query);
1047			}
1048
1049			// If the insert failed, exit the application.
1050			try
1051			{
1052				$db->execute();
1053			}
1054			catch (RuntimeException $e)
1055			{
1056				jexit($e->getMessage());
1057			}
1058		}
1059	}
1060
1061	/**
1062	 * After the session has been started we need to populate it with some default values.
1063	 *
1064	 * @return  void
1065	 *
1066	 * @since   12.2
1067	 */
1068	public function afterSessionStart()
1069	{
1070		$session = JFactory::getSession();
1071		if ($session->isNew())
1072		{
1073			$session->set('registry', new JRegistry('session'));
1074			$session->set('user', new JUser);
1075		}
1076	}
1077
1078	/**
1079	 * Gets the client id of the current running application.
1080	 *
1081	 * @return  integer  A client identifier.
1082	 *
1083	 * @since   11.1
1084	 */
1085	public function getClientId()
1086	{
1087		return $this->_clientId;
1088	}
1089
1090	/**
1091	 * Is admin interface?
1092	 *
1093	 * @return  boolean  True if this application is administrator.
1094	 *
1095	 * @since   11.1
1096	 */
1097	public function isAdmin()
1098	{
1099		return ($this->_clientId == 1);
1100	}
1101
1102	/**
1103	 * Is site interface?
1104	 *
1105	 * @return  boolean  True if this application is site.
1106	 *
1107	 * @since   11.1
1108	 */
1109	public function isSite()
1110	{
1111		return ($this->_clientId == 0);
1112	}
1113
1114	/**
1115	 * Method to determine if the host OS is  Windows
1116	 *
1117	 * @return  boolean  True if Windows OS
1118	 *
1119	 * @since   11.1
1120	 * @deprecated  13.3 Use the IS_WIN constant instead.
1121	 */
1122	public static function isWinOS()
1123	{
1124		JLog::add('JApplication::isWinOS() is deprecated. Use the IS_WIN constant instead.', JLog::WARNING, 'deprecated');
1125
1126		return IS_WIN;
1127	}
1128
1129	/**
1130	 * Determine if we are using a secure (SSL) connection.
1131	 *
1132	 * @return  boolean  True if using SSL, false if not.
1133	 *
1134	 * @since   12.2
1135	 */
1136	public function isSSLConnection()
1137	{
1138		return ((isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on')) || getenv('SSL_PROTOCOL_VERSION'));
1139	}
1140
1141	/**
1142	 * Returns the response as a string.
1143	 *
1144	 * @return  string  The response
1145	 *
1146	 * @since   11.1
1147	 */
1148	public function __toString()
1149	{
1150		$compress = $this->getCfg('gzip', false);
1151
1152		return JResponse::toString($compress);
1153	}
1154}