balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

svg-handler.php (18332B)


      1 <?php
      2 namespace Elementor\Core\Files\Assets\Svg;
      3 
      4 use Elementor\Core\Files\Assets\Files_Upload_Handler;
      5 
      6 if ( ! defined( 'ABSPATH' ) ) {
      7 	exit; // Exit if accessed directly.
      8 }
      9 
     10 class Svg_Handler extends Files_Upload_Handler {
     11 	/**
     12 	 * Inline svg attachment meta key
     13 	 */
     14 	const META_KEY = '_elementor_inline_svg';
     15 
     16 	const SCRIPT_REGEX = '/(?:\w+script|data):/xi';
     17 
     18 	/**
     19 	 * @var \DOMDocument
     20 	 */
     21 	private $svg_dom = null;
     22 
     23 	/**
     24 	 * Attachment ID.
     25 	 *
     26 	 * Holds the current attachment ID.
     27 	 *
     28 	 * @var int
     29 	 */
     30 	private $attachment_id;
     31 
     32 	public static function get_name() {
     33 		return 'svg-handler';
     34 	}
     35 
     36 	/**
     37 	 * get_meta
     38 	 * @return mixed
     39 	 */
     40 	protected function get_meta() {
     41 		return get_post_meta( $this->attachment_id, self::META_KEY, true );
     42 	}
     43 
     44 	/**
     45 	 * update_meta
     46 	 * @param $meta
     47 	 */
     48 	protected function update_meta( $meta ) {
     49 		update_post_meta( $this->attachment_id, self::META_KEY, $meta );
     50 	}
     51 
     52 	/**
     53 	 * delete_meta
     54 	 */
     55 	protected function delete_meta() {
     56 		delete_post_meta( $this->attachment_id, self::META_KEY );
     57 	}
     58 
     59 	public function get_mime_type() {
     60 		return 'image/svg+xml';
     61 	}
     62 
     63 	public function get_file_type() {
     64 		return 'svg';
     65 	}
     66 
     67 	/**
     68 	 * delete_meta_cache
     69 	 */
     70 	public function delete_meta_cache() {
     71 		delete_post_meta_by_key( self::META_KEY );
     72 	}
     73 
     74 	/**
     75 	 * read_from_file
     76 	 * @return bool|string
     77 	 */
     78 	public function read_from_file() {
     79 		return file_get_contents( get_attached_file( $this->attachment_id ) );
     80 	}
     81 
     82 	/**
     83 	 * get_inline_svg
     84 	 * @param $attachment_id
     85 	 *
     86 	 * @return bool|mixed|string
     87 	 */
     88 	public static function get_inline_svg( $attachment_id ) {
     89 		$svg = get_post_meta( $attachment_id, self::META_KEY, true );
     90 
     91 		if ( ! empty( $svg ) ) {
     92 			return $svg;
     93 		}
     94 
     95 		$attachment_file = get_attached_file( $attachment_id );
     96 
     97 		if ( ! $attachment_file ) {
     98 			return '';
     99 		}
    100 
    101 		$svg = file_get_contents( $attachment_file );
    102 
    103 		if ( ! empty( $svg ) ) {
    104 			update_post_meta( $attachment_id, self::META_KEY, $svg );
    105 		}
    106 
    107 		return $svg;
    108 	}
    109 
    110 	/**
    111 	 * decode_svg
    112 	 * @param $content
    113 	 *
    114 	 * @return string
    115 	 */
    116 	private function decode_svg( $content ) {
    117 		return gzdecode( $content );
    118 	}
    119 
    120 	/**
    121 	 * encode_svg
    122 	 * @param $content
    123 	 *
    124 	 * @return string
    125 	 */
    126 	private function encode_svg( $content ) {
    127 		return gzencode( $content );
    128 	}
    129 
    130 	/**
    131 	 * sanitize_svg
    132 	 * @param $filename
    133 	 *
    134 	 * @return bool
    135 	 */
    136 	public function sanitize_svg( $filename ) {
    137 		$original_content = file_get_contents( $filename );
    138 		$is_encoded = $this->is_encoded( $original_content );
    139 
    140 		if ( $is_encoded ) {
    141 			$decoded = $this->decode_svg( $original_content );
    142 			if ( false === $decoded ) {
    143 				return false;
    144 			}
    145 			$original_content = $decoded;
    146 		}
    147 
    148 		$valid_svg = $this->sanitizer( $original_content );
    149 
    150 		if ( false === $valid_svg ) {
    151 			return false;
    152 		}
    153 
    154 		// If we were gzipped, we need to re-zip
    155 		if ( $is_encoded ) {
    156 			$valid_svg = $this->encode_svg( $valid_svg );
    157 		}
    158 		file_put_contents( $filename, $valid_svg );
    159 
    160 		return true;
    161 	}
    162 
    163 	/**
    164 	 * Check if the contents are gzipped
    165 	 * @see http://www.gzip.org/zlib/rfc-gzip.html#member-format
    166 	 *
    167 	 * @param $contents
    168 	 * @return bool
    169 	 */
    170 	private function is_encoded( $contents ) {
    171 		$needle = "\x1f\x8b\x08";
    172 		if ( function_exists( 'mb_strpos' ) ) {
    173 			return 0 === mb_strpos( $contents, $needle );
    174 		} else {
    175 			return 0 === strpos( $contents, $needle );
    176 		}
    177 	}
    178 
    179 	/**
    180 	 * is_allowed_tag
    181 	 * @param $element
    182 	 *
    183 	 * @return bool
    184 	 */
    185 	private function is_allowed_tag( $element ) {
    186 		static $allowed_tags = false;
    187 		if ( false === $allowed_tags ) {
    188 			$allowed_tags = $this->get_allowed_elements();
    189 		}
    190 
    191 		$tag_name = $element->tagName; // phpcs:ignore -- php DomDocument
    192 
    193 		if ( ! in_array( strtolower( $tag_name ), $allowed_tags ) ) {
    194 			$this->remove_element( $element );
    195 			return false;
    196 		}
    197 
    198 		return true;
    199 	}
    200 
    201 	private function remove_element( $element ) {
    202 		$element->parentNode->removeChild( $element ); // phpcs:ignore -- php DomDocument
    203 	}
    204 
    205 	/**
    206 	 * is_a_attribute
    207 	 * @param $name
    208 	 * @param $check
    209 	 *
    210 	 * @return bool
    211 	 */
    212 	private function is_a_attribute( $name, $check ) {
    213 		return 0 === strpos( $name, $check . '-' );
    214 	}
    215 
    216 	/**
    217 	 * is_remote_value
    218 	 * @param $value
    219 	 *
    220 	 * @return string
    221 	 */
    222 	private function is_remote_value( $value ) {
    223 		$value = trim( preg_replace( '/[^ -~]/xu', '', $value ) );
    224 		$wrapped_in_url = preg_match( '~^url\(\s*[\'"]\s*(.*)\s*[\'"]\s*\)$~xi', $value, $match );
    225 		if ( ! $wrapped_in_url ) {
    226 			return false;
    227 		}
    228 
    229 		$value = trim( $match[1], '\'"' );
    230 		return preg_match( '~^((https?|ftp|file):)?//~xi', $value );
    231 	}
    232 
    233 	/**
    234 	 * has_js_value
    235 	 * @param $value
    236 	 *
    237 	 * @return false|int
    238 	 */
    239 	private function has_js_value( $value ) {
    240 		return preg_match( '/base64|data|(?:java)?script|alert\(|window\.|document/i', $value );
    241 	}
    242 
    243 	/**
    244 	 * get_allowed_attributes
    245 	 * @return array
    246 	 */
    247 	private function get_allowed_attributes() {
    248 		$allowed_attributes = [
    249 			'class',
    250 			'clip-path',
    251 			'clip-rule',
    252 			'fill',
    253 			'fill-opacity',
    254 			'fill-rule',
    255 			'filter',
    256 			'id',
    257 			'mask',
    258 			'opacity',
    259 			'stroke',
    260 			'stroke-dasharray',
    261 			'stroke-dashoffset',
    262 			'stroke-linecap',
    263 			'stroke-linejoin',
    264 			'stroke-miterlimit',
    265 			'stroke-opacity',
    266 			'stroke-width',
    267 			'style',
    268 			'systemlanguage',
    269 			'transform',
    270 			'href',
    271 			'xlink:href',
    272 			'xlink:title',
    273 			'cx',
    274 			'cy',
    275 			'r',
    276 			'requiredfeatures',
    277 			'clippathunits',
    278 			'type',
    279 			'rx',
    280 			'ry',
    281 			'color-interpolation-filters',
    282 			'stddeviation',
    283 			'filterres',
    284 			'filterunits',
    285 			'height',
    286 			'primitiveunits',
    287 			'width',
    288 			'x',
    289 			'y',
    290 			'font-size',
    291 			'display',
    292 			'font-family',
    293 			'font-style',
    294 			'font-weight',
    295 			'text-anchor',
    296 			'marker-end',
    297 			'marker-mid',
    298 			'marker-start',
    299 			'x1',
    300 			'x2',
    301 			'y1',
    302 			'y2',
    303 			'gradienttransform',
    304 			'gradientunits',
    305 			'spreadmethod',
    306 			'markerheight',
    307 			'markerunits',
    308 			'markerwidth',
    309 			'orient',
    310 			'preserveaspectratio',
    311 			'refx',
    312 			'refy',
    313 			'viewbox',
    314 			'maskcontentunits',
    315 			'maskunits',
    316 			'd',
    317 			'patterncontentunits',
    318 			'patterntransform',
    319 			'patternunits',
    320 			'points',
    321 			'fx',
    322 			'fy',
    323 			'offset',
    324 			'stop-color',
    325 			'stop-opacity',
    326 			'xmlns',
    327 			'xmlns:se',
    328 			'xmlns:xlink',
    329 			'xml:space',
    330 			'method',
    331 			'spacing',
    332 			'startoffset',
    333 			'dx',
    334 			'dy',
    335 			'rotate',
    336 			'textlength',
    337 		];
    338 
    339 		/**
    340 		 * Allowed attributes in SVG file.
    341 		 *
    342 		 * Filters the list of allowed attributes in SVG files.
    343 		 *
    344 		 * Since SVG files can run JS code that may inject malicious code, all attributes
    345 		 * are removed except the allowed attributes.
    346 		 *
    347 		 * This hook can be used to manage allowed SVG attributes. To either add new
    348 		 * attributes or delete existing attributes. To strengthen or weaken site security.
    349 		 *
    350 		 * @param array $allowed_attributes A list of allowed attributes.
    351 		 */
    352 		$allowed_attributes = apply_filters( 'elementor/files/svg/allowed_attributes', $allowed_attributes );
    353 
    354 		return $allowed_attributes;
    355 	}
    356 
    357 	/**
    358 	 * get_allowed_elements
    359 	 * @return array
    360 	 */
    361 	private function get_allowed_elements() {
    362 		$allowed_elements = [
    363 			'a',
    364 			'circle',
    365 			'clippath',
    366 			'defs',
    367 			'style',
    368 			'desc',
    369 			'ellipse',
    370 			'fegaussianblur',
    371 			'filter',
    372 			'foreignobject',
    373 			'g',
    374 			'image',
    375 			'line',
    376 			'lineargradient',
    377 			'marker',
    378 			'mask',
    379 			'metadata',
    380 			'path',
    381 			'pattern',
    382 			'polygon',
    383 			'polyline',
    384 			'radialgradient',
    385 			'rect',
    386 			'stop',
    387 			'svg',
    388 			'switch',
    389 			'symbol',
    390 			'text',
    391 			'textpath',
    392 			'title',
    393 			'tspan',
    394 			'use',
    395 		];
    396 
    397 		/**
    398 		 * Allowed elements in SVG file.
    399 		 *
    400 		 * Filters the list of allowed elements in SVG files.
    401 		 *
    402 		 * Since SVG files can run JS code that may inject malicious code, all elements
    403 		 * are removed except the allowed elements.
    404 		 *
    405 		 * This hook can be used to manage SVG elements. To either add new elements or
    406 		 * delete existing elements. To strengthen or weaken site security.
    407 		 *
    408 		 * @param array $allowed_elements A list of allowed elements.
    409 		 */
    410 		$allowed_elements = apply_filters( 'elementor/files/svg/allowed_elements', $allowed_elements );
    411 
    412 		return $allowed_elements;
    413 	}
    414 
    415 	/**
    416 	 * validate_allowed_attributes
    417 	 * @param \DOMElement $element
    418 	 */
    419 	private function validate_allowed_attributes( $element ) {
    420 		static $allowed_attributes = false;
    421 		if ( false === $allowed_attributes ) {
    422 			$allowed_attributes = $this->get_allowed_attributes();
    423 		}
    424 
    425 		for ( $index = $element->attributes->length - 1; $index >= 0; $index-- ) {
    426 			// get attribute name
    427 			$attr_name = $element->attributes->item( $index )->name;
    428 			$attr_name_lowercase = strtolower( $attr_name );
    429 			// Remove attribute if not in whitelist
    430 			if ( ! in_array( $attr_name_lowercase, $allowed_attributes ) && ! $this->is_a_attribute( $attr_name_lowercase, 'aria' ) && ! $this->is_a_attribute( $attr_name_lowercase, 'data' ) ) {
    431 				$element->removeAttribute( $attr_name );
    432 				continue;
    433 			}
    434 
    435 			$attr_value = $element->attributes->item( $index )->value;
    436 
    437 			// Remove attribute if it has a remote reference or js or data-URI/base64
    438 			if ( ! empty( $attr_value ) && ( $this->is_remote_value( $attr_value ) || $this->has_js_value( $attr_value ) ) ) {
    439 				$element->removeAttribute( $attr_name );
    440 				continue;
    441 			}
    442 		}
    443 	}
    444 
    445 	/**
    446 	 * strip_xlinks
    447 	 * @param \DOMElement $element
    448 	 */
    449 	private function strip_xlinks( $element ) {
    450 		$xlinks = $element->getAttributeNS( 'http://www.w3.org/1999/xlink', 'href' );
    451 
    452 		if ( ! $xlinks ) {
    453 			return;
    454 		}
    455 
    456 		$allowed_links = [
    457 			'data:image/png', // PNG
    458 			'data:image/gif', // GIF
    459 			'data:image/jpg', // JPG
    460 			'data:image/jpe', // JPEG
    461 			'data:image/pjp', // PJPEG
    462 		];
    463 		if ( 1 === preg_match( self::SCRIPT_REGEX, $xlinks ) ) {
    464 			if ( ! in_array( substr( $xlinks, 0, 14 ), $allowed_links ) ) {
    465 				$element->removeAttributeNS( 'http://www.w3.org/1999/xlink', 'href' );
    466 			}
    467 		}
    468 	}
    469 
    470 	/**
    471 	 * validate_use_tag
    472 	 * @param $element
    473 	 */
    474 	private function validate_use_tag( $element ) {
    475 		$xlinks = $element->getAttributeNS( 'http://www.w3.org/1999/xlink', 'href' );
    476 		if ( $xlinks && '#' !== substr( $xlinks, 0, 1 ) ) {
    477 			$element->parentNode->removeChild( $element ); // phpcs:ignore -- php DomNode
    478 		}
    479 	}
    480 
    481 	/**
    482 	 * strip_docktype
    483 	 */
    484 	private function strip_doctype() {
    485 		foreach ( $this->svg_dom->childNodes as $child ) {
    486 			if ( XML_DOCUMENT_TYPE_NODE === $child->nodeType ) { // phpcs:ignore -- php DomDocument
    487 				$child->parentNode->removeChild( $child ); // phpcs:ignore -- php DomDocument
    488 			}
    489 		}
    490 	}
    491 
    492 	/**
    493 	 * sanitize_elements
    494 	 */
    495 	private function sanitize_elements() {
    496 		$elements = $this->svg_dom->getElementsByTagName( '*' );
    497 		// loop through all elements
    498 		// we do this backwards so we don't skip anything if we delete a node
    499 		// see comments at: http://php.net/manual/en/class.domnamednodemap.php
    500 		for ( $index = $elements->length - 1; $index >= 0; $index-- ) {
    501 			/**
    502 			 * @var \DOMElement $current_element
    503 			 */
    504 			$current_element = $elements->item( $index );
    505 			// If the tag isn't in the whitelist, remove it and continue with next iteration
    506 			if ( ! $this->is_allowed_tag( $current_element ) ) {
    507 				continue;
    508 			}
    509 
    510 			//validate element attributes
    511 			$this->validate_allowed_attributes( $current_element );
    512 
    513 			$this->strip_xlinks( $current_element );
    514 
    515 			if ( 'use' === strtolower( $current_element->tagName ) ) { // phpcs:ignore -- php DomDocument
    516 				$this->validate_use_tag( $current_element );
    517 			}
    518 		}
    519 	}
    520 
    521 	/**
    522 	 * sanitizer
    523 	 * @param $content
    524 	 *
    525 	 * @return bool|string
    526 	 */
    527 	public function sanitizer( $content ) {
    528 		// Strip php tags
    529 		$content = $this->strip_comments( $content );
    530 		$content = $this->strip_php_tags( $content );
    531 
    532 		// Find the start and end tags so we can cut out miscellaneous garbage.
    533 		$start = strpos( $content, '<svg' );
    534 		$end = strrpos( $content, '</svg>' );
    535 		if ( false === $start || false === $end ) {
    536 			return false;
    537 		}
    538 
    539 		$content = substr( $content, $start, ( $end - $start + 6 ) );
    540 
    541 		// If the server's PHP version is 8 or up, make sure to Disable the ability to load external entities
    542 		$php_version_under_eight = version_compare( PHP_VERSION, '8.0.0', '<' );
    543 		if ( $php_version_under_eight ) {
    544 			$libxml_disable_entity_loader = libxml_disable_entity_loader( true ); // phpcs:ignore Generic.PHP.DeprecatedFunctions.Deprecated
    545 		}
    546 		// Suppress the errors
    547 		$libxml_use_internal_errors = libxml_use_internal_errors( true );
    548 
    549 		// Create DomDocument instance
    550 		$this->svg_dom = new \DOMDocument();
    551 		$this->svg_dom->formatOutput = false;
    552 		$this->svg_dom->preserveWhiteSpace = false;
    553 		$this->svg_dom->strictErrorChecking = false;
    554 
    555 		$open_svg = $this->svg_dom->loadXML( $content );
    556 		if ( ! $open_svg ) {
    557 			return false;
    558 		}
    559 
    560 		$this->strip_doctype();
    561 		$this->sanitize_elements();
    562 
    563 		// Export sanitized svg to string
    564 		// Using documentElement to strip out <?xml version="1.0" encoding="UTF-8"...
    565 		$sanitized = $this->svg_dom->saveXML( $this->svg_dom->documentElement, LIBXML_NOEMPTYTAG );
    566 
    567 		// Restore defaults
    568 		if ( $php_version_under_eight ) {
    569 			libxml_disable_entity_loader( $libxml_disable_entity_loader ); // phpcs:ignore Generic.PHP.DeprecatedFunctions.Deprecated
    570 		}
    571 		libxml_use_internal_errors( $libxml_use_internal_errors );
    572 
    573 		return $sanitized;
    574 	}
    575 
    576 	/**
    577 	 * strip_php_tags
    578 	 * @param $string
    579 	 *
    580 	 * @return string
    581 	 */
    582 	private function strip_php_tags( $string ) {
    583 		$string = preg_replace( '/<\?(=|php)(.+?)\?>/i', '', $string );
    584 		// Remove XML, ASP, etc.
    585 		$string = preg_replace( '/<\?(.*)\?>/Us', '', $string );
    586 		$string = preg_replace( '/<\%(.*)\%>/Us', '', $string );
    587 
    588 		if ( ( false !== strpos( $string, '<?' ) ) || ( false !== strpos( $string, '<%' ) ) ) {
    589 			return '';
    590 		}
    591 		return $string;
    592 	}
    593 
    594 	/**
    595 	 * strip_comments
    596 	 * @param $string
    597 	 *
    598 	 * @return string
    599 	 */
    600 	private function strip_comments( $string ) {
    601 		// Remove comments.
    602 		$string = preg_replace( '/<!--(.*)-->/Us', '', $string );
    603 		$string = preg_replace( '/\/\*(.*)\*\//Us', '', $string );
    604 		if ( ( false !== strpos( $string, '<!--' ) ) || ( false !== strpos( $string, '/*' ) ) ) {
    605 			return '';
    606 		}
    607 		return $string;
    608 	}
    609 
    610 	/**
    611 	 * wp_prepare_attachment_for_js
    612 	 * @param $attachment_data
    613 	 * @param $attachment
    614 	 * @param $meta
    615 	 *
    616 	 * @return mixed
    617 	 */
    618 	public function wp_prepare_attachment_for_js( $attachment_data, $attachment, $meta ) {
    619 		if ( 'image' !== $attachment_data['type'] || 'svg+xml' !== $attachment_data['subtype'] || ! class_exists( 'SimpleXMLElement' ) ) {
    620 			return $attachment_data;
    621 		}
    622 
    623 		$svg = self::get_inline_svg( $attachment->ID );
    624 
    625 		if ( ! $svg ) {
    626 			return $attachment_data;
    627 		}
    628 
    629 		try {
    630 			$svg = new \SimpleXMLElement( $svg );
    631 		} catch ( \Exception $e ) {
    632 			return $attachment_data;
    633 		}
    634 
    635 		$src = $attachment_data['url'];
    636 		$width = (int) $svg['width'];
    637 		$height = (int) $svg['height'];
    638 
    639 		// Media Gallery
    640 		$attachment_data['image'] = compact( 'src', 'width', 'height' );
    641 		$attachment_data['thumb'] = compact( 'src', 'width', 'height' );
    642 
    643 		// Single Details of Image
    644 		$attachment_data['sizes']['full'] = [
    645 			'height' => $height,
    646 			'width' => $width,
    647 			'url' => $src,
    648 			'orientation' => $height > $width ? 'portrait' : 'landscape',
    649 		];
    650 		return $attachment_data;
    651 	}
    652 
    653 	/**
    654 	 * set_attachment_id
    655 	 * @param $attachment_id
    656 	 *
    657 	 * @return int
    658 	 */
    659 	public function set_attachment_id( $attachment_id ) {
    660 		$this->attachment_id = $attachment_id;
    661 		return $this->attachment_id;
    662 	}
    663 
    664 	/**
    665 	 * get_attachment_id
    666 	 * @return int
    667 	 */
    668 	public function get_attachment_id() {
    669 		return $this->attachment_id;
    670 	}
    671 
    672 	/**
    673 	 * set_svg_meta_data
    674 	 * @return mixed
    675 	 */
    676 	public function set_svg_meta_data( $data, $id ) {
    677 		$attachment = get_post( $id ); // Filter makes sure that the post is an attachment.
    678 		$mime_type = $attachment->post_mime_type;
    679 
    680 		// If the attachment is an svg
    681 		if ( 'image/svg+xml' === $mime_type ) {
    682 			// If the svg metadata are empty or the width is empty or the height is empty.
    683 			// then get the attributes from xml.
    684 			if ( empty( $data ) || empty( $data['width'] ) || empty( $data['height'] ) ) {
    685 				$xml = simplexml_load_file( get_attached_file( $id ) );
    686 				$attr = $xml->attributes();
    687 				$view_box = explode( ' ', $attr->viewBox );// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
    688 				$data['width'] = isset( $attr->width ) && preg_match( '/\d+/', $attr->width, $value ) ? (int) $value[0] : ( 4 === count( $view_box ) ? (int) $view_box[2] : null );
    689 				$data['height'] = isset( $attr->height ) && preg_match( '/\d+/', $attr->height, $value ) ? (int) $value[0] : ( 4 === count( $view_box ) ? (int) $view_box[3] : null );
    690 			}
    691 		}
    692 
    693 		return $data;
    694 	}
    695 
    696 	/**
    697 	 * handle_upload_prefilter
    698 	 * @param $file
    699 	 *
    700 	 * @return mixed
    701 	 */
    702 	public function handle_upload_prefilter( $file ) {
    703 		if ( ! $this->is_file_should_handled( $file ) ) {
    704 			return $file;
    705 		}
    706 
    707 		$file = parent::handle_upload_prefilter( $file );
    708 
    709 		if ( ! $file['error'] && self::file_sanitizer_can_run() && ! $this->sanitize_svg( $file['tmp_name'] ) ) {
    710 			$display_type = strtoupper( $this->get_file_type() );
    711 
    712 			$file['error'] = sprintf( esc_html__( 'Invalid %1$s Format, file not uploaded for security reasons', 'elementor' ), $display_type );
    713 		}
    714 
    715 		return $file;
    716 	}
    717 
    718 	/**
    719 	 * @since 3.0.0
    720 	 * @deprecated 3.0.0 Use Files_Upload_Handler::file_sanitizer_can_run() instead.
    721 	 */
    722 	public function svg_sanitizer_can_run() {
    723 		_deprecated_function( __METHOD__, '3.0.0', 'Files_Upload_Handler::file_sanitizer_can_run()' );
    724 
    725 		return Files_Upload_Handler::file_sanitizer_can_run();
    726 	}
    727 
    728 	/**
    729 	 * @since 3.0.0
    730 	 * @deprecated 3.0.0
    731 	 */
    732 	public function upload_mimes() {
    733 		_deprecated_function( __METHOD__, '3.0.0' );
    734 	}
    735 
    736 	/**
    737 	 * @since 3.0.0
    738 	 * @deprecated 3.0.0
    739 	 */
    740 	public function wp_handle_upload_prefilter() {
    741 		_deprecated_function( __METHOD__, '3.0.0' );
    742 	}
    743 
    744 	/**
    745 	 * @since 3.0.0
    746 	 * @deprecated 3.0.0 Use Files_Upload_Handler::is_enabled() instead.
    747 	 * @see is_enabled()
    748 	 */
    749 	public function is_svg_uploads_enabled() {
    750 		_deprecated_function( __METHOD__, '3.0.0', 'Files_Upload_Handler::is_enabled()' );
    751 
    752 		return Files_Upload_Handler::is_enabled();
    753 	}
    754 
    755 	/**
    756 	 * Svg_Handler constructor.
    757 	 */
    758 	public function __construct() {
    759 		parent::__construct();
    760 
    761 		add_filter( 'wp_update_attachment_metadata', [ $this, 'set_svg_meta_data' ], 10, 2 );
    762 		add_filter( 'wp_prepare_attachment_for_js', [ $this, 'wp_prepare_attachment_for_js' ], 10, 3 );
    763 		add_action( 'elementor/core/files/clear_cache', [ $this, 'delete_meta_cache' ] );
    764 	}
    765 }