PageRenderTime 919ms CodeModel.GetById 415ms app.highlight 360ms RepoModel.GetById 74ms app.codeStats 1ms

/wp-content/plugins/simple-tags/inc/class.client.related_posts.php

https://bitbucket.org/Wallynm/iptb
PHP | 414 lines | 296 code | 52 blank | 66 comment | 71 complexity | 795f1cdeab22617bde383ca503f6ae8c MD5 | raw file
  1<?php
  2class SimpleTags_Client_RelatedPosts extends SimpleTags_Client {
  3	/**
  4	 * Constructor
  5	 *
  6	 * @return void
  7	 * @author Amaury Balmer
  8	 */
  9	function SimpleTags_Client_RelatedPosts() {
 10		// Get options
 11		$options = get_option( STAGS_OPTIONS_NAME );
 12		
 13		// Add related posts in post ( all / feedonly / blogonly / homeonly / singularonly / singleonly / pageonly /no )
 14		if ( (isset($options['rp_embedded']) && $options['rp_embedded'] != 'no') || (isset($options['rp_feed']) && $options['rp_feed'] == 1) ) {
 15			add_filter('the_content', array(&$this, 'inlineRelatedPosts'), 999993);
 16		}
 17	}
 18	
 19	/**
 20	 * Auto add related posts to post content
 21	 *
 22	 * @param string $content
 23	 * @return string
 24	 */
 25	function inlineRelatedPosts( $content = '' ) {
 26		// Get options
 27		$options = get_option( STAGS_OPTIONS_NAME );
 28		
 29		$marker = false;
 30		if ( is_feed() ) {
 31			if ( $options['rp_feed'] == '1' ) {
 32				$marker = true;
 33			}
 34		} elseif ( isset($options['rp_embedded']) ) {
 35			switch ( $options['rp_embedded'] ) {
 36				case 'blogonly' :
 37					$marker = ( is_feed() ) ? false : true;
 38					break;
 39				case 'homeonly' :
 40					$marker = ( is_home() ) ? true : false;
 41					break;
 42				case 'singularonly' :
 43					$marker = ( is_singular() ) ? true : false;
 44					break;
 45				case 'singleonly' :
 46					$marker = ( is_single() ) ? true : false;
 47					break;
 48				case 'pageonly' :
 49					$marker = ( is_page() ) ? true : false;
 50					break;
 51				case 'all' :
 52					$marker = true;
 53					break;
 54				case 'no' :
 55				default:
 56					$marker = false;
 57					break;
 58			}
 59		}
 60		
 61		if ( $marker === true ) {
 62			return ( $content . $this->relatedPosts( '', false ) );
 63		}
 64		return $content;
 65	}
 66	
 67	/**
 68	 * Generate related posts
 69	 *
 70	 * @param string $user_args
 71	 * @return string|array
 72	 */
 73	function relatedPosts( $user_args = '', $copyright = true ) {
 74		global $wpdb;
 75		
 76		// Get options
 77		$options = get_option( STAGS_OPTIONS_NAME );
 78		
 79		$defaults = array(
 80			'taxonomy' => 'post_tag',
 81			'post_type' => 'post',
 82			'number' => 5,
 83			'order' => 'count-desc',
 84			'format' => 'list',
 85			'separator' => '',
 86			'include_page' => 'true',
 87			'exclude_posts' => '',
 88			'exclude_terms' => '',
 89			'post_id' => 0,
 90			'excerpt_wrap' => 55,
 91			'limit_days' => 0,
 92			'min_shared' => 1,
 93			'title' => __('<h4>Related posts</h4>', 'simpletags'),
 94			'nopoststext' => __('No related posts.', 'simpletags'),
 95			'dateformat' => get_option('date_format'),
 96			'xformat' => __('<a href="%post_permalink%" title="%post_title% (%post_date%)">%post_title%</a> (%post_comment%)', 'simpletags')
 97		);
 98		
 99		// Get values in DB
100		$defaults['number'] 		= $options['rp_limit_qty'];
101		$defaults['order'] 			= $options['rp_order'];
102		$defaults['nopoststext'] 	= $options['rp_notagstext'];
103		$defaults['title'] 			= $options['rp_title'];
104		$defaults['xformat'] 		= $options['rp_xformat'];
105		$defaults['taxonomy'] 		= $options['rp_taxonomy'];
106		
107		if( empty($user_args) ) {
108			$user_args = $options['rp_adv_usage'];
109		}
110		
111		// Replace old markers by new
112		$markers = array('%date%' => '%post_date%', '%permalink%' => '%post_permalink%', '%title%' => '%post_title%', '%commentcount%' => '%post_comment%', '%tagcount%' => '%post_tagcount%', '%postid%' => '%post_id%');
113		if ( !is_array($user_args) )
114			$user_args = strtr($user_args, $markers);
115		
116		$args = wp_parse_args( $user_args, $defaults );
117		extract($args);
118		
119		// If empty use default xformat !
120		if ( empty($xformat) ) {
121			$xformat = $defaults['xformat'];
122		}
123		
124		// Clean memory
125		$args = array();
126		$defaults = array();
127		
128		// Get current post data
129		$object_id = (int) $post_id;
130		if ( $object_id == 0 ) {
131			global $post;
132			$object_id = (int) $post->ID;
133			if ( $object_id == 0 ) {
134				return false;
135			}
136		}
137		
138		// Get cache if exist
139		$results = false;
140		// Generate key cache
141		$key = md5(maybe_serialize($user_args).'-'.$object_id);
142		
143		if ( $cache = wp_cache_get( 'related_posts'.$taxonomy, 'simpletags' ) ) {
144			if ( isset( $cache[$key] ) ) {
145				$results = $cache[$key];
146			}
147		}
148		
149		// If cache not exist, get datas and set cache
150		if ( $results === false || $results === null ) {
151			// Get get tags
152			$current_terms = get_the_terms( (int) $object_id, $taxonomy );
153			
154			if ( $current_terms == false || is_wp_error($current_terms) ) {
155				return $this->outputContent( 'st-related-posts', $format, $title, $nopoststext, $copyright );
156			}
157			
158			// Number - Limit
159			$number = (int) $number;
160			if ( $number == 0 ) {
161				$number = 5;
162			} elseif( $number > 50 ) {
163				$number = 50;
164			}
165			$limit_sql = 'LIMIT 0, '.$number;
166			unset($number);
167			
168			// Order tags before output (count-asc/count-desc/date-asc/date-desc/name-asc/name-desc/random)
169			$order_by = '';
170			$order = strtolower($order);
171			switch ( $order ) {
172				case 'count-asc':
173					$order_by = 'counter ASC, p.post_title DESC';
174					break;
175				case 'random':
176					$order_by = 'RAND()';
177					break;
178				case 'date-asc':
179					$order_by = 'p.post_date ASC';
180					break;
181				case 'date-desc':
182					$order_by = 'p.post_date DESC';
183					break;
184				case 'name-asc':
185					$order_by = 'p.post_title ASC';
186					break;
187				case 'name-desc':
188					$order_by = 'p.post_title DESC';
189					break;
190				default: // count-desc
191				$order_by = 'counter DESC, p.post_title DESC';
192				break;
193			}
194			
195			// Limit days - 86400 seconds = 1 day
196			$limit_days = (int) $limit_days;
197			$limit_days_sql = '';
198			if ( $limit_days != 0 ) {
199				$limit_days_sql = 'AND p.post_date > "' .date( 'Y-m-d H:i:s', time() - $limit_days * 86400 ). '"';
200			}
201			unset($limit_days);
202			
203			// Make array post type
204			if ( is_string($post_type) ) {
205				$post_type = explode(',', $post_type);
206			}
207			
208			// Include_page
209			$include_page = strtolower($include_page);
210			if ( $include_page == 'true' ) {
211				$post_type[] = 'page';
212			}
213			unset($include_page);
214			
215			// Build post type SQL
216			$restrict_sql = "AND p.post_type IN ('".implode("', '", $post_type)."')";
217			
218			// Restrict posts
219			$exclude_posts_sql = '';
220			if ( $exclude_posts != '' ) {
221				$exclude_posts = (array) explode(',', $exclude_posts);
222				$exclude_posts = array_unique($exclude_posts);
223				$exclude_posts_sql = "AND p.ID NOT IN (";
224				foreach ( $exclude_posts as $value ) {
225					$value = (int) $value;
226					if( $value > 0 && $value != $object_id ) {
227						$exclude_posts_sql .= '"'.$value.'", ';
228					}
229				}
230				$exclude_posts_sql .= '"'.$object_id.'")';
231			} else {
232				$exclude_posts_sql = "AND p.ID <> {$object_id}";
233			}
234			unset($exclude_posts);
235			
236			// Restricts tags
237			$terms_to_exclude = array();
238			if ( $exclude_terms != '' ) {
239				$exclude_terms = (array) explode(',', $exclude_terms);
240				$exclude_terms = array_unique($exclude_terms);
241				foreach ( $exclude_terms as $value ) {
242					$terms_to_exclude[] = trim($value);
243				}
244			}
245			unset($exclude_terms);
246			
247			// SQL Terms list
248			$term_list = array();
249			foreach ( (array) $current_terms as $term ) {
250				if ( !in_array($term->name, $terms_to_exclude) ) {
251					$term_list[] = '"'.(int) $term->term_id.'"';
252				}
253			}
254			$term_list = implode(', ', $term_list);
255			
256			// Build SQL terms subqueries array
257			$include_terms_sql = array();
258			if ( !empty($term_list) ) {
259				$include_terms_sql[$taxonomy] = $term_list;
260			}
261			
262			// Group Concat check if post_relatedtags is used by xformat...
263			$select_gp_concat = '';
264			if ( strpos($xformat,'%post_relatedtags%') || $min_shared > 1 ) {
265				$select_gp_concat = ', GROUP_CONCAT(tt.term_id) as terms_id';
266			}
267			
268			// Check if post_excerpt is used by xformat...
269			$select_excerpt = '';
270			if ( strpos( $xformat, '%post_excerpt%' ) ) {
271				$select_excerpt = ', p.post_content, p.post_excerpt, p.post_password';
272			}
273			
274			// If empty return no posts text
275			if ( empty($include_terms_sql) ) {
276				return $this->outputContent( 'st-related-posts', $format, $title, $nopoststext, $copyright );
277			}
278			
279			// Posts: title, comments_count, date, permalink, post_id, counter
280			$results = $wpdb->get_results("
281				SELECT p.post_title, p.comment_count, p.post_date, p.ID, COUNT(tr.object_id) AS counter {$select_excerpt} {$select_gp_concat}
282				FROM {$wpdb->posts} AS p
283				INNER JOIN {$wpdb->term_relationships} AS tr ON (p.ID = tr.object_id)
284				INNER JOIN {$wpdb->term_taxonomy} AS tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)
285				WHERE 1 = 1
286				AND (tt.taxonomy = '{$taxonomy}' AND tt.term_id IN ({$term_list}))
287				{$exclude_posts_sql}
288				AND p.post_status = 'publish'
289				AND p.post_date_gmt < '".current_time('mysql')."'
290				{$limit_days_sql}
291				{$restrict_sql}
292				GROUP BY tr.object_id
293				ORDER BY {$order_by}
294				{$limit_sql}");
295			
296			$cache[$key] = $results;
297			wp_cache_set('related_posts'.$taxonomy, $cache, 'simpletags');
298		}
299		
300		if ( $format == 'object' || $format == 'array' ) {
301			return $results;
302		} elseif ( $results === false || empty($results) ) {
303			return $this->outputContent( 'st-related-posts', $format, $title, $nopoststext, $copyright );
304		}
305		
306		if ( empty($dateformat) ) {
307			$dateformat = get_option('date_format');
308		}
309		
310		$output = array();
311		// Replace placeholders
312		foreach ( (array) $results as $result ) {
313			if ( ( $min_shared > 1 && ( count(explode(',', $result->terms_id)) < $min_shared ) ) || !is_object($result) ) {
314				continue;
315			}
316			
317			$element_loop = $xformat;
318			$post_title = apply_filters( 'the_title', $result->post_title );
319			$element_loop = str_replace('%post_date%', mysql2date($dateformat, $result->post_date), $element_loop);
320			$element_loop = str_replace('%post_permalink%', get_permalink($result->ID), $element_loop);
321			$element_loop = str_replace('%post_title%', $post_title, $element_loop);
322			$element_loop = str_replace('%post_title_attribute%', esc_html(strip_tags($post_title)), $element_loop);
323			$element_loop = str_replace('%post_comment%', (int) $result->comment_count, $element_loop);
324			$element_loop = str_replace('%post_tagcount%', (int) $result->counter, $element_loop);
325			$element_loop = str_replace('%post_id%', $result->ID, $element_loop);
326			
327			if ( isset($result->terms_id) )
328				$element_loop = str_replace('%post_relatedtags%', $this->getTagsFromID($result->terms_id, $taxonomy), $element_loop);
329				
330			if ( isset($result->post_excerpt) || isset($result->post_content) )
331				$element_loop = str_replace('%post_excerpt%', $this->getExcerptPost( $result->post_excerpt, $result->post_content, $result->post_password, $excerpt_wrap ), $element_loop);
332				
333			$output[] = $element_loop;
334		}
335		
336		// Clean memory
337		$results = array();
338		unset($results, $result);
339		
340		return $this->outputContent( 'st-related-posts', $format, $title, $output, $copyright, $separator );
341	}
342	
343	/**
344	 * Build excerpt from post data with specific lenght
345	 *
346	 * @param string $excerpt 
347	 * @param string $content 
348	 * @param string $password 
349	 * @param integer $excerpt_length 
350	 * @return string
351	 * @author Amaury Balmer
352	 */
353	function getExcerptPost( $excerpt = '', $content = '', $password = '', $excerpt_length = 55 ) {
354		if ( !empty($password) ) { // if there's a password
355			if ( $_COOKIE['wp-postpass_'.COOKIEHASH] != $password ) { // and it doesn't match the cookie
356				return __('There is no excerpt because this is a protected post.', 'simpletags');
357			}
358		}
359		
360		if ( !empty($excerpt) ) {
361			return apply_filters('get_the_excerpt', $excerpt);
362		} else { // Fake excerpt
363			$content = str_replace(']]>', ']]&gt;', $content);
364			$content = strip_tags($content);
365			
366			$excerpt_length = (int) $excerpt_length;
367			if ( $excerpt_length == 0 ) {
368				$excerpt_length = 55;
369			}
370			
371			$words = explode(' ', $content, $excerpt_length + 1);
372			if ( count($words) > $excerpt_length ) {
373				array_pop($words);
374				array_push($words, '[...]');
375				$content = implode(' ', $words);
376			}
377			return $content;
378		}
379	}
380	
381	/**
382	 * Get and format tags from list ID (SQL Group Concat)
383	 *
384	 * @param string $terms 
385	 * @return string
386	 * @author Amaury Balmer
387	 */
388	function getTagsFromID( $terms = '', $taxonomy = 'post_tag' ) {
389		if ( empty($terms) ) {
390			return '';
391		}
392		
393		// Get tags since Term ID.
394		$terms = (array) get_terms( $taxonomy, 'include='.$terms );
395		if ( empty($terms) ) {
396			return '';
397		}
398		
399		// HTML Rel (tag)
400		$rel = $this->buildRel();
401		
402		$output = array();
403		foreach ( (array) $terms as $term ) {
404			$link = get_term_link($term->term_id, $term->taxonomy);
405			if ( empty($link) || is_wp_error($link) )
406				continue;
407				
408			$output[] = '<a href="'.$link.'" title="'.esc_attr(sprintf( _n('%d topic', '%d topics', (int) $term->count, 'simpletags'), $term->count )).'" '.$rel.'>'.esc_html($term->name).'</a>';
409		}
410		
411		return implode(', ', $output);
412	}
413}
414?>