way for using DATE_SUB(CURDATE(),INTERVAL 2 DAY) condition in cakephp - cakephp

i am using cakephp and creating this condition:
$conditions = array("Userword.levelid"=>0, "Userword.userid"=>$this->Auth->user('UserId'),"date(Userword.date)"=>"DATE_SUB(CURDATE(),INTERVAL 0 DAY)");
$Userword = $this->paginate(null, $conditions);
cake using this select :
`Userword`.`userwordid`, `Userword`.`userid`, `Userword`.`wordid`, `Userword`.`date`, `Userword`.`levelid`, `Word`.`wordid`, `Word`.`word`, `Word`.`meaning`, `User`.`UserId`, `User`.`Email`, `User`.`password`, `User`.`username`, `User`.`cell`, `User`.`web` FROM `userwords` AS `Userword` LEFT JOIN `words` AS `Word` ON (`Userword`.`wordid` = `Word`.`wordid`) LEFT JOIN `users` AS `User` ON (`Userword`.`userid` = `User`.`UserId`) WHERE date(`Userword`.`date`) = 'DATE_SUB(CURDATE(),INTERVAL 2 DAY)'
but by this select mysql can't return record because cakephp in this select use this character (') in last passage.
when i remove this character and test this code in phpmyadmin this code return rows. two images in below show this :

Just don't separate it out as key => value pair:
$conditions = array(
...
'DATE(Userword.date) = DATE_SUB(CURDATE(), INTERVAL 0 DAY)'
);

Related

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!!

How to add IN statement with JOIN ON clause in tablegateway ZF2

Getting all result so far until I added a 'IN' statement with join ON clause
My code is something like this:
// $this->table = 'category';
$sql = $this->getSql();
$select = $sql->select();
$select->join('user_category_subscriptions', 'user_category_subscriptions.category_id = category.id AND user_category_subscriptions.status IN (1,2,3,4)', array(), 'left');
$select->where(array('category.user_id = 2 OR (user_category_subscriptions.status IN (2,4))'));
Error
ZEND\DB\ADAPTER\EXCEPTION\INVALIDQUERYEXCEPTION
File:E:\htdocs\myproj\vendor\zendframework\zendframework\library\Zend\Db\Adapter\Driver\Pdo\Statement.php:245
Message:Statement could not be executed
Used 'echo $select->getSqlString();' to print the query:
SELECT "categories".* FROM "categories"
LEFT JOIN "user_category_subscriptions"
ON "user_category_subscriptions"."category_id" = "categories"."category_id" AND "user_category_subscriptions"."status" IN ("1""," "2""," "3""," "4")
WHERE category.user_id = 2 OR (user_category_subscriptions.status IN (2,4))
So the problem is zend's auto converting (1,2,3,4) into ("1""," "2""," "3""," "4")
Any idea to solve this? Thanks
I think you can pass an expression instead of the join string:
// $this->table = 'category';
$sql = $this->getSql();
$select = $sql->select();
$join = new Expression('user_category_subscriptions.category_id = category.id AND user_category_subscriptions.status IN (1,2,3,4)');
$select->join('user_category_subscriptions', $join, array(), 'left');
$select->where(array('category.user_id = 2 OR (user_category_subscriptions.status IN (2,4))'));
try this
$select->where
->AND->NEST->equalTo('category.user_id', 2)
->addPredicate(new Sql\Predicate\In('user_category_subscriptions.status', array(2,4)));

CAKEPHP Group by problem in paginate

CAKEPHP Group by problem in paginate..
This is my table structure
Friends Table
`id` int(11) NOT NULL AUTO_INCREMENT,
`user1_id` int(11) NOT NULL DEFAULT '0',--> UserFrom
`user2_id` int(11) NOT NULL DEFAULT '0',---> UserTo
I need to get all the unique records of one user and his user1_id = 100
There are lot of duplicate values in user2_id. I need to get the unique values
While i trying this code it returns only first 12 values(according to limit).
If i commented the group by line then all records are displaying (including duplicate values)
$this->paginate = array(
'conditions' => $conditions,
'contain'=>array(
'UserFrom'=>array(
'fields'=>array(
'UserFrom.id',
'UserFrom.first_name',
'UserFrom.last_name',
),
),
'UserTo'=>array(
'fields'=>array(
'UserTo.id',
'UserTo.first_name',
'UserTo.last_name',
)
)
),'limit' => 12,
'order' => array('Friend.id' => 'desc'),
'recursive'=>0,
'fields'=>array('DISTINCT Friend.user2_id','Friend.*'),
'group'=>array('UserTo.id'),
);
This is my sql query on that page
SELECT COUNT(*) AS count FROM friends AS Friend LEFT JOIN users AS UserTo ON (Friend.user2_id = UserTo.id) LEFT JOIN users AS UserFrom ON (Friend.user1_id = UserFrom.id) WHERE UserFrom.nick_name = 'shyam' AND Friend.status = 'friend' GROUP BY UserTo.id
SELECT DISTINCT Friend.user2_id, Friend.*, UserTo.id, UserTo.first_name, UserTo.last_name, UserTo.nick_name, UserTo.name, UserTo.icon_medium, UserTo.icon_big, UserFrom.id, UserFrom.first_name, UserFrom.last_name, UserFrom.nick_name, UserFrom.name FROM friends AS Friend LEFT JOIN users AS UserTo ON (Friend.user2_id = UserTo.id) LEFT JOIN users AS UserFrom ON (Friend.user1_id = UserFrom.id) WHERE UserFrom.nick_name = 'shyam' AND Friend.status = 'friend' GROUP BY UserTo.id ORDER BY Friend.id desc LIMIT 12
1.First count query returning count properly
2.Second query if i put limit it not working properly. i.e there are 144 records in my table i need to display 12 per page.. only first page coming if i use group by and limit
You should have either DISTINCT or GROUP BY, not both - they're duplicating each other and probably causing problems with your query. Remove one of them and retry.
Note: If you want to manually request pages other than 1st with $this->paginate(), add 'page' parameter with page number to your $this->paginate array, like this:
$this->paginate = array_merge($this->paginate, array('page' => $pageNumber);
However, normally you wouldn't want to do this, as paginator does this automatically (passing page variable via URL parameter to your action) as long as you use pagination controls in your view (see http://book.cakephp.org/view/1233/Pagination-in-Views).

Zend DB Select nested Joins

I'm trying to realize the following query with zend db select:
SELECT `uac`.`uid`, `u`.`uid`, `g`.`groupid`, `g`.`packageid`
FROM `user_has_data` AS `uac`
INNER JOIN `users` AS `u` ON u.uid = uac.uid
LEFT JOIN (`user_in_group` AS `uig`
INNER JOIN `groups` AS `ag` ON (ag.groupid = uig.groupid) AND (ag.packageid = 2)
) AS `g` ON uac.uid = g.uid
WHERE (uac.dataid = '3') AND (u.uname LIKE 'test%')
GROUP BY `u`.`uid`
I got the following, but got stuck when trying to convert the nested join to zend structure:
$select = $db->select()->from(array('uac' => 'user_has_data'), array('uac.uid'))
->join(array('u' => 'users'), 'u.uid = uac.uid', array('uid', 'uname'))
->joinLeft(array('uig' => 'user_in_groups'), 'uig.uid = uid', array('agid' => 'uig.groupid'))
->join(array('ag' => 'groups'), '(ag.agid = uig.groupid) AND ( ag.packageid = '.$packageid.')', array('packageid'))
->where('uac.dataid = ?', $dataid)
->where('(u.uname LIKE ?)', $value)
->group('u.uid');
Is it possible to get the given sql query into a suitable structure for zend db select? I need a select object for further handling in a paginator, so if this is not possible I have to make a straight forward sql query.
I don't believe you can do a nested join like that with Zend_Db_Select. Your best bet is to create your own paginator adapter (it's easier than you might think, look at the Select one) and manage the LIMIT part of the SQL yourself.
I know the question is old, but i think people might still benefit from the right answer for this question.
That nested join is the same as
SELECT * FROM `user_in_group` AS `uig`
INNER JOIN `groups` AS `ag` ON (ag.groupid = uig.groupid) AND (ag.packageid = 2)
So this should work just fine.
$subquery = $db->select()
->from(array('uig' => 'user_in_groups'),'*')
->joinInner(array('ag'=>'groups'),'(ag.groupid = uig.groupid) and (ag.packegeid = 2)',array('*'));
$select = $db->select()->from(array('uac' => 'user_has_data'), array('uac.uid'))
->join(array('u' => 'users'), 'u.uid = uac.uid', array('uid', 'uname'))
->joinLeft('g'=>$subquery), 'uac.uid = g.uid', array('g.groupid', 'g.packageid'))
->where('uac.dataid = ?', $dataid)
->where('(u.uname LIKE ?)', $value)
->group('u.uid');

CakePHP 3 find() with beforeFind() callback SQL issue

I'm having a problem with data integrity when using find() in my controller in conjunction with beforeFind() in a behavior callback. The WHERE Submissions.site_id is not being added in the WHERE clause like it should be. I get different result sets depending on where the WHERE clause is set.
in my SubmissionsController:
public function index()
{
$query = $this->Submissions->find('all')
->where(['user_id' => $this->Auth->user('id')])
->contain(['Users', 'Categories']);
$this->set('submissions', $this->paginate($query));
}
In my beforeFind() Model callback (attached as a 'TenantBehavior' to
$query->where([$this->_table->alias().'.'.'site_id' => 3]);
The problem is that with the above, the SQL generated puts the "WHERE" clause as an AND on the JOIN condition like so, and NOT on the actual WHERE:
...
FROM
submissions Submissions
INNER JOIN users Users ON (
Users.id = (Submissions.user_id)
AND Users.site_id = 3
)
INNER JOIN categories Categories ON (
Categories.id = (Submissions.category_id)
AND Categories.site_id = 3
)
WHERE
user_id = 315
If I remove the beforeFind() ->where and instead place it on the controller ->where I get the expected SQL and result set like so:
...
FROM
submissions Submissions
INNER JOIN users Users ON (
Users.id = (Submissions.user_id)
AND Users.site_id = 3
)
INNER JOIN categories Categories ON (
Categories.id = (Submissions.category_id)
AND Categories.site_id = 3
)
WHERE
(
user_id = 315
AND Submissions.site_id = 3
)
Thoughts? Suggestions?
EDIT
As #ndm's suggestion, I began to update and provide much more context. In doing so I discovered (like an idiot) that I was missing the $this->addBehavior('Tenant'); on my 'SubmissionsTable' model. Adding this of course solved the issue.
$query = $this->Submissions->find('all', [
'conditions' => [
'user_id' => $this->Auth->user('id')
],
'contain' => [
'Users',
'Categories',
]
]);
Passing conditions as inline array will solve your issue and append beforeFind() where conditions properly.

Resources