Linux webm002.cluster126.gra.hosting.ovh.net 5.15.206-ovh-vps-grsec-zfs-classid #1 SMP Fri May 15 02:41:25 UTC 2026 x86_64
/
home
/
ariannadhf
/
www
/
wp-content
/
plugins
/
themeisle-companion
/
obfx_modules
/
svg-uploads
/
/home/ariannadhf/www/wp-content/plugins/themeisle-companion/obfx_modules/svg-uploads/init.php
<?php /** * SVG Uploads Core Orbit Fox Module. * * @link https://themeisle.com * @since 3.0.0 * * @package Svg_Uploads_OBFX_Module */ use \enshrined\svgSanitize\Sanitizer; /** * The class defines a new module to be used by Orbit Fox plugin. * * @package Svg_Uploads_OBFX_Module * @author Themeisle <friends@themeisle.com> * @codeCoverageIgnore */ class Svg_Uploads_OBFX_Module extends Orbit_Fox_Module_Abstract { /** * The sanitizer instance. * * @var Sanitizer */ protected $sanitizer = null; /** * Setup module strings * * @access public */ public function set_module_strings() { $this->name = __( 'SVG Support', 'themeisle-companion' ); $this->description = __( 'Enable SVG file uploads and media library support. By default, WordPress doesn\'t allow uploading SVG files for security reasons. This module safely enables SVG support with proper sanitization.', 'themeisle-companion' ); $this->documentation_url = 'https://docs.themeisle.com/article/951-orbit-fox-documentation#svg-support'; $this->notices = array( array( 'message' => __( 'Only enable this if you trust all users who can upload files to your site. SVG files can contain malicious code if not properly sanitized.', 'themeisle-companion' ), 'type' => 'warning', ), ); } /** * Determine if module should be loaded. * * @return bool */ public function enable_module() { return true; } public function load() { } public function options() { return array(); } public function admin_enqueue() { return array(); } public function public_enqueue() { return array(); } /** * Method to define hooks needed. * * @since 3.0.0 * @access public * @return mixed | array */ public function hooks() { $this->load_sanitizer(); $this->loader->add_filter( 'upload_mimes', $this, 'add_svg_mime_type' ); $this->loader->add_filter( 'wp_prepare_attachment_for_js', $this, 'prepare_attachment_for_js', 10, 3 ); $this->loader->add_filter( 'wp_handle_upload_prefilter', $this, 'sanitize_uploaded_file' ); $this->loader->add_filter( 'wp_check_filetype_and_ext', $this, 'adjust_filetype_extension', 100, 4 ); $this->loader->add_filter( 'wp_generate_attachment_metadata', $this, 'generate_attachment_metadata', 10, 2 ); } /** * Load the SVG sanitizer and its required classes. * * @return void */ private function load_sanitizer() { $this->sanitizer = new Sanitizer(); $this->sanitizer->removeXMLTag( true ); $this->sanitizer->minify( true ); } /** * Sanitize uploaded file. * * @param array $file The file array. * * @return array The sanitized file array. */ public function sanitize_uploaded_file( $file ) { if ( ! is_file( $file['tmp_name'] ) ) { return $file; } $file_info = wp_check_filetype( basename( $file['tmp_name'] ) ); $file_type = $file_info['type']; $mime_types = array( 'image/svg+xml', 'image/svg' ); if ( ! in_array( $file_type, $mime_types, true ) ) { return $file; } if ( ! current_user_can( 'upload_files' ) ) { $file['error'] = __( 'You are not allowed to upload files.', 'themeisle-companion' ); return $file; } if ( ! $this->sanitize( $file['tmp_name'] ) ) { $file['error'] = __( 'This SVG can not be sanitized!', 'themeisle-companion' ); } return $file; } /** * Sanitize SVG file. * * Sanitizes the SVG, removes XML tags and minifies the code and replaces the original file. * * @param string $file The SVG file path. * * @return bool True if the SVG file is sanitized, false otherwise. */ private function sanitize( $file ) { if ( ! is_file( $file ) ) { return false; } $svg_code = file_get_contents( $file ); $is_compressed = $this->is_gzipped( $svg_code ); if ( $is_compressed && ( ! function_exists( 'gzdecode' ) || ! function_exists( 'gzencode' ) ) ) { return false; } if ( $is_compressed ) { $svg_code = gzdecode( $svg_code ); if ( $svg_code === false ) { return false; } } $clean_svg_code = $this->sanitizer->sanitize( $svg_code ); if ( ! $clean_svg_code ) { return false; } if ( $is_compressed ) { $clean_svg_code = gzencode( $clean_svg_code ); } file_put_contents( $file, $clean_svg_code ); return true; } /** * Check if the SVG is gzipped. * * @param string $svg_code The SVG code. * * @return bool True if the SVG is gzipped, false otherwise. */ public function is_gzipped( $svg_code ) { // phpcs:ignore Generic.Strings.UnnecessaryStringConcat.Found return 0 === strpos( $svg_code, "\x1f" . "\x8b" . "\x08" ); } /** * Add SVG mime type to the allowed mime types. * * @param array $mimes The mime types array. * * @return array The modified mime types array. */ public function add_svg_mime_type( $mimes ) { $mimes['svg'] = 'image/svg+xml'; $mimes['svgz'] = 'image/svg+xml'; return $mimes; } /** * Check file type and extension. * * @param array $filetype_ext_data The file type and extension data. * @param string $file The file path. * @param string $filename The file name. * @param array $mimes The mime types array. * * @return array The modified file type and extension data. */ public function adjust_filetype_extension( $filetype_ext_data, $file, $filename, $mimes ) { if ( substr( $filename, -4 ) === '.svg' ) { $filetype_ext_data['ext'] = 'svg'; $filetype_ext_data['type'] = 'image/svg+xml'; return $filetype_ext_data; } if ( substr( $filename, -5 ) === '.svgz' ) { $filetype_ext_data['ext'] = 'svgz'; $filetype_ext_data['type'] = 'image/svg+xml'; return $filetype_ext_data; } return $filetype_ext_data; } /** * Generate attachment metadata. * * @param array $metadata The attachment metadata. * @param int $attachment_id The attachment ID. * * @return array The modified attachment metadata. */ public function generate_attachment_metadata( $metadata, $attachment_id ) { $mime_type = get_post_mime_type( $attachment_id ); if ( $mime_type !== 'image/svg+xml' ) { return $metadata; } $svg_path = get_attached_file( $attachment_id ); $dimensions = $this->get_svg_dimensions( $svg_path ); $metadata['width'] = $dimensions['width']; $metadata['height'] = $dimensions['height']; return $metadata; } /** * Prepare attachment for JS. * * @param array $response The response array. * @param \WP_Post $attachment The attachment object. * @param array $meta The attachment metadata. * * @return array The modified response array. */ public function prepare_attachment_for_js( $response, $attachment, $meta ) { if ( $response['mime'] !== 'image/svg+xml' ) { return $response; } if ( ! empty( $response['sizes'] ) ) { return $response; } $svg_path = get_attached_file( $attachment->ID ); if ( ! file_exists( $svg_path ) ) { $svg_path = $response['url']; } $dimensions = $this->get_svg_dimensions( $svg_path ); $response['sizes'] = array( 'full' => array( 'url' => $response['url'], 'width' => $dimensions['width'], 'height' => $dimensions['height'], 'orientation' => $dimensions['width'] > $dimensions['height'] ? 'landscape' : 'portrait', ), ); return $response; } /** * Get SVG dimensions. * * Infers the dimensions from the SVG file either from the width and height attributes or from the viewBox attribute. * * @param string $svg The SVG file path. * * @return array { * 'width' => int, * 'height' => int, * } */ private function get_svg_dimensions( $svg ) { $defaults = array( 'width' => 0, 'height' => 0, ); if ( ! is_file( $svg ) ) { return $defaults; } $svg = simplexml_load_file( $svg ); if ( ! $svg ) { return $defaults; } $width = 0; $height = 0; $attributes = $svg->attributes(); if ( isset( $attributes->width, $attributes->height ) ) { if ( substr( trim( $attributes->width ), -1 ) !== '%' ) { $width = floatval( $attributes->width ); } if ( substr( trim( $attributes->height ), -1 ) !== '%' ) { $height = floatval( $attributes->height ); } } // phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase if ( ( ! $width || ! $height ) && isset( $attributes->viewBox ) ) { $sizes = explode( ' ', $attributes->viewBox ); if ( isset( $sizes[2], $sizes[3] ) ) { $width = floatval( $sizes[2] ); $height = floatval( $sizes[3] ); } } // phpcs:enable return array( 'width' => $width, 'height' => $height, ); } }