'warning',
'message' => __('Git Code Viewer: Wordfence detected. Please ensure the following URLs are whitelisted in Wordfence settings: api.github.com, gitlab.com, api.bitbucket.org, codeberg.org', 'maple-code-blocks'),
'dismissible' => true
);
}
// WooCommerce compatibility (informational)
if (class_exists('WooCommerce')) {
// No issues, just log for debugging
error_log('GCV: WooCommerce detected - compatibility mode active');
}
// LearnDash compatibility (informational)
if (defined('LEARNDASH_VERSION')) {
// No issues, just log for debugging
error_log('GCV: LearnDash detected - compatibility mode active');
}
// Memory limit warning
$memory_limit = ini_get('memory_limit');
if ($memory_limit && self::convert_to_bytes($memory_limit) < 67108864) { // 64MB
$notices[] = array(
'type' => 'warning',
'message' => __('Git Code Viewer: Low memory limit detected. Consider increasing memory_limit to at least 64MB for optimal performance.', 'maple-code-blocks'),
'dismissible' => true
);
}
// Display notices
foreach ($notices as $notice) {
$dismissible = $notice['dismissible'] ? 'is-dismissible' : '';
printf(
'
',
esc_attr($notice['type']),
esc_attr($dismissible),
esc_html($notice['message'])
);
}
}
/**
* Optimize plugin loading
*/
public static function optimize_loading() {
// Hook into admin_init for screen-specific optimizations
if (is_admin()) {
add_action('admin_init', function() {
// Check screen only after it's available
add_action('current_screen', function($screen) {
if ($screen && $screen->id !== 'settings_page_maple-code-blocks') {
remove_action('admin_enqueue_scripts', array('Maple_Code_Blocks', 'enqueue_scripts'));
}
});
});
}
// Optimize transient cleanup
if (!wp_next_scheduled('mcb_cleanup_transients')) {
wp_schedule_event(time(), 'daily', 'mcb_cleanup_transients');
}
add_action('mcb_cleanup_transients', function() {
global $wpdb;
// Use WordPress function instead of direct query
if (function_exists('delete_expired_transients')) {
delete_expired_transients();
} else {
// Fallback for older WordPress versions
$wpdb->query(
"DELETE FROM {$wpdb->options}
WHERE option_name LIKE '_transient_timeout_mcb_%'
AND option_value < UNIX_TIMESTAMP()"
);
}
});
}
/**
* Helper: Check if IP is in range
*/
private static function ip_in_range($ip, $range) {
if (strpos($range, '/') === false) {
$range .= '/32';
}
list($subnet, $bits) = explode('/', $range);
// IPv4
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) &&
filter_var($subnet, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
$ip = ip2long($ip);
$subnet = ip2long($subnet);
$mask = -1 << (32 - $bits);
$subnet &= $mask;
return ($ip & $mask) == $subnet;
}
// IPv6
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) &&
filter_var($subnet, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
$ip_bin = inet_pton($ip);
$subnet_bin = inet_pton($subnet);
$bytes = $bits / 8;
$remainder = $bits % 8;
if ($bytes > 0) {
if (substr($ip_bin, 0, $bytes) !== substr($subnet_bin, 0, $bytes)) {
return false;
}
}
if ($remainder > 0 && $bytes < 16) {
$mask = 0xFF << (8 - $remainder);
$ip_byte = ord($ip_bin[$bytes]);
$subnet_byte = ord($subnet_bin[$bytes]);
if (($ip_byte & $mask) !== ($subnet_byte & $mask)) {
return false;
}
}
return true;
}
return false;
}
/**
* Helper: Convert memory string to bytes
*/
private static function convert_to_bytes($val) {
$val = trim($val);
$last = strtolower($val[strlen($val)-1]);
$val = (int)$val;
switch($last) {
case 'g':
$val *= 1024;
case 'm':
$val *= 1024;
case 'k':
$val *= 1024;
}
return $val;
}
}
// Initialize security fixes
add_action('plugins_loaded', array('MCB_Security_Fixes', 'init'), 5);
add_action('rest_api_init', function() {
register_rest_route('maple-code-blocks/v1', '/health', array(
'methods' => 'GET',
'callback' => function() {
$health = array(
'status' => 'healthy',
'version' => '2.0.0',
'php_version' => PHP_VERSION,
'wordpress_version' => get_bloginfo('version'),
'memory_usage' => memory_get_usage(true),
'memory_limit' => ini_get('memory_limit'),
'wordfence_active' => defined('WORDFENCE_VERSION'),
'woocommerce_active' => class_exists('WooCommerce'),
'learndash_active' => defined('LEARNDASH_VERSION'),
'cache_size' => count(get_transient('mcb_security_logs') ?: array()),
'rate_limit_active' => !defined('WORDFENCE_VERSION')
);
return new WP_REST_Response($health, 200);
},
'permission_callback' => function() {
return current_user_can('manage_options');
}
));
});