using array in WHERE IN in CakePHP - cakephp

I'm working on CakePHP 3.2
I want to use an array in the query WHERE IN ()
The code is as
$filter_p_t = $this->request->query('p_t');
$pros10 = $this->Products->find()
->where([
'SellerProducts.stock >' => 0,
'SellerProducts.status' => 1,
'Products.p_status' => 1,
])
->contain([
'SellerProducts',
'ProductTypes.Subcategories.Categories',
]);
Here $filter_p_t is an array from url with parameter
/products/display/1?p_t[]=1&p_t[]=86
I want to include $filter_p_t in to the where condition to find all IN(1,86)
How can I use php array to the WHERE IN condition in CakePHP 3?

You can use the IN keyword directly after the column. This is assuming that $filter_p_t is an array like array(1, 86).
->where(['id IN' => $filter_p_t]);
http://book.cakephp.org/3.0/en/orm/query-builder.html#automatically-creating-in-clauses

Related

Laravel 5 form validation of array on different

from request I get an array like this:
'array' => [
0 => ['id' => 1,'val' => 2],
1 => ['id' => 1,'val' => 2]
]
I need to validate it so all ids of array will be unique.
right now I try this validation rule:
'array.*.id' => 'different:array.*.id'
but it will check current array with current array so result will be like
The array.0.id and array.0.id must be different.
You should use distinct rule:
'array.*.id' => 'distinct'

CakePHP 3.2 find first with where

I'm working with CakePHP 3.2. Here is my find query:
$a=$this->A->find('all', ['where' => [ 'b=='=>5, 'c>'=>1000 ]])->first();
// For debuging what I receive:
$data=$a->toArray();
print_r($data);
I'd like to select first record in 'A', whose column 'b' equals 5 and column 'c' is grater than 1000. What am I doing incorrectly? The above query returns all records from 'A' table.
Use conditions instead of where
$a=$this->A->find('all', ['conditions' => ['b'=>5, 'c >'=>1000]])->first();
simply
$a = $this->A->find()
->where([ 'b' => 5, 'c >' => 1000 ])
->first();
debug($a)
you don't need to call toArray() since first already returns a single entity
It should be like this:
$data = $this->A->find()->where(['b' => 5, 'c >' => 1000])->first();
Use conditions instead of where
$query = $articles->find('all', [
'conditions' => ['Articles.title LIKE' => '%Ovens%']
]);
$result = $query->toArray();

How to create a `IN` clause in CakePHP query?

How do you make it where in clause in new CakePHP? I'm trying:
$restaurants->find()->where(['id' => $r_ids])->all();
Where $r_ids is array of ids I need in my query, but this doesn't work as expected.
With CakePHP 3.x it's now necessary to either indicate the data type, which for an array of values need to have [] appended to the type:
$query = $articles
->find()
->where(['id' => $ids], ['id' => 'integer[]']);
or to explicitly make use of the IN keyword:
$query = $articles
->find()
->where(['id IN' => $ids]);
See also
Cookbook > Database Access & ORM > Query Builder > Automatically Creating IN Clauses
Try this one for CakePHP 3.x
$query = $restaurants
->find()
->where(['id IN' => $r_ids]);
$query->all();
You can also use the short syntax:
$result = $restaurants->find('all',
['conditions' => ['id IN' =>$r_ids]]
)->all();
In Cakephp 3.x, If you have multiple where conditions then your query will be as below:
return $this
->find()
->contain([
'XYZ.Articles',
'YYY.Managers',
'ZZZ.Readers',
])
->where([
'ID' => $ids,
'READER.STATUS' => $xyz,
],[
'ID' => 'integer[]'
])
;

cakephp correct array to use updateAll

I am using cakephp 2.5 and I have an array that I wish to update many records at once in the Page model. I can't seem to get the format of the array correct. I get the error:
Notice (8): Undefined index: newOrder [APP/Controller/PagesController.php, line 133]
$newOrder = array(
'Page' => array(
0 => array(
'id' => 3,
'order' => 0),
1 => array(
'id' => 4,
'order' => 0),
2 => array(
'id' => 7,
'order' => 0
)
));
$this->Page->updateAll($newOrder);
One of the parts I think I am missing is using 'data' as part of the array. But I am unsure where to place it.
I have also tried:
$this->Page->updateAll($newOrder['Page']);
You should use saveMany for your requirement. Find the explanation below -
updateAll
updateAll(array $fields, array $conditions) - is used to update one or more records with the same value based on a condition or multiple conditions. eg: If you want to update all your pages & set all of them to order = 0, you can use updateAll without passing the primary keys -
$this->Page->updateAll(
array('Page.order' => 0)
);
If you want to update some pages based on a condition you will do something like -
$this->Page->updateAll(
array('Page.order' => 0),
array('Page.type' => 'PROMOTED')
);
Assuming you have a type field in your page model, the above query will set order 0 for all pages with type PROMOTED
Ref - http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-updateall-array-fields-array-conditions
saveMany
Now if you want to update some specific records with some specific values which you want to create in an array, you should use a saveMany(array $data = null, array $options = array())
To save/update multiple records using a data array, you should first create the data array in this format -
$data = array(
array('Page' => array('id' => 1, 'order' => 0)),
array('Page' => array('id' => 2, 'order' => 0)),
array('Page' => array('id' => 3, 'order' => 0))
);
$this->Page->saveMany($data);
Now you can use saveMany to update the three records with the given id(primary key) with order 0. Note if you don't pass primary keys i.e id in the arrays, saveMany will just create new records for the given array.
Ref - http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-savemany-array-data-null-array-options-array

CakePHP function to convert dotted arrays to multidimensional

In CakePHP, it seems like a lot of functions can take their arguments as nested, multidimensional arrays, or as dotted strings:
$this->MyModel->contain(array(
'Something', 'Something.Else', 'Something.Else.Entirely'
));
$this->MyModel->contain(array(
'Something' => array(
'Else' => 'Entirely'
)
));
Therefore, I figure there must be a function somewhere in the core to switch from dotted to nested associative, but I can't find it for the life of me. Any ideas?
I've actually figured my own way to get this working leveraging the built-in Set functions.
Given:
$input = array (
'Post.id' => 1,
'Post.title' => 'Some post title.',
'Post.Tag.0.id' => 4,
'Post.Tag.0.name' => 'cakephp',
'Post.Tag.1.id' => 7,
'Post.Tag.1.name' => 'mysql',
);
This code will put that into a nested associative array.
$output = array();
foreach ($input as $key => $value) {
$output = Set::insert($output, $key, $value);
}
Here's the docs for Set::insert()
What you're looking for is Set::flatten(). It's not documented in the CakePHP manual, but take a look at the API definition.
It works something like this (the result might not be exact, this is from my head):
$array = array(
'Post' => array(
'id' => 1,
'title' => 'Some post title.',
'Tag' => array(
0 => array(
'id' => 4,
'name' => 'cakephp',
),
1 => array(
'id' => 7,
'name' => 'mysql',
),
),
);
);
$array = Set::flatten($array);
var_dump($array);
Your $array variable will now look like this:
Array (
'Post.id' => 1,
'Post.title' => 'Some post title.',
'Post.Tag.0.id' => 4,
'Post.Tag.0.name' => 'cakephp',
'Post.Tag.1.id' => 7,
'Post.Tag.1.name' => 'mysql',
)
It's just a convention throughout Cake, but each part does its own, customized parsing. If you look at the function ContainableBehavior::containments() in cake/libs/model/behaviors/containable.php, you'll see a lot of preg_matching and explode('.')ing going on. At least in the case of Containable, the verbose array('name' => array(...)) syntax seems to be the canonical syntax, but it can be abbreviated with the dot syntax, which will just be expanded. I'd guess that the expanding itself is just too varied among different parts to be easily summarized in a central function.
That, or they just haven't gotten to it yet. :)
Great question, I was just searching for the same thing. Apparently it's coming in Cake 2.2.
The new Hash class (a new, improved version of the Set class) has an expand() function which does this. You can view the code on Github if you need to use it in the meantime:
https://github.com/cakephp/cakephp/blob/2.2/lib/Cake/Utility/Hash.php
...However the solution nickf posted works great, too. :-)

Resources