1 | <?php |
||
11 | class Settings extends MetaBox |
||
12 | { |
||
13 | /** |
||
14 | * @var string |
||
15 | */ |
||
16 | const ID = 'settings'; |
||
17 | |||
18 | /** |
||
19 | * @var array |
||
20 | */ |
||
21 | public static $conditions = [ |
||
22 | 'class_exists', 'defined', 'function_exists', 'hook', 'is_plugin_active', |
||
23 | 'is_plugin_inactive', |
||
24 | ]; |
||
25 | |||
26 | /** |
||
27 | * @var string |
||
28 | */ |
||
29 | public $hook; |
||
30 | |||
31 | /** |
||
32 | * @return string |
||
33 | */ |
||
34 | public static function id() |
||
35 | { |
||
36 | return apply_filters( sprintf( 'pollux/%s/id', static::ID ), Application::prefix() . static::ID ); |
||
37 | } |
||
38 | |||
39 | /** |
||
40 | * {@inheritdoc} |
||
41 | */ |
||
42 | public function init() |
||
43 | { |
||
44 | if( empty( $this->app->config[static::ID] ))return; |
||
45 | if( is_bool( $this->app->config[static::ID] )) { |
||
46 | $this->app->config[static::ID] = []; |
||
47 | } |
||
48 | |||
49 | // @todo: run GateKeeper to check dependencies and capability (make sure it it run on the correct hook!) |
||
|
|||
50 | // if( !is_plugin_active( 'meta-box/meta-box.php' ))return; |
||
51 | |||
52 | $this->normalize( $this->app->config[static::ID] ); |
||
53 | |||
54 | add_action( 'admin_menu', [$this, 'addPage'] ); |
||
55 | add_action( 'pollux/'.static::ID.'/init', [$this, 'addSubmitMetaBox'] ); |
||
56 | add_action( 'current_screen', [$this, 'register'] ); |
||
57 | add_action( 'admin_menu', [$this, 'registerSetting'] ); |
||
58 | add_action( 'pollux/'.static::ID.'/init', [$this, 'reset'] ); |
||
59 | add_action( 'admin_print_footer_scripts', [$this, 'renderFooterScript'] ); |
||
60 | add_filter( 'pollux/'.static::ID.'/instruction', [$this, 'filterInstruction'], 10, 3 ); |
||
61 | add_filter( 'pollux/'.static::ID.'/before/instructions', [$this, 'filterBeforeInstructions'] ); |
||
62 | } |
||
63 | |||
64 | /** |
||
65 | * @return void |
||
66 | * @action admin_menu |
||
67 | */ |
||
68 | public function addPage() |
||
69 | { |
||
70 | $this->hook = call_user_func_array( 'add_menu_page', $this->filter( 'page', [ |
||
71 | __( 'Site Settings', 'pollux' ), |
||
72 | __( 'Site Settings', 'pollux' ), |
||
73 | 'edit_theme_options', |
||
74 | static::id(), |
||
75 | [$this, 'renderPage'], |
||
76 | 'dashicons-screenoptions', |
||
77 | 1313 |
||
78 | ])); |
||
79 | } |
||
80 | |||
81 | /** |
||
82 | * @return void |
||
83 | * @action pollux/{static::ID}/init |
||
84 | */ |
||
85 | public function addSubmitMetaBox() |
||
86 | { |
||
87 | call_user_func_array( 'add_meta_box', $this->filter( 'metabox/submit', [ |
||
88 | 'submitdiv', |
||
89 | __( 'Save Settings', 'pollux' ), |
||
90 | [$this, 'renderSubmitMetaBox'], |
||
91 | $this->hook, |
||
92 | 'side', |
||
93 | 'high', |
||
94 | ])); |
||
95 | } |
||
96 | |||
97 | /** |
||
98 | * @return string |
||
99 | * @filter pollux/{static::ID}/before/instructions |
||
100 | */ |
||
101 | public function filterBeforeInstructions() |
||
102 | { |
||
103 | return '<pre class="my-sites nav-tab-active misc-pub-section">SiteMeta::all();</pre>'; |
||
104 | } |
||
105 | |||
106 | /** |
||
107 | * @param string $instruction |
||
108 | * @return string |
||
109 | * @action pollux/{static::ID}/instruction |
||
110 | */ |
||
111 | public function filterInstruction( $instruction, array $field, array $metabox ) |
||
112 | { |
||
113 | return sprintf( "SiteMeta::%s('%s');", $metabox['slug'], $field['slug'] ); |
||
114 | } |
||
115 | |||
116 | /** |
||
117 | * @param null|array $settings |
||
118 | * @return array |
||
119 | * @callback register_setting |
||
120 | */ |
||
121 | public function filterSavedSettings( $settings ) |
||
122 | { |
||
123 | if( is_null( $settings )) { |
||
124 | $settings = []; |
||
125 | } |
||
126 | return $this->filter( 'save', array_merge( $this->getSettings(), $settings )); |
||
127 | } |
||
128 | |||
129 | /** |
||
130 | * @param string $key |
||
131 | * @param mixed $fallback |
||
132 | * @param string $group |
||
133 | * @return string|array |
||
134 | */ |
||
135 | public function getMetaValue( $key, $fallback = '', $group = '' ) |
||
136 | { |
||
137 | return SiteMeta::get( $group, $key, $fallback ); |
||
138 | } |
||
139 | |||
140 | /** |
||
141 | * @return void |
||
142 | * @action current_screen |
||
143 | */ |
||
144 | public function register() |
||
145 | { |
||
146 | if(( new Helper )->getCurrentScreen()->id != $this->hook )return; |
||
147 | foreach( parent::register() as $metabox ) { |
||
148 | new RWMetaBox( $metabox, static::ID, $this ); |
||
149 | } |
||
150 | add_screen_option( 'layout_columns', [ |
||
151 | 'max' => 2, |
||
152 | 'default' => 2, |
||
153 | ]); |
||
154 | $this->action( 'init' ); |
||
155 | } |
||
156 | |||
157 | /** |
||
158 | * @return void |
||
159 | * @action admin_menu |
||
160 | */ |
||
161 | public function registerSetting() |
||
162 | { |
||
163 | register_setting( static::id(), static::id(), [$this, 'filterSavedSettings'] ); |
||
164 | } |
||
165 | |||
166 | /** |
||
167 | * @return void |
||
168 | * @action admin_print_footer_scripts |
||
169 | */ |
||
170 | public function renderFooterScript() |
||
171 | { |
||
172 | if(( new Helper )->getCurrentScreen()->id != $this->hook )return; |
||
173 | $this->render( 'settings/script', [ |
||
174 | 'confirm' => __( 'Are you sure want to do this?', 'pollux' ), |
||
175 | 'hook' => $this->hook, |
||
176 | 'id' => static::id(), |
||
177 | ]); |
||
178 | } |
||
179 | |||
180 | /** |
||
181 | * @return void |
||
182 | * @callback add_menu_page |
||
183 | */ |
||
184 | public function renderPage() |
||
185 | { |
||
186 | $this->render( 'settings/index', [ |
||
187 | 'columns' => get_current_screen()->get_columns(), |
||
188 | 'heading' => __( 'Site Settings', 'pollux' ), |
||
189 | 'id' => static::id(), |
||
190 | ]); |
||
191 | } |
||
192 | |||
193 | /** |
||
194 | * @return void |
||
195 | * @callback add_meta_box |
||
196 | */ |
||
197 | public function renderSubmitMetaBox() |
||
198 | { |
||
199 | global $pagenow; |
||
200 | $query = [ |
||
201 | '_wpnonce' => wp_create_nonce( $this->hook ), |
||
202 | 'action' => 'reset', |
||
203 | 'page' => static::id(), |
||
204 | ]; |
||
205 | $this->render( 'settings/submit', [ |
||
206 | 'reset' => __( 'Reset all', 'pollux' ), |
||
207 | 'reset_url' => esc_url( add_query_arg( $query, admin_url( $pagenow ))), |
||
208 | 'submit' => get_submit_button( __( 'Save', 'pollux' ), 'primary', 'submit', false ), |
||
209 | ]); |
||
210 | } |
||
211 | |||
212 | /** |
||
213 | * @return void |
||
214 | * @action pollux/{static::ID}/init |
||
215 | */ |
||
216 | public function reset() |
||
217 | { |
||
218 | if( filter_input( INPUT_GET, 'page' ) !== static::id() |
||
219 | || filter_input( INPUT_GET, 'action' ) !== 'reset' |
||
220 | )return; |
||
221 | if( wp_verify_nonce( filter_input( INPUT_GET, '_wpnonce' ), $this->hook )) { |
||
222 | update_option( static::id(), $this->getDefaults() ); |
||
223 | add_settings_error( static::id(), 'reset', __( 'Reset successful.', 'pollux' ), 'updated' ); |
||
224 | } |
||
225 | else { |
||
226 | add_settings_error( static::id(), 'failed', __( 'Failed to reset. Please try again.', 'pollux' )); |
||
227 | } |
||
228 | set_transient( 'settings_errors', get_settings_errors(), 30 ); |
||
229 | wp_safe_redirect( add_query_arg( 'settings-updated', 'true', wp_get_referer() )); |
||
230 | exit; |
||
231 | } |
||
232 | |||
233 | /** |
||
234 | * @param string $key |
||
235 | * @return array |
||
236 | */ |
||
237 | protected function filterArrayByKey( array $array, $key ) |
||
238 | { |
||
239 | return array_filter( $array, function( $value ) use( $key ) { |
||
240 | return !empty( $value[$key] ); |
||
241 | }); |
||
242 | } |
||
243 | |||
244 | /** |
||
245 | * @return array |
||
246 | */ |
||
247 | protected function getDefaults() |
||
248 | { |
||
249 | $metaboxes = $this->filterArrayByKey( $this->metaboxes, 'slug' ); |
||
250 | |||
251 | array_walk( $metaboxes, function( &$metabox ) { |
||
252 | $fields = array_map( function( $field ) { |
||
253 | $field = wp_parse_args( $field, ['std' => ''] ); |
||
254 | return [$field['slug'] => $field['std']]; |
||
255 | }, $this->filterArrayByKey( $metabox['fields'], 'slug' )); |
||
256 | $metabox = [ |
||
257 | $metabox['slug'] => call_user_func_array( 'array_merge', $fields ), |
||
258 | ]; |
||
259 | }); |
||
260 | return call_user_func_array( 'array_merge', $metaboxes ); |
||
261 | } |
||
262 | |||
263 | protected function getSettings() |
||
264 | { |
||
265 | return (array) SiteMeta::all(); |
||
266 | } |
||
267 | |||
268 | /** |
||
269 | * @param string $name |
||
270 | * @param string $parentId |
||
271 | * @return string |
||
272 | */ |
||
273 | protected function normalizeFieldName( $name, array $data, $parentId ) |
||
274 | { |
||
275 | return sprintf( '%s[%s][%s]', static::id(), $parentId, $data['slug'] ); |
||
276 | } |
||
277 | |||
278 | /** |
||
279 | * @param string $id |
||
280 | * @param string $parentId |
||
281 | * @return string |
||
282 | */ |
||
283 | protected function normalizeId( $id, array $data, $parentId ) |
||
289 | } |
||
290 |