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

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