LoginSignup
3
3

More than 3 years have passed since last update.

🍰【CakePHP2】複雑なデータ取得結果を自作配列にしてページネートさせる

Last updated at Posted at 2019-12-12

環境

PHP 7.2.21
CakePHP 2.10.18
MySQL 5.7.27

内容

ページネイトは便利機能であるが単純なfindのデータのみでしか出来ないっぽい
別DBに接続して得たデータやPHP側で修正をかけた自作の配列でもページネイトできればうれしい

ページネイトは内部でfindを実行しているのでControllerで用意した配列をセットしてそれをfindとして返すのみのページネイト専用Modelを作成してそれを利用した

やったこと

Paginate専用のModelを新規作成し、Controllerでそれをuse
Controllerでデータを加工した後にPaginate専用Modelにデータをセットしてからpaginate関数にModel名を渡す

Model/CustomArrayPaginator.php
<?php

class CustomArrayPaginator extends AppModel {
    public $useTable = false;

    // Paginatorに渡す配列データ
    public $data = [];

    /**
     * 受け取ったデータをpagingする為にfindをoverride
     *
     * @return array
     */
    public function find($type = 'first', $query = []): array {
        if (is_null($this->data)) {
            $this->data = [];
        }

        $page = Hash::get($query, 'page', 1);
        $limit = Hash::get($query, 'limit', 10);
        if ($page === 1) {
            // 1ページ目はoffset無し
            $offset = 0;
        } else {
            // 2ページ目以降はページ数-1に分割数をかけたものをoffsetとする
            $offset = ($page - 1) * $limit;
        }
        $result = array_slice($this->data, $offset, $limit);
        return $result;
    }

    /**
     * 配列数の独自計算の為にpaginateCountをoverride
     *
     * @param array|null   $conditions
     * @param integer|null $recursive
     * @param array|null   $extra
     * @return integer カウント数
     */
    public function paginateCount($conditions = null, $recursive = 0, $extra = []) {
        $this->recursive = $recursive;
        return count($this->data);
    }
}

Controller/HogeController.php
<?php

// 追加Modelをuseに追加
App::uses('CustomArrayPaginator', 'Model');
App::uses('Fuga', 'Model');

class HogeController extends AppController {
    // 追加Modelを$uses配列に追加
    public $uses = [
        'CustomArrayPaginator',
        'Fuga',
    ];

    public $paginate = [
        'limit' => 10,
    ];

    public function index() {
        // 加工前のデータを取得
        // ※limitは設定しない!!!
        $tmpData = $this->Fuga->find('all', [
            'fields'     => ['*'],
            'conditions' => ['del_flg' => '0'],
            'order'      => [
                'Fuga.id' => 'asc',
            ]
        ]);

        // 関数で取得したデータを色々加工
        $dispData = $this->modDispData($tmpData);

        // 加工したデータをModelの$dataにセットし、overrideしたfindでページネイトすることでセットした値をそのまま使用
        $this->CustomArrayPaginator->data = $dispData;
        // Model名を渡す
        $result = $this->paginate('CustomArrayPaginator');
    }
}

結果

自分で任意に加工したデータをpaginateすることができた!!
今回の例ではFugaテーブルから単純なfindしかしていないげどJOINなども思いのままです

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3