85, 'png_quality_min' => 70, 'png_quality_max' => 90, 'jpeg_chroma_subsampling' => '4:4:4', // preserve edges; the fix for the Smush bug 'preserve_icc_profile' => true, // CRITICAL — the bug fix 'strip_gps_exif' => true, 'strip_camera_exif' => false, // keep camera info for art provenance // Format generation 'generate_webp' => true, 'generate_avif' => true, // design decision 1: on by default everywhere 'webp_quality' => 90, // matches source JPG luminance for B&W ink on white 'avif_quality' => 65, // ≈ JPEG q=85 visually 'avif_speed' => 6, // 0-10; 6 is balanced 'avif_async' => true, // background WP-Cron so upload UI is responsive // Behaviour 'optimise_on_upload' => true, 'backup_originals' => true, // design decision 4: always 'backup_prune_days' => 90, // 0 = keep forever 'resize_max_width' => 2560, 'resize_max_height' => 2560, 'skip_already_processed' => true, 'min_optimise_bytes' => 20480, // skip files < 20KB (thumbnails) // Serving 'rewrite_content_images' => true, // Picture tag rewriting 'use_htaccess_fallback' => true, // .htaccess content negotiation // Bulk 'bulk_batch_size' => 10, 'bulk_pause_seconds' => 1, // Exclusions 'exclude_mime_types' => [ 'image/svg+xml', 'image/x-icon', 'image/gif' ], 'exclude_paths_regex' => '', ]; } public static function install_defaults(): void { $existing = get_option( self::OPTION_KEY ); if ( false === $existing ) { add_option( self::OPTION_KEY, self::defaults(), '', false ); return; } // Merge new keys without clobbering user changes $merged = array_replace( self::defaults(), is_array( $existing ) ? $existing : [] ); update_option( self::OPTION_KEY, $merged, false ); } public static function get( string $key, mixed $default = null ): mixed { $settings = get_option( self::OPTION_KEY, self::defaults() ); return $settings[ $key ] ?? $default; } public static function set( string $key, mixed $value ): void { $settings = get_option( self::OPTION_KEY, self::defaults() ); $settings[ $key ] = $value; update_option( self::OPTION_KEY, $settings, false ); } public static function all(): array { return get_option( self::OPTION_KEY, self::defaults() ); } }