english textual date expression cakephp find queries - php

let's say that I have a database table called users in a cakephp application which contains a bunch of users and in that table I have a field called date which contains the registration date of each user. Let's say that I wanna make a find query to get all the users registered last month for example. Something like:
$last_month_users = $this->User->find('all', array(
'conditions' => array(
'User.date' => 'last month'
)
));
Something like this doesn't work. Any idea how I would do this please?
Thank you

If you're using mysql, you're looking to add in your statement:
WHERE MONTH(User.date) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)
I believe you can do this in cakePHP by doing the following:
$last_month_users = $this->User->find('all', array(
'conditions' => array(
'MONTH(User.date) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)'
)
));

Related

cant get the group of an int field from a query in cakephp3

I have a table with a field called 'year'. It has many repetitions in the column so I want to find the distinct group. I have 4 different 'years' in about 20 rows and I dont get these values from the query. Instead what is returned are 4 numbers which are not the years (5,14,4,70). The same code worked fine when I used this with suburb field in another table where there were multiple values of this field. I dont get why this isnt working.
//in view
echo $this->Form->input('year', ['label' => 'Year','options' => $allyears]);
//controller
$allyears = $this->TimesheetDates->find('list')
->select(['TimesheetDates.id', 'TimesheetDates.year'])
->group(['TimesheetDates.year'])->autoFields(true)
->order(['TimesheetDates.year'=> 'ASC'])
->hydrate(false);
$this->set('allyears',$allyears);
//another controller and this code worked fine
$suburb = $this->Students->find('list')->where(['Students.address_suburb !=' => '','Students.student_inactive' => 0])
->select(['Students.id','Students.address_suburb'])
->group(['Students.address_suburb'])->autoFields(true)
->order(['Students.address_suburb' => 'ASC'])
->hydrate(false);
take a look at the documentation about how find('list') works
$allyears = $this->TimesheetDates->find('list', [
'keyField' => 'id',
'valueField' => 'year']
)
->group(['year'])
->order(['year'=> 'ASC']);
Note that it has no meaning selecting the id of the TimesheetDates Table as you are grouping by year and the id is choosen randomly between all the records that share the same year

Cakephp get all months records with a single query i.e with single find

I am working on a ecommerce with platform cakephp and using google charts for reports.My requirement is to get all records as per all 12 months, so I have used following code for a single month
Query
SELECT COUNT(*) AS count FROM orderproductmasters AS Orderproductmaster
LEFT JOIN ordermasters AS Ordermaster ON
(Orderproductmaster.ordermaster_id = Ordermaster.id) LEFT JOIN productmasters AS Productmaster ON
(Orderproductmaster.productmaster_id = Productmaster.id)
WHERE Ordermaster.orderstatusmaster_id = 1 AND Month(Orderproductmaster.created) = 8
Code
$this->Orderproductmaster->find('count',
array('conditions'=>array('Ordermaster.orderstatusmaster_id'=>1,'
Month(Orderproductmaster.created)'=>8)));
Since, I need records as per Jan, feb,march and all 12 months...,so for 12 months I am using following code
for($i=1;$i<13;$i++)
{
$orderproductmasters[$i] = $this->Orderproductmaster->find('count',
array('conditions'=>array('Ordermaster.orderstatusmaster_id'=>1,
'Month(Orderproductmaster.created)'=>$i)));
}
So question might be silly, but is it possible to get all months record without using for loop i.e, within a single query.
Thanks in advance
I think , your need can be fulfilled by using cursors in stored procedure. And then using stored procedure to cake-php.
Example on db side is here
$options = array();
$options['fields'] = array('COUNT(Orderproductmaster.id)');
$options['conditions'] = array('Ordermaster.orderstatusmaster_id = 1',
'Month(Orderproductmaster.created) BETWEEN 1 AND 12');
$options['joins'] = array(
array(
'table' => 'ordermasters',
'alias' => 'Ordermaster',
'type' => 'left',
'conditions' => array(
'Orderproductmaster.ordermaster_id = Ordermaster.id'
)
),
array(
'table' => 'productmasters',
'alias' => 'Productmaster',
'type' => 'left',
'conditions' => array(
'Orderproductmaster.productmaster_id = Productmaster.id'
)
)
);
$options['group'] => array('Month(Orderproductmaster.created)');
$this->Orderproductmaster->find('all',$options);
What About something like:
$this->Orderproductmaster->find('count',
array(
'fields'=>'DISTINCT(Month(Orderproductmaster.created)),
'conditions'=>array('Ordermaster.orderstatusmaster_id'=>1,'
Month(Orderproductmaster.created)'=>8)));

PHP Triggering Actions Based on Dates

I am trying to make an area on my Wordpress site that checks the date field on each of my custom post type posts each time I get on for any dates that are 7 days or less until the current date and then displays the corresponding post title. If you have questions about any of that, please just ask, it is hard to really explain it.
I would like to put an if statement in there that just says if any of the dates are 7 days or closer to the current date, display the title of that post.
Problems:
The whole the_field( 'contract_sign_date' ); function displays the date as mm/dd/yy, so I'm not sure if subtracting the_field( 'contract_sign_date' ) by the current date will even come out right.
If problem 1 would for some reason work, what if the contract sign date is the first of the month? 1 - 7 will = -6 instead of the current date.
Like I said, if you have questions about any of that, please just ask, it is hard to really explain it.
Here you go this may help you get what you may need from wordpress
$contract_date = date(the_field( 'contract_sign_date' ));
$contract_date = strtotime ('-7 days', strtotime($contract_date) ) ;
$args = array(
'date_query' => array(
array(
'after' => array(
'year' => date ('Y', $contract_date),
'month' => date('m', $contract_date),
'day' => date('d', $contract_date)
),
),
),
);
$query = new WP_Query( $args );

MySQL query for dates with CakePHP

I'm trying to select the values that fall between 2 dates, so I'll have to use <= and >=, however, my query is seemingly behaving as just less than or greater than and not considering values equal to the date.
I'm using CakePHP which saves dates in "Y-m-d h:i:a" format. I wanted to find dates on given week intervals (starting on Sundays), so I used the following.
$start_date = date('Y/m/d', strtotime('last Sunday', strtotime($timestamp)));
$formatted_start_date = str_replace("/","-",$start_date);
I tried to do find $start_date formatted as "Y-m-d" but then it wouldn't find the correct date, so I switched it to the way it is and used str_replace to format it to using "-" instead of "/".
$date_query = $this->Order->query("select * from orders where id = '$id' and created => '$formatted_start_date' and created <= '$current_timestamp' ");
Considering the time values in my database are in "Y-m-d h:i:a" format, can I use "Y-m-d" for date comparison? Is it possible to do a MySQL query that involves both LIKE and <= ?
No need to do a str_replace() - just get the Y-m-d:
$start_date = date('Y-m-d', strtotime('last Sunday', strtotime($timestamp)));
Then, instead of manually creating a query, use the CakePHP conventions (yes, you can use Y-m-d for date comparison even though the datetimes stored in the database are Y-m-d H:i:s)
$this->Order->find('all', array(
'conditions' => array(
'id' => $id,
'created >=' => $start_date,
'created <=' => $end_date . ' 23:59:59',
'my_field LIKE' => '%whatever%'
));
Though - this seems kind of strange - usually you're either looking for something by 'id' OR by a date range - not both. But - maybe you have a reason :)
And as you can see above, yes, you can add a 'LIKE' also if you need.
Above answer is totally correct, but you can take easier approach using cakePHP time helper, which has function daysAsSql, it transcribes and time-readable strings into database range.
http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::daysAsSql
Just add condition's array like this.
$resl = $this->DBNAME->find('all',array(conditions=>array('date1>date','date1<date')));
Replace 'date' with your date.
This is worked for me.
Try this in your controller
$searchTutorQuery = $this->Tutordetails->find('all', array(
'conditions' => array(
"User.zip" => $zipcode1,
"Tutordetails.user_id"=>$uid,
"Tutordetails.subject_id" => $subjectName,
"Tutordetails.hourly_rate >=" => $hourly_rate
),
//"User.id =" => $userid,
'fields' => array('user_id', 'Tutordetails.subject_id', 'Tutordetails.hourly_rate',
'User.zip', 'Tutordetails.zip'),
'order' => array('Tutordetails.id DESC')
));

CakePHP database queries DISTINCT / GROUP BY error

In my CakePHP model I'm trying to get some data from my table.
I tried using DISTINCT but it seems like using DISTINCT doesn't change the query results.
I can see many rows that has the same nick
with 'DISTINCT Mytable.nick'
$this->Mytable->find('all',
array(
'fields'=> array(
'DISTINCT Mytable.nick',
'Mytable.age', 'Mytable.location',
),
'conditions' => array('Mytable.id >=' => 1, 'Mytable.id <=' => 100),
'order' => array('Mytable.id DESC')
));
with 'group Mytable.nick'
$this->Mytable->find('all',
array(
'fields'=> array(
'Mytable.nick',
'Mytable.age', 'Mytable.location',
),
'conditions' => array('Mytable.id >=' => 1, 'Mytable.id <=' => 100),
'group' => 'Mytable.nick',
'order' => array('Mytable.id DESC')
));
with 'Mytable.nick'
$this->Mytable->find('all',
array(
'fields'=> array(
'Mytable.nick',
'Mytable.age', 'Mytable.location',
),
'conditions' => array('Mytable.id >=' => 1, 'Mytable.id <=' => 100),
'order' => array('Mytable.id DESC')
));
Edit: It seems like even CakePHP 2.1 can't use DISTINCT option. When I tried "GROUP BY" it solved my issue. But as you can see from my query I need to order results with Mytable.id descended. When I use GROUP BY, when Mysql finds relevant row, it doesn't take others. For example.
id=1, nick=mike, age=38, location=uk
id=2, nick=albert, age=60, location=usa
id=3, nick=ash, age=42, location=uk
id=4, nick=albert, age=60, location=new_zelland
When I use group Mytable.nick, I don't see 4th row in my results, I see 2nd row. Because when mysql saw "albert" second time, it doesn't put it into my results. But I need latest "albert" result. Is it not possible?
Edit2: It seems like order by/group by conflict is a common problem. I found some tips in this question. But it gives solution for native Mysql queries. I need a solution for CakePHP type queries.
Not clear on why you want to group by nick and order by id. Do you intend to use an aggregate function like COUNT() to see how many occurrences of the same nick there are? In short you overall goal still is not clear to me. Might be worth being aware of the HAVING MySQL keyword.
Updated: Ok, that makes more sense. So you need to use a sub select on the condition or perhaps express that as a join. I'll try and show an example using the sub select in the WHERE clause.
/* select last occurrence for each nick (if you need one for each location )*/
SELECT nick, age, location
FROM myTable t1
WHERE id =
(SELECT MAX(id)
FROM myTable t1
WHERE t1.nick = t2.nick);
Would think something like this would work:
$this->Mytable->find('all',
array(
'fields'=> array(
'Mytable.nick',
'Mytable.age', 'Mytable.location',
),
'conditions' => array('Mytable.id =' => '(SELECT MAX(id) FROM myTable t2 WHERE myTable.nick = t2.nick)', 'Mytable.id <=' => 100)
));

Categories