Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 122 |
|
0.00% |
0 / 7 |
CRAP | |
0.00% |
0 / 1 |
| wpcom_widget_category_cloud | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| WPCOM_Category_Cloud_Widget | |
0.00% |
0 / 120 |
|
0.00% |
0 / 6 |
306 | |
0.00% |
0 / 1 |
| __construct | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
2 | |||
| flush_cache | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| widget | |
0.00% |
0 / 69 |
|
0.00% |
0 / 1 |
110 | |||
| form | |
0.00% |
0 / 27 |
|
0.00% |
0 / 1 |
2 | |||
| update | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
| normalize_int_value | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
12 | |||
| 1 | <?php // phpcs:ignore Squiz.Commenting.FileComment.Missing |
| 2 | |
| 3 | /** |
| 4 | * Category Cloud widget from WordPress.com |
| 5 | */ |
| 6 | class WPCOM_Category_Cloud_Widget extends WP_Widget { |
| 7 | /** |
| 8 | * Minimum font percentage. |
| 9 | * |
| 10 | * @var int $min_font_per |
| 11 | */ |
| 12 | private $min_font_per = 100; |
| 13 | |
| 14 | /** |
| 15 | * Maximum font percentage. |
| 16 | * |
| 17 | * @var int $max_font_per |
| 18 | */ |
| 19 | private $max_font_per = 275; |
| 20 | |
| 21 | /** |
| 22 | * Constructor. |
| 23 | */ |
| 24 | public function __construct() { |
| 25 | parent::__construct( |
| 26 | 'wpcom_category_cloud', |
| 27 | __( 'Category Cloud', 'wpcomsh' ), |
| 28 | array( |
| 29 | 'description' => __( 'Your most used categories in cloud format.', 'wpcomsh' ), |
| 30 | 'classname' => 'widget_tag_cloud', |
| 31 | ) |
| 32 | ); |
| 33 | |
| 34 | add_action( 'delete_category', array( $this, 'flush_cache' ) ); |
| 35 | add_action( 'edit_category', array( $this, 'flush_cache' ) ); |
| 36 | add_action( 'create_category', array( $this, 'flush_cache' ) ); |
| 37 | } |
| 38 | |
| 39 | /** |
| 40 | * Flush cache. |
| 41 | */ |
| 42 | public function flush_cache() { |
| 43 | wp_cache_delete( 'widget_cat_cloud_cache' . $this->id, 'widget' ); |
| 44 | } |
| 45 | |
| 46 | /** |
| 47 | * Display the widget. |
| 48 | * |
| 49 | * @param array $args Widget arguments. |
| 50 | * @param array $instance Widget instance. |
| 51 | */ |
| 52 | public function widget( $args, $instance ) { |
| 53 | $instance = wp_parse_args( |
| 54 | $instance, |
| 55 | array( |
| 56 | 'parent_pad' => 0, |
| 57 | 'max_tags' => 30, |
| 58 | 'exclude' => '', |
| 59 | 'min_font_per' => $this->min_font_per, |
| 60 | 'max_font_per' => $this->max_font_per, |
| 61 | ) |
| 62 | ); |
| 63 | |
| 64 | if ( empty( $instance['title'] ) ) { |
| 65 | $instance['title'] = __( 'Category Cloud', 'wpcomsh' ); |
| 66 | } |
| 67 | |
| 68 | $tags_info = wp_cache_get( 'widget_cat_cloud_cache' . $this->id, 'widget' ); |
| 69 | |
| 70 | if ( ! $tags_info ) { |
| 71 | $categories = get_categories( |
| 72 | array( |
| 73 | 'orderby' => 'count', |
| 74 | 'order' => 'DESC', |
| 75 | 'hierarchical' => 0, |
| 76 | 'pad_counts' => $instance['parent_pad'], |
| 77 | 'number' => $instance['max_tags'], |
| 78 | 'exclude' => $instance['exclude'], |
| 79 | ) |
| 80 | ); |
| 81 | |
| 82 | $tags = array(); |
| 83 | $tag_urls = array(); |
| 84 | |
| 85 | foreach ( $categories as $cat ) { |
| 86 | $tags[ $cat->name ] = $cat->count; |
| 87 | $tag_urls[ $cat->name ] = get_category_link( $cat->term_id ); |
| 88 | } |
| 89 | |
| 90 | uksort( $tags, 'strnatcasecmp' ); // case insensitive alphabetical sort |
| 91 | |
| 92 | // Cache only if we're not in the customizer view. That view can add some garbage to the urls, which we then cache and display to other users. |
| 93 | if ( ! $this->is_preview() ) { |
| 94 | wp_cache_add( |
| 95 | 'widget_cat_cloud_cache' . $this->id, |
| 96 | array( |
| 97 | 'tags' => $tags, |
| 98 | 'tag_urls' => $tag_urls, |
| 99 | ), |
| 100 | 'widget' |
| 101 | ); |
| 102 | } |
| 103 | } else { |
| 104 | $tags = $tags_info['tags']; |
| 105 | $tag_urls = $tags_info['tag_urls']; |
| 106 | } |
| 107 | |
| 108 | if ( empty( $tags ) ) { |
| 109 | return; |
| 110 | } |
| 111 | |
| 112 | $min_value = min( array_values( $tags ) ); |
| 113 | $max_value = max( array_values( $tags ) ); |
| 114 | |
| 115 | $spread = $max_value - $min_value; |
| 116 | |
| 117 | if ( $spread < 1 ) { |
| 118 | $spread = 1; |
| 119 | } |
| 120 | |
| 121 | $step = ( $instance['max_font_per'] - $instance['min_font_per'] ) / $spread; |
| 122 | |
| 123 | echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| 124 | echo $args['before_title'] . esc_html( $instance['title'] ) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| 125 | |
| 126 | echo '<div style="overflow: hidden;">'; |
| 127 | |
| 128 | foreach ( $tags as $tag_name => $num_posts ) { |
| 129 | $font_size = $instance['min_font_per'] + ( ( $num_posts - $min_value ) * $step ); |
| 130 | echo '<a href="' . esc_url( $tag_urls[ $tag_name ] ) . '" style="font-size: ' . esc_attr( $font_size . '%' ) . '; padding: 1px; margin: 1px;" title="' . esc_attr( $tag_name . ' (' . $num_posts . ')' ) . '">' . esc_html( $tag_name ) . '</a> '; |
| 131 | } |
| 132 | |
| 133 | echo '</div>'; |
| 134 | |
| 135 | if ( 1 >= count( $tags ) && current_user_can( 'edit_theme_options' ) ) { |
| 136 | /* translators: Link to post category documentation. */ |
| 137 | echo '<p>'; |
| 138 | printf( |
| 139 | wp_kses( |
| 140 | // translators: link to support doc about categories |
| 141 | __( 'If you use more <a href="%s">categories</a> on your site, they will appear here.', 'wpcomsh' ), |
| 142 | array( |
| 143 | 'a' => array( 'href' => array() ), |
| 144 | ) |
| 145 | ), |
| 146 | 'http://en.support.wordpress.com/posts/categories/' |
| 147 | ); |
| 148 | echo '</p>'; |
| 149 | } |
| 150 | |
| 151 | echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| 152 | } |
| 153 | |
| 154 | /** |
| 155 | * Display the widget settings form. |
| 156 | * |
| 157 | * @param array $instance Current settings. |
| 158 | * @return never |
| 159 | */ |
| 160 | public function form( $instance ) { |
| 161 | $instance = wp_parse_args( |
| 162 | $instance, |
| 163 | array( |
| 164 | 'title' => '', |
| 165 | 'parent_pad' => false, |
| 166 | 'max_tags' => 30, |
| 167 | 'exclude' => '', |
| 168 | 'min_font_per' => $this->min_font_per, |
| 169 | 'max_font_per' => $this->max_font_per, |
| 170 | ) |
| 171 | ); |
| 172 | |
| 173 | ?> |
| 174 | <p> |
| 175 | <label> |
| 176 | <?php esc_html_e( 'Title:', 'wpcomsh' ); ?> |
| 177 | <input class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $instance['title'] ); ?>"/> |
| 178 | </label> |
| 179 | </p> |
| 180 | <p> |
| 181 | <label> |
| 182 | <?php esc_html_e( 'Maximum number of categories to show:', 'wpcomsh' ); ?> |
| 183 | <input class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'max_tags' ) ); ?>" type="number" value="<?php echo esc_attr( $instance['max_tags'] ); ?>"/> |
| 184 | </label> |
| 185 | </p> |
| 186 | <p> |
| 187 | <label> |
| 188 | <?php esc_html_e( 'Exclude:', 'wpcomsh' ); ?> |
| 189 | <input class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'exclude' ) ); ?>" type="text" value="<?php echo esc_attr( $instance['exclude'] ); ?>"/> |
| 190 | <small><?php esc_html_e( 'Category IDs, separated by commas', 'wpcomsh' ); ?></small> |
| 191 | </label> |
| 192 | </p> |
| 193 | <p> |
| 194 | <label> |
| 195 | <?php esc_html_e( 'Minimum font percentage:', 'wpcomsh' ); ?> |
| 196 | <input class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'min_font_per' ) ); ?>" type="number" value="<?php echo esc_attr( $instance['min_font_per'] ); ?>" min="10" max="1000" maxlength="4"/> |
| 197 | </label> |
| 198 | </p> |
| 199 | <p> |
| 200 | <label> |
| 201 | <?php esc_html_e( 'Maximum font percentage:', 'wpcomsh' ); ?> |
| 202 | <input class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'max_font_per' ) ); ?>" type="number" value="<?php echo esc_attr( $instance['max_font_per'] ); ?>" min="10" max="9999" maxlength="4"/> |
| 203 | </label> |
| 204 | </p> |
| 205 | <p> |
| 206 | <label> |
| 207 | <input type="checkbox" name="<?php echo esc_attr( $this->get_field_name( 'parent_pad' ) ); ?>" <?php checked( $instance['parent_pad'] ); ?> value="1"/> |
| 208 | <?php |
| 209 | esc_html_e( 'Count items in sub-categories toward parent total.', 'wpcomsh' ); |
| 210 | ?> |
| 211 | (<a href="https://en.support.wordpress.com/widgets/category-cloud-widget/#settings" target="_blank" title="<?php esc_attr_e( 'Click for more information', 'wpcomsh' ); ?>">?</a>) |
| 212 | </label> |
| 213 | </p> |
| 214 | <?php |
| 215 | } |
| 216 | |
| 217 | /** |
| 218 | * Update the widget settings. |
| 219 | * |
| 220 | * @param array $new_instance New settings. |
| 221 | * @param array $old_instance Old settings. |
| 222 | */ |
| 223 | public function update( $new_instance, $old_instance ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable |
| 224 | $new_instance['title'] = wp_strip_all_tags( $new_instance['title'] ); |
| 225 | $new_instance['parent_pad'] = isset( $new_instance['parent_pad'] ); |
| 226 | $new_instance['max_tags'] = (int) $new_instance['max_tags']; |
| 227 | $new_instance['exclude'] = wp_strip_all_tags( $new_instance['exclude'] ); |
| 228 | $new_instance['min_font_per'] = $this->normalize_int_value( (int) $new_instance['min_font_per'], $this->min_font_per, 1000, 10 ); |
| 229 | $new_instance['max_font_per'] = $this->normalize_int_value( (int) $new_instance['max_font_per'], $this->max_font_per, 9999, 10 ); |
| 230 | |
| 231 | $this->flush_cache(); |
| 232 | |
| 233 | return $new_instance; |
| 234 | } |
| 235 | |
| 236 | /** |
| 237 | * Normalize int value. |
| 238 | * |
| 239 | * @param int $value Provided value. |
| 240 | * @param int $default Default value used if provided value is not between $min and $max. |
| 241 | * @param int $max Maximum value. |
| 242 | * @param int $min Minimum value. |
| 243 | * |
| 244 | * @return int Normalized value. |
| 245 | */ |
| 246 | private function normalize_int_value( $value, $default = 0, $max = 0, $min = 0 ) { |
| 247 | $value = (int) $value; |
| 248 | |
| 249 | if ( $value > $max || $value < $min ) { |
| 250 | $value = $default; |
| 251 | } |
| 252 | |
| 253 | return (int) $value; |
| 254 | } |
| 255 | } |
| 256 | |
| 257 | /** |
| 258 | * Register the widget. |
| 259 | */ |
| 260 | function wpcom_widget_category_cloud() { // phpcs:ignore Universal.Files.SeparateFunctionsFromOO.Mixed |
| 261 | register_widget( 'WPCOM_Category_Cloud_Widget' ); |
| 262 | } |
| 263 | add_action( 'widgets_init', 'wpcom_widget_category_cloud', 11 ); |