PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php

https://github.com/joebushi/magento-mirror
PHP | 431 lines | 299 code | 53 blank | 79 comment | 68 complexity | 2efb19ee1cc9cc960532f30e3bea4d25 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@magentocommerce.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.magentocommerce.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Core
  23. * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. class Mage_Core_Controller_Varien_Router_Standard extends Mage_Core_Controller_Varien_Router_Abstract
  27. {
  28. protected $_modules = array();
  29. protected $_routes = array();
  30. protected $_dispatchData = array();
  31. public function collectRoutes($configArea, $useRouterName)
  32. {
  33. $routers = array();
  34. $routersConfigNode = Mage::getConfig()->getNode($configArea.'/routers');
  35. if($routersConfigNode) {
  36. $routers = $routersConfigNode->children();
  37. }
  38. foreach ($routers as $routerName=>$routerConfig) {
  39. $use = (string)$routerConfig->use;
  40. if ($use == $useRouterName) {
  41. $modules = array((string)$routerConfig->args->module);
  42. if ($routerConfig->args->modules) {
  43. foreach ($routerConfig->args->modules->children() as $customModule) {
  44. if ($customModule) {
  45. if ($before = $customModule->getAttribute('before')) {
  46. $position = array_search($before, $modules);
  47. if ($position === false) {
  48. $position = 0;
  49. }
  50. array_splice($modules, $position, 0, (string)$customModule);
  51. } elseif ($after = $customModule->getAttribute('after')) {
  52. $position = array_search($after, $modules);
  53. if ($position === false) {
  54. $position = count($modules);
  55. }
  56. array_splice($modules, $position+1, 0, (string)$customModule);
  57. } else {
  58. $modules[] = (string)$customModule;
  59. }
  60. }
  61. }
  62. }
  63. $frontName = (string)$routerConfig->args->frontName;
  64. $this->addModule($frontName, $modules, $routerName);
  65. }
  66. }
  67. }
  68. public function fetchDefault()
  69. {
  70. $d = explode('/', Mage::getStoreConfig('web/default/front'));
  71. $this->getFront()->setDefault(array(
  72. 'module' => !empty($d[0]) ? $d[0] : 'core',
  73. 'controller' => !empty($d[1]) ? $d[1] : 'index',
  74. 'action' => !empty($d[2]) ? $d[2] : 'index'
  75. ));
  76. }
  77. /**
  78. * checking if this admin if yes then we don't use this router
  79. *
  80. * @return bool
  81. */
  82. protected function _beforeModuleMatch()
  83. {
  84. if (Mage::app()->getStore()->isAdmin()) {
  85. return false;
  86. }
  87. return true;
  88. }
  89. /**
  90. * dummy call to pass through checking
  91. *
  92. * @return bool
  93. */
  94. protected function _afterModuleMatch()
  95. {
  96. return true;
  97. }
  98. public function match(Zend_Controller_Request_Http $request)
  99. {
  100. //checking before even try to find out that current module
  101. //should use this router
  102. if (!$this->_beforeModuleMatch()) {
  103. return false;
  104. }
  105. $this->fetchDefault();
  106. $front = $this->getFront();
  107. $p = explode('/', trim($request->getPathInfo(), '/'));
  108. // get module name
  109. if ($request->getModuleName()) {
  110. $module = $request->getModuleName();
  111. } else {
  112. if(!empty($p[0])) {
  113. $module = $p[0];
  114. } else {
  115. $module = $this->getFront()->getDefault('module');
  116. $request->setAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS, '');
  117. }
  118. }
  119. if (!$module) {
  120. if (Mage::app()->getStore()->isAdmin()) {
  121. $module = 'admin';
  122. } else {
  123. return false;
  124. }
  125. }
  126. /**
  127. * Searching router args by module name from route using it as key
  128. */
  129. $modules = $this->getModuleByFrontName($module);
  130. /**
  131. * If we did not found anything we searching exact this module
  132. * name in array values
  133. */
  134. if ($modules === false) {
  135. if ($moduleFrontName = $this->getModuleByName($module, $this->_modules)) {
  136. $modules = array($module);
  137. $module = $moduleFrontName;
  138. } else {
  139. return false;
  140. }
  141. }
  142. //checkings after we foundout that this router should be used for current module
  143. if (!$this->_afterModuleMatch()) {
  144. return false;
  145. }
  146. /**
  147. * Going through modules to find appropriate controller
  148. */
  149. $found = false;
  150. foreach ($modules as $realModule) {
  151. $request->setRouteName($this->getRouteByFrontName($module));
  152. // get controller name
  153. if ($request->getControllerName()) {
  154. $controller = $request->getControllerName();
  155. } else {
  156. if (!empty($p[1])) {
  157. $controller = $p[1];
  158. } else {
  159. $controller = $front->getDefault('controller');
  160. $request->setAlias(
  161. Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS,
  162. ltrim($request->getOriginalPathInfo(), '/')
  163. );
  164. }
  165. }
  166. // get action name
  167. if (empty($action)) {
  168. if ($request->getActionName()) {
  169. $action = $request->getActionName();
  170. } else {
  171. $action = !empty($p[2]) ? $p[2] : $front->getDefault('action');
  172. }
  173. }
  174. //checking if this place should be secure
  175. $this->_checkShouldBeSecure($request, '/'.$module.'/'.$controller.'/'.$action);
  176. $controllerClassName = $this->_validateControllerClassName($realModule, $controller);
  177. if (!$controllerClassName) {
  178. continue;
  179. }
  180. // instantiate controller class
  181. $controllerInstance = Mage::getControllerInstance($controllerClassName, $request, $front->getResponse());
  182. if (!$controllerInstance->hasAction($action)) {
  183. continue;
  184. }
  185. $found = true;
  186. break;
  187. }
  188. /**
  189. * if we did not found any siutibul
  190. */
  191. if (!$found) {
  192. if ($this->_noRouteShouldBeApplied()) {
  193. $controller = 'index';
  194. $action = 'noroute';
  195. $controllerClassName = $this->_validateControllerClassName($realModule, $controller);
  196. if (!$controllerClassName) {
  197. return false;
  198. }
  199. // instantiate controller class
  200. $controllerInstance = Mage::getControllerInstance($controllerClassName, $request, $front->getResponse());
  201. if (!$controllerInstance->hasAction($action)) {
  202. return false;
  203. }
  204. } else {
  205. return false;
  206. }
  207. }
  208. // set values only after all the checks are done
  209. $request->setModuleName($module);
  210. $request->setControllerName($controller);
  211. $request->setActionName($action);
  212. $request->setControllerModule($realModule);
  213. // set parameters from pathinfo
  214. for ($i=3, $l=sizeof($p); $i<$l; $i+=2) {
  215. $request->setParam($p[$i], isset($p[$i+1]) ? $p[$i+1] : '');
  216. }
  217. // dispatch action
  218. $request->setDispatched(true);
  219. $controllerInstance->dispatch($action);
  220. return true;
  221. }
  222. /**
  223. * Allow to control if we need to enable no route functionality in current router
  224. *
  225. * @return bool
  226. */
  227. protected function _noRouteShouldBeApplied()
  228. {
  229. return false;
  230. }
  231. /**
  232. * Generating and validating class file name,
  233. * class and if evrything ok do include if needed and return of class name
  234. *
  235. * @return mixed
  236. */
  237. protected function _validateControllerClassName($realModule, $controller)
  238. {
  239. $controllerFileName = $this->getControllerFileName($realModule, $controller);
  240. if (!$this->validateControllerFileName($controllerFileName)) {
  241. return false;
  242. }
  243. $controllerClassName = $this->getControllerClassName($realModule, $controller);
  244. if (!$controllerClassName) {
  245. return false;
  246. }
  247. // include controller file if needed
  248. if (!$this->_inludeControllerClass($controllerFileName, $controllerClassName)) {
  249. return false;
  250. }
  251. return $controllerClassName;
  252. }
  253. /**
  254. * Including controller class if checking of existense class before include
  255. *
  256. * @param string $controllerFileName
  257. * @param string $controllerClassName
  258. * @return bool
  259. */
  260. protected function _inludeControllerClass($controllerFileName, $controllerClassName)
  261. {
  262. if (!class_exists($controllerClassName, false)) {
  263. if (!file_exists($controllerFileName)) {
  264. return false;
  265. }
  266. include $controllerFileName;
  267. if (!class_exists($controllerClassName, false)) {
  268. throw Mage::exception('Mage_Core', Mage::helper('core')->__('Controller file was loaded but class does not exist'));
  269. }
  270. }
  271. return true;
  272. }
  273. public function addModule($frontName, $moduleName, $routeName)
  274. {
  275. $this->_modules[$frontName] = $moduleName;
  276. $this->_routes[$routeName] = $frontName;
  277. return $this;
  278. }
  279. public function getModuleByFrontName($frontName)
  280. {
  281. if (isset($this->_modules[$frontName])) {
  282. return $this->_modules[$frontName];
  283. }
  284. return false;
  285. }
  286. public function getModuleByName($moduleName, $modules)
  287. {
  288. foreach ($modules as $module) {
  289. if ($moduleName === $module || (is_array($module)
  290. && $this->getModuleByName($moduleName, $module))) {
  291. return true;
  292. }
  293. }
  294. return false;
  295. }
  296. public function getFrontNameByRoute($routeName)
  297. {
  298. if (isset($this->_routes[$routeName])) {
  299. return $this->_routes[$routeName];
  300. }
  301. return false;
  302. }
  303. public function getRouteByFrontName($frontName)
  304. {
  305. return array_search($frontName, $this->_routes);
  306. }
  307. public function getControllerFileName($realModule, $controller)
  308. {
  309. $parts = explode('_', $realModule);
  310. $realModule = implode('_', array_splice($parts, 0, 2));
  311. $file = Mage::getModuleDir('controllers', $realModule);
  312. if (count($parts)) {
  313. $file .= DS . implode(DS, $parts);
  314. }
  315. $file .= DS.uc_words($controller, DS).'Controller.php';
  316. return $file;
  317. }
  318. public function validateControllerFileName($fileName)
  319. {
  320. if ($fileName && is_readable($fileName) && false===strpos($fileName, '//')) {
  321. return true;
  322. }
  323. return false;
  324. }
  325. public function getControllerClassName($realModule, $controller)
  326. {
  327. $class = $realModule.'_'.uc_words($controller).'Controller';
  328. return $class;
  329. }
  330. public function rewrite(array $p)
  331. {
  332. $rewrite = Mage::getConfig()->getNode('global/rewrite');
  333. if ($module = $rewrite->{$p[0]}) {
  334. if (!$module->children()) {
  335. $p[0] = trim((string)$module);
  336. }
  337. }
  338. if (isset($p[1]) && ($controller = $rewrite->{$p[0]}->{$p[1]})) {
  339. if (!$controller->children()) {
  340. $p[1] = trim((string)$controller);
  341. }
  342. }
  343. if (isset($p[2]) && ($action = $rewrite->{$p[0]}->{$p[1]}->{$p[2]})) {
  344. if (!$action->children()) {
  345. $p[2] = trim((string)$action);
  346. }
  347. }
  348. #echo "<pre>".print_r($p,1)."</pre>";
  349. return $p;
  350. }
  351. protected function _checkShouldBeSecure($request, $path='')
  352. {
  353. if (!Mage::isInstalled() || $request->getPost()) {
  354. return;
  355. }
  356. if ($this->_shouldBeSecure($path) && !Mage::app()->getStore()->isCurrentlySecure()) {
  357. $url = $this->_getCurrentSecureUrl($request);
  358. Mage::app()->getFrontController()->getResponse()
  359. ->setRedirect($url)
  360. ->sendResponse();
  361. exit;
  362. }
  363. }
  364. protected function _getCurrentSecureUrl($request)
  365. {
  366. if ($alias = $request->getAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS)) {
  367. return Mage::getBaseUrl('link', true).ltrim($alias, '/');
  368. }
  369. return Mage::getBaseUrl('link', true).ltrim($request->getPathInfo(), '/');
  370. }
  371. protected function _shouldBeSecure($path)
  372. {
  373. return substr(Mage::getStoreConfig('web/unsecure/base_url'),0,5)==='https'
  374. || Mage::getStoreConfigFlag('web/secure/use_in_frontend')
  375. && substr(Mage::getStoreConfig('web/secure/base_url'),0,5)=='https'
  376. && Mage::getConfig()->shouldUrlBeSecure($path);
  377. }
  378. }