PluginProbe
Edit Flow / 0.9.2
Edit Flow v0.9.2
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
← All changes | common/php/class-module.php +216 -184 0.7.20.9.2 View file →
@@ -5,12 +5,38 @@
5 5 * @desc Base class any Edit Flow module should extend
6 6 */
7 7
8 8 if ( !class_exists( 'EF_Module' ) ) {
9 -
9 +
10 10 class EF_Module {
11 -
12 - function __construct() {
11 +
12 + public $published_statuses = array(
13 + 'publish',
14 + 'future',
15 + 'private',
16 + );
17 +
18 + /**
19 + * Associative array of hook_name => callback_name
20 + * This is used for Gutenberg-compat initialization
21 + * [
22 + * 'init' => 'init_callback_on_module_instance'
23 + * ]
24 + * @var array
25 + */
26 + protected $compat_hooks = [];
27 +
28 + function __construct() {}
29 +
30 + /**
31 + * Returns whether the current module is enabled.
32 + *
33 + * @since 0.9.1
34 + *
35 + * @return <code>true</code> if the module is enabled, <code>false</code> otherwise
36 + */
37 + public function is_enabled() {
38 + return $this->module->options->enabled === 'on';
13 39 }
14 40
15 41 /**
16 42 * Returns whether the module with the given name is enabled.
@@ -22,12 +48,31 @@
22 48 */
23 49 function module_enabled( $slug ) {
24 50 global $edit_flow;
25 51
26 - return isset( $edit_flow->$slug ) && $edit_flow->$slug->module->options->enabled == 'on';
52 + return isset( $edit_flow->$slug ) && $edit_flow->$slug->is_enabled();
27 53 }
28 54
29 55 /**
56 + * Gets an array of allowed post types for a module
57 + *
58 + * @return array post-type-slug => post-type-label
59 + */
60 + function get_all_post_types() {
61 +
62 + $allowed_post_types = array(
63 + 'post' => __( 'Post' ),
64 + 'page' => __( 'Page' ),
65 + );
66 + $custom_post_types = $this->get_supported_post_types_for_module();
67 +
68 + foreach( $custom_post_types as $custom_post_type => $args ) {
69 + $allowed_post_types[$custom_post_type] = $args->label;
70 + }
71 + return $allowed_post_types;
72 + }
73 +
74 + /**
30 75 * Cleans up the 'on' and 'off' for post types on a given module (so we don't get warnings all over)
31 76 * For every post type that doesn't explicitly have the 'on' value, turn it 'off'
32 77 * If add_post_type_support() has been used anywhere (legacy support), inherit the state
33 78 *
@@ -38,11 +83,9 @@
38 83 * @since 0.7
39 84 */
40 85 function clean_post_type_options( $module_post_types = array(), $post_type_support = null ) {
41 86 $normalized_post_type_options = array();
42 - $all_post_types = wp_list_pluck( $this->get_supported_post_types_for_module(), 'name' );
43 - array_push( $all_post_types, 'post', 'page' );
44 - $all_post_types = array_merge( $all_post_types, array_keys( $module_post_types ) );
87 + $all_post_types = array_keys( $this->get_all_post_types() );
45 88 foreach( $all_post_types as $post_type ) {
46 89 if ( ( isset( $module_post_types[$post_type] ) && $module_post_types[$post_type] == 'on' ) || post_type_supports( $post_type, $post_type_support ) )
47 90 $normalized_post_type_options[$post_type] = 'on';
48 91 else
@@ -67,9 +110,9 @@
67 110 );
68 111 $pt_args = apply_filters( 'edit_flow_supported_module_post_types_args', $pt_args, $module );
69 112 return get_post_types( $pt_args, 'objects' );
70 113 }
71 -
114 +
72 115 /**
73 116 * Collect all of the active post types for a given module
74 117 *
75 118 * @param object $module Module's data
@@ -77,9 +120,9 @@
77 120 *
78 121 * @since 0.7
79 122 */
80 123 function get_post_types_for_module( $module ) {
81 -
124 +
82 125 $post_types = array();
83 126 if ( isset( $module->options->post_types ) && is_array( $module->options->post_types ) ) {
84 127 foreach( $module->options->post_types as $post_type => $value )
85 128 if ( 'on' == $value )
@@ -86,40 +129,71 @@
86 129 $post_types[] = $post_type;
87 130 }
88 131 return $post_types;
89 132 }
90 -
133 +
91 134 /**
92 135 * Get all of the currently available post statuses
93 136 * This should be used in favor of calling $edit_flow->custom_status->get_custom_statuses() directly
94 137 *
95 - * @return object $post_statuses All of the post statuses that aren't a published state
138 + * @return array $post_statuses All of the post statuses that aren't a published state
96 139 *
97 140 * @since 0.7
98 141 */
99 142 function get_post_statuses() {
100 143 global $edit_flow;
101 -
144 +
102 145 if ( $this->module_enabled('custom_status') ) {
103 146 return $edit_flow->custom_status->get_custom_statuses();
104 147 } else {
105 - $post_statuses = array(
148 + return $this->get_core_post_statuses();
149 + }
150 + }
151 +
152 + /**
153 + * Get core's 'draft' and 'pending' post statuses, but include our special attributes
154 + *
155 + * @since 0.8.1
156 + *
157 + * @return array
158 + */
159 + protected function get_core_post_statuses() {
160 +
161 + return array(
106 162 (object)array(
107 - 'name' => __( 'Draft' ),
108 - 'description' => '',
109 - 'slug' => 'draft',
163 + 'name' => __( 'Draft' ),
164 + 'description' => '',
165 + 'slug' => 'draft',
166 + 'position' => 1,
110 167 ),
111 168 (object)array(
112 - 'name' => __( 'Pending Review' ),
113 - 'description' => '',
114 - 'slug' => 'pending',
115 - ),
169 + 'name' => __( 'Pending Review' ),
170 + 'description' => '',
171 + 'slug' => 'pending',
172 + 'position' => 2,
173 + ),
116 174 );
117 - return (object)$post_statuses;
118 - }
119 175 }
120 176
121 177 /**
178 + * Gets the name of the default custom status. If custom statuses are disabled,
179 + * returns 'draft'.
180 + *
181 + * @return str Name of the status
182 + */
183 + function get_default_post_status(){
184 +
185 + // Check if custom status module is enabled
186 + $custom_status_module = EditFlow()->custom_status->module->options;
187 +
188 + if( $custom_status_module->enabled == 'on' )
189 + return $custom_status_module->default_status;
190 + else
191 + return 'draft';
192 +
193 + }
194 +
195 + /**
122 196 * Filter to all posts with a given post status (can be a custom status or a built-in status) and optional custom post type.
123 197 *
124 198 * @since 0.7
125 199 *
@@ -132,62 +206,30 @@
132 206 if ( $post_type != 'post' && in_array( $post_type, get_post_types( '', 'names' ) ) )
133 207 $filter_link = add_query_arg( 'post_type', $post_type, $filter_link );
134 208 return $filter_link;
135 209 }
136 -
210 +
137 211 /**
138 - * Returns the friendly name for a given status
139 - *
140 - * @since 0.7
141 - *
142 - * @param string $status The status slug
143 - * @return string $status_friendly_name The friendly name for the status
144 - */
145 - function get_post_status_friendly_name( $status ) {
146 - global $edit_flow;
147 -
148 - $status_friendly_name = '';
149 -
150 - $builtin_stati = array(
151 - 'publish' => __( 'Published', 'edit-flow' ),
152 - 'draft' => __( 'Draft', 'edit-flow' ),
153 - 'future' => __( 'Scheduled', 'edit-flow' ),
154 - 'private' => __( 'Private', 'edit-flow' ),
155 - 'pending' => __( 'Pending Review', 'edit-flow' ),
156 - 'trash' => __( 'Trash', 'edit-flow' ),
157 - );
158 -
159 - // Custom statuses only handles workflow statuses
160 - if ( $this->module_enabled( 'custom_status' ) && !in_array( $status, array( 'publish', 'future', 'private', 'trash' ) ) ) {
161 - $status_object = $edit_flow->custom_status->get_custom_status_by( 'slug', $status );
162 - if( $status_object && !is_wp_error( $status_object ) ) {
163 - $status_friendly_name = $status_object->name;
164 - }
165 - } else if ( array_key_exists( $status, $builtin_stati ) ) {
166 - $status_friendly_name = $builtin_stati[$status];
167 - }
168 - return $status_friendly_name;
169 - }
170 -
171 - /**
172 212 * Enqueue any resources (CSS or JS) associated with datepicker functionality
173 213 *
174 214 * @since 0.7
175 215 */
176 216 function enqueue_datepicker_resources() {
177 -
217 +
178 218 // Add the first day of the week as an available variable to wp_head
179 - echo "<script type=\"text/javascript\">var ef_week_first_day=\"" . get_option( 'start_of_week' ) . "\";</script>";
219 + echo "<script type=\"text/javascript\">var ef_week_first_day=\"" . get_option( 'start_of_week' ) . "\";</script>";
180 220
181 - // Datepicker is available WordPress 3.3. We have to register it ourselves for previous versions of WordPress
182 221 wp_enqueue_script( 'jquery-ui-datepicker' );
183 - wp_enqueue_script( 'edit_flow-date_picker', EDIT_FLOW_URL . 'common/js/ef_date.js', array( 'jquery', 'jquery-ui-datepicker' ), EDIT_FLOW_VERSION, true );
184 222
223 + //Timepicker needs to come after jquery-ui-datepicker and jquery
224 + wp_enqueue_script( 'edit_flow-timepicker', EDIT_FLOW_URL . 'common/js/jquery-ui-timepicker-addon.js', array( 'jquery', 'jquery-ui-datepicker' ), EDIT_FLOW_VERSION, true );
225 + wp_enqueue_script( 'edit_flow-date_picker', EDIT_FLOW_URL . 'common/js/ef_date.js', array( 'jquery', 'jquery-ui-datepicker', 'edit_flow-timepicker' ), EDIT_FLOW_VERSION, true );
226 +
185 227 // Now styles
186 228 wp_enqueue_style( 'jquery-ui-datepicker', EDIT_FLOW_URL . 'common/css/jquery.ui.datepicker.css', array( 'wp-jquery-ui-dialog' ), EDIT_FLOW_VERSION, 'screen' );
187 229 wp_enqueue_style( 'jquery-ui-theme', EDIT_FLOW_URL . 'common/css/jquery.ui.theme.css', false, EDIT_FLOW_VERSION, 'screen' );
188 230 }
189 -
231 +
190 232 /**
191 233 * Checks for the current post type
192 234 *
193 235 * @since 0.7
@@ -194,23 +236,32 @@
194 236 * @return string|null $post_type The post type we've found, or null if no post type
195 237 */
196 238 function get_current_post_type() {
197 239 global $post, $typenow, $pagenow, $current_screen;
240 + //get_post() needs a variable
241 + $post_id = isset( $_REQUEST['post'] ) ? (int)$_REQUEST['post'] : false;
198 242
199 - if ( $post && $post->post_type )
243 + if ( $post && $post->post_type ) {
200 244 $post_type = $post->post_type;
201 - elseif ( $typenow )
245 + } elseif ( $typenow ) {
202 246 $post_type = $typenow;
203 - elseif ( $current_screen && isset( $current_screen->post_type ) )
247 + } elseif ( $current_screen && !empty( $current_screen->post_type ) ) {
204 248 $post_type = $current_screen->post_type;
205 - elseif ( isset( $_REQUEST['post_type'] ) )
249 + } elseif ( isset( $_REQUEST['post_type'] ) ) {
206 250 $post_type = sanitize_key( $_REQUEST['post_type'] );
207 - else
251 + } elseif ( 'post.php' == $pagenow
252 + && $post_id
253 + && !empty( get_post( $post_id )->post_type ) ) {
254 + $post_type = get_post( $post_id )->post_type;
255 + } elseif ( 'edit.php' == $pagenow && empty( $_REQUEST['post_type'] ) ) {
256 + $post_type = 'post';
257 + } else {
208 258 $post_type = null;
259 + }
209 260
210 261 return $post_type;
211 262 }
212 -
263 +
213 264 /**
214 265 * Wrapper for the get_user_meta() function so we can replace it if we need to
215 266 *
216 267 * @since 0.7
@@ -220,18 +271,18 @@
220 271 * @param bool $single Whether or not to return just one value
221 272 * @return string|bool|array $value Whatever the stored value was
222 273 */
223 274 function get_user_meta( $user_id, $key, $string = true ) {
224 -
275 +
225 276 $response = null;
226 277 $response = apply_filters( 'ef_get_user_meta', $response, $user_id, $key, $string );
227 278 if ( !is_null( $response ) )
228 279 return $response;
229 -
280 +
230 281 return get_user_meta( $user_id, $key, $string );
231 -
282 +
232 283 }
233 -
284 +
234 285 /**
235 286 * Wrapper for the update_user_meta() function so we can replace it if we need to
236 287 *
237 288 * @since 0.7
@@ -242,18 +293,18 @@
242 293 * @param string|bool|array $previous (optional) Previous value to replace
243 294 * @return bool $success Whether we were successful in saving
244 295 */
245 296 function update_user_meta( $user_id, $key, $value, $previous = null ) {
246 -
297 +
247 298 $response = null;
248 299 $response = apply_filters( 'ef_update_user_meta', $response, $user_id, $key, $value, $previous );
249 300 if ( !is_null( $response ) )
250 301 return $response;
251 -
302 +
252 303 return update_user_meta( $user_id, $key, $value, $previous );
253 -
254 - }
255 -
304 +
305 + }
306 +
256 307 /**
257 308 * Take a status and a message, JSON encode and print
258 309 *
259 310 * @since 0.7
@@ -264,9 +315,9 @@
264 315 header( 'Content-type: application/json;' );
265 316 echo json_encode( array( 'status' => $status, 'message' => $message ) );
266 317 exit;
267 318 }
268 -
319 +
269 320 /**
270 321 * Whether or not the current page is a user-facing Edit Flow View
271 322 * @todo Think of a creative way to make this work
272 323 *
@@ -274,14 +325,14 @@
274 325 *
275 326 * @param string $module_name (Optional) Module name to check against
276 327 */
277 328 function is_whitelisted_functional_view( $module_name = null ) {
278 -
329 +
279 330 // @todo complete this method
280 -
331 +
281 332 return true;
282 333 }
283 -
334 +
284 335 /**
285 336 * Whether or not the current page is an Edit Flow settings view (either main or module)
286 337 * Determination is based on $pagenow, $_GET['page'], and the module's $settings_slug
287 338 * If there's no module name specified, it will return true against all Edit Flow settings views
@@ -292,103 +343,44 @@
292 343 * @return bool $is_settings_view Return true if it is
293 344 */
294 345 function is_whitelisted_settings_view( $module_name = null ) {
295 346 global $pagenow, $edit_flow;
296 -
347 +
297 348 // All of the settings views are based on admin.php and a $_GET['page'] parameter
298 349 if ( $pagenow != 'admin.php' || !isset( $_GET['page'] ) )
299 350 return false;
300 -
351 +
301 352 // Load all of the modules that have a settings slug/ callback for the settings page
302 353 foreach ( $edit_flow->modules as $mod_name => $mod_data ) {
303 354 if ( isset( $mod_data->options->enabled ) && $mod_data->options->enabled == 'on' && $mod_data->configure_page_cb )
304 355 $settings_view_slugs[] = $mod_data->settings_slug;
305 356 }
306 -
357 +
307 358 // The current page better be in the array of registered settings view slugs
308 359 if ( !in_array( $_GET['page'], $settings_view_slugs ) )
309 360 return false;
310 -
361 +
311 362 if ( $module_name && $edit_flow->modules->$module_name->settings_slug != $_GET['page'] )
312 363 return false;
313 -
364 +
314 365 return true;
315 366 }
316 -
317 - /**
318 - * Remove term(s) associated with a given object(s). Core doesn't have this as of 3.2
319 - * @see http://core.trac.wordpress.org/ticket/15475
320 - *
321 - * @author ericmann
322 - * @compat 3.3?
323 - *
324 - * @param int|array $object_ids The ID(s) of the object(s) to retrieve.
325 - * @param int|array $terms The ids of the terms to remove.
326 - * @param string|array $taxonomies The taxonomies to retrieve terms from.
327 - * @return bool|WP_Error Affected Term IDs
328 - */
329 - function remove_object_terms( $object_id, $terms, $taxonomy ) {
330 - global $wpdb;
331 367
332 - if ( !taxonomy_exists( $taxonomy ) )
333 - return new WP_Error( 'invalid_taxonomy', __( 'Invalid Taxonomy' ) );
334 368
335 - if ( !is_array( $object_id ) )
336 - $object_id = array( $object_id );
337 -
338 - if ( !is_array($terms) )
339 - $terms = array( $terms );
340 -
341 - $delete_objects = array_map( 'intval', $object_id );
342 - $delete_terms = array_map( 'intval', $terms );
343 -
344 - if ( $delete_terms ) {
345 - $in_delete_terms = "'" . implode( "', '", $delete_terms ) . "'";
346 - $in_delete_objects = "'" . implode( "', '", $delete_objects ) . "'";
347 - $return = $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->term_relationships WHERE object_id IN ($in_delete_objects) AND term_taxonomy_id IN ($in_delete_terms)", $object_id ) );
348 - wp_update_term_count( $delete_terms, $taxonomy );
349 - return true;
350 - }
351 - return false;
352 - }
353 -
354 369 /**
355 370 * This is a hack, Hack, HACK!!!
356 - * Encode all of the given arguments as JSON.
371 + * Encode all of the given arguments as a serialized array, and then base64_encode
357 372 * Used to store extra data in a term's description field
358 - * @todo This is ghetto ghetto because so so brittle. Base64 the description instead?
359 373 *
360 374 * @since 0.7
361 375 *
362 376 * @param array $args The arguments to encode
363 - * @param string $metadata_type Metadata type
364 - * @return string $encoded Type and description encoded as JSON
377 + * @return string Arguments encoded in base64
365 378 */
366 379 function get_encoded_description( $args = array() ) {
367 -
368 - $sanitized_args = array();
369 - foreach( $args as $key => $value ) {
370 - // Arrays make it through scot-free because we assume its just a set of integers
371 - if ( is_array( $value ) ) {
372 - $sanitized_args[$key] = $value;
373 - continue;
374 - }
375 - // Damn pesky carriage returns...
376 - $sanitized_args[$key] = str_replace( "\r\n", "\n", $value );
377 - $sanitized_args[$key] = str_replace( "\r", "\n", $sanitized_args[$key] );
378 - // Convert all newlines to <br /> for storage (and because it's the proper way to present them)
379 - $sanitized_args[$key] = str_replace("\n", "<br />", $sanitized_args[$key]);
380 - $allowed_tags = '<b><a><strong><i><ul><li><ol><blockquote><em><br>';
381 - $sanitized_args[$key] = strip_tags( $sanitized_args[$key], $allowed_tags );
382 - // Escape any special characters (', ", <, >, &)
383 - $sanitized_args[$key] = esc_attr( $sanitized_args[$key] );
384 - $sanitized_args[$key] = htmlentities( $sanitized_args[$key], ENT_QUOTES );
385 - }
386 - $encoded = json_encode( $args );
387 -
388 - return $encoded;
380 + return base64_encode( maybe_serialize( $args ) );
389 381 }
390 -
382 +
391 383 /**
392 384 * If given an encoded string from a term's description field,
393 385 * return an array of values. Otherwise, return the original string
394 386 *
@@ -394,29 +386,14 @@
394 386 *
395 387 * @since 0.7
396 388 *
397 389 * @param string $string_to_unencode Possibly encoded string
398 - * @return array $string_or_unencoded_array Array if string was encoded, otherwise the string as the 'description' field
390 + * @return array Array if string was encoded, otherwise the string as the 'description' field
399 391 */
400 392 function get_unencoded_description( $string_to_unencode ) {
401 - $string_to_unencode = stripslashes( htmlspecialchars_decode( $string_to_unencode ) );
402 - $unencoded_array = json_decode( $string_to_unencode, true );
403 - $string_or_unencoded_array = array();
404 - // Only continue processing if it actually was an array. Otherwise, set to the original string
405 - if ( is_array( $unencoded_array ) ) {
406 - foreach( $unencoded_array as $key => $value ) {
407 - // html_entity_decode only works on strings but sometimes we store nested arrays
408 - if ( !is_array( $value ) )
409 - $string_or_unencoded_array[$key] = html_entity_decode( $value, ENT_QUOTES );
410 - else
411 - $string_or_unencoded_array[$key] = $value;
412 - }
413 - } else {
414 - $string_or_unencoded_array['description'] = $string_to_unencode;
415 - }
416 - return $string_or_unencoded_array;
393 + return maybe_unserialize( base64_decode( $string_to_unencode ) );
417 394 }
418 -
395 +
419 396 /**
420 397 * Get the publicly accessible URL for the module based on the filename
421 398 *
422 399 * @since 0.7
@@ -427,9 +404,9 @@
427 404 function get_module_url( $file ) {
428 405 $module_url = plugins_url( '/', $file );
429 406 return trailingslashit( $module_url );
430 407 }
431 -
408 +
432 409 /**
433 410 * Produce a human-readable version of the time since a timestamp
434 411 *
435 412 * @param int $original The UNIX timestamp we're producing a relative time for
@@ -473,9 +450,9 @@
473 450 }
474 451
475 452 return sprintf( _n( "1 $name ago", "$count ${name}s ago", $count), $count);
476 453 }
477 -
454 +
478 455 /**
479 456 * Displays a list of users that can be selected!
480 457 *
481 458 * @since 0.7
@@ -485,13 +462,12 @@
485 462 * @param ???
486 463 * @param ???
487 464 */
488 465 function users_select_form( $selected = null, $args = null ) {
489 - global $blog_id;
490 466
491 467 // Set up arguments
492 468 $defaults = array(
493 - 'list_class' => 'ef-users-select-form',
469 + 'list_class' => 'ef-users-select-form',
494 470 'input_id' => 'ef-selected-users'
495 471 );
496 472 $parsed_args = wp_parse_args( $args, $defaults );
497 473 extract($parsed_args, EXTR_SKIP);
@@ -504,8 +480,10 @@
504 480 'user_email'
505 481 ),
506 482 'orderby' => 'display_name',
507 483 );
484 + $args = apply_filters( 'ef_users_select_form_get_users_args', $args );
485 +
508 486 $users = get_users( $args );
509 487
510 488 if ( !is_array($selected) ) $selected = array();
511 489 ?>
@@ -511,13 +489,20 @@
511 489 ?>
512 490
513 491 <?php if( !empty($users) ) : ?>
514 492 <ul class="<?php echo esc_attr( $list_class ) ?>">
515 - <?php foreach( $users as $user ) : ?>
516 - <?php $checked = ( in_array($user->ID, $selected) ) ? 'checked="checked"' : ''; ?>
493 + <?php foreach( $users as $user ) :
494 + $checked = ( in_array($user->ID, $selected) ) ? 'checked="checked"' : '';
495 + // Add a class to checkbox of current user so we know not to add them in notified list during notifiedMessage() js function
496 + $current_user_class = ( get_current_user_id() == $user->ID ) ? 'class="post_following_list-current_user" ' : '';
497 + ?>
517 498 <li>
518 499 <label for="<?php echo esc_attr( $input_id .'-'. $user->ID ) ?>">
519 - <input type="checkbox" id="<?php echo esc_attr( $input_id .'-'. $user->ID ) ?>" name="<?php echo esc_attr( $input_id ) ?>[]" value="<?php echo esc_attr( $user->ID ); ?>" <?php echo $checked; ?> />
500 + <div class="ef-user-subscribe-actions">
501 + <?php do_action( 'ef_user_subscribe_actions', $user->ID, $checked ) ?>
502 + <input type="checkbox" id="<?php echo esc_attr( $input_id .'-'. $user->ID ) ?>" name="<?php echo esc_attr( $input_id ) ?>[]" value="<?php echo esc_attr( $user->ID ); ?>" <?php echo $checked; echo $current_user_class; ?> />
503 + </div>
504 +
520 505 <span class="ef-user_displayname"><?php echo esc_html( $user->display_name ); ?></span>
521 506 <span class="ef-user_useremail"><?php echo esc_html( $user->user_email ); ?></span>
522 507 </label>
523 508 </li>
@@ -541,13 +526,14 @@
541 526 if ( apply_filters( 'ef_kill_add_caps_to_role', false, $role, $caps ) )
542 527 return;
543 528
544 529 global $wp_roles;
545 -
530 +
546 531 if ( $wp_roles->is_role( $role ) ) {
547 - $role =& get_role( $role );
548 - foreach ( $caps as $cap )
532 + $role = get_role( $role );
533 + foreach ( $caps as $cap ) {
549 534 $role->add_cap( $cap );
535 + }
550 536 }
551 537 }
552 538
553 539 /**
@@ -556,25 +542,71 @@
556 542 *
557 543 * @since 0.7
558 544 */
559 545 function action_settings_help_menu() {
560 -
546 +
561 547 $screen = get_current_screen();
562 -
563 - if ( !method_exists( $screen, 'add_help_tab' ) )
548 +
549 + if ( !method_exists( $screen, 'add_help_tab' ) )
564 550 return;
565 -
566 - if ( $screen->id != 'edit-flow_page_' . $this->module->settings_slug )
551 +
552 + if ( $screen->id != 'edit-flow_page_' . $this->module->settings_slug )
567 553 return;
568 554
569 555 // Make sure we have all of the required values for our tab
570 556 if ( isset( $this->module->settings_help_tab['id'], $this->module->settings_help_tab['title'], $this->module->settings_help_tab['content'] ) ) {
571 557 $screen->add_help_tab( $this->module->settings_help_tab );
572 -
558 +
573 559 if ( isset( $this->module->settings_help_sidebar ) ) {
574 560 $screen->set_help_sidebar( $this->module->settings_help_sidebar );
575 561 }
576 562 }
577 563 }
578 -
564 +
565 + /**
566 + * Upgrade the term descriptions for all of the terms in a given taxonomy
567 + */
568 + function upgrade_074_term_descriptions( $taxonomy ) {
569 + $args = array(
570 + 'hide_empty' => false,
571 + );
572 + $terms = get_terms( $taxonomy, $args );
573 + foreach( $terms as $term ) {
574 + // If we can detect that this term already follows the new scheme, let's skip it
575 + $maybe_serialized = base64_decode( $term->description );
576 + if ( is_serialized( $maybe_serialized ) )
577 + continue;
578 +
579 + $description_args = array();
580 + // This description has been JSON-encoded, so let's decode it
581 + if ( 0 === strpos( $term->description, '{' ) ) {
582 + $string_to_unencode = stripslashes( htmlspecialchars_decode( $term->description ) );
583 + $unencoded_array = json_decode( $string_to_unencode, true );
584 + // Only continue processing if it actually was an array. Otherwise, set to the original string
585 + if ( is_array( $unencoded_array ) ) {
586 + foreach( $unencoded_array as $key => $value ) {
587 + // html_entity_decode only works on strings but sometimes we store nested arrays
588 + if ( !is_array( $value ) )
589 + $description_args[$key] = html_entity_decode( $value, ENT_QUOTES );
590 + else
591 + $description_args[$key] = $value;
592 + }
593 + }
594 + } else {
595 + $description_args['description'] = $term->description;
596 + }
597 + $new_description = $this->get_encoded_description( $description_args );
598 + wp_update_term( $term->term_id, $taxonomy, array( 'description' => $new_description ) );
599 + }
600 + }
601 +
602 + /**
603 + * Return compatibility hooks for the current instance
604 + *
605 + * @return array
606 + */
607 + function get_compat_hooks() {
608 + return isset( $this->compat_hooks ) && is_array( $this->compat_hooks ) ? $this->compat_hooks : [];
609 + }
610 +
579 611 }
580 612 }