0

I have a nested array like this:

$settings = [
            'settings_page' => [
                'page' => 'handler_environment',
                'options' => [
                    'op_1' = 'val_1',
                    'op_2' = 'val_2',
                    'op_3' = 'val_3',
                    'op_4' = 'val_4'
                ]
            ]
        ]

and id like to access the key=>val structure in a foreach to fire some functions instantiated with their values like this:

public function add_settings_page()
    {
        foreach ($this->settings['settings_page'] as $setting) {
                var_dump($setting['page']); // handler_environment 
                var_dump($setting['options']); // val_1, val_2 etc... 

                add_menu_page(
                     __(ucwords($settingNiceName), // page_title
                     __(ucwords($settingNiceName), // menu_title
                     'manage_options', // capability
                     $setting['page'], // menu_slug
                     array( $this, 'create_admin_page', $setting['options']) // callback
                    );
                );

            }
        }
    }

but the looped variable evaluates to just the values of the nested array i.e 'handler_environment' and are therefore inaccessible via key reference due to them just being strings.

should be noted the array will contain multiple pages and options for them. It may be that im structuring my initial array incorrectly to achieve what i want.

Is there a way to get the loop to return the key value arrangement of the original nested array without having to reassign each value in to a new array in the loop? Am i overcomplicating this? I am lost at this point.

EDIT: I realise my answer deviates from the original question, but my issue was a combination of both my misunderstanding of how to access array items in the loop and how to push parameters to functions with a closure.

Here is what i ended up doing. i think i was trying to traverse the array incorrectly... but I am not 100% sure on that. Thank you @Barmar for showing how to call the closure and pass the parameters. Array:

$this->settings = [
            'settings_page' => [
                'page_name' => 'handler_environment',
                'page_type' => 'page',
                'options' => [
                    'op_1',
                    'op_2',
                    'op_3',
                    'op_4'
                ]
            ],

Loop:

foreach ($this->settings as $page) {
            register_setting(
                $page['page_name'], // option_group
                $page['page_name'] . '_options' // option_name
            );

            if($page['page_type'] == 'page') {
                add_settings_section(
                    $page['page_name'] . '_setting_section', // id
                    __('Settings', TEXT_DOMAIN), // title
                    function() use ($page) {
                        $this->sectionInfo($page['page_name']);
                    }, // callback
                    $page['page_name'] // page
                );

                foreach ($page['options'] as $option) {
                    add_settings_field(
                        $option, // id
                        __($option, TEXT_DOMAIN), // title
                        function() use ($option) {
                            $this->fieldCallback($option);
                        },
                        $page['page_name'], // page
                        $page['page_name'] . '_setting_section', // section
                        array(
                            'label_for' => $option
                        )
                    );
                }
            }
7
  • What are you trying to do with the anonymous function? You never call it or assign it to anything. Commented Oct 10, 2022 at 23:06
  • You need function() use($setting) { ... } so that it can access $setting Commented Oct 10, 2022 at 23:07
  • Sorry, the anon function is just an example i threw in to show what i would be trying to do in the loop, the reality is its a named function that uses the variables. i will update it to reflect that. Commented Oct 10, 2022 at 23:10
  • foreach ($settings['options'] as $option => $value) Commented Oct 10, 2022 at 23:10
  • Id like the $settings['options'] to be tied to the $settings['page'] and don't necessarily need to loop through them Commented Oct 10, 2022 at 23:21

1 Answer 1

1

Make the callback a closure that captures $setting

                add_menu_page(
                     __(ucwords($settingNiceName), // page_title
                     __(ucwords($settingNiceName), // menu_title
                     'manage_options', // capability
                     $setting['page'], // menu_slug
                     function() use ($setting) {
                        $this->create_admin_page($setting['options']);
                     }
                    );
                );
Sign up to request clarification or add additional context in comments.

7 Comments

My trouble isnt in the function but in accessing the correct variables of the array in the loop. On a high level i have settings i wish to bind to pages and construct the page with a unique name and settings. there could be many of them.
In other words forget the function in the loop, lets say i just want to get the name and all the options for that name in one iteration of the loop, and loop the iteration however many 'settings_page' 's there are
I don't understand the problem. Just use $setting to access the settings in the loop.
You are overlooking the settings_page value for which you have created the foreach loop. seetting_page have two sets page = 'handler_environment' which type string and options = [var1, var2, etc] type array. So to access one value from them in your current loop you need to specify their index or create another foerach for options array to go through them all
I need to get the value by reference, but var_dump($setting['page_name']); gives: Cannot access offset of type string on string because for some reason the key=>val structure isnt available within the scope of the loop (at least how i am going at it)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.