PluginProbe
bBlocks – Essential Gutenberg Blocks & Patterns Collection / 2.1.8
bBlocks – Essential Gutenberg Blocks & Patterns Collection v2.1.8
2.1.8 2.1.7 2.1.6 2.1.5 2.1.4 2.1.3 2.1.2 2.1.1 2.1.0 2.0.43 2.0.42 2.0.41 2.0.40 2.0.39 2.0.38 trunk 1.0 1.1 1.2 1.3 1.4 1.5 1.5.1 1.5.2 1.5.3 All 108 releases
b-blocks / includes / UploadFileTypes.php

UploadFileTypes.php in bBlocks – Essential Gutenberg Blocks & Patterns Collection 2.1.8, at includes/UploadFileTypes.php

157 lines 4.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace BBlocks\Inc;
4
5 if ( ! defined( 'ABSPATH' ) ) {
6 exit;
7 }
8
9 class UploadFileTypes
10 {
11 function __construct() {
12 add_filter( 'upload_mimes', [$this, 'uploadMimes'] );
13 add_filter( 'wp_check_filetype_and_ext', [$this, 'wpCheckFiletypeAndExt'], 10, 5 );
14 add_action( 'wp_ajax_b-blocks-enable-svg-mime-type', [$this, 'enableSvgMimeType'] );
15 add_filter( 'wp_handle_upload_prefilter', [$this, 'sanitizeSvgUpload'] );
16 }
17
18 private function svgTransientKey() {
19 return 'b_blocks_svg_' . get_current_user_id();
20 }
21 //Allow some additional file types for upload
22 function uploadMimes($mimes) {
23 $mimes['glb'] = 'model/gltf-binary'; // 3D Viewer
24 $mimes['gltf'] = 'model/gltf-binary'; // 3D Viewer
25 $mimes['json'] = 'application/json'; // Lottie Player
26 $mimes['lottie'] = 'application/json'; // Lottie Player
27 if (current_user_can('manage_options') && get_transient($this->svgTransientKey()) === 'true') {
28 $mimes['svg'] = 'image/svg+xml';
29 }
30 return $mimes;
31 }
32
33 function wpCheckFiletypeAndExt($data, $file, $filename, $mimes, $real_mime = null) {
34
35 $f_sp = explode('.', $filename);
36 $f_exp_count = count($f_sp);
37
38 if ($f_exp_count <= 1) {
39 return $data;
40 } else {
41 $f_name = $f_sp[0];
42 $ext = $f_sp[$f_exp_count - 1];
43 }
44
45 if ( 'glb' === $ext || 'gltf' === $ext ) { // 3D Viewer
46 $type = 'model/gltf-binary';
47 $proper_filename = '';
48 return compact('ext', 'type', 'proper_filename');
49 } elseif ( 'json' === $ext || 'lottie' === $ext ) { // Lottie Player
50 $type = 'application/json';
51 $proper_filename = '';
52 return compact('ext', 'type', 'proper_filename');
53 } else {
54 return $data;
55 }
56 }
57
58 public function sanitizeSvgUpload( $file ) {
59
60 if ( ! empty( $file['error'] ) ) {
61 return $file;
62 }
63
64 $name = isset( $file['name'] ) && is_string( $file['name'] ) ? $file['name'] : '';
65 $type = isset( $file['type'] ) && is_string( $file['type'] ) ? $file['type'] : '';
66
67 $ext = strtolower( pathinfo( $name, PATHINFO_EXTENSION ) );
68 if ( 'svg' !== $ext && 'svgz' !== $ext && 'image/svg+xml' !== $type ) {
69 return $file;
70 }
71
72 if ( ! current_user_can( 'manage_options' ) ) {
73 $file['error'] = __( 'You are not allowed to upload SVG files.', 'b-blocks' );
74 return $file;
75 }
76
77 $tmp = $file['tmp_name'] ?? '';
78 if ( ! is_string( $tmp ) || '' === $tmp || ! is_file( $tmp ) || ! $this->isSafeTempPath( $tmp ) ) {
79 $file['error'] = __( 'The uploaded SVG could not be read.', 'b-blocks' );
80 return $file;
81 }
82
83 $maxBytes = (int) apply_filters( 'b_blocks_svg_max_bytes', 2 * 1024 * 1024 );
84 if ( $maxBytes > 0 && (int) filesize( $tmp ) > $maxBytes ) {
85 $file['error'] = sprintf( __( 'SVG files must be smaller than %s.', 'b-blocks' ), size_format( $maxBytes ) );
86 return $file;
87 }
88
89 $dirty = file_get_contents( $tmp );
90 if ( false === $dirty || '' === trim( $dirty ) ) {
91 $file['error'] = __( 'This SVG file is empty or could not be read.', 'b-blocks' );
92 return $file;
93 }
94
95 if ( 0 === strncmp( $dirty, "\x1f\x8b", 2 ) ) {
96 $file['error'] = __( 'Compressed SVG (.svgz) files cannot be sanitized. Please upload an uncompressed .svg file.', 'b-blocks' );
97 return $file;
98 }
99
100 $sanitizer = Sanitize::sanitizer();
101 if ( ! $sanitizer ) {
102 $file['error'] = __( 'SVG uploads are unavailable because the sanitizer is missing.', 'b-blocks' );
103 return $file;
104 }
105
106 try {
107 $clean = $sanitizer->sanitize( $dirty );
108 } catch ( \Throwable $e ) {
109 $clean = false;
110 }
111
112 if ( ! is_string( $clean ) || '' === trim( $clean ) ) {
113 $file['error'] = __( 'This SVG file could not be sanitized.', 'b-blocks' );
114 return $file;
115 }
116
117 if ( ! Sanitize::isSafe( $clean ) ) {
118 $file['error'] = __( 'This SVG file could not be sanitized.', 'b-blocks' );
119 return $file;
120 }
121
122 if ( false === file_put_contents( $tmp, $clean ) ) {
123 $file['error'] = __( 'The sanitized SVG could not be saved.', 'b-blocks' );
124 return $file;
125 }
126
127 do_action( 'b_blocks_svg_sanitized', $sanitizer->getXmlIssues(), $file );
128
129 return $file;
130 }
131
132 private function isSafeTempPath( $tmp ) {
133 if ( is_uploaded_file( $tmp ) ) {
134 return true;
135 }
136
137 $real = realpath( $tmp );
138 $temp = realpath( get_temp_dir() );
139
140 return $real && $temp && 0 === strpos( $real, rtrim( $temp, '/\\' ) . DIRECTORY_SEPARATOR );
141 }
142
143 public function enableSvgMimeType() {
144 if (!wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_wpnonce'] ?? null)), 'wp_ajax')) {
145 wp_send_json_error();
146 }
147
148 if (!current_user_can('manage_options')) {
149 wp_send_json_error(null, 403);
150 }
151
152 set_transient( $this->svgTransientKey(), 'true', 80 );
153 wp_send_json_success();
154 }
155 }
156
157 new UploadFileTypes();