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