Completed
Push — master ( 24cf5e...bc1ad9 )
by Askupa
02:11
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(
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()
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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
}