/** * Displays the output * * @param array $args * @param array $instance * @since Achievements (3.3) */ public function widget($args, $instance) { $settings = $this->parse_settings($instance); $settings['post_id'] = absint(apply_filters('dpa_featured_achievement_post_id', $settings['post_id'], $instance, $this->id_base)); // Get the specified achievement $achievement = get_posts(array('no_found_rows' => true, 'numberposts' => 1, 'p' => $settings['post_id'], 'post_status' => 'publish', 'post_type' => dpa_get_achievement_post_type(), 'suppress_filters' => false)); // Bail if it doesn't exist if (empty($achievement)) { return; } $achievement = array_shift($achievement); $title = dpa_get_achievement_title($achievement->ID); echo $args['before_widget']; echo $args['before_title'] . $title . $args['after_title']; if (has_post_thumbnail($achievement->ID)) { ?> <a href="<?php dpa_achievement_permalink($achievement->ID); ?> "><?php echo get_the_post_thumbnail($achievement->ID, 'thumbnail', array('alt' => $title)); ?> </a> <?php } dpa_achievement_excerpt($settings['post_id']); echo $args['after_widget']; }
/** * List all achievements * * @since Achievements (3.3) * @subcommand list * @synopsis [--format=<table|csv|json>] */ public function _list($args, $assoc_args) { global $wpdb; $defaults = array('format' => 'table'); $assoc_args = array_merge($defaults, $assoc_args); // Get the posts $posts = $wpdb->get_results($wpdb->prepare("SELECT ID, post_title FROM {$wpdb->posts} WHERE post_type = %s AND post_status = %s ORDER BY post_title ASC", dpa_get_achievement_post_type(), 'publish')); if (empty($posts)) { WP_CLI::error('No published achievements found.'); } \WP_CLI\utils\format_items($assoc_args['format'], $posts, $this->fields); }
/** * Displays the output * * @param array $args * @param array $instance * @since Achievements (2.0) */ public function widget($args, $instance) { $settings = $this->parse_settings($instance); // Use these filters $settings['limit'] = absint(apply_filters('dpa_available_achievements_limit', $settings['limit'], $instance, $this->id_base)); $settings['title'] = apply_filters('dpa_available_achievements_title', $settings['title'], $instance, $this->id_base); // WordPress filters widget_title through esc_html. $settings['title'] = apply_filters('widget_title', $settings['title'], $instance, $this->id_base); echo $args['before_widget']; if (!empty($settings['title'])) { echo $args['before_title'] . $settings['title'] . $args['after_title']; } // Get the posts $achievements = get_posts(array('ignore_sticky_posts' => true, 'no_found_rows' => true, 'numberposts' => $settings['limit'], 'post_status' => 'publish', 'post_type' => dpa_get_achievement_post_type(), 'suppress_filters' => false)); // Bail if no posts if (empty($achievements)) { return; } echo '<ul>'; foreach ($achievements as $post) { if (has_post_thumbnail($post->ID)) { ?> <li> <a href="<?php dpa_achievement_permalink($post->ID); ?> "><?php echo get_the_post_thumbnail($post->ID, 'dpa-thumb', array('alt' => dpa_get_achievement_title($post->ID))); ?> </a> </li> <?php } } echo '</ul>'; echo $args['after_widget']; }
/** * Output the unique id of the custom post type for achievements * * @since 3.0 * @uses dpa_get_achievement_post_type() To get the forum post type */ function dpa_achievement_post_type() { echo dpa_get_achievement_post_type(); }
/** * Get an achievement's ID from the specified $post_name. * * @param string $post_name * @return int Achievement ID * @since Achievements (3.4) */ protected function _get_achievement_id_by_post_name($post_name) { global $wpdb; return absint($wpdb->get_var($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND post_name = %s LIMIT 1", dpa_get_achievement_post_type(), $post_name))); }
/** * Return the total count of the number of achievements * * @return int Total achievement count * @since Achievements (3.0) */ function dpa_get_total_achievement_count() { $counts = wp_count_posts(dpa_get_achievement_post_type()); return apply_filters('dpa_get_total_achievement_count', (int) $counts->publish); }
/** * Can the current user see a specific UI element? * * Used when registering post types and taxonomies to decide if 'show_ui' should * be set to true or false. Also used for fine-grained control over which admin * sections are visible under what conditions. * * This function is in core/caps.php rather than in /admin/ so that it * can be used during the dpa_register_post_types action. * * @param string $component Optional; defaults to no value. Component to check UI visibility for. * @return bool * @since Achievements (3.0) */ function dpa_current_user_can_see($component = '') { $retval = false; // Which component are we checking UI visibility for? switch ($component) { // Everywhere case dpa_get_achievement_post_type(): // Achievements $retval = current_user_can('edit_achievements'); break; // Admin setions // Admin setions default: // Anything else // @todo Use DPA_Admin->minimum_capability $retval = current_user_can('manage_options'); break; } return (bool) apply_filters('dpa_current_user_can_see', (bool) $retval, $component); }
/** * Display the Achievements user admin index screen, which contains a list of all the users. * * @since Achievements (3.0) */ function dpa_admin_screen_users() { global $dpa_users_list_table, $plugin_page, $usersearch; $messages = array(); // Prepare the list items for display $dpa_users_list_table->prepare_items(); // Call an action for plugins to modify the activity before we display the edit form do_action('dpa_admin_screen_users', $messages); ?> <div class="wrap"> <?php screen_icon('users'); ?> <h2> <?php _ex('Users', 'admin menu title', 'achievements'); ?> <?php if (!empty($usersearch)) { ?> <span class="subtitle"><?php printf(_x('Search results for “%s”', 'admin screen search results heading', 'achievements'), esc_html(wp_unslash($usersearch))); ?> </span> <?php } ?> </h2> <?php // If the user has just made a change to an item, display the status messages ?> <?php if (!empty($messages)) { ?> <div id="moderated" class="<?php echo !empty($_GET['error']) ? 'error' : 'updated'; ?> "><p><?php echo implode("<br/>\n", $messages); ?> </p></div> <?php } ?> <?php // Display each item on its own row ?> <?php $dpa_users_list_table->views(); ?> <form id="dpa-admin-users-form" action="" method="get"> <?php $dpa_users_list_table->search_box(__('Search all Users', 'achievements'), 'dpa-admin-users'); ?> <input type="hidden" name="post_type" value="<?php echo esc_attr(dpa_get_achievement_post_type()); ?> " /> <input type="hidden" name="page" value="<?php echo esc_attr($plugin_page); ?> " /> <?php $dpa_users_list_table->display(); ?> </form> </div><!-- .wrap --> <?php }
/** * Get the achievement archive template * * @return string Path to template file * @since Achievements (3.0) */ function dpa_get_achievement_archive_template() { $templates = array('archive-' . dpa_get_achievement_post_type() . '.php'); return dpa_get_query_template('achievement_archive', $templates); }
/** * Make sure WordPress supports post thumbnails for the achievements post type * * @link https://core.trac.wordpress.org/ticket/21912 * @since Achievements (3.4) */ function dpa_add_post_thumbnail_support() { $old_support = get_theme_support('post-thumbnails'); // If the theme is already supporting post-thumbnails for all post types, don't change anything. if ($old_support === true) { return; } if (!is_array($old_support)) { $old_support = array($old_support); } add_theme_support('post-thumbnails', array_merge($old_support, (array) dpa_get_achievement_post_type())); }
/** * Return a breadcrumb ( achievement archive -> achievement -> [achievement, ...] ) * * @param array $args Optional. * @return string Breadcrumbs * @since Achievements (3.0) */ function dpa_get_breadcrumb($args = array()) { // Turn off breadcrumbs if (apply_filters('dpa_no_breadcrumb', is_front_page())) { return ''; } // Define variables $front_id = $root_id = 0; $ancestors = $crumbs = array(); $pre_root_text = $pre_front_text = $pre_current_text = ''; $pre_include_root = $pre_include_home = $pre_include_current = true; /** * Home text */ // No custom home text if (empty($args['home_text'])) { // Set home text to page title $front_id = get_option('page_on_front'); if (!empty($front_id)) { $pre_front_text = get_the_title($front_id); } else { $pre_front_text = _x('Home', 'Home screen of the website', 'achievements'); } } /** * Root text */ // No custom root text if (empty($args['root_text'])) { $page = dpa_get_page_by_path(dpa_get_root_slug()); if (!empty($page)) { $root_id = $page->ID; } $pre_root_text = dpa_get_achievement_archive_title(); } /** * Includes */ // Root slug is also the front page if (!empty($front_id) && $front_id === $root_id) { $pre_include_root = false; } // Don't show root if viewing achievement archive if (dpa_is_achievement_archive()) { $pre_include_root = false; } // Don't show root if viewing page in place of achievement archive if (!empty($root_id) && ((is_single() || is_page()) && $root_id === get_the_ID())) { $pre_include_root = false; } /** * Current text */ // Achievement archive if (dpa_is_achievement_archive()) { $pre_current_text = dpa_get_achievement_archive_title(); // Single achievement } elseif (dpa_is_single_achievement()) { $pre_current_text = dpa_get_achievement_title(); // Single object of some type } else { $pre_current_text = get_the_title(); } /** * Parse args */ // Parse args $defaults = array('before' => '<div class="dpa-breadcrumb"><p>', 'after' => '</p></div>', 'sep' => is_rtl() ? _x('‹', 'HTML entity for left single angle quotes', 'achievements') : _x('›', 'HTML entity for right single angle quotes', 'achievements'), 'pad_sep' => 1, 'sep_before' => '<span class="dpa-breadcrumb-sep">', 'sep_after' => '</span>', 'crumb_before' => '', 'crumb_after' => '', 'include_home' => $pre_include_home, 'home_text' => $pre_front_text, 'include_root' => $pre_include_root, 'root_text' => $pre_root_text, 'include_current' => $pre_include_current, 'current_text' => $pre_current_text, 'current_before' => '<span class="dpa-breadcrumb-current">', 'current_after' => '</span>'); $r = dpa_parse_args($args, $defaults, 'get_breadcrumb'); extract($r); /** * Ancestors */ // Get post ancestors if (is_singular()) { $ancestors = array_reverse(get_post_ancestors(get_the_ID())); } // Do we want to include a link to home? if (!empty($include_home) || empty($home_text)) { $crumbs[] = '<a href="' . esc_url(trailingslashit(home_url())) . '" class="dpa-breadcrumb-home">' . esc_html($home_text) . '</a>'; } // Do we want to include a link to the achievement root? if (!empty($include_root) || empty($root_text)) { // Page exists at root slug path, so use its permalink $page = dpa_get_page_by_path(dpa_get_root_slug()); if (!empty($page)) { $root_url = get_permalink($page->ID); } else { $root_url = get_post_type_archive_link(dpa_get_achievement_post_type()); } // Add the breadcrumb $crumbs[] = '<a href="' . esc_url($root_url) . '" class="dpa-breadcrumb-root">' . esc_html($root_text) . '</a>'; } // Ancestors exist if (!empty($ancestors)) { // Loop through parents foreach ((array) $ancestors as $parent_id) { // Parents $parent = get_post($parent_id); // Skip parent if empty or error if (empty($parent) || is_wp_error($parent)) { continue; } // Switch through post_type to ensure correct filters are applied switch ($parent->post_type) { // Achievement case dpa_get_achievement_post_type(): $crumbs[] = '<a href="' . esc_url(dpa_get_achievement_permalink($parent->ID)) . '" class="dpa-breadcrumb-achievement">' . esc_html(dpa_get_achievement_title($parent->ID)) . '</a>'; break; // WordPress Post/Page/Other // WordPress Post/Page/Other default: $crumbs[] = '<a href="' . esc_url(get_permalink($parent->ID)) . '" class="dpa-breadcrumb-item">' . esc_html(get_the_title($parent->ID)) . '</a>'; break; } } } /** * Current */ // Add current page to breadcrumb if (!empty($include_current) || empty($current_text)) { $crumbs[] = $current_before . $current_text . $current_after; } /** * Separator */ // Wrap the separator in before/after before padding and filter if (!empty($sep)) { $sep = $sep_before . $sep . $sep_after; } // Pad the separator if (!empty($pad_sep)) { $sep = str_pad($sep, strlen($sep) + (int) $pad_sep * 2, ' ', STR_PAD_BOTH); if (function_exists('mb_strlen')) { $sep = str_pad($sep, mb_strlen($sep) + (int) $r['pad_sep'] * 2, ' ', STR_PAD_BOTH); } else { $sep = str_pad($sep, strlen($sep) + (int) $r['pad_sep'] * 2, ' ', STR_PAD_BOTH); } } /** * And -- eventually -- we're done. */ // Filter the separator and breadcrumb $sep = apply_filters('dpa_breadcrumb_separator', $sep); $crumbs = apply_filters('dpa_breadcrumbs', $crumbs); // Build the trail $trail = !empty($crumbs) ? $before . $crumb_before . implode($sep . $crumb_after . $crumb_before, $crumbs) . $crumb_after . $after : ''; return apply_filters('dpa_get_breadcrumb', $trail, $crumbs, $r); }
/** * Add wp-admin menus * * @since Achievements (3.0) */ public function admin_menus() { $hooks = array(); // Settings add_options_page(_x('Achievements', 'admin settings page title', 'achievements'), _x('Achievements', 'admin menu item title', 'achievements'), $this->minimum_capability, 'achievements', 'dpa_admin_settings'); // About add_dashboard_page(_x('Welcome to Achievements', 'admin page title', 'achievements'), _x('Welcome to Achievements', 'admin page title', 'achievements'), $this->minimum_capability, 'achievements-about', array($this, 'about_screen')); remove_submenu_page('index.php', 'achievements-about'); // About - Get Help add_dashboard_page(_x('Welcome to Achievements', 'admin page title', 'achievements'), _x('Welcome to Achievements', 'admin page title', 'achievements'), $this->minimum_capability, 'achievements-help', array($this, 'gethelp_screen')); remove_submenu_page('index.php', 'achievements-help'); // "Users" menu $hooks[] = add_submenu_page('edit.php?post_type=achievement', __('Achievements — Users', 'achievements'), _x('Users', 'admin menu title', 'achievements'), $this->minimum_capability, 'achievements-users', 'dpa_admin_screen_users'); // "Supported Plugins" menu $hooks[] = add_submenu_page('edit.php?post_type=achievement', __('Achievements — Supported Plugins', 'achievements'), __('Supported Plugins', 'achievements'), $this->minimum_capability, 'achievements-plugins', 'dpa_supported_plugins'); foreach ($hooks as $hook) { // Hook into early actions to register custom CSS and JS add_action("admin_print_styles-{$hook}", array($this, 'enqueue_styles')); add_action("admin_print_scripts-{$hook}", array($this, 'enqueue_scripts')); // Hook into early actions to register contextual help and screen options add_action("load-{$hook}", array($this, 'screen_options')); } // Actions for the edit.php?post_type=achievement index screen add_action('load-edit.php', array($this, 'enqueue_index_styles')); // Add/save custom profile field on the edit user screen add_action('edit_user_profile', array($this, 'add_profile_fields')); add_action('show_user_profile', array($this, 'add_profile_fields')); add_action('edit_user_profile_update', array($this, 'save_profile_fields')); add_action('personal_options_update', array($this, 'save_profile_fields')); // Remove the "categories" submenu from inside the achievement post type menu remove_submenu_page('edit.php?post_type=' . dpa_get_achievement_post_type(), 'edit-tags.php?taxonomy=category&post_type=' . dpa_get_achievement_post_type()); }
/** * Register the achievement event taxonomy * * @since Achievements (3.0) */ public function register_taxonomies() { $labels = $tax = array(); // Event tax labels $labels['event'] = array('add_new_item' => __('Add New Event', 'achievements'), 'all_items' => __('All', 'achievements'), 'edit_item' => __('Edit Event', 'achievements'), 'name' => _x('Events', 'event taxonomy general name', 'achievements'), 'new_item_name' => __('New Event Name', 'achievements'), 'popular_items' => __('Popular Events', 'achievements'), 'search_items' => __('Search Events', 'achievements'), 'singular_name' => _x('Event', 'event taxonomy singular name', 'achievements'), 'update_item' => __('Update Event', 'achievements'), 'view_item' => __('View Event', 'achievements')); // Action filter $tax = apply_filters('dpa_register_taxonomies_action', array('capabilities' => dpa_get_event_caps(), 'hierarchical' => false, 'labels' => $labels['event'], 'public' => false, 'query_var' => false, 'rewrite' => false, 'show_in_nav_menus' => false, 'show_tagcloud' => false, 'show_ui' => dpa_is_developer_mode(), 'update_count_callback' => 'dpa_update_event_term_count')); // Register the achievement event taxonomy register_taxonomy(dpa_get_event_tax_id(), dpa_get_achievement_post_type(), $tax); }
/** * Custom user feedback messages for achievement post type * * @param array $messages * @return array * @since Achievements (3.4) */ function dpa_achievement_feedback_messages($messages) { global $post; // Bail out if we're not on the right screen if (dpa_get_achievement_post_type() !== get_current_screen()->post_type) { return; } $achievement_url = dpa_get_achievement_permalink($post); $post_date = sanitize_post_field('post_date', $post->post_date, $post->ID, 'raw'); $messages[dpa_get_achievement_post_type()] = array(0 => '', 1 => sprintf(__('Achievement updated. <a href="%s">View achievement</a>', 'achievements'), $achievement_url), 2 => __('Custom field updated.', 'achievements'), 3 => __('Custom field deleted.', 'achievements'), 4 => __('Achievement updated.', 'achievements'), 5 => isset($_GET['revision']) ? sprintf(__('Achievement restored to revision from %s', 'achievements'), wp_post_revision_title((int) $_GET['revision'], false)) : false, 6 => sprintf(__('Achievement created. <a href="%s">View achievement</a>', 'achievements'), $achievement_url), 7 => __('Achievement saved.', 'achievements'), 8 => sprintf(__('Achievement submitted. <a target="_blank" href="%s">Preview achievement</a>', 'achievements'), esc_url(add_query_arg('preview', 'true', $achievement_url))), 9 => sprintf(__('Achievement scheduled for: <strong>%1$s</strong>. <a target="_blank" href="%2$s">Preview achievement</a>', 'achievements'), date_i18n(__('M j, Y @ G:i', 'achievements'), strtotime($post_date)), $achievement_url), 10 => sprintf(__('Achievement draft updated. <a target="_blank" href="%s">Preview topic</a>', 'achievements'), esc_url(add_query_arg('preview', 'true', $achievement_url)))); return $messages; }
/** * Display the contents of a specific achievement ID in an output buffer * and return to ensure that post/page contents are displayed first. * * @param array $attr * @param string $content Optional * @return string Contents of output buffer * @since Achievements (3.0) */ public function display_achievement($attr, $content = '') { // Sanity check required info if (!empty($content) || (empty($attr['id']) || !is_numeric($attr['id']))) { return $content; } $this->unset_globals(); // Set passed attribute to $achievement_id for clarity $achievement_id = achievements()->current_achievement_id = absint($attr['id']); // Bail if ID passed is not an achievement if (!dpa_is_achievement($achievement_id)) { return $content; } // If not in theme compat, reset necessary achievement_query attributes for achievements loop to function if (!dpa_is_theme_compat_active()) { achievements()->achievement_query->query_vars['post_type'] = dpa_get_achievement_post_type(); achievements()->achievement_query->in_the_loop = true; achievements()->achievement_query->post = get_post($achievement_id); } $this->start('dpa_single_achievement'); dpa_get_template_part('content-single-achievement'); return $this->end(); }
/** * Return the achievement archive title * * @param string $title Optional. Default text to use as title * @return string The achievement archive title * @since Achievements (3.0) */ function dpa_get_achievement_archive_title($title = '') { // If no title was passed if (empty($title)) { // Set root text to page title $page = dpa_get_page_by_path(dpa_get_root_slug()); if (!empty($page)) { $title = get_the_title($page->ID); // Default to achievement post type name label } else { $pto = get_post_type_object(dpa_get_achievement_post_type()); $title = $pto->labels->name; } } return apply_filters('dpa_get_achievement_archive_title', $title); }
/** * Reset main query vars and filter 'the_content' to output an Achievements template part as needed. * * @param string $template Optional * @since Achievements (3.0) */ function dpa_template_include_theme_compat($template = '') { // Bail if a root template was already found. This prevents unintended recursive filtering of 'the_content'. if (dpa_is_template_included()) { return $template; } // Bail if shortcodes are unset somehow if (!is_a(achievements()->shortcodes, 'DPA_Shortcodes')) { return $template; } // Achievements archive if (dpa_is_achievement_archive()) { // Page exists where this archive should be $page = dpa_get_page_by_path(dpa_get_root_slug()); // Should we replace the content... if (empty($page->post_content)) { $new_content = achievements()->shortcodes->display_achievements_index(); // ...or use the existing page content? } else { $new_content = apply_filters('the_content', $page->post_content); } // Should we replace the title... if (empty($page->post_title)) { $new_title = dpa_get_achievement_archive_title(); // ...or use the existing page title? } else { $new_title = apply_filters('the_title', $page->post_title); } dpa_theme_compat_reset_post(array('comment_status' => 'closed', 'ID' => !empty($page->ID) ? $page->ID : 0, 'is_archive' => true, 'post_author' => 0, 'post_content' => $new_content, 'post_date' => 0, 'post_status' => 'publish', 'post_title' => $new_title, 'post_type' => dpa_get_achievement_post_type())); // Single Achievement } elseif (dpa_is_single_achievement()) { dpa_theme_compat_reset_post(array('comment_status' => 'closed', 'ID' => dpa_get_achievement_id(), 'is_single' => true, 'post_author' => dpa_get_achievement_author_id(), 'post_content' => achievements()->shortcodes->display_achievement(array('id' => dpa_get_achievement_id())), 'post_date' => 0, 'post_status' => 'publish', 'post_title' => dpa_get_achievement_title(), 'post_type' => dpa_get_achievement_post_type())); // Single user's achievements template } elseif (dpa_is_single_user_achievements()) { dpa_theme_compat_reset_post(array('comment_status' => 'closed', 'ID' => 0, 'is_archive' => true, 'post_author' => 0, 'post_content' => achievements()->shortcodes->display_user_achievements(), 'post_date' => 0, 'post_status' => 'publish', 'post_title' => sprintf(_x("%s's achievements", 'possesive noun', 'achievements'), get_the_author_meta('display_name', dpa_get_displayed_user_id())), 'post_type' => dpa_get_achievement_post_type())); } /** * Bail if the template already matches an Achievements template. This includes * archive-* and single-* WordPress post_type matches (allowing themes to use the * expected format) as well as all other Achievements-specific template files. */ if (dpa_is_template_included()) { return $template; /** * If we are relying on Achievements' built-in theme compatibility to load * the proper content, we need to intercept the_content, replace the * output, and display ours instead. * * To do this, we first remove all filters from 'the_content' and hook * our own function into it, which runs a series of checks to determine * the context, and then uses the built in shortcodes to output the * correct results from inside an output buffer. * * Uses dpa_get_theme_compat_templates() to provide fall-backs that * should be coded without superfluous mark-up and logic (prev/next * navigation, comments, date/time, etc...) * * Hook into the 'dpa_get_achievements_template' to override the array of * possible templates, or 'dpa_achievements_template' to override the result. */ } elseif (dpa_is_theme_compat_active()) { dpa_remove_all_filters('the_content'); $template = dpa_get_theme_compat_templates(); } return apply_filters('dpa_template_include_theme_compat', $template); }