PluginProbe
WebberZone Top 10 — Popular Posts / 4.5.1
WebberZone Top 10 — Popular Posts v4.5.1
4.5.1 4.5.0 4.4.3 4.4.2 4.4.1 4.4.0 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 trunk 1.0 1.0.1 1.1 1.2 1.3 1.4 1.4.1 1.5 1.5.1 1.5.2 1.5.3 1.6 1.6.1 All 117 releases
← All changes | includes/frontend/class-styles-handler.php +238 -28 4.3.44.5.1 View file →
@@ -6,8 +6,9 @@
6 6 */
7 7
8 8 namespace WebberZone\Top_Ten\Frontend;
9 9
10 +use WebberZone\Top_Ten\Admin\Settings;
10 11 use WebberZone\Top_Ten\Util\Hook_Registry;
11 12
12 13 if ( ! defined( 'WPINC' ) ) {
13 14 die;
@@ -27,8 +28,9 @@
27 28 */
28 29 public function __construct() {
29 30 Hook_Registry::add_action( 'wp_head', array( $this, 'header' ) );
30 31 Hook_Registry::add_action( 'wp_enqueue_scripts', array( $this, 'register_styles' ) );
32 + Hook_Registry::add_action( 'elementor/preview/enqueue_styles', array( $this, 'enqueue_all_styles' ) );
31 33 }
32 34
33 35 /**
34 36 * Function to add CSS to header.
@@ -45,34 +47,252 @@
45 47 }
46 48 }
47 49
48 50 /**
49 - * Enqueue styles.
51 + * Enqueue every registered style. Elementor's preview iframe can switch widget styles without
52 + * a full reload, so all style choices need to be available there.
53 + *
54 + * @since 4.5.0
50 55 */
56 + public static function enqueue_all_styles() {
57 + foreach ( wp_list_pluck( Settings::get_styles(), 'id' ) as $style_id ) {
58 + self::enqueue_style( $style_id );
59 + }
60 + }
61 +
62 + /**
63 + * Register and enqueue one style by ID.
64 + *
65 + * @since 4.5.0
66 + *
67 + * @param string $style_id Style ID.
68 + */
69 + public static function enqueue_style( $style_id ) {
70 + $style_array = self::get_style( $style_id );
71 +
72 + if ( empty( $style_array['name'] ) ) {
73 + return;
74 + }
75 +
76 + $style = $style_array['name'];
77 + $extra_css = $style_array['extra_css'];
78 + $is_rtl = is_rtl();
79 + $handle = "tptn-style-{$style}";
80 +
81 + wp_register_style(
82 + $handle,
83 + plugins_url( self::get_stylesheet_path( $style, $is_rtl ), TOP_TEN_PLUGIN_FILE ),
84 + array(),
85 + TOP_TEN_VERSION
86 + );
87 + wp_enqueue_style( $handle );
88 +
89 + if ( ! empty( $extra_css ) ) {
90 + wp_add_inline_style( $handle, $extra_css );
91 + }
92 + }
93 +
94 + /**
95 + * Enqueue and print one style immediately when rendering happens after wp_head.
96 + *
97 + * @since 4.5.0
98 + *
99 + * @param string $style_id Style ID.
100 + */
101 + public static function enqueue_style_now( $style_id ) {
102 + self::enqueue_style( $style_id );
103 +
104 + if ( ! did_action( 'wp_head' ) ) {
105 + return;
106 + }
107 +
108 + $style_array = self::get_style( $style_id );
109 +
110 + if ( empty( $style_array['name'] ) ) {
111 + return;
112 + }
113 +
114 + wp_print_styles( array( "tptn-style-{$style_array['name']}" ) );
115 + }
116 +
117 + /**
118 + * Resolve a style ID using the same thumbnail-placement precedence everywhere.
119 + *
120 + * @since 4.5.0
121 + *
122 + * @param string|null $post_thumb_op Thumbnail placement override.
123 + * @param string|null $style_id Style override.
124 + * @return string Resolved style ID.
125 + */
126 + public static function resolve_style_id( $post_thumb_op = null, $style_id = null ) {
127 + if ( null === $post_thumb_op || '' === (string) $post_thumb_op ) {
128 + $post_thumb_op = tptn_get_option( 'post_thumb_op', 'text_only' );
129 + }
130 +
131 + if ( 'text_only' === $post_thumb_op ) {
132 + return 'text_only';
133 + }
134 +
135 + if ( null === $style_id || '' === (string) $style_id ) {
136 + $style_id = tptn_get_option( 'tptn_styles', 'no_style' );
137 + }
138 +
139 + return (string) $style_id;
140 + }
141 +
142 + /**
143 + * Enqueue styles for the site-wide setting and any builder/shortcode instance on the queried
144 + * post.
145 + *
146 + * @since 4.5.0
147 + */
51 148 public static function register_styles() {
149 + foreach ( self::get_style_ids_to_load() as $style_id ) {
150 + self::enqueue_style( $style_id );
151 + }
152 + }
52 153
53 - $style_array = self::get_style();
154 + /**
155 + * Get the style IDs required for the current request.
156 + *
157 + * Builder editors load every registered style because an element can change its style live.
158 + * Normal requests scan shortcode, Elementor, and Bricks data on the queried post; elements in
159 + * theme templates are covered by Builder_Atts::ensure_style_enqueued() at render time.
160 + *
161 + * @since 4.5.0
162 + *
163 + * @return string[] Style IDs.
164 + */
165 + protected static function get_style_ids_to_load() {
166 + if ( function_exists( 'vc_is_inline' ) && vc_is_inline() ) {
167 + return wp_list_pluck( Settings::get_styles(), 'id' );
168 + }
54 169
55 - if ( ! empty( $style_array['name'] ) ) {
56 - $style = $style_array['name'];
57 - $extra_css = $style_array['extra_css'];
58 - $is_rtl = is_rtl();
170 + if ( function_exists( 'bricks_is_builder' ) && bricks_is_builder() ) {
171 + return wp_list_pluck( Settings::get_styles(), 'id' );
172 + }
59 173
60 - wp_register_style(
61 - "tptn-style-{$style}",
62 - plugins_url( self::get_stylesheet_path( $style, $is_rtl ), TOP_TEN_PLUGIN_FILE ),
63 - array(),
64 - TOP_TEN_VERSION
65 - );
66 - wp_enqueue_style( "tptn-style-{$style}" );
174 + $style_ids = array( (string) tptn_get_option( 'tptn_styles', 'no_style' ) );
175 + $post = get_post();
67 176
68 - if ( ! empty( $extra_css ) ) {
69 - wp_add_inline_style( "tptn-style-{$style}", $extra_css );
177 + if ( ! $post ) {
178 + return array_unique( $style_ids );
179 + }
180 +
181 + if ( preg_match_all( '/\[(?:tptn_list|tptn_popular_posts)\b[^\]]*\]/', $post->post_content, $shortcodes ) ) {
182 + foreach ( $shortcodes[0] as $shortcode ) {
183 + if ( preg_match( '/\bpost_thumb_op=["\']text_only["\']/', $shortcode ) ) {
184 + $style_ids[] = 'text_only';
185 + } elseif ( preg_match( '/\btptn_styles=["\']([a-z_]+)["\']/', $shortcode, $match ) ) {
186 + $style_ids[] = $match[1];
187 + }
70 188 }
71 189 }
190 +
191 + array_push( $style_ids, ...self::get_elementor_style_ids( $post->ID ) );
192 + array_push( $style_ids, ...self::get_bricks_style_ids( $post->ID ) );
193 +
194 + return array_unique( $style_ids );
72 195 }
73 196
74 197 /**
198 + * Extract styles from Top 10 Elementor widgets saved in `_elementor_data`.
199 + *
200 + * @since 4.5.0
201 + *
202 + * @param int $post_id Post ID.
203 + * @return string[] Style IDs.
204 + */
205 + protected static function get_elementor_style_ids( $post_id ) {
206 + $data = get_post_meta( $post_id, '_elementor_data', true );
207 +
208 + if ( empty( $data ) ) {
209 + return array();
210 + }
211 +
212 + $elements = is_array( $data ) ? $data : json_decode( (string) $data, true );
213 +
214 + if ( ! is_array( $elements ) ) {
215 + return array();
216 + }
217 +
218 + $style_ids = array();
219 + self::walk_elementor_elements( $elements, $style_ids );
220 +
221 + return array_map( 'strval', $style_ids );
222 + }
223 +
224 + /**
225 + * Recursively collect style IDs from Top 10 Elementor widgets.
226 + *
227 + * @since 4.5.0
228 + *
229 + * @param array $elements Element tree.
230 + * @param array $style_ids Collected style IDs, by reference.
231 + */
232 + protected static function walk_elementor_elements( array $elements, array &$style_ids ) {
233 + foreach ( $elements as $element ) {
234 + if ( ! is_array( $element ) ) {
235 + continue;
236 + }
237 +
238 + if ( isset( $element['widgetType'] ) && 'tptn_popular_posts' === $element['widgetType'] ) {
239 + $settings = isset( $element['settings'] ) && is_array( $element['settings'] ) ? $element['settings'] : array();
240 + $style_ids[] = self::resolve_style_id(
241 + $settings['post_thumb_op'] ?? null,
242 + $settings['tptn_styles'] ?? null
243 + );
244 + }
245 +
246 + if ( ! empty( $element['elements'] ) && is_array( $element['elements'] ) ) {
247 + self::walk_elementor_elements( $element['elements'], $style_ids );
248 + }
249 + }
250 + }
251 +
252 + /**
253 + * Extract styles from Top 10 Bricks elements saved on a post.
254 + *
255 + * @since 4.5.0
256 + *
257 + * @param int $post_id Post ID.
258 + * @return string[] Style IDs.
259 + */
260 + protected static function get_bricks_style_ids( $post_id ) {
261 + $meta_keys = array();
262 +
263 + foreach ( array( 'BRICKS_DB_PAGE_CONTENT', 'BRICKS_DB_PAGE_HEADER', 'BRICKS_DB_PAGE_FOOTER' ) as $constant ) {
264 + if ( defined( $constant ) ) {
265 + $meta_keys[] = constant( $constant );
266 + }
267 + }
268 +
269 + $style_ids = array();
270 +
271 + foreach ( $meta_keys as $meta_key ) {
272 + $elements = get_post_meta( $post_id, $meta_key, true );
273 +
274 + if ( ! is_array( $elements ) ) {
275 + continue;
276 + }
277 +
278 + foreach ( $elements as $element ) {
279 + if ( ! is_array( $element ) || 'tptn-popular-posts' !== ( $element['name'] ?? '' ) ) {
280 + continue;
281 + }
282 +
283 + $settings = isset( $element['settings'] ) && is_array( $element['settings'] ) ? $element['settings'] : array();
284 + $style_ids[] = self::resolve_style_id(
285 + $settings['post_thumb_op'] ?? null,
286 + $settings['tptn_styles'] ?? null
287 + );
288 + }
289 + }
290 +
291 + return $style_ids;
292 + }
293 +
294 + /**
75 295 * Get stylesheet path accounting for minified and pro files.
76 296 *
77 297 * @since 4.2.0
78 298 *
@@ -107,21 +327,11 @@
107 327 */
108 328 public static function get_style( $style = '' ) {
109 329
110 330 $style_array = array();
111 - $thumb_width = tptn_get_option( 'thumb_width' );
112 - $thumb_height = tptn_get_option( 'thumb_height' );
113 - $width_value = absint( $thumb_width );
114 - $height_value = absint( $thumb_height );
115 -
116 - if ( ! $width_value ) {
117 - $width_value = 1;
118 - }
119 -
120 - if ( ! $height_value ) {
121 - $height_value = 1;
122 - }
123 - $aspect_ratio = sprintf( '%d / %d', $width_value, $height_value );
331 + $thumb_width = max( 1, (int) tptn_get_option( 'thumb_width', 150 ) );
332 + $thumb_height = max( 1, (int) tptn_get_option( 'thumb_height', 150 ) );
333 + $aspect_ratio = $thumb_width / $thumb_height;
124 334 $tptn_style = ! empty( $style ) ? $style : tptn_get_option( 'tptn_styles' );
125 335
126 336 switch ( $tptn_style ) {
127 337 case 'left_thumbs':