Version Description
- Fix: Updating staging site does not exclude Windows IIS configuration file web.config and can lead to server error
- Fix: Redirect to the correct url after log in to staging site
- Fix: Supports HTML entities in links created by WP Backery Page Builder Plugin
- New: Support for custom and non-default wp-content and uploads folder
- New: Option to show again the rating notice in a week
Download this release
Release Info
Developer | ReneHermi |
Plugin | WP Staging – DB & File Duplicator & Migration |
Version | 2.4.3 |
Comparing to | |
See all releases |
Code changes from version 2.4.1 to 2.4.3
- apps/Backend/Administrator.php +726 -713
- apps/Backend/Modules/Jobs/Data.php +82 -2
- apps/Backend/Modules/Jobs/Directories.php +427 -446
- apps/Backend/Modules/Jobs/Files.php +32 -1
- apps/Backend/Modules/Jobs/SearchReplace.php +11 -10
- apps/Backend/Modules/Jobs/Updating.php +3 -1
- apps/Backend/Notices/Notices.php +91 -72
- apps/Backend/public/js/wpstg-admin-rating.js +35 -0
- apps/Backend/views/_includes/messages/rating.php +5 -0
- apps/Core/Iterators/RecursiveFilterExclude.php +27 -12
- apps/Core/Iterators/RecursiveFilterNewLine.php +0 -21
- apps/Core/Utils/functions.php +60 -0
- apps/Core/WPStaging.php +1 -1
- apps/Frontend/loginForm.php +8 -1
- readme.txt +17 -48
- wp-staging.php +2 -2
apps/Backend/Administrator.php
CHANGED
@@ -4,7 +4,7 @@ namespace WPStaging\Backend;
|
|
4 |
|
5 |
// No Direct Access
|
6 |
if( !defined( "WPINC" ) ) {
|
7 |
-
|
8 |
}
|
9 |
|
10 |
use WPStaging\WPStaging;
|
@@ -29,735 +29,748 @@ use WPStaging\Backend\Activation;
|
|
29 |
*/
|
30 |
class Administrator extends InjectionAware {
|
31 |
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
// Existing clones
|
371 |
-
$availableClones = get_option( "wpstg_existing_clones_beta", array() );
|
372 |
-
|
373 |
-
// Get license data
|
374 |
-
$license = get_option( 'wpstg_license_status' );
|
375 |
-
|
376 |
-
// Get db
|
377 |
-
$db = WPStaging::getInstance()->get( 'wpdb' );
|
378 |
-
|
379 |
-
if( \WPStaging\WPStaging::getSlug() === 'wp-staging-pro' ) {
|
380 |
-
require_once "{$this->path}Pro/views/single-overview-pro.php";
|
381 |
-
} else {
|
382 |
-
require_once "{$this->path}views/clone/ajax/single-overview.php";
|
383 |
-
}
|
384 |
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
/**
|
389 |
-
* Ajax Scan
|
390 |
-
*/
|
391 |
-
public function ajaxScan() {
|
392 |
-
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
393 |
-
|
394 |
-
$db = WPStaging::getInstance()->get( 'wpdb' );
|
395 |
-
|
396 |
-
// Scan
|
397 |
-
$scan = new Scan();
|
398 |
-
$scan->start();
|
399 |
-
|
400 |
-
// Get Options
|
401 |
-
$options = $scan->getOptions();
|
402 |
-
|
403 |
-
require_once "{$this->path}views/clone/ajax/scan.php";
|
404 |
-
|
405 |
-
wp_die();
|
406 |
-
}
|
407 |
-
|
408 |
-
/**
|
409 |
-
* Ajax Check Clone Name
|
410 |
-
*/
|
411 |
-
public function ajaxCheckCloneName() {
|
412 |
-
$cloneName = sanitize_key( $_POST["cloneID"] );
|
413 |
-
$cloneNameLength = strlen( $cloneName );
|
414 |
-
$clones = get_option( "wpstg_existing_clones_beta", array() );
|
415 |
-
|
416 |
-
$clonePath = trailingslashit( get_home_path() ) . $cloneName;
|
417 |
-
|
418 |
-
// Check clone name length
|
419 |
-
if( $cloneNameLength < 1 || $cloneNameLength > 16 ) {
|
420 |
-
echo wp_send_json( array(
|
421 |
-
"status" => "failed",
|
422 |
-
"message" => "Clone name must be between 1 - 16 characters"
|
423 |
-
) );
|
424 |
-
} elseif( array_key_exists( $cloneName, $clones ) ) {
|
425 |
-
echo wp_send_json( array(
|
426 |
-
"status" => "failed",
|
427 |
-
"message" => "Clone name is already in use, please choose an another clone name."
|
428 |
-
) );
|
429 |
-
} elseif( is_dir( $clonePath ) ) {
|
430 |
-
echo wp_send_json( array(
|
431 |
-
"status" => "failed",
|
432 |
-
"message" => "Clone directory " . $clonePath . " already exists. Use another clone name."
|
433 |
-
) );
|
434 |
-
}
|
435 |
-
|
436 |
-
echo wp_send_json( array("status" => "success") );
|
437 |
-
}
|
438 |
-
|
439 |
-
/**
|
440 |
-
* Ajax Start Updating Clone (Basically just layout and saving data)
|
441 |
-
*/
|
442 |
-
public function ajaxUpdateProcess() {
|
443 |
-
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
444 |
|
445 |
-
|
|
|
|
|
|
|
|
|
446 |
|
447 |
-
|
448 |
-
|
449 |
-
|
|
|
|
|
450 |
|
451 |
-
|
|
|
452 |
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
461 |
|
462 |
-
|
463 |
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
|
468 |
-
|
469 |
|
470 |
-
|
471 |
-
|
472 |
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
|
479 |
-
|
480 |
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
|
485 |
-
|
486 |
-
}
|
487 |
|
488 |
-
|
489 |
-
|
490 |
-
*/
|
491 |
-
public function ajaxPrepareDirectories() {
|
492 |
-
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
493 |
|
494 |
-
|
|
|
|
|
|
|
|
|
495 |
|
496 |
-
|
497 |
-
}
|
498 |
-
|
499 |
-
/**
|
500 |
-
* Ajax Clone Files
|
501 |
-
*/
|
502 |
-
public function ajaxCopyFiles() {
|
503 |
-
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
504 |
-
|
505 |
-
$cloning = new Cloning();
|
506 |
-
|
507 |
-
wp_send_json( $cloning->start() );
|
508 |
-
}
|
509 |
-
|
510 |
-
/**
|
511 |
-
* Ajax Replace Data
|
512 |
-
*/
|
513 |
-
public function ajaxReplaceData() {
|
514 |
-
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
515 |
-
|
516 |
-
$cloning = new Cloning();
|
517 |
-
|
518 |
-
wp_send_json( $cloning->start() );
|
519 |
-
}
|
520 |
-
|
521 |
-
/**
|
522 |
-
* Ajax Finish
|
523 |
-
*/
|
524 |
-
public function ajaxFinish() {
|
525 |
-
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
526 |
-
|
527 |
-
$cloning = new Cloning();
|
528 |
-
|
529 |
-
wp_send_json( $cloning->start() );
|
530 |
-
}
|
531 |
-
|
532 |
-
/**
|
533 |
-
* Ajax Delete Confirmation
|
534 |
-
*/
|
535 |
-
public function ajaxDeleteConfirmation() {
|
536 |
-
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
537 |
-
|
538 |
-
$delete = new Delete();
|
539 |
-
$delete->setData();
|
540 |
-
|
541 |
-
$clone = $delete->getClone();
|
542 |
-
|
543 |
-
$dbname = $delete->getDbName();
|
544 |
-
|
545 |
-
require_once "{$this->path}views/clone/ajax/delete-confirmation.php";
|
546 |
-
|
547 |
-
wp_die();
|
548 |
-
}
|
549 |
-
|
550 |
-
/**
|
551 |
-
* Delete clone
|
552 |
-
*/
|
553 |
-
public function ajaxDeleteClone() {
|
554 |
-
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
555 |
-
|
556 |
-
$delete = new Delete();
|
557 |
-
|
558 |
-
wp_send_json( $delete->start() );
|
559 |
-
}
|
560 |
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
$cancel = new CancelUpdate();
|
579 |
-
wp_send_json( $cancel->start() );
|
580 |
-
}
|
581 |
-
|
582 |
-
/**
|
583 |
-
* Admin Messages
|
584 |
-
*/
|
585 |
-
public function messages() {
|
586 |
-
$notice = new Notices( $this->path, $this->url );
|
587 |
-
|
588 |
-
$run = $notice->messages();
|
589 |
-
}
|
590 |
-
|
591 |
-
/**
|
592 |
-
* Ajax Hide Poll
|
593 |
-
* @return mixed boolean | json
|
594 |
-
*/
|
595 |
-
public function ajaxHidePoll() {
|
596 |
-
if( false !== update_option( "wpstg_poll", "no" ) ) {
|
597 |
-
wp_send_json( true );
|
598 |
-
}
|
599 |
-
return wp_send_json();
|
600 |
-
}
|
601 |
-
|
602 |
-
/**
|
603 |
-
* Ajax Hide Rating
|
604 |
-
* @return mixed bool | json
|
605 |
-
*/
|
606 |
-
public function ajaxHideRating() {
|
607 |
-
if( false !== update_option( "wpstg_rating", "no" ) ) {
|
608 |
-
wp_send_json( true );
|
609 |
-
}
|
610 |
-
return wp_send_json();
|
611 |
-
}
|
612 |
-
|
613 |
-
/**
|
614 |
-
* Ajax Hide Beta
|
615 |
-
*/
|
616 |
-
public function ajaxHideBeta() {
|
617 |
-
wp_send_json( update_option( "wpstg_beta", "no" ) );
|
618 |
-
}
|
619 |
-
|
620 |
-
/**
|
621 |
-
* Clone logs
|
622 |
-
*/
|
623 |
-
public function ajaxLogs() {
|
624 |
-
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
625 |
-
|
626 |
-
$logs = new Logs();
|
627 |
-
wp_send_json( $logs->start() );
|
628 |
-
}
|
629 |
-
|
630 |
-
/**
|
631 |
-
* Ajax Checks Free Disk Space
|
632 |
-
*/
|
633 |
-
public function ajaxCheckFreeSpace() {
|
634 |
-
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
635 |
-
|
636 |
-
$scan = new Scan();
|
637 |
-
return $scan->hasFreeDiskSpace();
|
638 |
-
}
|
639 |
-
|
640 |
-
/**
|
641 |
-
* Ajax Start Push Changes Process
|
642 |
-
* Start with the module Scan
|
643 |
-
*/
|
644 |
-
public function ajaxPushScan() {
|
645 |
-
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
646 |
-
|
647 |
-
if( !class_exists( 'WPStaging\Backend\Pro\Modules\Jobs\Scan' ) ) {
|
648 |
-
return false;
|
649 |
-
}
|
650 |
-
|
651 |
-
// Scan
|
652 |
-
$scan = new Pro\Modules\Jobs\Scan();
|
653 |
-
|
654 |
-
$scan->start();
|
655 |
-
|
656 |
-
// Get Options
|
657 |
-
$options = $scan->getOptions();
|
658 |
-
|
659 |
-
require_once "{$this->path}Pro/views/scan.php";
|
660 |
-
|
661 |
-
wp_die();
|
662 |
-
}
|
663 |
-
|
664 |
-
/**
|
665 |
-
* Ajax Start Pushing. Needs wp quads pro
|
666 |
-
*/
|
667 |
-
public function ajaxPushProcessing() {
|
668 |
-
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
669 |
-
|
670 |
-
if( !class_exists( 'WPStaging\Backend\Pro\Modules\Jobs\Processing' ) ) {
|
671 |
-
return false;
|
672 |
-
}
|
673 |
-
// Start the process
|
674 |
-
$processing = new Processing();
|
675 |
-
wp_send_json( $processing->start() );
|
676 |
-
}
|
677 |
-
|
678 |
-
/**
|
679 |
-
* License Page
|
680 |
-
*/
|
681 |
-
public function getLicensePage() {
|
682 |
-
|
683 |
-
// Get license data
|
684 |
-
$license = get_option( 'wpstg_license_status' );
|
685 |
-
|
686 |
-
require_once "{$this->path}Pro/views/licensing.php";
|
687 |
-
}
|
688 |
-
|
689 |
-
/**
|
690 |
-
*
|
691 |
-
* @param type $args
|
692 |
-
*/
|
693 |
-
public function ajaxSendReport( $args = array() ) {
|
694 |
-
// Set params
|
695 |
-
if( empty( $args ) ) {
|
696 |
-
$args = stripslashes_deep( $_POST );
|
697 |
-
}
|
698 |
-
// Set e-mail
|
699 |
-
$email = null;
|
700 |
-
if( isset( $args['wpstg_email'] ) ) {
|
701 |
-
$email = trim( $args['wpstg_email'] );
|
702 |
-
}
|
703 |
-
|
704 |
-
// Set message
|
705 |
-
$message = null;
|
706 |
-
if( isset( $args['wpstg_message'] ) ) {
|
707 |
-
$message = trim( $args['wpstg_message'] );
|
708 |
-
}
|
709 |
-
|
710 |
-
// Set syslog
|
711 |
-
$syslog = false;
|
712 |
-
if( isset( $args['wpstg_syslog'] ) ) {
|
713 |
-
$syslog = ( bool ) $args['wpstg_syslog'];
|
714 |
-
}
|
715 |
-
|
716 |
-
// Set terms
|
717 |
-
$terms = false;
|
718 |
-
if( isset( $args['wpstg_terms'] ) ) {
|
719 |
-
$terms = ( bool ) $args['wpstg_terms'];
|
720 |
-
}
|
721 |
-
|
722 |
-
$report = new Report( $this->di );
|
723 |
-
$errors = $report->send( $email, $message, $terms, $syslog );
|
724 |
-
|
725 |
-
echo json_encode( array('errors' => $errors) );
|
726 |
-
exit;
|
727 |
-
}
|
728 |
-
|
729 |
-
/**
|
730 |
-
* Connect to external database for testing correct credentials
|
731 |
-
*/
|
732 |
-
public function ajaxDatabaseConnect() {
|
733 |
-
// Set params
|
734 |
-
if( empty( $args ) ) {
|
735 |
-
$args = stripslashes_deep( $_POST );
|
736 |
-
}
|
737 |
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
762 |
|
763 |
}
|
4 |
|
5 |
// No Direct Access
|
6 |
if( !defined( "WPINC" ) ) {
|
7 |
+
die;
|
8 |
}
|
9 |
|
10 |
use WPStaging\WPStaging;
|
29 |
*/
|
30 |
class Administrator extends InjectionAware {
|
31 |
|
32 |
+
/**
|
33 |
+
* @var string
|
34 |
+
*/
|
35 |
+
private $path;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @var string
|
39 |
+
*/
|
40 |
+
private $url;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Initialize class
|
44 |
+
*/
|
45 |
+
public function initialize() {
|
46 |
+
$this->defineHooks();
|
47 |
+
|
48 |
+
// Path to backend
|
49 |
+
$this->path = plugin_dir_path( __FILE__ );
|
50 |
+
|
51 |
+
// URL to public backend folder
|
52 |
+
$this->url = plugin_dir_url( __FILE__ ) . "public/";
|
53 |
+
|
54 |
+
// Load plugins meta data
|
55 |
+
$this->loadMeta();
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Load plugn meta data
|
60 |
+
*/
|
61 |
+
public function loadMeta() {
|
62 |
+
$run = new \WPStaging\Backend\Pluginmeta\Pluginmeta();
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Define Hooks
|
67 |
+
*/
|
68 |
+
private function defineHooks() {
|
69 |
+
// Get loader
|
70 |
+
$loader = $this->di->get( "loader" );
|
71 |
+
|
72 |
+
$Activation = new \WPStaging\Backend\Activation\Activation();
|
73 |
+
|
74 |
+
$Welcome = new Activation\Welcome();
|
75 |
+
|
76 |
+
$loader->addAction( "activated_plugin", $Activation, 'deactivate_other_instances' );
|
77 |
+
//$loader->addAction( "activated_plugin", $Activation, 'install_dependancies' );
|
78 |
+
$loader->addAction( "admin_menu", $this, "addMenu", 10 );
|
79 |
+
$loader->addAction( "admin_init", $this, "setOptionFormElements" );
|
80 |
+
$loader->addAction( "admin_init", $this, "upgrade" );
|
81 |
+
$loader->addAction( "admin_post_wpstg_download_sysinfo", $this, "systemInfoDownload" );
|
82 |
+
$loader->addAction( "admin_post_wpstg_export", $this, "export" );
|
83 |
+
$loader->addAction( "admin_post_wpstg_import_settings", $this, "import" );
|
84 |
+
$loader->addAction( "admin_notices", $this, "messages" );
|
85 |
+
|
86 |
+
// Ajax Requests
|
87 |
+
$loader->addAction( "wp_ajax_wpstg_overview", $this, "ajaxOverview" );
|
88 |
+
$loader->addAction( "wp_ajax_wpstg_scanning", $this, "ajaxScan" );
|
89 |
+
$loader->addAction( "wp_ajax_wpstg_check_clone", $this, "ajaxcheckCloneName" );
|
90 |
+
$loader->addAction( "wp_ajax_wpstg_update", $this, "ajaxUpdateProcess" );
|
91 |
+
$loader->addAction( "wp_ajax_wpstg_cloning", $this, "ajaxStartClone" );
|
92 |
+
$loader->addAction( "wp_ajax_wpstg_processing", $this, "ajaxCloneDatabase" );
|
93 |
+
$loader->addAction( "wp_ajax_wpstg_database_connect", $this, "ajaxDatabaseConnect" );
|
94 |
+
$loader->addAction( "wp_ajax_wpstg_clone_prepare_directories", $this, "ajaxPrepareDirectories" );
|
95 |
+
$loader->addAction( "wp_ajax_wpstg_clone_files", $this, "ajaxCopyFiles" );
|
96 |
+
$loader->addAction( "wp_ajax_wpstg_clone_replace_data", $this, "ajaxReplaceData" );
|
97 |
+
$loader->addAction( "wp_ajax_wpstg_clone_finish", $this, "ajaxFinish" );
|
98 |
+
$loader->addAction( "wp_ajax_wpstg_confirm_delete_clone", $this, "ajaxDeleteConfirmation" );
|
99 |
+
$loader->addAction( "wp_ajax_wpstg_delete_clone", $this, "ajaxDeleteClone" );
|
100 |
+
$loader->addAction( "wp_ajax_wpstg_cancel_clone", $this, "ajaxCancelClone" );
|
101 |
+
$loader->addAction( "wp_ajax_wpstg_cancel_update", $this, "ajaxCancelUpdate" );
|
102 |
+
$loader->addAction( "wp_ajax_wpstg_hide_poll", $this, "ajaxHidePoll" );
|
103 |
+
$loader->addAction( "wp_ajax_wpstg_hide_rating", $this, "ajaxHideRating" );
|
104 |
+
$loader->addAction( "wp_ajax_wpstg_hide_later", $this, "ajaxHideLaterRating" );
|
105 |
+
$loader->addAction( "wp_ajax_wpstg_hide_beta", $this, "ajaxHideBeta" );
|
106 |
+
$loader->addAction( "wp_ajax_wpstg_logs", $this, "ajaxLogs" );
|
107 |
+
$loader->addAction( "wp_ajax_wpstg_check_disk_space", $this, "ajaxCheckFreeSpace" );
|
108 |
+
$loader->addAction( "wp_ajax_wpstg_send_report", $this, "ajaxSendReport" );
|
109 |
+
|
110 |
+
// Ajax hooks pro Version
|
111 |
+
$loader->addAction( "wp_ajax_wpstg_scan", $this, "ajaxPushScan" );
|
112 |
+
$loader->addAction( "wp_ajax_wpstg_push_processing", $this, "ajaxPushProcessing" );
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Register options form elements
|
117 |
+
*/
|
118 |
+
public function setOptionFormElements() {
|
119 |
+
register_setting( "wpstg_settings", "wpstg_settings", array($this, "sanitizeOptions") );
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Upgrade routine
|
124 |
+
*/
|
125 |
+
public function upgrade() {
|
126 |
+
$upgrade = new Upgrade\Upgrade();
|
127 |
+
$upgrade->doUpgrade();
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Sanitize options data and delete the cache
|
132 |
+
* @param array $data
|
133 |
+
* @return array
|
134 |
+
*/
|
135 |
+
public function sanitizeOptions( $data = array() ) {
|
136 |
+
$sanitized = $this->sanitizeData( $data );
|
137 |
+
|
138 |
+
add_settings_error( "wpstg-notices", '', __( "Settings updated.", "wp-staging" ), "updated" );
|
139 |
+
|
140 |
+
return apply_filters( "wpstg-settings", $sanitized, $data );
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* @param array $data
|
145 |
+
* @return array
|
146 |
+
*/
|
147 |
+
private function sanitizeData( $data = array() ) {
|
148 |
+
$sanitized = array();
|
149 |
+
|
150 |
+
foreach ( $data as $key => $value ) {
|
151 |
+
$sanitized[$key] = (is_array( $value )) ? $this->sanitizeData( $value ) : htmlspecialchars( $value );
|
152 |
+
}
|
153 |
+
|
154 |
+
return $sanitized;
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Add Admin Menu(s)
|
159 |
+
*/
|
160 |
+
public function addMenu() {
|
161 |
+
|
162 |
+
$logo = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMTAwMCAxMDAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMDAwIDEwMDAiIHhtbDpzcGFjZT0icHJlc2VydmUiIGZpbGw9Im5vbmUiPgo8Zz48Zz48cGF0aCBzdHlsZT0iZmlsbDojZmZmIiAgZD0iTTEzNy42LDU2MS4zSDEzLjhIMTB2MzA2LjNsOTAuNy04My40QzE4OS42LDkwOC43LDMzNS4zLDk5MCw1MDAsOTkwYzI0OS45LDAsNDU2LjEtMTg3LjEsNDg2LjItNDI4LjhIODYyLjRDODMzLjMsNzM1LjEsNjgyLjEsODY3LjUsNTAwLDg2Ny41Yy0xMjksMC0yNDIuNS02Ni41LTMwOC4xLTE2Ny4ybDE1MS4zLTEzOS4xSDEzNy42eiIvPjxwYXRoIHN0eWxlPSJmaWxsOiNmZmYiICBkPSJNNTAwLDEwQzI1MC4xLDEwLDQzLjksMTk3LjEsMTMuOCw0MzguOGgxMjMuOEMxNjYuNywyNjQuOSwzMTcuOSwxMzIuNSw1MDAsMTMyLjVjMTMyLjksMCwyNDkuMyw3MC41LDMxMy44LDE3Ni4yTDY4My44LDQzOC44aDEyMi41aDU2LjJoMTIzLjhoMy44VjEzMi41bC04Ny43LDg3LjdDODEzLjgsOTMuMSw2NjYuNiwxMCw1MDAsMTB6Ii8+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjwvZz4KPC9zdmc+';
|
163 |
+
|
164 |
+
// Main WP Staging Menu
|
165 |
+
add_menu_page(
|
166 |
+
"WP-Staging", __( "WP Staging", "wp-staging" ), "manage_options", "wpstg_clone", array($this, "getClonePage"), $logo
|
167 |
+
);
|
168 |
+
|
169 |
+
// Page: Clone
|
170 |
+
add_submenu_page(
|
171 |
+
"wpstg_clone", __( "WP Staging Jobs", "wp-staging" ), __( "Sites / Start", "wp-staging" ), "manage_options", "wpstg_clone", array($this, "getClonePage")
|
172 |
+
);
|
173 |
+
|
174 |
+
// Page: Settings
|
175 |
+
add_submenu_page(
|
176 |
+
"wpstg_clone", __( "WP Staging Settings", "wp-staging" ), __( "Settings", "wp-staging" ), "manage_options", "wpstg-settings", array($this, "getSettingsPage")
|
177 |
+
);
|
178 |
+
|
179 |
+
// Page: Tools
|
180 |
+
add_submenu_page(
|
181 |
+
"wpstg_clone", __( "WP Staging Tools", "wp-staging" ), __( "Tools", "wp-staging" ), "manage_options", "wpstg-tools", array($this, "getToolsPage")
|
182 |
+
);
|
183 |
+
// Page: Tools
|
184 |
+
add_submenu_page(
|
185 |
+
"wpstg_clone", __( "WP Staging Welcome", "wp-staging" ), __( "Get WP Staging Pro", "wp-staging" ), "manage_options", "wpstg-welcome", array($this, "getWelcomePage")
|
186 |
+
);
|
187 |
+
|
188 |
+
if( class_exists( 'WPStaging\Backend\Pro\Licensing\Licensing' ) ) {
|
189 |
+
// Page: License
|
190 |
+
add_submenu_page(
|
191 |
+
"wpstg_clone", __( "WP Staging License", "wp-staging" ), __( "License", "wp-staging" ), "manage_options", "wpstg-license", array($this, "getLicensePage")
|
192 |
+
);
|
193 |
+
}
|
194 |
+
}
|
195 |
+
|
196 |
+
/**
|
197 |
+
* Settings Page
|
198 |
+
*/
|
199 |
+
public function getSettingsPage() {
|
200 |
+
// Tabs
|
201 |
+
$tabs = new Tabs( array(
|
202 |
+
"general" => __( "General", "wp-staging" )
|
203 |
+
) );
|
204 |
+
|
205 |
+
|
206 |
+
$this->di
|
207 |
+
// Set tabs
|
208 |
+
->set( "tabs", $tabs )
|
209 |
+
// Forms
|
210 |
+
->set( "forms", new FormSettings( $tabs ) );
|
211 |
+
|
212 |
+
|
213 |
+
require_once "{$this->path}views/settings/main-settings.php";
|
214 |
+
}
|
215 |
+
|
216 |
+
/**
|
217 |
+
* Clone Page
|
218 |
+
*/
|
219 |
+
public function getClonePage() {
|
220 |
+
// Existing clones
|
221 |
+
$availableClones = get_option( "wpstg_existing_clones_beta", array() );
|
222 |
+
|
223 |
+
require_once "{$this->path}views/clone/index.php";
|
224 |
+
}
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Welcome Page
|
228 |
+
*/
|
229 |
+
public function getWelcomePage() {
|
230 |
+
require_once "{$this->path}views/welcome/welcome.php";
|
231 |
+
}
|
232 |
+
|
233 |
+
/**
|
234 |
+
* Tools Page
|
235 |
+
*/
|
236 |
+
public function getToolsPage() {
|
237 |
+
// Tabs
|
238 |
+
$tabs = new Tabs( array(
|
239 |
+
"import_export" => __( "Import/Export", "wp-staging" ),
|
240 |
+
"system_info" => __( "System Info", "wp-staging" )
|
241 |
+
) );
|
242 |
+
|
243 |
+
$this->di->set( "tabs", $tabs );
|
244 |
+
|
245 |
+
$this->di->set( "systemInfo", new SystemInfo( $this->di ) );
|
246 |
+
|
247 |
+
require_once "{$this->path}views/tools/index.php";
|
248 |
+
}
|
249 |
+
|
250 |
+
/**
|
251 |
+
* System Information Download
|
252 |
+
*/
|
253 |
+
public function systemInfoDownload() {
|
254 |
+
if( !current_user_can( "update_plugins" ) ) {
|
255 |
+
return;
|
256 |
+
}
|
257 |
+
|
258 |
+
nocache_headers();
|
259 |
+
header( "Content-Type: text/plain" );
|
260 |
+
header( "Content-Disposition: attachment; filename='wpstg-system-info.txt'" );
|
261 |
+
echo wp_strip_all_tags( new SystemInfo( $this->di ) );
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* Import JSON settings file
|
266 |
+
*/
|
267 |
+
public function import() {
|
268 |
+
if( empty( $_POST["wpstg_import_nonce"] ) ) {
|
269 |
+
return;
|
270 |
+
}
|
271 |
+
|
272 |
+
if( !wp_verify_nonce( $_POST["wpstg_import_nonce"], "wpstg_import_nonce" ) ) {
|
273 |
+
return;
|
274 |
+
}
|
275 |
+
|
276 |
+
if( !current_user_can( "update_plugins" ) ) {
|
277 |
+
return;
|
278 |
+
}
|
279 |
+
|
280 |
+
$fileExtension = explode( '.', $_FILES["import_file"]["name"] );
|
281 |
+
$fileExtension = end( $fileExtension );
|
282 |
+
if( "json" !== $fileExtension ) {
|
283 |
+
wp_die( "Please upload a valid .json file", "wp-staging" );
|
284 |
+
}
|
285 |
+
|
286 |
+
|
287 |
+
$importFile = $_FILES["import_file"]["tmp_name"];
|
288 |
+
|
289 |
+
if( empty( $importFile ) ) {
|
290 |
+
wp_die( __( "Please upload a file to import", "wp-staging" ) );
|
291 |
+
}
|
292 |
+
|
293 |
+
update_option( "wpstg_settings", json_decode( file_get_contents( $importFile, true ) ) );
|
294 |
+
|
295 |
+
wp_safe_redirect( admin_url( "admin.php?page=wpstg-tools&wpstg-message=settings-imported" ) );
|
296 |
+
|
297 |
+
return;
|
298 |
+
}
|
299 |
+
|
300 |
+
/**
|
301 |
+
* Export settings to JSON file
|
302 |
+
*/
|
303 |
+
public function export() {
|
304 |
+
if( empty( $_POST["wpstg_export_nonce"] ) ) {
|
305 |
+
return;
|
306 |
+
}
|
307 |
+
|
308 |
+
if( !wp_verify_nonce( $_POST["wpstg_export_nonce"], "wpstg_export_nonce" ) ) {
|
309 |
+
return;
|
310 |
+
}
|
311 |
+
|
312 |
+
if( !current_user_can( "manage_options" ) ) {
|
313 |
+
return;
|
314 |
+
}
|
315 |
+
|
316 |
+
$settings = get_option( "wpstg_settings", array() );
|
317 |
+
|
318 |
+
ignore_user_abort( true );
|
319 |
+
|
320 |
+
if( !in_array( "set_time_limit", explode( ',', ini_get( "disable_functions" ) ) ) && !@ini_get( "safe_mode" ) ) {
|
321 |
+
set_time_limit( 0 );
|
322 |
+
}
|
323 |
+
|
324 |
+
$fileName = apply_filters( "wpstg_settings_export_filename", "wpstg-settings-export-" . date( "m-d-Y" ) ) . ".json";
|
325 |
+
|
326 |
+
nocache_headers();
|
327 |
+
header( "Content-Type: application/json; charset=utf-8" );
|
328 |
+
header( "Content-Disposition: attachment; filename={$fileName}" );
|
329 |
+
header( "Expires: 0" );
|
330 |
+
|
331 |
+
echo json_encode( $settings );
|
332 |
+
}
|
333 |
+
|
334 |
+
/**
|
335 |
+
* Render a view file
|
336 |
+
* @param string $file
|
337 |
+
* @param array $vars
|
338 |
+
* @return string
|
339 |
+
*/
|
340 |
+
public function render( $file, $vars = array() ) {
|
341 |
+
$fullPath = $this->path . "views" . DIRECTORY_SEPARATOR;
|
342 |
+
$fullPath = str_replace( array('/', "\\"), DIRECTORY_SEPARATOR, $fullPath . $file . ".php" );
|
343 |
+
|
344 |
+
if( !file_exists( $fullPath ) || !is_readable( $fullPath ) ) {
|
345 |
+
return "Can't render : {$fullPath} either file doesn't exist or can't read it";
|
346 |
+
}
|
347 |
+
|
348 |
+
$contents = @file_get_contents( $fullPath );
|
349 |
+
|
350 |
+
// Variables are set
|
351 |
+
if( count( $vars ) > 0 ) {
|
352 |
+
$vars = array_combine(
|
353 |
+
array_map( function ($key) {
|
354 |
+
return "{{" . $key . "}}";
|
355 |
+
}, array_keys( $vars )
|
356 |
+
), $vars
|
357 |
+
);
|
358 |
+
|
359 |
+
$contents = str_replace( array_keys( $vars ), array_values( $vars ), $contents );
|
360 |
+
}
|
361 |
+
|
362 |
+
return $contents;
|
363 |
+
}
|
364 |
+
|
365 |
+
/**
|
366 |
+
* Ajax Overview
|
367 |
+
*/
|
368 |
+
public function ajaxOverview() {
|
369 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
370 |
|
371 |
+
// Existing clones
|
372 |
+
$availableClones = get_option( "wpstg_existing_clones_beta", array() );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
373 |
|
374 |
+
// Get license data
|
375 |
+
$license = get_option( 'wpstg_license_status' );
|
376 |
+
|
377 |
+
// Get db
|
378 |
+
$db = WPStaging::getInstance()->get( 'wpdb' );
|
379 |
|
380 |
+
if( \WPStaging\WPStaging::getSlug() === 'wp-staging-pro' ) {
|
381 |
+
require_once "{$this->path}Pro/views/single-overview-pro.php";
|
382 |
+
} else {
|
383 |
+
require_once "{$this->path}views/clone/ajax/single-overview.php";
|
384 |
+
}
|
385 |
|
386 |
+
wp_die();
|
387 |
+
}
|
388 |
|
389 |
+
/**
|
390 |
+
* Ajax Scan
|
391 |
+
*/
|
392 |
+
public function ajaxScan() {
|
393 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
394 |
+
|
395 |
+
$db = WPStaging::getInstance()->get( 'wpdb' );
|
396 |
+
|
397 |
+
// Scan
|
398 |
+
$scan = new Scan();
|
399 |
+
$scan->start();
|
400 |
+
|
401 |
+
// Get Options
|
402 |
+
$options = $scan->getOptions();
|
403 |
+
|
404 |
+
require_once "{$this->path}views/clone/ajax/scan.php";
|
405 |
+
|
406 |
+
wp_die();
|
407 |
+
}
|
408 |
+
|
409 |
+
/**
|
410 |
+
* Ajax Check Clone Name
|
411 |
+
*/
|
412 |
+
public function ajaxCheckCloneName() {
|
413 |
+
$cloneName = sanitize_key( $_POST["cloneID"] );
|
414 |
+
$cloneNameLength = strlen( $cloneName );
|
415 |
+
$clones = get_option( "wpstg_existing_clones_beta", array() );
|
416 |
+
|
417 |
+
$clonePath = trailingslashit( get_home_path() ) . $cloneName;
|
418 |
+
|
419 |
+
// Check clone name length
|
420 |
+
if( $cloneNameLength < 1 || $cloneNameLength > 16 ) {
|
421 |
+
echo wp_send_json( array(
|
422 |
+
"status" => "failed",
|
423 |
+
"message" => "Clone name must be between 1 - 16 characters"
|
424 |
+
) );
|
425 |
+
} elseif( array_key_exists( $cloneName, $clones ) ) {
|
426 |
+
echo wp_send_json( array(
|
427 |
+
"status" => "failed",
|
428 |
+
"message" => "Clone name is already in use, please choose an another clone name."
|
429 |
+
) );
|
430 |
+
} elseif( is_dir( $clonePath ) ) {
|
431 |
+
echo wp_send_json( array(
|
432 |
+
"status" => "failed",
|
433 |
+
"message" => "Clone directory " . $clonePath . " already exists. Use another clone name."
|
434 |
+
) );
|
435 |
+
}
|
436 |
+
|
437 |
+
echo wp_send_json( array("status" => "success") );
|
438 |
+
}
|
439 |
+
|
440 |
+
/**
|
441 |
+
* Ajax Start Updating Clone (Basically just layout and saving data)
|
442 |
+
*/
|
443 |
+
public function ajaxUpdateProcess() {
|
444 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
445 |
|
446 |
+
$cloning = new Updating();
|
447 |
|
448 |
+
if( !$cloning->save() ) {
|
449 |
+
wp_die( 'can not save clone data' );
|
450 |
+
}
|
451 |
|
452 |
+
require_once "{$this->path}views/clone/ajax/update.php";
|
453 |
|
454 |
+
wp_die();
|
455 |
+
}
|
456 |
|
457 |
+
/**
|
458 |
+
* Ajax Start Clone (Basically just layout and saving data)
|
459 |
+
*/
|
460 |
+
public function ajaxStartClone() {
|
461 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
462 |
|
463 |
+
$cloning = new Cloning();
|
464 |
|
465 |
+
if( !$cloning->save() ) {
|
466 |
+
wp_die( 'can not save clone data' );
|
467 |
+
}
|
468 |
|
469 |
+
require_once "{$this->path}views/clone/ajax/start.php";
|
|
|
470 |
|
471 |
+
wp_die();
|
472 |
+
}
|
|
|
|
|
|
|
473 |
|
474 |
+
/**
|
475 |
+
* Ajax Clone Database
|
476 |
+
*/
|
477 |
+
public function ajaxCloneDatabase() {
|
478 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
479 |
|
480 |
+
$cloning = new Cloning();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
481 |
|
482 |
+
// Uncomment these lines to test different error codes
|
483 |
+
//http_response_code(504);
|
484 |
+
//wp_send_json( '<html><body><head></head><body>test</body></html>' );
|
485 |
+
|
486 |
+
wp_send_json( $cloning->start() );
|
487 |
+
}
|
488 |
+
|
489 |
+
/**
|
490 |
+
* Ajax Prepare Directories (get listing of files)
|
491 |
+
*/
|
492 |
+
public function ajaxPrepareDirectories() {
|
493 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
494 |
+
|
495 |
+
$cloning = new Cloning();
|
496 |
+
|
497 |
+
wp_send_json( $cloning->start() );
|
498 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
499 |
|
500 |
+
/**
|
501 |
+
* Ajax Clone Files
|
502 |
+
*/
|
503 |
+
public function ajaxCopyFiles() {
|
504 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
505 |
+
|
506 |
+
$cloning = new Cloning();
|
507 |
+
|
508 |
+
wp_send_json( $cloning->start() );
|
509 |
+
}
|
510 |
+
|
511 |
+
/**
|
512 |
+
* Ajax Replace Data
|
513 |
+
*/
|
514 |
+
public function ajaxReplaceData() {
|
515 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
516 |
+
|
517 |
+
$cloning = new Cloning();
|
518 |
+
|
519 |
+
wp_send_json( $cloning->start() );
|
520 |
+
}
|
521 |
+
|
522 |
+
/**
|
523 |
+
* Ajax Finish
|
524 |
+
*/
|
525 |
+
public function ajaxFinish() {
|
526 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
527 |
+
|
528 |
+
$cloning = new Cloning();
|
529 |
+
|
530 |
+
wp_send_json( $cloning->start() );
|
531 |
+
}
|
532 |
+
|
533 |
+
/**
|
534 |
+
* Ajax Delete Confirmation
|
535 |
+
*/
|
536 |
+
public function ajaxDeleteConfirmation() {
|
537 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
538 |
+
|
539 |
+
$delete = new Delete();
|
540 |
+
$delete->setData();
|
541 |
+
|
542 |
+
$clone = $delete->getClone();
|
543 |
+
|
544 |
+
$dbname = $delete->getDbName();
|
545 |
+
|
546 |
+
require_once "{$this->path}views/clone/ajax/delete-confirmation.php";
|
547 |
+
|
548 |
+
wp_die();
|
549 |
+
}
|
550 |
+
|
551 |
+
/**
|
552 |
+
* Delete clone
|
553 |
+
*/
|
554 |
+
public function ajaxDeleteClone() {
|
555 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
556 |
+
|
557 |
+
$delete = new Delete();
|
558 |
+
|
559 |
+
wp_send_json( $delete->start() );
|
560 |
+
}
|
561 |
+
|
562 |
+
/**
|
563 |
+
* Delete clone
|
564 |
+
*/
|
565 |
+
public function ajaxCancelClone() {
|
566 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
567 |
+
|
568 |
+
$cancel = new Cancel();
|
569 |
+
|
570 |
+
wp_send_json( $cancel->start() );
|
571 |
+
}
|
572 |
+
|
573 |
+
/**
|
574 |
+
* Cancel updating process / Do not delete clone!
|
575 |
+
*/
|
576 |
+
public function ajaxCancelUpdate() {
|
577 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
578 |
+
|
579 |
+
$cancel = new CancelUpdate();
|
580 |
+
wp_send_json( $cancel->start() );
|
581 |
+
}
|
582 |
+
|
583 |
+
/**
|
584 |
+
* Admin Messages
|
585 |
+
*/
|
586 |
+
public function messages() {
|
587 |
+
$notice = new Notices( $this->path, $this->url );
|
588 |
+
|
589 |
+
$run = $notice->messages();
|
590 |
+
}
|
591 |
+
|
592 |
+
/**
|
593 |
+
* Ajax Hide Poll
|
594 |
+
* @return mixed boolean | json
|
595 |
+
*/
|
596 |
+
public function ajaxHidePoll() {
|
597 |
+
if( false !== update_option( "wpstg_poll", "no" ) ) {
|
598 |
+
wp_send_json( true );
|
599 |
+
}
|
600 |
+
return wp_send_json();
|
601 |
+
}
|
602 |
+
|
603 |
+
/**
|
604 |
+
* Ajax Hide Rating
|
605 |
+
* @return mixed bool | json
|
606 |
+
*/
|
607 |
+
public function ajaxHideRating() {
|
608 |
+
if( false !== update_option( "wpstg_rating", "no" ) ) {
|
609 |
+
wp_send_json( true );
|
610 |
+
}
|
611 |
+
return wp_send_json();
|
612 |
+
}
|
613 |
+
|
614 |
+
/**
|
615 |
+
* Ajax Hide Rating and show it again after one week
|
616 |
+
* @return mixed bool | json
|
617 |
+
*/
|
618 |
+
public function ajaxHideLaterRating() {
|
619 |
+
if( false !== update_option( 'wpstg_rating', date( 'Y-m-d' ) )
|
620 |
+
) {
|
621 |
+
wp_send_json( true );
|
622 |
+
}
|
623 |
+
return wp_send_json(false);
|
624 |
+
}
|
625 |
+
|
626 |
+
/**
|
627 |
+
* Ajax Hide Beta
|
628 |
+
*/
|
629 |
+
public function ajaxHideBeta() {
|
630 |
+
wp_send_json( update_option( "wpstg_beta", "no" ) );
|
631 |
+
}
|
632 |
+
|
633 |
+
/**
|
634 |
+
* Clone logs
|
635 |
+
*/
|
636 |
+
public function ajaxLogs() {
|
637 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
638 |
+
|
639 |
+
$logs = new Logs();
|
640 |
+
wp_send_json( $logs->start() );
|
641 |
+
}
|
642 |
+
|
643 |
+
/**
|
644 |
+
* Ajax Checks Free Disk Space
|
645 |
+
*/
|
646 |
+
public function ajaxCheckFreeSpace() {
|
647 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
648 |
+
|
649 |
+
$scan = new Scan();
|
650 |
+
return $scan->hasFreeDiskSpace();
|
651 |
+
}
|
652 |
+
|
653 |
+
/**
|
654 |
+
* Ajax Start Push Changes Process
|
655 |
+
* Start with the module Scan
|
656 |
+
*/
|
657 |
+
public function ajaxPushScan() {
|
658 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
659 |
+
|
660 |
+
if( !class_exists( 'WPStaging\Backend\Pro\Modules\Jobs\Scan' ) ) {
|
661 |
+
return false;
|
662 |
+
}
|
663 |
+
|
664 |
+
// Scan
|
665 |
+
$scan = new Pro\Modules\Jobs\Scan();
|
666 |
+
|
667 |
+
$scan->start();
|
668 |
+
|
669 |
+
// Get Options
|
670 |
+
$options = $scan->getOptions();
|
671 |
+
|
672 |
+
require_once "{$this->path}Pro/views/scan.php";
|
673 |
+
|
674 |
+
wp_die();
|
675 |
+
}
|
676 |
+
|
677 |
+
/**
|
678 |
+
* Ajax Start Pushing. Needs wp quads pro
|
679 |
+
*/
|
680 |
+
public function ajaxPushProcessing() {
|
681 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
682 |
+
|
683 |
+
if( !class_exists( 'WPStaging\Backend\Pro\Modules\Jobs\Processing' ) ) {
|
684 |
+
return false;
|
685 |
+
}
|
686 |
+
// Start the process
|
687 |
+
$processing = new Processing();
|
688 |
+
wp_send_json( $processing->start() );
|
689 |
+
}
|
690 |
+
|
691 |
+
/**
|
692 |
+
* License Page
|
693 |
+
*/
|
694 |
+
public function getLicensePage() {
|
695 |
+
|
696 |
+
// Get license data
|
697 |
+
$license = get_option( 'wpstg_license_status' );
|
698 |
+
|
699 |
+
require_once "{$this->path}Pro/views/licensing.php";
|
700 |
+
}
|
701 |
+
|
702 |
+
/**
|
703 |
+
*
|
704 |
+
* @param type $args
|
705 |
+
*/
|
706 |
+
public function ajaxSendReport( $args = array() ) {
|
707 |
+
// Set params
|
708 |
+
if( empty( $args ) ) {
|
709 |
+
$args = stripslashes_deep( $_POST );
|
710 |
+
}
|
711 |
+
// Set e-mail
|
712 |
+
$email = null;
|
713 |
+
if( isset( $args['wpstg_email'] ) ) {
|
714 |
+
$email = trim( $args['wpstg_email'] );
|
715 |
+
}
|
716 |
+
|
717 |
+
// Set message
|
718 |
+
$message = null;
|
719 |
+
if( isset( $args['wpstg_message'] ) ) {
|
720 |
+
$message = trim( $args['wpstg_message'] );
|
721 |
+
}
|
722 |
+
|
723 |
+
// Set syslog
|
724 |
+
$syslog = false;
|
725 |
+
if( isset( $args['wpstg_syslog'] ) ) {
|
726 |
+
$syslog = ( bool ) $args['wpstg_syslog'];
|
727 |
+
}
|
728 |
+
|
729 |
+
// Set terms
|
730 |
+
$terms = false;
|
731 |
+
if( isset( $args['wpstg_terms'] ) ) {
|
732 |
+
$terms = ( bool ) $args['wpstg_terms'];
|
733 |
+
}
|
734 |
+
|
735 |
+
$report = new Report( $this->di );
|
736 |
+
$errors = $report->send( $email, $message, $terms, $syslog );
|
737 |
+
|
738 |
+
echo json_encode( array('errors' => $errors) );
|
739 |
+
exit;
|
740 |
+
}
|
741 |
+
|
742 |
+
/**
|
743 |
+
* Connect to external database for testing correct credentials
|
744 |
+
*/
|
745 |
+
public function ajaxDatabaseConnect() {
|
746 |
+
// Set params
|
747 |
+
if( empty( $args ) ) {
|
748 |
+
$args = stripslashes_deep( $_POST );
|
749 |
+
}
|
750 |
+
|
751 |
+
$user = !empty( $args['databaseUser'] ) ? $args['databaseUser'] : '';
|
752 |
+
$password = !empty( $args['databasePassword'] ) ? $args['databasePassword'] : '';
|
753 |
+
$database = !empty( $args['databaseDatabase'] ) ? $args['databaseDatabase'] : '';
|
754 |
+
$server = !empty( $args['databaseServer'] ) ? $args['databaseServer'] : '';
|
755 |
+
|
756 |
+
$db = new \wpdb( $user, $password, $database, $server );
|
757 |
+
|
758 |
+
// Can not connect to mysql
|
759 |
+
if( !empty( $db->error->errors['db_connect_fail']['0'] ) ) {
|
760 |
+
echo json_encode( array('errors' => $db->error->errors['db_connect_fail']['0']) );
|
761 |
+
exit;
|
762 |
+
}
|
763 |
+
|
764 |
+
|
765 |
+
// Can not connect to database
|
766 |
+
$sql = "SHOW DATABASES LIKE '{$database}';";
|
767 |
+
$results = $db->query( $sql );
|
768 |
+
if( empty( $results ) ) {
|
769 |
+
echo json_encode( array('errors' => " Database {$database} does not exist. You need to create it first. ") );
|
770 |
+
exit;
|
771 |
+
}
|
772 |
+
echo json_encode( array('success' => 'true') );
|
773 |
+
exit;
|
774 |
+
}
|
775 |
|
776 |
}
|
apps/Backend/Modules/Jobs/Data.php
CHANGED
@@ -75,7 +75,7 @@ class Data extends JobExecutable {
|
|
75 |
* @return void
|
76 |
*/
|
77 |
protected function calculateTotalSteps() {
|
78 |
-
$this->options->totalSteps =
|
79 |
}
|
80 |
|
81 |
/**
|
@@ -841,7 +841,6 @@ class Data extends JobExecutable {
|
|
841 |
preg_match( "/define\s*\(\s*'WP_CACHE'\s*,\s*(.*)\s*\);/", $content, $matches );
|
842 |
|
843 |
if( !empty( $matches[1] ) ) {
|
844 |
-
$matches[1];
|
845 |
|
846 |
$pattern = "/define\s*\(\s*'WP_CACHE'\s*,\s*(.*)\s*\);/";
|
847 |
|
@@ -864,6 +863,87 @@ class Data extends JobExecutable {
|
|
864 |
return true;
|
865 |
}
|
866 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
867 |
protected function getNewUploadPath() {
|
868 |
$uploadPath = get_option( 'upload_path' );
|
869 |
|
75 |
* @return void
|
76 |
*/
|
77 |
protected function calculateTotalSteps() {
|
78 |
+
$this->options->totalSteps = 17;
|
79 |
}
|
80 |
|
81 |
/**
|
841 |
preg_match( "/define\s*\(\s*'WP_CACHE'\s*,\s*(.*)\s*\);/", $content, $matches );
|
842 |
|
843 |
if( !empty( $matches[1] ) ) {
|
|
|
844 |
|
845 |
$pattern = "/define\s*\(\s*'WP_CACHE'\s*,\s*(.*)\s*\);/";
|
846 |
|
863 |
return true;
|
864 |
}
|
865 |
|
866 |
+
/**
|
867 |
+
* Remove WP_CONTENT_DIR in wp-config.php
|
868 |
+
* @return bool
|
869 |
+
*/
|
870 |
+
protected function step15() {
|
871 |
+
$path = $this->options->destinationDir . "wp-config.php";
|
872 |
+
|
873 |
+
$this->log( "Preparing Data Step15: Set WP_CONTENT_DIR in wp-config.php to false" );
|
874 |
+
|
875 |
+
if( false === ($content = file_get_contents( $path )) ) {
|
876 |
+
$this->log( "Preparing Data Step15: Failed to update WP_CONTENT_DIR in wp-config.php. Can't read wp-config.php", Logger::TYPE_ERROR );
|
877 |
+
return false;
|
878 |
+
}
|
879 |
+
|
880 |
+
|
881 |
+
// Get WP_CONTENT_DIR from wp-config.php
|
882 |
+
preg_match( "/define\s*\(\s*'WP_CONTENT_DIR'\s*,\s*(.*)\s*\);/", $content, $matches );
|
883 |
+
|
884 |
+
if( !empty( $matches[0] ) ) {
|
885 |
+
|
886 |
+
$pattern = "/define\s*\(\s*'WP_CONTENT_DIR'\s*,\s*(.*)\s*\);/";
|
887 |
+
|
888 |
+
$replace = "";
|
889 |
+
|
890 |
+
if( null === ($content = preg_replace( array($pattern), $replace, $content )) ) {
|
891 |
+
$this->log( "Preparing Data: Failed to change WP_CONTENT_DIR", Logger::TYPE_ERROR );
|
892 |
+
return false;
|
893 |
+
}
|
894 |
+
} else {
|
895 |
+
$this->log( "Preparing Data Step15: WP_CONTENT_DIR not defined in wp-config.php. Skipping this step." );
|
896 |
+
}
|
897 |
+
|
898 |
+
if( false === @file_put_contents( $path, $content ) ) {
|
899 |
+
$this->log( "Preparing Data Step15: Failed to update WP_CONTENT_DIR. Can't save contents", Logger::TYPE_ERROR );
|
900 |
+
return false;
|
901 |
+
}
|
902 |
+
$this->Log( "Preparing Data Step 15: Finished successfully" );
|
903 |
+
return true;
|
904 |
+
}
|
905 |
+
/**
|
906 |
+
* Remove WP_CONTENT_URL in wp-config.php
|
907 |
+
* @return bool
|
908 |
+
*/
|
909 |
+
protected function step16() {
|
910 |
+
$path = $this->options->destinationDir . "wp-config.php";
|
911 |
+
|
912 |
+
$this->log( "Preparing Data Step16: Set WP_CONTENT_URL in wp-config.php to false" );
|
913 |
+
|
914 |
+
if( false === ($content = file_get_contents( $path )) ) {
|
915 |
+
$this->log( "Preparing Data Step16: Failed to update WP_CONTENT_URL in wp-config.php. Can't read wp-config.php", Logger::TYPE_ERROR );
|
916 |
+
return false;
|
917 |
+
}
|
918 |
+
|
919 |
+
|
920 |
+
// Get WP_CONTENT_DIR from wp-config.php
|
921 |
+
preg_match( "/define\s*\(\s*'WP_CONTENT_URL'\s*,\s*(.*)\s*\);/", $content, $matches );
|
922 |
+
|
923 |
+
if( !empty( $matches[0] ) ) {
|
924 |
+
|
925 |
+
$pattern = "/define\s*\(\s*'WP_CONTENT_URL'\s*,\s*(.*)\s*\);/";
|
926 |
+
|
927 |
+
$replace = "";
|
928 |
+
|
929 |
+
if( null === ($content = preg_replace( array($pattern), $replace, $content )) ) {
|
930 |
+
$this->log( "Preparing Data: Failed to change WP_CONTENT_URL", Logger::TYPE_ERROR );
|
931 |
+
return false;
|
932 |
+
}
|
933 |
+
} else {
|
934 |
+
$this->log( "Preparing Data Step16: WP_CONTENT_URL not defined in wp-config.php. Skipping this step." );
|
935 |
+
}
|
936 |
+
|
937 |
+
if( false === @file_put_contents( $path, $content ) ) {
|
938 |
+
$this->log( "Preparing Data Step16: Failed to update WP_CONTENT_URL. Can't save contents", Logger::TYPE_ERROR );
|
939 |
+
return false;
|
940 |
+
}
|
941 |
+
$this->Log( "Preparing Data Step 16: Finished successfully" );
|
942 |
+
return true;
|
943 |
+
}
|
944 |
+
|
945 |
+
|
946 |
+
|
947 |
protected function getNewUploadPath() {
|
948 |
$uploadPath = get_option( 'upload_path' );
|
949 |
|
apps/Backend/Modules/Jobs/Directories.php
CHANGED
@@ -4,14 +4,13 @@ namespace WPStaging\Backend\Modules\Jobs;
|
|
4 |
|
5 |
// No Direct Access
|
6 |
if( !defined( "WPINC" ) ) {
|
7 |
-
|
8 |
}
|
9 |
|
10 |
use WPStaging\WPStaging;
|
11 |
use WPStaging\Utils\Logger;
|
12 |
use WPStaging\Utils\Strings;
|
13 |
use WPStaging\Iterators\RecursiveDirectoryIterator;
|
14 |
-
use WPStaging\Iterators\RecursiveFilterNewLine;
|
15 |
use WPStaging\Iterators\RecursiveFilterExclude;
|
16 |
|
17 |
/**
|
@@ -20,487 +19,469 @@ use WPStaging\Iterators\RecursiveFilterExclude;
|
|
20 |
*/
|
21 |
class Directories extends JobExecutable {
|
22 |
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
|
|
98 |
}
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
if( $this->isDirectoryExcluded( WP_CONTENT_DIR ) ) {
|
118 |
$this->log( "Skip " . \WPStaging\WPStaging::getWPpath() . 'wp-content' . DIRECTORY_SEPARATOR );
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
'node_modules'
|
128 |
-
|
129 |
|
130 |
-
|
131 |
|
132 |
-
|
133 |
-
|
134 |
|
135 |
-
|
136 |
-
|
137 |
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
|
143 |
-
|
144 |
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
|
|
150 |
|
151 |
-
|
152 |
-
|
153 |
-
|
|
|
154 |
}
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
// Skip it
|
176 |
-
if( $this->isDirectoryExcluded( \WPStaging\WPStaging::getWPpath() . 'wp-includes' . DIRECTORY_SEPARATOR ) ) {
|
177 |
$this->log( "Skip " . \WPStaging\WPStaging::getWPpath() . 'wp-includes' . DIRECTORY_SEPARATOR );
|
178 |
-
|
179 |
-
|
180 |
|
181 |
-
|
182 |
-
|
183 |
|
184 |
-
|
185 |
|
186 |
-
|
187 |
-
|
188 |
|
189 |
-
|
190 |
-
|
191 |
|
192 |
-
|
193 |
-
|
194 |
|
195 |
-
|
196 |
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
|
203 |
-
|
204 |
-
|
205 |
-
|
|
|
206 |
}
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
if( $this->isDirectoryExcluded( \WPStaging\WPStaging::getWPpath() . 'wp-admin' . DIRECTORY_SEPARATOR ) ) {
|
229 |
$this->log( "Skip " . \WPStaging\WPStaging::getWPpath() . 'wp-admin' . DIRECTORY_SEPARATOR );
|
230 |
-
|
231 |
-
|
232 |
|
233 |
-
|
234 |
-
|
235 |
|
236 |
-
|
237 |
|
238 |
-
|
239 |
-
|
240 |
|
241 |
-
|
242 |
-
|
243 |
|
244 |
-
|
245 |
-
|
246 |
|
247 |
-
|
248 |
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
|
|
257 |
}
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
*/
|
276 |
-
private function getExtraFiles( $folder ) {
|
277 |
|
278 |
if( !is_dir( $folder ) ) {
|
279 |
return true;
|
280 |
}
|
281 |
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
//
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
// Write path line
|
314 |
-
foreach ( $iterator as $item ) {
|
315 |
-
if( $item->isFile() ) {
|
316 |
-
//if( $this->write( $files, $strings->getLastElemAfterString( '/', $folder ) . DIRECTORY_SEPARATOR . $iterator->getSubPathName() . PHP_EOL ) ) {
|
317 |
-
if( $this->write( $files, str_replace( \WPStaging\WPStaging::getWPpath(), '', $folder ) . DIRECTORY_SEPARATOR . $iterator->getSubPathName() . PHP_EOL ) ) {
|
318 |
-
$this->options->totalFiles++;
|
319 |
-
// Too much cpu time
|
320 |
-
//$this->options->totalFileSize += $iterator->getSize();
|
321 |
-
}
|
322 |
}
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
if( $this->options->currentStep >= $this->options->totalSteps ) {
|
445 |
-
return true;
|
446 |
-
}
|
447 |
-
|
448 |
-
// return (
|
449 |
-
// //$this->options->currentStep > $this->total ||
|
450 |
-
// $this->options->currentStep >= $this->options->totalSteps
|
451 |
-
// );
|
452 |
-
}
|
453 |
-
|
454 |
-
/**
|
455 |
-
* Save files
|
456 |
-
* @return bool
|
457 |
-
*/
|
458 |
-
protected function saveProgress() {
|
459 |
-
return $this->saveOptions();
|
460 |
-
}
|
461 |
-
|
462 |
-
/**
|
463 |
-
* Get files
|
464 |
-
* @return void
|
465 |
-
*/
|
466 |
-
protected function getFiles() {
|
467 |
-
$fileName = $this->cache->getCacheDir() . "files_to_copy." . $this->cache->getCacheExtension();
|
468 |
-
|
469 |
-
if( false === ($this->files = @file_get_contents( $fileName )) ) {
|
470 |
-
$this->files = array();
|
471 |
-
return;
|
472 |
-
}
|
473 |
-
|
474 |
-
$this->files = explode( PHP_EOL, $this->files );
|
475 |
-
}
|
476 |
-
|
477 |
-
/**
|
478 |
-
* Replace forward slash with current directory separator
|
479 |
-
*
|
480 |
-
* @param string $path Path
|
481 |
-
*
|
482 |
-
* @return string
|
483 |
-
*/
|
484 |
-
private function sanitizeDirectorySeparator( $path ) {
|
485 |
-
$string = str_replace( "/", "\\", $path );
|
486 |
-
return str_replace( '\\\\', '\\', $string );
|
487 |
-
}
|
488 |
-
|
489 |
-
/**
|
490 |
-
* Check if directory is excluded
|
491 |
-
* @param string $directory
|
492 |
-
* @return bool
|
493 |
-
*/
|
494 |
-
protected function isDirectoryExcluded( $directory ) {
|
495 |
-
$directory = $this->sanitizeDirectorySeparator( $directory );
|
496 |
-
foreach ( $this->options->excludedDirectories as $excludedDirectory ) {
|
497 |
-
$excludedDirectory = $this->sanitizeDirectorySeparator( $excludedDirectory );
|
498 |
-
if( strpos( trailingslashit( $directory ), trailingslashit( $excludedDirectory ) ) === 0 ) {
|
499 |
return true;
|
500 |
-
|
501 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
502 |
|
503 |
-
|
504 |
-
|
505 |
|
506 |
}
|
4 |
|
5 |
// No Direct Access
|
6 |
if( !defined( "WPINC" ) ) {
|
7 |
+
die;
|
8 |
}
|
9 |
|
10 |
use WPStaging\WPStaging;
|
11 |
use WPStaging\Utils\Logger;
|
12 |
use WPStaging\Utils\Strings;
|
13 |
use WPStaging\Iterators\RecursiveDirectoryIterator;
|
|
|
14 |
use WPStaging\Iterators\RecursiveFilterExclude;
|
15 |
|
16 |
/**
|
19 |
*/
|
20 |
class Directories extends JobExecutable {
|
21 |
|
22 |
+
/**
|
23 |
+
* @var array
|
24 |
+
*/
|
25 |
+
private $files = array();
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Total steps to do
|
29 |
+
* @var int
|
30 |
+
*/
|
31 |
+
private $total = 4;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* path to the cache file
|
35 |
+
* @var string
|
36 |
+
*/
|
37 |
+
private $filename;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Initialize
|
41 |
+
*/
|
42 |
+
public function initialize() {
|
43 |
+
$this->filename = $this->cache->getCacheDir() . "files_to_copy." . $this->cache->getCacheExtension();
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Calculate Total Steps in This Job and Assign It to $this->options->totalSteps
|
48 |
+
* @return void
|
49 |
+
*/
|
50 |
+
protected function calculateTotalSteps() {
|
51 |
+
|
52 |
+
$this->options->totalSteps = $this->total + count( $this->options->extraDirectories );
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Start Module
|
57 |
+
* @return object
|
58 |
+
*/
|
59 |
+
public function start() {
|
60 |
+
|
61 |
+
// Execute steps
|
62 |
+
$this->run();
|
63 |
+
|
64 |
+
// Save option, progress
|
65 |
+
$this->saveProgress();
|
66 |
+
|
67 |
+
return ( object ) $this->response;
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Step 0
|
72 |
+
* Get WP Root files
|
73 |
+
* Does not collect any sub folders
|
74 |
+
*/
|
75 |
+
private function getWpRootFiles() {
|
76 |
+
|
77 |
+
// open file handle
|
78 |
+
$files = $this->open( $this->filename, 'a' );
|
79 |
+
|
80 |
+
|
81 |
+
try {
|
82 |
+
|
83 |
+
// Iterate over wp root directory
|
84 |
+
$iterator = new \DirectoryIterator( \WPStaging\WPStaging::getWPpath() );
|
85 |
+
|
86 |
+
$this->log( "Scanning / for files" );
|
87 |
+
|
88 |
+
// Write path line
|
89 |
+
foreach ( $iterator as $item ) {
|
90 |
+
if( !$item->isDot() && $item->isFile() ) {
|
91 |
+
if( $this->write( $files, $iterator->getFilename() . PHP_EOL ) ) {
|
92 |
+
$this->options->totalFiles++;
|
93 |
+
|
94 |
+
// Too much cpu time
|
95 |
+
//$this->options->totalFileSize += $iterator->getSize();
|
96 |
+
}
|
97 |
+
}
|
98 |
}
|
99 |
+
} catch ( \Exception $e ) {
|
100 |
+
$this->returnException( 'Error: ' . $e->getMessage() );
|
101 |
+
} catch ( \Exception $e ) {
|
102 |
+
// Skip bad file permissions
|
103 |
+
}
|
104 |
+
|
105 |
+
$this->close( $files );
|
106 |
+
return true;
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Step 2
|
111 |
+
* Get WP Content Files
|
112 |
+
*/
|
113 |
+
private function getWpContentFiles() {
|
114 |
+
|
115 |
+
// Skip it
|
116 |
+
if( $this->isDirectoryExcluded( WP_CONTENT_DIR ) ) {
|
|
|
117 |
$this->log( "Skip " . \WPStaging\WPStaging::getWPpath() . 'wp-content' . DIRECTORY_SEPARATOR );
|
118 |
+
return true;
|
119 |
+
}
|
120 |
+
// open file handle
|
121 |
+
$files = $this->open( $this->filename, 'a' );
|
122 |
+
|
123 |
+
$excludeWpContent = array(
|
124 |
+
'cache',
|
125 |
+
'wps-hide-login',
|
126 |
'node_modules'
|
127 |
+
);
|
128 |
|
129 |
+
try {
|
130 |
|
131 |
+
// Iterate over content directory
|
132 |
+
$iterator = new \WPStaging\Iterators\RecursiveDirectoryIterator( WP_CONTENT_DIR );
|
133 |
|
134 |
+
// Exclude new line file names Do not use this. Leads to error 500 on some systems
|
135 |
+
// $iterator = new \WPStaging\Iterators\RecursiveFilterNewLine( $iterator );
|
136 |
|
137 |
+
// Exclude uploads, plugins or themes
|
138 |
+
$iterator = new \WPStaging\Iterators\RecursiveFilterExclude( $iterator, apply_filters( 'wpstg_clone_excl_folders', $excludeWpContent ) );
|
139 |
+
// Recursively iterate over content directory
|
140 |
+
$iterator = new \RecursiveIteratorIterator( $iterator, \RecursiveIteratorIterator::LEAVES_ONLY, \RecursiveIteratorIterator::CATCH_GET_CHILD );
|
141 |
|
142 |
+
$this->log( "Scanning wp-content folder " . WP_CONTENT_DIR );
|
143 |
|
144 |
+
// Write path line
|
145 |
+
foreach ( $iterator as $item ) {
|
146 |
+
if( $item->isFile() ) {
|
147 |
+
$wpContentDir = str_replace(ABSPATH, '', WP_CONTENT_DIR);
|
148 |
+
if( $this->write( $files, $wpContentDir . '/' . $iterator->getSubPathName() . PHP_EOL ) ) {
|
149 |
+
$this->options->totalFiles++;
|
150 |
|
151 |
+
// Too much cpu time
|
152 |
+
//$this->options->totalFileSize += $iterator->getSize();
|
153 |
+
}
|
154 |
+
}
|
155 |
}
|
156 |
+
} catch ( \Exception $e ) {
|
157 |
+
$this->returnException( 'Error: ' . $e->getMessage() );
|
158 |
+
//throw new \Exception( 'Error: ' . $e->getMessage() );
|
159 |
+
}
|
160 |
+
|
161 |
+
// close the file handler
|
162 |
+
$this->close( $files );
|
163 |
+
return true;
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Step 2
|
168 |
+
* @return boolean
|
169 |
+
* @throws \Exception
|
170 |
+
*/
|
171 |
+
private function getWpIncludesFiles() {
|
172 |
+
|
173 |
+
// Skip it
|
174 |
+
if( $this->isDirectoryExcluded( \WPStaging\WPStaging::getWPpath() . 'wp-includes' . DIRECTORY_SEPARATOR ) ) {
|
|
|
|
|
|
|
175 |
$this->log( "Skip " . \WPStaging\WPStaging::getWPpath() . 'wp-includes' . DIRECTORY_SEPARATOR );
|
176 |
+
return true;
|
177 |
+
}
|
178 |
|
179 |
+
// open file handle and attach data to end of file
|
180 |
+
$files = $this->open( $this->filename, 'a' );
|
181 |
|
182 |
+
try {
|
183 |
|
184 |
+
// Iterate over wp-admin directory
|
185 |
+
$iterator = new \WPStaging\Iterators\RecursiveDirectoryIterator( \WPStaging\WPStaging::getWPpath() . 'wp-includes' . DIRECTORY_SEPARATOR );
|
186 |
|
187 |
+
// Exclude new line file names Do not use this. Leads to error 500 on some systems
|
188 |
+
// $iterator = new \WPStaging\Iterators\RecursiveFilterNewLine( $iterator );
|
189 |
|
190 |
+
// Recursively iterate over wp-includes directory
|
191 |
+
$iterator = new \RecursiveIteratorIterator( $iterator, \RecursiveIteratorIterator::LEAVES_ONLY, \RecursiveIteratorIterator::CATCH_GET_CHILD );
|
192 |
|
193 |
+
$this->log( "Scanning /wp-includes for its sub-directories and files" );
|
194 |
|
195 |
+
// Write files
|
196 |
+
foreach ( $iterator as $item ) {
|
197 |
+
if( $item->isFile() ) {
|
198 |
+
if( $this->write( $files, 'wp-includes' . DIRECTORY_SEPARATOR . $iterator->getSubPathName() . PHP_EOL ) ) {
|
199 |
+
$this->options->totalFiles++;
|
200 |
|
201 |
+
// Too much cpu time
|
202 |
+
//$this->options->totalFileSize += $iterator->getSize();
|
203 |
+
}
|
204 |
+
}
|
205 |
}
|
206 |
+
} catch ( \Exception $e ) {
|
207 |
+
//$this->returnException('Out of disk space.');
|
208 |
+
throw new \Exception( 'Error: ' . $e->getMessage() );
|
209 |
+
} catch ( \Exception $e ) {
|
210 |
+
// Skip bad file permissions
|
211 |
+
}
|
212 |
+
|
213 |
+
// close the file handler
|
214 |
+
$this->close( $files );
|
215 |
+
return true;
|
216 |
+
}
|
217 |
+
|
218 |
+
/**
|
219 |
+
* Step 3
|
220 |
+
* @return boolean
|
221 |
+
* @throws \Exception
|
222 |
+
*/
|
223 |
+
private function getWpAdminFiles() {
|
224 |
+
|
225 |
+
// Skip it
|
226 |
+
if( $this->isDirectoryExcluded( \WPStaging\WPStaging::getWPpath() . 'wp-admin' . DIRECTORY_SEPARATOR ) ) {
|
|
|
227 |
$this->log( "Skip " . \WPStaging\WPStaging::getWPpath() . 'wp-admin' . DIRECTORY_SEPARATOR );
|
228 |
+
return true;
|
229 |
+
}
|
230 |
|
231 |
+
// open file handle and attach data to end of file
|
232 |
+
$files = $this->open( $this->filename, 'a' );
|
233 |
|
234 |
+
try {
|
235 |
|
236 |
+
// Iterate over wp-admin directory
|
237 |
+
$iterator = new \WPStaging\Iterators\RecursiveDirectoryIterator( \WPStaging\WPStaging::getWPpath() . 'wp-admin' . DIRECTORY_SEPARATOR );
|
238 |
|
239 |
+
// Exclude new line file names Do not use this. Leads to error 500 on some systems
|
240 |
+
// $iterator = new \WPStaging\Iterators\RecursiveFilterNewLine( $iterator );
|
241 |
|
242 |
+
// Recursively iterate over content directory
|
243 |
+
$iterator = new \RecursiveIteratorIterator( $iterator, \RecursiveIteratorIterator::LEAVES_ONLY, \RecursiveIteratorIterator::CATCH_GET_CHILD );
|
244 |
|
245 |
+
$this->log( "Scanning /wp-admin for its sub-directories and files" );
|
246 |
|
247 |
+
// Write path line
|
248 |
+
foreach ( $iterator as $item ) {
|
249 |
+
if( $item->isFile() ) {
|
250 |
+
if( $this->write( $files, 'wp-admin' . DIRECTORY_SEPARATOR . $iterator->getSubPathName() . PHP_EOL ) ) {
|
251 |
+
$this->options->totalFiles++;
|
252 |
+
// Too much cpu time
|
253 |
+
//$this->options->totalFileSize += $iterator->getSize();
|
254 |
+
}
|
255 |
+
}
|
256 |
}
|
257 |
+
} catch ( \Exception $e ) {
|
258 |
+
$this->returnException( 'Error: ' . $e->getMessage() );
|
259 |
+
} catch ( \Exception $e ) {
|
260 |
+
// Skip bad file permissions
|
261 |
+
}
|
262 |
+
|
263 |
+
// close the file handler
|
264 |
+
$this->close( $files );
|
265 |
+
return true;
|
266 |
+
}
|
267 |
+
|
268 |
+
/**
|
269 |
+
* Step 4 - x
|
270 |
+
* Get extra folders of the wp root level
|
271 |
+
* Does not collect wp-includes, wp-admin and wp-content folder
|
272 |
+
*/
|
273 |
+
private function getExtraFiles( $folder ) {
|
|
|
|
|
274 |
|
275 |
if( !is_dir( $folder ) ) {
|
276 |
return true;
|
277 |
}
|
278 |
|
279 |
+
// open file handle and attach data to end of file
|
280 |
+
$files = $this->open( $this->filename, 'a' );
|
281 |
+
|
282 |
+
try {
|
283 |
+
|
284 |
+
// Iterate over extra directory
|
285 |
+
$iterator = new \WPStaging\Iterators\RecursiveDirectoryIterator( $folder );
|
286 |
+
|
287 |
+
// Exclude new line file names Do not use this. Leads to error 500 on some systems
|
288 |
+
// $iterator = new \WPStaging\Iterators\RecursiveFilterNewLine( $iterator );
|
289 |
+
|
290 |
+
$exclude = array();
|
291 |
+
|
292 |
+
$iterator = new \WPStaging\Iterators\RecursiveFilterExclude( $iterator, $exclude );
|
293 |
+
// Recursively iterate over content directory
|
294 |
+
$iterator = new \RecursiveIteratorIterator( $iterator, \RecursiveIteratorIterator::LEAVES_ONLY, \RecursiveIteratorIterator::CATCH_GET_CHILD );
|
295 |
+
|
296 |
+
$strings = new Strings();
|
297 |
+
$this->log( "Scanning {$strings->getLastElemAfterString( '/', $folder )} for its sub-directories and files" );
|
298 |
+
|
299 |
+
// Write path line
|
300 |
+
foreach ( $iterator as $item ) {
|
301 |
+
if( $item->isFile() ) {
|
302 |
+
//if( $this->write( $files, $strings->getLastElemAfterString( '/', $folder ) . DIRECTORY_SEPARATOR . $iterator->getSubPathName() . PHP_EOL ) ) {
|
303 |
+
if( $this->write( $files, str_replace( \WPStaging\WPStaging::getWPpath(), '', $folder ) . DIRECTORY_SEPARATOR . $iterator->getSubPathName() . PHP_EOL ) ) {
|
304 |
+
$this->options->totalFiles++;
|
305 |
+
// Too much cpu time
|
306 |
+
//$this->options->totalFileSize += $iterator->getSize();
|
307 |
+
}
|
308 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
309 |
}
|
310 |
+
} catch ( \Exception $e ) {
|
311 |
+
$this->returnException( 'Error: ' . $e->getMessage() );
|
312 |
+
} catch ( \Exception $e ) {
|
313 |
+
// Skip bad file permissions
|
314 |
+
}
|
315 |
+
|
316 |
+
// close the file handler
|
317 |
+
$this->close( $files );
|
318 |
+
return true;
|
319 |
+
}
|
320 |
+
|
321 |
+
/**
|
322 |
+
* Closes a file handle
|
323 |
+
*
|
324 |
+
* @param resource $handle File handle to close
|
325 |
+
* @return boolean
|
326 |
+
*/
|
327 |
+
public function close( $handle ) {
|
328 |
+
return @fclose( $handle );
|
329 |
+
}
|
330 |
+
|
331 |
+
/**
|
332 |
+
* Opens a file in specified mode
|
333 |
+
*
|
334 |
+
* @param string $file Path to the file to open
|
335 |
+
* @param string $mode Mode in which to open the file
|
336 |
+
* @return resource
|
337 |
+
* @throws Exception
|
338 |
+
*/
|
339 |
+
public function open( $file, $mode ) {
|
340 |
+
|
341 |
+
$file_handle = @fopen( $file, $mode );
|
342 |
+
if( false === $file_handle ) {
|
343 |
+
$this->returnException( sprintf( __( 'Unable to open %s with mode %s', 'wp-staging' ), $file, $mode ) );
|
344 |
+
//throw new Exception(sprintf(__('Unable to open %s with mode %s', 'wp-staging'), $file, $mode));
|
345 |
+
}
|
346 |
+
|
347 |
+
return $file_handle;
|
348 |
+
}
|
349 |
+
|
350 |
+
/**
|
351 |
+
* Write contents to a file
|
352 |
+
*
|
353 |
+
* @param resource $handle File handle to write to
|
354 |
+
* @param string $content Contents to write to the file
|
355 |
+
* @return integer
|
356 |
+
* @throws Exception
|
357 |
+
* @throws Exception
|
358 |
+
*/
|
359 |
+
public function write( $handle, $content ) {
|
360 |
+
$write_result = @fwrite( $handle, $content );
|
361 |
+
if( false === $write_result ) {
|
362 |
+
if( ( $meta = \stream_get_meta_data( $handle ) ) ) {
|
363 |
+
//$this->returnException(sprintf(__('Unable to write to: %s', 'wp-staging'), $meta['uri']));
|
364 |
+
throw new \Exception( sprintf( __( 'Unable to write to: %s', 'wp-staging' ), $meta['uri'] ) );
|
365 |
+
}
|
366 |
+
} elseif( strlen( $content ) !== $write_result ) {
|
367 |
+
//$this->returnException(__('Out of disk space.', 'wp-staging'));
|
368 |
+
throw new \Exception( __( 'Out of disk space.', 'wp-staging' ) );
|
369 |
+
}
|
370 |
+
|
371 |
+
return $write_result;
|
372 |
+
}
|
373 |
+
|
374 |
+
/**
|
375 |
+
* Execute the Current Step
|
376 |
+
* Returns false when over threshold limits are hit or when the job is done, true otherwise
|
377 |
+
* @return bool
|
378 |
+
*/
|
379 |
+
protected function execute() {
|
380 |
+
|
381 |
+
// No job left to execute
|
382 |
+
if( $this->isFinished() ) {
|
383 |
+
$this->prepareResponse( true, false );
|
384 |
+
return false;
|
385 |
+
}
|
386 |
+
|
387 |
+
|
388 |
+
if( $this->options->currentStep == 0 ) {
|
389 |
+
$this->getWpRootFiles();
|
390 |
+
$this->prepareResponse( false, true );
|
391 |
+
return false;
|
392 |
+
}
|
393 |
+
|
394 |
+
if( $this->options->currentStep == 1 ) {
|
395 |
+
$this->getWpContentFiles();
|
396 |
+
$this->prepareResponse( false, true );
|
397 |
+
return false;
|
398 |
+
}
|
399 |
+
|
400 |
+
if( $this->options->currentStep == 2 ) {
|
401 |
+
$this->getWpIncludesFiles();
|
402 |
+
$this->prepareResponse( false, true );
|
403 |
+
return false;
|
404 |
+
}
|
405 |
+
|
406 |
+
if( $this->options->currentStep == 3 ) {
|
407 |
+
$this->getWpAdminFiles();
|
408 |
+
$this->prepareResponse( false, true );
|
409 |
+
return false;
|
410 |
+
}
|
411 |
+
|
412 |
+
if( isset( $this->options->extraDirectories[$this->options->currentStep - $this->total] ) ) {
|
413 |
+
$this->getExtraFiles( $this->options->extraDirectories[$this->options->currentStep - $this->total] );
|
414 |
+
$this->prepareResponse( false, true );
|
415 |
+
return false;
|
416 |
+
}
|
417 |
+
|
418 |
+
|
419 |
+
// Prepare response
|
420 |
+
$this->prepareResponse( false, true );
|
421 |
+
// Not finished
|
422 |
+
return true;
|
423 |
+
}
|
424 |
+
|
425 |
+
/**
|
426 |
+
* Checks Whether There is Any Job to Execute or Not
|
427 |
+
* @return bool
|
428 |
+
*/
|
429 |
+
protected function isFinished() {
|
430 |
+
if( $this->options->currentStep >= $this->options->totalSteps ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
431 |
return true;
|
432 |
+
}
|
433 |
+
}
|
434 |
+
|
435 |
+
/**
|
436 |
+
* Save files
|
437 |
+
* @return bool
|
438 |
+
*/
|
439 |
+
protected function saveProgress() {
|
440 |
+
return $this->saveOptions();
|
441 |
+
}
|
442 |
+
|
443 |
+
/**
|
444 |
+
* Get files
|
445 |
+
* @return void
|
446 |
+
*/
|
447 |
+
protected function getFiles() {
|
448 |
+
$fileName = $this->cache->getCacheDir() . "files_to_copy." . $this->cache->getCacheExtension();
|
449 |
+
|
450 |
+
if( false === ($this->files = @file_get_contents( $fileName )) ) {
|
451 |
+
$this->files = array();
|
452 |
+
return;
|
453 |
+
}
|
454 |
+
|
455 |
+
$this->files = explode( PHP_EOL, $this->files );
|
456 |
+
}
|
457 |
+
|
458 |
+
/**
|
459 |
+
* Replace forward slash with current directory separator
|
460 |
+
*
|
461 |
+
* @param string $path Path
|
462 |
+
*
|
463 |
+
* @return string
|
464 |
+
*/
|
465 |
+
private function sanitizeDirectorySeparator( $path ) {
|
466 |
+
$string = str_replace( "/", "\\", $path );
|
467 |
+
return str_replace( '\\\\', '\\', $string );
|
468 |
+
}
|
469 |
+
|
470 |
+
/**
|
471 |
+
* Check if directory is excluded
|
472 |
+
* @param string $directory
|
473 |
+
* @return bool
|
474 |
+
*/
|
475 |
+
protected function isDirectoryExcluded( $directory ) {
|
476 |
+
$directory = $this->sanitizeDirectorySeparator( $directory );
|
477 |
+
foreach ( $this->options->excludedDirectories as $excludedDirectory ) {
|
478 |
+
$excludedDirectory = $this->sanitizeDirectorySeparator( $excludedDirectory );
|
479 |
+
if( strpos( trailingslashit( $directory ), trailingslashit( $excludedDirectory ) ) === 0 ) {
|
480 |
+
return true;
|
481 |
+
}
|
482 |
+
}
|
483 |
|
484 |
+
return false;
|
485 |
+
}
|
486 |
|
487 |
}
|
apps/Backend/Modules/Jobs/Files.php
CHANGED
@@ -238,6 +238,34 @@ class Files extends JobExecutable {
|
|
238 |
return true;
|
239 |
}
|
240 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
241 |
/**
|
242 |
* Set directory permissions
|
243 |
* @param type $file
|
@@ -247,7 +275,7 @@ class Files extends JobExecutable {
|
|
247 |
$dir = dirname( $file );
|
248 |
if( is_dir( $dir ) ) {
|
249 |
@chmod( $dir, wpstg_get_permissions_for_directory() );
|
250 |
-
|
251 |
return false;
|
252 |
}
|
253 |
|
@@ -259,6 +287,9 @@ class Files extends JobExecutable {
|
|
259 |
*/
|
260 |
private function getDestination( $file ) {
|
261 |
|
|
|
|
|
|
|
262 |
$relativePath = str_replace( \WPStaging\WPStaging::getWPpath(), null, $file );
|
263 |
$destinationPath = $this->destination . $relativePath;
|
264 |
$destinationDirectory = dirname( $destinationPath );
|
238 |
return true;
|
239 |
}
|
240 |
|
241 |
+
/**
|
242 |
+
* Get wp-content and wp-content/uploads destination dir
|
243 |
+
* Necessary if these folders were customized and changed from the default ones.
|
244 |
+
*
|
245 |
+
* @return string
|
246 |
+
*/
|
247 |
+
protected function getWpContentPath( $file ) {
|
248 |
+
// Get absolute custom upload dir
|
249 |
+
$uploads = wp_upload_dir();
|
250 |
+
|
251 |
+
// Get absolute upload dir from ABSPATH
|
252 |
+
$uploadsAbsPath = trailingslashit($uploads['basedir']);
|
253 |
+
|
254 |
+
// Get absolute custom wp-content dir
|
255 |
+
$wpContentDir = trailingslashit(WP_CONTENT_DIR);
|
256 |
+
|
257 |
+
// Check if there is a custom upload directory and do a search $ replace
|
258 |
+
$file = str_replace( $uploadsAbsPath, ABSPATH . 'wp-content/uploads/', $file, $count );
|
259 |
+
|
260 |
+
// If there is no custom upload directory do a search & replace of the custom wp-content directory
|
261 |
+
if( empty( $count ) || $count === 0 ) {
|
262 |
+
$file = str_replace( $wpContentDir, ABSPATH . 'wp-content/', $file );
|
263 |
+
}
|
264 |
+
|
265 |
+
|
266 |
+
return $file;
|
267 |
+
}
|
268 |
+
|
269 |
/**
|
270 |
* Set directory permissions
|
271 |
* @param type $file
|
275 |
$dir = dirname( $file );
|
276 |
if( is_dir( $dir ) ) {
|
277 |
@chmod( $dir, wpstg_get_permissions_for_directory() );
|
278 |
+
}
|
279 |
return false;
|
280 |
}
|
281 |
|
287 |
*/
|
288 |
private function getDestination( $file ) {
|
289 |
|
290 |
+
// Get custom wp-content and uploads folder
|
291 |
+
$file = $this->getWpContentPath( $file );
|
292 |
+
|
293 |
$relativePath = str_replace( \WPStaging\WPStaging::getWPpath(), null, $file );
|
294 |
$destinationPath = $this->destination . $relativePath;
|
295 |
$destinationDirectory = dirname( $destinationPath );
|
apps/Backend/Modules/Jobs/SearchReplace.php
CHANGED
@@ -28,7 +28,6 @@ class SearchReplace extends JobExecutable {
|
|
28 |
*/
|
29 |
public $db;
|
30 |
|
31 |
-
|
32 |
/**
|
33 |
*
|
34 |
* @var string
|
@@ -174,7 +173,7 @@ class SearchReplace extends JobExecutable {
|
|
174 |
$host = $this->options->homeHostname;
|
175 |
|
176 |
if( $this->isSubDir() ) {
|
177 |
-
$host = trailingslashit($this->options->homeHostname) . $this->getSubDir();
|
178 |
}
|
179 |
return $this->strings->getUrlWithoutScheme( $host );
|
180 |
}
|
@@ -299,17 +298,19 @@ class SearchReplace extends JobExecutable {
|
|
299 |
$pages = $this->get_pages_in_table( $table );
|
300 |
|
301 |
|
302 |
-
|
|
|
303 |
'\/\/' . str_replace( '/', '\/', $this->sourceHostname ), // Escaped \/ used by revslider and several visual editors
|
304 |
'//' . $this->sourceHostname,
|
305 |
-
|
306 |
-
|
307 |
|
308 |
-
|
|
|
309 |
'\/\/' . str_replace( '/', '\/', $this->destinationHostname ),
|
310 |
'//' . $this->destinationHostname,
|
311 |
-
rtrim
|
312 |
-
|
313 |
|
314 |
|
315 |
$args['replace_guids'] = 'off';
|
@@ -387,7 +388,7 @@ class SearchReplace extends JobExecutable {
|
|
387 |
}
|
388 |
|
389 |
// Skip mail addresses
|
390 |
-
if( 'off' === $args['replace_mails'] && false !== strpos( $dataRow, '@'
|
391 |
continue;
|
392 |
}
|
393 |
|
@@ -759,4 +760,4 @@ class SearchReplace extends JobExecutable {
|
|
759 |
return false;
|
760 |
}
|
761 |
|
762 |
-
|
28 |
*/
|
29 |
public $db;
|
30 |
|
|
|
31 |
/**
|
32 |
*
|
33 |
* @var string
|
173 |
$host = $this->options->homeHostname;
|
174 |
|
175 |
if( $this->isSubDir() ) {
|
176 |
+
$host = trailingslashit( $this->options->homeHostname ) . $this->getSubDir();
|
177 |
}
|
178 |
return $this->strings->getUrlWithoutScheme( $host );
|
179 |
}
|
298 |
$pages = $this->get_pages_in_table( $table );
|
299 |
|
300 |
|
301 |
+
$args['search_for'] = array(
|
302 |
+
'%2F%2F' . str_replace( '/', '%2F', $this->sourceHostname ), // HTML entitity for WP Backery Page Builder Plugin
|
303 |
'\/\/' . str_replace( '/', '\/', $this->sourceHostname ), // Escaped \/ used by revslider and several visual editors
|
304 |
'//' . $this->sourceHostname,
|
305 |
+
rtrim( ABSPATH, '/' ),
|
306 |
+
);
|
307 |
|
308 |
+
$args['replace_with'] = array(
|
309 |
+
'%2F%2F' . str_replace( '/', '%2F', $this->destinationHostname ),
|
310 |
'\/\/' . str_replace( '/', '\/', $this->destinationHostname ),
|
311 |
'//' . $this->destinationHostname,
|
312 |
+
rtrim( $this->options->destinationDir, '/' ),
|
313 |
+
);
|
314 |
|
315 |
|
316 |
$args['replace_guids'] = 'off';
|
388 |
}
|
389 |
|
390 |
// Skip mail addresses
|
391 |
+
if( 'off' === $args['replace_mails'] && false !== strpos( $dataRow, '@' . $this->options->homeHostname ) ) {
|
392 |
continue;
|
393 |
}
|
394 |
|
760 |
return false;
|
761 |
}
|
762 |
|
763 |
+
}
|
apps/Backend/Modules/Jobs/Updating.php
CHANGED
@@ -61,7 +61,9 @@ class Updating extends Job {
|
|
61 |
'.gitignore',
|
62 |
'.log',
|
63 |
'db.php',
|
64 |
-
'object-cache.php'
|
|
|
|
|
65 |
);
|
66 |
|
67 |
$this->options->excludedFilesFullPath = array(
|
61 |
'.gitignore',
|
62 |
'.log',
|
63 |
'db.php',
|
64 |
+
'object-cache.php',
|
65 |
+
'web.config' // Important: Windows IIS configuartion file. Must not be in the staging site!
|
66 |
+
|
67 |
);
|
68 |
|
69 |
$this->options->excludedFilesFullPath = array(
|
apps/Backend/Notices/Notices.php
CHANGED
@@ -31,7 +31,7 @@ class Notices {
|
|
31 |
|
32 |
public function __construct( $path, $url ) {
|
33 |
$this->path = $path;
|
34 |
-
$this->url
|
35 |
}
|
36 |
|
37 |
/**
|
@@ -64,87 +64,106 @@ class Notices {
|
|
64 |
return false;
|
65 |
}
|
66 |
|
67 |
-
$
|
|
|
68 |
$now = new \DateTime( "now" );
|
69 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
// Get days difference
|
71 |
$difference = $now->diff( $installDate )->days;
|
72 |
|
73 |
-
|
|
|
|
|
|
|
74 |
|
75 |
return false;
|
76 |
}
|
77 |
|
78 |
public function messages() {
|
79 |
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
* Show a message when pro or free plugin becomes deactivated
|
149 |
*
|
150 |
* @return void
|
@@ -164,4 +183,4 @@ class Notices {
|
|
164 |
}
|
165 |
}
|
166 |
|
167 |
-
}
|
31 |
|
32 |
public function __construct( $path, $url ) {
|
33 |
$this->path = $path;
|
34 |
+
$this->url = $url;
|
35 |
}
|
36 |
|
37 |
/**
|
64 |
return false;
|
65 |
}
|
66 |
|
67 |
+
$dbOption = get_option( $option );
|
68 |
+
|
69 |
$now = new \DateTime( "now" );
|
70 |
|
71 |
+
|
72 |
+
// Check if user clicked on "rate later" button
|
73 |
+
if( "no" !== $dbOption && wpstg_validate_date( $dbOption ) ) {
|
74 |
+
// Get days difference
|
75 |
+
$hideDate = new \DateTime( $dbOption );
|
76 |
+
$difference = $now->diff( $hideDate )->days;
|
77 |
+
|
78 |
+
if( $days <= $difference )
|
79 |
+
return true;
|
80 |
+
}
|
81 |
+
|
82 |
+
|
83 |
+
// Show X days after installation
|
84 |
+
$installDate = new \DateTime( get_option( "wpstg_installDate" ) );
|
85 |
+
|
86 |
// Get days difference
|
87 |
$difference = $now->diff( $installDate )->days;
|
88 |
|
89 |
+
if( $days <= $difference && "no" !== $dbOption ) {
|
90 |
+
return true;
|
91 |
+
}
|
92 |
+
|
93 |
|
94 |
return false;
|
95 |
}
|
96 |
|
97 |
public function messages() {
|
98 |
|
99 |
+
$viewsNoticesPath = "{$this->path}views/_includes/messages/";
|
100 |
+
|
101 |
+
// Show notice when free and pro version have been activated at the same time
|
102 |
+
$this->plugin_deactivated_notice();
|
103 |
+
|
104 |
+
|
105 |
+
// Show rating review message on all admin pages
|
106 |
+
if( $this->canShow( "wpstg_rating", 7 ) ) {
|
107 |
+
require_once "{$viewsNoticesPath}rating.php";
|
108 |
+
}
|
109 |
+
|
110 |
+
|
111 |
+
// Display messages below to admins only, only on admin panel
|
112 |
+
if( !current_user_can( "update_plugins" ) || !$this->isAdminPage() ) {
|
113 |
+
return;
|
114 |
+
}
|
115 |
+
|
116 |
+
|
117 |
+
$varsDirectory = \WPStaging\WPStaging::getContentDir();
|
118 |
+
if( !wp_is_writable( $varsDirectory ) ) {
|
119 |
+
require_once "{$viewsNoticesPath}/uploads-cache-directory-permission-problem.php";
|
120 |
+
}
|
121 |
+
// Staging directory is not writable
|
122 |
+
if( !wp_is_writable( ABSPATH ) ) {
|
123 |
+
require_once "{$viewsNoticesPath}/staging-directory-permission-problem.php";
|
124 |
+
}
|
125 |
+
|
126 |
+
// Version Control
|
127 |
+
if( version_compare( WPStaging::WP_COMPATIBLE, get_bloginfo( "version" ), "<" ) ) {
|
128 |
+
require_once "{$viewsNoticesPath}wp-version-compatible-message.php";
|
129 |
+
}
|
130 |
+
|
131 |
+
// Beta
|
132 |
+
if( false === get_option( "wpstg_beta" ) || "no" !== get_option( "wpstg_beta" ) ) {
|
133 |
+
require_once "{$viewsNoticesPath}beta.php";
|
134 |
+
}
|
135 |
+
|
136 |
+
// WP Staging Pro and Free can not be activated both
|
137 |
+
if( false !== ( $deactivatedNoticeID = get_transient( "wp_staging_deactivated_notice_id" ) ) ) {
|
138 |
+
require_once "{$viewsNoticesPath}transient.php";
|
139 |
+
delete_transient( "wp_staging_deactivated_notice_id" );
|
140 |
+
}
|
141 |
+
// Rating
|
142 |
+
if( $this->canShow( "wpstg_rating", 7 ) ) {
|
143 |
+
require_once "{$viewsNoticesPath}rating.php";
|
144 |
+
}
|
145 |
+
|
146 |
+
// Different scheme in home and siteurl
|
147 |
+
if( $this->isDifferentScheme() ) {
|
148 |
+
require_once "{$viewsNoticesPath}wrong-scheme.php";
|
149 |
+
}
|
150 |
+
}
|
151 |
+
|
152 |
+
/**
|
153 |
+
* Check if the url scheme of siteurl and home is identical
|
154 |
+
* @return boolean
|
155 |
+
*/
|
156 |
+
private function isDifferentScheme() {
|
157 |
+
$siteurlScheme = parse_url( get_option( 'siteurl' ), PHP_URL_SCHEME );
|
158 |
+
$homeScheme = parse_url( get_option( 'home' ), PHP_URL_SCHEME );
|
159 |
+
|
160 |
+
if( $siteurlScheme === $homeScheme ) {
|
161 |
+
return false;
|
162 |
+
}
|
163 |
+
return true;
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
* Show a message when pro or free plugin becomes deactivated
|
168 |
*
|
169 |
* @return void
|
183 |
}
|
184 |
}
|
185 |
|
186 |
+
}
|
apps/Backend/public/js/wpstg-admin-rating.js
CHANGED
@@ -29,4 +29,39 @@ jQuery(document).ready(function ($) {
|
|
29 |
}
|
30 |
});
|
31 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
});
|
29 |
}
|
30 |
});
|
31 |
});
|
32 |
+
|
33 |
+
$(".wpstg_rate_later").click(function (e) {
|
34 |
+
e.preventDefault();
|
35 |
+
|
36 |
+
$.ajax({
|
37 |
+
url: ajaxurl,
|
38 |
+
type: "POST",
|
39 |
+
data: {action: "wpstg_hide_later"},
|
40 |
+
error: function (xhr, textStatus, errorThrown) {
|
41 |
+
console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);
|
42 |
+
console.log(textStatus);
|
43 |
+
|
44 |
+
|
45 |
+
alert(
|
46 |
+
"Unknown error"
|
47 |
+
);
|
48 |
+
},
|
49 |
+
success: function (data) {
|
50 |
+
$(".wpstg_fivestar").slideUp("fast");
|
51 |
+
return true;
|
52 |
+
},
|
53 |
+
statusCode: {
|
54 |
+
404: function () {
|
55 |
+
alert("Something went wrong; can't find ajax request URL!");
|
56 |
+
},
|
57 |
+
500: function () {
|
58 |
+
alert("Something went wrong; internal server error while processing the request!");
|
59 |
+
}
|
60 |
+
}
|
61 |
+
});
|
62 |
+
});
|
63 |
+
|
64 |
+
|
65 |
+
|
66 |
+
|
67 |
});
|
apps/Backend/views/_includes/messages/rating.php
CHANGED
@@ -27,6 +27,11 @@
|
|
27 |
<?php _e('No, not good enough','wp-staging')?>
|
28 |
</a>
|
29 |
</li>
|
|
|
|
|
|
|
|
|
|
|
30 |
</ul>
|
31 |
</div>
|
32 |
<script type="text/javascript" src="<?php echo $this->url . "js/wpstg-admin-rating.js"?>"></script>
|
27 |
<?php _e('No, not good enough','wp-staging')?>
|
28 |
</a>
|
29 |
</li>
|
30 |
+
<li>
|
31 |
+
<a href="javascript:void(0);" class="wpstg_rate_later" title="Ask me again in a week" style="font-weight:normal;color:white;">
|
32 |
+
<?php _e('I want to rate later - Ask me again in a week','wp-staging')?>
|
33 |
+
</a>
|
34 |
+
</li>
|
35 |
</ul>
|
36 |
</div>
|
37 |
<script type="text/javascript" src="<?php echo $this->url . "js/wpstg-admin-rating.js"?>"></script>
|
apps/Core/Iterators/RecursiveFilterExclude.php
CHANGED
@@ -4,20 +4,35 @@ namespace WPStaging\Iterators;
|
|
4 |
|
5 |
class RecursiveFilterExclude extends \RecursiveFilterIterator {
|
6 |
|
7 |
-
|
8 |
|
9 |
-
|
10 |
-
|
11 |
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
|
16 |
-
|
17 |
-
|
18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
|
20 |
-
public function getChildren() {
|
21 |
-
return new self( $this->getInnerIterator()->getChildren(), $this->exclude );
|
22 |
-
}
|
23 |
}
|
4 |
|
5 |
class RecursiveFilterExclude extends \RecursiveFilterIterator {
|
6 |
|
7 |
+
protected $exclude = array();
|
8 |
|
9 |
+
public function __construct( \RecursiveIterator $iterator, $exclude = array() ) {
|
10 |
+
parent::__construct( $iterator );
|
11 |
|
12 |
+
// Set exclude filter
|
13 |
+
$this->exclude = $exclude;
|
14 |
+
}
|
15 |
|
16 |
+
public function accept() {
|
17 |
+
|
18 |
+
// Path contains new line character on linux
|
19 |
+
if(strpos( $this->getInnerIterator()->getSubPathname(), "\n" ) !== false)
|
20 |
+
return false;
|
21 |
+
|
22 |
+
// Path contains new line character on Windows
|
23 |
+
if(strpos( $this->getInnerIterator()->getSubPathname(), "\r" ) !== false)
|
24 |
+
return false;
|
25 |
+
|
26 |
+
// Part of the path is excluded
|
27 |
+
if (in_array( $this->getInnerIterator()->getSubPathname(), $this->exclude ))
|
28 |
+
return false;
|
29 |
+
|
30 |
+
return true;
|
31 |
+
|
32 |
+
}
|
33 |
+
|
34 |
+
public function getChildren() {
|
35 |
+
return new self( $this->getInnerIterator()->getChildren(), $this->exclude );
|
36 |
+
}
|
37 |
|
|
|
|
|
|
|
38 |
}
|
apps/Core/Iterators/RecursiveFilterNewLine.php
DELETED
@@ -1,21 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace WPStaging\Iterators;
|
4 |
-
|
5 |
-
// No Direct Access
|
6 |
-
if (!defined("WPINC")) {
|
7 |
-
die;
|
8 |
-
}
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Filter files which contain new line character in name
|
12 |
-
*/
|
13 |
-
|
14 |
-
class RecursiveFilterNewLine extends \RecursiveFilterIterator {
|
15 |
-
|
16 |
-
public function accept() {
|
17 |
-
return strpos( $this->getInnerIterator()->getSubPathname(), "\n" ) === false &&
|
18 |
-
strpos( $this->getInnerIterator()->getSubPathname(), "\r" ) === false;
|
19 |
-
}
|
20 |
-
}
|
21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
apps/Core/Utils/functions.php
CHANGED
@@ -73,3 +73,63 @@ function wpstg_escape_windows_directory_separator( $path ) {
|
|
73 |
function wpstg_replace_windows_directory_separator( $path ) {
|
74 |
return preg_replace( '/[\\\\]+/', '/', $path );
|
75 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
function wpstg_replace_windows_directory_separator( $path ) {
|
74 |
return preg_replace( '/[\\\\]+/', '/', $path );
|
75 |
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Mimics the mysql_real_escape_string function. Adapted from a post by 'feedr' on php.net.
|
79 |
+
* @link http://php.net/manual/en/function.mysql-real-escape-string.php#101248
|
80 |
+
* @access public
|
81 |
+
* @param string $input The string to escape.
|
82 |
+
* @return string
|
83 |
+
*/
|
84 |
+
function wpstg_mysql_escape_mimic( $input ) {
|
85 |
+
if( is_array( $input ) ) {
|
86 |
+
return array_map( __METHOD__, $input );
|
87 |
+
}
|
88 |
+
if( !empty( $input ) && is_string( $input ) ) {
|
89 |
+
return str_replace( array('\\', "\0", "\n", "\r", "'", '"', "\x1a"), array('\\\\', '\\0', '\\n', '\\r', "\\'", '\\"', '\\Z'), $input );
|
90 |
+
}
|
91 |
+
|
92 |
+
return $input;
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Search & Replace first occurence of string in haystack
|
97 |
+
* @param type $haystack
|
98 |
+
* @param type $needle
|
99 |
+
* @return type
|
100 |
+
*/
|
101 |
+
function wpstg_replace_first_match( $needle, $replace, $haystack ) {
|
102 |
+
$result = $haystack;
|
103 |
+
$pos = strpos( $haystack, $needle );
|
104 |
+
if( $pos !== false ) {
|
105 |
+
$result = substr_replace( $haystack, $replace, $pos, strlen( $needle ) );
|
106 |
+
}
|
107 |
+
return $result;
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Search & Replace last occurence of string in haystack
|
112 |
+
* @param type $haystack
|
113 |
+
* @param type $needle
|
114 |
+
* @return type
|
115 |
+
*/
|
116 |
+
function wpstg_replace_last_match( $needle, $replace, $haystack ) {
|
117 |
+
$result = $haystack;
|
118 |
+
$pos = strrpos( $haystack, $needle );
|
119 |
+
if( $pos !== false ) {
|
120 |
+
$result = substr_replace( $haystack, $replace, $pos, strlen( $needle ) );
|
121 |
+
}
|
122 |
+
return $result;
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Check if string is valid date
|
127 |
+
* @param type $date
|
128 |
+
* @param type $format
|
129 |
+
* @return bool
|
130 |
+
*/
|
131 |
+
function wpstg_validate_date( $date, $format = 'Y-m-d' ) {
|
132 |
+
$d = DateTime::createFromFormat( $format, $date );
|
133 |
+
// The Y ( 4 digits year ) returns TRUE for any integer with any number of digits so changing the comparison from == to === fixes the issue.
|
134 |
+
return $d && $d->format( $format ) === $date;
|
135 |
+
}
|
apps/Core/WPStaging.php
CHANGED
@@ -29,7 +29,7 @@ final class WPStaging {
|
|
29 |
/**
|
30 |
* Plugin version
|
31 |
*/
|
32 |
-
const VERSION = "2.4.
|
33 |
|
34 |
/**
|
35 |
* Plugin name
|
29 |
/**
|
30 |
* Plugin version
|
31 |
*/
|
32 |
+
const VERSION = "2.4.3";
|
33 |
|
34 |
/**
|
35 |
* Plugin name
|
apps/Frontend/loginForm.php
CHANGED
@@ -49,7 +49,14 @@ class loginForm {
|
|
49 |
wp_set_auth_cookie( $user_data->ID, $rememberme );
|
50 |
wp_set_current_user( $user_data->ID, $_POST['wpstg-username'] );
|
51 |
do_action( 'wp_login', $_POST['wpstg-username'], get_userdata( $user_data->ID ) );
|
52 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
} else {
|
54 |
$this->error = 'Username or password wrong!';
|
55 |
}
|
49 |
wp_set_auth_cookie( $user_data->ID, $rememberme );
|
50 |
wp_set_current_user( $user_data->ID, $_POST['wpstg-username'] );
|
51 |
do_action( 'wp_login', $_POST['wpstg-username'], get_userdata( $user_data->ID ) );
|
52 |
+
|
53 |
+
$redirect_to = get_site_url() . '/wp-admin/';
|
54 |
+
|
55 |
+
if( !empty( $_POST['redirect_to'] ) ) {
|
56 |
+
$redirectTo = $_POST['redirect_to'];
|
57 |
+
}
|
58 |
+
|
59 |
+
header( 'Location:' . $redirectTo );
|
60 |
} else {
|
61 |
$this->error = 'Username or password wrong!';
|
62 |
}
|
readme.txt
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
=== WP Staging - DB & File Duplicator & Migration ===
|
2 |
|
3 |
Author URL: https://wordpress.org/plugins/wp-staging
|
4 |
Plugin URL: https://wordpress.org/plugins/wp-staging
|
@@ -8,8 +8,8 @@ License: GPLv2 or later
|
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
Tags: staging, duplication, cloning, clone, migration, sandbox, test site, testing, backup, post, admin, administration, duplicate posts
|
10 |
Requires at least: 3.6+
|
11 |
-
Tested up to:
|
12 |
-
Stable tag: 2.4.
|
13 |
Requires PHP: 5.3
|
14 |
|
15 |
A duplicator plugin! Clone, duplicate and migrate live sites to independent staging and development sites that are available only to administrators.
|
@@ -81,7 +81,7 @@ I totally understand this and i am guilty as well here, but unfortunately this l
|
|
81 |
|
82 |
<strong> I think its time to change this, so i created "WP Staging" for WordPress migration of staging sites</strong>
|
83 |
|
84 |
-
<h3> Can´t
|
85 |
|
86 |
Nope! If your local hardware and software environment is not a 100% exact clone of your production server there is NO guarantee that every aspect
|
87 |
of your local copy is working on your live website exactely as you would expect it.
|
@@ -146,6 +146,16 @@ https://wp-staging.com
|
|
146 |
|
147 |
== Changelog ==
|
148 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
149 |
= 2.4.1 =
|
150 |
* Fix: Error notice if user tries to update staging site located in another database
|
151 |
* Fix: Search & Replace adds staging site subfolder multiple times to replaced string when staging site is updated
|
@@ -168,9 +178,6 @@ https://wp-staging.com
|
|
168 |
* Fix: Selected folders are not excluded under Windows IIS server
|
169 |
* Fix: Windows IIS server compatibilility issues resolved
|
170 |
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
= 2.3.9 =
|
175 |
* New: Support for wp-config.php located in one level up of the root folder for multisites
|
176 |
* New: Allow exclusion of custom options from wp_options from beeing pushed
|
@@ -181,50 +188,12 @@ https://wp-staging.com
|
|
181 |
* Fix: Filesize() failed if file to copy is not a regular file
|
182 |
* Fix: remove ? parameter from staging site
|
183 |
|
184 |
-
= 2.3.8 =
|
185 |
-
* Tweak: Lowering default performance settings for more reliability during cloning
|
186 |
-
* New: Set WP_CACHE to false in wp-config.php after cloning to prevent log in issues to staging site
|
187 |
-
* New: Compatibility mode to skip certain tables from third party plugins from beeing searched & replaced
|
188 |
-
* Fix: Do not clone db.php, object-cache.php and advanced-cache.php
|
189 |
-
* Fix: Show error message if ajax requests fail for any reason
|
190 |
-
|
191 |
-
|
192 |
-
= 2.3.7 =
|
193 |
-
* New: Increase cloning performance
|
194 |
-
* New: Show admin notice if php version and wordpress version do not meet requirements.
|
195 |
-
* New: Show error if there is not enough free diskspace
|
196 |
-
* New: Add resume function in case the cloning process interrupts
|
197 |
-
* New: Add italian translation
|
198 |
-
* New: Better looking admin notices
|
199 |
-
* Fix: Different scheme of siteurl and home leads to non available staging site. Show admin notice to ask user to fix that first before creating a staging site
|
200 |
-
* Fix: WP Staging welcome screen shown when any plugin is activated
|
201 |
-
* Fix: Lower default settings to 10000, cpu load low. File copy limit to 50
|
202 |
-
|
203 |
-
|
204 |
-
= 2.3.6 =
|
205 |
-
* Fix: Add version number to css and js files to prevent caching issues
|
206 |
-
* Fix: Wrong text domain in a few language strings
|
207 |
-
* Fix: Optimizer mu-plugin not installed all the time
|
208 |
-
* Fix: Language files not loaded correctly
|
209 |
-
* Fix: Remove heartbeat check only on wp staging admin pages
|
210 |
-
* Fix: WordPress custom upload path variable upload_path could be wrong after cloning
|
211 |
-
* Fix: Increase maximum memory consumption
|
212 |
-
|
213 |
-
= 2.3.5 =
|
214 |
-
* New: Enable Optimizer as default option
|
215 |
-
* New: Add filter to exclude strings from search & replace, docs: https://wp-staging.com/docs/actions-and-filters/
|
216 |
-
* New: Add filter to change search & replace parameters
|
217 |
-
* New: Add language files and change text domain to slug of the plugin
|
218 |
-
* New: Disable heartbeat api and user login check for wp staging processing
|
219 |
-
* New: Add issue reporting form
|
220 |
-
* New: Check if clone subfolder already exists before creating clone
|
221 |
-
* Fix: Changing file copy limit not working
|
222 |
-
|
223 |
|
224 |
Complete changelog: [https://wp-staging.com/wp-staging-changelog](https://wp-staging.com/wp-staging-changelog)
|
225 |
|
226 |
== Upgrade Notice ==
|
227 |
|
228 |
-
= 2.4.
|
229 |
-
* New:
|
|
|
230 |
|
1 |
+
=== WP Staging - DB & File Duplicator & Migration ===
|
2 |
|
3 |
Author URL: https://wordpress.org/plugins/wp-staging
|
4 |
Plugin URL: https://wordpress.org/plugins/wp-staging
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
Tags: staging, duplication, cloning, clone, migration, sandbox, test site, testing, backup, post, admin, administration, duplicate posts
|
10 |
Requires at least: 3.6+
|
11 |
+
Tested up to: 5.0
|
12 |
+
Stable tag: 2.4.3
|
13 |
Requires PHP: 5.3
|
14 |
|
15 |
A duplicator plugin! Clone, duplicate and migrate live sites to independent staging and development sites that are available only to administrators.
|
81 |
|
82 |
<strong> I think its time to change this, so i created "WP Staging" for WordPress migration of staging sites</strong>
|
83 |
|
84 |
+
<h3> Can´t I just use my local wordpress development copy for testing like xampp / lampp? </h3>
|
85 |
|
86 |
Nope! If your local hardware and software environment is not a 100% exact clone of your production server there is NO guarantee that every aspect
|
87 |
of your local copy is working on your live website exactely as you would expect it.
|
146 |
|
147 |
== Changelog ==
|
148 |
|
149 |
+
= 2.4.3 =
|
150 |
+
* Fix: Updating staging site does not exclude Windows IIS configuration file web.config and can lead to server error
|
151 |
+
* Fix: Redirect to the correct url after log in to staging site
|
152 |
+
* Fix: Supports HTML entities in links created by WP Backery Page Builder Plugin
|
153 |
+
* New: Support for custom and non-default wp-content and uploads folder
|
154 |
+
* New: Option to show again the rating notice in a week
|
155 |
+
|
156 |
+
= 2.4.2 =
|
157 |
+
* Fix: Error 500 on some systems when files are collected and plugin iterates through the directories
|
158 |
+
|
159 |
= 2.4.1 =
|
160 |
* Fix: Error notice if user tries to update staging site located in another database
|
161 |
* Fix: Search & Replace adds staging site subfolder multiple times to replaced string when staging site is updated
|
178 |
* Fix: Selected folders are not excluded under Windows IIS server
|
179 |
* Fix: Windows IIS server compatibilility issues resolved
|
180 |
|
|
|
|
|
|
|
181 |
= 2.3.9 =
|
182 |
* New: Support for wp-config.php located in one level up of the root folder for multisites
|
183 |
* New: Allow exclusion of custom options from wp_options from beeing pushed
|
188 |
* Fix: Filesize() failed if file to copy is not a regular file
|
189 |
* Fix: remove ? parameter from staging site
|
190 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
191 |
|
192 |
Complete changelog: [https://wp-staging.com/wp-staging-changelog](https://wp-staging.com/wp-staging-changelog)
|
193 |
|
194 |
== Upgrade Notice ==
|
195 |
|
196 |
+
= 2.4.3 =
|
197 |
+
* New: Support for custom directories of wp-content and uploads folder
|
198 |
+
|
199 |
|
wp-staging.php
CHANGED
@@ -7,7 +7,7 @@
|
|
7 |
* Author: WP-Staging
|
8 |
* Author URI: https://wp-staging.com
|
9 |
* Contributors: ReneHermi, ilgityildirim
|
10 |
-
* Version: 2.4.
|
11 |
* Text Domain: wp-staging
|
12 |
* Domain Path: /languages/
|
13 |
|
@@ -51,7 +51,7 @@ if( !defined( 'WPSTG_PLUGIN_URL' ) ) {
|
|
51 |
|
52 |
// Version
|
53 |
if( !defined( 'WPSTG_VERSION' ) ) {
|
54 |
-
define( 'WPSTG_VERSION', '2.4.
|
55 |
}
|
56 |
|
57 |
/**
|
7 |
* Author: WP-Staging
|
8 |
* Author URI: https://wp-staging.com
|
9 |
* Contributors: ReneHermi, ilgityildirim
|
10 |
+
* Version: 2.4.3
|
11 |
* Text Domain: wp-staging
|
12 |
* Domain Path: /languages/
|
13 |
|
51 |
|
52 |
// Version
|
53 |
if( !defined( 'WPSTG_VERSION' ) ) {
|
54 |
+
define( 'WPSTG_VERSION', '2.4.3' );
|
55 |
}
|
56 |
|
57 |
/**
|