laravel reading object file - laravel

![my collection is like][1]
foreach ($collection['documents'] as $user) {
$age = array("name"=>$user['data1'],"gender"=>$user['data3'],"martial"=>$user['data4'],"education"=>$user['data5'],"home"=>$user['data6'],
"phone"=>$user['data14'],"date"=>$user['data15'],"record"=>$user['data71'],"status"=>$user['data75'],"totalpoint"=>$user['data73'],"monitorypoint"=>$user['data74']);
$data[]=$age;
}
Error :
Cannot use object of type MrShan0\PHPFirestore\FirestoreDocument as array
Edit
when i try like this
foreach ($collection['documents'] as $user) {
dd($user->fields);
}
Cannot access private property MrShan0\PHPFirestore\FirestoreDocument::$fields
[1]: https://i.stack.imgur.com/7IvqS.png

You are treating Collections and Documents as arrays instead of objects (as in JSON), thus accessing them in the wrong way. For instance, take a look on the Firestore Data Model:
For example, you could have a users collection to contain your various users, each represented by a document:
users
|___alovelace
| |___first : "Ada"
| |___last : "Lovelace"
| |___born : 1815
|___aturing
|___first : "Alan"
|___last : "Turing"
|___born : 1912
According to the documentation, if you want (for example) to access multiple documents within your collection:
$citiesRef = $db->collection('samples/php/cities');
$documents = $citiesRef->documents();
foreach ($documents as $document) {
// blabla
}
Then, you can access fields within a document (DocumentSnapshot) as an array:
// One specific field wallet->cryptoCurrency->bitcoin
$bitcoinWalletValue = $snapshot['wallet']['cryptoCurrency']['bitcoin'];
See more on collection(), documents(), document(), data().
IMPORTANT
Please note that this is not an exact implementation of what you should do as I don't have enough context/information on your database structure. This is just to provide you some guidance.

Related

Eloquent going through 2 many-to-many relations

I have 5 entities that look like this :
character --> character_equipement <-- equipement --> stats_equipement <-- stats
I want to take for a defined character all of his equipements and for each equipements I need stats.
Character Model :
public function equipements(){
return $this->belongsToMany(EquipementsModel::class, 'stuff_equipement', 'id_stuff','id_equipement');
}
Equipements Model :
public function stats(){
return $this->belongsToMany(Stats::class, 'stats_equipement', 'id_equipement','id_equipement');
}
Controller :
$stuff = Character::with('equipements')->where('lien_stuff',$id)->first();
This way, I retrieve all equipements for the defined character. I don't know how to tell my Character model that he must look through Equipements Model to retrieve stats now.
I thought first way that while calling my controller, it will go through equipements() then look for a relation into his own model...
You can use dot notation to chain relations. It's actually fairly easy once you get the hang of it. I kind of guessed what the name of the column was on the stat to add up but hopefully you get the idea.
$character = Character::with('equipements.stats')->where('lien_stuff',$id)->first();
$totalStats = 0;
foreach ($character->equipments as $equipment) {
foreach ($equipment->stats as $stat) {
$totalStats += $stat->value;
}
}

Retrieving records from database using eloquent with optional query parameters

i have the following block of code in my Resource Controller:
$travel_company_id = Input::get('travel_company_id');
$transport_type = Input::get('transport_type');
$route_type = Input::get('route_type');
$travelRoutes = TravelRoute::where('travel_company_id', $travel_company_id)
->where('transport_type', $transport_type)
->where('route_type', $route_type)
->get();
Now what this does is it gets travelRoutes based on the parameters supplied. What i want is for it to do is perform a search based on the available parameters, that way if $route_type is empty the search will be performed only on travel_company_id and transport type.
Also if all the parameters are empty then it will simply do a get and return all available records.
I know i can do this with lots of if statements but then if i add a new parameter on the frontend i will have to add it to the backend as well, I was wondering if there was a much simpler and shorter way to do this in laravel.
The where method accepts an array of constraints:
$constraints = array_only(Input::all(), [
'travel_company_id',
'transport_type',
'route_type',
]);
$routes = TravelRoute::where($constraints)->get();
Warning: do not use Input::only() instead of array_only(). They're not the same.
Input::only() fills in any missing items with null, which is not what you want here.
This is pretty hacky and if you spend some time developing a solution I'm sure it could be much nicer. This assumes all the fields in the getSearchFields() function match the input names from the form and database.
/**
* Search fields to retrieve and search the database with. Assumed they match the
* column names in the database
*/
private function getSearchFields()
{
return ['travel_company_id', 'transport_type', 'route_type'];
}
public function search()
{
// Get a new query instance from the model
$query = TravelRoute::query();
// Loop through the fields checking if they've been input, if they have add
// them to the query.
foreach($this->getSearchFields() as $field)
{
if (Input::has($field))
{
$query->where($field, Input::get($field));
}
}
// Finally execute the query
$travelRoutes = $query->get();
}

Create collection from input array

Lets say I have a form that is a invoice. It has line items like $product[$key], $quantity[$key]. So when the form is submitted the input looks like
{
customer_id : "214"
product_id: [ "1","5", "6" ],
quantity: ["34", "1", "54"]
}
I have a model for that details table. What I have been doing is iterating over it and creating a details object then saving it like this
foreach($product as $key=>$p)
{
if($p)
{
$t = new Details;
$t->product = $p;
$t->quantity = $quantity[$key];
$t->save();
}
}
I'm guessing there is a way to be much more efficient about this. Like creating a collection of details straight from the input but I have no idea how I would accomplish that
You can instantiate models through mass assignment.
$details = new Details(['product_id'=>'1','quantity'=>'34']);
You can also specify columns of the table that you do not want to be mass assigned using the $guarded variable in the model.
Check out mass assignment in Laravel's docs: http://laravel.com/docs/eloquent#mass-assignment
For your particular issue it looks like you would need to build your input array out of the elements of the other arrays.
Seems it isn't possible. Here is Taylor responding to a issue request. It seems the problem is it wouldn't be possible to fire events then. I just ended up doing
$d = array();
foreach ($details as $detail) {
$d[] = new OrderDetail($detail);
}
$order->details()->saveMany($d);

laravel access model properties

I am looking for solution how to access eloquent model items by 'alias' field.
There is no problem accessing items by 'id'. But building a custom query I find myself unable to access item properties.
This piece of code works perfect
$cat = Category::find(1);
return $cat->title;
But if I am querying items with any other argument - properties are inaccessible
This code
$cat = Category::where('alias','=','vodosnab')->get();
return $cat->title;
throws an exception
Undefined property: Illuminate\Database\Eloquent\Collection::$title
Could you please help.
You already got the answer but here are some insights, when you use get() or all(), it returns a collection of model objects, which is an instance of Illuminate\Database\Eloquent\Collection, so here you'll get a Collection object
$cat = Category::where('alias','=','vodosnab')->get();
Now, you can use, $cat->first() to get the first item (Category Model) from the collection and you may also use $cat->last() to get the last item or $cat->get(1) to get the second item from the collection. These methods are available in the Collection object.
Using the first() method like Category::where('alias','=','vodosnab')->first(); will return you only a single (the first mathing item) model which is an instance of your Category model. So, use all() or get() to get a collection of model objects and you can loop through the collection like:
foreach(Category::all() as $cat) { // or Category::get()
$cat->propertyName;
}
Or you may use:
$categories = Category::where('alias','=','vodosnab')->get();
foreach($categories as $category) {
$category->propertyName;
}
Also, you may use:
$categories = Category::where('alias','=','vodosnab')->get();
$firstModel = $categories->first();
$lastModel = $categories->last();
$thirdModel = $categories->get(2); // 0 is first
If you need to get only one then you may directly use:
$category = Category::where('alias','=','vodosnab')->first();
$category->fieldname;
Remember that, if you use get() you'll get a collection of Model objects even if there is only one record available in the database. So, in your example here:
$cat = Category::where('alias','=','vodosnab')->get();
return $cat->title;
You are trying to get a property from the Collection object and if you want you may use:
$cat = Category::where('alias','=','vodosnab')->get();
return $cat->first()->title; // first item/Category model's title
return $cat->last()->title; // last item/Category model's title
return $cat->get(0)->title; // first item/Category model's title
You may read this article written on Laravel's Collection object.
get() returns a Collection of items. You probably need first() that returns a single item.

Getting an indexed collection

I would like to get an indexed collection from an eloquent call to get a specific item:
$items = FeedItem::all();
$specific_item = $items[4];
Or is it possible to do something like:
$items->get('id', 4);
where id is the attribute and 4 is the value of the attribute.
FeedItem::all() will return a Illuminate\Database\Eloquent\Collection.
To get a specific model you can use the find method:
$items = FeedItem::all();
$item = $items->find($id);
For more methods of the Collection class see the docs and the api.

Resources