PluginProbe
Master Addons for Elementor – Elementor Addons, Widgets, Mega Menu Builder, Popup Builder, Widget Builder & Template Kits / 3.1.2
Master Addons for Elementor – Elementor Addons, Widgets, Mega Menu Builder, Popup Builder, Widget Builder & Template Kits v3.1.2
3.2.2 3.2.3 3.2.1 3.2.0 3.1.9 3.1.8 3.1.7 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.9 trunk 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.3 1.1.4 1.1.5 All 174 releases
master-addons / inc / classes / helper.php

helper.php in Master Addons for Elementor – Elementor Addons, Widgets, Mega Menu Builder, Popup Builder, Widget Builder & Template Kits 3.1.2, at inc/classes/helper.php

2,607 lines 80.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace MasterAddons\Inc\Classes;
4
5 if (!defined('ABSPATH')) {
6 exit; // Exit if accessed directly
7 }
8
9 use Elementor\Utils;
10 use Elementor\Icons_Manager;
11 use MasterAddons\Inc\Classes\Pro_Upgrade;
12
13 class Helper {
14
15 public static function upgrade_to_pro( $content = '' ){
16 // Adds a direct checkout link in the free version.
17 if (!self::jltma_premium()) {
18 return apply_filters('master_addons/upgrade_pro', sprintf(
19 '%1$s <a href="%2$s" target="_blank">%3$s</a>',
20 ($content) ? $content : '',
21 ma_el_fs()->checkout_url(),
22 __('Upgrade Now', 'master-addons')
23 ));
24 }
25 }
26
27 // Adds a direct checkout link in the free version.
28 public static function unlock_pro_feature( $content = '' ){
29 $default_message = '<span class="pro-feature"> Upgrade to <a href="https://master-addons.com/pricing" target="_blank">Pro Version</a> to unlock this feature.</span>';
30 $message = !empty($content) ? $content : $default_message;
31 return apply_filters('master_addons/upgrade_pro', $message);
32 }
33
34 /**
35 * Remove spaces from Plugin Slug
36 */
37 public static function jltma_slug_cleanup() {
38 if ( self::jltma_premium() && defined( 'JLTMA_PRO_SLUG' ) ) {
39 return str_replace( '-', '_', strtolower( JLTMA_PRO_SLUG ) );
40 }
41 return str_replace( '-', '_', strtolower( JLTMA_SLUG ) );
42 }
43
44 /**
45 * Function current_datetime() compability for wp version < 5.3
46 *
47 * @return DateTimeImmutable
48 */
49 public static function jltma_current_datetime() {
50 if ( function_exists( 'current_datetime' ) ) {
51 return current_datetime();
52 }
53
54 return new \DateTimeImmutable( 'now', self::jltma_wp_timezone() );
55 }
56
57 /**
58 * Add Pro upgrade notice control to any Elementor widget/extension
59 *
60 * @param object $element The Elementor element (widget, section, etc.)
61 * @param string $control_id Optional custom control ID
62 * @param string $message Optional custom message
63 * @return void
64 */
65 public static function jltma_upgrade_to_popup($element, $control_id = 'jltma_editor_upgrade_notice', $message = ''){
66 if (!self::jltma_premium()) {
67 $element->add_control(
68 $control_id,
69 [
70 'label' => '',
71 'type' => \Elementor\Controls_Manager::RAW_HTML,
72 'raw' => !empty($message) ? $message : self::jltma_pro_notice_html(),
73 ]
74 );
75 }
76 }
77
78 /**
79 * Simple pro upgrade message for Elementor editor controls
80 * Light inline notice: "Click Here to see what options are available in the Pro version"
81 *
82 * @param string $url Optional custom URL
83 * @return string HTML markup
84 */
85 public static function jltma_pro_upgrade_message($url = '') {
86 if (empty($url)) {
87 $url = 'https://master-addons.com/pricing/';
88 }
89 return '<div style="background:#f0f5ff; padding:15px; border-radius:4px; text-align:center; line-height:1.6;">'
90 . '<a href="' . esc_url($url) . '" target="_blank" style="color:#2563eb; font-weight:600; text-decoration:none;">'
91 . esc_html__('Click Here', 'master-addons') . '</a> '
92 . esc_html__('to see what options are available in the', 'master-addons') . ' '
93 . '<a href="' . esc_url($url) . '" target="_blank" style="color:#2563eb; font-weight:600; text-decoration:none;">'
94 . esc_html__('Pro version', 'master-addons') . '</a>'
95 . '</div>';
96 }
97
98 /**
99 * Function jltma_wp_timezone() compability for wp version < 5.3
100 *
101 * @return DateTimeZone
102 */
103 public static function jltma_wp_timezone() {
104 if ( function_exists( 'wp_timezone' ) ) {
105 return wp_timezone();
106 }
107
108 return new \DateTimeZone( self::jltma_wp_timezone_string() );
109 }
110 public static function jltma_load_svg( $icon ) {
111
112 if ( ! file_exists( $icon ) ) {
113 return false;
114 }
115
116 ob_start();
117
118 include $icon;
119
120 $svg = ob_get_clean();
121
122 return $svg;
123 }
124
125 public static function get_plugin_name( $full = false ) {
126 return apply_filters( 'jltma_white_label_plugin_name', __( 'Master Addons', 'master-addons' ), $full );
127 }
128
129 /**
130 * API Endpoint
131 *
132 * @return string
133 */
134 public static function api_endpoint() {
135 $api_endpoint_url = 'https://pixarlabs.com';
136 $api_endpoint = apply_filters( 'jltma_endpoint', $api_endpoint_url );
137
138 return trailingslashit( $api_endpoint );
139 }
140
141 /**
142 * CRM Endpoint
143 *
144 * @return string
145 */
146 public static function crm_endpoint() {
147 $crm_endpoint_url = self::api_endpoint() . 'api/plugin/subscribe';
148 $crm_endpoint = apply_filters( 'jltma_crm_crm_endpoint', $crm_endpoint_url );
149
150 return trailingslashit( $crm_endpoint );
151 }
152
153 /**
154 * Function jltma_wp_timezone_string() compability for wp version < 5.3
155 *
156 * @return string
157 */
158 public static function jltma_wp_timezone_string() {
159 $timezone_string = get_option( 'timezone_string' );
160
161 if ( $timezone_string ) {
162 return $timezone_string;
163 }
164
165 $offset = (float) get_option( 'gmt_offset' );
166 $hours = (int) $offset;
167 $minutes = ( $offset - $hours );
168
169 $sign = ( $offset < 0 ) ? '-' : '+';
170 $abs_hour = abs( $hours );
171 $abs_mins = abs( $minutes * 60 );
172 $tz_offset = sprintf( '%s%02d:%02d', $sign, $abs_hour, $abs_mins );
173
174 return $tz_offset;
175 }
176
177 /**
178 * Get Merged Data
179 *
180 * @param [type] $data .
181 * @param string $start_date .
182 * @param string $end_data .
183 *
184 * @author Jewel Theme <support@jeweltheme.com>
185 */
186 public static function get_merged_data( $data, $start_date = '', $end_data = '' ) {
187 $_data = shortcode_atts(
188 array(
189 'image_url' => JLTMA_IMAGE_DIR . 'ma-fallback.png',
190 'start_date' => $start_date,
191 'end_date' => $end_data,
192 'counter_time' => '',
193 'is_campaign' => 'false',
194 'button_text' => 'Get Premium',
195 'button_url' => 'https://jeweltheme.com',
196 'btn_color' => '#CC22FF',
197 'notice' => '',
198 'notice_timestamp' => '',
199 'show_for_premium' => 'false',
200 ),
201 $data
202 );
203
204 if ( empty( $_data['image_url'] ) ) {
205 $_data['image_url'] = JLTMA_IMAGE_DIR . 'ma-fallback.png';
206 }
207
208 return $_data;
209 }
210
211
212 /**
213 * wp_kses attributes map
214 *
215 * @param array $attrs .
216 *
217 * @author Jewel Theme <support@jeweltheme.com>
218 */
219 public static function wp_kses_atts_map( array $attrs ) {
220 return array_fill_keys( array_values( $attrs ), true );
221 }
222
223 /**
224 * Custom method
225 *
226 * @param [type] $content .
227 *
228 * @author Jewel Theme <support@jeweltheme.com>
229 */
230 public static function wp_kses_custom( $content ) {
231 $allowed_tags = wp_kses_allowed_html( 'post' );
232
233 $custom_tags = array(
234 'select' => self::wp_kses_atts_map( array( 'class', 'id', 'style', 'width', 'height', 'title', 'data', 'name', 'autofocus', 'disabled', 'multiple', 'required', 'size' ) ),
235 'input' => self::wp_kses_atts_map( array( 'class', 'id', 'style', 'width', 'height', 'title', 'data', 'name', 'autofocus', 'disabled', 'required', 'size', 'type', 'checked', 'readonly', 'placeholder', 'value', 'maxlength', 'min', 'max', 'multiple', 'pattern', 'step', 'autocomplete' ) ),
236 'textarea' => self::wp_kses_atts_map( array( 'class', 'id', 'style', 'width', 'height', 'title', 'data', 'name', 'autofocus', 'disabled', 'required', 'rows', 'cols', 'wrap', 'maxlength' ) ),
237 'option' => self::wp_kses_atts_map( array( 'class', 'id', 'label', 'disabled', 'label', 'selected', 'value' ) ),
238 'optgroup' => self::wp_kses_atts_map( array( 'disabled', 'label', 'class', 'id' ) ),
239 'form' => self::wp_kses_atts_map( array( 'class', 'id', 'data', 'style', 'width', 'height', 'accept-charset', 'action', 'autocomplete', 'enctype', 'method', 'name', 'novalidate', 'rel', 'target' ) ),
240 'svg' => self::wp_kses_atts_map( array( 'class', 'xmlns', 'viewbox', 'width', 'height', 'fill', 'aria-hidden', 'aria-labelledby', 'role' ) ),
241 'rect' => self::wp_kses_atts_map( array( 'rx', 'width', 'height', 'fill' ) ),
242 'path' => self::wp_kses_atts_map( array( 'd', 'fill' ) ),
243 'g' => self::wp_kses_atts_map( array( 'fill' ) ),
244 'defs' => self::wp_kses_atts_map( array( 'fill' ) ),
245 'linearGradient' => self::wp_kses_atts_map( array( 'id', 'x1', 'x2', 'y1', 'y2', 'gradientUnits' ) ),
246 'stop' => self::wp_kses_atts_map( array( 'stop-color', 'offset', 'stop-opacity' ) ),
247 'style' => self::wp_kses_atts_map( array( 'type' ) ),
248 'div' => self::wp_kses_atts_map( array( 'class', 'id', 'style' ) ),
249 'ul' => self::wp_kses_atts_map( array( 'class', 'id', 'style' ) ),
250 'li' => self::wp_kses_atts_map( array( 'class', 'id', 'style' ) ),
251 'label' => self::wp_kses_atts_map( array( 'class', 'for' ) ),
252 'span' => self::wp_kses_atts_map( array( 'class', 'id', 'style' ) ),
253 'h1' => self::wp_kses_atts_map( array( 'class', 'id', 'style' ) ),
254 'h2' => self::wp_kses_atts_map( array( 'class', 'id', 'style' ) ),
255 'h3' => self::wp_kses_atts_map( array( 'class', 'id', 'style' ) ),
256 'h4' => self::wp_kses_atts_map( array( 'class', 'id', 'style' ) ),
257 'h5' => self::wp_kses_atts_map( array( 'class', 'id', 'style' ) ),
258 'h6' => self::wp_kses_atts_map( array( 'class', 'id', 'style' ) ),
259 'a' => self::wp_kses_atts_map( array( 'class', 'href', 'target', 'rel' ) ),
260 'p' => self::wp_kses_atts_map( array( 'class', 'id', 'style', 'data' ) ),
261 'table' => self::wp_kses_atts_map( array( 'class', 'id', 'style' ) ),
262 'thead' => self::wp_kses_atts_map( array( 'class', 'id', 'style' ) ),
263 'tbody' => self::wp_kses_atts_map( array( 'class', 'id', 'style' ) ),
264 'tr' => self::wp_kses_atts_map( array( 'class', 'id', 'style' ) ),
265 'th' => self::wp_kses_atts_map( array( 'class', 'id', 'style' ) ),
266 'td' => self::wp_kses_atts_map( array( 'class', 'id', 'style' ) ),
267 'i' => self::wp_kses_atts_map( array( 'class', 'id', 'style' ) ),
268 'button' => self::wp_kses_atts_map( array( 'class', 'id' ) ),
269 'nav' => self::wp_kses_atts_map( array( 'class', 'id', 'style' ) ),
270 'time' => self::wp_kses_atts_map( array( 'datetime' ) ),
271 'br' => array(),
272 'strong' => array(),
273 'style' => array(),
274 'img' => self::wp_kses_atts_map( array( 'class', 'src', 'alt', 'height', 'width', 'srcset', 'id', 'loading' ) ),
275 );
276
277 $allowed_tags = array_merge_recursive( $allowed_tags, $custom_tags );
278
279 return wp_kses( stripslashes_deep( $content ), $allowed_tags );
280 }
281
282 /**
283 * Validate HTML tag name to prevent XSS
284 *
285 * Only allows safe HTML tags from a whitelist.
286 * Returns default tag if provided tag is not in whitelist.
287 *
288 * @since 2.0.7.1
289 * @param string $tag The HTML tag to validate
290 * @param string $default Default tag to return if validation fails (default: 'div')
291 * @return string Safe HTML tag name
292 */
293 public static function jltma_validate_html_tag($tag, $default = 'div') {
294 $allowed_tags = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'span', 'p', 'header', 'footer', 'section', 'article', 'aside', 'nav', 'main'];
295 return in_array($tag, $allowed_tags, true) ? $tag : $default;
296 }
297
298 public static function jltma_elementor() {
299 return \Elementor\Plugin::$instance;
300 }
301
302 /**
303 * Check if Woocommerce is installed and active
304 *
305 * @since 1.5.7
306 */
307 public static function is_woocommerce_active() {
308 return in_array(
309 'woocommerce/woocommerce.php',
310 apply_filters( 'active_plugins', get_option( 'active_plugins' ) )
311 );
312 }
313
314 /**
315 * Get WooCommerce product categories
316 *
317 * @since 2.0.0
318 * @return array Array of category ID => name pairs
319 */
320 public static function jltma_get_woo_categories() {
321 $options = [];
322 if ( ! class_exists( 'WooCommerce' ) ) {
323 return $options;
324 }
325 $terms = get_terms([
326 'taxonomy' => 'product_cat',
327 'hide_empty' => false,
328 ]);
329 if ( ! is_wp_error( $terms ) && ! empty( $terms ) ) {
330 foreach ( $terms as $term ) {
331 $options[ $term->term_id ] = $term->name;
332 }
333 }
334 return $options;
335 }
336
337 /**
338 * Get WooCommerce product tags
339 *
340 * @since 2.0.0
341 * @return array Array of tag ID => name pairs
342 */
343 public static function jltma_get_woo_tags() {
344 $options = [];
345 if ( ! class_exists( 'WooCommerce' ) ) {
346 return $options;
347 }
348 $terms = get_terms([
349 'taxonomy' => 'product_tag',
350 'hide_empty' => false,
351 ]);
352 if ( ! is_wp_error( $terms ) && ! empty( $terms ) ) {
353 foreach ( $terms as $term ) {
354 $options[ $term->term_id ] = $term->name;
355 }
356 }
357 return $options;
358 }
359
360 /**
361 * Get WooCommerce products
362 *
363 * @since 2.0.0
364 * @return array Array of product ID => title pairs
365 */
366 public static function jltma_get_woo_products() {
367 $options = [];
368 if ( ! class_exists( 'WooCommerce' ) ) {
369 return $options;
370 }
371 $products = get_posts([
372 'post_type' => 'product',
373 'posts_per_page' => -1,
374 'post_status' => 'publish',
375 ]);
376 if ( ! empty( $products ) ) {
377 foreach ( $products as $product ) {
378 $options[ $product->ID ] = $product->post_title;
379 }
380 }
381 return $options;
382 }
383
384 /**
385 * Get WordPress user roles
386 *
387 * @since 2.0.0
388 * @return array Array of role slug => name pairs
389 */
390 public static function jltma_get_user_roles() {
391 global $wp_roles;
392 $options = [];
393 if ( ! isset( $wp_roles ) ) {
394 $wp_roles = new \WP_Roles();
395 }
396 $roles = $wp_roles->get_names();
397 foreach ( $roles as $role_slug => $role_name ) {
398 $options[ $role_slug ] = $role_name;
399 }
400 return $options;
401 }
402
403 /**
404 * Get data if isset.
405 * Retrieves data with selected key if isset.
406 *
407 * @param array|object $data Data to check.
408 * @param string $key Data key to look for.
409 * @param string $else Default value if key is not found.
410 *
411 * @return mixed Data with selected key, default value otherwise.
412 */
413 public static function get_if_isset( $data, $key, $else = '' ) {
414 if ( 'object' === gettype( $data ) ) {
415 return isset( $data->{$key} ) ? $data->{$key} : $else;
416 }
417
418 return isset( $data[ $key ] ) ? $data[ $key ] : $else;
419 }
420
421 /**
422 * Get data if not empty.
423 * Retrieves data with selected key if not empty.
424 *
425 * @param array $data Array of data.
426 * @param string $key Data key to look for.
427 * @param string $else Default value if key is empty.
428 *
429 * @return mixed Data with selected key, default value otherwise.
430 */
431 public static function get_if_not_empty( $data, $key, $else = '' ) {
432 return ( ! empty( $data[ $key ] ) ) ? $data[ $key ] : $else;
433 }
434
435
436 /**
437 * Check if value in array or equal.
438 *
439 * If `$haystack` is array - checks if `$needle` is in
440 * `$haystack` array, or if they are equal otherwise.
441 *
442 * @param string $needle Test value.
443 * @param mixed $haystack Array or value to check.
444 * @return bool True if `$needle` is in array or equal to
445 * `$haystack`, false otherwise.
446 */
447 public static function in_array_or_equal( $needle, $haystack ) {
448 if ( is_array( $haystack ) ) {
449 return in_array( $needle, $haystack, true );
450 }
451
452 return $needle === $haystack;
453 }
454
455 public static function generate_html_tag( $name, $attributes = array(), $content = false ) {
456 if ( is_array( $attributes ) ) {
457 $attributes_array = array();
458
459 foreach ( $attributes as $key => $value ) {
460 $attributes_array[] = sprintf( "{$key}=\"%s\"", esc_attr( $value ) );
461 }
462
463 $attributes = sprintf( ' %s', implode( ' ', $attributes_array ) );
464 } else {
465 $attributes = " {$attributes}";
466 }
467
468 $tag = "<{$name}{$attributes}>";
469
470 if ( $content ) {
471 $tag .= "{$content}</{$name}>";
472 }
473
474 return $tag;
475 }
476
477 /**
478 * Get class name.
479 * Converts string to valid class name.
480 *
481 * @param string $name The name string.
482 * @return array The class name.
483 */
484 public static function generate_class_name( $name ) {
485 return str_replace( '-', '_', ucwords( $name, '-' ) );
486 }
487
488
489 /**
490 * Unset key by value.
491 * Unset array items by value.
492 *
493 * @param string $needle The searchable value.
494 * @param array $haystack The array to search.
495 *
496 * @return array The filtered array.
497 */
498 public static function unset_items_by_value( $needle, $haystack ) {
499 foreach ( array_keys( $haystack, $needle, true ) as $key ) {
500 unset( $haystack[ $key ] );
501 }
502
503 return $haystack;
504 }
505
506 /**
507 * Check if request is ajax.
508 *
509 * Whether the current request is a WordPress ajax request.
510 *
511 * @since 1.0.0
512 *
513 * @return bool True if it's a WordPress ajax request, false otherwise.
514 */
515 public static function is_ajax() {
516 if ( function_exists( 'wp_doing_ajax' ) ) {
517 return wp_doing_ajax();
518 }
519
520 return defined( 'DOING_AJAX' ) && DOING_AJAX;
521 }
522
523 /**
524 * Get breakpoints.
525 *
526 * Retrieve the responsive breakpoints.
527 *
528 * @return array Responsive breakpoints.
529 */
530 public static function get_breakpoints() {
531 return self::jltma_elementor()->breakpoints->get_breakpoints();
532 }
533
534 /**
535 * Check if request is preview.
536 *
537 * Whether the current request is elementor preview mode or
538 * WordPress preview.
539 *
540 * @param int $post_id Post ID.
541 *
542 * @return bool True if it's a preview request, false otherwise.
543 */
544 public static function is_preview( $post_id = 0 ) {
545 return self::is_preview_mode( $post_id ) || is_preview();
546 }
547
548 /**
549 * Check if request is preview mode.
550 *
551 * Whether the current request is elementor preview mode.
552 *
553 * @return bool True if it's an elementor preview mode, false otherwise.
554 */
555 public static function is_preview_mode( $post_id = 0 ) {
556 return self::jltma_elementor()->preview->is_preview_mode( $post_id );
557 }
558
559 public static function jltma_is_edit_mode( $post_id = 0 ) {
560 if ( self::jltma_elementor()->preview->is_preview_mode() || self::jltma_elementor()->editor->is_edit_mode( $post_id ) ) {
561 return true;
562 }
563 return false;
564 }
565
566
567 /**
568 * Retrive the list of Contact Form 7 Forms [ if plugin activated ]
569 */
570 public static function maad_el_retrive_cf7() {
571 if ( function_exists( 'wpcf7' ) ) {
572 $wpcf7_form_list = get_posts(
573 array(
574 'post_type' => 'wpcf7_contact_form',
575 'showposts' => 999,
576 )
577 );
578 $options = array();
579 $options[0] = esc_html__( 'Select a Form', 'master-addons' );
580 if ( ! empty( $wpcf7_form_list ) && ! is_wp_error( $wpcf7_form_list ) ) {
581 foreach ( $wpcf7_form_list as $post ) {
582 $options[ $post->ID ] = $post->post_title;
583 }
584 } else {
585 $options[0] = esc_html__( 'Create a Form First', 'master-addons' );
586 }
587 return $options;
588 }
589 }
590
591 public static function get_page_template_options( $type = '' ) {
592
593 $page_templates = self::ma_get_page_templates( $type );
594
595 $options[-1] = __( 'Select', 'master-addons' );
596
597 if ( count( $page_templates ) ) {
598 foreach ( $page_templates as $id => $name ) {
599 $options[ $id ] = $name;
600 }
601 } else {
602 $options['no_template'] = __( 'No saved templates found!', 'master-addons' );
603 }
604
605 return $options;
606 }
607
608
609 public static function ma_get_page_templates( $type = '' ) {
610 $args = array(
611 'post_type' => 'elementor_library',
612 'posts_per_page' => -1,
613 );
614
615 if ( $type ) {
616 $args['tax_query'] = array(
617 array(
618 'taxonomy' => 'elementor_library_type',
619 'field' => 'slug',
620 'terms' => $type,
621 ),
622 );
623 }
624
625 $page_templates = get_posts( $args );
626
627 $options = array();
628
629 if ( ! empty( $page_templates ) && ! is_wp_error( $page_templates ) ) {
630 foreach ( $page_templates as $post ) {
631 $options[ $post->ID ] = $post->post_title;
632 }
633 }
634 return $options;
635 }
636
637
638 // Get all forms of Ninja Forms plugin
639 public static function ma_el_get_ninja_forms() {
640 if ( class_exists( 'Ninja_Forms' ) ) {
641 $options = array();
642
643 $contact_forms = Ninja_Forms()->form()->get_forms();
644
645 if ( ! empty( $contact_forms ) && ! is_wp_error( $contact_forms ) ) {
646
647 $i = 0;
648
649 foreach ( $contact_forms as $form ) {
650 if ( $i == 0 ) {
651 $options[0] = esc_html__( 'Select a Contact form', 'master-addons' );
652 }
653 $options[ $form->get_id() ] = $form->get_setting( 'title' );
654 ++$i;
655 }
656 }
657 } else {
658 $options = array();
659 }
660
661 return $options;
662 }
663
664
665 // Get all forms of WPForms plugin
666 public static function ma_el_get_wpforms_forms() {
667 if ( class_exists( 'WPForms' ) ) {
668 $options = array();
669
670 $args = array(
671 'post_type' => 'wpforms',
672 'posts_per_page' => -1,
673 );
674
675 $contact_forms = get_posts( $args );
676
677 if ( ! empty( $contact_forms ) && ! is_wp_error( $contact_forms ) ) {
678
679 $i = 0;
680
681 foreach ( $contact_forms as $post ) {
682 if ( $i == 0 ) {
683 $options[0] = esc_html__( 'Select a Contact form', 'master-addons' );
684 }
685 $options[ $post->ID ] = $post->post_title;
686 ++$i;
687 }
688 }
689 } else {
690 $options = array();
691 }
692
693 return $options;
694 }
695
696
697 // get weForms
698 public static function ma_el_get_weforms() {
699 $wpuf_form_list = get_posts(
700 array(
701 'post_type' => 'wpuf_contact_form',
702 'showposts' => 999,
703 )
704 );
705
706 $options = array();
707
708 if ( ! empty( $wpuf_form_list ) && ! is_wp_error( $wpuf_form_list ) ) {
709 $options[0] = esc_html__( 'Select weForm', 'master-addons' );
710 foreach ( $wpuf_form_list as $post ) {
711 $options[ $post->ID ] = $post->post_title;
712 }
713 } else {
714 $options[0] = esc_html__( 'Create a Form First', 'master-addons' );
715 }
716
717 return $options;
718 }
719
720 // Get forms of Caldera plugin
721 public static function ma_el_get_caldera_forms() {
722 if ( class_exists( 'Caldera_Forms' ) ) {
723 $options = array();
724
725 $contact_forms = \Caldera_Forms_Forms::get_forms( true, true );
726
727 if ( ! empty( $contact_forms ) && ! is_wp_error( $contact_forms ) ) {
728
729 $i = 0;
730
731 foreach ( $contact_forms as $form ) {
732 if ( $i == 0 ) {
733 $options[0] = esc_html__( 'Select a Contact form', 'master-addons' );
734 }
735 $options[ $form['ID'] ] = $form['name'];
736 ++$i;
737 }
738 }
739 } else {
740 $options = array();
741 }
742
743 return $options;
744 }
745
746
747 // Get forms of Gravity Forms plugin
748 public static function ma_el_get_gravity_forms() {
749 if ( class_exists( 'GFCommon' ) ) {
750 $options = array();
751
752 $contact_forms = \RGFormsModel::get_forms( null, 'title' );
753
754 if ( ! empty( $contact_forms ) && ! is_wp_error( $contact_forms ) ) {
755
756 $i = 0;
757
758 foreach ( $contact_forms as $form ) {
759 if ( $i == 0 ) {
760 $options[0] = esc_html__( 'Select a Contact form', 'master-addons' );
761 }
762 $options[ $form->id ] = $form->title;
763 ++$i;
764 }
765 }
766 } else {
767 $options = array();
768 }
769
770 return $options;
771 }
772
773
774 /**
775 * Check if Elementor Pro active.
776 *
777 * Checks whether the Elementor Pro plugin is currently active.
778 *
779 * @return bool True if Elementor Pro is active, false otherwise.
780 */
781 public static function is_elementor_pro() {
782 return class_exists( 'ElementorPro\Plugin' );
783 }
784
785 // Content Alignments
786 public static function jltma_content_alignment() {
787 $content_alignment = array(
788 'left' => array(
789 'title' => __( 'Left', 'master-addons' ),
790 'icon' => 'eicon-text-align-left',
791 ),
792 'center' => array(
793 'title' => __( 'Center', 'master-addons' ),
794 'icon' => 'eicon-text-align-center',
795 ),
796 'right' => array(
797 'title' => __( 'Right', 'master-addons' ),
798 'icon' => 'eicon-text-align-right',
799 ),
800 );
801 return $content_alignment;
802 }
803
804 // Justify Content Alignments
805 public static function jltma_content_alignments() {
806 $content_alignment = array(
807 'left' => array(
808 'title' => __( 'Left', 'master-addons' ),
809 'icon' => 'eicon-text-align-left',
810 ),
811 'center' => array(
812 'title' => __( 'Center', 'master-addons' ),
813 'icon' => 'eicon-text-align-center',
814 ),
815 'right' => array(
816 'title' => __( 'Right', 'master-addons' ),
817 'icon' => 'eicon-text-align-right',
818 ),
819 'justify' => array(
820 'title' => __( 'Justify', 'master-addons' ),
821 'icon' => 'eicon-text-align-justify',
822 ),
823 );
824 return $content_alignment;
825 }
826
827 // Justify Flex Content Alignments
828 public static function jltma_content_flex_alignments() {
829 $content_alignment = array(
830 'flex-start' => array(
831 'title' => __( 'Left', 'master-addons' ),
832 'icon' => 'eicon-text-align-left',
833 ),
834 'center' => array(
835 'title' => __( 'Center', 'master-addons' ),
836 'icon' => 'eicon-text-align-center',
837 ),
838 'flex-end' => array(
839 'title' => __( 'Right', 'master-addons' ),
840 'icon' => 'eicon-text-align-right',
841 ),
842 'space-between' => array(
843 'title' => __( 'Justify', 'master-addons' ),
844 'icon' => 'eicon-text-align-justify',
845 ),
846 );
847 return $content_alignment;
848 }
849
850 // Heading Tags
851 public static function jltma_heading_tags() {
852 $heading_tags = array(
853 'h1' => array(
854 'title' => __( 'H1', 'master-addons' ),
855 'icon' => 'eicon-editor-h1',
856 ),
857 'h2' => array(
858 'title' => __( 'H2', 'master-addons' ),
859 'icon' => 'eicon-editor-h2',
860 ),
861 'h3' => array(
862 'title' => __( 'H3', 'master-addons' ),
863 'icon' => 'eicon-editor-h3',
864 ),
865 'h4' => array(
866 'title' => __( 'H4', 'master-addons' ),
867 'icon' => 'eicon-editor-h4',
868 ),
869 'h5' => array(
870 'title' => __( 'H5', 'master-addons' ),
871 'icon' => 'eicon-editor-h5',
872 ),
873 'h6' => array(
874 'title' => __( 'H6', 'master-addons' ),
875 'icon' => 'eicon-editor-h6',
876 ),
877 );
878
879 return $heading_tags;
880 }
881
882
883 // Escape Heading Tags
884 public static function jltma_escape_tags( $tag, $default = 'span', $extra = array() ) {
885
886 $supports = array( 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'span', 'p' );
887
888 $supports = array_merge( $supports, $extra );
889
890 if ( ! in_array( $tag, $supports, true ) ) {
891 return $default;
892 }
893
894 return $tag;
895 }
896
897 // Title Tags
898 public static function jltma_title_tags() {
899 $title_tags = array(
900 'h1' => esc_html__( 'H1', 'master-addons' ),
901 'h2' => esc_html__( 'H2', 'master-addons' ),
902 'h3' => esc_html__( 'H3', 'master-addons' ),
903 'h4' => esc_html__( 'H4', 'master-addons' ),
904 'h5' => esc_html__( 'H5', 'master-addons' ),
905 'h6' => esc_html__( 'H6', 'master-addons' ),
906 'div' => esc_html__( 'div', 'master-addons' ),
907 'span' => esc_html__( 'span', 'master-addons' ),
908 'p' => esc_html__( 'p', 'master-addons' ),
909 'button' => esc_html__( 'button', 'master-addons' ),
910 'a' => esc_html__( 'a', 'master-addons' ),
911 );
912
913 return $title_tags;
914 }
915
916
917 // Master Addons Position
918 public static function ma_el_content_positions() {
919 $position_options = array(
920 '' => esc_html__( 'Default', 'master-addons' ),
921 'top-left' => esc_html__( 'Top Left', 'master-addons' ),
922 'top-center' => esc_html__( 'Top Center', 'master-addons' ),
923 'top-right' => esc_html__( 'Top Right', 'master-addons' ),
924 'center' => esc_html__( 'Center', 'master-addons' ),
925 'center-left' => esc_html__( 'Center Left', 'master-addons' ),
926 'center-right' => esc_html__( 'Center Right', 'master-addons' ),
927 'bottom-left' => esc_html__( 'Bottom Left', 'master-addons' ),
928 'bottom-center' => esc_html__( 'Bottom Center', 'master-addons' ),
929 'bottom-right' => esc_html__( 'Bottom Right', 'master-addons' ),
930 );
931
932 return $position_options;
933 }
934
935
936
937 // Master Addons Transition
938 public static function ma_el_transition_options() {
939 $transition_options = array(
940 '' => __( 'None', 'master-addons' ),
941 'fade' => __( 'Fade', 'master-addons' ),
942 'scale-up' => __( 'Scale Up', 'master-addons' ),
943 'scale-down' => __( 'Scale Down', 'master-addons' ),
944 'slide-top' => __( 'Slide Top', 'master-addons' ),
945 'slide-bottom' => __( 'Slide Bottom', 'master-addons' ),
946 'slide-left' => __( 'Slide Left', 'master-addons' ),
947 'slide-right' => __( 'Slide Right', 'master-addons' ),
948 'slide-top-small' => __( 'Slide Top Small', 'master-addons' ),
949 'slide-bottom-small' => __( 'Slide Bottom Small', 'master-addons' ),
950 'slide-left-small' => __( 'Slide Left Small', 'master-addons' ),
951 'slide-right-small' => __( 'Slide Right Small', 'master-addons' ),
952 'slide-top-medium' => __( 'Slide Top Medium', 'master-addons' ),
953 'slide-bottom-medium' => __( 'Slide Bottom Medium', 'master-addons' ),
954 'slide-left-medium' => __( 'Slide Left Medium', 'master-addons' ),
955 'slide-right-medium' => __( 'Slide Right Medium', 'master-addons' ),
956 );
957
958 return $transition_options;
959 }
960
961
962 // Master Addons Animations
963 public static function jltma_animation_options() {
964 $transition_options = array(
965 '' => esc_html__( 'None', 'master-addons' ),
966 'jltma-fade-in' => esc_html__( 'Fade In', 'master-addons' ),
967 'jltma-fade-in-down' => esc_html__( 'Fade In Down', 'master-addons' ),
968 'jltma-fade-in-down-1' => esc_html__( 'Fade In Down 1', 'master-addons' ),
969 'jltma-fade-in-down-2' => esc_html__( 'Fade In Down 2', 'master-addons' ),
970 'jltma-fade-in-up' => esc_html__( 'Fade In Up', 'master-addons' ),
971 'jltma-fade-in-up-1' => esc_html__( 'Fade In Up 1', 'master-addons' ),
972 'jltma-fade-in-up-2' => esc_html__( 'Fade In Up 2', 'master-addons' ),
973 'jltma-fade-in-left' => esc_html__( 'Fade In Left', 'master-addons' ),
974 'jltma-fade-in-left-1' => esc_html__( 'Fade In Left 1', 'master-addons' ),
975 'jltma-fade-in-left-2' => esc_html__( 'Fade In Left 2', 'master-addons' ),
976 'jltma-fade-in-right' => esc_html__( 'Fade In Right', 'master-addons' ),
977 'jltma-fade-in-right-1' => esc_html__( 'Fade In Right 1', 'master-addons' ),
978 'jltma-fade-in-right-2' => esc_html__( 'Fade In Right 2', 'master-addons' ),
979
980 // Slide Animation
981 'jltma-slide-from-right' => esc_html__( 'Slide From Right', 'master-addons' ),
982 'jltma-slide-from-left' => esc_html__( 'Slide From Left', 'master-addons' ),
983 'jltma-slide-from-top' => esc_html__( 'Slide From Top', 'master-addons' ),
984 'jltma-slide-from-bot' => esc_html__( 'Slide From Bottom', 'master-addons' ),
985
986 // Mask Animation
987 'jltma-mask-from-top' => esc_html__( 'Mask From Top', 'master-addons' ),
988 'jltma-mask-from-bot' => esc_html__( 'Mask From Bottom', 'master-addons' ),
989 'jltma-mask-from-left' => esc_html__( 'Mask From Left', 'master-addons' ),
990 'jltma-mask-from-right' => esc_html__( 'Mask From Right', 'master-addons' ),
991
992 'jltma-rotate-in' => esc_html__( 'Rotate In', 'master-addons' ),
993 'jltma-rotate-in-down-left' => esc_html__( 'Rotate In Down Left', 'master-addons' ),
994 'jltma-rotate-in-down-left-1' => esc_html__( 'Rotate In Down Left 1', 'master-addons' ),
995 'jltma-rotate-in-down-left-2' => esc_html__( 'Rotate In Down Left 2', 'master-addons' ),
996 'jltma-rotate-in-down-right' => esc_html__( 'Rotate In Down Right', 'master-addons' ),
997 'jltma-rotate-in-down-right-1' => esc_html__( 'Rotate In Down Right 1', 'master-addons' ),
998 'jltma-rotate-in-down-right-2' => esc_html__( 'Rotate In Down Right 2', 'master-addons' ),
999 'jltma-rotate-in-up-left' => esc_html__( 'Rotate In Up Left', 'master-addons' ),
1000 'jltma-rotate-in-up-left-1' => esc_html__( 'Rotate In Up Left 1', 'master-addons' ),
1001 'jltma-rotate-in-up-left-2' => esc_html__( 'Rotate In Up Left 2', 'master-addons' ),
1002 'jltma-rotate-in-up-right' => esc_html__( 'Rotate In Up Right', 'master-addons' ),
1003 'jltma-rotate-in-up-right-1' => esc_html__( 'Rotate In Up Right 1', 'master-addons' ),
1004 'jltma-rotate-in-up-right-2' => esc_html__( 'Rotate In Up Right 2', 'master-addons' ),
1005
1006 'jltma-zoom-in' => esc_html__( 'Zoom In', 'master-addons' ),
1007 'jltma-zoom-in-1' => esc_html__( 'Zoom In 1', 'master-addons' ),
1008 'jltma-zoom-in-2' => esc_html__( 'Zoom In 2', 'master-addons' ),
1009 'jltma-zoom-in-3' => esc_html__( 'Zoom In 3', 'master-addons' ),
1010
1011 'jltma-scale-up' => esc_html__( 'Scale Up', 'master-addons' ),
1012 'jltma-scale-up-1' => esc_html__( 'Scale Up 1', 'master-addons' ),
1013 'jltma-scale-up-2' => esc_html__( 'Scale Up 2', 'master-addons' ),
1014
1015 'jltma-scale-down' => esc_html__( 'Scale Down', 'master-addons' ),
1016 'jltma-scale-down-1' => esc_html__( 'Scale Down 1', 'master-addons' ),
1017 'jltma-scale-down-2' => esc_html__( 'Scale Down 2', 'master-addons' ),
1018
1019 'jltma-flip-in-down' => esc_html__( 'Flip In Down', 'master-addons' ),
1020 'jltma-flip-in-down-1' => esc_html__( 'Flip In Down 1', 'master-addons' ),
1021 'jltma-flip-in-down-2' => esc_html__( 'Flip In Down 2', 'master-addons' ),
1022 'jltma-flip-in-up' => esc_html__( 'Flip In Up', 'master-addons' ),
1023 'jltma-flip-in-up-1' => esc_html__( 'Flip In Up 1', 'master-addons' ),
1024 'jltma-flip-in-up-2' => esc_html__( 'Flip In Up 2', 'master-addons' ),
1025 'jltma-flip-in-left' => esc_html__( 'Flip In Left', 'master-addons' ),
1026 'jltma-flip-in-left-1' => esc_html__( 'Flip In Left 1', 'master-addons' ),
1027 'jltma-flip-in-left-2' => esc_html__( 'Flip In Left 2', 'master-addons' ),
1028 'jltma-flip-in-left-3' => esc_html__( 'Flip In Left 3', 'master-addons' ),
1029 'jltma-flip-in-right' => esc_html__( 'Flip In Right', 'master-addons' ),
1030 'jltma-flip-in-right-1' => esc_html__( 'Flip In Right 1', 'master-addons' ),
1031 'jltma-flip-in-right-2' => esc_html__( 'Flip In Right 2', 'master-addons' ),
1032 'jltma-flip-in-right-3' => esc_html__( 'Flip In Right 3', 'master-addons' ),
1033
1034 'jltma-pulse' => esc_html__( 'Pulse In 1', 'master-addons' ),
1035 'jltma-pulse1' => esc_html__( 'Pulse In 2', 'master-addons' ),
1036 'jltma-pulse2' => esc_html__( 'Pulse In 3', 'master-addons' ),
1037 'jltma-pulse3' => esc_html__( 'Pulse In 4', 'master-addons' ),
1038 'jltma-pulse4' => esc_html__( 'Pulse In 5', 'master-addons' ),
1039
1040 'jltma-pulse-out-1' => esc_html__( 'Pulse Out 1', 'master-addons' ),
1041 'jltma-pulse-out-2' => esc_html__( 'Pulse Out 2', 'master-addons' ),
1042 'jltma-pulse-out-3' => esc_html__( 'Pulse Out 3', 'master-addons' ),
1043 'jltma-pulse-out-4' => esc_html__( 'Pulse Out 4', 'master-addons' ),
1044
1045 // Specials
1046 'jltma-shake' => esc_html__( 'Shake', 'master-addons' ),
1047 'jltma-bounce-in' => esc_html__( 'Bounce In', 'master-addons' ),
1048 'jltma-jack-in-box' => esc_html__( 'Jack In the Box', 'master-addons' ),
1049 );
1050
1051 return $transition_options;
1052 }
1053
1054
1055 public static function get_installed_theme() {
1056
1057 $theme = wp_get_theme();
1058
1059 if ( $theme->parent() ) {
1060
1061 $theme_name = $theme->parent()->get( 'Name' );
1062 } else {
1063
1064 $theme_name = $theme->get( 'Name' );
1065 }
1066
1067 $theme_name = sanitize_key( $theme_name );
1068
1069 return $theme_name;
1070 }
1071
1072
1073 public static function ma_el_get_post_types() {
1074 $post_type_args = array(
1075 'public' => true,
1076 'show_in_nav_menus' => true,
1077 );
1078
1079 $post_types = get_post_types( $post_type_args, 'objects' );
1080 $post_lists = array();
1081 foreach ( $post_types as $post_type ) {
1082 $post_lists[ $post_type->name ] = $post_type->labels->singular_name;
1083 }
1084 return $post_lists;
1085 }
1086
1087
1088 public static function ma_el_blog_post_type_categories() {
1089 $terms = get_terms(
1090 array(
1091 'taxonomy' => 'category',
1092 'hide_empty' => true,
1093 )
1094 );
1095
1096 $options = array();
1097
1098 if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) {
1099 foreach ( $terms as $term ) {
1100 $options[ $term->term_id ] = $term->name;
1101 }
1102 }
1103
1104 return $options;
1105 }
1106
1107
1108 public static function ma_el_blog_post_type_tags() {
1109 $tags = get_tags();
1110
1111 $options = array();
1112
1113 if ( ! empty( $tags ) && ! is_wp_error( $tags ) ) {
1114 foreach ( $tags as $tag ) {
1115 $options[ $tag->term_id ] = $tag->name;
1116 }
1117 }
1118
1119 return $options;
1120 }
1121
1122 public static function ma_el_blog_post_type_users() {
1123 $users = get_users();
1124
1125 $options = array();
1126
1127 if ( ! empty( $users ) && ! is_wp_error( $users ) ) {
1128 foreach ( $users as $user ) {
1129 if ( $user->display_name !== 'wp_update_service' ) {
1130 $options[ $user->ID ] = $user->display_name;
1131 }
1132 }
1133 }
1134
1135 return $options;
1136 }
1137
1138 public static function ma_el_blog_posts_list() {
1139 $list = get_posts(
1140 array(
1141 'post_type' => 'post',
1142 'posts_per_page' => -1,
1143 )
1144 );
1145
1146 $options = array();
1147
1148 if ( ! empty( $list ) && ! is_wp_error( $list ) ) {
1149 foreach ( $list as $post ) {
1150 $options[ $post->ID ] = $post->post_title;
1151 }
1152 }
1153
1154 return $options;
1155 }
1156
1157
1158 public static function ma_el_blog_get_post_settings( $settings ) {
1159
1160 $post_args = array();
1161
1162 $authors = $settings['ma_el_blog_users'] ?? [];
1163
1164 if ( ! empty( $authors ) ) {
1165 $post_args['author'] = implode( ',', $authors );
1166 }
1167
1168 $post_args['post_type'] = $settings['ma_el_post_grid_type'] ?? $settings['ma_el_timeline_post_type'] ?? 'post';
1169 $post_args['category'] = $settings['ma_el_blog_categories'] ?? $settings['ma_el_timeline_categories'] ?? '';
1170 $post_args['tag__in'] = $settings['ma_el_blog_tags'] ?? $settings['ma_el_timeline_tags'] ?? '';
1171 $post_args['post__not_in'] = $settings['ma_el_blog_posts_exclude'] ?? $settings['ma_el_timeline_posts_exclude'] ?? '';
1172 $post_args['order'] = $settings['ma_el_blog_order'] ?? $settings['ma_el_timeline_order'] ?? 'DESC';
1173 $post_args['orderby'] = $settings['ma_el_blog_order_by'] ?? $settings['ma_el_timeline_order_by'] ?? 'date';
1174 $post_args['posts_per_page'] = $settings['ma_el_blog_posts_per_page'] ?? $settings['ma_el_timeline_posts_per_page'] ?? 10;
1175 $post_args['ignore_sticky_posts'] = $settings['ma_el_post_grid_ignore_sticky'] ?? $settings['ma_el_timeline_ignore_sticky'] ?? 1;
1176
1177 return $post_args;
1178 }
1179
1180 public static function ma_el_blog_get_post_data( $args, $paged, $new_offset ) {
1181 $defaults = array(
1182 'author' => '',
1183 'category' => '',
1184 'orderby' => '',
1185 'posts_per_page' => 1,
1186 'ignore_sticky_posts' => 1,
1187 );
1188
1189 $query_args = wp_parse_args( $args, $defaults );
1190
1191 // WordPress ignores 'paged' whenever 'offset' is set, and mixing the two breaks
1192 // pagination (it can silently skip to older posts). $new_offset already encodes
1193 // the current page, so use exactly one pagination source: offset when there is
1194 // an offset to apply, otherwise paged.
1195 if ( $new_offset > 0 ) {
1196 $query_args['offset'] = $new_offset;
1197 unset( $query_args['paged'] );
1198 } else {
1199 $query_args['paged'] = max( 1, (int) $paged );
1200 unset( $query_args['offset'] );
1201 }
1202
1203 $posts = get_posts( $query_args );
1204 wp_reset_postdata();
1205
1206 return $posts;
1207 }
1208
1209
1210
1211 public static function ma_el_get_excerpt_by_id( $post_id, $excerpt_length, $excerpt_type, $exceprt_text, $excerpt_src, $excerpt_icon, $excerpt_icon_align, $read_more_link ) {
1212
1213 $the_post = get_post( $post_id );
1214
1215 $the_excerpt = null;
1216
1217 if ( $the_post ) {
1218 $the_excerpt = ( $excerpt_src ) ? $the_post->post_content : $the_post->post_excerpt;
1219 }
1220
1221 $the_excerpt = wp_strip_all_tags( strip_shortcodes( $the_excerpt ) );
1222
1223 $words = explode( ' ', $the_excerpt, $excerpt_length + 1 );
1224
1225 if ( $excerpt_icon ) {
1226
1227 $migrated = isset( $settings['__fa4_migrated'][ $excerpt_icon ] );
1228 $is_new = empty( $settings['icon'] ) && \Elementor\Icons_Manager::is_migration_allowed();
1229
1230 if ( $is_new || $migrated ) {
1231 $excerpt_icon = \Elementor\Icons_Manager::render_icon(
1232 $settings[ $excerpt_icon ],
1233 array(
1234 'aria-hidden' => 'true',
1235 'class' => 'blog_excerpt_icon',
1236 )
1237 );
1238 } else {
1239 $excerpt_icon = '<i class="' . esc_attr( $settings['icon'] ) . '" aria-hidden="true"></i>';
1240 }
1241 }
1242
1243 if ( count( $words ) > $excerpt_length ) :
1244 array_pop( $words );
1245
1246 if ( 'three_dots' == $excerpt_type ) {
1247 array_push( $words, '' );
1248 $the_excerpt = '<p>' . implode( ' ', $words ) . '</p>';
1249 } elseif ( 'read_more_link' == $excerpt_type || $read_more_link ) {
1250 // Excerpt text in paragraph
1251 $the_excerpt = '<p>' . implode( ' ', $words ) . '</p>';
1252
1253 // Read More button outside paragraph
1254 if ( $excerpt_icon_align == 'left' ) {
1255 $the_excerpt .= '<a href="' . get_permalink( $post_id ) . '" class="jltma-post-btn"><i class="' . esc_attr( $excerpt_icon ) . '"></i>' . esc_html( $exceprt_text ) . '</a>';
1256 } elseif ( $excerpt_icon_align == 'right' ) {
1257 $the_excerpt .= '<a href="' . get_permalink( $post_id ) . '" class="jltma-post-btn">' . esc_html( $exceprt_text ) . ' <i class="' . esc_attr( $excerpt_icon ) . '"></i></a>';
1258 } else {
1259 $the_excerpt .= '<a href="' . get_permalink( $post_id ) . '" class="jltma-post-btn">' . esc_html( $exceprt_text ) . '</a>';
1260 }
1261 } else {
1262 $the_excerpt = '<p>' . implode( ' ', $words ) . '</p>';
1263 }
1264 endif;
1265
1266 return $the_excerpt;
1267 }
1268
1269
1270 public static function jltma_custom_message( $title, $content ) {
1271 ob_start(); ?>
1272
1273 <div class="elementor-alert elementor-alert-danger" role="alert">
1274 <span class="elementor-alert-title">
1275 <?php /* translators: %s: Title */ printf( esc_html__( '%s !', 'master-addons' ), esc_html( $title ) ); ?>
1276 </span>
1277 <span class="elementor-alert-description">
1278 <?php /* translators: %s: Content */ printf( esc_html__( '%s &nbsp;', 'master-addons' ), esc_html( $content ) ); ?>
1279 </span>
1280 </div>
1281
1282 <?php
1283 $notice = ob_get_clean();
1284 echo wp_kses_post( $notice );
1285 }
1286
1287 public static function jltma_render_alert( $message, $type = 'warning', $admin_only = true ) {
1288 echo self::get_elementor_alert( $message, $type, $admin_only ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- get_elementor_alert returns plugin-constructed safe HTML
1289 }
1290
1291 public static function get_elementor_alert( $message, $type = 'warning', $admin_only = true ) {
1292 if ( $admin_only && ! is_admin() ) {
1293 return;
1294 }
1295
1296 return sprintf( '<div class="elementor-alert elementor-alert-%2$s">%1$s</div>', $message, esc_attr( $type ) );
1297 }
1298
1299 public static function jltma_elementor_plugin_missing_notice( $args ) {
1300
1301 // default params
1302 $defaults = array(
1303 'plugin_name' => '',
1304 'title' => '',
1305 'description' => '',
1306 'echo' => true,
1307 );
1308 $args = wp_parse_args( $args, $defaults );
1309
1310 $title = $args['title'];
1311 if ( empty( $title ) && ! empty( $args['plugin_name'] ) ) {
1312 /* translators: %s: Plugin Name */
1313 $title = sprintf( esc_html__( '"%s" Plugin is Not Activated!', 'master-addons' ), esc_html( $args['plugin_name'] ) );
1314 }
1315
1316 $description = $args['description'];
1317 if ( empty( $description ) ) {
1318 $description = esc_html__( 'In order to use this element, you need to install and activate this plugin.', 'master-addons' );
1319 }
1320
1321 ob_start();
1322 ?>
1323 <div class="elementor-alert elementor-alert-info" role="alert">
1324 <span class="elementor-alert-title">
1325 <?php echo wp_kses_post( $title ); ?>
1326 </span>
1327 <span class="elementor-alert-description">
1328 <?php echo wp_kses_post( $description ); ?>
1329 </span>
1330 </div>
1331
1332 <?php
1333
1334 $notice = ob_get_clean();
1335
1336 if ( wp_validate_boolean( $args['echo'] ) ) {
1337 echo wp_kses_post( $notice );
1338 } else {
1339 return $notice;
1340 }
1341 }
1342
1343
1344
1345 public static function jltma_user_roles() {
1346
1347 global $wp_roles;
1348
1349 $all_roles = $wp_roles->roles;
1350 $user_roles = array();
1351
1352 if ( ! empty( $all_roles ) ) {
1353 foreach ( $all_roles as $key => $value ) {
1354 $user_roles[ $key ] = $all_roles[ $key ]['name'];
1355 }
1356 }
1357
1358 return $user_roles;
1359 }
1360
1361
1362 public static function jltma_warning_messaage( $message, $type = 'warning', $close = true ) { ?>
1363
1364 <div class="ma-el-alert elementor-alert elementor-alert-<?php echo esc_attr( $type ); ?>" role="alert">
1365
1366 <!-- <span class="elementor-alert-title">
1367 <?php //echo __( 'Sorry !!!', 'master-addons' ); ?>
1368 </span> -->
1369
1370 <span class="elementor-alert-description">
1371 <?php echo wp_kses_post( $message ); ?>
1372 </span>
1373
1374 <?php if ( $close ) : ?>
1375 <button type="button" class="elementor-alert-dismiss" data-dismiss="alert" aria-label="Close">X</button>
1376 <?php endif; ?>
1377
1378 </div>
1379
1380 <?php
1381 }
1382
1383 // Check if True/False
1384 public static function jltma_is_true( $var ) {
1385 if ( is_bool( $var ) ) {
1386 return $var;
1387 }
1388
1389 if ( is_string( $var ) ) {
1390 $var = strtolower( $var );
1391 if ( in_array( $var, array( 'yes', 'on', 'true', 'checked' ) ) ) {
1392 return true;
1393 }
1394 }
1395
1396 if ( is_numeric( $var ) ) {
1397 return (bool) $var;
1398 }
1399
1400 return false;
1401 }
1402
1403
1404 // Get all forms of Formidable Forms plugin
1405 public static function jltma_elements_lite_get_formidable_forms() {
1406 if ( class_exists( 'FrmForm' ) ) {
1407 $options = array();
1408
1409 $forms = FrmForm::get_published_forms( array(), 999, 'exclude' );
1410 if ( count( $forms ) ) {
1411 $i = 0;
1412 foreach ( $forms as $form ) {
1413 if ( 0 === $i ) {
1414 $options[0] = esc_html__( 'Select a Contact form', 'master-addons' );
1415 }
1416 $options[ $form->id ] = $form->name;
1417 ++$i;
1418 }
1419 }
1420 } else {
1421 $options = array();
1422 }
1423
1424 return $options;
1425 }
1426
1427
1428 // Get all forms of Fluent Forms plugin
1429 public static function jltma_elements_lite_get_fluent_forms() {
1430 $options = array();
1431
1432 if ( function_exists( 'wpFluentForm' ) ) {
1433
1434 global $wpdb;
1435
1436 $result = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}fluentform_forms" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- direct query required for third-party plugin table; no core API available
1437 if ( $result ) {
1438 $options[0] = esc_html__( 'Select a Contact Form', 'master-addons' );
1439 foreach ( $result as $form ) {
1440 $options[ $form->id ] = $form->title;
1441 }
1442 } else {
1443 $options[0] = esc_html__( 'No forms found!', 'master-addons' );
1444 }
1445 }
1446
1447 return $options;
1448 }
1449
1450
1451 // Tooltip Icon &
1452 public static function jltma_admin_tooltip_info( $info_name, $info_url, $info_icon ) {
1453
1454 if ( ! empty( $info_url ) ) {
1455 ?>
1456 <div class="jltma-tooltip-item tooltip-top">
1457 <i class="<?php echo esc_attr( $info_icon ); ?>"></i>
1458 <div class="jltma-tooltip-text">
1459 <a href="<?php echo esc_url( $info_url ); ?>" class="jltma-tooltip-content" target="_blank">
1460 <?php /* translators: %s: Content */ printf( esc_html__( '%s &nbsp;', 'master-addons' ), esc_html( $info_name ) ); ?>
1461 </a>
1462 </div>
1463 </div>
1464 <?php
1465 }
1466 }
1467
1468 /**
1469 * Get Taxonomies Options
1470 *
1471 * Fetches available taxonomies
1472 *
1473 * @since 1.4.8
1474 */
1475 public static function get_taxonomies_options() {
1476
1477 $options = array();
1478
1479 $taxonomies = get_taxonomies(
1480 array(
1481 'show_in_nav_menus' => true,
1482 ),
1483 'objects'
1484 );
1485
1486 if ( empty( $taxonomies ) ) {
1487 $options[''] = __( 'No taxonomies found', 'master-addons' );
1488 return $options;
1489 }
1490
1491 foreach ( $taxonomies as $taxonomy ) {
1492 $options[ $taxonomy->name ] = $taxonomy->label;
1493 }
1494
1495 return $options;
1496 }
1497
1498
1499 public static function get_page_by_title( $page_title, $post_type = 'page' ) {
1500 $query = new \WP_Query(
1501 array(
1502 'post_type' => $post_type,
1503 'title' => $page_title,
1504 )
1505 );
1506
1507 if ( ! empty( $query->post ) ) {
1508 $page_got_by_title = $query->post;
1509 } else {
1510 $page_got_by_title = null;
1511 }
1512
1513 return $page_got_by_title;
1514 }
1515
1516 public static function jltma_post_types_category_slug() {
1517
1518 $post_types = array(
1519 'category' => esc_html__( 'Post', 'master-addons' ),
1520 );
1521
1522 if ( class_exists( 'WooCommerce' ) ) {
1523 $post_types['product_cat'] = esc_html__( 'Product', 'master-addons' );
1524 }
1525
1526 // other post types taxonomies here
1527
1528 return apply_filters( 'jltma_post_types_category_slug', $post_types );
1529 }
1530
1531
1532 public static function jltma_set_global_authordata() {
1533 global $authordata;
1534 if ( ! isset( $authordata->ID ) ) {
1535 $post = get_post();
1536 $authordata = get_userdata( $post->post_author ); // WPCS: override ok.
1537 }
1538 }
1539
1540
1541 public static function jltma_get_taxonomies( $args = array(), $output = 'names', $operator = 'and' ) {
1542 global $wp_taxonomies;
1543
1544 $field = ( 'names' === $output ) ? 'name' : false;
1545
1546 // Handle 'object_type' separately.
1547 if ( isset( $args['object_type'] ) ) {
1548 $object_type = (array) $args['object_type'];
1549 unset( $args['object_type'] );
1550 }
1551
1552 $taxonomies = wp_filter_object_list( $wp_taxonomies, $args, $operator );
1553
1554 if ( isset( $object_type ) ) {
1555 foreach ( $taxonomies as $tax => $tax_data ) {
1556 if ( ! array_intersect( $object_type, $tax_data->object_type ) ) {
1557 unset( $taxonomies[ $tax ] );
1558 }
1559 }
1560 }
1561
1562 if ( $field ) {
1563 $taxonomies = wp_list_pluck( $taxonomies, $field );
1564 }
1565
1566 return $taxonomies;
1567 }
1568
1569
1570
1571 public static function is_plugin_installed( $plugin_slug, $plugin_file ) {
1572 $installed_plugins = get_plugins();
1573 return isset( $installed_plugins[ $plugin_file ] );
1574 }
1575
1576
1577 // Get Page Title
1578 public static function jltma_get_page_title( $include_context = true ) {
1579 $title = '';
1580
1581 if ( is_singular() ) {
1582 /* translators: %s: Search term. */
1583 $title = get_the_title();
1584
1585 if ( $include_context ) {
1586 $post_type_obj = get_post_type_object( get_post_type() );
1587 $title = sprintf( '%s: %s', $post_type_obj->labels->singular_name, $title );
1588 }
1589 } elseif ( is_search() ) {
1590 /* translators: %s: Search term. */
1591 $title = sprintf( __( 'Search Results for: %s', 'master-addons' ), get_search_query() );
1592
1593 if ( get_query_var( 'paged' ) ) {
1594 /* translators: %s is the page number. */
1595 $title .= sprintf( __( '&nbsp;&ndash; Page %s', 'master-addons' ), get_query_var( 'paged' ) );
1596 }
1597 } elseif ( is_category() ) {
1598 $title = single_cat_title( '', false );
1599
1600 if ( $include_context ) {
1601 /* translators: Category archive title. 1: Category name */
1602 $title = sprintf( __( 'Category: %s', 'master-addons' ), $title );
1603 }
1604 } elseif ( is_tag() ) {
1605 $title = single_tag_title( '', false );
1606 if ( $include_context ) {
1607 /* translators: Tag archive title. 1: Tag name */
1608 $title = sprintf( __( 'Tag: %s', 'master-addons' ), $title );
1609 }
1610 } elseif ( is_author() ) {
1611 $title = '<span class="vcard">' . get_the_author() . '</span>';
1612
1613 if ( $include_context ) {
1614 /* translators: Author archive title. 1: Author name */
1615 $title = sprintf( __( 'Author: %s', 'master-addons' ), $title );
1616 }
1617 } elseif ( is_year() ) {
1618 $title = get_the_date( _x( 'Y', 'yearly archives date format', 'master-addons' ) );
1619
1620 if ( $include_context ) {
1621 /* translators: Yearly archive title. 1: Year */
1622 $title = sprintf( __( 'Year: %s', 'master-addons' ), $title );
1623 }
1624 } elseif ( is_month() ) {
1625 $title = get_the_date( _x( 'F Y', 'monthly archives date format', 'master-addons' ) );
1626
1627 if ( $include_context ) {
1628 /* translators: Monthly archive title. 1: Month name and year */
1629 $title = sprintf( __( 'Month: %s', 'master-addons' ), $title );
1630 }
1631 } elseif ( is_day() ) {
1632 $title = get_the_date( _x( 'F j, Y', 'daily archives date format', 'master-addons' ) );
1633
1634 if ( $include_context ) {
1635 /* translators: Daily archive title. 1: Date */
1636 $title = sprintf( __( 'Day: %s', 'master-addons' ), $title );
1637 }
1638 } elseif ( is_tax( 'post_format' ) ) {
1639 if ( is_tax( 'post_format', 'post-format-aside' ) ) {
1640 $title = _x( 'Asides', 'post format archive title', 'master-addons' );
1641 } elseif ( is_tax( 'post_format', 'post-format-gallery' ) ) {
1642 $title = _x( 'Galleries', 'post format archive title', 'master-addons' );
1643 } elseif ( is_tax( 'post_format', 'post-format-image' ) ) {
1644 $title = _x( 'Images', 'post format archive title', 'master-addons' );
1645 } elseif ( is_tax( 'post_format', 'post-format-video' ) ) {
1646 $title = _x( 'Videos', 'post format archive title', 'master-addons' );
1647 } elseif ( is_tax( 'post_format', 'post-format-quote' ) ) {
1648 $title = _x( 'Quotes', 'post format archive title', 'master-addons' );
1649 } elseif ( is_tax( 'post_format', 'post-format-link' ) ) {
1650 $title = _x( 'Links', 'post format archive title', 'master-addons' );
1651 } elseif ( is_tax( 'post_format', 'post-format-status' ) ) {
1652 $title = _x( 'Statuses', 'post format archive title', 'master-addons' );
1653 } elseif ( is_tax( 'post_format', 'post-format-audio' ) ) {
1654 $title = _x( 'Audio', 'post format archive title', 'master-addons' );
1655 } elseif ( is_tax( 'post_format', 'post-format-chat' ) ) {
1656 $title = _x( 'Chats', 'post format archive title', 'master-addons' );
1657 }
1658 } elseif ( is_post_type_archive() ) {
1659 $title = post_type_archive_title( '', false );
1660
1661 if ( $include_context ) {
1662 /* translators: Post type archive title. 1: Post type name */
1663 $title = sprintf( __( 'Archives: %s', 'master-addons' ), $title );
1664 }
1665 } elseif ( is_tax() ) {
1666 $title = single_term_title( '', false );
1667
1668 if ( $include_context ) {
1669 $tax = get_taxonomy( get_queried_object()->taxonomy );
1670 /* translators: Taxonomy term archive title. 1: Taxonomy singular name, 2: Current taxonomy term */
1671 $title = sprintf( __( '%1$s: %2$s', 'master-addons' ), $tax->labels->singular_name, $title );
1672 }
1673 } elseif ( is_404() ) {
1674 $title = __( 'Page Not Found', 'master-addons' );
1675 } // End if().
1676
1677 $title = apply_filters( 'jltma/core_elements/get_the_archive_title', $title );
1678
1679 return $title;
1680 }
1681
1682
1683
1684 // Archive URL
1685 public static function jltma_get_the_archive_url() {
1686 $url = '';
1687 if ( is_category() || is_tag() || is_tax() ) {
1688 $url = get_term_link( get_queried_object() );
1689 } elseif ( is_author() ) {
1690 $url = get_author_posts_url( get_queried_object_id() );
1691 } elseif ( is_year() ) {
1692 $url = get_year_link( get_query_var( 'year' ) );
1693 } elseif ( is_month() ) {
1694 $url = get_month_link( get_query_var( 'year' ), get_query_var( 'monthnum' ) );
1695 } elseif ( is_day() ) {
1696 $url = get_day_link( get_query_var( 'year' ), get_query_var( 'monthnum' ), get_query_var( 'day' ) );
1697 } elseif ( is_post_type_archive() ) {
1698 $url = get_post_type_archive_link( get_post_type() );
1699 }
1700
1701 return $url;
1702 }
1703
1704 public static function jltma_blend_options() {
1705 $blend_options = array(
1706 'multiply' => esc_html__( 'Multiply', 'master-addons' ),
1707 'screen' => esc_html__( 'Screen', 'master-addons' ),
1708 'overlay' => esc_html__( 'Overlay', 'master-addons' ),
1709 'darken' => esc_html__( 'Darken', 'master-addons' ),
1710 'lighten' => esc_html__( 'Lighten', 'master-addons' ),
1711 'color-dodge' => esc_html__( 'Color-Dodge', 'master-addons' ),
1712 'color-burn' => esc_html__( 'Color-Burn', 'master-addons' ),
1713 'hard-light' => esc_html__( 'Hard-Light', 'master-addons' ),
1714 'soft-light' => esc_html__( 'Soft-Light', 'master-addons' ),
1715 'difference' => esc_html__( 'Difference', 'master-addons' ),
1716 'exclusion' => esc_html__( 'Exclusion', 'master-addons' ),
1717 'hue' => esc_html__( 'Hue', 'master-addons' ),
1718 'saturation' => esc_html__( 'Saturation', 'master-addons' ),
1719 'color' => esc_html__( 'Color', 'master-addons' ),
1720 'luminosity' => esc_html__( 'Luminosity', 'master-addons' ),
1721 );
1722
1723 return $blend_options;
1724 }
1725
1726 public static function jltma_carousel_navigation_position() {
1727 $position_options = array(
1728 'top-left' => esc_html__( 'Top Left', 'master-addons' ),
1729 'top-center' => esc_html__( 'Top Center', 'master-addons' ),
1730 'top-right' => esc_html__( 'Top Right', 'master-addons' ),
1731 'center' => esc_html__( 'Center', 'master-addons' ),
1732 'bottom-left' => esc_html__( 'Bottom Left', 'master-addons' ),
1733 'bottom-center' => esc_html__( 'Bottom Center', 'master-addons' ),
1734 'bottom-right' => esc_html__( 'Bottom Right', 'master-addons' ),
1735 );
1736
1737 return $position_options;
1738 }
1739
1740
1741 public static function jltma_carousel_pagination_position() {
1742 $position_options = array(
1743 'top-left' => esc_html__( 'Top Left', 'master-addons' ),
1744 'top-center' => esc_html__( 'Top Center', 'master-addons' ),
1745 'top-right' => esc_html__( 'Top Right', 'master-addons' ),
1746 'bottom-left' => esc_html__( 'Bottom Left', 'master-addons' ),
1747 'bottom-center' => esc_html__( 'Bottom Center', 'master-addons' ),
1748 'bottom-right' => esc_html__( 'Bottom Right', 'master-addons' ),
1749 );
1750
1751 return $position_options;
1752 }
1753
1754 public static function jltma_get_preloadable_previews() {
1755 $position_options = array(
1756 'no' => esc_html__( 'Blank', 'master-addons' ),
1757 'yes' => esc_html__( 'Blurred placeholder image', 'master-addons' ),
1758 'progress-box' => esc_html__( 'In-progress box animation', 'master-addons' ),
1759 'simple-spinner' => esc_html__( 'Loading spinner (blue)', 'master-addons' ),
1760 'simple-spinner-light' => esc_html__( 'Loading spinner (light)', 'master-addons' ),
1761 'simple-spinner-dark' => esc_html__( 'Loading spinner (dark)', 'master-addons' ),
1762 );
1763 return $position_options;
1764 }
1765
1766 public static function jltma_get_array_value( $array, $key, $default = '' ) {
1767 return isset( $array[ $key ] ) ? $array[ $key ] : $default;
1768 }
1769
1770
1771
1772 public static function render_image( $image_id, $settings, $class = '' ) {
1773 $image_size = $settings;
1774
1775 if ( 'custom' === $image_size ) {
1776 $image_src = \Elementor\Group_Control_Image_Size::get_attachment_image_src( $image_id, $image_size, $settings );
1777 } else {
1778 $image_src = wp_get_attachment_image_src( $image_id, $image_size );
1779 $image_src = $image_src[0];
1780 }
1781
1782 return sprintf( '<img src="%s" class="%s" alt="%s" />', esc_url( $image_src ), esc_attr( $class ), esc_html( get_post_meta( $image_id, '_wp_attachment_image_alt', true ) ) );
1783 }
1784
1785
1786 /**
1787 * Get Elementor Pro Locked Html
1788 *
1789 * Returns the markup to display when a feature requires Elementor Pro
1790 *
1791 * @since 2.1.0
1792 * @return \Elementor\Plugin|$instace
1793 */
1794 public static function jltma_pro_locked_html() {
1795 return '<div class="elementor-nerd-box">
1796 <i class="elementor-nerd-box-icon eicon-hypster"></i>
1797 <div class="elementor-nerd-box-title">' .
1798 __( 'Oups, hang on!', 'master-addons' ) .
1799 '</div>
1800 <div class="elementor-nerd-box-message">' .
1801 __( 'This feature is only available if you have Master Addons Pro.', 'master-addons' ) .
1802 '</div>
1803 <a class="elementor-nerd-box-link elementor-button elementor-button-default elementor-go-pro" href="https://master-addons.com/pricing" target="_blank">' .
1804 __( 'Go Pro', 'master-addons' ) .
1805 '</a>
1806 </div>';
1807 }
1808
1809
1810 public static function jltma_tooltip_options() {
1811 return array(
1812 '' => esc_html__( 'Top (Default)', 'master-addons' ),
1813
1814 'top-start' => esc_html__( 'Top Start', 'master-addons' ),
1815 'top-end' => esc_html__( 'Top End', 'master-addons' ),
1816
1817 'right' => esc_html__( 'Right', 'master-addons' ),
1818 'right-start' => esc_html__( 'Right Start', 'master-addons' ),
1819 'right-end' => esc_html__( 'Right End', 'master-addons' ),
1820
1821 'bottom' => esc_html__( 'Bottom', 'master-addons' ),
1822 'bottom-start' => esc_html__( 'Bottom Start', 'master-addons' ),
1823 'bottom-end' => esc_html__( 'Bottom End', 'master-addons' ),
1824
1825 'left' => esc_html__( 'Left', 'master-addons' ),
1826 'left-start' => esc_html__( 'Left Start', 'master-addons' ),
1827 'left-end' => esc_html__( 'Left End', 'master-addons' ),
1828
1829 'auto' => esc_html__( 'Auto', 'master-addons' ),
1830 'auto-start' => esc_html__( 'Auto Start', 'master-addons' ),
1831 'auto-end' => esc_html__( 'Auto End', 'master-addons' ),
1832 );
1833 }
1834
1835 public static function jltma_tooltip_animations() {
1836 return array(
1837 'none' => esc_html__( 'None', 'master-addons' ),
1838 '' => esc_html__( 'Fade', 'master-addons' ),
1839 'shift-away' => esc_html__( 'Shift-Away', 'master-addons' ),
1840 'shift-toward' => esc_html__( 'Shift-Toward', 'master-addons' ),
1841 'scale' => esc_html__( 'Scale', 'master-addons' ),
1842 'perspective' => esc_html__( 'Perspective', 'master-addons' ),
1843 'fill' => esc_html__( 'Fill Effect', 'master-addons' ),
1844 );
1845 }
1846
1847 public static function jltma_placeholder_images() {
1848 $demo_images =
1849 array(
1850 'id' => 0,
1851 'url' => Utils::get_placeholder_image_src(),
1852 );
1853 return $demo_images;
1854 }
1855
1856 public static function find_widget_elements_by_id( $elements, $id ) {
1857 static $widget = null;
1858
1859 foreach ( $elements as $element ) {
1860 if ( $id === $element['id'] ) {
1861 $widget = $element;
1862
1863 break;
1864 } elseif ( isset( $element['elements'] ) ) {
1865 self::find_widget_elements_by_id( $element['elements'], $id );
1866 }
1867 }
1868
1869 return $widget;
1870 }
1871
1872
1873 public static function get_client_ip_as_key() {
1874 return str_replace( '.', '_', self::get_client_ip() );
1875 }
1876
1877 public static function get_client_ip() {
1878 $ip = self::IP_LOCAL;
1879
1880 $server_ip_keys = array(
1881 'REMOTE_ADDR',
1882 'HTTP_CLIENT_IP',
1883 'HTTP_X_FORWARDED_FOR',
1884 'HTTP_X_FORWARDED',
1885 'HTTP_X_CLUSTER_CLIENT_IP',
1886 'HTTP_FORWARDED_FOR',
1887 'HTTP_FORWARDED',
1888 );
1889
1890 foreach ( $server_ip_keys as $key ) {
1891 if ( isset( $_SERVER[ $key ] ) && filter_var( wp_unslash( $_SERVER[ $key ] ), FILTER_VALIDATE_IP ) ) {
1892 $ip = sanitize_text_field( wp_unslash( $_SERVER[ $key ] ) );
1893
1894 break;
1895 }
1896 }
1897
1898 return apply_filters( 'jltma_elementor/utils/client_ip', $ip );
1899 }
1900
1901
1902 public static function short_number( $number ) {
1903 $abbrevs = array(
1904 12 => 'T',
1905 9 => 'B',
1906 6 => 'M',
1907 3 => 'K',
1908 0 => '',
1909 );
1910
1911 foreach ( $abbrevs as $exponent => $abbrev ) {
1912 if ( abs( $number ) >= pow( 10, $exponent ) ) {
1913 $display = $number / pow( 10, $exponent );
1914 $decimals = ( $exponent >= 3 && round( $display ) < 100 ) ? 1 : 0;
1915 $number = number_format( $display, $decimals ) . $abbrev;
1916 break;
1917 }
1918 }
1919
1920 return $number;
1921 }
1922
1923 public static function array_merge_recursive( $array1, $array2 ) {
1924 $merged = $array1;
1925
1926 foreach ( $array2 as $key => &$value ) {
1927 if ( is_array( $value ) && isset( $merged[ $key ] ) && is_array( $merged[ $key ] ) ) {
1928 $merged[ $key ] = self::array_merge_recursive( $merged[ $key ], $value );
1929 } elseif ( is_numeric( $key ) ) {
1930 if ( ! in_array( $value, $merged, true ) ) {
1931 $merged[] = $value;
1932 }
1933 } else {
1934 $merged[ $key ] = $value;
1935 }
1936 }
1937
1938 return $merged;
1939 }
1940
1941 /**
1942 * Get current elementor document id
1943 *
1944 * @return int|false
1945 */
1946 public static function get_document_id() {
1947 $document = self::jltma_elementor()->documents->get_current();
1948
1949 if ( $document ) {
1950 return $document->get_main_id();
1951 }
1952
1953 return $document;
1954 }
1955
1956 public static function get_ob_html( $callback ) {
1957 if ( ! is_callable( $callback ) ) {
1958 return '';
1959 }
1960
1961 ob_start();
1962
1963 call_user_func( $callback );
1964
1965 return ob_get_clean();
1966 }
1967
1968 public static function render_icon( $icon_setting, $attributes = array() ) {
1969 if ( empty( $icon_setting['value'] ) ) {
1970 return;
1971 }
1972
1973 echo '<span class="jltma-wrap-icon">';
1974
1975 Icons_Manager::render_icon( $icon_setting, $attributes );
1976
1977 echo '</span>';
1978 }
1979
1980 /**
1981 * Render Icon
1982 *
1983 * Used to render Icon for \Elementor\Controls_Manager::ICONS
1984 *
1985 * @param array $icon Icon Type, Icon value
1986 * @param array $attributes Icon HTML Attributes
1987 */
1988 public static function get_render_icon( $icon_setting, $attributes = array() ) {
1989 return self::get_ob_html(
1990 function () use ( $icon_setting, $attributes ) {
1991 self::render_icon( $icon_setting, $attributes );
1992 }
1993 );
1994 }
1995
1996
1997 /**
1998 * Prepare css var.
1999 *
2000 * @param string $control_id Control id.
2001 * @param string $value Control selectors value.
2002 *
2003 * @return string Control id that prepared for css vars.
2004 */
2005 public static function prepare_css_var( $control_id, $value = '' ) {
2006 $var_key = '--' . str_replace( '_', '-', $control_id );
2007
2008 if ( empty( $value ) ) {
2009 return $var_key;
2010 }
2011
2012 return $var_key . ': ' . $value . ';';
2013 }
2014
2015 public static function get_available_image_sizes() {
2016 $glob_sizes = wp_get_additional_image_sizes();
2017 $image_sizes = get_intermediate_image_sizes();
2018 $sizes = array();
2019
2020 if ( is_array( $image_sizes ) && $image_sizes ) {
2021 foreach ( $image_sizes as $size ) {
2022 if ( in_array( $size, array( 'thumbnail', 'medium', 'medium_large', 'large' ), true ) ) {
2023 $sizes[ $size ] = array(
2024 'width' => get_option( "{$size}_size_w" ),
2025 'height' => get_option( "{$size}_size_h" ),
2026 'crop' => (bool) get_option( "{$size}_crop" ),
2027 );
2028 } elseif ( isset( $glob_sizes[ $size ] ) ) {
2029 $sizes[ $size ] = array(
2030 'width' => $glob_sizes[ $size ]['width'],
2031 'height' => $glob_sizes[ $size ]['height'],
2032 'crop' => $glob_sizes[ $size ]['crop'],
2033 );
2034 }
2035
2036 if ( 0 === (int) $sizes[ $size ]['width'] || 0 === (int) $sizes[ $size ]['height'] ) {
2037 unset( $sizes[ $size ] );
2038 }
2039 }
2040 }
2041
2042 return $sizes;
2043 }
2044
2045 public static function jltma_animate_class( $addon_animate, $effect, $delay ) {
2046 if ( $addon_animate == 'on' ) :
2047 $animate_class = ' animate-in" data-anim-type="' . $effect . '" data-anim-delay="' . $delay . '"';
2048 else :
2049 $animate_class = '"';
2050 endif;
2051 return $animate_class;
2052 }
2053
2054
2055
2056 public static function jltma_post_type_query( $source, $posts_source, $posts_type, $categories, $categories_post_type, $order, $orderby, $pagination, $pagination_type, $num_posts, $num_posts_page ) {
2057
2058 if ( $orderby == 'views' ) {
2059 $orderby = 'meta_value_num';
2060 $view_order = 'views';
2061 } else {
2062 $view_order = '';
2063 }
2064
2065 if ( $source == 'post_type' ) {
2066 $posts_source = 'all_posts';
2067 }
2068
2069 if ( $posts_source == 'all_posts' ) {
2070
2071 $query = 'post_type=Post&post_status=publish&ignore_sticky_posts=1&orderby=' . $orderby . '&order=' . $order . '';
2072
2073 // CUSTOM POST TYPE
2074 if ( $source == 'post_type' ) {
2075 $query .= '&post_type=' . $posts_type . '';
2076 }
2077
2078 if ( $view_order == 'views' ) {
2079 $query .= '&meta_key=wpb_post_views_count';
2080 }
2081
2082 // CATEGORIES POST TYPE
2083 if ( $categories_post_type != '' && ! empty( $categories_post_type ) && $source == 'post_type' ) {
2084 $taxonomy_names = get_object_taxonomies( $posts_type );
2085 $query .= '&' . $taxonomy_names[0] . '=' . $categories_post_type . '';
2086 }
2087
2088 // CATEGORIES POSTS
2089 if ( $categories != '' && $categories != 'all' && ! empty( $categories ) && $source == 'wp_posts' ) {
2090 $query .= '&category_name=' . $categories . '';
2091 }
2092
2093 if ( $pagination == 'yes' || $pagination == 'load-more' ) {
2094 $query .= '&posts_per_page=' . $num_posts_page . '';
2095 } else {
2096 if ( $num_posts == '' ) {
2097 $num_posts = '-1';
2098 }
2099 $query .= '&posts_per_page=' . $num_posts . '';
2100 }
2101
2102 // PAGINATION
2103 if ( $pagination == 'yes' || $pagination == 'load-more' ) {
2104 if ( get_query_var( 'paged' ) ) {
2105 $paged = get_query_var( 'paged' );
2106 } elseif ( get_query_var( 'page' ) ) {
2107 $paged = get_query_var( 'page' );
2108 } else {
2109 $paged = 1;
2110 }
2111 $query .= '&paged=' . $paged . '';
2112 }
2113 // #PAGINATION
2114
2115 } else { // IF STICKY
2116
2117 if ( $pagination == 'yes' || $pagination == 'load-more' ) {
2118 $num_posts = $num_posts_page;
2119 } else {
2120 if ( $num_posts == '' ) {
2121 $num_posts = '-1';
2122 }
2123 $num_posts = $num_posts;
2124 }
2125
2126 // PAGINATION
2127
2128 if ( get_query_var( 'paged' ) ) {
2129 $paged = get_query_var( 'paged' );
2130 } elseif ( get_query_var( 'page' ) ) {
2131 $paged = get_query_var( 'page' );
2132 } else {
2133 $paged = 1;
2134 }
2135
2136 // #PAGINATION
2137
2138 /* STICKY POST DA FARE ARRAY PER SCRITTURA IN ARRAY */
2139
2140 $sticky = get_option( 'sticky_posts' );
2141 $sticky = array_slice( $sticky, 0, 5 );
2142 if ( $view_order == 'views' ) {
2143 $query = array(
2144 'post_type' => 'post',
2145 'post_status' => 'publish',
2146 'orderby' => $orderby,
2147 'order' => $order,
2148 'category_name' => $categories,
2149 'posts_per_page' => $num_posts,
2150 'meta_key' => 'wpb_post_views_count',
2151 'paged' => $paged,
2152 'post__in' => $sticky,
2153 'ignore_sticky_posts' => 1,
2154 );
2155 } else {
2156 $query = array(
2157 'post_type' => 'post',
2158 'post_status' => 'publish',
2159 'orderby' => $orderby,
2160 'order' => $order,
2161 'category_name' => $categories,
2162 'posts_per_page' => $num_posts,
2163 'paged' => $paged,
2164 'post__in' => $sticky,
2165 'ignore_sticky_posts' => 1,
2166 );
2167 }
2168 } // #all_posts
2169
2170 return $query;
2171 }
2172
2173
2174 /** Get Category **/
2175 public static function jltma_get_category( $source, $posts_type, $css_link, $limit = 1 ) {
2176 $separator = ' ';
2177 $output = '';
2178 $count = 1;
2179 if ( $source == 'wp_posts' ) {
2180 $categories = get_the_category();
2181 if ( $categories ) {
2182 foreach ( $categories as $category ) {
2183 $output .= '<a href="' . get_category_link( $category->term_id ) . '" title="' . esc_attr( /* translators: %s: Categories */sprintf( __( 'View all posts in %s', 'master-addons' ), $category->name ) ) . '" ' . $css_link . '>' . esc_html( $category->cat_name ) . '</a>' . esc_html( $separator );
2184 if ( $count == $limit ) {
2185 break;
2186 }
2187 ++$count;
2188 }
2189 }
2190 } elseif ( $source == 'post_type' ) {
2191 global $post;
2192 $taxonomy_names = get_object_taxonomies( $posts_type );
2193 $term_list = wp_get_post_terms( $post->ID, $taxonomy_names );
2194 if ( $term_list ) {
2195 foreach ( $term_list as $tax_term ) {
2196 /* translators: %s: Taxonomy term name. */
2197 $output .= '<a href="' . esc_attr( get_term_link( $tax_term, $posts_type ) ) . '" title="' . esc_attr( sprintf( __( 'View all posts in %s', 'master-addons' ), $tax_term->name ) ) . '" ' . $css_link . '>' . esc_html( $tax_term->name ) . '</a>' . esc_html( $separator );
2198 }
2199 }
2200 }
2201 $return = trim( $output, $separator );
2202 return $return;
2203 }
2204
2205
2206 /** Get Author **/
2207 public static function jltma_get_author( $css_link ) {
2208 $return = '<a href="' . get_author_posts_url( get_the_author_meta( 'ID' ) ) . '" ' . $css_link . '>' . get_the_author_meta( 'display_name' ) . '</a>';
2209 return $return;
2210 }
2211
2212 /** Get Blog Exceprt */
2213 public static function jltma_get_blogs_excerpt( $excerpt = 'default', $readmore = 'on', $css_link = '' ) {
2214 global $post;
2215 if ( $excerpt == 'default' ) :
2216 $return = get_the_excerpt();
2217 else :
2218 $return = substr( get_the_excerpt(), 0, $excerpt );
2219 if ( $readmore == 'on' ) :
2220 $return .= '<a class="article-read-more" href="' . get_permalink( $post->ID ) . '" ' . $css_link . '>' . esc_html__( 'Read More', 'master-addons' ) . '</a>';
2221 else :
2222 $return .= '...';
2223 endif;
2224 endif;
2225 return $return;
2226 }
2227
2228
2229 /** Post Social Share **/
2230 public static function jltma_post_social_share( $css_link ) {
2231
2232 $return = '<div class="container-social">
2233 <a target="_blank" href="http://www.facebook.com/sharer.php?u=' . get_the_permalink() . '&amp;t=' . get_the_title() . '" title="' . esc_html__( 'Click to share this post on Facebook', 'master-addons' ) . '" ' . $css_link . '><i class="fa fa-facebook"></i></a>
2234 <a target="_blank" href="http://twitter.com/home?status=' . get_the_permalink() . '" title="' . esc_html__( 'Click to share this post on Twitter', 'master-addons' ) . '"><i class="fa fa-twitter" ' . $css_link . '></i></a>
2235 <a target="_blank" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=' . get_the_permalink() . '" title="' . esc_html__( 'Click to share this post on Linkedin', 'master-addons' ) . '"><i class="fa fa-linkedin" ' . $css_link . '></i></a></div>';
2236
2237 return $return;
2238 }
2239
2240 /** Check Post Format **/
2241 public static function jltma_check_post_format() {
2242 global $post;
2243 $format = get_post_format_string( get_post_format() );
2244 if ( $format == 'Video' ) :
2245 $return = '<span class="fpg-format-type fa fa-play-circle-o"></span>';
2246 elseif ( $format == 'Audio' ) :
2247 $return = '<span class="fpg-format-type fa fa-headphones"></span>';
2248 else :
2249 $return = '';
2250 endif;
2251 return $return;
2252 }
2253
2254 /** Get Thumbnails **/
2255 public static function jltma_get_thumb( $thumbs_size = 'thumbnail' ) {
2256 global $post;
2257 $link = get_the_permalink();
2258 if ( has_post_thumbnail() ) {
2259 $id_post = get_the_id();
2260 $single_image = wp_get_attachment_image_src( get_post_thumbnail_id( $id_post ), $thumbs_size );
2261 $return = '<a href="' . esc_url( $link ) . '"><img class="fpg-thumbs" src="' . $single_image[0] . '" alt="' . get_the_title() . '"></a>';
2262 } else {
2263 $return = '';
2264 }
2265 return $return;
2266 }
2267
2268
2269 /** Get Blog Thumbnails **/
2270 public static function jltma_get_blogs_thumb( $columns, $post_id ) {
2271 global $post;
2272 if ( $columns == '1' ) :
2273 $return = self::jltma_get_thumb( 'large' );
2274 elseif ( $columns == '2' ) :
2275 $return = self::jltma_get_thumb( 'medium' );
2276 else :
2277 $return = self::jltma_get_thumb( 'small' );
2278 endif;
2279 return $return;
2280 }
2281
2282 // Get Template Part
2283 public static function jltma_get_template_part( $jltma_template, $jltma_data = array() ) {
2284 extract( $jltma_data );
2285 include JLTMA_PATH . 'inc/post-templates/' . $jltma_template . '.php';
2286 }
2287
2288 // Get Featured Image URL
2289 public static function jltma_get_featured_image_url() {
2290 $featured_image_full_url = wp_get_attachment_image_src( get_post_thumbnail_id(), 'full' );
2291 if ( isset( $featured_image_full_url[0] ) && strlen( $featured_image_full_url[0] ) > 0 ) {
2292 return $featured_image_full_url[0];
2293 } else {
2294 return false;
2295 }
2296 }
2297
2298 // Get Featured Image URL
2299 public static function jltma_excerpt_truncate( $jltma_string, $jltma_length = 80, $jltma_etc = '... ', $jltma_break_words = false, $jltma_middle = false ) {
2300 if ( $jltma_length == 0 ) {
2301 return '';
2302 }
2303
2304 if ( mb_strlen( $jltma_string, 'utf8' ) > $jltma_length ) {
2305 $jltma_length -= mb_strlen( $jltma_etc, 'utf8' );
2306 if ( ! $jltma_break_words && ! $jltma_middle ) {
2307 $jltma_string = preg_replace( '/\s+\S+\s*$/su', '', mb_substr( $jltma_string, 0, $jltma_length + 1, 'utf8' ) );
2308 }
2309 if ( ! $jltma_middle ) {
2310 return mb_substr( $jltma_string, 0, $jltma_length, 'utf8' ) . $jltma_etc;
2311 } else {
2312 return mb_substr( $jltma_string, 0, $jltma_length / 2, 'utf8' ) . $jltma_etc . mb_substr( $jltma_string, -$jltma_length / 2, utf8 );
2313 }
2314 } else {
2315 return $jltma_string;
2316 }
2317 }
2318
2319
2320 public static function jltma_pro_notice_html( $args = array() ) {
2321
2322 $defaults = array(
2323 'show_icon' => true,
2324 'show_heading' => true,
2325 );
2326 $args = wp_parse_args( $args, $defaults );
2327
2328 // Get Pro_Upgrade instance to access promo data
2329 $pro_upgrade = new \MasterAddons\Inc\Classes\Pro_Upgrade();
2330
2331 // Check if campaign is active, otherwise use fallback
2332 if ( 'FALSE' === $pro_upgrade->get_content( 'is_campaign' ) ) {
2333 $notice = 'Use "SPECIAL40" to Get Flat 40% OFF';
2334 $btn_url = 'https://master-addons.com/pricing/';
2335 $btn_text = 'GET THE DEAL';
2336 } else {
2337 $notice = $pro_upgrade->get_content( 'notice' );
2338 $btn_url = $pro_upgrade->get_content( 'button_url' );
2339 $btn_text = $pro_upgrade->get_content( 'button_text' );
2340 }
2341
2342 $end_date = $pro_upgrade->counter_date();
2343
2344 ob_start();
2345 ?>
2346 <div class="jltma-upgrade-banner" id="jltma-upgrade-banner">
2347 <div class="jltma-upgrade-banner-content">
2348 <?php if ( $args['show_icon'] ) : ?>
2349 <!-- Crown Icon with Speech Bubble Tail -->
2350 <div class="jltma-upgrade-banner-icon-wrapper">
2351 <div class="jltma-upgrade-banner-icon">
2352 <svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
2353 <path d="M6 30V26L3 12L12 18L20 8L28 18L37 12L34 26V30H6Z" fill="white"/>
2354 <circle cx="20" cy="22" r="2.5" fill="#6814cd"/>
2355 </svg>
2356 </div>
2357 </div>
2358 <?php endif; ?>
2359
2360 <?php if ( $args['show_heading'] ) : ?>
2361 <!-- Main Heading -->
2362 <h2 class="jltma-upgrade-banner-title"><?php echo esc_html__( 'Upgrade to unlock every powerful feature and faster performance', 'master-addons' ); ?></h2>
2363 <?php endif; ?>
2364
2365 <!-- Countdown Timer -->
2366 <div class="jltma-popup-countdown" style="display: none;">
2367 <?php if ( ! empty( $notice ) ) { ?>
2368 <span data-counter="notice" style="color:#F4B740; font-size:14px; padding-bottom:20px; font-style:italic;">
2369 <?php echo esc_html__( 'Notice:', 'master-addons' ); ?> <?php echo esc_html( $notice ); ?>
2370 </span>
2371 <?php } ?>
2372 <span class="jltma-popup-countdown-text"><?php echo esc_html__( 'Offer Ends In', 'master-addons' ); ?></span>
2373 <div class="jltma-popup-countdown-time">
2374 <div>
2375 <span data-counter="days">00</span>
2376 <span><?php echo esc_html__( 'Days', 'master-addons' ); ?></span>
2377 </div>
2378 <span>:</span>
2379 <div>
2380 <span data-counter="hours">00</span>
2381 <span><?php echo esc_html__( 'Hours', 'master-addons' ); ?></span>
2382 </div>
2383 <span>:</span>
2384 <div>
2385 <span data-counter="minutes">00</span>
2386 <span><?php echo esc_html__( 'Minutes', 'master-addons' ); ?></span>
2387 </div>
2388 <span>:</span>
2389 <div>
2390 <span data-counter="seconds">00</span>
2391 <span><?php echo esc_html__( 'Seconds', 'master-addons' ); ?></span>
2392 </div>
2393 </div>
2394 </div>
2395
2396 <!-- Upgrade Button -->
2397 <a class="jltma-upgrade-banner-button" target="_blank" href="https://master-addons.com/pricing"><?php echo esc_html__( 'Upgrade Now', 'master-addons' ); ?></a>
2398 </div>
2399 </div>
2400
2401 <script>
2402 (function() {
2403 var $container = jQuery('#jltma-upgrade-banner');
2404
2405 // Update Counter
2406 function updateCounter(seconds) {
2407 const $counter = $container.find(".jltma-popup-countdown-time");
2408 const $days = $counter.find("[data-counter='days']");
2409 const $hours = $counter.find("[data-counter='hours']");
2410 const $minutes = $counter.find("[data-counter='minutes']");
2411 const $seconds = $counter.find("[data-counter='seconds']");
2412 const days = Math.floor(seconds / (3600 * 24));
2413 seconds -= days * 3600 * 24;
2414 const hrs = Math.floor(seconds / 3600);
2415 seconds -= hrs * 3600;
2416 const mnts = Math.floor(seconds / 60);
2417 seconds -= mnts * 60;
2418
2419 $days.text(days);
2420 $hours.text(hrs);
2421 $minutes.text(mnts);
2422 $seconds.text(seconds);
2423 }
2424
2425 // initCounter
2426 function initCounter(last_date) {
2427 const countdown = () => {
2428 // system time
2429 const now = new Date().getTime();
2430
2431 // set end time to 11:59:59 PM
2432 const endDate = new Date(last_date);
2433 endDate.setHours(23);
2434 endDate.setMinutes(59);
2435 endDate.setSeconds(59);
2436
2437 const seconds = Math.floor((endDate.getTime() - now) / 1000);
2438
2439 if (seconds < 0) {
2440 return false;
2441 }
2442
2443 updateCounter(seconds);
2444 return true;
2445 }
2446
2447 let result = countdown();
2448
2449 if (result) {
2450 $container.find(".jltma-popup-countdown").show(0);
2451 } else {
2452 $container.find(".jltma-popup-countdown").hide(0);
2453 }
2454
2455 // update counter every 1 second
2456 const counter = setInterval(() => {
2457 const result = countdown();
2458 if (!result) {
2459 clearInterval(counter);
2460 $container.find(".jltma-popup-countdown").hide(0);
2461 }
2462 }, 1000);
2463 }
2464
2465 // Initialize countdown when DOM is ready
2466 jQuery(document).ready(function() {
2467 initCounter('<?php echo esc_attr( $end_date ); ?>');
2468 });
2469 })();
2470 </script>
2471
2472 <?php // Auto-open Elementor sections that contain upgrade banners ?>
2473 <script>
2474 (function(){
2475 if (window.jltmaUpgradeSectionAutoOpen) return;
2476 window.jltmaUpgradeSectionAutoOpen = true;
2477 var panel = document.getElementById("elementor-panel-content-wrapper");
2478 if (!panel) return;
2479 function openUpgradeSections() {
2480 var banners = panel.querySelectorAll(".jltma-upgrade-banner");
2481 banners.forEach(function(banner) {
2482 var section = banner.closest(".elementor-control-type-section");
2483 if (section && !section.classList.contains("elementor-open")) {
2484 section.classList.add("elementor-open");
2485 }
2486 });
2487 }
2488 var observer = new MutationObserver(openUpgradeSections);
2489 observer.observe(panel, {childList: true, subtree: true});
2490 openUpgradeSections();
2491 })();
2492 </script>
2493 <?php
2494
2495 $notice_html = ob_get_clean();
2496 return $notice_html;
2497 }
2498
2499
2500 public static function jltma_premium(){
2501 // Check Freemius license first (most reliable — respects actual license status)
2502 if (function_exists('ma_el_fs')) {
2503 return ma_el_fs()->can_use_premium_code__premium_only();
2504 }
2505
2506 // Fallback: If pro addon plugin is installed (JLTMA_PRO_PATH is defined by pro plugin)
2507 if (defined('JLTMA_PRO_PATH') && is_dir(JLTMA_PRO_PATH . 'premium/')) {
2508 return true;
2509 }
2510
2511 // Fallback: If premium modules directory exists, this is a pro build
2512 if (defined('JLTMA_PRO_EXTENSIONS') && is_dir(JLTMA_PRO_EXTENSIONS)) {
2513 return true;
2514 }
2515
2516 return apply_filters('master_addons/is_premium', false);
2517 }
2518
2519 /**
2520 * Get widget statistics for admin dashboard
2521 * Returns counts for all widgets, core, third party, and active widgets
2522 *
2523 * @return array Statistics array with totals and percentages
2524 */
2525 public static function jltma_get_widget_stats() {
2526 // Get saved settings
2527 $element_settings = \MasterAddons\Inc\Admin\Settings\Settings::get_addons() ?: [];
2528 $extension_settings = \MasterAddons\Inc\Admin\Settings\Settings::get_extensions() ?: [];
2529
2530 // Initialize counters
2531 $core_widgets = [];
2532 $third_party_widgets = [];
2533
2534 // Use unified config to get all addons
2535 $addons = \MasterAddons\Inc\Admin\Config::get_addons();
2536 foreach ($addons as $key => $addon) {
2537 $core_widgets[] = [
2538 'key' => $key,
2539 'type' => 'element'
2540 ];
2541 }
2542
2543 // Get all extensions
2544 $extensions = \MasterAddons\Inc\Admin\Config::get_extensions();
2545 foreach ($extensions as $key => $extension) {
2546 $core_widgets[] = [
2547 'key' => $key,
2548 'type' => 'extension'
2549 ];
2550 }
2551
2552 // Get third party plugins
2553 $plugins = \MasterAddons\Inc\Admin\Config::get_plugins();
2554 foreach ($plugins as $key => $plugin) {
2555 $third_party_widgets[] = [
2556 'key' => $key,
2557 'type' => 'third_party'
2558 ];
2559 }
2560
2561 // Calculate active counts
2562 $core_active = 0;
2563 $core_total = count($core_widgets);
2564 foreach ($core_widgets as $widget) {
2565 $settings = ($widget['type'] === 'extension') ? $extension_settings : $element_settings;
2566 if (isset($settings[$widget['key']]) && $settings[$widget['key']] == 1) {
2567 $core_active++;
2568 }
2569 }
2570
2571 $third_party_active = 0;
2572 $third_party_total = count($third_party_widgets);
2573 // Third party plugins don't have the same active/inactive mechanism
2574
2575 // Calculate totals
2576 $all_total = $core_total + $third_party_total;
2577 $all_active = $core_active + $third_party_active;
2578
2579 return [
2580 'all' => [
2581 'total' => $all_total,
2582 'active' => $all_active,
2583 'inactive' => $all_total - $all_active,
2584 'percentage' => $all_total > 0 ? round(($all_active / $all_total) * 100) : 0
2585 ],
2586 'core' => [
2587 'total' => $core_total,
2588 'active' => $core_active,
2589 'inactive' => $core_total - $core_active,
2590 'percentage' => $core_total > 0 ? round(($core_active / $core_total) * 100) : 0
2591 ],
2592 'third_party' => [
2593 'total' => $third_party_total,
2594 'active' => $third_party_active,
2595 'inactive' => $third_party_total - $third_party_active,
2596 'percentage' => $third_party_total > 0 ? round(($third_party_active / $third_party_total) * 100) : 0
2597 ],
2598 'active' => [
2599 'total' => $all_active,
2600 'active' => $all_active,
2601 'inactive' => 0,
2602 'percentage' => 100
2603 ]
2604 ];
2605 }
2606 }
2607