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 +170 -149 0.7.60.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,9 +129,9 @@
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 *
@@ -97,29 +140,60 @@
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 $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,63 +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' )
161 - && !in_array( $status, array( 'publish', 'future', 'private', 'trash' ) ) ) {
162 - $status_object = $edit_flow->custom_status->get_custom_status_by( 'slug', $status );
163 - if( $status_object && !is_wp_error( $status_object ) ) {
164 - $status_friendly_name = $status_object->name;
165 - }
166 - } else if ( array_key_exists( $status, $builtin_stati ) ) {
167 - $status_friendly_name = $builtin_stati[$status];
168 - }
169 - return $status_friendly_name;
170 - }
171 -
172 - /**
173 212 * Enqueue any resources (CSS or JS) associated with datepicker functionality
174 213 *
175 214 * @since 0.7
176 215 */
177 216 function enqueue_datepicker_resources() {
178 -
217 +
179 218 // Add the first day of the week as an available variable to wp_head
180 - 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>";
181 220
182 - // Datepicker is available WordPress 3.3. We have to register it ourselves for previous versions of WordPress
183 221 wp_enqueue_script( 'jquery-ui-datepicker' );
184 - wp_enqueue_script( 'edit_flow-date_picker', EDIT_FLOW_URL . 'common/js/ef_date.js', array( 'jquery', 'jquery-ui-datepicker' ), EDIT_FLOW_VERSION, true );
185 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 +
186 227 // Now styles
187 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' );
188 229 wp_enqueue_style( 'jquery-ui-theme', EDIT_FLOW_URL . 'common/css/jquery.ui.theme.css', false, EDIT_FLOW_VERSION, 'screen' );
189 230 }
190 -
231 +
191 232 /**
192 233 * Checks for the current post type
193 234 *
194 235 * @since 0.7
@@ -196,33 +237,31 @@
196 237 */
197 238 function get_current_post_type() {
198 239 global $post, $typenow, $pagenow, $current_screen;
199 240 //get_post() needs a variable
200 - $post_int;
201 - if( isset( $_REQUEST['post'] ) )
202 - $post_int = (int)$_REQUEST['post'];
241 + $post_id = isset( $_REQUEST['post'] ) ? (int)$_REQUEST['post'] : false;
203 242
204 - if ( $post && $post->post_type )
243 + if ( $post && $post->post_type ) {
205 244 $post_type = $post->post_type;
206 - elseif ( $typenow )
245 + } elseif ( $typenow ) {
207 246 $post_type = $typenow;
208 - elseif ( $current_screen && isset( $current_screen->post_type ) )
247 + } elseif ( $current_screen && !empty( $current_screen->post_type ) ) {
209 248 $post_type = $current_screen->post_type;
210 - elseif ( isset( $_REQUEST['post_type'] ) )
249 + } elseif ( isset( $_REQUEST['post_type'] ) ) {
211 250 $post_type = sanitize_key( $_REQUEST['post_type'] );
212 - elseif ( 'post.php' == $pagenow
213 - && isset( $_REQUEST['post'] )
214 - && isset( $post_int )
215 - && ! empty( get_post( $post_int )->post_type ) )
216 - $post_type = get_post( $post_int )->post_type;
217 - elseif ( 'edit.php' == $pagenow && empty( $_REQUEST['post_type'] ) )
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'] ) ) {
218 256 $post_type = 'post';
219 - else
257 + } else {
220 258 $post_type = null;
259 + }
221 260
222 261 return $post_type;
223 262 }
224 -
263 +
225 264 /**
226 265 * Wrapper for the get_user_meta() function so we can replace it if we need to
227 266 *
228 267 * @since 0.7
@@ -232,18 +271,18 @@
232 271 * @param bool $single Whether or not to return just one value
233 272 * @return string|bool|array $value Whatever the stored value was
234 273 */
235 274 function get_user_meta( $user_id, $key, $string = true ) {
236 -
275 +
237 276 $response = null;
238 277 $response = apply_filters( 'ef_get_user_meta', $response, $user_id, $key, $string );
239 278 if ( !is_null( $response ) )
240 279 return $response;
241 -
280 +
242 281 return get_user_meta( $user_id, $key, $string );
243 -
282 +
244 283 }
245 -
284 +
246 285 /**
247 286 * Wrapper for the update_user_meta() function so we can replace it if we need to
248 287 *
249 288 * @since 0.7
@@ -254,18 +293,18 @@
254 293 * @param string|bool|array $previous (optional) Previous value to replace
255 294 * @return bool $success Whether we were successful in saving
256 295 */
257 296 function update_user_meta( $user_id, $key, $value, $previous = null ) {
258 -
297 +
259 298 $response = null;
260 299 $response = apply_filters( 'ef_update_user_meta', $response, $user_id, $key, $value, $previous );
261 300 if ( !is_null( $response ) )
262 301 return $response;
263 -
302 +
264 303 return update_user_meta( $user_id, $key, $value, $previous );
265 -
266 - }
267 -
304 +
305 + }
306 +
268 307 /**
269 308 * Take a status and a message, JSON encode and print
270 309 *
271 310 * @since 0.7
@@ -276,9 +315,9 @@
276 315 header( 'Content-type: application/json;' );
277 316 echo json_encode( array( 'status' => $status, 'message' => $message ) );
278 317 exit;
279 318 }
280 -
319 +
281 320 /**
282 321 * Whether or not the current page is a user-facing Edit Flow View
283 322 * @todo Think of a creative way to make this work
284 323 *
@@ -286,14 +325,14 @@
286 325 *
287 326 * @param string $module_name (Optional) Module name to check against
288 327 */
289 328 function is_whitelisted_functional_view( $module_name = null ) {
290 -
329 +
291 330 // @todo complete this method
292 -
331 +
293 332 return true;
294 333 }
295 -
334 +
296 335 /**
297 336 * Whether or not the current page is an Edit Flow settings view (either main or module)
298 337 * Determination is based on $pagenow, $_GET['page'], and the module's $settings_slug
299 338 * If there's no module name specified, it will return true against all Edit Flow settings views
@@ -304,66 +343,30 @@
304 343 * @return bool $is_settings_view Return true if it is
305 344 */
306 345 function is_whitelisted_settings_view( $module_name = null ) {
307 346 global $pagenow, $edit_flow;
308 -
347 +
309 348 // All of the settings views are based on admin.php and a $_GET['page'] parameter
310 349 if ( $pagenow != 'admin.php' || !isset( $_GET['page'] ) )
311 350 return false;
312 -
351 +
313 352 // Load all of the modules that have a settings slug/ callback for the settings page
314 353 foreach ( $edit_flow->modules as $mod_name => $mod_data ) {
315 354 if ( isset( $mod_data->options->enabled ) && $mod_data->options->enabled == 'on' && $mod_data->configure_page_cb )
316 355 $settings_view_slugs[] = $mod_data->settings_slug;
317 356 }
318 -
357 +
319 358 // The current page better be in the array of registered settings view slugs
320 359 if ( !in_array( $_GET['page'], $settings_view_slugs ) )
321 360 return false;
322 -
361 +
323 362 if ( $module_name && $edit_flow->modules->$module_name->settings_slug != $_GET['page'] )
324 363 return false;
325 -
364 +
326 365 return true;
327 366 }
328 -
329 - /**
330 - * Remove term(s) associated with a given object(s). Core doesn't have this as of 3.2
331 - * @see http://core.trac.wordpress.org/ticket/15475
332 - *
333 - * @author ericmann
334 - * @compat 3.3?
335 - *
336 - * @param int|array $object_ids The ID(s) of the object(s) to retrieve.
337 - * @param int|array $terms The ids of the terms to remove.
338 - * @param string|array $taxonomies The taxonomies to retrieve terms from.
339 - * @return bool|WP_Error Affected Term IDs
340 - */
341 - function remove_object_terms( $object_id, $terms, $taxonomy ) {
342 - global $wpdb;
343 367
344 - if ( !taxonomy_exists( $taxonomy ) )
345 - return new WP_Error( 'invalid_taxonomy', __( 'Invalid Taxonomy' ) );
346 368
347 - if ( !is_array( $object_id ) )
348 - $object_id = array( $object_id );
349 -
350 - if ( !is_array($terms) )
351 - $terms = array( $terms );
352 -
353 - $delete_objects = array_map( 'intval', $object_id );
354 - $delete_terms = array_map( 'intval', $terms );
355 -
356 - if ( $delete_terms ) {
357 - $in_delete_terms = "'" . implode( "', '", $delete_terms ) . "'";
358 - $in_delete_objects = "'" . implode( "', '", $delete_objects ) . "'";
359 - $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 ) );
360 - wp_update_term_count( $delete_terms, $taxonomy );
361 - return true;
362 - }
363 - return false;
364 - }
365 -
366 369 /**
367 370 * This is a hack, Hack, HACK!!!
368 371 * Encode all of the given arguments as a serialized array, and then base64_encode
369 372 * Used to store extra data in a term's description field
@@ -375,9 +378,9 @@
375 378 */
376 379 function get_encoded_description( $args = array() ) {
377 380 return base64_encode( maybe_serialize( $args ) );
378 381 }
379 -
382 +
380 383 /**
381 384 * If given an encoded string from a term's description field,
382 385 * return an array of values. Otherwise, return the original string
383 386 *
@@ -388,9 +391,9 @@
388 391 */
389 392 function get_unencoded_description( $string_to_unencode ) {
390 393 return maybe_unserialize( base64_decode( $string_to_unencode ) );
391 394 }
392 -
395 +
393 396 /**
394 397 * Get the publicly accessible URL for the module based on the filename
395 398 *
396 399 * @since 0.7
@@ -401,9 +404,9 @@
401 404 function get_module_url( $file ) {
402 405 $module_url = plugins_url( '/', $file );
403 406 return trailingslashit( $module_url );
404 407 }
405 -
408 +
406 409 /**
407 410 * Produce a human-readable version of the time since a timestamp
408 411 *
409 412 * @param int $original The UNIX timestamp we're producing a relative time for
@@ -447,9 +450,9 @@
447 450 }
448 451
449 452 return sprintf( _n( "1 $name ago", "$count ${name}s ago", $count), $count);
450 453 }
451 -
454 +
452 455 /**
453 456 * Displays a list of users that can be selected!
454 457 *
455 458 * @since 0.7
@@ -462,9 +465,9 @@
462 465 function users_select_form( $selected = null, $args = null ) {
463 466
464 467 // Set up arguments
465 468 $defaults = array(
466 - 'list_class' => 'ef-users-select-form',
469 + 'list_class' => 'ef-users-select-form',
467 470 'input_id' => 'ef-selected-users'
468 471 );
469 472 $parsed_args = wp_parse_args( $args, $defaults );
470 473 extract($parsed_args, EXTR_SKIP);
@@ -478,8 +481,9 @@
478 481 ),
479 482 'orderby' => 'display_name',
480 483 );
481 484 $args = apply_filters( 'ef_users_select_form_get_users_args', $args );
485 +
482 486 $users = get_users( $args );
483 487
484 488 if ( !is_array($selected) ) $selected = array();
485 489 ?>
@@ -485,13 +489,20 @@
485 489 ?>
486 490
487 491 <?php if( !empty($users) ) : ?>
488 492 <ul class="<?php echo esc_attr( $list_class ) ?>">
489 - <?php foreach( $users as $user ) : ?>
490 - <?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 + ?>
491 498 <li>
492 499 <label for="<?php echo esc_attr( $input_id .'-'. $user->ID ) ?>">
493 - <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 +
494 505 <span class="ef-user_displayname"><?php echo esc_html( $user->display_name ); ?></span>
495 506 <span class="ef-user_useremail"><?php echo esc_html( $user->user_email ); ?></span>
496 507 </label>
497 508 </li>
@@ -515,13 +526,14 @@
515 526 if ( apply_filters( 'ef_kill_add_caps_to_role', false, $role, $caps ) )
516 527 return;
517 528
518 529 global $wp_roles;
519 -
530 +
520 531 if ( $wp_roles->is_role( $role ) ) {
521 - $role =& get_role( $role );
522 - foreach ( $caps as $cap )
532 + $role = get_role( $role );
533 + foreach ( $caps as $cap ) {
523 534 $role->add_cap( $cap );
535 + }
524 536 }
525 537 }
526 538
527 539 /**
@@ -530,21 +542,21 @@
530 542 *
531 543 * @since 0.7
532 544 */
533 545 function action_settings_help_menu() {
534 -
546 +
535 547 $screen = get_current_screen();
536 -
537 - if ( !method_exists( $screen, 'add_help_tab' ) )
548 +
549 + if ( !method_exists( $screen, 'add_help_tab' ) )
538 550 return;
539 -
540 - if ( $screen->id != 'edit-flow_page_' . $this->module->settings_slug )
551 +
552 + if ( $screen->id != 'edit-flow_page_' . $this->module->settings_slug )
541 553 return;
542 554
543 555 // Make sure we have all of the required values for our tab
544 556 if ( isset( $this->module->settings_help_tab['id'], $this->module->settings_help_tab['title'], $this->module->settings_help_tab['content'] ) ) {
545 557 $screen->add_help_tab( $this->module->settings_help_tab );
546 -
558 +
547 559 if ( isset( $this->module->settings_help_sidebar ) ) {
548 560 $screen->set_help_sidebar( $this->module->settings_help_sidebar );
549 561 }
550 562 }
@@ -585,7 +597,16 @@
585 597 $new_description = $this->get_encoded_description( $description_args );
586 598 wp_update_term( $term->term_id, $taxonomy, array( 'description' => $new_description ) );
587 599 }
588 600 }
589 -
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 +
590 611 }
591 612 }