unable to keep pagination track - php

Pagination links are shown correctly for 1st time, but when I click 2nd page link the data vanishes.
Here is my code:
Controller
class PostsController extends AppController {
public $components = array('Paginator');
var $paginate = array(
'Post' => array(
'limit' => 5
)
);
public function index() {
//debug("in index");
//$this->render();
$d=$this->data['lower_limit'];
//debug(" df ");
//debug($d);
$lower= $this->data['lower_limit'];
$upper= $this->data['upper_limit'];
$conditions = array('Post.post_id >=' => $lower, 'Post.post_id <=' => $upper);
$this->Paginator->settings = $this->paginate;
$data = $this->Paginator->paginate('Post', $conditions);
$this->set('data', $data);
$this->set('lower_limit',$lower);
$this->set('upper_limit', $upper);
}
}
Model
I have not overridden paginate and pagination count methods.

Related

Call to undefined method PaginatorComponent::paginate() cakephp2

I'm upgrading my cakephp1.x project to cakephp2.10.12. I got below error when I try to apply pagination to my view
Error
Call to undefined method PaginatorComponent::paginate()
My controller code like this
App::uses('Controller', 'Controller');
class ProductsController extends AppController {
var $name = "Product";
var $helpers = array('Html', 'Form','Paginator','Js');
var $paginate = array('limit' => 25,'order' => array('Product.pname' => 'asc'));
function allproducts() {
$this->paginate = array(
'conditions' => array("Product.status" => 'A','Product.stock >' => 0),
);
$this->Paginator->settings = $this->paginate;
list($order,$limit,$page) = $this->paginate(); // Added

How to use parameter in function with pagination CodeIgniter?

I have function which takes state name as a parameter and displays all the cities of that specific state. Since list of cities is very long I have used pagination in the same function but when I click on the 'Next' or any other pagination link the function accepts the offset value in the $state variable. The function is
public function load_Page($state){
$this->load->database();
$this->load->library('pagination');
$a = 1;
$this->db->select("*")->where("userstate" , $a)->where("state" , $state);
$query0 = $this->db->get("city");
$this->db->select("*")->where("userstate" , $a)->where("state" , $state);
$query1 = $this->db->get('city' , 10 , $this->uri->segment(3));
$config["base_url"] = base_url()."index.php/city/load_Page";
$total_row = $query0->num_rows();
$config['page_query_string'] = TRUE;
$config["total_rows"] = $total_row;
$config["per_page"] = 10;
$this->pagination->initialize($config);
$data["state"] = $state;
$data["result"] = $query1->result();
//$data["rows"] = $query1->num_rows();
$this->load->view('header');
$this->load->view('city', $data);
$this->load->view('footer');
}
Is there any other way out to do it or I am going completely wrong?
First of all, when you are paginating, the page number has to come from the URL, and that's always available as a parameter in the controller method. It should default to page 1.
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class City extends CI_Controller {
public function load_page( $state, $page = 1 ){
// I'm going to use an alias for this model
$this->load->model('example_model', 'model');
// Use the URL helper for site_url()
$this->load->helper('url');
// Set pagination config
$config['pagination_settings'] = [
'per_page' => 10,
'use_page_numbers' => TRUE,
'uri_segment' => 4, // This is very important!!!
'base_url' => site_url('city/load_page/' . $state)
];
// Get the total rows
$config['pagination_settings']["total_rows"] = $this->model->pagination_count( $state );
// Load and initialize pagination
$this->load->library('pagination');
$this->pagination->initialize($config['pagination_settings']);
$data = [
'state' => $state,
'rows' => $this->model->get_cities( $state, $page, $config['pagination_settings']['per_page'] ),
'links' => $this->pagination->create_links()
];
// Use data in views or wherever needed ...
$this->load->view('city', $data);
}
/**
* Create the rows to paginate
*/
public function setup()
{
// I'm going to use an alias for this model
$this->load->model('example_model', 'model');
$this->model->setup();
}
// -----------------------------------------------------------------------
}
Next, you should move your database queries to a model. You don't need to use transactions for your 2 select type queries.
<?php
defined('BASEPATH') or exit('No direct script access allowed');
class Example_model extends CI_Model{
public function __construct()
{
parent::__construct();
$this->load->database();
}
public function pagination_count( $state )
{
return $this->db->where("state" , $state)
->count_all_results('city');
}
public function get_cities( $state, $page, $limit )
{
$offset = ( $page * $limit ) - $limit;
$query = $this->db->where("state" , $state)
->limit( $limit, $offset )
->get('city');
if( $query->num_rows() > 0 )
return $query->result();
return NULL;
}
/**
* Setup for testing
*/
public function setup()
{
$this->load->dbforge();
$fields = array(
'id' => array(
'type' => 'INT',
'constraint' => 5,
'unsigned' => TRUE,
'auto_increment' => TRUE
),
'state' => array(
'type' => 'VARCHAR',
'constraint' => '32',
),
'city' => array(
'type' => 'VARCHAR',
'constraint' => '32',
),
);
$this->dbforge->add_field($fields);
$this->dbforge->add_key('id', TRUE);
$this->dbforge->create_table('city', TRUE);
for( $x = 1; $x <= 40; $x++ )
{
$this->db->insert('city', array(
'state' => 'ca',
'city' => 'x' . $x
));
}
}
}
This is the view that I used:
<?php
echo '<h1>' . $state . '</h1>';
echo $links . '<br /><br />';
foreach( $rows as $row )
{
echo $row->city . '<br />';
}
To set up the database for testing, I went to:
http://localhost/index.php/city/setup
Then to check out that the pagination works, I went to:
http://localhost/index.php/city/load_page/ca
It should work for you, as this code is now fully tested.
UPDATE --------------------
If you want to add more parameters to your pagination, do it with query strings. You will need to set the pagination config with this extra setting:
$config['pagination_settings']['reuse_query_string'] = TRUE;
That means the config would look like this:
$config['pagination_settings'] = [
'per_page' => 10,
'use_page_numbers' => TRUE,
'uri_segment' => 4, // This is very important!!!
'base_url' => site_url('city/load_page/' . $state),
'reuse_query_string' => TRUE
];
And then you create the link to the first page with your params:
http://localhost/index.php/city/load_page/ca?a=1&b=2&c=3
And because of the reuse_query_strings being set to TRUE, that means that ?a=1&b=2&c=3 would all be attached to the pagination links.

How to load all rows in codeigniter-base-model? REST api

I am trying to load all rows for my REST API through Postman.
I am using codeigniter-base-model MY_Model.php.
https://github.com/jamierumbelow/codeigniter-base-model
This is how my code currently looks like both in my controller/model:
Controller(api_news.php):
class Api_News extends REST_Controller {
function __construct()
{
parent::__construct();
}
function index_get()
{
$id = $this->uri->segment(3);
$this->load->model('News_model');
$news = $this->News_model->get_by(array('id' => $id));
if(isset($news['id'])) {
$this->response(array(
'message' => 'success',
'status' => 'true',
'data' => $news));
} else {
$this->response(array(
'message' => 'unsuccess',
'status' => 'false'));
}
}
}
Model(news_model.php):
class News_model extends MY_Model{
protected $_table = 'news';
protected $primary_key = 'id';
protected $return_type = 'array';
}
At the moment if I access:
localhost/my_api/api_news/id/1, 2, 3, etc...
I can access any record by its individual ID and it shows up which is great.
BUT I also want to be able to see all rows by doing this:
localhost/my_api/api_news/id/
and have all rows showing at once.
But I am not sure how to do this...and am getting an unsuccess/false if I try.
Can you please show me how? I am new to PHP in general and I appreciate any help.
Thank you so much!!
Make some changes in your Controller function as below -
function index_get(){
$id = $this->uri->segment(3);
$this->load->model('News_model');
// pass $id to model
$news = $this->News_model->get_by( $id );
if( !empty( $news ) ) {
$this->response(array(
'message' => 'success',
'status' => 'true',
'data' => $news));
} else {
$this->response(array(
'message' => 'unsuccess',
'status' => 'false'));
}
}
And in your model make id parameter optional and then check that if id is passed get data based on id otherwise return all data as below -
// $id variable is optional here
function get_by( $id = '' ) {
if ( $id == '' ) {
$news = $this->db->get( 'news' );
}
else {
$news = $this->db->get_where( 'news', array( 'id' => $id ) );
}
// return data to controller
return $news->result();
}
So if you enter id in API then data will be based on that id otherwise all data will be returned.

CakePHP trouble linking data from 2 tables in models

I am having trouble with linking data like first name from the table Users in the view of chats using cakePHP. Below is my code and whatever I do, the script does not select the user_id from the chats database table to display the first name. I must be overseeing something, but the loop I'm thinking in is giving me some headaches. Can someone please get me out of this loop?
User.php
<?php
class User extends AppModel {
public $hasMany = array(
'Ondutylog',
'Chat'
);
}
?>
Chat.php
<?php
class Chat extends AppModel {
public $belongsTo = array(
'User'
);
}
?>
ChatsController.php
<?php
class ChatsController extends AppController {
var $uses = array('User', 'Chat');
public function view() {
$chats = $this->Chat->find('all', array(
'order' => array('id' => 'ASC'),
'recursive' => -1
));
$this->set('chats', $chats);
$id = $chats['Chat']['user_id'];
$userdetails = $this->Chat->User->find('first', array(
'conditions' => array(
'id' => $id
),
recursive' => -1
));
return $userdetails;
}
}
?>
view.ctp
<?php
foreach($chats as $chat) :
echo "<tr>";
echo "<td>".$userdetails['User']['firstname']."</td>";
echo "<td>".$chat['Chat']['user_id']."</td>";
echo "<td>".$chat['Chat']['text']."</td>";
echo "<td>".$chat['Chat']['created']."</td>";
echo "</tr>";
endforeach
?>
The array I get returned in $chats
[Chat] => Array
(
[id] => 1
[user_id] => 11
[text] => hello
[created] => 2014-05-21 19:56:16
[modified] => 2014-05-21 19:56:16
)
Change
return $userdetails;
to
$this->set(compact('userDetails'));
You are supposed to set the view var not return the info.
Though why are you making a separate query for it instead of just using 'recursive' => 0 which would get the associated user record through table join and you can just use $chat['User']['firstname'] in view.
Also get rid of var $uses = array('User', 'Chat');. It's not needed. $this->Chat is already available and the User model is accessed through association as $this->Chat->User as you have already done.
You need charge the model in your controller
class ChatsController extends AppController {
public function view() {
$this->loadModel('User');
$this->loadModel('Chat');
$chats = $this->Chat->find('all', array(
'order' => array('id' => 'ASC'),
'recursive' => -1
));
$this->set('chats', $chats);
$id = $chats['Chat']['user_id'];
$userdetails = $this->Chat->User->find('first', array(
'conditions' => array(
'id' => $id
),
recursive => -1
));
$this->set(compact('userDetails'));
}
}
I found the solution and it's closer than I thought of myself. Because the Models User and Chat were already joined I just had to use a couple of lines in the Controller. So I modified it like this:
public function view() {
$chats = $this->Chat->find('all');
$this->set('chats', $chats);
}
And nothing more...

Yii CGridView handle special cases using model function

Having some trouble with CGridView on Yii Framework...
I'm looking to replace the contents of a column based on the value it holds.
I need to handle special cases so I added a function into the model to return a value to the GridView.
I get the resulting error " Undefined variable: model ".
I'm sure it's likely something simple. Is it because my dataProvider is not model?
Here is a shortened version of my code:
<?php
/* #var $this BookController */
/* #var $dataProvider CActiveDataProvider */
/* #var $model Book */
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'book-grid',
'dataProvider'=>$dataProvider,
'columns'=>array(
array(
'name'=>'userName',
'header'=>'Name',
),
array(
'name'=>'status',
'header'=>'Status',
'type'=>'raw',
'value'=>array($model, 'statusText')
),
)
));
?>
And here is code in models/Book.php
class Book extends CActiveRecord
{
...
...
public function statusText($data, $row) {
$content = '';
if (CHtml::encode($data->status) == "processed") {
$content = "Process completed";
}
else if ($data->status=="") {
$content = "Queued for Processing";
}
else {
$content = CHtml::encode($data->status);
}
return $content;
}
...
...
}
Here is a simplified example from my current project;
<?php
//My controller
class NewsController extends CController {
//The admin action
public function actionAdmin() {
$model = new News;
$this->render('admin', array(
'model' => $model
));
}
}
//In my view file
$this->widget('ext.widgets.MyTbGridView', array(
'dataProvider' => $model->search(),
'columns' => array(
array(
'name' => 'id',
'filter' => false,
),
array(
'name' => 'title',
),
array(
'value' => array($model, 'gridDate')
),
),
));
//My model function
class News extends CActiveRecord {
public function gridDate($data, $row) {
return 'Date formatted!';
}
}
?>
The code 'value' => array($model, 'gridFormatDate'), is important. there are two possibilities here. The function can reside in the controller, in which case it should be 'value' => array($this, 'gridFormatDate'), or it can be in the model, in which case the correct code is given
In stead of array($model, 'statusText'), try '$data->statusText'.
The method in your model should be like this:
public function getStatusText() {
$content = '';
if (CHtml::encode($this->status) == "processed") {
$content = "Process completed";
}
else if ($this->status=="") {
$content = "Queued for Processing";
}
else {
$content = CHtml::encode($this->status);
}
return $content;
}

Categories