Recursive Search array with Multiple Needle - PHP - 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

Related

Php Recursivity: Convert a multidimensional associative array into an array that contains each level of data

I am looking for the best way to convert a multidimensional associative array into a new array, where each row is the concatenation of each column ex :
$datas[] = [
"id" => "1000",
"parent" => "0",
"level" => "1",
"children" => [
[
"id" => "1001",
"parent" => "1000",
"level" => "2",
"children" => [
[
"id" => "1002",
"parent" => "1001",
"level" => "3",
"children" => [
[
"id" => "1003",
"parent" => "1002",
"niveau" => "4",
],
[
"id" => "1004",
"parent" => "1002",
"niveau" => "4",
],
[
"id" => "1005",
"parent" => "1002",
"niveau" => "4",
]
]
],
[
]
]
],
[
"id" => "1006",
"parent" => "1000",
"level" => "2"
]
],
[
"id" => "1007",
"parent" => "0",
"level" => "1"
]
];
Here's my method :
public function recursData(array $datas, &$str ="", &$row =[], int $level = 0)
{
$level++;
foreach ($datas as $data) {
foreach($data as $key => $d) {
if (is_array($d)) {
$this->recursData($d, $str, $row,$level);
} else {
$str.= "{$level}_{$key}_{$d}|";
if ($key == "parent") {
$row[] = $str;
}
}
}
}
return $row;
}
Output (not what i'm looking for) :
array:8 [
0 => "1_id_1000|1_parent_0|"
1 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000|"
2 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000|3_id_1002|3_parent_1001|"
3 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000|3_id_1002|3_parent_1001|4_id_1003|4_parent_1002|"
4 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000|3_id_1002|3_parent_1001|4_id_1003|4_parent_1002|4_id_1004|4_parent_1002|"
5 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000|3_id_1002|3_parent_1001|4_id_1003|4_parent_1002|4_id_1004|4_parent_1002|4_id_1005|4_parent_1002|"
6 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000|3_id_1002|3_parent_1001|4_id_1003|4_parent_1002|4_id_1004|4_parent_1002|4_id_1005|4_parent_1002|2_id_1006|2_parent_1000|"
7 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000|3_id_1002|3_parent_1001|4_id_1003|4_parent_1002|4_id_1004|4_parent_1002|4_id_1005|4_parent_1002|2_id_1006|2_parent_1000|1_id_1007|1_parent_0|"
]
The output i'm looking for:
array:8 [
0 => "1_id_1000|1_parent_0"
1 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000"
2 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000|3_id_1002|3_parent_1001"
3 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000|3_id_1002|3_parent_1001|4_id_1003|3_parent_1002"
4 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000|3_id_1002|3_parent_1001|4_id_1004|3_parent_1002"
5 => "1_id_1000|1_parent_0|2_id_1001|2_parent_1000|3_id_1002|3_parent_1001|4_id_1005|3_parent_1002"
6 => "1_id_1000|1_parent_0|2_id_1006|2_parent_1000"
7 => "1_id_1007|1_parent_0"
]
I'm stuck to finish this properly, I tried lot of things, but can't understand what to do obtain what I want to resolve this. Hope someone could help :)

Payment api multidimensional array issue in php

My payment provider issued the following example code for their API:
$order = $mollie->orders->create([
"amount" => [
"value" => "1027.99",
"currency" => "EUR"
],
"billingAddress" => [
"streetAndNumber" => "Keizersgracht 313",
"postalCode" => "1016 EE",
"city" => "Amsterdam",
"country" => "nl",
"givenName" => "Luke",
"familyName" => "Skywalker",
"email" => "luke#skywalker.com",
],
"shippingAddress" => [
"streetAndNumber" => "Keizersgracht 313",
"postalCode" => "1016 EE",
"city" => "Amsterdam",
"country" => "nl",
"givenName" => "Luke",
"familyName" => "Skywalker",
"email" => "luke#skywalker.com",
],
"metadata" => [
"order_id" => $orderId
],
"consumerDateOfBirth" => "1958-01-31",
"locale" => "en_US",
"orderNumber" => strval($orderId),
"redirectUrl" => "{$protocol}://{$hostname}{$path}/orders/return.php?order_id={$orderId}",
"webhookUrl" => "{$protocol}://{$hostname}{$path}/orders/webhook.php",
"method" => "ideal",
"lines" => [
[
"sku" => "5702016116977",
"name" => "LEGO 42083 Bugatti Chiron",
"productUrl" => "https://shop.lego.com/nl-NL/Bugatti-Chiron-42083",
"imageUrl" => 'https://sh-s7-live-s.legocdn.com/is/image//LEGO/42083_alt1?$main$',
"quantity" => 2,
"vatRate" => "21.00",
"unitPrice" => [
"currency" => "EUR",
"value" => "399.00"
],
"totalAmount" => [
"currency" => "EUR",
"value" => "698.00"
],
"discountAmount" => [
"currency" => "EUR",
"value" => "100.00"
],
"vatAmount" => [
"currency" => "EUR",
"value" => "121.14"
]
],
[
"type" => "digital",
"sku" => "5702015594028",
"name" => "LEGO 42056 Porsche 911 GT3 RS",
"productUrl" => "https://shop.lego.com/nl-NL/Porsche-911-GT3-RS-42056",
"imageUrl" => 'https://sh-s7-live-s.legocdn.com/is/image/LEGO/42056?$PDPDefault$',
"quantity" => 1,
"vatRate" => "21.00",
"unitPrice" => [
"currency" => "EUR",
"value" => "329.99"
],
"totalAmount" => [
"currency" => "EUR",
"value" => "329.99"
],
"vatAmount" => [
"currency" => "EUR",
"value" => "57.27"
]
]
]
]);
What I'd like to do is to replace the hard coded second dimension "lines" with data from these session vars.
foreach ($_SESSION['cart_products'] as $cart_itm) {
$name = $cart_itm['cat_item_titel_' . $lang . ''];
$unitPrice = $cart_itm['cat_item_prijs'];
$sku = $cart_itm['cat_item_code'];
}
And this is the solution I came up with but this just doesn't work. The reason, I assume, is that the data in the $orders array is echoed as a string and not functional code as i should be. But I haven't got a clue how to aproach this issue.
$i = 0;
$lngth = count($_SESSION['cart_products']);
foreach ($_SESSION['cart_products'] as $cart_itm) {
$orders[] = '[';
$orders[] .= '"sku" => ' . $cart_itm['cat_item_code'] . ',';
$orders[] .= '"name" => ' . $cart_itm['cat_item_titel_en'] . ',';
$orders[] .= '"quantity" => 1,';
$orders[] .= '"vatRate" => "0.00",';
$orders[] .= '"unitPrice" => [
"currency" => "EUR",
"value" => "15.50"],';
$orders[] .= '"totalAmount" => [
"currency" => "EUR",
"value" => "15.50"],';
$orders[] .= '"vatAmount" => [
"currency" => "EUR",
"value" => "0.00"]';
if ($i == $lngth - 1) {
$orders[] .= ']';
}
else {
$orders[] .= '],';
}
$i++;
}
$echoOrders = implode($orders);
$order = $mollie->orders->create([
"amount" => [
"value" => "15.50",
"currency" => "EUR"
],
"billingAddress" => [
"streetAndNumber" => $address,
"postalCode" => $postalcode,
"city" => $city,
"country" => $country,
"givenName" => $firstname,
"familyName" => $name,
"email" => $email,
],
"shippingAddress" => [
"streetAndNumber" => $addressa,
"postalCode" => $postalcodea,
"city" => $citya,
"country" => $countrya,
"givenName" => $firstnamea,
"familyName" => $namea,
"email" => $email,
],
"metadata" => [
"order_id" => $orderId
],
"locale" => "nl_BE",
"orderNumber" => strval($orderId),
"redirectUrl" => "{$protocol}://{$hostname}{$path}/thankyou.php?order_id={$orderId}",
"webhookUrl" => "https://www.cluster-park.com/dev/includes/webhook.php",
"lines" => [ $echoOrders ]
]);
All suggestions are more than welcome.
Thanks!
You need to build an associative array, at the moment you are building a string. This should give you a starting point...
$lines = [];
foreach ($_SESSION['cart_products'] as $cart_itm) {
$lines[] = [ "sku" => $cart_itm['cat_item_code'],
"name" => $cart_itm['cat_item_titel_en'],
"quantity" => 1,
"vatRate" => "0.00",
"unitPrice" => [
"currency" => "EUR",
"value" => "15.50"]
],
// Add all of the other data you have
];
}
then later in your code, you add them in using...
"lines" => $lines

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

PHP SOAP Object Reference Not Set to Reference of Object

I'm attempting to communicate with a SOAP Service to post some data to the database.
Here's the WSDL.
As you can see, the required data is quite cumbersome so apologies for the length of the code, you will need to scroll through to see everything. Here is how I am attempting to communicate with the service, however I'm getting the error System.NullReferenceException: Object reference not set to an instance of an object
PHP:
$soapClient = new soapClient("https://secure.quickflora.com/Admin/scripts/ws/QuickfloraOrders.asmx?WSDL");
$orderArray = array(
"Token" => $token,
"OrderErrorEmail" => "edwardsalexk#gmail.com",
"Billing" => array("CustomerID" => "1",
"FullName" => "Jack Nichols",
"FirstName" => "Jack",
"LastName" => "Nichols",
"Address1" => "9725 E Windrose Drive",
"Address2" => "",
"Address3" => "",
"City" => "Scottsdale",
"State" => "Arizona",
"Zip" => "85260",
"Phone"=> "4807218374",
"PhoneExt" => "123",
"Fax" => "1234",
"Email"=> "edwardsalexk#gmail.com",
"Cell" =>"480 721 8374",
),
"Shipping" => array("Attention "=> "Alexander",
"Salutation" => "Alexander",
"FirstName" => "Alexander",
"LastName" => "Edwards",
"Address1"=> "9725 E Windrose Drive",
"Address2" => "",
"Address3" => "",
"City"=>"Scottsdale",
"State" =>"Arizona",
"Zip" => "85260",
"Country" => "United States",
"Phone" => "480 721 8374",
"PhoneExt" => "123",
"Fax" => "123",
"Email" => "edwardsalexk#gmail.com",
"Cell" => "480 721 8374",
"CardMessage" => "I hope these flowers find you well!",
"DestinationType" => "House",
"DriverRouteInfo" => "None",
"Priority" => "Highest",
"Order Ship Date" => "4/20/2017",
),
"Payment" => array("MethodID" => "1",
"Check" =>array("Number" => "123",
"CheckID" => "1",
"ChkDate" => "4/20/2017,"),
"CreditCard" => array("TypeID" => "1",
"Name" => "Alexander Edwards",
"Account Number" => "12345678",
"Expiration Date" => "11/14/1993",
"SecurityCode" => "123",
"ApprovalCode" => "123")),
"WireServiceInfo" => array("WireService" => "Alexander Service",
"WireServiceCode" => "123",
"ReferenceID" => "123",
"TransmitMethod" => "123",
"RepresentativeTalkedTo" => "Alexander",
"FloristName" => "Alexander",
"FloristPhone" => "480 721 8734",
"FloristCity" => "Scottsdale",
"FloristState" => "Arizona"),
"Orderdetails" => array("OccasionCodeID" => "123",
"SourceCodeID" => "123",
"Comments" => "Hello",
"TaxGroupID" => "123",
"Currency" => array("ID" => "123",
"ExchangeRate" => 1.2),
"DeliveryCharge" => 12.5,
"ServiceCharge" => 12.5,
"Discounts" => array("Percentage" => 12.5,
"Amount" => 12.5),
"Tax" => array("Percentage" => 12.5,
"Amount" => 12.5),
"GSTTax" => array("Percentage" => 12.5,
"Amount" => 12.5),
"PSTTax" => array("Percentage" => 12.5,
"Amount" => 12.5),
"Total" => 123.34
),
"OrderItemsdetails" => array(
"Itemno" => array("String", "String"),
"Itemid" => array("String", "String"),
"UpcCode" => array("String", "String"),
"ItemName" => array("String", "String"),
"Description" => array("String", "String"),
"Quantity" => array("String", "String"),
"UnitOfMeasurement" => array("String", "String"),
"DiscountPercentage" => array("String", "String"),
"UnitPrice" => array("String", "String")
)
);
$response = $soapClient->PostOrder($orderArray);
echo var_dump($response);

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