magento 自定义url路径 和 filter data 小结

背景是往一个第三方的搜索插件里面加入filter功能。

 

首先是路径,插件自己定义了一个router,类似于cms。那首先说说router好了,从入口一路追查的话,会发现最后进入的是Mage_Core_Controller_Varien_Front类下面的dispatch()函数。

 1   public function dispatch()
 2     {
 3         $request = $this->getRequest();
 4 
 5         // If pre-configured, check equality of base URL and requested URL
 6         $this->_checkBaseUrl($request);
 7 
 8         $request->setPathInfo()->setDispatched(false);
 9 
10         $this->_getRequestRewriteController()->rewrite();
11 
12         Varien_Profiler::start('mage::dispatch::routers_match');
13         $i = 0;
14         while (!$request->isDispatched() && $i++ < 100) {
15             foreach ($this->_routers as $router) {
16                 /** @var $router Mage_Core_Controller_Varien_Router_Abstract */
17                 if ($router->match($request)) {
18                     break;
19                 }
20             }
21         }
22         Varien_Profiler::stop('mage::dispatch::routers_match');
23         if ($i>100) {
24             Mage::throwException('Front controller reached 100 router match iterations');
25         }
26         // This event gives possibility to launch something before sending output (allow cookie setting)
27         Mage::dispatchEvent('controller_front_send_response_before', array('front'=>$this));
28         Varien_Profiler::start('mage::app::dispatch::send_response');
29         $this->getResponse()->sendResponse();
30         Varien_Profiler::stop('mage::app::dispatch::send_response');
31         Mage::dispatchEvent('controller_front_send_response_after', array('front'=>$this));
32         return $this;
33     }

前面的代码是把url链接里的各项参数放到request类里面,方便后面调用,从第14行开始,magento会把所有继承自Mage_Core_Controller_Varien_Router_Abstract类的函数拉出来一个个循环match函数,直到找到一个匹配request的。

也就是说假如我想自定义路径,就可以继承Mage_Core_Controller_Varien_Router_Abstract类,然后在match函数里写上自己的路由规则,一旦匹配就跳转到自己想他去的controller类。

不过很显然插件自定义的router并不能很好的完成filter的工作,首先贴上,插件的原来的代码:

 1  public function match(Zend_Controller_Request_Http $request)
 2     {
 3         $identifier = trim($request->getPathInfo(), '/');
 4 
 5         $condition = new Varien_Object(array(
 6             'identifier' => $identifier,
 7             'continue' => true,
 8         ));
 9 
10         $identifier = $condition->getIdentifier();
11 
12         if ($condition->getRedirectUrl()) {
13             Mage::app()->getFrontController()->getResponse()
14                 ->setRedirect($condition->getRedirectUrl())
15                 ->sendResponse();
16             $request->setDispatched(true);
17 
18             return true;
19         }
20 
21         if (!$condition->getContinue()) {
22             return false;
23         }
24 
25         $page = Mage::getModel('searchlandingpage/page')->checkIdentifier($identifier);
26 //代码原理很简单,对url里的路径拆解,然后查询这个路径是否在自定义的表里面,checkIdentifier()就是sql查询。
27         if (!$page) {
28             return false;
29         }
30 
31         $request->setModuleName('searchlandingpage')
32             ->setControllerName('page')
33             ->setActionName('view')
34             ->setParam('q', $page->getQueryText())
35             ->setParam('id', $page->getId());
36 //若查询到了就设置request里的各项参数,告诉magento跳转到这里去
37         $request->setAlias(
38             Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS,
39             $identifier
40         );
41 
42         return true;
43     }

修改后:

 1  public function match(Zend_Controller_Request_Http $request)
 2     {
 3         $helper = Mage::helper('ajaxpriceslider');
 4         $suffix = Mage::getStoreConfig('catalog/seo/category_url_suffix');
 5         $identifier = ltrim($request->getPathInfo(), '/');
 6         $identifier = substr($identifier, 0, strlen($identifier) - strlen($suffix));
 7         $urlSplit = explode($helper->getRoutingSuffix(), $identifier, 2);
 8         
 9         if(isset($urlSplit[0])){
10             $cat = $urlSplit[0];
11         }else{
12             $cat = $identifier;
13         }
14 //这里主要作用是给自定义的路径添加magento的后缀, 如  xxx.html 之类
15 
16         $condition = new Varien_Object(array(
17             'identifier' => $cat,
18             'continue' => true,
19         ));
20 
21         $cat = $condition->getIdentifier();
22 
23         if ($condition->getRedirectUrl()) {
24             Mage::app()->getFrontController()->getResponse()
25                 ->setRedirect($condition->getRedirectUrl())
26                 ->sendResponse();
27             $request->setDispatched(true);
28 
29             return true;
30         }
31 
32         if (!$condition->getContinue()) {
33             return false;
34         }
35 
36         $page = Mage::getModel('searchlandingpage/page')->checkIdentifier($cat);
37 
38         if (!$page) {
39             return false;
40         }
41 
42         $request->setModuleName('searchlandingpage')
43             ->setControllerName('page')
44             ->setActionName('view')
45             ->setParam('q', $page->getQueryText())
46             ->setParam('id', $page->getId());
47 
48         $request->setAlias(
49             Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS,
50             $cat.$suffix
51         );
52     // 解析url参数,例如xxx.com/search/chiken_run/shopby/color/brown,green,white-and-green.html的网址,shopby后面的参数会被解析成array('color'=>'brown,green,white-and-green')
53         $params = explode('/', trim($urlSplit[1], '/'));
54         $layerParams = array();
55         $total = count($params);
56         for ($i = 0; $i < $total - 1; $i++) {
57             if (isset($params[$i + 1])) {
58                 $layerParams[$params[$i]] = urldecode($params[$i + 1]);
59                 ++$i;
60             }
61         }
62 
63         
65         $layerParams += $request->getPost();
67         $request->setParams($layerParams);
68 
69         // 这个生成链接用
70         Mage::register('layer_params', $layerParams);
71         $controllerClassName = $this->_validateControllerClassName('Mirasvit_SearchLandingPage', 'page');
72 
73         $controllerInstance =  Mage::getControllerInstance($controllerClassName, $request, $this->getFront()->getResponse());
74         // 这个是立即执行自己定义的controller类的view函数,不这样做的话,magento会继续加载两个系统router  然后修改了$params,导致我删选数据出问题
75         $request->setDispatched(true);
76         $controllerInstance->dispatch('view');
77         
78         return true;
79     }

以上路径修改完了,在点击删选的时候 ajax寻址就能寻到了,但是返回的数据还是有问题的,这时候就需要修改 刚刚定义的controller下面的view函数了。

其实修改就一步,将$this->renderLayout();修改成

      if ($this->getRequest()->isAjax()) {
                $listing = $this->getLayout()->getBlock('search_result_list')->toHtml();//根据页面的layout不同,这里的getBlock也会不同,下面也是
                $layer = $this->getLayout()->getBlock('catalogsearch.leftnav')->toHtml();

                // Fix urls that contain '___SID=U'
                $urlModel = Mage::getSingleton('core/url');
                $listing = $urlModel->sessionUrlVar($listing);
                $layer = $urlModel->sessionUrlVar($layer);

                $response = array(
                    'listing' => $listing,
                    'layer' => $layer
                );

                $this->getResponse()->setHeader('Content-Type', 'application/json', true);
                $this->getResponse()->setBody(json_encode($response));
            } else {
                $this->renderLayout();
            }

 

到这一步删选功能正常了,至于他是如何工作的,我有空补上

 

posted @ 2016-07-26 10:07  舟了个舟  阅读(404)  评论(0编辑  收藏  举报