PageRenderTime 30ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/plugins/system/languagefilter/languagefilter.php

https://bitbucket.org/pastor399/newcastleunifc
PHP | 635 lines | 468 code | 72 blank | 95 comment | 125 complexity | 935e66c1026da429b96adb2d2ca9fb97 MD5 | raw file
  1. <?php
  2. /**
  3. * @package Joomla.Plugin
  4. * @subpackage System.languagefilter
  5. *
  6. * @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE.txt
  8. */
  9. defined('_JEXEC') or die;
  10. JLoader::register('MenusHelper', JPATH_ADMINISTRATOR . '/components/com_menus/helpers/menus.php');
  11. /**
  12. * Joomla! Language Filter Plugin
  13. *
  14. * @package Joomla.Plugin
  15. * @subpackage System.languagefilter
  16. * @since 1.6
  17. */
  18. class PlgSystemLanguageFilter extends JPlugin
  19. {
  20. protected static $mode_sef;
  21. protected static $tag;
  22. protected static $sefs;
  23. protected static $lang_codes;
  24. protected static $default_lang;
  25. protected static $default_sef;
  26. protected static $cookie;
  27. private static $_user_lang_code;
  28. public function __construct(&$subject, $config)
  29. {
  30. parent::__construct($subject, $config);
  31. // Ensure that constructor is called one time
  32. self::$cookie = SID == '';
  33. if (!self::$default_lang)
  34. {
  35. $app = JFactory::getApplication();
  36. $router = $app->getRouter();
  37. if ($app->isSite())
  38. {
  39. // setup language data
  40. self::$mode_sef = ($router->getMode() == JROUTER_MODE_SEF) ? true : false;
  41. self::$sefs = JLanguageHelper::getLanguages('sef');
  42. self::$lang_codes = JLanguageHelper::getLanguages('lang_code');
  43. self::$default_lang = JComponentHelper::getParams('com_languages')->get('site', 'en-GB');
  44. self::$default_sef = self::$lang_codes[self::$default_lang]->sef;
  45. $user = JFactory::getUser();
  46. $levels = $user->getAuthorisedViewLevels();
  47. foreach (self::$sefs as $sef => &$language)
  48. {
  49. if (isset($language->access) && $language->access && !in_array($language->access, $levels))
  50. {
  51. unset(self::$sefs[$sef]);
  52. }
  53. }
  54. $app->setLanguageFilter(true);
  55. jimport('joomla.environment.uri');
  56. $uri = JURI::getInstance();
  57. if (self::$mode_sef)
  58. {
  59. // Get the route path from the request.
  60. $path = JString::substr($uri->toString(), JString::strlen($uri->base()));
  61. // Apache mod_rewrite is Off
  62. $path = JFactory::getConfig()->get('sef_rewrite') ? $path : JString::substr($path, 10);
  63. // Trim any spaces or slashes from the ends of the path and explode into segments.
  64. $path = JString::trim($path, '/ ');
  65. $parts = explode('/', $path);
  66. // The language segment is always at the beginning of the route path if it exists.
  67. $sef = $uri->getVar('lang');
  68. if (!empty($parts) && empty($sef))
  69. {
  70. $sef = reset($parts);
  71. }
  72. }
  73. else
  74. {
  75. $sef = $uri->getVar('lang');
  76. }
  77. if (isset(self::$sefs[$sef]))
  78. {
  79. $lang_code = self::$sefs[$sef]->lang_code;
  80. // Create a cookie
  81. $conf = JFactory::getConfig();
  82. $cookie_domain = $conf->get('config.cookie_domain', '');
  83. $cookie_path = $conf->get('config.cookie_path', '/');
  84. setcookie(JApplication::getHash('language'), $lang_code, $this->getLangCookieTime(), $cookie_path, $cookie_domain);
  85. $app->input->cookie->set(JApplication::getHash('language'), $lang_code);
  86. // set the request var
  87. $app->input->set('language', $lang_code);
  88. }
  89. }
  90. parent::__construct($subject, $config);
  91. // Detect browser feature
  92. if ($app->isSite())
  93. {
  94. $app->setDetectBrowser($this->params->get('detect_browser', '1') == '1');
  95. }
  96. }
  97. }
  98. public function onAfterInitialise()
  99. {
  100. $app = JFactory::getApplication();
  101. $app->item_associations = $this->params->get('item_associations', 0);
  102. if ($app->isSite())
  103. {
  104. self::$tag = JFactory::getLanguage()->getTag();
  105. $router = $app->getRouter();
  106. // attach build rules for language SEF
  107. $router->attachBuildRule(array($this, 'buildRule'));
  108. // attach parse rules for language SEF
  109. $router->attachParseRule(array($this, 'parseRule'));
  110. // Adding custom site name
  111. $languages = JLanguageHelper::getLanguages('lang_code');
  112. if (isset($languages[self::$tag]) && $languages[self::$tag]->sitename)
  113. {
  114. JFactory::getConfig()->set('sitename', $languages[self::$tag]->sitename);
  115. }
  116. }
  117. }
  118. public function buildRule(&$router, &$uri)
  119. {
  120. $sef = $uri->getVar('lang');
  121. if (empty($sef))
  122. {
  123. $sef = self::$lang_codes[self::$tag]->sef;
  124. }
  125. elseif (!isset(self::$sefs[$sef]))
  126. {
  127. $sef = self::$default_sef;
  128. }
  129. $Itemid = $uri->getVar('Itemid');
  130. if (!is_null($Itemid))
  131. {
  132. if ($item = JFactory::getApplication()->getMenu()->getItem($Itemid))
  133. {
  134. if ($item->home && $uri->getVar('option') != 'com_search')
  135. {
  136. $link = $item->link;
  137. $parts = JString::parse_url($link);
  138. if (isset ($parts['query']) && strpos($parts['query'], '&amp;'))
  139. {
  140. $parts['query'] = str_replace('&amp;', '&', $parts['query']);
  141. }
  142. parse_str($parts['query'], $vars);
  143. // test if the url contains same vars as in menu link
  144. $test = true;
  145. foreach ($uri->getQuery(true) as $key => $value)
  146. {
  147. if (!in_array($key, array('format', 'Itemid', 'lang')) && !(isset($vars[$key]) && $vars[$key] == $value))
  148. {
  149. $test = false;
  150. break;
  151. }
  152. }
  153. if ($test)
  154. {
  155. foreach ($vars as $key => $value)
  156. {
  157. $uri->delVar($key);
  158. }
  159. $uri->delVar('Itemid');
  160. }
  161. }
  162. }
  163. else
  164. {
  165. $uri->delVar('Itemid');
  166. }
  167. }
  168. if (self::$mode_sef)
  169. {
  170. $uri->delVar('lang');
  171. if (
  172. $this->params->get('remove_default_prefix', 0) == 0
  173. || $sef != self::$default_sef
  174. || $sef != self::$lang_codes[self::$tag]->sef
  175. || $this->params->get('detect_browser', 1) && JLanguageHelper::detectLanguage() != self::$tag && !self::$cookie
  176. )
  177. {
  178. $uri->setPath($uri->getPath().'/'.$sef.'/');
  179. }
  180. else
  181. {
  182. $uri->setPath($uri->getPath());
  183. }
  184. }
  185. else
  186. {
  187. $uri->setVar('lang', $sef);
  188. }
  189. }
  190. public function parseRule(&$router, &$uri)
  191. {
  192. $app = JFactory::getApplication();
  193. $array = array();
  194. $lang_code = $app->input->cookie->getString(JApplication::getHash('language'));
  195. // No cookie - let's try to detect browser language or use site default
  196. if (!$lang_code)
  197. {
  198. if ($this->params->get('detect_browser', 1))
  199. {
  200. $lang_code = JLanguageHelper::detectLanguage();
  201. }
  202. else
  203. {
  204. $lang_code = self::$default_lang;
  205. }
  206. }
  207. if (self::$mode_sef)
  208. {
  209. $path = $uri->getPath();
  210. $parts = explode('/', $path);
  211. $sef = $parts[0];
  212. // Redirect only if not in post
  213. if (!empty($lang_code) && ($app->input->getMethod() != "POST" || count($app->input->post) == 0))
  214. {
  215. if ($this->params->get('remove_default_prefix', 0) == 0)
  216. {
  217. // redirect if sef does not exists
  218. if (!isset(self::$sefs[$sef]))
  219. {
  220. // Use the current language sef or the default one
  221. $sef = isset(self::$lang_codes[$lang_code]) ? self::$lang_codes[$lang_code]->sef : self::$default_sef;
  222. $uri->setPath($sef . '/' . $path);
  223. if ($app->getCfg('sef_rewrite'))
  224. {
  225. $app->redirect($uri->base().$uri->toString(array('path', 'query', 'fragment')));
  226. }
  227. else
  228. {
  229. $path = $uri->toString(array('path', 'query', 'fragment'));
  230. $app->redirect($uri->base().'index.php'.($path ? ('/' . $path) : ''));
  231. }
  232. }
  233. }
  234. else
  235. {
  236. // redirect if sef does not exists and language is not the default one
  237. if (!isset(self::$sefs[$sef]) && $lang_code != self::$default_lang)
  238. {
  239. $sef = isset(self::$lang_codes[$lang_code]) ? self::$lang_codes[$lang_code]->sef : self::$default_sef;
  240. $uri->setPath($sef . '/' . $path);
  241. if ($app->getCfg('sef_rewrite'))
  242. {
  243. $app->redirect($uri->base().$uri->toString(array('path', 'query', 'fragment')));
  244. }
  245. else
  246. {
  247. $path = $uri->toString(array('path', 'query', 'fragment'));
  248. $app->redirect($uri->base().'index.php'.($path ? ('/' . $path) : ''));
  249. }
  250. }
  251. // redirect if sef is the default one
  252. elseif (isset(self::$sefs[$sef]) &&
  253. self::$default_lang == self::$sefs[$sef]->lang_code &&
  254. (!$this->params->get('detect_browser', 1) || JLanguageHelper::detectLanguage() == self::$tag || self::$cookie)
  255. )
  256. {
  257. array_shift($parts);
  258. $uri->setPath(implode('/', $parts));
  259. if ($app->getCfg('sef_rewrite'))
  260. {
  261. $app->redirect($uri->base().$uri->toString(array('path', 'query', 'fragment')));
  262. }
  263. else
  264. {
  265. $path = $uri->toString(array('path', 'query', 'fragment'));
  266. $app->redirect($uri->base().'index.php'.($path ? ('/' . $path) : ''));
  267. }
  268. }
  269. }
  270. }
  271. $lang_code = isset(self::$sefs[$sef]) ? self::$sefs[$sef]->lang_code : '';
  272. if ($lang_code && JLanguage::exists($lang_code))
  273. {
  274. array_shift($parts);
  275. $uri->setPath(implode('/', $parts));
  276. }
  277. }
  278. else
  279. {
  280. $sef = $uri->getVar('lang');
  281. if (!isset(self::$sefs[$sef]))
  282. {
  283. $sef = isset(self::$lang_codes[$lang_code]) ? self::$lang_codes[$lang_code]->sef : self::$default_sef;
  284. $uri->setVar('lang', $sef);
  285. if ($app->input->getMethod() != "POST" || count($app->input->post) == 0)
  286. {
  287. $app->redirect(JURI::base(true).'/index.php?'.$uri->getQuery());
  288. }
  289. }
  290. }
  291. $array = array('lang' => $sef);
  292. return $array;
  293. }
  294. /**
  295. * before store user method
  296. *
  297. * Method is called before user data is stored in the database
  298. *
  299. * @param array $user Holds the old user data.
  300. * @param boolean $isnew True if a new user is stored.
  301. * @param array $new Holds the new user data.
  302. *
  303. * @return void
  304. * @since 1.6
  305. */
  306. public function onUserBeforeSave($user, $isnew, $new)
  307. {
  308. if ($this->params->get('automatic_change', '1') == '1' && key_exists('params', $user))
  309. {
  310. $registry = new JRegistry;
  311. $registry->loadString($user['params']);
  312. self::$_user_lang_code = $registry->get('language');
  313. if (empty(self::$_user_lang_code))
  314. {
  315. self::$_user_lang_code = self::$default_lang;
  316. }
  317. }
  318. }
  319. /**
  320. * after store user method
  321. *
  322. * Method is called after user data is stored in the database
  323. *
  324. * @param array $user Holds the new user data.
  325. * @param boolean $isnew True if a new user is stored.
  326. * @param boolean $success True if user was succesfully stored in the database.
  327. * @param string $msg Message.
  328. *
  329. * @return void
  330. * @since 1.6
  331. */
  332. public function onUserAfterSave($user, $isnew, $success, $msg)
  333. {
  334. if ($this->params->get('automatic_change', '1') == '1' && key_exists('params', $user) && $success)
  335. {
  336. $registry = new JRegistry;
  337. $registry->loadString($user['params']);
  338. $lang_code = $registry->get('language');
  339. if (empty($lang_code))
  340. {
  341. $lang_code = self::$default_lang;
  342. }
  343. $app = JFactory::getApplication();
  344. if ($lang_code == self::$_user_lang_code || !isset(self::$lang_codes[$lang_code]))
  345. {
  346. if ($app->isSite())
  347. {
  348. $app->setUserState('com_users.edit.profile.redirect', null);
  349. }
  350. }
  351. else
  352. {
  353. if ($app->isSite())
  354. {
  355. $app->setUserState('com_users.edit.profile.redirect', 'index.php?Itemid='.$app->getMenu()->getDefault($lang_code)->id.'&lang='.$lang_codes[$lang_code]->sef);
  356. self::$tag = $lang_code;
  357. // Create a cookie
  358. $conf = JFactory::getConfig();
  359. $cookie_domain = $conf->get('config.cookie_domain', '');
  360. $cookie_path = $conf->get('config.cookie_path', '/');
  361. setcookie(JApplication::getHash('language'), $lang_code, $this->getLangCookieTime(), $cookie_path, $cookie_domain);
  362. }
  363. }
  364. }
  365. }
  366. /**
  367. * This method should handle any login logic and report back to the subject
  368. *
  369. * @param array $user Holds the user data
  370. * @param array $options Array holding options (remember, autoregister, group)
  371. *
  372. * @return boolean True on success
  373. * @since 1.5
  374. */
  375. public function onUserLogin($user, $options = array())
  376. {
  377. $app = JFactory::getApplication();
  378. $menu = $app->getMenu();
  379. if ($app->isSite() && $this->params->get('automatic_change', 1))
  380. {
  381. // Load associations
  382. $assoc = isset($app->item_associations) ? $app->item_associations : 0;
  383. if ($assoc)
  384. {
  385. $active = $menu->getActive();
  386. if ($active)
  387. {
  388. $associations = MenusHelper::getAssociations($active->id);
  389. }
  390. }
  391. $lang_code = $user['language'];
  392. if (empty($lang_code))
  393. {
  394. $lang_code = self::$default_lang;
  395. }
  396. if ($lang_code != self::$tag)
  397. {
  398. // Change language
  399. self::$tag = $lang_code;
  400. // Create a cookie
  401. $conf = JFactory::getConfig();
  402. $cookie_domain = $conf->get('config.cookie_domain', '');
  403. $cookie_path = $conf->get('config.cookie_path', '/');
  404. setcookie(JApplication::getHash('language'), $lang_code, $this->getLangCookieTime(), $cookie_path, $cookie_domain);
  405. // Change the language code
  406. JFactory::getLanguage()->setLanguage($lang_code);
  407. // Change the redirect (language have changed)
  408. if (isset($associations[$lang_code]) && $menu->getItem($associations[$lang_code]))
  409. {
  410. $itemid = $associations[$lang_code];
  411. $app->setUserState('users.login.form.return', 'index.php?&Itemid='.$itemid);
  412. }
  413. else
  414. {
  415. $itemid = isset($homes[$lang_code]) ? $homes[$lang_code]->id : $homes['*']->id;
  416. $app->setUserState('users.login.form.return', 'index.php?&Itemid='.$itemid);
  417. }
  418. }
  419. }
  420. }
  421. /**
  422. * This method adds alternate meta tags for associated menu items
  423. *
  424. * @return nothing
  425. * @since 1.7
  426. */
  427. public function onAfterDispatch()
  428. {
  429. $app = JFactory::getApplication();
  430. $doc = JFactory::getDocument();
  431. $menu = $app->getMenu();
  432. $server = JURI::getInstance()->toString(array('scheme', 'host', 'port'));
  433. $option = $app->input->get('option');
  434. $eName = JString::ucfirst(JString::str_ireplace('com_', '', $option));
  435. if ($app->isSite() && $this->params->get('alternate_meta') && $doc->getType() == 'html')
  436. {
  437. // Get active menu item
  438. $active = $menu->getActive();
  439. // load menu associations
  440. if ($active)
  441. {
  442. // Get menu item link
  443. if ($app->getCfg('sef'))
  444. {
  445. $active_link = JRoute::_('index.php?Itemid='.$active->id, false);
  446. }
  447. else
  448. {
  449. $active_link = JRoute::_($active->link.'&Itemid='.$active->id, false);
  450. }
  451. if ($active_link == JUri::base(true).'/')
  452. {
  453. $active_link .= 'index.php';
  454. }
  455. // Get current link
  456. $current_link = JURI::getInstance()->toString(array('path', 'query'));
  457. if ($current_link == JUri::base(true).'/')
  458. {
  459. $current_link .= 'index.php';
  460. }
  461. // Check the exact menu item's URL
  462. if ($active_link == $current_link)
  463. {
  464. $associations = MenusHelper::getAssociations($active->id);
  465. unset($associations[$active->language]);
  466. }
  467. }
  468. // load component associations
  469. $cName = JString::ucfirst($eName.'HelperAssociation');
  470. JLoader::register($cName, JPath::clean(JPATH_COMPONENT_SITE . '/helpers/association.php'));
  471. if (class_exists($cName) && is_callable(array($cName, 'getAssociations')))
  472. {
  473. $cassociations = call_user_func(array($cName, 'getAssociations'));
  474. $lang_code = $app->input->cookie->getString(JApplication::getHash('language'));
  475. // No cookie - let's try to detect browser language or use site default
  476. if (!$lang_code)
  477. {
  478. if ($this->params->get('detect_browser', 1)){
  479. $lang_code = JLanguageHelper::detectLanguage();
  480. } else {
  481. $lang_code = self::$default_lang;
  482. }
  483. }
  484. unset($cassociations[$lang_code]);
  485. }
  486. // handle the default associations
  487. if ((!empty($associations) || !empty($cassociations)) && $this->params->get('item_associations'))
  488. {
  489. foreach (JLanguageHelper::getLanguages() as $language)
  490. {
  491. if (!JLanguage::exists($language->lang_code))
  492. {
  493. continue;
  494. }
  495. if (isset($cassociations[$language->lang_code]))
  496. {
  497. $link = JRoute::_($cassociations[$language->lang_code].'&lang='.$language->sef);
  498. $doc->addHeadLink($server . $link, 'alternate', 'rel', array('hreflang' => $language->lang_code));
  499. }
  500. elseif (isset($associations[$language->lang_code]))
  501. {
  502. $item = $menu->getItem($associations[$language->lang_code]);
  503. if ($item)
  504. {
  505. if ($app->getCfg('sef'))
  506. {
  507. $link = JRoute::_('index.php?Itemid='.$item->id.'&lang='.$language->sef);
  508. }
  509. else
  510. {
  511. $link = JRoute::_($item->link.'&Itemid='.$item->id.'&lang='.$language->sef);
  512. }
  513. $doc->addHeadLink($server . $link, 'alternate', 'rel', array('hreflang' => $language->lang_code));
  514. }
  515. }
  516. }
  517. }
  518. // link to the home page of each language
  519. elseif ($active && $active->home)
  520. {
  521. foreach (JLanguageHelper::getLanguages() as $language)
  522. {
  523. if (!JLanguage::exists($language->lang_code))
  524. {
  525. continue;
  526. }
  527. $item = $menu->getDefault($language->lang_code);
  528. if ($item && $item->language != $active->language && $item->language != '*')
  529. {
  530. if ($app->getCfg('sef'))
  531. {
  532. $link = JRoute::_('index.php?Itemid='.$item->id.'&lang='.$language->sef);
  533. }
  534. else
  535. {
  536. $link = JRoute::_($item->link.'&Itemid='.$item->id.'&lang='.$language->sef);
  537. }
  538. $doc->addHeadLink($server . $link, 'alternate', 'rel', array('hreflang' => $language->lang_code));
  539. }
  540. }
  541. }
  542. }
  543. }
  544. /**
  545. * Getting the Language Cookie settings
  546. *
  547. * @return string The cookie time.
  548. *
  549. * @since 3.0.4
  550. */
  551. private function getLangCookieTime()
  552. {
  553. if ($this->params->get('lang_cookie', 1) == 1)
  554. {
  555. $lang_cookie = time() + 365 * 86400;
  556. }
  557. else
  558. {
  559. $lang_cookie = 0;
  560. }
  561. return $lang_cookie;
  562. }
  563. }