/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

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