How to fetch value from variable in laravel? - php

$product=ProductCatalog::where(['campaign_id' => $campaign_id])->get();
print($product);
OUTPUT:
[{"id":7,"campaign_id":64,"product_id":26,"created_at":"2018-03-20 10:29:51","updated_at":"2018-03-20 10:29:51"},{"id":8,"campaign_id":64,"product_id":27,"created_at":"2018-03-20 10:30:26","updated_at":"2018-03-20 10:30:26"}]
From $product i want to fetch value of product_id
How to fetch value from $product?
please help me with this problem...

You can use toArray() of eloquent as below.
The toArray method converts the collection into a plain PHP array. If the collection's values are Eloquent models, the models will also be converted to arrays.
$product = ProductCatalog::where(['campaign_id' => $campaign_id])->get()->toArray();
And then you can access the array properties as per your need. See sample below.
foreach($product as $productValue) {
print_r($productValue['product_id']);
}

$productCatalogs = ProductCatalog::with('product')->where(['campaign_id' => $campaign_id])->get();
foreach($productCatalogs as $productCatalog){
print_r($productCatalog->product);
}
This should work if you have defined relationship in ProductCatalog Model (ProductCatalog.php).

Related

Laravel: array to Model with relationship tree

I want to create an Eloquent Model from an Array() fetched from database which is already toArray() of some model stored in database. I am able to do that using this code:
$model = Admin::hydrate($notification->data);
$notification->data = [
"name" => "abcd"
"email" => "abcd#yahoo.com"
"verified" => 0
"shopowner_id" => 1
"id" => 86
"shopowner" => [
"id" => 1
"name" => "Owner1"
"email" => "owner1#owner.com"
]
];
But i can't access the $model->shopowner->name
I have to use $model->shopowner['name']
I want to use the same class of notification without any specific change to access the data.
If you want to access shopowner as a relationship, you have to hydrate it manually:
$data = $notification->data;
$model = Notification::hydrate([$data])[0];
$model->setRelation('shopowner', ShopOwner::hydrate([$data['shopowner']])[0]);
Solution:
Thanks to #Devon & #Junas. by combining their code I landed to this solution
$data = $notification->data;
$data['shopowner'] = (object) $data['shopowner'];
$model = Admin::hydrate([$data])[0];
I see this as an invalid use of an ORM model. While you could mutate the array to fit your needs:
$notification->data['shopowner'] = (object) $notification->data['shopowner'];
$model = Admin::hydrate($notification->data);
Your model won't be functional because 'shopowner' will live as an attribute instead of a relationship, so when you try to use this model for anything other than retrieving data, it will cause an exception.
You cannot access array data as object, what you can do is override the attribute and create an instance of the object in your model, so then you can use it like that. For example:
public function getShopownerAttribute($value)
{
return new Notification($value); // or whatever object here
}
class Notification {
public function __construct($data)
{
// here get the values from your array and make them as properties of the object
}
}
It has been a while since I used laravel but to my understanding once you use hydrate your getting a Illuminate\Database\Eloquent\Collection Object, which then holds Model classes.
These however could have attributes that are lazy loaded when nested.
Using the collections fresh method could help getting a Full database object as using load missing

Can we add custom values to a CakePHP Table Object?

I have a Cake Object when querying a table:
$invoices = TableRegistry::get('invoices')->find('all', ['conditions' => ['order_number =' => $orderNumber]]);
This works fine. I then want to add other array key/values to this Object, like this one:
$invoicesTmp = array();
$invoicesTmp['customer'] = "name of customer";
But $invoicesTmp is incompatible with $invoices. (one is an array, other is an CakePHP Object)
I have tried this:
compact($invoices, $invoicesTmp);
but that didn't worked.
The find() method of a Table object returns a Cake\ORM\Query object. This object is used to build SQL queries and to execute them. It has some features to define how the results from the query should be returned.
When CakePHP fetches results from the database the records are stored as an array, and CakePHP then converts them to Entity objects. A process called "hydration" of entities. If you disable hydration the records are returned as just an array.
$query = TableRegistry::get('invoices')
->find()
->where(['order_number'=>$orderNumber])
->enableHydration(false);
foreach($query as $record) {
pr($record);
}
The above creates a query object, and you can iterate over the query records because the object itself supports iteration.
The query object implements the Cake\Collection\CollectionInterface interface, which means we can perform a bunch of collection methods on it. The most common method is the toArray().
$invoices = TableRegistry::get('invoices')
->find()
->where(['order_number'=>$orderNumber])
->enableHydration(false)
->toArray();
The $invoices variable is now a valid array object holding the all the records with each record as an array object.
You can now easily use array_merge to assign extra metadata to each record.
$invoices = array_map(function($invoice) {
return array_merge(['customer'=>'name of customer'], $invoice);
}, $invoices);
$this-set(compact('invoices'));
Updated:
Based upon the comments it appears you wish to use two different tables with different column names, but those columns represent the same data.
Field Aliases
You can rename fields in the SQL query to share a common alias.
$table = TableRegistry::get($whichTable ? 'table_a' : 'table_b');
$records = $table->find()
->select([
'id',
'invoice_id',
'name' => ? $whichTable ? 'customer_name' : 'invoice_name'
])->all();
The above selects a different column for name depending upon which table is being used. This allows you to always use $record->name in your view no matter which table.
I don't like this approach, because it makes the source code of the view file appear to reference a property of the entity that doesn't really exist. You might get confused when returning to the code later.
Field Mapping
From a MVC perspective. Only the controller knows what a view needs. So it's easier if you express this knowledge as a mapping.
$map = [
'id'=>'id',
'invoice_id'=>'invoice_id',
'name' => ? $whichTable ? 'customer_name' : 'invoice_name'
];
$table = TableRegistry::get($whichTable ? 'table_a' : 'table_b');
$records = $table->find()
->select(array_values($map))
->all();
$this->set(compact('records','map'));
Later in your view to output the columns you do it like this:
foreach($records as $record) {
echo $record->get($map['name']);
}
It becomes verbose as to what is happening, and why. You can see in the view that the controller provided a mapping between something called name and the actual field. You also know that the $map variable was injected by the controller. You now know where to go to change it.

why foreach print just one value in laravel?

I have a method:
public function winnerDetails()
{
$winners = DB::table('winners')->get();
//dd($winners);
foreach ($winners as $winner) {
$qrMainId = $winner->qrdetails_id;
}
dd($qrMainId);
}
dd($winners); returns to value of array but when i use foreach its returns one value. How can i get who value returns with foreach loop?
dd($winners) output:
and dd($qrMainId); return one value 44. But it should return another value of array 35; Thanks in advance.
To get array of ID's use
foreach ($winners as $winner) {
$qrMainId[]= $winner->qrdetails_id;
For just value use
$qrMainId='';
foreach ($winners as $winner) {
$qrMainId.= $winner->qrdetails_id;
If you want to accomplish this task in a Laravel way use the pluck method to map the array for the key that you want
<?php
public function winnerDetails()
{
$winnersId = DB::table('winners')->get()->pluck('qrdetails_id');
dd($winnersId);
}
I think you are not leveraging the power of Laravel here. Obviously, I don't know what you are trying to do but here are some pointers.
You should probably be making a model for the winners table now models in Laravel return Collections as does the DB facade you are using now. Now the Collection class contains alot of usefull helpers like pluck
At this point it becomes as easy as Winner::all()->pluck('id') and you got yourself an array of id's.
And if you would like to get them comma seperated or anything like that you can use the implode
And you would get Winner::all()->implode('id',',');
$qrMainId is a variable not an array.
It is modified in the foreach during every loop.
So your code has always the last element of the array.
Use an array to collect values like
$qrMainId[] = $winner->qrdetails_id;
or sql select directly the field you want.

Converting an array of arrays from Laravel's collection into an object with an array in json

I am generating an an array of categories and subcategories in my Laravel API for use in my client side app.
I'm doing this by using the collection's filter and map methods to organize the data pulled from the database:
// get the data from the category table
$categoryData = $categories->all()->categories();
// filter the data by category names we know we want and create the multi-dimensional array of the fields we need
$categoryList = $categoryData->filter(function ($value) {
return $value['Category'] == "by Area of Interest" || $value['Category'] == "by Grade Level";
})
->map(function ($value) {
return ['category' => $value['Category'], 'subCategory' => $value['Subcategory']];
});
dd($categoryList);
When I review the die and dump result, I get my collection with it's array of correctly formatted items:
And if I output it as an array with:
dd($categoryList->toArray());
I see the multi-dimensional array I would expect.
The problem I'm running into is when I try to output it as json for my client app to consume.
dd($categoryList->toJson());
If I output as json I get an object that contains the php array indexes as properties and the php sub arrays as objects assigned to those properties.
What I want is a json object that contains an array of objects. e.g.
$categoryList = [['category' => 'test', 'subCategory' => 'test'], ['category' => 'test', 'subCategory' => 'test']];
dd(json_encode($categoryList));
Which outputs:
Is there something I'm doing wrong with my collection calls?
Update
Per Hognbin's comment:
The call to $categories->all()->categories(); returns a collection of category data that I then manipulate to get my list.
$categoryData = $categories->all()->categories();
dd($categoryData);
yields:
The problem is that the indexes are the ids of categories which You'll get from eloquent collection when You try to make array from it.
If you want to have a clean array of objects, I suggest doing this:
json_encode(array_values($categoryList->toArray()));
Final implementation by Chris
The above explanation and function calls got me the end result I needed. After confirming it worked via these function calls I looked at the Collection class methods to see how I could implement it using the class. Here's what I did:
$categoryList = $categoryData->filter(function ($value) {
return $value['Category'] == "by Area of Interest" || $value['Category'] == "by Grade Level";
})
->map(function ($value) {
return ['category' => $value['Category'], 'subCategory' => $value['Subcategory']];
})
->values()
;
If you look at the Collection class' values() method, it's doing the same thing:
Since the Laravel Collection items are stored as an array, the toArray() method call is not needed.

how to get all related model IDs in Yii?

Suppose $model hase some items (one to many relationship), So in Yii $model->items returns an array of item models. How can I get an array of IDs of related items. This means each element of returned array is an integer.
You should simply write your own function for this, e.g.
public function getItemsIDs()
{
$ids = array();
foreach($this->items as $item)
$ids[] = $item->id;
return $ids;
}
After you just have to call $model->itemsIDs.
EDIT : as darkheir said in its comment, you should consider using DAO.
Here is an example of direct query, run from Model:
$this->getDbConnection()->createCommand("SELECT id FROM items WHERE model_id = :modelId")->bindParam(":modelId", $model->id, PDO::PARAM_STR)->queryColumn();
In result you will get numeric Array() with IDs from the table as values.
Another variant.
Yii::app()->db->createCommand("SELECT id FROM items WHERE model_id=".$model->id)->queryColumn()
This will get all IDs from table as array

Categories