WordPress 获取相关文章

或许有点用,不过只适用与文章类型。

设想是:

  1. 首先获取拥有相同标贴的文章
  2. 如果数量不足,获取拥有部分相同标签的文章
  3. 如果数量还不足,获取拥有相同分类的文章
  4. 再不足,获取部分相同分类的文章

代码大致:

/*
 * class getRelatedPosts
 * get related post by tags and categories
 * $related_posts = new getRelatedPosts($post_id, 3);
 * */

class getRelatedPosts {

	protected $_date;

	public function __construct($post_id, $showposts){
		$this->setDefault($post_id, $showposts);
		$this->_getPosts();
	}

	protected function setDefault($post_id, $showposts){
		$this->_date['post_id']			= $post_id;
		$this->_date['exclude_ids'][] 	= $post_id;
		$this->_date['showposts']		= $showposts;
		$this->_date['args']['post_type']	= 'post';
		$this->_date['posts']	= array();
		$this->_date['post_count']	= 0;
		$this->_getTagIds();
		$this->_updateArgs();
	}

	protected function _updateArgs(){
		$this->_date['args']['post__not_in']	= $this->_date['exclude_ids'];
		$this->_date['args']['posts_per_page']	= $this->_date['showposts'] - $this->_date['post_count'];
	}

	protected function _getTagIds(){
		$posttags = get_the_tags($this->_date['post_id']);
		if ($posttags) {
			foreach($posttags as $tag) {
				$this->_date['tag_ids'][] = $tag->term_id;
			}
		}else{
			$this->_date['tag_ids'] = NULL;
		}
	}

	protected function _getCategoryIds(){
		$categories = get_the_category($this->_date['post_id']);
		if($categories){
			foreach($categories as $category) {
				$this->_date['category_ids'][] = $category->term_id;
			}
		}else{ 
			$this->_date['category_ids'] = NULL;
		}
	}

	protected function _getPosts(){
		if($this->_date['tag_ids'] != NULL){
			//Display posts that are tagged with both tag id 37 and tag id 47
			$this->_date['args']['tag__and'] = $this->_date['tag_ids'];
			$this->_pushPost($this->_date['args']);
				
			//To display posts from either tag id 37 or 47
			if($this->_date['post_count'] < $this->_date['showposts']){
				unset($this->_date['args']['tag__and']);
				$this->_date['args']['tag__in'] = $this->_date['tag_ids'];
				$this->_pushPost($this->_date['args']);
			}
		}

		if($this->_date['post_count'] < $this->_date['showposts']){
			$this->_getCategoryIds();
			if(isset($this->_date['args']['tag__and'])) unset($this->_date['args']['tag__and']);
			if(isset($this->_date['args']['tag__in'])) unset($this->_date['args']['tag__in']);
			//Display posts that are in multiple categories. This shows posts that are in both categories 2 and 6:
			$this->_date['args']['category__and'] = $this->_date['category_ids'];
			$this->_pushPost($this->_date['args']);
		}
		//To display posts from either category 2 OR 6
		if($this->_date['post_count'] < $this->_date['showposts']){
			unset($this->_date['args']['category__and']);
			$this->_date['args']['category__in'] = $this->_date['category_ids'];
			$this->_pushPost($this->_date['args']);
		}
	}

	protected function _pushPost($the_args){
		$the_query = new WP_Query($the_args);
		if ( $the_query->have_posts() ) {
			$this->_date['post_count'] = $this->_date['post_count'] + $the_query->post_count;
			while ( $the_query->have_posts() ) { 
				$the_query->the_post();
				$this->_date['exclude_ids'][] = get_the_ID();
				$this->_date['posts'][get_the_ID()] = array(
						'ID' => get_the_ID(),
						'title' => get_the_title(),
						'link'	=> get_permalink(),
						//'format'	=> get_label_format(get_the_ID()),
						'excerpt'	=> get_the_excerpt()
				);
				$this->_date['posts'][get_the_ID()]['date'] = get_the_date(__('F j, Y'));
			}
			$this->_updateArgs();
		}
		wp_reset_postdata();
	}

	public function getPosts(){
		return $this->_date['posts'];
	}

	public function get_date(){
		print_r($this->_date);
	}
}