PageRenderTime 66ms CodeModel.GetById 20ms RepoModel.GetById 13ms app.codeStats 0ms

/libraries/joomla/application/application.php

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