build_inline_styles()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 3
b 0
f 0
nc 1
nop 0
dl 0
loc 2
rs 10
1
<?php
2
/**
3
 * This is the base class for the Popular Posts output functionality.
4
 * Each actual Popular Posts option extends this class (inline, widget, products).
5
 *
6
 * @package MonsterInsights
7
 */
8
9
/**
10
 * Class MonsterInsights_Popular_Posts
11
 */
12
class MonsterInsights_Popular_Posts {
13
14
	/**
15
	 * The key prefix used to store the settings for the magic __get method.
16
	 *
17
	 * @var string
18
	 */
19
	protected $settings_key;
20
21
	/**
22
	 * Name of the shortcode
23
	 *
24
	 * @var string
25
	 */
26
	protected $shortcode_key;
27
28
	/**
29
	 * The popular posts object type, by default inline, widget or products.
30
	 *
31
	 * @var string
32
	 */
33
	protected $type;
34
35
	/**
36
	 * An array of posts used in the query process.
37
	 *
38
	 * @var array
39
	 */
40
	public $posts = array();
41
42
	/**
43
	 * An array of posts already displayed. Used to avoid duplicate posts on the same page.
44
	 *
45
	 * @var array
46
	 */
47
	public $shown_posts = array();
48
49
	/**
50
	 * The inline styles string with theme specifics from the Vue settings.
51
	 * Each instance should append to this variable so we print styles for all the instances in the same place.
52
	 *
53
	 * @var string
54
	 */
55
	public static $inline_styles = '';
56
57
	/**
58
	 * Stores the option to use ajax to display the popular posts widgets on the frontend.
59
	 *
60
	 * @var string
61
	 */
62
	public $ajaxify;
63
64
	/**
65
	 * Stores the cache instance, specific to the plugin version.
66
	 *
67
	 * @var MonsterInsights_Popular_Posts_Cache
68
	 */
69
	public $cache;
70
71
	/**
72
	 * Holds the class object.
73
	 *
74
	 * @since 7.13.0
75
	 * @access public
76
	 * @var array
77
	 */
78
	public static $instances = array();
79
80
	/**
81
	 * @var MonsterInsights_Popular_Posts_Themes
82
	 */
83
	protected $theme_props;
84
85
	/**
86
	 * Indicator that inline styles have been printed to avoid duplicates.
87
	 *
88
	 * @var bool
89
	 */
90
	private static $styles_printed = false;
91
92
	/**
93
	 * Number of posts to query from the db. Not all queried posts are used for display in the same widget.
94
	 *
95
	 * @var int
96
	 */
97
	public $posts_count = 15;
98
99
	/**
100
	 * MonsterInsights_Popular_Posts constructor.
101
	 */
102
	public function __construct() {
103
104
		$this->hooks();
105
		$this->register_shortcode();
106
107
		$this->ajaxify = monsterinsights_get_option( 'popular_posts_ajaxify', false );
108
	}
109
110
	/**
111
	 * Magic get for different types of popular posts.
112
	 *
113
	 * @param $name
114
	 *
115
	 * @return string|array|mixed
116
	 */
117
	public function __get( $name ) {
118
		return monsterinsights_get_option( $this->settings_key . '_' . $name );
119
	}
120
121
	/**
122
	 * Add hooks needed for the output.
123
	 */
124
	public function hooks() {
125
		add_action( 'wp_enqueue_scripts', array( $this, 'load_frontend_styles' ) );
126
127
		add_action( 'wp_enqueue_scripts', array( $this, 'maybe_load_ajaxify_script' ) );
128
129
		$this->add_inline_styles();
130
	}
131
132
	/**
133
	 * Add inline styles for each widget type to a single variable for printing.
134
	 */
135
	protected function add_inline_styles() {
136
		if ( 'no_styles' !== $this->styling ) {
0 ignored issues
show
Bug Best Practice introduced by
The property styling does not exist on MonsterInsights_Popular_Posts. Since you implemented __get, consider adding a @property annotation.
Loading history...
137
			self::$inline_styles .= $this->build_inline_styles();
138
		}
139
	}
140
141
	/**
142
	 * Should return object-specific inline styles.
143
	 *
144
	 * @return string
145
	 */
146
	public function build_inline_styles() {
147
		return '';
148
	}
149
150
	/**
151
	 * Register the shortcode for the specific class.
152
	 */
153
	public function register_shortcode() {
154
155
		if ( ! empty( $this->shortcode_key ) ) {
156
			add_shortcode( $this->shortcode_key, array( $this, 'render_shortcode' ) );
157
		}
158
159
	}
160
161
	/**
162
	 * Load the frontend styles if they are enabled.
163
	 */
164
	public function load_frontend_styles() {
165
166
		// Only load our styles if enabled.
167
		if ( apply_filters( 'monsterinsights_popular_posts_styles_output', 'no_styles' === $this->styling, $this ) ) {
0 ignored issues
show
Bug Best Practice introduced by
The property styling does not exist on MonsterInsights_Popular_Posts. Since you implemented __get, consider adding a @property annotation.
Loading history...
168
			return;
169
		}
170
		$suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
171
172
		$url = apply_filters(
173
			'monsterinsights_frontend_style_url',
174
			plugins_url( 'assets/css/frontend' . $suffix . '.css', MONSTERINSIGHTS_PLUGIN_FILE )
175
		);
176
177
		// Load Popular Posts styles.
178
		wp_register_style( 'monsterinsights-editor-frontend-style', $url, array(), monsterinsights_get_asset_version() );
179
180
		$this->add_theme_specific_styles();
181
	}
182
183
	/**
184
	 * If the Ajaxify option is enabled, print needed scripts.
185
	 */
186
	public function maybe_load_ajaxify_script() {
187
		if ( ! $this->ajaxify ) {
188
			return;
189
		}
190
		$suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
191
192
		wp_register_script( 'monsterinsights-popular-posts-js', plugins_url( 'assets/js/popular-posts' . $suffix . '.js', MONSTERINSIGHTS_PLUGIN_FILE ), array(), monsterinsights_get_asset_version(), true );
193
194
		wp_enqueue_script( 'monsterinsights-popular-posts-js' );
195
196
		monsterinsights_localize_script( 'monsterinsights-popular-posts-js', 'monsterinsights_pp', array(
197
			'ajaxurl' => admin_url( 'admin-ajax.php' ),
198
			'post_id' => get_the_ID(),
199
			'nonce'   => wp_create_nonce('mi-popular-posts'),
200
		) );
201
	}
202
203
	/**
204
	 * Add inline styles based on customizations from the vue panel.
205
	 */
206
	public function add_theme_specific_styles() {
207
208
		if ( ! self::$styles_printed ) {
209
			wp_add_inline_style( 'monsterinsights-editor-frontend-style', $this->get_inline_styles() );
210
			self::$styles_printed = true;
211
		}
212
213
	}
214
215
	/**
216
	 * We have a single static variable for inline styles shared by all instances so we print just once.
217
	 *
218
	 * @return string
219
	 */
220
	public function get_inline_styles() {
221
		return self::$inline_styles;
222
	}
223
224
	/**
225
	 * Rendering the shortcode.
226
	 *
227
	 * @return string
228
	 */
229
	public function render_shortcode( $args ) {
230
		if ( empty( $args ) || ! is_array( $args ) ) {
231
			$args = array();
232
		}
233
234
		return apply_filters( 'monsterinsights_popular_posts_shortcode_output', $this->shortcode_output( $args ), $args, $this );
235
236
	}
237
238
	/**
239
	 * Output of shortcode based on settings.
240
	 *
241
	 * @param array $args Arguments from shortcode/block.
242
	 *
243
	 * @return string
244
	 */
245
	public function shortcode_output( $args ) {
246
		// Load frontend.css file when shortcode is available
247
		wp_enqueue_style( 'monsterinsights-editor-frontend-style' );
248
249
		if ( $this->ajaxify ) {
250
			return $this->get_ajax_json_data( $args );
251
		} else {
252
			return $this->get_rendered_html( $args );
253
		}
254
	}
255
256
	/**
257
	 * Print inline JSON data that with settings that get processed using an AJAX call. Acts similar to printing out
258
	 * a shortcode with its settings but actually loading the output for that after the page was loaded, with AJAX.
259
	 *
260
	 * @param array $args Arguments from shortcode/block.
261
	 *
262
	 * @return string
263
	 */
264
	public function get_ajax_json_data( $args ) {
265
266
		$args['type'] = $this->type;
267
268
		$data = '<div><script type="application/json" class="monsterinsights-popular-posts-widget-json">';
269
		$data .= wp_json_encode( $args );
270
		$data .= '</script></div>';
271
272
		return $data;
273
	}
274
275
	/**
276
	 * This is replaced with actual HTML output in child classes.
277
	 *
278
	 * @param array $args Arguments used to build specific html.
279
	 *
280
	 * @return string
281
	 */
282
	public function get_rendered_html( $args ) {
283
		return '';
284
	}
285
286
	/**
287
	 * Get the cache instance for the set type.
288
	 *
289
	 * @return MonsterInsights_Popular_Posts_Cache
290
	 */
291
	public function get_cache() {
292
		if ( ! isset( $this->cache ) ) {
293
			$this->cache = new MonsterInsights_Popular_Posts_Cache( $this->type );
294
		}
295
296
		return $this->cache;
297
	}
298
299
	/**
300
	 * Use the query args to grab posts from the database.
301
	 */
302
	public function get_posts() {
303
304
		$posts_args = $this->get_query_args();
305
306
		$posts = $this->get_cache()->get_cached_posts( $posts_args );
307
308
		if ( empty( $posts ) ) {
309
310
			if ( isset( $posts_args['post__in'] ) && empty( $posts_args['post__in'] ) ) {
311
				$this->posts = array();
312
313
				return $this->posts;
314
			}
315
			$posts = get_posts( $posts_args );
316
317
			$this->get_cache()->save_posts_to_cache( $posts_args, $posts );
318
		}
319
320
		$posts = $this->process_posts( $posts );
321
322
		return apply_filters( 'monsterinsights_popular_posts_posts', $posts );
323
324
	}
325
326
	/**
327
	 * Go through posts from a WP Query and prepare them for output.
328
	 *
329
	 * @param array $posts Array of posts from WP Query or similar, also supports array of ids.
330
	 *
331
	 * @return array
332
	 */
333
	private function process_posts( $posts ) {
334
		$processed_posts = array();
335
		foreach ( $posts as $post ) {
336
			if ( is_int( $post ) ) {
337
				$post = get_post( $post );
338
			}
339
			$post_thumbnail    = get_post_thumbnail_id( $post->ID );
340
			$post_image        = '';
341
			$post_image_srcset = '';
342
			if ( ! empty( $post_thumbnail ) ) {
343
				$post_image = wp_get_attachment_image_src( $post_thumbnail, 'medium' );
344
				if ( is_array( $post_image ) && ! empty( $post_image[0] ) ) {
345
					$post_image = $post_image[0];
346
				}
347
				$post_image_srcset = wp_get_attachment_image_srcset( $post_thumbnail, 'medium' );
348
			}
349
350
			$author_data = get_userdata( $post->post_author );
0 ignored issues
show
Bug introduced by
$post->post_author of type string is incompatible with the type integer expected by parameter $user_id of get_userdata(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

350
			$author_data = get_userdata( /** @scrutinizer ignore-type */ $post->post_author );
Loading history...
351
352
			$processed_posts[] = array(
353
				'id'          => $post->ID,
354
				'title'       => get_the_title( $post->ID ),
355
				'link'        => get_permalink( $post->ID ),
356
				'image'       => $post_image,
357
				'srcset'      => $post_image_srcset,
358
				'image_id'    => $post_thumbnail,
359
				'author'      => $post->post_author,
360
				'author_name' => $author_data->display_name,
361
				'date'        => get_the_date( '', $post->ID ),
362
				'comments'    => get_comments_number( $post->ID ),
363
			);
364
		}
365
366
		return $processed_posts;
367
	}
368
369
	/**
370
	 * Get the query args for grabbing the posts. This should probably get overwritten in child classes.
371
	 *
372
	 * @return mixed|void
373
	 */
374
	private function get_query_args() {
375
376
		$args = array(
377
			'numberposts'         => 25,
378
			'ignore_sticky_posts' => true,
379
			'fields'              => 'ids',
380
			'orderby'              => 'rand',
381
		);
382
		$args = wp_parse_args( $this->query_args(), $args );
383
384
		return apply_filters( 'monsterinsights_popular_posts_query_args', $args );
385
	}
386
387
	/**
388
	 * Set the query args specific to this instance.
389
	 *
390
	 * @return array
391
	 */
392
	protected function query_args() {
393
394
		if ( 'comments' === $this->sort ) {
0 ignored issues
show
Bug Best Practice introduced by
The property sort does not exist on MonsterInsights_Popular_Posts. Since you implemented __get, consider adding a @property annotation.
Loading history...
395
			return $this->get_query_args_comments();
396
		} elseif ( 'sharedcount' === $this->sort ) {
397
			return $this->get_query_args_sharedcount();
398
		} elseif ( 'curated' === $this->sort ) {
399
			return $this->get_query_args_curated();
400
		}
401
402
	}
403
404
405
	/**
406
	 * Get the query args for ordering by comments.
407
	 *
408
	 * @return array
409
	 */
410
	protected function get_query_args_comments() {
411
		return array(
412
			'orderby'    => 'comment_count',
413
			'order'      => 'DESC',
414
			'date_query' => array(
415
				array(
416
					'after'     => '-1 month',
417
					'inclusive' => true,
418
				),
419
			)
420
		);
421
	}
422
423
	/**
424
	 * Get the query args for ordering by sharedcount.
425
	 *
426
	 * @return array
427
	 */
428
	protected function get_query_args_sharedcount() {
429
430
		$query_args = array(
431
			'orderby'  => 'meta_value_num',
432
			'order'    => 'DESC',
433
			'meta_key' => '_monsterinsights_sharedcount_total',
434
		);
435
436
		return $query_args;
437
	}
438
439
440
	/**
441
	 * Build the query args for the curated option from the settings in the panel.
442
	 *
443
	 * @return array
444
	 */
445
	protected function get_query_args_curated() {
446
447
		$posts   = $this->curated;
0 ignored issues
show
Bug Best Practice introduced by
The property curated does not exist on MonsterInsights_Popular_Posts. Since you implemented __get, consider adding a @property annotation.
Loading history...
448
		$post_in = array();
449
450
		if ( ! empty( $posts ) && is_array( $posts ) ) {
0 ignored issues
show
introduced by
The condition is_array($posts) is always false.
Loading history...
451
			foreach ( $posts as $post ) {
452
				if ( ! empty( $post['id'] ) ) {
453
					$post_in[] = intval( $post['id'] );
454
				}
455
			}
456
		}
457
458
		$query_args = array(
459
			'post__in' => $post_in,
460
		);
461
462
		return $query_args;
463
	}
464
465
	/**
466
	 * Load theme props for the specific instance.
467
	 *
468
	 * @param string $theme Theme key.
469
	 *
470
	 * @return MonsterInsights_Popular_Posts_Themes
471
	 */
472
	public function get_theme_props( $theme = '' ) {
473
474
		if ( empty( $theme ) ) {
475
			$theme = $this->theme;
0 ignored issues
show
Bug Best Practice introduced by
The property theme does not exist on MonsterInsights_Popular_Posts. Since you implemented __get, consider adding a @property annotation.
Loading history...
476
		}
477
		$theme_props = new MonsterInsights_Popular_Posts_Themes( $this->type, $theme );
478
479
		return $theme_props;
480
	}
481
482
	/**
483
	 * Marks a post as already displayed, by id.
484
	 *
485
	 * @param $id
486
	 */
487
	public function set_post_shown( $id ) {
488
		if ( ! in_array( $id, $this->shown_posts, true ) ) {
489
			$this->shown_posts[] = $id;
490
		}
491
	}
492
493
	/**
494
	 * Returns an array of posts that were already displayed on the current page.
495
	 *
496
	 * @return array
497
	 */
498
	public function get_shown_posts() {
499
500
		return $this->shown_posts;
501
502
	}
503
504
	/**
505
	 * Generic helper function to build style attributes for elements based on shortcode/block parameters.
506
	 *
507
	 * @param string $theme  The theme for which  we're building the style.
508
	 * @param string $object Object we're styling like title, label, background, etc.
509
	 * @param array  $atts   Attributes passed from shortcode/block.
510
	 * @param string $key    The key of the style we're going to output.
511
	 *
512
	 * @return string
513
	 */
514
	public function get_element_style( $theme, $object, $atts, $key = '' ) {
515
516
		if ( 'no_styles' === $this->styling ) {
0 ignored issues
show
Bug Best Practice introduced by
The property styling does not exist on MonsterInsights_Popular_Posts. Since you implemented __get, consider adding a @property annotation.
Loading history...
517
			// If no styles is selected don't output any styles.
518
			return '';
519
		}
520
521
		if ( empty( $theme ) ) {
522
			$theme = $this->theme;
0 ignored issues
show
Bug Best Practice introduced by
The property theme does not exist on MonsterInsights_Popular_Posts. Since you implemented __get, consider adding a @property annotation.
Loading history...
523
		}
524
525
		// Find theme-specific available options and check if our attributes have those set.
526
		$theme_styles = $this->get_theme_props( $theme )->get_theme();
527
		$style_css    = '';
528
529
		if ( ! empty( $theme_styles['styles'] ) ) {
530
			foreach ( $theme_styles['styles'] as $element => $options ) {
531
				if ( $object !== $element ) {
532
					continue;
533
				}
534
				foreach ( $options as $style_key => $value ) {
535
					$atts_key = $element . '_' . $style_key;
536
537
					if ( ! empty( $key ) && $key !== $style_key ) {
538
						// Allow output for just a specific key.
539
						continue;
540
					}
541
542
					if ( ! empty( $atts[ $atts_key ] ) ) {
543
						if ( is_bool( $atts[ $atts_key ] ) || 'on' === $atts[ $atts_key ] ) {
544
							continue;
545
						}
546
						if ( 'size' === $style_key ) {
547
							$style_key         = 'font-size';
548
							$atts[ $atts_key ] .= 'px';
549
						}
550
						if ( 'background' === $style_key || 'background' === $element && 'color' === $style_key ) {
551
							$style_key = 'background-color';
552
						}
553
						if ( 'border' === $element || 'border' === $style_key ) {
554
							$style_key = 'border-color';
555
						}
556
						$style_css .= $style_key . ':' . $atts[ $atts_key ] . ';';
557
					}
558
				}
559
			}
560
		}
561
562
		return $style_css;
563
	}
564
565
	/**
566
	 * Get the current instance based on the called class.
567
	 *
568
	 * @return mixed
569
	 */
570
	public static function get_instance() {
571
572
		if ( ! function_exists( 'get_called_class' ) ) {
573
			return false;
574
		}
575
576
		$class = get_called_class();
577
578
		if ( ! isset( self::$instances[ $class ] ) ) {
579
			self::$instances[ $class ] = new $class;
580
		}
581
582
		return self::$instances[ $class ];
583
584
	}
585
586
	/**
587
	 * Check if the post is excluded from loading the widget.
588
	 *
589
	 * @param null|WP_Post $post The post to check if it's excluded.
590
	 *
591
	 * @return bool
592
	 */
593
	public function is_post_excluded( $post = null ) {
594
		if ( is_null( $post ) ) {
595
			$post = get_post( get_the_ID() );
0 ignored issues
show
Bug introduced by
It seems like get_the_ID() can also be of type false; however, parameter $post of get_post() does only seem to accept WP_Post|integer|null, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

595
			$post = get_post( /** @scrutinizer ignore-type */ get_the_ID() );
Loading history...
596
		}
597
		$excluded = false;
598
599
		$posts_to_exclude = $this->exclude_posts;
0 ignored issues
show
Bug Best Practice introduced by
The property exclude_posts does not exist on MonsterInsights_Popular_Posts. Since you implemented __get, consider adding a @property annotation.
Loading history...
600
		if ( ! empty( $posts_to_exclude ) ) {
601
			$post_ids = array();
602
			foreach ( $posts_to_exclude as $exclude_post ) {
0 ignored issues
show
Bug introduced by
The expression $posts_to_exclude of type string is not traversable.
Loading history...
603
				if ( ! empty( $exclude_post['id'] ) ) {
604
					$post_ids[] = intval( $exclude_post['id'] );
605
				}
606
			}
607
608
			if ( in_array( $post->ID, $post_ids, true ) ) {
609
				$excluded = true;
610
			}
611
		}
612
613
		return $excluded;
614
	}
615
616
	/**
617
	 * Build a wrapper class based on theme, instance and some settings.
618
	 *
619
	 * @param array $atts Attributes of the shortcode/instance to process for output.
620
	 *
621
	 * @return string
622
	 */
623
	public function get_wrapper_class( $atts ) {
624
		$theme = $this->theme;
0 ignored issues
show
Bug Best Practice introduced by
The property theme does not exist on MonsterInsights_Popular_Posts. Since you implemented __get, consider adding a @property annotation.
Loading history...
625
		if ( ! empty( $atts['theme'] ) ) {
626
			$theme = $atts['theme'];
627
		}
628
		$columns = ! empty( $atts['columns'] ) ? $atts['columns'] : $this->theme_columns;
0 ignored issues
show
Bug Best Practice introduced by
The property theme_columns does not exist on MonsterInsights_Popular_Posts. Since you implemented __get, consider adding a @property annotation.
Loading history...
629
		$classes = array(
630
			'monsterinsights-' . $this->type . '-popular-posts',
631
			'monsterinsights-' . $this->type . '-popular-posts-' . $theme,
632
			'no_styles' !== $this->styling ? 'monsterinsights-popular-posts-styled' : '',
0 ignored issues
show
Bug Best Practice introduced by
The property styling does not exist on MonsterInsights_Popular_Posts. Since you implemented __get, consider adding a @property annotation.
Loading history...
633
		);
634
635
		if ( $columns ) {
636
			$classes[] = 'monsterinsights-' . $this->type . '-popular-posts-columns-' . $columns;
637
		}
638
639
		if ( isset( $atts['className'] ) ) {
640
			$classes[] = $atts['className'];
641
		}
642
643
		$classname = implode( ' ', $classes );
644
645
		return $classname;
646
	}
647
648
	/**
649
	 * Check if the id is of the currently displayed post. Compatible with the Ajaxify functionality.
650
	 *
651
	 * @param $id
652
	 *
653
	 * @return bool
654
	 */
655
	public function is_current_post( $id ) {
656
657
		if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
658
			$current_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : false;
659
660
			return $id === $current_id;
661
		}
662
663
		// Only run this check for singular pages.
664
		if ( ! is_singular() ) {
665
			return false;
666
		}
667
668
		return get_the_ID() === absint( $id );
669
670
	}
671
672
	/**
673
	 * Helper function that checks if a post should be displayed on the current page.
674
	 *
675
	 * @param int $id
676
	 *
677
	 * @return bool
678
	 */
679
	public function should_display_post( $id ) {
680
		$shown = $this->get_shown_posts();
681
		if ( in_array( $id, $shown, true ) ) {
682
			return false;
683
		}
684
		if ( $this->is_current_post( $id ) ) {
685
			return false;
686
		}
687
688
		return true;
689
	}
690
691
	/**
692
	 * This function grabs the posts from the cache or a fresh query and runs them through a check if they should be
693
	 * displayed on the current page to avoid duplicates.
694
	 *
695
	 * @return array
696
	 */
697
	public function get_posts_to_display() {
698
		$posts = $this->get_posts();
699
700
		$returned_posts = array();
701
702
		foreach ( $posts as $post ) {
703
			if ( $this->should_display_post( $post['id'] ) ) {
704
				$returned_posts[] = $post;
705
			}
706
		}
707
708
		if ( apply_filters( 'monsterinsights_popular_posts_show_duplicates', true ) && count( $posts ) > 0 && count( $this->shown_posts ) > 0 && count( $returned_posts ) === 0 ) {
709
			$this->shown_posts = array(); // Reset shown posts.
710
711
			return $this->get_posts_to_display(); // Run the function to grab the same posts again.
712
		}
713
714
		return $returned_posts;
715
	}
716
717
	/**
718
	 * Check if the current instance has any posts available to display.
719
	 *
720
	 * @param array $posts Posts array to check if still available for display.
721
	 *
722
	 * @return bool
723
	 */
724
	public function has_posts_to_show( $posts ) {
725
726
		foreach ( $posts as $post ) {
727
			if ( $this->should_display_post( $post['id'] ) ) {
728
				return true;
729
			}
730
		}
731
732
		return false;
733
734
	}
735
736
	/**
737
	 * Only inline styles that were customized for the specific instance.
738
	 *
739
	 * @return array
740
	 */
741
	public function get_themes_styles_for_output() {
742
743
		$stored_styles = $this->get_theme_props()->get_theme_stored_styles();
744
		$themes        = ! empty( $stored_styles[ $this->type ] ) && is_array( $stored_styles[ $this->type ] ) ? $stored_styles[ $this->type ] : array();
745
746
		return $themes;
747
748
	}
749
}
750