PluginProbe ʕ •ᴥ•ʔ
WP Popular Posts / trunk
WP Popular Posts vtrunk
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 / Block / Widget / Widget.php
wordpress-popular-posts / src / Block / Widget Last commit date
edit 4 weeks ago Widget.php 4 weeks ago edit.js 1 year ago editor.css 4 years ago widget.js 4 weeks ago
Widget.php
518 lines
1 <?php
2 namespace WordPressPopularPosts\Block\Widget;
3
4 use WordPressPopularPosts\{ Helper, Image, Output, Themer, Translate };
5 use WordPressPopularPosts\Block\Block;
6 use WordPressPopularPosts\Traits\QueriesPosts;
7
8 class Widget extends Block
9 {
10
11 use QueriesPosts;
12
13 /**
14 * Administrative settings.
15 *
16 * @since 5.4.0
17 * @var array
18 * @access private
19 */
20 private $config = [];
21
22 /**
23 * Image object.
24 *
25 * @since 5.4.0
26 * @var WordPressPopularPosts\Image
27 * @access private
28 */
29 private $thumbnail;
30
31 /**
32 * Output object.
33 *
34 * @since 5.4.0
35 * @var \WordPressPopularPosts\Output
36 * @access private
37 */
38 private $output;
39
40 /**
41 * Translate object.
42 *
43 * @since 5.4.0
44 * @var \WordPressPopularPosts\Translate $translate
45 * @access private
46 */
47 private $translate;
48
49 /**
50 * Themer object.
51 *
52 * @since 5.4.0
53 * @var \WordPressPopularPosts\Themer $themer
54 * @access private
55 */
56 private $themer;
57
58 /**
59 * Default attributes.
60 *
61 * @since 5.4.0
62 * @var array $defaults
63 * @access private
64 */
65 private $defaults;
66
67 /**
68 * Construct.
69 *
70 * @since 5.4.0
71 * @param array $config
72 * @param \WordPressPopularPosts\Output $output
73 * @param \WordPressPopularPosts\Image $image
74 * @param \WordPressPopularPosts\Translate $translate
75 * @param \WordPressPopularPosts\Themer $themer
76 */
77 public function __construct(array $config, Output $output, Image $thumbnail, Translate $translate, Themer $themer)
78 {
79 $this->config = $config;
80 $this->output = $output;
81 $this->thumbnail = $thumbnail;
82 $this->translate = $translate;
83 $this->themer = $themer;
84
85 $this->defaults = [
86 'title' => '',
87 'limit' => 10,
88 'offset' => 0,
89 'range' => 'daily',
90 'time_unit' => 'hour',
91 'time_quantity' => 24,
92 'freshness' => false,
93 'order_by' => 'views',
94 'post_type' => 'post',
95 'pid' => '', // Deprecated
96 'exclude' => '',
97 'cat' => '',
98 'taxonomy' => 'category',
99 'tax' => '',
100 'term_id' => '',
101 'author' => '',
102 'title_length' => 0,
103 'title_by_words' => 0,
104 'excerpt_length' => 0,
105 'excerpt_format' => 0,
106 'excerpt_by_words' => 0,
107 'thumbnail_width' => 0,
108 'thumbnail_height' => 0,
109 'thumbnail_build' => 'manual',
110 'thumbnail_size' => '',
111 'rating' => false,
112 'stats_comments' => false,
113 'stats_views' => true,
114 'stats_author' => false,
115 'stats_date' => false,
116 'stats_date_format' => 'F j, Y',
117 'stats_category' => false,
118 'stats_taxonomy' => false,
119 'custom_html' => false,
120 'wpp_start' => '<ul class="wpp-list">',
121 'wpp_end' => '</ul>',
122 'header_start' => '<h2>',
123 'header_end' => '</h2>',
124 'post_html' => '',
125 'theme' => ''
126 ];
127 }
128
129 /**
130 * Registers the block.
131 *
132 * @since 5.4.0
133 */
134 public function register()
135 {
136 // Block editor is not available, bail.
137 if ( ! function_exists('register_block_type') ) {
138 return;
139 }
140
141 $block_editor_support = apply_filters('wpp_block_editor_support', true);
142
143 if ( ! $block_editor_support ) {
144 return;
145 }
146
147 wp_register_script(
148 'block-wpp-widget-js',
149 plugin_dir_url(dirname(dirname(dirname(__FILE__)))) . 'assets/js/blocks/block-wpp-widget.js',
150 ['wp-blocks', 'wp-i18n', 'wp-element', 'wp-block-editor', 'wp-server-side-render'],
151 filemtime(plugin_dir_path(dirname(dirname(dirname(__FILE__)))) . 'assets/js/blocks/block-wpp-widget.js')
152 );
153
154 wp_localize_script(
155 'block-wpp-widget-js',
156 '_wordpress_popular_posts',
157 [
158 'can_show_rating' => function_exists('the_ratings_results')
159 ]
160 );
161
162 wp_register_style(
163 'block-wpp-editor-css',
164 plugins_url('editor.css', __FILE__),
165 [],
166 filemtime(plugin_dir_path(__FILE__) . 'editor.css')
167 );
168
169 register_block_type(
170 'wordpress-popular-posts/widget',
171 [
172 'api_version' => 3,
173 'editor_style' => 'block-wpp-editor-css',
174 'editor_script' => 'block-wpp-widget-js',
175 'render_callback' => [$this, 'render'],
176 'attributes' => [
177 '_editMode' => [
178 'type' => 'boolean',
179 'default' => true
180 ],
181 '_isSelected' => [
182 'type' => 'boolean',
183 'default' => false
184 ],
185 'title' => [
186 'type' => 'string',
187 'default' => ''
188 ],
189 'limit' => [
190 'type' =>'number',
191 'default' => 10
192 ],
193 'offset' => [
194 'type' => 'number',
195 'default' => 0
196 ],
197 'order_by' => [
198 'type' => 'string',
199 'default' => 'views'
200 ],
201 'range' => [
202 'type' => 'string',
203 'default' => 'last24hours'
204 ],
205 'time_quantity' => [
206 'type' => 'number',
207 'default' => 24
208 ],
209 'time_unit' => [
210 'type' => 'string',
211 'default' => 'hour'
212 ],
213 'freshness' => [
214 'type' => 'boolean',
215 'default' => false
216 ],
217 /* filters */
218 'post_type' => [
219 'type' => 'string',
220 'default' => 'post'
221 ],
222 'pid' => /* Deprecated */ [
223 'type' => 'string',
224 'default' => ''
225 ],
226 'exclude' => [
227 'type' => 'string',
228 'default' => ''
229 ],
230 'author' => [
231 'type' => 'string',
232 'default' => ''
233 ],
234 'tax' => [
235 'type' => 'string',
236 'default' => ''
237 ],
238 'term_id' => [
239 'type' => 'string',
240 'default' => ''
241 ],
242 /* post settings */
243 'shorten_title' => [
244 'type' => 'boolean',
245 'default' => false
246 ],
247 'title_length' => [
248 'type' =>'number',
249 'default' => 0
250 ],
251 'title_by_words' => [
252 'type' =>'number',
253 'default' => 0
254 ],
255 'display_post_excerpt' => [
256 'type' => 'boolean',
257 'default' => false
258 ],
259 'excerpt_format' => [
260 'type' => 'boolean',
261 'default' => false
262 ],
263 'excerpt_length' => [
264 'type' =>'number',
265 'default' => 0
266 ],
267 'excerpt_by_words' => [
268 'type' =>'number',
269 'default' => 0
270 ],
271 'display_post_thumbnail' => [
272 'type' => 'boolean',
273 'default' => false
274 ],
275 'thumbnail_width' => [
276 'type' =>'number',
277 'default' => 0
278 ],
279 'thumbnail_height' => [
280 'type' =>'number',
281 'default' => 0
282 ],
283 'thumbnail_build' => [
284 'type' => 'string',
285 'default' => 'manual'
286 ],
287 'thumbnail_size' => [
288 'type' => 'string',
289 'default' => ''
290 ],
291 'rating' => [
292 'type' => 'boolean',
293 'default' => false
294 ],
295 /* stats tag settings */
296 'stats_comments' => [
297 'type' => 'boolean',
298 'default' => false
299 ],
300 'stats_views' => [
301 'type' => 'boolean',
302 'default' => true
303 ],
304 'stats_author' => [
305 'type' => 'boolean',
306 'default' => false
307 ],
308 'stats_date' => [
309 'type' => 'boolean',
310 'default' => false
311 ],
312 'stats_date_format' => [
313 'type' => 'string',
314 'default' => 'F j, Y'
315 ],
316 'stats_taxonomy' => [
317 'type' => 'boolean',
318 'default' => false
319 ],
320 'taxonomy' => [
321 'type' => 'string',
322 'default' => 'category'
323 ],
324 /* HTML markup settings */
325 'custom_html' => [
326 'type' => 'boolean',
327 'default' => false
328 ],
329 'header_start' => [
330 'type' => 'string',
331 'default' => '<h2>'
332 ],
333 'header_end' => [
334 'type' => 'string',
335 'default' => '</h2>'
336 ],
337 'wpp_start' => [
338 'type' => 'string',
339 'default' => '<ul class="wpp-list">'
340 ],
341 'wpp_end' => [
342 'type' => 'string',
343 'default' => '</ul>'
344 ],
345 'post_html' => [
346 'type' => 'string',
347 'default' => '<li class="{current_class}">{thumb} {title} <span class="wpp-meta post-stats">{stats}</span></li>'
348 ],
349 'theme' => [
350 'type' => 'string',
351 'default' => ''
352 ],
353 ]
354 ]
355 );
356 }
357
358 /**
359 * Renders the block.
360 *
361 * @since 5.4.0
362 * @param array
363 * @return string
364 */
365 public function render(array $attributes)
366 {
367 extract($this->parse_attributes($attributes));
368
369 $html = '<div class="popular-posts' . (( isset($attributes['className']) && $attributes['className'] ) ? ' ' . esc_attr($attributes['className']) : '') . '">';
370
371 // possible values for "Time Range" and "Order by"
372 $time_units = ['minute', 'hour', 'day', 'week', 'month'];
373 $range_values = ['daily', 'last24hours', 'weekly', 'last7days', 'monthly', 'last30days', 'all', 'custom'];
374 $order_by_values = ['comments', 'views', 'avg'];
375
376 $theme_data = $this->themer->get_theme($theme);
377
378 if ( ! isset($theme_data['json']) ) {
379 $theme = '';
380 }
381
382 $query_args = [
383 'title' => strip_tags($title), // phpcs:ignore WordPress.WP.AlternativeFunctions.strip_tags_strip_tags -- We want the behavior of strip_tags
384 'limit' => ( ! empty($limit) && Helper::is_number($limit) && $limit > 0 ) ? $limit : 10,
385 'offset' => ( ! empty($offset) && Helper::is_number($offset) && $offset >= 0 ) ? $offset : 0,
386 'range' => ( in_array($range, $range_values) ) ? $range : 'daily',
387 'time_quantity' => ( ! empty($time_quantity) && Helper::is_number($time_quantity) && $time_quantity > 0 ) ? $time_quantity : 24,
388 'time_unit' => ( in_array($time_unit, $time_units) ) ? $time_unit : 'hour',
389 'freshness' => empty($freshness) ? false : $freshness,
390 'order_by' => ( in_array($order_by, $order_by_values) ) ? $order_by : 'views',
391 'post_type' => empty($post_type) ? 'post' : $post_type,
392 'pid' => rtrim(preg_replace('|[^0-9,]|', '', $pid), ','), /** Deprecated */
393 'exclude' => rtrim(preg_replace('|[^0-9,]|', '', $exclude), ','),
394 'taxonomy' => empty($tax) ? 'category' : $tax,
395 'term_id' => rtrim(preg_replace('|[^0-9,;-]|', '', $term_id), ','),
396 'author' => rtrim(preg_replace('|[^0-9,]|', '', $author), ','),
397 'shorten_title' => [
398 'active' => ( (bool) $attributes['shorten_title'] && ! empty($title_length) && Helper::is_number($title_length) && $title_length > 0 ),
399 'length' => ( ! empty($title_length) && Helper::is_number($title_length) ) ? $title_length : 0,
400 'words' => (( ! empty($title_by_words) && Helper::is_number($title_by_words) && $title_by_words > 0 )),
401 ],
402 'post-excerpt' => [
403 'active' => ( (bool) $attributes['display_post_excerpt'] && ! empty($excerpt_length) && Helper::is_number($excerpt_length) && $excerpt_length > 0 ),
404 'length' => ( ! empty($excerpt_length) && Helper::is_number($excerpt_length) ) ? $excerpt_length : 0,
405 'keep_format' => ( ! empty($excerpt_format) && Helper::is_number($excerpt_format) && $excerpt_format > 0 ),
406 'words' => ( ! empty($excerpt_by_words) && Helper::is_number($excerpt_by_words) && $excerpt_by_words > 0 ),
407 ],
408 'thumbnail' => [
409 'active' => ( 'predefined' == $thumbnail_build && (bool) $attributes['display_post_thumbnail'] ) ? true : ( ! empty($thumbnail_width) && Helper::is_number($thumbnail_width) && $thumbnail_width > 0 ),
410 'width' => ( ! empty($thumbnail_width) && Helper::is_number($thumbnail_width) && $thumbnail_width > 0 ) ? $thumbnail_width : 0,
411 'height' => ( ! empty($thumbnail_height) && Helper::is_number($thumbnail_height) && $thumbnail_height > 0 ) ? $thumbnail_height : 0,
412 'build' => 'predefined' == $thumbnail_build ? 'predefined' : 'manual',
413 'size' => empty($thumbnail_size) ? '' : $thumbnail_size,
414 ],
415 'rating' => (bool) $attributes['rating'],
416 'stats_tag' => [
417 'comment_count' => (bool) $attributes['stats_comments'],
418 'views' => (bool) $attributes['stats_views'],
419 'author' => (bool) $attributes['stats_author'],
420 'date' => [
421 'active' => (bool) $attributes['stats_date'],
422 'format' => empty($stats_date_format) ? 'F j, Y' : $stats_date_format
423 ],
424 'taxonomy' => [
425 'active' => (bool) $attributes['stats_taxonomy'],
426 'name' => empty($taxonomy) ? 'category' : $taxonomy,
427 ]
428 ],
429 'markup' => [
430 'custom_html' => (bool) $attributes['custom_html'],
431 'wpp-start' => empty($wpp_start) ? '' : $wpp_start,
432 'wpp-end' => empty($wpp_end) ? '' : $wpp_end,
433 'title-start' => empty($header_start) ? '' : $header_start,
434 'title-end' => empty($header_end) ? '' : $header_end,
435 'post-html' => empty($post_html) ? '<li>{thumb} {title} <span class="wpp-meta post-stats">{stats}</span></li>' : $post_html
436 ],
437 'theme' => [
438 'name' => empty($theme) ? '' : $theme
439 ]
440 ];
441
442 // Post / Page / CTP filter
443 $query_args['exclude'] = $query_args['pid'];
444
445 $ids = array_filter(explode(',', $query_args['exclude']), 'is_numeric');
446 // Got no valid IDs, clear
447 if ( empty($ids) ) {
448 $query_args['pid'] = '';
449 $query_args['exclude'] = '';
450 }
451
452 // Taxonomy filter
453 $ids = array_filter(explode(',', $query_args['term_id']), 'is_numeric');
454 // Got no valid term IDs, clear
455 if ( empty($ids) ) {
456 $query_args['term_id'] = '';
457 }
458
459 // Author filter
460 $ids = array_filter(explode(',', $query_args['author']), 'is_numeric');
461 // Got no valid IDs, clear
462 if ( empty($ids) ) {
463 $query_args['author'] = '';
464 }
465
466 // Has the user set a title?
467 if (
468 ! empty($query_args['title'])
469 && ! empty($query_args['markup']['title-start'])
470 && ! empty($query_args['markup']['title-end'])
471 ) {
472 $header_html = htmlspecialchars_decode($query_args['markup']['title-start'], ENT_QUOTES) . $query_args['title'] . htmlspecialchars_decode($query_args['markup']['title-end'], ENT_QUOTES);
473 $header_html = apply_filters('wpp_custom_header_html', $header_html, $query_args);
474 $header_html = Helper::sanitize_html($header_html, $query_args);
475 $html .= $header_html;
476 }
477
478 $isAdmin = isset($_GET['isSelected']) ? $_GET['isSelected'] : false; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- isSelected is a boolean from wp-admin
479
480 if ( $this->config['tools']['ajax'] && ! is_customize_preview() && ! $isAdmin ) {
481 $html .= '<script type="application/json" data-id="wpp-block-inline-js">' . json_encode($query_args) . '</script>';
482 $html .= '<div class="wpp-widget-block-placeholder"></div>';
483
484 return $html . '</div>';
485 }
486
487 $popular_posts = $this->maybe_query($query_args);
488
489 $this->output->set_data($popular_posts->get_posts());
490 $this->output->set_public_options($query_args);
491 $this->output->build_output();
492
493 $html .= $this->output->get_output();
494
495 $html .= '</div>';
496
497 return $html;
498 }
499
500 /**
501 * Parses attributes.
502 *
503 * @since 5.4.0
504 * @param array
505 * @return array
506 */
507 private function parse_attributes(array $atts = [])
508 {
509 $out = array();
510
511 foreach ( $this->defaults as $name => $default ) {
512 $out[$name] = array_key_exists($name, $atts) ? trim($atts[$name]) : $default;
513 }
514
515 return $out;
516 }
517 }
518