PluginProbe ʕ •ᴥ•ʔ
WP Popular Posts / 5.0.2
WP Popular Posts v5.0.2
4.0.8 4.0.9 4.1.0 4.1.1 4.1.2 4.2.0 4.2.1 4.2.2 5.0.0 5.0.1 5.0.2 5.1.0 5.2.0 5.2.1 5.2.2 5.2.3 5.2.4 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 6.0.0 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.1.0 6.1.1 6.1.2 6.1.3 6.1.4 6.2.0 6.2.1 6.3.0 6.3.1 6.3.2 6.3.3 6.3.4 6.4.0 6.4.1 6.4.2 7.0.0 7.0.1 7.1.0 7.2.0 7.3.0 7.3.1 7.3.2 7.3.3 7.3.4 7.3.5 7.3.6 7.3.7 7.3.8 7.4.0 trunk 2.3.7 3.0.0 3.0.1 3.0.2 3.0.3 3.1.0 3.1.1 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 4.0.0 4.0.1 4.0.10 4.0.11 4.0.12 4.0.13 4.0.2 4.0.3 4.0.5 4.0.6
wordpress-popular-posts / src / Widget / Widget.php
wordpress-popular-posts / src / Widget Last commit date
Widget.php 6 years ago form.php 6 years ago
Widget.php
497 lines
1 <?php
2
3 namespace WordPressPopularPosts\Widget;
4
5 use WordPressPopularPosts\Helper;
6 use WordPressPopularPosts\Query;
7
8 class Widget extends \WP_Widget {
9
10 /**
11 * Default options.
12 *
13 * @since 5.0.0
14 * @var array
15 */
16 private $defaults = [];
17
18 /**
19 * Administrative settings.
20 *
21 * @since 2.3.3
22 * @var array
23 */
24 private $admin_options = [];
25
26 /**
27 * Image object.
28 *
29 * @since 5.0.0
30 * @var WordPressPopularPosts\Image
31 */
32 private $thumbnail;
33
34 /**
35 * Output object.
36 *
37 * @var \WordPressPopularPosts\Output
38 * @access private
39 */
40 private $output;
41
42 /**
43 * Translate object.
44 *
45 * @var \WordPressPopularPosts\Translate $translate
46 * @access private
47 */
48 private $translate;
49
50 /**
51 * Themer object.
52 *
53 * @var \WordPressPopularPosts\Themer $themer
54 * @access private
55 */
56 private $themer;
57
58 /**
59 * Construct.
60 *
61 * @since 1.0.0
62 * @param array $options
63 * @param array $config
64 * @param \WordPressPopularPosts\Output $output
65 * @param \WordPressPopularPosts\Image $image
66 * @param \WordPressPopularPosts\Translate $translate
67 * @param \WordPressPopularPosts\Themer $themer
68 */
69 public function __construct(array $options, array $config, \WordPressPopularPosts\Output $output, \WordPressPopularPosts\Image $thumbnail, \WordPressPopularPosts\Translate $translate, \WordPressPopularPosts\Themer $themer)
70 {
71 // Create the widget
72 parent::__construct(
73 'wpp',
74 'WordPress Popular Posts',
75 [
76 'classname' => 'popular-posts',
77 'description' => __('The most Popular Posts on your blog.', 'wordpress-popular-posts')
78 ]
79 );
80
81 $this->defaults = $options;
82 $this->admin_options = $config;
83 $this->output = $output;
84 $this->thumbnail = $thumbnail;
85 $this->translate = $translate;
86 $this->themer = $themer;
87 }
88
89 /**
90 * Widget hooks.
91 *
92 * @since 5.0.0
93 */
94 public function hooks()
95 {
96 // Register the widget
97 add_action('widgets_init', [$this, 'register']);
98 }
99
100 /**
101 * Registers the widget.
102 *
103 * @since 5.0.0
104 */
105 public function register()
106 {
107 register_widget($this);
108 }
109
110 /**
111 * Outputs the content of the widget.
112 *
113 * @since 1.0.0
114 * @param array $args The array of form elements.
115 * @param array $instance The current instance of the widget.
116 */
117 public function widget($args, $instance)
118 {
119 /**
120 * @var string $name
121 * @var string $id
122 * @var string $description
123 * @var string $class
124 * @var string $before_widget
125 * @var string $after_widget
126 * @var string $before_title
127 * @var string $after_title
128 * @var string $widget_id
129 * @var string $widget_name
130 */
131 extract($args, EXTR_SKIP);
132
133 $instance = Helper::merge_array_r(
134 $this->defaults,
135 (array) $instance
136 );
137
138 $markup = ( $instance['markup']['custom_html'] || has_filter('wpp_custom_html') || has_filter('wpp_post') )
139 ? 'custom'
140 : 'regular';
141
142 echo "\n" . $before_widget . "\n";
143
144 // Has user set a title?
145 if ( '' != $instance['title'] ) {
146 $title = apply_filters('widget_title', $instance['title'], $instance, $this->id_base);
147
148 if (
149 $instance['markup']['custom_html']
150 && $instance['markup']['title-start'] != ""
151 && $instance['markup']['title-end'] != ""
152 ) {
153 echo htmlspecialchars_decode($instance['markup']['title-start'], ENT_QUOTES) . $title . htmlspecialchars_decode($instance['markup']['title-end'], ENT_QUOTES);
154 } else {
155 echo $before_title . $title . $after_title;
156 }
157 }
158
159 // Expose Widget ID for customization
160 $instance['widget_id'] = $widget_id;
161
162 // Get posts
163 if ( $this->admin_options['tools']['ajax'] && ! is_customize_preview() ) {
164
165 if ( empty($before_widget) || ! preg_match('/id="[^"]*"/', $before_widget) ) {
166 ?>
167 <p><?php printf(__('Error: cannot ajaxify WordPress Popular Posts on this sidebar. It\'s missing the <em>id</em> attribute on before_widget (see <a href="%s" target="_blank" rel="nofollow">register_sidebar</a> for more)', 'wordpress-popular-posts'), 'https://codex.wordpress.org/Function_Reference/register_sidebar'); ?>.</p>
168 <?php
169 }
170 else {
171 ?>
172 <script type="text/javascript">
173 document.addEventListener('DOMContentLoaded', function() {
174 var wpp_widget_container = document.getElementById('<?php echo $widget_id; ?>');
175
176 if ( 'undefined' != typeof WordPressPopularPosts ) {
177 WordPressPopularPosts.get(
178 wpp_params.ajax_url + '/widget/<?php echo $this->number; ?>',
179 'is_single=<?php echo Helper::is_single(); ?><?php echo (function_exists('PLL')) ? '&lang=' . $this->translate->get_current_language() : ''; ?>',
180 function(response){
181 wpp_widget_container.innerHTML += JSON.parse(response).widget;
182
183 let sr = wpp_widget_container.querySelector('.popular-posts-sr');
184
185 if ( sr ) {
186 WordPressPopularPosts.theme(sr);
187 }
188
189 var event = null;
190
191 if ( 'function' === typeof(Event) ) {
192 event = new Event("wpp-onload", {"bubbles": true, "cancelable": false});
193 } /* Fallback for older browsers */
194 else {
195 if ( document.createEvent ) {
196 event = document.createEvent('Event');
197 event.initEvent("wpp-onload", true, false);
198 }
199 }
200
201 if ( event ) {
202 wpp_widget_container.dispatchEvent(event);
203 }
204 }
205 );
206 }
207 });
208 </script>
209 <?php
210 }
211 } else {
212 $this->get_popular($instance);
213 }
214
215 echo "\n" . $after_widget . "\n";
216 }
217
218 /**
219 * Generates the administration form for the widget.
220 *
221 * @since 1.0.0
222 * @param array $instance The array of keys and values for the widget.
223 */
224 public function form($instance)
225 {
226 $instance = Helper::merge_array_r(
227 $this->defaults,
228 (array) $instance
229 );
230 require plugin_dir_path(__FILE__) . '/form.php';
231 }
232
233 /**
234 * Processes the widget's options to be saved.
235 *
236 * @since 1.0.0
237 * @param array $new_instance The previous instance of values before the update.
238 * @param array $old_instance The new instance of values to be generated via the update.
239 * @return array $instance Updated instance.
240 */
241 public function update($new_instance, $old_instance)
242 {
243 if ( empty($old_instance) ) {
244 $old_instance = $this->defaults;
245 } else {
246 $old_instance = Helper::merge_array_r(
247 $this->defaults,
248 (array) $old_instance
249 );
250 }
251
252 $instance = $old_instance;
253
254 $instance['title'] = htmlspecialchars(stripslashes_deep(strip_tags($new_instance['title'])), ENT_QUOTES);
255 $instance['limit'] = ( Helper::is_number($new_instance['limit']) && $new_instance['limit'] > 0 )
256 ? $new_instance['limit']
257 : 10;
258 $instance['range'] = $new_instance['range'];
259 $instance['time_quantity'] = ( Helper::is_number($new_instance['time_quantity']) && $new_instance['time_quantity'] > 0 )
260 ? $new_instance['time_quantity']
261 : 24;
262 $instance['time_unit'] = $new_instance['time_unit'];
263 $instance['order_by'] = $new_instance['order_by'];
264
265 // FILTERS
266 // user did not set a post type name, so we fall back to default
267 $instance['post_type'] = ( '' == $new_instance['post_type'] )
268 ? 'post,page'
269 : $new_instance['post_type'];
270
271 $instance['freshness'] = isset($new_instance['freshness']);
272
273 // Post / Page / CTP filter
274 $ids = array_filter(explode(",", rtrim(preg_replace('|[^0-9,]|', '', $new_instance['pid']), ",")), 'is_numeric');
275 // Got no valid IDs, clear
276 if ( empty($ids) ) {
277 $instance['pid'] = '';
278 }
279 else {
280 $instance['pid'] = implode(",", $ids);
281 }
282
283 // Taxonomy filter
284 $taxonomies = $new_instance['taxonomy'];
285
286 if ( isset($taxonomies['names']) ) {
287 // Remove taxonomies that don't have any valid term IDs
288 foreach( $taxonomies['terms'] as $taxonomy => $terms ) {
289 $taxonomies['terms'][$taxonomy] = array_filter(
290 explode(",", trim(preg_replace('|[^0-9,-]|', '', $taxonomies['terms'][$taxonomy]), ", ")),
291 'is_numeric'
292 );
293
294 if (
295 empty($taxonomies['terms'][$taxonomy])
296 || ! in_array($taxonomy, $taxonomies['names'])
297 ) {
298 unset($taxonomies['terms'][$taxonomy]);
299 } else {
300 $taxonomies['terms'][$taxonomy] = implode(',', $taxonomies['terms'][$taxonomy]);
301 }
302 }
303
304 if ( ! empty($taxonomies['terms']) ) {
305 $instance['taxonomy'] = implode(';', array_keys($taxonomies['terms']));
306 $instance['term_id'] = implode(';', array_values($taxonomies['terms']));
307 }
308 } // Discard everything
309 else {
310 $instance['taxonomy'] = '';
311 $instance['term_id'] = '';
312 }
313
314 // Author filter
315 $ids = array_filter(explode(",", rtrim(preg_replace('|[^0-9,]|', '', $new_instance['uid']), ",")), 'is_numeric');
316 // Got no valid IDs, clear
317 if ( empty($ids) ) {
318 $instance['author'] = '';
319 }
320 else {
321 $instance['author'] = implode( ",", $ids );
322 }
323
324 $instance['shorten_title']['words'] = $new_instance['shorten_title-words'];
325 $instance['shorten_title']['active'] = isset($new_instance['shorten_title-active']);
326 $instance['shorten_title']['length'] = ( Helper::is_number($new_instance['shorten_title-length']) && $new_instance['shorten_title-length'] > 0 )
327 ? $new_instance['shorten_title-length']
328 : 25;
329
330 $instance['post-excerpt']['keep_format'] = isset($new_instance['post-excerpt-format']);
331 $instance['post-excerpt']['words'] = $new_instance['post-excerpt-words'];
332 $instance['post-excerpt']['active'] = isset($new_instance['post-excerpt-active']);
333 $instance['post-excerpt']['length'] = ( Helper::is_number($new_instance['post-excerpt-length']) && $new_instance['post-excerpt-length'] > 0 )
334 ? $new_instance['post-excerpt-length']
335 : 55;
336
337 $instance['thumbnail']['active'] = isset($new_instance['thumbnail-active']);
338 $instance['thumbnail']['build'] = $new_instance['thumbnail-size-source'];
339 $instance['thumbnail']['width'] = 75;
340 $instance['thumbnail']['height'] = 75;
341
342 // Use predefined thumbnail sizes
343 if ( 'predefined' == $new_instance['thumbnail-size-source'] ) {
344 $default_thumbnail_sizes = $this->thumbnail->get_sizes();
345 $size = $default_thumbnail_sizes[$new_instance['thumbnail-size']];
346
347 $instance['thumbnail']['width'] = $size['width'];
348 $instance['thumbnail']['height'] = $size['height'];
349 $instance['thumbnail']['crop'] = $size['crop'];
350 } // Set thumbnail size manually
351 else {
352 if ( Helper::is_number($new_instance['thumbnail-width']) && Helper::is_number($new_instance['thumbnail-height']) ) {
353 $instance['thumbnail']['width'] = $new_instance['thumbnail-width'];
354 $instance['thumbnail']['height'] = $new_instance['thumbnail-height'];
355 $instance['thumbnail']['crop'] = true;
356 }
357 }
358
359 $instance['rating'] = isset($new_instance['rating']);
360 $instance['stats_tag']['comment_count'] = isset($new_instance['comment_count']);
361 $instance['stats_tag']['views'] = isset($new_instance['views']);
362 $instance['stats_tag']['author'] = isset($new_instance['author']);
363 $instance['stats_tag']['date']['active'] = isset($new_instance['date']);
364 $instance['stats_tag']['date']['format'] = empty($new_instance['date_format'])
365 ? 'F j, Y'
366 : $new_instance['date_format'];
367
368 $instance['stats_tag']['taxonomy']['active'] = isset($new_instance['stats_taxonomy']);
369 $instance['stats_tag']['taxonomy']['name'] = isset($new_instance['stats_taxonomy_name']) ? $new_instance['stats_taxonomy_name'] : 'category';
370 $instance['stats_tag']['category'] = isset($new_instance['stats_taxonomy'] ); // Deprecated in 4.0.0!
371
372 $instance['markup']['custom_html'] = isset($new_instance['custom_html']);
373 $instance['markup']['wpp-start'] = empty($new_instance['wpp-start'])
374 ? ! $old_instance['markup']['custom_html'] && $instance['markup']['custom_html'] ? htmlspecialchars('<ul class="wpp-list">', ENT_QUOTES) : ''
375 : htmlspecialchars($new_instance['wpp-start'], ENT_QUOTES);
376
377 $instance['markup']['wpp-end'] = empty($new_instance['wpp-end'])
378 ? ! $old_instance['markup']['custom_html'] && $instance['markup']['custom_html'] ? htmlspecialchars('</ul>', ENT_QUOTES) : ''
379 : htmlspecialchars($new_instance['wpp-end'], ENT_QUOTES);
380
381 $instance['markup']['post-html'] = empty($new_instance['post-html'])
382 ? htmlspecialchars('<li>{thumb} {title} {stats}</li>', ENT_QUOTES)
383 : htmlspecialchars($new_instance['post-html'], ENT_QUOTES);
384
385 $instance['markup']['title-start'] = empty($new_instance['title-start'])
386 ? ! $old_instance['markup']['custom_html'] && $instance['markup']['custom_html'] ? '<h2>' : ''
387 : htmlspecialchars($new_instance['title-start'], ENT_QUOTES);
388
389 $instance['markup']['title-end'] = empty($new_instance['title-end'])
390 ? ! $old_instance['markup']['custom_html'] && $instance['markup']['custom_html'] ? '</h2>' : '' :
391 htmlspecialchars($new_instance['title-end'], ENT_QUOTES);
392
393 $instance['theme'] = [
394 'name' => isset($new_instance['theme']) ? $new_instance['theme'] : '',
395 'applied' => isset($new_instance['theme']) ? (bool) $new_instance['theme-applied'] : false
396 ];
397
398 if ( ! isset($new_instance['theme']) || $old_instance['theme']['name'] != $new_instance['theme'] ) {
399 $instance['theme']['applied'] = false;
400 }
401
402 $theme = $instance['theme']['name'] ? $this->themer->get_theme($instance['theme']['name']) : null;
403
404 if (
405 is_array($theme)
406 && isset($theme['json'])
407 && isset($theme['json']['config'])
408 && is_array($theme['json']['config'])
409 && ! $instance['theme']['applied']
410 ) {
411 $instance = Helper::merge_array_r(
412 $instance,
413 $theme['json']['config']
414 );
415 $instance['markup']['custom_html'] = true;
416 $instance['theme']['applied'] = true;
417
418 $current_sidebar_data = $this->get_sidebar_data();
419
420 if ( $current_sidebar_data ) {
421 $instance['markup']['title-start'] = htmlspecialchars($current_sidebar_data['before_title'], ENT_QUOTES);
422 $instance['markup']['title-end'] = htmlspecialchars($current_sidebar_data['after_title'], ENT_QUOTES);
423 }
424 }
425
426 return $instance;
427 }
428
429 /**
430 * Returns HTML list.
431 *
432 * @since 2.3.3
433 */
434 public function get_popular($instance = null)
435 {
436 if ( is_array($instance) && ! empty($instance) ) {
437 // Return cached results
438 if ( $this->admin_options['tools']['cache']['active'] ) {
439
440 $key = md5(json_encode($instance));
441 $popular_posts = \WordPressPopularPosts\Cache::get($key);
442
443 if ( false === $popular_posts ) {
444 $popular_posts = new Query($instance);
445
446 $time_value = $this->admin_options['tools']['cache']['interval']['value']; // eg. 5
447 $time_unit = $this->admin_options['tools']['cache']['interval']['time']; // eg. 'minute'
448
449 // No popular posts found, check again in 1 minute
450 if ( ! $popular_posts->get_posts() ) {
451 $time_value = 1;
452 $time_unit = 'minute';
453 }
454
455 \WordPressPopularPosts\Cache::set(
456 $key,
457 $popular_posts,
458 $time_value,
459 $time_unit
460 );
461 }
462
463 } // Get popular posts
464 else {
465 $popular_posts = new Query($instance);
466 }
467
468 $this->output->set_data($popular_posts->get_posts());
469 $this->output->set_public_options($instance);
470 $this->output->build_output();
471
472 echo ( $this->admin_options['tools']['cache']['active'] ? '<!-- cached -->' : '' );
473 $this->output->output();
474 }
475 }
476
477 /**
478 * Returns data on the current sidebar.
479 *
480 * @since 5.0.0
481 * @access private
482 * @return array|null
483 */
484 private function get_sidebar_data()
485 {
486 global $wp_registered_sidebars;
487 $sidebars = wp_get_sidebars_widgets();
488
489 foreach ( (array) $sidebars as $sidebar_id => $sidebar ) {
490 if ( in_array($this->id, (array) $sidebar, true ) )
491 return $wp_registered_sidebars[$sidebar_id];
492 }
493
494 return null;
495 }
496 }
497