/** * Display for the shortcode [related_posts_by_tax] * * @since 0.1 * * @uses km_rpbt_related_posts_by_taxonomy() * @uses km_rpbt_related_posts_by_taxonomy_template() * * @param string $rpbt_args Attributes used by the shortcode * @return string Related posts html or empty string */ function km_rpbt_related_posts_by_taxonomy_shortcode($rpbt_args) { /* for filter recursion (infinite loop) */ static $recursing = false; if (!$recursing) { $recursing = true; } else { return ''; } $plugin_defaults = Related_Posts_By_Taxonomy_Defaults::get_instance(); $defaults = array('post_id' => '', 'taxonomies' => $plugin_defaults->all_tax, 'before_shortcode' => '<div class="rpbt_shortcode">', 'after_shortcode' => '</div>', 'before_title' => '<h3>', 'after_title' => '</h3>', 'title' => __('Related Posts', 'related-posts-by-taxonomy'), 'format' => 'links', 'image_size' => 'thumbnail', 'columns' => 3, 'caption' => 'post_title', 'post_types' => '', 'posts_per_page' => 5, 'order' => 'DESC', 'limit_posts' => -1, 'limit_year' => '', 'limit_month' => '', 'orderby' => 'post_date', 'exclude_terms' => '', 'include_terms' => '', 'exclude_posts' => '', 'related' => ''); /** * Set new default attributes. * * @since 0.2.1 * * @param array $defaults See $defaults above */ $defaults = apply_filters('related_posts_by_taxonomy_shortcode_defaults', $defaults); /* Can be filtered in WordPress > 3.5 (hook: shortcode_atts_related_posts_by_tax) */ $rpbt_args = shortcode_atts($defaults, $rpbt_args, 'related_posts_by_tax'); /** * Filter defaults. * * @param array $rpbt_args See $defaults above */ $filtered_args = apply_filters('related_posts_by_taxonomy_shortcode_atts', $rpbt_args); /* make sure all defaults are present after filtering */ $rpbt_args = array_merge($rpbt_args, (array) $filtered_args); /* add type for use in templates */ $rpbt_args['type'] = 'shortcode'; $rpbt_args['title'] = trim($rpbt_args['title']); /* validate filtered attributes */ if ('' === trim($rpbt_args['post_id'])) { $rpbt_args['post_id'] = get_the_ID(); } /* if no post type is set use the post type of the current post (new default since 0.3) */ if ('' === trim($rpbt_args['post_types'])) { $post_types = get_post_type($rpbt_args['post_id']); $rpbt_args['post_types'] = $post_types ? $post_types : 'post'; } if ($rpbt_args['taxonomies'] === $plugin_defaults->all_tax) { $rpbt_args['taxonomies'] = array_keys($plugin_defaults->taxonomies); } $rpbt_args['post_thumbnail'] = ''; if ('thumbnails' === $rpbt_args['format']) { $rpbt_args['post_thumbnail'] = 1; } /* public template variables $image_size && $columns (deprecated in version 0.3) */ $image_size = $rpbt_args['image_size']; $columns = absint($rpbt_args['columns']); // convert 'related' string to boolean. $rpbt_args['related'] = '' !== trim($rpbt_args['related']) ? $rpbt_args['related'] : true; $rpbt_args['related'] = filter_var($rpbt_args['related'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); // non boolean used, default to true $rpbt_args['related'] = $rpbt_args['related'] === NULL ? true : $rpbt_args['related']; $function_args = $rpbt_args; /* restricted arguments */ unset($function_args['post_id'], $function_args['taxonomies'], $function_args['fields']); if (isset($rpbt_args['cache']) && $rpbt_args['cache']) { $related_posts = $plugin_defaults->cache->get_related_posts($rpbt_args); } else { /* get related posts */ $related_posts = km_rpbt_related_posts_by_taxonomy($rpbt_args['post_id'], $rpbt_args['taxonomies'], $function_args); } /* clean up variables before calling the template */ unset($plugin_defaults, $defaults, $filtered_args, $post_types, $function_args); /** * Filter whether to hide the widget if no related posts are found. * * @since 0.1 * * @param bool $hide Whether to hide the shortcode if no related posts are found. * Defaults to true. */ $hide_empty = (bool) apply_filters('related_posts_by_taxonomy_shortcode_hide_empty', true); $rpbt_shortcode = $shortcode = ''; if (!$hide_empty || !empty($related_posts)) { /* get the template depending on the format */ $template = km_rpbt_related_posts_by_taxonomy_template($rpbt_args['format'], 'shortcode'); if ($rpbt_args['title']) { $rpbt_args['title'] = $rpbt_args['before_title'] . $rpbt_args['title'] . $rpbt_args['after_title']; } if ($template) { global $post; // used for setup_postdata() in templates ob_start(); require $template; $shortcode = ob_get_clean(); $shortcode = trim($shortcode); wp_reset_postdata(); // clean up global $post variable; } if ($shortcode) { $rpbt_shortcode = $rpbt_args['before_shortcode'] . "\n"; $rpbt_shortcode .= trim($rpbt_args['title']) . "\n"; $rpbt_shortcode .= $shortcode . "\n"; $rpbt_shortcode .= $rpbt_args['after_shortcode']; } } /** * After the related posts are displayed * * @param string Display type, widget or shortcode. */ do_action('related_posts_by_taxonomy_after_display', 'shortcode'); $recursing = false; return trim($rpbt_shortcode); }
/** * Cache related posts * * @since 2.1.0 * @param array $args Widget or shortcode args * @return array Array with related post objects that are cached. */ private function set_cache($args) { $function_args = $this->get_function_args($args); $key = $this->get_post_meta_key($args); // Add a filter to get the function arguments for the current post add_filter('related_posts_by_taxonomy', array($this, 'current_post'), 99, 4); // Get related posts $posts = km_rpbt_related_posts_by_taxonomy($args['post_id'], $args['taxonomies'], $function_args); // Remove the filter remove_filter('related_posts_by_taxonomy', array($this, 'current_post'), 99, 4); // Create the array with cached post ids, and add the related term count. $posts_arr = array(); foreach ($posts as $post) { $posts_arr[$post->ID] = isset($post->termcount) ? $post->termcount : 0; } // Add the properties used in the related_posts_by_taxonomy filter. if (!empty($posts_arr)) { $posts_arr['rpbt_current']['taxonomies'] = $args['taxonomies']; $posts_arr['rpbt_current']['post_id'] = $args['post_id']; if (isset($this->current['related_terms'])) { $posts_arr['rpbt_current']['related_terms'] = $this->current['related_terms']; } } // Reset current arguments. $this->current = array(); // Cache the post ids. update_post_meta($args['post_id'], $key, $posts_arr); return $posts; }
/** * Displays the related posts on the front end. * * @since 0.1 */ function widget($rpbt_widget_args, $rpbt_args) { $i = $rpbt_args; $i = $this->validate_instance($i); /* don't show widget on pages other than single if singular_template is set */ if ($i['singular_template'] && !is_singular()) { return; } if (empty($i['post_id'])) { $i['post_id'] = $this->get_the_ID(); } if (!empty($i['post_types'])) { $i['post_types'] = array_keys($i['post_types']); } /* added in 2.0 */ if ($i['random']) { unset($i['random']); $i['order'] = 'RAND'; } /* Added in 0.3 (not part of the widget settings). Can be filtered below */ $i['caption'] = 'post_title'; /** * Filter widget arguments to get the related posts. * * @since 0.1 * * @param string $i Widget instance. * @param string $rpbt_widget_args Widget arguments. */ $instance_filter = apply_filters('related_posts_by_taxonomy_widget_args', $i, $rpbt_widget_args); $i = array_merge($i, (array) $instance_filter); /* add type for use in templates */ $i['type'] = 'widget'; /* convert "all" to array with all public taxonomies */ if ($i['taxonomies'] === $this->defaults->all_tax) { $i['taxonomies'] = array_keys($this->defaults->taxonomies); } $i['post_thumbnail'] = false; if ('thumbnails' === $i['format']) { $i['post_thumbnail'] = true; } /* public template variables $image_size and $columns (deprecated in version 0.3) */ $image_size = $i['image_size']; $columns = $i['columns']; $function_args = $rpbt_args = $i; /* restricted arguments */ unset($function_args['fields'], $function_args['post_id'], $function_args['taxonomies']); //$cache = class_exists('Related_Posts_By_Taxonomy_Cache'); if (isset($rpbt_args['cache']) && $rpbt_args['cache']) { $related_posts = $this->defaults->cache->get_related_posts($rpbt_args); } else { /* get related posts */ $related_posts = km_rpbt_related_posts_by_taxonomy($rpbt_args['post_id'], $rpbt_args['taxonomies'], $function_args); } /** * Filter whether to hide the widget if no related posts are found. * * @since 0.1 * * @param bool $hide Whether to hide the widget if no related posts are found. * Defaults to true. */ $hide_empty = (bool) apply_filters('related_posts_by_taxonomy_widget_hide_empty', true); if (!$hide_empty || !empty($related_posts)) { /* get the template depending on the format */ $template = km_rpbt_related_posts_by_taxonomy_template((string) $rpbt_args['format'], $rpbt_args['type']); if (!$template) { return; } /* display of the widget */ echo $rpbt_widget_args['before_widget']; $rpbt_args['title'] = apply_filters('widget_title', $rpbt_args['title'], $rpbt_args, $this->id_base); /* show widget title if one was set. */ if ('' !== trim($rpbt_args['title'])) { echo $rpbt_widget_args['before_title'] . $rpbt_args['title'] . $rpbt_widget_args['after_title']; } /* clean up variables before calling the template */ unset($i, $instance_filter, $function_args, $hide_empty); global $post; // used for setup_postdata() in templates require $template; wp_reset_postdata(); // Clean up global $post variable; echo $rpbt_widget_args['after_widget']; } /** * After the related posts are displayed * * @param string Display type, widget or shortcode. */ do_action('related_posts_by_taxonomy_after_display', 'widget'); }