why my php array don't appears the changes on it - php

hi everyone i'm working on laravel project and for some reason i need to add some attributes to the request using middleware , but my request is nested arrays .
here is the code :
// Middleware //
public function handle(Request $request, Closure $next)
{
$request->json()->add(['created_by_user_id' => Auth::id()]);
$request->json()->add(['user_id' => Auth::id()]);
$request->json()->add(['updated_by_user_id' => Auth::id()]);
$request->json()->add(['deleted_by_user_id' => Auth::id()]);
foreach ($request->json()->all() as &$json_request){
if(is_array($json_request)){
foreach ($json_request as &$item){
$item += ['created_by_user_id' => Auth::id()];
$item += ['updated_by_user_id' => Auth::id()];
$item += ['deleted_by_user_id' => Auth::id()];
}
}
}
return $next($request);
}
it can add the attributes to the top level of arrays ,and when it get deeper it works fine but the attributes are not added to the main request , so when i return request's attributes from the controller to see attributes are arrived i get :
{
"max_price_new": 9999,
"min_price_new": 1111,
"max_price_old": 9999,
"min_price_old": 1111,
"names": [
{
"translation_lang_id": 1,
"category_name": "test9"
},
{
"translation_lang_id": 2,
"category_name": "9تجربة"
}
],
"category_pages": [
{
"page_id": 1
}
],
"category_regions": [
{
"region_id": 1
}
],
"category_photos": [
{
"device_id": 1,
"photo_path": "ite",
"photo_size": 1
}
],
"created_by_user_id": 1,
"user_id": 1,
"updated_by_user_id": 1,
"deleted_by_user_id": 1
}

Related

Sum all specified fields in a collection

I am using PHP to access a MongoDB collection in which I have recorded purchases of my shop.
Example document:
{"_id":{"$oid":"61ff011a5b55479726fe5208"},"monthYear":"2-2022","timestamp":{"$date":"2022-02-05T22:58:34.952Z"},"productIndex":"x","productPriceUSD":10,"customerName":"x","customerID":"x","notes":"x","__v":0}
Now I want to add the value of field "productPriceUSD" from all documents in the collection and get a sum at the end.
Maybe someone can help me?
That's my start:
I know, it probably does not make any sense.
$client = new MongoDB\Client(
'xxx'
);
$sumtotal = function() use ($client)
{
$collection = $client->database->purchases;
$options = [];
$filter = [
['$group' => [
'_id' => '$_id',
'productPriceUSD' => [
'$sum' => [
'$cond' => [ [ '$gt' => [ '$productPriceUSD', 0 ] ], '$productPriceUSD', 0 ],
],
]],
]];
$result = $collection->aggregate($filter, $options);
};
Here two pipelines you need
{
$group: {
_id: "",
total: { $sum: "$productPriceUSD" }
}
},
{
$project: {
_id: 0,
total: "$total"
}
}
Playground link: https://mongoplayground.net/p/8OTGkK7wLIp

Loop through Categories and its Products in PHP Laravel

I have to create an array with the categories array and its related products i'm fetching category with all related products using this query
$categoryData= Category::with('product')->get();
Data is beign fetched properly, using this loop to get data in the format given below:
foreach($categoryData as $row){
$categoriesData[] = [
'id' => $row->id,
'title' => $row->title,
];
foreach($row->product as $rowproduct){
$categoriesData['product_details'][] = [
'product_name' => $rowproduct->name,
'product_price' => $rowproduct->price
];
}
}
Format (It should be something like this) :
{
"categoriesData": {
"0": {
"id": 1,
"category_name" : "Name 1",
"product_details": [
{
"id": 1,
"product_name": Product Name,
},
],
"1": {
"id": 2,
""category_name" ": "Name 2",
"product_details": [
{
"id": 1,
"product_name": product name,
},
},
but through present loop all product is getting saved in one array. It is not saving inside category.
Any help is highly appreciated
You can do this with Collection methods if you wanted to, basically just map:
$array = $categoryData->map(function ($category) {
return [
'id' => $category->id,
'title' => $category->title,
'product_details' => $category->products->map(function ($product) {
return [
'product_name' => $product->name,
'product_price' => $product->price,
];
}),
];
})->all();
Though this is going in the direction of using a transformer or API resource to format this data.
Hi I think this is what you're looking for :
foreach ($categoryData as $key => $row) {
$categoriesData[$key] = [
'id' => $row->id,
'title' => $row->title,
];
foreach ($row->product as $rowproduct) {
$categoriesData[$key]['product_details'][] = [
'product_name' => $rowproduct->name,
'product_price' => $rowproduct->price
];
}
}

PHP array group by category

I have a list of stores and they can have multiple categories.
Today i display each store multiple times, one line with only one category.
How can i group the stores, creating an array of their categories, so the store is displayed only one time and have their multiple categories ?
This is my attempt:
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
array_push(
$stores,
[
"id"=> $row["id"],
"name"=> $row["nome"],
"categories"=> array([
"name"=> $row["categories"]
//how can i have an array of categories
])
]
);
}
This is how i display the json result:
{
id: 74,
name: "First Store",
categories: [
{
name: "Clothes"
}
]
},
{
id: 1,
name: "Second Store",
categories: [
{
name: "Food"
}
]
},
{
id: 1,
name: "Second Store",
categories: [
{
name: "Toys"
}
]
},
This is how i need to show the Json:
{
id: 74,
name: "First Store",
categories: [
{
name: "Clothes"
}
]
},
{
id: 1,
name: "Second Store",
categories: [
{
name: "Food"
},
{
name: "Toys"
}
]
},
In my attempt i try inside the while to create the categories but have a php warning: end() expects parameter 1 to be array, null given
if( isset($stores) ) {
if( end($stores['id']) != $row["id"] ) {
array_push($category_array, $row["categories"]);
}
}
I believe you are looking for something like this when processing your returned MySQL rows to json_encode: https://3v4l.org/d4Wf2
This will place the stores in 1 temp $storeTracker array with the store id as the array key (this assumes store id is a constant in each record you're getting back and is always the same). From here you can then check if the array key (store id) already exists, and if so, continue to add categories to the store if the category doesn't already exist. After doing this, you can then parse to json_encode to create a valid JSON object to return. Granted there may be a more eloquent way to achieve this, but this showcases the array manipulation and whatnot to try and group data for your case.
<?php
// Data coming from MySQL Database
$rowData = [];
$rowData[] = ['id' => 74, 'name' => 'First Store', 'categories' => 'Food'];
$rowData[] = ['id' => 74, 'name' => 'First Store', 'categories' => 'DVDs'];
$rowData[] = ['id' => 1, 'name' => 'Second Store', 'categories' => 'Food'];
$rowData[] = ['id' => 1, 'name' => 'Second Store', 'categories' => 'Toys'];
$rowData[] = ['id' => 1, 'name' => 'Second Store', 'categories' => 'Toys'];
$rowData[] = ['id' => 1, 'name' => 'Second Store', 'categories' => 'Clothing'];
$rowData[] = ['id' => 3, 'name' => 'Third Store', 'categories' => 'Toys'];
$rowData[] = ['id' => 3, 'name' => 'Third Store', 'categories' => 'Clothing'];
$rowData[] = ['id' => 3, 'name' => 'Third Store', 'categories' => 'Clothing'];
/**
* Check if store category name already added to store record
*/
function categoryExistsAlready($categories, $category) {
foreach($categories as $key => $catArr) {
if(strtolower($catArr['name']) === strtolower($category)) {
return true;
}
}
return false;
}
$storeTracker = [];
foreach($rowData as $key => $storeData) {
$storeCategory = $storeData['categories'];
$storeId = $storeData['id'];
// If store exists, add category to categories array
if (array_key_exists($storeId, $storeTracker)) {
if (!categoryExistsAlready($storeTracker[$storeId]['categories'], $storeCategory)) {
$storeTracker[$storeId]['categories'][] = ['name' => $storeCategory];
}
continue;
}
// Update store categories to be array with category
$storeData['categories'] = [];
$storeData['categories'][] = ['name' => $storeCategory];
// Add store data to overall tracking array
$storeTracker[$storeId] = $storeData;
}
// Format JSON response
$jsonReturn = '[';
$i = count($storeTracker);
foreach($storeTracker as $storeId => $storeData) {
$i--;
$jsonReturn .= json_encode($storeData);
// Determine last comma separating objects
if ($i > 0) {
$jsonReturn .= ',';
}
}
$jsonReturn .= ']';
echo $jsonReturn;
Will give you this valid JSON https://jsonlint.com/:
[{
"id": 74,
"name": "First Store",
"categories": [{
"name": "Food"
}, {
"name": "DVDs"
}]
}, {
"id": 1,
"name": "Second Store",
"categories": [{
"name": "Food"
}, {
"name": "Toys"
}, {
"name": "Clothing"
}]
}, {
"id": 3,
"name": "Third Store",
"categories": [{
"name": "Toys"
}, {
"name": "Clothing"
}]
}]

Create nested JSON with dynamic keys with PHP

I get some data from an API call and I try to construct a JSON to send it back to another API.
The final JSON must look like this:
{
"jobs": {
"MP_OFFER_ID_1": {
"job_id": "jobboard_reference_1",
"url": "url_1",
"status": 0
},
"MP_OFFER_ID_2": {
"job_id": "job_id_2",
"url": "url_2",
"status": 1
},
}
}
So under the jobs key, it's not an array of elements but a list of elements with unique keys.
And that's what I'm having trouble to get.
The data I want to parse is in an array structured like this:
Array(
[0] => Array(
[link] => some-url
[id] => 18790674
[ref] => 0015909-18790674
)
// ...
);
link has to be placed in the url key of the JSON.
id is the JSON key, in the examples it's MP_OFFER_ID_1 etc
ref has to be placed in job_id
I actually have this JSON at the end:
{
"jobs": [
[
{
"18790674": {
"job_id": "0015909-18790674",
"url": "test",
"status": 1
}
},
{
"18790678": {
"job_id": "0015892-18790678",
"url": "test",
"status": 1
}
}
]
]
}
As you can see, jobs is an array (actually it's an array of array ^^) and that's not what I want here...
I came up with this, but it was very difficult to understand what exactly you want from the very limited info in question:
<?php
$input = [
[
'id' => 18790674,
'link' => 'some-url',
'ref' => '0015909-18790674',
],
[
'id' => 18790678,
'link' => 'another-url',
'ref' => '0015909-18790678',
],
];
$output = new stdClass();
foreach ($input as $arr) {
$obj = new stdClass();
$key = $arr['id'];
$obj->job_id = $arr['id'];
$obj->url = $arr['link'];
$obj->status = '1'; // ?
$output->{$key} = $obj;
}
echo json_encode($output, JSON_PRETTY_PRINT);
Output:
{
"18790674": {
"job_id": 18790674,
"url": "some-url",
"status": "1"
},
"18790678": {
"job_id": 18790678,
"url": "another-url",
"status": "1"
}
}

Validation for an associative array in Laravel

I have a JSON structure like this which I want to validate.
{
"result":[{
"product_id": 1,
"client": 49,
"ticket": 2,
"sold_from_date": 1431588871,
"sold_to_date": 1433122200,
"discount_given":18,
"cheques":[{
"cheque_number" : 123456,
"amount": 6000,
"cheque_date": 1433122200,
"bank": "UCD"
},
{"cheque_number" : 456234,
"amount": 6000,
"cheque_date": 1433122200,
"bank": "AMB"
}
]
},
{
"product_id": 1,
"client": 49,
"ticket": 2,
"sold_from_date": 1433122200,
"sold_to_date": 1434688959
}]
}
I want to validate this JSON in Laravel.
I tried doing this:
$validator = \Validator::make($data, []);
$validator->each('result.product_id' , ['required|numeric']);
$validator->each('result.sold_from_date' , ['required|numeric']);
$validator->each('result.sold_to_date' , ['required|numeric']);
$validator->each('result.cheques.cheque_number' , ['sometimes|required|numeric']);
$validator->each('result.cheques.amount', ['sometimes|required|numeric']);
return $validator;
I am getting this error every time:
Attribute for each() must be an array.
Also, how can I validate cheques? Because it can or cannot be in JSON.
Create an array from json with json_decode function.
Try:
$dataarray = json_decode($data);
$validator = \Validator::make($dataarray['result'][0], [
'product_id' => 'required|numeric',
'sold_from_date' => 'required|numeric'
]);
iterate the array:
$roles = array(
'product_id' => 'required|numeric',
'sold_from_date' => 'required|numeric'
);
foreach($data as $element)
{
foreach($element as $value) {
$validator = \Validator::make($value, $roles);
}
}

Categories