PluginProbe
Adminify – White Label, Admin Menu Editor, Login Customizer / 4.2.25
Adminify – White Label, Admin Menu Editor, Login Customizer v4.2.25
4.3.1 4.3.0 4.2.26 4.2.25 4.2.24 4.2.23 4.2.22 4.2.21 4.2.20 4.2.19 4.2.18 4.2.17 4.2.16 4.2.15 4.2.14 4.2.13 4.2.12 4.2.11 4.2.10 4.2.9 4.2.8 4.2.7 4.2.6 4.2.5 4.1.17 All 164 releases
adminify / Inc / utils.php

utils.php in Adminify – White Label, Admin Menu Editor, Login Customizer 4.2.25, at Inc/utils.php

1,426 lines 46.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace PXLBSAdminify\Inc;
4
5 // no direct access allowed
6 if (!defined('ABSPATH')) {
7 exit;
8 }
9
10 class Utils
11 {
12 public $post_types = '';
13
14 /**
15 * Check if the Module is Enable/Disable
16 *
17 * @param [type] $value
18 *
19 * @return void
20 */
21 public static function check_modules($value)
22 {
23 if (empty($value)) {
24 return;
25 } else {
26 return true;
27 }
28 }
29
30 /**
31 * Check given value empty or not
32 *
33 * @param [type] $value
34 *
35 * @return void
36 */
37 public static function check_is_empty($value, $default = '')
38 {
39 $value = !empty(esc_attr($value)) ? $value : $default;
40 return $value;
41 }
42
43
44 /**
45 * Check hidden for roles or not
46 *
47 * @param [type] $value
48 *
49 * @return bool
50 */
51 public static function restricted_for($disabled_for)
52 {
53 if (empty($disabled_for)) {
54 return false;
55 }
56
57 // wp_get_current_user() lives in wp-includes/pluggable.php and is
58 // always available in normal plugin execution. If it is somehow
59 // unavailable (e.g. very early bootstrap), bail out instead of
60 // manually loading core files, which is disallowed by the
61 // WordPress.org plugin guidelines.
62 if (!function_exists('wp_get_current_user')) {
63 return false;
64 }
65
66 $restrict_for = array();
67
68 if (!is_array($disabled_for)) {
69 $restrict_for[] = $disabled_for;
70 } else {
71 $restrict_for = $disabled_for;
72 }
73
74
75 $current_user = wp_get_current_user();
76 $current_name = $current_user->display_name;
77 $current_roles = $current_user->roles;
78 // $all_roles = wp_roles()->get_names();
79
80 if (in_array($current_name, $restrict_for)) {
81 return true;
82 }
83
84 // if (in_array('Super Admin', $restrict_for) || in_array('administrator', $restrict_for)) {
85 // return true;
86 // }
87
88 // Super Admin for Multisite
89 if (is_super_admin() && is_multisite()) {
90 if (in_array('Super Admin', $restrict_for) || in_array('administrator', $restrict_for)) {
91 return true;
92 } else {
93 return false;
94 }
95 }
96
97 $formattedroles = [];
98
99 foreach ($restrict_for as $item) {
100 $item = is_string($item) ? strtolower($item) : $item;
101 $item = is_string($item) ? str_replace(' ', '_', $item) : $item;
102 array_push($formattedroles, $item);
103 }
104
105 foreach ($current_roles as $role) {
106 // $role_name = $all_roles[$role];
107 if (in_array($role, $restrict_for)) {
108 return true;
109 }
110 }
111 }
112
113
114 /**
115 * Check Site wide plugin settings
116 */
117 public static function is_site_wide($plugin)
118 {
119 if (!is_multisite()) {
120 return false;
121 }
122
123 $plugins = get_site_option('active_sitewide_plugins');
124 if (isset($plugins[$plugin])) {
125 return true;
126 }
127
128 return false;
129 }
130
131 /**
132 * Get All Taxonomies
133 *
134 * @return void
135 */
136 public static function get_all_taxonomies()
137 {
138 $taxonomies = get_taxonomies(
139 [
140 'show_ui' => true,
141 ],
142 'objects'
143 );
144 $taxonomy_names = [];
145 foreach ($taxonomies as $taxonomy) {
146 if ($taxonomy->name == 'post_format') {
147 continue;
148 }
149 $taxonomy_names[$taxonomy->name] = $taxonomy->label;
150 }
151 return $taxonomy_names;
152 }
153
154 /**
155 * Restricts for role / user
156 */
157
158 public static function restrict_for($disabled_for)
159 {
160 if (!is_array($disabled_for)) {
161 return false;
162 }
163
164 // wp_get_current_user() is provided by wp-includes/pluggable.php and
165 // is loaded by core early in normal plugin execution. Manually
166 // loading core files is disallowed by the plugin guidelines, so we
167 // simply bail out if it is unavailable for any reason.
168 if (!function_exists('wp_get_current_user')) {
169 return false;
170 }
171
172 $current_user = wp_get_current_user();
173 $current_name = $current_user->display_name;
174 $current_roles = $current_user->roles;
175
176 $formattedroles = [];
177
178 foreach ($disabled_for as $item) {
179 $item = strtolower($item);
180 $item = str_replace(' ', '_', $item);
181 array_push($formattedroles, $item);
182 }
183
184 if (in_array($current_name, $disabled_for)) {
185 return true;
186 }
187
188 foreach ($current_roles as $role) {
189 if (in_array($role, $formattedroles)) {
190 return true;
191 }
192 }
193 }
194
195
196 // Get Taxonomies
197 public static function get_taxonomies()
198 {
199 $args = [
200 'public' => true,
201 'show_ui' => true,
202 ];
203 $output = 'objects';
204 $taxonomies = get_taxonomies($args, $output);
205 $taxonomies = $taxonomies;
206 return $taxonomies;
207 }
208
209 // Get Post Types
210 public static function get_post_types()
211 {
212 $args = [
213 'public' => true,
214 'show_ui' => true,
215 ];
216 $output = 'objects';
217 $post_types = get_post_types($args, $output);
218 $post_types = $post_types;
219 return $post_types;
220 }
221
222 // Get Post Meta
223 public static function post_meta($meta_key)
224 {
225 $meta_key = get_post_meta(get_the_ID(), $meta_key, true);
226 return $meta_key;
227 }
228
229
230 // verfiy current page id
231 public static function currentpage_id($id)
232 {
233 if (!function_exists('get_current_screen')) {
234 return true;
235 }
236
237 $screen = get_current_screen();
238 return is_object($screen) && $screen->id == $id;
239 }
240
241 /**
242 * Get Current Admin Page Title
243 *
244 * @param string $title
245 *
246 * @return void
247 */
248 public static function admin_page_title($title = '')
249 {
250 $title = isset($title) && !empty($title) ? $title : PXLBSADMINIFY;
251 echo esc_html($title);
252
253 if (is_multisite()) {
254 $text = ' | ' . esc_html__('Current Blog ID', 'adminify') . ': ' . get_current_blog_id(); ?>
255 <?php echo self::kses_custom(self::admin_page_subtitle($text)); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- kses_custom() is a wp_kses() wrapper; output already escaped. ?>
256 <?php } ?>
257 <?php
258 }
259
260 /**
261 * Get Current Admin Subtitle
262 */
263
264 public static function admin_page_subtitle($text)
265 {
266 ?>
267 <span style="color:#8b959e;" <?php
268 if (is_rtl()) {
269 echo ' dir="rtl"';
270 }
271 ?>>
272 <?php echo esc_html($text); ?>
273 </span>
274
275 <?php
276 }
277
278 public static function convert_name_to_class($name)
279 {
280 $class = str_replace([' ', ',', '.', '"', "'", '/', '\\', '+', '=', ')', '(', '*', '&', '^', '%', '$', '#', '@', '!', '~', '`', '<', '>', '?', '[', ']', '{', '}', '|', ':'], '', $name);
281 return $class;
282 }
283
284 public static function class_cleanup($string)
285 {
286 // Lower case everything
287 $string = strtolower($string);
288 // Make alphanumeric (removes all other characters)
289 $string = preg_replace('/[^a-z0-9_\s-]/', '', $string);
290 // Clean up multiple dashes or whitespaces
291 $string = preg_replace('/[\s-]+/', ' ', $string);
292 // Convert whitespaces and underscore to dash
293 $string = preg_replace('/[\s_]/', '-', $string);
294 return $string;
295 }
296
297 public static function sanitize_id($url)
298 {
299 $url = preg_replace('/^customize.php\?return=.*$/', 'customize', $url);
300 $url = preg_replace('/(&|&amp;|&#038;)?_wpnonce=([^&]+)/', '', $url);
301 return str_replace(['.php', '.', '/', '?', '='], ['', '_', '_', '_', '_'], $url);
302 }
303
304 /**
305 * Strip tags and it's content from the given string.
306 *
307 * @link https://stackoverflow.com/questions/14684077/remove-all-html-tags-from-php-string/#answer-39320168
308 *
309 * @param string $text The string being stripped.
310 * @return string The stripped string.
311 */
312 public static function strip_tags_content($text)
313 {
314 $cleanup = preg_replace('@<(\w+)\b.*?>.*?</\1>@si', '', $text);
315 $cleanup = wp_strip_all_tags($cleanup);
316 $cleanup = trim($cleanup);
317
318 return $cleanup;
319 }
320
321 /**
322 * String to ID
323 * Remove Space replace with underscore and lowercase
324 *
325 * @param void
326 *
327 * @return string
328 */
329 public static function string_to_id($string)
330 {
331 $string_replace = str_replace(' ', '_', $string);
332 $formatted_string = strtolower($string_replace);
333 return $formatted_string;
334 }
335
336 /**
337 * ID to String
338 * Remove Space replace with underscore and lowercase
339 *
340 * @param void
341 *
342 * @return string
343 */
344 public static function id_to_string($string)
345 {
346 $string_replace = str_replace('_', ' ', $string);
347 $formatted_string = ucwords($string_replace);
348 return $formatted_string;
349 }
350
351 /**
352 * Check is Plugin Active
353 *
354 * @param [type] $plugin_path
355 *
356 * @return boolean
357 */
358 public static function is_plugin_active( $plugin_path )
359 {
360 if (!function_exists('is_plugin_active')) {
361 require_once ABSPATH . 'wp-admin/includes/plugin.php';
362 }
363 return is_plugin_active( $plugin_path );
364 }
365
366 /**
367 * Check if Block Editor Page
368 *
369 * @return boolean
370 */
371 public static function is_block_editor_page() {
372 if (function_exists('get_current_screen')) {
373 $current_screen = get_current_screen();
374 if (!empty($current_screen->is_block_editor)) {
375 return true;
376 }
377 }
378 return false;
379 }
380
381 /**
382 * Check is Plugin Active
383 *
384 * @param [type] $plugin_path
385 *
386 * @return boolean
387 */
388 public static function is_plugin_installed_and_active($plugin_path)
389 {
390 // Check if the plugin is active
391 if (is_plugin_active($plugin_path)) {
392 return true; // Plugin is both installed and active
393 } else {
394 return false; // Plugin is either not installed or not active
395 }
396 }
397
398 public static function is_plugin_installed($plugin_slug, $plugin_file)
399 {
400 $installed_plugins = get_plugins();
401 return isset($installed_plugins[$plugin_file]);
402 }
403
404 public static function notification_bar()
405 {
406 $plugin_slug = 'adminify-notification-bar';
407 $plugin_file = 'adminify-notification-bar/adminify-notification-bar.php';
408 $addons_page_url = network_admin_url('admin.php?page=wp-adminify-settings-addons');
409
410 // $addons_download_link = jltwp_adminify()->_get_latest_download_local_url(14434);
411
412 $html = '';
413 if (self::is_plugin_installed($plugin_slug, $plugin_file)) {
414 if (!current_user_can('install_plugins')) {
415 return;
416 }
417
418 if (!self::is_plugin_active($plugin_file)) {
419 $activation_url = wp_nonce_url('plugins.php?action=activate&amp;plugin=' . $plugin_file . '&amp;plugin_status=all&amp;paged=1&amp;s', 'activate-plugin_' . $plugin_file);
420 $html .= '<a class="wp-adminify-addons-download addon-active" href="' . $activation_url . '" ><span class="pr-1">' . esc_html__('Activate', 'adminify') . '</span><i class="dashicons dashicons-yes-alt"></i></a>';
421 }
422 } else {
423 // $install_url = wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=' . $plugin_slug), 'install-plugin_' . $plugin_slug);
424 $html = '<a class="wp-adminify-addons-download addon-download" href="' . $addons_page_url . '"><span class="wp-adminify-addons-download-text">' . esc_html__('Download', 'adminify') . '</span><i class="dashicons dashicons-download"></i></a>';
425
426 activate_plugin($plugin_file);
427 }
428
429 $html_content = '<div class="adminify-title">
430 <h4>' . esc_html__('Notification Bar', 'adminify') . '</h4>
431 <div class="adminify-subtitle-text">' . esc_html__('Cookie Notice, Promotional Bar on frontend', 'adminify') . '</div>
432 </div>
433 <div class="adminify-fieldset">
434 <div class="adminify--addons" style="width: 100px;">
435 ' . wp_kses_post($html) . '
436 </div>
437 </div>
438 <div class="clear"></div>';
439
440 echo wp_kses_post($html_content);
441 }
442
443
444 /**
445 * User Defined Settings
446 */
447
448 public static function get_user_preference($key)
449 {
450 $userid = get_current_user_id();
451 $current = get_user_meta($userid, 'pxlbsadminify_preferences', true);
452 $value = false;
453
454 if (is_array($current)) {
455 if (isset($current[$key])) {
456 $value = $current[$key];
457 }
458 }
459
460 return $value;
461 }
462
463 /**
464 * Sanitises and strips tags of input from ajax
465 *
466 * @since 1.0.0
467 * @variables $values = item to clean (array or string)
468 */
469 public static function clean_ajax_input($values)
470 {
471 if (is_array($values)) {
472 foreach ($values as $index => $in) {
473 if (is_array($in)) {
474 $values[$index] = self::clean_ajax_input($in);
475 } else {
476 $values[$index] = wp_strip_all_tags($in);
477 }
478 }
479 } else {
480 $values = wp_strip_all_tags($values);
481 }
482
483 return $values;
484 }
485
486 /**
487 * Check Ajax Error Messages
488 *
489 * @param [type] $message
490 *
491 * @return void
492 */
493 public static function ajax_error_message($message)
494 {
495 $returndata = [];
496 $returndata['error'] = true;
497 $returndata['error_message'] = $message;
498 return wp_json_encode($returndata);
499 }
500
501 /**
502 * Get All Updates
503 * Themes, Plugins, Core etc
504 *
505 * @return void
506 */
507 public static function get_all_updates()
508 {
509 $allupdates = [];
510 $allupdates['total'] = 0;
511 $allupdates['wordpress'] = 0;
512 $allupdates['theme'] = 0;
513 $allupdates['plugin'] = 0;
514
515 if (!is_admin()) {
516 return $allupdates;
517 }
518
519 if (!current_user_can('install_plugins')) {
520 return $allupdates;
521 }
522 $updatesTotal = 0;
523 if (is_super_admin() && is_admin()) {
524 $pluginUpdates = get_plugin_updates();
525 $themeUpdates = get_theme_updates();
526 $wpUpdates = get_core_updates();
527
528 if (isset($wpUpdates[0])) {
529 $wpversion = $wpUpdates[0]->version;
530 global $wp_version;
531
532 if ($wpversion > $wp_version) {
533 $wpUpdates = 1;
534 } else {
535 $wpUpdates = 0;
536 }
537 } else {
538 $wpUpdates = 0;
539 }
540
541 $updatesTotal = count($pluginUpdates) + count($themeUpdates) + $wpUpdates;
542
543 $allupdates['total'] = $updatesTotal;
544 $allupdates['wordpress'] = $wpUpdates;
545 $allupdates['theme'] = $themeUpdates;
546 $allupdates['plugin'] = $pluginUpdates;
547 }
548 return $allupdates;
549 }
550
551
552 /**
553 * Upgrade Pro Icon
554 *
555 * @return string
556 */
557 public static function upgrade_pro_icon()
558 {
559 return '<svg class="adminify-pro-notice-icon is-pulled-left mr-2" width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
560 <path fill-rule="evenodd" clip-rule="evenodd" d="M21.8233 0.18318C21.8541 0.215042 21.8753 0.255055 21.8843 0.298527C22.5767 3.32046 20.085 9.8239 16.4731 13.4209C15.8343 14.064 15.1407 14.6502 14.4002 15.1727C14.4955 16.2787 14.411 17.3846 13.9985 18.3318C12.8302 21.0043 9.75855 21.7824 8.44197 21.9937C8.36979 22.0059 8.29577 22.0012 8.22571 21.9799C8.15566 21.9587 8.09147 21.9215 8.03819 21.8713C7.9849 21.821 7.94397 21.7591 7.9186 21.6904C7.89323 21.6217 7.88411 21.548 7.89196 21.4751L8.36241 17.189C8.04096 17.1858 7.71987 17.1663 7.40039 17.1305C7.17735 17.1087 6.96893 17.0096 6.81109 16.8503L5.15076 15.1924C4.99146 15.0346 4.89242 14.8259 4.87084 14.6026C4.83497 14.281 4.81547 13.9578 4.8124 13.6343L0.524795 14.1076C0.451994 14.1156 0.378341 14.1065 0.309629 14.0811C0.240917 14.0558 0.17902 14.0148 0.128806 13.9615C0.0785915 13.9081 0.0414297 13.8438 0.0202432 13.7736C-0.000943262 13.7035 -0.0055768 13.6293 0.00670721 13.5571C0.223273 12.2368 1.00065 9.16771 3.67065 7.99148C4.61695 7.57859 5.72728 7.4965 6.83761 7.59481C7.35968 6.85546 7.94513 6.16306 8.58733 5.52547C12.1879 1.92304 18.8337 -0.585245 21.7099 0.118627C21.7531 0.128924 21.7924 0.151317 21.8233 0.18318ZM12.224 7.92186C12.3151 8.37957 12.5397 8.79996 12.8695 9.12986C13.0882 9.34908 13.348 9.52298 13.6339 9.64164C13.9198 9.7603 14.2263 9.82137 14.5358 9.82137C14.8453 9.82137 15.1517 9.7603 15.4377 9.64164C15.7236 9.52298 15.9833 9.34908 16.202 9.12986C16.5318 8.79996 16.7565 8.37957 16.8475 7.92186C16.9386 7.46415 16.892 6.98968 16.7137 6.55848C16.5353 6.12727 16.2332 5.7587 15.8455 5.49939C15.4578 5.24007 15.002 5.10166 14.5358 5.10166C14.0695 5.10166 13.6137 5.24007 13.226 5.49939C12.8384 5.7587 12.5362 6.12727 12.3579 6.55848C12.1795 6.98968 12.1329 7.46415 12.224 7.92186ZM5.47798 18.5161C5.99754 18.4262 6.4292 18.321 6.69831 18.0511C6.83974 17.9032 7.0897 18.0256 7.07153 18.2311C6.99299 18.8853 6.69667 19.4941 6.23032 19.9593C5.07579 21.1158 0.785726 21.225 0.785726 21.225C0.785726 21.225 0.894746 16.9334 2.04927 15.7768C2.51439 15.3115 3.12167 15.0153 3.77443 14.9353C3.81912 14.9292 3.86459 14.9374 3.90439 14.9586C3.94419 14.9799 3.97629 15.0131 3.99613 15.0537C4.01597 15.0942 4.02255 15.14 4.01493 15.1845C4.00731 15.229 3.98588 15.2699 3.95368 15.3015C3.80635 15.449 3.56965 16.0767 3.48961 16.5245C3.27991 17.7056 4.31069 18.7152 5.47798 18.5161Z" fill="#000"/>
561 </svg>';
562 }
563
564
565 // Upgrade to Pro Notice
566 public static function upgrade_pro_img_notice( $image ){
567 return '<div class="adminify-pro-notice"><img src="' . esc_url_raw($image ) . '" /></div>';
568 }
569
570 // Upgrade to Pro Notice Class
571 public static function upgrade_pro_notice_class($notice = '')
572 {
573 if(empty($notice)){
574 // return ' adminify-depend-visible adminify-depend-on adminify-pro-notice ';
575 return ' adminify-pro-feature adminify-pro-notice';
576 } else {
577 echo esc_attr($notice);
578 }
579 }
580
581 // Upgrade to Pro Notice
582 public static function upgrade_pro_notice($custom_message = '', $style='')
583 {
584
585 if (empty($custom_message)) {
586 $pro_content = '<strong>' . __('(Upgrade to Pro)', 'adminify') . '</strong>';
587 } else {
588 $pro_content = $custom_message;
589 }
590
591 if($style === 'inline'){
592 return '<strong style="font-size:16px;">' . $pro_content . '</strong>';
593 }
594
595 $upgrade_notice_msg = sprintf(
596 '<div class="adminify-pro-notice adminify-missing-addons"> %1$s %2$s </div>',
597 self::upgrade_pro_icon(),
598 self::kses_custom($pro_content)
599 );
600 return self::kses_custom($upgrade_notice_msg);
601 }
602
603
604
605 /**
606 * Documentation SVG Icon
607 */
608 public static function docs_icon()
609 {
610 return '<svg class="is-pulled-left mr-1 width="9" height="12" viewBox="0 0 9 12" fill="none" xmlns="http://www.w3.org/2000/svg">
611 <path d="M5.25 3.1875V0H0.5625C0.250781 0 0 0.250781 0 0.5625V11.4375C0 11.7492 0.250781 12 0.5625 12H8.4375C8.74922 12 9 11.7492 9 11.4375V3.75H5.8125C5.50313 3.75 5.25 3.49687 5.25 3.1875ZM6.75 8.71875C6.75 8.87344 6.62344 9 6.46875 9H2.53125C2.37656 9 2.25 8.87344 2.25 8.71875V8.53125C2.25 8.37656 2.37656 8.25 2.53125 8.25H6.46875C6.62344 8.25 6.75 8.37656 6.75 8.53125V8.71875ZM6.75 7.21875C6.75 7.37344 6.62344 7.5 6.46875 7.5H2.53125C2.37656 7.5 2.25 7.37344 2.25 7.21875V7.03125C2.25 6.87656 2.37656 6.75 2.53125 6.75H6.46875C6.62344 6.75 6.75 6.87656 6.75 7.03125V7.21875ZM6.75 5.53125V5.71875C6.75 5.87344 6.62344 6 6.46875 6H2.53125C2.37656 6 2.25 5.87344 2.25 5.71875V5.53125C2.25 5.37656 2.37656 5.25 2.53125 5.25H6.46875C6.62344 5.25 6.75 5.37656 6.75 5.53125ZM9 2.85703V3H6V0H6.14297C6.29297 0 6.43594 0.0585938 6.54141 0.164062L8.83594 2.46094C8.94141 2.56641 9 2.70938 9 2.85703Z" fill="#0347FF"/>
612 </svg>';
613 }
614 /**
615 * Video Tutorials SVG Icon
616 */
617 public static function video_tutorials_icon()
618 {
619 return '<svg class="is-pulled-left mr-1 width="8" height="10" viewBox="0 0 8 10" fill="none" xmlns="http://www.w3.org/2000/svg">
620 <path d="M7.5 4.13399C8.16667 4.51889 8.16667 5.48114 7.5 5.86604L1.5 9.33014C0.833334 9.71504 0 9.23392 0 8.46412V1.53592C0 0.766115 0.833333 0.28499 1.5 0.66989L7.5 4.13399Z" fill="#C30052"/>
621 </svg>';
622 }
623
624 /**
625 * Facebook Group SVG Icon
626 */
627 public static function fbgroup_icon()
628 {
629 return '<svg class="is-pulled-left mr-1 width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
630 <path d="M1.82594 0C0.814448 0 0 0.814448 0 1.82594V8.17405C0 9.18554 0.814448 9.99999 1.82594 9.99999H5.26656V6.09062H4.23281V4.68312H5.26656V3.48062C5.26656 2.53587 5.87735 1.66844 7.28437 1.66844C7.85404 1.66844 8.2753 1.72313 8.2753 1.72313L8.24217 3.0375C8.24217 3.0375 7.81254 3.03344 7.34374 3.03344C6.83635 3.03344 6.75499 3.26722 6.75499 3.65532V4.68313H8.28248L8.21592 6.09063H6.75499V10H8.17404C9.18553 10 9.99998 9.18555 9.99998 8.17406V1.82595C9.99998 0.814458 9.18553 9.99998e-06 8.17404 9.99998e-06H1.82593L1.82594 0Z" fill="#3B5998"/>
631 </svg>';
632 }
633
634 /**
635 * Support SVG Icon
636 */
637 public static function support_icon()
638 {
639 return '<svg class="is-pulled-left mr-1 width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
640 <path fill-rule="evenodd" clip-rule="evenodd" d="M10 5C10 6.32608 9.47322 7.59785 8.53553 8.53553C7.59785 9.47322 6.32608 10 5 10C3.67392 10 2.40215 9.47322 1.46447 8.53553C0.526784 7.59785 0 6.32608 0 5C0 3.67392 0.526784 2.40215 1.46447 1.46447C2.40215 0.526784 3.67392 0 5 0C6.32608 0 7.59785 0.526784 8.53553 1.46447C9.47322 2.40215 10 3.67392 10 5ZM8.75 5C8.75 5.62063 8.59937 6.20563 8.3325 6.72125L7.38 5.76813C7.52262 5.32668 7.5395 4.85425 7.42875 4.40375L8.405 3.4275C8.62625 3.90563 8.75 4.4375 8.75 5ZM5.52187 7.44563L6.50938 8.43312C6.03375 8.64254 5.51968 8.75046 5 8.75C4.45699 8.75068 3.92036 8.63294 3.4275 8.405L4.40375 7.42875C4.77042 7.5186 5.15266 7.52437 5.52187 7.44563ZM2.59875 5.69812C2.47576 5.27463 2.46692 4.82614 2.57313 4.39812L2.52313 4.44812L1.56687 3.49C1.35738 3.96582 1.24945 4.48011 1.25 5C1.25 5.59625 1.38937 6.16 1.63687 6.66062L2.59938 5.69812H2.59875ZM3.27875 1.66687C3.81076 1.39189 4.40112 1.24891 5 1.25C5.59625 1.25 6.16 1.38937 6.66062 1.63687L5.69812 2.59938C5.21829 2.45961 4.70759 2.46679 4.23187 2.62L3.27875 1.6675V1.66687ZM6.25 5C6.25 5.33152 6.1183 5.64946 5.88388 5.88388C5.64946 6.1183 5.33152 6.25 5 6.25C4.66848 6.25 4.35054 6.1183 4.11612 5.88388C3.8817 5.64946 3.75 5.33152 3.75 5C3.75 4.66848 3.8817 4.35054 4.11612 4.11612C4.35054 3.8817 4.66848 3.75 5 3.75C5.33152 3.75 5.64946 3.8817 5.88388 4.11612C6.1183 4.35054 6.25 4.66848 6.25 5Z" fill="#4E4B66"/>
641 </svg>';
642 }
643
644 /* White Label Upgrade Pro */
645 public static function white_label_upgrade()
646 {
647 ?>
648 <div class="wp-adminify-white-label-notice-content">
649 <div class="wp-adminify-white-label-notice-logo">
650 <img src="<?php echo esc_url(PXLBSADMINIFY_ASSETS_IMAGE) . 'logos/logo-text-light.svg'; ?>" alt="<?php echo esc_attr(PXLBSADMINIFY); ?>">
651 </div>
652 <h2>
653 <?php echo wp_kses_post( sprintf(__('Upgrade <span>Pro</span> for White Labeling', 'adminify')) ); ?>
654 </h2>
655 <p>
656 <?php
657 /* translators: %s: Plugin name */
658 echo wp_kses_post( sprintf(__('<strong>%1$s</strong> can be completely re-branded with your own brand Logo, Name and Author Details. Your clients will never know what tools you are using to build their website and will think that this is your own tool set. White-labeling works as long as your license is active. ', 'adminify'), esc_html(PXLBSADMINIFY)) );
659 ?>
660 <br>
661 <em><?php esc_html_e('Note: Agency or Higher Plans Only', 'adminify'); ?></em>
662 </p>
663 <a class="wp-adminify-btn wp-adminify-get-pro" href="<?php echo esc_url('https://wpadminify.com/pricing/'); ?>" target="_blank">
664 <?php esc_html_e('Upgrade Now', 'adminify'); ?>
665 </a>
666 </div>
667 <?php
668 }
669
670
671 public static function get_widget_template_options()
672 {
673 $type = 'widget';
674 $page_templates = self::get_page_templates($type);
675
676 $options[-1] = __('Select', 'adminify');
677
678 if (count($page_templates)) {
679 foreach ($page_templates as $id => $name) {
680 $options[$id] = $name;
681 }
682 } else {
683 $options['no_template'] = __('No saved templates found!', 'adminify');
684 }
685
686 return $options;
687 }
688
689 public static function get_section_template_options()
690 {
691 $type = 'section';
692 $page_templates = self::get_page_templates($type);
693
694 $options[-1] = __('Select', 'adminify');
695
696 if (count($page_templates)) {
697 foreach ($page_templates as $id => $name) {
698 $options[$id] = $name;
699 }
700 } else {
701 $options['no_template'] = __('No saved templates found!', 'adminify');
702 }
703
704 return $options;
705 }
706
707 public static function get_page_template_options()
708 {
709 $type = 'page';
710 $page_templates = self::get_page_templates($type);
711
712 $options[-1] = __('Select', 'adminify');
713
714 if (count($page_templates)) {
715 foreach ($page_templates as $id => $name) {
716 $options[$id] = $name;
717 }
718 } else {
719 $options['no_template'] = __('No saved templates found!', 'adminify');
720 }
721
722 return $options;
723 }
724
725 /**
726 * Common preset CSS variables (padding / sizing / typography
727 * defaults) shared by every theme preset and by the Pro
728 * custom-color preset path. Extracted so the Pro filter
729 * (Pro/Classes/OutputCSS_Body_Pro::build_custom_color_preset())
730 * can reuse the same defaults instead of re-declaring them.
731 *
732 * @return array<string,string>
733 */
734 public static function get_common_preset_vars()
735 {
736 return [
737 '--adminify-menu-vertical-padding' => '10px',
738 '--adminify-menu-horizontal-padding' => '8px',
739 '--adminify-menu-wrapper-padding-top' => '16px',
740 '--adminify-menu-wrapper-padding-right' => '8px',
741 '--adminify-menu-wrapper-padding-bottom' => '16px',
742 '--adminify-menu-wrapper-padding-left' => '8px',
743 '--adminify-submenu-vertical-padding' => '4px',
744 '--adminify-submenu-wrapper-padding-top' => '8px',
745 '--adminify-submenu-wrapper-padding-right' => '0px',
746 '--adminify-submenu-wrapper-padding-bottom' => '8px',
747 '--adminify-submenu-wrapper-padding-left' => '28px',
748 '--adminify-menu-font-size' => '13px',
749 '--adminify-menu-line-height' => '20px',
750 '--adminify-menu-letter-spacing' => '',
751 '--adminify-menu-width' => '260px',
752 ];
753 }
754
755 public static function get_theme_presets($theme = null)
756 {
757
758 $common_var = self::get_common_preset_vars();
759
760 $presets = [
761
762 // Base/ Default Preset
763 'preset1' => [
764 '--adminify-preset-background' => '#F9F9F9',
765 '--adminify-primary' => '#3a3ae9',
766 // '--adminify-text-color' => '#ffffff',
767 '--adminify-menu-border' => '#dedee7',
768 '--adminify-menu-bg' => '#ffffff',
769 '--adminify-menu-hover-bg' => '#3a3ae9',
770 '--adminify-menu-text-color' => '#48455f',
771 '--adminify-menu-text-hover-color' => '#ffffff',
772 '--adminify-menu-active-bg' => '#3a3ae9',
773 '--adminify-menu-active-color' => '#ffffff',
774 '--adminify-submenu-wrapper-bg' => '#ffffff',
775 '--adminify-submenu-hover-bg' => 'transparent',
776 '--adminify-submenu-text-color' => '#48455f',
777 '--adminify-submenu-text-hover-color' => '#3a3ae9',
778 '--adminify-submenu-active-bg' => 'transparent',
779 '--adminify-submenu-active-color' => '#3a3ae9',
780 '--adminify-notif-bg-color' => '#3a3ae9',
781 '--adminify-notif-color' => '#ffffff',
782 ],
783
784 'preset2' => [
785 '--adminify-preset-background' => '#F9F9F9',
786 '--adminify-primary' => '#0347FF',
787 '--adminify-notif-bg-color' => '#FF1C69',
788 // '--adminify-text-color' => '#ffffff',
789 '--adminify-menu-border' => '#404052',
790 '--adminify-menu-bg' => '#14142B',
791 '--adminify-menu-hover-bg' => '#0347FF',
792 '--adminify-menu-text-color' => '#ffffff',
793 '--adminify-menu-text-hover-color' => '#ffffff',
794 '--adminify-menu-active-bg' => '#0347FF',
795 '--adminify-menu-active-color' => '#ffffff',
796 '--adminify-submenu-wrapper-bg' => '#14142B',
797 '--adminify-submenu-hover-bg' => 'transparent',
798 '--adminify-submenu-text-color' => '#ffffff',
799 '--adminify-submenu-text-hover-color' => '#0347FF',
800 '--adminify-submenu-active-bg' => 'transparent',
801 '--adminify-submenu-active-color' => '#0347FF',
802 '--adminify-notif-bg-color' => '#0347FF',
803 '--adminify-notif-color' => '#ffffff',
804 ],
805 ];
806
807 $pro_presets = apply_filters('pxlbsadminify_settings/color_presets', $common_var);
808
809 if( !empty(array_key_exists('preset3', $pro_presets)) ) {
810 $presets = array_merge($presets, $pro_presets);
811 }
812
813 // Merge $common_var variable with every preset
814 foreach ($presets as $key => $value) {
815 $presets[$key] = array_merge($value, $common_var);
816 }
817
818 // return all presets
819 if (is_null($theme)) {
820 return $presets;
821 }
822
823 // return specific preset
824 if (array_key_exists($theme, $presets)) {
825 return $presets[$theme];
826 }
827
828 // specific preset not found (Pro-only/custom theme saved while Pro add-on inactive).
829 // Fall back to base preset so core CSS vars (--adminify-menu-width) always emit.
830 return isset($presets['preset1']) ? $presets['preset1'] : $common_var;
831 }
832
833 public static function get_page_templates($type = '')
834 {
835 $args = [
836 'post_type' => 'elementor_library',
837 'posts_per_page' => -1,
838 ];
839
840 if ($type) {
841 $args['tax_query'] = [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query -- intentional taxonomy filter on an admin-side query.
842 [
843 'taxonomy' => 'elementor_library_type',
844 'field' => 'slug',
845 'terms' => $type,
846 ],
847 ];
848 }
849
850 $page_templates = get_posts($args);
851
852 $options = [];
853
854 if (!empty($page_templates) && !is_wp_error($page_templates)) {
855 foreach ($page_templates as $post) {
856 $options[$post->ID] = $post->post_title;
857 }
858 }
859 return $options;
860 }
861
862 public static function assets_ext($ext)
863 {
864 if (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) {
865 return $ext;
866 }
867 return '.min' . $ext;
868 }
869
870 public static function kses_atts_map(array $attrs)
871 {
872 return array_fill_keys(array_values($attrs), true);
873 }
874
875 /**
876 * Whether the site is served over HTTPS well enough to run the Adminify UI.
877 *
878 * Mirrors the exact condition that gates the dashboard frame in
879 * Inc/Admin/Admin.php ( is_ssl() + an https:// site URL ), so the AJAX
880 * gate behaviour stays consistent with where the UI actually loads.
881 *
882 * @return array{ready:bool,message:string}
883 */
884 public static function adminify_ui_https_status()
885 {
886 $is_ssl = is_ssl();
887 $site_https = ( 0 === stripos( (string) site_url(), 'https://' ) );
888
889 if ( $is_ssl && $site_https ) {
890 return [
891 'ready' => true,
892 'message' => '',
893 ];
894 }
895
896 if ( ! $site_https ) {
897 $message = esc_html__( 'Site URL is not HTTPS. Switch to HTTPS first.', 'adminify' );
898 } else {
899 $message = esc_html__( 'Open the dashboard over HTTPS first.', 'adminify' );
900 }
901
902 return [
903 'ready' => false,
904 'message' => $message,
905 ];
906 }
907
908 public static function kses_allowed_html()
909 {
910 /**
911 * 'post' returns the tags allowed in post content (a, p, strong, em, etc.),
912 * which we then extend with the custom tags below (svg, form fields, style).
913 * https://developer.wordpress.org/reference/functions/wp_kses_allowed_html/
914 */
915 $allowed_tags = wp_kses_allowed_html('post');
916 if( !is_array($allowed_tags) ) $allowed_tags = [];
917
918 $custom_tags = [
919 'select' => self::kses_atts_map(['class', 'id', 'style', 'width', 'height', 'title', 'data', 'name', 'autofocus', 'disabled', 'multiple', 'required', 'size']),
920 'input' => self::kses_atts_map(['class', 'id', 'style', 'width', 'height', 'title', 'data', 'name', 'autofocus', 'disabled', 'required', 'size', 'type', 'checked', 'readonly', 'placeholder', 'value', 'maxlength', 'min', 'max', 'multiple', 'pattern', 'step', 'autocomplete']),
921 'textarea' => self::kses_atts_map(['class', 'id', 'style', 'width', 'height', 'title', 'data', 'name', 'autofocus', 'disabled', 'required', 'rows', 'cols', 'wrap', 'maxlength']),
922 'option' => self::kses_atts_map(['class', 'id', 'label', 'disabled', 'label', 'selected', 'value']),
923 'optgroup' => self::kses_atts_map(['disabled', 'label', 'class', 'id']),
924 'form' => self::kses_atts_map(['class', 'id', 'data', 'style', 'width', 'height', 'accept-charset', 'action', 'autocomplete', 'enctype', 'method', 'name', 'novalidate', 'rel', 'target']),
925 'svg' => self::kses_atts_map(['class', 'xmlns', 'viewbox', 'width', 'height', 'fill', 'stroke', 'aria-hidden', 'aria-labelledby', 'role']),
926 'rect' => self::kses_atts_map(['rx', 'width', 'height', 'fill']),
927 'path' => self::kses_atts_map(['d', 'fill', 'fill-rule', 'clip-rule', 'stroke', 'stroke-width', 'stroke-linecap', 'stroke-linejoin']),
928 'g' => self::kses_atts_map(['fill']),
929 'defs' => self::kses_atts_map(['fill']),
930 'linearGradient' => self::kses_atts_map(['id', 'x1', 'x2', 'y1', 'y2', 'gradientUnits']),
931 'stop' => self::kses_atts_map(['stop-color', 'offset', 'stop-opacity']),
932 'style' => self::kses_atts_map(['type']),
933 'div' => self::kses_atts_map(['class', 'id', 'style']),
934 'ul' => self::kses_atts_map(['class', 'id', 'style']),
935 'li' => self::kses_atts_map(['class', 'id', 'style']),
936 'label' => self::kses_atts_map(['class', 'for']),
937 'span' => self::kses_atts_map(['class', 'id', 'style']),
938 'h1' => self::kses_atts_map(['class', 'id', 'style']),
939 'h2' => self::kses_atts_map(['class', 'id', 'style']),
940 'h3' => self::kses_atts_map(['class', 'id', 'style']),
941 'h4' => self::kses_atts_map(['class', 'id', 'style']),
942 'h5' => self::kses_atts_map(['class', 'id', 'style']),
943 'h6' => self::kses_atts_map(['class', 'id', 'style']),
944 'a' => self::kses_atts_map(['class', 'href', 'target', 'rel']),
945 'p' => self::kses_atts_map(['class', 'id', 'style', 'data']),
946 'table' => self::kses_atts_map(['class', 'id', 'style']),
947 'thead' => self::kses_atts_map(['class', 'id', 'style']),
948 'tbody' => self::kses_atts_map(['class', 'id', 'style']),
949 'tr' => self::kses_atts_map(['class', 'id', 'style']),
950 'th' => self::kses_atts_map(['class', 'id', 'style']),
951 'td' => self::kses_atts_map(['class', 'id', 'style']),
952 'i' => self::kses_atts_map(['class', 'id', 'style']),
953 'button' => self::kses_atts_map(['class', 'id']),
954 'nav' => self::kses_atts_map(['class', 'id', 'style']),
955 'time' => self::kses_atts_map(['datetime']),
956 'br' => [],
957 'strong' => [],
958 'style' => [],
959 'img' => self::kses_atts_map(['class', 'src', 'alt', 'height', 'width', 'srcset', 'id', 'loading']),
960 ];
961
962 return array_merge_recursive($allowed_tags, $custom_tags);
963 }
964
965 /**
966 * Sanitize a string with wp_kses() using the extended allowed-tags list.
967 *
968 * @param string $content
969 * @return string
970 */
971 public static function kses_custom($content)
972 {
973 return wp_kses( stripslashes_deep($content), self::kses_allowed_html() );
974 }
975
976
977 /**
978 * Missing Addon/Plugin Notice
979 *
980 * @param [type] $args
981 *
982 * @return void
983 */
984 public static function missing_plugin_notice( $plugin_name = '' )
985 {
986 $missing_plugin_notice = sprintf(
987 /* translators: 1: Plugin name, 2: Addons/plugins admin page URL, 3: "Install Now" link text */
988 __('<strong>"%1$s"</strong> plugin is not Activated! Please install and activate <strong>%1$s</strong> Plugin <p> <a class="adminify-missing-addons" href="%2$s">%3$s</a></p>', 'adminify'),
989 esc_html($plugin_name),
990 admin_url('admin.php?page=wp-adminify-addons-plugins'),
991 __('Install Now', 'adminify')
992 );
993 return '<div class="adminify-missing-addons">' . self::upgrade_pro_icon() . self::kses_custom( $missing_plugin_notice ) . '</div>';
994 }
995
996
997 /**
998 * Update Existing Data to New Options data
999 *
1000 * @param [type] $get_option_value
1001 * @param [type] $update_option_value
1002 * @param [type] $option_name
1003 *
1004 * @return void
1005 */
1006 public static function update_options($get_option_value, $option_name)
1007 {
1008
1009 // Retrieve the current option value
1010 $current_value = get_option($option_name);
1011 // $current_value = self::$option_data;
1012 // Initialize the current value if it's empty
1013 if (empty($current_value)) {
1014 $current_value = [];
1015 }
1016 // If $get_option_value is provided, use it to update the current value
1017 if (!empty($get_option_value)) {
1018 // Ensure current value is an array before merging
1019 if (!is_array($current_value)) {
1020 $current_value = [];
1021 }
1022 // Merge the provided value into the current value
1023 $current_value = array_merge($current_value, $get_option_value);
1024 }
1025 // Update the specific key within the option with the new value
1026 // $current_value[$option_key] = $update_option_value;
1027
1028 // Update the option with the new value
1029 update_option($option_name, $current_value);
1030 // Optionally, return the updated value
1031 return get_option($option_name);
1032 }
1033
1034
1035 /**
1036 * Replace Array Keys
1037 *
1038 * @return void
1039 */
1040 public static function replace_keys($sourceArray, $newArray){
1041 $new_value = [];
1042 if( ! is_array($sourceArray)) $sourceArray = [];
1043 foreach ($newArray as $key => $value) {
1044 if (!array_key_exists($key, $sourceArray)) {
1045 return $sourceArray;
1046 }
1047 $new_value[$value] = $sourceArray[$key];
1048 unset($sourceArray[$key]);
1049 }
1050 return array_merge($sourceArray, $new_value);
1051 }
1052
1053
1054 /**
1055 * Move Array Keys
1056 *
1057 * @return void
1058 */
1059 public static function move_keys(&$sourceArray, $keysToMove)
1060 {
1061 $destinationArray = [];
1062 foreach ($keysToMove as $key) {
1063 if (array_key_exists($key, $sourceArray)) {
1064 $destinationArray[$key] = $sourceArray[$key];
1065 unset($sourceArray[$key]);
1066 }
1067 }
1068 return $destinationArray;
1069 }
1070
1071
1072 /**
1073 * Remove unnecessary keys.
1074 *
1075 * @param string $option_name The name of the option.
1076 * @param array $keys_to_remove An array of keys to remove.
1077 */
1078 public static function removeKeys($sourceArray, $keysToRemove)
1079 {
1080 foreach ($keysToRemove as $key) {
1081 if (array_key_exists($key, $sourceArray)) {
1082 unset($sourceArray[$key]);
1083 }
1084 }
1085 return $sourceArray;
1086 }
1087
1088
1089
1090 /**
1091 * Move Nested Keys
1092 *
1093 * @return void
1094 */
1095 public static function moveNestedKeys(&$sourceArray, $moveInstructions) {
1096 $destinationArray = [];
1097 foreach ($moveInstructions as $sourcePath => $destPath) {
1098 $sourcePathArray = explode('.', $sourcePath);
1099 $destPathArray = explode('.', $destPath);
1100 $sourceValue = self::getNestedValue($sourceArray, $sourcePathArray);
1101 if ($sourceValue !== null) {
1102 self::setNestedValue($destinationArray, $destPathArray, $sourceValue);
1103 self::unsetNestedValue($sourceArray, $sourcePathArray);
1104 }
1105 }
1106
1107 return array_merge_recursive($sourceArray, $destinationArray);
1108 }
1109
1110 public static function getNestedValue(&$array, $pathArray) {
1111 $value = &$array;
1112 foreach ($pathArray as $key) {
1113 if (is_array($value) && array_key_exists($key, $value)) {
1114 $value = &$value[$key];
1115 } else {
1116 return null;
1117 }
1118 }
1119 return $value;
1120 }
1121
1122 public static function setNestedValue(&$array, $pathArray, $value) {
1123 $temp = &$array;
1124 foreach ($pathArray as $key) {
1125 if (!isset($temp[$key])) {
1126 $temp[$key] = [];
1127 }
1128 $temp = &$temp[$key];
1129 }
1130 $temp = $value;
1131 }
1132
1133 public static function unsetNestedValue(&$array, $pathArray) {
1134 $temp = &$array;
1135 foreach ($pathArray as $key) {
1136 if (isset($temp[$key])) {
1137 if (count($pathArray) === 1) {
1138 unset($temp[$key]);
1139 } else {
1140 self::unsetNestedValue($temp[$key], array_slice($pathArray, 1));
1141 }
1142 return;
1143 }
1144 }
1145 }
1146
1147
1148
1149 /**
1150 *
1151 * Checkbox Method
1152 */
1153 public static function checkboxes(&$old_db, $checkbox_keys) {
1154 $result = [];
1155 $parentKey = "";
1156 $childKey = "";
1157
1158 $thirdStep = [];
1159
1160 foreach ($checkbox_keys as $key => $value) {
1161
1162 $sourceArray = explode(".", $value);
1163
1164 foreach ($sourceArray as $x => $element) {
1165 if (!array_key_exists($element, $result) && $x === 0) {
1166 $parentKey = $element;
1167 if (count($sourceArray) === 3) {
1168 $result[$element] = [];
1169 } else {
1170 $result[$element] = [];
1171 }
1172 }
1173
1174
1175 if ($x === 1 && !empty($old_db[$key])) {
1176 $childKey = $element;
1177 if (count($sourceArray) === 3) {
1178 $result[$parentKey][$element] = [];
1179 } else {
1180 $result[$parentKey][] = $element;
1181 }
1182 } elseif ($x === 1 && empty($old_db[$key]) && count($sourceArray) === 3) {
1183 $childKey = $element;
1184 if (!array_key_exists($element, $result[$parentKey])) {
1185 $result[$parentKey][$element] = [];
1186 }
1187 }
1188
1189 if ($x === 2 && !empty($old_db[$key]) && count($sourceArray) === 3) {
1190 $thirdStep[] = $element;
1191 $result[$parentKey][$childKey] = $thirdStep;
1192 }
1193 }
1194 }
1195
1196 return array_merge_recursive($old_db, $result);
1197 }
1198
1199 /**
1200 * Inline "Upgrade to Pro" marker rendered next to a checkbox option
1201 * label in the free build.
1202 *
1203 * Returns the rocket-icon + (Upgrade to Pro) span the settings UI
1204 * has rendered historically. The
1205 * Inc/Admin/AdminSettings::render_pro_locked_field() handler
1206 * detects this span inside a checkbox <li> and strips name= + sets
1207 * disabled on the enclosed input so the locked option cannot submit
1208 * a value.
1209 *
1210 * Returns an empty string when the Pro plugin is active so the Pro
1211 * UI is unchanged.
1212 */
1213 public static function upgrade_pro_class($inline_badge = false){
1214 if (function_exists('jltwp_adminify') && jltwp_adminify()->can_use_premium_code__premium_only()) {
1215 return '';
1216 }
1217 if (!empty($inline_badge)){
1218 return '<span class="adminify-pro-checkbox adminify-pro-badge adminify-pro-notice">Pro</span>';
1219 }
1220 return '<span class="adminify-pro-checkbox">' . self::upgrade_pro_icon() . ' <strong>(Upgrade to Pro)</strong>' . '</span>';
1221 }
1222
1223 /**
1224 * Inline "Pro" badge rendered next to a field title in the free
1225 * build.
1226 *
1227 * Returns the legacy <span class="adminify-pro-badge">Pro</span>
1228 * markup. The render handler detects fields whose class list
1229 * contains adminify-pro-fieldset / -feature / -notice (the
1230 * Pro-style classes used alongside this badge) and neutralises
1231 * the inputs at render time.
1232 *
1233 * Returns an empty string when the Pro plugin is active.
1234 */
1235 public static function upgrade_pro_badge($badge_text = 'Pro'){
1236 if (function_exists('jltwp_adminify') && jltwp_adminify()->can_use_premium_code__premium_only()) {
1237 return '';
1238 }
1239 if (!empty($badge_text)){
1240 return '<span class="adminify-pro-badge">' . esc_html($badge_text) . '</span>';
1241 }
1242 return '';
1243 }
1244
1245 public static function new_badge($badge_text = 'New') {
1246 if( empty( $badge_text ) ) {
1247 return '';
1248 }
1249
1250 return '<span class="adminify-new-badge">' . esc_html($badge_text) . '</span>';
1251 }
1252
1253 /*
1254 * Compares the version of WordPress running to the $version specified.
1255 * Usage: Utils::check_wp_version('>=', '4.0')
1256 version_compare( $wp_version, '4.3', '>=' )
1257 * @param string $operator
1258 * @param string $version
1259 * @returns boolean
1260 */
1261 public static function check_wp_version( $operator = '>', $version = '6.6' ) {
1262 global $wp_version;
1263 return version_compare( $wp_version, $version, $operator );
1264 }
1265
1266 public static function help_urls($module_name = '', $docs = '', $youtube = '', $facebook_grp = '', $support = '')
1267 {
1268 $help_content = '';
1269
1270 // Modules ( sanitize the label so the returned template is safe to echo ).
1271 // Callers may pass benign markup (e.g. an empty <span></span> used for layout/icons),
1272 // so use wp_kses_post() — it keeps that markup while stripping scripts. esc_html()
1273 // would print the tags literally (e.g. "<span></span>" shown as text).
1274 $module_name = empty($module_name) ? '' : wp_kses_post($module_name);
1275
1276 $help_content_urls = '';
1277
1278 // Docs
1279 if (!empty($docs)) {
1280 $help_content_urls .= '<a class="adminify-tag adminify-tag-purple adminify-docs-url" href="' . esc_url( $docs ) . '" target="_blank"> ' . self::docs_icon() . ' Docs</a>';
1281 }
1282
1283 // youtube
1284 if (!empty($youtube)) {
1285 $help_content_urls .= '<a class="adminify-tag adminify-tag-danger adminify-video-url" href="' . esc_url( $youtube ) . '" target="_blank">' . self::video_tutorials_icon() . ' Video Tutorial</a>';
1286 }
1287
1288 // facebook_grp
1289 if (!empty($facebook_grp)) {
1290 $help_content_urls .= '<a class="adminify-tag adminify-tag-primary adminify-fbgroup-url" href="' . esc_url($facebook_grp) . '" target="_blank">' . self::fbgroup_icon() . ' Facebook Group</a>';
1291 }
1292
1293 // Support
1294 if ( !empty($support)) {
1295 $help_content_urls .= '<a class="adminify-tag adminify-tag-secondary adminify-support-url" href="' . esc_url($support) . '" target="_blank">' . self::support_icon() . ' Support</a>';
1296 }
1297
1298 $help_content = sprintf( '%1$s <div class="adminify-helps">%2$s</div>', $module_name, $help_content_urls );
1299 return $help_content;
1300 }
1301
1302 /**
1303 * Check if the request is coming from an iframe.
1304 *
1305 * @param None
1306 * @throws None
1307 * @return bool
1308 */
1309 public static function is_iframe()
1310 {
1311 return isset($_SERVER["HTTP_SEC_FETCH_DEST"]) && strtolower(sanitize_text_field(wp_unslash($_SERVER["HTTP_SEC_FETCH_DEST"]))) === "iframe";
1312 // $isIframe = isset($_SERVER["HTTP_SEC_FETCH_DEST"]) && strtolower($_SERVER["HTTP_SEC_FETCH_DEST"]) === "iframe";
1313 // if ( $isIframe ) return true;
1314 // if ( isset($_GET['adminify-iframe']) ) return true;
1315 // return false;
1316 }
1317
1318 /**
1319 * Whether the request carries Fetch Metadata headers at all.
1320 *
1321 * `Sec-Fetch-*` is attached by the browser below the Service Worker layer, so
1322 * installs served through a Service Worker - WordPress Playground, offline
1323 * setups - never pass it to PHP. Older browsers do not send it either. When it
1324 * is missing, is_iframe() cannot tell an iframe request from a top-level one
1325 * and the client has to settle it instead.
1326 *
1327 * @return bool
1328 */
1329 public static function has_fetch_metadata()
1330 {
1331 return isset( $_SERVER['HTTP_SEC_FETCH_DEST'] )
1332 || isset( $_SERVER['HTTP_SEC_FETCH_MODE'] )
1333 || isset( $_SERVER['HTTP_SEC_FETCH_SITE'] );
1334 }
1335
1336 /**
1337 * Whether this is a plain GET request.
1338 *
1339 * @return bool
1340 */
1341 public static function is_get_request()
1342 {
1343 $method = isset( $_SERVER['REQUEST_METHOD'] ) ? strtoupper( sanitize_text_field( wp_unslash( $_SERVER['REQUEST_METHOD'] ) ) ) : 'GET';
1344
1345 return 'GET' === $method || 'HEAD' === $method;
1346 }
1347
1348 /**
1349 * Whether the current request renders a full admin page.
1350 *
1351 * Endpoints like async-upload.php run through wp-admin/admin.php (so `admin_init`
1352 * fires) but answer with a raw payload - an attachment ID, JSON, an HTML fragment.
1353 * Printing the Admin UI frame into those responses corrupts them: the media uploader
1354 * on media-new.php reads the response as an attachment ID and gives up when it is not
1355 * numeric. `wp_doing_ajax()` does not catch these: async-upload.php only defines
1356 * DOING_AJAX for the `upload-attachment` action, which media-new.php does not send.
1357 *
1358 * @return bool
1359 */
1360 public static function is_admin_page_request()
1361 {
1362 if ( wp_doing_ajax() || wp_doing_cron() || wp_is_json_request() ) {
1363 return false;
1364 }
1365
1366 if ( ( defined('REST_REQUEST') && REST_REQUEST ) || ( defined('XMLRPC_REQUEST') && XMLRPC_REQUEST ) || ( defined('WP_CLI') && WP_CLI ) ) {
1367 return false;
1368 }
1369
1370 $pagenow = isset($GLOBALS['pagenow']) ? $GLOBALS['pagenow'] : '';
1371
1372 if ( empty($pagenow) && isset($_SERVER['PHP_SELF']) ) {
1373 $pagenow = basename( sanitize_text_field( wp_unslash($_SERVER['PHP_SELF']) ) );
1374 }
1375
1376 $raw_response_endpoints = [
1377 'admin-ajax.php',
1378 'admin-post.php',
1379 'async-upload.php',
1380 'load-scripts.php',
1381 'load-styles.php',
1382 'ms-files.php',
1383 'wp-cron.php',
1384 ];
1385
1386 return ! in_array( $pagenow, $raw_response_endpoints, true );
1387 }
1388
1389 /**
1390 * Load a template file.
1391 *
1392 * @param string $template_name The name of the template file to load.
1393 * @throws None
1394 * @return void
1395 */
1396 public static function load_template($template_name)
1397 {
1398 require_once PXLBSADMINIFY_PATH . 'Inc/Admin/Frames/Templates/' . $template_name;
1399 }
1400
1401 /**
1402 * Multisite Check
1403 * @param URL
1404 * @return Admin_URL
1405 */
1406 public static function maybe_network_admin_url($url) {
1407 if ( is_network_admin() ) {
1408 return network_admin_url($url);
1409 }
1410 return admin_url($url);
1411 }
1412
1413 /**
1414 * Sluggify a string and replace hyphens with underscores.
1415 * @param string $string The string to sluggify.
1416 * @return string The sluggified string with underscores.
1417 */
1418 public static function sluggify_with_underscores($string) {
1419 $slug = sanitize_title($string);
1420 $slug = str_replace('-', '_', $slug);
1421
1422 return $slug;
1423 }
1424
1425 }
1426