/** * Possibly intercept the template being loaded * * Listens to the 'template_include' filter and waits for any Achievements specific * template condition to be met. If one is met and the template file exists it will be used. * * @param string $template Optional. * @return string The path to the template file that is being used * @see dpa_template_include_theme_compat() * @since Achievements (3.0) */ function dpa_template_include_theme_supports($template = '') { // Single achievement if (dpa_is_single_achievement() && ($new_template = dpa_get_single_achievement_template())) { // Achievement archive } elseif (dpa_is_achievement_archive() && ($new_template = dpa_get_achievement_archive_template())) { // User achievements page } elseif (dpa_is_single_user_achievements() && ($new_template = dpa_get_single_user_achievements_template())) { } // An Achievements template file was located, so override the WordPress template, and use it to switch off Achievements' theme compatibility. if (!empty($new_template)) { $template = dpa_set_template_included($new_template); } return apply_filters('dpa_template_include_theme_supports', $template); }
/** * The achievement post type loop. * * Most of the values that $args can accept are documented in {@link WP_Query}. The custom * values added by Achievements are as follows: * * 'ach_event' - string - Loads achievements for a specific event. Matches a slug from the dpa_event tax. Default is empty. * 'ach_populate_progress' - bool|int - Populate a user/users' progress for the results. * - bool: True - uses the logged in user (default). False - don't fetch progress. * - int: pass a user ID (single user). * 'ach_progress_status' - array - array: Post status IDs for the Progress post type. * * @param array|string $args All the arguments supported by {@link WP_Query}, and some more. * @return bool Returns true if the query has any results to loop over * @since Achievements (1.0) */ function dpa_has_achievements($args = array()) { // If multisite and running network-wide, switch_to_blog to the data store site if (is_multisite() && dpa_is_running_networkwide()) { switch_to_blog(DPA_DATA_STORE); } $default_post_parent = dpa_is_single_achievement() ? dpa_get_achievement_id() : 'any'; $default_progress_status = dpa_is_single_user_achievements() ? array(dpa_get_unlocked_status_id()) : array(dpa_get_locked_status_id(), dpa_get_unlocked_status_id()); $defaults = array('ignore_sticky_posts' => true, 'order' => 'ASC', 'orderby' => 'title', 'max_num_pages' => false, 'paged' => dpa_get_paged(), 'perm' => 'readable', 'post_parent' => $default_post_parent, 'post_type' => dpa_get_achievement_post_type(), 'posts_per_page' => dpa_get_achievements_per_page(), 'ach_progress_status' => $default_progress_status, 's' => !empty($_GET['achievements']) ? wp_unslash($_GET['achievements']) : '', 'ach_event' => '', 'ach_populate_progress' => false); // Load achievements for a specific event if (!empty($args['ach_event'])) { $args['tax_query'] = array(array('field' => 'slug', 'taxonomy' => dpa_get_event_tax_id(), 'terms' => $args['ach_event'])); unset($args['ach_event']); } $args = dpa_parse_args($args, $defaults, 'has_achievements'); extract($args); // Run the query achievements()->achievement_query = new WP_Query($args); // User to popular progress for $progress_user_ids = false; if (isset($args['ach_populate_progress'])) { if (true === $args['ach_populate_progress']) { if (dpa_is_single_user_achievements()) { $progress_user_ids = dpa_get_displayed_user_id(); } elseif (is_user_logged_in()) { $progress_user_ids = get_current_user_id(); } } else { $progress_user_ids = (int) $args['ach_populate_progress']; } } // If no limit to posts per page, set it to the current post_count if (-1 === $posts_per_page) { $posts_per_page = achievements()->achievement_query->post_count; } // Add pagination values to query object achievements()->achievement_query->posts_per_page = $posts_per_page; achievements()->achievement_query->paged = $paged; // Only add pagination if query returned results if (((int) achievements()->achievement_query->post_count || (int) achievements()->achievement_query->found_posts) && (int) achievements()->achievement_query->posts_per_page) { // Limit the number of achievements shown based on maximum allowed pages if (!empty($max_num_pages) && achievements()->achievement_query->found_posts > achievements()->achievement_query->max_num_pages * achievements()->achievement_query->post_count) { achievements()->achievement_query->found_posts = achievements()->achievement_query->max_num_pages * achievements()->achievement_query->post_count; } // If pretty permalinks are enabled, make our pagination pretty if ($GLOBALS['wp_rewrite']->using_permalinks()) { // Page or single post if (is_page() || is_single()) { $base = get_permalink(); } elseif (dpa_is_achievement_archive()) { $base = dpa_get_achievements_url(); } else { $base = get_permalink($post_parent); } // Use pagination base $base = trailingslashit($base) . user_trailingslashit($GLOBALS['wp_rewrite']->pagination_base . '/%#%/'); // Unpretty pagination } else { $base = add_query_arg('paged', '%#%'); } // Pagination settings with filter $achievement_pagination = apply_filters('dpa_achievement_pagination', array('base' => $base, 'current' => (int) achievements()->achievement_query->paged, 'format' => '', 'mid_size' => 1, 'next_text' => is_rtl() ? '←' : '→', 'prev_text' => is_rtl() ? '→' : '←', 'total' => $posts_per_page == achievements()->achievement_query->found_posts ? 1 : ceil((int) achievements()->achievement_query->found_posts / (int) $posts_per_page))); // Add pagination to query object achievements()->achievement_query->pagination_links = paginate_links($achievement_pagination); // Remove first page from pagination achievements()->achievement_query->pagination_links = str_replace($GLOBALS['wp_rewrite']->pagination_base . "/1/'", "'", achievements()->achievement_query->pagination_links); } // Populate extra progress information for the achievements if (!empty($progress_user_ids) && achievements()->achievement_query->have_posts()) { $progress_post_ids = wp_list_pluck((array) achievements()->achievement_query->posts, 'ID'); // Args for progress query $progress_args = array('author' => $progress_user_ids, 'no_found_rows' => true, 'post_parent' => $progress_post_ids, 'post_status' => $args['ach_progress_status'], 'posts_per_page' => -1); // Run the query dpa_has_progress($progress_args); } // If multisite and running network-wide, undo the switch_to_blog if (is_multisite() && dpa_is_running_networkwide()) { restore_current_blog(); } return apply_filters('dpa_has_achievements', achievements()->achievement_query->have_posts()); }
/** * Add checks for Achievements conditions to parse_query action * * @param WP_Query $posts_query * @since Achievements (3.0) */ function dpa_parse_query(WP_Query $posts_query) { // Bail if not the main loop, if filters are suppressed, or if in WP admin. if (!$posts_query->is_main_query() || true === $posts_query->get('suppress_filters') || is_admin()) { return; } // Set the per-page pagination value the same as the dpa_has_achievements() template loop's setting. if (dpa_is_achievement_archive()) { $posts_query->set('posts_per_page', dpa_get_achievements_per_page()); } }
/** * Enqueue the required Javascript files * * @since Achievements (3.0) */ public function enqueue_scripts() { // If user's not active or is inside the WordPress Admin, bail out. if (!dpa_is_user_active() || is_admin() || is_404() || is_preview()) { return; } /** * Core JS */ $file = 'js/achievements.js'; // Check child theme if (file_exists(trailingslashit(get_stylesheet_directory()) . $file)) { $location = trailingslashit(get_stylesheet_directory_uri()); $handle = 'dpa-child-javascript'; // Check parent theme } elseif (file_exists(trailingslashit(get_template_directory()) . $file)) { $location = trailingslashit(get_template_directory_uri()); $handle = 'dpa-parent-javascript'; // Achievements theme compatibility } else { $location = trailingslashit(dpa_get_theme_compat_url()); $handle = 'dpa-default-javascript'; } wp_enqueue_script($handle, $location . $file, array('heartbeat', 'underscore', 'wp-util'), dpa_get_theme_compat_version(), 'screen', true); /** * Third-party JS */ if (dpa_is_achievement_archive()) { wp_enqueue_script('masonry'); } }
/** * Custom page title for Achievements pages * * @param string $title Optional. The title (not used). * @param string $sep Optional, default is '»'. How to separate each part within the page title. * @param string $seplocation Optional. Direction to display title, 'right'. * @return string The title * @since Achievements (3.0) */ function dpa_title($title = '', $sep = '»', $seplocation = '') { $new_title = array(); // Achievement archive if (dpa_is_achievement_archive()) { $new_title['text'] = dpa_get_achievement_archive_title(); // Single achievement page } elseif (dpa_is_single_achievement()) { $new_title['text'] = dpa_get_achievement_title(); $new_title['format'] = esc_attr__('Achievement: %s', 'achievements'); } $new_title = apply_filters('dpa_raw_title_array', $new_title); $new_title = dpa_parse_args($new_title, array('format' => '%s', 'text' => $title), 'title'); // Get the formatted raw title $new_title = sprintf($new_title['format'], $new_title['text']); $new_title = apply_filters('dpa_raw_title', $new_title, $sep, $seplocation); // Compare new title with original title if ($new_title === $title) { return $title; } // Temporary separator for accurate flipping, if necessary $t_sep = '%WP_TITILE_SEP%'; $prefix = ''; if (!empty($new_title)) { $prefix = " {$sep} "; } // Separate on right, so reverse the order if ('right' === $seplocation) { $new_title_array = explode($t_sep, $new_title); $new_title_array = array_reverse($new_title_array); $new_title = implode(" {$sep} ", $new_title_array) . $prefix; // Separate on left, do not reverse } else { $new_title_array = explode($t_sep, $new_title); $new_title = $prefix . implode(" {$sep} ", $new_title_array); } // Filter and return return apply_filters('dpa_title', $new_title, $sep, $seplocation); }
/** * 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); }