/** * Root slug field. * * @since Achievements (3.6) */ function dpa_admin_setting_callback_root_slug() { ?> <input name="_dpa_root_slug" id="_dpa_root_slug" type="text" class="regular-text code" value="<?php echo esc_attr(dpa_get_root_slug()); ?> "<?php dpa_maybe_admin_setting_disabled('_dpa_root_slug'); ?> required /> <?php }
/** * Return the achievement post type slug * * This is just a wrapper function for dpa_get_root_slug() right now. * * @return string * @since Achievements (3.0) */ function dpa_get_achievement_slug() { return apply_filters('dpa_get_achievement_slug', dpa_get_root_slug()); }
/** * 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); }
/** * 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); }
/** * Set up the post types for: achievement, achievement_progress * * @since Achievements (3.0) */ public function register_post_types() { $cpt = $labels = $rewrite = $supports = array(); /** * If the plugin's been activated network-wide, only allow the normal access and behaviour on the DPA_DATA_STORE site. * This prevents the admin controls showing up on the wrong site's wp-admin, as well as the overhead of unused rewrite rules. * * The problem with this is that the post type needs to be registered all on sites in a multisite all the time, otherwise * achievements can't be awarded. See _update_blog_date_on_post_publish() which tries to create (in our case) a * "dpa-progress" post. * * The solution to this is $post_type_is_public. If it's false, the post type is registered, but it's hidden from the admin, * isn't publicly queryable, doesn't create rewrite rules, and so on. If it's set to true, the post type behaves as normal. */ $post_type_is_public = is_multisite() && dpa_is_running_networkwide() && get_current_blog_id() !== DPA_DATA_STORE ? false : true; // CPT labels $labels['achievement'] = array('add_new' => _x('Add New', 'achievement', 'achievements'), 'add_new_item' => __('Add New Achievement', 'achievements'), 'all_items' => __('All Achievements', 'achievements'), 'edit' => _x('Edit', 'achievement', 'achievements'), 'edit_item' => __('Edit Achievement', 'achievements'), 'menu_name' => __('Achievements', 'achievements'), 'name' => __('Achievements', 'achievements'), 'new_item' => __('New Achievement', 'achievements'), 'not_found' => __('No achievements found.', 'achievements'), 'not_found_in_trash' => __('No achievements found in Trash.', 'achievements'), 'search_items' => __('Search Achievements', 'achievements'), 'singular_name' => __('Achievement', 'achievements'), 'view' => __('View Achievement', 'achievements'), 'view_item' => __('View Achievement', 'achievements')); // CPT rewrite $rewrite['achievement'] = array('ep_mask' => 0, 'feed' => false, 'feeds' => false, 'pages' => true, 'slug' => dpa_get_singular_root_slug(), 'with_front' => false); // CPT supports $supports['achievement'] = array('editor', 'excerpt', 'revisions', 'thumbnail', 'title'); $supports['achievement_progress'] = array('author'); // CPT filter $cpt['achievement'] = apply_filters('dpa_register_post_type_achievement', array('capabilities' => dpa_get_achievement_caps(), 'capability_type' => array('achievement', 'achievements'), 'delete_with_user' => false, 'description' => _x('Achievements types (e.g. new post, new site, new user)', 'Achievement post type description', 'achievements'), 'has_archive' => $post_type_is_public ? dpa_get_root_slug() : false, 'labels' => $labels['achievement'], 'public' => $post_type_is_public, 'rewrite' => $rewrite['achievement'], 'register_meta_box_cb' => 'dpa_admin_setup_metaboxes', 'show_in_menu' => $post_type_is_public, 'show_ui' => dpa_current_user_can_see(dpa_get_achievement_post_type()), 'supports' => $supports['achievement'], 'taxonomies' => array('category'))); $cpt['achievement_progress'] = apply_filters('dpa_register_post_type_achievement_progress', array('capabilities' => dpa_get_achievement_progress_caps(), 'capability_type' => array('achievement_progress', 'achievement_progresses'), 'delete_with_user' => true, 'description' => _x('Achievement Progress (e.g. unlocked achievements for a user, progress on an achievement for a user)', 'Achievement Progress post type description', 'achievements'), 'public' => false, 'query_var' => false, 'rewrite' => false, 'supports' => $supports['achievement_progress'])); // Register Achievement post type register_post_type(dpa_get_achievement_post_type(), $cpt['achievement']); // Register Achievement Progress post type register_post_type(dpa_get_progress_post_type(), $cpt['achievement_progress']); }
/** * 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); }