PluginProbe
Adminify – White Label, Admin Menu Editor, Login Customizer / 4.1.17
Adminify – White Label, Admin Menu Editor, Login Customizer v4.1.17
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 / Admin / AdminSettings.php

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

435 lines 20.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPAdminify\Inc\Admin;
4
5 use WPAdminify\Inc\Utils;
6 use WPAdminify\Inc\Admin\AdminSettingsModel;
7 use WPAdminify\Inc\Admin\Options\Customize;
8 use WPAdminify\Inc\Admin\Options\Productivity;
9 use WPAdminify\Inc\Admin\Options\CustomCSSJS;
10 use WPAdminify\Inc\Admin\Options\Performance;
11 use WPAdminify\Inc\Admin\Options\MenuLayout;
12 use WPAdminify\Inc\Admin\Options\Security;
13 use WPAdminify\Inc\Admin\Options\White_Label;
14 if ( !defined( 'ABSPATH' ) ) {
15 die;
16 }
17 // Cannot access directly.
18 if ( !class_exists( 'AdminSettings' ) ) {
19 class AdminSettings extends AdminSettingsModel {
20 // AdminSettings cannot be extended by creating instances
21 public static $instance = null;
22
23 public $defaults = [];
24
25 private $message = [];
26
27 public function __construct() {
28 // this should be first so the default values get stored
29 $this->jltwp_adminify_options();
30 parent::__construct( (array) get_option( $this->prefix ) );
31 add_action( 'network_admin_menu', [$this, 'network_panel'] );
32 add_filter(
33 'adminify_render_field_html',
34 array($this, 'adminify_render_pro_locked_field'),
35 10,
36 2
37 );
38 }
39
40 public function network_panel() {
41 add_menu_page(
42 $this->get_plugin_menu_label(),
43 $this->get_plugin_menu_label(),
44 'manage_options',
45 'wp-adminify-settings',
46 [$this, 'network_panel_display'],
47 WP_ADMINIFY_ASSETS_IMAGE . 'logos/menu-icon.svg',
48 30
49 );
50 }
51
52 public function get_bloginfo( $blog_id, $fields = [] ) {
53 switch_to_blog( $blog_id );
54 $_fields = [];
55 foreach ( $fields as $field ) {
56 $_fields[$field] = get_bloginfo( $field );
57 }
58 restore_current_blog();
59 return $_fields;
60 }
61
62 public function get_sites() {
63 $sites = get_sites();
64 foreach ( $sites as $site ) {
65 $info = $this->get_bloginfo( $site->blog_id, ['name'] );
66 $site->name = $info['name'];
67 }
68 return $sites;
69 }
70
71 public function get_sites_option_empty() {
72 /* translators: 1: option value attribute, 2: option label text */
73 return sprintf( __( '<option value="%1$s">%2$s</option>', 'adminify' ), 0, __( 'Select', 'adminify' ) );
74 }
75
76 public function get_sites_option( $sites = [], $add_empty_slot = false ) {
77 if ( empty( $sites ) ) {
78 $sites = $this->get_sites();
79 }
80 $_sites = [];
81 if ( $add_empty_slot ) {
82 $_sites[] = $this->get_sites_option_empty();
83 }
84 foreach ( $sites as $site ) {
85 /* translators: 1: site blog ID used as option value, 2: site name shown as option label */
86 $_sites[] = sprintf( __( '<option value="%1$s">%2$s</option>', 'adminify' ), $site->blog_id, $site->name );
87 }
88 return implode( '', $_sites );
89 }
90
91 public function maybe_display_message() {
92 if ( empty( $this->message ) ) {
93 return;
94 }
95 $classes = 'adminify-status adminify-status--' . esc_attr( $this->message['type'] );
96 echo '<div class="' . esc_attr( $classes ) . '"><p>' . wp_kses_post( $this->message['message'] ) . '</p></div>';
97 }
98
99 public function network_panel_display() {
100 $multisite_settings = sprintf(
101 wp_kses_post( '<div class="%1$s"><h2>%2$s</h2> <a href="%3$s" target="_blank">%4$s</a></div>', 'adminify' ),
102 Utils::upgrade_pro_class(),
103 esc_html__( 'Network Settings', 'adminify' ),
104 esc_url( 'https://wpadminify.com/pricing' ),
105 Utils::adminify_upgrade_pro( 'Please Upgrade or Activate License' )
106 );
107 // Initialize the multisite_settings variable
108 $multisite_settings = apply_filters( 'adminify/admin_settings/network', $multisite_settings );
109 // Apply the filter
110 echo wp_kses_post( $multisite_settings );
111 }
112
113 public function option_modules() {
114 $extra_data_merge = [];
115 $clonable_data = [
116 '_wpadminify' => __( 'Adminify Options', 'adminify' ),
117 '_adminify_admin_columns_adminify_admin_page' => __( 'Admin Page Columns Data', 'adminify' ),
118 ];
119 // Activity Logs Active
120 if ( Utils::is_plugin_active( 'adminify-activity-logs/adminify-activity-logs.php' ) ) {
121 $extra_data_merge['adminify_activity_logs'] = __( 'Activity Logs Data', 'adminify' );
122 $clonable_data = array_merge( $clonable_data, $extra_data_merge );
123 }
124 // Quick Circle Menu Active
125 if ( Utils::is_plugin_active( 'adminify-quick-circle-menu/adminify-quick-circle-menu.php' ) ) {
126 $extra_data_merge['_wpadminify_quick_circle_menu'] = __( 'Quick Circle Menu', 'adminify' );
127 $clonable_data = array_merge( $clonable_data, $extra_data_merge );
128 }
129 // Google Pagespeed Active
130 if ( Utils::is_plugin_active( 'adminify-google-pagespeed/adminify-google-pagespeed.php' ) ) {
131 $extra_data_merge['adminify_page_speed'] = __( 'Google Pagespeed', 'adminify' );
132 $clonable_data = array_merge( $clonable_data, $extra_data_merge );
133 }
134 // Login Customizer Active
135 if ( Utils::is_plugin_active( 'loginfy/loginfy.php' ) ) {
136 $extra_data_merge['jltwp_adminify_login'] = __( 'Loginify Data', 'adminify' );
137 $clonable_data = array_merge( $clonable_data, $extra_data_merge );
138 }
139 // Header Footer Scripts Active
140 if ( Utils::is_plugin_active( 'adminify-sidebar-generator/adminify-sidebar-generator.php' ) ) {
141 $extra_data_merge['_wp_adminify_sidebar_settings'] = __( 'Sidebar Generator', 'adminify' );
142 $clonable_data = array_merge( $clonable_data, $extra_data_merge );
143 }
144 // Sidebar Generator Active
145 if ( Utils::is_plugin_active( 'adminify-header-footer-scripts/adminify-header-footer-scripts.php' ) ) {
146 $extra_data_merge['_wpadminify_custom_js_css'] = __( 'Custom JS/CSS', 'adminify' );
147 $clonable_data = array_merge( $clonable_data, $extra_data_merge );
148 }
149 // Admin Columns Active
150 if ( Utils::is_plugin_active( 'adminify-admin-columns/adminify-admin-columns.php' ) ) {
151 $extra_data_merge['_adminify_admin_columns_page'] = __( 'Admin Columns Page Data', 'adminify' );
152 $extra_data_merge['_adminify_admin_columns_post'] = __( 'Admin Columns Post Data', 'adminify' );
153 $clonable_data = array_merge( $clonable_data, $extra_data_merge );
154 }
155 return (array) apply_filters( 'adminify_clone_blog_option_modules', $clonable_data );
156 }
157
158 public function get_pagespeed_data( $copy_from ) {
159 switch_to_blog( $copy_from );
160 global $wpdb;
161 $table_name = $wpdb->prefix . 'adminify_page_speed';
162 $histories = $wpdb->get_results( "SELECT * FROM {$table_name}", ARRAY_A );
163 restore_current_blog();
164 return $histories;
165 }
166
167 public function clone_pagespeed_data( $histories, $copy_to ) {
168 switch_to_blog( $copy_to );
169 global $wpdb;
170 $table_name = $wpdb->prefix . 'adminify_page_speed';
171 foreach ( $histories as $history ) {
172 unset($history['id']);
173 $wpdb->insert( "{$table_name}", $history, [
174 'url' => '%s',
175 'score_desktop' => '%d',
176 'score_mobile' => '%d',
177 'data_desktop' => '%s',
178 'data_mobile' => '%s',
179 'screenshot' => '%s',
180 'time' => '%s',
181 ] );
182 }
183 restore_current_blog();
184 }
185
186 public function get_admin_columns_options( $copy_from ) {
187 $options = [];
188 switch_to_blog( $copy_from );
189 $args = [
190 'public' => true,
191 ];
192 $types = get_post_types( $args );
193 unset($types['attachment']);
194 restore_current_blog();
195 foreach ( $types as $type ) {
196 $options[] = '_adminify_admin_columns_meta_' . esc_attr( $type );
197 }
198 return $options;
199 }
200
201 public static function get_instance() {
202 if ( !is_null( self::$instance ) ) {
203 return self::$instance;
204 }
205 self::$instance = new self();
206 return self::$instance;
207 }
208
209 protected function get_defaults() {
210 return $this->defaults;
211 }
212
213 public static function get_pro_label() {
214 $is_pro = "";
215 $is_pro = WP_ADMINIFY;
216 return $is_pro;
217 }
218
219 public function get_plugin_menu_icon() {
220 $menu_icon = WP_ADMINIFY_ASSETS_IMAGE . 'logos/menu-icon-light.svg';
221 $saved_data = get_option( $this->prefix );
222 if ( isset( $saved_data['white_label']['adminify']['menu_icon'] ) && !empty( $saved_data['white_label']['adminify']['menu_icon']['url'] ) ) {
223 $menu_icon = $saved_data['white_label']['adminify']['menu_icon']['url'];
224 }
225 return $menu_icon;
226 }
227
228 public function get_plugin_menu_label() {
229 $plugin_menu_label = self::get_pro_label();
230 $saved_data = get_option( $this->prefix );
231 if ( isset( $saved_data['white_label']['adminify']['menu_label'] ) && !empty( $saved_data['white_label']['adminify']['menu_label'] ) ) {
232 $plugin_menu_label = $saved_data['white_label']['adminify']['menu_label'];
233 }
234 return $plugin_menu_label;
235 }
236
237 public static function support_url() {
238 $support_url = '';
239 $support_url = 'https://wordpress.org/support/plugin/adminify/#new-topic-0';
240 return $support_url;
241 }
242
243 public function jltwp_adminify_options() {
244 if ( !class_exists( 'ADMINIFY' ) ) {
245 return;
246 }
247 $submenu_position = apply_filters( 'jltwp_adminify_submenu_position', 30 );
248 $saved_data = get_option( $this->prefix );
249 $global_admin_ui_mode = ( empty( $saved_data['light_dark_mode']['admin_ui_mode'] ) ? 'light' : sanitize_text_field( $saved_data['light_dark_mode']['admin_ui_mode'] ) );
250 $admin_ui_mode = ( empty( get_user_meta( get_current_user_id(), 'color_mode', true ) ) ? $global_admin_ui_mode : get_user_meta( get_current_user_id(), 'color_mode', true ) );
251 $light_logo_image_url = WP_ADMINIFY_ASSETS_IMAGE . 'logos/logo-text-light.svg';
252 $dark_logo_image_url = WP_ADMINIFY_ASSETS_IMAGE . 'logos/logo-text-dark.svg';
253 $plugin_author_name = WP_ADMINIFY_AUTHOR;
254 // WP Adminify Options
255 \ADMINIFY::createOptions( $this->prefix, [
256 'framework_title' => '<img class="wp-adminify-settings-logo adminify-settings-light-logo" src=' . esc_url( $light_logo_image_url ) . '><img class="wp-adminify-settings-logo adminify-settings-dark-logo" src=' . esc_url( $dark_logo_image_url ) . '>' . ' <small>by ' . esc_html( $plugin_author_name ) . '</small>',
257 'framework_class' => '',
258 'menu_title' => $this->get_plugin_menu_label(),
259 'menu_slug' => 'wp-adminify-settings',
260 'menu_capability' => 'manage_options',
261 'menu_icon' => $this->get_plugin_menu_icon(),
262 'menu_position' => 30,
263 'menu_hidden' => false,
264 'menu_parent' => 'admin.php?page=wp-adminify-settings',
265 'show_bar_menu' => true,
266 'show_sub_menu' => false,
267 'show_in_network' => false,
268 'show_in_customizer' => false,
269 'show_search' => false,
270 'show_reset_all' => true,
271 'show_reset_section' => true,
272 'show_footer' => true,
273 'show_all_options' => false,
274 'show_form_warning' => true,
275 'sticky_header' => false,
276 'save_defaults' => false,
277 'ajax_save' => true,
278 'admin_bar_menu_icon' => '',
279 'admin_bar_menu_priority' => 80,
280 'footer_text' => ' ',
281 'footer_after' => ' ',
282 'footer_credit' => ' ',
283 'database' => 'options',
284 'transient_time' => 0,
285 'contextual_help' => [],
286 'contextual_help_sidebar' => '',
287 'enqueue_webfont' => true,
288 'async_webfont' => false,
289 'output_css' => true,
290 'nav' => 'normal',
291 'has_nav' => false,
292 'theme' => 'dark',
293 'class' => 'wp-adminify-settings',
294 'defaults' => [],
295 ] );
296 $this->defaults = array_merge( $this->defaults, ( new Customize() )->get_defaults() );
297 $this->defaults = array_merge( $this->defaults, ( new MenuLayout() )->get_defaults() );
298 $this->defaults = array_merge( $this->defaults, ( new Productivity() )->get_defaults() );
299 $this->defaults = array_merge( $this->defaults, ( new Security() )->get_defaults() );
300 $this->defaults = array_merge( $this->defaults, ( new Performance() )->get_defaults() );
301 $this->defaults = array_merge( $this->defaults, ( new CustomCSSJS() )->get_defaults() );
302 $this->defaults = array_merge( $this->defaults, ( new White_Label() )->get_defaults() );
303 // Fix Missing keys on save
304 add_filter( "adminify_{$this->prefix}_save", function ( $data ) {
305 $data = $this->fix_missing_keys( $this->defaults, $data );
306 return $data;
307 } );
308 // Backup Settings
309 \ADMINIFY::createSection( $this->prefix, [
310 'title' => __( 'Backup', 'adminify' ),
311 'icon' => 'fas fa-database',
312 'fields' => [[
313 'type' => 'subheading',
314 'content' => Utils::adminfiy_help_urls(
315 __( 'Backup Config Settings', 'adminify' ),
316 'https://wpadminify.com/docs/adminify/export-import/backup',
317 'https://www.youtube.com/playlist?list=PLqpMw0NsHXV-EKj9Xm1DMGa6FGniHHly8',
318 'https://www.facebook.com/groups/jeweltheme',
319 self::support_url()
320 ),
321 ], [
322 'type' => 'backup',
323 'class' => 'adminify-block',
324 ]],
325 ] );
326 }
327
328 function fix_missing_keys( $defaults, $data ) {
329 if ( is_array( $defaults ) ) {
330 foreach ( $defaults as $key => $value ) {
331 if ( is_array( $value ) ) {
332 if ( !isset( $data[$key] ) || gettype( $data[$key] ) !== 'array' ) {
333 $data[$key] = [];
334 }
335 $data[$key] = $this->fix_missing_keys( $value, $data[$key] );
336 }
337 }
338 }
339 return $data;
340 }
341
342 public function get_prefix() {
343 return $this->prefix;
344 }
345
346 /**
347 * Render-time hook that neutralizes Pro-locked controls in the
348 * free build. Bypassed when the Pro plugin is active so the Pro
349 * UI is unchanged.
350 *
351 * Two operating modes, both detected from the rendered HTML:
352 *
353 * 1. Field-level lock (the field's class array contains
354 * 'adminify-pro-locked'): strip name="..." from every input/
355 * select/textarea, add disabled + tabindex="-1", and wrap the
356 * entire field with a <div class="adminify-pro-locked-wrapper">
357 * that carries a lock-icon + "Upgrade to Pro" CTA overlay.
358 *
359 * 2. Option-level lock (a checkbox/radio option label contains
360 * <span class="adminify-pro-locked-option">): for every <li>
361 * that contains the marker span, strip name="..." from the
362 * enclosed input and add disabled + tabindex="-1". Inline lock
363 * icon is rendered by CSS off the marker class itself.
364 *
365 * @param string $html Rendered field HTML from the framework.
366 * @param array $field Field config array.
367 * @return string Possibly transformed HTML.
368 */
369 public function adminify_render_pro_locked_field( $html, $field ) {
370 // Pro plugin active: leave HTML untouched.
371 if ( function_exists( 'jltwp_adminify' ) && jltwp_adminify()->can_use_premium_code__premium_only() ) {
372 return $html;
373 }
374 $field_class = '';
375 if ( is_array( $field ) && isset( $field['class'] ) ) {
376 $field_class = (string) $field['class'];
377 }
378 // Detect field-level lock from either the new marker class
379 // (adminify-pro-locked) or the legacy Pro-feature classes that
380 // pre-date the render-disable hook. Both signal a Pro-only
381 // field that must not submit a value in the free build.
382 $has_field_lock = strpos( $field_class, 'adminify-pro-locked' ) !== false || strpos( $field_class, 'adminify-pro-fieldset' ) !== false || strpos( $field_class, 'adminify-pro-feature' ) !== false || strpos( $field_class, 'adminify-pro-notice' ) !== false;
383 // Per-option lock signal: the helper Utils::adminify_upgrade_pro_class()
384 // emits a <span class="adminify-pro-checkbox"> next to a Pro-only
385 // checkbox label. Match that span (or the historical
386 // adminify-pro-locked-option marker) inside <li> blocks.
387 $has_option_lock = strpos( $html, 'adminify-pro-checkbox' ) !== false || strpos( $html, 'adminify-pro-locked-option' ) !== false;
388 if ( !$has_field_lock && !$has_option_lock ) {
389 return $html;
390 }
391 if ( $has_field_lock ) {
392 // Strip name attrs and disable inputs across the whole field.
393 // The visual treatment is the inline <span class="adminify-pro-badge">Pro</span>
394 // rendered by the helper — no extra wrapper / overlay.
395 $html = $this->adminify_strip_inputs( $html );
396 return $html;
397 }
398 // Option-level: only strip inputs inside <li> blocks that
399 // carry the per-option marker. Match each <li> ... </li>
400 // non-greedily.
401 $html = preg_replace_callback( '#<li\\b[^>]*>(.*?)</li>#is', function ( $li_match ) {
402 $li_inner = $li_match[1];
403 if ( strpos( $li_inner, 'adminify-pro-checkbox' ) === false && strpos( $li_inner, 'adminify-pro-locked-option' ) === false ) {
404 return $li_match[0];
405 }
406 $open_tag_end = strpos( $li_match[0], '>' );
407 $open_tag = substr( $li_match[0], 0, $open_tag_end + 1 );
408 return $open_tag . $this->adminify_strip_inputs( $li_inner ) . '</li>';
409 }, $html );
410 return $html;
411 }
412
413 /**
414 * Strip name="..." from inputs/selects/textareas in the given
415 * HTML and add disabled + tabindex="-1" if missing. Pure string
416 * transform — the framework emits a known shape.
417 */
418 private function adminify_strip_inputs( $html ) {
419 $html = preg_replace( '/\\s+name="[^"]*"/i', '', $html );
420 $html = preg_replace_callback( '/<(input|select|textarea)\\b([^>]*)>/i', function ( $m ) {
421 $attrs = $m[2];
422 if ( strpos( $attrs, 'disabled' ) === false ) {
423 $attrs .= ' disabled="disabled"';
424 }
425 if ( strpos( $attrs, 'tabindex=' ) === false ) {
426 $attrs .= ' tabindex="-1"';
427 }
428 return '<' . $m[1] . $attrs . '>';
429 }, $html );
430 return $html;
431 }
432
433 }
434
435 }