Get particular values multidimensional array Laravel - php

I want to get the values of some fields form the #attributes field (like "title" and "location") so I can fill a calendar.
dd($events); Outputs:
Illuminate\Database\Eloquent\Collection {#948 ▼
#items: array:3 [▼
"26-01-2021" => Illuminate\Database\Eloquent\Collection {#972 ▶}
"01-02-2021" => Illuminate\Database\Eloquent\Collection {#962 ▶}
"03-11-2021" => Illuminate\Database\Eloquent\Collection {#965 ▼
#items: array:1 [▼
0 => App\Models\DaysEvent {#994 ▼
#table: "days_events"
#casts: array:11 [▶]
#dates: array:2 [▶]
#fillable: array:25 [▶]
#dispatchesEvents: array:1 [▶]
#connection: "mysql"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#escapeWhenCastingToString: false
#attributes: array:29 [▼
"id" => 166
"title" => "Individual Interview"
"slug" => "individual-interview"
"functionality_type" => "selection"
"days_event_type_id" => 1
"event_start" => "2021-11-03 09:00:00"
"event_end" => "2021-11-03 19:00:00"
"location" => "Online"
"excerpt" => "Suit up and sit down with a recruiter to get in touch with the company on an individual level."
"content" => "<div>Suit up and sit down with a recruiter to get in touch with the company on an individual level. The Individual Interview will last 30 or 50 minutes and is e ▶"
"event_link" => "https://zoom.us/j/1234"
"parent_event_id" => null
"requires_motivation" => 1
"requires_cv" => 1
"requires_followup" => 1
"requires_student_company_preference" => 0
"company_id" => 34
"force_in_calendar" => 0
"spots" => 9
"has_timeslots" => 1
"has_algorithm_priority" => 1
"timeslot_slots" => "["9:00-9:30","9:30-10:00","10:00-10:30","11:00-11:30","11:30-12:00","12:00-12:30","13:00-13:30","13:30-14:00","14:00-14:30"]"
"timeslot_people" => 1
"can_unsubscribe_late" => 1
"company_can_see_cvs" => 1
"sf_id" => null
"deleted_at" => null
"created_at" => "2021-01-04 10:33:38"
"updated_at" => "2021-11-16 12:33:00"
]
#original: array:29 [▶]
#changes: []
#classCastCache: []
#dateFormat: null
#appends: []
#observables: []
#relations: array:1 [▶]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
#forceDeleting: false
}
]
#escapeWhenCastingToString: false
}
]
#escapeWhenCastingToString: false
}
I think I can get the values using the collect function form Laravel. (read this on this very similar question)
But when I try do do: $event_items = collect($events->items);
It gives the error: Property [items] does not exist on this collection instance.
What am I doing wrong here?

you are not get direct use of item,
you use $event_items = collect($events['03-11-2021']['0']->title);

This result you have is basically a collection of collections of models. Collections implement array access so you can user $collection['index'] or you can use $collection->get('index'). If you want all the values in the collection you can call the $collection->all() method. I don't really understand what data you want to get from here or why you have a collection of collections in the first place but the $collection->map() or $collection->transform() method is usually used to extract specific data from a collection.
I also believe that $collection->items is a private property so if you want all the items it is the same as $collection->all()
You can check Collections documentation for how they work.

Related

Storing attributes of a multiple models, to single array in laravel

I have the following eloquent in my controller,
$getJobs=JobTitle::where('department_id',DepartmentUser::where('user_id', $user->id)->first()->department_id)->get();
This gives me following collection
Illuminate\Database\Eloquent\Collection {#2970 ▼
#items: array:3 [▼
0 => App\JobTitle {#2967 ▶}
1 => App\JobTitle {#2968 ▶}
2 => App\JobTitle {#2962 ▶}
]
#escapeWhenCastingToString: false
}
And one model element looks like this
1 => App\JobTitle {#2968 ▼
#connection: "mysql"
#table: "job_titles"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#escapeWhenCastingToString: false
#attributes: array:9 [▼
"id" => 898
"title" => "driver"
"company_id" => 635
"department_id" => 252
"created_by" => null
"created_at" => "2022-04-20 05:30:38"
"updated_at" => "2022-04-20 05:30:38"
"deleted_at" => null
"archived_at" => null
]
#original: array:9 [▶]
#changes: []
#casts: array:2 [▶]
#classCastCache: []
#attributeCastCache: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: array:3 [▶]
#guarded: array:1 [▶]
+archives: true
#forceDeleting: false
}
Now I want to store all the job title (title) value's into single array
"title" => "driver"
In the above scenario, I have array elements and therefore I need store all three respective job titles to one single array...
$jobs = ['driver', 'chef', 'engineer'];
I tried adding an foreach, but it was giving me the following error,
#foreach ($getJobs as $getJob)
dd ($getJob->title);
#endforeach
ParseError syntax error, unexpected token "foreach"
What is the best way to achieve this?
You can simply loop on $getJobs and collect the title names in an array like below:
<?php
$getJobs = JobTitle::where('department_id',DepartmentUser::where('user_id', $user->id)->first()->department_id)->get();
$titles = [];
foreach($getJobs as $job){
$titles[] = $job->title;
}
dd($titles);

Checking if a value exists in two or more arrays in php

Hi there I have this problem here:
I have this on my controller:
$questions = Question::select('text','question_image','question_type_id','id')
->whereIn('id', $question_ids)
->where('deleted', 0)
->orderBy('created_at','ASC')
->paginate(20);
which ouputs this:
LengthAwarePaginator {#1635 ▼
#total: 4
#lastPage: 1
#items: Collection {#1627 ▼
#items: array:4 [▼
0 => Question {#1622 ▼
#hidden: array:1 [▶]
#fillable: array:10 [▶]
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:4 [▼
"text" => "asd"
"question_image" => null
"question_type_id" => 5
"id" => 1213
]
#original: array:4 [▶]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#visible: []
#guarded: array:1 [▶]
}
1 => Question {#1623 ▶}
2 => Question {#1624 ▶}
3 => Question {#1625 ▶}
And then I have this one:
$owner_questions = BankQuestion::select('question_id')->where('bank_id', $bank_id)->where('user_id', $auth)->where('deleted', 0)->get()->toArray();
Which outputs this:
array:2 [▼
0 => array:1 [▼
"question_id" => 1217
]
1 => array:1 [▼
"question_id" => 1218
]
]
And here I have my loop of questions:
foreach ($questions as $question) {
if(in_array($question->id, $owner_questions )){
$question->authorQuestion = 1;
}else{
$question->authorQuestion = 0;
}
}
Here I need to find the $question->id that exists on $owner_questions arrays which there the numbers that I am looking for are 1217 and 1218. Can someone please help me what I am doing wrong here please..?
You are comparing numeric value($question->id) with an array, which has a property question_id. Here is what you can do:
$owner_questions_ids = array();
foreach($owner_questions as $owner_question){
$owner_questions_ids[] = $owner_question['question_id'];
}
// now you can compare them
in_array($question->id, $owner_questions_ids )

How to re-format laravel relationship collections

I have the following models and their relationships:
Product - (name, price, qty)
Product Attribute (qty, price - when there is a combination, the qty and price here is the one getting)
Attribute - (size, color)
Attribute Values - (small, medium, large, red, blue, green etc)
// One to Many Relationship
$product->productAttributes (returns a collection)
// Many to Many Relationship
$productAttribute->attributeValues (returns a collection)
// One to Many Relationship
$attribute->attributeValues
I need to format it in such a way like:
array:2 [
"color" => array:2 [
0 => "red"
1 => "blue"
]
"size" => array:3 [
0 => "small"
1 => "medium"
2 => "large"
]
]
This is what I get when I iterate on the collections:
$attributes = $productAttributes->map(function (ProductAttribute $pa){
return $pa->attributesValues->map(function (AttributeValue $av) {
return [$av->attribute->name => $av->value];
});
})->all();
it obviously returns:
array:6 [▼
0 => Collection {#508 ▼
#items: array:2 [▼
0 => array:1 [▼
"Color" => "red"
]
1 => array:1 [▼
"Size" => "small"
]
]
}
1 => Collection {#525 ▼
#items: array:2 [▼
0 => array:1 [▼
"Color" => "red"
]
1 => array:1 [▼
"Size" => "medium"
]
]
}
2 => Collection {#535 ▼
#items: array:2 [▼
0 => array:1 [▼
"Color" => "red"
]
1 => array:1 [▼
"Size" => "large"
]
]
}
3 => Collection {#545 ▼
#items: array:2 [▼
0 => array:1 [▼
"Color" => "red"
]
1 => array:1 [▼
"Size" => "small"
]
]
}
]
Again, my intent is to format it like this:
array:2 [
"color" => array:2 [
0 => "red"
1 => "blue"
]
"size" => array:3 [
0 => "small"
1 => "medium"
2 => "large"
]
]
TIA!
Edit:
$product->productAttributes
Collection {#513 ▼
#items: array:6 [▼
0 => ProductAttribute {#514 ▼
#fillable: array:2 [▶]
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:6 [▶]
#original: array:6 [▼
"id" => 7
"quantity" => 3
"price" => "100.00"
"product_id" => 25
"created_at" => "2018-03-11 16:56:36"
"updated_at" => "2018-03-11 16:56:36"
]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
1 => ProductAttribute {#515 ▶}
2 => ProductAttribute {#516 ▶}
3 => ProductAttribute {#517 ▶}
4 => ProductAttribute {#518 ▶}
5 => ProductAttribute {#519 ▶}
]
}
$productAttribute->attributeValues
array:6 [▼
0 => Collection {#507 ▼
#items: array:2 [▼
0 => AttributeValue {#521 ▼
#fillable: array:1 [▶]
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:5 [▶]
#original: array:7 [▼
"id" => 1
"value" => "red"
"attribute_id" => 1
"created_at" => "2018-03-11 16:49:15"
"updated_at" => "2018-03-11 16:49:15"
"pivot_product_attribute_id" => 7
"pivot_attribute_value_id" => 1
]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:1 [▶]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
1 => AttributeValue {#506 ▼
#fillable: array:1 [▶]
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:5 [▶]
#original: array:7 [▶]
#changes: []
#casts: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:1 [▶]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
]
}
1 => Collection {#523 ▶}
2 => Collection {#530 ▶}
3 => Collection {#537 ▶}
4 => Collection {#544 ▶}
5 => Collection {#547 ▶}
]
I think, what you're looking for is something like the following;
$attributes = $productAttributes->pluck('attributesValue')
->flatten()
->unique()
->groupBy(function (AttributeValue $av) {
return $av->attribute->name;
})
->each(function (Collection $avs) {
$avs->map(function (AttributeValue $av) {
return $av->value;
});
});
Here's what the above code does;
Pull the relationship attributesValue for all results.
Flatten it out so we have one collection containing all attributesValue
Make sure we don't have any duplicates
We group everything so that we have something like colour => (collection of colour attributesValue)
Now we cycle through our multi level collection, and map the instances of AttributeValue so that each is replaced with their value
I've not ran this code myself, but I believe this will work.

Sort or order items with multiple relationships in laravel 5.1

I'm using multiple relationship and uses eager loading. What I have now are three tables (quizzes, multiple_choice, question_numbers), and I want to sort the multiple_choice using the question_numbers table with the field question_number. How can I do that? Please see my code below:
$undeleted = function($query){
return $query->where('deleted', 0);
};
$quiz = Quiz::with([
'multiple_choices.question_numbers' => $undeleted
])->find($id);
$quiz_items = collect($quiz->multiple_choices);
//$quiz_items = $quiz_items->sortBy('question_number');
I tried the commented part, but nothings happen.
Update with dd()
After I used dd(), the result is:
Collection {#478 ▼
#items: array:13 [▼
0 => MultipleChoice {#427 ▼
#table: "multiple_choice"
#fillable: array:6 [▶]
#connection: null
#primaryKey: "id"
#perPage: 15
+incrementing: true
+timestamps: true
#attributes: array:9 [▼
"id" => 1
"name" => "My name"
"question" => "the question body"
"created_at" => "2017-06-06 00:00:00"
"updated_at" => "2017-10-07 18:34:36"
]
#original: array:13 [▶]
#relations: array:2 [▶]
#hidden: []
#visible: []
#appends: []
#guarded: array:1 [▶]
#dates: []
#dateFormat: null
#casts: []
#touches: []
#observables: []
#with: []
#morphClass: null
+exists: true
+wasRecentlyCreated: false
}
]
}
Update2
#relations: array:2 [▼
"pivot" => Pivot {#426 ▶}
"question_numbers" => Collection {#452 ▼
#items: array:1 [▼
0 => Quiz {#449 ▶}
]
}
]
Update 3
databases
quizzes — id, name, body
multiple_choice — id, name, question
multiple_choice_quiz — id, multiple_choice_id, quiz_id
question_numbers — id, quiz_id, question_id, question_number
The question_number field in the question_numbers table is the field that I want to sort or order.

How to access a particular attribute in a Collection?

I want to access the name attribute from the practice table but I am getting Collections. My code looks like.
$practice = Practice::withTrashed()->where('id',$appointment->practice_id)->get();
dd($practice);
and result looks like
Collection {#697
#items: array:1 [
0 => Practice {#698
#dates: array:1 [
0 => "deleted_at"
]
#fillable: array:2 [
0 => "name"
1 => "email"
]
#connection: null
#table: null
#primaryKey: "id"
#keyType: "int"
#perPage: 15
+incrementing: true
+timestamps: true
#attributes: array:7 [
"id" => 42
"name" => "DJ and Charlie Eye Associates"
"email" => "vendorsupport#ocuhub.com"
"created_at" => "0000-00-00 00:00:00"
"updated_at" => "2017-01-13 06:29:14"
"liferay_id" => 57238
"deleted_at" => "2017-01-13 06:29:14"
]
#original: array:7 [
"id" => 42
"name" => "DJ and Charlie Eye Associates"
"email" => "vendorsupport#ocuhub.com"
"created_at" => "0000-00-00 00:00:00"
"updated_at" => "2017-01-13 06:29:14"
"liferay_id" => 57238
"deleted_at" => "2017-01-13 06:29:14"
]
#relations: []
#hidden: []
#visible: []
#appends: []
#guarded: array:1 [
0 => "*"
]
#dateFormat: null
#casts: []
#touches: []
#observables: []
#with: []
#morphClass: null
+exists: true
+wasRecentlyCreated: false
#forceDeleting: false
}
]
}
Is there any way to do , so I can get the name "DJ and Charlie Eye Associates". I used withThrashed method because this entry is soft deleted in the practice table.
First you need to get an object from a collection and then you can get any property of that object:
$practice->first()->name;
Or:
$practice[0]->name;
You can Either use foreach loop
foreach($collection as $collect){
dd($collect->name);
}
or you can just convert the collection into array
$array = $collection->toArray();
dd($array[0]->name);
or
$collection->first()->name;
Hope This Helps You.
Ask if any query
You could simply get this by using this
dd($practice[0]->name);
Or if you know that your query will return only one object you could use ->first() in place of ->get() and then you could use.
dd($practice->name);
->first() gives first object
->get() gives array of objects.
$practice = Practice::withTrashed()->where('id',$appointment->practice_id)->get()->get('name');
dd($practice);
Though this is incredibly ugly and you probably read up on Collections: your statement is doing exactly what Laravel says it does.
https://laravel.com/docs/5.3/collections
Use find() if id is the primary key, you will get just the Practice back.
$practice = Practice::withTrashed()->find($appointment->practice_id);
https://laravel.com/docs/5.3/eloquent#retrieving-single-models

Categories