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