init_hooks(); } /** * Initialize hooks */ private function init_hooks() { // Add admin menu add_action( 'admin_menu', array( $this, 'add_menu' ) ); // Register settings add_action( 'admin_init', array( $this, 'register_settings' ) ); // Admin bar cache clear button add_action( 'admin_bar_menu', array( $this, 'add_admin_bar_button' ), 100 ); // Handle cache clear action add_action( 'admin_init', array( $this, 'handle_cache_clear' ) ); // Admin notices add_action( 'admin_notices', array( $this, 'admin_notices' ) ); // Admin styles add_action( 'admin_enqueue_scripts', array( $this, 'admin_styles' ) ); // Plugin action links add_filter( 'plugin_action_links_' . plugin_basename( MAPLE_PERF_FILE ), array( $this, 'action_links' ) ); // Privacy policy add_action( 'admin_init', array( $this, 'add_privacy_policy_content' ) ); } /** * Add privacy policy content */ public function add_privacy_policy_content() { if ( ! function_exists( 'wp_add_privacy_policy_content' ) ) { return; } $content = sprintf( '

%s

%s

%s

%s

%s

%s

%s

%s

', __( 'Maple Performance WP', 'maple-performance' ), __( 'This site uses the Maple Performance WP plugin to improve page load times through caching and asset optimization.', 'maple-performance' ), __( 'What personal data we collect and why', 'maple-performance' ), __( 'Maple Performance WP does not collect, store, or process any personal data. The plugin caches publicly-visible page content to improve performance. By default, pages are not cached for logged-in users, ensuring that no user-specific content is stored in the cache.', 'maple-performance' ), __( 'Cookies', 'maple-performance' ), __( 'Maple Performance WP does not set any cookies. The plugin may read existing cookies (such as WordPress login cookies or WooCommerce cart cookies) solely to determine whether to serve a cached page or bypass the cache for dynamic content. No cookie data is stored or transmitted.', 'maple-performance' ), __( 'Third-party services', 'maple-performance' ), __( 'Maple Performance WP does not connect to any external services or transmit any data to third parties. All caching and optimization is performed locally on your web server.', 'maple-performance' ) ); wp_add_privacy_policy_content( 'Maple Performance WP', wp_kses_post( $content ) ); } /** * Add admin menu */ public function add_menu() { add_options_page( __( 'Maple Performance', 'maple-performance' ), __( 'Maple Performance', 'maple-performance' ), 'manage_options', 'maple-performance', array( $this, 'settings_page' ) ); } /** * Register settings */ public function register_settings() { register_setting( 'maple_performance_settings', 'maple_performance_settings', array( $this, 'sanitize_settings' ) ); } /** * Sanitize settings */ public function sanitize_settings( $input ) { $sanitized = array(); // Site mode $sanitized['site_mode'] = sanitize_text_field( $input['site_mode'] ?? 'brochure' ); // Google Fonts mode $valid_font_modes = array( 'leave', 'remove', 'combine', 'defer' ); $sanitized['google_fonts'] = in_array( $input['google_fonts'] ?? 'defer', $valid_font_modes ) ? $input['google_fonts'] : 'defer'; // Plugin compatibility $sanitized['compat_auto_detect'] = ! empty( $input['compat_auto_detect'] ); // Manual plugin selection $valid_compat_plugins = array( 'woocommerce', 'learndash', 'wordfence', 'wpforms', 'gutenberg_fse' ); $sanitized['compat_plugins'] = array(); if ( ! empty( $input['compat_plugins'] ) && is_array( $input['compat_plugins'] ) ) { foreach ( $input['compat_plugins'] as $plugin ) { if ( in_array( $plugin, $valid_compat_plugins ) ) { $sanitized['compat_plugins'][] = $plugin; } } } // Boolean settings $booleans = array( 'cache_enabled', 'cache_logged_in', 'cache_gzip', 'cache_brotli', 'html_minify', 'html_remove_comments', 'css_minify', 'css_aggregate', 'css_inline_aggregate', 'css_defer', 'js_minify', 'js_aggregate', 'js_defer', 'js_exclude_jquery', 'remove_emojis', 'remove_query_strings', 'dns_prefetch', 'lazyload_images', 'lazyload_iframes', 'local_font_display', ); foreach ( $booleans as $key ) { $sanitized[ $key ] = ! empty( $input[ $key ] ); } // Integer settings $sanitized['cache_expiry'] = absint( $input['cache_expiry'] ?? 0 ); // Array settings (textarea, one per line) $arrays = array( 'exclude_paths', 'exclude_cookies', 'exclude_js', 'exclude_css', 'preconnect_domains', 'lazyload_exclude', 'preload_fonts', ); foreach ( $arrays as $key ) { $value = $input[ $key ] ?? ''; if ( is_string( $value ) ) { $lines = explode( "\n", $value ); $sanitized[ $key ] = array_filter( array_map( function( $line ) { // Sanitize each line - remove potentially dangerous characters $line = trim( $line ); $line = str_replace( array( "\0", "\r" ), '', $line ); // For URLs/paths, use esc_url_raw for domains, sanitize_text_field for others if ( strpos( $line, 'http' ) === 0 || strpos( $line, '//' ) === 0 ) { return esc_url_raw( $line ); } return sanitize_text_field( $line ); }, $lines ) ); } else { $sanitized[ $key ] = array(); } } // Clear cache when settings change maple_performance()->clear_cache(); return $sanitized; } /** * Add admin bar button */ public function add_admin_bar_button( $wp_admin_bar ) { if ( ! current_user_can( 'manage_options' ) ) { return; } $wp_admin_bar->add_node( array( 'id' => 'maple-performance', 'title' => '' . __( 'Maple Cache', 'maple-performance' ), 'href' => '#', ) ); $wp_admin_bar->add_node( array( 'parent' => 'maple-performance', 'id' => 'maple-clear-cache', 'title' => __( 'Clear All Cache', 'maple-performance' ), 'href' => wp_nonce_url( admin_url( 'admin.php?action=maple_clear_cache' ), 'maple_clear_cache' ), ) ); $wp_admin_bar->add_node( array( 'parent' => 'maple-performance', 'id' => 'maple-settings', 'title' => __( 'Settings', 'maple-performance' ), 'href' => admin_url( 'options-general.php?page=maple-performance' ), ) ); // Show cache stats - use transient to avoid filesystem scan on every page load $stats = get_transient( 'maple_perf_cache_stats' ); if ( false === $stats ) { // Only calculate if not cached, with a 5-minute expiry $stats = array( 'count' => Maple_Performance_Cache::get_cache_count(), 'size' => Maple_Performance_Cache::get_cache_size(), ); set_transient( 'maple_perf_cache_stats', $stats, 5 * MINUTE_IN_SECONDS ); } $wp_admin_bar->add_node( array( 'parent' => 'maple-performance', 'id' => 'maple-cache-stats', 'title' => sprintf( __( 'Cache: %d pages (%s)', 'maple-performance' ), $stats['count'], size_format( $stats['size'] ) ), 'href' => admin_url( 'options-general.php?page=maple-performance' ), ) ); } /** * Handle cache clear action */ public function handle_cache_clear() { if ( ! isset( $_GET['action'] ) || $_GET['action'] !== 'maple_clear_cache' ) { return; } if ( ! current_user_can( 'manage_options' ) ) { wp_die( __( 'Unauthorized', 'maple-performance' ) ); } if ( ! wp_verify_nonce( $_GET['_wpnonce'] ?? '', 'maple_clear_cache' ) ) { wp_die( __( 'Invalid nonce', 'maple-performance' ) ); } maple_performance()->clear_cache(); // Redirect back with notice $redirect = remove_query_arg( array( 'action', '_wpnonce' ), wp_get_referer() ); $redirect = add_query_arg( 'maple_cache_cleared', '1', $redirect ); wp_safe_redirect( $redirect ); exit; } /** * Admin notices */ public function admin_notices() { // Show activation conflict notice (only once, immediately after activation) $activation_conflicts = get_transient( 'maple_perf_activation_conflict' ); if ( false !== $activation_conflicts && is_array( $activation_conflicts ) ) { delete_transient( 'maple_perf_activation_conflict' ); echo '
'; echo '

' . esc_html__( '⚠️ Maple Performance WP - Important!', 'maple-performance' ) . '

'; echo '

' . sprintf( esc_html__( 'Another caching plugin is already active: %s', 'maple-performance' ), '' . esc_html( implode( ', ', $activation_conflicts ) ) . '' ) . '

'; echo '

' . esc_html__( 'Running multiple caching plugins can cause site errors, blank pages, or performance issues.', 'maple-performance' ) . '

'; echo '

'; echo '' . esc_html__( 'Choose which plugin to keep', 'maple-performance' ) . ' '; echo '' . esc_html__( 'Go to Settings', 'maple-performance' ) . ''; echo '

'; echo '
'; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only display check if ( isset( $_GET['maple_cache_cleared'] ) ) { echo '
'; echo '

' . esc_html__( 'Maple Performance: Cache cleared successfully.', 'maple-performance' ) . '

'; echo '
'; } // Check if settings were saved // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only display check $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; if ( isset( $_GET['settings-updated'] ) && $page === 'maple-performance' ) { echo '
'; echo '

' . esc_html__( 'Maple Performance: Settings saved and cache cleared.', 'maple-performance' ) . '

'; echo '
'; } } /** * Admin styles */ public function admin_styles( $hook ) { if ( $hook !== 'settings_page_maple-performance' ) { return; } wp_add_inline_style( 'common', ' .maple-settings { max-width: 900px; } .maple-settings h2 { border-bottom: 1px solid #ccc; padding-bottom: 10px; margin-top: 30px; } .maple-settings h2:first-of-type { margin-top: 10px; } .maple-settings table { margin-bottom: 20px; } .maple-settings .description { color: #666; font-style: italic; } .maple-settings textarea { width: 100%; max-width: 400px; } .maple-settings .site-mode-card { border: 2px solid #ddd; padding: 15px; margin: 10px 0; border-radius: 5px; cursor: pointer; } .maple-settings .site-mode-card:hover { border-color: #2271b1; } .maple-settings .site-mode-card.selected { border-color: #2271b1; background: #f0f7fc; } .maple-settings .site-mode-card h4 { margin: 0 0 5px; } .maple-settings .warning { color: #d63638; } .maple-settings .safe { color: #00a32a; } .maple-cache-stats { background: #f0f0f1; padding: 15px; border-radius: 5px; margin-bottom: 20px; } .maple-cache-stats strong { font-size: 1.2em; } .maple-detected-plugins { background: #f9f9f9; border: 1px solid #ddd; border-radius: 5px; padding: 15px 20px; margin-bottom: 25px; } .maple-detected-plugins h3 { margin-top: 0; } .maple-detected-plugins table { margin-top: 15px; } .maple-detected-plugins ul li { font-size: 13px; color: #555; } ' ); } /** * Plugin action links */ public function action_links( $links ) { $settings_link = '' . __( 'Settings', 'maple-performance' ) . ''; $clear_link = '' . __( 'Clear Cache', 'maple-performance' ) . ''; array_unshift( $links, $settings_link, $clear_link ); return $links; } /** * Settings page */ public function settings_page() { $settings = maple_performance()->settings; // Get cache stats $cache_count = Maple_Performance_Cache::get_cache_count(); $cache_size = Maple_Performance_Cache::get_cache_size(); ?>

  
get_detected() : array(); ?>

Manual selection below is recommended for reliability.', 'maple-performance' ); ?>

Tip: Select plugins you have installed even if not detected. Detection can miss plugins due to naming changes between versions.', 'maple-performance' ); ?>

Brochure: Full optimization enabled. WooCommerce/LearnDash: Conservative settings to protect checkout and lesson tracking.', 'maple-performance' ); ?>

get_caching_conflicts(); if ( ! empty( $caching_conflicts ) ) { echo '
'; echo '

' . esc_html__( '⚠️ Another caching plugin detected:', 'maple-performance' ) . ' '; echo esc_html( implode( ', ', $caching_conflicts ) ) . '

'; echo '

' . esc_html__( 'Consider disabling Page Cache below and using only the CSS/JS/HTML optimizations to avoid conflicts.', 'maple-performance' ) . '

'; echo '
'; } } ?>

Defer is recommended - loads fonts without blocking page render.', 'maple-performance' ); ?>


Example: /wp-content/themes/yourtheme/fonts/font-name.woff2', 'maple-performance' ); ?>


v | Maple Open Tech | 🍁