Completed
Push — master ( 6dc60e...24cf5e )
by Askupa
01:27
created

ChildPage.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Amarkal\Settings;
4
5
/**
6
 * Implements a settings child page.
7
 * Child pages are pages that appear and their parent's submenu (unless there is
8
 * only one child, in which case the child page handles the parent page HTML output).
9
 */
10
class ChildPage
11
{   
12
    /**
13
     * @var array Configuration array 
14
     */
15
    private $config;
16
    
17
    /**
18
     * @var Amarkal\UI\Form The UI form instance
19
     */
20
    private $form;
21
    
22
    /**
23
     * Set the config, create a form instance and add actions.
24
     * 
25
     * @param array $config
26
     */
27
    public function __construct( array $config = array() ) 
28
    {
29
        $this->config = array_merge($this->default_args(), $config);
30
        $this->form = new \Amarkal\UI\Form($this->config['fields']);
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Amarkal\UI\Form($this->config['fields']) of type object<Amarkal\UI\Form> is incompatible with the declared type object<Amarkal\Settings\Amarkal\UI\Form> of property $form.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
31
        
32
        \add_action('admin_menu', array($this,'add_submenu_page'));
33
        \add_action('admin_enqueue_scripts', array($this,'enqueue_scripts'));
34
    }
35
    
36
    /**
37
     * Internally used to add a submenu page for this child page
38
     */
39 View Code Duplication
    public function add_submenu_page()
40
    {
41
        \add_submenu_page(
42
            $this->config['parent_slug'], 
43
            $this->config['title'], 
44
            $this->config['menu_title'], 
45
            $this->config['capability'],
46
            $this->config['slug'],
47
            array($this, 'render')
48
        );
49
    }
50
    
51
    /**
52
     * Conditionally enqueue settings scripts and styles if the calling page is
53
     * a settings page.
54
     */
55
    public function enqueue_scripts()
56
    {
57
        // Only enqueue styles & scripts if this is a settings page
58
        if($this->config['slug'] === filter_input(INPUT_GET, 'page'))
59
        {
60
            \wp_enqueue_style('amarkal-settings');
61
            \wp_enqueue_script('amarkal-settings');
62
        }
63
    }
64
    
65
    /**
66
     * Render the settings page
67
     */
68
    public function render()
69
    {
70
        $this->form->update($this->get_old_instance());
71
        include __DIR__.'/ChildPage.phtml';
72
        \add_filter('admin_footer_text', array($this, 'footer_credits'));
73
    }
74
    
75
    /**
76
     * Ajax callback internally used to update options values for the given 
77
     * settings page.
78
     * 
79
     * @param array $new_instance
80
     * @return array
81
     */
82
    public function update( $new_instance )
83
    {
84
        if($this->can_update())
85
        {
86
            $old_instance = $this->get_old_instance();
87
            $final_instance = $this->form->update($new_instance, $old_instance);
88
            foreach($final_instance as $name => $value)
89
            {
90
                \update_option($name,$value);
91
            }
92
            return $this->results_array(
93
                $this->get_errors(),
94
                $final_instance
95
            );
96
        }
97
        return $this->results_array(
98
            array("You don't have permission to manage options on this site")
99
        );
100
    }
101
    
102
    /**
103
     * Ajax callback internally used to reset all component values to their 
104
     * defaults for the given settings page.
105
     * 
106
     * @return type
107
     */
108
    public function reset()
109
    {
110
        if($this->can_update())
111
        {
112
            foreach($this->config['fields'] as $field)
113
            {
114
                \delete_option($field['name']);
115
            }
116
            return $this->results_array(
117
                array(),
118
                $this->form->reset()
119
            );
120
        }
121
        return $this->results_array(
122
            array("You don't have permission to manage options on this site")
123
        );
124
    }
125
    
126
    /**
127
     * Renders Amarkal's credits on the page's footer.
128
     */
129
    public function footer_credits()
130
    {
131
        echo '<span id="footer-thankyou">Created with <a href="https://github.com/askupasoftware/amarkal-settings">amarkal-settings</a>, a module within the <a href="https://github.com/askupasoftware/amarkal">Amarkal Framework</a></span>';
132
    }
133
134
    /**
135
     * Get the component corresponding to the given name
136
     *
137
     * @param [string] $name
138
     * @throws RuntimeException when the component cannot be found
139
     * @return void
140
     */
141
    public function get_component($name)
142
    {
143
        return $this->form->get_component($name);
144
    }
145
    
146
    /**
147
     * Get all errors from the form instance.
148
     * 
149
     * @return array
150
     */
151
    private function get_errors()
152
    {
153
        $errors = array();
154
        foreach($this->form->get_errors() as $name => $error)
155
        {
156
            $errors[$name] = $error;
157
        }
158
        return $errors;
159
    }
160
    
161
    /**
162
     * Generates a results array to be returned when an Ajax request is made.
163
     * 
164
     * @param array $errors The list of errors
165
     * @param array $values The list of values
166
     * @return array
167
     */
168
    private function results_array( $errors = array(), $values = '' )
169
    {
170
        return array(
171
            'values' => $values,
172
            'errors' => $errors
173
        );
174
    }
175
    
176
    /**
177
     * Check if the current user has the required privileges to update the 
178
     * settings values.
179
     * 
180
     * @return boolean
181
     */
182
    private function can_update()
183
    {
184
        return \current_user_can($this->config['capability']);
185
    }
186
    
187
    /**
188
     * Get the old instance from the database.
189
     * 
190
     * @return array
191
     */
192
    private function get_old_instance()
193
    {
194
        $old_instance = array();
195
        foreach($this->form->get_components() as $component)
196
        {
197
            $old_instance[$component->name] = \get_option($component->name, $component->default);
198
        }
199
        return $old_instance;
200
    }
201
    
202
    /**
203
     * The default config arguments array.
204
     * 
205
     * @return array
206
     */
207
    private function default_args()
208
    {
209
        return array(
210
            'parent_slug'    => '',
211
            'slug'           => '',
212
            'title'          => '',
213
            'subtitle'       => '',
214
            'menu_title'     => '',
215
            'capability'     => 'manage_options',
216
            'footer_html'    => '',
217
            'subfooter_html' => '',
218
            'description'    => null,
219
            'fields'         => array()
220
        );
221
    }
222
}