pagination page gives 404 in codeigniter3 framework - php

I have written pagination code in Codeigniter3 framework, but when I want to go to the second, third and etc. page, it shows me 404 page. Where can be the problem? My routes file:
$route['courses/category/(:any)'] = 'courses/all_courses/$1';
$route['courses/(:any)'] = 'courses/single_course/$1';
My controller:
public function all_courses($categories_slug = NULL, $offset = 0) {
//pagination
$config['base_url'] = base_url() . 'courses/category/'.$categories_slug;
$config['total_rows'] = $this->db->count_all('courses');
$config['per_page'] = 2;
$config['uri_segment'] = 4;
$this->pagination->initialize($config);
$data['title'] = 'Bütün Kurslar Burada';
$data['courses'] = $this->courses_model->get_all_courses($categories_slug, $config['per_page'], $offset);
$this->load->view('templates/header');
$this->load->view('courses/courses', $data);
$this->load->view('templates/footer');
}
My model:
public function get_all_courses($categories_slug = FALSE, $limit = FALSE, $offset = FALSE) {
if($limit) {
$this->db->limit($limit, $offset);
}
<-- and other codes here -->
}
And my view:
<div class="col-md-12 courses_page_btn2">
<nav>
<ul class="pagination">
<li><a><?php echo $this->pagination->create_links(); ?> </a></li>
</ul>
</nav>
</div>

First, in your routes file, your route from courses/category/(:any) is set to route to courses/all_courses/$1, but your controller's all_courses method has a second parameter. So you need to do something about that. I'm guessing that since your pagination is using URI segment 4 that you'll need to adjust your route like this:
$route['courses/category/(:any)/(:num)'] = 'courses/all_courses/$1/$2';
The problem with that route is that if there is no (:num) then you'll get a 404. In most pagination schemes, you're going to want it to default to 1 (the first page). Consider this route instead:
$route['courses/category/(.+)'] = function ($x, $y = 1)
{
return 'courses/all_courses/' . $x . '/' . $y;
};
This will route to your all_courses method, and provide both parameters, even if you leave out the second one.
This pagination works for me with that route:
public function all_courses( $x, $y )
{
$this->load->helper('url');
$this->load->library('pagination');
$pconfig['base_url'] = base_url() . 'courses/category/'.$x;
$pconfig['total_rows'] = 10;
$pconfig['per_page'] = 2;
$pconfig['uri_segment'] = 4;
$this->pagination->initialize($pconfig);
echo $this->pagination->create_links();
}

Related

How can I change the structure of the links that Codeigniter create_links() generates?

I am working on a small blogging application. There is a clear separation between its back-end and its front-end:
The back-end is an API, made with Codeigniter 3, that spits out
pages, posts, pagination etc.
This API is consumed by an AngularJS (v. 1.7.x) front-end;
The front-end posts controller looks like this:
// All posts
.controller('PostsController', ['$scope', '$http', function($scope, $http){
//Get current page (?page=2, ?page=3 etc)
const currPage = window.location.search;
// Get all the posts on the current page
$http.get('api/' + currPage).then(function(response) {
// Posts
$scope.posts = response.data.posts;
// posts pagination
$scope.pagination = response.data.pagination;
});
}])
I have a problem with the pagination that Codeigniter (API) generates caused by the fact that its root is http://apiblog.com/api/. The pagination's HTML is this:
<ul class="pagination">
<li>‹</li>
<li>1</li>
<li class="active"><span>2</span></li>
<li>3</li>
<li>4</li>
<li>›</li>
</ul>
By looking at the front-end posts controller, you can see that the pagination links should miss the api/ part. It should be:
<ul class="pagination">
<li>‹</li>
<li>1</li>
<li class="active"><span>2</span></li>
<li>3</li>
<li>4</li>
<li>›</li>
</ul>
In the Posts controller responsible with displaying and paginating the posts in the front-end:
private function _initPagination($path, $totalRows, $query_string_segment = 'page') {
//load and configure pagination
$this->load->library('pagination');
$config['base_url'] = base_url($path);
$config['query_string_segment'] = $query_string_segment;
$config['enable_query_strings'] =TRUE;
$config['reuse_query_string'] =TRUE;
$config['total_rows'] = $totalRows;
$config['per_page'] = 12;
if (!isset($_GET[$config['query_string_segment']]) || $_GET[$config['query_string_segment']] < 1) {
$_GET[$config['query_string_segment']] = 1;
}
$this->pagination->initialize($config);
$limit = $config['per_page'];
$offset = ($this->input->get($config['query_string_segment']) - 1) * $limit;
return ['limit' => $limit, 'offset' => $offset];
}
public function index() {
//call initialization method
$config = $this->_initPagination("/", $this->Posts_model->get_num_rows());
$data = $this->Static_model->get_static_data();
//$data['pagination'] = $this->pagination->get_as_array();
$data['pagination'] = $this->pagination->create_links();
$data['pages'] = $this->Pages_model->get_pages();
$data['categories'] = $this->Categories_model->get_categories();
//use limit and offset returned by _initPaginator method
$data['posts'] = $this->Posts_model->get_posts($config['limit'], $config['offset']);
// All posts
$this->output->set_content_type('application/json')->set_output(json_encode($data, JSON_PRETTY_PRINT));
}
In the back-end (dashboard), the code for the posts is:
public function index() {
//load and configure pagination
$this->load->library('pagination');
$config['base_url'] = base_url("/dashboard/posts");
$config['query_string_segment'] = 'page';
$config['total_rows'] = $this->Posts_model->get_num_rows();
$config['per_page'] = 10;
if (!isset($_GET[$config['query_string_segment']]) || $_GET[$config['query_string_segment']] < 1) {
$_GET[$config['query_string_segment']] = 1;
}
$limit = $config['per_page'];
$offset = ($this->input->get($config['query_string_segment']) - 1) * $limit;
$this->pagination->initialize($config);
$data = $this->get_data();
$data['posts'] = $this->Posts_model->get_posts($limit, $offset);
$data['offset'] = $offset;
$this->load->view('partials/header', $data);
$this->load->view('dashboard/posts');
$this->load->view('partials/footer');
}
Given that the pagination items are generated "behind the scenes" by $data['pagination'] = $this->pagination->create_links();, I was unable to achieve the necessary configuration of the pagination links.
How can I achieve this?
Inside your _initPagination where you have following line of code
$config['base_url'] = base_url($path);
You can change the above to
$config['base_url'] = "http://".$_SERVER['HTTP_HOST'] . $path;

Codeigniter pagination giving 404 error

Could you help me with my problem about pagination in Codeigniter? I have a view that lists books. I wrote some code and now I see the buttons but the content is not limited as I wished. Can't find what is wrong with the code.
That is the updated code:
Controller:
public function index($offset=0){
$config['base_url'] = 'http://localhost/myLibrary/books/index';
//$config['total_rows'] = 200;
$config['total_rows'] = $this->db->get('books')->num_rows();
$config['per_page'] = 1;
$config['uri_segment']= 3;
$config['attributes'] = array('class' => 'pagination-link');
$config['page_query_string'] = TRUE;
$this->pagination->initialize($config);
$book_list = $this->Books_model->list_books();
$genre_list= $this->Books_model->list_genres();
$author_list= $this->Books_model->list_authors();
$view_data = array(
"book_list" => $book_list,
"genre_list" => $genre_list,
"author_list" => $author_list
);
$this->db->get('books', $config['per_page'], $this->uri->segment(3));
$start = isset($_GET['start']) ? $_GET['start'] : 0;
$book_list = $this->Books_model->list_books($start, $config['per_page']);
$this->load->view("book_list",$view_data);
$this->load->library('pagination');
$this->load->library('table');
}
Model:
public function list_books($limit = FALSE, $offset = FALSE){
if($limit)
{
$this->db->limit($offset, $limit);
}
$list=$this->db->get("books")->result();
return $list;
}
View:
<?php echo $this->pagination->create_links(); ?>
I'd be so happy if you could help and thanks in advance
You can't use base_url() function as a base_url for pagination unless this index function belongs to your default site controller.
Instead change your line to this:
$config['base_url'] = site_url('controller/method/');
Also the reason your data isn't limited is because you're sending start parameter as false to model
It should be:
$data['records'] = $this->Books_model->list_books($this->uri->segment(3), $config['per_page'], $offset);
By looking at your code, the list of books being sent to the view file is stored in the $book_list variable, so in order to limit the number of books returned alter your line to this:
$start = isset($_GET['start']) ? $_GET['start'] : 0;
$book_list = $this->Books_model->list_books($start, $config['per_page']);
And add this you your pagination config array:
$config['page_query_string'] = TRUE;
And in your model function change this line:
$this->db->limit($limit, $offset);
To:
$this->db->limit($offset, $limit);
as stated in the CI documentation
$this->db->limit(10, 20); // Produces: LIMIT 20, 10 (in MySQL. Other databases have slightly different syntax)
Check here for more reference CI Limiting
Also as a side note, by looking at your code the $query and $data['records'] variables are assigned values but are never used or passed to the view file, so they don't do anything
This is how an index method in your controller should look like now:
Controller:
public function index($offset=0){
$config['base_url'] = site_url('books/index');
//$config['total_rows'] = 200;
$config['total_rows'] = $this->db->get('books')->num_rows();
$config['per_page'] = 1;
$config['uri_segment']= 3;
$config['attributes'] = array('class' => 'pagination-link');
$config['page_query_string'] = TRUE;
$this->pagination->initialize($config);
$start = isset($_GET['start']) ? $_GET['start'] : 0;
$book_list = $this->Books_model->list_books($start, $config['per_page']);
$genre_list= $this->Books_model->list_genres();
$author_list= $this->Books_model->list_authors();
$view_data = array(
"book_list" => $book_list,
"genre_list" => $genre_list,
"author_list" => $author_list
);
$this->load->view("book_list",$view_data);
$this->load->library('pagination');
$this->load->library('table');
}
Model:
public function list_books($limit = FALSE, $offset = FALSE){
if($limit !== FALSE)
{
$this->db->limit($offset, $limit);
}
$list=$this->db->get("books")->result();
return $list;
}
$config['base_url'] = 'http://example.com/controller/index/page/'
Try to add index as method name config['base_url]. so that whenever your pagination url created it contains method name.
this happens due to index method call automatically i.e. we don't need to mention method name but in pagination url we have to pass offset parameter we must have to use full url.

Pagination with codeigniter URI issue

This is my first time working with pagination in codeigniter and I'm a little confused. I believe my problem may have something to do with the URI segments offset variable.
Here's my controller. I have replaced the $config["base_url"] with the full URL so you can see how many URI segments I have.
My controller
$gutterId = $this->gutter->convertGutterNameToId($name);
$this->load->library("pagination");
$config = array();
$config["base_url"] = "http://localhost/gutter/g/random/"; //base_url() . "/g/$name";
$config["total_rows"] = $this->gutter->countThreadRows($gutterId);
$config["per_page"] = 1;
$config["uri_segment"] = 5;
$this->pagination->initialize($config);
$limit = 1;
$offset = ($this->uri->segment(5)) ? $this->uri->segment(5) : 0;
$data['threads'] = $this->gutter->grabThreads($limit, $offset, $gutterId);
$data['title'] = $name;
echo $this->pagination->create_links();
And my model.
public function grabThreads($limit, $offset, $gutterId){
$query = $this->db->limit($limit, $offset)->order_by('thread_id', 'DESC')->get_where('threads', array('thread_sub_gutter' => $gutterId));
return $query->result();
}
So this is giving me one result on the http://localhost/gutter/g/random/ page which leads me to believe the query is working correctly. However, when I navigate to http://localhost/gutter/g/random/1 I get the following 404 error
The page you requested was not found.
You will need to route the request to your controller.
Should be something like this:
$route['g/(:any)/(:any)'] = 'g/index/$1/$2';
Also if your page number is going to be in the third segment, do this:
$config[‘uri_segment’] = 3;

Codeigniter pagination does not work for the second page

Codeigniter pagination does not work for me. It displays page numbers and first 5 search results, but when I click on the page '2' it loads 'search_nok' view with message "Please select your options". Could you please check my code below and help me to find the mistake.
Here is my controller:
public function search($offset = 0) {
$limit = 5;
$this->load->library('form_validation');
$this->load->model('model_x');
$this->form_validation->set_rules('country', 'Country','required');
if($this->form_validation->run()) {
$country = $this->input->post('country');
$this->load->library('pagination');
$config['base_url'] = 'http://localhost/abc/cont/search/'; //where 'http://localhost/abc' is my base url
$config['total_rows'] = 14;
$config['per_page'] = 5;
$data['pagination'] = $this->pagination->initialize($config);
if ($this->model_x->did_search($country, $limit, $offset)){
$data["results"] = $this->model_x->did_search($country, $limit, $offset);
$this->load->view("search_ok",$data);
}
}
else
{
$data['message'] = 'Please select your options.';
$this->load->view("search_nok",$data);
}
}
Here is my view:
<?php
echo $this->pagination->create_links();
foreach($results as $row){
$country = $row['country'];
$city = $row['city'];
?>
<table>
<tr>
<td >
<b><?php echo $country; ?></b>
</td>
<td>
<b><?php echo $city; ?></b>
</td>
</tr>
</table>
<?php }?>
I think you are confused about Pagination. First of all, technically all of the pagination stuff:
<?php
$this->load->library('pagination');
$config['base_url'] = 'http://localhost/abc/cont/search/'; //where 'http://localhost/abc' is my base url
$config['total_rows'] = 14;
$config['per_page'] = 5;
should be in your controller, secondly, you should actually be limiting the results in your model as well, since you haven't shown your model I will come up with an example
$this->db->limit ($limit $offset //these will be defined in your controller)
$data = $this->db->get('whatever_table')->whatever_result_type.
return $data
you should define $limit in your controller and pass it over your your model function as a parameter that the function accepts
the controller should also have $offset and $limit defined
public function search($offset = 0) {
$limit = 5;
when you call your model make sure to pass these over
$this->model_x->did_search($country, $limit, $offset);
then instead of just $this->pagination->initialize($config);
do this(still in your controller remember):
$data['pagination'] = $this->pagination->initialize($config);
then echo pagination wherever you want it in your view

How to create pagination with 3 argument in url using codeigniter?

I'm using Codeigniter 2.2 and I try to build pagination ask Codeigniter guide and it is work perfectly for me when I used as url below
$pages_num: is the amount of pages for view.
http://localhost/Codeigniter2.1.4/public_html/page/$pages_num
But I get error when I add one argument for url
as code below I try to find it 3 weeks ago But I have not solution Please
Notes: number 2 is id categories and number 4 is amount of pagination view
http://localhost/Codeigniter2.1.4/public_html/cat/2/4
Here is my code in controller
$this->load->model('frontend/categories_m');
$count = $this->db->count_all_results('job');
$perpage = 2;
if ($count > $perpage) {
$this->load->library('pagination');
$config['base_url'] = site_url('cat/2');
$config['total_rows'] = $count;
$config['per_page'] = $perpage;
$config['uri_segment'] = 3;
$this->pagination->initialize($config);
$this->data['pagination'] = $this->pagination->create_links();
$offset = $this->uri->segment(3);
} else {
$this->data['pagination'] = '';
$offset = 0;
}
$this->db->limit($perpage, $offset);
$this->data['job_cat'] = $this->job_m->get_job();
$this->data['subview'] = 'cat';
$this->load->view('_main_layout', $this->data);
Here is for view:
<?PHP if ($pagination): ?>
<section class="pagination">
<?PHP echo $pagination; ?>
</section>
<?PHP endif; ?>
Please help
Sorry I can't post images here
With codeigniter pagination, the default link structure is as below
http://website/pages/getPagesViaAjax/3/5
Here pages is controller, getPagesViaAjax is function inside it and 3 is a parameter for category id and 5 will be the pagination count(i.e. offset)
in this case my pagination config is something like
$config['base_url'] = site_url('getPagesViaAjax/3');
$offset = $this->uri->segment(4);
So basically your offset will be the last argument and i.e. 5(available at segment 4) in this case. So prior to firing your query to model, please check the offset.

Categories