PluginProbe ʕ •ᴥ•ʔ
Premium Addons for Elementor – Powerful Elementor Templates & Widgets / 4.11.62
Premium Addons for Elementor – Powerful Elementor Templates & Widgets v4.11.62
4.11.79 4.11.78 4.11.77 4.11.76 4.11.75 3.20.5 4.11.69 3.20.6 4.11.7 3.20.7 4.11.70 3.20.8 4.11.71 3.20.9 4.11.72 3.21.1 4.11.73 3.21.2 4.11.74 3.21.3 4.11.8 3.21.4 4.11.9 3.21.5 4.2.0 3.21.6 4.2.1 3.3.0 4.2.2 3.3.1 4.2.3 3.3.2 4.2.4 3.3.3 4.2.5 3.3.4 4.2.6 3.3.5 4.2.7 3.3.6 4.2.8 3.3.7 4.2.9 3.3.8 4.3.0 3.3.9 4.3.1 3.4.0 4.3.2 3.4.1 4.3.3 3.4.2 4.3.4 3.4.3 4.3.5 3.4.4 4.3.6 3.4.5 4.3.7 3.4.6 4.3.8 3.4.7 4.3.9 3.4.8 4.4.0 3.4.9 4.4.1 3.5.0 4.4.2 3.5.1 4.4.3 3.5.2 4.4.4 3.5.3 4.4.5 3.5.4 4.4.6 3.5.5 4.4.7 3.5.6 4.4.8 3.5.7 4.4.9 3.5.8 4.5.0 3.5.9 4.5.1 3.6.0 4.5.2 3.6.1 4.5.3 3.6.2 4.5.4 3.6.3 4.5.5 3.6.4 4.5.6 3.6.5 4.5.7 3.6.6 4.5.8 3.6.7 4.5.9 3.6.8 4.6.0 3.6.9 4.6.1 3.7.0 4.7.0 3.7.1 4.7.1 3.7.2 4.7.2 3.7.3 4.7.3 3.7.4 4.7.4 3.7.5 4.7.5 3.7.6 4.7.6 3.7.7 4.7.7 3.7.8 4.7.8 3.7.9 4.7.9 3.8.0 4.8.0 3.8.1 4.8.1 3.8.2 4.8.10 3.8.3 4.8.11 3.8.4 4.8.2 3.8.5 4.8.3 3.8.6 4.8.4 3.8.7 4.8.5 3.8.8 4.8.6 3.8.9 4.8.7 3.9.0 4.8.8 3.9.1 4.8.9 3.9.2 4.9.0 3.9.3 4.9.0-beta1 3.9.4 4.9.0-beta2 3.9.5 4.9.1 3.9.6 4.9.10 3.9.7 4.9.11 3.9.8 4.9.12 3.9.9 4.9.13 4.0.1 4.9.14 4.0.3 4.9.15 4.0.4 4.9.16 4.0.5 4.9.17 4.0.6 4.9.18 4.0.7 4.9.19 4.0.8 4.9.2 4.0.9 4.9.20 4.1.0 4.9.21 4.1.1 4.9.22 4.1.2 4.9.23 4.1.3 4.9.24 trunk 4.1.4 4.9.25 1.0 4.1.5 4.9.26 1.01 4.1.6 4.9.27 1.02 4.1.7 4.9.28 1.03 4.1.8 4.9.29 1.04 4.1.9 4.9.3 1.05 4.10.0 4.9.30 1.06 4.10.1 4.9.31 1.07 4.10.10 4.9.32 1.08 4.10.11 4.9.33 1.09 4.10.12 4.9.34 2.0 4.10.13 4.9.35 2.0.1 4.10.14 4.9.36 2.0.2 4.10.15 4.9.37 2.0.3 4.10.16 4.9.38 2.0.4 4.10.17 4.9.39 2.0.5 4.10.18 4.9.4 2.0.6 4.10.19 4.9.40 2.0.7 4.10.2 4.9.41 2.0.8 4.10.20 4.9.42 2.0.9 4.10.21 4.9.43 2.1.0 4.10.22 4.9.45 2.1.1 4.10.23 4.9.46 2.1.2 4.10.24 4.9.47 2.1.3 4.10.25 4.9.48 2.1.4 4.10.26 4.9.49 2.1.5 4.10.27 4.9.5 2.1.5-beta1 4.10.28 4.9.50 2.1.6 4.10.29 4.9.51 2.1.7 4.10.3 4.9.52 2.1.8 4.10.30 4.9.53 2.1.9 4.10.31 4.9.54 2.2.0 4.10.32 4.9.55 2.2.1 4.10.33 4.9.56 2.2.2 4.10.34 4.9.57 2.2.3 4.10.35 4.9.6 2.2.4 4.10.36 4.9.7 2.2.5 4.10.37 4.9.8 2.2.6 4.10.38 4.9.9 2.2.7 4.10.39 2.2.8 4.10.4 2.2.9 4.10.40 2.3.0 4.10.41 2.3.1 4.10.42 2.3.2 4.10.43 2.3.3 4.10.44 2.3.4 4.10.45 2.3.5 4.10.46 2.3.6 4.10.47 2.3.7 4.10.48 2.3.8 4.10.49 2.3.9 4.10.5 2.4.0 4.10.50 2.4.1 4.10.51 2.5.0 4.10.52 2.5.1 4.10.53 2.5.2 4.10.54 2.5.3 4.10.55 2.5.4 4.10.56 2.5.5 4.10.57 2.5.6 4.10.58 2.5.7 4.10.59 2.5.8 4.10.6 2.5.9 4.10.60 2.6.0 4.10.61 2.6.1 4.10.62 2.6.2 4.10.63 2.6.3 4.10.64 2.6.4 4.10.65 2.6.5 4.10.66 2.6.6 4.10.67 2.6.7 4.10.68 2.6.8 4.10.69 2.6.9 4.10.7 2.7.0 4.10.70 2.7.1 4.10.71 2.7.2 4.10.72 2.7.3 4.10.73 2.7.4 4.10.74 2.7.5 4.10.75 2.7.6 4.10.76 2.7.7 4.10.77 2.7.8 4.10.78 2.7.9 4.10.79 2.8.0 4.10.8 2.8.1 4.10.80 2.8.2 4.10.81 2.8.3 4.10.82 2.8.4 4.10.83 2.8.5 4.10.84 2.8.6 4.10.85 2.8.7 4.10.86 2.8.8 4.10.87 2.8.9 4.10.88 2.9.0 4.10.89 2.9.1 4.10.9 2.9.2 4.10.90 2.9.3 4.11.0 2.9.4 4.11.1 2.9.5 4.11.10 2.9.6 4.11.11 2.9.7 4.11.12 2.9.8 4.11.13 2.9.9 4.11.14 3.0.0 4.11.15 3.0.1 4.11.16 3.0.2 4.11.17 3.0.3 4.11.18 3.0.4 4.11.19 3.0.5 4.11.2 3.0.6 4.11.20 3.0.7 4.11.21 3.0.8 4.11.22 3.0.9 4.11.23 3.1.0 4.11.24 3.1.1 4.11.25 3.1.2 4.11.26 3.1.3 4.11.27 3.1.4 4.11.28 3.1.5 4.11.29 3.1.6 4.11.3 3.1.7 4.11.30 3.1.8 4.11.31 3.1.9 4.11.32 3.10.0 4.11.33 3.10.1 4.11.34 3.10.2 4.11.35 3.10.3 4.11.36 3.10.4 4.11.37 3.10.5 4.11.38 3.10.6 4.11.39 3.10.7 4.11.4 3.10.8 4.11.40 3.10.9 4.11.41 3.11.0 4.11.42 3.11.1 4.11.43 3.11.2 4.11.44 3.11.3 4.11.45 3.11.4 4.11.46 3.11.5 4.11.47 3.11.6 4.11.48 3.11.7 4.11.49 3.11.8 4.11.5 3.11.9 4.11.50 3.12.0 4.11.51 3.12.1 4.11.52 3.12.2 4.11.53 3.12.3 4.11.54 3.2.0 4.11.55 3.2.1 4.11.56 3.2.2 4.11.57 3.2.3 4.11.58 3.2.4 4.11.59 3.2.5 4.11.6 3.2.6 4.11.60 3.2.7 4.11.61 3.2.8 4.11.62 3.2.9 4.11.63 3.20.0 4.11.64 3.20.1 4.11.65 3.20.2 4.11.66 3.20.3 4.11.67 3.20.4 4.11.68
premium-addons-for-elementor / includes / helper-functions.php
premium-addons-for-elementor / includes Last commit date
controls 5 months ago extras 5 months ago helpers 5 months ago pa-display-conditions 5 months ago templates 5 months ago acf-helper.php 5 months ago addons-cross-cp.php 5 months ago addons-integration.php 5 months ago assets-manager.php 5 months ago class-pa-core.php 5 months ago cm-pointer.php 5 months ago helper-functions.php 5 months ago live-editor-modal.php 5 months ago module-base.php 5 months ago pa-nav-menu-walker.php 5 months ago papro-promotion.php 5 months ago premium-template-tags.php 5 months ago promotion-pointer.php 5 months ago
helper-functions.php
2044 lines
1 <?php
2 /**
3 * PA Helper Functions.
4 */
5
6 namespace PremiumAddons\Includes;
7
8 // Premium Addons Pro Classes.
9 use PremiumAddonsPro\Includes\White_Label\Helper;
10 use PremiumAddons\Admin\Includes\Admin_Helper;
11
12 // Elementor Classes.
13 use Elementor\Icons_Manager;
14 use Elementor\Core\Settings\Manager as SettingsManager;
15 use Elementor\Plugin;
16 use Elementor\Controls_Manager;
17
18 if ( ! defined( 'ABSPATH' ) ) {
19 exit;
20 }
21
22 /**
23 * Class Helper_Functions.
24 */
25 class Helper_Functions {
26
27 /**
28 * A list of safe tags for `validate_html_tag` method.
29 */
30 const ALLOWED_HTML_WRAPPER_TAGS = array(
31 'article',
32 'aside',
33 'div',
34 'footer',
35 'h1',
36 'h2',
37 'h3',
38 'h4',
39 'h5',
40 'h6',
41 'header',
42 'main',
43 'nav',
44 'p',
45 'section',
46 'span',
47 );
48
49 /**
50 * Theme
51 *
52 * @var theme
53 */
54 private static $current_theme = null;
55
56 /**
57 * Google maps prefixes
58 *
59 * @var google_localize
60 */
61 private static $google_localize = null;
62
63 /**
64 * SVG Shapes
65 *
66 * @var shapes
67 */
68 private static $shapes = null;
69
70 /**
71 * WP lang prefixes
72 *
73 * @var lang_locales
74 */
75 private static $lang_locales = null;
76
77 /**
78 * Script debug enabled
79 *
80 * @var script_debug
81 */
82 private static $script_debug = null;
83
84 /**
85 * JS scripts directory
86 *
87 * @var js_dir
88 */
89 private static $js_dir = null;
90
91 /**
92 * CSS files directory
93 *
94 * @var js_dir
95 */
96 private static $css_dir = null;
97
98 /**
99 * JS Suffix
100 *
101 * @var js_suffix
102 */
103 private static $assets_suffix = null;
104
105 /**
106 * Get Icon SVG Data
107 *
108 * @since 4.10.72
109 * @access private
110 *
111 * @return array icon data.
112 */
113 private static function get_icon_svg_data( $icon ) {
114
115 preg_match( '/fa(.*) fa-/', $icon['value'], $icon_name_matches );
116
117 if ( empty( $icon_name_matches ) ) {
118 return;
119 }
120
121 $icon_name = str_replace( $icon_name_matches[0], '', $icon['value'] );
122
123 $icon_key = str_replace( ' fa-', '-', $icon['value'] );
124
125 $icon_file_name = str_replace( 'fa-', '', $icon['library'] );
126
127 $path = ELEMENTOR_ASSETS_PATH . 'lib/font-awesome/json/' . $icon_file_name . '.json';
128
129 $data = file_get_contents( $path );
130
131 if ( ! $data ) {
132 return;
133 }
134
135 $data = json_decode( $data, true );
136
137 $svg_data = $data['icons'][ $icon_name ];
138
139 return array(
140 'width' => $svg_data[0],
141 'height' => $svg_data[1],
142 'path' => $svg_data[4],
143 );
144 }
145
146 /**
147 * Check if white labeling - Free version author field is set
148 *
149 * @since 1.0.0
150 * @access public
151 *
152 * @return string
153 */
154 public static function author() {
155
156 $author_free = 'Leap13';
157
158 if ( self::check_papro_version() ) {
159
160 $white_label = Helper::get_white_labeling_settings();
161
162 $author_free = $white_label['premium-wht-lbl-name'];
163
164 }
165
166 return '' !== $author_free ? $author_free : 'Leap13';
167 }
168
169 /**
170 * Check if white labeling - Free version name field is set
171 *
172 * @since 1.0.0
173 * @access public
174 *
175 * @return string
176 */
177 public static function name() {
178
179 $name_free = 'Premium Addons';
180
181 if ( self::check_papro_version() ) {
182
183 $white_label = Helper::get_white_labeling_settings();
184
185 $name_free = $white_label['premium-wht-lbl-plugin-name'];
186
187 }
188
189 return '' !== $name_free ? $name_free : 'Premium Addons';
190 }
191
192 /**
193 * Check if white labeling - Hide row meta option is checked
194 *
195 * @since 1.0.0
196 * @return boolean
197 */
198 public static function is_hide_row_meta() {
199
200 $hide_meta = false;
201
202 if ( self::check_papro_version() ) {
203
204 $white_label = Helper::get_white_labeling_settings();
205
206 $hide_meta = $white_label['premium-wht-lbl-row'];
207
208 }
209
210 return $hide_meta;
211 }
212
213 /**
214 * Check if white labeling - Hide plugin logo option is checked
215 *
216 * @since 1.0.0
217 * @access public
218 *
219 * @return boolean
220 */
221 public static function is_hide_logo() {
222
223 if ( self::check_papro_version() ) {
224
225 if ( isset( get_option( 'pa_wht_lbl_save_settings' )['premium-wht-lbl-logo'] ) ) {
226
227 $hide_logo = get_option( 'pa_wht_lbl_save_settings' )['premium-wht-lbl-logo'];
228
229 }
230 }
231
232 return isset( $hide_logo ) ? $hide_logo : false;
233 }
234
235 /**
236 * Get White Labeling - Widgets Category string
237 *
238 * @since 1.0.0
239 * @access public
240 *
241 * @return string
242 */
243 public static function get_category() {
244
245 $category = __( 'Premium Addons', 'premium-addons-for-elementor' );
246
247 if ( self::check_papro_version() ) {
248
249 $white_label = Helper::get_white_labeling_settings();
250
251 $category = $white_label['premium-wht-lbl-short-name'];
252
253 }
254
255 return '' !== $category ? $category : __( 'Premium Addons', 'premium-addons-for-elementor' );
256 }
257
258 /**
259 * Get White Labeling - Widgets Prefix string
260 *
261 * @since 1.0.0
262 * @access public
263 *
264 * @return string
265 */
266 public static function get_prefix() {
267
268 $prefix = __( 'Premium', 'premium-addons-for-elementor' );
269
270 if ( self::check_papro_version() ) {
271
272 $white_label = Helper::get_white_labeling_settings();
273
274 $prefix = $white_label['premium-wht-lbl-prefix'];
275
276 }
277
278 return '' !== $prefix ? $prefix : __( 'Premium', 'premium-addons-for-elementor' );
279 }
280
281 /**
282 * Check if white labeling - Future notification checked
283 *
284 * @since 1.0.0
285 * @return boolean
286 */
287 public static function check_hide_notifications() {
288
289 if ( self::check_papro_version() ) {
290
291 $white_label = Helper::get_white_labeling_settings();
292
293 $hide_notification = isset( $white_label['premium-wht-lbl-not'] ) ? $white_label['premium-wht-lbl-not'] : false;
294
295 }
296
297 return isset( $hide_notification ) ? $hide_notification : false;
298 }
299
300 /**
301 * Get White Labeling - Widgets Badge string
302 *
303 * @since 1.0.0
304 * @access public
305 *
306 * @return string
307 */
308 public static function get_badge() {
309
310 $badge = 'PA';
311
312 if ( self::check_papro_version() ) {
313
314 $white_label = Helper::get_white_labeling_settings();
315
316 $badge = $white_label['premium-wht-lbl-badge'];
317
318 }
319
320 return '' !== $badge ? $badge : 'PA';
321 }
322
323 /**
324 * Get Google Maps localization prefixes
325 *
326 * @since 1.0.0
327 * @access public
328 *
329 * @return array
330 */
331 public static function get_google_maps_prefixes() {
332
333 if ( null === self::$google_localize ) {
334
335 self::$google_localize = array(
336 'ar' => __( 'Arabic', 'premium-addons-for-elementor' ),
337 'eu' => __( 'Basque', 'premium-addons-for-elementor' ),
338 'bg' => __( 'Bulgarian', 'premium-addons-for-elementor' ),
339 'bn' => __( 'Bengali', 'premium-addons-for-elementor' ),
340 'ca' => __( 'Catalan', 'premium-addons-for-elementor' ),
341 'cs' => __( 'Czech', 'premium-addons-for-elementor' ),
342 'da' => __( 'Danish', 'premium-addons-for-elementor' ),
343 'de' => __( 'German', 'premium-addons-for-elementor' ),
344 'el' => __( 'Greek', 'premium-addons-for-elementor' ),
345 'en' => __( 'English', 'premium-addons-for-elementor' ),
346 'en-AU' => __( 'English (australian)', 'premium-addons-for-elementor' ),
347 'en-GB' => __( 'English (great britain)', 'premium-addons-for-elementor' ),
348 'es' => __( 'Spanish', 'premium-addons-for-elementor' ),
349 'fa' => __( 'Farsi', 'premium-addons-for-elementor' ),
350 'fi' => __( 'Finnish', 'premium-addons-for-elementor' ),
351 'fil' => __( 'Filipino', 'premium-addons-for-elementor' ),
352 'fr' => __( 'French', 'premium-addons-for-elementor' ),
353 'gl' => __( 'Galician', 'premium-addons-for-elementor' ),
354 'gu' => __( 'Gujarati', 'premium-addons-for-elementor' ),
355 'hi' => __( 'Hindi', 'premium-addons-for-elementor' ),
356 'hr' => __( 'Croatian', 'premium-addons-for-elementor' ),
357 'hu' => __( 'Hungarian', 'premium-addons-for-elementor' ),
358 'id' => __( 'Indonesian', 'premium-addons-for-elementor' ),
359 'it' => __( 'Italian', 'premium-addons-for-elementor' ),
360 'iw' => __( 'Hebrew', 'premium-addons-for-elementor' ),
361 'ja' => __( 'Japanese', 'premium-addons-for-elementor' ),
362 'kn' => __( 'Kannada', 'premium-addons-for-elementor' ),
363 'ko' => __( 'Korean', 'premium-addons-for-elementor' ),
364 'lt' => __( 'Lithuanian', 'premium-addons-for-elementor' ),
365 'lv' => __( 'Latvian', 'premium-addons-for-elementor' ),
366 'ml' => __( 'Malayalam', 'premium-addons-for-elementor' ),
367 'mr' => __( 'Marathi', 'premium-addons-for-elementor' ),
368 'nl' => __( 'Dutch', 'premium-addons-for-elementor' ),
369 'no' => __( 'Norwegian', 'premium-addons-for-elementor' ),
370 'pl' => __( 'Polish', 'premium-addons-for-elementor' ),
371 'pt' => __( 'Portuguese', 'premium-addons-for-elementor' ),
372 'pt-BR' => __( 'Portuguese (brazil)', 'premium-addons-for-elementor' ),
373 'pt-PT' => __( 'Portuguese (portugal)', 'premium-addons-for-elementor' ),
374 'ro' => __( 'Romanian', 'premium-addons-for-elementor' ),
375 'ru' => __( 'Russian', 'premium-addons-for-elementor' ),
376 'sk' => __( 'Slovak', 'premium-addons-for-elementor' ),
377 'sl' => __( 'Slovenian', 'premium-addons-for-elementor' ),
378 'sr' => __( 'Serbian', 'premium-addons-for-elementor' ),
379 'sv' => __( 'Swedish', 'premium-addons-for-elementor' ),
380 'tl' => __( 'Tagalog', 'premium-addons-for-elementor' ),
381 'ta' => __( 'Tamil', 'premium-addons-for-elementor' ),
382 'te' => __( 'Telugu', 'premium-addons-for-elementor' ),
383 'th' => __( 'Thai', 'premium-addons-for-elementor' ),
384 'tr' => __( 'Turkish', 'premium-addons-for-elementor' ),
385 'uk' => __( 'Ukrainian', 'premium-addons-for-elementor' ),
386 'vi' => __( 'Vietnamese', 'premium-addons-for-elementor' ),
387 'zh-CN' => __( 'Chinese (simplified)', 'premium-addons-for-elementor' ),
388 'zh-TW' => __( 'Chinese (traditional)', 'premium-addons-for-elementor' ),
389 );
390 }
391
392 return self::$google_localize;
393 }
394
395 /**
396 * Checks if a plugin is installed
397 *
398 * @since 1.0.0
399 * @access public
400 *
401 * @param string $plugin_path plugin path.
402 *
403 * @return boolean
404 */
405 public static function is_plugin_installed( $plugin_path ) {
406
407 require_once ABSPATH . 'wp-admin/includes/plugin.php';
408
409 $plugins = get_plugins();
410
411 return isset( $plugins[ $plugin_path ] );
412 }
413
414 /**
415 * Check Plugin Active
416 *
417 * @since 4.2.5
418 * @access public
419 *
420 * @param string $slug plugin slug.
421 *
422 * @return boolean $is_active plugin active.
423 */
424 public static function check_plugin_active( $slug = '' ) {
425
426 include_once ABSPATH . 'wp-admin/includes/plugin.php';
427
428 $is_active = in_array( $slug, (array) get_option( 'active_plugins', array() ), true );
429
430 return $is_active;
431 }
432
433 /**
434 * Check if script debug mode enabled.
435 *
436 * @since 3.11.1
437 * @access public
438 *
439 * @return boolean is debug mode enabled
440 */
441 public static function is_debug_enabled() {
442
443 if ( null === self::$script_debug ) {
444
445 self::$script_debug = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG;
446 }
447
448 return self::$script_debug;
449 }
450
451 /**
452 * Get scripts dir.
453 *
454 * @access public
455 *
456 * @return string JS scripts directory.
457 */
458 public static function get_scripts_dir() {
459
460 if ( null === self::$js_dir ) {
461
462 self::$js_dir = self::is_debug_enabled() ? 'js' : 'min-js';
463 }
464
465 return self::$js_dir;
466 }
467
468 /**
469 * Get styles dir.
470 *
471 * @access public
472 *
473 * @return string CSS files directory.
474 */
475 public static function get_styles_dir() {
476
477 if ( null === self::$css_dir ) {
478
479 self::$css_dir = self::is_debug_enabled() ? 'css' : 'min-css';
480 }
481
482 return self::$css_dir;
483 }
484
485 /**
486 * Get assets suffix.
487 *
488 * @access public
489 *
490 * @return string JS scripts suffix.
491 */
492 public static function get_assets_suffix() {
493
494 if ( null === self::$assets_suffix ) {
495
496 self::$assets_suffix = self::is_debug_enabled() ? '' : '.min';
497 }
498
499 return self::$assets_suffix;
500 }
501
502 /**
503 * Get Installed Theme
504 *
505 * Returns the active theme slug
506 *
507 * @access public
508 *
509 * @return string theme slug
510 */
511 public static function get_installed_theme() {
512
513 if ( null === self::$current_theme ) {
514
515 $theme = wp_get_theme();
516
517 if ( $theme->parent() ) {
518
519 $theme_name = sanitize_key( $theme->parent()->get( 'Name' ) );
520
521 } else {
522
523 $theme_name = $theme->get( 'Name' );
524
525 $theme_name = sanitize_key( $theme_name );
526
527 }
528
529 self::$current_theme = $theme_name;
530
531 }
532
533 return self::$current_theme;
534 }
535
536 /**
537 * Get Vimeo Video Data
538 *
539 * Get video data using Vimeo API
540 *
541 * @since 3.11.4
542 * @access public
543 *
544 * @param string $video_id video ID.
545 */
546 public static function get_vimeo_video_data( $video_id ) {
547
548 $vimeo_data = get_transient( 'premium_vimeo_' . $video_id );
549
550 if ( $vimeo_data === false ) {
551
552 $vimeo_data = wp_remote_get( 'http://www.vimeo.com/api/v2/video/' . intval( $video_id ) . '.php' );
553
554 if ( is_wp_error( $vimeo_data ) ) {
555 return false;
556 }
557
558 if ( isset( $vimeo_data['response']['code'] ) ) {
559
560 if ( 200 === $vimeo_data['response']['code'] ) {
561
562 $response = maybe_unserialize( $vimeo_data['body'] );
563 $thumbnail = isset( $response[0]['thumbnail_large'] ) ? $response[0]['thumbnail_large'] : false;
564
565 $data = array(
566 'src' => $thumbnail,
567 'url' => $response[0]['user_url'],
568 'portrait' => $response[0]['user_portrait_huge'],
569 'title' => $response[0]['title'],
570 'user' => $response[0]['user_name'],
571 );
572
573 set_transient( 'premium_vimeo_' . $video_id, $data, WEEK_IN_SECONDS );
574
575 return $data;
576
577 }
578 }
579 }
580
581 return $vimeo_data;
582 }
583
584 /**
585 * Get Video Thumbnail
586 *
587 * Get thumbnail URL for embed or self hosted
588 *
589 * @since 3.7.0
590 * @access public
591 *
592 * @param string $video_id video ID.
593 * @param string $type embed type.
594 * @param string $size youtube thumbnail size.
595 */
596 public static function get_video_thumbnail( $video_id, $type, $size = '' ) {
597
598 $thumbnail_src = 'transparent';
599
600 if ( 'youtube' === $type ) {
601 if ( '' === $size ) {
602 $size = 'maxresdefault';
603 }
604 $thumbnail_src = sprintf( 'https://i.ytimg.com/vi/%s/%s.jpg', $video_id, $size );
605
606 } elseif ( 'vimeo' === $type ) {
607
608 $vimeo = self::get_vimeo_video_data( $video_id );
609
610 $thumbnail_src = is_array( $vimeo ) ? $vimeo['src'] : '';
611
612 } elseif ( 'dailymotion' === $type ) {
613 $video_data = wp_remote_get( 'https://api.dailymotion.com/video/' . $video_id . '?fields=thumbnail_url' );
614
615 if ( is_wp_error( $video_data ) || 200 !== wp_remote_retrieve_response_code( $video_data ) ) {
616 return $thumbnail_src;
617 }
618
619 $video_data = wp_remote_retrieve_body( $video_data );
620 $video_data = json_decode( $video_data );
621
622 $thumbnail_src = $video_data->thumbnail_url;
623 }
624
625 return $thumbnail_src;
626 }
627
628 /**
629 * Transient Expire
630 *
631 * Gets expire time of transient.
632 *
633 * @since 3.20.8
634 * @access public
635 *
636 * @param string $period transient expiration period.
637 *
638 * @return string $expire_time expire time in seconds.
639 */
640 public static function transient_expire( $period ) {
641
642 $expire_time = 24 * HOUR_IN_SECONDS;
643
644 switch ( $period ) {
645 case 'minute':
646 $expire_time = MINUTE_IN_SECONDS;
647 break;
648 case 'minutes':
649 $expire_time = 5 * MINUTE_IN_SECONDS;
650 break;
651 case 'hour':
652 $expire_time = 60 * MINUTE_IN_SECONDS;
653 break;
654 case 'week':
655 $expire_time = 7 * DAY_IN_SECONDS;
656 break;
657 case 'month':
658 $expire_time = 30 * DAY_IN_SECONDS;
659 break;
660 case 'year':
661 $expire_time = 365 * DAY_IN_SECONDS;
662 break;
663 default:
664 $expire_time = 24 * HOUR_IN_SECONDS;
665 }
666
667 return $expire_time;
668 }
669
670 /**
671 * Get Campaign Link
672 *
673 * @since 3.20.9
674 * @access public
675 *
676 * @param string $link page link.
677 * @param string $source source.
678 * @param string $medium media.
679 * @param string $campaign campaign name.
680 *
681 * @return string $link campaign URL
682 */
683 public static function get_campaign_link( $link, $source, $medium, $campaign = '' ) {
684
685 if ( null === self::$current_theme ) {
686 self::get_installed_theme();
687 }
688
689 $args = array(
690 'utm_source' => $source,
691 'utm_medium' => $medium,
692 'utm_campaign' => $campaign,
693 'utm_term' => self::$current_theme,
694 );
695
696 $args = array_filter( $args );
697
698 $url = add_query_arg( $args, $link );
699
700 return $url;
701 }
702
703 /**
704 * Get Elementor UI Theme
705 *
706 * Detects user setting for UI theme
707 *
708 * @since 3.21.1
709 * @access public
710 *
711 * @return string $theme UI Theme
712 */
713 public static function get_elementor_ui_theme() {
714
715 $theme = SettingsManager::get_settings_managers( 'editorPreferences' )->get_model()->get_settings( 'ui_theme' );
716
717 return $theme;
718 }
719
720 /**
721 * Check PAPRO Version
722 *
723 * Check if PAPRO version is updated
724 *
725 * @since 3.21.6
726 * @access public
727 *
728 * @return boolean
729 */
730 public static function check_papro_version() {
731 return defined( 'PREMIUM_PRO_ADDONS_VERSION' );
732 }
733
734 /**
735 * Check Elementor Version
736 *
737 * Check if Elementor is installed and activated
738 *
739 * @since 4.11.54
740 * @access public
741 *
742 * @return boolean
743 */
744 public static function check_elementor_version() {
745 return defined( 'ELEMENTOR_VERSION' ) && class_exists( 'Elementor\Plugin' );
746 }
747
748 /**
749 * Validate HTML Tag
750 *
751 * Validates an HTML tag against a safe allowed list.
752 *
753 * @param string $tag HTML tag.
754 *
755 * @return string
756 */
757 public static function validate_html_tag( $tag ) {
758 return in_array( strtolower( $tag ), self::ALLOWED_HTML_WRAPPER_TAGS, true ) ? $tag : 'div';
759 }
760
761 /**
762 * Get Image Data
763 *
764 * Returns image data based on image id.
765 *
766 * @since 0.0.1
767 * @access public
768 *
769 * @param int $image_id Image ID.
770 * @param string $image_url Image URL.
771 * @param array $image_size Image sizes array.
772 *
773 * @return array $data image data.
774 */
775 public static function get_image_data( $image_id, $image_url, $image_size ) {
776
777 if ( ! $image_id && ! $image_url ) {
778 return false;
779 }
780
781 $data = array();
782
783 $image_url = esc_url_raw( $image_url );
784
785 if ( ! empty( $image_id ) ) { // Existing attachment.
786
787 $attachment = get_post( $image_id );
788
789 if ( is_object( $attachment ) ) {
790 $data['id'] = $image_id;
791 $data['url'] = $image_url;
792
793 $data['image'] = wp_get_attachment_image( $attachment->ID, $image_size, true );
794 $data['image_size'] = $image_size;
795 $data['caption'] = $attachment->post_excerpt;
796 $data['title'] = $attachment->post_title;
797 $data['description'] = $attachment->post_content;
798
799 }
800 } else { // Placeholder image, most likely.
801
802 if ( empty( $image_url ) ) {
803 return;
804 }
805
806 $data['id'] = false;
807 $data['url'] = $image_url;
808 $data['image'] = '<img src="' . $image_url . '" alt="" title="" />';
809 $data['image_size'] = $image_size;
810 $data['caption'] = '';
811 $data['title'] = '';
812 $data['description'] = '';
813 }
814
815 return $data;
816 }
817
818 /**
819 * Returns the current page id.
820 * get_the_ID returns the first product ID in the loop if it's the shop page.
821 * and it sometimes returns a wrong ID in the other cases.
822 *
823 * @access public
824 * @since 4.11.8
825 * @return int
826 */
827 public static function pa_get_current_page_id() {
828
829 if ( class_exists( 'woocommerce' ) ) {
830
831 switch ( true ) {
832 case is_shop():
833 $page_id = wc_get_page_id( 'shop' );
834 break;
835
836 case is_cart():
837 $page_id = wc_get_page_id( 'cart' );
838 break;
839
840 case is_checkout():
841 $page_id = wc_get_page_id( 'checkout' );
842 break;
843
844 case is_account_page():
845 $page_id = wc_get_page_id( 'myaccount' );
846 break;
847
848 default:
849 $page_id = get_the_ID();
850 break;
851 }
852 } else {
853 $page_id = get_the_ID();
854 }
855
856 return $page_id;
857 }
858
859 /**
860 * Get Final Result.
861 *
862 * @access public
863 * @since 4.4.8
864 *
865 * @param bool $condition_result result.
866 * @param string $operator operator.
867 *
868 * @return bool
869 */
870 public static function get_final_result( $condition_result, $operator ) {
871
872 if ( 'is' === $operator ) {
873 return true === $condition_result;
874 } else {
875 return true !== $condition_result;
876 }
877 }
878
879 /**
880 * Get Local Time ( WordPress TimeZone Setting ).
881 *
882 * @access public
883 * @since 4.4.8
884 *
885 * @param string $format format.
886 */
887 public static function get_local_time( $format ) {
888
889 $local_time_zone = isset( $_COOKIE['localTimeZone'] ) && ! empty( $_COOKIE['localTimeZone'] ) ?
890 str_replace( 'GMT ', 'GMT+', sanitize_text_field( wp_unslash( $_COOKIE['localTimeZone'] ) ) )
891 : self::get_location_time_zone();
892
893 // $today = new \DateTime( 'now', new \DateTimeZone( $local_time_zone ) );
894
895 try {
896 $today = new \DateTime( 'now', new \DateTimeZone( $local_time_zone ) );
897 } catch ( \Exception $e ) {
898 $today = new \DateTime( 'now', new \DateTimeZone( 'UTC' ) );
899 }
900
901 return $today->format( $format );
902 }
903
904 /**
905 * Gets the user's timezone based on his ip address.
906 *
907 * @access public
908 * @since 4.10.26
909 *
910 * @return string
911 */
912 public static function get_location_time_zone() {
913
914 $ip_address = self::get_user_ip_address();
915
916 return self::get_timezone_by_ip( $ip_address );
917 }
918
919 /**
920 * Get user's IP address.
921 *
922 * @access public
923 * @since 4.10.26
924 *
925 * @return string
926 */
927 public static function get_user_ip_address() {
928
929 if ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
930
931 $x_forward = sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ) );
932
933 if ( is_array( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
934
935 $http_x_headers = explode( ',', filter_var_array( $x_forward ) );
936 $_SERVER['REMOTE_ADDR'] = $http_x_headers[0];
937 } else {
938 $_SERVER['REMOTE_ADDR'] = $x_forward;
939 }
940 }
941
942 return isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '';
943 }
944
945 /**
946 * Get timezone by ip address.
947 *
948 * @access public
949 * @since 4.10.26
950 *
951 * @param string $ip_address user's ip address.
952 *
953 * @return string
954 */
955 public static function get_timezone_by_ip( $ip_address ) {
956
957 if ( '127.0.0.1' === $ip_address || empty( $ip_address ) ) {
958 return date_default_timezone_get();
959 }
960
961 $location_data = wp_remote_get(
962 'https://api.findip.net/' . $ip_address . '/?token=e21d68c353324af0af206c907e77ff97',
963 array(
964 'timeout' => 15,
965 'sslverify' => false,
966 )
967 );
968
969 if ( is_wp_error( $location_data ) || empty( $location_data ) ) {
970 return date_default_timezone_get(); // localhost.
971 }
972
973 $location_data = json_decode( wp_remote_retrieve_body( $location_data ), true );
974
975 $time_zone = strtolower( $location_data['location']['time_zone'] );
976
977 return $time_zone;
978 }
979
980 /**
981 * Get Site Server Time ( WordPress TimeZone Setting ).
982 *
983 * @access public
984 * @since 4.4.8
985 *
986 * @param string $format format.
987 */
988 public static function get_site_server_time( $format ) {
989
990 $today = gmdate( $format, strtotime( 'now' ) + ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) );
991
992 return $today;
993 }
994
995 /**
996 * Get All Breakpoints.
997 *
998 * @param string $type result return type.
999 *
1000 * @access public
1001 * @since 4.6.1
1002 *
1003 * @return array $devices enabled breakpoints.
1004 */
1005 public static function get_all_breakpoints( $type = 'assoc' ) {
1006
1007 $devices = array(
1008 'desktop' => __( 'Desktop', 'elementor' ),
1009 'tablet' => __( 'Tablet', 'elementor' ),
1010 'mobile' => __( 'Mobile', 'elementor' ),
1011 );
1012
1013 $method_available = method_exists( Plugin::$instance->breakpoints, 'has_custom_breakpoints' );
1014
1015 if ( ( defined( 'ELEMENTOR_VERSION' ) && version_compare( ELEMENTOR_VERSION, '3.4.0', '>' ) ) && $method_available ) {
1016
1017 if ( Plugin::$instance->breakpoints->has_custom_breakpoints() ) {
1018 $devices = array_merge(
1019 $devices,
1020 array(
1021 'widescreen' => __( 'Widescreen', 'elementor' ),
1022 'laptop' => __( 'Laptop', 'elementor' ),
1023 'tablet_extra' => __( 'Tablet Extra', 'elementor' ),
1024 'mobile_extra' => __( 'Mobile Extra', 'elementor' ),
1025 )
1026 );
1027 }
1028 }
1029
1030 if ( 'keys' === $type ) {
1031 $devices = array_keys( $devices );
1032 }
1033
1034 return $devices;
1035 }
1036
1037 /**
1038 * Get WordPress language prefixes.
1039 *
1040 * @since 4.4.8
1041 * @access public
1042 *
1043 * @return array
1044 */
1045 public static function get_lang_prefixes() {
1046
1047 if ( null === self::$lang_locales ) {
1048
1049 $langs = require_once PREMIUM_ADDONS_PATH . 'includes/pa-display-conditions/lang-locale.php';
1050
1051 foreach ( $langs as $lang => $props ) {
1052 /* translators: %s: Language Name */
1053 $val = ucwords( $props['name'] );
1054 self::$lang_locales[ $lang ] = $val;
1055 }
1056 }
1057
1058 return self::$lang_locales;
1059 }
1060
1061 /**
1062 * Get Woocommerce Categories.
1063 *
1064 * @access public
1065 * @since 4.4.8
1066 *
1067 * @param string $id array key.
1068 *
1069 * @return array
1070 */
1071 public static function get_woo_categories( $id = 'slug' ) {
1072
1073 $product_cat = array();
1074
1075 $cat_args = array(
1076 'taxonomy' => 'product_cat',
1077 'orderby' => 'name',
1078 'order' => 'asc',
1079 'hide_empty' => false,
1080 );
1081
1082 $product_categories = get_terms( $cat_args );
1083
1084 if ( ! empty( $product_categories ) ) {
1085
1086 foreach ( $product_categories as $key => $category ) {
1087
1088 $cat_id = 'slug' === $id ? $category->slug : $category->term_id;
1089 $product_cat[ $cat_id ] = $category->name;
1090
1091 }
1092 }
1093
1094 return $product_cat;
1095 }
1096
1097 /**
1098 * Check Elementor Experiment
1099 *
1100 * Check if an Elementor experiment is enabled.
1101 *
1102 * @since 4.8.6
1103 * @access public
1104 *
1105 * @param string $experiment feature ID.
1106 *
1107 * @return boolean $is_enabled is feature enabled.
1108 */
1109 public static function check_elementor_experiment( $experiment ) {
1110
1111 $experiments_manager = Plugin::$instance->experiments;
1112
1113 $is_enabled = $experiments_manager->is_feature_active( $experiment );
1114
1115 return $is_enabled;
1116 }
1117
1118 /**
1119 * Is Edit Mode.
1120 *
1121 * @access public
1122 * @since 4.6.1
1123 *
1124 * @return boolean
1125 */
1126 public static function is_edit_mode() {
1127 return isset( $_REQUEST['elementor-preview'] ) && ! empty( $_REQUEST['elementor-preview'] ); // phpcs:ignore WordPress.Security.NonceVerification
1128 }
1129
1130 /**
1131 * Generate Unique ID
1132 *
1133 * Generates a unique ID for the current page.
1134 *
1135 * @since 4.6.9
1136 * @access public
1137 *
1138 * @param string $id page ID.
1139 *
1140 * @return string unique ID.
1141 */
1142 public static function generate_unique_id( $id ) {
1143 return substr( md5( $id ), 0, 9 );
1144 }
1145
1146 /**
1147 * Get Safe Path
1148 *
1149 * @since 4.6.9
1150 * @access public
1151 *
1152 * @param string $file_path unsafe file path.
1153 *
1154 * @return string safe file path.
1155 */
1156 public static function get_safe_path( $file_path ) {
1157
1158 $path = str_replace( array( '//', '\\\\' ), array( '/', '\\' ), $file_path );
1159
1160 return str_replace( array( '/', '\\' ), DIRECTORY_SEPARATOR, $path );
1161 }
1162
1163 public static function get_safe_url( $url ) {
1164 if ( is_ssl() ) {
1165 $url = wp_parse_url( $url );
1166
1167 if ( ! empty( $url['host'] ) ) {
1168 $url['scheme'] = 'https';
1169 }
1170
1171 return self::unparse_url( $url );
1172 }
1173
1174 return $url;
1175 }
1176
1177 public static function unparse_url( $parsed_url ) {
1178 $scheme = isset( $parsed_url['scheme'] ) ? $parsed_url['scheme'] . '://' : '';
1179 $host = isset( $parsed_url['host'] ) ? $parsed_url['host'] : '';
1180 $port = isset( $parsed_url['port'] ) ? ':' . $parsed_url['port'] : '';
1181 $user = isset( $parsed_url['user'] ) ? $parsed_url['user'] : '';
1182 $pass = isset( $parsed_url['pass'] ) ? ':' . $parsed_url['pass'] : '';
1183 $pass = ( $user || $pass ) ? "$pass@" : '';
1184 $path = isset( $parsed_url['path'] ) ? $parsed_url['path'] : '';
1185 $query = isset( $parsed_url['query'] ) ? '?' . $parsed_url['query'] : '';
1186 $fragment = isset( $parsed_url['fragment'] ) ? '#' . $parsed_url['fragment'] : '';
1187
1188 return "$scheme$user$pass$host$port$path$query$fragment";
1189 }
1190
1191 /**
1192 * Check if the current post type should include addons.
1193 *
1194 * @param string $id current post ID.
1195 *
1196 * @since 4.9.18
1197 * @access public
1198 */
1199 public static function check_post_type( $id ) {
1200
1201 if ( ! $id ) {
1202 return false;
1203 }
1204
1205 $template_name = get_post_meta( $id, '_elementor_template_type', true );
1206
1207 $template_list = array(
1208 'header',
1209 'footer',
1210 'single',
1211 'post',
1212 'page',
1213 'archive',
1214 'search-results',
1215 'error-404',
1216 'product',
1217 'product-archive',
1218 'section',
1219 );
1220
1221 return in_array( $template_name, $template_list );
1222 }
1223
1224 /**
1225 * Get Draw SVG Notice
1226 *
1227 * @since 4.9.26
1228 * @access public
1229 *
1230 * @param object $elem element object.
1231 * @param string $search search query.
1232 * @param array $conditions control conditions
1233 */
1234 public static function get_draw_svg_notice( $elem, $search, $conditions, $index = 0, $nested = 'condition' ) {
1235
1236 $url = add_query_arg(
1237 array(
1238 'page' => 'premium-addons',
1239 'search' => $search,
1240 '#tab' => 'elements',
1241 ),
1242 esc_url( admin_url( 'admin.php' ) )
1243 );
1244
1245 $control_attr = array(
1246 'type' => Controls_Manager::RAW_HTML,
1247 'raw' => __( 'You need first to enable SVG Draw option checkbox from ', 'premium-addons-for-elementor' ) . '<a href="' . esc_url( $url ) . '" target="_blank">' . __( 'here.', 'premium-addons-for-elementor' ) . '</a>',
1248 'classes' => 'editor-pa-control-notice',
1249 'content_classes' => 'elementor-panel-alert elementor-panel-alert-warning',
1250 );
1251
1252 $control_attr[ $nested ] = $conditions;
1253
1254 $elem->add_control(
1255 'draw_svg_notice_' . $index,
1256 $control_attr
1257 );
1258 }
1259
1260 /**
1261 * Checks if Elementor PRO 3.8 or higher is activated && if the Loop experiment is activated.
1262 *
1263 * @since 4.9.45
1264 * @access public
1265 *
1266 * @return bool
1267 */
1268 public static function is_loop_exp_enabled() {
1269
1270 if ( defined( 'ELEMENTOR_PRO_VERSION' ) ) {
1271
1272 if ( version_compare( ELEMENTOR_PRO_VERSION, '3.16.0', '>=' ) ) {
1273 return true;
1274 } elseif ( version_compare( ELEMENTOR_PRO_VERSION, '3.8', '>=' ) ) {
1275 $is_loop_enabled = self::check_elementor_experiment( 'loop' );
1276
1277 if ( $is_loop_enabled ) {
1278 return true;
1279 }
1280 }
1281 }
1282
1283 return false;
1284 }
1285
1286 /**
1287 * Get Element Classes.
1288 *
1289 * @access private
1290 * @since 2.8.22
1291 *
1292 * @param array $devices devices to hide on.
1293 *
1294 * @return array
1295 */
1296 public static function get_element_classes( $devices, $default = array() ) {
1297
1298 $classes = $default;
1299
1300 if ( count( $devices ) ) {
1301 foreach ( $devices as $index => $device ) {
1302 array_push( $classes, 'elementor-hidden-' . $device );
1303 }
1304
1305 array_push( $classes, 'premium-addons-element' );
1306 }
1307
1308 return $classes;
1309 }
1310
1311 /**
1312 * Round Numbers In A Reading-friendly Format.
1313 *
1314 * @param integer $num followers number.
1315 */
1316 public static function premium_format_numbers( $num ) {
1317 $num = intval( $num );
1318 $result = '';
1319
1320 if ( $num >= 1000000000 ) {
1321 $tmp = round( ( $num / 1000000 ), 1 );
1322 $result = $tmp . 'B';
1323 return $result;
1324 }
1325
1326 if ( $num >= 1000000 ) {
1327 $tmp = round( ( $num / 1000000 ), 1 );
1328 $result = $tmp . 'M';
1329 return $result;
1330 }
1331
1332 if ( $num >= 1000 ) {
1333 $tmp = round( ( $num / 1000 ), 1 );
1334 $result = $tmp . 'K';
1335
1336 return $result;
1337 }
1338
1339 return round( $num, 1 );
1340 }
1341
1342 /**
1343 * Render Rating Stars
1344 *
1345 * @since 4.10.13
1346 * @access public
1347 *
1348 * @param float $rating rating score.
1349 * @param string $fill_color fill color.
1350 * @param string $empty_color empty color.
1351 * @param float $star_size star size.
1352 */
1353 public static function render_rating_stars( $rating, $fill_color, $empty_color, $star_size ) {
1354
1355 ?>
1356
1357 <span class="premium-fb-rev-stars">
1358 <?php
1359
1360 foreach ( array( 1, 2, 3, 4, 5 ) as $val ) {
1361 $score = round( ( $rating - $val ), 2 );
1362
1363 if ( $score >= -0.2 ) {
1364
1365 ?>
1366 <span class="premium-fb-rev-star"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" version="1.1" width="<?php echo esc_attr( $star_size ); ?>" height="<?php echo esc_attr( $star_size ); ?>" viewBox="0 0 1792 1792"><path d="M1728 647q0 22-26 48l-363 354 86 500q1 7 1 20 0 21-10.5 35.5t-30.5 14.5q-19 0-40-12l-449-236-449 236q-22 12-40 12-21 0-31.5-14.5t-10.5-35.5q0-6 2-20l86-500-364-354q-25-27-25-48 0-37 56-46l502-73 225-455q19-41 49-41t49 41l225 455 502 73q56 9 56 46z" fill="<?php echo esc_attr( $fill_color ); ?>"></path></svg></span>
1367 <?php
1368 } elseif ( $score > -0.8 && $score < -0.2 ) {
1369 ?>
1370 <span class="premium-fb-rev-star"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" version="1.1" width="<?php echo esc_attr( $star_size ); ?>" height="<?php echo esc_attr( $star_size ); ?>" viewBox="0 0 1792 1792"><path d="M1250 957l257-250-356-52-66-10-30-60-159-322v963l59 31 318 168-60-355-12-66zm452-262l-363 354 86 500q5 33-6 51.5t-34 18.5q-17 0-40-12l-449-236-449 236q-23 12-40 12-23 0-34-18.5t-6-51.5l86-500-364-354q-32-32-23-59.5t54-34.5l502-73 225-455q20-41 49-41 28 0 49 41l225 455 502 73q45 7 54 34.5t-24 59.5z" fill="<?php echo esc_attr( $fill_color ); ?>"></path></svg></span>
1371 <?php } else { ?>
1372 <span class="premium-fb-rev-star"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" version="1.1" width="<?php echo esc_attr( $star_size ); ?>" height="<?php echo esc_attr( $star_size ); ?>" viewBox="0 0 1792 1792"><path d="M1201 1004l306-297-422-62-189-382-189 382-422 62 306 297-73 421 378-199 377 199zm527-357q0 22-26 48l-363 354 86 500q1 7 1 20 0 50-41 50-19 0-40-12l-449-236-449 236q-22 12-40 12-21 0-31.5-14.5t-10.5-35.5q0-6 2-20l86-500-364-354q-25-27-25-48 0-37 56-46l502-73 225-455q19-41 49-41t49 41l225 455 502 73q56 9 56 46z" fill="<?php echo esc_attr( $empty_color ); ?>"></path></svg></span>
1373 <?php
1374 }
1375 }
1376 ?>
1377 </span>
1378
1379 <?php
1380 }
1381
1382
1383 /**
1384 * Get SVG Shapes
1385 *
1386 * @since 4.10.13
1387 * @access public
1388 */
1389 public static function get_svg_shapes( $shape = '' ) {
1390
1391 if ( null === self::$shapes ) {
1392
1393 self::$shapes = require PREMIUM_ADDONS_PATH . 'addons/shapes.php';
1394
1395 }
1396
1397 $shapes = self::$shapes;
1398
1399 if ( empty( $shape ) ) {
1400 return $shapes;
1401 } else {
1402 return $shapes[ $shape ]['imagesmall'];
1403 }
1404 }
1405
1406 public static function get_btn_svgs( $style = 'line1' ) {
1407
1408 $html = '';
1409
1410 switch ( $style ) {
1411 case 'line1':
1412 $html = '<div class="premium-btn-line-wrap"><svg class="premium-btn-svg" aria-hidden="true" width="100%" height="9" viewBox="0 0 101 9">
1413 <path d="M.426 1.973C4.144 1.567 17.77-.514 21.443 1.48 24.296 3.026 24.844 4.627 27.5 7c3.075 2.748 6.642-4.141 10.066-4.688 7.517-1.2 13.237 5.425 17.59 2.745C58.5 3 60.464-1.786 66 2c1.996 1.365 3.174 3.737 5.286 4.41 5.423 1.727 25.34-7.981 29.14-1.294" pathLength="1"></path>
1414 </svg></div>';
1415 break;
1416
1417 case 'line3':
1418 $html = '<div class="premium-btn-line-wrap"><svg class="premium-btn-svg" aria-hidden="true" width="100%" height="18" viewBox="0 0 59 18">
1419 <path d="M.945.149C12.3 16.142 43.573 22.572 58.785 10.842" pathLength="1"></path>
1420 </svg></div>';
1421 break;
1422
1423 case 'line4':
1424 $html = '<svg class="premium-btn-svg" aria-hidden="true" width="300%" height="100%" viewBox="0 0 1200 60" preserveAspectRatio="none">
1425 <path d="M0,56.5c0,0,298.666,0,399.333,0C448.336,56.5,513.994,46,597,46c77.327,0,135,10.5,200.999,10.5c95.996,0,402.001,0,402.001,0"></path>
1426 </svg>';
1427 break;
1428
1429 default:
1430 // code...
1431 break;
1432 }
1433
1434 return $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1435 }
1436
1437 /**
1438 * Add Button Hover Controls
1439 *
1440 * @since 4.10.17
1441 * @access public
1442 *
1443 * @param object $elem widget object.
1444 * @param array $conditions controls conditions.
1445 */
1446 public static function add_btn_hover_controls( $elem, $conditions ) {
1447
1448 $elem->add_control(
1449 'premium_button_hover_effect',
1450 array(
1451 'label' => __( 'Hover Effect', 'premium-addons-for-elementor' ),
1452 'type' => Controls_Manager::SELECT,
1453 'default' => 'none',
1454 'options' => array(
1455 'none' => __( 'None', 'premium-addons-for-elementor' ),
1456 'style1' => __( 'Slide', 'premium-addons-for-elementor' ),
1457 'style2' => __( 'Shutter', 'premium-addons-for-elementor' ),
1458 'style5' => apply_filters( 'pa_pro_label', __( 'In & Out (Pro)', 'premium-addons-for-elementor' ) ),
1459 'style6' => apply_filters( 'pa_pro_label', __( 'Grow (Pro)', 'premium-addons-for-elementor' ) ),
1460 'style7' => apply_filters( 'pa_pro_label', __( 'Double Layers (Pro)', 'premium-addons-for-elementor' ) ),
1461 'style8' => apply_filters( 'pa_pro_label', __( 'Animated Underline (Pro)', 'premium-addons-for-elementor' ) ),
1462 ),
1463 'separator' => 'before',
1464 'label_block' => true,
1465 'condition' => $conditions,
1466 )
1467 );
1468
1469 $elem->add_control(
1470 'button_hover_effect_notice',
1471 array(
1472 'raw' => __( 'Important: You need to set a background to the button to see the effects.', 'premium-addons-for-elementor' ),
1473 'type' => Controls_Manager::RAW_HTML,
1474 'content_classes' => 'elementor-panel-alert elementor-panel-alert-warning',
1475 'condition' => array_merge(
1476 $conditions,
1477 array(
1478 'premium_button_hover_effect!' => 'none',
1479 )
1480 ),
1481 )
1482 );
1483
1484 do_action( 'pa_button_hover_controls', $elem, $conditions );
1485
1486 $elem->add_control(
1487 'premium_button_style1_dir',
1488 array(
1489 'label' => __( 'Slide Direction', 'premium-addons-for-elementor' ),
1490 'type' => Controls_Manager::SELECT,
1491 'default' => 'bottom',
1492 'options' => array(
1493 'bottom' => __( 'Top to Bottom', 'premium-addons-for-elementor' ),
1494 'top' => __( 'Bottom to Top', 'premium-addons-for-elementor' ),
1495 'left' => __( 'Right to Left', 'premium-addons-for-elementor' ),
1496 'right' => __( 'Left to Right', 'premium-addons-for-elementor' ),
1497 ),
1498 'condition' => array_merge(
1499 $conditions,
1500 array(
1501 'premium_button_hover_effect' => 'style1',
1502 )
1503 ),
1504 'label_block' => true,
1505 )
1506 );
1507
1508 $elem->add_control(
1509 'premium_button_style2_dir',
1510 array(
1511 'label' => __( 'Shutter Direction', 'premium-addons-for-elementor' ),
1512 'type' => Controls_Manager::SELECT,
1513 'default' => 'shutouthor',
1514 'options' => array(
1515 'shutinhor' => __( 'Shutter in Horizontal', 'premium-addons-for-elementor' ),
1516 'shutinver' => __( 'Shutter in Vertical', 'premium-addons-for-elementor' ),
1517 'shutoutver' => __( 'Shutter out Horizontal', 'premium-addons-for-elementor' ),
1518 'shutouthor' => __( 'Shutter out Vertical', 'premium-addons-for-elementor' ),
1519 'scshutoutver' => __( 'Scaled Shutter Vertical', 'premium-addons-for-elementor' ),
1520 'scshutouthor' => __( 'Scaled Shutter Horizontal', 'premium-addons-for-elementor' ),
1521 'dshutinver' => __( 'Tilted Left', 'premium-addons-for-elementor' ),
1522 'dshutinhor' => __( 'Tilted Right', 'premium-addons-for-elementor' ),
1523 ),
1524 'condition' => array_merge(
1525 $conditions,
1526 array(
1527 'premium_button_hover_effect' => 'style2',
1528 )
1529 ),
1530 'label_block' => true,
1531 )
1532 );
1533 }
1534
1535 /**
1536 * Add Templates Controls
1537 *
1538 * @since 4.11.25
1539 * @access public
1540 *
1541 * @param string $keyword keyword for templates.
1542 * @param string $demo demo url.
1543 */
1544 public static function add_templates_controls( $element, $keyword, $demo ) {
1545
1546 if ( ! Admin_Helper::check_element_by_key( 'premium-templates' ) ) {
1547 return;
1548 }
1549
1550 $element->add_control(
1551 'premium_templates_links',
1552 array(
1553 'type' => Controls_Manager::RAW_HTML,
1554 'raw' => '<div class="premium-promote-box widget-box">
1555 <div class="premium-promote-ctas">
1556 <a class="premium-promote-demo elementor-button elementor-button-default" href="' . esc_url( $demo ) . '" target="_blank"> ' .
1557 __( 'Widget Demo', 'premium-addons-for-elementor' ) .
1558 '</a>
1559 <a class="premium-promote-upgrade premium-widget-blocks elementor-button elementor-button-default" href="#" data-keyword="' . esc_attr( $keyword ) . '">' .
1560 __( 'Templates', 'premium-addons-for-elementor' ) .
1561 '</a>
1562 </div>
1563 </div>',
1564 )
1565 );
1566 }
1567
1568 /**
1569 * Add Templates Controls
1570 *
1571 * @since 4.11.29
1572 * @access public
1573 *
1574 * @param string $keyword keyword for templates.
1575 * @param string $demo demo url.
1576 */
1577 public static function register_papro_promotion_controls( $element, $keyword ) {
1578
1579 if ( ! self::check_papro_version() ) {
1580
1581 $pro_link = self::get_campaign_link( 'https://premiumaddons.com/pro/#get-pa-pro', $keyword, 'wp-editor', 'get-pro' );
1582
1583 $element->start_controls_section(
1584 'section_pro_features_field',
1585 array(
1586 'label' => __( 'Go Pro for More Features', 'premium-addons-for-elementor' ),
1587 )
1588 );
1589
1590 $element->add_control(
1591 'pa_pro_promotion_notice',
1592 array(
1593 'type' => Controls_Manager::NOTICE,
1594 'notice_type' => 'info',
1595 'dismissible' => false,
1596 'content' => __( '<b>Build smarter and faster</b> with premium widgets, 580+ container blocks, and advanced customization controls — all available in the <a href="' . esc_url( $pro_link ) . '" target="_blank">PA Pro</a>. <b>Save up to 30%!</b>.', 'premium-addons-for-elementor' ),
1597 )
1598 );
1599
1600 $element->end_controls_section();
1601 }
1602 }
1603
1604 /**
1605 * Register Element Feedback Controls
1606 *
1607 * @since 4.11.36
1608 * @access public
1609 *
1610 * @param object $element widget object.
1611 */
1612 public static function register_element_feedback_controls( $element ) {
1613
1614 $element->add_control(
1615 'feedback_message',
1616 array(
1617 'label' => __( 'Feedback & Feature Request', 'premium-addons-for-elementor' ),
1618 'type' => Controls_Manager::TEXTAREA,
1619 'placeholder' => __( 'Share your feedback or feature request here...', 'premium-addons-for-elementor' ),
1620 'label_block' => true,
1621 'render_type' => 'ui',
1622 'ai' => array(
1623 'active' => false,
1624 ),
1625 )
1626 );
1627
1628 $element->add_control(
1629 'feedback_message_submit',
1630 array(
1631 'type' => Controls_Manager::RAW_HTML,
1632 'raw' => '<form onsubmit="submitFeedbackMessage(this,\'' . $element->get_title() . '\');" action="javascript:void(0);"><input type="submit" value="Send Feedback" class="elementor-button" style="background-color: rgba(207, 211, 215, 0.35); color: #000;"></form>',
1633 'label_block' => true,
1634 )
1635 );
1636
1637 }
1638
1639 /**
1640 * Get Button Class
1641 *
1642 * @since 4.10.17
1643 * @access public
1644 *
1645 * @param $settings object widget settings.
1646 *
1647 * @return string $class css class.
1648 */
1649 public static function get_button_class( $settings ) {
1650
1651 $class = '';
1652
1653 $papro_activated = self::check_papro_version();
1654
1655 if ( ! $papro_activated && ! in_array( $settings['premium_button_hover_effect'], array( 'none', 'style1', 'style2' ) ) ) {
1656 return '';
1657 }
1658
1659 if ( 'style1' === $settings['premium_button_hover_effect'] ) {
1660 $class = 'premium-button-style1-' . $settings['premium_button_style1_dir'];
1661 } elseif ( 'style2' === $settings['premium_button_hover_effect'] ) {
1662 $class = 'premium-button-style2-' . $settings['premium_button_style2_dir'];
1663 } elseif ( 'style5' === $settings['premium_button_hover_effect'] ) {
1664 $class = 'premium-button-style5-' . $settings['premium_button_style5_dir'];
1665 } elseif ( 'style6' === $settings['premium_button_hover_effect'] ) {
1666 $class = 'premium-button-style6';
1667 } elseif ( 'style7' === $settings['premium_button_hover_effect'] ) {
1668 $class = 'premium-button-style7-' . $settings['premium_button_style7_dir'];
1669 } elseif ( 'style8' === $settings['premium_button_hover_effect'] ) {
1670 $class = 'premium-button-' . $settings['underline_style'];
1671 }
1672
1673 return 'premium-button-' . $settings['premium_button_hover_effect'] . ' ' . $class;
1674 }
1675
1676
1677 /**
1678 * Get Empty Query Message
1679 *
1680 * Written in PHP and used to generate the final HTML when the query is empty
1681 *
1682 * @since 4.10.29
1683 * @access protected
1684 *
1685 * @param string $notice empty query notice.
1686 */
1687 public static function render_empty_query_message( $notice ) {
1688
1689 if ( empty( $notice ) ) {
1690 $notice = __( 'The current query has no posts. Please make sure you have published items matching your query.', 'premium-addons-for-elementor' );
1691 }
1692
1693 ?>
1694 <div class="premium-error-notice">
1695 <?php echo wp_kses_post( $notice ); ?>
1696 </div>
1697 <?php
1698 }
1699
1700 /**
1701 * Check Capability
1702 *
1703 * @since 4.10.28
1704 * @access public
1705 *
1706 * @param string $check capability.
1707 */
1708 public static function check_capability( $capability ) {
1709
1710 $post_author_id = get_the_author_meta( 'ID' );
1711
1712 $current_user_can = user_can( $post_author_id, $capability );
1713
1714 return $current_user_can;
1715 }
1716
1717
1718 /**
1719 * Get Allowed Icon Tags
1720 *
1721 * Returns an array of allowed HTML tags.
1722 *
1723 * @since 4.10.69
1724 * @access public
1725 *
1726 * @return array Array of allowed HTML tags.
1727 */
1728 public static function get_allowed_icon_tags() {
1729 return array(
1730 'svg' => array(
1731 'id' => array(),
1732 'class' => array(),
1733 'aria-hidden' => array(),
1734 'aria-labelledby' => array(),
1735 'role' => array(),
1736 'xmlns' => array(),
1737 'width' => array(),
1738 'height' => array(),
1739 'viewbox' => array(),
1740 'data-*' => true,
1741 ),
1742 'g' => array( 'fill' => array() ),
1743 'title' => array( 'title' => array() ),
1744 'path' => array(
1745 'd' => array(),
1746 'fill' => array(),
1747 ),
1748 'i' => array(
1749 'class' => array(),
1750 'id' => array(),
1751 'style' => array(),
1752 ),
1753 );
1754 }
1755
1756 /**
1757 * Get SVG By Icon
1758 *
1759 * @since 4.10.69
1760 * @access public
1761 */
1762 public static function get_svg_by_icon( $icon, $attributes = array() ) {
1763
1764 if ( empty( $icon ) || empty( $icon['value'] ) || empty( $icon['library'] ) ) {
1765 return '';
1766 }
1767
1768 // If icon library is SVG, then go to Elementor. Used for widgets where this function is called in all cases.
1769 if ( false === strpos( $icon['library'], 'fa-' ) ) {
1770
1771 if ( is_string( $attributes ) ) {
1772 $attributes = str_replace( '"', '', $attributes );
1773 }
1774
1775 $svg_html = Icons_Manager::try_get_icon_html( $icon, wp_parse_args( $attributes, array( 'aria-hidden' => 'true' ) ) );
1776
1777 return $svg_html;
1778 }
1779
1780 $icon['font_family'] = 'font-awesome';
1781
1782 $i_class = str_replace( ' ', '-', $icon['value'] );
1783
1784 $svg_html = '<svg ';
1785
1786 $icon = self::get_icon_svg_data( $icon );
1787
1788 if ( ! $icon ) {
1789 // Icons_Manager::render_icon( $icon, array( 'aria-hidden' => 'true' ) );
1790 Icons_Manager::render_icon( $icon, wp_parse_args( $attributes, array( 'aria-hidden' => 'true' ) ) );
1791 return;
1792 }
1793
1794 $view_box = '0 0 ' . $icon['width'] . ' ' . $icon['height'];
1795
1796 if ( is_array( $attributes ) ) {
1797
1798 foreach ( $attributes as $key => $value ) {
1799
1800 if ( 'class' === $key ) {
1801
1802 $svg_html .= 'class="svg-inline--' . $i_class . ' ' . $value . '" ';
1803
1804 } else {
1805 $svg_html .= " {$key}='{$value}' ";
1806 }
1807 }
1808 } else {
1809
1810 $attributes = str_replace( 'class="', 'class="svg-inline--' . $i_class . ' ', $attributes );
1811
1812 $svg_html .= $attributes;
1813 }
1814
1815 $svg_html .= " aria-hidden='true' xmlns='http://www.w3.org/2000/svg' viewBox='{$view_box}'>";
1816
1817 $svg_html .= '<path d="' . esc_attr( $icon['path'] ) . '"></path>';
1818 $svg_html .= '</svg>';
1819
1820 return wp_kses( $svg_html, self::get_allowed_icon_tags() );
1821 }
1822
1823 /**
1824 * Get Elementor Template ID
1825 *
1826 * @since 4.10.80
1827 * @access public
1828 *
1829 * @param string $title template title.
1830 *
1831 * @return string $template_id template ID.
1832 */
1833 public static function get_elementor_template_id( $title ) {
1834
1835 if ( empty( $title ) ) {
1836 return;
1837 }
1838
1839 $args = array(
1840 'post_type' => 'elementor_library',
1841 'post_status' => 'publish',
1842 'posts_per_page' => 1,
1843 'title' => $title,
1844 'suppress_filters' => true,
1845 );
1846
1847 $query = new \WP_Query( $args );
1848
1849 $post_id = '';
1850
1851 if ( $query->have_posts() ) {
1852 $post_id = $query->post->ID;
1853
1854 wp_reset_postdata();
1855 }
1856
1857 return $post_id;
1858 }
1859
1860 /**
1861 * Render Elementor Template
1862 *
1863 * @since 4.10.80
1864 * @access public
1865 *
1866 * @param string|int $title Template Title||id.
1867 * @param bool $id indicates if $title is the template title or id.
1868 *
1869 * @return $template_content string HTML Markup of the selected template.
1870 */
1871 public static function render_elementor_template( $title, $id = false ) {
1872
1873 $frontend = Plugin::$instance->frontend;
1874
1875 $custom_temp = apply_filters( 'pa_temp_id', false );
1876
1877 if ( $custom_temp ) {
1878 $id = $title = $custom_temp;
1879 }
1880
1881 if ( ! $id ) {
1882 $id = self::get_elementor_template_id( $title );
1883
1884 if ( ! $id ) {
1885 // To replace the &#8211; in templates names with dash.
1886 $decoded_title = html_entity_decode( $title );
1887 $id = self::get_elementor_template_id( $decoded_title );
1888 }
1889
1890 $id = apply_filters( 'wpml_object_id', $id, 'elementor_library', true );
1891 } else {
1892 $id = $title;
1893 }
1894
1895 // $template_content = $frontend->get_builder_content( $id, true );
1896 $template_content = $frontend->get_builder_content_for_display( $id, true );
1897
1898 return $template_content;
1899 }
1900
1901 /**
1902 * Get Device Type
1903 *
1904 * @since 4.11.50
1905 * @access public
1906 *
1907 * @return string device type.
1908 */
1909 public static function get_device_type() {
1910
1911 static $device_type = null;
1912
1913 // Return cached result if already detected.
1914 if ( null !== $device_type ) {
1915 return $device_type;
1916 }
1917
1918 // Default to desktop.
1919 $device_type = 'desktop';
1920
1921 // Only load Device_Detector if not already loaded.
1922 if ( ! class_exists( 'PremiumAddons\Includes\Helpers\Device_Detector' ) ) {
1923 require_once PREMIUM_ADDONS_PATH . 'includes/helpers/device-detector.php';
1924 }
1925
1926 $detect = new Helpers\Device_Detector();
1927
1928 // Detect device type with priority: tablet > mobile > desktop.
1929 if ( $detect->isTablet() ) {
1930 $device_type = 'tablet';
1931 } elseif ( $detect->isMobile() ) {
1932 $device_type = 'mobile';
1933 }
1934
1935 return $device_type;
1936 }
1937
1938 /**
1939 * Get Widget Class Name
1940 *
1941 * @since 4.11.51
1942 * @access public
1943 *
1944 * @param string $widget_key Widget slug/key, e.g. 'premium-banner'.
1945 * @return string|false Fully-qualified class name on success, false on failure.
1946 */
1947 public static function get_widget_class_name( $widget_key ) {
1948
1949 static $classes_list = null;
1950
1951 $default_namespace = 'PremiumAddons\\Widgets\\';
1952
1953 // load the map once.
1954 if ( null === $classes_list ) {
1955
1956 $map_file = PREMIUM_ADDONS_PATH . 'includes/helpers/widget-class-map.php';
1957
1958 if ( file_exists( $map_file ) ) {
1959
1960 $map = include $map_file;
1961 $classes_list = is_array( $map ) ? $map : array();
1962 } else {
1963 $classes_list = array();
1964 }
1965 }
1966
1967 if ( empty( $widget_key ) || ! is_string( $widget_key ) ) {
1968 return false;
1969 }
1970
1971 if ( ! isset( $classes_list[ $widget_key ] ) ) {
1972 return false;
1973 }
1974
1975 $class_name = $classes_list[ $widget_key ];
1976
1977 if ( is_string( $class_name ) && false !== strpos( $class_name, '\\' ) ) {
1978 return $class_name;
1979 }
1980
1981 // Otherwise treat as short class name and prepend the default namespace.
1982 $short_class = (string) $class_name;
1983 $full_class = rtrim( $default_namespace, '\\' ) . '\\' . ltrim( $short_class, '\\' );
1984
1985 return $full_class;
1986 }
1987
1988 /**
1989 * Get Enabled Widgets
1990 *
1991 * @since 4.11.54
1992 * @access public
1993 *
1994 * @return array enabled widgets.
1995 */
1996 public static function get_enabled_widgets() {
1997
1998 $enabled_elements = Admin_Helper::get_enabled_elements();
1999
2000 $enabled_elements = array_filter(
2001 $enabled_elements,
2002 function ( $value, $key ) {
2003 return ( strpos( $key, 'premium-' ) === 0 || strpos( $key, 'mini-' ) === 0 || strpos( $key, 'woo-' ) === 0 ) && filter_var( $value, FILTER_VALIDATE_BOOLEAN );
2004 },
2005 ARRAY_FILTER_USE_BOTH
2006 );
2007
2008 return array_keys( $enabled_elements );
2009 }
2010
2011 /*
2012 * Get Enabled Widgets Names
2013 *
2014 * @since 4.11.54
2015 * @access public
2016 *
2017 * @return array enabled widgets names.
2018 */
2019 public static function get_enabled_widgets_names() {
2020
2021 $enabled_elements = self::get_enabled_widgets();
2022
2023 $enabled_names = array();
2024
2025 $map_file = PREMIUM_ADDONS_PATH . 'includes/helpers/widget-name-map.php';
2026
2027 if ( file_exists( $map_file ) ) {
2028
2029 $map = include $map_file;
2030 $names_list = is_array( $map ) ? $map : array();
2031 } else {
2032 $names_list = array();
2033 }
2034
2035 foreach ( $enabled_elements as $key ) {
2036
2037 $widget_name = isset( $names_list[ $key ] ) ? $names_list[ $key ] : $key;
2038 $enabled_names[] = $widget_name;
2039 }
2040
2041 return $enabled_names;
2042 }
2043 }
2044