Skip to content

Instantly share code, notes, and snippets.

@ngekoding
Created April 7, 2024 10:05
Show Gist options
  • Save ngekoding/5ae7af8ebad602db23d05bcc332f44ab to your computer and use it in GitHub Desktop.
Save ngekoding/5ae7af8ebad602db23d05bcc332f44ab to your computer and use it in GitHub Desktop.
CodeIgniter 3 Paging Library
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
use ChangeCase\ChangeCase;
class Paging {
private $ci;
private $qb;
private $current_page;
private $per_page;
private $total_record;
private $total_page;
private $default_orders = [];
private $default_filters = [];
private $column_aliases = [];
public function __construct()
{
$this->ci =& get_instance();
$this->ci->load->database();
$this->ci->load->helper('url');
}
public function set_default_orders($orders = [])
{
$this->default_orders = $orders;
return $this;
}
public function set_default_filters($filters = [])
{
$this->default_filters = $filters;
return $this;
}
/**
* Mapping the column aliases for querying
* Used for used defined filter columns
*
* Formatted as: alias => field name
*/
public function set_column_aliases($column_aliases)
{
$this->column_aliases = $column_aliases;
return $this;
}
private function filter()
{
$q = $this->ci->input->get('q');
$filter_cols = $this->ci->input->get('filter_cols');
$filters = [];
if (!empty($q)) {
foreach ($filter_cols as $col) {
// We get camel case from the client
// Let's change it to snake case
$col_snake = ChangeCase::snake($col);
if (array_key_exists($col_snake, $this->column_aliases)) {
if (is_array($this->column_aliases[$col_snake])) {
foreach ($this->column_aliases[$col_snake] as $field) {
$filters[] = $field." LIKE '%$q%'";
}
} else {
$filters[] = $this->column_aliases[$col_snake]." LIKE '%$q%'";
}
} else {
$filters[] = $col_snake." LIKE '%$q%'";
}
}
}
$filter_search = !empty($filters) ? '('.implode(' OR ', $filters).')' : NULL;
$default_filter = !empty($this->default_filters) ? implode(' AND ', $this->default_filters) : NULL;
$filter = $filter_search ?? '';
if (!empty($default_filter)) {
$filter .= !empty($filter_search) ? ' AND '.$default_filter : $default_filter;
}
if (!empty($filter)) {
$this->qb->where($filter);
}
$this->total_record = $this->qb->count_all_results('', FALSE);
$this->total_page = ceil($this->total_record / $this->per_page);
}
private function order()
{
$sorts = $this->ci->input->get('sorts') ?? [];
$orders = [];
foreach ($sorts as $sort) {
$order = json_decode($sort);
$orders[$order->prop] = $order->prop.' '.($order->order == 'ascending' ? 'ASC' : 'DESC');
}
foreach ($this->default_orders as $key => $val) {
if (!isset($orders[$key])) {
$orders[$key] = $key.' '.$val; // coded already with ASC or DESC
}
}
if (!empty($orders)) {
$this->qb->order_by(implode(', ', $orders));
}
}
private function limit()
{
$offset = ($this->current_page - 1) * $this->per_page;
$this->qb->limit($this->per_page, $offset);
}
/**
* Generate the result
* @param CI_DB_query_builder $qb The query builder
* @return object
*/
public function generate($qb)
{
$this->qb = $qb;
$this->current_page = $this->ci->input->get('page') ?? 1;
$this->per_page = $this->ci->input->get('per_page') ?? 10;
$this->filter();
$this->order();
$this->limit();
$results = $this->qb->get()
->result();
return (object) [
'data' => $results,
'paging' => (object) [
'current_page' => intval($this->current_page),
'per_page' => intval($this->per_page),
'total_page' => $this->total_page,
'total_record' => $this->total_record,
]
];
}
/**
* Get formatted data for empty result
*/
public function empty_result()
{
return (object) [
'data' => [],
'paging' => (object) [
'current_page' => 1,
'per_page' => 10,
'total_page' => 0,
'total_record' => 0,
]
];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment