'editing.posts.disable_autosave', 'category' => 'editing', 'ui_config' => fn() => [ 'tags' => [ __('Editing', 'advanced-settings'), __('Posts', 'advanced-settings'), __('Performance', 'advanced-settings'), __('Database', 'advanced-settings'), __('Admin', 'advanced-settings'), ], 'fields' => [ 'enable' => [ 'type' => 'toggle', 'label' => __('Disable auto save', 'advanced-settings'), ], ] ], 'execution_handler' => function() { define('AUTOSAVE_INTERVAL', 60 * 60 * 24 * 365 * 100); // save interval => 100 years }, 'priority' => 10, ]); advset_register_feature([ 'id' => 'editing.posts.limit_revisions', 'category' => 'editing', 'ui_config' => fn() => [ 'tags' => [ __('Editing', 'advanced-settings'), __('Posts', 'advanced-settings'), __('Performance', 'advanced-settings'), __('Database', 'advanced-settings'), __('Admin', 'advanced-settings'), ], 'fields' => [ 'enable' => [ 'type' => 'toggle', 'label' => __('Limit post revisions', 'advanced-settings'), 'description' => __('Reduce database size by limiting the number of saved revisions', 'advanced-settings'), ], 'limit' => [ 'type' => 'number', 'label' => __('Revisions to keep', 'advanced-settings'), 'description' => __('0 means revisions are disabled.', 'advanced-settings'), 'min' => 0, 'default' => 5, 'visible' => ['enable' => true], ], 'type' => [ 'type' => 'radio', 'label' => __('Post types', 'advanced-settings'), 'description' => __('Select the post types that should be affected by the revision limit.', 'advanced-settings'), 'options' => [ 'post' => ['label' => 'Posts only'], 'page' => ['label' => 'Pages only'], 'post_and_page' => ['label' => 'Posts and Pages'], 'all' => ['label' => 'All post types (includes custom post types)'], ], 'default' => 'post', 'visible' => ['enable' => true], ], ] ], 'handler_cleanup' => function($settings) { return empty($settings['enable']) ? null : $settings; }, 'execution_handler' => function($settings) { if ($settings['type'] === 'all') { add_filter('wp_revisions_to_keep', function($num) use($settings) { return $settings['limit']; }); return; } foreach (explode('_and_', $settings['type']) as $type) { add_filter('wp_' . $type . '_revisions_to_keep', function($num) use($settings) { return $settings['limit']; }); } }, 'priority' => 20, ]); advset_register_feature([ 'id' => 'editing.media.enable_svg', 'category' => 'editing', 'ui_config' => fn() => [ 'tags' => [ __('Editing', 'advanced-settings'), __('Media', 'advanced-settings'), __('Images', 'advanced-settings'), __('Frontend', 'advanced-settings'), __('Performance', 'advanced-settings'), ], 'fields' => [ 'enable' => [ 'type' => 'toggle', 'label' => __('Allow SVG upload for admins', 'advanced-settings'), 'description' => __('To keep the plugin lightweight, the SVG security checks in this feature are very limited. Therefore, this feature is only available to administrators.', 'advanced-settings'), ], ] ], 'execution_handler' => function() { if (!current_user_can('administrator')) { return; } add_filter('upload_mimes', function($mimes) { $mimes['svg'] = 'image/svg+xml'; $mimes['svgz'] = 'image/svg+xml'; return $mimes; }); add_filter('wp_handle_upload_prefilter', function($file) { if ($file['type'] !== 'image/svg+xml') { return $file; } $file_content = file_get_contents($file['tmp_name']); // 1. Check if the file is empty if (empty($file_content)) { $file['error'] = __('Empty SVG file', 'advanced-settings'); return $file; } // 2. Remove XML declaration and Doctype for better compatibility $clean_content = preg_replace('/<\?xml\b[^>]*>\s*/i', '', $file_content); $clean_content = preg_replace('/[]*(\[[^]]*\])?[^>]*>\s*/is', '', $clean_content); // 3. XXE-Protection (critical!) // libxml_disable_entity_loader() is deprecated since PHP 8.0 and unnecessary there, // because external entity loading is disabled by default since libxml2 2.9. $entity_loader_state = PHP_VERSION_ID < 80000 ? libxml_disable_entity_loader(true) : null; libxml_use_internal_errors(true); libxml_clear_errors(); $svg = @simplexml_load_string($clean_content); if ($svg === false) { $errors = libxml_get_errors(); $first_error = !empty($errors[0]) ? $errors[0]->message : __('Unknown error', 'advanced-settings'); libxml_clear_errors(); /* translators: %s is the first error message from libxml */ $file['error'] = sprintf(__('Invalid SVG: %s', 'advanced-settings'), esc_html($first_error)); return $file; } // 4. Simple, but effective security checks $unsafe_patterns = [ '/