1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
26:
27:
28: class Mage_Core_Controller_Varien_Front extends Varien_Object
29: {
30: protected $_defaults = array();
31:
32: 33: 34: 35: 36:
37: protected $_routers = array();
38:
39: protected $_urlCache = array();
40:
41: const XML_STORE_ROUTERS_PATH = 'web/routers';
42:
43: public function setDefault($key, $value=null)
44: {
45: if (is_array($key)) {
46: $this->_defaults = $key;
47: } else {
48: $this->_defaults[$key] = $value;
49: }
50: return $this;
51: }
52:
53: public function getDefault($key=null)
54: {
55: if (is_null($key)) {
56: return $this->_defaults;
57: } elseif (isset($this->_defaults[$key])) {
58: return $this->_defaults[$key];
59: }
60: return false;
61: }
62:
63: 64: 65: 66: 67:
68: public function getRequest()
69: {
70: return Mage::app()->getRequest();
71: }
72:
73: 74: 75: 76: 77:
78: public function getResponse()
79: {
80: return Mage::app()->getResponse();
81: }
82:
83: 84: 85: 86: 87: 88: 89:
90: public function addRouter($name, Mage_Core_Controller_Varien_Router_Abstract $router)
91: {
92: $router->setFront($this);
93: $this->_routers[$name] = $router;
94: return $this;
95: }
96:
97: 98: 99: 100: 101: 102:
103: public function getRouter($name)
104: {
105: if (isset($this->_routers[$name])) {
106: return $this->_routers[$name];
107: }
108: return false;
109: }
110:
111: 112: 113: 114: 115:
116: public function getRouters()
117: {
118: return $this->_routers;
119: }
120:
121: 122: 123: 124: 125:
126: public function init()
127: {
128: Mage::dispatchEvent('controller_front_init_before', array('front'=>$this));
129:
130: $routersInfo = Mage::app()->getStore()->getConfig(self::XML_STORE_ROUTERS_PATH);
131:
132: Varien_Profiler::start('mage::app::init_front_controller::collect_routers');
133: foreach ($routersInfo as $routerCode => $routerInfo) {
134: if (isset($routerInfo['disabled']) && $routerInfo['disabled']) {
135: continue;
136: }
137: if (isset($routerInfo['class'])) {
138: $router = new $routerInfo['class'];
139: if (isset($routerInfo['area'])) {
140: $router->collectRoutes($routerInfo['area'], $routerCode);
141: }
142: $this->addRouter($routerCode, $router);
143: }
144: }
145: Varien_Profiler::stop('mage::app::init_front_controller::collect_routers');
146:
147: Mage::dispatchEvent('controller_front_init_routers', array('front'=>$this));
148:
149:
150: $default = new Mage_Core_Controller_Varien_Router_Default();
151: $this->addRouter('default', $default);
152:
153: return $this;
154: }
155:
156: public function dispatch()
157: {
158: $request = $this->getRequest();
159:
160:
161: $this->_checkBaseUrl($request);
162:
163: $request->setPathInfo()->setDispatched(false);
164: if (!$request->isStraight()) {
165: Varien_Profiler::start('mage::dispatch::db_url_rewrite');
166: Mage::getModel('core/url_rewrite')->rewrite();
167: Varien_Profiler::stop('mage::dispatch::db_url_rewrite');
168: }
169: Varien_Profiler::start('mage::dispatch::config_url_rewrite');
170: $this->rewrite();
171: Varien_Profiler::stop('mage::dispatch::config_url_rewrite');
172: Varien_Profiler::start('mage::dispatch::routers_match');
173: $i = 0;
174: while (!$request->isDispatched() && $i++<100) {
175: foreach ($this->_routers as $router) {
176: if ($router->match($this->getRequest())) {
177: break;
178: }
179: }
180: }
181: Varien_Profiler::stop('mage::dispatch::routers_match');
182: if ($i>100) {
183: Mage::throwException('Front controller reached 100 router match iterations');
184: }
185:
186: Mage::dispatchEvent('controller_front_send_response_before', array('front'=>$this));
187: Varien_Profiler::start('mage::app::dispatch::send_response');
188: $this->getResponse()->sendResponse();
189: Varien_Profiler::stop('mage::app::dispatch::send_response');
190: Mage::dispatchEvent('controller_front_send_response_after', array('front'=>$this));
191: return $this;
192: }
193:
194: public function getRouterByRoute($routeName)
195: {
196:
197: if (empty($routeName)) {
198: $router = $this->getRouter('standard');
199: } elseif ($this->getRouter('admin')->getFrontNameByRoute($routeName)) {
200:
201: $router = $this->getRouter('admin');
202: } elseif ($this->getRouter('standard')->getFrontNameByRoute($routeName)) {
203:
204: $router = $this->getRouter('standard');
205: } elseif ($router = $this->getRouter($routeName)) {
206:
207: } else {
208:
209: $router = $this->getRouter('default');
210: }
211:
212: return $router;
213: }
214:
215: public function getRouterByFrontName($frontName)
216: {
217:
218: if (empty($frontName)) {
219: $router = $this->getRouter('standard');
220: } elseif ($this->getRouter('admin')->getRouteByFrontName($frontName)) {
221:
222: $router = $this->getRouter('admin');
223: } elseif ($this->getRouter('standard')->getRouteByFrontName($frontName)) {
224:
225: $router = $this->getRouter('standard');
226: } elseif ($router = $this->getRouter($frontName)) {
227:
228: } else {
229:
230: $router = $this->getRouter('default');
231: }
232:
233: return $router;
234: }
235:
236: 237: 238: 239: 240:
241: public function rewrite()
242: {
243: $request = $this->getRequest();
244: $config = Mage::getConfig()->getNode('global/rewrite');
245: if (!$config) {
246: return;
247: }
248: foreach ($config->children() as $rewrite) {
249: $from = (string)$rewrite->from;
250: $to = (string)$rewrite->to;
251: if (empty($from) || empty($to)) {
252: continue;
253: }
254: $from = $this->_processRewriteUrl($from);
255: $to = $this->_processRewriteUrl($to);
256:
257: $pathInfo = preg_replace($from, $to, $request->getPathInfo());
258:
259: if (isset($rewrite->complete)) {
260: $request->setPathInfo($pathInfo);
261: } else {
262: $request->rewritePathInfo($pathInfo);
263: }
264: }
265: }
266:
267: 268: 269: 270: 271: 272:
273: protected function _processRewriteUrl($url)
274: {
275: $startPos = strpos($url, '{');
276: if ($startPos!==false) {
277: $endPos = strpos($url, '}');
278: $routeName = substr($url, $startPos+1, $endPos-$startPos-1);
279: $router = $this->getRouterByRoute($routeName);
280: if ($router) {
281: $fronName = $router->getFrontNameByRoute($routeName);
282: $url = str_replace('{'.$routeName.'}', $fronName, $url);
283: }
284: }
285: return $url;
286: }
287:
288: 289: 290: 291: 292: 293:
294: protected function _checkBaseUrl($request)
295: {
296: if (!Mage::isInstalled() || $request->getPost()) {
297: return;
298: }
299:
300: $redirectCode = (int)Mage::getStoreConfig('web/url/redirect_to_base');
301: if (!$redirectCode) {
302: return;
303: } elseif ($redirectCode != 301) {
304: $redirectCode = 302;
305: }
306:
307: if ($this->_isAdminFrontNameMatched($request)) {
308: return;
309: }
310:
311: $baseUrl = Mage::getBaseUrl(
312: Mage_Core_Model_Store::URL_TYPE_WEB,
313: Mage::app()->getStore()->isCurrentlySecure()
314: );
315: if (!$baseUrl) {
316: return;
317: }
318:
319: $uri = @parse_url($baseUrl);
320: $requestUri = $request->getRequestUri() ? $request->getRequestUri() : '/';
321: if (isset($uri['scheme']) && $uri['scheme'] != $request->getScheme()
322: || isset($uri['host']) && $uri['host'] != $request->getHttpHost()
323: || isset($uri['path']) && strpos($requestUri, $uri['path']) === false
324: ) {
325: Mage::app()->getFrontController()->getResponse()
326: ->setRedirect($baseUrl, $redirectCode)
327: ->sendResponse();
328: exit;
329: }
330: }
331:
332: 333: 334: 335: 336: 337:
338: protected function _isAdminFrontNameMatched($request)
339: {
340: $useCustomAdminPath = (bool)(string)Mage::getConfig()
341: ->getNode(Mage_Adminhtml_Helper_Data::XML_PATH_USE_CUSTOM_ADMIN_PATH);
342: $customAdminPath = (string)Mage::getConfig()->getNode(Mage_Adminhtml_Helper_Data::XML_PATH_CUSTOM_ADMIN_PATH);
343: $adminPath = ($useCustomAdminPath) ? $customAdminPath : null;
344:
345: if (!$adminPath) {
346: $adminPath = (string)Mage::getConfig()
347: ->getNode(Mage_Adminhtml_Helper_Data::XML_PATH_ADMINHTML_ROUTER_FRONTNAME);
348: }
349: $adminFrontNames = array($adminPath);
350:
351:
352: $adminFrontNameNodes = Mage::getConfig()->getNode('admin/routers')
353: ->xpath('*[not(self::adminhtml) and use = "admin"]/args/frontName');
354:
355: if (is_array($adminFrontNameNodes)) {
356: foreach ($adminFrontNameNodes as $frontNameNode) {
357:
358: array_push($adminFrontNames, (string)$frontNameNode);
359: }
360: }
361:
362: $pathPrefix = ltrim($request->getPathInfo(), '/');
363: $urlDelimiterPos = strpos($pathPrefix, '/');
364: if ($urlDelimiterPos) {
365: $pathPrefix = substr($pathPrefix, 0, $urlDelimiterPos);
366: }
367:
368: return in_array($pathPrefix, $adminFrontNames);
369: }
370: }
371: