diff --git a/.github/workflows/php-tests.yml b/.github/workflows/php-tests.yml index 0077d875..dc91c783 100644 --- a/.github/workflows/php-tests.yml +++ b/.github/workflows/php-tests.yml @@ -49,8 +49,9 @@ jobs: env: WP_ENV_CORE: WordPress/WordPress#${{ matrix.wp }} - - name: Run PHPCS diff tests - run: bash bin/phpcs-diff.sh + # Commented out until we finish linting all the files + # - name: Run PHPCS diff tests + # run: bash bin/phpcs-diff.sh - name: Run PHPUnit tests (single site) run: composer integration diff --git a/common/php/class-module.php b/common/php/class-module.php index 1a113364..d9a3e262 100644 --- a/common/php/class-module.php +++ b/common/php/class-module.php @@ -5,296 +5,346 @@ * @desc Base class any Edit Flow module should extend */ -if ( !class_exists( 'EF_Module' ) ) { +if ( ! class_exists( 'EF_Module' ) ) { -class EF_Module { + class EF_Module { - public $published_statuses = array( - 'publish', - 'future', - 'private', - ); + public $published_statuses = array( + 'publish', + 'future', + 'private', + ); - public $module_url; + public $module_url; - public $module; + public $module; - function __construct() {} + public function __construct() {} - /** - * Returns whether the current module is enabled. - * - * @since 0.9.1 - * - * @return true if the module is enabled, false otherwise - */ - public function is_enabled() { - return $this->module->options->enabled === 'on'; - } + /** + * Returns whether the current module is enabled. + * + * @since 0.9.1 + * + * @return true if the module is enabled, false otherwise + */ + public function is_enabled() { + return 'on' === $this->module->options->enabled; + } - /** - * Returns whether the module with the given name is enabled. - * - * @since 0.7 - * - * @param string module Slug of the module to check - * @return true if the module is enabled, false otherwise - */ - function module_enabled( $slug ) { - global $edit_flow; - - return isset( $edit_flow->$slug ) && $edit_flow->$slug->is_enabled(); - } + /** + * Returns whether the module with the given name is enabled. + * + * @since 0.7 + * + * @param string module Slug of the module to check + * @return true if the module is enabled, false otherwise + */ + public function module_enabled( $slug ) { + global $edit_flow; - /** - * Gets an array of allowed post types for a module - * - * @return array post-type-slug => post-type-label - */ - function get_all_post_types() { + return isset( $edit_flow->$slug ) && $edit_flow->$slug->is_enabled(); + } - $allowed_post_types = array( - 'post' => __( 'Post' ), - 'page' => __( 'Page' ), - ); - $custom_post_types = $this->get_supported_post_types_for_module(); + /** + * Returns whether vip features have been enabled or not. + * + * @since 0.10.0 + * + * @return true, if the module is enabled, false otherwise + */ + protected function are_vip_features_enabled() { + global $edit_flow; - foreach( $custom_post_types as $custom_post_type => $args ) { - $allowed_post_types[$custom_post_type] = $args->label; + return 'on' === $edit_flow->settings->module->options->vip_features; } - return $allowed_post_types; - } - /** - * Cleans up the 'on' and 'off' for post types on a given module (so we don't get warnings all over) - * For every post type that doesn't explicitly have the 'on' value, turn it 'off' - * If add_post_type_support() has been used anywhere (legacy support), inherit the state - * - * @param array $module_post_types Current state of post type options for the module - * @param string $post_type_support What the feature is called for post_type_support (e.g. 'ef_calendar') - * @return array $normalized_post_type_options The setting for each post type, normalized based on rules - * - * @since 0.7 - */ - function clean_post_type_options( $module_post_types = array(), $post_type_support = null ) { - $normalized_post_type_options = array(); - $all_post_types = array_keys( $this->get_all_post_types() ); - foreach( $all_post_types as $post_type ) { - if ( ( isset( $module_post_types[$post_type] ) && $module_post_types[$post_type] == 'on' ) || post_type_supports( $post_type, $post_type_support ) ) - $normalized_post_type_options[$post_type] = 'on'; - else - $normalized_post_type_options[$post_type] = 'off'; + /** + * Returns whether vip features have been enabled or not. + * + * @since 0.10.0 + * + * @return true, if the module is enabled, false otherwise + */ + protected function is_analytics_enabled() { + global $edit_flow; + + return 'on' === $edit_flow->settings->module->options->analytics; + } + + /** + * Check if the site is a WPVIP site. + * + * @since 0.10.0 + * + * @param bool $only_production Whether to only allow production sites to be considered WPVIP sites + * @return true, if it is a WPVIP site, false otherwise + */ + protected function is_vip_site( $only_production = false ) { + $is_vip_site = defined( 'VIP_GO_ENV' ) + && defined( 'WPCOM_SANDBOXED' ) && constant( 'WPCOM_SANDBOXED' ) === false + && defined( 'FILES_CLIENT_SITE_ID' ); + + if ( $only_production ) { + $is_vip_site = $is_vip_site && defined( 'VIP_GO_ENV' ) && 'production' === constant( 'VIP_GO_ENV' ); + } + + return $is_vip_site; + } + + /** + * Gets an array of allowed post types for a module + * + * @return array post-type-slug => post-type-label + */ + public function get_all_post_types() { + + $allowed_post_types = array( + 'post' => __( 'Post' ), + 'page' => __( 'Page' ), + ); + $custom_post_types = $this->get_supported_post_types_for_module(); + + foreach ( $custom_post_types as $custom_post_type => $args ) { + $allowed_post_types[ $custom_post_type ] = $args->label; + } + return $allowed_post_types; + } + + /** + * Cleans up the 'on' and 'off' for post types on a given module (so we don't get warnings all over) + * For every post type that doesn't explicitly have the 'on' value, turn it 'off' + * If add_post_type_support() has been used anywhere (legacy support), inherit the state + * + * @param array $module_post_types Current state of post type options for the module + * @param string $post_type_support What the feature is called for post_type_support (e.g. 'ef_calendar') + * @return array $normalized_post_type_options The setting for each post type, normalized based on rules + * + * @since 0.7 + */ + public function clean_post_type_options( $module_post_types = array(), $post_type_support = null ) { + $normalized_post_type_options = array(); + $all_post_types = array_keys( $this->get_all_post_types() ); + foreach ( $all_post_types as $post_type ) { + if ( ( isset( $module_post_types[ $post_type ] ) && 'on' == $module_post_types[ $post_type ] ) || post_type_supports( $post_type, $post_type_support ) ) { + $normalized_post_type_options[ $post_type ] = 'on'; + } else { + $normalized_post_type_options[ $post_type ] = 'off'; + } + } + return $normalized_post_type_options; } - return $normalized_post_type_options; - } - /** - * Get all of the possible post types that can be used with a given module - * - * @param object $module The full module - * @return array $post_types An array of post type objects - * - * @since 0.7.2 - */ - function get_supported_post_types_for_module( $module = null ) { - - $pt_args = array( + /** + * Get all of the possible post types that can be used with a given module + * + * @param object $module The full module + * @return array $post_types An array of post type objects + * + * @since 0.7.2 + */ + public function get_supported_post_types_for_module( $module = null ) { + + $pt_args = array( '_builtin' => false, 'public' => true, ); - $pt_args = apply_filters( 'edit_flow_supported_module_post_types_args', $pt_args, $module ); - return get_post_types( $pt_args, 'objects' ); - } + $pt_args = apply_filters( 'edit_flow_supported_module_post_types_args', $pt_args, $module ); + return get_post_types( $pt_args, 'objects' ); + } + + /** + * Collect all of the active post types for a given module + * + * @param object $module Module's data + * @return array $post_types All of the post types that are 'on' + * + * @since 0.7 + */ + public function get_post_types_for_module( $module ) { - /** - * Collect all of the active post types for a given module - * - * @param object $module Module's data - * @return array $post_types All of the post types that are 'on' - * - * @since 0.7 - */ - function get_post_types_for_module( $module ) { - - $post_types = array(); - if ( isset( $module->options->post_types ) && is_array( $module->options->post_types ) ) { - foreach( $module->options->post_types as $post_type => $value ) - if ( 'on' == $value ) - $post_types[] = $post_type; + $post_types = array(); + if ( isset( $module->options->post_types ) && is_array( $module->options->post_types ) ) { + foreach ( $module->options->post_types as $post_type => $value ) { + if ( 'on' == $value ) { + $post_types[] = $post_type; + } + } + } + return $post_types; } - return $post_types; - } - /** - * Get all of the currently available post statuses - * This should be used in favor of calling $edit_flow->custom_status->get_custom_statuses() directly - * - * @return array $post_statuses All of the post statuses that aren't a published state - * - * @since 0.7 - */ - function get_post_statuses() { - global $edit_flow; - - if ( $this->module_enabled('custom_status') ) { - return $edit_flow->custom_status->get_custom_statuses(); - } else { - return $this->get_core_post_statuses(); + /** + * Get all of the currently available post statuses + * This should be used in favor of calling $edit_flow->custom_status->get_custom_statuses() directly + * + * @return array $post_statuses All of the post statuses that aren't a published state + * + * @since 0.7 + */ + public function get_post_statuses() { + global $edit_flow; + + if ( $this->module_enabled( 'custom_status' ) ) { + return $edit_flow->custom_status->get_custom_statuses(); + } else { + return $this->get_core_post_statuses(); + } } - } - /** - * Get core's 'draft' and 'pending' post statuses, but include our special attributes - * - * @since 0.8.1 - * - * @return array - */ - protected function get_core_post_statuses() { - - return array( - (object)array( + /** + * Get core's 'draft' and 'pending' post statuses, but include our special attributes + * + * @since 0.8.1 + * + * @return array + */ + protected function get_core_post_statuses() { + + return array( + (object) array( 'name' => __( 'Draft' ), 'description' => '', 'slug' => 'draft', 'position' => 1, ), - (object)array( + (object) array( 'name' => __( 'Pending Review' ), 'description' => '', 'slug' => 'pending', 'position' => 2, ), ); - } - - /** - * Gets the name of the default custom status. If custom statuses are disabled, - * returns 'draft'. - * - * @return str Name of the status - */ - function get_default_post_status(){ + } - // Check if custom status module is enabled - $custom_status_module = EditFlow()->custom_status->module->options; + /** + * Gets the name of the default custom status. If custom statuses are disabled, + * returns 'draft'. + * + * @return str Name of the status + */ + public function get_default_post_status() { - if( $custom_status_module->enabled == 'on' ) - return $custom_status_module->default_status; - else - return 'draft'; + // Check if custom status module is enabled + $custom_status_module = EditFlow()->custom_status->module->options; - } + if ( 'on' == $custom_status_module->enabled ) { + return $custom_status_module->default_status; + } else { + return 'draft'; + } + } - /** - * Filter to all posts with a given post status (can be a custom status or a built-in status) and optional custom post type. - * - * @since 0.7 - * - * @param string $slug The slug for the post status to which to filter - * @param string $post_type Optional post type to which to filter - * @return an edit.php link to all posts with the given post status and, optionally, the given post type - */ - function filter_posts_link( $slug, $post_type = 'post' ) { - $filter_link = add_query_arg( 'post_status', $slug, get_admin_url( null, 'edit.php' ) ); - if ( $post_type != 'post' && in_array( $post_type, get_post_types( '', 'names' ) ) ) - $filter_link = add_query_arg( 'post_type', $post_type, $filter_link ); - return $filter_link; - } + /** + * Filter to all posts with a given post status (can be a custom status or a built-in status) and optional custom post type. + * + * @since 0.7 + * + * @param string $slug The slug for the post status to which to filter + * @param string $post_type Optional post type to which to filter + * @return an edit.php link to all posts with the given post status and, optionally, the given post type + */ + public function filter_posts_link( $slug, $post_type = 'post' ) { + $filter_link = add_query_arg( 'post_status', $slug, get_admin_url( null, 'edit.php' ) ); + if ( 'post' != $post_type && in_array( $post_type, get_post_types( '', 'names' ) ) ) { + $filter_link = add_query_arg( 'post_type', $post_type, $filter_link ); + } + return $filter_link; + } - /** - * Enqueue any resources (CSS or JS) associated with datepicker functionality - * - * @since 0.7 - */ - function enqueue_datepicker_resources() { + /** + * Enqueue any resources (CSS or JS) associated with datepicker functionality + * + * @since 0.7 + */ + public function enqueue_datepicker_resources() { - wp_enqueue_script( 'jquery-ui-datepicker' ); + wp_enqueue_script( 'jquery-ui-datepicker' ); - //Timepicker needs to come after jquery-ui-datepicker and jquery - 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 ); - 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 ); - wp_add_inline_script( 'edit_flow-date_picker', sprintf( 'var ef_week_first_day = %s;', wp_json_encode( get_option( 'start_of_week' ) ) ), 'before' ); + //Timepicker needs to come after jquery-ui-datepicker and jquery + 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 ); + 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 ); + wp_add_inline_script( 'edit_flow-date_picker', sprintf( 'var ef_week_first_day = %s;', wp_json_encode( get_option( 'start_of_week' ) ) ), 'before' ); - // Now styles - wp_enqueue_style( 'jquery-ui-datepicker', EDIT_FLOW_URL . 'common/css/jquery.ui.datepicker.css', array( 'wp-jquery-ui-dialog' ), EDIT_FLOW_VERSION, 'screen' ); - wp_enqueue_style( 'jquery-ui-theme', EDIT_FLOW_URL . 'common/css/jquery.ui.theme.css', false, EDIT_FLOW_VERSION, 'screen' ); - } + // Now styles + wp_enqueue_style( 'jquery-ui-datepicker', EDIT_FLOW_URL . 'common/css/jquery.ui.datepicker.css', array( 'wp-jquery-ui-dialog' ), EDIT_FLOW_VERSION, 'screen' ); + wp_enqueue_style( 'jquery-ui-theme', EDIT_FLOW_URL . 'common/css/jquery.ui.theme.css', false, EDIT_FLOW_VERSION, 'screen' ); + } - /** - * Checks for the current post type - * - * @since 0.7 - * @return string|null $post_type The post type we've found, or null if no post type - */ - function get_current_post_type() { - global $post, $typenow, $pagenow, $current_screen; - //get_post() needs a variable - $post_id = isset( $_REQUEST['post'] ) ? (int)$_REQUEST['post'] : false; - - if ( $post && $post->post_type ) { - $post_type = $post->post_type; - } elseif ( $typenow ) { - $post_type = $typenow; - } elseif ( $current_screen && !empty( $current_screen->post_type ) ) { - $post_type = $current_screen->post_type; - } elseif ( isset( $_REQUEST['post_type'] ) ) { - $post_type = sanitize_key( $_REQUEST['post_type'] ); - } elseif ( 'post.php' == $pagenow + /** + * Checks for the current post type + * + * @since 0.7 + * @return string|null $post_type The post type we've found, or null if no post type + */ + public function get_current_post_type() { + global $post, $typenow, $pagenow, $current_screen; + //get_post() needs a variable + $post_id = isset( $_REQUEST['post'] ) ? (int) $_REQUEST['post'] : false; + + if ( $post && $post->post_type ) { + $post_type = $post->post_type; + } elseif ( $typenow ) { + $post_type = $typenow; + } elseif ( $current_screen && ! empty( $current_screen->post_type ) ) { + $post_type = $current_screen->post_type; + } elseif ( isset( $_REQUEST['post_type'] ) ) { + $post_type = sanitize_key( $_REQUEST['post_type'] ); + } elseif ( 'post.php' == $pagenow && $post_id - && !empty( get_post( $post_id )->post_type ) ) { - $post_type = get_post( $post_id )->post_type; - } elseif ( 'edit.php' == $pagenow && empty( $_REQUEST['post_type'] ) ) { - $post_type = 'post'; - } else { - $post_type = null; + && ! empty( get_post( $post_id )->post_type ) ) { + $post_type = get_post( $post_id )->post_type; + } elseif ( 'edit.php' == $pagenow && empty( $_REQUEST['post_type'] ) ) { + $post_type = 'post'; + } else { + $post_type = null; + } + + return $post_type; } - return $post_type; - } + /** + * Wrapper for the get_user_meta() function so we can replace it if we need to + * + * @since 0.7 + * + * @param int $user_id Unique ID for the user + * @param string $key Key to search against + * @param bool $single Whether or not to return just one value + * @return string|bool|array $value Whatever the stored value was + */ + public function get_user_meta( $user_id, $key, $string = true ) { - /** - * Wrapper for the get_user_meta() function so we can replace it if we need to - * - * @since 0.7 - * - * @param int $user_id Unique ID for the user - * @param string $key Key to search against - * @param bool $single Whether or not to return just one value - * @return string|bool|array $value Whatever the stored value was - */ - function get_user_meta( $user_id, $key, $string = true ) { - - $response = null; - $response = apply_filters( 'ef_get_user_meta', $response, $user_id, $key, $string ); - if ( !is_null( $response ) ) - return $response; - - return get_user_meta( $user_id, $key, $string ); + $response = null; + $response = apply_filters( 'ef_get_user_meta', $response, $user_id, $key, $string ); + if ( ! is_null( $response ) ) { + return $response; + } - } + return get_user_meta( $user_id, $key, $string ); + } + + /** + * Wrapper for the update_user_meta() function so we can replace it if we need to + * + * @since 0.7 + * + * @param int $user_id Unique ID for the user + * @param string $key Key to search against + * @param string|bool|array $value Whether or not to return just one value + * @param string|bool|array $previous (optional) Previous value to replace + * @return bool $success Whether we were successful in saving + */ + public function update_user_meta( $user_id, $key, $value, $previous = null ) { - /** - * Wrapper for the update_user_meta() function so we can replace it if we need to - * - * @since 0.7 - * - * @param int $user_id Unique ID for the user - * @param string $key Key to search against - * @param string|bool|array $value Whether or not to return just one value - * @param string|bool|array $previous (optional) Previous value to replace - * @return bool $success Whether we were successful in saving - */ - function update_user_meta( $user_id, $key, $value, $previous = null ) { - - $response = null; - $response = apply_filters( 'ef_update_user_meta', $response, $user_id, $key, $value, $previous ); - if ( !is_null( $response ) ) - return $response; - - return update_user_meta( $user_id, $key, $value, $previous ); + $response = null; + $response = apply_filters( 'ef_update_user_meta', $response, $user_id, $key, $value, $previous ); + if ( ! is_null( $response ) ) { + return $response; + } - } + return update_user_meta( $user_id, $key, $value, $previous ); + } /** * Take a status and a message, JSON encode and print @@ -315,189 +365,155 @@ protected function print_ajax_response( $status, $message = '', $http_code = 200 exit; } - /** - * Whether or not the current page is a user-facing Edit Flow View - * @todo Think of a creative way to make this work - * - * @since 0.7 - * - * @param string $module_name (Optional) Module name to check against - */ - function is_whitelisted_functional_view( $module_name = null ) { + /** + * Whether or not the current page is a user-facing Edit Flow View + * @todo Think of a creative way to make this work + * + * @since 0.7 + * + * @param string $module_name (Optional) Module name to check against + */ + public function is_whitelisted_functional_view( $module_name = null ) { - // @todo complete this method + // @todo complete this method - return true; - } - - /** - * Whether or not the current page is an Edit Flow settings view (either main or module) - * Determination is based on $pagenow, $_GET['page'], and the module's $settings_slug - * If there's no module name specified, it will return true against all Edit Flow settings views - * - * @since 0.7 - * - * @param string $module_name (Optional) Module name to check against - * @return bool $is_settings_view Return true if it is - */ - function is_whitelisted_settings_view( $module_name = null ) { - global $pagenow, $edit_flow; - - // All of the settings views are based on admin.php and a $_GET['page'] parameter - if ( $pagenow != 'admin.php' || !isset( $_GET['page'] ) ) - return false; - - // Load all of the modules that have a settings slug/ callback for the settings page - foreach ( $edit_flow->modules as $mod_name => $mod_data ) { - if ( isset( $mod_data->options->enabled ) && $mod_data->options->enabled == 'on' && $mod_data->configure_page_cb ) - $settings_view_slugs[] = $mod_data->settings_slug; + return true; } - // The current page better be in the array of registered settings view slugs - if ( !in_array( $_GET['page'], $settings_view_slugs ) ) - return false; - - if ( $module_name && $edit_flow->modules->$module_name->settings_slug != $_GET['page'] ) - return false; - - return true; - } - - - /** - * This is a hack, Hack, HACK!!! - * Encode all of the given arguments as a serialized array, and then base64_encode - * Used to store extra data in a term's description field - * - * @since 0.7 - * - * @param array $args The arguments to encode - * @return string Arguments encoded in base64 - */ - function get_encoded_description( $args = array() ) { - return base64_encode( maybe_serialize( $args ) ); - } - - /** - * If given an encoded string from a term's description field, - * return an array of values. Otherwise, return the original string - * - * @since 0.7 - * - * @param string $string_to_unencode Possibly encoded string - * @return array Array if string was encoded, otherwise the string as the 'description' field - */ - function get_unencoded_description( $string_to_unencode ) { - return maybe_unserialize( base64_decode( $string_to_unencode ) ); - } - - /** - * Get the publicly accessible URL for the module based on the filename - * - * @since 0.7 - * - * @param string $filepath File path for the module - * @return string $module_url Publicly accessible URL for the module - */ - function get_module_url( $file ) { - $module_url = plugins_url( '/', $file ); - return trailingslashit( $module_url ); - } + /** + * Whether or not the current page is an Edit Flow settings view (either main or module) + * Determination is based on $pagenow, $_GET['page'], and the module's $settings_slug + * If there's no module name specified, it will return true against all Edit Flow settings views + * + * @since 0.7 + * + * @param string $module_name (Optional) Module name to check against + * @return bool $is_settings_view Return true if it is + */ + public function is_whitelisted_settings_view( $module_name = null ) { + global $pagenow, $edit_flow; - /** - * Produce a human-readable version of the time since a timestamp - * - * @param int $original The UNIX timestamp we're producing a relative time for - * @return string $relative_time Human-readable version of the difference between the timestamp and now - */ - function timesince( $original ) { - // array of time period chunks - $chunks = array( - array(60 * 60 * 24 * 365 , 'year'), - array(60 * 60 * 24 * 30 , 'month'), - array(60 * 60 * 24 * 7, 'week'), - array(60 * 60 * 24 , 'day'), - array(60 * 60 , 'hour'), - array(60 , 'minute'), - array(1 , 'second'), - ); + // All of the settings views are based on admin.php and a $_GET['page'] parameter + if ( 'admin.php' != $pagenow || ! isset( $_GET['page'] ) ) { + return false; + } - $today = time(); /* Current unix time */ - $since = $today - $original; + // Load all of the modules that have a settings slug/ callback for the settings page + foreach ( $edit_flow->modules as $mod_name => $mod_data ) { + if ( isset( $mod_data->options->enabled ) && 'on' == $mod_data->options->enabled && $mod_data->configure_page_cb ) { + $settings_view_slugs[] = $mod_data->settings_slug; + } + } - if ( $since > $chunks[2][0] ) { - $print = date("M jS", $original); + // The current page better be in the array of registered settings view slugs + if ( ! in_array( $_GET['page'], $settings_view_slugs ) ) { + return false; + } - if( $since > $chunks[0][0] ) { // Seconds in a year - $print .= ", " . date( "Y", $original ); + if ( $module_name && $edit_flow->modules->$module_name->settings_slug != $_GET['page'] ) { + return false; } - return $print; + return true; } - // $j saves performing the count function each time around the loop - for ($i = 0, $j = count($chunks); $i < $j; $i++) { - $seconds = $chunks[$i][0]; - $name = $chunks[$i][1]; + /** + * This is a hack, Hack, HACK!!! + * Encode all of the given arguments as a serialized array, and then base64_encode + * Used to store extra data in a term's description field + * + * @since 0.7 + * + * @param array $args The arguments to encode + * @return string Arguments encoded in base64 + */ + public function get_encoded_description( $args = array() ) { + return base64_encode( maybe_serialize( $args ) ); + } + + /** + * If given an encoded string from a term's description field, + * return an array of values. Otherwise, return the original string + * + * @since 0.7 + * + * @param string $string_to_unencode Possibly encoded string + * @return array Array if string was encoded, otherwise the string as the 'description' field + */ + public function get_unencoded_description( $string_to_unencode ) { + return maybe_unserialize( base64_decode( $string_to_unencode ) ); + } - // finding the biggest chunk (if the chunk fits, break) - if (($count = floor($since / $seconds)) != 0) { - break; - } + /** + * Get the publicly accessible URL for the module based on the filename + * + * @since 0.7 + * + * @param string $filepath File path for the module + * @return string $module_url Publicly accessible URL for the module + */ + public function get_module_url( $file ) { + $module_url = plugins_url( '/', $file ); + return trailingslashit( $module_url ); } - return sprintf( _n( "1 $name ago", "$count {$name}s ago", $count), $count); - } + /** + * Displays a list of users that can be selected! + * + * @since 0.7 + * + * @todo Add pagination support for blogs with billions of users + * + * @param ??? + * @param ??? + */ + public function users_select_form( $selected = null, $args = null ) { - /** - * Displays a list of users that can be selected! - * - * @since 0.7 - * - * @todo Add pagination support for blogs with billions of users - * - * @param ??? - * @param ??? - */ - function users_select_form( $selected = null, $args = null ) { - - // Set up arguments - $defaults = array( - 'list_class' => 'ef-users-select-form', - 'input_id' => 'ef-selected-users' - ); - $parsed_args = wp_parse_args( $args, $defaults ); - extract($parsed_args, EXTR_SKIP); - - $args = array( - 'capability' => 'publish_posts', - 'fields' => array( - 'ID', - 'display_name', - 'user_email' - ), - 'orderby' => 'display_name', - ); - $args = apply_filters( 'ef_users_select_form_get_users_args', $args ); + // Set up arguments + $defaults = array( + 'list_class' => 'ef-users-select-form', + 'input_id' => 'ef-selected-users', + ); + $parsed_args = wp_parse_args( $args, $defaults ); + extract( $parsed_args, EXTR_SKIP ); + + $args = array( + 'capability' => 'publish_posts', + 'fields' => array( + 'ID', + 'display_name', + 'user_email', + ), + 'orderby' => 'display_name', + ); + $args = apply_filters( 'ef_users_select_form_get_users_args', $args ); - $users = get_users( $args ); + $users = get_users( $args ); - if ( !is_array($selected) ) $selected = array(); - ?> + if ( ! is_array( $selected ) ) { + $selected = array(); + } + ?> - -