Using a form to create JSON - php

I have an API which expects a JSON string in the following format:
{
"Title": "Mr",
"Forenames": "Steve",
"Surname": "Williams",
"CountryOfBirth": 1,
"EmailAddress": "john.doe#email.com",
"EmailType": "Personal",
"BirthDate": "\/Date(632880000000)\/",
"Suffix": null,
"NationalInsuranceNumber": null,
"PrimaryAddress": {
"Address1": "Flat 1",
"Address2": "Oxford Street",
"City": "London",
"County": "London",
"Postcode": "L12456",
"Country": 1
},
"AdditionalAddresses": [
{
"Address1": null,
"Address2": null,
"City": null,
"County": null,
"Postcode": null,
"Country": 0,
"AddressType": 0
}
],
"PrimaryTelephone": {
"Number": "123456789",
"DialingCode": 1,
"TelephoneType": 1
},
"AdditionalTelephone": [
{
"Number": null,
"DialingCode": 0,
"TelephoneType": 0
}
],
"BankAccount": {
"AccountName": "John Doe Account",
"AccountNumber": "123456789",
"SortCode": "123456"
},
"PrimaryCitizenship": {
"CountryOfResidency": 1,
"TaxIdentificationNumber": "AB12CD34EF56"
},
"AdditionalCitizenship": [
{
"CountryOfResidency": 0,
"TaxIdentificationNumber": null
}
],
"ExternalCustomerId": "151",
"ExternalPlanId": "151",
"PlanType": 10
}
As you can see there are some inner nested elements where each value can itself be an array, such as AdditionalTelephone
I re-created this JSON string in PHP with the following:
<?php
$dataArray = array(
"Title" => "Mr",
"Forename" => "Jesse",
"Surname" => "Orange",
"CountryOfBirth" => 1,
"EmailAddress" => "email#gmail.com",
"EmailType" => "Personal",
"BirthDate" => "\/Date(632880000000)\/",
"Suffix" => null,
"PrimaryAddress" => array(
"Address1" => "Flat 1",
"Address2" => "Oxford Street",
"City" => "London",
"County" => "London",
"Postcode" => "L12456",
"Country" => 1
),
"AdditionalAddresses" => array(
array(
"Address1" => null,
"Address2" => null,
"City" => null,
"County" => null,
"Postcode" => null,
"Country" => 0,
"AddressType" => 0
)
),
"PrimaryTelephone" => array(
"Number" => "123456789",
"DialingCode" => 1,
"TelephoneType" => 1
),
"AdditionalTelephone" => array(
array(
"Number" => "123456789",
"DialingCode" => 1,
"TelephoneType" => 1
)
),
"BankAccount" => array(
"AccountName" => "John Doe Account",
"AccountNumber" => "123456789",
"SortCode" => "123456"
),
"PrimaryCitizenship" => array(
"CountryOfResidency" => 1,
"TaxIdentificationNumber" => "AB12CD34EF56"
),
"AdditionalCitizenship" => array(
array(
"CountryOfResidency" => 0,
"TaxIdentificationNumber" => null
)
),
"ExternalCustomerId" => "151",
"ExternalPlanId" => "151",
"PlanType" => 10
);
header("Content-type:application/json");
$jsonDataArray = json_encode($dataArray, JSON_PRETTY_PRINT);
echo $jsonDataArray;
die();
?>
This prints the same kind of thing.
Now, I have a form that a user fills in and the data is POSTed, so I wanted to use these values in the array I had created.
For example:
$dataArray = array(
"Title" => POST['Title'],
etc
)
The question is: when a value is a list of inner arrays such as the case with AdditionalCitizenship can I use names of inputs as arrays?
<input type="text" name=AdditionalCitizenship[Array1]['CountryOfResidency']>
<input type="text" name=AdditionalCitizenship[Array2]['CountryOfResidency']>

Yes, except you would use
<input type="text" name="AdditionalCitizenship[0][CountryOfResidency]">
<input type="text" name="AdditionalCitizenship[0][TaxIdentificationNumber]">
<input type="text" name="AdditionalCitizenship[1][CountryOfResidency]">
<input type="text" name="AdditionalCitizenship[1][TaxIdentificationNumber]">
In your $_POST array this will look like
"AdditionalCitizenship" => array(
array(
"CountryOfResidency" => 0,
"TaxIdentificationNumber" => null
),
array(
"CountryOfResidency" => 0,
"TaxIdentificationNumber" => null
)
)

Related

Recursive Search array with Multiple Needle - PHP

Array :
$arrayStr = ["user_id" => 2,
"user_name" => "Denny Septian Panggabean",
"user_company" => "KMK Global Sports",
"user_relation" => "Broker",
"user_roles" => "Super Admin",
"user_rules" => [
[
"menu_no" => "1",
"menu_parent" => "0",
"menu_name" => "Dashboard",
"menu_link" => "dashboard",
"menu_icon" => "fas fa-tachometer-alt",
"menu_class" => "",
"menu_access" => "F",
"menu_order" => "1",
"menu_locked" => "0"
],
[
"menu_no" => "2",
"menu_parent" => "0",
"menu_name" => "Settings",
"menu_link" => "javascript:void(0)",
"menu_icon" => "fas fa-cogs",
"menu_class" => "",
"menu_access" => "F",
"menu_order" => "2",
"menu_locked" => "0",
"menu_child" => [
[
"menu_no" => "5",
"menu_parent" => "2",
"menu_name" => "Diagnosa",
"menu_link" => "dashboard/diagnosa",
"menu_icon" => "fas fa-angle-double-right",
"menu_class" => "",
"menu_access" => "F",
"menu_order" => "1",
"menu_locked" => "0"
],
[
"menu_no" => "6",
"menu_parent" => "2",
"menu_name" => "Provider",
"menu_link" => "dashboard/provider",
"menu_icon" => "fas fa-angle-double-right",
"menu_class" => "",
"menu_access" => "F",
"menu_order" => "2",
"menu_locked" => "0"
],
[
"menu_no" => "7",
"menu_parent" => "2",
"menu_name" => "Relation",
"menu_link" => "dashboard/relation",
"menu_icon" => "fas fa-angle-double-right",
"menu_class" => "",
"menu_access" => "F",
"menu_order" => "3",
"menu_locked" => "0"
],
[
"menu_no" => "8",
"menu_parent" => "2",
"menu_name" => "Plan",
"menu_link" => "dashboard/plan",
"menu_icon" => "fas fa-angle-double-right",
"menu_class" => "",
"menu_access" => "F",
"menu_order" => "4",
"menu_locked" => "0"
],
[
"menu_no" => "4",
"menu_parent" => "2",
"menu_name" => "Benefit Group",
"menu_link" => "dashboard/benefit-group",
"menu_icon" => "fas fa-angle-double-right",
"menu_class" => "",
"menu_access" => "F",
"menu_order" => "5",
"menu_locked" => "0"
],
[
"menu_no" => "3",
"menu_parent" => "2",
"menu_name" => "Benefit",
"menu_link" => "dashboard/benefit",
"menu_icon" => "fas fa-angle-double-right",
"menu_class" => "",
"menu_access" => "F",
"menu_order" => "6",
"menu_locked" => "0"
],
[
"menu_no" => "9",
"menu_parent" => "2",
"menu_name" => "Menu",
"menu_link" => "dashboard/menu",
"menu_icon" => "fas fa-angle-double-right",
"menu_class" => "",
"menu_access" => "R",
"menu_order" => "7",
"menu_locked" => "0"
],
[
"menu_no" => "10",
"menu_parent" => "2",
"menu_name" => "User",
"menu_link" => "dashboard/user",
"menu_icon" => "fas fa-angle-double-right",
"menu_class" => "",
"menu_access" => "F",
"menu_order" => "8",
"menu_locked" => "0"
],
[
"menu_no" => "11",
"menu_parent" => "2",
"menu_name" => "Policy",
"menu_link" => "dashboard/policy",
"menu_icon" => "fas fa-angle-double-right",
"menu_class" => "",
"menu_access" => "F",
"menu_order" => "9",
"menu_locked" => "0"
],
],
],
],
];
Function :
public function arrRecursiveAccessMap(string $needle = '', string $needleOther = '', array $haystack = [])
{
$dataParams = array(
'create' => array('F','W'),
'update' => array('F','W'),
'delete' => array('F'),
);
$paramKeys = array_keys($dataParams);
if (is_numeric($needleOther) || in_array($needleOther, $paramKeys, true)) {
foreach($haystack as $first_level_key=>$value) {
if ($needle === $value) {
return array($first_level_key);
} elseif (is_array($value)) {
$callback = $this->arrRecursiveAccessMap($needle, $needleOther, $value);
if ($callback) {
return array_merge(array($first_level_key), $callback);
}
}
}
return false;
}
return false;
}
Concepts :
Any user get access list to menu, If every user enter to not accessible uri param, decline it.
Example :
User John Doe have list menu
Products (Full Access)
Report (Full Access)
Menu (Read Only)
And John Doe opened https://localhost/dashboard/menu/create , by system decline it.
Expectation :
I want to search value dashboard/menu to get 'menu_access' value is R. And validate what if value R in array $dataParams['create'] alias ['F','W'] ?
Example :
Use : arrRecursiveAccessMap('dashboard/menu', 'create', $arrayStr);
Expect Result : false
$dataParams = array(
'create' => array('F','W'),
'update' => array('F','W'),
'delete' => array('F'),
);
$paramKeys = array_keys($dataParams);
You are repeating the above code snippet in every recursive call which is not needed. You can rather make this as a parameter for your function.
You also did return array_merge(array($first_level_key), $callback); but you said Expect Result : false. So, an array_merge is also not needed.
You also have this check if (is_numeric($needleOther) || in_array($needleOther, $paramKeys, true)) {, which is again not needed.
Solution:
You can simply make a function, pass the $dataParams and create key as parameters. Keep calling the same function recursively on menu_child and return true if you find the value of menu_access inside $dataParams['create'], else return false.
Snippet:
<?php
function userHasAccess($menu_rules, $dataParams, $data_param_key, $value_to_search){
foreach($menu_rules as $menu_rule){
if(($menu_rule['menu_link'] === $value_to_search && in_array($menu_rule['menu_access'], $dataParams[$data_param_key]))
|| userHasAccess($menu_rule['menu_child'] ?? [], $dataParams, $data_param_key, $value_to_search)){
return true;
}
}
return false;
}
var_dump(userHasAccess($arrayStr['user_rules'], $dataParams, 'create', 'dashboard/menu'));
Online Demo

Unexpected token while deserializing object: when using Click and Drop API - Royal Mail

I am making a POST request to create an order for Royal Mail Click and Drop:
$response = Http::withHeaders([
'Content-Type' => 'application/json',
'Authorization' => 'Bearer secret-123'
])->post('https://api.parcel.royalmail.com/api/v1/orders/', [
'items' => [
'recipient' => [
'address' => [
"fullName" => 'Tom',
"companyName" => "Test",
"addressLine1" => "150",
"addressLine2" => "Valley Close",
"addressLine3" => "Elmdom",
"city" => "Birmingham",
"county" => "West Midlands",
"postcode" => "B12 2YT",
"countryCode" => "GB"
],
"emailAddress" => "test#test.com"
],
"billing" => [
"address" => [
"fullName" => 'Tom',
"companyName" => "Test",
"addressLine1" => "150",
"addressLine2" => "Valley Close",
"addressLine3" => "Elmdom",
"city" => "Birmingham",
"county" => "West Midlands",
"postcode" => "B12 2YT",
"countryCode" => "GB"
],
"phoneNumber" => "42425 5252552",
"emailAddress" => "test#test.com"
],
"orderDate" => "2021-05-18T16:39:01Z",
"subtotal" => 0,
"shippingCostCharged" => 0,
"total" => 0,
]
])->json();
dd($response);
but keep getting
'Unexpected token while deserializing object: PropertyName. Path 'items.recipient', line 1, position 22. Failed to deserialize following order request'
I keep getting the same error for all required fields...
API docs do not provide much details https://api.parcel.royalmail.com/. The same payload works in Insomnia. I am using Laravel Http client.
The API shows that items is an array of objects.
items": [
{
"orderReference": "string",
"recipient": {},
"sender": {},
"billing": {},
"packages": [],
"orderDate": "2019-08-24T14:15:22Z",
"plannedDespatchDate": "2019-08-24T14:15:22Z",
"specialInstructions": "string",
"subtotal": 0,
"shippingCostCharged": 0,
"otherCosts": 0,
"customsDutyCosts": 0,
"total": 0,
"currencyCode": "str",
"postageDetails": {},
"tags": [],
"label": {}
}
]
So you just need to wrap everything in items in another set of brackets.
$response = Http::withHeaders([
'Content-Type' => 'application/json',
'Authorization' => 'Bearer secret-123'
])->post('https://api.parcel.royalmail.com/api/v1/orders/', [
'items' => [[
'recipient' => [
'address' => [
"fullName" => 'Tom',
"companyName" => "Test",
"addressLine1" => "150",
"addressLine2" => "Valley Close",
"addressLine3" => "Elmdom",
"city" => "Birmingham",
"county" => "West Midlands",
"postcode" => "B12 2YT",
"countryCode" => "GB"
],
"emailAddress" => "test#test.com"
],
"billing" => [
"address" => [
"fullName" => 'Tom',
"companyName" => "Test",
"addressLine1" => "150",
"addressLine2" => "Valley Close",
"addressLine3" => "Elmdom",
"city" => "Birmingham",
"county" => "West Midlands",
"postcode" => "B12 2YT",
"countryCode" => "GB"
],
"phoneNumber" => "42425 5252552",
"emailAddress" => "test#test.com"
],
"orderDate" => "2021-05-18T16:39:01Z",
"subtotal" => 0,
"shippingCostCharged" => 0,
"total" => 0,
]]
])->json();

multi-dimensional array hierarchy

I like to know how can I get the hierarchy by the identifier.
This is an example :
$inputArray = array(
array(
"text" => "Dir1",
"parent_id" => "",
"id" => "1",
"filesize" => "109"
),array(
"text" => "dir2",
"parent_id" => "",
"id" => "2",
"filesize" => "88",
"children" => array(
"text" => "Dir3",
"parent_id" => "2",
"id" => "3",
"filesize" => "",
"children" => array(
"text" => "dir4",
"parent_id" => "3",
"id" => "4",
"filesize" => "",
"children" => array(
"text" => "dir5",
"parent_id" => "4",
"id" => "4",
"filesize" => ""
)
)
)
));
looking for this example :
dir3/dir4/dir5
function getText($array) {
$save[] = $array['text'];
if (isset($array['children'])) {
$save = array_merge($save, getText($array['children']));
}
return $save;
}
foreach($inputArray as $x) {
echo implode('/', getText($x)) . "\n";
}
result
Dir1
dir2/Dir3/dir4/dir5
demo

Sort documents based on array field size

I'm trying to use the size of an array called "empofthemonth" to sort each field returned by their amount of employee of the month wins.
Here is the insert code:
$db->users->insert(
["firstname" => "firstname1",
"lastname" => "test",
"email" => "test#email.org.uk",
"keyinfo" =>
["age" => 22,
"gender" => "Male",
"yearsemployed" => 1,
"empofthemonth" => ["Apr"]]
]);
$db->users->insert(
["firstname" => "firstname2",
"lastname" => "test2",
"email" => "test#email.co.uk",
"keyinfo" =>
["age" => 24,
"gender" => "Female",
"yearsemployed" => 5,
"empofthemonth" => ["Feb", "Mar"]]
]);
$db->users->insert(
["firstname" => "firstname3",
"lastname" => "test2",
"email" => "test#email.com",
"keyinfo" =>
["age" => 31,
"gender" => "Female",
"yearsemployed" => 2,
"empofthemonth" => ["Jan", "May", "Jun"]]
]);
I realise that aggregation might be used but i cannot work out the full syntax.
To conclude the query results should be in this order:
firstname3 (3 emp of the months)
firstname2 (2)
firstname1 (1)
We need to $project our documents and return the $size then $sort each document by that "size" in descending order. Note that to access the array field, we need to use the "dot notation".
db.users.aggregate(
[
{ "$project": {
"firstname": 1,
"lastname": 1,
"email": 1,
"keyinfo": 1,
"sz": { "$size": "$keyinfo.empofthemonth" }
}},
{ "$sort": { "sz": -1 } }
]
)
Everything in PHP:
$db->users->aggregate(
[
[ "$project" => [
"firstname" => 1,
"lastname" => 1,
"email" => 1,
"keyinfo" => 1,
"sz" => [ "$size" => "$keyinfo.empofthemonth" ]
]],
[ "$sort" => [ "sz" => -1 ] ]
]
)

Array multisort not working for an array

$artists = [
0 => [
"id" => "3",
"plan_id" => "1",
"name" => "Artist-A",
"views" => "1189189",
"soundcloud" => "42",
"facebook" => "59881948",
"twitter" => "21760757",
"youtube" => 0,
"instagram" => "3429017"
],
1 => [
"id" => "10",
"plan_id" => "1",
"name" => "Artist-B",
"views" => "1",
"soundcloud" => 0,
"facebook" => 0,
"twitter" => 0,
"youtube" => 0,
"instagram" => 0
],
2 => [
"id" => "2",
"plan_id" => "1",
"name" => "Artist-C",
"views" => "1629",
"soundcloud" => "20",
"facebook" => "5025158",
"twitter" => "582899",
"youtube" => 0,
"instagram" => "112127"
],
3 => [
"id" => "4",
"plan_id" => "2",
"name" => "Artist-D",
"views" => "484353",
"soundcloud" => "7",
"facebook" => "104449606",
"twitter" => "36820201",
"youtube" => 0,
"instagram" => "16483226"
],
4 => [
"id" => "5",
"plan_id" => "2",
"name" => "Artist-E",
"views" => "98765432",
"soundcloud" => "13",
"facebook" => "59551072",
"twitter" => "38995648",
"youtube" => 0,
"instagram" => "64997436"
]
]
foreach ($remaining_artists as $key => $value) {
$soundcloud[$key] = $value['soundcloud'];
}
array_multisort($soundcloud, SORT_ASC, $artists);
I use array_multisort to sort array. It's working perfectly fine. But there is an error 'array_multisort(): Array sizes are inconsistent' for the above array. I really can't figure out what's the problem here and its solution.
Your array_multisort() parameters were out of order.
http://php.net/manual/en/function.array-multisort.php
Also, syntax problems.
This works
<?php
$artists = [
0 => [
"id" => "3",
"plan_id" => "1",
"name" => "Artist-A",
"views" => "1189189",
"soundcloud" => "42",
"facebook" => "59881948",
"twitter" => "21760757",
"youtube" => 0,
"instagram" => "3429017"
],
1 => [
"id" => "10",
"plan_id" => "1",
"name" => "Artist-B",
"views" => "1",
"soundcloud" => 0,
"facebook" => 0,
"twitter" => 0,
"youtube" => 0,
"instagram" => 0
],
2 => [
"id" => "2",
"plan_id" => "1",
"name" => "Artist-C",
"views" => "1629",
"soundcloud" => "20",
"facebook" => "5025158",
"twitter" => "582899",
"youtube" => 0,
"instagram" => "112127"
],
3 => [
"id" => "4",
"plan_id" => "2",
"name" => "Artist-D",
"views" => "484353",
"soundcloud" => "7",
"facebook" => "104449606",
"twitter" => "36820201",
"youtube" => 0,
"instagram" => "16483226"
],
4 => [
"id" => "5",
"plan_id" => "2",
"name" => "Artist-E",
"views" => "98765432",
"soundcloud" => "13",
"facebook" => "59551072",
"twitter" => "38995648",
"youtube" => 0,
"instagram" => "64997436"
]
];
$soundcloud = [];
foreach ($artists as $key => $value) {
$soundcloud[$key] = $value['soundcloud'];
}
array_multisort($soundcloud, $artists, SORT_ASC);
print_r($artists);

Categories