CakePHP find condition for a query between two dates - cakephp

I have a start and an end date in my database and a $date variable from a form field. I am now trying to query all the rows where $date is either = start/end date in the db, or ANY date between those two.
It's kind of the opposite of what is described in the docs of how daysAsSql works. I can't figure out how to get it to work. The following line does not work as a find condition in the controller:
'? BETWEEN ? AND ?' => array($date, 'Item.date_start', 'Item.date_end'),
Any help is greatly appreciated. This is driving me crazy.
Here is the complete Query and corresponding SQL:
$conditions = array(
'conditions' => array(
'and' => array(
'? BETWEEN ? AND ?' => array($date, 'Item.date_start', 'Item.date_end'),
'Item.title LIKE' => "%$title%",
'Item.status_id =' => '1'
)));
$this->set('items', $this->Item->find('all', $conditions));
WHERE (('2012-10-06' BETWEEN 'Item.date_start' AND 'Item.date_end') AND (`Item`.`title` LIKE '%%') AND (`Item`.`status_id` = 1))

$conditions = array(
'conditions' => array(
'and' => array(
array('Item.date_start <= ' => $date,
'Item.date_end >= ' => $date
),
'Item.title LIKE' => "%$title%",
'Item.status_id =' => '1'
)));
Try the above code and ask if it not worked for you.
Edit:
As per #Aryan request, if we have to find users registered between 1 month:
$start_date = '2013-05-26'; //should be in YYYY-MM-DD format
$this->User->find('all', array('conditions' => array('User.reg_date BETWEEN '.$start_date.' AND DATE_ADD('.$start_date.', INTERVAL 30 DAY)')));

Here is CakePHP BETWEEN query example.
I'm defining my arrays as variables, and then using those variables in my CakePHP find function call:
// just return these two fields
$fields = array('uri', 'page_views');
// use this "between" range
$conditions = array('Event.date BETWEEN ? and ?' => array($start_date, $end_date));
// run the "select between" query
$results = $this->Event->find('all',
array('fields'=>$fields,
'conditions'=>$conditions));
Ref from

General Example For CakePHP 2.x Query
$_condition = array("TABLENAME.id" => $id, "TABLENAME.user_id" => array_unique($_array), 'date(TABLENAME.created_at) BETWEEN ? AND ?' => array($start_date, $end_date));
$result_array = $this->TABLENAME->find("all", array(
'fields' => array("TABLENAME.id", "TABLENAME.user_id", 'TABLENAME.created_at'),
"conditions" => $_condition,
"group" => array("TABLENAME.id"), //fields to GROUP BY
'joins' => array(
array(
'alias' => 'T2',
'table' => 'TABLENAME2',
'type' => 'LEFT',
'conditions' => array('TABLENAME.t_id = TABLENAME2.t_id')
),
array(
'alias' => 'T3',
'table' => 'TABLENAME3',
'type' => 'LEFT',
'conditions' => array(
'IF(
TABLENAME.t3_id > 0,
T2.f_id = T3.f_id,
TABLENAME.ff_id = T2.ff_id
)'
)
),
),
'recursive' => 0
)
);

This is more efficient and understandable IN BETWEEN query in cakephp 2.x
$testing_log_device_site_name = $testingLogData['TestingLogDevice']['Siteid'];
$conditions = array('TestingLogDevice.dateee BETWEEN ? and ?' => array($start_date, $end_date));
$results = $this->TestingLogDevice->find('all',
array(
'fields'=>array('dateee','timeee','Siteid'),
'conditions'=>array($conditions, 'TestingLogDevice.Siteid'=>$testing_log_device_site_name)
)
);
pr($results);

$data=$this->post->find('all')->where([ 'id'=>$id,
'price between'=>$price1,'and'=>$price2])->toArray();
This query works as following:
select * from post where id=$id and price between $price1 and $price2;
" -- 'price between'=>$price1 --" become "price between $price1"

Use this
$today = new DateTime( date('Y-m-d'));
$fiveYearsBack = $today->sub(new DateInterval('P5Y'));

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.

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.

How to combine multiple queries in paginate

in my app i want to integrate a distance search by zipcode.
$result['zipcode'] = $this->Locations->find('all', array('conditions' => array('plz' => $param)));
if (count($city['Plz']) > 1)
$result['city'] = $this->Locations->find('all', array('conditions' => array('ort' => $city['Stadt']['name'], 'plz !=' => $city['Plz']['zipcode'])));
$this->Locations->virtualFields['distance'] = 'ACOS(SIN(RADIANS(Locations.lat)) * SIN(RADIANS('.$city["Stadt"]["lat"].')) + COS(RADIANS(Locations.lat)) * COS(RADIANS('.$city["Stadt"]["lat"].')) * COS(RADIANS(Locations.lng) - RADIANS('.$city["Stadt"]["lng"].')) ) * 6380';
$result['near'] = $this->Locations->find('all', array(
'conditions' => array(
'plz !=' => $param,
'ort !=' => $city['Stadt']['name'],
),
'order' => 'distance ASC'
));
i want to display results in order by zipcode, city (if city has many zipcodes) and near, so i did it this way.
but now i want to paginate this results by cake pagination.
is it possible to make these queries getting one i.e.
$this->Locations->find('all', array('conditions' => array(
'order' => 'RESULTS BY ZIPCODE, RESULTS BY CITY, RESULTS BY MISSMATCH ORDERED BY DISTANCE'
)));
how would you solve this problem?
M.
In CakePHP you can specify multiple fields to sort on via an associative array;
$this->MyModel->find('all', array(
'conditions' => array(/* .... */),
'order' => array(
'MyModel.field1' => 'asc',
'MyModel.field2' => 'desc',
'MyModel.field3' => 'asc',
)
);

CakePHP - How to use SQL NOW() in find conditions

I am having trouble getting any find operations to work using the SQL function NOW() in my conditions.
I am effectively trying to build a find query that says:
Desired SQL:
WHERE (NOW() BETWEEN Promotion.start AND Promotion.end) AND Promotion.active = 1
I have tried many combinations but no matter what I do when using NOW() in the condition, it doesn't work because the query Cake builds puts ' quotation marks around the model fields so they are interpreted by MySQL as a string.
$this->find('all', array(
'conditions' => array(
'(NOW() BETWEEN ? AND ?)' => array('Promotion.start', 'Promotion.end'),
'Promotion.active' => 1
)
));
CakePHP created SQL:
Notice the single quotes around the model fields in the BETWEEN(), so they are treated as strings.
WHERE (NOW() BETWEEN 'Promotion.start' AND 'Promotion.end') AND `Promotion`.`active` = '1'
This doesn't work either.
$this->find('all', array(
'conditions' => array(
'NOW() >=' => 'Promotion.start',
'NOW() <=' => 'Promotion.end',
'Promotion.active' => 1
)
));
I know why these solutions don't work. It's because the model fields are only treated as such if they are the array key in the conditions, not the array value.
I know I can get this to work if I just put the whole BETWEEN() condition as a string:
$this->find('all', array(
'conditions' => array(
'NOW() BETWEEN Promotion.start AND Promotion.end',
'Promotion.active' => 1
)
));
Another example of the same problem is, which is simpler to understand:
Desired SQL:
WHERE Promotion.start > NOW() AND Promotion.active = 1
So I try this:
$this->find('all', array(
'conditions' => array(
'Promotion.start >' => 'NOW()',
'Promotion.active' => 1
)
));
And again it doesn't work because Cake puts ' quotations around the NOW() part.
CakePHP created SQL:
WHERE `Promotion`.`start` > 'NOW()' AND `Promotion`.`active` = '1''
$this->find('all', array(
'conditions' => array(
'NOW() BETWEEN Promotion.start AND Promotion.end',
'Promotion.active' => 1
)
));
Better to not use NOW() as its a function and functions don't use indexes. A better solution would be:
$this->find('all', array(
'conditions' => array(
"'" . date('Y-m-d') . "' BETWEEN Promotion.start AND Promotion.end",
'Promotion.active' => 1
)
));

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