Add one more condition in controller with cakephp - cakephp

I have created following function in controller:
function beg($status_id = null) {
if(!empty($status_id)){
$conditions = array('winner_id >' => 0, 'Product.beginner' => '1', 'Product.status_id' => $status_id);
}else{
$conditions = array('winner_id >' => 0, 'Product.beginner' => '1');
}
$this->paginate = array('conditions' => $conditions, 'limit' => $this->appConfigurations['adminPageLimit'], 'order' => array('end_time' => 'asc'), 'contain' => array('Product' => array('Category'), 'Status', 'Winner'));
$this->set('products', $this->paginate('Product'));
$this->set('statuses', $this->Product->Status->find('list'));
$this->set('selected', $status_id);
$this->set('extraCrumb', array('title' => __('Product List', true), 'url' => 'beg'));
$this->render('beg');
}
I want to add one more condition in it, that is:
Search winner_id from Accounts table match with 'user_id' in accounts table, and only add Products in the list where winner Id is in Accounts table ('user_id' in accounts table).
Anybody know how to add condition with this $conditions = array('winner_id >' => 0, 'Product.beginner' => '1', 'Product.status_id' => $status_id);
I have added on more condition like below
$acc_id = $this->Account->find('all', array('Account.user_id'));
$conditions += array('Product.winner_id' => $acc_id);
But its not working, anybody please tell me where I am getting wrong

if you wanted to add one more condition to the $conditions than you can try using code
$conditions += array('Product.status_id' => $status_id);
hope it will help

yes you can add it with code like below
if ($account_user){
$conditions['accounts.user_id'] = $account_userid;
}
above code will add one more conditions in same array $conditions.

Related

CakePHP - select from database with condition

I have this selector:
$this->Table->find('list',array('contain'=>false,'conditions'=>array('status'=>1,'unit_id'=>null,'country_id'=>$countryId,'eday'=>$eday),'fields'=>'id'));
And this works perfect. But now i need to have another one i cant find how to do this ;)
I need to select all records from Table but with condition:
'eday'>=$eday AND 'eday'<$eday+7
Its this posibble in easy way? Maybe this is stupid question but i dont have exp in PHP ;)
In cakephp the equivalent for and condition is
Example: column1 = 'value' AND column2 = 'value'
'AND' => array(
'column1' => 'value',
'column2' => 'value'
)
So your query builder would be like this
$this->Table->find('list',array(
'contain' => false,
'conditions' => array(
'status' => 1,
'unit_id' => null,
'country_id' => $country,
'AND' => array(
'eday >=' => $eday,
'eday <' => ($eday+7)
)
),
'fields'=>'id'
));
Just pass an AND array with in your current conditions array :
$this->Table->find('list',array('contain'=>false, 'conditions'=>array('status'=>1,'unit_id'=>null,'country_id'=>$countryId,'eday'=>$eday, AND => array( array('eday >=' => $eday) , array( 'eday <' => $eday+7) )), 'fields'=>'id' ));
Have you tried something like this :
$conditions['status'] = 1;
$conditions['unit_id'] = null;
$conditions['country_id'] = $countryId;
$conditions['eday >='] = $eday;
$conditions['eday <'] = $eday + 7;
$this->Table
->find('list') //either use this
->find('all') //or use this
->find() //or this
->where($conditions)
->select(['addFiledsToSelectHere'])
This looks more cleaner.

CakePHP: How to make the paginator component use distinct counting?

I am making simple pagination which using this code:
$paginate = array(
'limit' => 30,
'fields' => array('DISTINCT Doctor.id','Doctor.*'),
'order' => array('Doctor.id' => 'desc'),
'joins' => array(
array('table' => 'doctors_medical_degrees',
'alias' => 'DoctorsMedicalDegree',
'type' => 'INNER',
'conditions' => array(
'Doctor.id = DoctorsMedicalDegree.doctor_id',
)
),
),
'recursive' => -1,
);
$this->Paginator->settings = $paginate;
$data = $this->Paginator->paginate('Doctor');
Now the problem is I am using Inner join so for Distinct result I am using Distinct Doctor.id, but the cakephp when doing query for pagination the count query not including Distinct Doctor.id
'query' => 'SELECT COUNT(*) AS `count` FROM `pharma`.`doctors` AS `Doctor` INNER JOIN `pharma`.`doctors_medical_degrees` AS `DoctorsMedicalDegree` ON (`Doctor`.`id` = `DoctorsMedicalDegree`.`doctor_id`)'
as you can see No
COUNT(DISTINCT Doctor.id)
so pagination return more number of result which it can actually return for
The problem is that the paginator doesn't pass the fields to the find('count') call, so by default it will always count on *.
But even if it would pass the fields, passing an array would make the find('count') call expect that the field to count is passed as a COUNT() expression, ie something like
'fields' => array('COUNT(DISTINCT Doctor.id) as `count`')
However that won't work with the paginator anyways, so what you need is a customized find('count') call.
Custom query pagination to the rescue
See Cookbook > Pagination > Custom Query Pagination for more information.
Custom query pagination is probably your best bet, that way it's totally up to you how counting is being done.
For example you could make use of the extra values passed by the paginator component, that way you could pass the field to count on to the find('count')` call, something like this (untested example code):
class Doctor extends AppModel {
// ...
public function paginateCount($conditions = null, $recursive = 0, $extra = array()) {
$parameters = compact('conditions');
if($recursive != $this->recursive) {
$parameters['recursive'] = $recursive;
}
if(!empty($extra['countField'])) {
$parameters['fields'] = $extra['countField'];
unset($extra['countField']);
}
return $this->find('count', array_merge($parameters, $extra));
}
}
$this->Paginator->settings = array(
'limit' => 30,
'fields' => array('DISTINCT Doctor.id','Doctor.*'),
// ...
'countField' => 'DISTINCT Doctor.id'
);
$data = $this->Paginator->paginate('Doctor');
This should then create a COUNT query that looks like
SELECT COUNT(DISTINCT Doctor.id) AS `count` ...
I found the solution on CakePHP - Pagination total count differs from actual count when using DISTINCT
Add the public function paginateCount in your model and use the distinct option in your paginator like:
$this->paginate = array('limit' => $limit, 'order' => array('Item.created' => 'ASC', 'Item.code' => 'ASC'),
'fields' => 'DISTINCT Item.*',
'conditions' => $conditions,
'countField' => array('Item.id'),
'joins' => $joins,
'distinct' => 'Item.id',
'contain' => array(
'Image' => array('limit' => 1),
'ItemsTag'
)
);

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.

Cakephp IN(x,x) with 'AND'

I am struggeling with a custom find in cakephp 2.1.
In my model I have this function:
public function findByGenres($data = array()) {
$this->Item2genre->Behaviors->attach('Containable', array('autoFields' => false));
$this->Item2genre->Behaviors->attach('Search.Searchable');
$query = $this->Item2genre->getQuery('all', array(
'conditions' => array('Genre.name' => $data['genre']),
'fields' => array('item_id'),
'contain' => array('Genre')
));
return $query;
}
This returns the following query:
SELECT `Item`.`id` FROM `items` AS `Item`
WHERE `Item`.`id`
IN(SELECT `Item2genre`.`item_id` FROM `item2genre` AS Item2genre
LEFT JOIN `genres` AS Genre ON(`genre_id` = `Genre`.`id`)
WHERE `Genre`.`name`
IN ('Comedy', 'Thriller')
)
The result of the query returns Items with either 'Comedy' or 'Thriller' genre associated to them.
How can I modify the query to only return Items with 'Comedy' AND 'Thriller' genre associated to them?
Any suggestions?
edit:
content of data is:
'genre' => array(
(int) 0 => 'Comedy',
(int) 1 => 'Thriller'
)
You would want your 'conditions' key to be this:
'conditions' => array(
array('Genre.name' => 'Comedy'),
array('Genre.name' => 'Thriller')
)
So specifically to your problem your $data['genre'] is array('Comedy', 'Thriller'). So you could create a variable that has contents similar to what you need by doing:
$conditions = array();
foreach ($data['genre'] as $genre) {
$conditions[] = array('Genre.name' => $genre);
}

Cakephp $this->paginate with custom JOIN and filtering options

I've been working with cakephp paginations options for 2 days. I need to make a INNER Joins to list a few fields, but I have to deal with search to filter results.
This is portion of code in which I deal with search options by $this->passedArgs
function crediti() {
if(isset($this->passedArgs['Search.cognome'])) {
debug($this->passedArgs);
$this->paginate['conditions'][]['Member.cognome LIKE'] = str_replace('*','%',$this->passedArgs['Search.cognome']);
}
if(isset($this->passedArgs['Search.nome'])) {
$this->paginate['conditions'][]['Member.nome LIKE'] = str_replace('*','%',$this->passedArgs['Search.nome']);
}
and after
$this->paginate = array(
'joins' => array(array('table'=> 'reservations',
'type' => 'INNER',
'alias' => 'Reservation',
'conditions' => array('Reservation.member_id = Member.id','Member.totcrediti > 0' ))),
'limit' => 10);
$this->Member->recursive = -1;
$this->paginate['conditions'][]['Reservation.pagamento_verificato'] = 'SI';
$this->paginate['fields'] = array('DISTINCT Member.id','Member.nome','Member.cognome','Member.totcrediti');
$members = $this->paginate('Member');
$this->set(compact('members'));
INNER JOIN works good, but $this->paginations ignore every $this->paginate['conditions'][] by $this->passedArgs and I cannot have idea how I can work it out.
No query in debug, just the original INNER JOIN.
Can someone helps me ?
Thank you very much
Update:
No luck about it.
I've been dealing with this part of code for many hours.
If I use
if(isset($this->passedArgs['Search.cognome'])) {
$this->paginate['conditions'][]['Member.cognome LIKE'] = str_replace('*','%',$this->passedArgs['Search.cognome']);
}
$this->paginate['conditions'][]['Member.sospeso'] = 'SI';
$this->Member->recursive = 0;
$this->paginate['fields'] = array(
'Member.id','Member.nome','Member.cognome','Member.codice_fiscale','Member.sesso','Member.region_id',
'Member.district_id','Member.city_id','Member.date','Member.sospeso','Region.name','District.name','City.name');
$sospesi = $this->paginate('Member');
everything goes well, and from debug I receive the first condition and the conditions from $this->paginate['conditions'][]['Member.cognome LIKE'], as you can see
array $this->passedArgs
Array
(
[Search.cognome] => aiello
)
Array $this->paginate['conditions'][]
(
[0] => Array
(
[Member.cognome LIKE] => aiello
)
[1] => Array
(
[Member.sospeso] => NO
)
But, if I write the joins with paginate , $this->paginate['conditions'][] will ignore all the stuff, and give me from debug, just $this->paginate['conditions'][]['Reservation.pagamento_verificato'] = 'SI';
Another bit of information.
If I put all the stuff dealing with $this->paginate['conditions'][]['Reservation.pagamento_verificato'] = 'SI';
before the $this->paginate JOIN, nothing will be in $this->paginate['conditions'][].
This is an old question, so I'll just review how to do a JOIN in a paginate for others who got here from Google like I did. Here's the sample code from the Widget's Controller, joining a Widget.user_id FK to a User.id column, only showing the current user (in conditions):
// Limit widgets shown to only those owned by the user.
$this->paginate = array(
'conditions' => array('User.id' => $this->Auth->user('id')),
'joins' => array(
array(
'alias' => 'User',
'table' => 'users',
'type' => 'INNER',
'conditions' => '`User`.`id` = `Widget`.`user_id`'
)
),
'limit' => 20,
'order' => array(
'created' => 'desc'
)
);
$this->set( 'widgets', $this->paginate( $this->Widget ) );
This makes a query similar to:
SELECT widgets.* FROM widgets
INNER JOIN users ON widgets.user_id = users.id
WHERE users.id = {current user id}
And still paginates.
I'm not sure if you need those [] - try just doing this:
$this->paginate['conditions']['Reservation.pagamento_verificato'] = 'SI';
I use the conditions when I call paginate method.
$this->paginate($conditions)
This works ok for me, I hope it works for you!
If you have setted previous params, you may use:
$this->paginate(null,$conditions)
This might be help full to someone....
This is how I did complicated joins with pagination in cakephp.
$parsedConditions['`Assessment`.`showme`'] = 1;
$parsedConditions['`Assessment`.`recruiter_id`'] = $user_id;
$this->paginate = array(
'conditions' => array($parsedConditions ),
'joins' => array(
array(
'alias' => 'UserTest',
'table' => 'user_tests',
'type' => 'LEFT',
'conditions' => '`UserTest`.`user_id` = `Assessment`.`testuser_id`'
),
array(
'alias' => 'RecruiterUser',
'table' => 'users',
'type' => 'LEFT',
'conditions' => '`Assessment`.`recruiter_id` = `RecruiterUser`.`id`'
)
,
array(
'alias' => 'OwnerUser',
'table' => 'users',
'type' => 'LEFT',
'conditions' => '`Assessment`.`owner_id` = `OwnerUser`.`id`'
)
),
'fields' => array('Assessment.id', 'Assessment.recruiter_id', 'Assessment.owner_id', 'Assessment.master_id', 'Assessment.title', 'Assessment.status', 'Assessment.setuptype','Assessment.linkkey', 'Assessment.review', 'Assessment.testuser_email', 'Assessment.counttype_2', 'Assessment.bookedtime', 'Assessment.textqstatus', 'Assessment.overallperc', 'UserTest.user_id', 'UserTest.fname', 'UserTest.lname', 'RecruiterUser.company_name', 'OwnerUser.company_name'),
'limit' => $limit,
'order'=> array('Assessment.endtime' => 'desc')
);

Resources