init_hooks(); } /** * Get the single instance of the SVG_Support class. * * @since 1.0.0 * @access public * * @return SVG_Support The single instance. */ public static function get_instance() { if ( is_null( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Initialize WordPress hooks. * * @since 1.0.0 * @access private * * @return void */ private function init_hooks() { add_filter( 'wp_check_filetype_and_ext', array( $this, 'check_svg_filetype' ), 10, 4 ); add_filter( 'upload_mimes', array( $this, 'add_svg_mime_type' ) ); add_filter( 'user_has_cap', array( $this, 'grant_svg_upload_capability' ), 10, 3 ); add_action( 'admin_enqueue_scripts', array( $this, 'add_svg_admin_styles' ) ); } /** * Check and validate SVG file type during upload. * * @since 1.0.0 * @access public * * @param array $data File data containing ext and type. * @param string $file Full path to the file. * @param string $filename The name of the file. * @param array $mimes Array of allowed mime types. * * @return array Modified file data. */ public function check_svg_filetype( $data, $file, $filename, $mimes ) { // Check if user has capability to upload SVG. if ( ! current_user_can( 'upload_svg' ) ) { return $data; } // Check file extension. $filetype = wp_check_filetype( $filename, $mimes ); if ( 'svg' !== $filetype['ext'] ) { return $data; } // Validate SVG content. if ( ! $this->validate_svg_file( $file ) ) { $data['error'] = esc_html__( 'SVG file contains potentially unsafe content.', 'acumen-popup' ); return $data; } // Set correct file type. $data['ext'] = 'svg'; $data['type'] = 'image/svg+xml'; return $data; } /** * Validate SVG file content for security. * * @since 1.0.0 * @access private * * @param string $file Path to the SVG file. * * @return bool True if valid, false otherwise. */ private function validate_svg_file( $file ) { // Initialize filesystem. global $wp_filesystem; if ( empty( $wp_filesystem ) ) { require_once ABSPATH . '/wp-admin/includes/file.php'; WP_Filesystem(); } if ( ! $wp_filesystem || ! file_exists( $file ) ) { return false; } $content = $wp_filesystem->get_contents( $file ); if ( empty( $content ) ) { return false; } // Check for potentially dangerous content. $dangerous_patterns = array( '/