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 -88 1.0.151.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,109 +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 - return wc_get_related_products($post->ID, $limit);
208 + return wc_get_related_products($ID, $limit);
178 209 }
179 210
180 211 /*
181 212 * Get the current post id (used in Theme Builder - UiCore Framework)
@@ -181,13 +212,13 @@
181 212 * Get the current post id (used in Theme Builder - UiCore Framework)
182 213 */
183 214 static function get_current_meta_id()
184 215 {
185 - 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')) {
186 217 $post_id = get_option('page_for_posts', true);
187 - }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')) {
188 219 $post_id = \UiCore\Portfolio\Frontend::get_portfolio_page_id();
189 - }else{
220 + } else {
190 221 $post_id = get_queried_object_id();
191 222 }
192 223
193 224 return $post_id;
@@ -195,11 +226,11 @@
195 226
196 227 /**
197 228 * Return a list of textual html tags for Elementor Controls Options
198 229 */
230 + public static function get_title_tags()
231 + {
199 232
200 - public static function get_title_tags($type = null) {
201 -
202 233 $tags = [
203 234 'h1' => 'H1',
204 235 'h2' => 'H2',
205 236 'h3' => 'H3',
@@ -223,13 +254,14 @@
223 254 * @param string $custom The custom format to use if $format is set to 'custom'.
224 255 *
225 256 * @return string The formatted date value.
226 257 */
227 - public static function format_date($date, $format, $custom) {
258 + public static function format_date($date, $format, $custom)
259 + {
228 260
229 - if ( 'custom' === $format ) {
261 + if ('custom' === $format) {
230 262 $date_format = $custom;
231 - } else if ('default' === $format ) {
263 + } else if ('default' === $format) {
232 264 $date_format = get_option('date_format');
233 265 } else {
234 266 $date_format = $format;
235 267 }
@@ -239,17 +271,48 @@
239 271 return wp_kses_post($value);
240 272 }
241 273
242 274 /**
243 - * 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.
244 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 + *
245 307 * @param string $svg The raw SVG content to be sanitized.
246 308 * @return string The sanitized SVG content, with only allowed tags and attributes.
247 309 *
248 310 * @since 1.0.2
249 311 */
250 - public static function esc_svg($svg) {
251 - $default = wp_kses_allowed_html( 'post' );
312 + public static function esc_svg($svg)
313 + {
314 + $default = wp_kses_allowed_html('post');
252 315
253 316 $args = array(
254 317 'svg' => array(
255 318 'class' => true,
@@ -262,22 +325,23 @@
262 325 // has to be lowercase
263 326 'viewbox' => true,
264 327 'preserveaspectratio' => true
265 328 ),
266 - 'g' => array( 'fill' => true ),
267 - 'title' => array( 'title' => true ),
329 + 'g' => array('fill' => true),
330 + 'title' => array('title' => true),
268 331 'path' => array(
269 332 'd' => true,
270 333 'fill' => true
271 334 )
272 335 );
273 - $allowed_tags = array_merge( $default, $args );
336 + $allowed_tags = array_merge($default, $args);
274 337
275 - return wp_kses( $svg, $allowed_tags );
338 + return wp_kses($svg, $allowed_tags);
276 339 }
277 340
278 341 /**
279 - * 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.
280 344 *
281 345 * @param string $content The content to be sanitized
282 346 * @return string The sanitized string content.
283 347 *
@@ -282,9 +346,10 @@
282 346 * @return string The sanitized string content.
283 347 *
284 348 * @since 1.0.3
285 349 */
286 - public static function esc_string($content) {
350 + public static function esc_string($content)
351 + {
287 352
288 353 $allowed_tags = [
289 354 'strong' => array(),
290 355 'em' => array(),
@@ -294,12 +359,18 @@
294 359 's' => array(),
295 360 'sub' => array(),
296 361 'sup' => array(),
297 362 'span' => array(),
298 - 'br' => array()
363 + 'br' => array(),
364 + 'a' => [
365 + 'href' => true,
366 + 'title' => true,
367 + 'target' => true,
368 + 'rel' => true
369 + ]
299 370 ];
300 371
301 - return wp_kses( $content, $allowed_tags );
372 + return wp_kses($content, $allowed_tags);
302 373 }
303 374
304 375 /**
305 376 * Retrieves the available image sizes.
@@ -307,9 +378,10 @@
307 378 * @return array An array of image sizes.
308 379 *
309 380 * @since 1.0.0
310 381 */
311 - public static function get_images_sizes() {
382 + public static function get_images_sizes()
383 + {
312 384 $sizes = [];
313 385 foreach (get_intermediate_image_sizes() as $size) {
314 386 $sizes[$size] = $size;
315 387 }
@@ -318,9 +390,10 @@
318 390
319 391 /**
320 392 * @since 1.0.5
321 393 */
322 - private static function get_element_recursive($elements, $form_id) {
394 + private static function get_element_recursive($elements, $form_id)
395 + {
323 396
324 397 foreach ($elements as $element) {
325 398 if ($form_id === $element['id']) {
326 399 return $element;
@@ -347,9 +420,10 @@
347 420 *
348 421 * @since 1.0.5
349 422 * @deprecated Deprecated since version 1.0.11 Use the transient method instead.
350 423 */
351 - public static function get_widget_settings($post_id, $widget_id) {
424 + public static function get_widget_settings($post_id, $widget_id)
425 + {
352 426
353 427 if (!$post_id || !$widget_id) {
354 428 return false;
355 429 }
@@ -375,5 +449,71 @@
375 449
376 450 return $settings;
377 451 }
378 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 + }
379 519 }