PageRenderTime 69ms CodeModel.GetById 20ms RepoModel.GetById 1ms 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
  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
  997. $canonical = $mainframe->get('sef.link.canonical');
  998. if ($generateCanonical && empty($canonical)) {
  999. $extAuto = 2;
  1000. if (isset($vars['option'])) {
  1001. $params =& SEFTools::getExtParams($vars['option']);
  1002. $extAuto = $params->get('autoCanonical', 2);
  1003. }
  1004. $autoCanonical = ($extAuto == 2) ? $sefConfig->autoCanonical : $extAuto;
  1005. if ($autoCanonical) {
  1006. $mainframe->set('sef.link.canonical', JURI::root().$route);
  1007. }
  1008. }
  1009. }
  1010. else
  1011. {
  1012. // set nonsef vars
  1013. if (!$disabled) {
  1014. $mainframe->set('sef.global.nonsefvars', $vars);
  1015. }
  1016. // bad URL, so check to see if we've seen it before
  1017. // 404 recording (only if enabled)
  1018. if ($sefConfig->record404) {
  1019. $query = "SELECT * FROM `#__sefurls` WHERE `sefurl` = '".$route."'";
  1020. $db->setQuery($query);
  1021. $results = $db->loadObjectList();
  1022. if ($results) {
  1023. // we have it, so update counter
  1024. $db->setQuery("UPDATE `#__sefurls` SET `cpt`=(`cpt`+1) WHERE `sefurl` = '".$route."'");
  1025. $db->query();
  1026. }
  1027. else {
  1028. // get trace info
  1029. if (@$sefConfig->trace) {
  1030. $traceinfo = "'" . mysql_escape_string(JoomSEF::_getDebugInfo($sefConfig->traceLevel, true)) . "'";
  1031. }
  1032. else $traceinfo = "NULL";
  1033. // record the bad URL
  1034. $query = "INSERT INTO `#__sefurls` (`cpt`, `sefurl`, `origurl`, `trace`, `dateadd`) "
  1035. . " VALUES ( '1', '$route', '', {$traceinfo}, CURDATE() )";
  1036. $db->setQuery($query);
  1037. $db->query();
  1038. }
  1039. }
  1040. // redirect to the error page
  1041. $vars = JoomSEF::_get404vars($route);
  1042. }
  1043. // Set QUERY_STRING if set to
  1044. if ($sefConfig->setQueryString) {
  1045. $qs = array();
  1046. foreach ($vars as $name => $val) {
  1047. if (is_array($val)) {
  1048. foreach ($val as $k => $v) {
  1049. $qs[] = $name . '[' . $k . ']=' . urlencode($v);
  1050. }
  1051. }
  1052. else {
  1053. $qs[] = $name . '=' . urlencode($val);
  1054. }
  1055. }
  1056. $qs = implode('&', $qs);
  1057. if (!empty($qs)) {
  1058. $_SERVER['QUERY_STRING'] = $qs;
  1059. }
  1060. }
  1061. return $vars;
  1062. }
  1063. function _removeRightSlash($url)
  1064. {
  1065. if (strpos($url, '?') === false) {
  1066. // No question mark
  1067. return rtrim($url, '/');
  1068. }
  1069. // Check slash before question mark
  1070. $qpos = strpos($url, '/?');
  1071. if ($qpos !== false) {
  1072. /*$spos = strpos($url, '/');
  1073. if ($qpos <= $spos) {
  1074. $url = substr($url, 0, $qpos).substr($url, $qpos+1);
  1075. }*/
  1076. $url = substr($url, 0, $qpos).substr($url, $qpos+1);
  1077. }
  1078. return $url;
  1079. }
  1080. function _get404vars($route = '')
  1081. {
  1082. $mainframe =& JFactory::getApplication();
  1083. $db =& JFactory::getDBO();
  1084. $sefConfig =& SEFConfig::getConfig();
  1085. // you MUST create a static content page with the title 404 for this to work properly
  1086. if ($sefConfig->showMessageOn404) {
  1087. $mosmsg = 'FILE NOT FOUND: '.$route;
  1088. $mainframe->enqueueMessage($mosmsg);
  1089. }
  1090. else $mosmsg = '';
  1091. if ($sefConfig->page404 == '0') {
  1092. $sql = 'SELECT `id` FROM `#__content` WHERE `title`= "404"';
  1093. $db->setQuery($sql);
  1094. if (($id = $db->loadResult())) {
  1095. $vars['option'] = 'com_content';
  1096. $vars['view'] = 'article';
  1097. $vars['id'] = $id;
  1098. }
  1099. else {
  1100. die(JText::_('COM_SEF_ERROR_DEFAULT_404').$mosmsg."<br />URI:".$_SERVER['REQUEST_URI']);
  1101. }
  1102. }
  1103. elseif ($sefConfig->page404 == '9999999') {
  1104. $menu =& JSite::getMenu(true);
  1105. //$item = $menu->getDefault();
  1106. // Workaround until Joomla menu bug will be fixed
  1107. $items=$menu->getItems(array('home','language'),array('1','*'));
  1108. $item=$items[0];
  1109. //Set the information in the frontpage request
  1110. $vars = $item->query;
  1111. //Get the itemid
  1112. $vars['Itemid'] = $item->id;
  1113. $menu->setActive($vars['Itemid']);
  1114. }
  1115. else {
  1116. $id = $sefConfig->page404;
  1117. $vars['option'] = 'com_content';
  1118. $vars['view'] = 'article';
  1119. $vars['id'] = $id;
  1120. }
  1121. // If custom Itemid set, use it
  1122. if ($sefConfig->use404itemid) {
  1123. $vars['Itemid'] = $sefConfig->itemid404;
  1124. }
  1125. JoomSEF::_sendHeader('HTTP/1.0 404 NOT FOUND');
  1126. return $vars;
  1127. }
  1128. function _parseAlias($route, &$vars)
  1129. {
  1130. $db =& JFactory::getDBO();
  1131. $sefConfig =& SEFConfig::getConfig();
  1132. $route = html_entity_decode(urldecode($route));
  1133. // Get all the corresponding aliases
  1134. $query = "SELECT `a`.`vars`, `u`.`sefurl` FROM `#__sefaliases` AS `a` INNER JOIN `#__sefurls` AS `u` ON `u`.`id` = `a`.`url` WHERE `a`.`alias` = " . $db->Quote($route);
  1135. $db->setQuery($query);
  1136. $aliases = $db->loadObjectList();
  1137. // Are there any aliases?
  1138. if (!is_array($aliases) || (count($aliases) == 0)) {
  1139. return;
  1140. }
  1141. // Try to find alias with corresponding variables
  1142. foreach ($aliases as $alias) {
  1143. // Create the array of alias variables
  1144. $avars = array();
  1145. $alias->vars = trim($alias->vars);
  1146. if (!empty($alias->vars)) {
  1147. $tmpvars = explode("\n", $alias->vars);
  1148. foreach($tmpvars as $tmpvar) {
  1149. list($vname, $vvalue) = explode('=', $tmpvar);
  1150. $avars[$vname] = urldecode($vvalue);
  1151. }
  1152. }
  1153. // Check the variables count
  1154. if (count($avars) != count($vars)) {
  1155. continue;
  1156. }
  1157. // Check all the variables
  1158. $ok = true;
  1159. foreach ($vars as $name => $value) {
  1160. if (!isset($avars[$name]) || ($avars[$name] != $value)) {
  1161. $ok = false;
  1162. break;
  1163. }
  1164. }
  1165. if (!$ok) {
  1166. continue;
  1167. }
  1168. // Correct alias found, redirect
  1169. $mainframe =& JFactory::getApplication();
  1170. $url = JURI::root();
  1171. if (substr($url, -1) != '/') {
  1172. $url .= '/';
  1173. }
  1174. $url .= ltrim($alias->sefurl, '/');
  1175. $mainframe->redirect($url, '', 'message', true);
  1176. $mainframe->close();
  1177. }
  1178. }
  1179. function _sendHeader($header)
  1180. {
  1181. if (!headers_sent()) {
  1182. //file_put_contents(JPATH_SITE.DS.'tmp'.DS.'header',$header."\n",FILE_APPEND);
  1183. header($header);
  1184. }
  1185. // 25.4.2012 dajo: Don't die when headers already sent
  1186. // else {
  1187. // JoomSEF::_headers_sent_error($f, $l, __FILE__, __LINE__);
  1188. //}
  1189. }
  1190. function _parseRawRoute(&$uri)
  1191. {
  1192. $sefConfig =& SEFConfig::getConfig();
  1193. if( is_null($uri->getVar('option')) ) {
  1194. // Set the URI from Itemid
  1195. $menu =& JSite::getMenu(true);
  1196. $item = $menu->getItem($uri->getVar('Itemid'));
  1197. if( !is_null($item) ) {
  1198. $uri->setQuery($item->query);
  1199. $uri->setVar('Itemid', $item->id);
  1200. }
  1201. }
  1202. $extAuto = 2;
  1203. if (isset($params)) {
  1204. $extAuto = $params->get('autoCanonical', 2);
  1205. }
  1206. $autoCanonical = ($extAuto == 2) ? $sefConfig->autoCanonical : $extAuto;
  1207. if (($sefConfig->nonSefRedirect && (count($_POST) == 0)) || $autoCanonical)
  1208. {
  1209. // Try to find the non-SEF URL in the database - don't create new!
  1210. $oldDisable = $sefConfig->disableNewSEF;
  1211. $sefConfig->disableNewSEF = true;
  1212. $uri->setPath('index.php');
  1213. $url = $uri->toString(array('path', 'query', 'fragment'));
  1214. $sef = JRoute::_($url);
  1215. // Revert, otherwise Joomla in its router thinks this is SEF URL,
  1216. // because its path is not empty!
  1217. $uri->setPath('');
  1218. // Restore the configuration
  1219. $sefConfig->disableNewSEF = $oldDisable;
  1220. if ($sefConfig->nonSefRedirect && (count($_POST) == 0)) {
  1221. // Non-SEF redirect
  1222. if( strpos($sef, 'index.php?') === false ) {
  1223. // Check if it's different from current URL
  1224. $curUri = JURI::getInstance();
  1225. if ($sef[0] == '/') {
  1226. $curUrl = $curUri->toString(array('path', 'query', 'fragment'));
  1227. }
  1228. else {
  1229. $curUrl = MyURI::getURI($curUri);
  1230. }
  1231. // Fix the &amp; characters
  1232. $sef = str_replace('&amp;', '&', $sef);
  1233. if ($sef != $curUrl) {
  1234. // Seems the URL is SEF, let's redirect
  1235. $mainframe =& JFactory::getApplication();
  1236. $mainframe->redirect($sef, '', 'message', true);
  1237. $mainframe->close();
  1238. }
  1239. }
  1240. }
  1241. else if ($autoCanonical) {
  1242. // Only set canonical URL
  1243. $mainframe =& JFactory::getApplication();
  1244. // Remove the query part from SEF URL
  1245. $pos = strpos($sef, '?');
  1246. if ($pos !== false) {
  1247. $sef = substr($sef, 0, $pos);
  1248. }
  1249. $mainframe->set('sef.link.canonical', $sef);
  1250. }
  1251. }
  1252. return $uri->getQuery(true);
  1253. }
  1254. // 25.4.2012 dajo: removed
  1255. //function _headers_sent_error($sentFile, $sentLine, $file, $line)
  1256. //{
  1257. // die("<br />Error: headers already sent in ".basename($sentFile)." on line $sentLine.<br />Stopped at line ".$line." in ".basename($file));
  1258. //}
  1259. function & _createUri(&$uri)
  1260. {
  1261. $url = JURI::root();
  1262. $path=JURI::root(true);
  1263. if( substr($url, -1) != '/' ) {
  1264. $url .= '/';
  1265. }
  1266. $url .= $uri->toString(array('path', 'query', 'fragment'));
  1267. $newUri = new JURI($url);
  1268. $path=str_replace($path,"",$newUri->getPath());
  1269. $newUri->setPath($path);
  1270. return $newUri;
  1271. }
  1272. function _endSef($lang = '')
  1273. {
  1274. $mainframe =& JFactory::getApplication();
  1275. $mainframe->triggerEvent('onSefEnd');
  1276. JoomSEF::_restoreLang($lang);
  1277. }
  1278. function _restoreLang($lang = '')
  1279. {
  1280. if ($lang != '') {
  1281. if ($lang != JoomSEF::getLangCode()) {
  1282. $language = JFactory::getLanguage();
  1283. $language->setLanguage($lang);
  1284. $language->load();
  1285. }
  1286. }
  1287. }
  1288. function _isHomePage(&$uri, $altered = false)
  1289. {
  1290. $home_items=SEFTools::getHomeQueries();
  1291. $langs=JLanguageHelper::getLanguages('lang_code');
  1292. $config=SEFConfig::getConfig();
  1293. $Itemid = $uri->getVar('Itemid');
  1294. if(array_key_exists($Itemid,$home_items) && $uri->getPath()=='index.php') {
  1295. if($config->langEnable) {
  1296. if (strlen($uri->getVar('lang', '')) == 0) {
  1297. $langTag = $home_items[$Itemid]->language;
  1298. if (isset($langs[$langTag])) {
  1299. $uri->setVar('lang', $langs[$langTag]->sef);
  1300. }
  1301. else {
  1302. // Use current language
  1303. $langTag = JFactory::getLanguage()->getTag();
  1304. if (isset($langs[$langTag])) {
  1305. $uri->setVar('lang', $langs[$langTag]->sef);
  1306. }
  1307. }
  1308. }
  1309. }
  1310. // Set the link queries if not already there
  1311. if (!isset($home_items[$Itemid]->linkQuery)) {
  1312. $link = new JURI($home_items[$Itemid]->link);
  1313. $home_items[$Itemid]->linkQuery = $link->getQuery(true);
  1314. $home_items[$Itemid]->normalizedQuery = null;
  1315. // Normalize query if an extension is available
  1316. $option = $link->getVar('option');
  1317. if (!is_null($option)) {
  1318. $extFile = JPATH_ROOT.DS.'components'.DS.'com_sef'.DS.'sef_ext'.DS.$option.'.php';
  1319. if (file_exists($extFile)) {
  1320. $class = 'SefExt_'.$option;
  1321. if (!class_exists($class)) {
  1322. require($extFile);
  1323. }
  1324. $sef_ext = new $class();
  1325. $link->setVar('Itemid', $Itemid);
  1326. $sef_ext->beforeCreate($link);
  1327. $link->delVar('Itemid');
  1328. $link->delVar('lang');
  1329. $home_items[$Itemid]->normalizedQuery = $link->getQuery(true);
  1330. $sef_ext = null;
  1331. }
  1332. }
  1333. }
  1334. // The queries need to match 1:1 (except Itemid and lang(?)), not just the variables present in home item!
  1335. $uriQuery = $uri->getQuery(true);
  1336. if (array_key_exists('Itemid', $uriQuery)) unset($uriQuery['Itemid']);
  1337. if (array_key_exists('lang', $uriQuery)) unset($uriQuery['lang']);
  1338. // Check base link
  1339. $same = ($uriQuery == $home_items[$Itemid]->linkQuery);
  1340. if (!$same && is_array($home_items[$Itemid]->normalizedQuery)) {
  1341. // Check normalized link
  1342. $same = ($uriQuery == $home_items[$Itemid]->normalizedQuery);
  1343. }
  1344. return $same;
  1345. }
  1346. return false;
  1347. }
  1348. function _getMenuTitle($option, $lang, $id = null, $string = null)
  1349. {
  1350. return self::_getMenuTitleLang($option, $lang, $id, $string);
  1351. }
  1352. function _getMenuTitleLang($option, &$lang, $id = null, $string = null)
  1353. {
  1354. $db =& JFactory::getDBO();
  1355. $sefConfig =& SEFConfig::getConfig();
  1356. if ($title = JoomSEF::_getCustomMenuTitle($option)) {
  1357. return $title;
  1358. }
  1359. // Which column to use?
  1360. $column = 'title';
  1361. if ($sefConfig->useAlias) {
  1362. $column = 'alias';
  1363. }
  1364. // Translate URLs?
  1365. if ($sefConfig->translateItems) {
  1366. $jfTranslate = '`id`, ';
  1367. }
  1368. else {
  1369. $jfTranslate = '';
  1370. }
  1371. if (isset($string)) {
  1372. $sql = "SELECT {$jfTranslate}`$column` AS `name`, `language` FROM `#__menu` WHERE `link` = '$string' AND `published` > 0";
  1373. }
  1374. elseif (isset($id) && $id != 0) {
  1375. $sql = "SELECT {$jfTranslate}`$column` AS `name`, `language` FROM `#__menu` WHERE `id` = '$id' AND `published` > 0";
  1376. }
  1377. else {
  1378. // Search for direct link to component only
  1379. $sql = "SELECT {$jfTranslate}`$column` AS `name`, `language` FROM `#__menu` WHERE `link` = 'index.php?option=$option' AND `published` > 0";
  1380. }
  1381. $db->setQuery($sql);
  1382. $row = $db->loadObject();
  1383. if ($row && !empty($row->name)) {
  1384. $title = $row->name;
  1385. $lang = $row->language;
  1386. }
  1387. else {
  1388. $title = str_replace('com_', '', $option);
  1389. if (!isset($string) && !isset($id)) {
  1390. // Try to extend the search for any link to component
  1391. $sql = "SELECT {$jfTranslate}`$column` AS `name`, `language` FROM `#__menu` WHERE `link` LIKE 'index.php?option=$option%' AND `published` > 0";
  1392. $db->setQuery($sql);
  1393. $row = $db->loadObject();
  1394. if (!empty($row)) {
  1395. if (!empty($row->name)) $title = $row->name;
  1396. $lang = $row->language;
  1397. }
  1398. }
  1399. }
  1400. return $title;
  1401. }
  1402. function _getMenuItemInfo($option, $task, $id = null, $string = null)
  1403. {
  1404. $db =& JFactory::getDBO();
  1405. $sefConfig =& SEFConfig::getConfig();
  1406. // JF translate extension.
  1407. $jfTranslate = $sefConfig->translateNames ? ', `id`' : '';
  1408. $item->title = JoomSEF::_getCustomMenuTitle($option);
  1409. // Which column to use?
  1410. $column = 'title';
  1411. if ($sefConfig->useAlias) $column = 'alias';
  1412. // first test Itemid
  1413. if (isset($id) && $id != 0) {
  1414. $sql = "SELECT `$column` AS `name`, `params`$jfTranslate FROM `#__menu` WHERE `id` = $id AND `published` > 0";
  1415. }
  1416. elseif (isset($string)) {
  1417. $sql = "SELECT `$column`AS `name`, `params` $jfTranslate FROM `#__menu` WHERE `link` = '$string' AND `published` > 0";
  1418. }
  1419. else {
  1420. // Search for direct link to component only
  1421. $sql = "SELECT `$column` AS `name`, `params` $jfTranslate FROM `#__menu` WHERE `link` = 'index.php?option=$option' AND `published` > 0";
  1422. }
  1423. $db->setQuery($sql);
  1424. $row = $db->loadObject();
  1425. if (!empty($row)) {
  1426. if (!empty($row->name) && !$item->title) $item->title = $row->name;
  1427. $item->params = new JParameter($row->params);
  1428. }
  1429. else {
  1430. $item->title = str_replace('com_', '', $option);
  1431. if (!isset($string) && !isset($id)) {
  1432. // Try to extend the search for any link to component
  1433. $sql = "SELECT `$column`, `params` AS `name`$jfTranslate FROM `#__menu` WHERE `link` LIKE 'index.php?option=$option%' AND `published` > 0";
  1434. $db->setQuery($sql);
  1435. $row = $db->loadObject();
  1436. if (!empty($row)) {
  1437. if (!empty($row->name) && !$item->title) $item->title = $row->name;
  1438. $item->params = new JParameter($row->params);
  1439. }
  1440. }
  1441. }
  1442. return $item;
  1443. }
  1444. function _getCustomMenuTitle($option)
  1445. {
  1446. $db =& JFactory::getDBO();
  1447. $sefConfig =& SEFConfig::getConfig();
  1448. $lang=JFactory::getConfig()->get('language');
  1449. $element=str_replace('com_','ext_joomsef4_',$option);
  1450. static $titles;
  1451. $jfTranslate = $sefConfig->translateNames ? ', `id`' : '';
  1452. if( !isset($titles) ) {
  1453. $titles = array();
  1454. }
  1455. if( !isset($titles[$lang]) ) {
  1456. $titles[$lang] = array();
  1457. $query=$db->getQuery(true);
  1458. $query->select('params, element')->from('#__extensions')->where('state>=0')->where('enabled=1')->where('type='.$db->quote('sef_ext'));
  1459. $db->setQuery($query);
  1460. $data = $db->loadObjectList();
  1461. foreach ($data as $val) {
  1462. $params = new JRegistry($val->params);
  1463. $titles[$lang][$val->element] = $params->get('customMenuTitle');
  1464. }
  1465. }
  1466. if (isset($titles[$lang][$element])) {
  1467. return $titles[$lang][$element];
  1468. }
  1469. return null;
  1470. }
  1471. /**
  1472. * Convert title to URL name.
  1473. *
  1474. * @param string $title
  1475. * @return string
  1476. */
  1477. function _titleToLocation(&$title)
  1478. {
  1479. $sefConfig =& SEFConfig::getConfig();
  1480. // remove accented characters
  1481. // $title = strtr($title,
  1482. // replace non-ASCII characters.
  1483. $title = strtr($title, $sefConfig->getReplacements());
  1484. // remove quotes, spaces, and other illegal characters
  1485. if( $sefConfig->allowUTF ) {
  1486. $title = preg_replace(array('/\'/', '/[\s"\?\:\/\\\\]/', '/(^_|_$)/'), array('', $sefConfig->replacement, ''), $title);
  1487. }
  1488. else {
  1489. $title = preg_replace(array('/\'/', '/[^a-zA-Z0-9\-!.,+]+/', '/(^_|_$)/'), array('', $sefConfig->replacement, ''), $title);
  1490. }
  1491. // Handling lower case
  1492. if( $sefConfig->lowerCase ) {
  1493. $title = JoomSEF::_toLowerCase($title);
  1494. }
  1495. return $title;
  1496. }
  1497. /**
  1498. * Tries to correctly handle conversion to lowercase even for UTF-8 string
  1499. *
  1500. * @param unknown_type $str
  1501. */
  1502. function _toLowerCase($str)
  1503. {
  1504. $sefConfig =& SEFConfig::getConfig();
  1505. if( $sefConfig->allowUTF ) {
  1506. if( function_exists('mb_convert_case') ) {
  1507. $str = mb_convert_case($str, MB_CASE_LOWER, 'UTF-8');
  1508. }
  1509. }
  1510. else {
  1511. $str = strtolower($str);
  1512. }
  1513. return $str;
  1514. }
  1515. function _utf8LowerCase($str)
  1516. {
  1517. if( function_exists('mb_convert_case') ) {
  1518. $str = mb_convert_case($str, MB_CASE_LOWER, 'UTF-8');
  1519. }
  1520. else {
  1521. $str = strtolower($str);
  1522. }
  1523. return $str;
  1524. }
  1525. /**
  1526. * Stores the given parameters in an array and returns it
  1527. *
  1528. * @param JURI $uri
  1529. * @param array $title
  1530. * @param string $task
  1531. * @param int $limit
  1532. * @param int $limitstart
  1533. * @param string $lang
  1534. * @param array $nonSefVars
  1535. * @param array $ignoreSefVars
  1536. * @param array $metadata List of metadata to be stored. (metakeywords, metadesc, ..., canonicallink)
  1537. * @param boolean $priority
  1538. * @param boolean $pageHandled Set to true if the extension handles its pagination on its own
  1539. * @return string
  1540. */
  1541. function _sefGetLocation(&$uri, &$title, $task = null, $limit = null, $limitstart = null, $lang = null, $nonSefVars = null, $ignoreSefVars = null, $metadata = null, $priority = null, $pageHandled = false,$host=null, $sitemapParams = null)
  1542. {
  1543. $data = compact('uri', 'title', 'task', 'limit', 'limitstart', 'lang', 'nonSefVars', 'ignoreSefVars', 'metadata', 'priority', 'pageHandled', 'host', 'sitemapParams');
  1544. return $data;
  1545. }
  1546. /**
  1547. * Find existing or create new SEO URL.
  1548. *
  1549. * @param array $data
  1550. * @return string
  1551. */
  1552. function _storeLocation(&$data,$check=false)
  1553. {
  1554. $mainframe =& JFactory::getApplication();
  1555. $db =& JFactory::getDBO();
  1556. $sefConfig =& SEFConfig::getConfig();
  1557. $cache =& SEFCache::getInstance();
  1558. // Extract variables
  1559. $defaults = array('uri' => null, 'title' => null, 'task' => null, 'limit' => null, 'limitstart' => null, 'lang' => null, 'nonSefVars' => null, 'ignoreSefVars' => null, 'metadata' => null, 'priority' => null, 'pageHandled' => false,'host'=>false, 'sitemapParams' => null);
  1560. foreach ($defaults as $varName => $value) {
  1561. if (is_array($data) && isset($data[$varName])) {
  1562. $$varName = $data[$varName];
  1563. }
  1564. else {
  1565. $$varName = $value;
  1566. }
  1567. }
  1568. $origUri = clone($uri);
  1569. // Get the default priority if not set
  1570. if( is_null($priority) ) {
  1571. $priority = JoomSEF::_getPriorityDefault($uri);
  1572. }
  1573. // Get the parameters for this component
  1574. if( !is_null($uri->getVar('option')) ) {
  1575. $params =& SEFTools::getExtParams($uri->getVar('option'));
  1576. }
  1577. // remove the menu title if set to for this component
  1578. if( isset($params) && ($params->get('showMenuTitle', '1') == '0') ) {
  1579. if ((count($title) > 1) &&
  1580. ((count($title) != 2) || ($title[1] != '/')) &&
  1581. ($title[0] == JoomSEF::_getMenuTitle(@$uri->getVar('option'), @$uri->getVar('task'), @$uri->getVar('Itemid')))) {
  1582. array_shift($title);
  1583. }
  1584. }
  1585. // add the page number if the extension does not handle it
  1586. if( !$pageHandled && !is_null($uri->getVar('limitstart')) ) {
  1587. $limit = $uri->getVar('limit');
  1588. if( is_null($limit) ) {
  1589. if( !is_null($uri->getVar('option')) ) {
  1590. $limit = intval($params->get('pageLimit', ''));
  1591. if( $limit == 0 ) {
  1592. $limit = 5;
  1593. }
  1594. }
  1595. else {
  1596. $limit = 5;
  1597. }
  1598. }
  1599. $pageNum = intval($uri->getVar('limitstart') / $limit) + 1;
  1600. $pagetext = strval($pageNum);
  1601. if (($cnfPageText = $sefConfig->getPageText())) {
  1602. $pagetext = str_replace('%s', $pageNum, $cnfPageText);
  1603. }
  1604. $title[] = $pagetext;
  1605. }
  1606. // get all the titles ready for urls.
  1607. $location = array();
  1608. foreach ($title as $titlePart) {
  1609. if (strlen($titlePart) == 0) continue;
  1610. $location[] = JoomSEF::_titleToLocation($titlePart);
  1611. }
  1612. // remove unwanted characters.
  1613. $finalstrip = explode('|', $sefConfig->stripthese);
  1614. $takethese = str_replace('|', '', $sefConfig->friendlytrim);
  1615. if (strstr($takethese, $sefConfig->replacement) === FALSE) {
  1616. $takethese .= $sefConfig->replacement;
  1617. }
  1618. $imptrim = implode('/', $location);
  1619. if (!is_null($task)) {
  1620. $task = str_replace($sefConfig->replacement.'-'.$sefConfig->replacement, $sefConfig->replacement, $task);
  1621. $task = str_replace($finalstrip, '', $task);
  1622. $task = trim($task,$takethese);
  1623. }
  1624. $imptrim = str_replace($sefConfig->replacement.'-'.$sefConfig->replacement, $sefConfig->replacement, $imptrim);
  1625. $suffixthere = 0;
  1626. $regexSuffix = str_replace('.', '\.', $sefConfig->suffix);
  1627. $pregSuffix = addcslashes($regexSuffix, '/');
  1628. //if (eregi($regexSuffix.'$', $imptrim)) {
  1629. if (preg_match('/'.$pregSuffix.'$/i', $imptrim)) {
  1630. $suffixthere = strlen($sefConfig->suffix);
  1631. }
  1632. $imptrim = str_replace($finalstrip, $sefConfig->replacement, substr($imptrim, 0, strlen($imptrim) - $suffixthere));
  1633. $imptrim = str_replace($sefConfig->replacement.$sefConfig->replacement, $sefConfig->replacement, $imptrim);
  1634. $suffixthere = 0;
  1635. //if (eregi($regexSuffix.'$', $imptrim)) {
  1636. if (preg_match('/'.$pregSuffix.'$/i', $imptrim)) {
  1637. $suffixthere = strlen($sefConfig->suffix);
  1638. }
  1639. $imptrim = trim(substr($imptrim, 0, strlen($imptrim) - $suffixthere), $takethese);
  1640. // add the task if set
  1641. $imptrim .= (!is_null($task) ? '/'.$task.$sefConfig->suffix : '');
  1642. // remove all the -/
  1643. $imptrim = SEFTools::ReplaceAll($sefConfig->replacement.'/', '/', $imptrim);
  1644. // remove all the /-
  1645. $imptrim = SEFTools::ReplaceAll('/'.$sefConfig->replacement, '/', $imptrim);
  1646. // Remove all the //
  1647. $location = SEFTools::ReplaceAll('//', '/', $imptrim);
  1648. // check if the location isn't too long for database storage and truncate it in that case
  1649. $suffixthere = 0;
  1650. //if (eregi($regexSuffix.'$', $location)) {
  1651. if (preg_match('/'.$pregSuffix.'$/i', $location)) {
  1652. $suffixthere = strlen($sefConfig->suffix);
  1653. }
  1654. $suffixLen = strlen($sefConfig->suffix);
  1655. $maxlen = 240 + $suffixthere - $suffixLen; // Leave some space for language and numbers
  1656. if (strlen($location) > $maxlen) {
  1657. // Temporarily remove the suffix
  1658. //$location = ereg_replace($regexSuffix.'$', '', $location);
  1659. $location = preg_replace('/'.$pregSuffix.'$/', '', $location);
  1660. // Explode the location to parts
  1661. $parts = explode('/', $location);
  1662. do {
  1663. // Find the key of the longest part
  1664. $key = 0;
  1665. $len = strlen($parts[0]);
  1666. for( $i = 1, $n = count($parts); $i < $n; $i++ ) {
  1667. $tmpLen = strlen($parts[$i]);
  1668. if( $tmpLen > $len ) {
  1669. $key = $i;
  1670. $len = $tmpLen;
  1671. }
  1672. }
  1673. // Truncate the longest part
  1674. $truncBy = strlen($location) - $maxlen;
  1675. if( $truncBy > 10 ) {
  1676. $truncBy = 10;
  1677. }
  1678. $parts[$key] = substr($parts[$key], 0, -$truncBy);
  1679. // Implode to location again
  1680. $location = implode('/', $parts);
  1681. // Add suffix if was there
  1682. if( $suffixthere > 0 ) {
  1683. $location .= $sefConfig->suffix;
  1684. }
  1685. } while(strlen($location) > $maxlen);
  1686. }
  1687. // remove variables we don't want to be included in non-SEF URL
  1688. // and build the non-SEF part of our SEF URL
  1689. $nonSefUrl = '';
  1690. // load the nonSEF vars from option parameters
  1691. $paramNonSef = array();
  1692. if( isset($params) ) {
  1693. $nsef = $params->get('customNonSef', '');
  1694. if( !empty($nsef) ) {
  1695. // Some variables are set, let's explode them
  1696. $paramNonSef = explode(';', $nsef);
  1697. }
  1698. }
  1699. // get globally configured nonSEF vars
  1700. $configNonSef = array();
  1701. if( !empty($sefConfig->customNonSef) ) {
  1702. $configNonSef = explode(';', $sefConfig->customNonSef);
  1703. }
  1704. // combine all the nonSEF vars arrays
  1705. $nsefvars = array_merge($paramNonSef, $configNonSef);
  1706. if (!empty($nsefvars)) {
  1707. foreach($nsefvars as $nsefvar) {
  1708. // add each variable, that isn't already set, and that is present in our URL
  1709. if( !isset($nonSefVars[$nsefvar]) && !is_null($uri->getVar($nsefvar)) ) {
  1710. $nonSefVars[$nsefvar] = $uri->getVar($nsefvar);
  1711. }
  1712. }
  1713. }
  1714. // nonSefVars - variables to exclude only if set to in configuration
  1715. if ($sefConfig->appendNonSef && isset($nonSefVars)) {
  1716. $vars = array_keys($nonSefVars);
  1717. $q = SEFTools::RemoveVariables($uri, $vars);
  1718. if ($q != '') {
  1719. if ($nonSefUrl == '') {
  1720. $nonSefUrl = '?'.$q;
  1721. }
  1722. else {
  1723. $nonSefUrl .= '&amp;'.$q;
  1724. }
  1725. }
  1726. // if $nonSefVars mixes with $GLOBALS['JOOMSEF_NONSEFVARS'], exclude the mixed vars
  1727. // this is important to prevent duplicating params by adding JOOMSEF_NONSEFVARS to
  1728. // $ignoreSefVars
  1729. $gNonSef = $mainframe->get('sef.global.nonsefvars');
  1730. if (!empty($gNonSef)) {
  1731. foreach (array_keys($gNonSef) as $key) {
  1732. if (in_array($key, array_keys($nonSefVars))) unset($gNonSef[$key]);
  1733. }
  1734. $mainframe->set('sef.global.nonsefvars', $gNonSef);
  1735. }
  1736. }
  1737. // if there are global variables to exclude, add them to ignoreSefVars array
  1738. $gNonSef = $mainframe->get('sef.global.nonsefvars');
  1739. if (!empty($gNonSef)) {
  1740. if (!empty($ignoreSefVars)) {
  1741. $ignoreSefVars = array_merge($gNonSef, $ignoreSefVars);
  1742. } else {
  1743. $ignoreSefVars = $gNonSef;
  1744. }
  1745. }
  1746. // ignoreSefVars - variables to exclude allways
  1747. if (isset($ignoreSefVars)) {
  1748. $vars = array_keys($ignoreSefVars);
  1749. $q = SEFTools::RemoveVariables($uri, $vars);
  1750. if ($q != '') {
  1751. if ($nonSefUrl == '') {
  1752. $nonSefUrl = '?'.$q;
  1753. }
  1754. else {
  1755. $nonSefUrl .= '&amp;'.$q;
  1756. }
  1757. }
  1758. }
  1759. // If the component requests strict accept variables filtering, remove the ones that don't match
  1760. if( isset($params) && ($params->get('acceptStrict', '0') == '1') ) {
  1761. $acceptVars =& SEFTools::getExtAcceptVars($uri->getVar('option'));
  1762. $uriVars = $uri->getQuery(true);
  1763. if( (count($acceptVars) > 0) && (count($uriVars) > 0) ) {
  1764. foreach($uriVars as $name => $value) {
  1765. // Standard Joomla variables
  1766. if (in_array($name, $sefConfig->globalAcceptVars)) {
  1767. continue;
  1768. }
  1769. // Accepted variables
  1770. if( in_array($name, $acceptVars) ) {
  1771. continue;
  1772. }
  1773. // Variable not accepted, add it to non-SEF part of the URL
  1774. $value = urlencode($value);
  1775. if (strlen($nonSefUrl) > 0) {
  1776. $nonSefUrl .= '&amp;'.$name.'='.$value;
  1777. } else {
  1778. $nonSefUrl = '?'.$name.'='.$value;
  1779. }
  1780. $uri->delVar($name);
  1781. }
  1782. }
  1783. }
  1784. // always remove Itemid and store it in a separate column
  1785. if (!is_null($uri->getVar('Itemid'))) {
  1786. $Itemid = $uri->getVar('Itemid');
  1787. $uri->delVar('Itemid');
  1788. }
  1789. // check for non-sef url first and avoid repeative lookups
  1790. // we only want to look for title variations when adding new
  1791. // this should also help eliminate duplicates.
  1792. // David (284): ignore Itemid if set to
  1793. if( isset($params) ) {
  1794. $extIgnore = $params->get('ignoreSource', 2);
  1795. } else {
  1796. $extIgnore = 2;
  1797. }
  1798. $ignoreSource = ($extIgnore == 2 ? $sefConfig->ignoreSource : $extIgnore);
  1799. // If Itemid is set as ignored for the component, set ignoreSource to 1
  1800. $itemidIgnored = false;
  1801. if (isset($Itemid) && !is_null($uri->getVar('option'))) {
  1802. $itemidIgnored = SEFTools::isItemidIgnored($uri->getVar('option'), $Itemid);
  1803. if ($itemidIgnored) {
  1804. $ignoreSource = 1;
  1805. }
  1806. }
  1807. $where = '';
  1808. if (!$ignoreSource && isset($Itemid)) {
  1809. $where .= " AND (`Itemid` = '".$Itemid."' OR `Itemid` IS NULL)";
  1810. }
  1811. $url = JoomSEF::_uriToUrl($uri);
  1812. // if cache is activated, search in cache first
  1813. if ($sefConfig->useCache) {
  1814. if(!$check) {
  1815. $realloc = $cache->GetSefUrl($url, @$Itemid);
  1816. }
  1817. }
  1818. // search if URL exists, if we do not use cache or URL was not cached
  1819. if (!$sefConfig->useCache || !$realloc) {
  1820. $query = "SELECT * FROM `#__sefurls` WHERE `origurl` = '" . addslashes(html_entity_decode(urldecode($url))) . "'" . $where . ' LIMIT 2';
  1821. $db->setQuery($query);
  1822. $sefurls = $db->loadObjectList('Itemid');
  1823. if (!$ignoreSource && isset($Itemid)) {
  1824. if (isset($sefurls[$Itemid])) {
  1825. $realloc = $sefurls[$Itemid];
  1826. }
  1827. else if (isset($sefurls[''])) {
  1828. // We've found one of the ignored Itemids, update it with the current and return
  1829. $realloc = $sefurls[''];
  1830. $realloc->Itemid = $Itemid;
  1831. $query = "UPDATE `#__sefurls` SET `Itemid` = '{$Itemid}' WHERE `id` = '{$realloc->id}' LIMIT 1";
  1832. $db->setQuery($query);
  1833. $db->query();
  1834. }
  1835. else {
  1836. $realloc = reset($sefurls);
  1837. }
  1838. }
  1839. else {
  1840. $realloc = reset($sefurls);
  1841. }
  1842. /*
  1843. // removed - causing problems, ignore multiple sources not working correctly
  1844. // test if current Itemid record exists, if YES, use it, if NO, use first found
  1845. $curId = isset($Itemid) ? $Itemid : '';
  1846. $active = isset($sefurls[$curId]) ? $sefurls[$curId] : reset($sefurls);
  1847. $realloc = $active;
  1848. */
  1849. }
  1850. // if not found, try to find the url without lang variable
  1851. if (!$realloc && ($sefConfig->langPlacement == _COM_SEF_LANG_DOMAIN)) {
  1852. $url = JoomSEF::_uriToUrl($uri, 'lang');
  1853. if ($sefConfig->useCache) {
  1854. $realloc = $cache->GetSefUrl($url, @$Itemid);
  1855. }
  1856. if (!$sefConfig->useCache || !$realloc) {
  1857. $query = "SELECT * FROM `#__sefurls` WHERE `origurl` = '".addslashes(html_entity_decode(urldecode($url)))."'" . $where . ' LIMIT 2';
  1858. $db->setQuery($query);
  1859. $sefurls = $db->loadObjectList('Itemid');
  1860. if (!$ignoreSource && isset($Itemid)) {
  1861. if (isset($sefurls[$Itemid])) {
  1862. $realloc = $sefurls[$Itemid];
  1863. }
  1864. else if (isset($sefurls[''])) {
  1865. // We've found one of the ignored Itemids, update it with the current and return
  1866. $realloc = $sefurls[''];
  1867. $realloc->Itemid = $Itemid;
  1868. $query = "UPDATE `#__sefurls` SET `Itemid` = '{$Itemid}' WHERE `id` = '{$realloc->id}' LIMIT 1";
  1869. $db->setQuery($query);
  1870. $db->query();
  1871. }
  1872. else {
  1873. $realloc = reset($sefurls);
  1874. }
  1875. }
  1876. else {
  1877. $realloc = reset($sefurls);
  1878. }
  1879. /*
  1880. // removed - causing problems, ignore multiple sources not working correctly
  1881. // test if current Itemid record exists, if YES, use it, if NO, use first found
  1882. $curId = isset($Itemid) ? $Itemid : '';
  1883. $active = isset($sefurls[$curId]) ? $sefurls[$curId] : reset($sefurls);
  1884. $realloc = $active;
  1885. */
  1886. }
  1887. }
  1888. // found a match, so we are done
  1889. if (is_object($realloc) && !$check) {
  1890. // return the original URL if SEF is disabled
  1891. if (!$realloc->sef) {
  1892. return $origUri;
  1893. }
  1894. // return found URL with non-SEF part appended
  1895. if (($nonSefUrl != '') && (strstr($realloc->sefurl, '?'))) {
  1896. $nonSefUrl = str_replace('?', '&amp;', $nonSefUrl);
  1897. }
  1898. if(!strlen($host)) {
  1899. $root=JFactory::getURI()->getHost();
  1900. } else {
  1901. $root=$host;
  1902. }
  1903. $url=JFactory::getURI()->getScheme()."://".$root;
  1904. if (substr($url, -1) != '/') $url .= '/';
  1905. $url .= $realloc->sefurl.$nonSefUrl;
  1906. $fragment = $uri->getFragment();
  1907. if (!empty($fragment)) $url .= '#'.$fragment;
  1908. return new JURI($url);
  1909. }
  1910. // URL not found, so lets create it
  1911. else if(!is_object($realloc)||$check) {
  1912. // return the original URL if we don't want to save new URLs
  1913. if ($sefConfig->disableNewSEF) return $origUri;
  1914. $realloc = null;
  1915. $suffixMust = false;
  1916. if (!isset($suffix)) {
  1917. $suffix = $sefConfig->suffix;
  1918. }
  1919. $addFile = $sefConfig->addFile;
  1920. if (($pos = strrpos($addFile, '.')) !== false) {
  1921. $addFile = substr($addFile, 0, $pos);
  1922. }
  1923. // in case the created SEF URL is already in database for different non-SEF URL,
  1924. // we need to distinguish them by using numbers, so let's find the first unused URL
  1925. $leftPart = ''; // string to be searched before page number
  1926. $rightPart = ''; // string to be searched after page number
  1927. if (substr($location, -1) == '/' || strlen($location) == 0) {
  1928. if (($pagetext = $sefConfig->getPageText())) {
  1929. // use global limit if NULL and set in globals
  1930. if (is_null($limit) && isset($_REQUEST['limit']) && $_REQUEST['limit'] > 0) $limit = $_REQUEST['limit'];
  1931. // if we are using pagination, try to calculate page number
  1932. if (!is_null($limitstart) && $limitstart > 0) {
  1933. // make sure limit is not 0
  1934. if ($limit == 0) {
  1935. $config =& JFactory::getConfig();
  1936. $listLimit = $config->getValue('list_limit');
  1937. $limit = ($listLimit > 0) ? $listLimit : 20;
  1938. }
  1939. $pagenum = $limitstart / $limit;
  1940. $pagenum++;
  1941. }
  1942. else $pagenum = 1;
  1943. if (strpos($pagetext, '%s') !== false) {
  1944. $page = str_replace('%s', $pagenum == 1 ? $addFile : $pagenum, $pagetext) . $suffix;
  1945. $pages = explode('%s', $pagetext);
  1946. $leftPart = $location . $pages[0];
  1947. $rightPart = $pages[1] . $suffix;
  1948. }
  1949. else {
  1950. $page = $pagetext.($pagenum == 1 ? $addFile : $sefConfig->pagerep . $pagenum) . $suffix;
  1951. $leftPart = $location . $pagetext . $sefConfig->pagerep;
  1952. $rightPart = $suffix;
  1953. }
  1954. $temploc = $location . ($pagenum == 1 && !$suffixMust ? '' : $page);
  1955. }
  1956. else {
  1957. $temploc = $location . ($suffixMust ? $sefConfig->pagerep.$suffix : '');
  1958. $leftPart = $location . $sefConfig->pagerep;
  1959. $rightPart = $suffix;
  1960. }
  1961. }
  1962. elseif ($suffix) {
  1963. if ($sefConfig->suffix != '/') {
  1964. //if (eregi($regexSuffix, $location)) {
  1965. if (preg_match('/'.$pregSuffix.'/i', $location)) {
  1966. $temploc = preg_replace('/' . $pregSuffix . '/', '', $location) . $suffix;
  1967. $leftPart = preg_replace('/' . $pregSuffix . '/', '', $location) . $sefConfig->pagerep;
  1968. $rightPart = $suffix;
  1969. }
  1970. else {
  1971. $temploc = $location . $suffix;
  1972. $leftPart = $location . $sefConfig->pagerep;
  1973. $rightPart = $suffix;
  1974. }
  1975. }
  1976. else {
  1977. $temploc = $location . $suffix;
  1978. $leftPart = $location . $sefConfig->pagerep;
  1979. $rightPart = $suffix;
  1980. }
  1981. }
  1982. else {
  1983. $temploc = $location . ($suffixMust ? $sefConfig->pagerep . $suffix : '');
  1984. $leftPart = $location . $sefConfig->pagerep;
  1985. $rightPart = $suffix;
  1986. }
  1987. // add language to path
  1988. if($sefConfig->langEnable && isset($lang) && $sefConfig->langPlacementJoomla==_COM_SEF_LANG_PATH) {
  1989. if($sefConfig->mainLanguageJoomla==0 || ($lang!=$sefCnfig->mainLanguageJoomla)) {
  1990. $slash = ($temploc != '' && $temploc[0] == '/');
  1991. $temploc = $lang . ($slash || strlen($temploc) > 0 ? '/' : '') . $temploc;
  1992. $leftPart = $lang . '/' . $leftPart;
  1993. }
  1994. }
  1995. if ($sefConfig->addFile) {
  1996. //if (!eregi($regexSuffix . '$', $temploc) && substr($temploc, -1) == '/') {
  1997. if (!preg_match('/'.$pregSuffix . '$/i', $temploc) && substr($temploc, -1) == '/') {
  1998. $temploc .= $sefConfig->addFile;
  1999. }
  2000. }
  2001. // convert to lowercase if set to
  2002. if ($sefConfig->lowerCase) {
  2003. $temploc = JoomSEF::_toLowerCase($temploc);
  2004. $leftPart = JoomSEF::_toLowerCase($leftPart);
  2005. $rightPart = JoomSEF::_toLowerCase($rightPart);
  2006. }
  2007. $url = JoomSEF::_uriToUrl($uri);
  2008. // see if we have a result for this location
  2009. $sql = "SELECT `id`, `origurl`, `Itemid`, `sefurl` FROM `#__sefurls` WHERE `sefurl` = '$temploc' AND `origurl` != ''";
  2010. $db->setQuery($sql);
  2011. $row = $db->loadObject();
  2012. if ($itemidIgnored) {
  2013. $Itemid = null;
  2014. }
  2015. $realloc = JoomSEF::_checkRow($row, $ignoreSource, @$Itemid, $url, $metadata, $temploc, $priority, $uri->getVar('option'),$check,$host, $sitemapParams);
  2016. // the correct URL could not be used, we must find the first free number
  2017. if( is_null($realloc) ) {
  2018. // let's get all the numbered pages
  2019. $sql = "SELECT `id`, `origurl`, `Itemid`, `sefurl` FROM `#__sefurls` WHERE `sefurl` LIKE '{$leftPart}%{$rightPart}'";
  2020. $db->setQuery($sql);
  2021. $pages = $db->loadObjectList();
  2022. // create associative array of form number => URL info
  2023. $urls = array();
  2024. if (!empty($pages)) {
  2025. $leftLen = strlen($leftPart);
  2026. $rightLen = strlen($rightPart);
  2027. foreach ($pages as $page) {
  2028. $sefurl = $page->sefurl;
  2029. // separate URL number
  2030. $urlnum = substr($sefurl, $leftLen, strlen($sefurl) - $leftLen - $rightLen);
  2031. // use only if it's really numeric
  2032. if (is_numeric($urlnum)) {
  2033. $urls[intval($urlnum)] = $page;
  2034. }
  2035. }
  2036. }
  2037. $i = 2;
  2038. do {
  2039. $temploc = $leftPart . $i . $rightPart;
  2040. $row = null;
  2041. if (isset($urls[$i])) {
  2042. $row = $urls[$i];
  2043. }
  2044. $realloc = JoomSEF::_checkRow($row, $ignoreSource, @$Itemid, $url, $metadata, $temploc, $priority, $uri->getVar('option'),false,$host,$sitemapParams);
  2045. $i++;
  2046. } while( is_null($realloc) );
  2047. }
  2048. }
  2049. // return found URL with non-SEF part appended
  2050. if (($nonSefUrl != '') && (strstr($realloc, '?'))) {
  2051. $nonSefUrl = str_replace('?', '&amp;', $nonSefUrl);
  2052. }
  2053. if (!strlen($host)) {
  2054. $root = JFactory::getUri()->toString(array('host', 'port'));
  2055. } else {
  2056. $root = $host;
  2057. }
  2058. $url = JFactory::getURI()->getScheme()."://".$root.JURI::root(true);
  2059. if (substr($url, -1) != '/') $url .= '/';
  2060. $url .= $realloc.$nonSefUrl;
  2061. $fragment = $uri->getFragment();
  2062. if (!empty($fragment)) {
  2063. $url .= '#'.$fragment;
  2064. }
  2065. return new JURI($url);
  2066. }
  2067. function enabled(&$plugin)
  2068. {
  2069. $mainframe =& JFactory::getApplication();
  2070. $cosi = 'file';
  2071. $cosi = implode($cosi(JPATH_ROOT.DS.'administrator'.DS.'components'.DS.'com_sef'.DS.'sef.xml'));
  2072. $cosi = md5($cosi);
  2073. if ($mainframe->get('sef.global.meta', '') == $cosi) return true;
  2074. else $plugin = $plugin;
  2075. $doc =& JFactory::getDocument();
  2076. $cacheBuf =& $doc->getBuffer('component');
  2077. $cacheBuf2 =
  2078. '<div><a href="http://www.artio'.
  2079. '.net" style="font-size: 8px; v'.
  2080. 'isibility: visible; display: i'.
  2081. 'nline;" title="Web development'.
  2082. ', Joomla, CMS, CRM, Online sho'.
  2083. 'p software, databases">Joomla '.
  2084. 'SEF URLs by Artio</a></div>';
  2085. if (JRequest::getCmd('format') != 'raw')
  2086. $doc->setBuffer($cacheBuf . $cacheBuf2, 'component');
  2087. return true;
  2088. }
  2089. /**
  2090. * Checks the found row
  2091. *
  2092. */
  2093. function _checkRow(&$row, $ignoreSource, $Itemid, $url, &$metadata, $temploc, $priority, $option,$check=false,$host, $sitemapParams = null)
  2094. {
  2095. $realloc = null;
  2096. $db =& JFactory::getDBO();
  2097. $sefConfig =& SEFConfig::getConfig();
  2098. $numberDuplicates = $sefConfig->numberDuplicates;
  2099. if( !empty($option) ) {
  2100. $params =& SEFTools::getExtParams($option);
  2101. $extDuplicates = $params->get('numberDuplicates', '2');
  2102. if( $extDuplicates != '2' ) {
  2103. $numberDuplicates = $extDuplicates;
  2104. }
  2105. }
  2106. if( ($row != false) && !is_null($row) ) {
  2107. if ($ignoreSource || (!$ignoreSource && (empty($Itemid) || $row->Itemid == $Itemid))) {
  2108. // ... check that it matches original URL
  2109. if ($row->origurl == $url) {
  2110. // found the matching object
  2111. // it probably should have been found sooner
  2112. // but is checked again here just for CYA purposes
  2113. // and to end the loop
  2114. $realloc = $row->sefurl;
  2115. }
  2116. else if ($sefConfig->langPlacement == _COM_SEF_LANG_DOMAIN) {
  2117. // check if the urls differ only by lang variable
  2118. if (SEFTools::removeVariable($row->origurl, 'lang') == SEFTools::removeVariable($url, 'lang')) {
  2119. $db->setQuery("UPDATE `#__sefurls` SET `origurl` = '".SEFTools::removeVariable($row->origurl, 'lang')."' WHERE `id` = '".$row->id."' LIMIT 1");
  2120. // if error occured.
  2121. if (!$db->query()) {
  2122. JError::raiseError('JoomSEF Error', JText::_('COM_SEF_ERROR_SEF_URL_UPDATE') . $db->getErrorMsg());
  2123. }
  2124. $realloc = $row->sefurl;
  2125. }
  2126. }
  2127. }
  2128. // The found URL is not the same
  2129. if( !$numberDuplicates ) {
  2130. // But duplicates management is turned on
  2131. // so we can save the same SEF URL for different non-SEF URL
  2132. if(!$check) {
  2133. JoomSEF::_saveNewURL($Itemid, $metadata, $priority, $temploc, $url,$host, $sitemapParams);
  2134. }
  2135. $realloc = $temploc;
  2136. }
  2137. }
  2138. // URL not found
  2139. else {
  2140. // first, try to search among 404s
  2141. $query = "SELECT `id` FROM `#__sefurls` WHERE `sefurl` = '$temploc' AND `origurl` = ''";
  2142. $db->setQuery($query);
  2143. $id = $db->loadResult();
  2144. // if 404 exists, rewrite it to the new URL
  2145. if (!is_null($id)) {
  2146. $sqlId = (!empty($Itemid) ? ", `Itemid` = '$Itemid'" : '');
  2147. $query = "UPDATE `#__sefurls` SET `origurl` = '" . mysql_escape_string(html_entity_decode(urldecode($url)))."'$sqlId, `priority` = '$priority' WHERE `id` = '$id' LIMIT 1";
  2148. $db->setQuery($query);
  2149. // if error occured
  2150. if (!$db->query()) {
  2151. JError::raiseError('JoomSEF Error', JText::_('COM_SEF_ERROR_SEF_URL_UPDATE') . $db->getErrorMsg());
  2152. }
  2153. }
  2154. // else save URL in the database as new record
  2155. else {
  2156. if(!$check) {
  2157. JoomSEF::_saveNewURL($Itemid, $metadata, $priority, $temploc, $url,$host, $sitemapParams);
  2158. }
  2159. }
  2160. $realloc = $temploc;
  2161. }
  2162. return $realloc;
  2163. }
  2164. /**
  2165. * Inserts new SEF URL to database
  2166. *
  2167. */
  2168. function _saveNewURL($Itemid, &$metadata, $priority, $temploc, $url,$host, $sitemapParams)
  2169. {
  2170. $db =& JFactory::getDBO();
  2171. $col = $val = '';
  2172. if( !empty($Itemid) ) {
  2173. $col = ', `Itemid`';
  2174. $val = ", '$Itemid'";
  2175. }
  2176. $metakeys = $metavals = '';
  2177. if (is_array($metadata) && count($metadata) > 0) {
  2178. foreach($metadata as $metakey => $metaval) {
  2179. $metakeys .= ", `$metakey`";
  2180. $metavals .= ", '".str_replace(array("\\", "'", ';'), array("\\\\", "\\'", "\\;"), $metaval)."'";
  2181. }
  2182. }
  2183. // get trace information if set to
  2184. $sefConfig =& SEFConfig::getConfig();
  2185. if (@$sefConfig->trace) {
  2186. $traceinfo = "'" . mysql_escape_string(JoomSEF::_getDebugInfo($sefConfig->traceLevel)) . "'";
  2187. }
  2188. else $traceinfo = "NULL";
  2189. // Sitemap default values
  2190. $sm_indexed = (isset($sitemapParams['indexed']) ? $sitemapParams['indexed'] : ($sefConfig->sitemap_indexed ? 1 : 0));
  2191. $sm_date = date('Y-m-d');
  2192. $sm_frequency = (isset($sitemapParams['frequency']) ? $sitemapParams['frequency'] : $sefConfig->sitemap_frequency);
  2193. $sm_priority = (isset($sitemapParams['priority']) ? $sitemapParams['priority'] : $sefConfig->sitemap_priority);
  2194. $autolock=(int)$sefConfig->autolock_urls;
  2195. $query = 'INSERT INTO `#__sefurls` (`sefurl`, `origurl`, `priority`' . $col . $metakeys . ', `trace`, `sm_indexed`, `sm_date`, `sm_frequency`, `sm_priority`,`locked`,`host`) ' .
  2196. "VALUES ('".$temploc."', '" . mysql_escape_string(html_entity_decode(urldecode($url)))."', '$priority'" . $val . $metavals . ", " . $traceinfo . ", '{$sm_indexed}', '{$sm_date}', '{$sm_frequency}', '{$sm_priority}',".$autolock.",'".$host."')";
  2197. $db->setQuery($query);
  2198. // if error occured
  2199. if (!$db->query()) {
  2200. JError::raiseError('JoomSEF Error', JText::_('COM_SEF_ERROR_SEF_URL_STORE') . $db->getErrorMsg());
  2201. }
  2202. }
  2203. function _checkURLs($option,$item) {
  2204. $db=JFactory::getDBO();
  2205. $sefConfig =& SEFConfig::getConfig();
  2206. $cache=SEFCache::getInstance();
  2207. if ($sefConfig->update_urls == false) {
  2208. return;
  2209. }
  2210. $file = JPATH_ROOT.DS.'components'.DS.'com_sef'.DS.'sef_ext'.DS.$option.'.php';
  2211. if (!file_exists($file)) {
  2212. return;
  2213. }
  2214. require_once ($file);
  2215. $class = 'SefExt_'.$option;
  2216. if (!class_exists($class)) {
  2217. return;
  2218. }
  2219. $sef_ext = new $class();
  2220. if (!method_exists($sef_ext, 'getURLPatterns')) {
  2221. return;
  2222. }
  2223. $urls = $sef_ext->getURLPatterns($item);
  2224. /*echo "<pre>";
  2225. print_r($item->language);
  2226. echo "</pre>";*/
  2227. /*$langs=array();
  2228. if($sefConfig->langEnable) {
  2229. if($sefConfig->langPlacementJoomla==_COM_SEF_LANG_PATH) {
  2230. $sefs=JLanguageHelper::getLanguages('sef');
  2231. $codes=JLanguageHelper::getLanguages('lang_code');
  2232. $langs=array_keys($sefs);
  2233. if($item->language=='*') {
  2234. if($sefConfig->addLangMulti==false) {
  2235. $langs=array();
  2236. }
  2237. } else {
  2238. if($sefConfig->alwaysUseLangJoomla==false) {
  2239. if($sefConfig->mainLanguageJoomla==$codes[$item->language]->sef) {
  2240. $langs=array();
  2241. } else {
  2242. $langs=array($codes[$item->language]->sef);
  2243. }
  2244. } else {
  2245. $langs=array($codes[$item->language]->sef);
  2246. }
  2247. }
  2248. }
  2249. print_r($langs);
  2250. }*/
  2251. foreach($urls as $url) {
  2252. $query="SELECT id, origurl, sefurl, metadesc, metakey, metatitle, metalang, metarobots, metagoogle, metaauthor, locked \n";
  2253. $query.="FROM #__sefurls \n";
  2254. $query.="WHERE origurl REGEXP ".$db->quote($url);
  2255. $db->setQuery($query);
  2256. //echo str_replace('#__','jos_',$query)."<br><br>";
  2257. $sefs=$db->loadObjectList();
  2258. //echo "<pre>";print_r($sefs);echo "</pre>";
  2259. foreach($sefs as $sef) {
  2260. if($sef->locked==1) {
  2261. continue;
  2262. }
  2263. //if(empty($langs)) {
  2264. $uri=new JURI($sef->origurl);
  2265. $this->build($uri,true);
  2266. $new_url=$uri->toString();
  2267. // Strip scheme and host - it's simpler than check other URL parts
  2268. $hostname=JFactory::getUri()->toString(array('scheme','host'));
  2269. $new_url=str_replace($hostname."/",'',$new_url);
  2270. $redirect_inserted=false;
  2271. echo $sef->sefurl."<br>".$new_url."<br><br>";
  2272. if(strcmp($sef->sefurl,$new_url)!=0) {
  2273. $redirect_inserted=true;
  2274. $this->_insertRedirect($sef->sefurl,$new_url);
  2275. $this->_updateURL($sef->id,$new_url);
  2276. }
  2277. /*} else {
  2278. foreach($langs as $lang) {
  2279. echo $sef->origurl."<br>";
  2280. $uri=new JURI($sef->origurl);
  2281. //$uri->setVar('lang',$lang);
  2282. $this->build($uri,true);
  2283. $new_url=$uri->toString();
  2284. // Strip scheme and host - it's simpler than check other URL parts
  2285. $hostname=JFactory::getUri()->toString(array('scheme','host'));
  2286. $new_url=str_replace($hostname."/",'',$new_url);
  2287. echo $new_url."<br><br>";
  2288. $redirect_inserted=false;
  2289. if(strcmp($sef->sefurl,$new_url)!=0) {
  2290. $redirect_inserted=true;
  2291. //$this->_insertRedirect($sef->sefurl,$new_url);
  2292. //$this->_updateURL($sef->id,$new_url);
  2293. }
  2294. }
  2295. }
  2296. exit;*/
  2297. $metadata=$this->_data["metadata"];
  2298. $metas=array();
  2299. foreach($metadata as $key=>$value) {
  2300. if($sef->$key!=$value) {
  2301. $metas[]=$key."=".$db->quote(str_replace(array("\\", "'", ';'), array("\\\\", "\\'", "\\;"), $value));
  2302. }
  2303. }
  2304. if(count($metas)) {
  2305. $this->_updateMetas($sef->id,$metas);
  2306. }
  2307. }
  2308. //exit;
  2309. $cache_urls=$cache->checkSEFURL($url);
  2310. foreach($cache_urls as $cache_orig=>$cache_sef) {
  2311. $cache->updateCacheURL($cache_orig,$cache_sef,$new_url,$metadata);
  2312. if($redirect_inserted==false && $cache_sef!=$new_url) {
  2313. $this->_insertRedirect($cache_sef,$new_url);
  2314. }
  2315. }
  2316. }
  2317. }
  2318. function _updateURL($id,$new_url) {
  2319. $db=JFactory::getDBO();
  2320. $query="UPDATE #__sefurls \n";
  2321. $query.="SET sefurl=".$db->quote(html_entity_decode(urldecode($new_url)))." \n";
  2322. $query.="WHERE id=".$id;
  2323. $db->setQUery($query);
  2324. if(!$db->query()) {
  2325. JError::raiseError('JoomSEF Error', JText::_('COM_SEF_ERROR_SEF_URL_STORE') . $db->getErrorMsg());
  2326. }
  2327. }
  2328. function _insertRedirect($old_url,$new_url) {
  2329. $db=JFactory::getDBO();
  2330. $query="DELETE FROM #__sefmoved \n";
  2331. $query.="WHERE old=".$db->quote($old_url);
  2332. $db->setQUery($query);
  2333. if(!$db->query()) {
  2334. JError::raiseError('JoomSEF Error', JText::_('COM_SEF_ERROR_SEF_URL_STORE') . $db->getErrorMsg());
  2335. }
  2336. // Added to avoid loops when someone want adds back original URL
  2337. $query="DELETE FROM #__sefmoved \n";
  2338. $query.="WHERE old=".$db->quote($new_url)." \n";
  2339. $query.="AND new=".$db->quote($old_url)." \n";
  2340. $db->setQUery($query);
  2341. if(!$db->query()) {
  2342. JError::raiseError('JoomSEF Error', JText::_('COM_SEF_ERROR_SEF_URL_STORE') . $db->getErrorMsg());
  2343. }
  2344. $query="SELECT COUNT(*) \n";
  2345. $query.="FROM #__sefmoved \n";
  2346. $query.="WHERE old=".$db->quote($old_url)." AND new=".$db->quote($new_url)." \n";
  2347. $db->setQuery($query);
  2348. $cnt=$db->loadResult();
  2349. if($cnt==0) {
  2350. $query="INSERT INTO #__sefmoved \n";
  2351. $query.="SET old=".$db->quote($old_url).", new=".$db->quote($new_url)." \n";
  2352. $db->setQuery($query);
  2353. if(!$db->query()) {
  2354. JError::raiseError('JoomSEF Error', JText::_('COM_SEF_ERROR_SEF_URL_STORE') . $db->getErrorMsg());
  2355. }
  2356. }
  2357. }
  2358. function _updateMetas($id,$metas) {
  2359. $db=JFactory::getDBO();
  2360. $query="UPDATE #__sefurls SET ".implode(",",$metas)." \n";
  2361. $query.="WHERE id=".$id;
  2362. $db->setQUery($query);
  2363. if(!$db->query()) {
  2364. JError::raiseError('JoomSEF Error', JText::_('COM_SEF_ERROR_SEF_URL_STORE') . $db->getErrorMsg());
  2365. }
  2366. }
  2367. function _removeURL($option,$item) {
  2368. $db=JFactory::getDBO();
  2369. $sefConfig =& SEFConfig::getConfig();
  2370. $cache=SEFCache::getInstance();
  2371. if ($sefConfig->update_urls == false) {
  2372. return true;
  2373. }
  2374. $file = JPATH_ROOT.DS.'components'.DS.'com_sef'.DS.'sef_ext'.DS.$option.'.php';
  2375. if (!file_exists($file)) {
  2376. return true;
  2377. }
  2378. require_once ($file);
  2379. $class = 'SefExt_'.$option;
  2380. if (!class_exists($class)) {
  2381. return true;
  2382. }
  2383. $sef_ext=new $class();
  2384. if (!method_exists($sef_ext, 'getURLPatterns')) {
  2385. return true;
  2386. }
  2387. $urls=$sef_ext->getURLPatterns($item);
  2388. foreach($urls as $url) {
  2389. $query="SELECT id, sefurl,locked \n";
  2390. $query.="FROM #__sefurls \n";
  2391. $query.="WHERE origurl REGEXP ".$db->quote($url);
  2392. $db->setQuery($query);
  2393. $sefurl=$db->loadObject();
  2394. if(is_object($sefurl)) {
  2395. if($sefurl->locked) {
  2396. JError::raiseError('JoomSEF Error',JText::_('COM_SEF_ERROR_LOCKED_URL'));
  2397. return false;
  2398. }
  2399. // Clean urls which relate to removed item
  2400. $query="DELETE FROM #__sefurls \n";
  2401. $query.="WHERE id=".$sefurl->id;
  2402. $db->setQuery($query);
  2403. if(!$db->query()) {
  2404. JError::raiseError('JoomSEF Error',$db->stderr(true));
  2405. return false;
  2406. }
  2407. // Clean unnecessary redirects
  2408. $query="DELETE FROM #__sefmoved \n";
  2409. $query.="WHERE new=".$db->quote($sefurl->sefurl);
  2410. $db->setQuery($query);
  2411. if(!$db->query()) {
  2412. JError::raiseError('JoomSEF Error',$db->stderr(true));
  2413. return false;
  2414. }
  2415. }
  2416. // Clean urls which relate to removed item from cache too
  2417. $cache->removeCacheURL($url);
  2418. }
  2419. return true;
  2420. }
  2421. function getNonSEFURL($sefurl) {
  2422. $db=JFactory::getDBO();
  2423. $path=substr(JURI::root(true)."/",1);
  2424. $sefurl=str_replace($path,'',$sefurl);
  2425. $query="SELECT origurl \n";
  2426. $query.="FROM #__sefurls \n";
  2427. $query.="WHERE sefurl=".$db->quote($sefurl);
  2428. $db->setQuery($query);
  2429. $origurl=$db->loadResult();
  2430. if(strlen($origurl)) {
  2431. return $origurl;
  2432. }
  2433. $cache=SEFCache::getInstance();
  2434. $origurl=$cache->getNonSEFURL($sefurl,false);
  2435. return @$origurl->origurl;
  2436. }
  2437. function _uriToUrl($uri, $removeVariables = null)
  2438. {
  2439. // Create new JURI object
  2440. $url = new JURI($uri->toString(array('path','query','fragment')));
  2441. // Remove variables if needed
  2442. if (!empty($removeVariables)) {
  2443. if (is_array($removeVariables)) {
  2444. foreach ($removeVariables as $var) {
  2445. $url->delVar($var);
  2446. }
  2447. } else {
  2448. $url->delVar($removeVariables);
  2449. }
  2450. }
  2451. // sort variables
  2452. $vars = $url->getQuery(true);
  2453. ksort($vars);
  2454. // Move option to beginning
  2455. if (isset($vars['option'])) {
  2456. $opt = $vars['option'];
  2457. unset($vars['option']);
  2458. $vars = array_merge(array('option' => $opt), $vars);
  2459. }
  2460. // Set vars
  2461. $url->setQuery($vars);
  2462. // Create string for db
  2463. return $url->toString(array('path', 'query'));
  2464. }
  2465. /**
  2466. * Returns the default priority value for the url
  2467. *
  2468. * @param JURI $uri
  2469. * @return int
  2470. */
  2471. function _getPriorityDefault(&$uri)
  2472. {
  2473. $itemid = $uri->getVar('Itemid');
  2474. if( is_null($itemid) ) {
  2475. return _COM_SEF_PRIORITY_DEFAULT;
  2476. }
  2477. else {
  2478. return _COM_SEF_PRIORITY_DEFAULT_ITEMID;
  2479. }
  2480. }
  2481. function _getDebugInfo($traceLevel = 3, $onlyUserInfo = false)
  2482. {
  2483. $debuginfo = '';
  2484. $tr = 0;
  2485. $uri =& JURI::getInstance();
  2486. if (!$onlyUserInfo) {
  2487. $debuginfo = 'From: ' . @$uri->toString() . "\n";
  2488. }
  2489. $debuginfo .= 'Referer: ' . @$_SERVER['HTTP_REFERER'] . "\n";
  2490. $debuginfo .= 'User agent: ' . @$_SERVER['HTTP_USER_AGENT'];
  2491. if ($onlyUserInfo) {
  2492. return $debuginfo;
  2493. }
  2494. $debuginfo .= "\n\n";
  2495. $trace = debug_backtrace();
  2496. foreach ($trace as $row) {
  2497. if (@$row['class'] == 'JRouterJoomsef' && @$row['function'] == 'build') {
  2498. // this starts tracing for next 3 rounds
  2499. $tr = 1;
  2500. continue;
  2501. }
  2502. elseif ($tr == 0) continue;
  2503. $file = isset($row['file']) ? str_replace(JPATH_BASE, '', $row['file']) : 'n/a';
  2504. $args = array();
  2505. foreach ($row['args'] as $arg) {
  2506. if (is_object($arg)) $args[] = get_class($arg);
  2507. elseif (is_array($arg)) $args[] = 'Array';
  2508. else $args[] = "'" . $arg . "'";
  2509. }
  2510. $debuginfo .= '#' . $tr . ': ' . @$row['class'] . @$row['type'] . @$row['function'] . "(" . implode(', ', $args) . "), " . $file . ' line ' . @$row['line'] . "\n";
  2511. if ($tr == $traceLevel) break;
  2512. $tr++;
  2513. }
  2514. return $debuginfo;
  2515. }
  2516. function CheckAccess()
  2517. {
  2518. if (isset($_GET['query'])) {
  2519. if (strtolower($_GET['query']) == 'ispaid') {
  2520. echo 'false'; exit();
  2521. }
  2522. }
  2523. die('Restricted access');
  2524. }
  2525. function OnlyPaidVersion()
  2526. {
  2527. echo '<strong>'.sprintf(JText::_('COM_SEF_INFO_ONLY_PAID_VERSION'), '<a href="http://www.artio.net/e-shop/joomsef" target="_blank">', '</a>').'</strong>';
  2528. }
  2529. }
  2530. ?>