PluginProbe
UiCore Elements – Free widgets and templates for Elementor / 1.3.18
UiCore Elements – Free widgets and templates for Elementor v1.3.18
1.3.18 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 All 42 releases
← All changes | includes/class-helper.php +519 -362 1.0.10 → 1.3.18 View file →
@@ -1,362 +1,519 @@
1 -<?php
2 -namespace UiCoreElements;
3 -
4 -use Elementor\Plugin;
5 -
6 -defined('ABSPATH') || exit();
7 -/**
8 - * UiCore Utils Functions
9 - */
10 -class Helper
11 -{
12 -
13 - public static function get_separator()
14 - {
15 - return '<span class="uicore-meta-separator"></span>';
16 - }
17 -
18 - public static function get_taxonomies($custom = true)
19 - {
20 - $taxonomies = get_taxonomies(['public' => true], 'objects');
21 - $exclusions = ['nav_menu', 'link_category', 'post_format']; // Exclude these taxonomies from the list
22 -
23 - $taxonomies = array_filter($taxonomies, function ($taxonomy) use ($exclusions) {
24 - return !in_array($taxonomy->name, $exclusions);
25 - });
26 -
27 - $taxonomies = array_map(function ($taxonomy) {
28 - if('portfolio_category' === $taxonomy->name){
29 - return 'Portfolio Category';
30 - }
31 - return $taxonomy->label;
32 - }, $taxonomies);
33 -
34 - if ($custom) {
35 - $taxonomies = array_merge(['custom' => __('Custom Meta', 'uicore-elements')], $taxonomies);
36 - }
37 -
38 - return $taxonomies;
39 - }
40 -
41 - static function get_taxonomy($name)
42 - {
43 - global $post;
44 -
45 - $categories = get_the_terms( $post->ID, $name );
46 - if ( ! $categories || is_wp_error( $categories ) ) {
47 - return false;
48 - }
49 -
50 - $categories = array_values( $categories );
51 - foreach ($categories as $t) {
52 - $term_name[] =
53 - '<a href="' . get_term_link($t) . '" title="View ' . \esc_attr($t->name) . ' posts">' . esc_html($t->name) . '</a>';
54 - }
55 - $category = implode(', ', $term_name);
56 -
57 - return $category;
58 - }
59 -
60 - static function get_reading_time()
61 - {
62 - global $post;
63 - // get the content
64 - $the_content = $post->post_content;
65 - // count the number of words
66 - $words = str_word_count( wp_strip_all_tags( $the_content ) );
67 - // rounding off and deviding per 200 words per minute
68 - $minute = floor( $words / 200 );
69 -
70 - // calculate the amount of time needed to read
71 - return $minute;
72 - }
73 -
74 - static function get_site_domain() {
75 - return str_ireplace( 'www.', '', parse_url( home_url(), PHP_URL_HOST ) );
76 - }
77 -
78 - /**
79 - * Returns the Uicore Elements settings page URL. You may pass a message so it'll be wrapped under a <a> tag.
80 - *
81 - * @param string $message Optional. A clickable message to be displayed that'll redirect, in a new tab, to settings page.
82 - * @return string Uicore Elements settings page URL or an <a> tag HTML with the url and the passed message.
83 - */
84 - static function get_admin_settings_url(string $message = '') {
85 - $url = admin_url( 'options-general.php?page=uicore-elements' );
86 - return !empty($message) ? '<a href="'.esc_url($url).'" target="_blank">' . esc_html($message) . '</a>' : $url;
87 - }
88 -
89 - static function register_widget_style($name,$deps=[],$external=false)
90 - {
91 - $handle = (!$external ? 'ui-e-' : '' ). $name;
92 - wp_register_style($handle, UICORE_ELEMENTS_ASSETS . '/css/elements/'.$name.'.css',$deps,UICORE_ELEMENTS_VERSION);
93 - return $handle;
94 - }
95 - static function register_widget_script($name,$deps=[],$external=false)
96 - {
97 - $handle = (!$external ? 'ui-e-' : '' ). $name;
98 - //if name contains / then we need to set a custom path
99 - if(strpos($name,'/') !== false){
100 - $path ='';
101 - }else{
102 - $path = 'elements/';
103 - }
104 - wp_register_script($handle, UICORE_ELEMENTS_ASSETS . '/js/'.$path.$name.'.js',$deps,UICORE_ELEMENTS_VERSION,true);
105 - return $handle;
106 - }
107 -
108 -
109 - public static function get_related($filter, $number)
110 - {
111 - global $post;
112 -
113 - $args = [];
114 -
115 - if ($filter == 'category') {
116 - $categories = get_the_category($post->ID);
117 -
118 - if ($categories) {
119 - $category_ids = [];
120 - foreach ($categories as $individual_category) {
121 - $category_ids[] = $individual_category->term_id;
122 - }
123 -
124 - $args = [
125 - 'category__in' => $category_ids,
126 - 'post__not_in' => [$post->ID],
127 - 'posts_per_page' => $number,
128 - 'ignore_sticky_posts' => 1,
129 - ];
130 - }
131 - } elseif ($filter == 'tag') {
132 - $tags = wp_get_post_tags($post->ID);
133 -
134 - if ($tags) {
135 - $tag_ids = [];
136 - foreach ($tags as $individual_tag) {
137 - $tag_ids[] = $individual_tag->term_id;
138 - }
139 - $args = [
140 - 'tag__in' => $tag_ids,
141 - 'post__not_in' => [$post->ID],
142 - 'posts_per_page' => $number,
143 - 'ignore_sticky_posts' => 1,
144 - ];
145 - }
146 - } else {
147 - $args = [
148 - 'post__not_in' => [$post->ID],
149 - 'posts_per_page' => $number,
150 - 'orderby' => 'rand',
151 - ];
152 - }
153 -
154 - $related_query = new \wp_query($args);
155 -
156 - if ($related_query->have_posts()) {
157 - return $related_query;
158 - } else {
159 - return false;
160 - }
161 - }
162 -
163 -
164 - /*
165 - * Get the current post id (used in Theme Builder - UiCore Framework)
166 - */
167 - static function get_current_meta_id()
168 - {
169 - if(\class_exists('\UiCore\Blog\Frontend') && \UiCore\Blog\Frontend::is_blog() && !is_singular('post')){
170 - $post_id = get_option('page_for_posts', true);
171 - }elseif(\class_exists('\UiCore\Portfolio\Frontend') && \UiCore\Portfolio\Frontend::is_portfolio() && !is_singular('portfolio')){
172 - $post_id = \UiCore\Portfolio\Frontend::get_portfolio_page_id();
173 - }else{
174 - $post_id = get_queried_object_id();
175 - }
176 -
177 - return $post_id;
178 - }
179 -
180 - /**
181 - * Return a list of textual html tags for Elementor Controls Options
182 - */
183 -
184 - public static function get_title_tags($type = null) {
185 -
186 - $tags = [
187 - 'h1' => 'H1',
188 - 'h2' => 'H2',
189 - 'h3' => 'H3',
190 - 'h4' => 'H4',
191 - 'h5' => 'H5',
192 - 'h6' => 'H6',
193 - 'div' => 'div',
194 - 'span' => 'span',
195 - 'p' => 'p',
196 - ];
197 -
198 - return $tags;
199 - }
200 -
201 -
202 - /**
203 - * Formats a date meta value according to the specified format.
204 - *
205 - * @param mixed $date The date value to format.
206 - * @param string $format The format to use for formatting the date. Can be 'custom' or a predefined format.
207 - * @param string $custom The custom format to use if $format is set to 'custom'.
208 - *
209 - * @return string The formatted date value.
210 - */
211 - public static function format_date($date, $format, $custom) {
212 -
213 - if ( 'custom' === $format ) {
214 - $date_format = $custom;
215 - } else if ('default' === $format ) {
216 - $date_format = get_option('date_format');
217 - } else {
218 - $date_format = $format;
219 - }
220 -
221 - $value = date_i18n($date_format, $date);
222 -
223 - return wp_kses_post($value);
224 - }
225 -
226 - /**
227 - * Sanitizes SVG content, also allowing `post` tags and atts.
228 - *
229 - * @param string $svg The raw SVG content to be sanitized.
230 - * @return string The sanitized SVG content, with only allowed tags and attributes.
231 - *
232 - * @since 1.0.2
233 - */
234 - public static function esc_svg($svg) {
235 - $default = wp_kses_allowed_html( 'post' );
236 -
237 - $args = array(
238 - 'svg' => array(
239 - 'class' => true,
240 - 'aria-hidden' => true,
241 - 'aria-labelledby' => true,
242 - 'role' => true,
243 - 'xmlns' => true,
244 - 'width' => true,
245 - 'height' => true,
246 - // has to be lowercase
247 - 'viewbox' => true,
248 - 'preserveaspectratio' => true
249 - ),
250 - 'g' => array( 'fill' => true ),
251 - 'title' => array( 'title' => true ),
252 - 'path' => array(
253 - 'd' => true,
254 - 'fill' => true
255 - )
256 - );
257 - $allowed_tags = array_merge( $default, $args );
258 -
259 - return wp_kses( $svg, $allowed_tags );
260 - }
261 -
262 - /**
263 - * Sanitizes text strings, but allowing some html tags usefull for styling and manipulating texts.
264 - *
265 - * @param string $content The content to be sanitized
266 - * @return string The sanitized string content.
267 - *
268 - * @since 1.0.3
269 - */
270 - public static function esc_string($content) {
271 -
272 - $allowed_tags = [
273 - 'strong' => array(),
274 - 'em' => array(),
275 - 'b' => array(),
276 - 'i' => array(),
277 - 'u' => array(),
278 - 's' => array(),
279 - 'sub' => array(),
280 - 'sup' => array(),
281 - 'span' => array(),
282 - 'br' => array()
283 - ];
284 -
285 - return wp_kses( $content, $allowed_tags );
286 - }
287 -
288 - /**
289 - * Retrieves the available image sizes.
290 - *
291 - * @return array An array of image sizes.
292 - *
293 - * @since 1.0.0
294 - */
295 - public static function get_images_sizes() {
296 - $sizes = [];
297 - foreach (get_intermediate_image_sizes() as $size) {
298 - $sizes[$size] = $size;
299 - }
300 - return $sizes;
301 - }
302 -
303 - /**
304 - * @since 1.0.5
305 - */
306 - private static function get_element_recursive($elements, $form_id) {
307 -
308 - foreach ($elements as $element) {
309 - if ($form_id === $element['id']) {
310 - return $element;
311 - }
312 -
313 - if (!empty($element['elements'])) {
314 - $element = self::get_element_recursive($element['elements'], $form_id);
315 -
316 - if ($element) {
317 - return $element;
318 - }
319 - }
320 - }
321 -
322 - return false;
323 - }
324 -
325 - /**
326 - * Retrieves the settings of a specific widget without relying on transient data.
327 - *
328 - * @param int $post_id The ID of the post or page.
329 - * @param int $widget_id The ID of the widget.
330 - * @return array|string The settings of the widget, or an error message if the request is invalid.
331 - *
332 - * @since 1.0.5
333 - */
334 - public static function get_widget_settings($post_id, $widget_id) {
335 -
336 - if (!$post_id || !$widget_id) {
337 - return false;
338 - }
339 -
340 - $elementor = Plugin::$instance;
341 - $pageMeta = $elementor->documents->get($post_id);
342 -
343 - if (!$pageMeta) {
344 - return false;
345 - }
346 - $metaData = $pageMeta->get_elements_data();
347 - if (!$metaData) {
348 - return false;
349 - }
350 -
351 - $widget_data = self::get_element_recursive($metaData, $widget_id);
352 - $settings = [];
353 -
354 - if (is_array($widget_data)) {
355 - $widget = $elementor->elements_manager->create_element_instance($widget_data);
356 - $settings = $widget->get_settings();
357 - }
358 -
359 - return $settings;
360 - }
361 -
362 -}
1 +<?php
2 +
3 +namespace UiCoreElements;
4 +
5 +use Elementor\Plugin;
6 +
7 +defined('ABSPATH') || exit();
8 +/**
9 + * UiCore Utils Functions
10 + */
11 +class Helper
12 +{
13 +
14 + public static function get_separator()
15 + {
16 + return '<span class="uicore-meta-separator"></span>';
17 + }
18 +
19 + public static function get_taxonomies($custom = true, $only_products = false)
20 + {
21 +
22 + // Woo only taxonomies
23 + if ($only_products) {
24 + $taxonomies = [
25 + 'product_cat' => 'Product Categories',
26 + 'product_tag' => 'Product Tags'
27 + ];
28 +
29 + $attributes = wc_get_attribute_taxonomies();
30 + foreach ($attributes as $att) {
31 + $taxonomies['pa_' . $att->attribute_name] = $att->attribute_label;
32 + }
33 +
34 + // All taxonomies
35 + } else {
36 +
37 + $taxonomies = get_taxonomies(['public' => true], 'objects');
38 + $exclusions = ['nav_menu', 'link_category', 'post_format']; // Exclude these taxonomies from the list
39 +
40 + $taxonomies = array_filter($taxonomies, function ($taxonomy) use ($exclusions) {
41 + return !in_array($taxonomy->name, $exclusions);
42 + });
43 +
44 + $taxonomies = array_map(function ($taxonomy) {
45 + if ('portfolio_category' === $taxonomy->name) {
46 + return 'Portfolio Category';
47 + }
48 + return $taxonomy->label;
49 + }, $taxonomies);
50 + }
51 +
52 + if ($custom) {
53 + $taxonomies = array_merge(['custom' => __('Custom Meta', 'uicore-elements')], $taxonomies);
54 + }
55 +
56 + return $taxonomies;
57 + }
58 +
59 + static function get_taxonomy($name)
60 + {
61 + global $post;
62 + $categories = get_the_terms($post->ID, $name);
63 +
64 + if (! $categories || is_wp_error($categories)) {
65 + return false;
66 + }
67 +
68 + $categories = array_values($categories);
69 + foreach ($categories as $t) {
70 + $term_name[] =
71 + '<a href="' . get_term_link($t) . '" title="View ' . \esc_attr($t->name) . ' posts">' . esc_html($t->name) . '</a>';
72 + }
73 + $category = implode(', ', $term_name);
74 +
75 + return $category;
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 +
96 + static function get_reading_time()
97 + {
98 + global $post;
99 +
100 + $the_content = $post->post_content;
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
103 +
104 + return $minute;
105 + }
106 +
107 + static function get_site_domain()
108 + {
109 + return str_ireplace('www.', '', parse_url(home_url(), PHP_URL_HOST));
110 + }
111 +
112 + /**
113 + * Returns the Uicore Elements settings page URL. You may pass a message so it'll be wrapped under a <a> tag.
114 + *
115 + * @param string $message Optional. A clickable message to be displayed that'll redirect, in a new tab, to settings page.
116 + *
117 + * @return string Uicore Elements settings page URL or an <a> tag HTML with the url and the passed message.
118 + */
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;
125 + }
126 +
127 + static function register_widget_style($name, $deps = [], $external = false)
128 + {
129 + $handle = (!$external ? 'ui-e-' : '') . $name;
130 + wp_register_style($handle, UICORE_ELEMENTS_ASSETS . '/css/elements/' . $name . '.css', $deps, UICORE_ELEMENTS_VERSION);
131 + return $handle;
132 + }
133 + static function register_widget_script($name, $deps = [], $external = false)
134 + {
135 + $handle = (!$external ? 'ui-e-' : '') . $name;
136 + //if name contains / then we need to set a custom path
137 + if (strpos($name, '/') !== false) {
138 + $path = '';
139 + } else {
140 + $path = 'elements/';
141 + }
142 + wp_register_script($handle, UICORE_ELEMENTS_ASSETS . '/js/' . $path . $name . '.js', $deps, UICORE_ELEMENTS_VERSION, true);
143 + return $handle;
144 + }
145 +
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)
156 + {
157 + $args = [
158 + 'post__not_in' => [$pageID],
159 + 'posts_per_page' => $per_page,
160 + 'paged' => $page_number,
161 + ];
162 +
163 + $categories = get_the_category($pageID);
164 + $tags = wp_get_post_tags($pageID);
165 +
166 + $tax_query = [];
167 +
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 + }
177 +
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 + }
187 +
188 + if (!empty($tax_query)) {
189 + $args['tax_query'] = [
190 + 'relation' => 'OR',
191 + ...$tax_query,
192 + ];
193 + }
194 +
195 + return new \WP_Query($args);
196 + }
197 +
198 + /**
199 + * Returns an array of related products IDs.
200 + */
201 + public static function get_product_related($limit, $ID)
202 + {
203 + if (empty($ID)) {
204 + global $post;
205 + $ID = $post->ID;
206 + }
207 +
208 + return wc_get_related_products($ID, $limit);
209 + }
210 +
211 + /*
212 + * Get the current post id (used in Theme Builder - UiCore Framework)
213 + */
214 + static function get_current_meta_id()
215 + {
216 + if (\class_exists('\UiCore\Blog\Frontend') && \UiCore\Blog\Frontend::is_blog() && !is_singular('post')) {
217 + $post_id = get_option('page_for_posts', true);
218 + } elseif (\class_exists('\UiCore\Portfolio\Frontend') && \UiCore\Portfolio\Frontend::is_portfolio() && !is_singular('portfolio')) {
219 + $post_id = \UiCore\Portfolio\Frontend::get_portfolio_page_id();
220 + } else {
221 + $post_id = get_queried_object_id();
222 + }
223 +
224 + return $post_id;
225 + }
226 +
227 + /**
228 + * Return a list of textual html tags for Elementor Controls Options
229 + */
230 + public static function get_title_tags()
231 + {
232 +
233 + $tags = [
234 + 'h1' => 'H1',
235 + 'h2' => 'H2',
236 + 'h3' => 'H3',
237 + 'h4' => 'H4',
238 + 'h5' => 'H5',
239 + 'h6' => 'H6',
240 + 'div' => 'div',
241 + 'span' => 'span',
242 + 'p' => 'p',
243 + ];
244 +
245 + return $tags;
246 + }
247 +
248 +
249 + /**
250 + * Formats a date meta value according to the specified format.
251 + *
252 + * @param mixed $date The date value to format.
253 + * @param string $format The format to use for formatting the date. Can be 'custom' or a predefined format.
254 + * @param string $custom The custom format to use if $format is set to 'custom'.
255 + *
256 + * @return string The formatted date value.
257 + */
258 + public static function format_date($date, $format, $custom)
259 + {
260 +
261 + if ('custom' === $format) {
262 + $date_format = $custom;
263 + } else if ('default' === $format) {
264 + $date_format = get_option('date_format');
265 + } else {
266 + $date_format = $format;
267 + }
268 +
269 + $value = date_i18n($date_format, $date);
270 +
271 + return wp_kses_post($value);
272 + }
273 +
274 + /**
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.
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 + *
307 + * @param string $svg The raw SVG content to be sanitized.
308 + * @return string The sanitized SVG content, with only allowed tags and attributes.
309 + *
310 + * @since 1.0.2
311 + */
312 + public static function esc_svg($svg)
313 + {
314 + $default = wp_kses_allowed_html('post');
315 +
316 + $args = array(
317 + 'svg' => array(
318 + 'class' => true,
319 + 'aria-hidden' => true,
320 + 'aria-labelledby' => true,
321 + 'role' => true,
322 + 'xmlns' => true,
323 + 'width' => true,
324 + 'height' => true,
325 + // has to be lowercase
326 + 'viewbox' => true,
327 + 'preserveaspectratio' => true
328 + ),
329 + 'g' => array('fill' => true),
330 + 'title' => array('title' => true),
331 + 'path' => array(
332 + 'd' => true,
333 + 'fill' => true
334 + )
335 + );
336 + $allowed_tags = array_merge($default, $args);
337 +
338 + return wp_kses($svg, $allowed_tags);
339 + }
340 +
341 + /**
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.
344 + *
345 + * @param string $content The content to be sanitized
346 + * @return string The sanitized string content.
347 + *
348 + * @since 1.0.3
349 + */
350 + public static function esc_string($content)
351 + {
352 +
353 + $allowed_tags = [
354 + 'strong' => array(),
355 + 'em' => array(),
356 + 'b' => array(),
357 + 'i' => array(),
358 + 'u' => array(),
359 + 's' => array(),
360 + 'sub' => array(),
361 + 'sup' => array(),
362 + 'span' => array(),
363 + 'br' => array(),
364 + 'a' => [
365 + 'href' => true,
366 + 'title' => true,
367 + 'target' => true,
368 + 'rel' => true
369 + ]
370 + ];
371 +
372 + return wp_kses($content, $allowed_tags);
373 + }
374 +
375 + /**
376 + * Retrieves the available image sizes.
377 + *
378 + * @return array An array of image sizes.
379 + *
380 + * @since 1.0.0
381 + */
382 + public static function get_images_sizes()
383 + {
384 + $sizes = [];
385 + foreach (get_intermediate_image_sizes() as $size) {
386 + $sizes[$size] = $size;
387 + }
388 + return $sizes;
389 + }
390 +
391 + /**
392 + * @since 1.0.5
393 + */
394 + private static function get_element_recursive($elements, $form_id)
395 + {
396 +
397 + foreach ($elements as $element) {
398 + if ($form_id === $element['id']) {
399 + return $element;
400 + }
401 +
402 + if (!empty($element['elements'])) {
403 + $element = self::get_element_recursive($element['elements'], $form_id);
404 +
405 + if ($element) {
406 + return $element;
407 + }
408 + }
409 + }
410 +
411 + return false;
412 + }
413 +
414 + /**
415 + * Retrieves the settings of a specific widget without relying on transient data.
416 + *
417 + * @param int $post_id The ID of the post or page.
418 + * @param int $widget_id The ID of the widget.
419 + * @return array|string The settings of the widget, or an error message if the request is invalid.
420 + *
421 + * @since 1.0.5
422 + * @deprecated Deprecated since version 1.0.11 Use the transient method instead.
423 + */
424 + public static function get_widget_settings($post_id, $widget_id)
425 + {
426 +
427 + if (!$post_id || !$widget_id) {
428 + return false;
429 + }
430 +
431 + $elementor = Plugin::$instance;
432 + $pageMeta = $elementor->documents->get($post_id);
433 +
434 + if (!$pageMeta) {
435 + return false;
436 + }
437 + $metaData = $pageMeta->get_elements_data();
438 + if (!$metaData) {
439 + return false;
440 + }
441 +
442 + $widget_data = self::get_element_recursive($metaData, $widget_id);
443 + $settings = [];
444 +
445 + if (is_array($widget_data)) {
446 + $widget = $elementor->elements_manager->create_element_instance($widget_data);
447 + $settings = $widget->get_settings();
448 + }
449 +
450 + return $settings;
451 + }
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 + }
519 +}