Pagination problem in codeigniter 4 using Query Buildeer

Viewed 5311

I have work so deep loving ci4 with query builder but i find it hard to make pagination.

While checked to docs it only explain how to use it with the Model no query builder explanation.

I try to use the Manual pagination and set offset in my query but not working properly instead of return the next paging it only return one result for the next paging and join it to the ckurent paging . am defiantly stuck here.

Controller:

$blog = new BlogModel();

            //* Retrieve blogs
            $total = $blog->getActiveBlogTotal();

            $segment = route_to('adminBlogPost', 'active');
            if($this->request->uri->getTotalSegments() == 4)
            {
                $page = $this->request->uri->getSegment(4);
            }
            else
            {
                $page = 1;
            }
            $perPage = 5;
            $pages = $pager->makeLinks($page, $perPage, $total, 'admin_pag', 5);

            $blogs = $blog->getActiveBlogsInAdmin($page);
            return $this->smarty->view('blog/active.tpl', compact(
                'blogs',
                'pages'
            )); 

Model:

//* Get blog in admin
public function getActiveBlogsInAdmin($page)
{

    $table = $this->db->table('zd_blogs');
    $table->select('*');
    $table->join('zd_main_cats', 'zd_main_cats.main_cat_id = zd_blogs.blog_main_cat', 'left');
    $table->join('zd_users', 'zd_users.user_id = zd_blogs.blog_user', 'left');
    $table->where('zd_blogs.blog_status', 1);
    $table->where('zd_blogs.blog_deleted', 0);
    $table->orderBy('zd_blogs.blog_id', 'DESC');
    $table->limit(5, $page);
    $query = $table->get();
    if($table->countAllResults() > 0)
    {
        return $query->getResult();
    }
    else
    {
        return FALSE;
    }
} 

I will really appreciate if some one can be kind enough to give me a clear through

5 Answers

Do not know if you already found solution, however you could do as follows (for CI4)

In controller do as follows..

$pager=service('pager); //instantiate pager..
$page=(int)(($this>request->getVar('page)!==null)?$this->request->getVar('page'):1)-1; //limit  ie ?page=1 would be set to page=0;
$perPage =  5; //offset
$total = $blog->getActiveBlogTotal();
$pager->makeLinks($page,$perPage,$total);
$data['pager'] = $pager;

in model modify function as follows

public function getActiveBlogsInAdmin($page=0,$perPage=1000) and..

$table->limit($page, $perPage);

in view add

<?= $pager->links() ?>

EDIT : Just noted that you used mentioned that you are using builder, in which case you could remove the

$table->limit($page,$perPage)

and use

$query = $builder->get($page, $perPage); 

ie the limit and offset.

It seems you are mixing things up here. Your database query is limited to 5 results with the LIMIT clause in your function getActiveBlogsInAdmin(). Therefore you'll always have with your current pagination setting one page only.

You need to return the complete data set, so the Pager class can render First/Last/etc. page links.

Remove the line: $table->limit(5, $page);

Controller:

$blog = new BlogModel();

    //* Retrieve blogs
    $segment = route_to('adminBlogPost', 'active');

    $blogs = $blog->getActiveBlogsInAdmin($perPage);
    $pager = $blog->pager;
    return $this->smarty->view('blog/active.tpl', compact(
        'blogs',
        'pager'
    )); 

Model:

public function getActiveBlogsInAdmin($perPage=10)
{
    return $this->asArray()
        ->select('*')
        ->join('zd_main_cats', 'zd_main_cats.main_cat_id = zd_blogs.blog_main_cat', 'left')
        ->join('zd_users', 'zd_users.user_id = zd_blogs.blog_user', 'left')
        ->where('zd_blogs.blog_status', 1)
        ->where('zd_blogs.blog_deleted', 0)
        ->orderBy('zd_blogs.blog_id', 'DESC')
        ->pageinate($perPage);
}

Using CI 4.1.5 and PHP 7.4.9, I tried everything to make this work that I could find online or think of just trying random stuff. Turns out, you just have to chain query builder methods on the Model like any simple lookup. Then the built-in pagination works fantastic.

I did hunt for this and found nothing but wrong answers. Paginate is part of the Model, however, so this makes perfect sense. It needed to be posted. Good luck to whoever needs this.

I have the same problem. But I try to tinker with it and it works fine. You can try this instead

  • Model
    <?php

      namespace App\Models\PersediaanBarang;
    
      use CodeIgniter\Database\BaseBuilder;
      use CodeIgniter\Model;
    
      class M_pengadaan extends Model {

           // ...

            public function getData($per_page, $page, $filter) {

                  // Define builder
                  $builder = $this->db->table('t_req_pengadaan as TRP');
                  $builder->select('
                      TRP.*,
                      TL.nama_lab,
                      (SELECT COUNT(*) FROM t_req_pengadaan_detail TRPD WHERE TRPD.pengadaan_id = TRP.id) AS status_realisasi_wait,
                      (SELECT COUNT(*) FROM t_req_pengadaan_detail TRPD WHERE TRPD.pengadaan_id = TRP.id AND TRPD.status_realisasi = 2) AS status_realisasi_done
                   ', false);

                  $builder->join('t_lab as TL', 'TRP.lab_id = TL.id', 'LEFT');                

                  if (isset($filter['status_realisasi_src']) && $filter['status_realisasi_src'] != '') {
                      if ($filter['status_realisasi_src'] == 1) {
                          $builder->having('status_realisasi_done = status_realisasi_wait');
                      } else if ($filter['status_realisasi_src'] == 2) {
                          $builder->having('status_realisasi_done < status_realisasi_wait AND status_realisasi_done != 0');
                      } else if ($filter['status_realisasi_src'] == 3) {
                          $builder->having('status_realisasi_done = 0');
                      }
                  }                  

                  // Custom Pagination
                  if ($page != 1) {
                      $offset = (($page - 1) * $per_page);
                  } else {
                      $offset = $page - 1;
                  }
    
                  if ($per_page != -1) {
                      $data_get = $builder->get($per_page, $offset);
                  } else {
                      $data_get = $builder->get();
                  }
            
                  return $data_get->getResult('object');
            }

            public function getDataRows($filter) {
    
                  // Define builder
                  $builder = $this->db->table('t_req_pengadaan as TRP');
                  $builder->select('
                      TRP.*,
                      TL.nama_lab,
                      (SELECT COUNT(*) FROM t_req_pengadaan_detail TRPD WHERE TRPD.pengadaan_id = TRP.id) AS status_realisasi_wait,
                      (SELECT COUNT(*) FROM t_req_pengadaan_detail TRPD WHERE TRPD.pengadaan_id = TRP.id AND TRPD.status_realisasi = 2) AS status_realisasi_done
                   ', false);

                  $builder->join('t_lab as TL', 'TRP.lab_id = TL.id', 'LEFT');                

                  if (isset($filter['status_realisasi_src']) && $filter['status_realisasi_src'] != '') {
                      if ($filter['status_realisasi_src'] == 1) {
                          $builder->having('status_realisasi_done = status_realisasi_wait');
                      } else if ($filter['status_realisasi_src'] == 2) {
                          $builder->having('status_realisasi_done < status_realisasi_wait AND status_realisasi_done != 0');
                      } else if ($filter['status_realisasi_src'] == 3) {
                          $builder->having('status_realisasi_done = 0');
                      }
                  }    
            
                  return $builder->get()->getResult('object');
            }

      }

  • Controller

    <?php
    
       namespace App\Controllers\Transaksi\PersediaanBarang;
    
       use App\Controllers\BaseController;
       use App\Models\PersediaanBarang\M_pengadaan;

       class ControllerPengadaan extends BaseController {
           
           protected $m_pengadaan;
           protected $pager;

           public function __construct() {
             
              $this->m_pengadaan = new M_pengadaan();
              $this->pager = \Config\Services::pager();

          }

          public function index() {

                // Pagination
                $per_page = 10;
    
                if (isset($_GET['page_custom']) && $_GET['page_custom'] != "") {
                    $page = ($_GET['page_custom']);
                } else {
                    $page = 1;
                }
    
                // Passing data to View
                $data['onLaporan'] = $this->m_pengadaan->getData($per_page, $page, $_GET);
                
                $total_rows = count($this->m_pengadaan->getDataRows($_GET));
                $data['pagination'] = $this->pager->makeLinks($page, $per_page, $total_rows);

                echo view('transaksi/persediaan_barang/pengadaan/v_index', $data);
          }

       }

I hope you are helped with my simple code.

I have recently started working with codeigniter 4 and face the same problem. I have follow Jason J.M's code to solve this problem. here is my code:

Controller:-

$myModel = new MyModel();
$contest_images = $myModel->my_method_name();

$pager=service('pager');
$page=(int)(($this->request->getVar('page')!==null)?$this->request->getVar('page'):1)-1;
$perPage =  12;
$total = count($contest_images);
$pager->makeLinks($page+1, $perPage, $total);
$offset = $page * $perPage;
$data['result'] = $myModel->my_method_name($perPage, $offset);

Model:-

public function my_method_name($perPage = null, $offset = null){
    $builder = $this->db->table("my_db_table");
    return $builder
        ->select()
        ->join('db_table_two','db_table_two.table_two_id = my_db_table.table_id')
        ->limit($perPage, $offset)
        ->get()
        ->getResult();
}

View (Pagination code):-

<?php $pager = \Config\Services::pager(); ?>
<?php if ($pager):?>
    <?php $pagi_path = 'my_controller/my_model'; ?>
    <?php $pager->setPath($pagi_path); ?>
    <?= $pager->links(); ?>
<?php endif; ?>
Related