source: trunk/www.guidonia.net/wp/wp-content/plugins/simple-tags/2.7/simple-tags.client.php@ 44

Last change on this file since 44 was 44, checked in by luciano, 14 years ago
File size: 62.8 KB
Line 
1<?php
2class SimpleTags {
3 var $version = '1.6.6';
4
5 var $info;
6 var $options;
7 var $default_options;
8 var $db_options = 'simpletags';
9 var $dateformat;
10
11 // Stock Post ID for current view
12 var $posts = array();
13 var $tags_currentposts = array();
14 var $link_tags = 'null';
15
16 // WP Object Cache
17 var $use_cache = false;
18
19 /**
20 * PHP4 constructor - Initialize ST
21 *
22 * @return SimpleTags
23 */
24 function SimpleTags() {
25 // Determine installation path & url
26 $path = str_replace('\\','/',dirname(__FILE__));
27 $path = substr($path, strpos($path, 'plugins') + 8, strlen($path));
28
29 $info['siteurl'] = get_option('siteurl');
30 if ( $this->isMuPlugin() ) {
31 $info['install_url'] = $info['siteurl'] . '/wp-content/mu-plugins';
32 $info['install_dir'] = ABSPATH . 'wp-content/mu-plugins';
33
34 if ( $path != 'mu-plugins' ) {
35 $info['install_url'] .= '/' . $path;
36 $info['install_dir'] .= '/' . $path;
37 }
38 } else {
39 $info['install_url'] = $info['siteurl'] . '/wp-content/plugins';
40 $info['install_dir'] = ABSPATH . 'wp-content/plugins';
41
42 if ( $path != 'plugins' ) {
43 $info['install_url'] .= '/' . $path;
44 $info['install_dir'] .= '/' . $path;
45 }
46 }
47
48 // Set informations
49 $this->info = array(
50 'home' => get_option('home'),
51 'siteurl' => $info['siteurl'],
52 'install_url' => $info['install_url'],
53 'install_dir' => $info['install_dir']
54 );
55 unset($info);
56
57 // Localization
58 $locale = get_locale();
59 if ( !empty( $locale ) ) {
60 $mofile = str_replace('/2.7', '', $this->info['install_dir']).'/languages/simpletags-'.$locale.'.mo';
61 load_textdomain('simpletags', $mofile);
62 }
63
64 // Options
65 $default_options = array(
66 // General
67 'use_tag_pages' => 1,
68 'allow_embed_tcloud' => 0,
69 'no_follow' => 0,
70 // Auto link
71 'auto_link_tags' => 0,
72 'auto_link_min' => 1,
73 'auto_link_case' => 1,
74 'auto_link_max_by_post' => 20,
75 // Administration
76 'use_click_tags' => 1,
77 'use_suggested_tags' => 1,
78 'use_autocompletion' => 1,
79 // Embedded Tags
80 'use_embed_tags' => 0,
81 'start_embed_tags' => '[tags]',
82 'end_embed_tags' => '[/tags]',
83 // Related Posts
84 'rp_feed' => 0,
85 'rp_embedded' => 'no',
86 'rp_order' => 'count-desc',
87 'rp_limit_qty' => 5,
88 'rp_notagstext' => __('No related posts.', 'simpletags'),
89 'rp_title' => __('<h4>Related posts</h4>', 'simpletags'),
90 'rp_xformat' => __('<a href="%post_permalink%" title="%post_title% (%post_date%)">%post_title%</a> (%post_comment%)', 'simpletags'),
91 'rp_adv_usage' => '',
92 // Tag cloud
93 'cloud_selection' => 'count-desc',
94 'cloud_sort' => 'random',
95 'cloud_limit_qty' => 45,
96 'cloud_notagstext' => __('No tags.', 'simpletags'),
97 'cloud_title' => __('<h4>Tag Cloud</h4>', 'simpletags'),
98 'cloud_format' => 'flat',
99 'cloud_xformat' => __('<a href="%tag_link%" id="tag-link-%tag_id%" class="st-tags t%tag_scale%" title="%tag_count% topics" %tag_rel% style="%tag_size% %tag_color%">%tag_name%</a>', 'simpletags'),
100 'cloud_max_color' => '#000000',
101 'cloud_min_color' => '#CCCCCC',
102 'cloud_max_size' => 22,
103 'cloud_min_size' => 8,
104 'cloud_unit' => 'pt',
105 'cloud_inc_cats' => 0,
106 'cloud_adv_usage' => '',
107 // The tags
108 'tt_feed' => 0,
109 'tt_embedded' => 'no',
110 'tt_separator' => ', ',
111 'tt_before' => __('Tags: ', 'simpletags'),
112 'tt_after' => '<br />',
113 'tt_notagstext' => __('No tags for this post.', 'simpletags'),
114 'tt_number' => 0,
115 'tt_inc_cats' => 0,
116 'tt_xformat' => __('<a href="%tag_link%" title="%tag_name%" %tag_rel%>%tag_name%</a>', 'simpletags'),
117 'tt_adv_usage' => '',
118 // Related tags
119 'rt_number' => 5,
120 'rt_order' => 'count-desc',
121 'rt_separator' => ' ',
122 'rt_format' => 'list',
123 'rt_method' => 'OR',
124 'rt_title' => __('<h4>Related tags</h4>', 'simpletags'),
125 'rt_notagstext' => __('No related tags found.', 'simpletags'),
126 'rt_xformat' => __('<span>%tag_count%</span> <a href="%tag_link_add%">+</a> <a href="%tag_link%">%tag_name%</a>', 'simpletags'),
127 // Remove related tags
128 'rt_remove_separator' => ' ',
129 'rt_remove_format' => 'list',
130 'rt_remove_notagstext' => ' ',
131 'rt_remove_xformat' => __('&raquo; <a href="%tag_link_remove%" title="Remove %tag_name_attribute% from search">Remove %tag_name%</a>', 'simpletags'),
132 // Meta keywords
133 'meta_autoheader' => 1,
134 'meta_always_include' => '',
135 'meta_keywords_qty' => 0,
136 // Auto tags
137 'use_auto_tags' => 0,
138 'at_all' => 0,
139 'at_empty' => 0,
140 'auto_list' => ''
141 );
142
143 // Set class property for default options
144 $this->default_options = $default_options;
145
146 // Get options from WP options
147 $options_from_table = get_option( $this->db_options );
148
149 // Update default options by getting not empty values from options table
150 foreach( (array) $default_options as $default_options_name => $default_options_value ) {
151 if ( !is_null($options_from_table[$default_options_name]) ) {
152 if ( is_int($default_options_value) ) {
153 $default_options[$default_options_name] = (int) $options_from_table[$default_options_name];
154 } else {
155 $default_options[$default_options_name] = $options_from_table[$default_options_name];
156 }
157 }
158 }
159
160 // Set the class property and unset no used variable
161 $this->options = $default_options;
162
163 // Clean memory
164 $default_options = array();
165 $options_from_table = array();
166 unset($default_options);
167 unset($options_from_table);
168 unset($default_options_value);
169
170 // Use WP Object ? Or not ?
171 global $wp_object_cache;
172 $this->use_cache = ( $wp_object_cache->cache_enabled === true ) ? true : false;
173
174 // Set date for class
175 $this->dateformat = get_option('date_format');
176
177 // Add pages in WP_Query
178 if ( $this->options['use_tag_pages'] == 1 ) {
179 // Remove default taxonomy
180 global $wp_taxonomies;
181 unset($wp_taxonomies['post_tag']);
182 // Add the same taxonomy with an another callback who allow page and post
183 register_taxonomy( 'post_tag', 'post', array('hierarchical' => false, 'update_count_callback' => array(&$this, '_update_post_and_page_term_count')) );
184 add_filter('posts_where', array(&$this, 'prepareQuery'));
185 }
186
187 // Remove embedded tags in posts display
188 if ( $this->options['use_embed_tags'] == 1 ) {
189 add_filter('the_content', array(&$this, 'filterEmbedTags'), 0);
190 }
191
192 // Add related posts in post ( all / feedonly / blogonly / homeonly / singularonly / singleonly / pageonly /no )
193 if ( $this->options['tt_embedded'] != 'no' || $this->options['tt_feed'] == 1 ) {
194 add_filter('the_content', array(&$this, 'inlinePostTags'), 999992);
195 }
196
197 // Add post tags in post ( all / feedonly / blogonly / homeonly / singularonly / singleonly / pageonly /no )
198 if ( $this->options['rp_embedded'] != 'no' || $this->options['rp_feed'] == 1 ) {
199 add_filter('the_content', array(&$this, 'inlineRelatedPosts'), 999993);
200 }
201
202 // Embedded tag cloud
203 if ( $this->options['allow_embed_tcloud'] == 1 ) {
204 add_filter('the_content', array(&$this, 'inlineTagCloud'));
205 }
206
207 // Stock Posts ID (useful for autolink and metakeywords)
208 add_filter( 'the_posts', array(&$this, 'getPostIds') );
209
210 // Add keywords to header
211 if ( ( $this->options['meta_autoheader'] == 1 && !class_exists('Platinum_SEO_Pack') && !class_exists('All_in_One_SEO_Pack') && apply_filters('st_meta_header', true) ) ) {
212 add_action('wp_head', array(&$this, 'outputMetaKeywords'));
213 }
214
215 // Auto link tags
216 if ( $this->options['auto_link_tags'] == '1' ) {
217 add_filter('the_content', array(&$this, 'autoLinkTags'), 12);
218 }
219 return true;
220 }
221
222 /**
223 * Get links for each tag for auto link feature
224 *
225 */
226 function prepareAutoLinkTags() {
227 $this->getTagsFromCurrentPosts();
228
229 $auto_link_min = (int) $this->options['auto_link_min'];
230 if ( $auto_link_min == 0 ) {
231 $auto_link_min = 1;
232 }
233
234 $this->link_tags = array();
235 foreach ( (array) $this->tags_currentposts as $term ) {
236 if ( $term->count >= $auto_link_min ) {
237 $this->link_tags[$term->name] = clean_url(get_tag_link( $term->term_id ));
238 }
239 }
240 return true;
241 }
242
243 /**
244 * Replace text by link to tag
245 *
246 * @param string $content
247 * @return string
248 */
249 function autoLinkTags( $content = '' ) {
250 // Get currents tags if no exists
251 if ( $this->link_tags == 'null' ) {
252 $this->prepareAutoLinkTags();
253 }
254
255 // Shuffle array
256 $link_tags = $this->randomArray($this->link_tags);
257
258
259 // HTML Rel (tag/no-follow)
260 $rel = $this->buildRel( $this->options['no_follow'] );
261
262 // only continue if the database actually returned any links
263 if ( isset($link_tags) && is_array($link_tags) && count($link_tags) > 0 ) {
264
265 // Limit array
266 if ( (int) $this->options['auto_link_max_by_post'] != 0 ) {
267 $link_tags = array_slice($link_tags, 0, (int) $this->options['auto_link_max_by_post']);
268 }
269
270 $must_tokenize = TRUE; // will perform basic tokenization
271 $tokens = NULL; // two kinds of tokens: markup and text
272
273 $case = ( $this->options['auto_link_case'] == 1 ) ? 'i' : '';
274
275 foreach ( (array) $link_tags as $term_name => $term_link ) {
276 $filtered = ""; // will filter text token by token
277 $match = "/\b" . preg_quote($term_name, "/") . "\b/".$case;
278 $substitute = '<a href="'.$term_link.'" class="st_tag internal_tag" '.$rel.' title="'. attribute_escape( sprintf( __('Posts tagged with %s', 'simpletags'), $term_name ) )."\">$0</a>";
279
280 // for efficiency only tokenize if forced to do so
281 if ( $must_tokenize ) {
282 // this regexp is taken from PHP Markdown by Michel Fortin: http://www.michelf.com/projects/php-markdown/
283 $comment = '(?s:<!(?:--.*?--\s*)+>)|';
284 $processing_instruction = '(?s:<\?.*?\?>)|';
285 $tag = '(?:<[/!$]?[-a-zA-Z0-9:]+\b(?>[^"\'>]+|"[^"]*"|\'[^\']*\')*>)';
286
287 $markup = $comment . $processing_instruction . $tag;
288 $flags = PREG_SPLIT_DELIM_CAPTURE;
289 $tokens = preg_split("{($markup)}", $content, -1, $flags);
290 $must_tokenize = FALSE;
291 }
292
293 // there should always be at least one token, but check just in case
294 if ( isset($tokens) && is_array($tokens) && count($tokens) > 0 ) {
295 $i = 0;
296 foreach ($tokens as $token) {
297 if (++$i % 2 && $token != '') { // this token is (non-markup) text
298 if ($anchor_level == 0) { // linkify if not inside anchor tags
299 if ( preg_match($match, $token) ) { // use preg_match for compatibility with PHP 4
300 $token = preg_replace($match, $substitute, $token); // only PHP 5 supports calling preg_replace with 5 arguments
301 $must_tokenize = TRUE; // re-tokenize next time around
302 }
303 }
304 }
305 else { // this token is markup
306 if ( preg_match("#<\s*a\s+[^>]*>#i", $token) ) { // found <a ...>
307 $anchor_level++;
308 } elseif ( preg_match("#<\s*/\s*a\s*>#i", $token) ) { // found </a>
309 $anchor_level--;
310 }
311 }
312 $filtered .= $token; // this token has now been filtered
313 }
314 $content = $filtered; // filtering completed for this link
315 }
316 }
317 }
318
319 return $content;
320 }
321
322 /**
323 * Replace marker by a tag cloud in post content
324 *
325 * @param string $content
326 * @return string
327 */
328 function inlineTagCloud( $content = '' ) {
329 if ( strpos($content, '<!--st_tag_cloud-->') ) {
330 $content = str_replace('<!--st_tag_cloud-->', $this->extendedTagCloud( '', false ), $content);
331 }
332 return $content;
333 }
334
335 /**
336 * Stock posts ID as soon as possible
337 *
338 * @param array $posts
339 * @return array
340 */
341 function getPostIds( $posts = array() ) {
342 if ( !empty($posts) && is_array($posts) ) {
343 foreach( (array) $posts as $post) {
344 $this->posts[] = $post->ID;
345 }
346 }
347 return $posts;
348 }
349
350 /**
351 * Get tags from current post views
352 *
353 * @return boolean
354 */
355 function getTagsFromCurrentPosts() {
356 if ( is_array($this->posts) && count($this->posts) > 0 ) {
357 // Generate SQL from post id
358 $postlist = implode( "', '", $this->posts );
359
360 if ( $this->use_cache === true ) { // Use cache
361 // Generate key cache
362 $key = md5(maybe_serialize($postlist));
363 // Get cache if exist
364 if ( $cache = wp_cache_get( 'generate_keywords', 'simpletags' ) ) {
365 if ( isset( $cache[$key] ) ) {
366 $this->tags_currentposts = $cache[$key];
367 return true;
368 }
369 }
370 }
371
372 // If cache not exist, get datas and set cache
373 global $wpdb;
374 $results = $wpdb->get_results("
375 SELECT t.name AS name, t.term_id AS term_id, tt.count AS count
376 FROM {$wpdb->term_relationships} AS tr
377 INNER JOIN {$wpdb->term_taxonomy} AS tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)
378 INNER JOIN {$wpdb->terms} AS t ON (tt.term_id = t.term_id)
379 WHERE tt.taxonomy = 'post_tag'
380 AND ( tr.object_id IN ('{$postlist}') )
381 GROUP BY t.term_id
382 ORDER BY tt.count DESC");
383
384 if ( $this->use_cache === true ) { // Use cache
385 $cache[$key] = $results;
386 wp_cache_set('generate_keywords', $cache, 'simpletags');
387 }
388
389 $this->tags_currentposts = $results;
390 unset($results, $key);
391 }
392 return true;
393 }
394
395 /**
396 * Generate keywords for meta data
397 *
398 * @return string
399 */
400 function generateKeywords() {
401 // Get tags for current posts
402 if ( empty($this->tags_currentposts) ) {
403 $this->getTagsFromCurrentPosts();
404 }
405
406 $results = array();
407 foreach ( (array) $this->tags_currentposts as $term ) {
408 $results[] = $term->name;
409 }
410 unset($this->tags_currentposts);
411
412 $always_list = trim($this->options['meta_always_include']); // Static keywords
413 $always_array = (array) explode(',', $always_list);
414
415 // Trim
416 foreach ( $always_array as $keyword ) {
417 if ( empty($keyword) ) {
418 continue;
419 }
420 $results[] = trim($keyword);
421 }
422 unset($always_list, $always_array);
423
424 // Unique keywords
425 $results = array_unique($results);
426
427 // Return if empty
428 if ( empty($results) ) {
429 return '';
430 }
431
432 // Limit to max quantity if set
433 $number = (int) $this->options['meta_keywords_qty'];
434 if ( $number != 0 && is_array($results) && !empty($results) && count($results) > 1 ) {
435 shuffle($results); // Randomize keywords
436 $results = array_slice( $results, 0, $number );
437 }
438
439 return strip_tags(implode(', ', $results));
440 }
441
442 /**
443 * Display meta keywords
444 *
445 */
446 function outputMetaKeywords() {
447 $terms_list = $this->generateKeywords();
448 if ( !empty($terms_list) ) {
449 echo "\n\t" . '<!-- Generated by Simple Tags ' . $this->version . ' - http://wordpress.org/extend/plugins/simple-tags -->' ."\n\t". '<meta name="keywords" content="' . $terms_list . '" />' ."\n";
450 return true;
451 }
452 return false;
453 }
454
455 /**
456 * Auto add related posts to post content
457 *
458 * @param string $content
459 * @return string
460 */
461 function inlineRelatedPosts( $content = '' ) {
462 $marker = false;
463 if ( is_feed() ) {
464 if ( $this->options['rp_feed'] == '1' ) {
465 $marker = true;
466 }
467 } else {
468 switch ( $this->options['rp_embedded'] ) {
469 case 'blogonly' :
470 $marker = ( is_feed() ) ? false : true;
471 break;
472 case 'homeonly' :
473 $marker = ( is_home() ) ? true : false;
474 break;
475 case 'singularonly' :
476 $marker = ( is_singular() ) ? true : false;
477 break;
478 case 'singleonly' :
479 $marker = ( is_single() ) ? true : false;
480 break;
481 case 'pageonly' :
482 $marker = ( is_page() ) ? true : false;
483 break;
484 case 'all' :
485 $marker = true;
486 break;
487 case 'no' :
488 default:
489 $marker = false;
490 break;
491 }
492 }
493
494 if ( $marker === true ) {
495 return ( $content . $this->relatedPosts( '', false ) );
496 }
497 return $content;
498 }
499
500 /**
501 * Auto add current tags post to post content
502 *
503 * @param string $content
504 * @return string
505 */
506 function inlinePostTags( $content = '' ) {
507 $marker = false;
508 if ( is_feed() ) {
509 if ( $this->options['tt_feed'] == '1' ) {
510 $marker = true;
511 }
512 } else {
513 switch ( $this->options['tt_embedded'] ) {
514 case 'blogonly' :
515 $marker = ( is_feed() ) ? false : true;
516 break;
517 case 'homeonly' :
518 $marker = ( is_home() ) ? true : false;
519 break;
520 case 'singularonly' :
521 $marker = ( is_singular() ) ? true : false;
522 break;
523 case 'singleonly' :
524 $marker = ( is_single() ) ? true : false;
525 break;
526 case 'pageonly' :
527 $marker = ( is_page() ) ? true : false;
528 break;
529 case 'all' :
530 $marker = true;
531 break;
532 case 'no' :
533 default:
534 $marker = false;
535 break;
536 }
537 }
538
539 if ( $marker === true ) {
540 return ( $content . $this->extendedPostTags( '', false ) );
541 }
542 return $content;
543 }
544
545 /**
546 * Generate related posts
547 *
548 * @param string $user_args
549 * @return string|array
550 */
551 function relatedPosts( $user_args = '', $copyright = true ) {
552 $defaults = array(
553 'number' => 5,
554 'order' => 'count-desc',
555 'format' => 'list',
556 'separator' => '',
557 'include_page' => 'true',
558 'include_cat' => '',
559 'exclude_posts' => '',
560 'exclude_tags' => '',
561 'post_id' => 0,
562 'excerpt_wrap' => 55,
563 'limit_days' => 0,
564 'min_shared' => 1,
565 'title' => __('<h4>Related posts</h4>', 'simpletags'),
566 'nopoststext' => __('No related posts.', 'simpletags'),
567 'dateformat' => $this->dateformat,
568 'xformat' => __('<a href="%post_permalink%" title="%post_title% (%post_date%)">%post_title%</a> (%post_comment%)', 'simpletags')
569 );
570
571 // Get values in DB
572 $defaults['number'] = $this->options['rp_limit_qty'];
573 $defaults['order'] = $this->options['rp_order'];
574 $defaults['nopoststext'] = $this->options['rp_notagstext'];
575 $defaults['title'] = $this->options['rp_title'];
576 $defaults['xformat'] = $this->options['rp_xformat'];
577
578 if( empty($user_args) ) {
579 $user_args = $this->options['rp_adv_usage'];
580 }
581
582 // Replace old markers by new
583 $markers = array('%date%' => '%post_date%', '%permalink%' => '%post_permalink%', '%title%' => '%post_title%', '%commentcount%' => '%post_comment%', '%tagcount%' => '%post_tagcount%', '%postid%' => '%post_id%');
584 if (!is_array($user_args)) $user_args = strtr($user_args, $markers);
585
586 $args = wp_parse_args( $user_args, $defaults );
587 extract($args);
588
589 // If empty use default xformat !
590 if ( empty($xformat) ) {
591 $xformat = $defaults['xformat'];
592 }
593
594 // Clean memory
595 $args = array();
596 $defaults = array();
597
598 // Get current post data
599 $object_id = (int) $post_id;
600 if ( $object_id == 0 ) {
601 global $post;
602 $object_id = (int) $post->ID;
603 if ( $object_id == 0 ) {
604 return false;
605 }
606 }
607
608 // Get cache if exist
609 $results = false;
610 if ( $this->use_cache === true ) { // Use cache
611 // Generate key cache
612 $key = md5(maybe_serialize($user_args.'-'.$object_id));
613
614 if ( $cache = wp_cache_get( 'related_posts', 'simpletags' ) ) {
615 if ( isset( $cache[$key] ) ) {
616 $results = $cache[$key];
617 }
618 }
619 }
620
621 // If cache not exist, get datas and set cache
622 if ( $results === false || $results === null ) {
623 // Get get tags
624 $current_tags = get_the_tags( (int) $object_id );
625
626 if ( $current_tags === false ) {
627 return $this->outputContent( 'st-related-posts', $format, $title, $nopoststext, $copyright );
628 }
629
630 // Number - Limit
631 $number = (int) $number;
632 if ( $number == 0 ) {
633 $number = 5;
634 } elseif( $number > 50 ) {
635 $number = 50;
636 }
637 $limit_sql = 'LIMIT 0, '.$number;
638 unset($number);
639
640 // Order tags before output (count-asc/count-desc/date-asc/date-desc/name-asc/name-desc/random)
641 $order_by = '';
642 $order = strtolower($order);
643 switch ( $order ) {
644 case 'count-asc':
645 $order_by = 'counter ASC, p.post_title DESC';
646 break;
647 case 'random':
648 $order_by = 'RAND()';
649 break;
650 case 'date-asc':
651 $order_by = 'p.post_date ASC';
652 break;
653 case 'date-desc':
654 $order_by = 'p.post_date DESC';
655 break;
656 case 'name-asc':
657 $order_by = 'p.post_title ASC';
658 break;
659 case 'name-desc':
660 $order_by = 'p.post_title DESC';
661 break;
662 default: // count-desc
663 $order_by = 'counter DESC, p.post_title DESC';
664 break;
665 }
666
667 // Limit days - 86400 seconds = 1 day
668 $limit_days = (int) $limit_days;
669 $limit_days_sql = '';
670 if ( $limit_days != 0 ) {
671 $limit_days_sql = 'AND p.post_date > "' .date( 'Y-m-d H:i:s', time() - $limit_days * 86400 ). '"';
672 }
673 unset($limit_days);
674
675 // Include_page
676 $include_page = strtolower($include_page);
677 if ( $include_page == 'true' ) {
678 $restrict_sql = "AND p.post_type IN ('page', 'post')";
679 } else {
680 $restrict_sql = "AND p.post_type = 'post'";
681 }
682 unset($include_page);
683
684 // Restrict posts
685 $exclude_posts_sql = '';
686 if ( $exclude_posts != '' ) {
687 $exclude_posts = (array) explode(',', $exclude_posts);
688 $exclude_posts = array_unique($exclude_posts);
689 $exclude_posts_sql = "AND p.ID NOT IN (";
690 foreach ( $exclude_posts as $value ) {
691 $value = (int) $value;
692 if( $value > 0 && $value != $object_id ) {
693 $exclude_posts_sql .= '"'.$value.'", ';
694 }
695 }
696 $exclude_posts_sql .= '"'.$object_id.'")';
697 } else {
698 $exclude_posts_sql = "AND p.ID <> {$object_id}";
699 }
700 unset($exclude_posts);
701
702 // Restricts tags
703 $tags_to_exclude = array();
704 if ( $exclude_tags != '' ) {
705 $exclude_tags = (array) explode(',', $exclude_tags);
706 $exclude_tags = array_unique($exclude_tags);
707 foreach ( $exclude_tags as $value ) {
708 $tags_to_exclude[] = trim($value);
709 }
710 }
711 unset($exclude_tags);
712
713 // SQL Tags list
714 $tag_list = '';
715 foreach ( (array) $current_tags as $tag ) {
716 if ( !in_array($tag->name, $tags_to_exclude) ) {
717 $tag_list .= '"'.(int) $tag->term_id.'", ';
718 }
719 }
720
721 // If empty return no posts text
722 if ( empty($tag_list) ) {
723 return $this->outputContent( 'st-related-posts', $format, $title, $nopoststext, $copyright );
724 }
725
726 // Remove latest ", "
727 $tag_list = substr($tag_list, 0, strlen($tag_list) - 2);
728
729 global $wpdb;
730
731 // Include category
732 $include_cat_sql = '';
733 $inner_cat_sql = '';
734 if ($include_cat != '') {
735 $include_cat = (array) explode(',', $include_cat);
736 $include_cat = array_unique($include_cat);
737 foreach ( $include_cat as $value ) {
738 $value = (int) $value;
739 if( $value > 0 ) {
740 $sql_cat_in .= '"'.$value.'", ';
741 }
742 }
743 $sql_cat_in = substr($sql_cat_in, 0, strlen($sql_cat_in) - 2);
744 $include_cat_sql = " AND (ctt.taxonomy = 'category' AND ctt.term_id IN ({$sql_cat_in})) ";
745 $inner_cat_sql = " INNER JOIN {$wpdb->term_relationships} AS ctr ON (p.ID = ctr.object_id) ";
746 $inner_cat_sql .= " INNER JOIN {$wpdb->term_taxonomy} AS ctt ON (ctr.term_taxonomy_id = ctt.term_taxonomy_id) ";
747 }
748
749 // Group Concat only for MySQL > 4.1 and check if post_relatedtags is used by xformat...
750 $select_gp_concat = '';
751 if ( version_compare(mysql_get_server_info(), '4.1.0', '>=') && ( strpos($xformat,'%post_relatedtags%') || $min_shared > 1 ) ) {
752 $select_gp_concat = ', GROUP_CONCAT(tt.term_id) as terms_id';
753 } else {
754 $xformat = str_replace('%post_relatedtags%', '', $xformat); // Group Concat only for MySQL > 4.1, remove related tags
755 }
756
757 // Check if post_excerpt is used by xformat...
758 $select_excerpt = '';
759 if ( strpos( $xformat, '%post_excerpt%' ) ) {
760 $select_excerpt = ', p.post_content, p.post_excerpt, p.post_password';
761 }
762
763 // Posts: title, comments_count, date, permalink, post_id, counter
764 $results = $wpdb->get_results("
765 SELECT p.post_title, p.comment_count, p.post_date, p.ID, COUNT(tr.object_id) AS counter {$select_excerpt} {$select_gp_concat}
766 FROM {$wpdb->posts} AS p
767 INNER JOIN {$wpdb->term_relationships} AS tr ON (p.ID = tr.object_id)
768 INNER JOIN {$wpdb->term_taxonomy} AS tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)
769 {$inner_cat_sql}
770 WHERE (tt.taxonomy = 'post_tag' AND tt.term_id IN ({$tag_list}))
771 {$include_cat_sql}
772 {$exclude_posts_sql}
773 AND p.post_status = 'publish'
774 AND p.post_date_gmt < '".current_time('mysql')."'
775 {$limit_days_sql}
776 {$restrict_sql}
777 GROUP BY tr.object_id
778 ORDER BY {$order_by}
779 {$limit_sql}");
780
781 if ( $this->use_cache === true ) { // Use cache
782 $cache[$key] = $results;
783 wp_cache_set('related_posts', $cache, 'simpletags');
784 }
785 }
786
787 if ( $format == 'object' || $format == 'array' ) {
788 return $results;
789 } elseif ( $results === false || empty($results) ) {
790 return $this->outputContent( 'st-related-posts', $format, $title, $nopoststext, $copyright );
791 }
792
793 if ( empty($dateformat) ) {
794 $dateformat = $this->dateformat;
795 }
796
797 $output = array();
798 // Replace placeholders
799 foreach ( (array) $results as $result ) {
800 if ( ( $min_shared > 1 && ( count(explode(',', $result->terms_id)) < $min_shared ) ) || !is_object($result) ) {
801 continue;
802 }
803
804 $element_loop = $xformat;
805 $post_title = apply_filters( 'the_title', $result->post_title );
806 $element_loop = str_replace('%post_date%', mysql2date($dateformat, $result->post_date), $element_loop);
807 $element_loop = str_replace('%post_permalink%', get_permalink($result->ID), $element_loop);
808 $element_loop = str_replace('%post_title%', $post_title, $element_loop);
809 $element_loop = str_replace('%post_title_attribute%', wp_specialchars(strip_tags($post_title)), $element_loop);
810 $element_loop = str_replace('%post_comment%', $result->comment_count, $element_loop);
811 $element_loop = str_replace('%post_tagcount%', $result->counter, $element_loop);
812 $element_loop = str_replace('%post_id%', $result->ID, $element_loop);
813 $element_loop = str_replace('%post_relatedtags%', $this->getTagsFromID($result->terms_id), $element_loop);
814 $element_loop = str_replace('%post_excerpt%', $this->getExcerptPost( $result->post_excerpt, $result->post_content, $result->post_password, $excerpt_wrap ), $element_loop);
815 $output[] = $element_loop;
816 }
817
818 // Clean memory
819 $results = array();
820 unset($results, $result);
821
822 return $this->outputContent( 'st-related-posts', $format, $title, $output, $copyright, $separator );
823 }
824
825 /**
826 * Build excerpt from post data with specific lenght
827 *
828 * @param string $excerpt
829 * @param string $content
830 * @param string $password
831 * @param integer $excerpt_length
832 * @return string
833 */
834 function getExcerptPost( $excerpt = '', $content = '', $password = '', $excerpt_length = 55 ) {
835 if ( !empty($password) ) { // if there's a password
836 if ( $_COOKIE['wp-postpass_'.COOKIEHASH] != $password ) { // and it doesn't match the cookie
837 return __('There is no excerpt because this is a protected post.', 'simpletags');
838 }
839 }
840
841 if ( !empty($excerpt) ) {
842 return apply_filters('get_the_excerpt', $excerpt);
843 } else { // Fake excerpt
844 $content = str_replace(']]>', ']]&gt;', $content);
845 $content = strip_tags($content);
846
847 $excerpt_length = (int) $excerpt_length;
848 if ( $excerpt_length == 0 ) {
849 $excerpt_length = 55;
850 }
851
852 $words = explode(' ', $content, $excerpt_length + 1);
853 if ( count($words) > $excerpt_length ) {
854 array_pop($words);
855 array_push($words, '[...]');
856 $content = implode(' ', $words);
857 }
858 return $content;
859 }
860 }
861
862 /**
863 * Get and format tags from list ID (SQL Group Concat)
864 *
865 * @param array $terms
866 * @return string
867 */
868 function getTagsFromID( $terms = '' ) {
869 if ( empty($terms) ) {
870 return '';
871 }
872
873 // Get tags since Term ID.
874 $terms = (array) get_terms('post_tag', 'include='.$terms);
875 if ( empty($terms) ) {
876 return '';
877 }
878
879 // HTML Rel (tag/no-follow)
880 $rel = $this->buildRel( $this->options['no_follow'] );
881
882 $output = '';
883 foreach ( $terms as $term ) {
884 $output .= '<a href="'.get_tag_link($term->term_id).'" title="'.attribute_escape(sprintf( __ngettext('%d topic', '%d topics', $term->count, 'simpletags'), $term->count )).'" '.$rel.'>'.wp_specialchars($term->name).'</a>, ';
885 }
886 $output = substr($output, 0, strlen($output) - 2); // Remove latest ", "
887 return $output;
888 }
889
890 /**
891 * Check is page is a tag view, even if tags haven't post
892 *
893 * @return boolean
894 */
895 function isTag() {
896 if ( get_query_var('tag') == '' ) {
897 return false;
898 }
899 return true;
900 }
901
902 /**
903 * Get related tags for a tags view
904 *
905 * @param string $user_args
906 * @return string|array
907 */
908 function relatedTags( $user_args = '' ) {
909 $defaults = array(
910 'number' => 5,
911 'order' => 'count-desc',
912 'separator' => ' ',
913 'format' => 'list',
914 'method' => 'OR',
915 'no_follow' => 0,
916 'title' => __('<h4>Related tags</h4>', 'simpletags'),
917 'notagstext' => __('No related tag found.', 'simpletags'),
918 'xformat' => __('<span>%tag_count%</span> <a %tag_rel% href="%tag_link_add%">+</a> <a %tag_rel% href="%tag_link%" title="See posts with %tag_name_attribute%">%tag_name%</a>', 'simpletags')
919 );
920
921 // Get values in DB
922 $defaults['no_follow'] = $this->options['no_follow'];
923 $defaults['number'] = $this->options['rt_number'];
924 $defaults['order'] = $this->options['rt_order'];
925 $defaults['separator'] = $this->options['rt_separator'];
926 $defaults['format'] = $this->options['rt_format'];
927 $defaults['method'] = $this->options['rt_method'];
928 $defaults['title'] = $this->options['rt_title'];
929 $defaults['notagstext'] = $this->options['rt_notagstext'];
930 $defaults['xformat'] = $this->options['rt_xformat'];
931
932 if( empty($user_args) ) {
933 $user_args = $this->options['rt_adv_usage'];
934 }
935
936 $args = wp_parse_args( $user_args, $defaults );
937 extract($args);
938
939 // If empty use default xformat !
940 if ( empty($xformat) ) {
941 $xformat = $defaults['xformat'];
942 }
943
944 // Clean memory
945 $args = array();
946 $defaults = array();
947 unset($args, $defaults);
948
949 if ( !is_tag() && !$this->isTag() ) {
950 return '';
951 }
952
953 // Method union/intersection
954 $method = strtoupper($method);
955 if ( $method == 'AND' ) {
956 $url_tag_sep = '+';
957 } else {
958 $url_tag_sep = ',';
959 }
960
961 // Get currents slugs
962 $slugs = get_query_var('tag');
963 if ( strpos( $slugs, ',') ) {
964 $current_slugs = explode(',', $slugs);
965 } elseif ( strpos( $slugs, '+') ) {
966 $current_slugs = explode('+', $slugs);
967 } elseif ( strpos( $slugs, ' ') ) {
968 $current_slugs = explode(' ', $slugs);
969 }else {
970 $current_slugs[] = $slugs;
971 }
972
973 // Get cache if exist
974 $related_tags = false;
975 if ( $this->use_cache === true ) { // Use cache
976 // Generate key cache
977 $key = md5(maybe_serialize($user_args.$slugs.$url_tag_sep));
978 $cache = wp_cache_get( 'related_tags', 'simpletags' );
979 if ( $cache ) {
980 if ( isset( $cache[$key] ) ) {
981 $related_tags = $cache[$key];
982 }
983 }
984 }
985
986 // If cache not exist, get datas and set cache
987 if ( $related_tags === false || $related_tags === null ) {
988 // Order tags before selection (count-asc/count-desc/name-asc/name-desc/random)
989 $order_tmp = strtolower($order);
990 $order_by = $order = '';
991 switch ( $order_tmp ) {
992 case 'count-asc':
993 $order_by = 'count';
994 $order = 'ASC';
995 break;
996 case 'random':
997 $order_by = 'RAND()';
998 $order = '';
999 break;
1000 case 'name-asc':
1001 $order_by = 'name';
1002 $order = 'ASC';
1003 break;
1004 case 'name-desc':
1005 $order_by = 'name';
1006 $order = 'DESC';
1007 break;
1008 default: // count-desc
1009 $order_by = 'count';
1010 $order = 'DESC';
1011 break;
1012 }
1013
1014 // Get objets
1015 $terms = "'" . implode("', '", $current_slugs) . "'";
1016 global $wpdb;
1017 $object_ids = $wpdb->get_col("
1018 SELECT tr.object_id
1019 FROM {$wpdb->term_relationships} AS tr
1020 INNER JOIN {$wpdb->term_taxonomy} AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
1021 INNER JOIN {$wpdb->terms} AS t ON tt.term_id = t.term_id
1022 WHERE tt.taxonomy = 'post_tag'
1023 AND t.slug IN ({$terms})
1024 GROUP BY tr.object_id
1025 ORDER BY tr.object_id ASC");
1026
1027 // Clean memory
1028 $terms = array();
1029 unset($terms);
1030
1031 // Get tags for specified objects
1032 $all_related_tags = wp_get_object_terms( $object_ids, 'post_tag', array('orderby' => $order_by, 'order' => $order) );
1033
1034 // Remove duplicates tags
1035 $all_related_tags = array_intersect_key($all_related_tags, array_unique(array_map('serialize', $all_related_tags)));
1036
1037 // Exclude current tags
1038 foreach ( (array) $all_related_tags as $tag ) {
1039 if ( !in_array($tag->slug, $current_slugs) ) {
1040 $related_tags[] = $tag;
1041 }
1042 }
1043
1044 // Clean memory
1045 $all_related_tags = array();
1046 unset($all_related_tags);
1047
1048 if ( $this->use_cache === true ) { // Use cache
1049 $cache[$key] = $related_tags;
1050 wp_cache_set('related_tags', $cache, 'simpletags');
1051 }
1052 }
1053
1054 if ( empty($related_tags) ) {
1055 return $this->outputContent( 'st-related-tags', $format, $title, $notagstext, true );
1056 } elseif ( $format == 'object' || $format == 'array' ) {
1057 return $related_tags;
1058 }
1059
1060 // Limit to max quantity if set
1061 $number = (int) $number;
1062 if ( $number != 0 ) {
1063 $related_tags = array_slice( $related_tags, 0, $number );
1064 }
1065
1066 // HTML Rel (tag/no-follow)
1067 $rel = $this->buildRel( $no_follow );
1068
1069 // Build outpout
1070 $output = array();
1071 foreach( $related_tags as $tag ) {
1072 if ( !is_object($tag) ) {
1073 continue;
1074 }
1075
1076 $element_loop = $xformat;
1077 $element_loop = $this->formatInternalTag( $element_loop, $tag, $rel, null );
1078 $element_loop = str_replace('%tag_link_add%', $this->getAddTagToLink( $current_slugs, $tag->slug, $url_tag_sep ), $element_loop);
1079 $output[] = $element_loop;
1080 }
1081
1082 // Clean memory
1083 $related_tags = array();
1084 unset($related_tags, $tag, $element_loop);
1085
1086 return $this->outputContent( 'st-related-tags', $format, $title, $output, true, $separator );
1087 }
1088
1089 /**
1090 * Add a tag to a current link
1091 *
1092 * @param array $current_slugs
1093 * @param string $tag_slug
1094 * @param string $separator
1095 * @return string
1096 */
1097 function getAddTagToLink( $current_slugs = array(), $tag_slug = '', $separator = ',' ) {
1098 // Add new tag slug to current slug
1099 $current_slugs[] = $tag_slug;
1100
1101 // Array to string with good separator
1102 $slugs = implode( $separator, $current_slugs );
1103
1104 global $wp_rewrite;
1105 $taglink = $wp_rewrite->get_tag_permastruct();
1106
1107 if ( empty($taglink) ) { // No permalink
1108 $taglink = $this->info['home'] . '/?tag=' . $slugs;
1109 } else { // Custom permalink
1110 $taglink = $this->info['home'] . user_trailingslashit( str_replace('%tag%', $slugs, $taglink), 'category');
1111 }
1112
1113 return apply_filters('st_add_tag_link', clean_url($taglink));
1114 }
1115
1116 /**
1117 * Get tags to remove in related tags
1118 *
1119 * @param string $user_args
1120 * @return string|array
1121 */
1122 function removeRelatedTags( $user_args = '' ) {
1123 $defaults = array(
1124 'separator' => '<br />',
1125 'format' => 'list',
1126 'notagstext' => '',
1127 'no_follow' => 0,
1128 'xformat' => __('<a %tag_rel% href="%tag_link_remove%" title="Remove %tag_name_attribute% from search">Remove %tag_name%</a>', 'simpletags')
1129 );
1130
1131 // Get values in DB
1132 $defaults['no_follow'] = $this->options['no_follow'];
1133 $defaults['separator'] = $this->options['rt_remove_separator'];
1134 $defaults['format'] = $this->options['rt_remove_format'];
1135 $defaults['notagstext'] = $this->options['rt_remove_notagstext'];
1136 $defaults['xformat'] = $this->options['rt_remove_xformat'];
1137
1138 if( empty($user_args) ) {
1139 $user_args = $this->options['rt_remove_adv_usage'];
1140 }
1141
1142 $args = wp_parse_args( $user_args, $defaults );
1143 extract($args);
1144
1145 // If empty use default xformat !
1146 if ( empty($xformat) ) {
1147 $xformat = $defaults['xformat'];
1148 }
1149
1150 // Clean memory
1151 $args = array();
1152 $defaults = array();
1153 unset($args, $defaults, $user_args);
1154
1155 if ( !is_tag() && !$this->isTag() ) {
1156 return '';
1157 }
1158
1159 // Get currents slugs
1160 $slugs = get_query_var('tag');
1161 if ( strpos( $slugs, ',') ) {
1162 $current_slugs = explode(',', $slugs);
1163 $url_tag_sep = ',';
1164 } elseif ( strpos( $slugs, '+') ) {
1165 $current_slugs = explode('+', $slugs);
1166 $url_tag_sep = '+';
1167 } elseif ( strpos( $slugs, ' ') ) {
1168 $current_slugs = explode(' ', $slugs);
1169 $url_tag_sep = '+';
1170 } else {
1171 return $this->outputContent( 'st-remove-related-tags', $format, '', $notagstext, true );
1172 }
1173
1174 if ( $format == 'array' || $format == 'object' ) {
1175 return $current_slugs;
1176 }
1177
1178 // HTML Rel (tag/no-follow)
1179 $rel = $this->buildRel( $no_follow );
1180
1181 foreach ( $current_slugs as $slug ) {
1182 // Get term by slug
1183 $term = get_term_by('slug', $slug, 'post_tag');
1184 if ( !is_object($term) ) {
1185 continue;
1186 }
1187
1188 $element_loop = $xformat;
1189 $element_loop = $this->formatInternalTag( $element_loop, $term, $rel, null );
1190 // Specific marker
1191 $element_loop = str_replace('%tag_link_remove%', $this->getRemoveTagToLink( $current_slugs, $term->slug, $url_tag_sep ), $element_loop);
1192 $output[] = $element_loop;
1193 }
1194
1195 // Clean memory
1196 $current_slugs = array();
1197 unset($current_slugs, $slug, $element_loop);
1198
1199 return $this->outputContent( 'st-remove-related-tags', $format, '', $output );
1200 }
1201
1202 /**
1203 * Build tag url without a specifik tag
1204 *
1205 * @param array $current_slugs
1206 * @param string $tag_slug
1207 * @param string $separator
1208 * @return string
1209 */
1210 function getRemoveTagToLink( $current_slugs = array(), $tag_slug = '', $separator = ',' ) {
1211 // Remove tag slug to current slugs
1212 $key = array_search($tag_slug, $current_slugs);
1213 unset($current_slugs[$key]);
1214
1215 // Array to string with good separator
1216 $slugs = implode( $separator, $current_slugs );
1217
1218 global $wp_rewrite;
1219 $taglink = $wp_rewrite->get_tag_permastruct();
1220
1221 if ( empty($taglink) ) { // No permalink
1222 $taglink = $this->info['home'] . '/?tag=' . $slugs;
1223 } else { // Custom permalink
1224 $taglink = $this->info['home'] . user_trailingslashit( str_replace('%tag%', $slugs, $taglink), 'category');
1225 }
1226 return apply_filters('st_remove_tag_link', clean_url($taglink));
1227 }
1228
1229 /**
1230 * Sort an array without accent for naturel order :)
1231 *
1232 * @param string $a
1233 * @param string $b
1234 * @return boolean
1235 */
1236 function uksortByName( $a = '', $b = '' ) {
1237 return strnatcasecmp( remove_accents($a), remove_accents($b) );
1238 }
1239
1240 /**
1241 * Generate extended tag cloud
1242 *
1243 * @param string $args
1244 * @return string|array
1245 */
1246 function extendedTagCloud( $args = '', $copyright = true ) {
1247 $defaults = array(
1248 'size' => 'true',
1249 'smallest' => 8,
1250 'largest' => 22,
1251 'unit' => 'pt',
1252 'color' => 'true',
1253 'maxcolor' => '#000000',
1254 'mincolor' => '#CCCCCC',
1255 'number' => 45,
1256 'format' => 'flat',
1257 'cloud_selection' => 'count-desc',
1258 'cloud_sort' => 'random',
1259 'exclude' => '',
1260 'include' => '',
1261 'no_follow' => 0,
1262 'limit_days' => 0,
1263 'min_usage' => 0,
1264 'inc_cats' => 0,
1265 'notagstext' => __('No tags.', 'simpletags'),
1266 'xformat' => __('<a href="%tag_link%" id="tag-link-%tag_id%" class="st-tags t%tag_scale%" title="%tag_count% topics" %tag_rel% style="%tag_size% %tag_color%">%tag_name%</a>', 'simpletags'),
1267 'title' => __('<h4>Tag Cloud</h4>', 'simpletags'),
1268 'category' => 0
1269 );
1270
1271 // Get values in DB
1272 $defaults['no_follow'] = $this->options['no_follow'];
1273 $defaults['cloud_selection'] = $this->options['cloud_selection'];
1274 $defaults['cloud_sort'] = $this->options['cloud_sort'];
1275 $defaults['number'] = $this->options['cloud_limit_qty'];
1276 $defaults['notagstext'] = $this->options['cloud_notagstext'];
1277 $defaults['title'] = $this->options['cloud_title'];
1278 $defaults['maxcolor'] = $this->options['cloud_max_color'];
1279 $defaults['mincolor'] = $this->options['cloud_min_color'];
1280 $defaults['largest'] = $this->options['cloud_max_size'];
1281 $defaults['smallest'] = $this->options['cloud_min_size'];
1282 $defaults['unit'] = $this->options['cloud_unit'];
1283 $defaults['xformat'] = $this->options['cloud_xformat'];
1284 $defaults['format'] = $this->options['cloud_format'];
1285 $defaults['inc_cats'] = $this->options['cloud_inc_cats'];
1286
1287 if ( empty($args) ) {
1288 $args = $this->options['cloud_adv_usage'];
1289 }
1290 $args = wp_parse_args( $args, $defaults );
1291
1292 // Get categories ?
1293 $taxonomy = ( (int) $args['inc_cats'] == 0 ) ? 'post_tag' : array('post_tag', 'category');
1294
1295 // Get terms
1296 $terms = $this->getTags( $args, $this->use_cache, $taxonomy );
1297 extract($args); // Params to variables
1298
1299 // If empty use default xformat !
1300 if ( empty($xformat) ) {
1301 $xformat = $defaults['xformat'];
1302 }
1303
1304 // Clean memory
1305 $args = array();
1306 $defaults = array();
1307 unset($args, $defaults);
1308
1309 if ( empty($terms) ) {
1310 return $this->outputContent( 'st-tag-cloud', $format, $title, $notagstext, $copyright );
1311 }
1312
1313 $counts = $terms_data = array();
1314 foreach ( (array) $terms as $term ) {
1315 $counts[$term->name] = $term->count;
1316 $terms_data[$term->name] = $term;
1317 }
1318
1319 // Remove temp data from memory
1320 $terms = array();
1321 unset($terms);
1322
1323 // Use full RBG code
1324 if ( strlen($maxcolor) == 4 ) {
1325 $maxcolor = $maxcolor . substr($maxcolor, 1, strlen($maxcolor));
1326 }
1327 if ( strlen($mincolor) == 4 ) {
1328 $mincolor = $mincolor . substr($mincolor, 1, strlen($mincolor));
1329 }
1330
1331 // Check as smallest inferior or egal to largest
1332 if ( $smallest > $largest ) {
1333 $smallest = $largest;
1334 }
1335
1336 // Scaling - Hard value for the moment
1337 $scale_min = 1;
1338 $scale_max = 10;
1339
1340 $minval = min($counts);
1341 $maxval = max($counts);;
1342
1343 $minout = max($scale_min, 0);
1344 $maxout = max($scale_max, $minout);
1345
1346 $scale = ($maxval > $minval) ? (($maxout - $minout) / ($maxval - $minval)) : 0;
1347
1348 // HTML Rel (tag/no-follow)
1349 $rel = $this->buildRel( $no_follow );
1350
1351 // Remove color marquer if color = false
1352 if ( $color == 'false' ) {
1353 $xformat = str_replace('%tag_color%', '', $xformat);
1354 }
1355
1356 // Remove size marquer if size = false
1357 if ( $size == 'false' ) {
1358 $xformat = str_replace('%tag_size%', '', $xformat);
1359 }
1360
1361 // Order terms before output
1362 // count-asc/count-desc/name-asc/name-desc/random
1363 $cloud_sort = strtolower($cloud_sort);
1364 switch ( $cloud_sort ) {
1365 case 'count-asc':
1366 asort($counts);
1367 break;
1368 case 'count-desc':
1369 arsort($counts);
1370 break;
1371 case 'name-asc':
1372 uksort($counts, array( &$this, 'uksortByName'));
1373 break;
1374 case 'name-desc':
1375 uksort($counts, array( &$this, 'uksortByName'));
1376 array_reverse($counts);
1377 break;
1378 default: // random
1379 $counts = $this->randomArray($counts);
1380 break;
1381 }
1382
1383 $output = array();
1384 foreach ( (array) $counts as $term_name => $count ) {
1385 if ( !is_object($terms_data[$term_name]) ) {
1386 continue;
1387 }
1388
1389 $term = $terms_data[$term_name];
1390 $scale_result = (int) (($term->count - $minval) * $scale + $minout);
1391 $output[] = $this->formatInternalTag( $xformat, $term, $rel, $scale_result, $scale_max, $scale_min, $largest, $smallest, $unit, $maxcolor, $mincolor );
1392 }
1393
1394 // Remove unused variables
1395 $counts = array();
1396 $terms = array();
1397 unset($counts, $terms, $element_loop, $term);
1398
1399 return $this->outputContent( 'st-tag-cloud', $format, $title, $output, $copyright );
1400 }
1401
1402 /**
1403 * Randomize an array and keep association
1404 *
1405 * @param array $data
1406 * @return array
1407 */
1408 function randomArray( $data_in = array() ) {
1409 if ( empty($data_in) ) {
1410 return $data_in;
1411 }
1412
1413 srand( (float) microtime() * 1000000 ); // For PHP < 4.2
1414 $rand_keys = array_rand($data_in, count($data_in));
1415
1416 foreach( (array) $rand_keys as $key ) {
1417 $data_out[$key] = $data_in[$key];
1418 }
1419
1420 return $data_out;
1421 }
1422
1423 /**
1424 * Remplace marker by dynamic values (use for related tags, current tags and tag cloud)
1425 *
1426 * @param string $element_loop
1427 * @param object $term
1428 * @param string $rel
1429 * @param integer $scale_result
1430 * @param integer $scale_max
1431 * @param integer $scale_min
1432 * @param integer $largest
1433 * @param integer $smallest
1434 * @param string $unit
1435 * @param string $maxcolor
1436 * @param string $mincolor
1437 * @return string
1438 */
1439 function formatInternalTag( $element_loop = '', $term = null, $rel = '', $scale_result = 0, $scale_max = null, $scale_min = 0, $largest = 0, $smallest = 0, $unit = '', $maxcolor = '', $mincolor = '' ) {
1440 // Need term object
1441 if ( $term->taxonomy == 'post_tag' ) { // Tag post
1442 $element_loop = str_replace('%tag_link%', clean_url(get_tag_link($term->term_id)), $element_loop);
1443 $element_loop = str_replace('%tag_feed%', clean_url(get_tag_feed_link($term->term_id)), $element_loop);
1444 } else { // Category
1445 $element_loop = str_replace('%tag_link%', clean_url(get_category_link($term->term_id)), $element_loop);
1446 $element_loop = str_replace('%tag_feed%', clean_url(get_category_rss_link(false, $term->term_id, '')), $element_loop);
1447 }
1448 $element_loop = str_replace('%tag_name%', wp_specialchars( $term->name ), $element_loop);
1449 $element_loop = str_replace('%tag_name_attribute%', wp_specialchars(strip_tags($term->name)), $element_loop);
1450 $element_loop = str_replace('%tag_id%', $term->term_id, $element_loop);
1451 $element_loop = str_replace('%tag_count%', (int) $term->count, $element_loop);
1452
1453 // Need rel
1454 $element_loop = str_replace('%tag_rel%', $rel, $element_loop);
1455
1456 // Need max/min/scale and other :)
1457 if ( $scale_result !== null ) {
1458 $element_loop = str_replace('%tag_size%', 'font-size:'.round(($scale_result - $scale_min)*($largest-$smallest)/($scale_max - $scale_min) + $smallest, 2).$unit.';', $element_loop);
1459 $element_loop = str_replace('%tag_color%', 'color:'.$this->getColorByScale(round(($scale_result - $scale_min)*(100)/($scale_max - $scale_min), 2),$mincolor,$maxcolor).';', $element_loop);
1460 $element_loop = str_replace('%tag_scale%', $scale_result, $element_loop);
1461 }
1462
1463 // External link
1464 $element_loop = str_replace('%tag_technorati%', $this->formatExternalTag( 'technorati', $term->name ), $element_loop);
1465 $element_loop = str_replace('%tag_flickr%', $this->formatExternalTag( 'flickr', $term->name ), $element_loop);
1466 $element_loop = str_replace('%tag_delicious%', $this->formatExternalTag( 'delicious', $term->name ), $element_loop);
1467
1468 return $element_loop;
1469 }
1470
1471 /**
1472 * Format nice URL depending service
1473 *
1474 * @param string $type
1475 * @param string $tag_name
1476 * @return string
1477 */
1478 function formatExternalTag( $type = '', $term_name = '' ) {
1479 if ( empty($term_name) ) {
1480 return '';
1481 }
1482
1483 $term_name = wp_specialchars($term_name);
1484 switch ( $type ) {
1485 case 'technorati':
1486 $link = clean_url('http://technorati.com/tag/'.str_replace(' ', '+', $term_name));
1487 return '<a class="tag_technorati" href="'.$link.'" rel="tag">'.$term_name.'</a>';
1488 break;
1489 case 'flickr':
1490 $link = clean_url('http://www.flickr.com/photos/tags/'.preg_replace('/[^a-zA-Z0-9]/', '', strtolower($term_name)).'/');
1491 return '<a class="tag_flickr" href="'.$link.'" rel="tag">'.$term_name.'</a>';
1492 break;
1493 case 'delicious':
1494 $link = clean_url('http://del.icio.us/popular/'.strtolower(str_replace(' ', '', $term_name)));
1495 return '<a class="tag_delicious" href="'.$link.'" rel="tag">'.$term_name.'</a>';
1496 break;
1497 default:
1498 return '';
1499 break;
1500 }
1501 }
1502
1503 /**
1504 * Generate current post tags
1505 *
1506 * @param string $args
1507 * @return string
1508 */
1509 function extendedPostTags( $args = '', $copyright = true ) {
1510 $defaults = array(
1511 'before' => __('Tags: ', 'simpletags'),
1512 'separator' => ', ',
1513 'after' => '<br />',
1514 'post_id' => 0,
1515 'no_follow' => 0,
1516 'inc_cats' => 0,
1517 'xformat' => __('<a href="%tag_link%" title="%tag_name_attribute%" %tag_rel%>%tag_name%</a>', 'simpletags'),
1518 'notagtext' => __('No tag for this post.', 'simpletags'),
1519 'number' => 0,
1520 'format' => ''
1521 );
1522
1523 // Get values in DB
1524 $defaults['before'] = $this->options['tt_before'];
1525 $defaults['separator'] = $this->options['tt_separator'];
1526 $defaults['after'] = $this->options['tt_after'];
1527 $defaults['no_follow'] = (int) $this->options['no_follow'];
1528 $defaults['inc_cats'] = $this->options['tt_inc_cats'];
1529 $defaults['xformat'] = $this->options['tt_xformat'];
1530 $defaults['notagtext'] = $this->options['tt_notagstext'];
1531 $defaults['number'] = (int) $this->options['tt_number'];
1532 if ( empty($args) ) {
1533 $args = $this->options['tt_adv_usage'];
1534 }
1535
1536 // Extract data in variables
1537 $args = wp_parse_args( $args, $defaults );
1538 extract($args);
1539
1540 // If empty use default xformat !
1541 if ( empty($xformat) ) {
1542 $xformat = $defaults['xformat'];
1543 }
1544
1545 // Clean memory
1546 $args = array();
1547 $defaults = array();
1548
1549 // Choose post ID
1550 $object_id = (int) $post_id;
1551 if ( $object_id == 0 ) {
1552 global $post;
1553 $object_id = (int) $post->ID;
1554 if ( $object_id == 0 ) {
1555 return false;
1556 }
1557 }
1558
1559 // Get categories ?
1560 $taxonomy = ( (int) $inc_cats == 0 ) ? 'post_tag' : array('post_tag', 'category');
1561 // Get terms
1562 $terms = apply_filters( 'get_the_tags', wp_get_object_terms($object_id, $taxonomy) );
1563
1564 // Limit to max quantity if set
1565 $number = (int) $number;
1566 if ( $number != 0 ) {
1567 shuffle($terms); // Randomize terms
1568 $terms = array_slice( $terms, 0, $number );
1569 }
1570
1571 // Return for object format
1572 if ( $format == 'object' ) {
1573 return $terms;
1574 }
1575
1576 // If no terms, return text nothing.
1577 if ( empty($terms) ) {
1578 return $notagtext;
1579 }
1580
1581 // HTML Rel (tag/no-follow)
1582 $rel = $this->buildRel( $no_follow );
1583
1584 // Prepare output
1585 foreach ( (array) $terms as $term ) {
1586 if ( !is_object($term) ) {
1587 continue;
1588 }
1589
1590 $output[] = $this->formatInternalTag( $xformat, $term, $rel, null );
1591 }
1592
1593 // Clean memory
1594 $terms = array();
1595 unset($terms, $term);
1596
1597
1598 // Array to string
1599 if ( is_array($output) && !empty($output) ) {
1600 $output = implode($separator, $output);
1601 } else {
1602 $output = $notagtext;
1603 }
1604
1605 // Add container
1606 $output = $before . $output . $after;
1607
1608 return $this->outputContent( '', 'string', '', $output, $copyright );
1609 }
1610
1611 /**
1612 * Build rel for tag link
1613 *
1614 * @param integer $no_follow
1615 * @return string
1616 */
1617 function buildRel( $no_follow = 1 ) {
1618 $rel = '';
1619
1620 global $wp_rewrite;
1621 $rel .= ( is_object($wp_rewrite) && $wp_rewrite->using_permalinks() ) ? 'tag' : ''; // Tag ?
1622
1623 $no_follow = (int) $no_follow;
1624 if ( $no_follow == 1 ) { // No follow ?
1625 $rel .= ( empty($rel) ) ? 'nofollow' : ' nofollow';
1626 }
1627
1628 if ( !empty($rel) ) {
1629 $rel = 'rel="' . $rel . '"'; // Add HTML Tag
1630 }
1631
1632 return $rel;
1633 }
1634
1635 /**
1636 * Delete embedded tags
1637 *
1638 * @param string $content
1639 * @return string
1640 */
1641 function filterEmbedTags( $content ) {
1642 $tag_start = $this->options['start_embed_tags'];
1643 $tag_end = $this->options['end_embed_tags'];
1644 $len_tagend = strlen($tag_end);
1645
1646 while ( strpos($content, $tag_start) != false && strpos($content, $tag_end) != false ) {
1647 $pos1 = strpos($content, $tag_start);
1648 $pos2 = strpos($content, $tag_end);
1649 $content = str_replace(substr($content, $pos1, ($pos2 - $pos1 + $len_tagend)), '', $content);
1650 }
1651 return $content;
1652 }
1653
1654 /**
1655 * This is pretty filthy. Doing math in hex is much too weird. It's more likely to work, this way!
1656 * Provided from UTW. Thanks.
1657 *
1658 * @param integer $scale_color
1659 * @param string $min_color
1660 * @param string $max_color
1661 * @return string
1662 */
1663 function getColorByScale($scale_color, $min_color, $max_color) {
1664 $scale_color = $scale_color / 100;
1665
1666 $minr = hexdec(substr($min_color, 1, 2));
1667 $ming = hexdec(substr($min_color, 3, 2));
1668 $minb = hexdec(substr($min_color, 5, 2));
1669
1670 $maxr = hexdec(substr($max_color, 1, 2));
1671 $maxg = hexdec(substr($max_color, 3, 2));
1672 $maxb = hexdec(substr($max_color, 5, 2));
1673
1674 $r = dechex(intval((($maxr - $minr) * $scale_color) + $minr));
1675 $g = dechex(intval((($maxg - $ming) * $scale_color) + $ming));
1676 $b = dechex(intval((($maxb - $minb) * $scale_color) + $minb));
1677
1678 if (strlen($r) == 1) $r = '0'.$r;
1679 if (strlen($g) == 1) $g = '0'.$g;
1680 if (strlen($b) == 1) $b = '0'.$b;
1681
1682 return '#'.$r.$g.$b;
1683 }
1684
1685 /**
1686 * Add page in tag search
1687 *
1688 * @param string $where
1689 * @return string
1690 */
1691 function prepareQuery( $where ) {
1692 if ( is_tag() ) {
1693 $where = str_replace('post_type = \'post\'', 'post_type IN(\'page\', \'post\')', $where);
1694 }
1695 return $where;
1696 }
1697
1698 /**
1699 * Reset to default options
1700 *
1701 */
1702 function resetToDefaultOptions() {
1703 update_option($this->db_options, $this->default_options);
1704 $this->options = $this->default_options;
1705 }
1706
1707 /**
1708 * Extended get_tags function that use getTerms function
1709 *
1710 * @param string $args
1711 * @return array
1712 */
1713 function getTags( $args = '', $skip_cache = false, $taxonomy = 'post_tag', $internal_st = false ) {
1714 if ( $skip_cache == true ) {
1715 $terms = $this->getTerms( $taxonomy, $args, $skip_cache, $internal_st );
1716 } else {
1717 $key = md5(serialize($args.$taxonomy));
1718
1719 // Get cache if exist
1720 if ( $cache = wp_cache_get( 'st_get_tags', 'simpletags' ) ) {
1721 if ( isset( $cache[$key] ) ) {
1722 return apply_filters('get_tags', $cache[$key], $args);
1723 }
1724 }
1725
1726 // Get tags
1727 $terms = $this->getTerms( $taxonomy, $args, $skip_cache, $internal_st );
1728 if ( empty($terms) ) {
1729 return array();
1730 }
1731
1732 $cache[$key] = $terms;
1733 wp_cache_set( 'st_get_tags', $cache, 'simpletags' );
1734 }
1735
1736 $terms = apply_filters('get_tags', $terms, $args);
1737 return $terms;
1738 }
1739
1740 /**
1741 * Extended get_terms function support
1742 * - Limit category
1743 * - Limit days
1744 * - Selection restrict
1745 * - Min usage
1746 *
1747 * @param string|array $taxonomies
1748 * @param string $args
1749 * @return array
1750 */
1751 function getTerms( $taxonomies, $args = '', $skip_cache = false, $internal_st = false ) {
1752 global $wpdb;
1753 $empty_array = array();
1754
1755 $single_taxonomy = false;
1756 if ( !is_array($taxonomies) ) {
1757 $single_taxonomy = true;
1758 $taxonomies = array($taxonomies);
1759 }
1760
1761 foreach ( $taxonomies as $taxonomy ) {
1762 if ( ! is_taxonomy($taxonomy) ) {
1763 return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy'));
1764 }
1765 }
1766
1767 $in_taxonomies = "'" . implode("', '", $taxonomies) . "'";
1768
1769 $defaults = array(
1770 'orderby' => 'name',
1771 'order' => 'ASC',
1772 'cloud_selection' => 'count-desc',
1773 'hide_empty' => true,
1774 'exclude' => '',
1775 'include' => '',
1776 'number' => '',
1777 'fields' => 'all',
1778 'slug' => '',
1779 'parent' => '',
1780 'hierarchical' => true,
1781 'child_of' => 0,
1782 'get' => '',
1783 'name__like' => '',
1784 'st_name_like' => '',
1785 'pad_counts' => false,
1786 'offset' => '',
1787 'search' => '',
1788 'limit_days' => 0,
1789 'category' => 0,
1790 'min_usage' => 0
1791 );
1792
1793 $args = wp_parse_args( $args, $defaults );
1794 if ( $internal_st != true ) { // Allow limit :)
1795 $args['number'] = absint( $args['number'] );
1796 }
1797 $args['offset'] = absint( $args['offset'] );
1798 if ( !$single_taxonomy || !is_taxonomy_hierarchical($taxonomies[0]) || '' != $args['parent'] ) {
1799 $args['child_of'] = 0;
1800 $args['hierarchical'] = false;
1801 $args['pad_counts'] = false;
1802 }
1803
1804 if ( 'all' == $args['get'] ) {
1805 $args['child_of'] = 0;
1806 $args['hide_empty'] = 0;
1807 $args['hierarchical'] = false;
1808 $args['pad_counts'] = false;
1809 }
1810 extract($args, EXTR_SKIP);
1811
1812 if ( $child_of ) {
1813 $hierarchy = _get_term_hierarchy($taxonomies[0]);
1814 if ( !isset($hierarchy[$child_of]) )
1815 return $empty_array;
1816 }
1817
1818 if ( $parent ) {
1819 $hierarchy = _get_term_hierarchy($taxonomies[0]);
1820 if ( !isset($hierarchy[$parent]) )
1821 return $empty_array;
1822 }
1823
1824 if ( $skip_cache != true ) {
1825 // $args can be whatever, only use the args defined in defaults to compute the key
1826 $filter_key = ( has_filter('list_terms_exclusions') ) ? serialize($GLOBALS['wp_filter']['list_terms_exclusions']) : '';
1827 $key = md5( serialize( compact(array_keys($defaults)) ) . serialize( $taxonomies ) . $filter_key );
1828 $last_changed = wp_cache_get('last_changed', 'terms');
1829 if ( !$last_changed ) {
1830 $last_changed = time();
1831 wp_cache_set('last_changed', $last_changed, 'terms');
1832 }
1833 $cache_key = "get_terms:$key:$last_changed";
1834
1835 if ( $cache = wp_cache_get( $cache_key, 'terms' ) ) {
1836 $terms = apply_filters('get_terms', $cache, $taxonomies, $args);
1837 return $terms;
1838 }
1839 }
1840
1841 // Restrict category
1842 $category_sql = '';
1843 if ( !empty($category) && $category != '0' ) {
1844 $incategories = preg_split('/[\s,]+/', $category);
1845
1846 $objects_id = get_objects_in_term( $incategories, 'category' );
1847 $objects_id = array_unique ($objects_id); // to be sure haven't duplicates
1848
1849 if ( empty($objects_id) ) { // No posts for this category = no tags for this category
1850 return array();
1851 }
1852
1853 foreach ( (array) $objects_id as $object_id ) {
1854 $category_sql .= "'". $object_id . "', ";
1855 }
1856
1857 $category_sql = substr($category_sql, 0, strlen($category_sql) - 2); // Remove latest ", "
1858 $category_sql = 'AND p.ID IN ('.$category_sql.')';
1859 }
1860
1861 // count-asc/count-desc/name-asc/name-desc/random
1862 $cloud_selection = strtolower($cloud_selection);
1863 switch ( $cloud_selection ) {
1864 case 'count-asc':
1865 $order_by = 'tt.count ASC';
1866 break;
1867 case 'random':
1868 $order_by = 'RAND()';
1869 break;
1870 case 'name-asc':
1871 $order_by = 't.name ASC';
1872 break;
1873 case 'name-desc':
1874 $order_by = 't.name DESC';
1875 break;
1876 default: // count-desc
1877 $order_by = 'tt.count DESC';
1878 break;
1879 }
1880
1881 // Min usage
1882 $restict_usage = '';
1883 $min_usage = (int) $min_usage;
1884 if ( $min_usage != 0 ) {
1885 $restict_usage = ' AND tt.count >= '. $min_usage;
1886 }
1887
1888 $where = '';
1889 $inclusions = '';
1890 if ( !empty($include) ) {
1891 $exclude = '';
1892 $interms = preg_split('/[\s,]+/',$include);
1893 foreach ( (array) $interms as $interm ) {
1894 if (empty($inclusions)) {
1895 $inclusions = ' AND ( t.term_id = ' . intval($interm) . ' ';
1896 } else {
1897 $inclusions .= ' OR t.term_id = ' . intval($interm) . ' ';
1898 }
1899 }
1900 }
1901
1902 if ( !empty($inclusions) ) {
1903 $inclusions .= ')';
1904 }
1905 $where .= $inclusions;
1906
1907 $exclusions = '';
1908 if ( !empty($exclude) ) {
1909 $exterms = preg_split('/[\s,]+/',$exclude);
1910 foreach ( (array) $exterms as $exterm ) {
1911 if (empty($exclusions)) {
1912 $exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' ';
1913 } else {
1914 $exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' ';
1915 }
1916 }
1917 }
1918
1919 if ( !empty($exclusions) ) {
1920 $exclusions .= ')';
1921 }
1922 $exclusions = apply_filters('list_terms_exclusions', $exclusions, $args );
1923 $where .= $exclusions;
1924
1925 if ( !empty($slug) ) {
1926 $slug = sanitize_title($slug);
1927 $where .= " AND t.slug = '$slug'";
1928 }
1929
1930 if ( !empty($name__like) ) {
1931 $where .= " AND t.name LIKE '{$name__like}%'";
1932 }
1933
1934 if ( strpos($st_name_like, ' ') != false || strpos($st_name_like, ' ') != null ) {
1935 $tmp = '';
1936 $sts = explode(' ', $st_name_like);
1937 foreach ( (array) $sts as $st ) {
1938 if ( empty($st) )
1939 continue;
1940
1941 $st = addslashes_gpc($st);
1942 $tmp .= " t.name LIKE '%{$st}%' OR ";
1943 }
1944 // Remove latest OR
1945 $tmp = substr( $tmp, 0, strlen($tmp) - 4);
1946
1947 $where .= " AND ( $tmp ) ";
1948 unset($tmp) ;
1949 } elseif ( !empty($st_name_like) ) {
1950 $where .= " AND t.name LIKE '%{$st_name_like}%'";
1951 }
1952
1953 if ( '' != $parent ) {
1954 $parent = (int) $parent;
1955 $where .= " AND tt.parent = '$parent'";
1956 }
1957
1958 if ( $hide_empty && !$hierarchical ) {
1959 $where .= ' AND tt.count > 0';
1960 }
1961
1962 $number_sql = '';
1963 if ( strpos($number, ',') != false || strpos($number, ',') != null ) {
1964 $number_sql = $number;
1965 } else {
1966 $number = (int) $number;
1967 if ( $number != 0 ) {
1968 $number_sql = 'LIMIT ' . $number;
1969 }
1970 }
1971
1972 if ( !empty($search) ) {
1973 $search = like_escape($search);
1974 $where .= " AND (t.name LIKE '%$search%')";
1975 }
1976
1977 $select_this = '';
1978
1979 if ( 'all' == $fields ) {
1980 $select_this = 't.*, tt.*';
1981 } else if ( 'ids' == $fields ) {
1982 $select_this = 't.term_id, tt.parent, tt.count';
1983 } else if ( 'names' == $fields ) {
1984 $select_this = 't.term_id, tt.parent, tt.count, t.name';
1985 }
1986
1987 // Limit posts date
1988 $limitdays_sql = '';
1989 $limit_days = (int) $limit_days;
1990 if ( $limit_days != 0 ) {
1991 $limitdays_sql = 'AND p.post_date_gmt > "' .date( 'Y-m-d H:i:s', time() - $limit_days * 86400 ). '"';
1992 }
1993
1994 $query = "SELECT {$select_this}
1995 FROM {$wpdb->terms} AS t
1996 INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id
1997 INNER JOIN {$wpdb->term_relationships} AS tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
1998 INNER JOIN {$wpdb->posts} AS p ON tr.object_id = p.ID
1999 WHERE tt.taxonomy IN ( {$in_taxonomies} )
2000 AND p.post_date_gmt < '".current_time('mysql')."'
2001 {$limitdays_sql}
2002 {$category_sql}
2003 {$where}
2004 {$restict_usage}
2005 GROUP BY t.term_id
2006 ORDER BY {$order_by}
2007 {$number_sql}";
2008
2009 if ( 'all' == $fields ) {
2010 $terms = $wpdb->get_results($query);
2011 if ( $skip_cache != true ) {
2012 update_term_cache($terms);
2013 }
2014 } else if ( ('ids' == $fields) || ('names' == $fields) ) {
2015 $terms = $wpdb->get_results($query);
2016 }
2017
2018 if ( empty($terms) ) {
2019 $cache[ $key ] = array();
2020 wp_cache_set( 'get_terms', $cache, 'terms' );
2021 $terms = apply_filters('get_terms', array(), $taxonomies, $args);
2022 return $terms;
2023 }
2024
2025 if ( $child_of ) {
2026 $children = _get_term_hierarchy($taxonomies[0]);
2027 if ( ! empty($children) )
2028 $terms = & _get_term_children($child_of, $terms, $taxonomies[0]);
2029 }
2030
2031 // Update term counts to include children.
2032 if ( $pad_counts && 'all' == $fields )
2033 _pad_term_counts($terms, $taxonomies[0]);
2034
2035 // Make sure we show empty categories that have children.
2036 if ( $hierarchical && $hide_empty && is_array($terms) ) {
2037 foreach ( $terms as $k => $term ) {
2038 if ( ! $term->count ) {
2039 $children = _get_term_children($term->term_id, $terms, $taxonomies[0]);
2040 if( is_array($children) )
2041 foreach ( $children as $child )
2042 if ( $child->count )
2043 continue 2;
2044
2045 // It really is empty
2046 unset($terms[$k]);
2047 }
2048 }
2049 }
2050 reset ( $terms );
2051
2052 $_terms = array();
2053 if ( 'ids' == $fields ) {
2054 while ( $term = array_shift($terms) )
2055 $_terms[] = $term->term_id;
2056 $terms = $_terms;
2057 } elseif ( 'names' == $fields ) {
2058 while ( $term = array_shift($terms) )
2059 $_terms[] = $term->name;
2060 $terms = $_terms;
2061 }
2062
2063 if ( $skip_cache != true ) {
2064 wp_cache_add( $cache_key, $terms, 'terms' );
2065 }
2066
2067 $terms = apply_filters('get_terms', $terms, $taxonomies, $args);
2068 return $terms;
2069 }
2070
2071 /**
2072 * Format data for output
2073 *
2074 * @param string $html_class
2075 * @param string $format
2076 * @param string $title
2077 * @param string $content
2078 * @param boolean $copyright
2079 * @param string $separator
2080 * @return string|array
2081 */
2082 function outputContent( $html_class= '', $format = 'list', $title = '', $content = '', $copyright = true, $separator = '' ) {
2083 if ( empty($content) ) {
2084 return ''; // return nothing
2085 }
2086
2087 if ( $format == 'array' && is_array($content) ) {
2088 return $content; // Return PHP array if format is array
2089 }
2090
2091 if ( is_array($content) ) {
2092 switch ( $format ) {
2093 case 'list' :
2094 $output = '<ul class="'.$html_class.'">'. "\n\t".'<li>' . implode("</li>\n\t<li>", $content) . "</li>\n</ul>\n";
2095 break;
2096 default :
2097 $output = '<div class="'.$html_class.'">'. "\n\t" . implode("{$separator}\n", $content) . "</div>\n";
2098 break;
2099 }
2100 } else {
2101 $content = trim($content);
2102 switch ( $format ) {
2103 case 'string' :
2104 $output = $content;
2105 break;
2106 case 'list' :
2107 $output = '<ul class="'.$html_class.'">'. "\n\t" . '<li>'.$content."</li>\n\t" . "</ul>\n";
2108 break;
2109 default :
2110 $output = '<div class="'.$html_class.'">'. "\n\t" . $content . "</div>\n";
2111 break;
2112 }
2113 }
2114
2115 // Replace false by empty
2116 $title = trim($title);
2117 if ( strtolower($title) == 'false' ) {
2118 $title = '';
2119 }
2120
2121 // Put title if exist
2122 if ( !empty($title) ) {
2123 $title .= "\n\t";
2124 }
2125
2126 if ( $copyright === true )
2127 return "\n" . '<!-- Generated by Simple Tags ' . $this->version . ' - http://wordpress.org/extend/plugins/simple-tags -->' ."\n\t". $title . $output. "\n";
2128 else
2129 return "\n\t". $title . $output. "\n";
2130 }
2131
2132 /**
2133 * Test if local installation is mu-plugin or a classic plugin
2134 *
2135 * @return boolean
2136 */
2137 function isMuPlugin() {
2138 if ( strpos(dirname(__FILE__), 'mu-plugins') ) {
2139 return true;
2140 }
2141 return false;
2142 }
2143
2144 /**
2145 * Update taxonomy counter for post AND page
2146 *
2147 * @param array $terms
2148 */
2149 function _update_post_and_page_term_count( $terms ) {
2150 global $wpdb;
2151 foreach ( (array) $terms as $term ) {
2152 $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts WHERE $wpdb->posts.ID = $wpdb->term_relationships.object_id AND post_status = 'publish' AND post_type IN ('page', 'post') AND term_taxonomy_id = %d", $term ) );
2153 $wpdb->update( $wpdb->term_taxonomy, compact( 'count' ), array( 'term_taxonomy_id' => $term ) );
2154 }
2155 return true;
2156 }
2157}
2158
2159
2160// Init ST
2161global $simple_tags;
2162function st_init() {
2163 global $simple_tags, $simple_tags_admin;
2164 $simple_tags = new SimpleTags();
2165
2166 // Admin and XML-RPC
2167 if ( is_admin() || ( defined('XMLRPC_REQUEST') && XMLRPC_REQUEST ) ) {
2168 require(dirname(__FILE__).'/inc/simple-tags.admin.php');
2169 $simple_tags_admin = new SimpleTagsAdmin( $simple_tags->default_options, $simple_tags->version, $simple_tags->info );
2170
2171 // Activation
2172 register_activation_hook(__FILE__, array(&$simple_tags_admin, 'installSimpleTags') );
2173
2174 // Uninstall
2175 register_uninstall_hook (__FILE__, array(&$simple_tags_admin, 'uninstall') );
2176 }
2177
2178 // Templates functions
2179 require(dirname(__FILE__).'/inc/simple-tags.functions.php');
2180
2181 // Widgets
2182 require(dirname(__FILE__).'/inc/simple-tags.widgets.php');
2183}
2184add_action('plugins_loaded', 'st_init');
2185?>
Note: See TracBrowser for help on using the repository browser.