PluginProbe
Migrate to WordPress.com / 5.88
Migrate to WordPress.com v5.88
6.72 6.65 trunk 5.72 5.81 5.88
wpcom-migration / callback / wings / fs_write.php

fs_write.php in Migrate to WordPress.com 5.88, at callback/wings/fs_write.php

452 lines 11.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('ABSPATH')) exit;
3 if (!class_exists('BVFSWriteCallback')) :
4
5 class BVFSWriteCallback extends BVCallbackBase {
6
7 const MEGABYTE = 1048576;
8 const FS_WRITE_WING_VERSION = 1.1;
9
10 public function __construct() {
11 }
12
13 public function removeFiles($files) {
14 $result = array();
15
16 foreach($files as $file) {
17 $file_result = array();
18
19 if (file_exists($file)) {
20
21 $file_result['status'] = unlink($file);
22 if ($file_result['status'] === false) {
23 $file_result['error'] = "UNLINK_FAILED";
24 }
25
26 } else {
27 $file_result['status'] = true;
28 $file_result['error'] = "NOT_PRESENT";
29 }
30
31 $result[$file] = $file_result;
32 }
33
34 $result['status'] = true;
35 return $result;
36 }
37
38 public function makeDirs($dirs, $permissions = 0777, $recursive = true) {
39 $result = array();
40
41 foreach($dirs as $dir) {
42 $dir_result = array();
43
44 if (file_exists($dir)) {
45
46 if (is_dir($dir)) {
47 $dir_result['status'] = true;
48 $dir_result['message'] = "DIR_ALREADY_PRESENT";
49 } else {
50 $dir_result['status'] = false;
51 $dir_result['error'] = "FILE_PRESENT_IN_PLACE_OF_DIR";
52 }
53
54 } else {
55 // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_mkdir -- Using mkdir() directly as there is no direct suport for recursion
56 $dir_result['status'] = mkdir($dir, $permissions, $recursive);
57 if ($dir_result['status'] === false) {
58 $dir_result['error'] = "MKDIR_FAILED";
59 }
60
61 }
62
63 $result[$dir] = $dir_result;
64 }
65
66 $result['status'] = true;
67 return $result;
68 }
69
70 public function removeDirs($dirs) {
71 $result = array();
72 $filesystem = WPCOMHelper::get_direct_filesystem();
73
74 foreach($dirs as $dir) {
75 $dir_result = array();
76
77 if ($filesystem->is_dir($dir) && !is_link($dir)) {
78 if ($this->isEmptyDir($dir)) {
79 $dir_result['status'] = $filesystem->rmdir($dir);
80 if ($dir_result['status'] === false) {
81 $dir_result['error'] = "RMDIR_FAILED";
82 if (is_wp_error($filesystem->errors) && $filesystem->errors->has_errors()) {
83 $dir_result['fs_error'] = $filesystem->errors->get_error_message();
84 }
85 }
86 } else {
87 $dir_result['status'] = false;
88 $dir_result['error'] = "NOT_EMPTY";
89 }
90 } else {
91 $dir_result['status'] = false;
92 $dir_result['error'] = "NOT_DIR";
93 }
94
95 $result[$dir] = $dir_result;
96 }
97
98 $result['status'] = true;
99 return $result;
100 }
101
102 public function isEmptyDir($dir) {
103 $handle = opendir($dir);
104
105 while (false !== ($entry = readdir($handle))) {
106 if ($entry != "." && $entry != "..") {
107 closedir($handle);
108 return false;
109 }
110 }
111 closedir($handle);
112
113 return true;
114 }
115
116 public function doChmod($path_infos) {
117 $result = array();
118 $filesystem = WPCOMHelper::get_direct_filesystem();
119
120 foreach($path_infos as $path => $mode) {
121 $path_result = array();
122
123 if ($filesystem->exists($path)) {
124 $path_result['status'] = $filesystem->chmod($path, $mode);
125 if ($path_result['status'] === false) {
126 $path_result['error'] = "CHMOD_FAILED";
127 if (is_wp_error($filesystem->errors) && $filesystem->errors->has_errors()) {
128 $path_result['fs_error'] = $filesystem->errors->get_error_message();
129 }
130 }
131 } else {
132 $path_result['status'] = false;
133 $path_result['error'] = "NOT_FOUND";
134 }
135
136 $result[$path] = $path_result;
137 }
138
139 $result['status'] = true;
140 return $result;
141 }
142
143 // phpcs:disable WordPress.WP.AlternativeFunctions.file_system_operations_fopen
144 // phpcs:disable WordPress.WP.AlternativeFunctions.file_system_operations_fread
145 // phpcs:disable WordPress.WP.AlternativeFunctions.file_system_operations_fwrite
146 // phpcs:disable WordPress.WP.AlternativeFunctions.file_system_operations_fclose
147 public function concatFiles($ifiles, $ofile, $bsize, $offset) {
148 if (($offset !== 0) && (!file_exists($ofile))) {
149 return array(
150 'status' => false,
151 'error' => 'OFILE_NOT_FOUND_BEFORE_CONCAT'
152 );
153 }
154
155 if (file_exists($ofile) && ($offset !== 0)) {
156 $handle = fopen($ofile, 'rb+');
157 } else {
158 $handle = fopen($ofile, 'wb+');
159 }
160
161 if ($handle === false) {
162 return array(
163 'status' => false,
164 'error' => 'FOPEN_FAILED'
165 );
166 }
167
168 if ($offset !== 0) {
169 if (fseek($handle, $offset, SEEK_SET) === -1) {
170 return array(
171 'status' => false,
172 'error' => 'FSEEK_FAILED'
173 );
174 }
175 }
176
177 $total_written = 0;
178 foreach($ifiles as $file) {
179 $fp = fopen($file, 'rb');
180 if ($fp === false) {
181 return array(
182 'status' => false,
183 'error' => "UNABLE_TO_OPEN_TMP_OFILE_FOR_READING"
184 );
185 }
186
187 while (!feof($fp)) {
188 $content = fread($fp, $bsize);
189 if ($content === false) {
190 return array(
191 'status' => false,
192 'error' => "UNABLE_TO_READ_INFILE",
193 'filename' => $file
194 );
195 }
196
197 $written = fwrite($handle, $content);
198 if ($written === false) {
199 return array(
200 'status' => false,
201 'error' => "UNABLE_TO_WRITE_TO_OFILE",
202 'filename' => $file
203 );
204 }
205 $total_written += $written;
206 }
207
208 fclose($fp);
209 }
210
211 $result = array();
212 $result['fclose'] = fclose($handle);
213
214 if (file_exists($ofile) && ($total_written != 0)) {
215 $result['status'] = true;
216 $result['fsize'] = filesize($ofile);
217 $result['total_written'] = $total_written;
218 } else {
219 $result['status'] = false;
220 $result['error'] = 'CONCATINATED_FILE_FAILED';
221 }
222
223 return $result;
224 }
225 // phpcs:enable
226 public function renameFiles($path_infos) {
227 $result = array();
228 $filesystem = WPCOMHelper::get_direct_filesystem();
229
230 foreach ($path_infos as $oldpath => $newpath) {
231 $action_result = array();
232
233 if ($filesystem->exists($oldpath)) {
234 $action_result['status'] = $filesystem->move($oldpath, $newpath, true);
235 if ($action_result['status'] === false) {
236 $action_result['error'] = "RENAME_FAILED";
237 if (is_wp_error($filesystem->errors) && $filesystem->errors->has_errors()) {
238 $action_result['fs_error'] = $filesystem->errors->get_error_message();
239 }
240 }
241 } else {
242 $action_result['status'] = false;
243 $action_result['error'] = "NOT_FOUND";
244 }
245
246 $result[$oldpath] = $action_result;
247 }
248
249 $result['status'] = true;
250 return $result;
251 }
252
253 public function curlFile($ifile_url, $ofile, $timeout) {
254 // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen
255 $fp = fopen($ofile, "wb+");
256 if ($fp === false) {
257 return array(
258 'error' => 'FOPEN_FAILED_FOR_TEMP_OFILE'
259 );
260 }
261
262 $result = array();
263
264 // phpcs:disable WordPress.WP.AlternativeFunctions.curl_curl_init, WordPress.WP.AlternativeFunctions.curl_curl_exec, WordPress.WP.AlternativeFunctions.curl_curl_setopt, WordPress.WP.AlternativeFunctions.curl_curl_close, WordPress.WP.AlternativeFunctions.curl_curl_error, WordPress.WP.AlternativeFunctions.curl_curl_errno
265 $ch = curl_init($ifile_url);
266 curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
267 curl_setopt($ch, CURLOPT_HEADER, 0);
268 curl_setopt($ch, CURLOPT_FILE, $fp);
269
270 if (!curl_exec($ch)) {
271 $result['error'] = curl_error($ch);
272 $result['errorno'] = curl_errno($ch);
273 }
274
275 curl_close($ch);
276
277 // phpcs:enable WordPress.WP.AlternativeFunctions.curl_curl_init, WordPress.WP.AlternativeFunctions.curl_curl_exec, WordPress.WP.AlternativeFunctions.curl_curl_setopt, WordPress.WP.AlternativeFunctions.curl_curl_close, WordPress.WP.AlternativeFunctions.curl_curl_error, WordPress.WP.AlternativeFunctions.curl_curl_errno
278
279 // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
280 fclose($fp);
281
282
283 return $result;
284 }
285
286 public function streamCopyFile($ifile_url, $ofile) {
287 $result = array();
288 // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen
289 $handle = fopen($ifile_url, "rb");
290
291 if ($handle === false) {
292 return array(
293 'error' => "UNABLE_TO_OPEN_REMOTE_FILE_STREAM"
294 );
295 }
296
297 // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen
298 $fp = fopen($ofile, "wb+");
299 if ($fp === false) {
300 fclose($handle); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
301
302 return array(
303 'error' => 'FOPEN_FAILED_FOR_OFILE'
304 );
305 }
306
307 if (stream_copy_to_stream($handle, $fp) === false) {
308 $result['error'] = "UNABLE_TO_WRITE_TO_TMP_OFILE";
309 }
310
311 fclose($handle); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
312 fclose($fp); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
313
314 return $result;
315 }
316
317 public function writeContentToFile($content, $ofile) {
318 $result = array();
319 $filesystem = WPCOMHelper::get_direct_filesystem();
320
321 if ($filesystem->put_contents($ofile, $content) === false) {
322 $result['error'] = 'UNABLE_TO_WRITE_TO_TMP_OFILE';
323
324 if (is_wp_error($filesystem->errors) && $filesystem->errors->has_errors()) {
325 $result['fs_error'] = $filesystem->errors->get_error_message();
326 }
327 }
328
329 return $result;
330 }
331
332 public function moveUploadedFile($ofile) {
333 $result = array();
334
335 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
336 if (isset($_FILES['myfile'])) {
337 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing -- tmp_name is a path and nonce is ignored here
338 $myfile = $_FILES['myfile'];
339 $is_upload_ok = false;
340
341 switch ($myfile['error']) {
342 case UPLOAD_ERR_OK:
343 $is_upload_ok = true;
344 break;
345 case UPLOAD_ERR_NO_FILE:
346 $result['error'] = "UPLOADERR_NO_FILE";
347 break;
348 case UPLOAD_ERR_INI_SIZE:
349 case UPLOAD_ERR_FORM_SIZE:
350 $result['error'] = "UPLOADERR_FORM_SIZE";
351 break;
352 default:
353 $result['error'] = "UPLOAD_ERR_UNKNOWN";
354 }
355
356 if ($is_upload_ok && !isset($myfile['tmp_name'])) {
357 $result['error'] = "MYFILE_TMP_NAME_NOT_FOUND";
358 $is_upload_ok = false;
359 }
360
361 if ($is_upload_ok) {
362 if (move_uploaded_file($myfile['tmp_name'], $ofile) === false) {
363 $result['error'] = 'MOVE_UPLOAD_FILE_FAILED';
364 }
365 }
366
367 } else {
368 $result['error'] = "FILE_NOT_PRESENT_IN_FILES";
369 }
370
371 return $result;
372 }
373
374
375 public function uploadFile($params) {
376 $resp = array();
377 $ofile = $params['ofile'];
378
379 switch($params['protocol']) {
380 case "curl":
381 $timeout = isset($params['timeout']) ? $params['timeout'] : 60;
382 $ifile_url = isset($params['ifileurl']) ? $params['ifileurl'] : null;
383
384 $resp = $this->curlFile($ifile_url, $ofile, $timeout);
385 break;
386 case "streamcopy":
387 $ifile_url = isset($params['ifileurl']) ? $params['ifileurl'] : null;
388
389 $resp = $this->streamCopyFile($ifile_url, $ofile);
390 break;
391 case "httpcontenttransfer":
392 $resp = $this->writeContentToFile($params['content'], $ofile);
393 break;
394 case "httpfiletransfer":
395 $resp = $this->moveUploadedFile($ofile);
396 break;
397 default:
398 $resp['error'] = "INVALID_PROTOCOL";
399 }
400
401 if (isset($resp['error'])) {
402 $resp['status'] = false;
403 } else {
404
405 if (file_exists($ofile)) {
406 $resp['status'] = true;
407 $resp['fsize'] = filesize($ofile);
408 } else {
409 $resp['status'] = false;
410 $resp['error'] = "OFILE_NOT_FOUND";
411 }
412
413 }
414
415 return $resp;
416 }
417
418 public function process($request) {
419 $params = $request->params;
420
421 switch ($request->method) {
422 case "rmfle":
423 $resp = $this->removeFiles($params['files']);
424 break;
425 case "chmd":
426 $resp = $this->doChmod($params['pathinfos']);
427 break;
428 case "mkdr":
429 $resp = $this->makeDirs($params['dirs'], $params['permissions'], $params['recursive']);
430 break;
431 case "rmdr":
432 $resp = $this->removeDirs($params['dirs']);
433 break;
434 case "renmefle":
435 $resp = $this->renameFiles($params['pathinfos']);
436 break;
437 case "wrtfle":
438 $resp = $this->uploadFile($params);
439 break;
440 case "cncatfls":
441 $bsize = (isset($params['bsize'])) ? $params['bsize'] : (8 * BVFSWriteCallback::MEGABYTE);
442 $offset = (isset($params['offset'])) ? $params['offset'] : 0;
443 $resp = $this->concatFiles($params['infiles'], $params['ofile'], $bsize, $offset);
444 break;
445 default:
446 $resp = false;
447 }
448
449 return $resp;
450 }
451 }
452 endif;