Skip to content
Advertisement

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

  1. Products (Full Access)
  2. Report (Full Access)
  3. 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

Advertisement

Answer

 $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

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement