CakePHP check two find conditions at the same time - php

I have the following find code:
if($this->User->find('first', array(
'conditions' => array(
'User.username' => $this->data['User']['username'],
'User.email' => $this->data['User']['username'])
)))
The idea is that it will find if a user exists with an email or username that matches what was sent in the username input field.
The problem is that in fact it will try and match BOTH rather than one or the other which is what I really want. How do I do this though?
I tried with the following but still no success:
if($this->User->find('first', array(
'conditions' => array('OR' => array(
array('User.username' => $this->data['User']['username']),
array('User.email' => $this->data['User']['username'])))))
Thanks

You were close, it should go like this
$opts = array(
'conditions' => array(
'or' => array(
'User.username' => $this->data['User']['username'],
'User.email' => $this->data['User']['username']
)
)
)
$this->User->find('first', $opts)

Related

CakePHP multiple request

I am facing the issue of multiple request at same time.I am checking in DB if this data exists then not insert the same record.
Using cakephp 2.6 version
$userdata = $this->MobappFan->find('first', array(
'conditions' => array(
'MobappFan.id' => 123,
'MobappFan.mobapp_id' => 234,
'MobappFan.deleted' => 0
),
'fields' => array('MobappFan.id', 'MobappFan.status', 'MobappFan.blocked'),
'contain' => false
)
);
if(!$userdata) {
$this->MobappFan->save($this->request->data);
}
But due to same request with same parameters is not able to find the existing record.
Please help
Thanks
I think basically you just want to not check in the current posted id
you can do this as below
$userdata = $this->MobappFan->find('first', array(
'conditions' => array(
'MobappFan.id' => 123,
'MobappFan.id !=' => $this->request->data['MobappFan']['id'],
'MobappFan.mobapp_id' => 234,
'MobappFan.deleted' => 0
),
'fields' => array('MobappFan.id', 'MobappFan.status', 'MobappFan.blocked'),
'contain' => false
)
);
if(!$userdata) {
$this->MobappFan->save($this->request->data);
}
or
$userdata = $this->MobappFan->find('first', array(
'conditions' => array(
'MobappFan.id' => 123,
"NOT" => array( 'MobappFan.id' => $this->request->data['MobappFan']['id']),
'MobappFan.mobapp_id' => 234,
'MobappFan.deleted' => 0
),
'fields' => array('MobappFan.id', 'MobappFan.status', 'MobappFan.blocked'),
'contain' => false
)
);
if(!$userdata) {
$this->MobappFan->save($this->request->data);
}
Hope this helps. If you can explain more what you need then I can write a better conditions or you can check details here

CakePHP find not inserting correct quotes into query

I am using this code to make a list of truck types counted and sorted by type.
$count['type'] = $this->Type->find('all',
array('joins' => array(
array(
'table' => 'truck_has_types',
'alias' => 'TruckHasTypes',
'type' => 'LEFT',
'conditions' => array(
'Type.id' => 'TruckHasTypes.types_id',
)
)
),
'fields' => array(
'Type.id',
'Type.name',
'COUNT(TruckHasTypes.types_id) as N'),
'group' => 'TruckHasTypes.types_id'
)
);
The query only returns a single result even thought there should be many more. I found the culprit. The query looks like this (got this from sql_dump)
SELECT `Type`.`id`, `Type`.`name`, COUNT(`TruckHasTypes`.`types_id`) as N FROM `douglass_cake`.`types` AS `Type` LEFT JOIN `douglass_cake`.`truck_has_types` AS `TruckHasTypes` ON (`Type`.`id` = 'TruckHasTypes.types_id') WHERE 1 = 1 GROUP BY `TruckHasTypes`.`types_id`
You can see that
ON (`Type`.`id` = 'TruckHasTypes.types_id')
Does no have the same quotes as
ON (`Type`.`id` = `TruckHasTypes`.`types_id`)
I have added those quotes manually in phpmyadmin and the query is successful, but I cannot not get cakephp to automatically generate this query. Any ideas?
Thank you!
Ryan
Do it this way:
$count['type'] = $this->Type->find('all',
array(
'joins' => array(
array(
'table' => 'truck_has_types',
'alias' => 'TruckHasTypes',
'type' => 'LEFT',
'conditions' => array(
'Type.id=TruckHasTypes.types_id',
)
)
),
'fields' => array(
'Type.id',
'Type.name',
'COUNT(TruckHasTypes.types_id) as N'
),
'group' => 'TruckHasTypes.types_id'
)
);
Instead of writing joins do it "Cake way" — write model association: Associations: Linking Models Together
Also does 'group' => 'TruckHasTypes.types_id' needs to be one level upper?

CakePHP getting data form an ID which is inside another table?

Right, so my data returns in the following way,
(int) 0 => array(
'MODEL-XX' => array(
//DATA HERE
'xxs_id' => '11',
'aas_id' => '44',
'vvs_id' => '2'
),
'xxs' => array(
'id' => '11',
'customername' => 'XX name here'
),
'aas' => array(
'id' => '44',
'clientname' => 'aa name here',
'xxs_id' => '11'
),
'vvs' => array(
'id' => '2',
'start' => '1405296000',
'end' => '1405814400',
'users_id' => '1'
)
This works fine, but I want to know how to link my users table to this model. So the details of each user for my VV model would become apart of the data. My MODEL-XX does not have any links with my users table so the place I need to call in the users details are held with my VV model.
I have been looking into this but have not been able to find a simple easy method for doing this?
I was thinking that this would be doable with my model, so I opened my my XX model and added the following within my '$belongsTo' section,
'Users' => array(
'className' => 'Users',
'foreignKey' => 'vvs.users_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
So is there a easy method for linking data like this?
Please give me time, if I have not explained myself right or not enough data, please tell me and let me fix or explain better.
Thanks,
Either set your recusive higher:
$this->MODEL-XX->recursive = 1; //or 2
Or and this should be your prefered way to go, start using the containable behaviour:
http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html
In your appModel:
public $actsAs = array('Containable');
Then try this find:
$this->MODEL-XX->recursive = -1;
$data = $this-MODEL-XX>find(
'all', array(
'conditions' => $conditions,
'contain' => array('xxs', 'aas', 'vvs', 'user')
)
);
I might be 'vvs.user' but I forgot what is used for deeper models

CakePHP find all not setting values to variables. All other find functions working

In my controller I have two functions that pull all records from the db with a status = 4. In one function it works fine. I copied the find all statement from the working function:
$this->set('completed', $this->Topic->find('all', array('fields' => array(
'Topic.creator','Topic.link','Topic.id', 'Topic.topic_name', 'Topic.info', 'Topic.priority', 'Topic.user_id',
'Topic.completed','Topic.created', 'Topic.status','User.name','User.id','Topic.category','Topic.tags'),'conditions' => array(
'Topic.status' => 4))));
But in the new function the $completed array doesn't seem to exist. The debug statement is just a blank line. If I debug the sql log using debug($this->Topic->getDataSource()->getLog()); this is the returned array:
Array
(
[log] => Array
(
[0] => Array
(
[query] => SELECT `Topic`.`creator`, `Topic`.`link`, `Topic`.`id`, `Topic`.`topic_name`, `Topic`.`info`, `Topic`.`priority`, `Topic`.`user_id`, `Topic`.`completed`, `Topic`.`created`, `Topic`.`status`, `User`.`name`, `User`.`id`, `Topic`.`category`, `Topic`.`tags` FROM `topics` AS `Topic` LEFT JOIN `users` AS `User` ON (`Topic`.`user_id` = `User`.`id`) LEFT JOIN `events` AS `Event` ON (`Event`.`topic_id` = `Topic`.`id`) WHERE `Topic`.`status` = 4
[affected] => 9
[numRows] => 9
[took] => 0
)
)
[count] => 1
[time] => 0
)
The SQL statement in the log works. If I plug in into mySQL it produces results. And the affected and numRows field show the correct number of records. But the produced data isn't being set to variables. Any ideas would be greatly appreciated. My boss and I are stumped. Here are both complete functions:
public function dashboard(){
$this->set('completed', $this->Topic->find('all', array('fields' => array(
'Topic.creator','Topic.link','Topic.id', 'Topic.topic_name', 'Topic.info', 'Topic.priority', 'Topic.user_id',
'Topic.completed','Topic.created', 'Topic.status','User.name','User.id','Topic.category','Topic.tags'),'conditions' => array(
'Topic.status' => 4))));
$this->set('total_inprogress_release', $this->Topic->find('count', array('conditions' => array(
'OR' => array('status <>' => 4,'status <>' => 0),
'priority' => 4))));
$this->set('upcoming_events', $this->Topic->Event->find('all'));
$this->Topic->virtualFields['count'] = 'COUNT(*)';
$this->set('graph_data', $this->Topic->find('chart', array('fields' => array('status_txt', 'priority_txt', 'count'), 'group' => array('status', 'priority'),
'chart' => array(
'xaxisTitle' => 'Status',
'yaxisLabels' => array('Release', 'Company', 'News'),
'xaxisLabels' => array('Open','In Progress','Completed'),
'yaxis' => 'Topic.priority_txt',
'xaxis' => 'Topic.status_txt',
'data' => 'Topic.count'
))));
}
And here's the nonworking function:
public function completed(){
$foo = $this->Topic->find('all', array('fields' => array(
'Topic.creator','Topic.link','Topic.id', 'Topic.topic_name', 'Topic.info', 'Topic.priority', 'Topic.user_id',
'Topic.completed','Topic.created', 'Topic.status','User.name','User.id','Topic.category','Topic.tags'),'conditions' => array(
'Topic.status' => 4)));
debug($foo);
debug($this->Topic->getDataSource()->getLog());
}
After several hours of tracking the data until we figured out where it was being lost, we found that the problem was some of the data in the database. It was encoded and it was causing a while statement in the core cake files to reset when it encountered said data. The solution was to alter Config/database.php as such:
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'login',
'password' => 'Password',
'database' => 'database',
'prefix' => '',
'encoding' => 'utf8',//this line allows the database to read utf8 data.
);
}
I think the relationships may be causing an issue here. Try this in the completed function and pr($foo) the results:
$foo = $this->Topic->find('all', array(
'fields' => array(
'Topic.creator',
'Topic.link',
'Topic.id',
'Topic.topic_name',
'Topic.info',
'Topic.priority',
'Topic.user_id',
'Topic.completed',
'Topic.created',
'Topic.status',
'User.name',
'User.id',
'Topic.category',
'Topic.tags'
),
'conditions' => array(
'Topic.status' => 4,
),
'joins' => array(
array(
'table' => 'users',
'alias' => 'User',
'type' => 'LEFT',
'conditions' => array(
'Topic.user_id = User.id'
),
),
),
'recursive' => -1,
));
I suspect you will get the results you are looking for.

CakePHP, wrting a better query string

In Cakephp is there a better way to write this:
$unread_orders = $this->Order->find('all', array('conditions' => array('Order.status' => 'unread') ));
$read_orders = $this->Order->find('all', array('conditions' => array('Order.status' => 'read') ));
$dispatched = $this->Order->find('all', array('conditions' => array('Order.status' => 'dispatched'), 'limit' => 5));
$canceled = $this->Order->find('all', array('conditions' => array('Order.status' => 'canceled'), 'limit' => 5));
There is a limit on the dispatched and canceled items.
It's seems like there would be a more effcient way of doing this, in one call to the database instead of 4.
Cheers.
One way is to do
$orders_read_unread = $this->Order->find('all', array('conditions' => array('OR' => array(array('Order.status' => 'unread'), array('Order.status' => 'read')))));
$orders_disp_cancel = $this->Order->find('all', array('conditions' => array('OR' => array(array('Order.status' => 'canceled'), array('Order.status' => 'dispatched'))), 'limit' => 5));
EDIT: Updated queries. Thanks Mark for clarifying.
<?php
...
$orders_read_unread = $this->Order->find( 'all', array(
'conditions' => array( 'Order.status' => array( 'unread', 'read' )),
'group' => array( 'Order.status' ),
));
/**
* Use this if you need 5 of EITHER canceled OR dispatched order
* if you need 5 of EACH you need to break it into two queries.
*/
$orders_dispatched_canceled = $this->Order->find( 'all', array(
'conditions' => array( 'Order.status' => array( 'canceled', 'dispatched' )),
'group' => array( 'Order.status' ),
'limit' => 5
));
/**
* Use these if you need 5 of EACH dispatched AND canceled orders
*/
$orders_dispatched = $this->Order->find( 'all', array(
'conditions' => array( 'Order.status' => 'dispatched' ),
'group' => array( 'Order.status' ),
'limit' => 5
));
$orders_canceled = $this->Order->find( 'all', array(
'conditions' => array( 'Order.status' => 'canceled' ),
'group' => array( 'Order.status' ),
'limit' => 5
));
...
?>
Should do the trick for you without having to deal with the 'OR' key syntax. It will generate a slightly less efficient IN ARRAY( '..' ,'..' ) syntax but keeps the php a little cleaner.
As an alternative you could look at either sub-queries - which are a pain with Cake. The book has an example of using the query builder via the datasource to inject a query into the conditions array of a normal cake find call.
http://book.cakephp.org/view/1030/Complex-Find-Conditions
And remember both of these finds should be in the model inside a function - you can either define a custom find type or just call a model function directly from your controller.
http://www.pixelastic.com/blog/88:using-custom-find-and-paginate-methods-in-cakephp-1-3

Categories