PluginProbe
WPGet API – Connect to any external REST API / 1.1.0
WPGet API – Connect to any external REST API v1.1.0
1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.1.0 2.1.1 2.1.3 2.1.4 2.1.5 2.2.0 2.2.1 2.2.10 2.2.2 2.2.3 All 97 releases
wpgetapi / lib / cmb2 / includes / CMB2_Options_Hookup.php

CMB2_Options_Hookup.php in WPGet API – Connect to any external REST API 1.1.0, at lib/cmb2/includes/CMB2_Options_Hookup.php

373 lines 11.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Handles hooking CMB2 forms/metaboxes into the post/attachement/user screens
4 * and handles hooking in and saving those fields.
5 *
6 * @since 2.0.0
7 *
8 * @category WordPress_Plugin
9 * @package CMB2
10 * @author CMB2 team
11 * @license GPL-2.0+
12 * @link https://cmb2.io
13 */
14 class CMB2_Options_Hookup extends CMB2_Hookup {
15
16 /**
17 * The object type we are performing the hookup for
18 *
19 * @var string
20 * @since 2.0.9
21 */
22 protected $object_type = 'options-page';
23
24 /**
25 * Options page key.
26 *
27 * @var string
28 * @since 2.2.5
29 */
30 protected $option_key = '';
31
32 /**
33 * Constructor
34 *
35 * @since 2.0.0
36 * @param CMB2 $cmb The CMB2 object to hookup.
37 * @param string $option_key Option key to use.
38 */
39 public function __construct( CMB2 $cmb, $option_key ) {
40 $this->cmb = $cmb;
41 $this->option_key = $option_key;
42 }
43
44 public function hooks() {
45 if ( empty( $this->option_key ) ) {
46 return;
47 }
48
49 if ( ! $this->cmb->prop( 'autoload', true ) ) {
50 // Disable option autoload if requested.
51 add_filter( "cmb2_should_autoload_{$this->option_key}", '__return_false' );
52 }
53
54 /**
55 * For WP < 4.7. Ensure the register_setting function exists.
56 */
57 if ( ! CMB2_Utils::wp_at_least( '4.7' ) && ! function_exists( 'register_setting' ) ) {
58 require_once ABSPATH . 'wp-admin/includes/plugin.php';
59 }
60
61 // Register setting to cmb2 group.
62 register_setting( 'cmb2', $this->option_key );
63
64 // Handle saving the data.
65 add_action( 'admin_post_' . $this->option_key, array( $this, 'save_options' ) );
66
67 // Optionally network_admin_menu.
68 $hook = $this->cmb->prop( 'admin_menu_hook' );
69
70 // Hook in to add our menu.
71 add_action( $hook, array( $this, 'options_page_menu_hooks' ), $this->get_priority() );
72
73 // If in the network admin, need to use get/update_site_option.
74 if ( 'network_admin_menu' === $hook ) {
75 // Override CMB's getter.
76 add_filter( "cmb2_override_option_get_{$this->option_key}", array( $this, 'network_get_override' ), 10, 2 );
77 // Override CMB's setter.
78 add_filter( "cmb2_override_option_save_{$this->option_key}", array( $this, 'network_update_override' ), 10, 2 );
79 }
80 }
81
82 /**
83 * Hook up our admin menu item and admin page.
84 *
85 * @since 2.2.5
86 *
87 * @return void
88 */
89 public function options_page_menu_hooks() {
90 $parent_slug = $this->cmb->prop( 'parent_slug' );
91 $title = $this->cmb->prop( 'title' );
92 $menu_title = $this->cmb->prop( 'menu_title', $title );
93 $capability = $this->cmb->prop( 'capability' );
94 $callback = array( $this, 'options_page_output' );
95
96 if ( $parent_slug ) {
97 $page_hook = add_submenu_page(
98 $parent_slug,
99 $title,
100 $menu_title,
101 $capability,
102 $this->option_key,
103 $callback
104 );
105 } else {
106 $page_hook = add_menu_page(
107 $title,
108 $menu_title,
109 $capability,
110 $this->option_key,
111 $callback,
112 $this->cmb->prop( 'icon_url' ),
113 $this->cmb->prop( 'position' )
114 );
115 }
116
117 if ( $this->cmb->prop( 'cmb_styles' ) ) {
118 // Include CMB CSS in the head to avoid FOUC.
119 add_action( "admin_print_styles-{$page_hook}", array( 'CMB2_Hookup', 'enqueue_cmb_css' ) );
120 }
121
122 $this->maybe_register_message();
123 }
124
125 /**
126 * If there is a message callback, let it determine how to register the message,
127 * else add a settings message if on this settings page.
128 *
129 * @since 2.2.6
130 *
131 * @return void
132 */
133 public function maybe_register_message() {
134 $is_options_page = self::is_page( $this->option_key );
135 $should_notify = ! $this->cmb->prop( 'disable_settings_errors' ) && isset( $_GET['settings-updated'] ) && $is_options_page;
136 $is_updated = $should_notify && 'true' === $_GET['settings-updated'];
137 $setting = "{$this->option_key}-notices";
138 $code = '';
139 $message = __( 'Nothing to update.', 'cmb2' );
140 $type = 'notice-warning';
141
142 if ( $is_updated ) {
143 $message = __( 'Settings updated.', 'cmb2' );
144 $type = 'updated';
145 }
146
147 // Check if parameter has registered a callback.
148 if ( $cb = $this->cmb->maybe_callback( 'message_cb' ) ) {
149
150 /**
151 * The 'message_cb' callback will receive the following parameters.
152 * Unless there are other reasons for notifications, the callback should only
153 * `add_settings_error()` if `$args['should_notify']` is truthy.
154 *
155 * @param CMB2 $cmb The CMB2 object.
156 * @param array $args {
157 * An array of message arguments
158 *
159 * @type bool $is_options_page Whether current page is this options page.
160 * @type bool $should_notify Whether options were saved and we should be notified.
161 * @type bool $is_updated Whether options were updated with save (or stayed the same).
162 * @type string $setting For add_settings_error(), Slug title of the setting to which
163 * this error applies.
164 * @type string $code For add_settings_error(), Slug-name to identify the error.
165 * Used as part of 'id' attribute in HTML output.
166 * @type string $message For add_settings_error(), The formatted message text to display
167 * to the user (will be shown inside styled `<div>` and `<p>` tags).
168 * Will be 'Settings updated.' if $is_updated is true, else 'Nothing to update.'
169 * @type string $type For add_settings_error(), Message type, controls HTML class.
170 * Accepts 'error', 'updated', '', 'notice-warning', etc.
171 * Will be 'updated' if $is_updated is true, else 'notice-warning'.
172 * }
173 */
174 $args = compact( 'is_options_page', 'should_notify', 'is_updated', 'setting', 'code', 'message', 'type' );
175
176 $this->cmb->do_callback( $cb, $args );
177
178 } elseif ( $should_notify ) {
179
180 add_settings_error( $setting, $code, $message, $type );
181 }
182 }
183
184 /**
185 * Display options-page output. To override, set 'display_cb' box property.
186 *
187 * @since 2.2.5
188 */
189 public function options_page_output() {
190 $this->maybe_output_settings_notices();
191
192 $callback = $this->cmb->prop( 'display_cb' );
193 if ( is_callable( $callback ) ) {
194 return call_user_func( $callback, $this );
195 }
196
197 ?>
198 <div class="wrap cmb2-options-page option-<?php echo esc_attr( sanitize_html_class( $this->option_key ) ); ?>">
199 <?php if ( $this->cmb->prop( 'title' ) ) : ?>
200 <h2><?php echo wp_kses_post( $this->cmb->prop( 'title' ) ); ?></h2>
201 <?php endif; ?>
202 <?php $this->options_page_tab_nav_output(); ?>
203 <form class="cmb-form" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="POST" id="<?php echo $this->cmb->cmb_id; ?>" enctype="multipart/form-data" encoding="multipart/form-data">
204 <input type="hidden" name="action" value="<?php echo esc_attr( $this->option_key ); ?>">
205 <?php $this->options_page_metabox(); ?>
206 <?php submit_button( esc_attr( $this->cmb->prop( 'save_button' ) ), 'primary', 'submit-cmb' ); ?>
207 </form>
208 </div>
209 <?php
210 }
211
212 /**
213 * Display options-page Tab Navigation output.
214 *
215 * @since 2.9.0
216 */
217 public function options_page_tab_nav_output() {
218 $tabs = $this->get_tab_group_tabs();
219 if ( empty( $tabs ) ) {
220 return;
221 }
222 ?>
223 <h2 class="nav-tab-wrapper">
224 <?php foreach ( $tabs as $option_key => $tab_title ) : ?>
225 <a class="nav-tab<?php if ( self::is_page( $option_key ) ) : ?> nav-tab-active<?php endif; ?>" href="<?php menu_page_url( $option_key ); ?>"><?php echo wp_kses_post( $tab_title ); ?></a>
226 <?php endforeach; ?>
227 </h2>
228 <?php
229 }
230
231 /**
232 * Outputs the settings notices if a) not a sub-page of 'options-general.php'
233 * (because settings_errors() already called in wp-admin/options-head.php),
234 * and b) the 'disable_settings_errors' prop is not set or truthy.
235 *
236 * @since 2.2.5
237 * @return void
238 */
239 public function maybe_output_settings_notices() {
240 global $parent_file;
241
242 // The settings sub-pages will already have settings_errors() called in wp-admin/options-head.php.
243 if ( 'options-general.php' !== $parent_file ) {
244 settings_errors( "{$this->option_key}-notices" );
245 }
246 }
247
248 /**
249 * Gets navigation tabs array for CMB2 options pages which share the
250 * same tab_group property.
251 *
252 * @since 2.4.0
253 * @return array Array of tab information ($option_key => $tab_title)
254 */
255 public function get_tab_group_tabs() {
256 $tab_group = $this->cmb->prop( 'tab_group' );
257 $tabs = array();
258
259 if ( $tab_group ) {
260 $boxes = CMB2_Boxes::get_by( 'tab_group', $tab_group );
261
262 foreach ( $boxes as $cmb_id => $cmb ) {
263 $option_key = $cmb->options_page_keys();
264
265 // Must have an option key, must be an options page box.
266 if ( ! isset( $option_key[0] ) || 'options-page' !== $cmb->mb_object_type() ) {
267 continue;
268 }
269
270 $tabs[ $option_key[0] ] = $cmb->prop( 'tab_title', $cmb->prop( 'title' ) );
271 }
272 }
273
274 return apply_filters( 'cmb2_tab_group_tabs', $tabs, $tab_group );
275 }
276
277 /**
278 * Display metaboxes for an options-page object.
279 *
280 * @since 2.2.5
281 */
282 public function options_page_metabox() {
283 $this->show_form_for_type( 'options-page' );
284 }
285
286 /**
287 * Save data from options page, then redirects back.
288 *
289 * @since 2.2.5
290 * @return void
291 */
292 public function save_options() {
293 $url = wp_get_referer();
294 if ( ! $url ) {
295 $url = admin_url();
296 }
297
298 if (
299 $this->can_save( 'options-page' )
300 // check params.
301 && isset( $_POST['submit-cmb'], $_POST['action'] )
302 && $this->option_key === $_POST['action']
303 ) {
304
305 $updated = $this->cmb
306 ->save_fields( $this->option_key, $this->cmb->object_type(), $_POST )
307 ->was_updated(); // Will be false if no values were changed/updated.
308
309 $url = add_query_arg( 'settings-updated', $updated ? 'true' : 'false', $url );
310 }
311
312 wp_safe_redirect( esc_url_raw( $url ), 303 /* WP_Http::SEE_OTHER */ );
313 exit;
314 }
315
316 /**
317 * Replaces get_option with get_site_option.
318 *
319 * @since 2.2.5
320 *
321 * @param mixed $test Not used.
322 * @param mixed $default Default value to use.
323 * @return mixed Value set for the network option.
324 */
325 public function network_get_override( $test, $default = false ) {
326 return get_site_option( $this->option_key, $default );
327 }
328
329 /**
330 * Replaces update_option with update_site_option.
331 *
332 * @since 2.2.5
333 *
334 * @param mixed $test Not used.
335 * @param mixed $option_value Value to use.
336 * @return bool Success/Failure
337 */
338 public function network_update_override( $test, $option_value ) {
339 return update_site_option( $this->option_key, $option_value );
340 }
341
342 /**
343 * Determines if given page slug matches the 'page' GET query variable.
344 *
345 * @since 2.4.0
346 *
347 * @param string $page Page slug.
348 * @return boolean
349 */
350 public static function is_page( $page ) {
351 return isset( $_GET['page'] ) && $page === $_GET['page'];
352 }
353
354 /**
355 * Magic getter for our object.
356 *
357 * @param string $field Property to retrieve.
358 *
359 * @throws Exception Throws an exception if the field is invalid.
360 * @return mixed
361 */
362 public function __get( $field ) {
363 switch ( $field ) {
364 case 'object_type':
365 case 'option_key':
366 case 'cmb':
367 return $this->{$field};
368 default:
369 throw new Exception( sprintf( esc_html__( 'Invalid %1$s property: %2$s', 'cmb2' ), __CLASS__, $field ) );
370 }
371 }
372 }
373