Update Collection value - laravel

I am trying to update a column in a Collection but nothing seems to work.
Tried update and $kk->amount = 100 and ['amount'] = 100 but none of that is working.
$newReturnBoxes = collect([
{
"boxable_id": 2,
"box_id": 1,
"boxable_type": "return",
"amount": 3,
"created_at": "2022-03-29T08:29:03.000000Z",
"updated_at": "2022-03-29T08:29:03.000000Z"
},
{
"boxable_id": 3,
"box_id": 1,
"boxable_type": "return",
"amount": 4,
"created_at": "2022-03-29T08:32:02.000000Z",
"updated_at": "2022-03-29T08:32:02.000000Z"
},
{
"boxable_id": 3,
"box_id": 2,
"boxable_type": "return",
"amount": 2,
"created_at": null,
"updated_at": null
}
]);
$returnBoxes->each(function ($trx) use ($newReturnBoxes) {
$amount = $trx->amount;
$boxId = $trx->box_id;
if ($newReturnBoxes->contains('box_id', $boxId)) {
// Already contains key, increment amount
$kk = $newReturnBoxes->firstWhere('box_id', $boxId);
$kk['amount'] = 100; // actually want to increase prev amount with current amount
} else {
$newReturnBoxes->push([
'box_id' => $boxId,
'amount' => $amount
]);
}
});

Maybe the problem is that you are not passing the $newReturnBoxes by reference.
Try to replace this:
use ($newReturnBoxes)
With this:
use (&$newReturnBoxes)
Reference: https://www.php.net/manual/en/language.references.pass.php

Related

How to loop read all the column from the spreadsheet using Laravel-Excel

I have a spreadsheet that contains quiz records where I save all the quiz_questions and choices in the database.
I have this code reading and saving the spreadsheet but it has some issues, I want to save the choice_1, choice_2, choice_3, and choice_4 inside the database with the column name of choices. When I run this code it only save the choice_4 columns but not all of the choices. How can I get all the choices and save it? can anyone help me? thanks in advance.
This is my QuizImport
public function collection(Collection $rows)
{
foreach($rows as $row){
$quizQuestions = quizQuestions::create([
'quiz_id' => $row['quiz_id'],
'question_num' => $row['question_num'],
'question_content' => $row['question_content'],
'tagalog_question'=> $row['tagalog_question'],
]);
$quizQuestions->choices()->create([
'option' => $row['option_1'] || $row['option_2'] || $row['option_3'] || $row['option_4'],
'remarks' => $row['remarks_1'] || $row['remarks_2'] || $row['remarks_3'] || $row['remarks_4'],
'tagalog_choices'=> $row['tagalog_choices'],
]);
}
}
This is my controller
public function store(Request $request){
$file = $request->file('file');
Excel::import(new QuizImport, $file);
return response(['message'=>"Quiz successfully imported",
'error'=>false,
'error code'=>200,
'line'=>"line".__LINE__."".basename(__LINE__),
'file'=>$file],200,[],JSON_NUMERIC_CHECK);
}
This is the sample structure of my excel
This is the expected output
"quizQuestions": [
{
"id": 2,
"quiz_id": 6,
"question_num": 1,
"question_content": "<p>Sample Question</p>",
"correct_answer": null,
"created_by": 7,
"updated_by": null,
"created_at": "2021-09-06T07:27:20.000000Z",
"updated_at": "2021-10-18T17:35:17.000000Z",
"question_image": null,
"tagalog_question": "<p><span style=\"color: black;\">Tagalog Translation of the question</span></p>",
"choices": [
{
"id": 2,
"quiz_questions_id": 2,
"option": "choices_1",
"remarks": 1,
"created_at": "2021-09-06T07:27:48.000000Z",
"updated_at": "2021-10-18T17:53:13.000000Z",
"choices_image": null,
"tagalog_choices": "Tagalog"
},
{
"id": 3,
"quiz_questions_id": 2,
"option": "choices_2",
"remarks": 0,
"created_at": "2021-09-06T07:28:01.000000Z",
"updated_at": "2021-10-18T17:53:25.000000Z",
"choices_image": null,
"tagalog_choices": "Tagalog"
},
{
"id": 4,
"quiz_questions_id": 2,
"option": "choices_3",
"remarks": 0,
"created_at": "2021-09-06T07:28:54.000000Z",
"updated_at": "2021-10-18T17:53:32.000000Z",
"choices_image": null,
"tagalog_choices": "Tagalog"
},
{
"id": 5,
"quiz_questions_id": 2,
"option": "choices_4",
"remarks": 0,
"created_at": "2021-09-06T07:29:07.000000Z",
"updated_at": "2021-10-18T17:53:37.000000Z",
"choices_image": null,
"tagalog_choices": "Tagalog"
}
]
},
But this is what I get
"quizQuestions": [
{
"id": 541,
"quiz_id": 33,
"question_num": 1,
"question_content": "Sample Question",
"correct_answer": null,
"created_by": null,
"updated_by": null,
"created_at": "2022-01-10T11:35:42.000000Z",
"updated_at": "2022-01-10T11:35:42.000000Z",
"question_image": null,
"tagalog_question": "Tagalog Translation of the Question",
"choices": [
{
"id": 1735,
"quiz_questions_id": 541,
"option": "choice4",
"remarks": 0,
"created_at": "2022-01-10T11:35:42.000000Z",
"updated_at": "2022-01-10T11:35:42.000000Z",
"choices_image": null,
"tagalog_choices": "Tagalog"
}
]
},
I believe you need a loop for creating multiple choices with the same parent. (not tested)
public function collection(Collection $rows)
{
foreach($rows as $row){
$quizQuestions = quizQuestions::create([
'quiz_id' => $row['quiz_id'],
'question_num' => $row['question_num'],
'question_content' => $row['question_content'],
'tagalog_question'=> $row['tagalog_question'],
]);
for($i = 1; $i < 5; $++) {
$quizQuestions->choices()->create([
'option' => $row['option_' .$i],
'remarks' => $row['remarks_' . $i],
'tagalog_choices'=> $row['tagalog_choices'],
]);
}
}
}

Laravel access JSON object in controller

I have this array in the controller after the submitted form holds in variable $product.
[
{
"id": 2,
"name": "nancy",
"cost": 34,
"quantity": 0,
"barcode": 12345,
"category_id": 2,
"created_at": "2020-07-05T16:04:10.000000Z",
"updated_at": "2020-07-09T04:06:09.000000Z"
},
{
"id": 5,
"name": "jk",
"cost": 100,
"quantity": 2,
"barcode": 147258,
"category_id": 2,
"created_at": "2020-07-08T20:34:56.000000Z",
"updated_at": "2020-10-18T13:09:16.000000Z"
}
]
How can I access the properties in objects like id, name, barcode ?
If you want to make it as array of array.
$products = json_decode($products, true); // Return array of array.
foreach($products as $product){
echo $product['name'];
}
Just decode it, use json_decode
$products = json_decode($products, true); // When TRUE, JSON objects will be returned as associative arrays
foreach($products as $product){
echo $product['id'];
}

Laravel - Sort array by string value first and then date

I need help to sort array by couple of logics
[
{
"id": 1,
"status": "pending",
"date": "2019-08-01"
},
{
"id": 2,
"status": "delivered",
"date": "2019-08-01"
},
{
"id": 3,
"status": "pending",
"date": "2019-08-03"
},
{
"id": 4,
"status": "delivered",
"date": "2019-08-03"
},
{
"id": 5,
"status": "delivered",
"date": "2019-08-02"
}
]
what I want to do is to sort the array to status pending show first, and then sort it by the date descending
I already test to using sortByDesc from laravel collection but the array looks like sorted it by just 1 function
$collection = $collection->sortByDesc('date')->sortByDesc(function ($row, $key) {
if($row['status'] == 'pending'){
return 1;
}else{
return 0;
}
});
My expected final result look like this :
[
{
"id": 3,
"status": "pending",
"date": "2019-08-03"
},
{
"id": 1,
"status": "pending",
"date": "2019-08-01"
},
{
"id": 4,
"status": "delivered",
"date": "2019-08-03"
},
{
"id": 5,
"status": "delivered",
"date": "2019-08-02"
},
{
"id": 2,
"status": "delivered",
"date": "2019-08-01"
}
]
Few solutions:
Use a custom callback and return an array source
$products->sortBy(function($product) {
return [$product->param1, $product->param2];
});
This will sort a collection by param2 first, and then by param1
Use a custom callback and return a composite property to sort on source
$posts = $posts->sortBy(function($post) {
return sprintf('%-12s%s', $post->column1, $post->column2);
});
Sort your array by column 1, then split it up by column 2 and then merge it again (untested).
$collection->sortByDesc('date');
$collection->groupBy('status');
$collection->keyBy('status');
EDIT: Also I'm not sure if sortByDesc('date') works with date strings.
Your expected result can be achieved like this.
$sorted = $collection
->sortByDesc('date')
->sortBy(function ($item) {
return 'pending' == $item['status'] ? 0 : 1;
})
->values();
To be more precise:
$collection= $collection->sort(
function ($a, $b) {
if(($a->status== $b->status) &&($a->status== 'pending')){
return ($a->date >= $b->date) ? -1 : 1;
}elseif($a->status== 'pending' && ($a->status!= $b->status)){
return 1;
}else{
return ($a->date <= $b->date) ? 1 : -1;
}
}
);
$collection= $collection->sortByDesc('status');

Laravel get only one column from relation

I have a table user_childrens whose contains id_parent and id_user.
I'm trying to list all childrens of the parent with this:
code:
//relation in model via belongsTo
$idparent = auth('api')->user()->id;
$list = UserChildren::where('id_parent',$idparent)
->with('child:id,name,email')
->get();
return $list->toJson();
The return is:
[
{
"id": 1,
"id_parent": 1,
"id_user": 1,
"created_at": null,
"updated_at": null,
"child": {
"id": 1,
"name": "Mr. Davin Conroy Sr.",
"email": "prempel#example.com"
}
},
{
"id": 4,
"id_parent": 1,
"id_user": 2,
"created_at": null,
"updated_at": null,
"child": {
"id": 2,
"name": "Krystel Lehner",
"email": "cernser#example.net"
}
}
]
But it's API so I want only the child column like:
[
{
"id": 1,
"name": "Mr. Davin Conroy Sr.",
"email": "prempel#example.com"
},
{..}
]
UserChildren Model:
public function child() {
return $this->belongsTo('App\User','id_user','id');
}
I know that I could do this via .map() on collection but maybe there is other solution already on this query
You can use this code
$idparent = auth('api')->user()->id;
$childs = User::whereHas('user_childrens', function ($query) use ($idparent) {
$query->where('id_parent', $idparent);
})->get(['id', 'name', 'email']);
dd($childs->toJson());
And User model define user_childrens relation.
public function user_childrens()
{
return $this->hasMany('App\UserChildren','id_user','id');
}
See also docs https://laravel.com/docs/5.5/eloquent-relationships#querying-relationship-existence

Laravel 5 + DingoApi paginate

i'm developing an api with Laravel and DingoAPI which returns the message threads of the user with pagination.
$threads = Thread::forUser($currentUserId)->latest('updated_at')->simplePaginate(1);
return API::response()->array($threads);
and i get this kind of response :
{
"per_page": 1,
"current_page": 1,
"next_page_url": "http://my.app/api/messages?page=2",
"prev_page_url": null,
"from": 1,
"to": 1,
"data": [
{
"id": 1,
"subject": null,
"created_at": "2016-03-18 12:33:38",
"updated_at": "2016-03-18 12:33:38",
"deleted_at": null
}
]
}
What can i do to remove some field of the response ? i just need data and next_page_url …
i tried this way :
$array_response = [
'next_page_url' => $threads['next_page_url'],
'data' => $threads['data']
];
but only null values are returned.
I guess Dingo Api is doing some work behind the scene…
Try this
$threads = Thread::forUser($currentUserId)->latest('updated_at')->simplePaginate(1);
$arrayResponse = json_decode(API::response()->array($threads));
$arrayResponseEdited = [
'next_page_url' => $arrayResponse['next_page_url'],
'data' => $arrayResponse['data']
];
return arrayResponseEdited;

Resources