PageRenderTime 57ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 1ms

/components/com_sef/joomsef.php

https://bitbucket.org/organicdevelopment/joomla-2.5
PHP | 2980 lines | 2140 code | 403 blank | 437 comment | 627 complexity | d34461bb6c8992b69d199fdc81d5dc87 MD5 | raw file
Possible License(s): LGPL-3.0, GPL-2.0, MIT, BSD-3-Clause, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * SEF component for Joomla!
  4. *
  5. * @package JoomSEF
  6. * @version 4.2.8
  7. * @author ARTIO s.r.o., http://www.artio.net
  8. * @copyright Copyright (C) 2012 ARTIO s.r.o.
  9. * @license GNU/GPLv3 http://www.artio.net/license/gnu-general-public-license
  10. */
  11. // Check to ensure this file is included in Joomla!
  12. if (!defined('_JEXEC')) JoomSEF::CheckAccess();
  13. jimport('joomla.plugin.helper');
  14. jimport('joomla.language.helper');
  15. require_once JPATH_SITE.DS.'components'.DS.'com_sef'.DS.'sef.cache.php';
  16. require_once JPATH_ADMINISTRATOR.DS.'components'.DS.'com_sef'.DS.'classes'.DS.'seftools.php';
  17. require_once JPATH_ADMINISTRATOR.DS.'components'.DS.'com_sef'.DS.'models'.DS.'logger.php';
  18. define ('JROUTER_MODE_DONT_PARSE', 2);
  19. class JoomSEF
  20. {
  21. private $_data=null;
  22. static $props = array();
  23. function getInstance() {
  24. static $instance;
  25. if(!isset($instance)) {
  26. $instance=new JoomSEF();
  27. }
  28. return $instance;
  29. }
  30. function setData($data) {
  31. $this->_data=$data;
  32. }
  33. function set($name, $value)
  34. {
  35. if (!is_array(self::$props)) {
  36. self::$props = array();
  37. }
  38. $previous = self::get($name);
  39. self::$props[$name] = $value;
  40. return $previous;
  41. }
  42. function get($name, $default = null)
  43. {
  44. if (!is_array(self::$props) || !isset(self::$props[$name])) {
  45. return $default;
  46. }
  47. return self::$props[$name];
  48. }
  49. function build(&$uri,$check=false)
  50. {
  51. static $extsCache;
  52. if (!isset($extsCache)) {
  53. $extsCache = array();
  54. }
  55. $mainframe =& JFactory::getApplication();
  56. $jRouter = $mainframe->getRouter();
  57. $jRouter->SetMode(JROUTER_MODE_SEF);
  58. $config =& JFactory::getConfig();
  59. $sefConfig =& SEFConfig::getConfig();
  60. $cache =& SEFCache::getInstance();
  61. // Restore global "Add suffix to URLs"
  62. $sefSuffix = $mainframe->get('sef.global.orig_sef_suffix');
  63. $config->set('sef_suffix', $sefSuffix);
  64. // trigger onSefStart patches
  65. $mainframe->triggerEvent('onSefStart');
  66. // Do not SEF URLs with specific format or template according to configuration
  67. if (in_array($uri->getVar('format'), array('raw', 'json', 'xml')) || ($uri->getVar('tmpl') == 'raw') ||
  68. (!$sefConfig->sefComponentUrls && ($uri->getVar('tmpl') == 'component')))
  69. {
  70. $uri = JoomSEF::_createUri($uri);
  71. $mainframe->triggerEvent('onSefEnd');
  72. $jRouter->SetMode(JROUTER_MODE_RAW);
  73. return;
  74. }
  75. // check URL for junk if set to
  76. $vars = $uri->getQuery(true);
  77. if ($sefConfig->checkJunkUrls) {
  78. $junkWords =& $sefConfig->getJunkWords();
  79. $seferr = false;
  80. if (substr($uri->getVar('option', ''), 0, 4) != 'com_') {
  81. $seferr = true;
  82. }
  83. elseif (count($junkWords)) {
  84. $exclude =& $sefConfig->getJunkExclude();
  85. foreach ($vars as $key => $val) {
  86. if (in_array($key, $exclude)) continue;
  87. // Check junk words
  88. foreach ($junkWords as $word) {
  89. if (is_string($val)) {
  90. if (strpos($val, $word) !== false) {
  91. $seferr = true;
  92. break;
  93. }
  94. }
  95. }
  96. if ($seferr) break;
  97. }
  98. }
  99. if ($seferr) {
  100. // trigger onSefEnd patches
  101. $mainframe->triggerEvent('onSefEnd');
  102. $jRouter->SetMode(JROUTER_MODE_RAW);
  103. // fix the path
  104. $path = $uri->getPath();
  105. return;
  106. }
  107. }
  108. if($sefConfig->langEnable && $check==false) {
  109. if(strlen($uri->getVar('lang'))==0) {
  110. $uri->setVar('lang',JRequest::getVar('lang'));
  111. }
  112. }
  113. // Correct FaLang support for translations
  114. $prevLang = '';
  115. if ($sefConfig->langEnable && $check == false) {
  116. $langVar = $uri->getVar('lang');
  117. if (!empty($langVar)) {
  118. $langCode = JoomSEF::getLangCode($langVar);
  119. if (!is_null($langCode)) {
  120. $curCode = JoomSEF::getLangCode();
  121. if ($langCode != $curCode) {
  122. // URL language is different from current language,
  123. // change current language for correct translations
  124. $language = JFactory::getLanguage();
  125. $prevLang = $language->setLanguage($langCode);
  126. $language->load();
  127. }
  128. }
  129. }
  130. }
  131. // if there are no variables and only single language is used
  132. $vars = $uri->getQuery(true);
  133. if (empty($vars) && !isset($lang)) {
  134. JoomSEF::_endSef($prevLang);
  135. return;
  136. }
  137. $option = $uri->getVar('option');
  138. if (!is_null($option)) {
  139. $params =& SEFTools::getExtParams($option);
  140. // Check the stop rule
  141. $stopRule = trim($params->get('stopRule', ''));
  142. if( $stopRule != '' ) {
  143. if( preg_match('/'.$stopRule.'/', $uri->toString()) > 0 ) {
  144. // Don't SEF this URL
  145. $uri = JoomSEF::_createUri($uri);
  146. JoomSEF::_endSef($prevLang);
  147. $jRouter->SetMode(JROUTER_MODE_RAW);
  148. return;
  149. }
  150. }
  151. if(strlen($uri->getVar('Itemid'))==0) {
  152. $uri->delVar('Itemid');
  153. }
  154. $handling = $params->get('handling', '0');
  155. switch($handling) {
  156. // skipped extensions
  157. case '2': {
  158. // Check homepage
  159. if (JoomSEF::_isHomePage($uri)) {
  160. $lang = $uri->getVar('lang');
  161. if (empty($lang)) {
  162. $uri = new JURI('index.php');
  163. }
  164. else {
  165. $uri = new JURI('index.php?lang='.$lang);
  166. }
  167. }
  168. // Build URL
  169. $uri = JoomSEF::_createUri($uri);
  170. JoomSEF::_endSef($prevLang);
  171. $jRouter->SetMode(JROUTER_MODE_RAW);
  172. return;
  173. }
  174. // non-cached extensions
  175. case '1': {
  176. // Check homepage
  177. if (JoomSEF::_isHomePage($uri)) {
  178. $lang = $uri->getVar('lang');
  179. if (empty($lang)) {
  180. $uri = new JURI('index.php');
  181. }
  182. else {
  183. $uri = new JURI('index.php?lang='.$lang);
  184. }
  185. }
  186. JoomSEF::_endSef($prevLang);
  187. return;
  188. }
  189. // default handler or basic rewriting
  190. default: {
  191. // if component has its own sef_ext plug-in included.
  192. // however, prefer own plugin if exists (added by Michal, 28.11.2006)
  193. $compExt = JPATH_ROOT.DS.'components'.DS.$option.DS.'router.php';
  194. $ownExt = JPATH_ROOT.DS.'components'.DS.'com_sef'.DS.'sef_ext'.DS.$option.'.php';
  195. // compatible extension build block
  196. if (file_exists($compExt) && !file_exists($ownExt) && ($handling == '0')) {
  197. // Check homepage
  198. if (JoomSEF::_isHomePage($uri)) {
  199. $lang = $uri->getVar('lang');
  200. if (empty($lang)) {
  201. $uri = new JURI('index.php');
  202. }
  203. else {
  204. $uri = new JURI('index.php?lang='.$lang);
  205. }
  206. // Create homepage SEF URL
  207. $title = array();
  208. $data = JoomSEF::_sefGetLocation($uri, $title, null, null, null, $uri->getVar('lang'));
  209. $uri = JoomSEF::_storeLocation($data);
  210. // remove path as Joomla will add it back
  211. $uri->setPath(preg_replace("@^".$uri->base(true)."@","",$uri->getPath()));
  212. JoomSEF::_endSef($prevLang);
  213. return;
  214. }
  215. // load the plug-in file
  216. require_once($compExt);
  217. $app =& JFactory::getApplication();
  218. $menu =& JSite::getMenu();
  219. $route = $uri->getPath();
  220. $query = $uri->getQuery(true);
  221. $component = preg_replace('/[^A-Z0-9_\.-]/i', '', $query['option']);
  222. $tmp = '';
  223. $function = substr($component, 4) . 'BuildRoute';
  224. $parts = $function($query);
  225. $total = count($parts);
  226. for ($i = 0; $i < $total; $i++) {
  227. $parts[$i] = str_replace(':', '-', $parts[$i]);
  228. }
  229. $result = implode('/', $parts);
  230. $tmp = ($result != "") ? '/'.$result : '';
  231. // build the application route
  232. $built = false;
  233. if (isset($query['Itemid']) && !empty($query['Itemid'])) {
  234. $item = $menu->getItem($query['Itemid']);
  235. if (is_object($item) && $query['option'] == $item->component) {
  236. $tmp = !empty($tmp) ? $item->route.$tmp : $item->route;
  237. $built = true;
  238. }
  239. }
  240. if(!$built) {
  241. $tmp = 'component/'.substr($query['option'], 4).$tmp;
  242. }
  243. $route .= '/'.$tmp;
  244. if($app->getCfg('sef_suffix') && !(substr($route, -9) == 'index.php' || substr($route, -1) == '/')) {
  245. if (($format = $uri->getVar('format', 'html'))) {
  246. $route .= '.' . $format;
  247. $uri->delVar('format');
  248. }
  249. }
  250. if($app->getCfg('sef_rewrite')) {
  251. // transform the route
  252. $route = str_replace('index.php/', '', $route);
  253. }
  254. // Unset unneeded query information
  255. unset($query['Itemid']);
  256. unset($query['option']);
  257. //Set query again in the URI
  258. $uri->setQuery($query);
  259. $uri->setPath($route);
  260. $uri = JoomSEF::_createUri($uri);
  261. JoomSEF::_endSef($prevLang);
  262. // Disable global "Add suffix to URLs" again
  263. $config->set('sef_suffix', 0);
  264. return;
  265. }
  266. // own extension block
  267. else {
  268. // Disable global "Add suffix to URLs"
  269. $config->set('sef_suffix', 0);
  270. if ($handling == '3') {
  271. // Basic rewriting
  272. $class = 'SefExt_Basic';
  273. }
  274. else {
  275. if (file_exists($ownExt)) {
  276. $class = 'SefExt_'.$option;
  277. } else {
  278. $class = 'SefExt';
  279. }
  280. }
  281. // Extensions cache
  282. if (!class_exists($class)) {
  283. require($ownExt);
  284. }
  285. $sef_ext = new $class();
  286. $extsCache[$class] = $sef_ext;
  287. // Set currently handled URI
  288. $sef_ext->setCurrentUri($uri);
  289. // 17.2.2012, dajo: isHomePage should be tested before the beforeCreate() is called
  290. // Grr Joomla SEF router adds home Itemid to Items without menu Item assigned
  291. $homes=array_keys(SEFTools::getHomeQueries());
  292. if(in_array($uri->getVar('Itemid'),$homes) && !JoomSEF::_isHomePage($uri)) {
  293. $uri->setVar('Itemid',JRequest::getInt('Itemid'));
  294. }
  295. // Let the extension change the url and options
  296. $sef_ext->beforeCreate($uri);
  297. list($sid, $mosmsg) = self::_prepareUriForCreate($params, $uri);
  298. // Get nonsef and ignore vars from extension
  299. list($nonSefVars, $ignoreVars) = $sef_ext->getNonSefVars($uri);
  300. // Create array of all the non sef vars
  301. $nonSefVars = SEFTools::getNonSefVars($uri, $nonSefVars, $ignoreVars);
  302. // Create a copy of JURI object
  303. $uri2 = clone($uri);
  304. // Remove nonsef variables from our JURI copy
  305. $nonSefUrl = SEFTools::RemoveVariables($uri2, array_keys($nonSefVars));
  306. // Check homepage
  307. if (JoomSEF::_isHomePage($uri2, true)) {
  308. $title[] = $uri2->getVar('lang');
  309. $pagination=false;
  310. if(method_exists($sef_ext,"_processPagination")) {
  311. $title=array_merge($title,$sef_ext->_processPagination($uri2));
  312. $pagination=true;
  313. }
  314. if($uri2->getVar('format')=='feed') {
  315. $title[]=$uri2->getVar('type');
  316. }
  317. $data = JoomSEF::_sefGetLocation($uri2, $title, null, null, null, $uri->getVar('lang'),null,null,null,null,$pagination);
  318. unset($data["lang"]);
  319. $uri = JoomSEF::_storeLocation($data);
  320. // remove path as Joomla will add it back
  321. $uri->setPath(preg_replace("@^".$uri->base(true)."@","",$uri->getPath()));
  322. // Set non-SEF variables
  323. $uri->setQuery($nonSefUrl);
  324. JoomSEF::_endSef($prevLang);
  325. return;
  326. }
  327. // clean Itemid if desired
  328. // David: only if overriding is disabled
  329. $override = $params->get('itemid', '0');
  330. if (isset($sefConfig->excludeSource) && $sefConfig->excludeSource && ($override == '0')) {
  331. $Itemid = $uri->getVar('Itemid');
  332. $uri2->delVar('Itemid');
  333. }
  334. $url = JoomSEF::_uriToUrl($uri2);
  335. // try to get url from cache
  336. $sefUrl = false;
  337. if ($sefConfig->useCache) {
  338. if(!$check) {
  339. $sefUrl = $cache->GetSefUrl($url);
  340. }
  341. }
  342. if (!$sefConfig->useCache || !$sefUrl) {
  343. // check if the url is already saved in the database
  344. $sefUrl = $sef_ext->getSefUrlFromDatabase($uri2);
  345. if (is_string($sefUrl)) {
  346. // Backward compatibility
  347. $sefstring = $sefUrl;
  348. $sefUrl = new stdClass();
  349. $sefUrl->sefurl = $sefstring;
  350. $sefUrl->sef = 1;
  351. $sefUrl->host = '';
  352. }
  353. }
  354. // unknown URL yet
  355. if (!$sefUrl || $check) {
  356. // load JoomSEF Language File
  357. JFactory::getLanguage()->load('com_sef',JPATH_ADMINISTRATOR);
  358. // rewrite the URL, creating new JURI object
  359. $data = $sef_ext->create($uri);
  360. if (is_object($data) && is_a($data, 'JURI')) {
  361. // Backwards compatibility
  362. $uri = $data;
  363. }
  364. else {
  365. if($sefConfig->langPlacementJoomla==_COM_SEF_LANG_PATH) {
  366. // if data is not array, than we don't have in lang language from SEF extension, because is't original URL
  367. if(is_array($data)) {
  368. if($data['lang']=='*') {
  369. // If we don't want to have language in multilanguage content strip down the language from path to eleminate duplicit pages with same content
  370. if($sefConfig->addLangMulti) {
  371. $data["lang"]=$data["uri"]->getVar('lang');
  372. } else {
  373. unset($data["lang"]);
  374. $data["uri"]->delVar('lang');
  375. }
  376. } else {
  377. $langs=JLanguageHelper::getLanguages('lang_code');
  378. if(array_key_exists($data["lang"],$langs)) {
  379. $data["lang"]=$langs[$data["lang"]]->sef;
  380. }
  381. if(!strlen($data["lang"])) {
  382. $data["lang"]=$data["uri"]->getVar('lang');
  383. }
  384. }
  385. }
  386. if($sefConfig->alwaysUseLangJoomla==false) {
  387. if(isset($data["lang"]) && $data["lang"]==$sefConfig->mainLanguageJoomla) {
  388. unset($data["lang"]);
  389. $data["uri"]->delVar('lang');
  390. }
  391. }
  392. }
  393. $titlepage=false;
  394. $subdomain=SEFTools::getSubdomain($uri->getVar('Itemid'),$uri,$titlepage);
  395. if(strlen($subdomain)) {
  396. $uri->setHost($subdomain.".".JFactory::getURI()->getHost());
  397. }
  398. if($titlepage) {
  399. $data["title"]=array();
  400. }
  401. if(!isset($data["host"])) {
  402. $data["host"]=$uri->getHost();
  403. }
  404. if($check) {
  405. $this->_data=$data;
  406. }
  407. if (isset($sefConfig->excludeSource) && $sefConfig->excludeSource && ($override == '0')) {
  408. if (isset($data['uri'])) {
  409. $data['uri']->delVar('Itemid');
  410. }
  411. }
  412. $uri = JoomSEF::_storeLocation($data,$check);
  413. }
  414. } else {
  415. // if SEF is disabled, don't SEF
  416. if (isset($sefUrl->sef) && !$sefUrl->sef) {
  417. $uri = JoomSEF::_createUri($uri);
  418. JoomSEF::_endSef($prevLang);
  419. $jRouter->SetMode(JROUTER_MODE_RAW);
  420. return;
  421. }
  422. // Create new JURI object from $sefstring
  423. if (!isset($sefUrl->host) || !strlen($sefUrl->host)) {
  424. $root = JFactory::getUri()->toString(array('host', 'port'));
  425. } else {
  426. $root = $sefUrl->host;
  427. }
  428. $url = JFactory::getURI()->getScheme()."://".$root.JURI::root(true);
  429. if (substr($url, -1) != '/') {
  430. $url .= '/';
  431. }
  432. $url .= $sefUrl->sefurl;
  433. // Add nonSef part if set
  434. if( !empty($nonSefUrl) ) {
  435. $url .= '?'.$nonSefUrl;
  436. }
  437. // Add fragment if set
  438. $fragment = $uri->getFragment();
  439. if (!empty($fragment)) {
  440. $url .= '#'.$fragment;
  441. }
  442. $uri = new JURI($url);
  443. }
  444. // reconnect the sid to the url
  445. if (!empty($sid) && !$sefConfig->dontRemoveSid) $uri->setVar('sid', $sid);
  446. // reconnect mosmsg to the url
  447. if (!empty($mosmsg)) $uri->setVar('mosmsg', $mosmsg);
  448. // reconnect ItemID to the url
  449. // David: only if extension doesn't set its own Itemid through overrideId parameter
  450. if (isset($sefConfig->excludeSource) && $sefConfig->excludeSource && $sefConfig->reappendSource && ($override == '0') && !empty($Itemid)) {
  451. $uri->setVar('Itemid', $Itemid);
  452. }
  453. // let the extension change the resulting SEF url
  454. $sef_ext->afterCreate($uri);
  455. }
  456. }
  457. }
  458. }
  459. else if (!is_null($uri->getVar('Itemid'))) {
  460. // there is only Itemid present - we must override the Ignore multiple sources option
  461. $oldIgnore = $sefConfig->ignoreSource;
  462. $sefConfig->ignoreSource = 0;
  463. $lang="";
  464. $title = array();
  465. $title[] = JoomSEF::_getMenuTitleLang(null, $lang, $uri->getVar('Itemid'));
  466. $data = JoomSEF::_sefGetLocation($uri, $title, null, null, null, strlen($lang)?$lang:$uri->getVar('lang'));
  467. $uri = JoomSEF::_storeLocation($data);
  468. $sefConfig->ignoreSource = $oldIgnore;
  469. }
  470. $uri->setPath(preg_replace("@^".$uri->base(true)."@","",$uri->getPath()));
  471. JoomSEF::_endSef($prevLang);
  472. // Set Joomla's router so it doesn't process URL further
  473. $jRouter->SetMode(JROUTER_MODE_RAW);
  474. }
  475. function _prepareUriForCreate(&$params, &$uri) {
  476. $sefConfig = SEFConfig::getConfig();
  477. // Ensure that the session IDs are removed
  478. // If set to
  479. $sid = $uri->getVar('sid');
  480. if (!$sefConfig->dontRemoveSid) $uri->delVar('sid');
  481. // Ensure that the mosmsg are removed.
  482. $mosmsg = $uri->getVar('mosmsg');
  483. $uri->delVar('mosmsg');
  484. // override Itemid if set to
  485. $override = $params->get('itemid', '0');
  486. $overrideId = $params->get('overrideId', '');
  487. if (($override != '0') && ($overrideId != '')) {
  488. $uri->setVar('Itemid', $overrideId);
  489. }
  490. return array($sid, $mosmsg);
  491. }
  492. /**
  493. * Converts given language sef code to tag (eg. en => en-GB)
  494. * If given language is empty, returns current language tag
  495. */
  496. function getLangCode($sef = '') {
  497. if (empty($sef)) {
  498. $lang = JFactory::getLanguage();
  499. return $lang->getTag();
  500. }
  501. $langs = JLanguageHelper::getLanguages('sef');
  502. if (isset($langs[$sef])) {
  503. return $langs[$sef]->lang_code;
  504. }
  505. return null;
  506. }
  507. function getLanguage($uri) {
  508. $sefConfig =& SEFConfig::getConfig();
  509. if (!$sefConfig->langEnable) {
  510. // Use default language from Joomla or whichever plugin
  511. return;
  512. }
  513. $suffix=$sefConfig->suffix;
  514. $lang="";
  515. $langs=JLanguageHelper::getLanguages('sef');
  516. JFactory::getApplication()->setLanguageFilter(true);
  517. switch($sefConfig->langPlacementJoomla) {
  518. case _COM_SEF_LANG_PATH:
  519. $lang=$uri->getVar('lang');
  520. if(strlen($lang)==0) {
  521. $path=explode("/",ltrim(str_replace($uri->base(true),"",str_replace($suffix,"",$uri->getPath())),"/"));
  522. if(strlen($path[0])<=3) {
  523. $lang=$path[0];
  524. }
  525. }
  526. break;
  527. case _COM_SEF_LANG_DOMAIN:
  528. // 22.2.2012, dajo: simplified and fixed the function
  529. $host = trim($uri->toString(array('host')), "/");
  530. foreach ($sefConfig->subDomainsJoomla as $lng => $domain) {
  531. if ($host == $domain) {
  532. $lang = $lng;
  533. // Save the language code obtained from domain for later use
  534. self::set('domain_lang', $lang);
  535. break;
  536. }
  537. }
  538. break;
  539. }
  540. if(strlen($lang)==0) {
  541. // If is title page
  542. if($uri->getPath()=='/') {
  543. if($sefConfig->langCookieJoomla) {
  544. $lang=JRequest::getString('joomsef_lang','','cookie');
  545. }
  546. if(strlen($lang)==0 || !isset($langs[$lang])) {
  547. if($sefConfig->browserLangJoomla) {
  548. $lang=JLanguageHelper::detectLanguage();
  549. $langsCode = JLanguageHelper::getLanguages('lang_code');
  550. if (isset($langsCode[$lang])) {
  551. $lang = $langsCode[$lang]->sef;
  552. }
  553. }
  554. }
  555. if(strlen($lang)==0 || !isset($langs[$lang])) {
  556. $lang=$sefConfig->mainLanguageJoomla;
  557. }
  558. // If is the main lang ang for main lang is lanuage not in URL
  559. } else {
  560. $lang=$sefConfig->mainLanguageJoomla;
  561. }
  562. }
  563. if(strlen($lang)) {
  564. if (!isset($langs[$lang])) {
  565. $lang = reset(array_keys($langs));
  566. }
  567. $lang_code = $langs[$lang]->lang_code;
  568. $cfg = JFactory::getConfig();
  569. $cfg->set('language', $lang_code);
  570. JRequest::setVar('lang', $lang);
  571. JRequest::setVar('language', $lang_code);
  572. JFactory::getLanguage()->setLanguage($lang_code);
  573. if ($sefConfig->langCookieJoomla && !headers_sent()) {
  574. setcookie('joomsef_lang',$lang,time()+24*60*60*1000,"/");
  575. }
  576. JFactory::getLanguage()->getMetadata($lang_code);
  577. }
  578. }
  579. function parse(&$uri)
  580. {
  581. $sefConfig =& SEFConfig::getConfig();
  582. $langs=JLanguageHelper::getLanguages('sef');
  583. // add base path, as Joomla does not send it but we count on it
  584. $uri->setPath(JURI::base(true) . '/' . $uri->getPath());
  585. $url_query=$uri->getQuery();
  586. $host=explode(".",$uri->getHost());
  587. $subdomain=array_shift($host);
  588. $db=JFactory::getDBO();
  589. // Subdomain titlepage
  590. if(($uri->getPath()==JURI::base(true).'/') && empty($url_query) && empty($_POST)) {
  591. $query=$db->getQuery(true);
  592. $query->select('Itemid_titlepage')->from('#__sef_subdomains');
  593. $query->where('subdomain='.$db->quote($subdomain));
  594. if($sefConfig->langEnable) {
  595. $lang=JRequest::getVar('lang');
  596. $query->where('lang='.$db->quote($lang));
  597. }
  598. $db->setQuery($query, 0, 1);
  599. $Itemid=$db->loadResult();
  600. if($sefConfig->langEnable==1 && $Itemid>0) {
  601. JFactory::getApplication()->redirect($uri->base(true).'/'.$lang, '', 'message', true);
  602. JFactory::getApplication()->close();
  603. } else {
  604. if($Itemid>0) {
  605. $uri->setVar('Itemid',$Itemid);
  606. JoomSEF::set('real_domain', JFactory::getUri()->getHost());
  607. JFactory::getUri()->setHost(implode(".",$host));
  608. }
  609. }
  610. } else if(empty($url_query) && empty($_POST) && $sefConfig->langEnable) {
  611. $query=$db->getQuery(true);
  612. $query->select('Itemid_titlepage')->from('#__sef_subdomains');
  613. $query->where('subdomain='.$db->quote($subdomain));
  614. $lang=JRequest::getVar('lang');
  615. $query->where('lang='.$db->quote($lang));
  616. $db->setQuery($query, 0, 1);
  617. $Itemid=$db->loadResult();
  618. if($Itemid>0) {
  619. $uri->setVar('Itemid',$Itemid);
  620. JoomSEF::set('real_domain', JFactory::getUri()->getHost());
  621. JFactory::getUri()->setHost(implode(".",$host));
  622. }
  623. } else {
  624. $query=$db->getQuery(true);
  625. $query->select('COUNT(*)')->from('#__sef_subdomains')->where('subdomain='.$db->quote($subdomain));
  626. $db->setQuery($query);
  627. $cnt=$db->loadResult();
  628. if($cnt) {
  629. JoomSEF::set('real_domain', JFactory::getUri()->getHost());
  630. JFactory::getUri()->setHost(implode(".",$host));
  631. }
  632. }
  633. // Set Joomla's router so it doesn't process URL further
  634. $mainframe =& JFactory::getApplication();
  635. $jRouter = $mainframe->getRouter();
  636. $jRouter->SetMode(JROUTER_MODE_DONT_PARSE);
  637. // store the old URI before we change it in case we will need it
  638. // for default Joomla SEF
  639. $oldUri = clone $uri;
  640. // load patches
  641. JPluginHelper::importPlugin('sefpatch');
  642. // trigger onSefLoad patches
  643. $mainframe->triggerEvent('onSefLoad');
  644. // get path
  645. $path = $uri->getPath();
  646. // remove basepath
  647. $path = substr_replace($path, '', 0, strlen(JURI::base(true)));
  648. // remove slashes
  649. $path = ltrim($path, '/');
  650. // Redirect URL with / on the end to URL without / on the end
  651. if($sefConfig->redirectSlash) {
  652. $request=$_SERVER["REQUEST_URI"];
  653. if($request!=$uri->base(true)."/" && substr($request,-1)=='/') {
  654. $mainframe->redirect(rtrim($request,"/"),'','message', true);
  655. JFactory::getApplication()->close();
  656. }
  657. }
  658. $request=$_SERVER["REQUEST_URI"];
  659. $route=str_replace($uri->getPath(),'',$request);
  660. $route=str_replace("?".$uri->getQuery(),'',$route);
  661. // Redirect the index.php (need to check this before index.php removal)
  662. if ($sefConfig->fixIndexPhp && ($route == 'index.php') && (count($_POST) == 0)) {
  663. $newUrl = JURI::root();
  664. if (substr($newUrl, -1) != '/') {
  665. $newUrl .= '/';
  666. }
  667. $q = $uri->getQuery();
  668. if (!empty($q)) {
  669. $newUrl .= '?'.$q;
  670. }
  671. $mainframe->redirect($newUrl, '', 'message', true);
  672. exit();
  673. }
  674. // fix Joomla URLs with index.php/
  675. $path = preg_replace('#^index\\.php\\/#i', '', $path);
  676. if($sefConfig->langEnable) {
  677. if($sefConfig->langPlacementJoomla==_COM_SEF_LANG_PATH) {
  678. $query=$uri->getQuery(true);
  679. if(str_replace($uri->base(true),"",$uri->getPath())=='/' && empty($query) && empty($_POST)) {
  680. $home_items=SEFTools::getHomeQueries();
  681. $lang=$langs[JRequest::getVar('lang')]->lang_code;
  682. foreach($home_items as $id=>$item) {
  683. if($item->language==$lang) {
  684. $Itemid=$item->id;
  685. $link=$item->link;
  686. }
  687. }
  688. JFactory::getApplication()->redirect($uri->base(true).'/'.$langs[JRequest::getVar('lang')]->sef, '', 'message', true);
  689. JFactory::getApplication()->close();
  690. }
  691. }
  692. }
  693. // Try the 301 Alias redirect
  694. if (count($_POST) == 0) {
  695. Joomsef::_parseAlias($path, $uri->getQuery(true));
  696. }
  697. // remove prefix (both index.php and index2.php)
  698. //$path = eregi_replace('^index2?.php', '', $path);
  699. $path = preg_replace('/^index2?.php/i', '', $path);
  700. // remove slashes again to be sure there aren't any left
  701. $path = ltrim($path, '/');
  702. // replace spaces with our replacement character
  703. // (mainly for '+' handling, but may be useful in some other situations too)
  704. $path = str_replace(' ', $sefConfig->replacement, $path);
  705. // set the route
  706. $uri->setPath($path);
  707. // parse the url
  708. $vars = JoomSEF::_parseSefUrl($uri, $oldUri);
  709. // handle custom site name for extensions
  710. if (isset($vars['option'])) {
  711. $params =& SEFTools::getExtParams($vars['option']);
  712. $useSitename = $params->get('useSitename', '1');
  713. $customSitename = trim($params->get('customSitename', ''));
  714. $config =& JFactory::getConfig();
  715. if ($useSitename == '0') {
  716. // don't use site name
  717. $config->setValue('sitename', '');
  718. }
  719. elseif (!empty($customSitename)) {
  720. // use custom site name
  721. $config->setValue('sitename', $customSitename);
  722. }
  723. }
  724. // trigger onSefUnload patches
  725. $mainframe->triggerEvent('onSefUnload');
  726. return $vars;
  727. }
  728. function _parseSefUrl(&$uri, &$oldUri)
  729. {
  730. $mainframe =& JFactory::getApplication();
  731. $db =& JFactory::getDBO();
  732. $sefConfig =& SEFConfig::getConfig();
  733. $route = $uri->getPath();
  734. //Get the variables from the uri
  735. $vars = $uri->getQuery(true);
  736. // Should we generate canonical link automatically?
  737. $generateCanonical = (count($vars) > 0);
  738. // handle an empty URL (special case)
  739. if (empty($route) || $route==JRequest::getVar('lang')) {
  740. if (count($vars) > 0) {
  741. $redir = false;
  742. }
  743. else {
  744. $redir = true;
  745. }
  746. $menu =& JSite::getMenu(true);
  747. // TODO: handle metatags for subdomains correctly
  748. // if route is empty AND option is set in the query, assume it's non-sef url, and parse apropriately
  749. if (isset($vars['option']) || isset($vars['Itemid'])) {
  750. return JoomSEF::_parseRawRoute($uri);
  751. }
  752. //$item = $menu->getDefault();
  753. // Workaround until Joomla menu bug will be fixed
  754. $langs=JLanguageHelper::getLanguages('sef');
  755. $items = null;
  756. if (isset($langs[JRequest::getVar('lang')])) {
  757. $items=$menu->getItems(array('home','language'),array('1',$langs[JRequest::getVar('lang')]->lang_code));
  758. }
  759. if (!is_array($items) || (count($items) == 0)) {
  760. $items = $menu->getItems(array('home'), array('1'));
  761. }
  762. $item=$items[0];
  763. //Set the information in the request
  764. $vars = $item->query;
  765. //Get the itemid
  766. $vars['Itemid'] = $item->id;
  767. // Set the active menu item
  768. $menu->setActive($vars['Itemid']);
  769. // Create automatic canonical link if set to
  770. if ($generateCanonical) {
  771. $extAuto = 2;
  772. if (isset($vars['option'])) {
  773. $params =& SEFTools::getExtParams($vars['option']);
  774. $extAuto = $params->get('autoCanonical', 2);
  775. }
  776. $autoCanonical = ($extAuto == 2) ? $sefConfig->autoCanonical : $extAuto;
  777. if ($autoCanonical) {
  778. $mainframe->set('sef.link.canonical', JURI::root());
  779. }
  780. }
  781. // MetaTags for frontpage
  782. if (JPluginHelper::isEnabled('system', 'joomsef')) {
  783. // ... and frontpage has meta tags
  784. // Get all the URLs for frontpage and try to find the correct one
  785. $lang = JRequest::getVar('lang');
  786. $query = "SELECT * FROM #__sefurls WHERE sefurl = ".$db->quote($route)." ORDER BY `priority`";
  787. $db->setQuery($query);
  788. $sefRows = $db->loadObjectList();
  789. if (is_array($sefRows)) {
  790. $count = count($sefRows);
  791. if ($count == 1) {
  792. // Use the only one
  793. $sefRow = $sefRows[0];
  794. }
  795. else if ($count > 1) {
  796. // Loop through URLs and find the one corresponding to menu item and possibly language
  797. foreach ($sefRows as $row) {
  798. // Check if variables match
  799. $varsOk = true;
  800. parse_str(str_replace('index.php?', '', $row->origurl), $rowVars);
  801. foreach ($vars as $varKey => $varVal) {
  802. if ($varKey == 'Itemid') {
  803. if ($row->Itemid != $varVal) {
  804. $varsOk = false;
  805. break;
  806. }
  807. }
  808. else {
  809. if (!isset($rowVars[$varKey]) || ($rowVars[$varKey] != $varVal)) {
  810. $varsOk = false;
  811. break;
  812. }
  813. }
  814. }
  815. if (!$varsOk) {
  816. continue;
  817. }
  818. // Variables match, this seems to be home page URL, try checking language
  819. if (is_null($lang)) {
  820. // No language, use this URL
  821. $sefRow = $row;
  822. break;
  823. }
  824. else {
  825. // Check language
  826. if (isset($rowVars['lang'])) {
  827. if ($rowVars['lang'] == $lang) {
  828. // Found exact URL
  829. $sefRow = $row;
  830. break;
  831. }
  832. }
  833. else if (empty($noLang)) {
  834. // This URL doesn't contain lang variable, store it for later use
  835. $noLang = $row;
  836. }
  837. }
  838. }
  839. // If we didn't find correct URL, try to use the one without lang variable
  840. if (empty($sefRow) && !empty($noLang)) {
  841. $sefRow = $noLang;
  842. }
  843. }
  844. }
  845. // Set meta tags
  846. if( !empty($sefRow) ) {
  847. $mainframe =& JFactory::getApplication();
  848. if (!empty($sefRow->metatitle)) $mainframe->set('sef.meta.title', $sefRow->metatitle);
  849. if (!empty($sefRow->metadesc)) $mainframe->set('sef.meta.desc', $sefRow->metadesc);
  850. if (!empty($sefRow->metakey)) $mainframe->set('sef.meta.key', $sefRow->metakey);
  851. if (!empty($sefRow->metalang)) $mainframe->set('sef.meta.lang', $sefRow->metalang);
  852. if (!empty($sefRow->metarobots)) $mainframe->set('sef.meta.robots', $sefRow->metarobots);
  853. if (!empty($sefRow->metagoogle)) $mainframe->set('sef.meta.google', $sefRow->metagoogle);
  854. if (!empty($sefRow->canonicallink)) $mainframe->set('sef.link.canonical', $sefRow->canonicallink);
  855. if (isset($sefRow->showsitename)) $mainframe->set('sef.meta.showsitename', $sefRow->showsitename);
  856. }
  857. }
  858. return $vars;
  859. }
  860. $disabled = false;
  861. $sef_ext = new SefExt();
  862. $newVars = $sef_ext->revert($route, $disabled);
  863. // We need to determine language BEFORE Joomla SEO
  864. // so the menu is translated correctly
  865. $lang = self::get('domain_lang');
  866. if (empty($lang)) {
  867. $lang = (isset($newVars['lang']) ? $newVars['lang'] : (isset($vars['lang']) ? $vars['lang'] : null));
  868. }
  869. else if ($sefConfig->wrongDomainHandling != _COM_SEF_WRONG_DOMAIN_DO_NOTHING) {
  870. // We have a language from domain, check if it corresponds to language in SEF URL
  871. if (isset($newVars['lang']) && ($newVars['lang'] != $lang)) {
  872. // Domain and SEF URL languages don't match
  873. if ($sefConfig->wrongDomainHandling == _COM_SEF_WRONG_DOMAIN_REDIRECT) {
  874. // Redirect to correct domain
  875. if (isset($sefConfig->subDomainsJoomla[$newVars['lang']])) {
  876. $domain = $sefConfig->subDomainsJoomla[$newVars['lang']];
  877. $redir = JURI::getInstance();
  878. $redir->setHost($domain);
  879. // Redirect
  880. $mainframe =& JFactory::getApplication();
  881. $mainframe->redirect($redir->toString(), '', 'message', true);
  882. exit();
  883. }
  884. // No domain found, show 404
  885. $disabled = true;
  886. }
  887. else {
  888. // Show 404 page
  889. $disabled = true;
  890. }
  891. }
  892. }
  893. if (!empty($newVars) && !empty($vars) && $sefConfig->nonSefQueryVariables) {
  894. // If this was SEF url, consider the vars in query as nonsef
  895. $nonsef = array_diff_key($vars, $newVars);
  896. if (!empty($nonsef)) {
  897. $mainframe->set('sef.global.nonsefvars', $nonsef);
  898. }
  899. }
  900. // try to parse joomla native seo
  901. if ($sefConfig->parseJoomlaSEO && empty($newVars)) {
  902. $oldUrl = $oldUri->toString(array('path', 'query', 'fragment'));
  903. $router = $mainframe->getRouter();
  904. $router->setMode(JROUTER_MODE_SEF);
  905. $jvars = $router->parse($oldUri);
  906. $router->setMode(JROUTER_MODE_DONT_PARSE);
  907. // Check 404
  908. if (isset($jvars['option']) && ($jvars['option'] == 'com_content') &&
  909. isset($jvars['view']) &&
  910. isset($jvars['id']) && ($jvars['id'] == 0))
  911. {
  912. // 404
  913. $jvars = array();
  914. }
  915. if (!empty($jvars['option']) || !empty($jvars['Itemid'])) {
  916. // Fix Itemid
  917. if (array_key_exists('Itemid', $jvars) && is_null($jvars['Itemid'])) {
  918. unset($jvars['Itemid']);
  919. }
  920. // Try to get option from URL or menu item
  921. if (!isset($jvars['option'])) {
  922. // Get the option from menu item
  923. $menu =& JSite::getMenu(true);
  924. $item =& $menu->getItem($jvars['Itemid']);
  925. if (!is_null($item) && isset($item->query['option']))
  926. {
  927. $jopt = $item->query['option'];
  928. }
  929. }
  930. else {
  931. $jopt = $jvars['option'];
  932. }
  933. // Was it possible to retrieve component?
  934. if (isset($jopt)) {
  935. // If the component is not handled by default Joomla router
  936. // try to find corresponding SEF URL in JoomSEF's database
  937. require_once(JPATH_ADMINISTRATOR.DS.'components'.DS.'com_sef'.DS.'models'.DS.'extensions.php');
  938. $handler = SEFModelExtensions::_getActiveHandler($jopt);
  939. if (!in_array($handler->code, array(_COM_SEF_HANDLER_ROUTER, _COM_SEF_HANDLER_JOOMLA, _COM_SEF_HANDLER_NONE))) {
  940. // Try to get the SEF URL
  941. $oldDisable = $sefConfig->disableNewSEF;
  942. $sefConfig->disableNewSEF = true;
  943. $jUri = new JURI('index.php');
  944. $jUri->setQuery($jvars);
  945. if ($jUri->getVar('format') == 'html') {
  946. $jUri->delVar('format');
  947. }
  948. $jUrl = $jUri->toString(array('path', 'query', 'fragment'));
  949. $jSefUri = new JURI(JRoute::_($jUrl));
  950. $jSef = $jSefUri->toString(array('path', 'query', 'fragment'));
  951. //$jSef = urldecode(str_replace('&amp;', '&', $jSef));
  952. // Remove base
  953. $base = JURI::base(true);
  954. $baseLen = strlen($base);
  955. if (substr($oldUrl, 0, $baseLen) == $base) {
  956. $oldUrl = substr($oldUrl, $baseLen);
  957. }
  958. if (substr($jSef, 0, $baseLen) == $base) {
  959. $jSef = substr($jSef, $baseLen);
  960. }
  961. // Fix slashes - left
  962. $oldUrl = ltrim($oldUrl, '/');
  963. $jSef = ltrim($jSef, '/');
  964. // Fix slashes - right
  965. //$oldUrl = preg_replace('/^([^?]*)\/(\??)/', '$1$2', $oldUrl);
  966. //$jSef = preg_replace('/^([^?]*)\/(\??)/', '$1$2', $jSef);
  967. $oldUrl = JoomSEF::_removeRightSlash($oldUrl);
  968. $jSef = JoomSEF::_removeRightSlash($jSef);
  969. // Restore the configuration
  970. $sefConfig->disableNewSEF = $oldDisable;
  971. if (count($_POST) == 0) {
  972. // Non-SEF redirect
  973. if ((strpos($jSef, 'index.php?') === false) && ($oldUrl != $jSef)) {
  974. // Seems the URL is SEF, let's redirect
  975. $mainframe =& JFactory::getApplication();
  976. $mainframe->redirect(JURI::root() . $jSef, '', 'message', true);
  977. $mainframe->close();
  978. }
  979. }
  980. }
  981. // OK, we can show the page for this component
  982. $newVars = $jvars;
  983. }
  984. }
  985. }
  986. if (!empty($vars)) {
  987. // append the original query string because some components
  988. // (like SMF Bridge and SOBI2) use it
  989. $vars = array_merge($vars, $newVars);
  990. } else {
  991. $vars = $newVars;
  992. }
  993. if (empty($newVars)==false && $disabled==false) {
  994. // Parsed correctly and enabled
  995. JoomSEF::_sendHeader('HTTP/1.0 200 OK');
  996. // Create automatic canonical link if set to and it is not already set

Large files files are truncated, but you can click here to view the full file