Just a quick question.
I need to create a find query in Yii2 where an andWhere is only present if a variable is true.
public function getCheckBoxItems($holiday=false)
{
$Items = Items::find()->where(['type'=>'checkbox']);
Yii::info(print_r($Items,1), 'c');
if($holiday)
$Items->andWhere(['<>','category','holiday']);
$Items->All();
foreach($Items as $Item)
{
//do something
}
}
This doesn't work
However this deos work and i expected it to.
$Items = Items::find()->where(['type'=>'checkbox'])->andWhere(['<>','category','holiday'])->All();
How do I only add the andWhere based on the $holiday variable
Thanks in advance
Regards
Liam
UPDATE
i have found one way, but i am sure there is a better way
if($holiday)
$Items = Items::find()->where(['type'=>'checkbox'])->andWhere(['<>','category','holiday'])->All();
else
$Items = Items::find()->where(['type'=>'checkbox'])->All();
Just to make your code more clear and readable, you should simply try :
$itemsQuery = Items::find()->where(['type'=>'checkbox']);
if($holiday)
$itemsQuery->andWhere(['<>','category','holiday']);
$items = $itemsQuery->all();
foreach($items as $item)
{
//do something
}
You have to store $items result at each checkpoint:
public function getCheckBoxItems($holiday=false)
{
$Items = Items::find()->where(['type'=>'checkbox']);
Yii::info(print_r($Items,1), 'c');
if($holiday)
$Items->andWhere(['<>','category','holiday']);
$Items = $Items->All();
foreach($Items as $Item)
{
//do something
}
}
Related
I need to get all products for category and sub categories when click on parent category
so i make loop or recursive loop to get all id for category and subcategory to search for its products
public function tree($category, $cats = array())
{
$items = category_model::select('id')->where('parent_id', $category)->get();
foreach ($items as $key=>$value)
{
//$cats = $value;
$cats = Arr::add($cats, 'id', $value);
self::tree($value, $cats);
}
return $cats;
}
public function allproduct(Request $request)
{
return self::tree($request->id);
}
I have tried this code but looping with our result
I need to add this all id to make search for products through this array
You can improve your own code and make it work by taking all the category ids at once, instead of making a for each loop there.
Also, you are missing a terminating condition which is a must when using recursive functions.
Also, you don't need to process the same ids again and again if they have already been processed.
Taking all those points in mind, do something like this:
public function tree($cats, $alreadyProcessedCats = [])
{
if (empty($cats)) {
return [];
}
$newCatIds = [];
foreach ($cats as $catId) {
//do not process it if it was alreadt processed
if (in_array($catId, $alreadyProcessedCats)) {
continue;
}
//fetch all the categories id where parent id is one of the id which is present in the $cats
$items = category_model::where('parent_id', $category)->pluck('id');
if (empty($items)) {
continue;
}
$items = $items->toArray();
$newCatIds = array_merge($newCatIds, $items);
}
//terminal condition
if (empty($newCatIds)) {
return $cats;
}
$newCats = array_merge($cats, $newCatIds);
return self::tree($newCats, $cats);
}
public function allproduct(Request $request)
{
$allCategoriesIds = [$request->id];
$allCategoriesIds = self::tree($allCategoriesIds);
}
Fix your foreach loop.
foreach ($items as $key=$value)
should be
foreach ($items as $key => $value)
I can't comment on that static Arr function (a Laravel thing I guess? due to the misuse of statics everywhere?)
controller:
$sold_fruits = [];
foreach ($clients as $client) {
$sold_fruits[] = $client->bought_fruits;
}
$supermarkets = [];
foreach ($sold_fruits as $sold_fruit) {
// HERE: I want to stop using this [0]
$supermarkets[] = $sold_fruit[0]->supermarket;
}
client model:
public function bought_fruits()
{
return $this->hasMany(BoughtFruits::class);
}
sold fruits model:
public function supermarket()
{
return $this->belongsTo(Supermarket::class);
}
In the first loop Im getting something like this:
[[obj1],[obj2]]. Thats why I have to use that [0] in there!
Is there any good way to stop using that [0]??
You can achieve your goal easily by using Laravel collection functions.
Use flatMap() when where there is an array of items in a property.
Use map() when there is only one item in a property.
In your case
There are many bought_fruits for a client, so use flatMap()
There is one supermarket for a bought_fruit, so use map()
$superMarkets = collect($clients)
->flatMap->bought_fruits
->map->supermarket;
You try to put index number in the array like these below.
$sold_fruits = [];
foreach($clients as $key => $value){
$sold_fruits[$key] = $value;
}
$supermarkets = [];
foreach($sold_fruits as $key => $value){
$supermarkets[$key] = $value;
}
NOTE: This is just to answer the question, scroll down more to see the other approach.
I'm looping through an object:
foreach ($data as $asset) {
$asset->test = 'test';
}
test exists in $data and is set to something else, I wish to replace it with 'test'.
The above fails to work. Where am I going wrong?
You should use referenced loop with & like foreach ($data as &$asset)
foreach ($data as &$asset)
{
$asset->test = 'test';
}
Referenced loop will have an effect to $data, otherwise only current $asset object changes.
You can think about using a function that already exists, like array_walk that would execute your function.
function test_exists(&$asset) {
$asset->test = "test";
}
array_walk($data, "test_exists");
I couldn't find anything that answers my question so here it is:
I need to have a foreach loop to take each function inside of an array and run each and check if it returns true, simple enough. Like this:
$array_name = array(function1(),function2(),function3());
foreach($array_name as &$value) {
/* run each function */
/* checks if it returns true */
}
This may be so easy I just don't see it, but I can't find any definitive documentation on how to correctly implement this.
$array_name = array('function1', 'function2', 'function3');
foreach($array_name as $value) {
if($value()) {
// do stuff if the function returned a true-ish value
}
}
Another option to call the function would be call_user_func($value).
Try it:
$array_name = array('function1','function2','function3');
foreach($array_name as &$value) {
if(function_exists($value) && ($value())) {
//function exists and it returns true
}
}
Try to adopt things from : http://php.net/manual/en/functions.variable-functions.php
foreach($functionName as $arg) {
$arg();
}
But as you question contains:
$array_name = array(function1(),function2(),function3());
Make sure "function1()" is used in your array. So we can have:
foreach($functionName as $arg) {
$check = $arg;
if($check != false){
//Do stuff here
}else{
//Do stuff here
}
}
I would like to loop through the contents of a query object update certain values and return the object.
function clearAllIds($queryObject)
{
foreach($queryObject->result() as $row)
{
$row->id = 0;
}
return $queryObject
}
In this example I would like to zero out all of the ID values. How can I accomplish this within the foreach loop?
Please excuse the formatting.
This entirely depends on what the class of your query object is, and whether or not you'll be able to Pass by reference.
Assuming your $queryObject->result() can be delivered in a write-context, you could preface the $row with an ampersand to pass it by reference, like so:
foreach($queryObject->result() as &$row)
{
$row->id = 0;
}
function clearAllIds($queryObject)
{
foreach($queryObject->result() as &$row)
{
$row->id = 0;
}
return $queryObject
}
Use the & operator to get $row as a reference.
Edit: This will work if $queryObject is an array. You should probably do
$data = $queryObject->result();
foreach($data as &$row) { ... }
return $data;
function trim_spaces($object)
{
foreach (get_object_vars($object) as $property=> $value)
{
$object->$property=trim($value);
}
}
//no need to return object as they are passed by reference by default