PluginProbe
Edit Flow / 0.11.0
Edit Flow v0.11.0
0.11.1 0.11.0 0.7.2 0.7.3 0.7.4 0.7.5 0.7.6 0.8 0.8.1 0.8.2 0.9 0.9.1 0.9.2 0.9.3 0.9.4 0.9.5 0.9.6 0.9.7 0.9.8 0.9.9 trunk 0.1.5 0.10.0 0.10.1 0.10.2 All 44 releases
edit-flow / common / php / screen-options.php

screen-options.php in Edit Flow 0.11.0, at common/php/screen-options.php

291 lines 9.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // Retrieved from this blog post: http://w-shadow.com/blog/2010/06/29/adding-stuff-to-wordpress-screen-options/
4
5 if ( ! class_exists( 'wsScreenOptions10' ) ) :
6
7 /**
8 * Class for adding new panels to the "Screen Options" box.
9 *
10 * Do not access this class directly. Instead, use the add_screen_options_panel() function.
11 *
12 * @author Janis Elsts
13 * @copyright 2010
14 * @version 1.0
15 * @access public
16 */
17 class wsScreenOptions10 {
18 public $registered_panels; // List of custom "Screen Options" panels
19 public $page_panels; // Index of panels registered for each page ($page => array of panel ids).
20
21 /**
22 * Class constructor
23 *
24 * @return void
25 */
26 public function __construct() {
27 $this->registered_panels = array();
28 $this->page_panels = array();
29
30 add_filter( 'screen_settings', array( $this, 'append_screen_settings' ), 10, 2 );
31 add_action( 'admin_print_scripts', array( $this, 'add_autosave_script' ) );
32 }
33
34 /**
35 * Add a new settings panel to the "Screen Options" box.
36 *
37 * @param string $id String to use in the 'id' attribute of the settings panel. Should be unique.
38 * @param string $title Title of the settings panel. Set to an empty string to omit title.
39 * @param callback $callback Function that fills the panel with the desired content. Should return its output.
40 * @param string|array $page The page(s) on which to show the panel (similar to add_meta_box()).
41 * @param callback $save_callback Optional. Function that saves the settings.
42 * @param bool $autosave Optional. If se, settings will be automatically saved (via AJAX) when the value of any input element in the panel changes. Defaults to false.
43 * @return void
44 */
45 public function add_screen_options_panel( $id, $title, $callback, $page, $save_callback = null, $autosave = false ) {
46 if ( ! is_array( $page ) ) {
47 $page = array( $page );
48 }
49 // Convert page hooks/slugs to screen IDs
50 $page = array_map( array( $this, 'page_to_screen_id' ), $page );
51 $page = array_unique( $page );
52
53 $new_panel = array(
54 'title' => $title,
55 'callback' => $callback,
56 'page' => $page,
57 'save_callback' => $save_callback,
58 'autosave' => $autosave,
59 );
60
61 if ( $save_callback ) {
62 add_action( 'wp_ajax_save_settings-' . $id, array( $this, 'ajax_save_callback' ) );
63 }
64
65 // Store the panel ID in each relevant page's list
66 foreach ( $page as $page_id ) {
67 if ( ! isset( $this->page_panels[ $page_id ] ) ) {
68 $this->page_panels[ $page_id ] = array();
69 }
70 $this->page_panels[ $page_id ][] = $id;
71 }
72
73 $this->registered_panels[ $id ] = $new_panel;
74 }
75
76 /**
77 * Convert a page hook name to a screen ID.
78 *
79 * @uses convert_to_screen()
80 * @access private
81 *
82 * @param string $page
83 * @return string
84 */
85 public function page_to_screen_id( $page ) {
86 if ( function_exists( 'convert_to_screen' ) ) {
87 $screen = convert_to_screen( $page );
88 if ( isset( $screen->id ) ) {
89 return $screen->id;
90 } else {
91 return '';
92 }
93 } else {
94 return str_replace( array( '.php', '-new', '-add' ), '', $page );
95 }
96 }
97
98 /**
99 * Append custom panel HTML to the "Screen Options" box of the current page.
100 * Callback for the 'screen_settings' filter (available in WP 3.0 and up).
101 *
102 * @access private
103 *
104 * @param string $current
105 * @param string $screen Screen object (undocumented).
106 * @return string The HTML code to append to "Screen Options"
107 */
108 public function append_screen_settings( $current, $screen ) {
109 global $hook_suffix;
110
111 // Sanity check
112 if ( ! isset( $screen->id ) ) {
113 return $current;
114 }
115
116 // Are there any panels that want to appear on this page?
117 $panels = $this->get_panels_for_screen( $screen->id, $hook_suffix );
118 if ( empty( $panels ) ) {
119 return $current;
120 }
121
122 // Append all panels registered for this screen
123 foreach ( $panels as $panel_id ) {
124 $panel = $this->registered_panels[ $panel_id ];
125
126 // Add panel title
127 if ( ! empty( $panel['title'] ) ) {
128 $current .= "\n<h5>" . $panel['title'] . "</h5>\n";
129 }
130 // Generate panel contents
131 if ( is_callable( $panel['callback'] ) ) {
132 $contents = call_user_func( $panel['callback'] );
133 $classes = array(
134 'metabox-prefs',
135 'custom-options-panel',
136 );
137 if ( $panel['autosave'] ) {
138 $classes[] = 'requires-autosave';
139 }
140
141 $contents = sprintf(
142 '<div id="%s" class="%s"><input type="hidden" name="_wpnonce-%s" value="%s" />%s</div>',
143 esc_attr( $panel_id ),
144 implode( ' ', $classes ),
145 esc_attr( $panel_id ),
146 wp_create_nonce( 'save_settings-' . $panel_id ),
147 $contents
148 );
149
150 $current .= $contents;
151 }
152 }
153
154 return $current;
155 }
156
157 /**
158 * AJAX callback for the "Screen Options" autosave.
159 *
160 * @access private
161 * @return void
162 */
163 public function ajax_save_callback() {
164 if ( empty( $_POST['action'] ) ) {
165 wp_die( '0' );
166 }
167
168 // The 'action' argument is in the form "save_settings-panel_id"
169 // phpcs:ignore WordPress.Security.NonceVerification.Missing -- it's being verified 2 lines down
170 $ids = explode( '-', $_POST['action'], 2 );
171 $id = end( $ids );
172
173 // Basic security check.
174 check_ajax_referer( 'save_settings-' . $id, '_wpnonce-' . $id );
175
176 // Baseline capability gate (defence-in-depth). Edit Flow's Screen Options panels
177 // are editorial admin features; each registered save_callback should additionally
178 // enforce its own specific authorisation.
179 if ( ! current_user_can( 'edit_posts' ) ) {
180 wp_die( '0' );
181 }
182
183 // Hand the request to the registered callback, if any
184 if ( ! isset( $this->registered_panels[ $id ] ) ) {
185 wp_die( '0' );
186 }
187 $panel = $this->registered_panels[ $id ];
188 if ( is_callable( $panel['save_callback'] ) ) {
189 call_user_func( $panel['save_callback'], $_POST );
190 wp_die( '1' );
191 } else {
192 wp_die( '0' );
193 }
194 }
195
196 /**
197 * Add/enqueue supporting JavaScript for the autosave function of custom "Screen Options" panels.
198 *
199 * Checks if the current page is supposed to contain any autosave-enabled
200 * panels and adds the script only if that's the case.
201 *
202 * @return void
203 */
204 public function add_autosave_script() {
205 // Get the page id/hook/slug/whatever.
206 global $hook_suffix;
207
208 // Check if we have some panels with autosave registered for this page.
209 $panels = $this->get_panels_for_screen( '', $hook_suffix );
210 if ( empty( $panels ) ) {
211 return;
212 }
213
214 $got_autosave = false;
215 foreach ( $panels as $panel_id ) {
216 if ( $this->registered_panels[ $panel_id ]['autosave'] ) {
217 $got_autosave = true;
218 break;
219 }
220 }
221
222 if ( $got_autosave ) {
223 // Enqueue the script itself
224 $url = EDIT_FLOW_URL . '/common/js/screen-options.js';
225 wp_enqueue_script( 'screen-options-custom-autosave', $url, array( 'jquery' ), EDIT_FLOW_VERSION );
226 }
227 }
228
229 /**
230 * Get custom panels registered for a particular screen and/or page.
231 *
232 * @param string $screen_id Screen ID.
233 * @param string $page Optional. Page filename or hook name.
234 * @return array Array of custom panels.
235 */
236 public function get_panels_for_screen( $screen_id, $page = '' ) {
237 if ( isset( $this->page_panels[ $screen_id ] ) && ! empty( $this->page_panels[ $screen_id ] ) ) {
238 $panels = $this->page_panels[ $screen_id ];
239 } else {
240 $panels = array();
241 }
242 if ( ! empty( $page ) ) {
243 $page_as_screen = $this->page_to_screen_id( $page );
244 if ( isset( $this->page_panels[ $page_as_screen ] ) && ! empty( $this->page_panels[ $page_as_screen ] ) ) {
245 $panels = array_merge( $panels, $this->page_panels[ $page_as_screen ] );
246 }
247 }
248 return array_unique( $panels );
249 }
250 }
251
252 // All versions of the class are stored in a global array
253 // and only the latest version is actually used.
254 global $ws_screen_options_versions;
255 if ( ! isset( $ws_screen_options_versions ) ) {
256 $ws_screen_options_versions = array();
257 }
258 $ws_screen_options_versions['1.0'] = 'wsScreenOptions10';
259 endif;
260
261 if ( ! function_exists( 'add_screen_options_panel' ) ) {
262
263 /**
264 * Add a new settings panel to the "Screen Options" box.
265 *
266 * @see wsScreenOptions10::add_screen_options_panel()
267 *
268 * @param string $id String to use in the 'id' attribute of the settings panel. Should be unique.
269 * @param string $title Title of the settings panel. Set to an empty string to omit title.
270 * @param callback $callback Function that fills the panel with the desired content. Should return its output.
271 * @param string|array $page The page(s) on which to show the panel (similar to add_meta_box()).
272 * @param callback $save_callback Optional. Function that saves the settings contained in the panel.
273 * @param bool $autosave Optional. If set, settings will be automatically saved (via AJAX) when the value of any input element in the panel changes. Defaults to false.
274 * @return void
275 */
276 function add_screen_options_panel( $id, $title, $callback, $page, $save_callback = null, $autosave = false ) {
277 global $ws_screen_options_versions;
278
279 static $instance = null;
280 if ( is_null( $instance ) ) {
281 // Instantiate the latest version of the wsScreenOptions class
282 uksort( $ws_screen_options_versions, 'version_compare' );
283 $class_name = end( $ws_screen_options_versions );
284 $instance = new $class_name();
285 }
286
287 return $instance->add_screen_options_panel( $id, $title, $callback, $page, $save_callback, $autosave );
288 }
289
290 }
291