• 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();
                }

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

  • 相关阅读:
    一步一步学习sharepoint2010 workflow 系列第二部分:sharepoint无代码工作流 第3章 自定义工作流(Custom Designer workflows)
    巧用BroadcastReceiver实现开机“自”启动
    webview 与 javascript
    android webview设置内容的字体大小
    android中使用BitmapFactory的decodeStream()方法解码图片失败问题
    在ListView的item项里使用CheckBox或者Button时,OnItemClickListener无响应的问题
    修改Android中strings.xml文件, 动态改变数据
    在使用google map 时出现Android关于java.lang.NoClassDefFoundError问题
    android中String.xml可以传参数的资源
    android 代码实现应用强制装到手机内存
  • 原文地址:https://www.cnblogs.com/cangzhou/p/5706380.html
Copyright © 2020-2023  润新知