How can i set orderby in cakephp - cakephp

This is my code ,here how can i give orderby .
$this->set('added', $this->paginate('TravancoMarketing', array('status = 0', 'assigned_by = '.$user_level)));
Here i want to give order by TravancoMarketing.id DESC
How can i give this?

You can either add it as the default order by to the TravancoMarketing model:
class TravancoMarketing {
public $order = array('TravancoMarketing.id'=>'DESC');
}
or to the paginate query itself:
$this->paginate = array(
'conditions'=>array(
'TravancoMarketing.status'=>0,
'TravancoMarketing.assigned_by'=>$user_level
),
'order'=>array(
'TravancoMarketing.id'=>'DESC'
)
);
$this->set('added', $this->paginate('TravancoMarketing'));

in your controller you should declare something like this:
public $paginate = array(
'order' => array(
'TravancoMarketing.id' => 'DESC'
)
);

Related

Paginate ignores conditions

when I try to run this code, it will not change my query, the condition is just not taken:
$this->paginate = array(
'conditions' => array(
'campaign_id' => $this->request->data['Campaign']['campaign_id']
)
);
$this->set('products', $this->Paginator->paginate());
the query looks like this
SELECT
`Product`.`id`, `Product`.`campaign_id`, `Campaign`.`id`, `Campaign`.`title`, `Campaign`.`text`
FROM
`db`.`products` AS `Product`
LEFT JOIN
`db`.`campaigns` AS `Campaign` ON (`Product`.`campaign_id` = `Campaign`.`id`)
WHERE
1 = 1
LIMIT
20
Is there anything wrong in my syntax?
(CakePHP 2.5.1)
What #ndm means is replace your existing code with this:
$this->Paginator->settings['conditions'] = array(
'Product.campaign_id' => $this->request->data['Campaign']['campaign_id']
)
$this->set('products', $this->Paginator->paginate());

how to pass raw sql query into paginator component in cakephp

I have row sql query and i want to paginate this query with the help of cakephp paginator component.How could i ?
$q = "SELECT
`UserList`.`id`,`UserList`.`user_id`,`UserList`.`list_user_id`,
`User`.`username` ,`User`.`id` ,
`UserDetail`.`sex`,`UserDetail`.`image`,`UserDetail`.`display_name`,`UserDetail`.`country`,`UserDetail`.`height`,`UserDetail`.`weight`,`UserDetail`.`hair_color`,`UserDetail`.`eye_color`
from `user_lists` as `UserList`
inner join `users` as `User` on `UserList`.`list_user_id` = `User`.`id`
inner join `user_details` as `UserDetail` on `UserList`.`list_user_id` = `UserDetail`.`user_id`
where ((`UserList`.`user_id`=".$user_id.") and (`UserList`.`in_list`='short')) order by `UserList`.`created` desc limit 1";
$this->paginate = array(
'conditions' => /*Pass $q here */,
'limit' => 15,
)
);
thanks in advance.
You don't
That just doesn't work, from the query in the question though, all you need is to use pagination as normal:
class UserListsController extends AppController {
public $paginate = array(
'contain' => array(
'User',
'UserDetail'
)
);
public function index($userId = null) {
$conditions = array(
'user_id' => $userId,
'in_list' => 'short'
);
$data = $this->paginate($conditions);
$this->set('data', $data);
}
}

cakephp paginate with group and group count

I have a db table with items with a matching group_id. I'd like to display those items in a paginator like this:
codeset_id - itemsInGroupCount
group1 - 3
group2 - 6
How can I do this? I have the distinct groups but how do I get the count?
My Controller:
public function admin_index() {
$this->Codesetitem->recursive = 0;
$this->paginate = array(
'Codesetitem' => array(
'group' => 'codeset_id',
'order' => array('codeset_id' => 'asc')
)
);
$this->set('codesetitems', $this->paginate());
}
The following seems to work on my side:
public $components = array('Paginator');
public function index() {
$this->Paginator->settings = array(
'fields' => array('Item.group_id', 'COUNT(*) AS "Item.group_count"'),
'limit' => 3,
'group' => 'group_id'
);
$this->set('items', $this->Paginator->paginate('Item'));
}
I simply added COUNT(*) AS "Foo.bar" to the fields key.

CakePHP Pagination. Keeping Model Fat

I currently have this in my Model (Referer Model):
public function getReferers($type = 'today') {
if ($type == 'this_month') {
return $this->_getThisMonthsReferers();
} elseif ($type == 'today') {
return $this->_getTodaysPageReferers();
}
}
private function _getThisMonthsReferers() {
$today = new DateTime();
return $this->Visitor->find('all', array(
'fields' => array(
'Referer.url',
'COUNT(UserRequest.visitor_id) as request_count',
'COUNT(DISTINCT(Visitor.id)) as visitor_count',
'COUNT(UserRequest.visitor_id) / COUNT(DISTINCT(Visitor.id)) as pages_per_visit',
'COUNT(DISTINCT(Visitor.id)) / COUNT(UserRequest.visitor_id) * 100 as percent_new_visit'
),
'joins' => array(
array(
'table' => 'user_requests',
'alias' => 'UserRequest',
'type' => 'RIGHT',
'conditions' => array(
'UserRequest.visitor_id = Visitor.id'
)
)
),
'conditions' => array(
'Visitor.site_id' => $this->Site->id,
'MONTH(UserRequest.created)' => $today->format('m'),
'YEAR(UserRequest.created)' => $today->format('Y')
),
'group' => array(
'url'
)
));
}
The thing is that I how I would paginate this. It will be so easy if just copy my code out of the model and to the controller. The thing is I want the keep the query in my Model.
How is this supposed to be done in CakePHP?
A custom find type is one method. You can find more information here: http://book.cakephp.org/2.0/en/core-libraries/components/pagination.html#custom-query-pagination
To turn your _getThisMonthsReferers into a custom find, follow this http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#creating-custom-find-types
For example:
// model
protected function _findThisMonthsReferers($state, $query, $results = array()) {
if ($state === 'before') {
$query['fields'] = ....
$query['joins'] = ....
return $query;
}
return $results;
}
// controller
public $paginate = array('findType' => 'thisMonthsReferers')
EDIT:
I think it should be :
public $paginate = array('thisMonthsReferers');
However the Solution I used derived from this answer is adding this to the method I am using
$this->paginate = array('thisMonthsReferers');
Since I don't want i used in all my actions. Then paginating the Model like this.
$this->paginate('Visitor);
Instead of returning the results of the find, just return it's array of options:
return array(
'fields' => array(
//...etc
Then use those options to paginate in the controller. More details on this answer of this similar question: Paginate from within a model in CakePHP
It still keeps the model fat (with any logic that might alter the conditions, joins, fields...etc), and the controller skinny, which just uses the returned array as paginate options.

CakePHP 2.0: display associated records

I know the solutions is simple and might have something to do with the Containable behavior but I can't get it working. Without all the tries
This is the case. I'd like to display the Event details of an Event (eg. a conference). Each event takes place in a EventVenue and each EventVenue is located in a Country.
So in the Country Model the following is present:
public $hasMany = array(
'EventVenue' => array(
'className' => 'EventVenue',
'foreignKey' => 'country_id'
))
In the EventVenue model a BelongsTo association is made
public $belongsTo = array(
'Country' => array(
'className' => 'Country',
'foreignKey' => 'country_id'
))
And in the Event model a hasOne association is made
public $hasOne = array(
'EventVenue' => array(
'className' => 'EventVenue',
'foreignKey' => 'event_id',
))
What I want is to display the country name on the page that is renderd in the EventsController. I do get all the Event and EventVenue data but the associated Country for the venue is not retrieved.
The data is retrieved in the following way
$item = $this->Event->findBySlug($slug);
How can I also get the country name (eg. Netherlands) retrieved from the database? I tried something like this but that did not work:
$item = $this->Event->findBySlug($slug,array(
'contain' => array(
'Event' => array(
'EventVenue' => array(
'Country'
)
)
)
)
Try this:
$item = $this->Event->findBySlug($slug,array(
'contain' => array(
'EventVenue' => array(
'Country'
)
)
);
Update
Turns out findBy does not support Containable. You could use this to get the desired result:
$item = $this->Event->find('first',array(
'conditions' => array(
'Event.slug' => $slug
),
'contain' => array(
'EventVenue' => array(
'Country'
)
)
);
Oh and make sure you have this in the model: public $actsAs = array('Containable');
try this method:
$this->Event->recusive = 2;
$item = $this->Event->findBySlug($slug);
You need to set the recursive to 2 before you make the find, something like this
$this->Event->recursive = 2;
with this, you'll get the Event, the EventVenue and the Country on one shot
Hope it helps

Resources