I m trying to separated single quote from the values inside BETWEEN condition in cakephp 2 but it always gets values with single quotes like BETWEEN '2' and '34' .
here is my code:
$ref_no1 = $this->request->data['Lead']['ref_no1'];
$ref_no2 = $this->request->data['Lead']['ref_no2'];
$customerHo = $this-> Customer -> find('all',array(
'order' => array('Customer.customer_name' => 'asc'),
'joins'=>array(
array('table'=>'leads','alias'=>'Lead','type'=>'LEFT','foreignKey'=>false,'conditions'=>array('Customer.customer_id = Lead.customer_id')),
),
'fields'=>'Customer.*,Lead.*',
'conditions' => array(
'Customer.status' => 'active','Customer.customer_id Like'=>'S%',
'Customer.company_id'=>$company_id,
'AND' => array(
array('Lead.ref_no BETWEEN ? and ?' => array($ref_no1,$ref_no2) ),
),
)));
I am getting output like :
SELECT `Customer`.*, `Lead`.*
FROM `customers` AS `Customer`
LEFT JOIN `timezip_db_demo`.`leads` AS `Lead` ON (`Customer`.`customer_id` = `Lead`.`customer_id`)
WHERE `Customer`.`customer_id` Like 'S%' AND
`Lead`.`ref_no` BETWEEN '2' and '34'
ORDER BY `Customer`.`customer_name` asc
Expected output :
SELECT `Customer`.*, `Lead`.*
FROM `customers` AS `Customer`
LEFT JOIN `timezip_db_demo`.`leads` AS `Lead` ON (`Customer`.`customer_id` = `Lead`.`customer_id`)
WHERE `Customer`.`customer_id` Like 'S%' AND
`Lead`.`ref_no` BETWEEN 2 and 34
ORDER BY `Customer`.`customer_name` asc
can't you just do it like this? I didn't test this code yet.
$ref_no1 = $this->request->data['Lead']['ref_no1'];
$ref_no2 = $this->request->data['Lead']['ref_no2'];
$customerHo = $this-> Customer -> find('all',array(
'order' => array('Customer.customer_name' => 'asc'),
'joins'=>array(
array('table'=>'leads','alias'=>'Lead','type'=>'LEFT','foreignKey'=>false,'conditions'=>array('Customer.customer_id = Lead.customer_id')),
),
'fields'=>'Customer.*,Lead.*',
'conditions' => array(
'Customer.status' => 'active','Customer.customer_id Like'=>'S%',
'Customer.company_id'=>$company_id,
'AND' => array(
array('Lead.ref_no BETWEEN' . $ref_no1 . 'and' . $ref_no2 ),
),
)));
you can convert that string into integer, i hope it will work
array((int)$ref_no1,(int)$ref_no2)
Related
I have Contents, which can have Tags belonging to different TagGroups. I have a quite complex search condition which is as follows:
A Content matches if it is tagged with at least one tag from the search as long as it belongs to the same tag group.
Example:
TagGroup 1 are colours, TagGroup2 are shapes.
So if a Content is tagged with "blue", "turquoise" and "rectangular" it will be found, when I search for "blue" and "rectangular"
However this example is only to show that the logic behind this is quite complex.
Content -> ContentsTag <- Tag -> TagGroup
I want to develop a search with paging of the results I had it working, but between refactoring and framework updates it is broken.
At some point I loose the information for the joins and so my SQL is crashing because it is missing tables.
array(
'limit' => (int) 10,
'order' => array(
'Content.objnbr' => 'asc'
),
'joins' => array(
(int) 0 => array(
'table' => 'sang_contents_tags',
'alias' => 'CT1', //join for the first TagGroup
'type' => 'INNER',
'conditions' => array(
(int) 0 => 'CT1.content_id = Content.Id'
)
),
(int) 1 => array(
'table' => 'sang_contents_tags',
'alias' => 'CT2', //join for the second TagGroup
'type' => 'INNER',
'conditions' => array(
(int) 0 => 'CT2.content_id = Content.Id'
)
)
),
'conditions' => array(
'AND' => array(
(int) 0 => array(
'OR' => array(
(int) 0 => array(
'CT1.tag_id' => '189' // chosen Tag 1 from the first TagGroup
)
)
),
(int) 1 => array(
'OR' => array(
(int) 0 => array(
'CT2.tag_id' => '7' // chosen Tag 2 from the second TagGroup
)
)
)
)
),
'contain' => array(
(int) 0 => 'Description',
'ContentsTag' => array(
'Tag' => array(
(int) 0 => 'Taggroup'
)
)
)
)
results in the following SQL:
SELECT `Content`.`id`, `Content`.`objnbr`, `Content`.`name`, `Content`.`imagecounter`, `Content`.`videolength`, `Content`.`money_maker`, `Content`.`comment`
FROM `my_db`.`contents` AS `Content`
WHERE ((`CT1`.`tag_id` = '189') AND (`CT2`.`tag_id` = '7'))
ORDER BY `Content`.`id` DESC
LIMIT 20
So clearly the Tags CT1 and CT2 are not joined and my sql is crashing.
Could it be that the contain is blocking the joins? If I unset the contain I still get the same result / error.
Any ideas?
Edit: To clarify, what I want to achieve:
The result should be a SQL statement like this:
SELECT `Content`.`id`, `Content`.`objnbr`, `Content`.`name`, `Content`.`imagecounter`, `Content`.`videolength`, `Content`.`money_maker`, `Content`.`comment`
FROM
`my_db`.`contents` AS `Content`
INNER JOIN
contents_tags AS CT1 ON CT1.content_id = Content.Id
INNER JOIN
contents_tags AS CT2 ON CT2.content_id = Content.Id
WHERE
((`CT1`.`tag_id` = '189')
AND (`CT2`.`tag_id` = '7'))
ORDER BY `Content`.`id` DESC
LIMIT 10
It looks like the trouble is caused by the pagination. If I do a "simple" find I get Contents based on the Tags:
$result = $this->Content->find('all', $this->paginate['Content']);
generated query by find:
SELECT
`Content`.`id`,
`Content`.`objnbr`,
`Content`.`name`,
`Content`.`imagecounter`,
`Content`.`videolength`,
`Content`.`money_maker`,
`Content`.`comment`
FROM
`my_db`.`contents` AS `Content`
INNER JOIN
`my_db`.`contents_tags` AS `CT0` ON (`CT0`.`content_id` = `Content`.`Id`)
INNER JOIN
`my_db`.`contents_tags` AS `CT2` ON (`CT2`.`content_id` = `Content`.`Id`)
WHERE
((`CT0`.`tag_id` = '56')
AND (`CT2`.`tag_id` = '7'))
ORDER BY `Content`.`objnbr` ASC
I did a research in the bowels of the pagination class and my conclusion is, that it simply is not able to work with the current Paginator, because I cannot pass on my special joins I need for this complex query.
A custom find type also will not help, because my query is too dynamic for that.
Should anybody prove me wrong I will be a happy coder.
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.
I am Cakephp Beginner.
I want this query with cakephp..
Original Query..
SELECT `Advertisement`.*, `Gallery`.`image` FROM `moenatmi_moen`.`advertisements`
AS `Advertisement` LEFT JOIN `moenatmi_moen`.`galleries` AS `Gallery` ON
(`Gallery`.`advertise_id` = `Advertisement`.`id` AND `Gallery`.`main_ad_image`
= 1) WHERE `Advertisement`.`status` = 1 AND `Advertisement`.`category_id` = 14 AND
((`Advertisement`.`expiry_date` >= '2014-11-18') OR (`Advertisement`.`expiry_date`
IS NULL)) GROUP BY `Advertisement`.`id` ORDER BY `Advertisement`.`id` desc
LIMIT 10
I Want Like this query..
SELECT `Advertisement`.*, `Gallery`.`image` FROM `moenatmi_moen`.`advertisements`
AS `Advertisement` LEFT JOIN `moenatmi_moen`.`galleries` AS `Gallery` ON
(`Gallery`.`advertise_id` = `Advertisement`.`id` AND `Gallery`.`main_ad_image` = 1)
WHERE `Advertisement`.`status` = 1 AND `Advertisement`.`category_id` IN (select id from
categories where id=14 or parent_id=14) AND ((`Advertisement`.`expiry_date` >=
'2014-11-18') OR (`Advertisement`.`expiry_date` IS NULL)) GROUP BY
`Advertisement`.`id` ORDER BY `Advertisement`.`id` desc LIMIT 10
Original Cakephp Code..
$this->paginate['conditions'] = array(
'Advertisement.status'=>1,
'Advertisement.category_id'=>$cat_id,
'OR'=>array(
'Advertisement.expiry_date >='=>date('Y-m-d'),
'Advertisement.expiry_date'=>null
)
);
Help me..
Thanks You..
this should be a painless switch. This first query calls the category ids that you're wanting within your main query.
$cat_id is the same variable you're using in the original query.
$ids = $this->Category->find('all', array(
'conditions' => array(
'id' => $cat_id,
'parent_id' => $cat_id
)
)
);
The important thing to note here, this query will output your typical nested array..
array(
array(),
array(),
array()
);
The classicExtract function will sift through the mess for you and give you a single array with a list of 'id' which is exactly what you want for your query. EX:
array(14, 15, 16, 18, 19);
Finally, your main query.
$this->paginate['conditions'] = array(
'Advertisement.status'=>1,
'Advertisement.category_id'=> Set::classicExtract($ids, '{n}.Category.id'),
'OR'=>array(
'Advertisement.expiry_date >=' => date('Y-m-d'),
'Advertisement.expiry_date'=>null
)
);
Conclusion
All together your new conditions will look just like this:
$ids = $this->Category->find('all', array(
'conditions' => array(
'id' => $cat_id,
'parent_id' => $cat_id
)
)
);
$this->paginate['conditions'] = array(
'Advertisement.status'=>1,
'Advertisement.category_id'=> Set::classicExtract($ids, '{n}.Category.id'),
'OR'=>array(
'Advertisement.expiry_date >=' => date('Y-m-d'),
'Advertisement.expiry_date'=>null
)
);
I have a simple select query using Case Statement in CakePHP.
$this->M->find('all', array(
'fields'=>array(
'M.id',
'(CASE WHEN M.check> 0 THEN
TRUNCATE((M.col1 + M.col2),2)
ELSE
TRUNCATE(M.col2, 2)
END) AS TOTAL'
)));
I'm trying to have this result.
(int) 0 => array(
'M' => array(
'id' => '200',
'TOTAL' => '1073.00'
)
)
But Cake Outputs
(int) 0 => array(
'M' => array(
'id' => '200',
),
(int) 0 => array(
'TOTAL' => '1073.00'
)
)
Does cake renders the result like this for the Case Statement or I miss out something?
You should be using
http://book.cakephp.org/2.0/en/models/virtual-fields.html
as documented.
$this->virtualFields['total'] = ...;
Then it would work as expected.
I'm having a real headache getting this to work correctly. This is my desired outcome in raw MySQL:
WHERE `EmailTemplate`.`is_archived` = '0'
AND
((`EmailTemplate`.`project_id` IS NULL) OR (`EmailTemplate`.`project_id` = 101))
AND
((`EmailTemplate`.`user_id` IS NULL) OR (`EmailTemplate`.`user_id` = 44))
How does this translate into a CakePHP conditions array?
Solved this, eventually.
$templateConditions = array(
'EmailTemplate.is_archived' => 0,
'AND' => array(
'OR' => array(
array('EmailTemplate.project_id IS NULL'),
array('EmailTemplate.project_id' => $this->request->data['Project']['project_id'])
)
),
array(
'OR' => array(
array('EmailTemplate.user_id IS NULL'),
array('EmailTemplate.user_id' => $this->Auth->user('id'))
)
)
);