CakePHP find conditions not working - cakephp

I have an action for CommentsView in which i want to retrieve all the comments with a condition that Comment.post_id = Post.id but when i debug it, it gives me an empty array.
Action CommentsView:
public function commentsview()
{
$commentsview = $this->Comment->find('all', array('conditions'=>array('Comment.post_id' => 'Post.id')));
if (!empty($this->params['requested']))
{
return $commentsview;
}
}

You are providing the condition for a join which is passed differently.
The conditions arguments are for a WHERE clause.
But you only need to specify:
$comments = $this->Comment->find('all',
array(
'conditions'=>array(
'Comment.post_id' => $post_id
)
)
);
Or when you are fetching the comments from the PostsController
$comments = $this->Post->Comment->find('all',
array(
'fields'=>array(
'Comment.*'
)
'conditions'=>array(
'Post.id' => $post_id
)
)
);

change your function to this:
public function commentsview($post_id=null) {
$commentsview = $this->Comment->find('all', array('conditions'=>
array('Comment.post_id' => $post_id))
);
debug($commentsview);
exit;
}
Visit this URL: yourapp.com/comments/commentsview/37
The comments will be output. Now you know it's working. Then you can pass it to the view or do whatever.
You have asked similar questions several times. This is a BASIC concept.

Related

save is not working in cakeph when all is okay

My code:
$this->PackageCustomer->id = $customer_id;
$data['PackageCustomer'] = array(
'shipment' => 2,
'comments' => $this->request->data['Ticket']['content'],
'shipment_equipment' => $this->request->data['Ticket']['shipment_equipment'],
'shipment_note' => $this->request->data['Ticket']['shipment_note'],
'issue_id' => $this->request->data['Ticket']['issue_id']
);
pr($data); exit;
$this->PackageCustomer->save($data['PackageCustomer']);
//var_dump($this->PackageCustomer->invalidFields());
// pr($this->PackageCustomer->error);
echo $this->PackageCustomer->getLastQuery(); exit;
I inspect array $data. Data is being revived properly. And getLastQuery function is:
function getLastQuery() {
$dbo = $this->getDatasource();
$logs = $dbo->getLog();
$lastLog = end($logs['log']);
return $lastLog['query'];
}
Which is defined in appModel. I am using cakephp 2.6.9. But last query is :COMMIT which does not make any sense. I check My model convention. It is okay. Now what is the problem in my code?
Try this::
$this->PackageCustomer->id = $customer_id;
$data['PackageCustomer'] = array(
'shipment' => 2,
'comments' => $this->request->data['Ticket']['content'],
'shipment_equipment' => $this->request->data['Ticket']['shipment_equipment'],
'shipment_note' => $this->request->data['Ticket']['shipment_note'],
'issue_id' => $this->request->data['Ticket']['issue_id']
);
pr($data); exit;
$this->loadModel('PackageCustomer');
$this->PackageCustomer->save($data['PackageCustomer']);
//var_dump($this->PackageCustomer->invalidFields());
// pr($this->PackageCustomer->error);
echo $this->PackageCustomer->getLastQuery(); exit;
If the above code doesn't work I need the following answered to help further...
I need bit more information can you confirm the following:
What is the name of the table you are trying to save to?
What is the name of the class relating the to the table you are trying to save to?
Are you trying to edit or create a new record in this table?

Cakephp paginator array error

I'm new to CakePHP and have a question about this controller:
function showmy($userid) {
return $this->Voucher->find('all', array('conditions' => array('Voucher.user_id' => $userid)));
}
public function index() {
$this->Voucher->recursive = 0;
$userid = $this->Session->read('Auth.User.id');
$this->set('vouchers', $this->showmy($userid ));
}
I want all the Voucher with user_id by the loged in user.
It works, but i get many errors like :
Warning (2): array_filter() expects parameter 1 to be array, null given [CORE\Cake\View\Helper\PaginatorHelper.php, line 419]
Maybe someone with more experienced could give me some advice!
Thanks,
Julius
I think you need to use PaginatorComponent::paginate() to be able to use the PaginatorHelper in your view. More info in the manual.
You must declare $paginate array in you controller for the pagination
public $paginate = array(
'limit' => 25,
'order' => array(
'Post.title' => 'asc'
)
);
paginate => array
public function index() {
$this->Voucher->recursive = 0;
$userid = $this->Session->read('Auth.User.id');
$this->Paginator->settings = array(
array('conditions' => array('Voucher.user_id' => $userid))
);
$this->set('vouchers', $this->Paginator->paginate('Voucher'));
}

CakePHP Pagination: how can I sort by multiple columns to achieve "sticky" functionality?

I see that this paginate can't sort two columns at the same time ticket is still open, which leads me to believe that what I'm trying to do is not possible without a workaround. So I guess what I'm looking for is a workaround.
I'm trying to do what many message boards do: have a "sticky" function. I'd like to make it so that no matter which table header link the user clicks on to sort, my model's "sticky" field is always the first thing sorted, followed by whatever column the user clicked on. I know that you can set $this->paginate['Model']['order'] to whatever you want, so you could hack it to put the "sticky" field first and the user's chosen column second. The problem with this method is that pagination doesn't behave properly after you do it. The table header links don't work right and switching pages doesn't work right either. Is there some other workaround?
User ten1 on the CakePHP IRC channel helped me find the solution. I told him that if he posted the answer here then I would mark it as the correct one, but he said I should do it myself since he doesn't have a Stack Overflow account yet.
The trick is to inject the "sticky" field into the query's "order" setting using the model's "beforeFind" callback method, like this:
public function beforeFind($queryData) {
$sticky = array('Model.sticky' => 'DESC');
if (is_array($queryData['order'][0])) {
$queryData['order'][0] = $sticky + $queryData['order'][0];
}
else {
$queryData['order'][0] = $sticky;
}
return $queryData;
}
What you can do is code it in the action. Just create the query you want when some parameters exist on the URL. (parameters has to be sent by GET)
For example:
public function posts(){
$optional= array();
if(!empty($this->params->query['status'])){
if(strlower($this->params->query['status']=='des')){
$optional= array('Post.status DESC');
}
else if(strlower($this->params->query['status']=='asc')){
$optional= array('Post.status ASC');
}
}
if(!empty($this->params->query['department'])){
//same...
}
//order first by the sticky field and then by the optional parameters.
$order = array('Post.stickyField DESC') + $optional;
$this->paginate = array(
'conditions' => $conditions,
'order' => $order,
'paramType' => 'querystring',
);
$this->set('posts', $this->paginate('Post'));
}
I have used something similar to filter some data using $conditions instead of $order and it works well.
You can use custom field for sorting and update pagination component.
Controller code
$order['Document.DATE'] = 'asc';
$this->paginate = array(
"conditions"=> $conditions ,
"order" => $order ,
"limit" => 10,
**"sortcustom" => array('field' =>'Document.DATE' , 'direction' =>'desc'),**
);
Changes in pagination component.
public function validateSort($object, $options, $whitelist = array()) {
if (isset($options['sort'])) {
$direction = null;
if (isset($options['direction'])) {
$direction = strtolower($options['direction']);
}
if ($direction != 'asc' && $direction != 'desc') {
$direction = 'asc';
}
$options['order'] = array($options['sort'] => $direction);
}
if (!empty($whitelist) && isset($options['order']) && is_array($options['order'])) {
$field = key($options['order']);
if (!in_array($field, $whitelist)) {
$options['order'] = null;
}
}
if (!empty($options['order']) && is_array($options['order'])) {
$order = array();
foreach ($options['order'] as $key => $value) {
$field = $key;
$alias = $object->alias;
if (strpos($key, '.') !== false) {
list($alias, $field) = explode('.', $key);
}
if ($object->hasField($field)) {
$order[$alias . '.' . $field] = $value;
} elseif ($object->hasField($key, true)) {
$order[$field] = $value;
} elseif (isset($object->{$alias}) && $object->{$alias}->hasField($field, true)) {
$order[$alias . '.' . $field] = $value;
}
}
**if(count($options['sortcustom']) > 0 )
{
$order[$options['sortcustom']['field']] = $options['sortcustom']['direction'];
}**
$options['order'] = $order;
}
return $options;
}
Easy insert 'paramType' => 'querystring',
Show Code Example:
$this->paginate = array(
'conditions' => $conditions,
'order' => array(
'Post.name' => 'ASC',
'Post.created' => 'DESC',
),
'paramType' => 'querystring',
);
$this->set('posts', $this->paginate('Post'));

how to tell cakephp to use function index($type) to just go to the index page?

I have this application that directs users to Types of attractions with this function:
public function index($type=null) {
$this->set('title','What to do when you visit Gulf Shores');
$this->paginate['Attraction']=array(
'limit'=>9,
'order'=>array('Attraction.id'=>'asc'),
'conditions'=>array(
'active'=>1,
'attr_type'=>$type
)
);
$c=$this->paginate('Attraction');
$this->set('attractions', $c);
}
and it works great, but I'd like users to also be able to go to a front page /attractions/ that doesn't filter out by attr_type. This function shows zero results (as obviously $type still = null) for the front page. Is there a step I'm missing or must I have a view.ctp file and function in my controller?
You could use an if statement to determine the conditions:
public function index($type = null) {
$this->set('title', 'What to do when you visit Gulf Shores');
$conditions = array(); //create $conditions outside of the if statement
if ($type) { //if $type is equal to anything other than null or 0
$conditions = array(
'active' => 1,
'attr_type' => $type
);
} else {
$conditions = array(
'active' => 1
);
}
$this->paginate['Attraction'] = array(
'limit' => 9,
'order' => array('Attraction.id' => 'asc'),
'conditions' => $conditions
);
$c = $this->paginate('Attraction');
$this->set('attractions', $c);
}
It's not actually necessary to create $conditions outside of the if statement in PHP but it is in a lot of other programming languages because of scope.
If you create a variable inside a if statement is it available outside the if statement?

Never display some records in CakePHP

I would like return some records from my base (eg. users roles)
And I use usually function find(), findAll(), etc., and I always must write 'conditions' with like this: not display role admin (name!=admin).
My question is, how I can in RoleModel set for all function will be return with this conditions.
Sorry for english!
Bye!
Use the beforeFind() (http://book.cakephp.org/view/680/beforeFind) callback for this kind of thing. Here's one I use from time to time that ensures only active records are returned:
function beforeFind( $queryData )
{
$conditions = $queryData['conditions'];
if( !is_array( $conditions ) ) {
if( !$conditions ) {
$conditions = array();
}
else {
$conditions = array( $conditions );
}
}
if( !array_key_exists( $conditions, 'active' ) && !isset( $conditions[$this->alias . '.active'] ) ) {
$conditions[$this->alias . '.active'] = 1;
}
return true;
}
That's a bit off the cuff, so the syntax may not be exact, but it should give you something to start with. I think everything's in order except, perhaps, the argument order in a few function calls. Anyway, it should be close.
I think a better solution would be setting the condition in your hasMany relationship.
// User.php Model:
var $hasMany = array('Role' => array('conditions' => array('name <>' => admin)));
and vice versa, you can do it for your Role model:
// Role.php Model:
var $belongsTo = array('User' => array('conditions' => array('User.name <>' => admin)));

Resources