cakephp: how to use or/and in conditions of $paginate - cakephp

actually, i want to meet this sql requirement:
... where (type_id = 6 OR type_id = 8) and status = 2 ....
but i don NOT know how to set conditions in $paginate.
var $paginate = array(
'Student'=>array(
'limit' => 10,
'fields'=>array('Student.id','Student.firstname','Student.lastname'),
'order' =>array('Student.id'=>'desc'),
'conditions' => ?,
),
);
any one knows how to set conditions ?

Based on this site http://book.cakephp.org/1.3/view/1030/Complex-Find-Conditions
(It's not the lastes release, but try it)
var $paginate = array(
'Student'=>array(
'limit' => 10,
'fields'=>array('Student.id','Student.firstname','Student.lastname'),
'order' =>array('Student.id'=>'desc'),
'conditions' => array(
'Student.type_id' => array(6, 8),
'Student.status' => 2
)
),
);
or
var $paginate = array(
'Student'=>array(
'limit' => 10,
'fields'=>array('Student.id','Student.firstname','Student.lastname'),
'order' =>array('Student.id'=>'desc'),
'conditions' => array(
'Student.status' => 2,
"OR" => array (
'Student.type_id' => 6,
'Student.type_id' => 8
)
)
),
);
EDIT: This second version cannot be used in this situation, because now the OR array have two elements with the same keys and will check only the last (8)
[N.B.] Excuse me if I made some syntax error :)

Related

get data using not ids not working in cakephp

I want to select data for all rows where the below ids dont exist. I thought this would work but there is no error and the below ids still appear in the retrieved records. I am using cakephp 2.5 for this
$ids///
array(
(int) 0 => '14721',
(int) 1 => '14731',
(int) 2 => '14905',
(int) 3 => '15808',
(int) 4 => '15818',
$test=$this->Lessonbak->find('all', array(
'fields'=>array('id'),
'recursive' => -1 ) );
$ids=array();
foreach( $test as $item):
array_push($ids,$item['Lessonbak']['id']);
endforeach;
$lessonstudent2=$this->LessonsStudent2->find('all', array(
'conditions' => array( "NOT" => array( 'LessonsStudent2.lesson_id' => $ids )),
'recursive' => -1 ) );
Instead of selecting all of the Lessonbak ids, pushing them to an array, and using that in your LessonsStudent2 query, you should simply use a subquery:
$dbo = $this->getDataSource();
$subquery = $dbo->buildStatement(
array(
'table' => 'lessonbak',
'alias' => 'Lessonbak',
'recursive' => -1,
'fields' => array(
'Lessonbak.id'
)
),
$this
)
$this->LessonsStudent2->find('all', array(
'conditions' => array(
'NOT' => array(
'LessonsStudent2.lesson_id IN (' . $subquery . ')'
)
)
)

CakePHP find conditions with multiple 'OR'

I'm having a real headache getting this to work correctly. This is my desired outcome in raw MySQL:
WHERE `EmailTemplate`.`is_archived` = '0'
AND
((`EmailTemplate`.`project_id` IS NULL) OR (`EmailTemplate`.`project_id` = 101))
AND
((`EmailTemplate`.`user_id` IS NULL) OR (`EmailTemplate`.`user_id` = 44))
How does this translate into a CakePHP conditions array?
Solved this, eventually.
$templateConditions = array(
'EmailTemplate.is_archived' => 0,
'AND' => array(
'OR' => array(
array('EmailTemplate.project_id IS NULL'),
array('EmailTemplate.project_id' => $this->request->data['Project']['project_id'])
)
),
array(
'OR' => array(
array('EmailTemplate.user_id IS NULL'),
array('EmailTemplate.user_id' => $this->Auth->user('id'))
)
)
);

Joining two tables in CakePHP using bindModel method Cakephp

I am working on a cakephp 2.x .. I have two tables in my database both have the userid I am using bindModel.. my query is working fine ... I just have one problem .. I want to add the condition in where clause that
**where userid = $userid**
function getMessages($userid){
$this->bindModel(array(
'belongsTo' => array(
'Contact' => array(
'className' => 'Contact',
'foreignKey' => false,
'conditions' => array(
'Message.user_id = Contact.user_id',
'AND' =>
array(
array('OR' => array(
array('Message.mobileNo = Contact.mobileNo'),
array('Message.mobileNo = Contact.workNo'),
)),
)
),
'type' => 'LEFT',
)
)
), false);
return $this->find('all', array('conditions' => array(),
'fields' => array('Message.mobileNo'
),
'group' => 'Message.mobileNo',
'limit' => 6));
}
I am getting user id in parameter ... so I want to add the condition that get the following result where
message.userid and contact.userid = $userid ...
Just split the conditions in two lines like:
'conditions' => array(
'Contact.user_id' => $userid,
'Message.user_id = Contact.user_id',
[...]
)
But the approach that makes more sense is to leave the bind as is - after all the bind is generally between message users and contact users with the same id - and add the condition for the specific case in your find('all') with 'Message.user_id' => $userid.

Retrieve specific table fields in Cakephp

i have a table in which i want to get only two columns data .. right now i am using findAll method ... i don't know how can I get the specific two fields data in CakePHP
$recentContacts = $this->Contact->find('all',
array(
'order'=>'Contact.idContacts DESC',
'limit' => 6,
'conditions' => array(
'Contact.User_id' => $id)));
in my contacts table there are two fields one is "name" and other is "number"
which I want to extract ...
You can do this by adding fields attribute.
$recentContacts = $this->Contact->find('all',
array
(
'order'=> array( 'Contact.id' , 'Contacts DESC'),
'limit' => 6,
'fields' => array(
'Contact.name',
'Contact.number'
),
'conditions' => array
(
'Contact.User_id' => $id
)
));
you can use like this way with your same code to add fields
$recentContacts = $this->Contact->find('all',
array(
'order'=>'Contact.idContacts DESC',
'limit' => 6,
'fields' => array(
'Contact.name',
'Contact.number'
),
'conditions' => array(
'Contact.User_id' => $id)));
in previous answer they have changed you id instead of idContacts, you can just copy my code and solve your problem.
let me know if i can help you more.

CakePHP 2.x containable behavior conditions on deep associations

I have model relations like this:
Project hasMany SubProject hasMany Item
I want to set up a containable array so that I can find all of the Items which belong to a particular Project, and paginate the results. So, in my ItemsController I have:
public $paginate = array(
'Item' => array(
'limit' => 10,
'order' => array('
'Item.create_time' => 'desc'
),
'contain' => array(
'SubProject' => array(
'Project'
)
)
)
);
Somewhere, obviously, I need to place a condition like "SubProject.project_id = $pid", but nothing I've tried yields the correct results. The best I can manage is results that look like this:
Array
(
[0] => Array
(
[Item] => Array
(
[id] => 13
[file_name] => foo.tar.gz
.... other keys ...
[create_time] => 2013-01-23 14:59:49
[subProject_id] => 4
)
[SubProject] => Array
(
[id] => 4
[name] => foo
[project_id] => 2
..... other keys ....
[Project] => Array
(
)
)
)
[1] => Array
.....
Edit: It is quite correctly omitting the Project record that doesn't match; I want to skip any Item records with out a matching Project record.
It has crossed my mind to manually specify my joins, but I feel like that shouldn't be necessary.
It seems like this should be obvious, but alas, the solution escapes me.
I did eventually solve this problem, so I thought I'd explain what I did in the hope it might help someone else.
After reading this blog post by Mark Story (which is from the days of 1.2 but still relevant) I decided that the thing to do was create a custom find type in my Item model that binds the Project model directly. This gives a first-level association that Containable can filter correctly.
So, in the Items model, I have something like the following (see the documentation on custom find types).
public $findMethods = array('byProject' => true);
public function _findByProject($state, $query, $results=array()) {
if ($state == 'before') {
$this->bindModel(array(
'hasOne' => array(
'Project' => array(
'foreignKey' => false,
'conditions' => array('Project.id = SubProject.project_id')
)
)
));
return $query;
}
return $results;
}
Note that setting foreignKey to false is necessary to prevent CakePHP from trying to automatically use a non-existent database key. In the ItemsController, the pagination options now look like this:
public $paginate = array(
'Item' => array(
'findType' => 'byProject',
'limit' => 10,
'order' => array(
'Item.create_time' => 'desc'
),
'contain' => array(
'SubProject',
'Project'
),
'conditions' => array('Project.id' = $pid)
),
);
...where $pid is the id of the project to display. Some minor tweaks in the view code to accomodate the slightly different results array structure, and I was all set.
EDIT ===============
public $paginate = array(
'limit' => 10,
'order' => 'Item.create_time DESC', //'order' => array(''Item.create_time' => 'desc'),
'contain' => array(
'SubProject' => array(
'Project' => array(
'conditions' => array(
'id' => $project_id // Passed parameter
)
)
)
)
);
=================================================
Have you tried using conditions as in the following? Also, I did not write the 'order' section of the code the way you have it.
public $paginate = array(
'Item' => array(
'limit' => 10,
'order' => 'Item.create_time DESC', //'order' => array(''Item.create_time' => 'desc'),
'contain' => array(
'SubProject' => array(
'Project' => array(
'conditions' => array(
'id' => $project_id // Passed parameter
)
)
)
)
)
);

Resources