~canonical-sysadmins/wordpress/4.7.2

« back to all changes in this revision

Viewing changes to wp-includes/category-template.php

  • Committer: Jacek Nykis
  • Date: 2015-01-05 16:17:05 UTC
  • Revision ID: jacek.nykis@canonical.com-20150105161705-w544l1h5mcg7u4w9
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/**
 
3
 * Category Template Tags and API.
 
4
 *
 
5
 * @package WordPress
 
6
 * @subpackage Template
 
7
 */
 
8
 
 
9
/**
 
10
 * Retrieve category link URL.
 
11
 *
 
12
 * @since 1.0.0
 
13
 * @see get_term_link()
 
14
 *
 
15
 * @param int|object $category Category ID or object.
 
16
 * @return string Link on success, empty string if category does not exist.
 
17
 */
 
18
function get_category_link( $category ) {
 
19
        if ( ! is_object( $category ) )
 
20
                $category = (int) $category;
 
21
 
 
22
        $category = get_term_link( $category, 'category' );
 
23
 
 
24
        if ( is_wp_error( $category ) )
 
25
                return '';
 
26
 
 
27
        return $category;
 
28
}
 
29
 
 
30
/**
 
31
 * Retrieve category parents with separator.
 
32
 *
 
33
 * @since 1.2.0
 
34
 *
 
35
 * @param int $id Category ID.
 
36
 * @param bool $link Optional, default is false. Whether to format with link.
 
37
 * @param string $separator Optional, default is '/'. How to separate categories.
 
38
 * @param bool $nicename Optional, default is false. Whether to use nice name for display.
 
39
 * @param array $visited Optional. Already linked to categories to prevent duplicates.
 
40
 * @return string|WP_Error A list of category parents on success, WP_Error on failure.
 
41
 */
 
42
function get_category_parents( $id, $link = false, $separator = '/', $nicename = false, $visited = array() ) {
 
43
        $chain = '';
 
44
        $parent = get_term( $id, 'category' );
 
45
        if ( is_wp_error( $parent ) )
 
46
                return $parent;
 
47
 
 
48
        if ( $nicename )
 
49
                $name = $parent->slug;
 
50
        else
 
51
                $name = $parent->name;
 
52
 
 
53
        if ( $parent->parent && ( $parent->parent != $parent->term_id ) && !in_array( $parent->parent, $visited ) ) {
 
54
                $visited[] = $parent->parent;
 
55
                $chain .= get_category_parents( $parent->parent, $link, $separator, $nicename, $visited );
 
56
        }
 
57
 
 
58
        if ( $link )
 
59
                $chain .= '<a href="' . esc_url( get_category_link( $parent->term_id ) ) . '">'.$name.'</a>' . $separator;
 
60
        else
 
61
                $chain .= $name.$separator;
 
62
        return $chain;
 
63
}
 
64
 
 
65
/**
 
66
 * Retrieve post categories.
 
67
 *
 
68
 * @since 0.71
 
69
 * @uses $post
 
70
 *
 
71
 * @param int $id Optional, default to current post ID. The post ID.
 
72
 * @return array
 
73
 */
 
74
function get_the_category( $id = false ) {
 
75
        $categories = get_the_terms( $id, 'category' );
 
76
        if ( ! $categories || is_wp_error( $categories ) )
 
77
                $categories = array();
 
78
 
 
79
        $categories = array_values( $categories );
 
80
 
 
81
        foreach ( array_keys( $categories ) as $key ) {
 
82
                _make_cat_compat( $categories[$key] );
 
83
        }
 
84
 
 
85
        /**
 
86
         * Filter the array of categories to return for a post.
 
87
         *
 
88
         * @since 3.1.0
 
89
         *
 
90
         * @param array $categories An array of categories to return for the post.
 
91
         */
 
92
        return apply_filters( 'get_the_categories', $categories );
 
93
}
 
94
 
 
95
/**
 
96
 * Sort categories by name.
 
97
 *
 
98
 * Used by usort() as a callback, should not be used directly. Can actually be
 
99
 * used to sort any term object.
 
100
 *
 
101
 * @since 2.3.0
 
102
 * @access private
 
103
 *
 
104
 * @param object $a
 
105
 * @param object $b
 
106
 * @return int
 
107
 */
 
108
function _usort_terms_by_name( $a, $b ) {
 
109
        return strcmp( $a->name, $b->name );
 
110
}
 
111
 
 
112
/**
 
113
 * Sort categories by ID.
 
114
 *
 
115
 * Used by usort() as a callback, should not be used directly. Can actually be
 
116
 * used to sort any term object.
 
117
 *
 
118
 * @since 2.3.0
 
119
 * @access private
 
120
 *
 
121
 * @param object $a
 
122
 * @param object $b
 
123
 * @return int
 
124
 */
 
125
function _usort_terms_by_ID( $a, $b ) {
 
126
        if ( $a->term_id > $b->term_id )
 
127
                return 1;
 
128
        elseif ( $a->term_id < $b->term_id )
 
129
                return -1;
 
130
        else
 
131
                return 0;
 
132
}
 
133
 
 
134
/**
 
135
 * Retrieve category name based on category ID.
 
136
 *
 
137
 * @since 0.71
 
138
 *
 
139
 * @param int $cat_ID Category ID.
 
140
 * @return string|WP_Error Category name on success, WP_Error on failure.
 
141
 */
 
142
function get_the_category_by_ID( $cat_ID ) {
 
143
        $cat_ID = (int) $cat_ID;
 
144
        $category = get_term( $cat_ID, 'category' );
 
145
 
 
146
        if ( is_wp_error( $category ) )
 
147
                return $category;
 
148
 
 
149
        return ( $category ) ? $category->name : '';
 
150
}
 
151
 
 
152
/**
 
153
 * Retrieve category list in either HTML list or custom format.
 
154
 *
 
155
 * @since 1.5.1
 
156
 *
 
157
 * @param string $separator Optional, default is empty string. Separator for between the categories.
 
158
 * @param string $parents Optional. How to display the parents.
 
159
 * @param int $post_id Optional. Post ID to retrieve categories.
 
160
 * @return string
 
161
 */
 
162
function get_the_category_list( $separator = '', $parents='', $post_id = false ) {
 
163
        global $wp_rewrite;
 
164
        if ( ! is_object_in_taxonomy( get_post_type( $post_id ), 'category' ) ) {
 
165
                /** This filter is documented in wp-includes/category-template.php */
 
166
                return apply_filters( 'the_category', '', $separator, $parents );
 
167
        }
 
168
 
 
169
        $categories = get_the_category( $post_id );
 
170
        if ( empty( $categories ) ) {
 
171
                /** This filter is documented in wp-includes/category-template.php */
 
172
                return apply_filters( 'the_category', __( 'Uncategorized' ), $separator, $parents );
 
173
        }
 
174
 
 
175
        $rel = ( is_object( $wp_rewrite ) && $wp_rewrite->using_permalinks() ) ? 'rel="category tag"' : 'rel="category"';
 
176
 
 
177
        $thelist = '';
 
178
        if ( '' == $separator ) {
 
179
                $thelist .= '<ul class="post-categories">';
 
180
                foreach ( $categories as $category ) {
 
181
                        $thelist .= "\n\t<li>";
 
182
                        switch ( strtolower( $parents ) ) {
 
183
                                case 'multiple':
 
184
                                        if ( $category->parent )
 
185
                                                $thelist .= get_category_parents( $category->parent, true, $separator );
 
186
                                        $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name.'</a></li>';
 
187
                                        break;
 
188
                                case 'single':
 
189
                                        $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '"  ' . $rel . '>';
 
190
                                        if ( $category->parent )
 
191
                                                $thelist .= get_category_parents( $category->parent, false, $separator );
 
192
                                        $thelist .= $category->name.'</a></li>';
 
193
                                        break;
 
194
                                case '':
 
195
                                default:
 
196
                                        $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name.'</a></li>';
 
197
                        }
 
198
                }
 
199
                $thelist .= '</ul>';
 
200
        } else {
 
201
                $i = 0;
 
202
                foreach ( $categories as $category ) {
 
203
                        if ( 0 < $i )
 
204
                                $thelist .= $separator;
 
205
                        switch ( strtolower( $parents ) ) {
 
206
                                case 'multiple':
 
207
                                        if ( $category->parent )
 
208
                                                $thelist .= get_category_parents( $category->parent, true, $separator );
 
209
                                        $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name.'</a>';
 
210
                                        break;
 
211
                                case 'single':
 
212
                                        $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>';
 
213
                                        if ( $category->parent )
 
214
                                                $thelist .= get_category_parents( $category->parent, false, $separator );
 
215
                                        $thelist .= "$category->name</a>";
 
216
                                        break;
 
217
                                case '':
 
218
                                default:
 
219
                                        $thelist .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name.'</a>';
 
220
                        }
 
221
                        ++$i;
 
222
                }
 
223
        }
 
224
 
 
225
        /**
 
226
         * Filter the category or list of categories.
 
227
         *
 
228
         * @since 1.2.0
 
229
         *
 
230
         * @param array  $thelist   List of categories for the current post.
 
231
         * @param string $separator Separator used between the categories.
 
232
         * @param string $parents   How to display the category parents. Accepts 'multiple',
 
233
         *                          'single', or empty.
 
234
         */
 
235
        return apply_filters( 'the_category', $thelist, $separator, $parents );
 
236
}
 
237
 
 
238
/**
 
239
 * Check if the current post in within any of the given categories.
 
240
 *
 
241
 * The given categories are checked against the post's categories' term_ids, names and slugs.
 
242
 * Categories given as integers will only be checked against the post's categories' term_ids.
 
243
 *
 
244
 * Prior to v2.5 of WordPress, category names were not supported.
 
245
 * Prior to v2.7, category slugs were not supported.
 
246
 * Prior to v2.7, only one category could be compared: in_category( $single_category ).
 
247
 * Prior to v2.7, this function could only be used in the WordPress Loop.
 
248
 * As of 2.7, the function can be used anywhere if it is provided a post ID or post object.
 
249
 *
 
250
 * @since 1.2.0
 
251
 * @uses has_category()
 
252
 *
 
253
 * @param int|string|array $category Category ID, name or slug, or array of said.
 
254
 * @param int|object $post Optional. Post to check instead of the current post. (since 2.7.0)
 
255
 * @return bool True if the current post is in any of the given categories.
 
256
 */
 
257
function in_category( $category, $post = null ) {
 
258
        if ( empty( $category ) )
 
259
                return false;
 
260
 
 
261
        return has_category( $category, $post );
 
262
}
 
263
 
 
264
/**
 
265
 * Display the category list for the post.
 
266
 *
 
267
 * @since 0.71
 
268
 *
 
269
 * @param string $separator Optional, default is empty string. Separator for between the categories.
 
270
 * @param string $parents Optional. How to display the parents.
 
271
 * @param int $post_id Optional. Post ID to retrieve categories.
 
272
 */
 
273
function the_category( $separator = '', $parents='', $post_id = false ) {
 
274
        echo get_the_category_list( $separator, $parents, $post_id );
 
275
}
 
276
 
 
277
/**
 
278
 * Retrieve category description.
 
279
 *
 
280
 * @since 1.0.0
 
281
 *
 
282
 * @param int $category Optional. Category ID. Will use global category ID by default.
 
283
 * @return string Category description, available.
 
284
 */
 
285
function category_description( $category = 0 ) {
 
286
        return term_description( $category, 'category' );
 
287
}
 
288
 
 
289
/**
 
290
 * Display or retrieve the HTML dropdown list of categories.
 
291
 *
 
292
 * The list of arguments is below:
 
293
 *     'show_option_all' (string) - Text to display for showing all categories.
 
294
 *     'show_option_none' (string) - Text to display for showing no categories.
 
295
 *     'option_none_value' (mixed) - Value to use when no category is selected.
 
296
 *     'orderby' (string) default is 'ID' - What column to use for ordering the
 
297
 * categories.
 
298
 *     'order' (string) default is 'ASC' - What direction to order categories.
 
299
 *     'show_count' (bool|int) default is 0 - Whether to show how many posts are
 
300
 * in the category.
 
301
 *     'hide_empty' (bool|int) default is 1 - Whether to hide categories that
 
302
 * don't have any posts attached to them.
 
303
 *     'child_of' (int) default is 0 - See {@link get_categories()}.
 
304
 *     'exclude' (string) - See {@link get_categories()}.
 
305
 *     'echo' (bool|int) default is 1 - Whether to display or retrieve content.
 
306
 *     'depth' (int) - The max depth.
 
307
 *     'tab_index' (int) - Tab index for select element.
 
308
 *     'name' (string) - The name attribute value for select element.
 
309
 *     'id' (string) - The ID attribute value for select element. Defaults to name if omitted.
 
310
 *     'class' (string) - The class attribute value for select element.
 
311
 *     'selected' (int) - Which category ID is selected.
 
312
 *     'taxonomy' (string) - The name of the taxonomy to retrieve. Defaults to category.
 
313
 *
 
314
 * The 'hierarchical' argument, which is disabled by default, will override the
 
315
 * depth argument, unless it is true. When the argument is false, it will
 
316
 * display all of the categories. When it is enabled it will use the value in
 
317
 * the 'depth' argument.
 
318
 *
 
319
 * @since 2.1.0
 
320
 *
 
321
 * @param string|array $args Optional. Override default arguments.
 
322
 * @return string HTML content only if 'echo' argument is 0.
 
323
 */
 
324
function wp_dropdown_categories( $args = '' ) {
 
325
        $defaults = array(
 
326
                'show_option_all' => '', 'show_option_none' => '',
 
327
                'orderby' => 'id', 'order' => 'ASC',
 
328
                'show_count' => 0,
 
329
                'hide_empty' => 1, 'child_of' => 0,
 
330
                'exclude' => '', 'echo' => 1,
 
331
                'selected' => 0, 'hierarchical' => 0,
 
332
                'name' => 'cat', 'id' => '',
 
333
                'class' => 'postform', 'depth' => 0,
 
334
                'tab_index' => 0, 'taxonomy' => 'category',
 
335
                'hide_if_empty' => false, 'option_none_value' => -1
 
336
        );
 
337
 
 
338
        $defaults['selected'] = ( is_category() ) ? get_query_var( 'cat' ) : 0;
 
339
 
 
340
        // Back compat.
 
341
        if ( isset( $args['type'] ) && 'link' == $args['type'] ) {
 
342
                _deprecated_argument( __FUNCTION__, '3.0', '' );
 
343
                $args['taxonomy'] = 'link_category';
 
344
        }
 
345
 
 
346
        $r = wp_parse_args( $args, $defaults );
 
347
        $option_none_value = $r['option_none_value'];
 
348
 
 
349
        if ( ! isset( $r['pad_counts'] ) && $r['show_count'] && $r['hierarchical'] ) {
 
350
                $r['pad_counts'] = true;
 
351
        }
 
352
 
 
353
        $tab_index = $r['tab_index'];
 
354
 
 
355
        $tab_index_attribute = '';
 
356
        if ( (int) $tab_index > 0 ) {
 
357
                $tab_index_attribute = " tabindex=\"$tab_index\"";
 
358
        }
 
359
        $categories = get_terms( $r['taxonomy'], $r );
 
360
        $name = esc_attr( $r['name'] );
 
361
        $class = esc_attr( $r['class'] );
 
362
        $id = $r['id'] ? esc_attr( $r['id'] ) : $name;
 
363
 
 
364
        if ( ! $r['hide_if_empty'] || ! empty( $categories ) ) {
 
365
                $output = "<select name='$name' id='$id' class='$class' $tab_index_attribute>\n";
 
366
        } else {
 
367
                $output = '';
 
368
        }
 
369
        if ( empty( $categories ) && ! $r['hide_if_empty'] && ! empty( $r['show_option_none'] ) ) {
 
370
 
 
371
                /**
 
372
                 * Filter a taxonomy drop-down display element.
 
373
                 *
 
374
                 * A variety of taxonomy drop-down display elements can be modified
 
375
                 * just prior to display via this filter. Filterable arguments include
 
376
                 * 'show_option_none', 'show_option_all', and various forms of the
 
377
                 * term name.
 
378
                 *
 
379
                 * @since 1.2.0
 
380
                 *
 
381
                 * @see wp_dropdown_categories()
 
382
                 *
 
383
                 * @param string $element Taxonomy element to list.
 
384
                 */
 
385
                $show_option_none = apply_filters( 'list_cats', $r['show_option_none'] );
 
386
                $output .= "\t<option value='" . esc_attr( $option_none_value ) . "' selected='selected'>$show_option_none</option>\n";
 
387
        }
 
388
 
 
389
        if ( ! empty( $categories ) ) {
 
390
 
 
391
                if ( $r['show_option_all'] ) {
 
392
 
 
393
                        /** This filter is documented in wp-includes/category-template.php */
 
394
                        $show_option_all = apply_filters( 'list_cats', $r['show_option_all'] );
 
395
                        $selected = ( '0' === strval($r['selected']) ) ? " selected='selected'" : '';
 
396
                        $output .= "\t<option value='0'$selected>$show_option_all</option>\n";
 
397
                }
 
398
 
 
399
                if ( $r['show_option_none'] ) {
 
400
 
 
401
                        /** This filter is documented in wp-includes/category-template.php */
 
402
                        $show_option_none = apply_filters( 'list_cats', $r['show_option_none'] );
 
403
                        $selected = selected( $option_none_value, $r['selected'], false );
 
404
                        $output .= "\t<option value='" . esc_attr( $option_none_value ) . "'$selected>$show_option_none</option>\n";
 
405
                }
 
406
 
 
407
                if ( $r['hierarchical'] ) {
 
408
                        $depth = $r['depth'];  // Walk the full depth.
 
409
                } else {
 
410
                        $depth = -1; // Flat.
 
411
                }
 
412
                $output .= walk_category_dropdown_tree( $categories, $depth, $r );
 
413
        }
 
414
 
 
415
        if ( ! $r['hide_if_empty'] || ! empty( $categories ) ) {
 
416
                $output .= "</select>\n";
 
417
        }
 
418
        /**
 
419
         * Filter the taxonomy drop-down output.
 
420
         *
 
421
         * @since 2.1.0
 
422
         *
 
423
         * @param string $output HTML output.
 
424
         * @param array  $r      Arguments used to build the drop-down.
 
425
         */
 
426
        $output = apply_filters( 'wp_dropdown_cats', $output, $r );
 
427
 
 
428
        if ( $r['echo'] ) {
 
429
                echo $output;
 
430
        }
 
431
        return $output;
 
432
}
 
433
 
 
434
/**
 
435
 * Display or retrieve the HTML list of categories.
 
436
 *
 
437
 * The list of arguments is below:
 
438
 *     'show_option_all' (string) - Text to display for showing all categories.
 
439
 *     'orderby' (string) default is 'ID' - What column to use for ordering the
 
440
 * categories.
 
441
 *     'order' (string) default is 'ASC' - What direction to order categories.
 
442
 *     'show_count' (bool|int) default is 0 - Whether to show how many posts are
 
443
 * in the category.
 
444
 *     'hide_empty' (bool|int) default is 1 - Whether to hide categories that
 
445
 * don't have any posts attached to them.
 
446
 *     'use_desc_for_title' (bool|int) default is 1 - Whether to use the
 
447
 * category description as the title attribute.
 
448
 *     'feed' - See {@link get_categories()}.
 
449
 *     'feed_type' - See {@link get_categories()}.
 
450
 *     'feed_image' - See {@link get_categories()}.
 
451
 *     'child_of' (int) default is 0 - See {@link get_categories()}.
 
452
 *     'exclude' (string) - See {@link get_categories()}.
 
453
 *     'exclude_tree' (string) - See {@link get_categories()}.
 
454
 *     'echo' (bool|int) default is 1 - Whether to display or retrieve content.
 
455
 *     'current_category' (int) - See {@link get_categories()}.
 
456
 *     'hierarchical' (bool) - See {@link get_categories()}.
 
457
 *     'title_li' (string) - See {@link get_categories()}.
 
458
 *     'depth' (int) - The max depth.
 
459
 *
 
460
 * @since 2.1.0
 
461
 *
 
462
 * @param string|array $args Optional. Override default arguments.
 
463
 * @return string HTML content only if 'echo' argument is 0.
 
464
 */
 
465
function wp_list_categories( $args = '' ) {
 
466
        $defaults = array(
 
467
                'show_option_all' => '', 'show_option_none' => __('No categories'),
 
468
                'orderby' => 'name', 'order' => 'ASC',
 
469
                'style' => 'list',
 
470
                'show_count' => 0, 'hide_empty' => 1,
 
471
                'use_desc_for_title' => 1, 'child_of' => 0,
 
472
                'feed' => '', 'feed_type' => '',
 
473
                'feed_image' => '', 'exclude' => '',
 
474
                'exclude_tree' => '', 'current_category' => 0,
 
475
                'hierarchical' => true, 'title_li' => __( 'Categories' ),
 
476
                'echo' => 1, 'depth' => 0,
 
477
                'taxonomy' => 'category'
 
478
        );
 
479
 
 
480
        $r = wp_parse_args( $args, $defaults );
 
481
 
 
482
        if ( !isset( $r['pad_counts'] ) && $r['show_count'] && $r['hierarchical'] )
 
483
                $r['pad_counts'] = true;
 
484
 
 
485
        if ( true == $r['hierarchical'] ) {
 
486
                $r['exclude_tree'] = $r['exclude'];
 
487
                $r['exclude'] = '';
 
488
        }
 
489
 
 
490
        if ( ! isset( $r['class'] ) )
 
491
                $r['class'] = ( 'category' == $r['taxonomy'] ) ? 'categories' : $r['taxonomy'];
 
492
 
 
493
        if ( ! taxonomy_exists( $r['taxonomy'] ) ) {
 
494
                return false;
 
495
        }
 
496
 
 
497
        $show_option_all = $r['show_option_all'];
 
498
        $show_option_none = $r['show_option_none'];
 
499
 
 
500
        $categories = get_categories( $r );
 
501
 
 
502
        $output = '';
 
503
        if ( $r['title_li'] && 'list' == $r['style'] ) {
 
504
                $output = '<li class="' . esc_attr( $r['class'] ) . '">' . $r['title_li'] . '<ul>';
 
505
        }
 
506
        if ( empty( $categories ) ) {
 
507
                if ( ! empty( $show_option_none ) ) {
 
508
                        if ( 'list' == $r['style'] ) {
 
509
                                $output .= '<li class="cat-item-none">' . $show_option_none . '</li>';
 
510
                        } else {
 
511
                                $output .= $show_option_none;
 
512
                        }
 
513
                }
 
514
        } else {
 
515
                if ( ! empty( $show_option_all ) ) {
 
516
                        $posts_page = ( 'page' == get_option( 'show_on_front' ) && get_option( 'page_for_posts' ) ) ? get_permalink( get_option( 'page_for_posts' ) ) : home_url( '/' );
 
517
                        $posts_page = esc_url( $posts_page );
 
518
                        if ( 'list' == $r['style'] ) {
 
519
                                $output .= "<li class='cat-item-all'><a href='$posts_page'>$show_option_all</a></li>";
 
520
                        } else {
 
521
                                $output .= "<a href='$posts_page'>$show_option_all</a>";
 
522
                        }
 
523
                }
 
524
 
 
525
                if ( empty( $r['current_category'] ) && ( is_category() || is_tax() || is_tag() ) ) {
 
526
                        $current_term_object = get_queried_object();
 
527
                        if ( $current_term_object && $r['taxonomy'] === $current_term_object->taxonomy ) {
 
528
                                $r['current_category'] = get_queried_object_id();
 
529
                        }
 
530
                }
 
531
 
 
532
                if ( $r['hierarchical'] ) {
 
533
                        $depth = $r['depth'];
 
534
                } else {
 
535
                        $depth = -1; // Flat.
 
536
                }
 
537
                $output .= walk_category_tree( $categories, $depth, $r );
 
538
        }
 
539
 
 
540
        if ( $r['title_li'] && 'list' == $r['style'] )
 
541
                $output .= '</ul></li>';
 
542
 
 
543
        /**
 
544
         * Filter the HTML output of a taxonomy list.
 
545
         *
 
546
         * @since 2.1.0
 
547
         *
 
548
         * @param string $output HTML output.
 
549
         * @param array  $args   An array of taxonomy-listing arguments.
 
550
         */
 
551
        $html = apply_filters( 'wp_list_categories', $output, $args );
 
552
 
 
553
        if ( $r['echo'] ) {
 
554
                echo $html;
 
555
        } else {
 
556
                return $html;
 
557
        }
 
558
}
 
559
 
 
560
/**
 
561
 * Display tag cloud.
 
562
 *
 
563
 * The text size is set by the 'smallest' and 'largest' arguments, which will
 
564
 * use the 'unit' argument value for the CSS text size unit. The 'format'
 
565
 * argument can be 'flat' (default), 'list', or 'array'. The flat value for the
 
566
 * 'format' argument will separate tags with spaces. The list value for the
 
567
 * 'format' argument will format the tags in a UL HTML list. The array value for
 
568
 * the 'format' argument will return in PHP array type format.
 
569
 *
 
570
 * The 'orderby' argument will accept 'name' or 'count' and defaults to 'name'.
 
571
 * The 'order' is the direction to sort, defaults to 'ASC' and can be 'DESC'.
 
572
 *
 
573
 * The 'number' argument is how many tags to return. By default, the limit will
 
574
 * be to return the top 45 tags in the tag cloud list.
 
575
 *
 
576
 * The 'topic_count_text' argument is a nooped plural from _n_noop() to generate the
 
577
 * text for the tooltip of the tag link.
 
578
 *
 
579
 * The 'topic_count_text_callback' argument is a function, which given the count
 
580
 * of the posts with that tag returns a text for the tooltip of the tag link.
 
581
 *
 
582
 * The 'post_type' argument is used only when 'link' is set to 'edit'. It determines the post_type
 
583
 * passed to edit.php for the popular tags edit links.
 
584
 *
 
585
 * The 'exclude' and 'include' arguments are used for the {@link get_tags()}
 
586
 * function. Only one should be used, because only one will be used and the
 
587
 * other ignored, if they are both set.
 
588
 *
 
589
 * @since 2.3.0
 
590
 *
 
591
 * @param array|string $args Optional. Override default arguments.
 
592
 * @return array Generated tag cloud, only if no failures and 'array' is set for the 'format' argument.
 
593
 */
 
594
function wp_tag_cloud( $args = '' ) {
 
595
        $defaults = array(
 
596
                'smallest' => 8, 'largest' => 22, 'unit' => 'pt', 'number' => 45,
 
597
                'format' => 'flat', 'separator' => "\n", 'orderby' => 'name', 'order' => 'ASC',
 
598
                'exclude' => '', 'include' => '', 'link' => 'view', 'taxonomy' => 'post_tag', 'post_type' => '', 'echo' => true
 
599
        );
 
600
        $args = wp_parse_args( $args, $defaults );
 
601
 
 
602
        $tags = get_terms( $args['taxonomy'], array_merge( $args, array( 'orderby' => 'count', 'order' => 'DESC' ) ) ); // Always query top tags
 
603
 
 
604
        if ( empty( $tags ) || is_wp_error( $tags ) )
 
605
                return;
 
606
 
 
607
        foreach ( $tags as $key => $tag ) {
 
608
                if ( 'edit' == $args['link'] )
 
609
                        $link = get_edit_term_link( $tag->term_id, $tag->taxonomy, $args['post_type'] );
 
610
                else
 
611
                        $link = get_term_link( intval($tag->term_id), $tag->taxonomy );
 
612
                if ( is_wp_error( $link ) )
 
613
                        return false;
 
614
 
 
615
                $tags[ $key ]->link = $link;
 
616
                $tags[ $key ]->id = $tag->term_id;
 
617
        }
 
618
 
 
619
        $return = wp_generate_tag_cloud( $tags, $args ); // Here's where those top tags get sorted according to $args
 
620
 
 
621
        /**
 
622
         * Filter the tag cloud output.
 
623
         *
 
624
         * @since 2.3.0
 
625
         *
 
626
         * @param string $return HTML output of the tag cloud.
 
627
         * @param array  $args   An array of tag cloud arguments.
 
628
         */
 
629
        $return = apply_filters( 'wp_tag_cloud', $return, $args );
 
630
 
 
631
        if ( 'array' == $args['format'] || empty($args['echo']) )
 
632
                return $return;
 
633
 
 
634
        echo $return;
 
635
}
 
636
 
 
637
/**
 
638
 * Default topic count scaling for tag links
 
639
 *
 
640
 * @param integer $count number of posts with that tag
 
641
 * @return integer scaled count
 
642
 */
 
643
function default_topic_count_scale( $count ) {
 
644
        return round(log10($count + 1) * 100);
 
645
}
 
646
 
 
647
/**
 
648
 * Generates a tag cloud (heatmap) from provided data.
 
649
 *
 
650
 * The text size is set by the 'smallest' and 'largest' arguments, which will
 
651
 * use the 'unit' argument value for the CSS text size unit. The 'format'
 
652
 * argument can be 'flat' (default), 'list', or 'array'. The flat value for the
 
653
 * 'format' argument will separate tags with spaces. The list value for the
 
654
 * 'format' argument will format the tags in a UL HTML list. The array value for
 
655
 * the 'format' argument will return in PHP array type format.
 
656
 *
 
657
 * The 'tag_cloud_sort' filter allows you to override the sorting.
 
658
 * Passed to the filter: $tags array and $args array, has to return the $tags array
 
659
 * after sorting it.
 
660
 *
 
661
 * The 'orderby' argument will accept 'name' or 'count' and defaults to 'name'.
 
662
 * The 'order' is the direction to sort, defaults to 'ASC' and can be 'DESC' or
 
663
 * 'RAND'.
 
664
 *
 
665
 * The 'number' argument is how many tags to return. By default, the limit will
 
666
 * be to return the entire tag cloud list.
 
667
 *
 
668
 * The 'topic_count_text' argument is a nooped plural from _n_noop() to generate the
 
669
 * text for the tooltip of the tag link.
 
670
 *
 
671
 * The 'topic_count_text_callback' argument is a function, which given the count
 
672
 * of the posts with that tag returns a text for the tooltip of the tag link.
 
673
 *
 
674
 * @todo Complete functionality.
 
675
 * @since 2.3.0
 
676
 *
 
677
 * @param array $tags List of tags.
 
678
 * @param string|array $args Optional, override default arguments.
 
679
 * @return string|array Tag cloud as a string or an array, depending on 'format' argument.
 
680
 */
 
681
function wp_generate_tag_cloud( $tags, $args = '' ) {
 
682
        $defaults = array(
 
683
                'smallest' => 8, 'largest' => 22, 'unit' => 'pt', 'number' => 0,
 
684
                'format' => 'flat', 'separator' => "\n", 'orderby' => 'name', 'order' => 'ASC',
 
685
                'topic_count_text' => null, 'topic_count_text_callback' => null,
 
686
                'topic_count_scale_callback' => 'default_topic_count_scale', 'filter' => 1,
 
687
        );
 
688
 
 
689
        $args = wp_parse_args( $args, $defaults );
 
690
 
 
691
        $return = ( 'array' === $args['format'] ) ? array() : '';
 
692
 
 
693
        if ( empty( $tags ) ) {
 
694
                return $return;
 
695
        }
 
696
 
 
697
        // Juggle topic count tooltips:
 
698
        if ( isset( $args['topic_count_text'] ) ) {
 
699
                // First look for nooped plural support via topic_count_text.
 
700
                $translate_nooped_plural = $args['topic_count_text'];
 
701
        } elseif ( ! empty( $args['topic_count_text_callback'] ) ) {
 
702
                // Look for the alternative callback style. Ignore the previous default.
 
703
                if ( $args['topic_count_text_callback'] === 'default_topic_count_text' ) {
 
704
                        $translate_nooped_plural = _n_noop( '%s topic', '%s topics' );
 
705
                } else {
 
706
                        $translate_nooped_plural = false;
 
707
                }
 
708
        } elseif ( isset( $args['single_text'] ) && isset( $args['multiple_text'] ) ) {
 
709
                // If no callback exists, look for the old-style single_text and multiple_text arguments.
 
710
                $translate_nooped_plural = _n_noop( $args['single_text'], $args['multiple_text'] );
 
711
        } else {
 
712
                // This is the default for when no callback, plural, or argument is passed in.
 
713
                $translate_nooped_plural = _n_noop( '%s topic', '%s topics' );
 
714
        }
 
715
 
 
716
        /**
 
717
         * Filter how the items in a tag cloud are sorted.
 
718
         *
 
719
         * @since 2.8.0
 
720
         *
 
721
         * @param array $tags Ordered array of terms.
 
722
         * @param array $args An array of tag cloud arguments.
 
723
         */
 
724
        $tags_sorted = apply_filters( 'tag_cloud_sort', $tags, $args );
 
725
        if ( empty( $tags_sorted ) ) {
 
726
                return $return;
 
727
        }
 
728
 
 
729
        if ( $tags_sorted !== $tags ) {
 
730
                $tags = $tags_sorted;
 
731
                unset( $tags_sorted );
 
732
        } else {
 
733
                if ( 'RAND' === $args['order'] ) {
 
734
                        shuffle( $tags );
 
735
                } else {
 
736
                        // SQL cannot save you; this is a second (potentially different) sort on a subset of data.
 
737
                        if ( 'name' === $args['orderby'] ) {
 
738
                                uasort( $tags, '_wp_object_name_sort_cb' );
 
739
                        } else {
 
740
                                uasort( $tags, '_wp_object_count_sort_cb' );
 
741
                        }
 
742
 
 
743
                        if ( 'DESC' === $args['order'] ) {
 
744
                                $tags = array_reverse( $tags, true );
 
745
                        }
 
746
                }
 
747
        }
 
748
 
 
749
        if ( $args['number'] > 0 )
 
750
                $tags = array_slice( $tags, 0, $args['number'] );
 
751
 
 
752
        $counts = array();
 
753
        $real_counts = array(); // For the alt tag
 
754
        foreach ( (array) $tags as $key => $tag ) {
 
755
                $real_counts[ $key ] = $tag->count;
 
756
                $counts[ $key ] = call_user_func( $args['topic_count_scale_callback'], $tag->count );
 
757
        }
 
758
 
 
759
        $min_count = min( $counts );
 
760
        $spread = max( $counts ) - $min_count;
 
761
        if ( $spread <= 0 )
 
762
                $spread = 1;
 
763
        $font_spread = $args['largest'] - $args['smallest'];
 
764
        if ( $font_spread < 0 )
 
765
                $font_spread = 1;
 
766
        $font_step = $font_spread / $spread;
 
767
 
 
768
        $a = array();
 
769
 
 
770
        foreach ( $tags as $key => $tag ) {
 
771
                $count = $counts[ $key ];
 
772
                $real_count = $real_counts[ $key ];
 
773
                $tag_link = '#' != $tag->link ? esc_url( $tag->link ) : '#';
 
774
                $tag_id = isset($tags[ $key ]->id) ? $tags[ $key ]->id : $key;
 
775
                $tag_name = $tags[ $key ]->name;
 
776
 
 
777
                if ( $translate_nooped_plural ) {
 
778
                        $title_attribute = sprintf( translate_nooped_plural( $translate_nooped_plural, $real_count ), number_format_i18n( $real_count ) );
 
779
                } else {
 
780
                        $title_attribute = call_user_func( $args['topic_count_text_callback'], $real_count, $tag, $args );
 
781
                }
 
782
 
 
783
                $a[] = "<a href='$tag_link' class='tag-link-$tag_id' title='" . esc_attr( $title_attribute ) . "' style='font-size: " .
 
784
                        str_replace( ',', '.', ( $args['smallest'] + ( ( $count - $min_count ) * $font_step ) ) )
 
785
                        . $args['unit'] . ";'>$tag_name</a>";
 
786
        }
 
787
 
 
788
        switch ( $args['format'] ) {
 
789
                case 'array' :
 
790
                        $return =& $a;
 
791
                        break;
 
792
                case 'list' :
 
793
                        $return = "<ul class='wp-tag-cloud'>\n\t<li>";
 
794
                        $return .= join( "</li>\n\t<li>", $a );
 
795
                        $return .= "</li>\n</ul>\n";
 
796
                        break;
 
797
                default :
 
798
                        $return = join( $args['separator'], $a );
 
799
                        break;
 
800
        }
 
801
 
 
802
        if ( $args['filter'] ) {
 
803
                /**
 
804
                 * Filter the generated output of a tag cloud.
 
805
                 *
 
806
                 * The filter is only evaluated if a true value is passed
 
807
                 * to the $filter argument in wp_generate_tag_cloud().
 
808
                 *
 
809
                 * @since 2.3.0
 
810
                 *
 
811
                 * @see wp_generate_tag_cloud()
 
812
                 *
 
813
                 * @param array|string $return String containing the generated HTML tag cloud output
 
814
                 *                             or an array of tag links if the 'format' argument
 
815
                 *                             equals 'array'.
 
816
                 * @param array        $tags   An array of terms used in the tag cloud.
 
817
                 * @param array        $args   An array of wp_generate_tag_cloud() arguments.
 
818
                 */
 
819
                return apply_filters( 'wp_generate_tag_cloud', $return, $tags, $args );
 
820
        }
 
821
 
 
822
        else
 
823
                return $return;
 
824
}
 
825
 
 
826
/**
 
827
 * Callback for comparing objects based on name
 
828
 *
 
829
 * @since 3.1.0
 
830
 * @access private
 
831
 */
 
832
function _wp_object_name_sort_cb( $a, $b ) {
 
833
        return strnatcasecmp( $a->name, $b->name );
 
834
}
 
835
 
 
836
/**
 
837
 * Callback for comparing objects based on count
 
838
 *
 
839
 * @since 3.1.0
 
840
 * @access private
 
841
 */
 
842
function _wp_object_count_sort_cb( $a, $b ) {
 
843
        return ( $a->count > $b->count );
 
844
}
 
845
 
 
846
//
 
847
// Helper functions
 
848
//
 
849
 
 
850
/**
 
851
 * Retrieve HTML list content for category list.
 
852
 *
 
853
 * @uses Walker_Category to create HTML list content.
 
854
 * @since 2.1.0
 
855
 * @see Walker_Category::walk() for parameters and return description.
 
856
 */
 
857
function walk_category_tree() {
 
858
        $args = func_get_args();
 
859
        // the user's options are the third parameter
 
860
        if ( empty($args[2]['walker']) || !is_a($args[2]['walker'], 'Walker') )
 
861
                $walker = new Walker_Category;
 
862
        else
 
863
                $walker = $args[2]['walker'];
 
864
 
 
865
        return call_user_func_array(array( &$walker, 'walk' ), $args );
 
866
}
 
867
 
 
868
/**
 
869
 * Retrieve HTML dropdown (select) content for category list.
 
870
 *
 
871
 * @uses Walker_CategoryDropdown to create HTML dropdown content.
 
872
 * @since 2.1.0
 
873
 * @see Walker_CategoryDropdown::walk() for parameters and return description.
 
874
 */
 
875
function walk_category_dropdown_tree() {
 
876
        $args = func_get_args();
 
877
        // the user's options are the third parameter
 
878
        if ( empty($args[2]['walker']) || !is_a($args[2]['walker'], 'Walker') )
 
879
                $walker = new Walker_CategoryDropdown;
 
880
        else
 
881
                $walker = $args[2]['walker'];
 
882
 
 
883
        return call_user_func_array(array( &$walker, 'walk' ), $args );
 
884
}
 
885
 
 
886
/**
 
887
 * Create HTML list of categories.
 
888
 *
 
889
 * @package WordPress
 
890
 * @since 2.1.0
 
891
 * @uses Walker
 
892
 */
 
893
class Walker_Category extends Walker {
 
894
        /**
 
895
         * What the class handles.
 
896
         *
 
897
         * @see Walker::$tree_type
 
898
         * @since 2.1.0
 
899
         * @var string
 
900
         */
 
901
        public $tree_type = 'category';
 
902
 
 
903
        /**
 
904
         * Database fields to use.
 
905
         *
 
906
         * @see Walker::$db_fields
 
907
         * @since 2.1.0
 
908
         * @todo Decouple this
 
909
         * @var array
 
910
         */
 
911
        public $db_fields = array ('parent' => 'parent', 'id' => 'term_id');
 
912
 
 
913
        /**
 
914
         * Starts the list before the elements are added.
 
915
         *
 
916
         * @see Walker::start_lvl()
 
917
         *
 
918
         * @since 2.1.0
 
919
         *
 
920
         * @param string $output Passed by reference. Used to append additional content.
 
921
         * @param int    $depth  Depth of category. Used for tab indentation.
 
922
         * @param array  $args   An array of arguments. Will only append content if style argument value is 'list'.
 
923
         *                       @see wp_list_categories()
 
924
         */
 
925
        public function start_lvl( &$output, $depth = 0, $args = array() ) {
 
926
                if ( 'list' != $args['style'] )
 
927
                        return;
 
928
 
 
929
                $indent = str_repeat("\t", $depth);
 
930
                $output .= "$indent<ul class='children'>\n";
 
931
        }
 
932
 
 
933
        /**
 
934
         * Ends the list of after the elements are added.
 
935
         *
 
936
         * @see Walker::end_lvl()
 
937
         *
 
938
         * @since 2.1.0
 
939
         *
 
940
         * @param string $output Passed by reference. Used to append additional content.
 
941
         * @param int    $depth  Depth of category. Used for tab indentation.
 
942
         * @param array  $args   An array of arguments. Will only append content if style argument value is 'list'.
 
943
         *                       @wsee wp_list_categories()
 
944
         */
 
945
        public function end_lvl( &$output, $depth = 0, $args = array() ) {
 
946
                if ( 'list' != $args['style'] )
 
947
                        return;
 
948
 
 
949
                $indent = str_repeat("\t", $depth);
 
950
                $output .= "$indent</ul>\n";
 
951
        }
 
952
 
 
953
        /**
 
954
         * Start the element output.
 
955
         *
 
956
         * @see Walker::start_el()
 
957
         *
 
958
         * @since 2.1.0
 
959
         *
 
960
         * @param string $output   Passed by reference. Used to append additional content.
 
961
         * @param object $category Category data object.
 
962
         * @param int    $depth    Depth of category in reference to parents. Default 0.
 
963
         * @param array  $args     An array of arguments. @see wp_list_categories()
 
964
         * @param int    $id       ID of the current category.
 
965
         */
 
966
        public function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
 
967
                /** This filter is documented in wp-includes/category-template.php */
 
968
                $cat_name = apply_filters(
 
969
                        'list_cats',
 
970
                        esc_attr( $category->name ),
 
971
                        $category
 
972
                );
 
973
 
 
974
                $link = '<a href="' . esc_url( get_term_link( $category ) ) . '" ';
 
975
                if ( $args['use_desc_for_title'] && ! empty( $category->description ) ) {
 
976
                        /**
 
977
                         * Filter the category description for display.
 
978
                         *
 
979
                         * @since 1.2.0
 
980
                         *
 
981
                         * @param string $description Category description.
 
982
                         * @param object $category    Category object.
 
983
                         */
 
984
                        $link .= 'title="' . esc_attr( strip_tags( apply_filters( 'category_description', $category->description, $category ) ) ) . '"';
 
985
                }
 
986
 
 
987
                $link .= '>';
 
988
                $link .= $cat_name . '</a>';
 
989
 
 
990
                if ( ! empty( $args['feed_image'] ) || ! empty( $args['feed'] ) ) {
 
991
                        $link .= ' ';
 
992
 
 
993
                        if ( empty( $args['feed_image'] ) ) {
 
994
                                $link .= '(';
 
995
                        }
 
996
 
 
997
                        $link .= '<a href="' . esc_url( get_term_feed_link( $category->term_id, $category->taxonomy, $args['feed_type'] ) ) . '"';
 
998
 
 
999
                        if ( empty( $args['feed'] ) ) {
 
1000
                                $alt = ' alt="' . sprintf(__( 'Feed for all posts filed under %s' ), $cat_name ) . '"';
 
1001
                        } else {
 
1002
                                $alt = ' alt="' . $args['feed'] . '"';
 
1003
                                $name = $args['feed'];
 
1004
                                $link .= empty( $args['title'] ) ? '' : $args['title'];
 
1005
                        }
 
1006
 
 
1007
                        $link .= '>';
 
1008
 
 
1009
                        if ( empty( $args['feed_image'] ) ) {
 
1010
                                $link .= $name;
 
1011
                        } else {
 
1012
                                $link .= "<img src='" . $args['feed_image'] . "'$alt" . ' />';
 
1013
                        }
 
1014
                        $link .= '</a>';
 
1015
 
 
1016
                        if ( empty( $args['feed_image'] ) ) {
 
1017
                                $link .= ')';
 
1018
                        }
 
1019
                }
 
1020
 
 
1021
                if ( ! empty( $args['show_count'] ) ) {
 
1022
                        $link .= ' (' . number_format_i18n( $category->count ) . ')';
 
1023
                }
 
1024
                if ( 'list' == $args['style'] ) {
 
1025
                        $output .= "\t<li";
 
1026
                        $class = 'cat-item cat-item-' . $category->term_id;
 
1027
                        if ( ! empty( $args['current_category'] ) ) {
 
1028
                                $_current_category = get_term( $args['current_category'], $category->taxonomy );
 
1029
                                if ( $category->term_id == $args['current_category'] ) {
 
1030
                                        $class .=  ' current-cat';
 
1031
                                } elseif ( $category->term_id == $_current_category->parent ) {
 
1032
                                        $class .=  ' current-cat-parent';
 
1033
                                }
 
1034
                        }
 
1035
                        $output .=  ' class="' . $class . '"';
 
1036
                        $output .= ">$link\n";
 
1037
                } else {
 
1038
                        $output .= "\t$link<br />\n";
 
1039
                }
 
1040
        }
 
1041
 
 
1042
        /**
 
1043
         * Ends the element output, if needed.
 
1044
         *
 
1045
         * @see Walker::end_el()
 
1046
         *
 
1047
         * @since 2.1.0
 
1048
         *
 
1049
         * @param string $output Passed by reference. Used to append additional content.
 
1050
         * @param object $page   Not used.
 
1051
         * @param int    $depth  Depth of category. Not used.
 
1052
         * @param array  $args   An array of arguments. Only uses 'list' for whether should append to output. @see wp_list_categories()
 
1053
         */
 
1054
        public function end_el( &$output, $page, $depth = 0, $args = array() ) {
 
1055
                if ( 'list' != $args['style'] )
 
1056
                        return;
 
1057
 
 
1058
                $output .= "</li>\n";
 
1059
        }
 
1060
 
 
1061
}
 
1062
 
 
1063
/**
 
1064
 * Create HTML dropdown list of Categories.
 
1065
 *
 
1066
 * @package WordPress
 
1067
 * @since 2.1.0
 
1068
 * @uses Walker
 
1069
 */
 
1070
class Walker_CategoryDropdown extends Walker {
 
1071
        /**
 
1072
         * @see Walker::$tree_type
 
1073
         * @since 2.1.0
 
1074
         * @var string
 
1075
         */
 
1076
        public $tree_type = 'category';
 
1077
 
 
1078
        /**
 
1079
         * @see Walker::$db_fields
 
1080
         * @since 2.1.0
 
1081
         * @todo Decouple this
 
1082
         * @var array
 
1083
         */
 
1084
        public $db_fields = array ('parent' => 'parent', 'id' => 'term_id');
 
1085
 
 
1086
        /**
 
1087
         * Start the element output.
 
1088
         *
 
1089
         * @see Walker::start_el()
 
1090
         * @since 2.1.0
 
1091
         *
 
1092
         * @param string $output   Passed by reference. Used to append additional content.
 
1093
         * @param object $category Category data object.
 
1094
         * @param int    $depth    Depth of category. Used for padding.
 
1095
         * @param array  $args     Uses 'selected' and 'show_count' keys, if they exist. @see wp_dropdown_categories()
 
1096
         */
 
1097
        public function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
 
1098
                $pad = str_repeat('&nbsp;', $depth * 3);
 
1099
 
 
1100
                /** This filter is documented in wp-includes/category-template.php */
 
1101
                $cat_name = apply_filters( 'list_cats', $category->name, $category );
 
1102
 
 
1103
                $output .= "\t<option class=\"level-$depth\" value=\"".$category->term_id."\"";
 
1104
                if ( $category->term_id == $args['selected'] )
 
1105
                        $output .= ' selected="selected"';
 
1106
                $output .= '>';
 
1107
                $output .= $pad.$cat_name;
 
1108
                if ( $args['show_count'] )
 
1109
                        $output .= '&nbsp;&nbsp;('. number_format_i18n( $category->count ) .')';
 
1110
                $output .= "</option>\n";
 
1111
        }
 
1112
}
 
1113
 
 
1114
//
 
1115
// Tags
 
1116
//
 
1117
 
 
1118
/**
 
1119
 * Retrieve the link to the tag.
 
1120
 *
 
1121
 * @since 2.3.0
 
1122
 * @see get_term_link()
 
1123
 *
 
1124
 * @param int|object $tag Tag ID or object.
 
1125
 * @return string Link on success, empty string if tag does not exist.
 
1126
 */
 
1127
function get_tag_link( $tag ) {
 
1128
        if ( ! is_object( $tag ) )
 
1129
                $tag = (int) $tag;
 
1130
 
 
1131
        $tag = get_term_link( $tag, 'post_tag' );
 
1132
 
 
1133
        if ( is_wp_error( $tag ) )
 
1134
                return '';
 
1135
 
 
1136
        return $tag;
 
1137
}
 
1138
 
 
1139
/**
 
1140
 * Retrieve the tags for a post.
 
1141
 *
 
1142
 * @since 2.3.0
 
1143
 *
 
1144
 * @param int $id Post ID.
 
1145
 * @return array|bool Array of tag objects on success, false on failure.
 
1146
 */
 
1147
function get_the_tags( $id = 0 ) {
 
1148
 
 
1149
        /**
 
1150
         * Filter the array of tags for the given post.
 
1151
         *
 
1152
         * @since 2.3.0
 
1153
         *
 
1154
         * @see get_the_terms()
 
1155
         *
 
1156
         * @param array $terms An array of tags for the given post.
 
1157
         */
 
1158
        return apply_filters( 'get_the_tags', get_the_terms( $id, 'post_tag' ) );
 
1159
}
 
1160
 
 
1161
/**
 
1162
 * Retrieve the tags for a post formatted as a string.
 
1163
 *
 
1164
 * @since 2.3.0
 
1165
 *
 
1166
 * @param string $before Optional. Before tags.
 
1167
 * @param string $sep Optional. Between tags.
 
1168
 * @param string $after Optional. After tags.
 
1169
 * @param int $id Optional. Post ID. Defaults to the current post.
 
1170
 * @return string|bool|WP_Error A list of tags on success, false if there are no terms, WP_Error on failure.
 
1171
 */
 
1172
function get_the_tag_list( $before = '', $sep = '', $after = '', $id = 0 ) {
 
1173
 
 
1174
        /**
 
1175
         * Filter the tags list for a given post.
 
1176
         *
 
1177
         * @since 2.3.0
 
1178
         *
 
1179
         * @param string $tag_list List of tags.
 
1180
         * @param string $before   String to use before tags.
 
1181
         * @param string $sep      String to use between the tags.
 
1182
         * @param string $after    String to use after tags.
 
1183
         * @param int    $id       Post ID.
 
1184
         */
 
1185
        return apply_filters( 'the_tags', get_the_term_list( $id, 'post_tag', $before, $sep, $after ), $before, $sep, $after, $id );
 
1186
}
 
1187
 
 
1188
/**
 
1189
 * Retrieve the tags for a post.
 
1190
 *
 
1191
 * @since 2.3.0
 
1192
 *
 
1193
 * @param string $before Optional. Before list.
 
1194
 * @param string $sep Optional. Separate items using this.
 
1195
 * @param string $after Optional. After list.
 
1196
 */
 
1197
function the_tags( $before = null, $sep = ', ', $after = '' ) {
 
1198
        if ( null === $before )
 
1199
                $before = __('Tags: ');
 
1200
        echo get_the_tag_list($before, $sep, $after);
 
1201
}
 
1202
 
 
1203
/**
 
1204
 * Retrieve tag description.
 
1205
 *
 
1206
 * @since 2.8.0
 
1207
 *
 
1208
 * @param int $tag Optional. Tag ID. Will use global tag ID by default.
 
1209
 * @return string Tag description, available.
 
1210
 */
 
1211
function tag_description( $tag = 0 ) {
 
1212
        return term_description( $tag );
 
1213
}
 
1214
 
 
1215
/**
 
1216
 * Retrieve term description.
 
1217
 *
 
1218
 * @since 2.8.0
 
1219
 *
 
1220
 * @param int $term Optional. Term ID. Will use global term ID by default.
 
1221
 * @param string $taxonomy Optional taxonomy name. Defaults to 'post_tag'.
 
1222
 * @return string Term description, available.
 
1223
 */
 
1224
function term_description( $term = 0, $taxonomy = 'post_tag' ) {
 
1225
        if ( ! $term && ( is_tax() || is_tag() || is_category() ) ) {
 
1226
                $term = get_queried_object();
 
1227
                if ( $term ) {
 
1228
                        $taxonomy = $term->taxonomy;
 
1229
                        $term = $term->term_id;
 
1230
                }
 
1231
        }
 
1232
        $description = get_term_field( 'description', $term, $taxonomy );
 
1233
        return is_wp_error( $description ) ? '' : $description;
 
1234
}
 
1235
 
 
1236
/**
 
1237
 * Retrieve the terms of the taxonomy that are attached to the post.
 
1238
 *
 
1239
 * @since 2.5.0
 
1240
 *
 
1241
 * @param int|object $post Post ID or object.
 
1242
 * @param string $taxonomy Taxonomy name.
 
1243
 * @return array|bool|WP_Error Array of term objects on success, false if there are no terms
 
1244
 *                             or the post does not exist, WP_Error on failure.
 
1245
 */
 
1246
function get_the_terms( $post, $taxonomy ) {
 
1247
        if ( ! $post = get_post( $post ) )
 
1248
                return false;
 
1249
 
 
1250
        $terms = get_object_term_cache( $post->ID, $taxonomy );
 
1251
        if ( false === $terms ) {
 
1252
                $terms = wp_get_object_terms( $post->ID, $taxonomy );
 
1253
                wp_cache_add($post->ID, $terms, $taxonomy . '_relationships');
 
1254
        }
 
1255
 
 
1256
        /**
 
1257
         * Filter the list of terms attached to the given post.
 
1258
         *
 
1259
         * @since 3.1.0
 
1260
         *
 
1261
         * @param array|WP_Error $terms    List of attached terms, or WP_Error on failure.
 
1262
         * @param int            $post_id  Post ID.
 
1263
         * @param string         $taxonomy Name of the taxonomy.
 
1264
         */
 
1265
        $terms = apply_filters( 'get_the_terms', $terms, $post->ID, $taxonomy );
 
1266
 
 
1267
        if ( empty( $terms ) )
 
1268
                return false;
 
1269
 
 
1270
        return $terms;
 
1271
}
 
1272
 
 
1273
/**
 
1274
 * Retrieve a post's terms as a list with specified format.
 
1275
 *
 
1276
 * @since 2.5.0
 
1277
 *
 
1278
 * @param int $id Post ID.
 
1279
 * @param string $taxonomy Taxonomy name.
 
1280
 * @param string $before Optional. Before list.
 
1281
 * @param string $sep Optional. Separate items using this.
 
1282
 * @param string $after Optional. After list.
 
1283
 * @return string|bool|WP_Error A list of terms on success, false if there are no terms, WP_Error on failure.
 
1284
 */
 
1285
function get_the_term_list( $id, $taxonomy, $before = '', $sep = '', $after = '' ) {
 
1286
        $terms = get_the_terms( $id, $taxonomy );
 
1287
 
 
1288
        if ( is_wp_error( $terms ) )
 
1289
                return $terms;
 
1290
 
 
1291
        if ( empty( $terms ) )
 
1292
                return false;
 
1293
 
 
1294
        foreach ( $terms as $term ) {
 
1295
                $link = get_term_link( $term, $taxonomy );
 
1296
                if ( is_wp_error( $link ) )
 
1297
                        return $link;
 
1298
                $term_links[] = '<a href="' . esc_url( $link ) . '" rel="tag">' . $term->name . '</a>';
 
1299
        }
 
1300
 
 
1301
        /**
 
1302
         * Filter the term links for a given taxonomy.
 
1303
         *
 
1304
         * The dynamic portion of the filter name, $taxonomy, refers
 
1305
         * to the taxonomy slug.
 
1306
         *
 
1307
         * @since 2.5.0
 
1308
         *
 
1309
         * @param array $term_links An array of term links.
 
1310
         */
 
1311
        $term_links = apply_filters( "term_links-$taxonomy", $term_links );
 
1312
 
 
1313
        return $before . join( $sep, $term_links ) . $after;
 
1314
}
 
1315
 
 
1316
/**
 
1317
 * Display the terms in a list.
 
1318
 *
 
1319
 * @since 2.5.0
 
1320
 *
 
1321
 * @param int $id Post ID.
 
1322
 * @param string $taxonomy Taxonomy name.
 
1323
 * @param string $before Optional. Before list.
 
1324
 * @param string $sep Optional. Separate items using this.
 
1325
 * @param string $after Optional. After list.
 
1326
 * @return null|bool False on WordPress error. Returns null when displaying.
 
1327
 */
 
1328
function the_terms( $id, $taxonomy, $before = '', $sep = ', ', $after = '' ) {
 
1329
        $term_list = get_the_term_list( $id, $taxonomy, $before, $sep, $after );
 
1330
 
 
1331
        if ( is_wp_error( $term_list ) )
 
1332
                return false;
 
1333
 
 
1334
        /**
 
1335
         * Filter the list of terms to display.
 
1336
         *
 
1337
         * @since 2.9.0
 
1338
         *
 
1339
         * @param array  $term_list List of terms to display.
 
1340
         * @param string $taxonomy  The taxonomy name.
 
1341
         * @param string $before    String to use before the terms.
 
1342
         * @param string $sep       String to use between the terms.
 
1343
         * @param string $after     String to use after the terms.
 
1344
         */
 
1345
        echo apply_filters( 'the_terms', $term_list, $taxonomy, $before, $sep, $after );
 
1346
}
 
1347
 
 
1348
/**
 
1349
 * Check if the current post has any of given category.
 
1350
 *
 
1351
 * @since 3.1.0
 
1352
 *
 
1353
 * @param string|int|array $category Optional. The category name/term_id/slug or array of them to check for.
 
1354
 * @param int|object $post Optional. Post to check instead of the current post.
 
1355
 * @return bool True if the current post has any of the given categories (or any category, if no category specified).
 
1356
 */
 
1357
function has_category( $category = '', $post = null ) {
 
1358
        return has_term( $category, 'category', $post );
 
1359
}
 
1360
 
 
1361
/**
 
1362
 * Check if the current post has any of given tags.
 
1363
 *
 
1364
 * The given tags are checked against the post's tags' term_ids, names and slugs.
 
1365
 * Tags given as integers will only be checked against the post's tags' term_ids.
 
1366
 * If no tags are given, determines if post has any tags.
 
1367
 *
 
1368
 * Prior to v2.7 of WordPress, tags given as integers would also be checked against the post's tags' names and slugs (in addition to term_ids)
 
1369
 * Prior to v2.7, this function could only be used in the WordPress Loop.
 
1370
 * As of 2.7, the function can be used anywhere if it is provided a post ID or post object.
 
1371
 *
 
1372
 * @since 2.6.0
 
1373
 *
 
1374
 * @param string|int|array $tag Optional. The tag name/term_id/slug or array of them to check for.
 
1375
 * @param int|object $post Optional. Post to check instead of the current post. (since 2.7.0)
 
1376
 * @return bool True if the current post has any of the given tags (or any tag, if no tag specified).
 
1377
 */
 
1378
function has_tag( $tag = '', $post = null ) {
 
1379
        return has_term( $tag, 'post_tag', $post );
 
1380
}
 
1381
 
 
1382
/**
 
1383
 * Check if the current post has any of given terms.
 
1384
 *
 
1385
 * The given terms are checked against the post's terms' term_ids, names and slugs.
 
1386
 * Terms given as integers will only be checked against the post's terms' term_ids.
 
1387
 * If no terms are given, determines if post has any terms.
 
1388
 *
 
1389
 * @since 3.1.0
 
1390
 *
 
1391
 * @param string|int|array $term Optional. The term name/term_id/slug or array of them to check for.
 
1392
 * @param string $taxonomy Taxonomy name
 
1393
 * @param int|object $post Optional. Post to check instead of the current post.
 
1394
 * @return bool True if the current post has any of the given tags (or any tag, if no tag specified).
 
1395
 */
 
1396
function has_term( $term = '', $taxonomy = '', $post = null ) {
 
1397
        $post = get_post($post);
 
1398
 
 
1399
        if ( !$post )
 
1400
                return false;
 
1401
 
 
1402
        $r = is_object_in_term( $post->ID, $taxonomy, $term );
 
1403
        if ( is_wp_error( $r ) )
 
1404
                return false;
 
1405
 
 
1406
        return $r;
 
1407
}