4

CakePHP 2.3 でアプリケーションを開発していますが、ページネーションに問題があります。ページネーション リンクをクリックすると、/cab/ServiceDirectory/refine/page:2 (またはこれまでのリンク) がこのサーバーに見つかりませんでした。/cab/ServiceDirectory/refine に移動すると、5 ページあるはずのページネーション リンクが表示されます。コントローラーとビューからページネーション コードを削除すると、表示されるはずのすべての結果が表示されます。

私の ServiceDirectoryResultsController には

public function index() {
  $this->ServiceLocation->recursive=0;
}

public function refine ($id=null) (

 // All my code to get the ServiceLocations from the DB

$this->paginate->array(
  'conditions' => array('ServiceLocation.state' => $states[$state], 'ServiceLocation.solution_categories' => $active_cat),
  'limit' => 8,
);

$results = $this->paginate('ServiceLocation');
$this->set('serviceLocation' ,$results);

}

私の見解では、私は持っています

<div class="paging">
  <?php
    echo $this->Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled'));
    echo $this->Paginator->numbers(array('separator' => ''));
    echo $this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled'));
  ?>
</div>

<?php foreach ($serviceLocation as $Location): ?>

  // I echo a few things from the $Location array

<?php endforeach; ?>

<div class="paging">
  <?php
    echo $this->Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled'));
    echo $this->Paginator->numbers(array('separator' => ''));
    echo $this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled'));
  ?>
</div>

ページングを使用せずに、すべてを検索してそれをビューに送信しなければ、期待する 40 の結果が表示されます。

ページネーションを使用すると、ページネーションのリンクが表示され、それらの上にカーソルを置くと、URL /cab/ServiceDirectoryResults/refine/page:2 または page:3 または page:4 または page:5 が表示されます

:pageX が付いたこれらのリンクのいずれかをクリックすると、エラーが発生します

エラー: 要求されたアドレス '/cab/ServiceDirectoryResults/refine/page:2 は、このサーバーで見つかりませんでした'

私は CakePHP のページングについて多くのことを読みましたが、この動作の理由を見つけることができません。このエラーをデバッグするためにたどる理由、考えられる解決策、またはパスを誰かが提案できますか?

よろしく

リチャード

エラーレベルを確認したところ、すでにレベル2に設定されていました

エラーログの最後のエントリは次のとおりです

2013-05-22 17:09:28 Error: [NotFoundException] Not Found
Request URL: /cab/ServiceDirectoryResults/refine/page:2
Stack Trace:
#0 /var/www/html/cab/lib/Cake/Controller/Controller.php(1074): PaginatorComponent->paginate('ServiceLocation', Array, Array)
#1 /var/www/html/cab/app/Controller/ServiceDirectoryResultsController.php(381): Controller->paginate('ServiceLocation')
#2 [internal function]: ServiceDirectoryResultsController->refine()
#3 /var/www/html/cab/lib/Cake/Controller/Controller.php(486): ReflectionMethod->invokeArgs(Object(ServiceDirectoryResultsController), Array)
#4 /var/www/html/cab/lib/Cake/Routing/Dispatcher.php(187): Controller->invokeAction(Object(CakeRequest))
#5 /var/www/html/cab/lib/Cake/Routing/Dispatcher.php(162): Dispatcher->_invoke(Object(ServiceDirectoryResultsController), Object(CakeRequest), Object(CakeResponse))
#6 /var/www/html/cab/app/webroot/index.php(109): Dispatcher-   >dispatch(Object(CakeRequest), Object(CakeResponse))
#7 {main}

それが役立つことを願っています

4

3 に答える 3

6

参考: 私は Cakephp 2.4 を使用しています。このバージョンでのみテストしました。

この同じ問題に遭遇しました。ページネーション変数をユーザーのセッションに保存します。
このようにして、ユーザーがページから離れたときに、ページに戻ったときに場所 (ページ/並べ替えフィールド/方向) が失われることはありません。

変数をセッションに保存してからセッションから取得するため、ユーザーがリンクをクリックすると、結果が表示されていたページよりも少なくなると、404 が返されます。

例 (彼らがいたページ):
http://localhost/products/index/page:5/sort:Product.name

私は彼らにこのリンクを送ります:
http://localhost/products/index/search:[search_term]

これにより、結果が 2 ページのみにフィルター処理されます。
この場合、セッション変数が復元された実際の (パーマ) リンクは次のようになります。
http://localhost/products/index/page:5/sort:Product.name/search:[search_term]

5 ページは、新しい結果の 2 ページの範囲外です。これにより、ここに見られるもの
がスローされます: http://api.cakephp.org/2.4/source-class-PaginatorComponent.html#238NotFoundException();

これを解決した方法は、例外をキャッチしてから最初のページにリダイレクトすることでした。すべてのページネーション変数 (「検索」を含む) はセッションに保存されるため、ページ変数を渡すだけで済みます。

例:
http://localhost/products/index/page:1

Cakephp はこれを克服する方法としてこれを推奨しています:
http://book.cakephp.org/2.0/en/core-libraries/components/pagination.html#out-of-range-page-requests

ただし、これをすべての「インデックス」ページで使用できるようにしたかったのでController::paginate()AppController.
ここに表示される元のページネーション メソッド:
http://api.cakephp.org/2.4/source-class-Controller.html#1070-1081

Controller/AppController.phpでそれを行った方法は次のとおりです。

<?php

class CommonAppController extends Controller
{
    // ..... other code
    public function paginate($object = null, $scope = array(), $whitelist = array())
    {
    /*
     * Used to see if we get an exception thrown, 
     * If so, send them to the first page, and set the flash so they know
     */
        try
        {
            // taken from their current paginate();
            // http://api.cakephp.org/2.4/source-class-Controller.html#1070-1081
            return $this->Components->load('Paginator', $this->paginate)->paginate($object, $scope, $whitelist);
        }
        catch (NotFoundException $e)
        {
            //Do something here like redirecting to first or last page.
            //$this->request->params['paging'] will give you required info.
            $page = (isset($this->request->params['named']['page'])?$this->request->params['named']['page']:1);

            $this->Session->setFlash(__('Unable to find results on page: %s. Redirected you to page 1.', $page));
            return $this->redirect(array('page' => 1));
        }
    }
    // ..... other code
}
?>
于 2014-09-16T19:28:09.973 に答える