PageRenderTime 42ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/app/code/core/Mage/Core/Model/Url/Rewrite/Request.php

https://gitlab.com/LisovyiEvhenii/ismextensions
PHP | 397 lines | 212 code | 41 blank | 144 comment | 39 complexity | 1d981ff6255931373ab21012ef728a43 MD5 | raw file
  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magento.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magento.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Core
  23. * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. /**
  27. * Url rewrite request model
  28. *
  29. * @category Mage
  30. * @package Mage_Core
  31. * @author Magento Core Team <core@magentocommerce.com>
  32. */
  33. class Mage_Core_Model_Url_Rewrite_Request
  34. {
  35. /**
  36. * Instance of request
  37. *
  38. * @var Zend_Controller_Request_Http
  39. */
  40. protected $_request;
  41. /**
  42. * Instance of core config model
  43. *
  44. * @var Mage_Core_Model_Config
  45. */
  46. protected $_config;
  47. /**
  48. * Collection of front controller's routers
  49. *
  50. * @var array
  51. */
  52. protected $_routers = array();
  53. /**
  54. * Instance of url rewrite model
  55. *
  56. * @var Mage_Core_Model_Url_Rewrite
  57. */
  58. protected $_rewrite;
  59. /**
  60. * Application
  61. *
  62. * @var Mage_Core_Model_App
  63. */
  64. protected $_app;
  65. /**
  66. * Mage Factory model
  67. *
  68. * @var Mage_Core_Model_Factory
  69. */
  70. protected $_factory;
  71. /**
  72. * Constructor
  73. * Arguments:
  74. * request - Zend_Controller_Request_Http
  75. * config - Mage_Core_Model_Config
  76. * factory - Mage_Core_Model_Factory
  77. * routers - array
  78. *
  79. * @param array $args
  80. */
  81. public function __construct(array $args)
  82. {
  83. $this->_factory = !empty($args['factory']) ? $args['factory'] : Mage::getModel('core/factory');
  84. $this->_app = !empty($args['app']) ? $args['app'] : Mage::app();
  85. $this->_config = !empty($args['config']) ? $args['config'] : Mage::getConfig();
  86. $this->_request = !empty($args['request'])
  87. ? $args['request'] : Mage::app()->getFrontController()->getRequest();
  88. $this->_rewrite = !empty($args['rewrite'])
  89. ? $args['rewrite'] : $this->_factory->getModel('core/url_rewrite');
  90. if (!empty($args['routers'])) {
  91. $this->_routers = $args['routers'];
  92. }
  93. }
  94. /**
  95. * Implement logic of custom rewrites
  96. *
  97. * @return bool
  98. */
  99. public function rewrite()
  100. {
  101. if (!Mage::isInstalled()) {
  102. return false;
  103. }
  104. if (!$this->_request->isStraight()) {
  105. Varien_Profiler::start('mage::dispatch::db_url_rewrite');
  106. $this->_rewriteDb();
  107. Varien_Profiler::stop('mage::dispatch::db_url_rewrite');
  108. }
  109. Varien_Profiler::start('mage::dispatch::config_url_rewrite');
  110. $this->_rewriteConfig();
  111. Varien_Profiler::stop('mage::dispatch::config_url_rewrite');
  112. return true;
  113. }
  114. /**
  115. * Implement logic of custom rewrites
  116. *
  117. * @return bool
  118. */
  119. protected function _rewriteDb()
  120. {
  121. if (null === $this->_rewrite->getStoreId() || false === $this->_rewrite->getStoreId()) {
  122. $this->_rewrite->setStoreId($this->_app->getStore()->getId());
  123. }
  124. $requestCases = $this->_getRequestCases();
  125. $this->_rewrite->loadByRequestPath($requestCases);
  126. $fromStore = $this->_request->getQuery('___from_store');
  127. if (!$this->_rewrite->getId() && $fromStore) {
  128. $stores = $this->_app->getStores(false, true);
  129. if (!empty($stores[$fromStore])) {
  130. /** @var $store Mage_Core_Model_Store */
  131. $store = $stores[$fromStore];
  132. $fromStoreId = $store->getId();
  133. } else {
  134. return false;
  135. }
  136. $this->_rewrite->setStoreId($fromStoreId)->loadByRequestPath($requestCases);
  137. if (!$this->_rewrite->getId()) {
  138. return false;
  139. }
  140. // Load rewrite by id_path
  141. $currentStore = $this->_app->getStore();
  142. $this->_rewrite->setStoreId($currentStore->getId())->loadByIdPath($this->_rewrite->getIdPath());
  143. $this->_setStoreCodeCookie($currentStore->getCode());
  144. $targetUrl = $currentStore->getBaseUrl() . $this->_rewrite->getRequestPath();
  145. $this->_sendRedirectHeaders($targetUrl, true);
  146. }
  147. if (!$this->_rewrite->getId()) {
  148. return false;
  149. }
  150. $this->_request->setAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS,
  151. $this->_rewrite->getRequestPath());
  152. $this->_processRedirectOptions();
  153. return true;
  154. }
  155. /**
  156. * Set store code to a cookie
  157. *
  158. * @param string $storeCode
  159. */
  160. protected function _setStoreCodeCookie($storeCode)
  161. {
  162. $store = $this->_app->getStore($storeCode);
  163. if ($store->getWebsite()->getDefaultStore()->getId() == $store->getId()) {
  164. $this->_app->getCookie()->delete(Mage_Core_Model_Store::COOKIE_NAME);
  165. } else {
  166. $this->_app->getCookie()->set(Mage_Core_Model_Store::COOKIE_NAME, $storeCode, true);
  167. }
  168. }
  169. /**
  170. * Process redirect (R) and permanent redirect (RP)
  171. *
  172. * @return Mage_Core_Model_Url_Rewrite_Request
  173. */
  174. protected function _processRedirectOptions()
  175. {
  176. $isPermanentRedirectOption = $this->_rewrite->hasOption('RP');
  177. $external = substr($this->_rewrite->getTargetPath(), 0, 6);
  178. if ($external === 'http:/' || $external === 'https:') {
  179. $destinationStoreCode = $this->_app->getStore($this->_rewrite->getStoreId())->getCode();
  180. $this->_setStoreCodeCookie($destinationStoreCode);
  181. $this->_sendRedirectHeaders($this->_rewrite->getTargetPath(), $isPermanentRedirectOption);
  182. }
  183. $targetUrl = $this->_request->getBaseUrl() . '/' . $this->_rewrite->getTargetPath();
  184. $storeCode = $this->_app->getStore()->getCode();
  185. if (Mage::getStoreConfig('web/url/use_store') && !empty($storeCode)) {
  186. $targetUrl = $this->_request->getBaseUrl() . '/' . $storeCode . '/' . $this->_rewrite->getTargetPath();
  187. }
  188. if ($this->_rewrite->hasOption('R') || $isPermanentRedirectOption) {
  189. $this->_sendRedirectHeaders($targetUrl, $isPermanentRedirectOption);
  190. }
  191. $queryString = $this->_getQueryString();
  192. if ($queryString) {
  193. $targetUrl .= '?' . $queryString;
  194. }
  195. $this->_request->setRequestUri($targetUrl);
  196. $this->_request->setPathInfo($this->_rewrite->getTargetPath());
  197. return $this;
  198. }
  199. /**
  200. * Apply configuration rewrites to current url
  201. *
  202. * @return bool
  203. */
  204. protected function _rewriteConfig()
  205. {
  206. $config = $this->_config->getNode('global/rewrite');
  207. if (!$config) {
  208. return false;
  209. }
  210. foreach ($config->children() as $rewrite) {
  211. $from = (string)$rewrite->from;
  212. $to = (string)$rewrite->to;
  213. if (empty($from) || empty($to)) {
  214. continue;
  215. }
  216. $from = $this->_processRewriteUrl($from);
  217. $to = $this->_processRewriteUrl($to);
  218. $pathInfo = preg_replace($from, $to, $this->_request->getPathInfo());
  219. if (isset($rewrite->complete)) {
  220. $this->_request->setPathInfo($pathInfo);
  221. } else {
  222. $this->_request->rewritePathInfo($pathInfo);
  223. }
  224. }
  225. return true;
  226. }
  227. /**
  228. * Prepare request cases.
  229. *
  230. * We have two cases of incoming paths - with and without slashes at the end ("/somepath/" and "/somepath").
  231. * Each of them matches two url rewrite request paths
  232. * - with and without slashes at the end ("/somepath/" and "/somepath").
  233. * Choose any matched rewrite, but in priority order that depends on same presence of slash and query params.
  234. *
  235. * @return array
  236. */
  237. protected function _getRequestCases()
  238. {
  239. $pathInfo = $this->_request->getPathInfo();
  240. $requestPath = trim($pathInfo, '/');
  241. $origSlash = (substr($pathInfo, -1) == '/') ? '/' : '';
  242. // If there were final slash - add nothing to less priority paths. And vice versa.
  243. $altSlash = $origSlash ? '' : '/';
  244. $requestCases = array();
  245. // Query params in request, matching "path + query" has more priority
  246. $queryString = $this->_getQueryString();
  247. if ($queryString) {
  248. $requestCases[] = $requestPath . $origSlash . '?' . $queryString;
  249. $requestCases[] = $requestPath . $altSlash . '?' . $queryString;
  250. }
  251. $requestCases[] = $requestPath . $origSlash;
  252. $requestCases[] = $requestPath . $altSlash;
  253. return $requestCases;
  254. }
  255. /**
  256. * Add location header and disable browser page caching
  257. *
  258. * @param string $url
  259. * @param bool $isPermanent
  260. */
  261. protected function _sendRedirectHeaders($url, $isPermanent = false)
  262. {
  263. if ($isPermanent) {
  264. header('HTTP/1.1 301 Moved Permanently');
  265. }
  266. header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
  267. header('Pragma: no-cache');
  268. header('Location: ' . $url);
  269. exit;
  270. }
  271. /**
  272. * Prepare and return QUERY_STRING
  273. *
  274. * @return bool|string
  275. */
  276. protected function _getQueryString()
  277. {
  278. if (!empty($_SERVER['QUERY_STRING'])) {
  279. $queryParams = array();
  280. parse_str($_SERVER['QUERY_STRING'], $queryParams);
  281. $hasChanges = false;
  282. foreach ($queryParams as $key => $value) {
  283. if (substr($key, 0, 3) === '___') {
  284. unset($queryParams[$key]);
  285. $hasChanges = true;
  286. }
  287. }
  288. if ($hasChanges) {
  289. return http_build_query($queryParams);
  290. } else {
  291. return $_SERVER['QUERY_STRING'];
  292. }
  293. }
  294. return false;
  295. }
  296. /**
  297. * Replace route name placeholders in url to front name
  298. *
  299. * @param string $url
  300. * @return string
  301. */
  302. protected function _processRewriteUrl($url)
  303. {
  304. $startPos = strpos($url, '{');
  305. if ($startPos !== false) {
  306. $endPos = strpos($url, '}');
  307. $routeName = substr($url, $startPos + 1, $endPos - $startPos - 1);
  308. $router = $this->_getRouterByRoute($routeName);
  309. if ($router) {
  310. $frontName = $router->getFrontNameByRoute($routeName);
  311. $url = str_replace('{' . $routeName . '}', $frontName, $url);
  312. }
  313. }
  314. return $url;
  315. }
  316. /**
  317. * Retrieve router by name
  318. *
  319. * @param string $name
  320. * @return Mage_Core_Controller_Varien_Router_Abstract|bool
  321. */
  322. protected function _getRouter($name)
  323. {
  324. if (isset($this->_routers[$name])) {
  325. return $this->_routers[$name];
  326. }
  327. return false;
  328. }
  329. /**
  330. * Retrieve router by name
  331. *
  332. * @param string $routeName
  333. * @return Mage_Core_Controller_Varien_Router_Abstract
  334. */
  335. protected function _getRouterByRoute($routeName)
  336. {
  337. // empty route supplied - return base url
  338. if (empty($routeName)) {
  339. $router = $this->_getRouter('standard');
  340. } elseif ($this->_getRouter('admin')->getFrontNameByRoute($routeName)) {
  341. // try standard router url assembly
  342. $router = $this->_getRouter('admin');
  343. } elseif ($this->_getRouter('standard')->getFrontNameByRoute($routeName)) {
  344. // try standard router url assembly
  345. $router = $this->_getRouter('standard');
  346. } else {
  347. // try custom router url assembly
  348. $router = $this->_getRouter($routeName);
  349. if (!$router) {
  350. // get default router url
  351. $router = $this->_getRouter('default');
  352. }
  353. }
  354. return $router;
  355. }
  356. }