generate dynamic array inside array - php

I am using Laravel .if i dd() $arrBody I get following result dd($arrBody);
array:7[▼
"first_name" => "john"
"last_name" => "doe"
"email_address" => "john#gmail.com",
"age"=> 25,
"date"=>"2021-07-9",
"country"=>"USA",
"code"=>"3045"
]
Now I want to get email,firstname and last name from $arryBody and assigned them to email,first_name and last_name key. But rest of keys like age, country,state and date i want them to go in custom_fields array but its like a hardcoded here. since I am displaying age, date,country one by one. My array may have more key/values so I want to make custom_fields array dynamic. I want field_name inside inside custom_fields to have a same name that comes after email,first_name and last_name of $arrBody array instead of manually writing field_name and want to assign that keys value to "value"
$data = [
"subscribers"=>[
[
"email"=> $arrBody['email'],
"first_name"=> $arrBody['first_name'],
"last_name"=> $arrBody['last_name'],
"subscribed"=> true,
"custom_fields"=>[
[
"field_name"=> "age",
"value_type"=> "text",
"value"=> array_key_exists('age',$arrBody) ? $arrBody['age']:''
],
[
"field_name"=> "country",
"value_type"=> "text",
"value"=> array_key_exists('country',$arrBody) ? $arrBody['country']:''
],
[
"field_name"=> "date",
"value_type"=> "text",
"value"=> array_key_exists('date',$arrBody) ? $arrBody['date']:''
],
//so on...
]
]
]
];
In Laravel I can use
$main = ['email', 'first_name', 'last_name'];
$subscriber = Arr::only($arrBody, $main);
$custom = Arr::exclude($arrBody, $main);
Now I want this $custom array inside "custom_fields"=>[] dynamically until the length of $custom array instead of checking if it has age, country etc or not.
something like this if possible
custom_fields" => [
[
"field_name" => array_keys($custom)
"value_type" => "text",
"value" => array_values($custom)
],
//go until the end of $custom array
];

$data = [
"subscribers"=>[
[
"email"=> $arrBody['email'],
"first_name"=> $arrBody['first_name'],
"last_name"=> $arrBody['last_name'],
"subscribed"=> true,
"custom_fields"=> collect($custom)->map(function($value, $key) {
return [
'field_name' => $key,
'value_type' => gettype($value),
'value' => $value,
];
}),
]
]
];
add ->toArray() after if you want it back to an array over a collection,
Also gettype wont work unless you actually use those types, not a number in a string format.

Related

How can I build an object/array?

I am rather new to PHP so I don't know how to work with these datasets. I make a MySQL select and get back an object like this:
{
"membername": "NAME",
"bookingdate": "2020-02-03",
"categoryid": 1,
"dailyworkhourssum": "7.70"
},
{
"membername": "NAME",
"bookingdate": "2020-02-03",
"categoryid": 3,
"dailyworkhourssum": "1.2"
},
{
"membername": "NAME",
"bookingdate": "2020-02-05",
"categoryid": 3,
"dailyworkhourssum": "7.70"
},
I want to iterate through this and in the end it should look like this:
{
"membername": "NAME",
"bookingdate": "2020-02-03",
"categoryid1": true,
"categorid3": true,
"dailyworkhourssum1": "7.70",
"dailyworkhourssum3": "1.2"
},
{
"membername": "NAME",
"bookingdate": "2020-02-05",
"categoryid": 3,
"dailyworkhourssum": "7.70"
},
What this does is that it merges tow fields together (if they have the same bookingdate )into one so that I can display it in a table without reoccurring dates.
My problem:
I don't know what this type of data is called.
I don't know how to create something like this.
I can add fields to this type of data with $data->newField = example so I think that this is an object.
In JS it's called an object, but in PHP you will use an associative array instead.
In your case, I think, you have an array of associative arrays. It looks like this:
$books = [
[
"membername" => "NAME",
"bookingdate" => "2020-02-03",
"categoryid" => 1,
"dailyworkhourssum" => "7.70"
],
[
"membername" => "NAME",
"bookingdate" => "2020-02-03",
"categoryid" => 3,
"dailyworkhourssum" => "1.2"
],
[
"membername" => "NAME",
"bookingdate" => "2020-02-05",
"categoryid" => 3,
"dailyworkhourssum" => "7.70"
]
];
If you wanna merge an arrays with the same "bookingdate" then I recommend you to loop through this array and add its elements to another associative array with bookingdates as keys, and check, in case if there is such key already, then merge the arrays, like this:
$merged = [];
foreach ($books as $book) {
$date = $book['bookingdate'];
if (isset($merged[$date])) {
$merged[$date] = $merged[$date] + $book;
} else {
$merged[$date] = $book;
}
}
I think that it is not a valid code (no time, sorry), but I hope, you cautch the idea.
If you want a 'list' instead of an associative array, than you can do this:
$mergedList = array_values($merged);
Thus you will rid of string keys.
If I understood correctly, you obtain a table with 4 columns an a variable number of rows and you want to transform it to a table with a variable number of columns. For that, using a data structure where every item is different from the previous one can make everything harder than it needs. I'd suggest you use a fixed structure:
// I'm assuming you have a PHP array as starting point
$input = [
[
'membername' => 'NAME',
'bookingdate' => '2020-02-03',
'categoryid' => 1,
'dailyworkhourssum' => '7.70',
],
[
'membername' => 'NAME',
'bookingdate' => '2020-02-03',
'categoryid' => 3,
'dailyworkhourssum' => '1.2',
],
[
'membername' => 'NAME',
'bookingdate' => '2020-02-05',
'categoryid' => 3,
'dailyworkhourssum' => '7.70',
],
];
$output = [];
foreach ($input as $data) {
// We'll group by booking date
if (!isset($output[$data['bookingdate']])) {
$output[$data['bookingdate']] = [
'membername' => $data['membername'],
'bookingdate' => $data['bookingdate'],
'categoryid' => $data['categoryid'],
'dailyworkhourssum' => [],
];
}
// A single date may have several daily work hours
$output[$data['bookingdate']]['dailyworkhourssum'][] = $data['dailyworkhourssum'];
}
// We discard array keys (we only needed them to group)
echo json_encode(array_values($output));
[{
"membername": "NAME",
"bookingdate": "2020-02-03",
"categoryid": 1,
"dailyworkhourssum": ["7.70", "1.2"]
}, {
"membername": "NAME",
"bookingdate": "2020-02-05",
"categoryid": 3,
"dailyworkhourssum": ["7.70"]
}]
Wherever you consume this JSON you just need to loop the dailyworkhourssum array. You may also want to loop the entire structure before printing the table and keep a counter in order to determine the maximum number of columns so you can draw empty cells where needed (tables are rectangular).

How to compare two columns instead of values using medoo framework

I want to compare two columns of medoo rather its values.
$issues = $database->select("issues","*",[
"AND" => [
"projectid" => 1,
"estimated_hrs[<]" => "timespent"
]
]);
But getting an error while doing so.Is there any solution??
Check out columns relationship here: https://medoo.in/api/where
$database->select("post", [
"[>]account" => ["author_id" => "user_id"],
], [
"post.id",
"post.content"
], [
"AND" => [
// Connect two column with condition sign like [=], [>], [<], [!=] as one of array value
"post.restrict[<]account.age",
"account.user_name" => "foo",
"account.email" => "foo#bar.com",
]
]
);
// WHERE "post"."restrict" < "account"."age" AND "account"."user_name" = 'foo' AND "account"."email" = 'foo#bar.com'

PHP Append array in nested array

I have below array, I need to append a new array inside $newData['_embedded']['settings']['web/vacation/filters']['data'], How can I access and append inside it ?
$newData = [
"id" => "47964173",
"email" => "abced#gmail.com",
"firstName" => "Muhammad",
"lastName" => "Taqi",
"type" => "employee",
"_embedded" => [
"settings" => [
[
"alias" => "web/essentials",
"data" => [],
"dateUpdated" => "2017-08-16T08:54:11Z"
],
[
"alias" => "web/personalization",
"data" => [],
"dateUpdated" => "2016-07-14T10:31:46Z"
],
[
"alias" => "wizard/login",
"data" => [],
"dateUpdated" => "2016-09-26T07:56:43Z"
],
[
"alias" => "web/vacation/filters",
"data" => [
"test" => [
"type" => "teams",
"value" => [
0 => "09b285ec-7687-fc95-2630-82d321764ea7",
1 => "0bf117b4-668b-a9da-72d4-66407be64a56",
2 => "16f30bfb-060b-360f-168e-1ddff04ef5cd"
],
],
"multiple teams" => [
"type" => "teams",
"value" => [
0 => "359c0f53-c9c3-3f88-87e3-aa9ec2748313"
]
]
],
"dateUpdated" => "2017-07-03T09:10:36Z"
],
[
"alias" => "web/vacation/state",
"data" => [],
"dateUpdated" => "2016-12-08T06:58:57Z"
]
]
]
];
$newData['_embedded']['settings']['web/vacation/filters']['data'] = $newArray;
Any Hint to quickly append it, I don't want to loop-in and check for keys inside loops.
The settings subarray is "indexed". You first need to search the alias column of the subarray for web/vacation/filters to find the correct index. Using a foreach loop without a break will mean your code will continue to iterate even after the index is found (bad coding practice).
There is a cleaner way that avoids a loop & condition & break, use array_search(array_column()). It will seek your associative element, return the index, and immediately stop seeking.
You can use the + operator to add the new data to the subarray. This avoids calling a function like array_merge().
Code: (Demo)
if(($index=array_search('web/vacation/filters',array_column($newData['_embedded']['settings'],'alias')))!==false){
$newData['_embedded']['settings'][$index]['data']+=$newArray;
}
var_export($newData);
Perhaps a more considered process would be to force the insert of the new data when the search returns no match, rather than just flagging the process as unsuccessful. You may have to tweak the date generation for your specific timezone or whatever... (Demo Link)
$newArray=["test2"=>[
"type" =>"teams2",
"value" => [
0 => "09b285ec-7687-fc95-2630-82d321764ea7",
1 => "0bf117b4-668b-a9da-72d4-66407be64a56",
2 => "16f30bfb-060b-360f-168e-1ddff04ef5cd"
],
]
];
if(($index=array_search('web/vacation/filters',array_column($newData['_embedded']['settings'],'alias')))!==false){
//echo $index;
$newData['_embedded']['settings'][$index]['data']+=$newArray;
}else{
//echo "couldn't find index, inserting new subarray";
$dt = new DateTime();
$dt->setTimeZone(new DateTimeZone('UTC')); // or whatever you are using
$stamp=$dt->format('Y-m-d\TH-i-s\Z');
$newData['_embedded']['settings'][]=[
"alias" => "web/vacation/filters",
"data" => $newArray,
"dateUpdated" => $stamp
];
}
You need to find the key that corresponds to web/vacation/filters. For Example you could use this.
foreach ($newData['_embedded']['settings'] as $key => $value) {
if ($value["alias"]==='web/vacation/filters') {
$indexOfWVF = $key;
}
}
$newData['_embedded']['settings'][$indexOfWVF]['data'][] = $newArray;
From the comments. Then you want to merge the arrays. Not append them.
$newData['_embedded']['settings'][$indexOfWVF]['data'] = array_merge($newData['_embedded']['settings'][$indexOfWVF]['data'],$newArray);
Or (if it's always Filter1):
$newData['_embedded']['settings'][$indexOfWVF]['data']['Filter1'] = $newArray['Filter1'];

how to aggregate mongodb collection data in laravel

i have collection like this
{
"wl_total" : 380,
"player_id" : 1241,
"username" : "Robin",
"hand_id" : 292656,
"time" : 1429871584
}
{
"wl_total" : -400,
"player_id" : 1243,
"username" : "a",
"hand_id" : 292656,
"time" : 1429871584
}
as both collection have same hand_id i want to aggregate both these collection on the basis of hand_id
i want result as combine of
data=array(
'hand_id'=>292656,
'wl_total'=>
{
0=>380,
1=>-400
},
'username'=>
{
0=>"Robin",
1=>"a"
},
"time"=>1429871584
)
You basically want a $group by the "hand_id" common to all players, and then $push to different arrays in the document and then also do something with "time", I took $max. Nees to be an accumulator of some sort at any rate.
Also not sure what your underlying collection name is, but you can call this in laravel with a construct like this:
$result = DB::collection('collection_name')->raw(function($collection)
{
return $collection->aggregate(array(
array(
'$group' => array(
'_id' => '$hand_id',
'wl_total' => array(
'$push' => '$wl_total'
),
'username' => array(
'$push' => '$username'
),
'time' => array(
'$max' => '$time'
)
)
)
));
});
Which returns output ( shown in json ) like this:
{
"_id" : 292656,
"wl_total" : [
380,
-400
],
"username" : [
"Robin",
"a"
],
"time" : 1429871584
}
Personally I would have gone for a single array with all the infomation in it for the grouped "hand", but I supose you have your reasons why you want it this way.

Nested PHP arrays to json

So my code here:
$featurecollection = ("FeatureCollection");
$test[] = array (
"type" => $featurecollection,
$features[] = array($images)
);
file_put_contents($cache,json_encode($test));
results in the following json:
[
{
"type":"feature",
"0":[
[
{
"title":"some title",
"src":"value",
"lat":"value",
"lon":"value"
},
{
"title":"some title",
...
But I need to nest things differently and I'm perplexed on how the php array should be constructed in order to get a result like:
{
"type":"FeatureCollection",
"features":[
{
"type":"Feature",
"geometry":{
"coordinates":[
-94.34885,
39.35757
],
"type":"Point"
},
"properties":{
"latitude":39.35757,
"title":"Kearney",
"id":919,
"description":"I REALLY need new #converse, lol. I've had these for three years. So #destroyed ! :( Oh well. Can't wait to get a new pair and put my #rainbow laces through. #gay #gaypride #bi #proud #pride #colors #shoes #allstar #supporting ",
"longitude":-94.34885,
"user":"trena1echo5",
"image":"http://images.instagram.com/media/2011/09/09/ddeb9bb508c94f2b8ff848a2d2cd3ece_7.jpg",
"instagram_id":211443415
}
},
What would the php array look like for that? I'm thrown off by the way everything is nested but still has a key value.
Here's how I'd represent that in PHP:
array(
'type' => 'FeatureCollection',
'features' => array(
array(
'type' => 'Feature',
'geometry' => array(
'coordinates' => array(-94.34885, 39.35757),
'type' => 'Point'
), // geometry
'properties' => array(
// latitude, longitude, id etc.
) // properties
), // end of first feature
array( ... ), // etc.
) // features
)
So to get that structure, each feature has to be an associative array of:
type,
geometry - an associative array of:
coordinates - an indexed array of values,
type
properties - an associative array of values like latitude, longitude, id etc.
It's times like these when I prefer languages that distinguish between lists (array(1, 2, 3)) and dictionaries or maps (array('a' => 1, 'b' => 2)).
With PHP 5.4 and above:
$array = [
'type' => 'FeatureCollection',
'features' => [
[
'type' => 'Feature',
'geometry' => [
'coordinates' => [-94.34885, 39.35757],
'type' => 'Point'
], // geometry
'properties' => [
// latitude, longitude, id etc.
] // properties
], // end of first feature
[] // another feature, and so on
] // end of features
];
For the PHP script below:
<?php
header('Content-type=> application/json');
echo json_encode($array);
This is the JSON output;
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"coordinates": [
-94.34885,
39.35757
],
"type": "Point"
},
"properties": []
},
[]
]
}

Categories