PluginProbe
UiCore Elements – Free widgets and templates for Elementor / 1.3.17
UiCore Elements – Free widgets and templates for Elementor v1.3.17
1.3.17 1.3.16 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 All 41 releases
← All changes | includes/class-helper.php +228 -90 1.0.141.3.17 View file →
@@ -1,5 +1,6 @@
1 1 <?php
2 +
2 3 namespace UiCoreElements;
3 4
4 5 use Elementor\Plugin;
5 6
@@ -29,9 +30,9 @@
29 30 foreach ($attributes as $att) {
30 31 $taxonomies['pa_' . $att->attribute_name] = $att->attribute_label;
31 32 }
32 33
33 - // All taxonomies
34 + // All taxonomies
34 35 } else {
35 36
36 37 $taxonomies = get_taxonomies(['public' => true], 'objects');
37 38 $exclusions = ['nav_menu', 'link_category', 'post_format']; // Exclude these taxonomies from the list
@@ -40,9 +41,9 @@
40 41 return !in_array($taxonomy->name, $exclusions);
41 42 });
42 43
43 44 $taxonomies = array_map(function ($taxonomy) {
44 - if('portfolio_category' === $taxonomy->name){
45 + if ('portfolio_category' === $taxonomy->name) {
45 46 return 'Portfolio Category';
46 47 }
47 48 return $taxonomy->label;
48 49 }, $taxonomies);
@@ -57,15 +58,15 @@
57 58
58 59 static function get_taxonomy($name)
59 60 {
60 61 global $post;
62 + $categories = get_the_terms($post->ID, $name);
61 63
62 - $categories = get_the_terms( $post->ID, $name );
63 - if ( ! $categories || is_wp_error( $categories ) ) {
64 + if (! $categories || is_wp_error($categories)) {
64 65 return false;
65 66 }
66 67
67 - $categories = array_values( $categories );
68 + $categories = array_values($categories);
68 69 foreach ($categories as $t) {
69 70 $term_name[] =
70 71 '<a href="' . get_term_link($t) . '" title="View ' . \esc_attr($t->name) . ' posts">' . esc_html($t->name) . '</a>';
71 72 }
@@ -73,111 +74,139 @@
73 74
74 75 return $category;
75 76 }
76 77
78 + static function get_custom_meta($name, $product_id = null)
79 + {
80 + if (isset($product_id)) {
81 + $product = wc_get_product($product_id);
82 + $meta = $product->get_meta($name);
83 + } else {
84 + global $post;
85 + $meta = get_post_meta($post->ID, $name, true);
86 + }
87 +
88 + // If is an array means meta is not valid since we are expecting a single value string
89 + if (! $meta || is_array($meta)) {
90 + return false;
91 + }
92 +
93 + return $meta;
94 + }
95 +
77 96 static function get_reading_time()
78 97 {
79 98 global $post;
80 - // get the content
99 +
81 100 $the_content = $post->post_content;
82 - // count the number of words
83 - $words = str_word_count( wp_strip_all_tags( $the_content ) );
84 - // rounding off and deviding per 200 words per minute
85 - $minute = floor( $words / 200 );
101 + $words = str_word_count(wp_strip_all_tags($the_content)); // count the number of words
102 + $minute = floor($words / 200); // rounding off and deviding per 200 words per minute
86 103
87 - // calculate the amount of time needed to read
88 104 return $minute;
89 105 }
90 106
91 - static function get_site_domain() {
92 - return str_ireplace( 'www.', '', parse_url( home_url(), PHP_URL_HOST ) );
93 - }
107 + static function get_site_domain()
108 + {
109 + return str_ireplace('www.', '', parse_url(home_url(), PHP_URL_HOST));
110 + }
94 111
95 112 /**
96 113 * Returns the Uicore Elements settings page URL. You may pass a message so it'll be wrapped under a <a> tag.
97 114 *
98 115 * @param string $message Optional. A clickable message to be displayed that'll redirect, in a new tab, to settings page.
116 + *
99 117 * @return string Uicore Elements settings page URL or an <a> tag HTML with the url and the passed message.
100 118 */
101 - static function get_admin_settings_url(string $message = '') {
102 - $url = admin_url( 'options-general.php?page=uicore-elements' );
103 - return !empty($message) ? '<a href="'.esc_url($url).'" target="_blank">' . esc_html($message) . '</a>' : $url;
119 + static function get_admin_settings_url(string $message = '')
120 + {
121 + $url = admin_url('options-general.php?page=uicore-elements');
122 + return !empty($message)
123 + ? '<a href="' . esc_url($url) . '" target="_blank">' . esc_html($message) . '</a>'
124 + : $url;
104 125 }
105 126
106 - static function register_widget_style($name,$deps=[],$external=false)
127 + static function register_widget_style($name, $deps = [], $external = false)
107 128 {
108 - $handle = (!$external ? 'ui-e-' : '' ). $name;
109 - wp_register_style($handle, UICORE_ELEMENTS_ASSETS . '/css/elements/'.$name.'.css',$deps,UICORE_ELEMENTS_VERSION);
129 + $handle = (!$external ? 'ui-e-' : '') . $name;
130 + wp_register_style($handle, UICORE_ELEMENTS_ASSETS . '/css/elements/' . $name . '.css', $deps, UICORE_ELEMENTS_VERSION);
110 131 return $handle;
111 132 }
112 - static function register_widget_script($name,$deps=[],$external=false)
133 + static function register_widget_script($name, $deps = [], $external = false)
113 134 {
114 - $handle = (!$external ? 'ui-e-' : '' ). $name;
135 + $handle = (!$external ? 'ui-e-' : '') . $name;
115 136 //if name contains / then we need to set a custom path
116 - if(strpos($name,'/') !== false){
117 - $path ='';
118 - }else{
137 + if (strpos($name, '/') !== false) {
138 + $path = '';
139 + } else {
119 140 $path = 'elements/';
120 141 }
121 - wp_register_script($handle, UICORE_ELEMENTS_ASSETS . '/js/'.$path.$name.'.js',$deps,UICORE_ELEMENTS_VERSION,true);
142 + wp_register_script($handle, UICORE_ELEMENTS_ASSETS . '/js/' . $path . $name . '.js', $deps, UICORE_ELEMENTS_VERSION, true);
122 143 return $handle;
123 144 }
124 145
125 - public static function get_related($filter, $number)
146 + /**
147 + * Build the related posts query in REST API context.
148 + *
149 + * @param int $page_number The current page number for pagination.
150 + * @param int $per_page The number of posts to retrieve per page.
151 + * @param string/int $pageID The current post/page ID.
152 + *
153 + * @return \WP_Query Returns a WP_Query object.
154 + */
155 + public static function get_related_ajax(int $page_number, int $per_page, $pageID)
126 156 {
127 - global $post;
157 + $args = [
158 + 'post__not_in' => [$pageID],
159 + 'posts_per_page' => $per_page,
160 + 'paged' => $page_number,
161 + ];
128 162
129 - $args = [];
163 + $categories = get_the_category($pageID);
164 + $tags = wp_get_post_tags($pageID);
130 165
131 - if ($filter == 'category') {
132 - $categories = get_the_category($post->ID);
166 + $tax_query = [];
133 167
134 - if ($categories) {
135 - $category_ids = array_map(fn($cat) => $cat->term_id, $categories);
168 + if ($categories) {
169 + $category_ids = array_map(fn($cat) => $cat->term_id, $categories);
170 + $tax_query[] = [
171 + 'taxonomy' => 'category',
172 + 'field' => 'term_id',
173 + 'terms' => $category_ids,
174 + 'operator' => 'IN',
175 + ];
176 + }
136 177
137 - // basic args
138 - $args = [
139 - 'post__not_in' => [$post->ID],
140 - 'posts_per_page' => $number,
141 - 'category__in' => $category_ids,
142 - 'ignore_sticky_posts' => 1,
143 - ];
144 - }
178 + if ($tags) {
179 + $tag_ids = array_map(fn($tag) => $tag->term_id, $tags);
180 + $tax_query[] = [
181 + 'taxonomy' => 'post_tag',
182 + 'field' => 'term_id',
183 + 'terms' => $tag_ids,
184 + 'operator' => 'IN',
185 + ];
186 + }
145 187
146 - } elseif ($filter == 'tag') {
147 - $tags = wp_get_post_tags($post->ID);
148 -
149 - if ($tags) {
150 - $tag_ids = array_map(fn($tag) => $tag->term_id, $tags);
151 -
152 - $args = [
153 - 'post__not_in' => [$post->ID],
154 - 'posts_per_page' => $number,
155 - 'tag__in' => $tag_ids,
156 - 'ignore_sticky_posts' => 1,
157 - ];
158 - }
159 -
160 - // default/random filter
161 - } else {
162 - $args = [
163 - 'post__not_in' => [$post->ID],
164 - 'posts_per_page' => $number,
165 - 'orderby' => 'rand',
188 + if (!empty($tax_query)) {
189 + $args['tax_query'] = [
190 + 'relation' => 'OR',
191 + ...$tax_query,
166 192 ];
167 193 }
168 194
169 - $related_query = new \WP_Query($args);
170 - return $related_query->have_posts() ? $related_query : false;
195 + return new \WP_Query($args);
171 196 }
172 197
173 - public static function get_product_related($limit)
198 + /**
199 + * Returns an array of related products IDs.
200 + */
201 + public static function get_product_related($limit, $ID)
174 202 {
175 - global $post;
203 + if (empty($ID)) {
204 + global $post;
205 + $ID = $post->ID;
206 + }
176 207
177 - // TODO: problems related to the lack of ID on posts object should be treated here.
178 -
179 - return wc_get_related_products($post->ID, $limit);
208 + return wc_get_related_products($ID, $limit);
180 209 }
181 210
182 211 /*
183 212 * Get the current post id (used in Theme Builder - UiCore Framework)
@@ -183,13 +212,13 @@
183 212 * Get the current post id (used in Theme Builder - UiCore Framework)
184 213 */
185 214 static function get_current_meta_id()
186 215 {
187 - if(\class_exists('\UiCore\Blog\Frontend') && \UiCore\Blog\Frontend::is_blog() && !is_singular('post')){
216 + if (\class_exists('\UiCore\Blog\Frontend') && \UiCore\Blog\Frontend::is_blog() && !is_singular('post')) {
188 217 $post_id = get_option('page_for_posts', true);
189 - }elseif(\class_exists('\UiCore\Portfolio\Frontend') && \UiCore\Portfolio\Frontend::is_portfolio() && !is_singular('portfolio')){
218 + } elseif (\class_exists('\UiCore\Portfolio\Frontend') && \UiCore\Portfolio\Frontend::is_portfolio() && !is_singular('portfolio')) {
190 219 $post_id = \UiCore\Portfolio\Frontend::get_portfolio_page_id();
191 - }else{
220 + } else {
192 221 $post_id = get_queried_object_id();
193 222 }
194 223
195 224 return $post_id;
@@ -197,11 +226,11 @@
197 226
198 227 /**
199 228 * Return a list of textual html tags for Elementor Controls Options
200 229 */
230 + public static function get_title_tags()
231 + {
201 232
202 - public static function get_title_tags($type = null) {
203 -
204 233 $tags = [
205 234 'h1' => 'H1',
206 235 'h2' => 'H2',
207 236 'h3' => 'H3',
@@ -225,13 +254,14 @@
225 254 * @param string $custom The custom format to use if $format is set to 'custom'.
226 255 *
227 256 * @return string The formatted date value.
228 257 */
229 - public static function format_date($date, $format, $custom) {
258 + public static function format_date($date, $format, $custom)
259 + {
230 260
231 - if ( 'custom' === $format ) {
261 + if ('custom' === $format) {
232 262 $date_format = $custom;
233 - } else if ('default' === $format ) {
263 + } else if ('default' === $format) {
234 264 $date_format = get_option('date_format');
235 265 } else {
236 266 $date_format = $format;
237 267 }
@@ -241,17 +271,48 @@
241 271 return wp_kses_post($value);
242 272 }
243 273
244 274 /**
245 - * Sanitizes SVG content, also allowing `post` tags and atts.
275 + * Sanitizes HTML tags. Since is a custom sanitizer, require us, by wp plugin repo security standards,
276 + * to add `//phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped` comment.
246 277 *
278 + * @param mixed $raw_tag The HTML tag to sanitize.
279 + * @param string $default Default HTML value to fallback to in case an invalid tag is passed. Default is 'h3'.
280 + * @param bool $spacing Whether to add a trailing space after the tag. Default is false.
281 + * @return string The sanitized HTML tag.
282 + *
283 + * @since 1.3.5
284 + */
285 + public static function esc_tag($raw_tag, $default = 'h3', $spacing = false)
286 + {
287 +
288 + $allowed_tags_names = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'span', 'p', 'a'];
289 + $tag = sanitize_key(strtolower($raw_tag)); // normalizes to [a-z0-9_]
290 +
291 + // fallback if tag not whitelisted
292 + if (! in_array($tag, $allowed_tags_names, true)) {
293 + $tag = $default;
294 + }
295 +
296 + if ($spacing) {
297 + return $tag . ' ';
298 + }
299 +
300 + return $tag;
301 + }
302 +
303 + /**
304 + * Sanitizes SVG content, also allowing `post` tags and atts. Since is a custom sanitizer, require us,
305 + * by wp plugin repo security standards, to add `//phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped` comment.
306 + *
247 307 * @param string $svg The raw SVG content to be sanitized.
248 308 * @return string The sanitized SVG content, with only allowed tags and attributes.
249 309 *
250 310 * @since 1.0.2
251 311 */
252 - public static function esc_svg($svg) {
253 - $default = wp_kses_allowed_html( 'post' );
312 + public static function esc_svg($svg)
313 + {
314 + $default = wp_kses_allowed_html('post');
254 315
255 316 $args = array(
256 317 'svg' => array(
257 318 'class' => true,
@@ -264,22 +325,23 @@
264 325 // has to be lowercase
265 326 'viewbox' => true,
266 327 'preserveaspectratio' => true
267 328 ),
268 - 'g' => array( 'fill' => true ),
269 - 'title' => array( 'title' => true ),
329 + 'g' => array('fill' => true),
330 + 'title' => array('title' => true),
270 331 'path' => array(
271 332 'd' => true,
272 333 'fill' => true
273 334 )
274 335 );
275 - $allowed_tags = array_merge( $default, $args );
336 + $allowed_tags = array_merge($default, $args);
276 337
277 - return wp_kses( $svg, $allowed_tags );
338 + return wp_kses($svg, $allowed_tags);
278 339 }
279 340
280 341 /**
281 - * Sanitizes text strings, but allowing some html tags usefull for styling and manipulating texts.
342 + * Sanitizes text strings, but allowing some html tags usefull for styling and manipulating texts. Since is a custom sanitizer,
343 + * require us, by wp plugin repo security standards, to add `//phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped` comment.
282 344 *
283 345 * @param string $content The content to be sanitized
284 346 * @return string The sanitized string content.
285 347 *
@@ -284,9 +346,10 @@
284 346 * @return string The sanitized string content.
285 347 *
286 348 * @since 1.0.3
287 349 */
288 - public static function esc_string($content) {
350 + public static function esc_string($content)
351 + {
289 352
290 353 $allowed_tags = [
291 354 'strong' => array(),
292 355 'em' => array(),
@@ -296,12 +359,18 @@
296 359 's' => array(),
297 360 'sub' => array(),
298 361 'sup' => array(),
299 362 'span' => array(),
300 - 'br' => array()
363 + 'br' => array(),
364 + 'a' => [
365 + 'href' => true,
366 + 'title' => true,
367 + 'target' => true,
368 + 'rel' => true
369 + ]
301 370 ];
302 371
303 - return wp_kses( $content, $allowed_tags );
372 + return wp_kses($content, $allowed_tags);
304 373 }
305 374
306 375 /**
307 376 * Retrieves the available image sizes.
@@ -309,9 +378,10 @@
309 378 * @return array An array of image sizes.
310 379 *
311 380 * @since 1.0.0
312 381 */
313 - public static function get_images_sizes() {
382 + public static function get_images_sizes()
383 + {
314 384 $sizes = [];
315 385 foreach (get_intermediate_image_sizes() as $size) {
316 386 $sizes[$size] = $size;
317 387 }
@@ -320,9 +390,10 @@
320 390
321 391 /**
322 392 * @since 1.0.5
323 393 */
324 - private static function get_element_recursive($elements, $form_id) {
394 + private static function get_element_recursive($elements, $form_id)
395 + {
325 396
326 397 foreach ($elements as $element) {
327 398 if ($form_id === $element['id']) {
328 399 return $element;
@@ -349,9 +420,10 @@
349 420 *
350 421 * @since 1.0.5
351 422 * @deprecated Deprecated since version 1.0.11 Use the transient method instead.
352 423 */
353 - public static function get_widget_settings($post_id, $widget_id) {
424 + public static function get_widget_settings($post_id, $widget_id)
425 + {
354 426
355 427 if (!$post_id || !$widget_id) {
356 428 return false;
357 429 }
@@ -377,5 +449,71 @@
377 449
378 450 return $settings;
379 451 }
380 452
453 + /**
454 + * Get the `posts per page` value from Framework or WordPress settings last case scenario.
455 + * Usefull if we're using `current` post type and don't have posts per page option.
456 + *
457 + * @param string $post_type The post type slug.
458 + *
459 + * @since 1.2.1
460 + * @return int The number of posts per page.
461 + */
462 + public static function get_framework_visible_posts(string $post_type)
463 + {
464 + // Get from Uicore Framework, if available
465 + if (defined('UICORE_ASSETS')) {
466 +
467 + switch ($post_type) {
468 + case 'product':
469 + return \Uicore\Helper::get_option('woocommerce_posts_number');
470 +
471 + case 'post':
472 + return \Uicore\Helper::get_option('blog_posts_number');
473 +
474 + case 'portfolio':
475 + return \Uicore\Helper::get_option('portfolio_posts_number');
476 +
477 + default:
478 + return get_option('posts_per_page');
479 + }
480 + }
481 +
482 + return get_option('posts_per_page');
483 + }
484 + /**
485 + * Retrieves the list of Uicore Framework registered popups.
486 + *
487 + * @return array
488 + *
489 + * @since 1.3.3
490 + */
491 + public static function get_uicore_popups(): array
492 + {
493 + // get elementor popups posts
494 + $args = [
495 + 'post_type' => 'uicore-tb',
496 + 'post_status' => 'publish',
497 + 'posts_per_page' => 50,
498 + 'tax_query' => [
499 + [
500 + 'taxonomy' => 'tb_type',
501 + 'field' => 'slug',
502 + 'terms' => '_type_popup',
503 + ]
504 + ]
505 + ];
506 +
507 + $query = new \WP_Query($args);
508 + $popups = [];
509 + if ($query->have_posts()) {
510 + while ($query->have_posts()) {
511 + $query->the_post();
512 + $popups[esc_html(get_the_ID())] = esc_html(html_entity_decode(get_the_title()));
513 + }
514 + wp_reset_postdata();
515 + }
516 +
517 + return $popups;
518 + }
381 519 }