CakePHP : Search date from form helper - cakephp

I use form helpers to show drop down select date. My problem is, i can't compare date from ms sql with form data.
My View :
<?php echo $this->Form->input('collect_date', array('label' => 'Collect Date','type'=>'date','dateFormat'=> 'DMY','minYear' => date('Y'),'maxYear' => date('Y')+1));?>
My Controller
$status =array(0,2,4);
$find_date = $this->data['Transaction']['collect_date'];
$field = array('Transaction.status','Catalogue.title', 'Catalogue.author', 'Catalogue.isbn', 'Location.rack');
$condition = array('OR' => array('AND' =>array('Transaction.return_date <'=> $find_date,'Transaction.status '=> '3'),array('Transaction.status'=> $status)));
$data = $this->Catalogue->Transaction->find('count',array('fields' => $field,'conditions'=>$condition,'order'=>array('Transaction.id desc') ));
$this->set('Found', $data);
And the sql dump
SELECT COUNT(*) AS [count] FROM [transactions] AS [Transaction]
LEFT JOIN [catalogues] AS [Catalogue] ON ([Transaction].[catalogue_id] = [Catalogue].[id])
LEFT JOIN [users] AS [User] ON ([Transaction].[user_id] = [User].[id])
WHERE (((([Transaction].[return_date] < ('01', '09', 2013))
AND ([Transaction].[status] = 3))) OR ([Transaction].[status] IN (0, 2, 4)))
As you can see the date format ('01', '09', 2013). But when try to convert use this
'Transaction.return_date <'=> date('Y-m-d', strtotime($find_date))
it show error:
Warning (2): strtotime() expects parameter 1 to be string, array given [APP\Controller\CataloguesController.php, line 66]
and the sql show:
[Transaction].[return_date] < '1970-01-01'

You could use:
$date = DateTime::createFromFormat('d/m/y', implode('/', $find_date));
'Transaction.return_date <'=> $date->format('Y-m-d');
Edit:
I think the way its meant to be 'flattened' is with
$this->Model->deconstruct('find_date', $find_date);
However, last time i tried to use this, i couldn't get it to work properly, so i went with the above.
http://api21.cakephp.org/class/model#method-Modeldeconstruct

Try converting return date using UNIX_TIMESTAMP in sql query and then comparing it with
strtotime($find_date).

Related

select count of records group by month in cakephp 3

I'm using CakePHP 3.x+
I have to show a graph on the page and thus want to build script for that.
I have to select count of records group by month for current year.
This is what I have tried.
$graph = $this->GenerateVideos->find()
->select('COUNT(id)', 'MONTH(created)')
->where(['YEAR(created)' => date('Y')])
->group(['MONTH(created)']);
which generates sql like
'sql' => 'SELECT GenerateVideos.COUNT(id) AS GenerateVideos__COUNT(`id`) FROM generate_videos GenerateVideos WHERE YEAR(created) = :c0 GROUP BY MONTH(created) ',
'params' => [
':c0' => [
'value' => '2018',
'type' => null,
'placeholder' => 'c0'
]
],
But this is giving error as
Error: SQLSTATE[42000]: Syntax error or access violation:
1064 You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near '(`id`)
FROM generate_videos GenerateVideos WHERE YEAR(created) = '2018' GROUP BY' at line 1
Try using an array in your ->select() value:
->select(['COUNT(id)', 'MONTH(created)'])
In the book, it always shows an array, and it doesn't appear to be utilizing your second select value.
Or, per the book here, you could try this:
$query = $this->GenerateVideos->find();
$query->select(['count' => $query->func()->count('id'), 'month' => 'MONTH(created)']);
$query->where(['YEAR(created)' => date('Y')])
$query->group(['month' => 'MONTH(created)']);

UpdateAll is not working with bigint() fields

I'm quite new to CakePHP and have an issue. I'm trying to update one field in a row with this:
$options = array('conditions' => array('User.id' => $_POST['userid']));
$user = $this->User->find('first', $options);
$currentpoint = $user['User']['point'];
$correctanswerpoint = Configure::read('CORRECT_SYSTEMANSWER_POINT');
$newpoint = $currentpoint + $correctanswerpoint;
$this->User->updateAll(array('User.point'=>$newpoint), array('User.id'=>$_POST['userid']));
There are no errors, but the field point (bigint(20)) is not being updated. I've changed the field to update to another one in the same row which is of smallint type and the update goes through fine.
My debugging log seems to show that the SQL query is ok too:
[query] => UPDATE `askyoode_askyoo`.`users` AS `User` LEFT JOIN `askyoode_askyoo`.`countries` AS `Country` ON (`User`.`country_id` = `Country`.`id`) LEFT JOIN `askyoode_askyoo`.`accesstypes` AS `Accesstype` ON (`User`.`accesstype_id` = `Accesstype`.`id`) SET `User`.`point` = 57 WHERE `User`.`id` = 124
[params] => Array
(
)
[affected] => 1
[numRows] => 1
[took] => 12
)
And manually running the same SQL statement in MySQL works. Been tearing out my hair for the whole day trying to resolve this. Any help is greatly appreciated. Thanks!!

CakePHP count query gives different result when run in phpmyadmin

I am running the following query on my database:-
SELECT COUNT(*) AS COUNT, `Doctor`.`device_type` FROM `doctors` AS `Doctor` WHERE 1 = 1 GROUP BY `Doctor`.`device_type`
and it gives the result:-
count device_type
47 Android
23 iPhone
Whereas when running this query as a CakePHP query it gives the result as '2':-
$this->Doctor->find('count',array('group'=>'Doctor.device_type'));
Can anyone please suggest why this is happening?
The CakePHP result is correct as it is returning a count of the number of results returned by your query. In your case you have 2 rows: 'Android' and 'iPhone'.
find('count') always returns an integer, not an array. What Cake is doing is basically this:-
$data = $this->Doctor->find('all', array('group' => 'Doctor.device_type'));
$count = count($data); // This is what find('count') will return.
You need to do something like the following instead:-
$data = $this->Doctor->find('all', array(
'fields' => array(
'Doctor.device_type',
'COUNT(Doctor.*) AS count'
)
'group' => 'Doctor.device_type'
));

How to find items by date when the field is datetime?

I have a model with a DateTime field.
How can I get all entries by Date even if the column is DateTime?
Example table Cars:
id; expiration
1;2014-12-22 00:00:00
2;2014-12-22 03:12:00
3;2014-10-09 01:10:29
If I do this:
$this->Car->find("all", array('conditions' => array('expiration' => '2014-12-22' ) ))
I get only the item with ID 1 (2014-12-22 00:00:00)
But I need all the items (1 and 2)
Any ideas how to accomplish this? in MySql I could do something like this:
SELECT * ... FROM..WHERE DATE_FORMAT(conditions, '%Y-%m-%d') = '2014-12-22'
Try this
$this->Car->find("all", array('conditions' => array('DATE(ondate)' => '2014-12-22') ));
This will generate
SELECT * ... FROM..WHERE WHERE DATE(ondate) = '2014-12-22'
You need to update your query as shown below:
$this->Car->find("all", array(
'conditions' => array(
'DATE(expiration)' => '2014-12-22'
)
)
);
In the above query, Mysql now compare only date not the date and time as it was using in the query mentioned by you.
You will need to search trough a range: 00:00:00 - 23:59:59
http://cookbook.mongodb.org/patterns/date_range/

Covert into Cakephp query with subquery

Does anybody know how transform this query:
SELECT * from diminventory where partnumber='350964-B22' or partnumber in (SELECT partnumber from dimparts where parentpartnumber='350964-b22')
in a cakephp query
Thanks
I'm not 100% certain what you're asking for as yet, but here's a brief tutorial on cakephp querying.
$this->ModelName->query("SELECT * FROM tablename LIMIT 2;");
You query from the model, but you use the literal tablename. You use the SQL "AS" keyword to rename the keys of the resultant array.
Sample results:
Array
(
[0] => Array
(
[tablename] => Array
(
[id] => 1304
[user_id] => 759
)
)
[1] => Array
(
[tablename] => Array
(
[id] => 1305
[user_id] => 759
)
)
)
He is asking for Cakephp query not custom SQL query. In the controller:
$partnumber = $this->diminventory->find('all',array('conditions' => array('diminventory.partnumber' => '350964-B22')));
$this->set('partnumber',$partnumber);
set function passes a variable as $partnumber to the view. Then int view (which is .ctp file) you need to output the array.
foreach($partnumber as $partnumbers){
echo $partnumbers;
}
Make sure that diminventory table has 's' after the name otherwise it won't work as this is part of Cakephp's strict naming conventions.
Tutorial for find function:
http://book.cakephp.org/view/1018/find
To do it fully Cake'ish, you need to use CakePHP subquery:
$dbo = $this->User->getDataSource();
$subQuery = $dbo->buildStatement(
array(
'fields' => array('`Dimpart`.`partnumber`'),
'table' => $dbo->fullTableName($this->Dimpart),
'alias' => 'Dimpart',
'conditions' => array('`Dimpart`.`parentpartnumber`' => '350964-b22'),
),
$this->Dimpart
);
$subQuery = ' `DiminventoryEntry`.`partnumber` IN (' . $subQuery . ') ';
$subQueryExpression = $dbo->expression($subQuery);
$conditions[] = $subQueryExpression;
$conditions['DiminventoryEntry.partnumber'] = '350964-B22';
$result = $this->DiminventoryEntry->find('all', compact('conditions'));
Where Dimpart is your model for table dimparts, and DiminventoryEntry is your model for table diminventory (which is not actually Cake'ish, you should've renamed your table according to conventions).

Resources