【问题标题】:CakePHP - How to add to/edit $this->passedArgsCakePHP - 如何添加/编辑 $this->passedArgs
【发布时间】:2011-04-11 05:28:23
【问题描述】:

我有一个通过 url 传递多个参数的搜索 - 城市、美食、功能以及您所在的页面(感谢 paginator)

如果用户在第 2 页 - ...index/page:2 并点击城市“纽约”,他们应该转到 ...index/page:2/city:New York

然后,如果他们随后点击休斯顿,他们应该转到 ...index/page:2/city:New York_Houston

是否有任何简单/内置的方法可以做到这一点?我已经开始编写我的代码来分解 $this->passedArgs,并重建它 - 但到目前为止这一直很痛苦,看起来我正在为我希望 Cake 有的东西编写大量代码一种处理方式。


示例:

用户位于餐厅列表的第 2 页 - index/page:2

用户点击“纽约”,页面刷新 index/page:2/city:New York

用户点击“圣地亚哥” - 页面刷新 index/page:2/city:New York_San Diego

用户再次点击“纽约”(取消切换),页面刷新为 index/page:2/city:San Diego


我尝试创建可以进行这种切换的城市链接列表:

最大的问题不是我做不到(下面的代码有效),而是 1)它没有考虑任何其他查询选项,如页面、美食、功能......等等 - 和 2)感觉就像一堆代码来做一些简单的事情。

我不太关心任何非常小的代码错误,而更关心解决这个问题的整体最佳方法。 (尽管有任何问题,请随时发表评论 - 我总是喜欢听到更好的方法来做任何事情/所有事情)。

非常感谢您的帮助!

$passedCities = explode("_", $this->passedArgs['city']);

foreach($cities as $city):

    $city_name = trim(ucwords(strtolower($city['City']['name'])));
    $cityExists = in_array($city_name, $passedCities);
    $queryCities = $passedCities;

    if($cityExists) {
        unset($queryCities[array_search($city_name, $queryCities)]);
    } else if($city_name != "") {
        array_unshift($queryCities, $city_name);
    }

    $urlSuffix = "";
    if(count($queryCities) > 0) {
        $urlSuffix = "city:";
        foreach($queryCities as $c) {
            $urlSuffix .= trim($c) . "_";
        }
    }

    $urlSuffix = substr($urlSuffix,0,-1);

    echo "<li>" . $this->Html->link($city_name . 
            " (" . $city[0]['count'] . ")", array($urlSuffix)) . "</li>";

endforeach;

【问题讨论】:

    标签: php mysql cakephp cakephp-1.3


    【解决方案1】:

    我会这样工作,假设您的模型名称是 Restaurant

    我会制作“Get”类型的搜索表单

    echo $form->create('Restaurant',  array('type' => 'get', 'action' => 'index', 'class' => 'search-form'));
    echo $form->input('city'); 
    echo $form->input('cuisine');  
    echo $form->input('feature');  
    echo $form->end('Search'); 
    

    在餐厅控制器中,在行动索引中

    function index() {
    
        $this->redirectToNamed();
        $conditions = array();
        $params = $this->params['named'];
    
        if (!empty($params['city'])){
          $conditions['Restaurant.city LIKE'] = '%'.trim($params['city']).'%';
        }
        if (!empty($params['cuisine'])){
          $conditions['Restaurant.cuisine LIKE'] = '%'.trim($params['cuisine']).'%';
        }
        if (!empty($params['background'])){
          $conditions['Restaurant.feature LIKE'] = '%'.trim($params['feature']).'%';
        }
        //refill the form with args
        $this->data['Restaurant'] = $params;
    
        $restaurants = $this->paginate('Restaurant', $conditions);
    
    }
    
    
    function redirectToNamed() { 
    
        $urlArray = $this->params['url'];
        unset($urlArray['url']);
    
        if( !empty($urlArray) ){
            $this->redirect($urlArray, null, true);
        }
    }
    

    如果我没有忘记任何内容,您的搜索表单将保留之前的参数。

    【讨论】:

    • 这可能是我应该采取的方式 - 我会尽快试一试并标记为已回答,如果它解决了其他无法预料的问题 - 谢谢!
    【解决方案2】:

    也许您可以在用户会话中保存一个包含所选城市的数组。 可以使用会话组件将数据写入会话。查看相应的CakeBook 章节。

    将城市存储在数组中而不是 URL 的好处是您不需要拆分搜索字符串。

    【讨论】:

    • 但这会阻止某人为页面添加书签或通过电子邮件发送链接 - 我绝对希望他们能够这样做。
    【解决方案3】:

    我会不回答。

    对我来说,改变城市就像执行新搜索一样,所以我会在此之后显示第 1 页。还因为,通过更改搜索参数,您可能不会拥有相同的页数。如果用户在第 6 页,更改参数,搜索只返回 4 页会怎样?

    【讨论】:

    • 关于分页变量的观点非常好——我同意。但是“features”变量或“cuisines”变量呢?所有这些变量都可以在任何给定时间出现在 url 中。
    【解决方案4】:

    我会创建一个 Helper,它具有创建链接的功能(我称它们为“过滤器”,似乎更合适)。对于该函数,我将传递元素列表(城市、美食、功能等)和 passArgs 变量的副本(我不确定助手是否可以直接访问 passArgs):

    函数 createFilters($elements,$copyPassedArgs,$filterName){

    这个函数的想法是像你在你的例子中那样创建链接,只需改变你的代码:

    /*$urlSuffix = "";
    if(count($queryCities) > 0) {
        $urlSuffix = "city:";
        foreach($queryCities as $c) {
            $urlSuffix .= trim($c) . "_";
        }
        $urlSuffix = substr($urlSuffix,0,-1);
    }*/
    
    $filter = implode("_",$queryCities);
    
    echo "<li>" . $this->Html->link($city_name . 
            " (" . $city[0]['count'] . ")", array_merge($copyPassedArgs,array($filterName => $filter)) . "</li>";
    

    您可能需要更改此代码,但主要思想是:

    • 使用 implode 而不是 foreach。
    • 使用 array_merge 合并传递的参数和你设置的值 想换个链接

    祝你好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多