Version Description
- New: Add more details to tools->system info log for better debugging
- New: Add buttons to select all default wp tables with one click
- New: Show used db table in list of staging sites
- Fix: Delete staging site not possible if db prefix is same as one of the live site
- Fix: Edit/Update clone function is duplicating tables.
- Fix: Other staging site can be overwritten when Edit/Update clone function is executed
- Fix: Several improvements to improve reliability and prevent timeouts and fatal errors during cloning
Download this release
Release Info
Developer | ReneHermi |
Plugin | WP Staging – DB & File Duplicator & Migration |
Version | 2.1.3 |
Comparing to | |
See all releases |
Code changes from version 2.1.2 to 2.1.3
- apps/Backend/Administrator.php +695 -651
- apps/Backend/Modules/Jobs/CancelUpdate.php +90 -0
- apps/Backend/Modules/Jobs/Cloning.php +66 -5
- apps/Backend/Modules/Jobs/Data.php +408 -406
- apps/Backend/Modules/Jobs/Database.php +262 -250
- apps/Backend/Modules/Jobs/Delete.php +66 -47
- apps/Backend/Modules/Jobs/Files.php +102 -72
- apps/Backend/Modules/Jobs/Job.php +28 -18
- apps/Backend/Modules/Jobs/JobExecutable.php +111 -108
- apps/Backend/Modules/Jobs/Scan.php +399 -376
- apps/Backend/Modules/Jobs/Updating.php +262 -0
- apps/Backend/Modules/SystemInfo.php +512 -480
- apps/Backend/public/css/wpstg-admin.css +782 -771
- apps/Backend/public/js/wpstg-admin.js +1251 -1085
- apps/Backend/views/clone/ajax/scan.php +128 -118
- apps/Backend/views/clone/ajax/single-overview.php +55 -48
- apps/Backend/views/clone/ajax/update.php +46 -0
- apps/Core/WPStaging.php +429 -425
- readme.txt +10 -1
- wp-staging.php +1 -1
apps/Backend/Administrator.php
CHANGED
@@ -1,651 +1,695 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace WPStaging\Backend;
|
4 |
-
|
5 |
-
// No Direct Access
|
6 |
-
if( !defined( "WPINC" ) ) {
|
7 |
-
die;
|
8 |
-
}
|
9 |
-
|
10 |
-
use WPStaging\Backend\Modules\Jobs\Cancel;
|
11 |
-
use WPStaging\Backend\Modules\Jobs\
|
12 |
-
use WPStaging\Backend\Modules\Jobs\
|
13 |
-
use WPStaging\Backend\Modules\Jobs\
|
14 |
-
use WPStaging\Backend\Modules\Jobs\
|
15 |
-
use WPStaging\Backend\Modules\Jobs\
|
16 |
-
use WPStaging\Backend\Modules\Jobs\
|
17 |
-
use WPStaging\Backend\Modules\Jobs\
|
18 |
-
use WPStaging\Backend\Modules\
|
19 |
-
use WPStaging\Backend\Modules\
|
20 |
-
use WPStaging\Backend\Modules\
|
21 |
-
use WPStaging\Backend\
|
22 |
-
use WPStaging\
|
23 |
-
use WPStaging\Backend\
|
24 |
-
use WPStaging\
|
25 |
-
use WPStaging\
|
26 |
-
use WPStaging\Backend\
|
27 |
-
use WPStaging\
|
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 |
-
$loader->addAction( "
|
82 |
-
$loader->addAction( "
|
83 |
-
$loader->addAction( "
|
84 |
-
$loader->addAction( "
|
85 |
-
$loader->addAction( "
|
86 |
-
$loader->addAction( "
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
$loader->addAction( "
|
102 |
-
$loader->addAction( "
|
103 |
-
$loader->addAction( "
|
104 |
-
$loader->addAction( "
|
105 |
-
$loader->addAction( "
|
106 |
-
$loader->addAction( "
|
107 |
-
$loader->addAction( "
|
108 |
-
$loader->addAction( "
|
109 |
-
$loader->addAction( "
|
110 |
-
$loader->addAction( "
|
111 |
-
|
112 |
-
|
113 |
-
$loader->addAction( "
|
114 |
-
$loader->addAction( "
|
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 |
-
$sanitized
|
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 |
-
$this->
|
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 |
-
if(
|
287 |
-
|
288 |
-
}
|
289 |
-
|
290 |
-
|
291 |
-
$
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
$importFile
|
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 |
-
|
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 |
-
$scan
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
$
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
echo wp_send_json( array(
|
425 |
-
"status" => "failed",
|
426 |
-
"message" => "Clone name
|
427 |
-
) );
|
428 |
-
}
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
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 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
$
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
}
|
625 |
-
|
626 |
-
/**
|
627 |
-
*
|
628 |
-
*/
|
629 |
-
public function
|
630 |
-
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPStaging\Backend;
|
4 |
+
|
5 |
+
// No Direct Access
|
6 |
+
if( !defined( "WPINC" ) ) {
|
7 |
+
die;
|
8 |
+
}
|
9 |
+
|
10 |
+
use WPStaging\Backend\Modules\Jobs\Cancel;
|
11 |
+
use WPStaging\Backend\Modules\Jobs\CancelUpdate;
|
12 |
+
use WPStaging\Backend\Modules\Jobs\Cloning;
|
13 |
+
use WPStaging\Backend\Modules\Jobs\Updating;
|
14 |
+
use WPStaging\Backend\Modules\Jobs\Data;
|
15 |
+
use WPStaging\Backend\Modules\Jobs\Database;
|
16 |
+
use WPStaging\Backend\Modules\Jobs\Delete;
|
17 |
+
use WPStaging\Backend\Modules\Jobs\Files;
|
18 |
+
use WPStaging\Backend\Modules\Jobs\Scan;
|
19 |
+
use WPStaging\Backend\Modules\Jobs\Logs;
|
20 |
+
use WPStaging\Backend\Modules\Optimizer;
|
21 |
+
use WPStaging\Backend\Modules\SystemInfo;
|
22 |
+
use WPStaging\Backend\Modules\Views\Tabs\Tabs;
|
23 |
+
use WPStaging\Backend\Notices\Notices;
|
24 |
+
use WPStaging\DI\InjectionAware;
|
25 |
+
use WPStaging\Backend\Modules\Views\Forms\Settings as FormSettings;
|
26 |
+
use WPStaging\Backend\Activation;
|
27 |
+
use WPStaging\WPStaging;
|
28 |
+
use WPStaging\Backend\Pro\Modules\Jobs\Processing;
|
29 |
+
use WPStaging\Backend\Pro\Licensing;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Class Administrator
|
33 |
+
* @package WPStaging\Backend
|
34 |
+
*/
|
35 |
+
class Administrator extends InjectionAware {
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @var string
|
39 |
+
*/
|
40 |
+
private $path;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @var string
|
44 |
+
*/
|
45 |
+
private $url;
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Initialize class
|
49 |
+
*/
|
50 |
+
public function initialize() {
|
51 |
+
$this->defineHooks();
|
52 |
+
|
53 |
+
// Path to backend
|
54 |
+
$this->path = plugin_dir_path( __FILE__ );
|
55 |
+
|
56 |
+
// URL to public backend folder
|
57 |
+
$this->url = plugin_dir_url( __FILE__ ) . "public/";
|
58 |
+
|
59 |
+
// Load plugins meta data
|
60 |
+
$this->loadMeta();
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Load plugn meta data
|
65 |
+
*/
|
66 |
+
public function loadMeta() {
|
67 |
+
$run = new \WPStaging\Backend\Pluginmeta\Pluginmeta();
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Define Hooks
|
72 |
+
*/
|
73 |
+
private function defineHooks() {
|
74 |
+
// Get loader
|
75 |
+
$loader = $this->di->get( "loader" );
|
76 |
+
|
77 |
+
$Activation = new \WPStaging\Backend\Activation\Activation();
|
78 |
+
|
79 |
+
$Welcome = new Activation\Welcome();
|
80 |
+
|
81 |
+
$loader->addAction( "activated_plugin", $Activation, 'deactivate_other_instances' );
|
82 |
+
$loader->addAction( "admin_menu", $this, "addMenu", 10 );
|
83 |
+
$loader->addAction( "admin_init", $this, "setOptionFormElements" );
|
84 |
+
$loader->addAction( "admin_init", $this, "upgrade" );
|
85 |
+
$loader->addAction( "admin_post_wpstg_download_sysinfo", $this, "systemInfoDownload" );
|
86 |
+
$loader->addAction( "admin_post_wpstg_export", $this, "export" );
|
87 |
+
$loader->addAction( "admin_post_wpstg_import_settings", $this, "import" );
|
88 |
+
$loader->addAction( "admin_notices", $this, "messages" );
|
89 |
+
|
90 |
+
// Ajax Requests
|
91 |
+
$loader->addAction( "wp_ajax_wpstg_overview", $this, "ajaxOverview" );
|
92 |
+
$loader->addAction( "wp_ajax_wpstg_scanning", $this, "ajaxScan" );
|
93 |
+
$loader->addAction( "wp_ajax_wpstg_check_clone", $this, "ajaxcheckCloneName" );
|
94 |
+
//$loader->addAction( "wp_ajax_wpstg_update_struc", $this, "ajaxStartUpdate" );
|
95 |
+
$loader->addAction( "wp_ajax_wpstg_update", $this, "ajaxUpdateProcess" );
|
96 |
+
$loader->addAction( "wp_ajax_wpstg_cloning", $this, "ajaxStartClone" );
|
97 |
+
$loader->addAction( "wp_ajax_wpstg_clone_database", $this, "ajaxCloneDatabase" );
|
98 |
+
$loader->addAction( "wp_ajax_wpstg_clone_prepare_directories", $this, "ajaxPrepareDirectories" );
|
99 |
+
$loader->addAction( "wp_ajax_wpstg_clone_files", $this, "ajaxCopyFiles" );
|
100 |
+
$loader->addAction( "wp_ajax_wpstg_clone_replace_data", $this, "ajaxReplaceData" );
|
101 |
+
$loader->addAction( "wp_ajax_wpstg_clone_finish", $this, "ajaxFinish" );
|
102 |
+
$loader->addAction( "wp_ajax_wpstg_confirm_delete_clone", $this, "ajaxDeleteConfirmation" );
|
103 |
+
$loader->addAction( "wp_ajax_wpstg_delete_clone", $this, "ajaxDeleteClone" );
|
104 |
+
$loader->addAction( "wp_ajax_wpstg_cancel_clone", $this, "ajaxCancelClone" );
|
105 |
+
$loader->addAction( "wp_ajax_wpstg_cancel_update", $this, "ajaxCancelUpdate" );
|
106 |
+
$loader->addAction( "wp_ajax_wpstg_hide_poll", $this, "ajaxHidePoll" );
|
107 |
+
$loader->addAction( "wp_ajax_wpstg_hide_rating", $this, "ajaxHideRating" );
|
108 |
+
$loader->addAction( "wp_ajax_wpstg_hide_beta", $this, "ajaxHideBeta" );
|
109 |
+
$loader->addAction( "wp_ajax_wpstg_logs", $this, "ajaxLogs" );
|
110 |
+
$loader->addAction( "wp_ajax_wpstg_check_disk_space", $this, "ajaxCheckFreeSpace" );
|
111 |
+
|
112 |
+
// Ajax hooks pro Version
|
113 |
+
$loader->addAction( "wp_ajax_wpstg_scan", $this, "ajaxPushScan" );
|
114 |
+
$loader->addAction( "wp_ajax_wpstg_push_processing", $this, "ajaxPushProcessing" );
|
115 |
+
//$loader->addAction( "wp_ajax_wpstg_copy_database", $this, "ajaxCopyDatabase" );
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Register options form elements
|
120 |
+
*/
|
121 |
+
public function setOptionFormElements() {
|
122 |
+
register_setting( "wpstg_settings", "wpstg_settings", array($this, "sanitizeOptions") );
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Upgrade routine
|
127 |
+
*/
|
128 |
+
public function upgrade() {
|
129 |
+
$upgrade = new Upgrade\Upgrade();
|
130 |
+
$upgrade->doUpgrade();
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Sanitize options data and delete the cache
|
135 |
+
* @param array $data
|
136 |
+
* @return array
|
137 |
+
*/
|
138 |
+
public function sanitizeOptions( $data = array() ) {
|
139 |
+
$sanitized = $this->sanitizeData( $data );
|
140 |
+
|
141 |
+
add_settings_error( "wpstg-notices", '', __( "Settings updated.", "wpstg" ), "updated" );
|
142 |
+
|
143 |
+
// Return sanitized data
|
144 |
+
//return $sanitized;
|
145 |
+
return apply_filters( "wpstg-settings", $sanitized, $data );
|
146 |
+
}
|
147 |
+
|
148 |
+
/**
|
149 |
+
* @param array $data
|
150 |
+
* @return array
|
151 |
+
*/
|
152 |
+
private function sanitizeData( $data = array() ) {
|
153 |
+
$sanitized = array();
|
154 |
+
|
155 |
+
foreach ( $data as $key => $value ) {
|
156 |
+
$sanitized[$key] = (is_array( $value )) ? $this->sanitizeData( $value ) : htmlspecialchars( $value );
|
157 |
+
}
|
158 |
+
|
159 |
+
return $sanitized;
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* Add Admin Menu(s)
|
164 |
+
*/
|
165 |
+
public function addMenu() {
|
166 |
+
|
167 |
+
$logo = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMTAwMCAxMDAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMDAwIDEwMDAiIHhtbDpzcGFjZT0icHJlc2VydmUiIGZpbGw9Im5vbmUiPgo8Zz48Zz48cGF0aCBzdHlsZT0iZmlsbDojZmZmIiAgZD0iTTEzNy42LDU2MS4zSDEzLjhIMTB2MzA2LjNsOTAuNy04My40QzE4OS42LDkwOC43LDMzNS4zLDk5MCw1MDAsOTkwYzI0OS45LDAsNDU2LjEtMTg3LjEsNDg2LjItNDI4LjhIODYyLjRDODMzLjMsNzM1LjEsNjgyLjEsODY3LjUsNTAwLDg2Ny41Yy0xMjksMC0yNDIuNS02Ni41LTMwOC4xLTE2Ny4ybDE1MS4zLTEzOS4xSDEzNy42eiIvPjxwYXRoIHN0eWxlPSJmaWxsOiNmZmYiICBkPSJNNTAwLDEwQzI1MC4xLDEwLDQzLjksMTk3LjEsMTMuOCw0MzguOGgxMjMuOEMxNjYuNywyNjQuOSwzMTcuOSwxMzIuNSw1MDAsMTMyLjVjMTMyLjksMCwyNDkuMyw3MC41LDMxMy44LDE3Ni4yTDY4My44LDQzOC44aDEyMi41aDU2LjJoMTIzLjhoMy44VjEzMi41bC04Ny43LDg3LjdDODEzLjgsOTMuMSw2NjYuNiwxMCw1MDAsMTB6Ii8+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjwvZz4KPC9zdmc+';
|
168 |
+
|
169 |
+
// Main WP Staging Menu
|
170 |
+
add_menu_page(
|
171 |
+
"WP-Staging", __( "WP Staging", "wpstg" ), "manage_options", "wpstg_clone", array($this, "getClonePage"), $logo
|
172 |
+
);
|
173 |
+
|
174 |
+
// Page: Clone
|
175 |
+
add_submenu_page(
|
176 |
+
"wpstg_clone", __( "WP Staging Jobs", "wpstg" ), __( "Start", "wpstg" ), "manage_options", "wpstg_clone", array($this, "getClonePage")
|
177 |
+
);
|
178 |
+
|
179 |
+
// Page: Settings
|
180 |
+
add_submenu_page(
|
181 |
+
"wpstg_clone", __( "WP Staging Settings", "wpstg" ), __( "Settings", "wpstg" ), "manage_options", "wpstg-settings", array($this, "getSettingsPage")
|
182 |
+
);
|
183 |
+
|
184 |
+
// Page: Tools
|
185 |
+
add_submenu_page(
|
186 |
+
"wpstg_clone", __( "WP Staging Tools", "wpstg" ), __( "Tools", "wpstg" ), "manage_options", "wpstg-tools", array($this, "getToolsPage")
|
187 |
+
);
|
188 |
+
// Page: Tools
|
189 |
+
add_submenu_page(
|
190 |
+
"wpstg_clone", __( "WP Staging Welcome", "wpstg" ), __( "Get WP Staging Pro", "wpstg" ), "manage_options", "wpstg-welcome", array($this, "getWelcomePage")
|
191 |
+
);
|
192 |
+
|
193 |
+
if( class_exists( 'WPStaging\Backend\Pro\Licensing\Licensing' ) ) {
|
194 |
+
// Page: License
|
195 |
+
add_submenu_page(
|
196 |
+
"wpstg_clone", __( "WP Staging License", "wpstg" ), __( "License", "wpstg" ), "manage_options", "wpstg-license", array($this, "getLicensePage")
|
197 |
+
);
|
198 |
+
}
|
199 |
+
}
|
200 |
+
|
201 |
+
/**
|
202 |
+
* Settings Page
|
203 |
+
*/
|
204 |
+
public function getSettingsPage() {
|
205 |
+
// Tabs
|
206 |
+
$tabs = new Tabs( array(
|
207 |
+
"general" => __( "General", "wpstg" )
|
208 |
+
) );
|
209 |
+
|
210 |
+
|
211 |
+
$this->di
|
212 |
+
// Set tabs
|
213 |
+
->set( "tabs", $tabs )
|
214 |
+
// Forms
|
215 |
+
->set( "forms", new FormSettings( $tabs ) );
|
216 |
+
|
217 |
+
require_once "{$this->path}views/settings/index.php";
|
218 |
+
}
|
219 |
+
|
220 |
+
/**
|
221 |
+
* Clone Page
|
222 |
+
*/
|
223 |
+
public function getClonePage() {
|
224 |
+
// Existing clones
|
225 |
+
$availableClones = get_option( "wpstg_existing_clones_beta", array() );
|
226 |
+
|
227 |
+
require_once "{$this->path}views/clone/index.php";
|
228 |
+
}
|
229 |
+
|
230 |
+
/**
|
231 |
+
* Welcome Page
|
232 |
+
*/
|
233 |
+
public function getWelcomePage() {
|
234 |
+
require_once "{$this->path}views/welcome/welcome.php";
|
235 |
+
}
|
236 |
+
|
237 |
+
/**
|
238 |
+
* Tools Page
|
239 |
+
*/
|
240 |
+
public function getToolsPage() {
|
241 |
+
// Tabs
|
242 |
+
$tabs = new Tabs( array(
|
243 |
+
"import_export" => __( "Import/Export", "wpstg" ),
|
244 |
+
"system_info" => __( "System Info", "wpstg" )
|
245 |
+
) );
|
246 |
+
|
247 |
+
$this->di->set( "tabs", $tabs );
|
248 |
+
|
249 |
+
$this->di->set( "systemInfo", new SystemInfo( $this->di ) );
|
250 |
+
|
251 |
+
require_once "{$this->path}views/tools/index.php";
|
252 |
+
}
|
253 |
+
|
254 |
+
/**
|
255 |
+
* System Information Download
|
256 |
+
*/
|
257 |
+
public function systemInfoDownload() {
|
258 |
+
if( !current_user_can( "update_plugins" ) ) {
|
259 |
+
return;
|
260 |
+
}
|
261 |
+
|
262 |
+
nocache_headers();
|
263 |
+
header( "Content-Type: text/plain" );
|
264 |
+
header( "Content-Disposition: attachment; filename='wpstg-system-info.txt'" );
|
265 |
+
echo wp_strip_all_tags( new SystemInfo( $this->di ) );
|
266 |
+
}
|
267 |
+
|
268 |
+
/**
|
269 |
+
* Import JSON settings file
|
270 |
+
*/
|
271 |
+
public function import() {
|
272 |
+
if( empty( $_POST["wpstg_import_nonce"] ) ) {
|
273 |
+
return;
|
274 |
+
}
|
275 |
+
|
276 |
+
if( !wp_verify_nonce( $_POST["wpstg_import_nonce"], "wpstg_import_nonce" ) ) {
|
277 |
+
return;
|
278 |
+
}
|
279 |
+
|
280 |
+
if( !current_user_can( "update_plugins" ) ) {
|
281 |
+
return;
|
282 |
+
}
|
283 |
+
|
284 |
+
$fileExtension = explode( '.', $_FILES["import_file"]["name"] );
|
285 |
+
$fileExtension = end( $fileExtension );
|
286 |
+
if( "json" !== $fileExtension ) {
|
287 |
+
wp_die( "Please upload a valid .json file", "wpstg" );
|
288 |
+
}
|
289 |
+
|
290 |
+
|
291 |
+
$importFile = $_FILES["import_file"]["tmp_name"];
|
292 |
+
|
293 |
+
if( empty( $importFile ) ) {
|
294 |
+
wp_die( __( "Please upload a file to import", "wpstg" ) );
|
295 |
+
}
|
296 |
+
|
297 |
+
update_option( "wpstg_settings", json_decode( file_get_contents( $importFile, true ) ) );
|
298 |
+
|
299 |
+
wp_safe_redirect( admin_url( "admin.php?page=wpstg-tools&wpstg-message=settings-imported" ) );
|
300 |
+
|
301 |
+
return;
|
302 |
+
}
|
303 |
+
|
304 |
+
/**
|
305 |
+
* Export settings to JSON file
|
306 |
+
*/
|
307 |
+
public function export() {
|
308 |
+
if( empty( $_POST["wpstg_export_nonce"] ) ) {
|
309 |
+
return;
|
310 |
+
}
|
311 |
+
|
312 |
+
if( !wp_verify_nonce( $_POST["wpstg_export_nonce"], "wpstg_export_nonce" ) ) {
|
313 |
+
return;
|
314 |
+
}
|
315 |
+
|
316 |
+
if( !current_user_can( "manage_options" ) ) {
|
317 |
+
return;
|
318 |
+
}
|
319 |
+
|
320 |
+
$settings = get_option( "wpstg_settings", array() );
|
321 |
+
|
322 |
+
ignore_user_abort( true );
|
323 |
+
|
324 |
+
if( !in_array( "set_time_limit", explode( ',', ini_get( "disable_functions" ) ) ) && !@ini_get( "safe_mode" ) ) {
|
325 |
+
set_time_limit( 0 );
|
326 |
+
}
|
327 |
+
|
328 |
+
$fileName = apply_filters( "wpstg_settings_export_filename", "wpstg-settings-export-" . date( "m-d-Y" ) ) . ".json";
|
329 |
+
|
330 |
+
nocache_headers();
|
331 |
+
header( "Content-Type: application/json; charset=utf-8" );
|
332 |
+
header( "Content-Disposition: attachment; filename={$fileName}" );
|
333 |
+
header( "Expires: 0" );
|
334 |
+
|
335 |
+
echo json_encode( $settings );
|
336 |
+
}
|
337 |
+
|
338 |
+
/**
|
339 |
+
* Render a view file
|
340 |
+
* @param string $file
|
341 |
+
* @param array $vars
|
342 |
+
* @return string
|
343 |
+
*/
|
344 |
+
public function render( $file, $vars = array() ) {
|
345 |
+
$fullPath = $this->path . "views" . DIRECTORY_SEPARATOR;
|
346 |
+
$fullPath = str_replace( array('/', "\\"), DIRECTORY_SEPARATOR, $fullPath . $file . ".php" );
|
347 |
+
|
348 |
+
if( !file_exists( $fullPath ) || !is_readable( $fullPath ) ) {
|
349 |
+
return "Can't render : {$fullPath} either file doesn't exist or can't read it";
|
350 |
+
}
|
351 |
+
|
352 |
+
$contents = @file_get_contents( $fullPath );
|
353 |
+
|
354 |
+
// Variables are set
|
355 |
+
if( count( $vars ) > 0 ) {
|
356 |
+
$vars = array_combine(
|
357 |
+
array_map( function ($key) {
|
358 |
+
return "{{" . $key . "}}";
|
359 |
+
}, array_keys( $vars )
|
360 |
+
), $vars
|
361 |
+
);
|
362 |
+
|
363 |
+
$contents = str_replace( array_keys( $vars ), array_values( $vars ), $contents );
|
364 |
+
}
|
365 |
+
|
366 |
+
return $contents;
|
367 |
+
}
|
368 |
+
|
369 |
+
/**
|
370 |
+
* Ajax Overview
|
371 |
+
*/
|
372 |
+
public function ajaxOverview() {
|
373 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
374 |
+
|
375 |
+
// Existing clones
|
376 |
+
$availableClones = get_option( "wpstg_existing_clones_beta", array() );
|
377 |
+
|
378 |
+
// Get license data
|
379 |
+
$license = get_option( 'wpstg_license_status' );
|
380 |
+
|
381 |
+
|
382 |
+
if( \WPStaging\WPStaging::getSlug() === 'wp-staging-pro' ) {
|
383 |
+
require_once "{$this->path}Pro/views/single-overview-pro.php";
|
384 |
+
} else {
|
385 |
+
require_once "{$this->path}views/clone/ajax/single-overview.php";
|
386 |
+
}
|
387 |
+
|
388 |
+
wp_die();
|
389 |
+
}
|
390 |
+
|
391 |
+
/**
|
392 |
+
* Ajax Scan
|
393 |
+
*/
|
394 |
+
public function ajaxScan() {
|
395 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
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 |
+
// Check clone name length
|
418 |
+
if( $cloneNameLength < 1 || $cloneNameLength > 16 ) {
|
419 |
+
echo wp_send_json( array(
|
420 |
+
"status" => "failed",
|
421 |
+
"message" => "Clone name must be between 1 - 16 characters"
|
422 |
+
) );
|
423 |
+
} elseif( array_key_exists( $cloneName, $clones ) ) {
|
424 |
+
echo wp_send_json( array(
|
425 |
+
"status" => "failed",
|
426 |
+
"message" => "Clone name is already in use, please choose an another clone name"
|
427 |
+
) );
|
428 |
+
}
|
429 |
+
|
430 |
+
echo wp_send_json( array("status" => "success") );
|
431 |
+
}
|
432 |
+
|
433 |
+
|
434 |
+
|
435 |
+
|
436 |
+
/**
|
437 |
+
* Ajax Start Updating Clone (Basically just layout and saving data)
|
438 |
+
*/
|
439 |
+
// public function ajaxStartUpdate() {
|
440 |
+
// check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
441 |
+
//
|
442 |
+
// $cloning = new Updating();
|
443 |
+
//
|
444 |
+
// if( !$cloning->save() ) {
|
445 |
+
// wp_die('can not save clone data');
|
446 |
+
// }
|
447 |
+
//
|
448 |
+
// require_once "{$this->path}views/clone/ajax/update.php";
|
449 |
+
//
|
450 |
+
// wp_die();
|
451 |
+
// }
|
452 |
+
/**
|
453 |
+
* Ajax Start Updating Clone (Basically just layout and saving data)
|
454 |
+
*/
|
455 |
+
public function ajaxUpdateProcess() {
|
456 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
457 |
+
|
458 |
+
$cloning = new Updating();
|
459 |
+
|
460 |
+
if( !$cloning->save() ) {
|
461 |
+
wp_die('can not save clone data');
|
462 |
+
}
|
463 |
+
|
464 |
+
require_once "{$this->path}views/clone/ajax/update.php";
|
465 |
+
|
466 |
+
wp_die();
|
467 |
+
|
468 |
+
//wp_send_json( $cloning->start() );
|
469 |
+
}
|
470 |
+
/**
|
471 |
+
* Ajax Start Clone (Basically just layout and saving data)
|
472 |
+
*/
|
473 |
+
public function ajaxStartClone() {
|
474 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
475 |
+
|
476 |
+
$cloning = new Cloning();
|
477 |
+
|
478 |
+
if( !$cloning->save() ) {
|
479 |
+
wp_die('can not save clone data');
|
480 |
+
}
|
481 |
+
|
482 |
+
require_once "{$this->path}views/clone/ajax/start.php";
|
483 |
+
|
484 |
+
wp_die();
|
485 |
+
}
|
486 |
+
|
487 |
+
/**
|
488 |
+
* Ajax Clone Database
|
489 |
+
*/
|
490 |
+
public function ajaxCloneDatabase() {
|
491 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
492 |
+
|
493 |
+
$cloning = new Cloning();
|
494 |
+
|
495 |
+
wp_send_json( $cloning->start() );
|
496 |
+
}
|
497 |
+
|
498 |
+
/**
|
499 |
+
* Ajax Prepare Directories (get listing of files)
|
500 |
+
*/
|
501 |
+
public function ajaxPrepareDirectories() {
|
502 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
503 |
+
|
504 |
+
$cloning = new Cloning();
|
505 |
+
|
506 |
+
wp_send_json( $cloning->start() );
|
507 |
+
}
|
508 |
+
|
509 |
+
/**
|
510 |
+
* Ajax Clone Files
|
511 |
+
*/
|
512 |
+
public function ajaxCopyFiles() {
|
513 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
514 |
+
|
515 |
+
$cloning = new Cloning();
|
516 |
+
|
517 |
+
wp_send_json( $cloning->start() );
|
518 |
+
}
|
519 |
+
|
520 |
+
/**
|
521 |
+
* Ajax Replace Data
|
522 |
+
*/
|
523 |
+
public function ajaxReplaceData() {
|
524 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
525 |
+
|
526 |
+
$cloning = new Cloning();
|
527 |
+
|
528 |
+
wp_send_json( $cloning->start() );
|
529 |
+
}
|
530 |
+
|
531 |
+
/**
|
532 |
+
* Ajax Finish
|
533 |
+
*/
|
534 |
+
public function ajaxFinish() {
|
535 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
536 |
+
|
537 |
+
$cloning = new Cloning();
|
538 |
+
|
539 |
+
wp_send_json( $cloning->start() );
|
540 |
+
}
|
541 |
+
|
542 |
+
/**
|
543 |
+
* Ajax Delete Confirmation
|
544 |
+
*/
|
545 |
+
public function ajaxDeleteConfirmation() {
|
546 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
547 |
+
|
548 |
+
$delete = new Delete();
|
549 |
+
$delete->setData();
|
550 |
+
|
551 |
+
$clone = $delete->getClone();
|
552 |
+
|
553 |
+
require_once "{$this->path}views/clone/ajax/delete-confirmation.php";
|
554 |
+
|
555 |
+
wp_die();
|
556 |
+
}
|
557 |
+
|
558 |
+
/**
|
559 |
+
* Delete clone
|
560 |
+
*/
|
561 |
+
public function ajaxDeleteClone() {
|
562 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
563 |
+
|
564 |
+
$delete = new Delete();
|
565 |
+
wp_send_json( $delete->start() );
|
566 |
+
}
|
567 |
+
|
568 |
+
/**
|
569 |
+
* Delete clone
|
570 |
+
*/
|
571 |
+
public function ajaxCancelClone() {
|
572 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
573 |
+
|
574 |
+
$cancel = new Cancel();
|
575 |
+
wp_send_json( $cancel->start() );
|
576 |
+
}
|
577 |
+
|
578 |
+
/**
|
579 |
+
* Cancel updating process / Do not delete clone!
|
580 |
+
*/
|
581 |
+
public function ajaxCancelUpdate() {
|
582 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
583 |
+
|
584 |
+
$cancel = new CancelUpdate();
|
585 |
+
wp_send_json( $cancel->start() );
|
586 |
+
}
|
587 |
+
|
588 |
+
/**
|
589 |
+
* Admin Messages
|
590 |
+
*/
|
591 |
+
public function messages() {
|
592 |
+
$notice = new Notices( $this->path, $this->url );
|
593 |
+
|
594 |
+
$run = $notice->messages();
|
595 |
+
}
|
596 |
+
|
597 |
+
/**
|
598 |
+
* Ajax Hide Poll
|
599 |
+
* @return mixed boolean | json
|
600 |
+
*/
|
601 |
+
public function ajaxHidePoll() {
|
602 |
+
if( false !== update_option( "wpstg_poll", "no" ) ) {
|
603 |
+
wp_send_json( true );
|
604 |
+
}
|
605 |
+
return wp_send_json();
|
606 |
+
}
|
607 |
+
|
608 |
+
/**
|
609 |
+
* Ajax Hide Rating
|
610 |
+
* @return mixed bool | json
|
611 |
+
*/
|
612 |
+
public function ajaxHideRating() {
|
613 |
+
if( false !== update_option( "wpstg_rating", "no" ) ) {
|
614 |
+
wp_send_json( true );
|
615 |
+
}
|
616 |
+
return wp_send_json();
|
617 |
+
}
|
618 |
+
|
619 |
+
/**
|
620 |
+
* Ajax Hide Beta
|
621 |
+
*/
|
622 |
+
public function ajaxHideBeta() {
|
623 |
+
wp_send_json( update_option( "wpstg_beta", "no" ) );
|
624 |
+
}
|
625 |
+
|
626 |
+
/**
|
627 |
+
* Clone logs
|
628 |
+
*/
|
629 |
+
public function ajaxLogs() {
|
630 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
631 |
+
|
632 |
+
$logs = new Logs();
|
633 |
+
wp_send_json( $logs->start() );
|
634 |
+
}
|
635 |
+
|
636 |
+
/**
|
637 |
+
* Ajax Checks Free Disk Space
|
638 |
+
*/
|
639 |
+
public function ajaxCheckFreeSpace() {
|
640 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
641 |
+
|
642 |
+
$scan = new Scan();
|
643 |
+
return $scan->hasFreeDiskSpace();
|
644 |
+
}
|
645 |
+
|
646 |
+
/**
|
647 |
+
* Ajax Start Push Changes Process
|
648 |
+
* Start with the module Scan
|
649 |
+
*/
|
650 |
+
public function ajaxPushScan() {
|
651 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
652 |
+
|
653 |
+
if( !class_exists( 'WPStaging\Backend\Pro\Modules\Jobs\Scan' ) ) {
|
654 |
+
return false;
|
655 |
+
}
|
656 |
+
|
657 |
+
// Scan
|
658 |
+
$scan = new Pro\Modules\Jobs\Scan();
|
659 |
+
|
660 |
+
$scan->start();
|
661 |
+
|
662 |
+
// Get Options
|
663 |
+
$options = $scan->getOptions();
|
664 |
+
|
665 |
+
require_once "{$this->path}Pro/views/scan.php";
|
666 |
+
|
667 |
+
wp_die();
|
668 |
+
}
|
669 |
+
|
670 |
+
/**
|
671 |
+
* Ajax Start Pushing. Needs wp quads pro)
|
672 |
+
*/
|
673 |
+
public function ajaxPushProcessing() {
|
674 |
+
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
|
675 |
+
|
676 |
+
if( !class_exists( 'WPStaging\Backend\Pro\Modules\Jobs\Processing' ) ) {
|
677 |
+
return false;
|
678 |
+
}
|
679 |
+
// Start the process
|
680 |
+
$processing = new Processing();
|
681 |
+
wp_send_json( $processing->start() );
|
682 |
+
}
|
683 |
+
|
684 |
+
/**
|
685 |
+
* License Page
|
686 |
+
*/
|
687 |
+
public function getLicensePage() {
|
688 |
+
|
689 |
+
// Get license data
|
690 |
+
$license = get_option( 'wpstg_license_status' );
|
691 |
+
|
692 |
+
require_once "{$this->path}Pro/views/licensing.php";
|
693 |
+
}
|
694 |
+
|
695 |
+
}
|
apps/Backend/Modules/Jobs/CancelUpdate.php
ADDED
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPStaging\Backend\Modules\Jobs;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Cancel Update Processing
|
7 |
+
* @package WPStaging\Backend\Modules\Jobs
|
8 |
+
*/
|
9 |
+
class CancelUpdate extends Job {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Start Module
|
13 |
+
* @return bool
|
14 |
+
*/
|
15 |
+
public function start() {
|
16 |
+
$cloneData = $this->createCloneData();
|
17 |
+
|
18 |
+
if (empty($cloneData)) {
|
19 |
+
return true;
|
20 |
+
}
|
21 |
+
// Delete Cache Files
|
22 |
+
$this->deleteCacheFiles();
|
23 |
+
|
24 |
+
$this->returnFinish();
|
25 |
+
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @return array
|
30 |
+
*/
|
31 |
+
protected function createCloneData() {
|
32 |
+
$clone = array();
|
33 |
+
|
34 |
+
if (!$this->check()) {
|
35 |
+
return $clone;
|
36 |
+
}
|
37 |
+
|
38 |
+
$clone["name"] = $this->options->clone;
|
39 |
+
$clone["number"] = $this->options->cloneNumber;
|
40 |
+
$clone["path"] = ABSPATH . $this->options->cloneDirectoryName;
|
41 |
+
$clone["prefix"] = ABSPATH . $this->options->prefix;
|
42 |
+
|
43 |
+
return $clone;
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @return bool
|
48 |
+
*/
|
49 |
+
public function check() {
|
50 |
+
return (
|
51 |
+
isset($this->options) &&
|
52 |
+
isset($this->options->clone) &&
|
53 |
+
isset($this->options->cloneNumber) &&
|
54 |
+
isset($this->options->cloneDirectoryName) &&
|
55 |
+
isset($_POST["clone"]) &&
|
56 |
+
$_POST["clone"] === $this->options->clone
|
57 |
+
);
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Get json response
|
62 |
+
* return json
|
63 |
+
*/
|
64 |
+
private function returnFinish($message = '') {
|
65 |
+
|
66 |
+
wp_die(json_encode(array(
|
67 |
+
'job' => 'delete',
|
68 |
+
'status' => true,
|
69 |
+
'message' => $message,
|
70 |
+
'error' => false,
|
71 |
+
'delete' => 'finished'
|
72 |
+
)));
|
73 |
+
}
|
74 |
+
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Delete Cache Files
|
78 |
+
*/
|
79 |
+
protected function deleteCacheFiles()
|
80 |
+
{
|
81 |
+
$this->log("Cancel Updating: Deleting clone job's cache files...");
|
82 |
+
|
83 |
+
// Clean cache files
|
84 |
+
$this->cache->delete("clone_options");
|
85 |
+
$this->cache->delete("files_to_copy");
|
86 |
+
|
87 |
+
$this->log("Updating process canceled");
|
88 |
+
}
|
89 |
+
|
90 |
+
}
|
apps/Backend/Modules/Jobs/Cloning.php
CHANGED
@@ -2,6 +2,7 @@
|
|
2 |
namespace WPStaging\Backend\Modules\Jobs;
|
3 |
|
4 |
use WPStaging\Backend\Modules\Jobs\Exceptions\JobNotFoundException;
|
|
|
5 |
|
6 |
/**
|
7 |
* Class Cloning
|
@@ -9,6 +10,12 @@ use WPStaging\Backend\Modules\Jobs\Exceptions\JobNotFoundException;
|
|
9 |
*/
|
10 |
class Cloning extends Job
|
11 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
/**
|
14 |
* Save Chosen Cloning Settings
|
@@ -22,26 +29,39 @@ class Cloning extends Job
|
|
22 |
}
|
23 |
|
24 |
// Generate Options
|
25 |
-
|
26 |
// Clone
|
27 |
$this->options->clone = $_POST["cloneID"];
|
28 |
$this->options->cloneDirectoryName = preg_replace("#\W+#", '-', strtolower($this->options->clone));
|
29 |
$this->options->cloneNumber = 1;
|
|
|
|
|
|
|
|
|
|
|
30 |
$this->options->includedDirectories = array();
|
31 |
$this->options->excludedDirectories = array();
|
32 |
-
$this->options->extraDirectories
|
33 |
-
$this->options->excludedFiles
|
34 |
|
35 |
// Job
|
36 |
$this->options->job = new \stdClass();
|
37 |
|
38 |
-
if
|
|
|
39 |
{
|
|
|
40 |
$this->options->cloneNumber = $this->options->existingClones[$this->options->clone]->number;
|
41 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
elseif (!empty($this->options->existingClones))
|
43 |
{
|
44 |
$this->options->cloneNumber = count($this->options->existingClones)+1;
|
|
|
45 |
}
|
46 |
|
47 |
// Excluded Tables
|
@@ -91,6 +111,47 @@ class Cloning extends Job
|
|
91 |
return $this->saveOptions();
|
92 |
}
|
93 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
/**
|
95 |
* Start the cloning job
|
96 |
*/
|
2 |
namespace WPStaging\Backend\Modules\Jobs;
|
3 |
|
4 |
use WPStaging\Backend\Modules\Jobs\Exceptions\JobNotFoundException;
|
5 |
+
use WPStaging\WPStaging;
|
6 |
|
7 |
/**
|
8 |
* Class Cloning
|
10 |
*/
|
11 |
class Cloning extends Job
|
12 |
{
|
13 |
+
/**
|
14 |
+
* Initialize is called in \Job
|
15 |
+
*/
|
16 |
+
public function initialize(){
|
17 |
+
$this->db = WPStaging::getInstance()->get("wpdb");
|
18 |
+
}
|
19 |
|
20 |
/**
|
21 |
* Save Chosen Cloning Settings
|
29 |
}
|
30 |
|
31 |
// Generate Options
|
|
|
32 |
// Clone
|
33 |
$this->options->clone = $_POST["cloneID"];
|
34 |
$this->options->cloneDirectoryName = preg_replace("#\W+#", '-', strtolower($this->options->clone));
|
35 |
$this->options->cloneNumber = 1;
|
36 |
+
//$this->options->prefix = "wpstg1_";
|
37 |
+
//$this->options->prefix = '2323';
|
38 |
+
$this->options->prefix = $this->getStagingPrefix();
|
39 |
+
|
40 |
+
//$this->options->prefix = $this->getStagingPrefix();
|
41 |
$this->options->includedDirectories = array();
|
42 |
$this->options->excludedDirectories = array();
|
43 |
+
$this->options->extraDirectories = array();
|
44 |
+
$this->options->excludedFiles = array('.htaccess', '.DS_Store', '.git', '.svn', '.tmp', 'desktop.ini', '.gitignore', '.log');
|
45 |
|
46 |
// Job
|
47 |
$this->options->job = new \stdClass();
|
48 |
|
49 |
+
// Check if clone data already exists and use that one
|
50 |
+
if (isset($this->options->existingClones[$this->options->clone]) )
|
51 |
{
|
52 |
+
|
53 |
$this->options->cloneNumber = $this->options->existingClones[$this->options->clone]->number;
|
54 |
+
|
55 |
+
$this->options->prefix = isset($this->options->existingClones[$this->options->clone]->prefix) ?
|
56 |
+
$this->options->existingClones[$this->options->clone]->prefix :
|
57 |
+
$this->getStagingPrefix();
|
58 |
+
|
59 |
+
} // Clone does not exist but there are other clones in db
|
60 |
+
// Get data and increment it
|
61 |
elseif (!empty($this->options->existingClones))
|
62 |
{
|
63 |
$this->options->cloneNumber = count($this->options->existingClones)+1;
|
64 |
+
$this->options->prefix = $this->getStagingPrefix();
|
65 |
}
|
66 |
|
67 |
// Excluded Tables
|
111 |
return $this->saveOptions();
|
112 |
}
|
113 |
|
114 |
+
/**
|
115 |
+
* Create a new staging prefix which does not already exists in database
|
116 |
+
*/
|
117 |
+
public function getStagingPrefix(){
|
118 |
+
|
119 |
+
// Find a new prefix that does not already exist in database.
|
120 |
+
// 1000 different possible prefixes should be enough here
|
121 |
+
for($i=0; $i <= 10000; $i++){
|
122 |
+
$this->options->prefix = isset($this->options->existingClones) ?
|
123 |
+
'wpstg' . (count($this->options->existingClones)+$i) . '_' :
|
124 |
+
'wpstg' . $i . '_';
|
125 |
+
|
126 |
+
$sql = "SHOW TABLE STATUS LIKE '{$this->options->prefix}%'";
|
127 |
+
$tables = $this->db->get_results($sql);
|
128 |
+
|
129 |
+
// Prefix does not exists. We can use it
|
130 |
+
if (!$tables){
|
131 |
+
//$this->returnException('new ' . $this->options->prefix);
|
132 |
+
return $this->options->prefix;
|
133 |
+
}
|
134 |
+
}
|
135 |
+
$this->returnException("Fatal Error: Can not create staging prefix. '{$this->options->prefix}' already exists! Stopping for security reasons. Contact support@wp-staging.com");
|
136 |
+
wp_die("Fatal Error: Can not create staging prefix. Prefix '{$this->options->prefix}' already exists! Stopping for security reasons. Contact support@wp-staging.com");
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Check if potential new prefix of staging site would be identical with live site.
|
141 |
+
* @return boolean
|
142 |
+
*/
|
143 |
+
private function isPrefixIdentical(){
|
144 |
+
$db = WPStaging::getInstance()->get("wpdb");
|
145 |
+
|
146 |
+
$livePrefix = $db->prefix;
|
147 |
+
$stagingPrefix = $this->options->prefix;
|
148 |
+
|
149 |
+
if ($livePrefix == $stagingPrefix){
|
150 |
+
return true;
|
151 |
+
}
|
152 |
+
return false;
|
153 |
+
}
|
154 |
+
|
155 |
/**
|
156 |
* Start the cloning job
|
157 |
*/
|
apps/Backend/Modules/Jobs/Data.php
CHANGED
@@ -1,407 +1,409 @@
|
|
1 |
-
<?php
|
2 |
-
namespace WPStaging\Backend\Modules\Jobs;
|
3 |
-
|
4 |
-
// No Direct Access
|
5 |
-
if (!defined("WPINC"))
|
6 |
-
{
|
7 |
-
die;
|
8 |
-
}
|
9 |
-
|
10 |
-
use WPStaging\Utils\Logger;
|
11 |
-
use WPStaging\WPStaging;
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Class Data
|
15 |
-
* @package WPStaging\Backend\Modules\Jobs
|
16 |
-
*/
|
17 |
-
class Data extends JobExecutable
|
18 |
-
{
|
19 |
-
|
20 |
-
/**
|
21 |
-
* @var \wpdb
|
22 |
-
*/
|
23 |
-
private $db;
|
24 |
-
|
25 |
-
/**
|
26 |
-
* @var string
|
27 |
-
*/
|
28 |
-
private $prefix;
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Initialize
|
32 |
-
*/
|
33 |
-
public function initialize()
|
34 |
-
{
|
35 |
-
$this->db = WPStaging::getInstance()->get("wpdb");
|
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 |
-
$this->
|
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 |
}
|
1 |
+
<?php
|
2 |
+
namespace WPStaging\Backend\Modules\Jobs;
|
3 |
+
|
4 |
+
// No Direct Access
|
5 |
+
if (!defined("WPINC"))
|
6 |
+
{
|
7 |
+
die;
|
8 |
+
}
|
9 |
+
|
10 |
+
use WPStaging\Utils\Logger;
|
11 |
+
use WPStaging\WPStaging;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Class Data
|
15 |
+
* @package WPStaging\Backend\Modules\Jobs
|
16 |
+
*/
|
17 |
+
class Data extends JobExecutable
|
18 |
+
{
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @var \wpdb
|
22 |
+
*/
|
23 |
+
private $db;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @var string
|
27 |
+
*/
|
28 |
+
private $prefix;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Initialize
|
32 |
+
*/
|
33 |
+
public function initialize()
|
34 |
+
{
|
35 |
+
$this->db = WPStaging::getInstance()->get("wpdb");
|
36 |
+
|
37 |
+
//$this->prefix = "wpstg{$this->options->cloneNumber}_";
|
38 |
+
$this->prefix = $this->options->prefix;
|
39 |
+
|
40 |
+
// Fix current step
|
41 |
+
if (0 == $this->options->currentStep)
|
42 |
+
{
|
43 |
+
$this->options->currentStep = 1;
|
44 |
+
}
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Calculate Total Steps in This Job and Assign It to $this->options->totalSteps
|
49 |
+
* @return void
|
50 |
+
*/
|
51 |
+
protected function calculateTotalSteps()
|
52 |
+
{
|
53 |
+
$this->options->totalSteps = 6;
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Start Module
|
58 |
+
* @return object
|
59 |
+
*/
|
60 |
+
public function start()
|
61 |
+
{
|
62 |
+
// Execute steps
|
63 |
+
$this->run();
|
64 |
+
|
65 |
+
// Save option, progress
|
66 |
+
$this->saveOptions();
|
67 |
+
|
68 |
+
// Prepare response
|
69 |
+
$this->response = array(
|
70 |
+
"status" => true,
|
71 |
+
"percentage" => 100,
|
72 |
+
"total" => $this->options->totalSteps,
|
73 |
+
"step" => $this->options->totalSteps,
|
74 |
+
"last_msg" => $this->logger->getLastLogMsg(),
|
75 |
+
"running_time" => $this->time() - time(),
|
76 |
+
"job_done" => true
|
77 |
+
);
|
78 |
+
|
79 |
+
return (object) $this->response;
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Execute the Current Step
|
84 |
+
* Returns false when over threshold limits are hit or when the job is done, true otherwise
|
85 |
+
* @return bool
|
86 |
+
*/
|
87 |
+
protected function execute()
|
88 |
+
{
|
89 |
+
// Fatal error. Let this happen never and break here immediately
|
90 |
+
if ($this->isRoot()){
|
91 |
+
return false;
|
92 |
+
}
|
93 |
+
|
94 |
+
// Over limits threshold
|
95 |
+
if ($this->isOverThreshold())
|
96 |
+
{
|
97 |
+
// Prepare response and save current progress
|
98 |
+
$this->prepareResponse(false, false);
|
99 |
+
$this->saveOptions();
|
100 |
+
return false;
|
101 |
+
}
|
102 |
+
|
103 |
+
// No more steps, finished
|
104 |
+
if ($this->isFinished())
|
105 |
+
{
|
106 |
+
$this->prepareResponse(true, false);
|
107 |
+
return false;
|
108 |
+
}
|
109 |
+
|
110 |
+
// Execute step
|
111 |
+
$stepMethodName = "step" . $this->options->currentStep;
|
112 |
+
if (!$this->{$stepMethodName}())
|
113 |
+
{
|
114 |
+
$this->prepareResponse(false, false);
|
115 |
+
return false;
|
116 |
+
}
|
117 |
+
|
118 |
+
// Prepare Response
|
119 |
+
$this->prepareResponse();
|
120 |
+
|
121 |
+
// Not finished
|
122 |
+
return true;
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Checks Whether There is Any Job to Execute or Not
|
127 |
+
* @return bool
|
128 |
+
*/
|
129 |
+
private function isFinished()
|
130 |
+
{
|
131 |
+
return (
|
132 |
+
$this->options->currentStep > $this->options->totalSteps ||
|
133 |
+
!method_exists($this, "step" . $this->options->currentStep)
|
134 |
+
);
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Check if current operation is done on the root folder or on the live DB
|
139 |
+
* @return boolean
|
140 |
+
*/
|
141 |
+
private function isRoot(){
|
142 |
+
|
143 |
+
// Prefix is the same as the one of live site
|
144 |
+
$wpdb = WPStaging::getInstance()->get("wpdb");
|
145 |
+
if ($wpdb->prefix === $this->prefix){
|
146 |
+
return true;
|
147 |
+
}
|
148 |
+
|
149 |
+
// CloneName is empty
|
150 |
+
$name = (array)$this->options->cloneDirectoryName;
|
151 |
+
if (empty($name)){
|
152 |
+
return true;
|
153 |
+
}
|
154 |
+
|
155 |
+
// Live Path === Staging path
|
156 |
+
if (get_home_url() . $this->options->cloneDirectoryName === get_home_url()){
|
157 |
+
return true;
|
158 |
+
}
|
159 |
+
|
160 |
+
return false;
|
161 |
+
}
|
162 |
+
|
163 |
+
|
164 |
+
/**
|
165 |
+
* Check if table exists
|
166 |
+
* @param string $table
|
167 |
+
* @return boolean
|
168 |
+
*/
|
169 |
+
protected function isTable($table){
|
170 |
+
if($this->db->get_var("SHOW TABLES LIKE '{$table}'") != $table ){
|
171 |
+
$this->log( "Table {$table} does not exists", Logger::TYPE_ERROR );
|
172 |
+
return false;
|
173 |
+
}
|
174 |
+
return true;
|
175 |
+
}
|
176 |
+
|
177 |
+
/**
|
178 |
+
* Replace "siteurl"
|
179 |
+
* @return bool
|
180 |
+
*/
|
181 |
+
protected function step1() {
|
182 |
+
$this->log( "Search & Replace: Updating siteurl and homeurl in {$this->prefix}options {$this->db->last_error}", Logger::TYPE_INFO );
|
183 |
+
|
184 |
+
if( false === $this->isTable( $this->prefix . 'options' ) ) {
|
185 |
+
return true;
|
186 |
+
}
|
187 |
+
|
188 |
+
// Installed in sub-directory
|
189 |
+
if( isset( $this->settings->wpSubDirectory ) && "1" === $this->settings->wpSubDirectory ) {
|
190 |
+
$subDirectory = str_replace( get_home_path(), '', ABSPATH );
|
191 |
+
$this->log( "Updating siteurl and homeurl to " . get_home_url() . '/' . $subDirectory . $this->options->cloneDirectoryName );
|
192 |
+
// Replace URLs
|
193 |
+
$result = $this->db->query(
|
194 |
+
$this->db->prepare(
|
195 |
+
"UPDATE {$this->prefix}options SET option_value = %s WHERE option_name = 'siteurl' or option_name='home'", get_home_url() . '/' . $subDirectory . $this->options->cloneDirectoryName
|
196 |
+
)
|
197 |
+
);
|
198 |
+
} else {
|
199 |
+
$this->log( "Search & Replace:: Updating siteurl and homeurl to " . get_home_url() . '/' . $this->options->cloneDirectoryName );
|
200 |
+
// Replace URLs
|
201 |
+
$result = $this->db->query(
|
202 |
+
$this->db->prepare(
|
203 |
+
"UPDATE {$this->prefix}options SET option_value = %s WHERE option_name = 'siteurl' or option_name='home'", get_home_url() . '/' . $this->options->cloneDirectoryName
|
204 |
+
)
|
205 |
+
);
|
206 |
+
}
|
207 |
+
|
208 |
+
|
209 |
+
// All good
|
210 |
+
if( $result ) {
|
211 |
+
return true;
|
212 |
+
}
|
213 |
+
|
214 |
+
$this->log( "Search & Replace: Failed to update siteurl and homeurl in {$this->prefix}options {$this->db->last_error}", Logger::TYPE_ERROR );
|
215 |
+
return false;
|
216 |
+
}
|
217 |
+
|
218 |
+
/**
|
219 |
+
* Update "wpstg_is_staging_site"
|
220 |
+
* @return bool
|
221 |
+
*/
|
222 |
+
protected function step2()
|
223 |
+
{
|
224 |
+
|
225 |
+
$this->log( "Search & Replace: Updating row wpstg_is_staging_site in {$this->prefix}options {$this->db->last_error}" );
|
226 |
+
|
227 |
+
if( false === $this->isTable( $this->prefix . 'options' ) ) {
|
228 |
+
return true;
|
229 |
+
}
|
230 |
+
|
231 |
+
$result = $this->db->query(
|
232 |
+
$this->db->prepare(
|
233 |
+
"UPDATE {$this->prefix}options SET option_value = %s WHERE option_name = 'wpstg_is_staging_site'",
|
234 |
+
"true"
|
235 |
+
)
|
236 |
+
);
|
237 |
+
|
238 |
+
// No errors but no option name such as wpstg_is_staging_site
|
239 |
+
if ('' === $this->db->last_error && 0 == $result)
|
240 |
+
{
|
241 |
+
$result = $this->db->query(
|
242 |
+
$this->db->prepare(
|
243 |
+
"INSERT INTO {$this->prefix}options (option_name,option_value) VALUES ('wpstg_is_staging_site',%s)",
|
244 |
+
"true"
|
245 |
+
)
|
246 |
+
);
|
247 |
+
}
|
248 |
+
|
249 |
+
// All good
|
250 |
+
if ($result)
|
251 |
+
{
|
252 |
+
return true;
|
253 |
+
}
|
254 |
+
|
255 |
+
$this->log("Search & Replace: Failed to update wpstg_is_staging_site in {$this->prefix}options {$this->db->last_error}", Logger::TYPE_ERROR);
|
256 |
+
return false;
|
257 |
+
}
|
258 |
+
|
259 |
+
/**
|
260 |
+
* Update rewrite_rules
|
261 |
+
* @return bool
|
262 |
+
*/
|
263 |
+
protected function step3()
|
264 |
+
{
|
265 |
+
|
266 |
+
$this->log("Search & Replace: Updating rewrite_rules in {$this->prefix}options {$this->db->last_error}");
|
267 |
+
|
268 |
+
if( false === $this->isTable( $this->prefix . 'options' ) ) {
|
269 |
+
return true;
|
270 |
+
}
|
271 |
+
|
272 |
+
$result = $this->db->query(
|
273 |
+
$this->db->prepare(
|
274 |
+
"UPDATE {$this->prefix}options SET option_value = %s WHERE option_name = 'rewrite_rules'",
|
275 |
+
' '
|
276 |
+
)
|
277 |
+
);
|
278 |
+
|
279 |
+
// All good
|
280 |
+
if ($result)
|
281 |
+
{
|
282 |
+
return true;
|
283 |
+
}
|
284 |
+
|
285 |
+
$this->log("Failed to update rewrite_rules in {$this->prefix}options {$this->db->last_error}", Logger::TYPE_ERROR);
|
286 |
+
return true;
|
287 |
+
}
|
288 |
+
|
289 |
+
/**
|
290 |
+
* Update Table Prefix in meta_keys
|
291 |
+
* @return bool
|
292 |
+
*/
|
293 |
+
protected function step4() {
|
294 |
+
$this->log( "Search & Replace: Updating {$this->prefix}usermeta db prefix {$this->db->last_error}" );
|
295 |
+
|
296 |
+
if( false === $this->isTable( $this->prefix . 'usermeta' ) ) {
|
297 |
+
return true;
|
298 |
+
}
|
299 |
+
|
300 |
+
$resultOptions = $this->db->query(
|
301 |
+
$this->db->prepare(
|
302 |
+
"UPDATE {$this->prefix}usermeta SET meta_key = replace(meta_key, %s, %s) WHERE meta_key LIKE %s", $this->db->prefix, $this->prefix, $this->db->prefix . "_%"
|
303 |
+
)
|
304 |
+
);
|
305 |
+
|
306 |
+
if( !$resultOptions ) {
|
307 |
+
$this->log( "Search & Replace: Failed to update usermeta meta_key database table prefixes; {$this->db->last_error}", Logger::TYPE_ERROR );
|
308 |
+
return false;
|
309 |
+
}
|
310 |
+
|
311 |
+
$this->log( "Updating {$this->prefix}options, option_name database table prefixes; {$this->db->last_error}" );
|
312 |
+
|
313 |
+
$resultUserMeta = $this->db->query(
|
314 |
+
$this->db->prepare(
|
315 |
+
"UPDATE {$this->prefix}options SET option_name= replace(option_name, %s, %s) WHERE option_name LIKE %s", $this->db->prefix, $this->prefix, $this->db->prefix . "_%"
|
316 |
+
)
|
317 |
+
);
|
318 |
+
|
319 |
+
if( !$resultUserMeta ) {
|
320 |
+
$this->log( "Search & Replace: Failed to update options, option_name database table prefixes; {$this->db->last_error}", Logger::TYPE_ERROR );
|
321 |
+
return false;
|
322 |
+
}
|
323 |
+
|
324 |
+
return true;
|
325 |
+
}
|
326 |
+
|
327 |
+
/**
|
328 |
+
* Update $table_prefix in wp-config.php
|
329 |
+
* @return bool
|
330 |
+
*/
|
331 |
+
protected function step5()
|
332 |
+
{
|
333 |
+
$path = ABSPATH . $this->options->cloneDirectoryName . "/wp-config.php";
|
334 |
+
|
335 |
+
$this->log("Search & Replace: Updating table_prefix in {$path} to " . $this->prefix);
|
336 |
+
if (false === ($content = file_get_contents($path)))
|
337 |
+
{
|
338 |
+
$this->log("Search & Replace: Failed to update table_prefix in {$path}. Can't read contents", Logger::TYPE_ERROR);
|
339 |
+
return false;
|
340 |
+
}
|
341 |
+
|
342 |
+
// Replace table prefix
|
343 |
+
$content = str_replace('$table_prefix', '$table_prefix = \'' . $this->prefix . '\';//', $content);
|
344 |
+
|
345 |
+
// Replace URLs
|
346 |
+
$content = str_replace(get_home_url(), get_home_url() . '/' . $this->options->cloneDirectoryName, $content);
|
347 |
+
|
348 |
+
if (false === @file_put_contents($path, $content))
|
349 |
+
{
|
350 |
+
$this->log("Search & Replace: Failed to update $table_prefix in {$path} to " .$this->prefix . ". Can't save contents", Logger::TYPE_ERROR);
|
351 |
+
return false;
|
352 |
+
}
|
353 |
+
|
354 |
+
return true;
|
355 |
+
}
|
356 |
+
|
357 |
+
/**
|
358 |
+
* Reset index.php to original file
|
359 |
+
* Check first if main wordpress is used in subfolder and index.php in parent directory
|
360 |
+
* @see: https://codex.wordpress.org/Giving_WordPress_Its_Own_Directory
|
361 |
+
* @return bool
|
362 |
+
*/
|
363 |
+
protected function step6()
|
364 |
+
{
|
365 |
+
// No settings, all good
|
366 |
+
if (!isset($this->settings->wpSubDirectory) || "1" !== $this->settings->wpSubDirectory)
|
367 |
+
{
|
368 |
+
$this->log("Search & Replace: WP installation is not in a subdirectory! All good, skipping this step");
|
369 |
+
return true;
|
370 |
+
}
|
371 |
+
|
372 |
+
$path = ABSPATH . $this->options->cloneDirectoryName . "/index.php";
|
373 |
+
|
374 |
+
if (false === ($content = file_get_contents($path)))
|
375 |
+
{
|
376 |
+
$this->log("Search & Replace: Failed to reset {$path} for sub directory; can't read contents", Logger::TYPE_ERROR);
|
377 |
+
return false;
|
378 |
+
}
|
379 |
+
|
380 |
+
|
381 |
+
if (!preg_match("/(require(.*)wp-blog-header.php' \);)/", $content, $matches))
|
382 |
+
{
|
383 |
+
$this->log(
|
384 |
+
"Search & Replace: Failed to reset index.php for sub directory; wp-blog-header.php is missing",
|
385 |
+
Logger::TYPE_ERROR
|
386 |
+
);
|
387 |
+
return false;
|
388 |
+
}
|
389 |
+
|
390 |
+
$pattern = "/require(.*) dirname(.*) __FILE__ (.*) \. '(.*)wp-blog-header.php'(.*);/";
|
391 |
+
|
392 |
+
$replace = "require( dirname( __FILE__ ) . '/wp-blog-header.php' ); // " . $matches[0];
|
393 |
+
$replace.= " // Changed by WP-Staging";
|
394 |
+
|
395 |
+
if (null === preg_replace($pattern, $replace, $content))
|
396 |
+
{
|
397 |
+
$this->log("Search & Replace: Failed to reset index.php for sub directory; replacement failed", Logger::TYPE_ERROR);
|
398 |
+
return false;
|
399 |
+
}
|
400 |
+
|
401 |
+
if (false === @file_put_contents($path, $content))
|
402 |
+
{
|
403 |
+
$this->log("Search & Replace: Failed to reset index.php for sub directory; can't save contents", Logger::TYPE_ERROR);
|
404 |
+
return false;
|
405 |
+
}
|
406 |
+
|
407 |
+
return true;
|
408 |
+
}
|
409 |
}
|
apps/Backend/Modules/Jobs/Database.php
CHANGED
@@ -1,251 +1,263 @@
|
|
1 |
-
<?php
|
2 |
-
namespace WPStaging\Backend\Modules\Jobs;
|
3 |
-
|
4 |
-
//
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
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 |
-
|
118 |
-
|
119 |
-
|
120 |
-
//
|
121 |
-
$this->
|
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 |
-
$this->
|
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 |
-
return
|
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 |
}
|
1 |
+
<?php
|
2 |
+
namespace WPStaging\Backend\Modules\Jobs;
|
3 |
+
|
4 |
+
// No Direct Access
|
5 |
+
if (!defined("WPINC"))
|
6 |
+
{
|
7 |
+
die;
|
8 |
+
}
|
9 |
+
|
10 |
+
use WPStaging\WPStaging;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Class Database
|
14 |
+
* @package WPStaging\Backend\Modules\Jobs
|
15 |
+
*/
|
16 |
+
class Database extends JobExecutable
|
17 |
+
{
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @var int
|
21 |
+
*/
|
22 |
+
private $total = 0;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @var \WPDB
|
26 |
+
*/
|
27 |
+
private $db;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Initialize
|
31 |
+
*/
|
32 |
+
public function initialize()
|
33 |
+
{
|
34 |
+
// Variables
|
35 |
+
$this->total = count($this->options->tables);
|
36 |
+
$this->db = WPStaging::getInstance()->get("wpdb");
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Calculate Total Steps in This Job and Assign It to $this->options->totalSteps
|
41 |
+
* @return void
|
42 |
+
*/
|
43 |
+
protected function calculateTotalSteps()
|
44 |
+
{
|
45 |
+
$this->options->totalSteps = $this->total;
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Execute the Current Step
|
50 |
+
* Returns false when over threshold limits are hit or when the job is done, true otherwise
|
51 |
+
* @return bool
|
52 |
+
*/
|
53 |
+
protected function execute()
|
54 |
+
{
|
55 |
+
// Over limits threshold
|
56 |
+
if ($this->isOverThreshold())
|
57 |
+
{
|
58 |
+
// Prepare response and save current progress
|
59 |
+
$this->prepareResponse(false, false);
|
60 |
+
$this->saveOptions();
|
61 |
+
return false;
|
62 |
+
}
|
63 |
+
|
64 |
+
// No more steps, finished
|
65 |
+
if ($this->options->currentStep > $this->total || !isset($this->options->tables[$this->options->currentStep]))
|
66 |
+
{
|
67 |
+
$this->prepareResponse(true, false);
|
68 |
+
return false;
|
69 |
+
}
|
70 |
+
|
71 |
+
// Table is excluded
|
72 |
+
if (in_array($this->options->tables[$this->options->currentStep]->name, $this->options->excludedTables))
|
73 |
+
{
|
74 |
+
$this->prepareResponse();
|
75 |
+
return true;
|
76 |
+
}
|
77 |
+
|
78 |
+
// Copy table
|
79 |
+
if (!$this->copyTable($this->options->tables[$this->options->currentStep]->name))
|
80 |
+
{
|
81 |
+
// Prepare Response
|
82 |
+
$this->prepareResponse(false, false);
|
83 |
+
|
84 |
+
// Not finished
|
85 |
+
return true;
|
86 |
+
}
|
87 |
+
|
88 |
+
// Prepare Response
|
89 |
+
$this->prepareResponse();
|
90 |
+
|
91 |
+
// Not finished
|
92 |
+
return true;
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Get new prefix for the staging site
|
97 |
+
* @return string
|
98 |
+
*/
|
99 |
+
private function getStagingPrefix(){
|
100 |
+
$stagingPrefix = $this->options->prefix;
|
101 |
+
// Make sure prefix of staging site is NEVER identical to prefix of live site!
|
102 |
+
if ( $stagingPrefix == $this->db->prefix ){
|
103 |
+
wp_die('Fatal error 7: The new database table prefix '. $stagingPrefix .' would be identical to the table prefix of the live site. Please open a support ticket to support@wp-staging.com');
|
104 |
+
}
|
105 |
+
return $stagingPrefix;
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* No worries, SQL queries don't eat from PHP execution time!
|
110 |
+
* @param string $tableName
|
111 |
+
* @return bool
|
112 |
+
*/
|
113 |
+
private function copyTable($tableName)
|
114 |
+
{
|
115 |
+
//$this->returnException($this->getStagingPrefix());
|
116 |
+
|
117 |
+
//$newTableName = "wpstg{$this->options->cloneNumber}_" . str_replace($this->db->prefix, null, $tableName);
|
118 |
+
$newTableName = $this->getStagingPrefix() . str_replace($this->db->prefix, null, $tableName);
|
119 |
+
|
120 |
+
// Drop table if necessary
|
121 |
+
$this->dropTable($newTableName);
|
122 |
+
|
123 |
+
// Save current job
|
124 |
+
$this->setJob($newTableName);
|
125 |
+
|
126 |
+
// Beginning of the job
|
127 |
+
if (!$this->startJob($newTableName, $tableName))
|
128 |
+
{
|
129 |
+
return true;
|
130 |
+
}
|
131 |
+
|
132 |
+
// Copy data
|
133 |
+
$this->copyData($newTableName, $tableName);
|
134 |
+
|
135 |
+
// Finis the step
|
136 |
+
return $this->finishStep();
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Copy data from old table to new table
|
141 |
+
* @param string $new
|
142 |
+
* @param string $old
|
143 |
+
*/
|
144 |
+
private function copyData($new, $old)
|
145 |
+
{
|
146 |
+
$rows = $this->options->job->start+$this->settings->queryLimit;
|
147 |
+
$this->log(
|
148 |
+
"DB Copy: {$old} as {$new} between {$this->options->job->start} to {$rows} records"
|
149 |
+
);
|
150 |
+
|
151 |
+
$limitation = '';
|
152 |
+
|
153 |
+
if (0 < (int) $this->settings->queryLimit)
|
154 |
+
{
|
155 |
+
$limitation = " LIMIT {$this->settings->queryLimit} OFFSET {$this->options->job->start}";
|
156 |
+
}
|
157 |
+
|
158 |
+
$this->db->query(
|
159 |
+
"INSERT INTO {$new} SELECT * FROM {$old} {$limitation}"
|
160 |
+
);
|
161 |
+
|
162 |
+
// Set new offset
|
163 |
+
$this->options->job->start += $this->settings->queryLimit;
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Set the job
|
168 |
+
* @param string $table
|
169 |
+
*/
|
170 |
+
private function setJob($table)
|
171 |
+
{
|
172 |
+
if (isset($this->options->job->current))
|
173 |
+
{
|
174 |
+
return;
|
175 |
+
}
|
176 |
+
|
177 |
+
$this->options->job->current = $table;
|
178 |
+
$this->options->job->start = 0;
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* Start Job
|
183 |
+
* @param string $new
|
184 |
+
* @param string $old
|
185 |
+
* @return bool
|
186 |
+
*/
|
187 |
+
private function startJob($new, $old)
|
188 |
+
{
|
189 |
+
if (0 != $this->options->job->start)
|
190 |
+
{
|
191 |
+
return true;
|
192 |
+
}
|
193 |
+
|
194 |
+
$this->log("DB Copy: Creating table {$new} like {$old}");
|
195 |
+
|
196 |
+
$this->db->query("CREATE TABLE {$new} LIKE {$old}");
|
197 |
+
|
198 |
+
$this->options->job->total = (int) $this->db->get_var("SELECT COUNT(1) FROM {$old}");
|
199 |
+
|
200 |
+
if (0 == $this->options->job->total)
|
201 |
+
{
|
202 |
+
$this->finishStep();
|
203 |
+
return false;
|
204 |
+
}
|
205 |
+
|
206 |
+
return true;
|
207 |
+
}
|
208 |
+
|
209 |
+
/**
|
210 |
+
* Finish the step
|
211 |
+
*/
|
212 |
+
private function finishStep()
|
213 |
+
{
|
214 |
+
// This job is not finished yet
|
215 |
+
if ($this->options->job->total > $this->options->job->start)
|
216 |
+
{
|
217 |
+
return false;
|
218 |
+
}
|
219 |
+
|
220 |
+
// Add it to cloned tables listing
|
221 |
+
$this->options->clonedTables[] = $this->options->tables[$this->options->currentStep];
|
222 |
+
|
223 |
+
// Reset job
|
224 |
+
$this->options->job = new \stdClass();
|
225 |
+
|
226 |
+
return true;
|
227 |
+
}
|
228 |
+
|
229 |
+
/**
|
230 |
+
* Drop table if necessary
|
231 |
+
* @param string $new
|
232 |
+
*/
|
233 |
+
private function dropTable($new)
|
234 |
+
{
|
235 |
+
$old = $this->db->get_var($this->db->prepare("SHOW TABLES LIKE %s", $new));
|
236 |
+
|
237 |
+
if (!$this->shouldDropTable($new, $old))
|
238 |
+
{
|
239 |
+
return;
|
240 |
+
}
|
241 |
+
|
242 |
+
$this->log("DB Copy: {$new} already exists, dropping it first");
|
243 |
+
$this->db->query("DROP TABLE {$new}");
|
244 |
+
}
|
245 |
+
|
246 |
+
/**
|
247 |
+
* Check if table needs to be dropped
|
248 |
+
* @param string $new
|
249 |
+
* @param string $old
|
250 |
+
* @return bool
|
251 |
+
*/
|
252 |
+
private function shouldDropTable($new, $old)
|
253 |
+
{
|
254 |
+
return (
|
255 |
+
$old === $new &&
|
256 |
+
(
|
257 |
+
!isset($this->options->job->current) ||
|
258 |
+
!isset($this->options->job->start) ||
|
259 |
+
0 == $this->options->job->start
|
260 |
+
)
|
261 |
+
);
|
262 |
+
}
|
263 |
}
|
apps/Backend/Modules/Jobs/Delete.php
CHANGED
@@ -117,6 +117,49 @@ class Delete extends Job {
|
|
117 |
* Check and return prefix of the staging site
|
118 |
*/
|
119 |
public function getStagingPrefix() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
// prefix not defined! Happens if staging site has ben generated with older version of wpstg
|
121 |
// Try to get staging prefix from wp-config.php of staging site
|
122 |
//wp_die($this->clone->directoryName);
|
@@ -146,12 +189,11 @@ class Delete extends Job {
|
|
146 |
|
147 |
// Check if staging prefix is the same as the live prefix
|
148 |
if ($this->wpdb->prefix == $this->clone->prefix) {
|
149 |
-
|
150 |
-
wp_die("Fatal Error: Can not delete staging site. Prefix. '{$this->clone->prefix}' is used for the live site. Creating a new staging site will likely resolve this the next time. Stopping for security reasons. Contact support@wp-staging.com");
|
151 |
}
|
152 |
|
153 |
// Else
|
154 |
-
return
|
155 |
}
|
156 |
|
157 |
/**
|
@@ -215,12 +257,23 @@ class Delete extends Job {
|
|
215 |
return;
|
216 |
}
|
217 |
|
218 |
-
//
|
219 |
-
$this->
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
224 |
|
225 |
$this->cache->save("delete_job_{$this->clone->name}", $this->job);
|
226 |
}
|
@@ -263,12 +316,11 @@ class Delete extends Job {
|
|
263 |
return;
|
264 |
}
|
265 |
|
266 |
-
//$wpdb = WPStaging::getInstance()->get("wpdb");
|
267 |
|
268 |
foreach ($this->getTablesToRemove() as $table) {
|
269 |
// PROTECTION: Never delete any table that beginns with wp prefix of live site
|
270 |
if ($this->startsWith($table, $this->wpdb->prefix)) {
|
271 |
-
$this->log("Fatal Error: Trying to delete table {$table} of main WP installation!", Logger::TYPE_CRITICAL);
|
272 |
return false;
|
273 |
} else {
|
274 |
$this->wpdb->query("DROP TABLE {$table}");
|
@@ -328,36 +380,14 @@ class Delete extends Job {
|
|
328 |
return;
|
329 |
}
|
330 |
}
|
331 |
-
|
332 |
-
|
333 |
-
// return $this->returnException('Unable to delete all files in folder' . $this->clone->path . '<br>Please try to delete the folder manually via FTP. Than run the delete function again.');
|
334 |
-
// } else {
|
335 |
-
// return $this->returnFinish();
|
336 |
-
// }
|
337 |
-
if (@rmdir($this->clone->path)){
|
338 |
return $this->returnFinish();
|
339 |
}
|
340 |
return;
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
}
|
345 |
|
346 |
-
/**
|
347 |
-
* Delete Directories
|
348 |
-
*/
|
349 |
-
public function deleteDirectory_old() {
|
350 |
-
// No deleting directories or root of this clone is deleted
|
351 |
-
if ($this->isDirectoryDeletingFinished()) {
|
352 |
-
$this->job->current = "finish";
|
353 |
-
$this->updateJob();
|
354 |
-
return;
|
355 |
-
}
|
356 |
-
|
357 |
-
$this->processDirectory($this->job->nextDirectoryToDelete);
|
358 |
|
359 |
-
return;
|
360 |
-
}
|
361 |
|
362 |
/**
|
363 |
* @return bool
|
@@ -456,18 +486,7 @@ class Delete extends Job {
|
|
456 |
wp_die(json_encode($response));
|
457 |
}
|
458 |
|
459 |
-
|
460 |
-
* Get json response
|
461 |
-
* return json
|
462 |
-
*/
|
463 |
-
// private function returnException($message = ''){
|
464 |
-
// wp_die( json_encode(array(
|
465 |
-
// 'job' => 'delete',
|
466 |
-
// 'status' => false,
|
467 |
-
// 'message' => $message,
|
468 |
-
// 'error' => true
|
469 |
-
// )));
|
470 |
-
// }
|
471 |
/**
|
472 |
* Get json response
|
473 |
* return json
|
117 |
* Check and return prefix of the staging site
|
118 |
*/
|
119 |
public function getStagingPrefix() {
|
120 |
+
// prefix not defined! Happens if staging site has ben generated with older version of wpstg
|
121 |
+
// Try to get staging prefix from wp-config.php of staging site
|
122 |
+
//wp_die($this->clone->directoryName);
|
123 |
+
if (empty($this->clone->prefix)) {
|
124 |
+
// Throw error
|
125 |
+
$path = ABSPATH . $this->clone->directoryName . "/wp-config.php";
|
126 |
+
if (false === ($content = @file_get_contents($path))) {
|
127 |
+
$this->log("Can not open {$path}. Can't read contents", Logger::TYPE_ERROR);
|
128 |
+
// Create a random prefix which highly like never exists
|
129 |
+
$this->clone->prefix = rand(7, 15) . '_';
|
130 |
+
} else {
|
131 |
+
|
132 |
+
// Get prefix from wp-config.php
|
133 |
+
//preg_match_all("/table_prefix\s*=\s*'(\w*)';/", $content, $matches);
|
134 |
+
preg_match("/table_prefix\s*=\s*'(\w*)';/", $content, $matches);
|
135 |
+
|
136 |
+
if (!empty($matches[1])) {
|
137 |
+
$this->clone->prefix = $matches[1];
|
138 |
+
} else {
|
139 |
+
$this->log("Can not find Prefix. '{$matches[1]}'.");
|
140 |
+
// Create a random prefix which highly like never exists
|
141 |
+
return $this->clone->prefix = rand(7, 15) . '_';
|
142 |
+
}
|
143 |
+
}
|
144 |
+
}
|
145 |
+
|
146 |
+
// Check if staging prefix is the same as the live prefix
|
147 |
+
if ($this->wpdb->prefix == $this->clone->prefix) {
|
148 |
+
// Create a random prefix which highly like never exists
|
149 |
+
return $this->clone->prefix = rand(7, 15) . '_';
|
150 |
+
$this->log("Can not use prefix. '{$this->clone->prefix}', is used for the live site. Creating a new random prefix");
|
151 |
+
//wp_die("Fatal Error: Can not delete staging site. Prefix. '{$this->clone->prefix}' is used for the live site. Creating a new staging site will likely resolve this the next time. Stopping for security reasons. Contact support@wp-staging.com");
|
152 |
+
}
|
153 |
+
|
154 |
+
// Else
|
155 |
+
return $this->clone->prefix;
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Check if we can delete the staging site tables without affecting live ones
|
160 |
+
* @return bool
|
161 |
+
*/
|
162 |
+
public function isInvalidStagingPrefix() {
|
163 |
// prefix not defined! Happens if staging site has ben generated with older version of wpstg
|
164 |
// Try to get staging prefix from wp-config.php of staging site
|
165 |
//wp_die($this->clone->directoryName);
|
189 |
|
190 |
// Check if staging prefix is the same as the live prefix
|
191 |
if ($this->wpdb->prefix == $this->clone->prefix) {
|
192 |
+
return true;
|
|
|
193 |
}
|
194 |
|
195 |
// Else
|
196 |
+
return false;
|
197 |
}
|
198 |
|
199 |
/**
|
257 |
return;
|
258 |
}
|
259 |
|
260 |
+
// Skip deletion of tables and generate JOB to delete directories
|
261 |
+
if ($this->isInvalidStagingPrefix()) {
|
262 |
+
$this->log('Invalid staging prefix. Skip deleting tables');
|
263 |
+
// Generate JOB and delete tables
|
264 |
+
$this->job = (object) array(
|
265 |
+
"current" => "directory",
|
266 |
+
"nextDirectoryToDelete" => $this->clone->path,
|
267 |
+
"name" => $this->clone->name
|
268 |
+
);
|
269 |
+
} else {
|
270 |
+
// Generate JOB and delete tables
|
271 |
+
$this->job = (object) array(
|
272 |
+
"current" => "tables",
|
273 |
+
"nextDirectoryToDelete" => $this->clone->path,
|
274 |
+
"name" => $this->clone->name
|
275 |
+
);
|
276 |
+
}
|
277 |
|
278 |
$this->cache->save("delete_job_{$this->clone->name}", $this->job);
|
279 |
}
|
316 |
return;
|
317 |
}
|
318 |
|
|
|
319 |
|
320 |
foreach ($this->getTablesToRemove() as $table) {
|
321 |
// PROTECTION: Never delete any table that beginns with wp prefix of live site
|
322 |
if ($this->startsWith($table, $this->wpdb->prefix)) {
|
323 |
+
$this->log("Fatal Error: Trying to delete table {$table} of main WP installation! Contact support[at]wp-staging.com", Logger::TYPE_CRITICAL);
|
324 |
return false;
|
325 |
} else {
|
326 |
$this->wpdb->query("DROP TABLE {$table}");
|
380 |
return;
|
381 |
}
|
382 |
}
|
383 |
+
|
384 |
+
if (@rmdir($this->clone->path)) {
|
|
|
|
|
|
|
|
|
|
|
385 |
return $this->returnFinish();
|
386 |
}
|
387 |
return;
|
|
|
|
|
|
|
388 |
}
|
389 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
390 |
|
|
|
|
|
391 |
|
392 |
/**
|
393 |
* @return bool
|
486 |
wp_die(json_encode($response));
|
487 |
}
|
488 |
|
489 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
490 |
/**
|
491 |
* Get json response
|
492 |
* return json
|
apps/Backend/Modules/Jobs/Files.php
CHANGED
@@ -1,11 +1,11 @@
|
|
1 |
<?php
|
|
|
2 |
namespace WPStaging\Backend\Modules\Jobs;
|
3 |
|
4 |
// No Direct Access
|
5 |
use WPStaging\Utils\Logger;
|
6 |
|
7 |
-
if (!defined("WPINC"))
|
8 |
-
{
|
9 |
die;
|
10 |
}
|
11 |
|
@@ -13,8 +13,7 @@ if (!defined("WPINC"))
|
|
13 |
* Class Files
|
14 |
* @package WPStaging\Backend\Modules\Jobs
|
15 |
*/
|
16 |
-
class Files extends JobExecutable
|
17 |
-
{
|
18 |
|
19 |
/**
|
20 |
* @var \SplFileObject
|
@@ -24,7 +23,13 @@ class Files extends JobExecutable
|
|
24 |
/**
|
25 |
* @var int
|
26 |
*/
|
|
|
27 |
private $maxFilesPerRun;
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
/**
|
30 |
* @var string
|
@@ -34,34 +39,35 @@ class Files extends JobExecutable
|
|
34 |
/**
|
35 |
* Initialization
|
36 |
*/
|
37 |
-
public function initialize()
|
38 |
-
|
|
|
39 |
$this->destination = ABSPATH . $this->options->cloneDirectoryName . DIRECTORY_SEPARATOR;
|
40 |
|
41 |
$filePath = $this->cache->getCacheDir() . "files_to_copy." . $this->cache->getCacheExtension();
|
42 |
|
43 |
-
if (is_file($filePath))
|
44 |
-
{
|
45 |
$this->file = new \SplFileObject($filePath, 'r');
|
46 |
}
|
47 |
|
48 |
// Informational logs
|
49 |
-
if (0 == $this->options->currentStep)
|
50 |
-
{
|
51 |
$this->log("Copying files...");
|
52 |
}
|
53 |
|
54 |
$this->settings->batchSize = $this->settings->batchSize * 1000000;
|
55 |
$this->maxFilesPerRun = $this->settings->fileLimit;
|
|
|
|
|
56 |
}
|
57 |
|
58 |
/**
|
59 |
* Calculate Total Steps in This Job and Assign It to $this->options->totalSteps
|
60 |
* @return void
|
61 |
*/
|
62 |
-
protected function calculateTotalSteps()
|
63 |
-
{
|
64 |
$this->options->totalSteps = ceil($this->options->totalFiles / $this->maxFilesPerRun);
|
|
|
65 |
}
|
66 |
|
67 |
/**
|
@@ -69,19 +75,16 @@ class Files extends JobExecutable
|
|
69 |
* Returns false when over threshold limits are hit or when the job is done, true otherwise
|
70 |
* @return bool
|
71 |
*/
|
72 |
-
protected function execute()
|
73 |
-
{
|
74 |
// Finished
|
75 |
-
if ($this->isFinished())
|
76 |
-
{
|
77 |
$this->log("Copying files finished");
|
78 |
$this->prepareResponse(true, false);
|
79 |
return false;
|
80 |
}
|
81 |
|
82 |
// Get files and copy'em
|
83 |
-
if (!$this->getFilesAndCopy())
|
84 |
-
{
|
85 |
$this->prepareResponse(false, false);
|
86 |
return false;
|
87 |
}
|
@@ -97,39 +100,52 @@ class Files extends JobExecutable
|
|
97 |
* Get files and copy
|
98 |
* @return bool
|
99 |
*/
|
100 |
-
private function getFilesAndCopy()
|
101 |
-
{
|
102 |
// Over limits threshold
|
103 |
-
if ($this->isOverThreshold())
|
104 |
-
{
|
105 |
// Prepare response and save current progress
|
106 |
$this->prepareResponse(false, false);
|
107 |
$this->saveOptions();
|
108 |
return false;
|
109 |
}
|
110 |
|
111 |
-
//
|
112 |
-
if ($this->options->copiedFiles != 0)
|
113 |
-
{
|
114 |
$this->file->seek($this->options->copiedFiles);
|
115 |
}
|
116 |
|
117 |
$this->file->setFlags(\SplFileObject::SKIP_EMPTY | \SplFileObject::READ_AHEAD);
|
118 |
|
119 |
-
//
|
120 |
-
|
121 |
-
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
122 |
// End of file
|
123 |
-
if ($this->file->eof())
|
124 |
-
{
|
125 |
break;
|
126 |
}
|
|
|
|
|
|
|
|
|
127 |
|
128 |
-
$this->copyFile($this->file->fgets());
|
129 |
}
|
130 |
|
131 |
$totalFiles = $this->maxFilesPerRun + $this->options->copiedFiles;
|
|
|
132 |
$this->log("Total {$totalFiles} files processed");
|
|
|
133 |
|
134 |
return true;
|
135 |
}
|
@@ -138,36 +154,28 @@ class Files extends JobExecutable
|
|
138 |
* Checks Whether There is Any Job to Execute or Not
|
139 |
* @return bool
|
140 |
*/
|
141 |
-
private function isFinished()
|
142 |
-
{
|
143 |
return (
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
}
|
148 |
|
149 |
/**
|
150 |
* @param string $file
|
151 |
* @return bool
|
152 |
*/
|
153 |
-
private function copyFile($file)
|
154 |
-
{
|
155 |
$file = trim($file);
|
156 |
|
157 |
-
// Increment copied files whatever the result is
|
158 |
-
// This way we don't get stuck in the same step / files
|
159 |
-
$this->options->copiedFiles++;
|
160 |
-
|
161 |
// Invalid file, skipping it as if succeeded
|
162 |
-
if (!is_file($file) || !is_readable($file))
|
163 |
-
{
|
164 |
$this->log("Can't read file or file doesn't exist {$file}");
|
165 |
return true;
|
166 |
}
|
167 |
|
168 |
// Failed to get destination
|
169 |
-
if (false === ($destination = $this->getDestination($file)))
|
170 |
-
{
|
171 |
$this->log("Can't get the destination of {$file}");
|
172 |
return false;
|
173 |
}
|
@@ -182,14 +190,12 @@ class Files extends JobExecutable
|
|
182 |
* @param string $file
|
183 |
* @return bool|string
|
184 |
*/
|
185 |
-
private function getDestination($file)
|
186 |
-
|
187 |
-
$
|
188 |
-
$
|
189 |
-
|
190 |
-
|
191 |
-
if (!is_dir($destinationDirectory) && !@mkdir($destinationDirectory, 0775, true))
|
192 |
-
{
|
193 |
$this->log("Destination directory doesn't exist; {$destinationDirectory}", Logger::TYPE_ERROR);
|
194 |
return false;
|
195 |
}
|
@@ -203,21 +209,18 @@ class Files extends JobExecutable
|
|
203 |
* @param string $destination
|
204 |
* @return bool
|
205 |
*/
|
206 |
-
private function copy($file, $destination)
|
207 |
-
{
|
208 |
// Get file size
|
209 |
$fileSize = filesize($file);
|
210 |
|
211 |
// File is over batch size
|
212 |
-
if ($fileSize >= $this->settings->batchSize)
|
213 |
-
{
|
214 |
$this->log("Trying to copy big file {$file} -> {$destination}", Logger::TYPE_INFO);
|
215 |
return $this->copyBig($file, $destination, $this->settings->batchSize);
|
216 |
}
|
217 |
|
218 |
// Attempt to copy
|
219 |
-
if (!@copy($file, $destination))
|
220 |
-
{
|
221 |
$this->log("Failed to copy file to destination: {$file} -> {$destination}", Logger::TYPE_ERROR);
|
222 |
return false;
|
223 |
}
|
@@ -251,7 +254,7 @@ class Files extends JobExecutable
|
|
251 |
//
|
252 |
// return ($bytes > 0);
|
253 |
// }
|
254 |
-
|
255 |
/**
|
256 |
* Copy bigger files than $this->settings->batchSize
|
257 |
* @param string $src
|
@@ -260,19 +263,19 @@ class Files extends JobExecutable
|
|
260 |
* @return boolean
|
261 |
*/
|
262 |
private function copyBig($src, $dst, $buffersize) {
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
// Try first method:
|
267 |
-
while (!
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
}
|
272 |
// Try second method if first one failed
|
273 |
-
if (isset($error) && ($error === true)){
|
274 |
-
while(!feof($src)){
|
275 |
-
if (false === stream_copy_to_stream($src, $dest, 1024
|
276 |
$this->log("Can not copy big file; {$src} -> {$dest}");
|
277 |
fclose($src);
|
278 |
fclose($dest);
|
@@ -284,5 +287,32 @@ class Files extends JobExecutable
|
|
284 |
fclose($src);
|
285 |
fclose($dest);
|
286 |
return true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
287 |
}
|
288 |
-
}
|
1 |
<?php
|
2 |
+
|
3 |
namespace WPStaging\Backend\Modules\Jobs;
|
4 |
|
5 |
// No Direct Access
|
6 |
use WPStaging\Utils\Logger;
|
7 |
|
8 |
+
if (!defined("WPINC")) {
|
|
|
9 |
die;
|
10 |
}
|
11 |
|
13 |
* Class Files
|
14 |
* @package WPStaging\Backend\Modules\Jobs
|
15 |
*/
|
16 |
+
class Files extends JobExecutable {
|
|
|
17 |
|
18 |
/**
|
19 |
* @var \SplFileObject
|
23 |
/**
|
24 |
* @var int
|
25 |
*/
|
26 |
+
//private $maxFilesPerRun = 500;
|
27 |
private $maxFilesPerRun;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* File Object
|
31 |
+
*/
|
32 |
+
//private $verifyFiles = array();
|
33 |
|
34 |
/**
|
35 |
* @var string
|
39 |
/**
|
40 |
* Initialization
|
41 |
*/
|
42 |
+
public function initialize() {
|
43 |
+
//$this->getVerifyFiles();
|
44 |
+
|
45 |
$this->destination = ABSPATH . $this->options->cloneDirectoryName . DIRECTORY_SEPARATOR;
|
46 |
|
47 |
$filePath = $this->cache->getCacheDir() . "files_to_copy." . $this->cache->getCacheExtension();
|
48 |
|
49 |
+
if (is_file($filePath)) {
|
|
|
50 |
$this->file = new \SplFileObject($filePath, 'r');
|
51 |
}
|
52 |
|
53 |
// Informational logs
|
54 |
+
if (0 == $this->options->currentStep) {
|
|
|
55 |
$this->log("Copying files...");
|
56 |
}
|
57 |
|
58 |
$this->settings->batchSize = $this->settings->batchSize * 1000000;
|
59 |
$this->maxFilesPerRun = $this->settings->fileLimit;
|
60 |
+
//$this->maxFilesPerRun = 1;
|
61 |
+
//$this->options->copiedFiles = 0;
|
62 |
}
|
63 |
|
64 |
/**
|
65 |
* Calculate Total Steps in This Job and Assign It to $this->options->totalSteps
|
66 |
* @return void
|
67 |
*/
|
68 |
+
protected function calculateTotalSteps() {
|
|
|
69 |
$this->options->totalSteps = ceil($this->options->totalFiles / $this->maxFilesPerRun);
|
70 |
+
//$this->options->totalSteps = $this->options->totalFiles;
|
71 |
}
|
72 |
|
73 |
/**
|
75 |
* Returns false when over threshold limits are hit or when the job is done, true otherwise
|
76 |
* @return bool
|
77 |
*/
|
78 |
+
protected function execute() {
|
|
|
79 |
// Finished
|
80 |
+
if ($this->isFinished()) {
|
|
|
81 |
$this->log("Copying files finished");
|
82 |
$this->prepareResponse(true, false);
|
83 |
return false;
|
84 |
}
|
85 |
|
86 |
// Get files and copy'em
|
87 |
+
if (!$this->getFilesAndCopy()) {
|
|
|
88 |
$this->prepareResponse(false, false);
|
89 |
return false;
|
90 |
}
|
100 |
* Get files and copy
|
101 |
* @return bool
|
102 |
*/
|
103 |
+
private function getFilesAndCopy() {
|
|
|
104 |
// Over limits threshold
|
105 |
+
if ($this->isOverThreshold()) {
|
|
|
106 |
// Prepare response and save current progress
|
107 |
$this->prepareResponse(false, false);
|
108 |
$this->saveOptions();
|
109 |
return false;
|
110 |
}
|
111 |
|
112 |
+
// Go to last copied line and than to next one
|
113 |
+
if ($this->options->copiedFiles != 0) {
|
|
|
114 |
$this->file->seek($this->options->copiedFiles);
|
115 |
}
|
116 |
|
117 |
$this->file->setFlags(\SplFileObject::SKIP_EMPTY | \SplFileObject::READ_AHEAD);
|
118 |
|
119 |
+
// End of file
|
120 |
+
// if ($this->file->eof())
|
121 |
+
// {
|
122 |
+
// // Increment copied files when end of file is reached
|
123 |
+
// $this->options->copiedFiles++;
|
124 |
+
// return;
|
125 |
+
// }
|
126 |
+
// Loop x files at a time
|
127 |
+
for ($i = 0; $i < $this->maxFilesPerRun; $i++) {
|
128 |
+
|
129 |
+
|
130 |
+
// Increment copied files
|
131 |
+
// Do this anytime to make sure to not stuck in the same step / files
|
132 |
+
$this->options->copiedFiles++;
|
133 |
+
|
134 |
// End of file
|
135 |
+
if ($this->file->eof()) {
|
|
|
136 |
break;
|
137 |
}
|
138 |
+
$file = $this->file->fgets();
|
139 |
+
$this->debugLog('copy file ' . $file, Logger::TYPE_DEBUG);
|
140 |
+
$this->copyFile($file);
|
141 |
+
//$this->verifyFiles[] = $file;
|
142 |
|
|
|
143 |
}
|
144 |
|
145 |
$totalFiles = $this->maxFilesPerRun + $this->options->copiedFiles;
|
146 |
+
//$totalFiles = $this->options->copiedFiles;
|
147 |
$this->log("Total {$totalFiles} files processed");
|
148 |
+
//$this->saveCopiedFiles();
|
149 |
|
150 |
return true;
|
151 |
}
|
154 |
* Checks Whether There is Any Job to Execute or Not
|
155 |
* @return bool
|
156 |
*/
|
157 |
+
private function isFinished() {
|
|
|
158 |
return (
|
159 |
+
$this->options->currentStep > $this->options->totalSteps ||
|
160 |
+
$this->options->copiedFiles >= $this->options->totalFiles
|
161 |
+
);
|
162 |
}
|
163 |
|
164 |
/**
|
165 |
* @param string $file
|
166 |
* @return bool
|
167 |
*/
|
168 |
+
private function copyFile($file) {
|
|
|
169 |
$file = trim($file);
|
170 |
|
|
|
|
|
|
|
|
|
171 |
// Invalid file, skipping it as if succeeded
|
172 |
+
if (!is_file($file) || !is_readable($file)) {
|
|
|
173 |
$this->log("Can't read file or file doesn't exist {$file}");
|
174 |
return true;
|
175 |
}
|
176 |
|
177 |
// Failed to get destination
|
178 |
+
if (false === ($destination = $this->getDestination($file))) {
|
|
|
179 |
$this->log("Can't get the destination of {$file}");
|
180 |
return false;
|
181 |
}
|
190 |
* @param string $file
|
191 |
* @return bool|string
|
192 |
*/
|
193 |
+
private function getDestination($file) {
|
194 |
+
$relativePath = str_replace(ABSPATH, null, $file);
|
195 |
+
$destinationPath = $this->destination . $relativePath;
|
196 |
+
$destinationDirectory = dirname($destinationPath);
|
197 |
+
|
198 |
+
if (!is_dir($destinationDirectory) && !@mkdir($destinationDirectory, 0775, true)) {
|
|
|
|
|
199 |
$this->log("Destination directory doesn't exist; {$destinationDirectory}", Logger::TYPE_ERROR);
|
200 |
return false;
|
201 |
}
|
209 |
* @param string $destination
|
210 |
* @return bool
|
211 |
*/
|
212 |
+
private function copy($file, $destination) {
|
|
|
213 |
// Get file size
|
214 |
$fileSize = filesize($file);
|
215 |
|
216 |
// File is over batch size
|
217 |
+
if ($fileSize >= $this->settings->batchSize) {
|
|
|
218 |
$this->log("Trying to copy big file {$file} -> {$destination}", Logger::TYPE_INFO);
|
219 |
return $this->copyBig($file, $destination, $this->settings->batchSize);
|
220 |
}
|
221 |
|
222 |
// Attempt to copy
|
223 |
+
if (!@copy($file, $destination)) {
|
|
|
224 |
$this->log("Failed to copy file to destination: {$file} -> {$destination}", Logger::TYPE_ERROR);
|
225 |
return false;
|
226 |
}
|
254 |
//
|
255 |
// return ($bytes > 0);
|
256 |
// }
|
257 |
+
|
258 |
/**
|
259 |
* Copy bigger files than $this->settings->batchSize
|
260 |
* @param string $src
|
263 |
* @return boolean
|
264 |
*/
|
265 |
private function copyBig($src, $dst, $buffersize) {
|
266 |
+
$src = fopen($src, 'r');
|
267 |
+
$dest = fopen($dst, 'w');
|
268 |
+
|
269 |
// Try first method:
|
270 |
+
while (!feof($src)) {
|
271 |
+
if (false === fwrite($dest, fread($src, $buffersize))) {
|
272 |
+
$error = true;
|
273 |
+
}
|
274 |
}
|
275 |
// Try second method if first one failed
|
276 |
+
if (isset($error) && ($error === true)) {
|
277 |
+
while (!feof($src)) {
|
278 |
+
if (false === stream_copy_to_stream($src, $dest, 1024)) {
|
279 |
$this->log("Can not copy big file; {$src} -> {$dest}");
|
280 |
fclose($src);
|
281 |
fclose($dest);
|
287 |
fclose($src);
|
288 |
fclose($dest);
|
289 |
return true;
|
290 |
+
}
|
291 |
+
|
292 |
+
/**
|
293 |
+
* Save verified Files
|
294 |
+
* @return bool
|
295 |
+
*/
|
296 |
+
// private function saveCopiedFiles(){
|
297 |
+
// $fileName = $this->cache->getCacheDir() . "files_to_verify." . $this->cache->getCacheExtension();
|
298 |
+
// $files = implode( PHP_EOL, $this->verifyFiles );
|
299 |
+
//
|
300 |
+
// return (false !== @file_put_contents( $fileName, $files ));
|
301 |
+
// }
|
302 |
+
|
303 |
+
/**
|
304 |
+
* Get files
|
305 |
+
* @return void
|
306 |
+
*/
|
307 |
+
// protected function getVerifyFiles() {
|
308 |
+
// $fileName = $this->cache->getCacheDir() . "files_to_verify." . $this->cache->getCacheExtension();
|
309 |
+
//
|
310 |
+
// if( false === ($this->verifyFiles = @file_get_contents( $fileName )) ) {
|
311 |
+
// $this->verifyFiles = array();
|
312 |
+
// return;
|
313 |
+
// }
|
314 |
+
//
|
315 |
+
// $this->verifyFiles = explode( PHP_EOL, $this->verifyFiles );
|
316 |
+
// }
|
317 |
+
|
318 |
}
|
|
apps/Backend/Modules/Jobs/Job.php
CHANGED
@@ -97,16 +97,10 @@ abstract class Job implements JobInterface
|
|
97 |
//$this->maxExecutionTime = (int) ini_get("max_execution_time");
|
98 |
$this->maxExecutionTime = (int) 30;
|
99 |
|
100 |
-
// if ($this->maxExecutionTime > 30)
|
101 |
// {
|
102 |
// $this->maxExecutionTime = 30;
|
103 |
// }
|
104 |
-
//
|
105 |
-
// if ($this->maxExecutionTime < 1)
|
106 |
-
// {
|
107 |
-
// $this->maxExecutionTime = 30;
|
108 |
-
// }
|
109 |
-
|
110 |
|
111 |
// Services
|
112 |
$this->cache = new Cache(-1, \WPStaging\WPStaging::getContentDir());
|
@@ -115,12 +109,9 @@ abstract class Job implements JobInterface
|
|
115 |
// Settings and Options
|
116 |
$this->options = $this->cache->get("clone_options");
|
117 |
//$this->settings = json_decode(json_encode(get_option("wpstg_settings", array())));
|
118 |
-
$this->settings = (object)get_option("wpstg_settings", array());
|
119 |
-
|
120 |
-
|
121 |
|
122 |
-
|
123 |
-
if (!$this->settings)
|
124 |
{
|
125 |
$this->options = new \stdClass();
|
126 |
}
|
@@ -130,7 +121,14 @@ abstract class Job implements JobInterface
|
|
130 |
$this->options->existingClones = json_decode(json_encode($this->options->existingClones), true);
|
131 |
}
|
132 |
|
133 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
{
|
135 |
$this->settings = new \stdClass();
|
136 |
$this->setDefaultSettings();
|
@@ -176,7 +174,7 @@ abstract class Job implements JobInterface
|
|
176 |
*/
|
177 |
protected function setDefaultSettings(){
|
178 |
$this->settings->queryLimit = "1000";
|
179 |
-
$this->settings->
|
180 |
$this->settings->batchSize = "2";
|
181 |
$this->settings->cpuLoad = 'medium';
|
182 |
update_option('wpstg_settings', $this->settings);
|
@@ -231,7 +229,6 @@ abstract class Job implements JobInterface
|
|
231 |
|
232 |
// Ensure that it is an object
|
233 |
$options = json_decode(json_encode($options));
|
234 |
-
|
235 |
return $this->cache->save("clone_options", $options);
|
236 |
}
|
237 |
|
@@ -320,8 +317,8 @@ abstract class Job implements JobInterface
|
|
320 |
|
321 |
if ($usedMemory >= $this->memoryLimit)
|
322 |
{
|
323 |
-
$this->log('Used Memory: ' . $this->formatBytes($usedMemory) . ' Memory Limit: ' . $this->formatBytes($this->maxMemoryLimit) . ' Max Script memory limit: ' . $this->formatBytes( $this->memoryLimit ) );
|
324 |
-
|
325 |
return true;
|
326 |
}
|
327 |
|
@@ -334,7 +331,7 @@ abstract class Job implements JobInterface
|
|
334 |
// Check if execution time is over threshold
|
335 |
///$time = round($this->start + $this->time(), 4);
|
336 |
$time = round($this->time() - $this->start, 4);
|
337 |
-
|
338 |
if ($time >= $this->executionLimit)
|
339 |
{
|
340 |
//$this->log('RESET TIME');
|
@@ -471,4 +468,17 @@ abstract class Job implements JobInterface
|
|
471 |
}
|
472 |
|
473 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
474 |
}
|
97 |
//$this->maxExecutionTime = (int) ini_get("max_execution_time");
|
98 |
$this->maxExecutionTime = (int) 30;
|
99 |
|
100 |
+
// if ($this->maxExecutionTime < 1 || $this->maxExecutionTime > 30)
|
101 |
// {
|
102 |
// $this->maxExecutionTime = 30;
|
103 |
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
104 |
|
105 |
// Services
|
106 |
$this->cache = new Cache(-1, \WPStaging\WPStaging::getContentDir());
|
109 |
// Settings and Options
|
110 |
$this->options = $this->cache->get("clone_options");
|
111 |
//$this->settings = json_decode(json_encode(get_option("wpstg_settings", array())));
|
112 |
+
$this->settings = (object) get_option("wpstg_settings", array());
|
|
|
|
|
113 |
|
114 |
+
if (!$this->options)
|
|
|
115 |
{
|
116 |
$this->options = new \stdClass();
|
117 |
}
|
121 |
$this->options->existingClones = json_decode(json_encode($this->options->existingClones), true);
|
122 |
}
|
123 |
|
124 |
+
// check default options
|
125 |
+
if ( !isset($this->settings) ||
|
126 |
+
!isset($this->settings->queryLimit) ||
|
127 |
+
!isset($this->settings->batchSize) ||
|
128 |
+
!isset($this->settings->cpuLoad) ||
|
129 |
+
!isset($this->settings->fileLimit)
|
130 |
+
)
|
131 |
+
|
132 |
{
|
133 |
$this->settings = new \stdClass();
|
134 |
$this->setDefaultSettings();
|
174 |
*/
|
175 |
protected function setDefaultSettings(){
|
176 |
$this->settings->queryLimit = "1000";
|
177 |
+
$this->settings->fileLimit = "10";
|
178 |
$this->settings->batchSize = "2";
|
179 |
$this->settings->cpuLoad = 'medium';
|
180 |
update_option('wpstg_settings', $this->settings);
|
229 |
|
230 |
// Ensure that it is an object
|
231 |
$options = json_decode(json_encode($options));
|
|
|
232 |
return $this->cache->save("clone_options", $options);
|
233 |
}
|
234 |
|
317 |
|
318 |
if ($usedMemory >= $this->memoryLimit)
|
319 |
{
|
320 |
+
$this->log('Used Memory: ' . $this->formatBytes($usedMemory) . ' Memory Limit: ' . $this->formatBytes($this->maxMemoryLimit) . ' Max Script memory limit: ' . $this->formatBytes( $this->memoryLimit ), Logger::TYPE_ERROR );
|
321 |
+
//$this->resetMemory();
|
322 |
return true;
|
323 |
}
|
324 |
|
331 |
// Check if execution time is over threshold
|
332 |
///$time = round($this->start + $this->time(), 4);
|
333 |
$time = round($this->time() - $this->start, 4);
|
334 |
+
|
335 |
if ($time >= $this->executionLimit)
|
336 |
{
|
337 |
//$this->log('RESET TIME');
|
468 |
}
|
469 |
|
470 |
}
|
471 |
+
|
472 |
+
/**
|
473 |
+
* Throw a errror message via json and stop further execution
|
474 |
+
* @param string $message
|
475 |
+
*/
|
476 |
+
protected function returnException($message = ''){
|
477 |
+
wp_die( json_encode(array(
|
478 |
+
'job' => $this->options->currentJob,
|
479 |
+
'status' => false,
|
480 |
+
'message' => $message,
|
481 |
+
'error' => true
|
482 |
+
)));
|
483 |
+
}
|
484 |
}
|
apps/Backend/Modules/Jobs/JobExecutable.php
CHANGED
@@ -1,109 +1,112 @@
|
|
1 |
-
<?php
|
2 |
-
namespace WPStaging\Backend\Modules\Jobs;
|
3 |
-
|
4 |
-
// No Direct Access
|
5 |
-
if (!defined("WPINC"))
|
6 |
-
{
|
7 |
-
die;
|
8 |
-
}
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
*
|
13 |
-
*
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
"
|
24 |
-
"
|
25 |
-
"
|
26 |
-
"
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
*
|
43 |
-
* @param bool $
|
44 |
-
* @
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
$percentage = (
|
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 |
}
|
1 |
+
<?php
|
2 |
+
namespace WPStaging\Backend\Modules\Jobs;
|
3 |
+
|
4 |
+
// No Direct Access
|
5 |
+
if (!defined("WPINC"))
|
6 |
+
{
|
7 |
+
die;
|
8 |
+
}
|
9 |
+
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Class JobExecutable
|
13 |
+
* I'm sorry for such mess, we need to support PHP 5.3
|
14 |
+
* @package WPStaging\Backend\Modules\Jobs
|
15 |
+
*/
|
16 |
+
abstract class JobExecutable extends Job
|
17 |
+
{
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @var array
|
21 |
+
*/
|
22 |
+
protected $response = array(
|
23 |
+
"status" => false,
|
24 |
+
"percentage" => 0,
|
25 |
+
"total" => 0,
|
26 |
+
"step" => 0,
|
27 |
+
"last_msg" => '',
|
28 |
+
);
|
29 |
+
|
30 |
+
/**
|
31 |
+
* JobExecutable constructor.
|
32 |
+
*/
|
33 |
+
public function __construct()
|
34 |
+
{
|
35 |
+
parent::__construct();
|
36 |
+
|
37 |
+
// Calculate total steps
|
38 |
+
$this->calculateTotalSteps();
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Prepare Response Array
|
43 |
+
* @param bool $status
|
44 |
+
* @param bool $incrementCurrentStep
|
45 |
+
* @return array
|
46 |
+
*/
|
47 |
+
protected function prepareResponse($status = false, $incrementCurrentStep = true)
|
48 |
+
{
|
49 |
+
if ($incrementCurrentStep)
|
50 |
+
{
|
51 |
+
$this->options->currentStep++;
|
52 |
+
}
|
53 |
+
|
54 |
+
$percentage = round(($this->options->currentStep / $this->options->totalSteps) * 100);
|
55 |
+
$percentage = (100 < $percentage) ? 100 : $percentage;
|
56 |
+
|
57 |
+
return $this->response = array(
|
58 |
+
"status" => $status,
|
59 |
+
"percentage" => $percentage,
|
60 |
+
"total" => $this->options->totalSteps,
|
61 |
+
"step" => $this->options->currentStep,
|
62 |
+
"job" => $this->options->currentJob,
|
63 |
+
"last_msg" => $this->logger->getLastLogMsg(),
|
64 |
+
"running_time" => $this->time() - time(),
|
65 |
+
"job_done" => $status
|
66 |
+
);
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Start Module
|
71 |
+
* @return object
|
72 |
+
*/
|
73 |
+
public function start()
|
74 |
+
{
|
75 |
+
// Execute steps
|
76 |
+
$this->run();
|
77 |
+
|
78 |
+
// Save option, progress
|
79 |
+
$this->saveOptions();
|
80 |
+
|
81 |
+
return (object) $this->response;
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Run Steps
|
86 |
+
*/
|
87 |
+
protected function run()
|
88 |
+
{
|
89 |
+
// Execute steps
|
90 |
+
for ($i = 0; $i < $this->options->totalSteps; $i++)
|
91 |
+
{
|
92 |
+
// Job is finished or over threshold limits was hit
|
93 |
+
if (!$this->execute())
|
94 |
+
{
|
95 |
+
break;
|
96 |
+
}
|
97 |
+
}
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Calculate Total Steps in This Job and Assign It to $this->options->totalSteps
|
102 |
+
* @return void
|
103 |
+
*/
|
104 |
+
abstract protected function calculateTotalSteps();
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Execute the Current Step
|
108 |
+
* Returns false when over threshold limits are hit or when the job is done, true otherwise
|
109 |
+
* @return bool
|
110 |
+
*/
|
111 |
+
abstract protected function execute();
|
112 |
}
|
apps/Backend/Modules/Jobs/Scan.php
CHANGED
@@ -1,377 +1,400 @@
|
|
1 |
-
<?php
|
2 |
-
namespace WPStaging\Backend\Modules\Jobs;
|
3 |
-
|
4 |
-
// No Direct Access
|
5 |
-
if (!defined("WPINC"))
|
6 |
-
{
|
7 |
-
die;
|
8 |
-
}
|
9 |
-
|
10 |
-
use WPStaging\Utils\Directories;
|
11 |
-
use WPStaging\WPStaging;
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Class Scan
|
15 |
-
* @package WPStaging\Backend\Modules\Jobs
|
16 |
-
*/
|
17 |
-
class Scan extends Job
|
18 |
-
{
|
19 |
-
|
20 |
-
/**
|
21 |
-
* @var array
|
22 |
-
*/
|
23 |
-
private $directories = array();
|
24 |
-
|
25 |
-
/**
|
26 |
-
* @var Directories
|
27 |
-
*/
|
28 |
-
private $objDirectories;
|
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 |
-
$this->options->
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
$this->options->
|
72 |
-
$this->options->
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
$this->options->
|
78 |
-
$this->options->
|
79 |
-
$this->options->
|
80 |
-
|
81 |
-
//
|
82 |
-
$this->
|
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 |
-
$output .= "
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
if (
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
$output .= "</
|
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 |
-
$this->options->
|
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 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
377 |
}
|
1 |
+
<?php
|
2 |
+
namespace WPStaging\Backend\Modules\Jobs;
|
3 |
+
|
4 |
+
// No Direct Access
|
5 |
+
if (!defined("WPINC"))
|
6 |
+
{
|
7 |
+
die;
|
8 |
+
}
|
9 |
+
|
10 |
+
use WPStaging\Utils\Directories;
|
11 |
+
use WPStaging\WPStaging;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Class Scan
|
15 |
+
* @package WPStaging\Backend\Modules\Jobs
|
16 |
+
*/
|
17 |
+
class Scan extends Job
|
18 |
+
{
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @var array
|
22 |
+
*/
|
23 |
+
private $directories = array();
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @var Directories
|
27 |
+
*/
|
28 |
+
private $objDirectories;
|
29 |
+
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Upon class initialization
|
33 |
+
*/
|
34 |
+
protected function initialize()
|
35 |
+
{
|
36 |
+
$this->objDirectories = new Directories();
|
37 |
+
|
38 |
+
// Database Tables
|
39 |
+
$this->getTables();
|
40 |
+
|
41 |
+
// Get directories
|
42 |
+
$this->directories();
|
43 |
+
|
44 |
+
$this->db = WPStaging::getInstance()->get('wpdb');
|
45 |
+
$this->prefix = $this->db->prefix;
|
46 |
+
|
47 |
+
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Start Module
|
52 |
+
* @return $this
|
53 |
+
*/
|
54 |
+
public function start()
|
55 |
+
{
|
56 |
+
// Basic Options
|
57 |
+
$this->options->root = str_replace(array("\\", '/'), DIRECTORY_SEPARATOR, ABSPATH);
|
58 |
+
$this->options->existingClones = get_option("wpstg_existing_clones_beta", array());
|
59 |
+
$this->options->current = null;
|
60 |
+
|
61 |
+
if (isset($_POST["clone"]) && array_key_exists($_POST["clone"], $this->options->existingClones))
|
62 |
+
{
|
63 |
+
$this->options->current = $_POST["clone"];
|
64 |
+
}
|
65 |
+
|
66 |
+
// Tables
|
67 |
+
//$this->options->excludedTables = array();
|
68 |
+
$this->options->clonedTables = array();
|
69 |
+
|
70 |
+
// Files
|
71 |
+
$this->options->totalFiles = 0;
|
72 |
+
$this->options->copiedFiles = 0;
|
73 |
+
|
74 |
+
// Directories
|
75 |
+
$this->options->includedDirectories = array();
|
76 |
+
$this->options->excludedDirectories = array();
|
77 |
+
$this->options->extraDirectories = array();
|
78 |
+
$this->options->directoriesToCopy = array();
|
79 |
+
$this->options->scannedDirectories = array();
|
80 |
+
|
81 |
+
// Job
|
82 |
+
$this->options->currentJob = "database";
|
83 |
+
$this->options->currentStep = 0;
|
84 |
+
$this->options->totalSteps = 0;
|
85 |
+
|
86 |
+
// Delete previous cached files
|
87 |
+
$this->cache->delete("files_to_copy");
|
88 |
+
$this->cache->delete("clone_options");
|
89 |
+
//$this->cache->delete("files_to_verify");
|
90 |
+
//$this->cache->delete("files_verified");
|
91 |
+
|
92 |
+
// Save options
|
93 |
+
$this->saveOptions();
|
94 |
+
|
95 |
+
return $this;
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Format bytes into human readable form
|
100 |
+
* @param int $bytes
|
101 |
+
* @param int $precision
|
102 |
+
* @return string
|
103 |
+
*/
|
104 |
+
public function formatSize($bytes, $precision = 2)
|
105 |
+
{
|
106 |
+
if ((double) $bytes < 1)
|
107 |
+
{
|
108 |
+
return '';
|
109 |
+
}
|
110 |
+
|
111 |
+
$units = array('B', "KB", "MB", "GB", "TB");
|
112 |
+
|
113 |
+
$bytes = (double) $bytes;
|
114 |
+
$base = log($bytes) / log(1000); // 1024 would be for MiB KiB etc
|
115 |
+
$pow = pow(1000, $base - floor($base)); // Same rule for 1000
|
116 |
+
|
117 |
+
return round($pow, $precision) . ' ' . $units[(int) floor($base)];
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* @param null|string $directories
|
122 |
+
* @param bool $forceDisabled
|
123 |
+
* @return string
|
124 |
+
*/
|
125 |
+
public function directoryListing($directories = null, $forceDisabled = false)
|
126 |
+
{
|
127 |
+
if (null == $directories)
|
128 |
+
{
|
129 |
+
$directories = $this->directories;
|
130 |
+
}
|
131 |
+
|
132 |
+
$output = '';
|
133 |
+
foreach ($directories as $name => $directory)
|
134 |
+
{
|
135 |
+
// Need to preserve keys so no array_shift()
|
136 |
+
$data = reset($directory);
|
137 |
+
unset($directory[key($directory)]);
|
138 |
+
|
139 |
+
$isChecked = (
|
140 |
+
empty($this->options->includedDirectories) ||
|
141 |
+
in_array($data["path"], $this->options->includedDirectories)
|
142 |
+
);
|
143 |
+
|
144 |
+
$isDisabled = ($this->options->existingClones && isset($this->options->existingClones[$name]));
|
145 |
+
|
146 |
+
$output .= "<div class='wpstg-dir'>";
|
147 |
+
$output .= "<input type='checkbox' class='wpstg-check-dir'";
|
148 |
+
|
149 |
+
if ($isChecked && !$isDisabled && !$forceDisabled) $output .= " checked";
|
150 |
+
if ($forceDisabled || $isDisabled) $output .= " disabled";
|
151 |
+
|
152 |
+
$output .= " name='selectedDirectories[]' value='{$data["path"]}'>";
|
153 |
+
|
154 |
+
$output .= "<a href='#' class='wpstg-expand-dirs";
|
155 |
+
if (!$isChecked || $isDisabled) $output .= " disabled";
|
156 |
+
$output .= "'>{$name}";
|
157 |
+
$output .= "</a>";
|
158 |
+
|
159 |
+
$output .= "<span class='wpstg-size-info'>{$this->formatSize($data["size"])}</span>";
|
160 |
+
|
161 |
+
if (!empty($directory))
|
162 |
+
{
|
163 |
+
$output .= "<div class='wpstg-dir wpstg-subdir'>";
|
164 |
+
$output .= $this->directoryListing($directory, $isDisabled);
|
165 |
+
$output .= "</div>";
|
166 |
+
}
|
167 |
+
|
168 |
+
$output .= "</div>";
|
169 |
+
}
|
170 |
+
|
171 |
+
return $output;
|
172 |
+
}
|
173 |
+
|
174 |
+
/**
|
175 |
+
* Checks if there is enough free disk space to create staging site
|
176 |
+
* Returns null when can't run disk_free_space function one way or another
|
177 |
+
* @return bool|null
|
178 |
+
*/
|
179 |
+
public function hasFreeDiskSpace() {
|
180 |
+
if( !function_exists( "disk_free_space" ) ) {
|
181 |
+
return null;
|
182 |
+
}
|
183 |
+
|
184 |
+
$freeSpace = @disk_free_space( ABSPATH );
|
185 |
+
|
186 |
+
if( false === $freeSpace ) {
|
187 |
+
$data = array(
|
188 |
+
'freespace' => false,
|
189 |
+
'usedspace' => $this->formatSize($this->getDirectorySizeInclSubdirs(ABSPATH))
|
190 |
+
);
|
191 |
+
echo json_encode($data);
|
192 |
+
die();
|
193 |
+
}
|
194 |
+
|
195 |
+
|
196 |
+
$data = array(
|
197 |
+
'freespace' => $this->formatSize($freeSpace),
|
198 |
+
'usedspace' => $this->formatSize($this->getDirectorySizeInclSubdirs(ABSPATH))
|
199 |
+
);
|
200 |
+
|
201 |
+
echo json_encode( $data );
|
202 |
+
die();
|
203 |
+
}
|
204 |
+
|
205 |
+
/**
|
206 |
+
* Get Database Tables
|
207 |
+
*/
|
208 |
+
protected function getTables()
|
209 |
+
{
|
210 |
+
$wpDB = WPStaging::getInstance()->get("wpdb");
|
211 |
+
|
212 |
+
if (strlen($wpDB->prefix) > 0)
|
213 |
+
{
|
214 |
+
$prefix = str_replace('_', '', $wpDB->prefix);
|
215 |
+
//$sql = "SHOW TABLE STATUS LIKE '{$prefix}\%'";
|
216 |
+
$sql = "SHOW TABLE STATUS LIKE '{$wpDB->prefix}%'";
|
217 |
+
}
|
218 |
+
else
|
219 |
+
{
|
220 |
+
$sql = "SHOW TABLE STATUS";
|
221 |
+
}
|
222 |
+
|
223 |
+
$tables = $wpDB->get_results($sql);
|
224 |
+
|
225 |
+
$currentTables = array();
|
226 |
+
|
227 |
+
// Reset excluded Tables than loop through all tables
|
228 |
+
$this->options->excludedTables = array();
|
229 |
+
foreach ($tables as $table)
|
230 |
+
{
|
231 |
+
|
232 |
+
// Exclude WP Staging Tables
|
233 |
+
// if (0 === strpos($table->Name, "wpstg"))
|
234 |
+
// {
|
235 |
+
// continue;
|
236 |
+
// }
|
237 |
+
// Create array of unchecked tables
|
238 |
+
if (0 !== strpos($table->Name, $wpDB->prefix))
|
239 |
+
{
|
240 |
+
$this->options->excludedTables[] = $table->Name;
|
241 |
+
}
|
242 |
+
|
243 |
+
|
244 |
+
$currentTables[] = array(
|
245 |
+
"name" => $table->Name,
|
246 |
+
"size" => ($table->Data_length + $table->Index_length)
|
247 |
+
);
|
248 |
+
}
|
249 |
+
|
250 |
+
$this->options->tables = json_decode(json_encode($currentTables));
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* Get directories and main meta data about'em recursively
|
255 |
+
*/
|
256 |
+
protected function directories()
|
257 |
+
{
|
258 |
+
$directories = new \DirectoryIterator(ABSPATH);
|
259 |
+
|
260 |
+
foreach($directories as $directory)
|
261 |
+
{
|
262 |
+
// Not a valid directory
|
263 |
+
if (false === ($path = $this->getPath($directory)))
|
264 |
+
{
|
265 |
+
continue;
|
266 |
+
}
|
267 |
+
|
268 |
+
$this->handleDirectory($path);
|
269 |
+
|
270 |
+
// Get Sub-directories
|
271 |
+
$this->getSubDirectories($directory->getRealPath());
|
272 |
+
}
|
273 |
+
|
274 |
+
// Gather Plugins
|
275 |
+
$this->getSubDirectories(WP_PLUGIN_DIR);
|
276 |
+
|
277 |
+
// Gather Themes
|
278 |
+
$this->getSubDirectories(WP_CONTENT_DIR . DIRECTORY_SEPARATOR . "themes");
|
279 |
+
|
280 |
+
// Gather Uploads
|
281 |
+
$this->getSubDirectories(WP_CONTENT_DIR . DIRECTORY_SEPARATOR . "uploads");
|
282 |
+
}
|
283 |
+
|
284 |
+
/**
|
285 |
+
* @param string $path
|
286 |
+
*/
|
287 |
+
protected function getSubDirectories($path)
|
288 |
+
{
|
289 |
+
$directories = new \DirectoryIterator($path);
|
290 |
+
|
291 |
+
foreach($directories as $directory)
|
292 |
+
{
|
293 |
+
// Not a valid directory
|
294 |
+
if (false === ($path = $this->getPath($directory)))
|
295 |
+
{
|
296 |
+
continue;
|
297 |
+
}
|
298 |
+
|
299 |
+
$this->handleDirectory($path);
|
300 |
+
}
|
301 |
+
}
|
302 |
+
|
303 |
+
/**
|
304 |
+
* Get Path from $directory
|
305 |
+
* @param \SplFileInfo $directory
|
306 |
+
* @return string|false
|
307 |
+
*/
|
308 |
+
protected function getPath($directory)
|
309 |
+
{
|
310 |
+
|
311 |
+
/*
|
312 |
+
* Do not follow root path like src/web/..
|
313 |
+
* This must be done before \SplFileInfo->isDir() is used!
|
314 |
+
* Prevents open base dir restriction fatal errors
|
315 |
+
*/
|
316 |
+
if (strpos( $directory->getRealPath(), ABSPATH ) !== 0 ) {
|
317 |
+
return false;
|
318 |
+
}
|
319 |
+
$path = str_replace(ABSPATH, null, $directory->getRealPath());
|
320 |
+
|
321 |
+
// Using strpos() for symbolic links as they could create nasty stuff in nix stuff for directory structures
|
322 |
+
if (!$directory->isDir() || strlen($path) < 1)
|
323 |
+
{
|
324 |
+
return false;
|
325 |
+
}
|
326 |
+
|
327 |
+
return $path;
|
328 |
+
}
|
329 |
+
|
330 |
+
/**
|
331 |
+
* Organizes $this->directories
|
332 |
+
* @param string $path
|
333 |
+
*/
|
334 |
+
protected function handleDirectory($path)
|
335 |
+
{
|
336 |
+
$directoryArray = explode(DIRECTORY_SEPARATOR, $path);
|
337 |
+
$total = count($directoryArray);
|
338 |
+
|
339 |
+
if (count($total) < 1)
|
340 |
+
{
|
341 |
+
return;
|
342 |
+
}
|
343 |
+
|
344 |
+
$total = $total - 1;
|
345 |
+
$currentArray = &$this->directories;
|
346 |
+
|
347 |
+
for ($i = 0; $i <= $total; $i++)
|
348 |
+
{
|
349 |
+
if (!isset($currentArray[$directoryArray[$i]]))
|
350 |
+
{
|
351 |
+
$currentArray[$directoryArray[$i]] = array();
|
352 |
+
}
|
353 |
+
|
354 |
+
$currentArray = &$currentArray[$directoryArray[$i]];
|
355 |
+
|
356 |
+
// Attach meta data to the end
|
357 |
+
if ($i < $total)
|
358 |
+
{
|
359 |
+
continue;
|
360 |
+
}
|
361 |
+
|
362 |
+
$fullPath = ABSPATH . $path;
|
363 |
+
$size = $this->getDirectorySize($fullPath);
|
364 |
+
|
365 |
+
$currentArray["metaData"] = array(
|
366 |
+
"size" => $size,
|
367 |
+
"path" => ABSPATH . $path,
|
368 |
+
);
|
369 |
+
}
|
370 |
+
}
|
371 |
+
|
372 |
+
/**
|
373 |
+
* Gets size of given directory
|
374 |
+
* @param string $path
|
375 |
+
* @return int|null
|
376 |
+
*/
|
377 |
+
protected function getDirectorySize($path)
|
378 |
+
{
|
379 |
+
if (!isset($this->settings->checkDirectorySize) || '1' !== $this->settings->checkDirectorySize)
|
380 |
+
{
|
381 |
+
return null;
|
382 |
+
}
|
383 |
+
|
384 |
+
return $this->objDirectories->size($path);
|
385 |
+
}
|
386 |
+
|
387 |
+
/**
|
388 |
+
* Get total size of a directory including all its subdirectories
|
389 |
+
* @param string $dir
|
390 |
+
* @return int
|
391 |
+
*/
|
392 |
+
function getDirectorySizeInclSubdirs( $dir ) {
|
393 |
+
$size = 0;
|
394 |
+
foreach ( glob( rtrim( $dir, '/' ) . '/*', GLOB_NOSORT ) as $each ) {
|
395 |
+
$size += is_file( $each ) ? filesize( $each ) : $this->getDirectorySizeInclSubdirs( $each );
|
396 |
+
}
|
397 |
+
return $size;
|
398 |
+
}
|
399 |
+
|
400 |
}
|
apps/Backend/Modules/Jobs/Updating.php
ADDED
@@ -0,0 +1,262 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace WPStaging\Backend\Modules\Jobs;
|
3 |
+
|
4 |
+
use WPStaging\Backend\Modules\Jobs\Exceptions\JobNotFoundException;
|
5 |
+
use WPStaging\WPStaging;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Class Cloning
|
9 |
+
* @package WPStaging\Backend\Modules\Jobs
|
10 |
+
*/
|
11 |
+
class Updating extends Job
|
12 |
+
{
|
13 |
+
/**
|
14 |
+
* Initialize is called in \Job
|
15 |
+
*/
|
16 |
+
public function initialize(){
|
17 |
+
$this->db = WPStaging::getInstance()->get("wpdb");
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Save Chosen Cloning Settings
|
22 |
+
* @return bool
|
23 |
+
*/
|
24 |
+
public function save()
|
25 |
+
{
|
26 |
+
if (!isset($_POST) || !isset($_POST["cloneID"]))
|
27 |
+
{
|
28 |
+
return false;
|
29 |
+
}
|
30 |
+
|
31 |
+
// Generate Options
|
32 |
+
// Clone
|
33 |
+
$this->options->clone = $_POST["cloneID"];
|
34 |
+
$this->options->cloneDirectoryName = preg_replace("#\W+#", '-', strtolower($this->options->clone));
|
35 |
+
$this->options->cloneNumber = 1;
|
36 |
+
$this->options->includedDirectories = array();
|
37 |
+
$this->options->excludedDirectories = array();
|
38 |
+
$this->options->extraDirectories = array();
|
39 |
+
$this->options->excludedFiles = array('.htaccess', '.DS_Store', '.git', '.svn', '.tmp', 'desktop.ini', '.gitignore', '.log');
|
40 |
+
|
41 |
+
// Job
|
42 |
+
$this->options->job = new \stdClass();
|
43 |
+
|
44 |
+
// Check if clone data already exists and use that one
|
45 |
+
if (isset($this->options->existingClones[$this->options->clone]) )
|
46 |
+
{
|
47 |
+
$this->options->cloneNumber = $this->options->existingClones[$this->options->clone]['number'];
|
48 |
+
$this->options->prefix = $this->getStagingPrefix();
|
49 |
+
} else {
|
50 |
+
wp_die('Fatal Error: Can not update clone because there is no clone data.');
|
51 |
+
}
|
52 |
+
|
53 |
+
|
54 |
+
// Excluded Tables
|
55 |
+
if (isset($_POST["excludedTables"]) && is_array($_POST["excludedTables"]))
|
56 |
+
{
|
57 |
+
$this->options->excludedTables = $_POST["excludedTables"];
|
58 |
+
}
|
59 |
+
|
60 |
+
// Excluded Directories
|
61 |
+
if (isset($_POST["excludedDirectories"]) && is_array($_POST["excludedDirectories"]))
|
62 |
+
{
|
63 |
+
$this->options->excludedDirectories = $_POST["excludedDirectories"];
|
64 |
+
}
|
65 |
+
|
66 |
+
// Excluded Directories TOTAL
|
67 |
+
// Do not copy these folders and plugins
|
68 |
+
$excludedDirectories = array(
|
69 |
+
ABSPATH . 'wp-content' . DIRECTORY_SEPARATOR . 'cache',
|
70 |
+
ABSPATH . 'wp-content' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'wps-hide-login'
|
71 |
+
);
|
72 |
+
|
73 |
+
$this->options->excludedDirectories = array_merge($excludedDirectories, $this->options->excludedDirectories);
|
74 |
+
|
75 |
+
// Included Directories
|
76 |
+
if (isset($_POST["includedDirectories"]) && is_array($_POST["includedDirectories"]))
|
77 |
+
{
|
78 |
+
$this->options->includedDirectories = $_POST["includedDirectories"];
|
79 |
+
}
|
80 |
+
|
81 |
+
// Extra Directories
|
82 |
+
if (isset($_POST["extraDirectories"]) && !empty($_POST["extraDirectories"]) )
|
83 |
+
{
|
84 |
+
$this->options->extraDirectories = $_POST["extraDirectories"];
|
85 |
+
}
|
86 |
+
|
87 |
+
// Directories to Copy
|
88 |
+
$this->options->directoriesToCopy = array_merge(
|
89 |
+
$this->options->includedDirectories,
|
90 |
+
$this->options->extraDirectories
|
91 |
+
);
|
92 |
+
|
93 |
+
array_unshift($this->options->directoriesToCopy, ABSPATH);
|
94 |
+
|
95 |
+
// Delete files to copy listing
|
96 |
+
$this->cache->delete("files_to_copy");
|
97 |
+
|
98 |
+
return $this->saveOptions();
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Check and return prefix of the staging site
|
103 |
+
*/
|
104 |
+
|
105 |
+
|
106 |
+
// public function getStagingPrefix_old(){
|
107 |
+
// $prefix = !empty($this->options->existingClones[$this->options->clone]['prefix']) ?
|
108 |
+
// $this->options->existingClones[$this->options->clone]['prefix'] :
|
109 |
+
// false;
|
110 |
+
//
|
111 |
+
// if(!$prefix){
|
112 |
+
// $this->returnException("Fatal Error: Can not update staging site. Can not find Prefix. '{$prefix}'. Stopping for security reasons. Creating a new staging site will likely resolve this the next time. Contact support@wp-staging.com");
|
113 |
+
// wp_die("Fatal Error: Can not update staging site. Can not find Prefix. '{$prefix}'. Stopping for security reasons. Creating a new staging site will likely resolve this the next time. Contact support@wp-staging.com");
|
114 |
+
// }
|
115 |
+
//
|
116 |
+
// if ($this->options->existingClones[$this->options->clone]['prefix'] == $this->db->prefix){
|
117 |
+
// $this->returnException("Fatal Error: Can not update staging site. Prefix. '{$prefix}' is used for the live site. Creating a new staging site will likely resolve this the next time. Stopping for security reasons. Contact support@wp-staging.com");
|
118 |
+
// wp_die("Fatal Error: Can not update staging site. Prefix. '{$prefix}' is used for the live site. Creating a new staging site will likely resolve this the next time. Stopping for security reasons. Contact support@wp-staging.com");
|
119 |
+
// }
|
120 |
+
//
|
121 |
+
// return $prefix;
|
122 |
+
// }
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Check and return prefix of the staging site
|
126 |
+
*/
|
127 |
+
public function getStagingPrefix() {
|
128 |
+
// prefix not defined! Happens if staging site has ben generated with older version of wpstg
|
129 |
+
// Try to get staging prefix from wp-config.php of staging site
|
130 |
+
$this->options->prefix = $this->options->existingClones[$this->options->clone]['prefix'];
|
131 |
+
//wp_die($this->options->prefix);
|
132 |
+
if (empty($this->options->prefix)) {
|
133 |
+
// Throw error if wp-config.php is not readable
|
134 |
+
$path = ABSPATH . $this->options->cloneDirectoryName . "/wp-config.php";
|
135 |
+
//wp_die($path);
|
136 |
+
if (false === ($content = @file_get_contents($path))) {
|
137 |
+
$this->log("Can not open {$path}. Can't read contents", Logger::TYPE_ERROR);
|
138 |
+
$this->returnException("Fatal Error: Can not read {$path} to get correct table prefix. Stopping for security reasons. Deleting this staging site and creating a new one could fix this issue. Otherwise contact us support@wp-staging.com");
|
139 |
+
wp_die("Fatal Error: Can not read {$path} to get correct table prefix. Stopping for security reasons. Deleting this staging site and creating a new one could fix this issue. Otherwise contact us support@wp-staging.com");
|
140 |
+
} else {
|
141 |
+
// Get prefix from wp-config.php
|
142 |
+
preg_match("/table_prefix\s*=\s*'(\w*)';/", $content, $matches);
|
143 |
+
//wp_die(var_dump($matches));
|
144 |
+
|
145 |
+
if (!empty($matches[1])) {
|
146 |
+
$this->options->prefix = $matches[1];
|
147 |
+
} else {
|
148 |
+
$this->returnException("Fatal Error: Can not detect prefix from {$path}. Stopping for security reasons. Deleting this staging site and creating a new one could fix this issue. Otherwise contact us support@wp-staging.com");
|
149 |
+
wp_die("Fatal Error: Can not detect prefix from {$path}. Stopping for security reasons. Deleting this staging site and creating a new one could fix this issue. Otherwise contact us support@wp-staging.com");
|
150 |
+
}
|
151 |
+
}
|
152 |
+
}
|
153 |
+
|
154 |
+
// Die() if staging prefix is the same as the live prefix
|
155 |
+
if ($this->db->prefix == $this->options->prefix) {
|
156 |
+
$this->log("Fatal Error: Can not updatte staging site. Prefix. '{$this->options->prefix}' is used for the live site. Stopping for security reasons. Deleting this staging site and creating a new one could fix this issue. Otherwise contact us support@wp-staging.com");
|
157 |
+
wp_die("Fatal Error: Can not update staging site. Prefix. '{$this->options->prefix}' is used for the live site. Stopping for security reasons. Deleting this staging site and creating a new one could fix this issue. Otherwise contact us support@wp-staging.com");
|
158 |
+
}
|
159 |
+
|
160 |
+
// Else
|
161 |
+
//$this->returnException($this->options->prefix);
|
162 |
+
//wp_die($this->options->prefix);
|
163 |
+
return $this->options->prefix;
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Start the cloning job
|
168 |
+
*/
|
169 |
+
public function start()
|
170 |
+
{
|
171 |
+
if (null === $this->options->currentJob)
|
172 |
+
{
|
173 |
+
$this->log("Cloning job for {$this->options->clone} finished");
|
174 |
+
return true;
|
175 |
+
}
|
176 |
+
|
177 |
+
$methodName = "job" . ucwords($this->options->currentJob);
|
178 |
+
|
179 |
+
if (!method_exists($this, $methodName))
|
180 |
+
{
|
181 |
+
$this->log("Can't execute job; Job's method {$methodName} is not found");
|
182 |
+
throw new JobNotFoundException($methodName);
|
183 |
+
}
|
184 |
+
|
185 |
+
// Call the job
|
186 |
+
//$this->log("execute job: Job's method {$methodName}");
|
187 |
+
return $this->{$methodName}();
|
188 |
+
}
|
189 |
+
|
190 |
+
/**
|
191 |
+
* @param object $response
|
192 |
+
* @param string $nextJob
|
193 |
+
* @return object
|
194 |
+
*/
|
195 |
+
private function handleJobResponse($response, $nextJob)
|
196 |
+
{
|
197 |
+
// Job is not done
|
198 |
+
if (true !== $response->status)
|
199 |
+
{
|
200 |
+
return $response;
|
201 |
+
}
|
202 |
+
|
203 |
+
$this->options->currentJob = $nextJob;
|
204 |
+
$this->options->currentStep = 0;
|
205 |
+
$this->options->totalSteps = 0;
|
206 |
+
|
207 |
+
// Save options
|
208 |
+
$this->saveOptions();
|
209 |
+
|
210 |
+
return $response;
|
211 |
+
}
|
212 |
+
|
213 |
+
/**
|
214 |
+
* Clone Database
|
215 |
+
* @return object
|
216 |
+
*/
|
217 |
+
public function jobDatabase()
|
218 |
+
{
|
219 |
+
$database = new Database();
|
220 |
+
return $this->handleJobResponse($database->start(), "directories");
|
221 |
+
}
|
222 |
+
|
223 |
+
/**
|
224 |
+
* Get All Files From Selected Directories Recursively Into a File
|
225 |
+
* @return object
|
226 |
+
*/
|
227 |
+
public function jobDirectories()
|
228 |
+
{
|
229 |
+
$directories = new Directories();
|
230 |
+
return $this->handleJobResponse($directories->start(), "files");
|
231 |
+
}
|
232 |
+
|
233 |
+
/**
|
234 |
+
* Copy Files
|
235 |
+
* @return object
|
236 |
+
*/
|
237 |
+
public function jobFiles()
|
238 |
+
{
|
239 |
+
$files = new Files();
|
240 |
+
return $this->handleJobResponse($files->start(), "data");
|
241 |
+
}
|
242 |
+
|
243 |
+
/**
|
244 |
+
* Replace Data
|
245 |
+
* @return object
|
246 |
+
*/
|
247 |
+
public function jobData()
|
248 |
+
{
|
249 |
+
$data = new Data();
|
250 |
+
return $this->handleJobResponse($data->start(), "finish");
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* Save Clone Data
|
255 |
+
* @return object
|
256 |
+
*/
|
257 |
+
public function jobFinish()
|
258 |
+
{
|
259 |
+
$finish = new Finish();
|
260 |
+
return $this->handleJobResponse($finish->start(), '');
|
261 |
+
}
|
262 |
+
}
|
apps/Backend/Modules/SystemInfo.php
CHANGED
@@ -1,481 +1,513 @@
|
|
1 |
-
<?php
|
2 |
-
namespace WPStaging\Backend\Modules;
|
3 |
-
|
4 |
-
use WPStaging\DI\InjectionAware;
|
5 |
-
use WPStaging\Library\Browser;
|
6 |
-
use WPStaging\WPStaging;
|
7 |
-
|
8 |
-
// No Direct Access
|
9 |
-
if (!defined("WPINC"))
|
10 |
-
{
|
11 |
-
die;
|
12 |
-
}
|
13 |
-
|
14 |
-
/**
|
15 |
-
* Class SystemInfo
|
16 |
-
* @package WPStaging\Backend\Modules
|
17 |
-
*/
|
18 |
-
class SystemInfo extends InjectionAware
|
19 |
-
{
|
20 |
-
|
21 |
-
/**
|
22 |
-
* @var bool
|
23 |
-
*/
|
24 |
-
private $isMultiSite;
|
25 |
-
|
26 |
-
|
27 |
-
/**
|
28 |
-
* Initialize class
|
29 |
-
*/
|
30 |
-
public function initialize()
|
31 |
-
{
|
32 |
-
$this->isMultiSite = is_multisite();
|
33 |
-
}
|
34 |
-
|
35 |
-
/**
|
36 |
-
* Magic method
|
37 |
-
* @return string
|
38 |
-
*/
|
39 |
-
public function __toString()
|
40 |
-
{
|
41 |
-
return $this->get();
|
42 |
-
}
|
43 |
-
|
44 |
-
/**
|
45 |
-
* Get System Information as text
|
46 |
-
* @return string
|
47 |
-
*/
|
48 |
-
public function get()
|
49 |
-
{
|
50 |
-
$output = "### Begin System Info ###" . PHP_EOL . PHP_EOL;
|
51 |
-
|
52 |
-
$output .= $this->wpstaging();
|
53 |
-
|
54 |
-
$output .= $this->site();
|
55 |
-
|
56 |
-
$output .= $this->browser();
|
57 |
-
|
58 |
-
$output .= $this->wp();
|
59 |
-
|
60 |
-
$output .= $this->plugins();
|
61 |
-
|
62 |
-
$output .= $this->multiSitePlugins();
|
63 |
-
|
64 |
-
$output .= $this->server();
|
65 |
-
|
66 |
-
$output .= $this->php();
|
67 |
-
|
68 |
-
$output .= $this->phpExtensions();
|
69 |
-
|
70 |
-
$output .= PHP_EOL . "### End System Info ###";
|
71 |
-
|
72 |
-
return $output;
|
73 |
-
}
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
/**
|
78 |
-
* @param string $string
|
79 |
-
* @return string
|
80 |
-
*/
|
81 |
-
public function header($string)
|
82 |
-
{
|
83 |
-
return PHP_EOL . "-- {$string}" . PHP_EOL . PHP_EOL;
|
84 |
-
}
|
85 |
-
|
86 |
-
/**
|
87 |
-
* Formating title and the value
|
88 |
-
* @param string $title
|
89 |
-
* @param string $value
|
90 |
-
* @return string
|
91 |
-
*/
|
92 |
-
public function info($title, $value)
|
93 |
-
{
|
94 |
-
return str_pad($title, 56, ' ', STR_PAD_RIGHT) . $value . PHP_EOL;
|
95 |
-
}
|
96 |
-
|
97 |
-
/**
|
98 |
-
* Theme Information
|
99 |
-
* @return string
|
100 |
-
*/
|
101 |
-
public function theme()
|
102 |
-
{
|
103 |
-
// Versions earlier than 3.4
|
104 |
-
if (get_bloginfo("version") < "3.4" )
|
105 |
-
{
|
106 |
-
$themeData = get_theme_data(get_stylesheet_directory() . "/style.css");
|
107 |
-
return "{$themeData["Name"]} {$themeData["Version"]}";
|
108 |
-
}
|
109 |
-
|
110 |
-
$themeData = wp_get_theme();
|
111 |
-
return "{$themeData->Name} {$themeData->Version}";
|
112 |
-
}
|
113 |
-
|
114 |
-
/**
|
115 |
-
* Site Information
|
116 |
-
* @return string
|
117 |
-
*/
|
118 |
-
public function site()
|
119 |
-
{
|
120 |
-
$output = "-- Site Info" . PHP_EOL . PHP_EOL;
|
121 |
-
$output .= $this->info("Site URL:", site_url());
|
122 |
-
$output .= $this->info("Home URL:", home_url());
|
123 |
-
$output .= $this->info("Home Path:", get_home_path());
|
124 |
-
$output .= $this->info("Installed in subdir:", ( $this->isSubDir() ? 'Yes' : 'No' )) ;
|
125 |
-
$output .= $this->info("Multisite:", ($this->isMultiSite ? "Yes" : "No" ));
|
126 |
-
|
127 |
-
return apply_filters("wpstg_sysinfo_after_site_info", $output);
|
128 |
-
}
|
129 |
-
|
130 |
-
/**
|
131 |
-
* Wp Staging plugin Information
|
132 |
-
* @return string
|
133 |
-
*/
|
134 |
-
public function wpstaging() {
|
135 |
-
// Get wpstg settings
|
136 |
-
$settings = ( object ) get_option( 'wpstg_settings', array() );
|
137 |
-
|
138 |
-
// Clones data < 1.6.x
|
139 |
-
$clones = ( object ) get_option( 'wpstg_existing_clones', array() );
|
140 |
-
// Clones data version > 2.x
|
141 |
-
$clonesBeta = get_option( 'wpstg_existing_clones_beta' );
|
142 |
-
|
143 |
-
|
144 |
-
$output = "-- WP Staging Settings" . PHP_EOL . PHP_EOL;
|
145 |
-
$output .= $this->info( "Query Limit:", isset( $settings->queryLimit ) ? $settings->queryLimit : 'undefined' );
|
146 |
-
$output .= $this->info( "File Copy Limit:", isset( $settings->fileLimit ) ? $settings->fileLimit : 'undefined' );
|
147 |
-
$output .= $this->info( "Batch Size:", isset( $settings->batchSize ) ? $settings->batchSize : 'undefined' );
|
148 |
-
$output .= $this->info( "CPU Load:", isset( $settings->cpuLoad ) ? $settings->cpuLoad : 'undefined' );
|
149 |
-
$output .= $this->info( "WP in Subdir:", isset( $settings->wpSubDirectory ) ? $settings->wpSubDirectory : 'false' );
|
150 |
-
|
151 |
-
$output .= PHP_EOL . PHP_EOL . "-- Available Sites Version < 1.6.x" . PHP_EOL . PHP_EOL;
|
152 |
-
|
153 |
-
$i = 1;
|
154 |
-
foreach ( $clones as $key => $value ) {
|
155 |
-
$output .= $this->info( "Site name & subfolder :", $value );
|
156 |
-
}
|
157 |
-
$output .= PHP_EOL . PHP_EOL . "-- Available Sites Version > 2.0.x" . PHP_EOL . PHP_EOL;
|
158 |
-
|
159 |
-
foreach ( $clonesBeta as $key => $clone ) {
|
160 |
-
$output .= $this->info( "Number:", isset( $clone['number'] ) ? $clone['number'] : 'undefined' );
|
161 |
-
$output .= $this->info( "directoryName:", isset( $clone['directoryName'] ) ? $clone['directoryName'] : 'undefined' );
|
162 |
-
$output .= $this->info( "Path:", isset( $clone['path'] ) ? $clone['path'] : 'undefined' );
|
163 |
-
$output .= $this->info( "URL:", isset( $clone['url'] ) ? $clone['url'] : 'undefined' );
|
164 |
-
$output .= $this->info( "
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
$output .= $this->info( "
|
172 |
-
$output .= $this->info( "
|
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 |
-
$output
|
253 |
-
|
254 |
-
$
|
255 |
-
|
256 |
-
|
257 |
-
$output .= $this->info("
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
$
|
270 |
-
|
271 |
-
$
|
272 |
-
|
273 |
-
|
274 |
-
$output .= $this->info("
|
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 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
$output
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
$output
|
404 |
-
$output .= $this->info("
|
405 |
-
$output .= $this->info("
|
406 |
-
$output .= $this->info("
|
407 |
-
$output .= $this->info("Max
|
408 |
-
|
409 |
-
$
|
410 |
-
$output .= $this->info("
|
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 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
$output
|
466 |
-
$output .= $this->info("
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
481 |
}
|
1 |
+
<?php
|
2 |
+
namespace WPStaging\Backend\Modules;
|
3 |
+
|
4 |
+
use WPStaging\DI\InjectionAware;
|
5 |
+
use WPStaging\Library\Browser;
|
6 |
+
use WPStaging\WPStaging;
|
7 |
+
|
8 |
+
// No Direct Access
|
9 |
+
if (!defined("WPINC"))
|
10 |
+
{
|
11 |
+
die;
|
12 |
+
}
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Class SystemInfo
|
16 |
+
* @package WPStaging\Backend\Modules
|
17 |
+
*/
|
18 |
+
class SystemInfo extends InjectionAware
|
19 |
+
{
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @var bool
|
23 |
+
*/
|
24 |
+
private $isMultiSite;
|
25 |
+
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Initialize class
|
29 |
+
*/
|
30 |
+
public function initialize()
|
31 |
+
{
|
32 |
+
$this->isMultiSite = is_multisite();
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Magic method
|
37 |
+
* @return string
|
38 |
+
*/
|
39 |
+
public function __toString()
|
40 |
+
{
|
41 |
+
return $this->get();
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Get System Information as text
|
46 |
+
* @return string
|
47 |
+
*/
|
48 |
+
public function get()
|
49 |
+
{
|
50 |
+
$output = "### Begin System Info ###" . PHP_EOL . PHP_EOL;
|
51 |
+
|
52 |
+
$output .= $this->wpstaging();
|
53 |
+
|
54 |
+
$output .= $this->site();
|
55 |
+
|
56 |
+
$output .= $this->browser();
|
57 |
+
|
58 |
+
$output .= $this->wp();
|
59 |
+
|
60 |
+
$output .= $this->plugins();
|
61 |
+
|
62 |
+
$output .= $this->multiSitePlugins();
|
63 |
+
|
64 |
+
$output .= $this->server();
|
65 |
+
|
66 |
+
$output .= $this->php();
|
67 |
+
|
68 |
+
$output .= $this->phpExtensions();
|
69 |
+
|
70 |
+
$output .= PHP_EOL . "### End System Info ###";
|
71 |
+
|
72 |
+
return $output;
|
73 |
+
}
|
74 |
+
|
75 |
+
|
76 |
+
|
77 |
+
/**
|
78 |
+
* @param string $string
|
79 |
+
* @return string
|
80 |
+
*/
|
81 |
+
public function header($string)
|
82 |
+
{
|
83 |
+
return PHP_EOL . "-- {$string}" . PHP_EOL . PHP_EOL;
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Formating title and the value
|
88 |
+
* @param string $title
|
89 |
+
* @param string $value
|
90 |
+
* @return string
|
91 |
+
*/
|
92 |
+
public function info($title, $value)
|
93 |
+
{
|
94 |
+
return str_pad($title, 56, ' ', STR_PAD_RIGHT) . $value . PHP_EOL;
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Theme Information
|
99 |
+
* @return string
|
100 |
+
*/
|
101 |
+
public function theme()
|
102 |
+
{
|
103 |
+
// Versions earlier than 3.4
|
104 |
+
if (get_bloginfo("version") < "3.4" )
|
105 |
+
{
|
106 |
+
$themeData = get_theme_data(get_stylesheet_directory() . "/style.css");
|
107 |
+
return "{$themeData["Name"]} {$themeData["Version"]}";
|
108 |
+
}
|
109 |
+
|
110 |
+
$themeData = wp_get_theme();
|
111 |
+
return "{$themeData->Name} {$themeData->Version}";
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Site Information
|
116 |
+
* @return string
|
117 |
+
*/
|
118 |
+
public function site()
|
119 |
+
{
|
120 |
+
$output = "-- Site Info" . PHP_EOL . PHP_EOL;
|
121 |
+
$output .= $this->info("Site URL:", site_url());
|
122 |
+
$output .= $this->info("Home URL:", home_url());
|
123 |
+
$output .= $this->info("Home Path:", get_home_path());
|
124 |
+
$output .= $this->info("Installed in subdir:", ( $this->isSubDir() ? 'Yes' : 'No' )) ;
|
125 |
+
$output .= $this->info("Multisite:", ($this->isMultiSite ? "Yes" : "No" ));
|
126 |
+
|
127 |
+
return apply_filters("wpstg_sysinfo_after_site_info", $output);
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Wp Staging plugin Information
|
132 |
+
* @return string
|
133 |
+
*/
|
134 |
+
public function wpstaging() {
|
135 |
+
// Get wpstg settings
|
136 |
+
$settings = ( object ) get_option( 'wpstg_settings', array() );
|
137 |
+
|
138 |
+
// Clones data < 1.6.x
|
139 |
+
$clones = ( object ) get_option( 'wpstg_existing_clones', array() );
|
140 |
+
// Clones data version > 2.x
|
141 |
+
$clonesBeta = get_option( 'wpstg_existing_clones_beta' );
|
142 |
+
|
143 |
+
|
144 |
+
$output = "-- WP Staging Settings" . PHP_EOL . PHP_EOL;
|
145 |
+
$output .= $this->info( "Query Limit:", isset( $settings->queryLimit ) ? $settings->queryLimit : 'undefined' );
|
146 |
+
$output .= $this->info( "File Copy Limit:", isset( $settings->fileLimit ) ? $settings->fileLimit : 'undefined' );
|
147 |
+
$output .= $this->info( "Batch Size:", isset( $settings->batchSize ) ? $settings->batchSize : 'undefined' );
|
148 |
+
$output .= $this->info( "CPU Load:", isset( $settings->cpuLoad ) ? $settings->cpuLoad : 'undefined' );
|
149 |
+
$output .= $this->info( "WP in Subdir:", isset( $settings->wpSubDirectory ) ? $settings->wpSubDirectory : 'false' );
|
150 |
+
|
151 |
+
$output .= PHP_EOL . PHP_EOL . "-- Available Sites Version < 1.6.x" . PHP_EOL . PHP_EOL;
|
152 |
+
|
153 |
+
$i = 1;
|
154 |
+
foreach ( $clones as $key => $value ) {
|
155 |
+
$output .= $this->info( "Site name & subfolder :", $value );
|
156 |
+
}
|
157 |
+
$output .= PHP_EOL . PHP_EOL . "-- Available Sites Version > 2.0.x" . PHP_EOL . PHP_EOL;
|
158 |
+
|
159 |
+
foreach ( $clonesBeta as $key => $clone ) {
|
160 |
+
$output .= $this->info( "Number:", isset( $clone['number'] ) ? $clone['number'] : 'undefined' );
|
161 |
+
$output .= $this->info( "directoryName:", isset( $clone['directoryName'] ) ? $clone['directoryName'] : 'undefined' );
|
162 |
+
$output .= $this->info( "Path:", isset( $clone['path'] ) ? $clone['path'] : 'undefined' );
|
163 |
+
$output .= $this->info( "URL:", isset( $clone['url'] ) ? $clone['url'] : 'undefined' );
|
164 |
+
$output .= $this->info( "DB Prefix:", isset( $clone['prefix'] ) ? $clone['prefix'] : 'undefined' );
|
165 |
+
$output .= $this->info( "DB Prefix wp-config.php:", $this->getStagingPrefix($clone));
|
166 |
+
$output .= $this->info( "Version:", isset( $clone['version'] ) ? $clone['version'] : 'undefined' ) . PHP_EOL . PHP_EOL;
|
167 |
+
}
|
168 |
+
|
169 |
+
//$output .= PHP_EOL . PHP_EOL;
|
170 |
+
|
171 |
+
$output .= $this->info( "Plugin Version:", get_option('wpstg_version', 'undefined') );
|
172 |
+
$output .= $this->info( "Install Date:", get_option('wpstg_installDate', 'undefined') );
|
173 |
+
$output .= $this->info( "Upgraded from:", get_option('wpstg_version_upgraded_from', 'undefined') );
|
174 |
+
$output .= $this->info( "Is Staging Site:", get_option('wpstg_is_staging_site', 'undefined') ) . PHP_EOL . PHP_EOL;
|
175 |
+
|
176 |
+
|
177 |
+
return apply_filters( "wpstg_sysinfo_after_wpstaging_info", $output );
|
178 |
+
}
|
179 |
+
|
180 |
+
/**
|
181 |
+
* Browser Information
|
182 |
+
* @return string
|
183 |
+
*/
|
184 |
+
public function browser()
|
185 |
+
{
|
186 |
+
$output = $this->header("User Browser");
|
187 |
+
$output .= (new Browser);
|
188 |
+
|
189 |
+
return apply_filters("wpstg_sysinfo_after_user_browser", $output);
|
190 |
+
}
|
191 |
+
|
192 |
+
/**
|
193 |
+
* Frontpage Information when frontpage is set to "page"
|
194 |
+
* @return string
|
195 |
+
*/
|
196 |
+
public function frontPage()
|
197 |
+
{
|
198 |
+
if (get_option("show_on_front") !== "page")
|
199 |
+
{
|
200 |
+
return '';
|
201 |
+
}
|
202 |
+
|
203 |
+
$frontPageID = get_option("page_on_front");
|
204 |
+
$blogPageID = get_option("page_for_posts");
|
205 |
+
|
206 |
+
// Front Page
|
207 |
+
$pageFront = ($frontPageID != 0) ? get_the_title($frontPageID) . " (#{$frontPageID})" : "Unset";
|
208 |
+
// Blog Page ID
|
209 |
+
$pageBlog = ($blogPageID != 0) ? get_the_title($blogPageID) . " (#{$blogPageID})" : "Unset";
|
210 |
+
|
211 |
+
$output = $this->info("Page On Front:", $pageFront);
|
212 |
+
$output .= $this->info("Page For Posts:", $pageBlog);
|
213 |
+
|
214 |
+
return $output;
|
215 |
+
}
|
216 |
+
|
217 |
+
/**
|
218 |
+
* Check wp_remote_post() functionality
|
219 |
+
* @return string
|
220 |
+
*/
|
221 |
+
public function wpRemotePost()
|
222 |
+
{
|
223 |
+
// Make sure wp_remote_post() is working
|
224 |
+
$wpRemotePost = "wp_remote_post() does not work";
|
225 |
+
|
226 |
+
// Send request
|
227 |
+
$response = wp_remote_post(
|
228 |
+
"https://www.paypal.com/cgi-bin/webscr",
|
229 |
+
array(
|
230 |
+
"sslverify" => false,
|
231 |
+
"timeout" => 60,
|
232 |
+
"user-agent" => "WPSTG/" . WPStaging::VERSION,
|
233 |
+
"body" => array("cmd" => "_notify-validate")
|
234 |
+
)
|
235 |
+
);
|
236 |
+
|
237 |
+
// Validate it worked
|
238 |
+
if (!is_wp_error($response) && 200 <= $response["response"]["code"] && 300> $response["response"]["code"])
|
239 |
+
{
|
240 |
+
$wpRemotePost = "wp_remote_post() works";
|
241 |
+
}
|
242 |
+
|
243 |
+
return $this->info("Remote Post:", $wpRemotePost);
|
244 |
+
}
|
245 |
+
|
246 |
+
/**
|
247 |
+
* WordPress Configuration
|
248 |
+
* @return string
|
249 |
+
*/
|
250 |
+
public function wp()
|
251 |
+
{
|
252 |
+
$output = $this->header("WordPress Configuration");
|
253 |
+
$output .= $this->info("Version:", get_bloginfo("version"));
|
254 |
+
$output .= $this->info("Language:", (defined("WPLANG") && WPLANG) ? WPLANG : "en_US");
|
255 |
+
|
256 |
+
$permalinkStructure = get_option("permalink_structure");;
|
257 |
+
$output .= $this->info("Permalink Structure:", ($permalinkStructure) ? $permalinkStructure : "Default");
|
258 |
+
|
259 |
+
$output .= $this->info("Active Theme:", $this->theme());
|
260 |
+
$output .= $this->info("Show On Front:", get_option("show_on_front"));
|
261 |
+
|
262 |
+
// Frontpage information
|
263 |
+
$output .= $this->frontPage();
|
264 |
+
|
265 |
+
// WP Remote Post
|
266 |
+
$output .= $this->wpRemotePost();
|
267 |
+
|
268 |
+
// Table Prefix
|
269 |
+
$wpDB = $this->di->get("wpdb");
|
270 |
+
$tablePrefix = "DB Prefix: " . $wpDB->prefix . ' ';
|
271 |
+
$tablePrefix .= "Length: " . strlen($wpDB->prefix) . " Status: ";
|
272 |
+
$tablePrefix .= (strlen($wpDB->prefix) > 16) ? " ERROR: Too long" : " Acceptable";
|
273 |
+
|
274 |
+
$output .= $this->info("Table Prefix:", $tablePrefix);
|
275 |
+
|
276 |
+
// WP Debug
|
277 |
+
$output .= $this->info("WP_DEBUG:", (defined("WP_DEBUG")) ? WP_DEBUG ? "Enabled" : "Disabled" : "Not set");
|
278 |
+
$output .= $this->info("Memory Limit:", WP_MEMORY_LIMIT);
|
279 |
+
$output .= $this->info("Registered Post Stati:", implode(", ", \get_post_stati()));
|
280 |
+
|
281 |
+
return apply_filters("wpstg_sysinfo_after_wpstg_config", $output);
|
282 |
+
}
|
283 |
+
|
284 |
+
/**
|
285 |
+
* List of Active Plugins
|
286 |
+
* @param array $plugins
|
287 |
+
* @param array $activePlugins
|
288 |
+
* @return string
|
289 |
+
*/
|
290 |
+
public function activePlugins($plugins, $activePlugins)
|
291 |
+
{
|
292 |
+
$output = $this->header("WordPress Active Plugins");
|
293 |
+
|
294 |
+
foreach ($plugins as $path => $plugin)
|
295 |
+
{
|
296 |
+
if (!in_array($path, $activePlugins))
|
297 |
+
{
|
298 |
+
continue;
|
299 |
+
}
|
300 |
+
|
301 |
+
$output .= "{$plugin["Name"]}: {$plugin["Version"]}" . PHP_EOL;
|
302 |
+
}
|
303 |
+
|
304 |
+
return apply_filters("wpstg_sysinfo_after_wordpress_plugins", $output);
|
305 |
+
}
|
306 |
+
|
307 |
+
/**
|
308 |
+
* List of Inactive Plugins
|
309 |
+
* @param array $plugins
|
310 |
+
* @param array $activePlugins
|
311 |
+
* @return string
|
312 |
+
*/
|
313 |
+
public function inactivePlugins($plugins, $activePlugins)
|
314 |
+
{
|
315 |
+
$output = $this->header("WordPress Inactive Plugins");
|
316 |
+
|
317 |
+
foreach ($plugins as $path => $plugin)
|
318 |
+
{
|
319 |
+
if (in_array($path, $activePlugins))
|
320 |
+
{
|
321 |
+
continue;
|
322 |
+
}
|
323 |
+
|
324 |
+
$output .= "{$plugin["Name"]}: {$plugin["Version"]}" . PHP_EOL;
|
325 |
+
}
|
326 |
+
|
327 |
+
return apply_filters("wpstg_sysinfo_after_wordpress_plugins_inactive", $output);
|
328 |
+
}
|
329 |
+
|
330 |
+
/**
|
331 |
+
* Get list of active and inactive plugins
|
332 |
+
* @return string
|
333 |
+
*/
|
334 |
+
public function plugins()
|
335 |
+
{
|
336 |
+
// Get plugins and active plugins
|
337 |
+
$plugins = get_plugins();
|
338 |
+
$activePlugins = get_option("active_plugins", array());
|
339 |
+
|
340 |
+
// Active plugins
|
341 |
+
$output = $this->activePlugins($plugins, $activePlugins);
|
342 |
+
$output .= $this->inactivePlugins($plugins, $activePlugins);
|
343 |
+
|
344 |
+
return $output;
|
345 |
+
}
|
346 |
+
|
347 |
+
/**
|
348 |
+
* Multisite Plugins
|
349 |
+
* @return string
|
350 |
+
*/
|
351 |
+
public function multiSitePlugins()
|
352 |
+
{
|
353 |
+
if (!$this->isMultiSite)
|
354 |
+
{
|
355 |
+
return '';
|
356 |
+
}
|
357 |
+
|
358 |
+
$output = $this->header("Network Active Plugins");
|
359 |
+
|
360 |
+
$plugins = wp_get_active_network_plugins();
|
361 |
+
$activePlugins = get_site_option("active_sitewide_plugins", array());
|
362 |
+
|
363 |
+
foreach ($plugins as $pluginPath)
|
364 |
+
{
|
365 |
+
$pluginBase = plugin_basename($pluginPath);
|
366 |
+
|
367 |
+
if (!array_key_exists($pluginBase, $activePlugins))
|
368 |
+
{
|
369 |
+
continue;
|
370 |
+
}
|
371 |
+
|
372 |
+
$plugin = get_plugin_data($pluginPath);
|
373 |
+
|
374 |
+
$output .= "{$plugin["Name"]}: {$plugin["Version"]}" . PHP_EOL;
|
375 |
+
}
|
376 |
+
unset($plugins, $activePlugins);
|
377 |
+
|
378 |
+
return $output;
|
379 |
+
}
|
380 |
+
|
381 |
+
/**
|
382 |
+
* Server Information
|
383 |
+
* @return string
|
384 |
+
*/
|
385 |
+
public function server()
|
386 |
+
{
|
387 |
+
// Server Configuration
|
388 |
+
$output = $this->header("Webserver Configuration");
|
389 |
+
|
390 |
+
$output .= $this->info("PHP Version:", PHP_VERSION);
|
391 |
+
$output .= $this->info("MySQL Version:", $this->di->get("wpdb")->db_version());
|
392 |
+
$output .= $this->info("Webserver Info:", $_SERVER["SERVER_SOFTWARE"]);
|
393 |
+
|
394 |
+
return apply_filters("wpstg_sysinfo_after_webserver_config", $output);
|
395 |
+
}
|
396 |
+
|
397 |
+
/**
|
398 |
+
* PHP Configuration
|
399 |
+
* @return string
|
400 |
+
*/
|
401 |
+
public function php()
|
402 |
+
{
|
403 |
+
$output = $this->header("PHP Configuration");
|
404 |
+
$output .= $this->info("Safe Mode:", ($this->isSafeModeEnabled() ? "Enabled" : "Disabled"));
|
405 |
+
$output .= $this->info("Memory Limit:", ini_get("memory_limit"));
|
406 |
+
$output .= $this->info("Upload Max Size:", ini_get("upload_max_filesize"));
|
407 |
+
$output .= $this->info("Post Max Size:", ini_get("post_max_size"));
|
408 |
+
$output .= $this->info("Upload Max Filesize:", ini_get("upload_max_filesize"));
|
409 |
+
$output .= $this->info("Time Limit:", ini_get("max_execution_time"));
|
410 |
+
$output .= $this->info("Max Input Vars:", ini_get("max_input_vars"));
|
411 |
+
|
412 |
+
$displayErrors = ini_get("display_errors");
|
413 |
+
$output .= $this->info("Display Errors:", ($displayErrors) ? "On ({$displayErrors})" : "N/A");
|
414 |
+
|
415 |
+
return apply_filters("wpstg_sysinfo_after_php_config", $output);
|
416 |
+
}
|
417 |
+
|
418 |
+
/**
|
419 |
+
* Check if PHP is on Safe Mode
|
420 |
+
* @return bool
|
421 |
+
*/
|
422 |
+
public function isSafeModeEnabled()
|
423 |
+
{
|
424 |
+
return (
|
425 |
+
version_compare(PHP_VERSION, "5.4.0", '<') &&
|
426 |
+
@ini_get("safe_mode")
|
427 |
+
);
|
428 |
+
}
|
429 |
+
|
430 |
+
/**
|
431 |
+
* Checks if function exists or not
|
432 |
+
* @param string $functionName
|
433 |
+
* @return string
|
434 |
+
*/
|
435 |
+
public function isSupported($functionName)
|
436 |
+
{
|
437 |
+
return (function_exists($functionName)) ? "Supported" : "Not Supported";
|
438 |
+
}
|
439 |
+
|
440 |
+
/**
|
441 |
+
* Checks if class or extension is loaded / exists to determine if it is installed or not
|
442 |
+
* @param string $name
|
443 |
+
* @param bool $isClass
|
444 |
+
* @return string
|
445 |
+
*/
|
446 |
+
public function isInstalled($name, $isClass = true)
|
447 |
+
{
|
448 |
+
if (true === $isClass)
|
449 |
+
{
|
450 |
+
return (class_exists($name)) ? "Installed" : "Not Installed";
|
451 |
+
}
|
452 |
+
else
|
453 |
+
{
|
454 |
+
return (extension_loaded($name)) ? "Installed" : "Not Installed";
|
455 |
+
}
|
456 |
+
}
|
457 |
+
|
458 |
+
/**
|
459 |
+
* Gets Installed Important PHP Extensions
|
460 |
+
* @return string
|
461 |
+
*/
|
462 |
+
public function phpExtensions()
|
463 |
+
{
|
464 |
+
// Important PHP Extensions
|
465 |
+
$output = $this->header("PHP Extensions");
|
466 |
+
$output .= $this->info("cURL:", $this->isSupported("curl_init"));
|
467 |
+
$output .= $this->info("fsockopen:", $this->isSupported("fsockopen"));
|
468 |
+
$output .= $this->info("SOAP Client:", $this->isInstalled("SoapClient"));
|
469 |
+
$output .= $this->info("Suhosin:", $this->isInstalled("suhosin", false));
|
470 |
+
|
471 |
+
return apply_filters("wpstg_sysinfo_after_php_ext", $output);
|
472 |
+
}
|
473 |
+
|
474 |
+
/**
|
475 |
+
* Check if WP is installed in subdir
|
476 |
+
* @return boolean
|
477 |
+
*/
|
478 |
+
private function isSubDir(){
|
479 |
+
if ( get_option( 'siteurl' ) !== get_option( 'home' ) ) {
|
480 |
+
return true;
|
481 |
+
}
|
482 |
+
return false;
|
483 |
+
}
|
484 |
+
|
485 |
+
/**
|
486 |
+
* Check and return prefix of the staging site
|
487 |
+
*/
|
488 |
+
/**
|
489 |
+
* Try to get the staging prefix from wp-config.php of staging site
|
490 |
+
* @param array $clone
|
491 |
+
* @return sting
|
492 |
+
*/
|
493 |
+
private function getStagingPrefix($clone=array()) {
|
494 |
+
// Throw error
|
495 |
+
$path = ABSPATH . $clone['directoryName'] . "/wp-config.php";
|
496 |
+
if (false === ($content = @file_get_contents($path))) {
|
497 |
+
return 'Can\'t find staging wp-config.php';
|
498 |
+
} else {
|
499 |
+
|
500 |
+
// Get prefix from wp-config.php
|
501 |
+
//preg_match_all("/table_prefix\s*=\s*'(\w*)';/", $content, $matches);
|
502 |
+
preg_match("/table_prefix\s*=\s*'(\w*)';/", $content, $matches);
|
503 |
+
//wp_die(var_dump($matches));
|
504 |
+
|
505 |
+
if (!empty($matches[1])) {
|
506 |
+
return $matches[1];
|
507 |
+
} else {
|
508 |
+
return 'No table_prefix in wp-config.php';
|
509 |
+
}
|
510 |
+
}
|
511 |
+
|
512 |
+
}
|
513 |
}
|
apps/Backend/public/css/wpstg-admin.css
CHANGED
@@ -1,772 +1,783 @@
|
|
1 |
-
/**
|
2 |
-
* WPSTG Admin CSS
|
3 |
-
*
|
4 |
-
* @package WPSTG
|
5 |
-
* @subpackage Admin CSS
|
6 |
-
* @copyright Copyright (c) 2015, René Hermenau
|
7 |
-
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
8 |
-
*/
|
9 |
-
|
10 |
-
|
11 |
-
/* CSS for Tabs */
|
12 |
-
|
13 |
-
#tab_container ul {
|
14 |
-
/*height: 200px;*/
|
15 |
-
list-style: none;
|
16 |
-
margin: 0;
|
17 |
-
padding: 0;
|
18 |
-
background: #f1f1f1;
|
19 |
-
float: left;
|
20 |
-
/*list-style-type: square;*/
|
21 |
-
}
|
22 |
-
|
23 |
-
#tab_container ul li:first-child.selected-tab {
|
24 |
-
border-top: none;
|
25 |
-
}
|
26 |
-
|
27 |
-
#tab_container ul li a.selected-tab {
|
28 |
-
font-weight: bold;
|
29 |
-
text-decoration: none;
|
30 |
-
}
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
#tab_container .row{
|
35 |
-
padding-top:10px;
|
36 |
-
padding-bottom:12px;
|
37 |
-
}
|
38 |
-
|
39 |
-
#wpstg-tools .nav-tab-wrapper{
|
40 |
-
padding:0;
|
41 |
-
}
|
42 |
-
|
43 |
-
|
44 |
-
#tab_container .row label strong, #tab_container .row strong {
|
45 |
-
font-weight: bold;
|
46 |
-
}
|
47 |
-
|
48 |
-
.wpstg-tabs a {
|
49 |
-
padding:5px;
|
50 |
-
}
|
51 |
-
|
52 |
-
#tab_container > ul > li.wpstg-tabs.active {
|
53 |
-
background-color:white;
|
54 |
-
}
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
#wpstg_settingsgeneral_header .row:nth-child(3), #wpstg_settingsgeneral_header .row:nth-child(4){
|
59 |
-
display:none;
|
60 |
-
}
|
61 |
-
|
62 |
-
/* Layout of admin table and rows
|
63 |
-
*/
|
64 |
-
|
65 |
-
#tab_container .panel-container {
|
66 |
-
background: #FFF;
|
67 |
-
padding:0 20px 20px 20px;
|
68 |
-
overflow:auto;
|
69 |
-
}
|
70 |
-
|
71 |
-
#tab_container .form-table th {
|
72 |
-
vertical-align: top;
|
73 |
-
text-align: left;
|
74 |
-
padding: 20px 10px 20px 0;
|
75 |
-
line-height: 1.3;
|
76 |
-
font-weight: bold;
|
77 |
-
font-size: 14px;
|
78 |
-
color:#484848;
|
79 |
-
width: 30%;
|
80 |
-
}
|
81 |
-
|
82 |
-
#tab_container .form-table tr {
|
83 |
-
border-bottom: 1px solid #E7E7E7;
|
84 |
-
}
|
85 |
-
|
86 |
-
#tab_container span.description{
|
87 |
-
display: block;
|
88 |
-
font-weight: 400;
|
89 |
-
font-style: normal;
|
90 |
-
font-size: 13px;
|
91 |
-
margin-top: 7px;
|
92 |
-
color:#484848;
|
93 |
-
}
|
94 |
-
|
95 |
-
#tab_container .col-title{
|
96 |
-
color:#484848;
|
97 |
-
}
|
98 |
-
|
99 |
-
@media only screen and (max-width:680px) {
|
100 |
-
#tab_container ul {
|
101 |
-
float:none;
|
102 |
-
}
|
103 |
-
#tab_container .form-table tr > th {
|
104 |
-
width:100%;
|
105 |
-
}
|
106 |
-
#tab_container span.description{
|
107 |
-
font-size: 14px;
|
108 |
-
}
|
109 |
-
#tab_container .form-table tr > th, #tab_container .form-table tr > td {
|
110 |
-
padding:10px;
|
111 |
-
}
|
112 |
-
}
|
113 |
-
|
114 |
-
#tab_container ul li {
|
115 |
-
margin-bottom:0;
|
116 |
-
}
|
117 |
-
|
118 |
-
#tab_container ul li a {
|
119 |
-
display: block;
|
120 |
-
padding:10px 4px 10px 14px;
|
121 |
-
border-width: 1px 0;
|
122 |
-
border-style: solid;
|
123 |
-
border-top-color:white;
|
124 |
-
border-bottom-color:#e7e7e7;
|
125 |
-
text-decoration: none;
|
126 |
-
color: #0097DF;
|
127 |
-
font-weight: bold;
|
128 |
-
}
|
129 |
-
#tab_container ul li a:hover {
|
130 |
-
background-color: #e5e5e5;
|
131 |
-
color:#777777;
|
132 |
-
}
|
133 |
-
|
134 |
-
|
135 |
-
.wp-staginglogo{
|
136 |
-
display: block;
|
137 |
-
font-size:16px;
|
138 |
-
padding-top:20px;
|
139 |
-
width:220px;
|
140 |
-
float:left;
|
141 |
-
}
|
142 |
-
|
143 |
-
.wpstg-version{
|
144 |
-
display: block;
|
145 |
-
padding-top:29px
|
146 |
-
}
|
147 |
-
|
148 |
-
|
149 |
-
.wpstg_admin .nav-tab {
|
150 |
-
color: #3C3C3C;
|
151 |
-
}
|
152 |
-
|
153 |
-
|
154 |
-
#tab_container table tbody tr:nth-child(1) > th > div {
|
155 |
-
font-size: 20px;
|
156 |
-
}
|
157 |
-
|
158 |
-
.wpstg_hidden{
|
159 |
-
display: none;
|
160 |
-
}
|
161 |
-
|
162 |
-
/* End layout of admin table and rows
|
163 |
-
*/
|
164 |
-
#mashtabcontainer > .mashtabs {
|
165 |
-
background-color: #ffffff;
|
166 |
-
}
|
167 |
-
|
168 |
-
#mashtabcontainer ul .active {
|
169 |
-
background-color: #00adef;
|
170 |
-
color: white;
|
171 |
-
border-bottom-color: #0098D2;
|
172 |
-
}
|
173 |
-
|
174 |
-
#mashtabcontainer ul .active:hover {
|
175 |
-
background-color: #00A4E2;
|
176 |
-
color: white;
|
177 |
-
border-bottom-color: #0098D2;
|
178 |
-
}
|
179 |
-
|
180 |
-
#mashtabcontainer ul li a {
|
181 |
-
padding: 10px 14px 10px 14px;
|
182 |
-
background-color: #f3f3f3
|
183 |
-
|
184 |
-
}
|
185 |
-
|
186 |
-
#mashtabcontainer .mashtab-container {
|
187 |
-
border: 0 solid #ececec;
|
188 |
-
}
|
189 |
-
|
190 |
-
/* Cloning workflow */
|
191 |
-
#wpstg-clonepage-wrapper {
|
192 |
-
margin-bottom: 20px;
|
193 |
-
/*width: 690px; */
|
194 |
-
}
|
195 |
-
|
196 |
-
@media screen and (min-width:1090px){
|
197 |
-
#wpstg-clonepage-wrapper {
|
198 |
-
float: left;
|
199 |
-
margin-bottom: 20px;
|
200 |
-
/*width: 690px;*/
|
201 |
-
}
|
202 |
-
.wpstg-sidebar{
|
203 |
-
display: none;
|
204 |
-
margin-left: 700px;
|
205 |
-
margin-top: 138px;
|
206 |
-
}
|
207 |
-
}
|
208 |
-
|
209 |
-
.wpstg-sidebar{
|
210 |
-
display: none;
|
211 |
-
padding: 10px;
|
212 |
-
border: 1px solid #DFDFDF;
|
213 |
-
max-width: 250px;
|
214 |
-
height: 250px;
|
215 |
-
}
|
216 |
-
|
217 |
-
#wpstg-steps {
|
218 |
-
margin-top:30px;
|
219 |
-
}
|
220 |
-
|
221 |
-
#wpstg-steps li {
|
222 |
-
color: #444;
|
223 |
-
line-height: 20px;
|
224 |
-
padding-right:10px;
|
225 |
-
float:left;
|
226 |
-
}
|
227 |
-
|
228 |
-
|
229 |
-
.wpstg-step-num {
|
230 |
-
border: 1px solid #444;
|
231 |
-
border-radius: 3px;
|
232 |
-
display: inline-block;
|
233 |
-
width: 20px;
|
234 |
-
height: 20px;
|
235 |
-
text-align: center;
|
236 |
-
margin-right: 5px;
|
237 |
-
}
|
238 |
-
|
239 |
-
.wpstg-current-step {
|
240 |
-
font-weight: bold;
|
241 |
-
}
|
242 |
-
|
243 |
-
.wpstg-current-step .wpstg-step-num {
|
244 |
-
background: #444;
|
245 |
-
color: #eee;
|
246 |
-
}
|
247 |
-
|
248 |
-
.wpstg-clone {
|
249 |
-
border: 3px solid #ffffff;
|
250 |
-
margin-bottom: 5px;
|
251 |
-
padding: 5px 10px;
|
252 |
-
width: 300px;
|
253 |
-
position: relative;
|
254 |
-
overflow: hidden;
|
255 |
-
transition: border-color .2s ease-in-out;
|
256 |
-
background-color: #DDDDDD;
|
257 |
-
}
|
258 |
-
|
259 |
-
.wpstg-clone.active {
|
260 |
-
border-color: #1d94cf;;
|
261 |
-
}
|
262 |
-
|
263 |
-
.wpstg-clone-title {
|
264 |
-
display: inline-block;
|
265 |
-
font-size: 15px;
|
266 |
-
max-width: 130px;
|
267 |
-
text-decoration: none;
|
268 |
-
font-weight: bold;
|
269 |
-
color:#0285AE;
|
270 |
-
}
|
271 |
-
|
272 |
-
.wpstg-clone-action {
|
273 |
-
background: #ffffff;
|
274 |
-
border-left: 1px solid #ccc;
|
275 |
-
color: #bbb;
|
276 |
-
padding: 0 5px;
|
277 |
-
float: right;
|
278 |
-
text-decoration: none;
|
279 |
-
position: relative;
|
280 |
-
transition: color .2s ease-in-out;
|
281 |
-
}
|
282 |
-
|
283 |
-
.wpstg-remove-clone:hover {
|
284 |
-
color: #ef6d6d;
|
285 |
-
}
|
286 |
-
|
287 |
-
.wpstg-clone-action:last-child {
|
288 |
-
border: none;
|
289 |
-
}
|
290 |
-
|
291 |
-
.wpstg-clone:hover .wpstg-clone-action {
|
292 |
-
display: inline-block;
|
293 |
-
}
|
294 |
-
|
295 |
-
#wpstg-show-error-details:focus,
|
296 |
-
#wpstg-workflow .wpstg-clone-action {
|
297 |
-
outline: none;
|
298 |
-
box-shadow: none;
|
299 |
-
}
|
300 |
-
|
301 |
-
.wpstg-link-btn {
|
302 |
-
background: #45a1c9;
|
303 |
-
color: #fff;
|
304 |
-
display: inline-block;
|
305 |
-
padding: 5px 10px;
|
306 |
-
text-decoration: none;
|
307 |
-
vertical-align: baseline;
|
308 |
-
transition: all .2s ease-in-out;
|
309 |
-
}
|
310 |
-
|
311 |
-
.wpstg-link-btn:hover,
|
312 |
-
.wpstg-link-btn:focus {
|
313 |
-
color: #fff;
|
314 |
-
outline: none;
|
315 |
-
box-shadow: none;
|
316 |
-
}
|
317 |
-
|
318 |
-
#wpstg-workflow .wpstg-link-btn:active {
|
319 |
-
vertical-align: baseline;
|
320 |
-
}
|
321 |
-
|
322 |
-
.wpstg-link-btn[disabled] {
|
323 |
-
background: #777 !important;
|
324 |
-
pointer-events: none;
|
325 |
-
}
|
326 |
-
|
327 |
-
#wpstg-cancel-cloning {
|
328 |
-
background: #ff3428;
|
329 |
-
border-color: #e72f24;
|
330 |
-
margin-top: 5px;
|
331 |
-
}
|
332 |
-
|
333 |
-
#wpstg-cancel-cloning.success {
|
334 |
-
background: #64dd58;
|
335 |
-
border-color: #54bd4a;
|
336 |
-
}
|
337 |
-
|
338 |
-
#wpstg-error-wrapper,
|
339 |
-
#wpstg-error-details {
|
340 |
-
display: none;
|
341 |
-
margin-top: 10px;
|
342 |
-
font-size: 13px;
|
343 |
-
}
|
344 |
-
|
345 |
-
#wpstg-show-error-details {
|
346 |
-
display: inline-block;
|
347 |
-
margin-left: 5px;
|
348 |
-
color: #555;
|
349 |
-
text-decoration: none;
|
350 |
-
transition: color .2s ease-in-out;
|
351 |
-
}
|
352 |
-
|
353 |
-
#wpstg-show-error-details:hover {
|
354 |
-
color: #1d94cf;
|
355 |
-
}
|
356 |
-
|
357 |
-
#wpstg-error-details {
|
358 |
-
border-left: 5px solid #ef6d6d;
|
359 |
-
padding: 10px;
|
360 |
-
width: 500px;
|
361 |
-
}
|
362 |
-
|
363 |
-
#wpstg-home-link,
|
364 |
-
#wpstg-try-again {
|
365 |
-
display: none;
|
366 |
-
}
|
367 |
-
|
368 |
-
|
369 |
-
#wpstg-loader {
|
370 |
-
content: url('../img/loading.gif');
|
371 |
-
margin-top:-5px;
|
372 |
-
}
|
373 |
-
|
374 |
-
#wpstg-loader.wpstg-finished {
|
375 |
-
content:"Finished";
|
376 |
-
background-color:#00c89a;
|
377 |
-
color:white;
|
378 |
-
padding:2px;
|
379 |
-
margin-top:6px;
|
380 |
-
}
|
381 |
-
|
382 |
-
#wpstg-workflow {
|
383 |
-
position: relative;
|
384 |
-
clear:both;
|
385 |
-
padding-top:20px;
|
386 |
-
margin-right:20px;
|
387 |
-
float:left;
|
388 |
-
min-width: 500px;
|
389 |
-
border-right: 1px solid #DFDFDF;
|
390 |
-
min-height: 380px;
|
391 |
-
padding-right: 20px;
|
392 |
-
}
|
393 |
-
|
394 |
-
#wpstg-sidebar {
|
395 |
-
float: left;
|
396 |
-
max-width: 400px;
|
397 |
-
display: block;
|
398 |
-
}
|
399 |
-
|
400 |
-
@media screen and (max-width:1150px){
|
401 |
-
#wpstg-sidebar img{
|
402 |
-
margin-top: 30px;
|
403 |
-
}
|
404 |
-
}
|
405 |
-
|
406 |
-
#wpstg-workflow.loading::after,
|
407 |
-
#wpstg-removing-clone.loading::after {
|
408 |
-
background: rgba(255, 255, 255, .7);
|
409 |
-
content: 'Loading... may take a while for huge websites';
|
410 |
-
display: block;
|
411 |
-
width: 100%;
|
412 |
-
height: 100%;
|
413 |
-
font-size: 20px;
|
414 |
-
padding-top: 100px;
|
415 |
-
text-align: center;
|
416 |
-
position: absolute;
|
417 |
-
top: 0;
|
418 |
-
left: 0;
|
419 |
-
z-index: 99;
|
420 |
-
}
|
421 |
-
|
422 |
-
#wpstg-removing-clone.loading::after {
|
423 |
-
content: 'REMOVING' !important;
|
424 |
-
}
|
425 |
-
|
426 |
-
#wpstg-existing-clones,
|
427 |
-
#wpstg-removing-clone {
|
428 |
-
position: relative;
|
429 |
-
}
|
430 |
-
|
431 |
-
.wpstg-progress-bar {
|
432 |
-
max-width: 900px;
|
433 |
-
height: 27px;
|
434 |
-
padding: 0;
|
435 |
-
background-color: #d6d8d7;
|
436 |
-
}
|
437 |
-
|
438 |
-
.wpstg-progress {
|
439 |
-
background: #1d94cf;
|
440 |
-
width: 0;
|
441 |
-
height: 100%;
|
442 |
-
transition: width 1s;
|
443 |
-
color:white;
|
444 |
-
line-height:25px;
|
445 |
-
text-align:center;
|
446 |
-
}
|
447 |
-
|
448 |
-
#wpstg-new-clone-id.wpstg-error-input,
|
449 |
-
#wpstg-clone-path.wpstg-error-input {
|
450 |
-
border: 1px solid #ff4235;
|
451 |
-
box-shadow: 0 0 2px rgba(255, 66, 53, .8);
|
452 |
-
}
|
453 |
-
|
454 |
-
#wpstg-clone-path {
|
455 |
-
margin-left: 10px;
|
456 |
-
width: 350px;
|
457 |
-
}
|
458 |
-
|
459 |
-
.wpstg-error-msg {
|
460 |
-
color: #ff4235;
|
461 |
-
}
|
462 |
-
|
463 |
-
#wpstg-clone-id-error {
|
464 |
-
display: block;
|
465 |
-
text-align: right;
|
466 |
-
margin-right: 90px;
|
467 |
-
}
|
468 |
-
|
469 |
-
#wpstg-start-cloning + .wpstg-error-msg {
|
470 |
-
display: block;
|
471 |
-
margin-top: 5px;
|
472 |
-
}
|
473 |
-
|
474 |
-
.wpstg-size-info {
|
475 |
-
color: #999;
|
476 |
-
font-weight: normal;
|
477 |
-
position: relative;
|
478 |
-
left: 2px;
|
479 |
-
}
|
480 |
-
|
481 |
-
.wpstg-db-table .wpstg-size-info {
|
482 |
-
top: 2px;
|
483 |
-
}
|
484 |
-
|
485 |
-
#wpstg-workflow #wpstg-start-cloning {
|
486 |
-
display: inline-block;
|
487 |
-
margin-left: 5px;
|
488 |
-
font-size: 14px;
|
489 |
-
vertical-align: baseline;
|
490 |
-
}
|
491 |
-
|
492 |
-
/* Tabs */
|
493 |
-
.wpstg-tabs-wrapper {
|
494 |
-
max-width: 640px;
|
495 |
-
margin: 10px 0;
|
496 |
-
}
|
497 |
-
|
498 |
-
#wpstg-path-wrapper {
|
499 |
-
border-bottom: 2px dashed #ccc;
|
500 |
-
padding-bottom: 10px;
|
501 |
-
margin-bottom: 10px;
|
502 |
-
}
|
503 |
-
|
504 |
-
.wpstg-tabs-wrapper {
|
505 |
-
border: 1px solid #ddd;
|
506 |
-
border-right: none;
|
507 |
-
border-left: none;
|
508 |
-
}
|
509 |
-
|
510 |
-
.wpstg-tab-section {
|
511 |
-
border: 1px solid #ddd;
|
512 |
-
border-right: none;
|
513 |
-
border-left: none;
|
514 |
-
display: none;
|
515 |
-
padding: 20px;
|
516 |
-
}
|
517 |
-
|
518 |
-
.wpstg-tab-section::after {
|
519 |
-
display: block;
|
520 |
-
content: '';
|
521 |
-
clear: both;
|
522 |
-
}
|
523 |
-
|
524 |
-
.wpstg-tab-header {
|
525 |
-
border: 1px solid #ddd;
|
526 |
-
border-right: none;
|
527 |
-
border-left: none;
|
528 |
-
color: #444;
|
529 |
-
font-size: 16px;
|
530 |
-
font-weight: bolder;
|
531 |
-
display: block;
|
532 |
-
padding: 10px;;
|
533 |
-
text-decoration: none;
|
534 |
-
}
|
535 |
-
|
536 |
-
.wpstg-tab-triangle {
|
537 |
-
font-family: arial;
|
538 |
-
display: inline-block;
|
539 |
-
margin-right: 10px;
|
540 |
-
}
|
541 |
-
|
542 |
-
.wpstg-tab-header:focus {
|
543 |
-
color: #444;
|
544 |
-
outline: none;
|
545 |
-
box-shadow: none;
|
546 |
-
}
|
547 |
-
|
548 |
-
#wpstg-large-files {
|
549 |
-
display:none;
|
550 |
-
border: 1px dashed #ccc;
|
551 |
-
/*float: right;*/
|
552 |
-
padding: 10px 10px 10px;
|
553 |
-
margin-top:20px;
|
554 |
-
position: relative;
|
555 |
-
font-size:12px;
|
556 |
-
}
|
557 |
-
|
558 |
-
#wpstg-large-files h3 {
|
559 |
-
background: #fff;
|
560 |
-
margin: 0;
|
561 |
-
padding: 0 5px;
|
562 |
-
position: absolute;
|
563 |
-
top: -10px;
|
564 |
-
left: 5px;
|
565 |
-
}
|
566 |
-
|
567 |
-
/* tmp */
|
568 |
-
.wpstg-subdir {
|
569 |
-
display: none;
|
570 |
-
margin-left: 20px;
|
571 |
-
}
|
572 |
-
|
573 |
-
.wpstg-dir a.disabled {
|
574 |
-
color: #888;
|
575 |
-
cursor: default;
|
576 |
-
text-decoration: none;
|
577 |
-
}
|
578 |
-
|
579 |
-
.wpstg-check-subdirs {
|
580 |
-
display: inline-block;
|
581 |
-
margin-left: 10px;
|
582 |
-
}
|
583 |
-
|
584 |
-
.wpstg-notice-alert{
|
585 |
-
display:block;
|
586 |
-
background-color:#FFD0D0;
|
587 |
-
padding:20px;
|
588 |
-
border: 1px solid #fff;
|
589 |
-
max-width: 600px;
|
590 |
-
}
|
591 |
-
|
592 |
-
.wpstg-header{
|
593 |
-
font-weight: 400;
|
594 |
-
line-height: 1.6em;
|
595 |
-
font-size: 19px;
|
596 |
-
border-bottom: 1px solid #DFDFDF;
|
597 |
-
clear:both;
|
598 |
-
}
|
599 |
-
|
600 |
-
|
601 |
-
#wpstg-clone-label{
|
602 |
-
font-size: 14px;
|
603 |
-
font-weight: bold;
|
604 |
-
}
|
605 |
-
|
606 |
-
#wpstg-log-details{
|
607 |
-
height: 300px;
|
608 |
-
max-width: 700px;
|
609 |
-
overflow: scroll;
|
610 |
-
/*max-width: 650px;*/
|
611 |
-
font-family: monospace;
|
612 |
-
font-size: 12px;
|
613 |
-
line-height: 15px;
|
614 |
-
border: 1px solid #FFF;
|
615 |
-
background-color: black;
|
616 |
-
color: #c0c0c0;
|
617 |
-
padding:3px;
|
618 |
-
white-space: nowrap;
|
619 |
-
margin-top: 15px;
|
620 |
-
}
|
621 |
-
|
622 |
-
#wpstg-finished-result {
|
623 |
-
display:none;
|
624 |
-
}
|
625 |
-
|
626 |
-
#wpstg-remove-cloning {
|
627 |
-
background: #ff3428;
|
628 |
-
border-color: #e72f24;
|
629 |
-
margin-top: 5px;
|
630 |
-
}
|
631 |
-
|
632 |
-
#wpstg-success-notice{
|
633 |
-
padding: 10px;
|
634 |
-
background-color: white;
|
635 |
-
max-width: 900px;
|
636 |
-
border: 1px solid #ccc;
|
637 |
-
margin-top: 20px;
|
638 |
-
}
|
639 |
-
|
640 |
-
.wpstg_beta_notice {
|
641 |
-
margin-bottom:20px;
|
642 |
-
}
|
643 |
-
|
644 |
-
.wpstg-sysinfo {
|
645 |
-
width:700px;
|
646 |
-
height: 500px;
|
647 |
-
}
|
648 |
-
|
649 |
-
.form-table .col-title label {
|
650 |
-
font-weight: 600;
|
651 |
-
}
|
652 |
-
|
653 |
-
.form-table td:first-child {
|
654 |
-
width:30%;
|
655 |
-
}
|
656 |
-
|
657 |
-
|
658 |
-
.wpstg-share-button-container{
|
659 |
-
margin: 5px 0;
|
660 |
-
}
|
661 |
-
|
662 |
-
.wpstg-share-button-container p{
|
663 |
-
margin:0px 0 10px 0;
|
664 |
-
}
|
665 |
-
|
666 |
-
.wpstg-share-button {
|
667 |
-
display: inline-block;
|
668 |
-
}
|
669 |
-
|
670 |
-
.wpstg-share-button a{
|
671 |
-
text-decoration:none;
|
672 |
-
}
|
673 |
-
|
674 |
-
.wpstg-share-button .wpstg-share {
|
675 |
-
font-family:sans-serif;
|
676 |
-
font-weight:bold;
|
677 |
-
text-decoration:none;
|
678 |
-
text-align:center;
|
679 |
-
}
|
680 |
-
|
681 |
-
|
682 |
-
.wpstg-share-button .wpstg-share {
|
683 |
-
-webkit-border-radius:2px;
|
684 |
-
-moz-border-radius:2px;
|
685 |
-
border-radius:2px;
|
686 |
-
color:#FFF;
|
687 |
-
display:inline;
|
688 |
-
font-size:16px;
|
689 |
-
width:40px;
|
690 |
-
padding:4px 8px;
|
691 |
-
}
|
692 |
-
|
693 |
-
.wpstg-share-button-twitter .wpstg-share {
|
694 |
-
background-color:#00ABF0;
|
695 |
-
}
|
696 |
-
|
697 |
-
.wpstg-share-button-facebook .wpstg-share {
|
698 |
-
background-color:#3b5998;
|
699 |
-
}
|
700 |
-
|
701 |
-
.wpstg-share-button-googleplus .wpstg-share {
|
702 |
-
background-color:#F53424;
|
703 |
-
}
|
704 |
-
|
705 |
-
.wpstg-share-button-twitter .share:active,.wpstg-share-button-facebook .share:active,.wpstg-share-button-googleplus .share:active {
|
706 |
-
background-color:#353535;
|
707 |
-
}
|
708 |
-
|
709 |
-
#wpstg-check-space {
|
710 |
-
margin-left:8px;
|
711 |
-
}
|
712 |
-
|
713 |
-
/* welcome screen */
|
714 |
-
.wpstg-button.green {
|
715 |
-
display: inline-block;
|
716 |
-
background-color: #83c11f;
|
717 |
-
padding: 10px;
|
718 |
-
min-width: 170px;
|
719 |
-
color: white;
|
720 |
-
font-size: 16px;
|
721 |
-
text-decoration: none;
|
722 |
-
text-align: center;
|
723 |
-
margin-top: 20px;
|
724 |
-
}
|
725 |
-
#wpstg-welcome li {
|
726 |
-
font-size: 18px;
|
727 |
-
line-height: 29px;
|
728 |
-
position: relative;
|
729 |
-
padding-left: 23px;
|
730 |
-
list-style: none!important;
|
731 |
-
}
|
732 |
-
#wpstg-welcome {
|
733 |
-
margin-top:20px;
|
734 |
-
margin-right: 20px;
|
735 |
-
background-color: white;
|
736 |
-
}
|
737 |
-
.wpstg-heading-pro {
|
738 |
-
color: #0080ff;
|
739 |
-
font-weight: bold;
|
740 |
-
}
|
741 |
-
.wpstg-h2 {
|
742 |
-
margin-top: 0px;
|
743 |
-
margin-bottom: 1.2rem;
|
744 |
-
font-size: 30px;
|
745 |
-
line-height: 2.5rem;
|
746 |
-
}
|
747 |
-
#wpstg-welcome li:before {
|
748 |
-
width: 1em;
|
749 |
-
height: 100%;
|
750 |
-
background: url(data:image/svg+xml;charset=utf8,%3Csvg%20width%3D%221792%22%20height%3D%221792%22%20viewBox%3D%220%200%201792%201792%22%20xmlns%3D%22http%3A%2F%2Fwww%2Ew3%2Eorg%2F2000%2Fsvg%22%3E%3Cpath%20fill%3D%22%2377B227%22%20d%3D%22M1671%20566q0%2040%2D28%2068l%2D724%20724%2D136%20136q%2D28%2028%2D68%2028t%2D68%2D28l%2D136%2D136%2D362%2D362q%2D28%2D28%2D28%2D68t28%2D68l136%2D136q28%2D28%2068%2D28t68%2028l294%20295%20656%2D657q28%2D28%2068%2D28t68%2028l136%20136q28%2028%2028%2068z%22%2F%3E%3C%2Fsvg%3E) left .4em no-repeat;
|
751 |
-
background-size: contain;
|
752 |
-
content: "";
|
753 |
-
position: absolute;
|
754 |
-
top: 0;
|
755 |
-
left: 0;
|
756 |
-
color: #77b227;
|
757 |
-
}
|
758 |
-
.wpstg-h1 {
|
759 |
-
font-size: 2.75em;
|
760 |
-
margin-bottom: 1.35rem;
|
761 |
-
font-size: 2.5em;
|
762 |
-
line-height: 3.68rem;
|
763 |
-
letter-spacing: normal;
|
764 |
-
}
|
765 |
-
#wpstg-welcome h2 {
|
766 |
-
margin: 0 0 15px;
|
767 |
-
}
|
768 |
-
#wpstg-welcome .wpstg-footer {
|
769 |
-
clear: both;
|
770 |
-
margin-top: 20px;
|
771 |
-
font-style: italic;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
772 |
}
|
1 |
+
/**
|
2 |
+
* WPSTG Admin CSS
|
3 |
+
*
|
4 |
+
* @package WPSTG
|
5 |
+
* @subpackage Admin CSS
|
6 |
+
* @copyright Copyright (c) 2015, René Hermenau
|
7 |
+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
8 |
+
*/
|
9 |
+
|
10 |
+
|
11 |
+
/* CSS for Tabs */
|
12 |
+
|
13 |
+
#tab_container ul {
|
14 |
+
/*height: 200px;*/
|
15 |
+
list-style: none;
|
16 |
+
margin: 0;
|
17 |
+
padding: 0;
|
18 |
+
background: #f1f1f1;
|
19 |
+
float: left;
|
20 |
+
/*list-style-type: square;*/
|
21 |
+
}
|
22 |
+
|
23 |
+
#tab_container ul li:first-child.selected-tab {
|
24 |
+
border-top: none;
|
25 |
+
}
|
26 |
+
|
27 |
+
#tab_container ul li a.selected-tab {
|
28 |
+
font-weight: bold;
|
29 |
+
text-decoration: none;
|
30 |
+
}
|
31 |
+
|
32 |
+
|
33 |
+
|
34 |
+
#tab_container .row{
|
35 |
+
padding-top:10px;
|
36 |
+
padding-bottom:12px;
|
37 |
+
}
|
38 |
+
|
39 |
+
#wpstg-tools .nav-tab-wrapper{
|
40 |
+
padding:0;
|
41 |
+
}
|
42 |
+
|
43 |
+
|
44 |
+
#tab_container .row label strong, #tab_container .row strong {
|
45 |
+
font-weight: bold;
|
46 |
+
}
|
47 |
+
|
48 |
+
.wpstg-tabs a {
|
49 |
+
padding:5px;
|
50 |
+
}
|
51 |
+
|
52 |
+
#tab_container > ul > li.wpstg-tabs.active {
|
53 |
+
background-color:white;
|
54 |
+
}
|
55 |
+
|
56 |
+
|
57 |
+
|
58 |
+
#wpstg_settingsgeneral_header .row:nth-child(3), #wpstg_settingsgeneral_header .row:nth-child(4){
|
59 |
+
display:none;
|
60 |
+
}
|
61 |
+
|
62 |
+
/* Layout of admin table and rows
|
63 |
+
*/
|
64 |
+
|
65 |
+
#tab_container .panel-container {
|
66 |
+
background: #FFF;
|
67 |
+
padding:0 20px 20px 20px;
|
68 |
+
overflow:auto;
|
69 |
+
}
|
70 |
+
|
71 |
+
#tab_container .form-table th {
|
72 |
+
vertical-align: top;
|
73 |
+
text-align: left;
|
74 |
+
padding: 20px 10px 20px 0;
|
75 |
+
line-height: 1.3;
|
76 |
+
font-weight: bold;
|
77 |
+
font-size: 14px;
|
78 |
+
color:#484848;
|
79 |
+
width: 30%;
|
80 |
+
}
|
81 |
+
|
82 |
+
#tab_container .form-table tr {
|
83 |
+
border-bottom: 1px solid #E7E7E7;
|
84 |
+
}
|
85 |
+
|
86 |
+
#tab_container span.description{
|
87 |
+
display: block;
|
88 |
+
font-weight: 400;
|
89 |
+
font-style: normal;
|
90 |
+
font-size: 13px;
|
91 |
+
margin-top: 7px;
|
92 |
+
color:#484848;
|
93 |
+
}
|
94 |
+
|
95 |
+
#tab_container .col-title{
|
96 |
+
color:#484848;
|
97 |
+
}
|
98 |
+
|
99 |
+
@media only screen and (max-width:680px) {
|
100 |
+
#tab_container ul {
|
101 |
+
float:none;
|
102 |
+
}
|
103 |
+
#tab_container .form-table tr > th {
|
104 |
+
width:100%;
|
105 |
+
}
|
106 |
+
#tab_container span.description{
|
107 |
+
font-size: 14px;
|
108 |
+
}
|
109 |
+
#tab_container .form-table tr > th, #tab_container .form-table tr > td {
|
110 |
+
padding:10px;
|
111 |
+
}
|
112 |
+
}
|
113 |
+
|
114 |
+
#tab_container ul li {
|
115 |
+
margin-bottom:0;
|
116 |
+
}
|
117 |
+
|
118 |
+
#tab_container ul li a {
|
119 |
+
display: block;
|
120 |
+
padding:10px 4px 10px 14px;
|
121 |
+
border-width: 1px 0;
|
122 |
+
border-style: solid;
|
123 |
+
border-top-color:white;
|
124 |
+
border-bottom-color:#e7e7e7;
|
125 |
+
text-decoration: none;
|
126 |
+
color: #0097DF;
|
127 |
+
font-weight: bold;
|
128 |
+
}
|
129 |
+
#tab_container ul li a:hover {
|
130 |
+
background-color: #e5e5e5;
|
131 |
+
color:#777777;
|
132 |
+
}
|
133 |
+
|
134 |
+
|
135 |
+
.wp-staginglogo{
|
136 |
+
display: block;
|
137 |
+
font-size:16px;
|
138 |
+
padding-top:20px;
|
139 |
+
width:220px;
|
140 |
+
float:left;
|
141 |
+
}
|
142 |
+
|
143 |
+
.wpstg-version{
|
144 |
+
display: block;
|
145 |
+
padding-top:29px
|
146 |
+
}
|
147 |
+
|
148 |
+
|
149 |
+
.wpstg_admin .nav-tab {
|
150 |
+
color: #3C3C3C;
|
151 |
+
}
|
152 |
+
|
153 |
+
|
154 |
+
#tab_container table tbody tr:nth-child(1) > th > div {
|
155 |
+
font-size: 20px;
|
156 |
+
}
|
157 |
+
|
158 |
+
.wpstg_hidden{
|
159 |
+
display: none;
|
160 |
+
}
|
161 |
+
|
162 |
+
/* End layout of admin table and rows
|
163 |
+
*/
|
164 |
+
#mashtabcontainer > .mashtabs {
|
165 |
+
background-color: #ffffff;
|
166 |
+
}
|
167 |
+
|
168 |
+
#mashtabcontainer ul .active {
|
169 |
+
background-color: #00adef;
|
170 |
+
color: white;
|
171 |
+
border-bottom-color: #0098D2;
|
172 |
+
}
|
173 |
+
|
174 |
+
#mashtabcontainer ul .active:hover {
|
175 |
+
background-color: #00A4E2;
|
176 |
+
color: white;
|
177 |
+
border-bottom-color: #0098D2;
|
178 |
+
}
|
179 |
+
|
180 |
+
#mashtabcontainer ul li a {
|
181 |
+
padding: 10px 14px 10px 14px;
|
182 |
+
background-color: #f3f3f3
|
183 |
+
|
184 |
+
}
|
185 |
+
|
186 |
+
#mashtabcontainer .mashtab-container {
|
187 |
+
border: 0 solid #ececec;
|
188 |
+
}
|
189 |
+
|
190 |
+
/* Cloning workflow */
|
191 |
+
#wpstg-clonepage-wrapper {
|
192 |
+
margin-bottom: 20px;
|
193 |
+
/*width: 690px; */
|
194 |
+
}
|
195 |
+
|
196 |
+
@media screen and (min-width:1090px){
|
197 |
+
#wpstg-clonepage-wrapper {
|
198 |
+
float: left;
|
199 |
+
margin-bottom: 20px;
|
200 |
+
/*width: 690px;*/
|
201 |
+
}
|
202 |
+
.wpstg-sidebar{
|
203 |
+
display: none;
|
204 |
+
margin-left: 700px;
|
205 |
+
margin-top: 138px;
|
206 |
+
}
|
207 |
+
}
|
208 |
+
|
209 |
+
.wpstg-sidebar{
|
210 |
+
display: none;
|
211 |
+
padding: 10px;
|
212 |
+
border: 1px solid #DFDFDF;
|
213 |
+
max-width: 250px;
|
214 |
+
height: 250px;
|
215 |
+
}
|
216 |
+
|
217 |
+
#wpstg-steps {
|
218 |
+
margin-top:30px;
|
219 |
+
}
|
220 |
+
|
221 |
+
#wpstg-steps li {
|
222 |
+
color: #444;
|
223 |
+
line-height: 20px;
|
224 |
+
padding-right:10px;
|
225 |
+
float:left;
|
226 |
+
}
|
227 |
+
|
228 |
+
|
229 |
+
.wpstg-step-num {
|
230 |
+
border: 1px solid #444;
|
231 |
+
border-radius: 3px;
|
232 |
+
display: inline-block;
|
233 |
+
width: 20px;
|
234 |
+
height: 20px;
|
235 |
+
text-align: center;
|
236 |
+
margin-right: 5px;
|
237 |
+
}
|
238 |
+
|
239 |
+
.wpstg-current-step {
|
240 |
+
font-weight: bold;
|
241 |
+
}
|
242 |
+
|
243 |
+
.wpstg-current-step .wpstg-step-num {
|
244 |
+
background: #444;
|
245 |
+
color: #eee;
|
246 |
+
}
|
247 |
+
|
248 |
+
.wpstg-clone {
|
249 |
+
border: 3px solid #ffffff;
|
250 |
+
margin-bottom: 5px;
|
251 |
+
padding: 5px 10px;
|
252 |
+
width: 300px;
|
253 |
+
position: relative;
|
254 |
+
overflow: hidden;
|
255 |
+
transition: border-color .2s ease-in-out;
|
256 |
+
background-color: #DDDDDD;
|
257 |
+
}
|
258 |
+
|
259 |
+
.wpstg-clone.active {
|
260 |
+
border-color: #1d94cf;;
|
261 |
+
}
|
262 |
+
|
263 |
+
.wpstg-clone-title {
|
264 |
+
display: inline-block;
|
265 |
+
font-size: 15px;
|
266 |
+
max-width: 130px;
|
267 |
+
text-decoration: none;
|
268 |
+
font-weight: bold;
|
269 |
+
color:#0285AE;
|
270 |
+
}
|
271 |
+
|
272 |
+
.wpstg-clone-action {
|
273 |
+
background: #ffffff;
|
274 |
+
border-left: 1px solid #ccc;
|
275 |
+
color: #bbb;
|
276 |
+
padding: 0 5px;
|
277 |
+
float: right;
|
278 |
+
text-decoration: none;
|
279 |
+
position: relative;
|
280 |
+
transition: color .2s ease-in-out;
|
281 |
+
}
|
282 |
+
|
283 |
+
.wpstg-remove-clone:hover {
|
284 |
+
color: #ef6d6d;
|
285 |
+
}
|
286 |
+
|
287 |
+
.wpstg-clone-action:last-child {
|
288 |
+
border: none;
|
289 |
+
}
|
290 |
+
|
291 |
+
.wpstg-clone:hover .wpstg-clone-action {
|
292 |
+
display: inline-block;
|
293 |
+
}
|
294 |
+
|
295 |
+
#wpstg-show-error-details:focus,
|
296 |
+
#wpstg-workflow .wpstg-clone-action {
|
297 |
+
outline: none;
|
298 |
+
box-shadow: none;
|
299 |
+
}
|
300 |
+
|
301 |
+
.wpstg-link-btn {
|
302 |
+
background: #45a1c9;
|
303 |
+
color: #fff;
|
304 |
+
display: inline-block;
|
305 |
+
padding: 5px 10px;
|
306 |
+
text-decoration: none;
|
307 |
+
vertical-align: baseline;
|
308 |
+
transition: all .2s ease-in-out;
|
309 |
+
}
|
310 |
+
|
311 |
+
.wpstg-link-btn:hover,
|
312 |
+
.wpstg-link-btn:focus {
|
313 |
+
color: #fff;
|
314 |
+
outline: none;
|
315 |
+
box-shadow: none;
|
316 |
+
}
|
317 |
+
|
318 |
+
#wpstg-workflow .wpstg-link-btn:active {
|
319 |
+
vertical-align: baseline;
|
320 |
+
}
|
321 |
+
|
322 |
+
.wpstg-link-btn[disabled] {
|
323 |
+
background: #777 !important;
|
324 |
+
pointer-events: none;
|
325 |
+
}
|
326 |
+
|
327 |
+
#wpstg-cancel-cloning {
|
328 |
+
background: #ff3428;
|
329 |
+
border-color: #e72f24;
|
330 |
+
margin-top: 5px;
|
331 |
+
}
|
332 |
+
|
333 |
+
#wpstg-cancel-cloning.success {
|
334 |
+
background: #64dd58;
|
335 |
+
border-color: #54bd4a;
|
336 |
+
}
|
337 |
+
|
338 |
+
#wpstg-error-wrapper,
|
339 |
+
#wpstg-error-details {
|
340 |
+
display: none;
|
341 |
+
margin-top: 10px;
|
342 |
+
font-size: 13px;
|
343 |
+
}
|
344 |
+
|
345 |
+
#wpstg-show-error-details {
|
346 |
+
display: inline-block;
|
347 |
+
margin-left: 5px;
|
348 |
+
color: #555;
|
349 |
+
text-decoration: none;
|
350 |
+
transition: color .2s ease-in-out;
|
351 |
+
}
|
352 |
+
|
353 |
+
#wpstg-show-error-details:hover {
|
354 |
+
color: #1d94cf;
|
355 |
+
}
|
356 |
+
|
357 |
+
#wpstg-error-details {
|
358 |
+
border-left: 5px solid #ef6d6d;
|
359 |
+
padding: 10px;
|
360 |
+
width: 500px;
|
361 |
+
}
|
362 |
+
|
363 |
+
#wpstg-home-link,
|
364 |
+
#wpstg-try-again {
|
365 |
+
display: none;
|
366 |
+
}
|
367 |
+
|
368 |
+
|
369 |
+
#wpstg-loader {
|
370 |
+
content: url('../img/loading.gif');
|
371 |
+
margin-top:-5px;
|
372 |
+
}
|
373 |
+
|
374 |
+
#wpstg-loader.wpstg-finished {
|
375 |
+
content:"Finished";
|
376 |
+
background-color:#00c89a;
|
377 |
+
color:white;
|
378 |
+
padding:2px;
|
379 |
+
margin-top:6px;
|
380 |
+
}
|
381 |
+
|
382 |
+
#wpstg-workflow {
|
383 |
+
position: relative;
|
384 |
+
clear:both;
|
385 |
+
padding-top:20px;
|
386 |
+
margin-right:20px;
|
387 |
+
float:left;
|
388 |
+
min-width: 500px;
|
389 |
+
border-right: 1px solid #DFDFDF;
|
390 |
+
min-height: 380px;
|
391 |
+
padding-right: 20px;
|
392 |
+
}
|
393 |
+
|
394 |
+
#wpstg-sidebar {
|
395 |
+
float: left;
|
396 |
+
max-width: 400px;
|
397 |
+
display: block;
|
398 |
+
}
|
399 |
+
|
400 |
+
@media screen and (max-width:1150px){
|
401 |
+
#wpstg-sidebar img{
|
402 |
+
margin-top: 30px;
|
403 |
+
}
|
404 |
+
}
|
405 |
+
|
406 |
+
#wpstg-workflow.loading::after,
|
407 |
+
#wpstg-removing-clone.loading::after {
|
408 |
+
background: rgba(255, 255, 255, .7);
|
409 |
+
content: 'Loading... may take a while for huge websites';
|
410 |
+
display: block;
|
411 |
+
width: 100%;
|
412 |
+
height: 100%;
|
413 |
+
font-size: 20px;
|
414 |
+
padding-top: 100px;
|
415 |
+
text-align: center;
|
416 |
+
position: absolute;
|
417 |
+
top: 0;
|
418 |
+
left: 0;
|
419 |
+
z-index: 99;
|
420 |
+
}
|
421 |
+
|
422 |
+
#wpstg-removing-clone.loading::after {
|
423 |
+
content: 'REMOVING' !important;
|
424 |
+
}
|
425 |
+
|
426 |
+
#wpstg-existing-clones,
|
427 |
+
#wpstg-removing-clone {
|
428 |
+
position: relative;
|
429 |
+
}
|
430 |
+
|
431 |
+
.wpstg-progress-bar {
|
432 |
+
max-width: 900px;
|
433 |
+
height: 27px;
|
434 |
+
padding: 0;
|
435 |
+
background-color: #d6d8d7;
|
436 |
+
}
|
437 |
+
|
438 |
+
.wpstg-progress {
|
439 |
+
background: #1d94cf;
|
440 |
+
width: 0;
|
441 |
+
height: 100%;
|
442 |
+
transition: width 1s;
|
443 |
+
color:white;
|
444 |
+
line-height:25px;
|
445 |
+
text-align:center;
|
446 |
+
}
|
447 |
+
|
448 |
+
#wpstg-new-clone-id.wpstg-error-input,
|
449 |
+
#wpstg-clone-path.wpstg-error-input {
|
450 |
+
border: 1px solid #ff4235;
|
451 |
+
box-shadow: 0 0 2px rgba(255, 66, 53, .8);
|
452 |
+
}
|
453 |
+
|
454 |
+
#wpstg-clone-path {
|
455 |
+
margin-left: 10px;
|
456 |
+
width: 350px;
|
457 |
+
}
|
458 |
+
|
459 |
+
.wpstg-error-msg {
|
460 |
+
color: #ff4235;
|
461 |
+
}
|
462 |
+
|
463 |
+
#wpstg-clone-id-error {
|
464 |
+
display: block;
|
465 |
+
text-align: right;
|
466 |
+
margin-right: 90px;
|
467 |
+
}
|
468 |
+
|
469 |
+
#wpstg-start-cloning + .wpstg-error-msg {
|
470 |
+
display: block;
|
471 |
+
margin-top: 5px;
|
472 |
+
}
|
473 |
+
|
474 |
+
.wpstg-size-info {
|
475 |
+
color: #999;
|
476 |
+
font-weight: normal;
|
477 |
+
position: relative;
|
478 |
+
left: 2px;
|
479 |
+
}
|
480 |
+
|
481 |
+
.wpstg-db-table .wpstg-size-info {
|
482 |
+
top: 2px;
|
483 |
+
}
|
484 |
+
|
485 |
+
#wpstg-workflow #wpstg-start-cloning {
|
486 |
+
display: inline-block;
|
487 |
+
margin-left: 5px;
|
488 |
+
font-size: 14px;
|
489 |
+
vertical-align: baseline;
|
490 |
+
}
|
491 |
+
|
492 |
+
/* Tabs */
|
493 |
+
.wpstg-tabs-wrapper {
|
494 |
+
max-width: 640px;
|
495 |
+
margin: 10px 0;
|
496 |
+
}
|
497 |
+
|
498 |
+
#wpstg-path-wrapper {
|
499 |
+
border-bottom: 2px dashed #ccc;
|
500 |
+
padding-bottom: 10px;
|
501 |
+
margin-bottom: 10px;
|
502 |
+
}
|
503 |
+
|
504 |
+
.wpstg-tabs-wrapper {
|
505 |
+
border: 1px solid #ddd;
|
506 |
+
border-right: none;
|
507 |
+
border-left: none;
|
508 |
+
}
|
509 |
+
|
510 |
+
.wpstg-tab-section {
|
511 |
+
border: 1px solid #ddd;
|
512 |
+
border-right: none;
|
513 |
+
border-left: none;
|
514 |
+
display: none;
|
515 |
+
padding: 20px;
|
516 |
+
}
|
517 |
+
|
518 |
+
.wpstg-tab-section::after {
|
519 |
+
display: block;
|
520 |
+
content: '';
|
521 |
+
clear: both;
|
522 |
+
}
|
523 |
+
|
524 |
+
.wpstg-tab-header {
|
525 |
+
border: 1px solid #ddd;
|
526 |
+
border-right: none;
|
527 |
+
border-left: none;
|
528 |
+
color: #444;
|
529 |
+
font-size: 16px;
|
530 |
+
font-weight: bolder;
|
531 |
+
display: block;
|
532 |
+
padding: 10px;;
|
533 |
+
text-decoration: none;
|
534 |
+
}
|
535 |
+
|
536 |
+
.wpstg-tab-triangle {
|
537 |
+
font-family: arial;
|
538 |
+
display: inline-block;
|
539 |
+
margin-right: 10px;
|
540 |
+
}
|
541 |
+
|
542 |
+
.wpstg-tab-header:focus {
|
543 |
+
color: #444;
|
544 |
+
outline: none;
|
545 |
+
box-shadow: none;
|
546 |
+
}
|
547 |
+
|
548 |
+
#wpstg-large-files {
|
549 |
+
display:none;
|
550 |
+
border: 1px dashed #ccc;
|
551 |
+
/*float: right;*/
|
552 |
+
padding: 10px 10px 10px;
|
553 |
+
margin-top:20px;
|
554 |
+
position: relative;
|
555 |
+
font-size:12px;
|
556 |
+
}
|
557 |
+
|
558 |
+
#wpstg-large-files h3 {
|
559 |
+
background: #fff;
|
560 |
+
margin: 0;
|
561 |
+
padding: 0 5px;
|
562 |
+
position: absolute;
|
563 |
+
top: -10px;
|
564 |
+
left: 5px;
|
565 |
+
}
|
566 |
+
|
567 |
+
/* tmp */
|
568 |
+
.wpstg-subdir {
|
569 |
+
display: none;
|
570 |
+
margin-left: 20px;
|
571 |
+
}
|
572 |
+
|
573 |
+
.wpstg-dir a.disabled {
|
574 |
+
color: #888;
|
575 |
+
cursor: default;
|
576 |
+
text-decoration: none;
|
577 |
+
}
|
578 |
+
|
579 |
+
.wpstg-check-subdirs {
|
580 |
+
display: inline-block;
|
581 |
+
margin-left: 10px;
|
582 |
+
}
|
583 |
+
|
584 |
+
.wpstg-notice-alert{
|
585 |
+
display:block;
|
586 |
+
background-color:#FFD0D0;
|
587 |
+
padding:20px;
|
588 |
+
border: 1px solid #fff;
|
589 |
+
max-width: 600px;
|
590 |
+
}
|
591 |
+
|
592 |
+
.wpstg-header{
|
593 |
+
font-weight: 400;
|
594 |
+
line-height: 1.6em;
|
595 |
+
font-size: 19px;
|
596 |
+
border-bottom: 1px solid #DFDFDF;
|
597 |
+
clear:both;
|
598 |
+
}
|
599 |
+
|
600 |
+
|
601 |
+
#wpstg-clone-label{
|
602 |
+
font-size: 14px;
|
603 |
+
font-weight: bold;
|
604 |
+
}
|
605 |
+
|
606 |
+
#wpstg-log-details{
|
607 |
+
height: 300px;
|
608 |
+
max-width: 700px;
|
609 |
+
overflow: scroll;
|
610 |
+
/*max-width: 650px;*/
|
611 |
+
font-family: monospace;
|
612 |
+
font-size: 12px;
|
613 |
+
line-height: 15px;
|
614 |
+
border: 1px solid #FFF;
|
615 |
+
background-color: black;
|
616 |
+
color: #c0c0c0;
|
617 |
+
padding:3px;
|
618 |
+
white-space: nowrap;
|
619 |
+
margin-top: 15px;
|
620 |
+
}
|
621 |
+
|
622 |
+
#wpstg-finished-result {
|
623 |
+
display:none;
|
624 |
+
}
|
625 |
+
|
626 |
+
#wpstg-remove-cloning {
|
627 |
+
background: #ff3428;
|
628 |
+
border-color: #e72f24;
|
629 |
+
margin-top: 5px;
|
630 |
+
}
|
631 |
+
|
632 |
+
#wpstg-success-notice{
|
633 |
+
padding: 10px;
|
634 |
+
background-color: white;
|
635 |
+
max-width: 900px;
|
636 |
+
border: 1px solid #ccc;
|
637 |
+
margin-top: 20px;
|
638 |
+
}
|
639 |
+
|
640 |
+
.wpstg_beta_notice {
|
641 |
+
margin-bottom:20px;
|
642 |
+
}
|
643 |
+
|
644 |
+
.wpstg-sysinfo {
|
645 |
+
width:700px;
|
646 |
+
height: 500px;
|
647 |
+
}
|
648 |
+
|
649 |
+
.form-table .col-title label {
|
650 |
+
font-weight: 600;
|
651 |
+
}
|
652 |
+
|
653 |
+
.form-table td:first-child {
|
654 |
+
width:30%;
|
655 |
+
}
|
656 |
+
|
657 |
+
|
658 |
+
.wpstg-share-button-container{
|
659 |
+
margin: 5px 0;
|
660 |
+
}
|
661 |
+
|
662 |
+
.wpstg-share-button-container p{
|
663 |
+
margin:0px 0 10px 0;
|
664 |
+
}
|
665 |
+
|
666 |
+
.wpstg-share-button {
|
667 |
+
display: inline-block;
|
668 |
+
}
|
669 |
+
|
670 |
+
.wpstg-share-button a{
|
671 |
+
text-decoration:none;
|
672 |
+
}
|
673 |
+
|
674 |
+
.wpstg-share-button .wpstg-share {
|
675 |
+
font-family:sans-serif;
|
676 |
+
font-weight:bold;
|
677 |
+
text-decoration:none;
|
678 |
+
text-align:center;
|
679 |
+
}
|
680 |
+
|
681 |
+
|
682 |
+
.wpstg-share-button .wpstg-share {
|
683 |
+
-webkit-border-radius:2px;
|
684 |
+
-moz-border-radius:2px;
|
685 |
+
border-radius:2px;
|
686 |
+
color:#FFF;
|
687 |
+
display:inline;
|
688 |
+
font-size:16px;
|
689 |
+
width:40px;
|
690 |
+
padding:4px 8px;
|
691 |
+
}
|
692 |
+
|
693 |
+
.wpstg-share-button-twitter .wpstg-share {
|
694 |
+
background-color:#00ABF0;
|
695 |
+
}
|
696 |
+
|
697 |
+
.wpstg-share-button-facebook .wpstg-share {
|
698 |
+
background-color:#3b5998;
|
699 |
+
}
|
700 |
+
|
701 |
+
.wpstg-share-button-googleplus .wpstg-share {
|
702 |
+
background-color:#F53424;
|
703 |
+
}
|
704 |
+
|
705 |
+
.wpstg-share-button-twitter .share:active,.wpstg-share-button-facebook .share:active,.wpstg-share-button-googleplus .share:active {
|
706 |
+
background-color:#353535;
|
707 |
+
}
|
708 |
+
|
709 |
+
#wpstg-check-space {
|
710 |
+
margin-left:8px;
|
711 |
+
}
|
712 |
+
|
713 |
+
/* welcome screen */
|
714 |
+
.wpstg-button.green {
|
715 |
+
display: inline-block;
|
716 |
+
background-color: #83c11f;
|
717 |
+
padding: 10px;
|
718 |
+
min-width: 170px;
|
719 |
+
color: white;
|
720 |
+
font-size: 16px;
|
721 |
+
text-decoration: none;
|
722 |
+
text-align: center;
|
723 |
+
margin-top: 20px;
|
724 |
+
}
|
725 |
+
#wpstg-welcome li {
|
726 |
+
font-size: 18px;
|
727 |
+
line-height: 29px;
|
728 |
+
position: relative;
|
729 |
+
padding-left: 23px;
|
730 |
+
list-style: none!important;
|
731 |
+
}
|
732 |
+
#wpstg-welcome {
|
733 |
+
margin-top:20px;
|
734 |
+
margin-right: 20px;
|
735 |
+
background-color: white;
|
736 |
+
}
|
737 |
+
.wpstg-heading-pro {
|
738 |
+
color: #0080ff;
|
739 |
+
font-weight: bold;
|
740 |
+
}
|
741 |
+
.wpstg-h2 {
|
742 |
+
margin-top: 0px;
|
743 |
+
margin-bottom: 1.2rem;
|
744 |
+
font-size: 30px;
|
745 |
+
line-height: 2.5rem;
|
746 |
+
}
|
747 |
+
#wpstg-welcome li:before {
|
748 |
+
width: 1em;
|
749 |
+
height: 100%;
|
750 |
+
background: url(data:image/svg+xml;charset=utf8,%3Csvg%20width%3D%221792%22%20height%3D%221792%22%20viewBox%3D%220%200%201792%201792%22%20xmlns%3D%22http%3A%2F%2Fwww%2Ew3%2Eorg%2F2000%2Fsvg%22%3E%3Cpath%20fill%3D%22%2377B227%22%20d%3D%22M1671%20566q0%2040%2D28%2068l%2D724%20724%2D136%20136q%2D28%2028%2D68%2028t%2D68%2D28l%2D136%2D136%2D362%2D362q%2D28%2D28%2D28%2D68t28%2D68l136%2D136q28%2D28%2068%2D28t68%2028l294%20295%20656%2D657q28%2D28%2068%2D28t68%2028l136%20136q28%2028%2028%2068z%22%2F%3E%3C%2Fsvg%3E) left .4em no-repeat;
|
751 |
+
background-size: contain;
|
752 |
+
content: "";
|
753 |
+
position: absolute;
|
754 |
+
top: 0;
|
755 |
+
left: 0;
|
756 |
+
color: #77b227;
|
757 |
+
}
|
758 |
+
.wpstg-h1 {
|
759 |
+
font-size: 2.75em;
|
760 |
+
margin-bottom: 1.35rem;
|
761 |
+
font-size: 2.5em;
|
762 |
+
line-height: 3.68rem;
|
763 |
+
letter-spacing: normal;
|
764 |
+
}
|
765 |
+
#wpstg-welcome h2 {
|
766 |
+
margin: 0 0 15px;
|
767 |
+
}
|
768 |
+
#wpstg-welcome .wpstg-footer {
|
769 |
+
clear: both;
|
770 |
+
margin-top: 20px;
|
771 |
+
font-style: italic;
|
772 |
+
}
|
773 |
+
|
774 |
+
.wpstg-staging-info {
|
775 |
+
clear:both;
|
776 |
+
float: right;
|
777 |
+
color:grey;
|
778 |
+
font-size: 12px;
|
779 |
+
}
|
780 |
+
|
781 |
+
.wpstg-bold{
|
782 |
+
font-weight: 600;
|
783 |
}
|
apps/Backend/public/js/wpstg-admin.js
CHANGED
@@ -1,1086 +1,1252 @@
|
|
1 |
-
"use strict";
|
2 |
-
|
3 |
-
var WPStaging = (function ($)
|
4 |
-
{
|
5 |
-
var that = {
|
6 |
-
isCancelled: false,
|
7 |
-
isFinished: false,
|
8 |
-
getLogs: false
|
9 |
-
},
|
10 |
-
cache = {elements: []},
|
11 |
-
timeout, ajaxSpinner;
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
*
|
16 |
-
* @
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
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 |
-
cache.get("#wpstg-
|
49 |
-
cache.get("#wpstg-
|
50 |
-
cache.get("#wpstg-
|
51 |
-
cache.get("#wpstg-error-
|
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 |
-
cache.get(".wpstg-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
cache.get(".wpstg-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
e.preventDefault();
|
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 |
-
|
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 |
-
|
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 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
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 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
-
|
909 |
-
|
910 |
-
|
911 |
-
|
912 |
-
|
913 |
-
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
|
943 |
-
|
944 |
-
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
}
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
-
|
982 |
-
|
983 |
-
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
|
990 |
-
|
991 |
-
|
992 |
-
|
993 |
-
|
994 |
-
|
995 |
-
|
996 |
-
|
997 |
-
|
998 |
-
|
999 |
-
|
1000 |
-
|
1001 |
-
|
1002 |
-
|
1003 |
-
|
1004 |
-
|
1005 |
-
|
1006 |
-
|
1007 |
-
|
1008 |
-
|
1009 |
-
|
1010 |
-
|
1011 |
-
|
1012 |
-
|
1013 |
-
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
-
)
|
1023 |
-
|
1024 |
-
|
1025 |
-
|
1026 |
-
|
1027 |
-
|
1028 |
-
|
1029 |
-
|
1030 |
-
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
|
1042 |
-
|
1043 |
-
|
1044 |
-
|
1045 |
-
|
1046 |
-
|
1047 |
-
|
1048 |
-
|
1049 |
-
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
1053 |
-
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
-
|
1058 |
-
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
-
//
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
|
1071 |
-
|
1072 |
-
|
1073 |
-
|
1074 |
-
|
1075 |
-
|
1076 |
-
|
1077 |
-
|
1078 |
-
|
1079 |
-
|
1080 |
-
|
1081 |
-
|
1082 |
-
}
|
1083 |
-
|
1084 |
-
|
1085 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1086 |
});
|
1 |
+
"use strict";
|
2 |
+
|
3 |
+
var WPStaging = (function ($)
|
4 |
+
{
|
5 |
+
var that = {
|
6 |
+
isCancelled: false,
|
7 |
+
isFinished: false,
|
8 |
+
getLogs: false
|
9 |
+
},
|
10 |
+
cache = {elements: []},
|
11 |
+
timeout, ajaxSpinner;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Get / Set Cache for Selector
|
15 |
+
* @param {String} selector
|
16 |
+
* @returns {*}
|
17 |
+
*/
|
18 |
+
cache.get = function (selector)
|
19 |
+
{
|
20 |
+
// It is already cached!
|
21 |
+
if ($.inArray(selector, cache.elements) !== -1)
|
22 |
+
{
|
23 |
+
return cache.elements[selector];
|
24 |
+
}
|
25 |
+
|
26 |
+
// Create cache and return
|
27 |
+
cache.elements[selector] = jQuery(selector);
|
28 |
+
|
29 |
+
return cache.elements[selector];
|
30 |
+
};
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Refreshes given cache
|
34 |
+
* @param {String} selector
|
35 |
+
*/
|
36 |
+
cache.refresh = function (selector)
|
37 |
+
{
|
38 |
+
selector.elements[selector] = jQuery(selector);
|
39 |
+
};
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Show and Log Error Message
|
43 |
+
* @param {String} message
|
44 |
+
*/
|
45 |
+
var showError = function (message)
|
46 |
+
{
|
47 |
+
cache.get("#wpstg-try-again").css("display", "inline-block");
|
48 |
+
cache.get("#wpstg-cancel-cloning").text("Reset");
|
49 |
+
cache.get("#wpstg-cloning-result").text("Fail");
|
50 |
+
cache.get("#wpstg-error-wrapper").show();
|
51 |
+
cache.get("#wpstg-error-details")
|
52 |
+
.show()
|
53 |
+
.html(message);
|
54 |
+
cache.get("#wpstg-removing-clone").removeClass("loading");
|
55 |
+
cache.get("#wpstg-loader").hide();
|
56 |
+
};
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Common Elements
|
60 |
+
*/
|
61 |
+
var elements = function ()
|
62 |
+
{
|
63 |
+
var $workFlow = cache.get("#wpstg-workflow"),
|
64 |
+
isAllChecked = true,
|
65 |
+
urlSpinner = ajaxurl.replace("/admin-ajax.php", '') + "/images/spinner",
|
66 |
+
timer;
|
67 |
+
|
68 |
+
if (2 < window.devicePixelRatio)
|
69 |
+
{
|
70 |
+
urlSpinner += "-2x";
|
71 |
+
}
|
72 |
+
|
73 |
+
urlSpinner += ".gif";
|
74 |
+
|
75 |
+
ajaxSpinner = "<img src=''" + urlSpinner + "' alt='' class='ajax-spinner general-spinner' />";
|
76 |
+
|
77 |
+
$workFlow
|
78 |
+
// Check / Un-check Database Tables
|
79 |
+
.on("click", ".wpstg-button-unselect", function (e) {
|
80 |
+
e.preventDefault();
|
81 |
+
|
82 |
+
if (false === isAllChecked)
|
83 |
+
{
|
84 |
+
cache.get(".wpstg-db-table-checkboxes").prop("checked", true);
|
85 |
+
cache.get(".wpstg-button-unselect").text("Un-check All");
|
86 |
+
isAllChecked = true;
|
87 |
+
}
|
88 |
+
else
|
89 |
+
{
|
90 |
+
cache.get(".wpstg-db-table-checkboxes").prop("checked", false);
|
91 |
+
cache.get(".wpstg-button-unselect").text("Check All");
|
92 |
+
isAllChecked = false;
|
93 |
+
}
|
94 |
+
})
|
95 |
+
.on("click", ".wpstg-button-select", function (e) {
|
96 |
+
console.log('test1');
|
97 |
+
|
98 |
+
e.preventDefault();
|
99 |
+
|
100 |
+
$(".wpstg-db-table input").each(function () {
|
101 |
+
if ($(this).attr('name').match("^" + wpstg.tblprefix)) {
|
102 |
+
$(this).prop("checked", true);
|
103 |
+
} else {
|
104 |
+
$(this).prop("checked", false);
|
105 |
+
|
106 |
+
}
|
107 |
+
});
|
108 |
+
})
|
109 |
+
// Expand Directories
|
110 |
+
.on("click", ".wpstg-expand-dirs", function (e) {
|
111 |
+
e.preventDefault();
|
112 |
+
|
113 |
+
var $this = $(this);
|
114 |
+
|
115 |
+
if (!$this.hasClass("disabled"))
|
116 |
+
{
|
117 |
+
$this.siblings(".wpstg-subdir").slideToggle();
|
118 |
+
}
|
119 |
+
})
|
120 |
+
// When a Directory is Selected
|
121 |
+
.on("change", ".wpstg-check-dir", function () {
|
122 |
+
var $directory = $(this).parent(".wpstg-dir");
|
123 |
+
|
124 |
+
if (this.checked)
|
125 |
+
{
|
126 |
+
$directory.parents(".wpstg-dir").children(".wpstg-check-dir").prop("checked", true);
|
127 |
+
$directory.find(".wpstg-expand-dirs").removeClass("disabled");
|
128 |
+
$directory.find(".wpstg-subdir .wpstg-check-dir").prop("checked", true);
|
129 |
+
}
|
130 |
+
else
|
131 |
+
{
|
132 |
+
$directory.find(".wpstg-dir .wpstg-check-dir").prop("checked", false);
|
133 |
+
$directory.find(".wpstg-expand-dirs, .wpstg-check-subdirs").addClass("disabled");
|
134 |
+
$directory.find(".wpstg-check-subdirs").data("action", "check").text("check");
|
135 |
+
$directory.children(".wpstg-subdir").slideUp();
|
136 |
+
}
|
137 |
+
})
|
138 |
+
// Check the max length of the clone name and if the clone name already exists
|
139 |
+
.on("keyup", "#wpstg-new-clone-id", function () {
|
140 |
+
|
141 |
+
// This request was already sent, clear it up!
|
142 |
+
if ("number" === typeof (timer))
|
143 |
+
{
|
144 |
+
clearInterval(timer);
|
145 |
+
}
|
146 |
+
|
147 |
+
var cloneID = this.value;
|
148 |
+
|
149 |
+
timer = setTimeout(
|
150 |
+
function () {
|
151 |
+
ajax(
|
152 |
+
{
|
153 |
+
action: "wpstg_check_clone",
|
154 |
+
cloneID: cloneID
|
155 |
+
},
|
156 |
+
function (response)
|
157 |
+
{
|
158 |
+
if (response.status === "success")
|
159 |
+
{
|
160 |
+
cache.get("#wpstg-new-clone-id").removeClass("wpstg-error-input");
|
161 |
+
cache.get("#wpstg-start-cloning").removeAttr("disabled");
|
162 |
+
cache.get("#wpstg-clone-id-error").text('').hide();
|
163 |
+
}
|
164 |
+
else
|
165 |
+
{
|
166 |
+
cache.get("#wpstg-new-clone-id").addClass("wpstg-error-input");
|
167 |
+
cache.get("#wpstg-start-cloning").prop("disabled", true);
|
168 |
+
cache.get("#wpstg-clone-id-error").text(response.message).show();
|
169 |
+
}
|
170 |
+
}
|
171 |
+
);
|
172 |
+
},
|
173 |
+
500
|
174 |
+
);
|
175 |
+
})
|
176 |
+
// Restart cloning process
|
177 |
+
.on("click", "#wpstg-start-cloning", function () {
|
178 |
+
that.isCancelled = false;
|
179 |
+
that.getLogs = false;
|
180 |
+
})
|
181 |
+
// Display logs
|
182 |
+
// .on("click", "#wpstg-show-log-button", function (e) {
|
183 |
+
// e.preventDefault();
|
184 |
+
// var $logDetails = cache.get("#wpstg-log-details");
|
185 |
+
//
|
186 |
+
// $logDetails.toggle();
|
187 |
+
//
|
188 |
+
// logscroll();
|
189 |
+
//
|
190 |
+
// that.getLogs = (false === that.getLogs);
|
191 |
+
// });
|
192 |
+
|
193 |
+
cloneActions();
|
194 |
+
};
|
195 |
+
|
196 |
+
|
197 |
+
/**
|
198 |
+
* Clone actions
|
199 |
+
*/
|
200 |
+
var cloneActions = function ()
|
201 |
+
{
|
202 |
+
var $workFlow = cache.get("#wpstg-workflow");
|
203 |
+
|
204 |
+
$workFlow
|
205 |
+
// Cancel cloning
|
206 |
+
.on("click", "#wpstg-cancel-cloning", function () {
|
207 |
+
if (!confirm("Are you sure you want to cancel cloning process?"))
|
208 |
+
{
|
209 |
+
return false;
|
210 |
+
}
|
211 |
+
|
212 |
+
var $this = $(this);
|
213 |
+
|
214 |
+
$("#wpstg-try-again, #wpstg-home-link").hide();
|
215 |
+
$this.prop("disabled", true);
|
216 |
+
|
217 |
+
that.isCancelled = true;
|
218 |
+
|
219 |
+
$("#wpstg-cloning-result").text("Please wait...this can take up a while.");
|
220 |
+
$("#wpstg-loader, #wpstg-show-log-button").hide();
|
221 |
+
|
222 |
+
$this.parent().append(ajaxSpinner);
|
223 |
+
|
224 |
+
cancelCloning();
|
225 |
+
})
|
226 |
+
// Cancel update cloning
|
227 |
+
.on("click", "#wpstg-cancel-cloning-update", function () {
|
228 |
+
if (!confirm("Are you sure you want to cancel clone updating process?"))
|
229 |
+
{
|
230 |
+
return false;
|
231 |
+
}
|
232 |
+
|
233 |
+
var $this = $(this);
|
234 |
+
|
235 |
+
$("#wpstg-try-again, #wpstg-home-link").hide();
|
236 |
+
$this.prop("disabled", true);
|
237 |
+
|
238 |
+
that.isCancelled = true;
|
239 |
+
|
240 |
+
$("#wpstg-cloning-result").text("Please wait...this can take up a while.");
|
241 |
+
$("#wpstg-loader, #wpstg-show-log-button").hide();
|
242 |
+
|
243 |
+
$this.parent().append(ajaxSpinner);
|
244 |
+
|
245 |
+
cancelCloningUpdate();
|
246 |
+
})
|
247 |
+
// Delete clone - confirmation
|
248 |
+
.on("click", ".wpstg-remove-clone[data-clone]", function (e) {
|
249 |
+
e.preventDefault();
|
250 |
+
|
251 |
+
var $existingClones = cache.get("#wpstg-existing-clones");
|
252 |
+
|
253 |
+
$workFlow.removeClass('active');
|
254 |
+
|
255 |
+
cache.get("#wpstg-loader").show();
|
256 |
+
|
257 |
+
ajax(
|
258 |
+
{
|
259 |
+
action: "wpstg_confirm_delete_clone",
|
260 |
+
nonce: wpstg.nonce,
|
261 |
+
clone: $(this).data("clone")
|
262 |
+
},
|
263 |
+
function (response)
|
264 |
+
{
|
265 |
+
cache.get("#wpstg-removing-clone").html(response);
|
266 |
+
|
267 |
+
$existingClones.children("img").remove();
|
268 |
+
|
269 |
+
cache.get("#wpstg-loader").hide();
|
270 |
+
},
|
271 |
+
"HTML"
|
272 |
+
);
|
273 |
+
})
|
274 |
+
// Delete clone - confirmed
|
275 |
+
.on("click", "#wpstg-remove-clone", function (e) {
|
276 |
+
e.preventDefault();
|
277 |
+
|
278 |
+
cache.get("#wpstg-removing-clone").addClass("loading");
|
279 |
+
|
280 |
+
cache.get("#wpstg-loader").show();
|
281 |
+
|
282 |
+
deleteClone($(this).data("clone"));
|
283 |
+
})
|
284 |
+
// Cancel deleting clone
|
285 |
+
.on("click", "#wpstg-cancel-removing", function (e) {
|
286 |
+
e.preventDefault();
|
287 |
+
$(".wpstg-clone").removeClass("active");
|
288 |
+
cache.get("#wpstg-removing-clone").html('');
|
289 |
+
})
|
290 |
+
// Update
|
291 |
+
.on("click", ".wpstg-execute-clone", function (e) {
|
292 |
+
e.preventDefault();
|
293 |
+
|
294 |
+
if (!confirm("Are you sure you want to update the staging site? All your staging site modifications will be overwritten with the data from the live site. So make sure that your live site is up to date."))
|
295 |
+
{
|
296 |
+
return false;
|
297 |
+
}
|
298 |
+
|
299 |
+
var clone = $(this).data("clone");
|
300 |
+
|
301 |
+
$workFlow.addClass("loading");
|
302 |
+
|
303 |
+
ajax(
|
304 |
+
{
|
305 |
+
action: "wpstg_scanning",
|
306 |
+
clone: clone,
|
307 |
+
nonce: wpstg.nonce
|
308 |
+
},
|
309 |
+
function (response)
|
310 |
+
{
|
311 |
+
if (response.length < 1)
|
312 |
+
{
|
313 |
+
showError("Something went wrong, please try again");
|
314 |
+
}
|
315 |
+
|
316 |
+
$workFlow.removeClass("loading").html(response);
|
317 |
+
|
318 |
+
cache.get(".wpstg-current-step")
|
319 |
+
.removeClass("wpstg-current-step")
|
320 |
+
.next("li")
|
321 |
+
.addClass("wpstg-current-step");
|
322 |
+
},
|
323 |
+
"HTML"
|
324 |
+
);
|
325 |
+
});
|
326 |
+
};
|
327 |
+
|
328 |
+
|
329 |
+
/**
|
330 |
+
* Ajax Requests
|
331 |
+
* @param {Object} data
|
332 |
+
* @param {Function} callback
|
333 |
+
* @param {String} dataType
|
334 |
+
* @param {Boolean} showErrors
|
335 |
+
*/
|
336 |
+
var ajax = function (data, callback, dataType, showErrors)
|
337 |
+
{
|
338 |
+
if ("undefined" === typeof (dataType))
|
339 |
+
{
|
340 |
+
dataType = "json";
|
341 |
+
}
|
342 |
+
|
343 |
+
if (false !== showErrors)
|
344 |
+
{
|
345 |
+
showErrors = true;
|
346 |
+
}
|
347 |
+
|
348 |
+
$.ajax({
|
349 |
+
url: ajaxurl,
|
350 |
+
type: "POST",
|
351 |
+
dataType: dataType,
|
352 |
+
cache: false,
|
353 |
+
data: data,
|
354 |
+
error: function (xhr, textStatus, errorThrown) {
|
355 |
+
console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);
|
356 |
+
console.log(textStatus);
|
357 |
+
|
358 |
+
if (false === showErrors)
|
359 |
+
{
|
360 |
+
return false;
|
361 |
+
}
|
362 |
+
|
363 |
+
showError(
|
364 |
+
"Fatal Unknown Error. Go to WP Staging > Settings and lower 'File Copy Limit'" +
|
365 |
+
"Than try again. If this does not help, " +
|
366 |
+
"<a href='https://wpquads.com/support/' target='_blank'>open a support ticket</a> "
|
367 |
+
);
|
368 |
+
},
|
369 |
+
success: function (data) {
|
370 |
+
if ("function" === typeof (callback))
|
371 |
+
{
|
372 |
+
callback(data);
|
373 |
+
}
|
374 |
+
},
|
375 |
+
statusCode: {
|
376 |
+
404: function () {
|
377 |
+
showError("Something went wrong; can't find ajax request URL!");
|
378 |
+
},
|
379 |
+
500: function () {
|
380 |
+
showError("Something went wrong; internal server error while processing the request!");
|
381 |
+
}
|
382 |
+
}
|
383 |
+
});
|
384 |
+
};
|
385 |
+
|
386 |
+
/**
|
387 |
+
* Next / Previous Step Clicks to Navigate Through Staging Job
|
388 |
+
*/
|
389 |
+
var stepButtons = function ()
|
390 |
+
{
|
391 |
+
var $workFlow = cache.get("#wpstg-workflow");
|
392 |
+
|
393 |
+
$workFlow
|
394 |
+
// Next Button
|
395 |
+
.on("click", ".wpstg-next-step-link", function (e) {
|
396 |
+
e.preventDefault();
|
397 |
+
|
398 |
+
var $this = $(this),
|
399 |
+
isScan = false;
|
400 |
+
|
401 |
+
// Button is disabled
|
402 |
+
if ($this.attr("disabled"))
|
403 |
+
{
|
404 |
+
return false;
|
405 |
+
}
|
406 |
+
|
407 |
+
// Add loading overlay
|
408 |
+
$workFlow.addClass("loading");
|
409 |
+
|
410 |
+
// Prepare data
|
411 |
+
that.data = {
|
412 |
+
action: $this.data("action"),
|
413 |
+
nonce: wpstg.nonce
|
414 |
+
};
|
415 |
+
|
416 |
+
// Cloning data
|
417 |
+
getCloningData();
|
418 |
+
|
419 |
+
console.log(that.data);
|
420 |
+
|
421 |
+
isScan = ("wpstg_scanning" === that.action);
|
422 |
+
|
423 |
+
// Send ajax request
|
424 |
+
ajax(
|
425 |
+
that.data,
|
426 |
+
function (response) {
|
427 |
+
|
428 |
+
if (response.length < 1)
|
429 |
+
{
|
430 |
+
showError("Something went wrong, please try again");
|
431 |
+
}
|
432 |
+
|
433 |
+
// Styling of elements
|
434 |
+
$workFlow.removeClass("loading").html(response);
|
435 |
+
|
436 |
+
cache.get(".wpstg-current-step")
|
437 |
+
.removeClass("wpstg-current-step")
|
438 |
+
.next("li")
|
439 |
+
.addClass("wpstg-current-step");
|
440 |
+
|
441 |
+
// Start cloning
|
442 |
+
that.startCloning();
|
443 |
+
//processing();
|
444 |
+
},
|
445 |
+
"HTML"
|
446 |
+
);
|
447 |
+
})
|
448 |
+
// Previous Button
|
449 |
+
.on("click", ".wpstg-prev-step-link", function (e) {
|
450 |
+
e.preventDefault();
|
451 |
+
cache.get("#wpstg-loader").removeClass('wpstg-finished');
|
452 |
+
cache.get("#wpstg-loader").hide();
|
453 |
+
loadOverview();
|
454 |
+
});
|
455 |
+
};
|
456 |
+
|
457 |
+
/**
|
458 |
+
* Get Excluded (Unchecked) Database Tables
|
459 |
+
* @returns {Array}
|
460 |
+
*/
|
461 |
+
var getExcludedTables = function ()
|
462 |
+
{
|
463 |
+
var excludedTables = [];
|
464 |
+
|
465 |
+
$(".wpstg-db-table input:not(:checked)").each(function () {
|
466 |
+
excludedTables.push(this.name);
|
467 |
+
});
|
468 |
+
|
469 |
+
return excludedTables;
|
470 |
+
};
|
471 |
+
|
472 |
+
/**
|
473 |
+
* Get Included Directories
|
474 |
+
* @returns {Array}
|
475 |
+
*/
|
476 |
+
var getIncludedDirectories = function ()
|
477 |
+
{
|
478 |
+
var includedDirectories = [];
|
479 |
+
|
480 |
+
$(".wpstg-dir input:checked").each(function () {
|
481 |
+
var $this = $(this);
|
482 |
+
if (!$this.parent(".wpstg-dir").parents(".wpstg-dir").children(".wpstg-expand-dirs").hasClass("disabled"))
|
483 |
+
{
|
484 |
+
includedDirectories.push($this.val());
|
485 |
+
}
|
486 |
+
});
|
487 |
+
|
488 |
+
return includedDirectories;
|
489 |
+
};
|
490 |
+
|
491 |
+
/**
|
492 |
+
* Get Excluded Directories
|
493 |
+
* @returns {Array}
|
494 |
+
*/
|
495 |
+
var getExcludedDirectories = function ()
|
496 |
+
{
|
497 |
+
var excludedDirectories = [];
|
498 |
+
|
499 |
+
$(".wpstg-dir input:not(:checked)").each(function () {
|
500 |
+
var $this = $(this);
|
501 |
+
if (!$this.parent(".wpstg-dir").parents(".wpstg-dir").children(".wpstg-expand-dirs").hasClass("disabled"))
|
502 |
+
{
|
503 |
+
excludedDirectories.push($this.val());
|
504 |
+
}
|
505 |
+
});
|
506 |
+
|
507 |
+
return excludedDirectories;
|
508 |
+
};
|
509 |
+
|
510 |
+
/**
|
511 |
+
* Get Included Extra Directories
|
512 |
+
* @returns {Array}
|
513 |
+
*/
|
514 |
+
var getIncludedExtraDirectories = function ()
|
515 |
+
{
|
516 |
+
var extraDirectories = [];
|
517 |
+
|
518 |
+
if (!$("#wpstg_extraDirectories").val()) {
|
519 |
+
return extraDirectories;
|
520 |
+
}
|
521 |
+
|
522 |
+
var extraDirectories = $("#wpstg_extraDirectories").val().split(/\r?\n/);
|
523 |
+
console.log(extraDirectories);
|
524 |
+
|
525 |
+
//excludedDirectories.push($this.val());
|
526 |
+
|
527 |
+
return extraDirectories;
|
528 |
+
};
|
529 |
+
|
530 |
+
|
531 |
+
|
532 |
+
/**
|
533 |
+
* Get Cloning Step Data
|
534 |
+
*/
|
535 |
+
var getCloningData = function ()
|
536 |
+
{
|
537 |
+
if ("wpstg_cloning" !== that.data.action && "wpstg_update" !== that.data.action)
|
538 |
+
{
|
539 |
+
return;
|
540 |
+
}
|
541 |
+
|
542 |
+
that.data.cloneID = $("#wpstg-new-clone-id").val() || new Date().getTime().toString();
|
543 |
+
that.data.excludedTables = getExcludedTables();
|
544 |
+
that.data.includedDirectories = getIncludedDirectories();
|
545 |
+
that.data.excludedDirectories = getExcludedDirectories();
|
546 |
+
that.data.extraDirectories = getIncludedExtraDirectories();
|
547 |
+
console.log(that.data);
|
548 |
+
|
549 |
+
};
|
550 |
+
|
551 |
+
/**
|
552 |
+
* Loads Overview (first step) of Staging Job
|
553 |
+
*/
|
554 |
+
var loadOverview = function ()
|
555 |
+
{
|
556 |
+
var $workFlow = cache.get("#wpstg-workflow");
|
557 |
+
|
558 |
+
$workFlow.addClass("loading");
|
559 |
+
|
560 |
+
ajax(
|
561 |
+
{
|
562 |
+
action: "wpstg_overview",
|
563 |
+
nonce: wpstg.nonce
|
564 |
+
},
|
565 |
+
function (response) {
|
566 |
+
|
567 |
+
if (response.length < 1)
|
568 |
+
{
|
569 |
+
showError("Something went wrong, please try again");
|
570 |
+
}
|
571 |
+
|
572 |
+
var $currentStep = cache.get(".wpstg-current-step");
|
573 |
+
|
574 |
+
// Styling of elements
|
575 |
+
$workFlow.removeClass("loading").html(response);
|
576 |
+
|
577 |
+
},
|
578 |
+
"HTML"
|
579 |
+
);
|
580 |
+
};
|
581 |
+
|
582 |
+
/**
|
583 |
+
* Load Tabs
|
584 |
+
*/
|
585 |
+
var tabs = function ()
|
586 |
+
{
|
587 |
+
// var $loaded = false;
|
588 |
+
//
|
589 |
+
// if ($loaded === false) {
|
590 |
+
// console.log('select default tables');
|
591 |
+
//
|
592 |
+
// $(".wpstg-db-table input").each(function () {
|
593 |
+
//
|
594 |
+
// $loaded = true;
|
595 |
+
//
|
596 |
+
// if ($(this).attr('name').match("^" + wpstg.tblprefix)) {
|
597 |
+
// $(this).prop("checked", true);
|
598 |
+
// } else {
|
599 |
+
// $(this).prop("checked", false);
|
600 |
+
// }
|
601 |
+
// });
|
602 |
+
// }
|
603 |
+
|
604 |
+
cache.get("#wpstg-workflow").on("click", ".wpstg-tab-header", function (e) {
|
605 |
+
e.preventDefault();
|
606 |
+
|
607 |
+
var $this = $(this);
|
608 |
+
var $section = cache.get($this.data("id"));
|
609 |
+
|
610 |
+
$this.toggleClass("expand");
|
611 |
+
|
612 |
+
$section.slideToggle();
|
613 |
+
|
614 |
+
if ($this.hasClass("expand"))
|
615 |
+
{
|
616 |
+
$this.find(".wpstg-tab-triangle").html("▼");
|
617 |
+
}
|
618 |
+
else
|
619 |
+
{
|
620 |
+
$this.find(".wpstg-tab-triangle").html("►");
|
621 |
+
}
|
622 |
+
|
623 |
+
|
624 |
+
|
625 |
+
});
|
626 |
+
};
|
627 |
+
|
628 |
+
/**
|
629 |
+
* Delete Clone
|
630 |
+
* @param {String} clone
|
631 |
+
*/
|
632 |
+
var deleteClone = function (clone)
|
633 |
+
{
|
634 |
+
|
635 |
+
ajax(
|
636 |
+
{
|
637 |
+
action: "wpstg_delete_clone",
|
638 |
+
clone: clone,
|
639 |
+
nonce: wpstg.nonce,
|
640 |
+
excludedTables: getExcludedTables(),
|
641 |
+
deleteDir: $("#deleteDirectory:checked").val()
|
642 |
+
},
|
643 |
+
function (response)
|
644 |
+
{
|
645 |
+
if (response) {
|
646 |
+
// Error
|
647 |
+
if ("undefined" !== typeof response.error && "undefined" !== typeof response.message) {
|
648 |
+
showError(response.message);
|
649 |
+
console.log(response.message);
|
650 |
+
}
|
651 |
+
|
652 |
+
// Finished
|
653 |
+
if ("undefined" !== typeof response.delete && response.delete === 'finished') {
|
654 |
+
|
655 |
+
cache.get("#wpstg-removing-clone").removeClass("loading").html('');
|
656 |
+
$(".wpstg-clone#" + clone).remove();
|
657 |
+
|
658 |
+
if ($(".wpstg-clone").length < 1)
|
659 |
+
{
|
660 |
+
cache.get("#wpstg-existing-clones").find("h3").text('');
|
661 |
+
}
|
662 |
+
|
663 |
+
cache.get("#wpstg-loader").hide();
|
664 |
+
return;
|
665 |
+
}
|
666 |
+
}
|
667 |
+
// continue
|
668 |
+
if (true !== response)
|
669 |
+
{
|
670 |
+
deleteClone(clone);
|
671 |
+
return;
|
672 |
+
}
|
673 |
+
|
674 |
+
}
|
675 |
+
);
|
676 |
+
};
|
677 |
+
|
678 |
+
/**
|
679 |
+
* Cancel Cloning Process
|
680 |
+
*/
|
681 |
+
var cancelCloning = function ()
|
682 |
+
{
|
683 |
+
if (true === that.isFinished)
|
684 |
+
{
|
685 |
+
return true;
|
686 |
+
}
|
687 |
+
|
688 |
+
ajax(
|
689 |
+
{
|
690 |
+
action: "wpstg_cancel_clone",
|
691 |
+
clone: that.data.cloneID,
|
692 |
+
nonce: wpstg.nonce
|
693 |
+
},
|
694 |
+
function (response)
|
695 |
+
{
|
696 |
+
|
697 |
+
|
698 |
+
if (response && "undefined" !== typeof (response.delete) && response.delete === "finished") {
|
699 |
+
// Load overview
|
700 |
+
loadOverview();
|
701 |
+
return;
|
702 |
+
}
|
703 |
+
|
704 |
+
if (true !== response)
|
705 |
+
{
|
706 |
+
// continue
|
707 |
+
cancelCloning();
|
708 |
+
return;
|
709 |
+
}
|
710 |
+
|
711 |
+
// Load overview
|
712 |
+
loadOverview();
|
713 |
+
}
|
714 |
+
);
|
715 |
+
};
|
716 |
+
/**
|
717 |
+
* Cancel Cloning Process
|
718 |
+
*/
|
719 |
+
var cancelCloningUpdate = function ()
|
720 |
+
{
|
721 |
+
if (true === that.isFinished)
|
722 |
+
{
|
723 |
+
return true;
|
724 |
+
}
|
725 |
+
|
726 |
+
//alert(that.data.cloneID);
|
727 |
+
ajax(
|
728 |
+
{
|
729 |
+
action: "wpstg_cancel_update",
|
730 |
+
clone: that.data.cloneID,
|
731 |
+
nonce: wpstg.nonce
|
732 |
+
},
|
733 |
+
function (response)
|
734 |
+
{
|
735 |
+
|
736 |
+
|
737 |
+
if (response && "undefined" !== typeof (response.delete) && response.delete === "finished") {
|
738 |
+
// Load overview
|
739 |
+
loadOverview();
|
740 |
+
return;
|
741 |
+
}
|
742 |
+
|
743 |
+
if (true !== response)
|
744 |
+
{
|
745 |
+
// continue
|
746 |
+
cancelCloningUpdate();
|
747 |
+
return;
|
748 |
+
}
|
749 |
+
|
750 |
+
// Load overview
|
751 |
+
loadOverview();
|
752 |
+
}
|
753 |
+
);
|
754 |
+
};
|
755 |
+
|
756 |
+
/**
|
757 |
+
* Scroll the window log to bottom
|
758 |
+
* @returns void
|
759 |
+
*/
|
760 |
+
var logscroll = function () {
|
761 |
+
var $div = cache.get("#wpstg-log-details");
|
762 |
+
if ("undefined" !== typeof ($div[0])) {
|
763 |
+
$div.scrollTop($div[0].scrollHeight);
|
764 |
+
}
|
765 |
+
}
|
766 |
+
|
767 |
+
/**
|
768 |
+
* Append the log to the logging window
|
769 |
+
* @param string log
|
770 |
+
* @returns void
|
771 |
+
*/
|
772 |
+
var getLogs = function (log)
|
773 |
+
{
|
774 |
+
if (log != null && "undefined" !== typeof (log)) {
|
775 |
+
if (log.constructor === Array) {
|
776 |
+
$.each(log, function (index, value) {
|
777 |
+
if (value === null) {
|
778 |
+
return;
|
779 |
+
}
|
780 |
+
if (value.type === 'ERROR') {
|
781 |
+
cache.get("#wpstg-log-details").append('<span style="color:red;">[' + value.type + ']</span>-' + '[' + value.date + '] ' + value.message + '</br>');
|
782 |
+
} else {
|
783 |
+
cache.get("#wpstg-log-details").append('[' + value.type + ']-' + '[' + value.date + '] ' + value.message + '</br>');
|
784 |
+
}
|
785 |
+
})
|
786 |
+
} else {
|
787 |
+
cache.get("#wpstg-log-details").append('[' + log.type + ']-' + '[' + log.date + '] ' + log.message + '</br>');
|
788 |
+
}
|
789 |
+
}
|
790 |
+
logscroll();
|
791 |
+
|
792 |
+
};
|
793 |
+
|
794 |
+
/**
|
795 |
+
* Check diskspace
|
796 |
+
* @returns string json
|
797 |
+
*/
|
798 |
+
var checkDiskSpace = function () {
|
799 |
+
cache.get("#wpstg-check-space").on("click", function (e) {
|
800 |
+
cache.get("#wpstg-loader").show();
|
801 |
+
console.log("check disk space");
|
802 |
+
ajax(
|
803 |
+
{
|
804 |
+
action: "wpstg_check_disk_space",
|
805 |
+
nonce: wpstg.nonce
|
806 |
+
},
|
807 |
+
function (response)
|
808 |
+
{
|
809 |
+
if (false === response)
|
810 |
+
{
|
811 |
+
cache.get("#wpstg-clone-id-error").text('Can not detect disk space').show();
|
812 |
+
cache.get("#wpstg-loader").hide();
|
813 |
+
return;
|
814 |
+
}
|
815 |
+
|
816 |
+
// Not enough disk space
|
817 |
+
cache.get("#wpstg-clone-id-error").text('Available free disk space ' + response.freespace + ' | Estimated necessary disk space: ' + response.usedspace).show();
|
818 |
+
cache.get("#wpstg-loader").hide();
|
819 |
+
},
|
820 |
+
"json",
|
821 |
+
false
|
822 |
+
);
|
823 |
+
});
|
824 |
+
|
825 |
+
}
|
826 |
+
|
827 |
+
/**
|
828 |
+
* Fire the update cloning process
|
829 |
+
* @returns {undefined}
|
830 |
+
*/
|
831 |
+
// var startUpdate = function (){
|
832 |
+
// var $workFlow = cache.get("#wpstg-workflow");
|
833 |
+
// $workFlow.on("click", "#wpstg-start-updating", function (e) {
|
834 |
+
// e.preventDefault();
|
835 |
+
//
|
836 |
+
// var cloneID = $("#wpstg-new-clone-id").val();
|
837 |
+
// updateStruc(cloneID);
|
838 |
+
// });
|
839 |
+
// };
|
840 |
+
//
|
841 |
+
// var updateStruc = function (cloneID){
|
842 |
+
// ajax(
|
843 |
+
// {
|
844 |
+
// action: "wpstg_update_struc",
|
845 |
+
// nonce: wpstg.nonce,
|
846 |
+
// cloneID: cloneID,
|
847 |
+
// excludedTables: getExcludedTables(),
|
848 |
+
// includedDirectories: getIncludedDirectories(),
|
849 |
+
// excludedDirectories: getExcludedDirectories(),
|
850 |
+
// extraDirectories: getIncludedExtraDirectories()
|
851 |
+
// },
|
852 |
+
// function (response) {
|
853 |
+
// //console.log(response);
|
854 |
+
// updating(cloneID);
|
855 |
+
// },
|
856 |
+
// "HTML",
|
857 |
+
// false
|
858 |
+
// );
|
859 |
+
// }
|
860 |
+
|
861 |
+
/**
|
862 |
+
* Start ajax updating process
|
863 |
+
* @returns string
|
864 |
+
*/
|
865 |
+
// var updating = function (cloneID) {
|
866 |
+
//
|
867 |
+
// console.log("Start updating");
|
868 |
+
//
|
869 |
+
// // Show loader gif
|
870 |
+
// cache.get("#wpstg-loader").show();
|
871 |
+
// cache.get(".wpstg-loader").show();
|
872 |
+
//
|
873 |
+
// ajax(
|
874 |
+
// {
|
875 |
+
// action: "wpstg_update",
|
876 |
+
// nonce: wpstg.nonce,
|
877 |
+
// cloneID: cloneID,
|
878 |
+
// excludedTables: getExcludedTables(),
|
879 |
+
// includedDirectories: getIncludedDirectories(),
|
880 |
+
// excludedDirectories: getExcludedDirectories(),
|
881 |
+
// extraDirectories: getIncludedExtraDirectories()
|
882 |
+
// },
|
883 |
+
// function (response) {
|
884 |
+
//
|
885 |
+
// // Throw Error
|
886 |
+
// if ("undefined" !== typeof(response.error) && response.error){
|
887 |
+
// console.log(response.message);
|
888 |
+
// showError(response.message);
|
889 |
+
// return;
|
890 |
+
// }
|
891 |
+
//
|
892 |
+
// // Add percentage
|
893 |
+
// if ("undefined" !== typeof (response.percentage))
|
894 |
+
// {
|
895 |
+
// cache.get("#wpstg-db-progress").width(response.percentage + '%');
|
896 |
+
// }
|
897 |
+
// // Add Log
|
898 |
+
// if ("undefined" !== typeof (response.last_msg))
|
899 |
+
// {
|
900 |
+
// getLogs(response.last_msg);
|
901 |
+
// }
|
902 |
+
//
|
903 |
+
// // Continue clone DB
|
904 |
+
// if (false === response.status)
|
905 |
+
// {
|
906 |
+
// setTimeout(function () {
|
907 |
+
// updating(cloneID);
|
908 |
+
// }, wpstg.cpuLoad);
|
909 |
+
// }
|
910 |
+
// // Next Step
|
911 |
+
// else if (true === response.status)
|
912 |
+
// {
|
913 |
+
// console.log('startCloning ' + response.status);
|
914 |
+
// setTimeout(function () {
|
915 |
+
// // Prepare data
|
916 |
+
// that.data = {
|
917 |
+
// action: 'wpstg_cloning',
|
918 |
+
// nonce: wpstg.nonce
|
919 |
+
// };
|
920 |
+
// that.startCloning();
|
921 |
+
// }, wpstg.cpuLoad);
|
922 |
+
// }
|
923 |
+
// },
|
924 |
+
// "json",
|
925 |
+
// false
|
926 |
+
// );
|
927 |
+
// };
|
928 |
+
|
929 |
+
/**
|
930 |
+
* Start Cloning Process
|
931 |
+
* @type {Function}
|
932 |
+
*/
|
933 |
+
that.startCloning = (function () {
|
934 |
+
|
935 |
+
// Register function for checking disk space
|
936 |
+
checkDiskSpace();
|
937 |
+
|
938 |
+
if ("wpstg_cloning" !== that.data.action && "wpstg_update" !== that.data.action)
|
939 |
+
{
|
940 |
+
return;
|
941 |
+
}
|
942 |
+
|
943 |
+
// Start the process
|
944 |
+
start();
|
945 |
+
|
946 |
+
// Functions
|
947 |
+
// Start
|
948 |
+
function start()
|
949 |
+
{
|
950 |
+
console.log("Starting cloning process...");
|
951 |
+
|
952 |
+
cache.get("#wpstg-loader").show();
|
953 |
+
|
954 |
+
// Clone Database
|
955 |
+
setTimeout(function () {
|
956 |
+
cloneDatabase();
|
957 |
+
}, wpstg.cpuLoad);
|
958 |
+
}
|
959 |
+
|
960 |
+
// Step 1: Clone Database
|
961 |
+
function cloneDatabase()
|
962 |
+
{
|
963 |
+
if (true === that.isCancelled)
|
964 |
+
{
|
965 |
+
return false;
|
966 |
+
}
|
967 |
+
|
968 |
+
if (true === that.getLogs)
|
969 |
+
{
|
970 |
+
getLogs();
|
971 |
+
}
|
972 |
+
|
973 |
+
setTimeout(
|
974 |
+
function () {
|
975 |
+
ajax(
|
976 |
+
{
|
977 |
+
action: "wpstg_clone_database",
|
978 |
+
nonce: wpstg.nonce
|
979 |
+
},
|
980 |
+
function (response) {
|
981 |
+
// Add percentage
|
982 |
+
if ("undefined" !== typeof (response.percentage))
|
983 |
+
{
|
984 |
+
cache.get("#wpstg-db-progress").width(response.percentage + '%');
|
985 |
+
}
|
986 |
+
// Add Log
|
987 |
+
if ("undefined" !== typeof (response.last_msg))
|
988 |
+
{
|
989 |
+
getLogs(response.last_msg);
|
990 |
+
}
|
991 |
+
|
992 |
+
// Continue clone DB
|
993 |
+
if (false === response.status)
|
994 |
+
{
|
995 |
+
setTimeout(function () {
|
996 |
+
cloneDatabase();
|
997 |
+
}, wpstg.cpuLoad);
|
998 |
+
}
|
999 |
+
// Next Step
|
1000 |
+
else if (true === response.status)
|
1001 |
+
{
|
1002 |
+
//console.log('prepareDirectories ' + response.status);
|
1003 |
+
setTimeout(function () {
|
1004 |
+
prepareDirectories();
|
1005 |
+
}, wpstg.cpuLoad);
|
1006 |
+
}
|
1007 |
+
}
|
1008 |
+
);
|
1009 |
+
},
|
1010 |
+
500
|
1011 |
+
);
|
1012 |
+
}
|
1013 |
+
|
1014 |
+
// Step 2: Prepare Directories
|
1015 |
+
function prepareDirectories()
|
1016 |
+
{
|
1017 |
+
if (true === that.isCancelled)
|
1018 |
+
{
|
1019 |
+
return false;
|
1020 |
+
}
|
1021 |
+
|
1022 |
+
if (true === that.getLogs)
|
1023 |
+
{
|
1024 |
+
getLogs();
|
1025 |
+
}
|
1026 |
+
|
1027 |
+
setTimeout(
|
1028 |
+
function () {
|
1029 |
+
ajax(
|
1030 |
+
{
|
1031 |
+
action: "wpstg_clone_prepare_directories",
|
1032 |
+
nonce: wpstg.nonce
|
1033 |
+
},
|
1034 |
+
function (response) {
|
1035 |
+
// Add percentage
|
1036 |
+
if ("undefined" !== typeof (response.percentage))
|
1037 |
+
{
|
1038 |
+
cache.get("#wpstg-directories-progress").width(response.percentage + '%');
|
1039 |
+
}
|
1040 |
+
|
1041 |
+
// Add Log
|
1042 |
+
if ("undefined" !== typeof (response.last_msg))
|
1043 |
+
{
|
1044 |
+
getLogs(response.last_msg);
|
1045 |
+
}
|
1046 |
+
|
1047 |
+
if (false === response.status)
|
1048 |
+
{
|
1049 |
+
setTimeout(function () {
|
1050 |
+
prepareDirectories();
|
1051 |
+
}, wpstg.cpuLoad);
|
1052 |
+
}
|
1053 |
+
else if (true === response.status)
|
1054 |
+
{
|
1055 |
+
console.log('prepareDirectories' + response.status);
|
1056 |
+
cloneFiles();
|
1057 |
+
}
|
1058 |
+
}
|
1059 |
+
);
|
1060 |
+
},
|
1061 |
+
500
|
1062 |
+
);
|
1063 |
+
}
|
1064 |
+
|
1065 |
+
// Step 3: Clone Files
|
1066 |
+
function cloneFiles()
|
1067 |
+
{
|
1068 |
+
if (true === that.isCancelled)
|
1069 |
+
{
|
1070 |
+
return false;
|
1071 |
+
}
|
1072 |
+
|
1073 |
+
if (true === that.getLogs)
|
1074 |
+
{
|
1075 |
+
getLogs();
|
1076 |
+
}
|
1077 |
+
|
1078 |
+
ajax(
|
1079 |
+
{
|
1080 |
+
action: "wpstg_clone_files",
|
1081 |
+
nonce: wpstg.nonce
|
1082 |
+
},
|
1083 |
+
function (response) {
|
1084 |
+
// Add percentage
|
1085 |
+
if ("undefined" !== typeof (response.percentage))
|
1086 |
+
{
|
1087 |
+
cache.get("#wpstg-files-progress").width(response.percentage + '%');
|
1088 |
+
}
|
1089 |
+
|
1090 |
+
// Add Log
|
1091 |
+
if ("undefined" !== typeof (response.last_msg))
|
1092 |
+
{
|
1093 |
+
getLogs(response.last_msg);
|
1094 |
+
}
|
1095 |
+
|
1096 |
+
if (false === response.status)
|
1097 |
+
{
|
1098 |
+
setTimeout(function () {
|
1099 |
+
cloneFiles();
|
1100 |
+
}, wpstg.cpuLoad);
|
1101 |
+
}
|
1102 |
+
else if (true === response.status)
|
1103 |
+
{
|
1104 |
+
setTimeout(function () {
|
1105 |
+
replaceData();
|
1106 |
+
}, wpstg.cpuLoad);
|
1107 |
+
}
|
1108 |
+
}
|
1109 |
+
);
|
1110 |
+
}
|
1111 |
+
|
1112 |
+
// Step 4: Replace Data
|
1113 |
+
function replaceData()
|
1114 |
+
{
|
1115 |
+
if (true === that.isCancelled)
|
1116 |
+
{
|
1117 |
+
return false;
|
1118 |
+
}
|
1119 |
+
|
1120 |
+
if (true === that.getLogs)
|
1121 |
+
{
|
1122 |
+
console.log('getLogs1')
|
1123 |
+
getLogs();
|
1124 |
+
}
|
1125 |
+
|
1126 |
+
ajax(
|
1127 |
+
{
|
1128 |
+
action: "wpstg_clone_replace_data",
|
1129 |
+
nonce: wpstg.nonce
|
1130 |
+
},
|
1131 |
+
function (response) {
|
1132 |
+
// Add percentage
|
1133 |
+
if ("undefined" !== typeof (response.percentage))
|
1134 |
+
{
|
1135 |
+
cache.get("#wpstg-links-progress").width(response.percentage + '%');
|
1136 |
+
}
|
1137 |
+
|
1138 |
+
// Add Log
|
1139 |
+
if ("undefined" !== typeof (response.last_msg))
|
1140 |
+
{
|
1141 |
+
console.log('get Logs');
|
1142 |
+
getLogs(response.last_msg);
|
1143 |
+
}
|
1144 |
+
|
1145 |
+
if (false === response.status)
|
1146 |
+
{
|
1147 |
+
setTimeout(function () {
|
1148 |
+
console.log('replace data');
|
1149 |
+
replaceData();
|
1150 |
+
}, wpstg.cpuLoad);
|
1151 |
+
}
|
1152 |
+
else if (true === response.status)
|
1153 |
+
{
|
1154 |
+
console.log('finish');
|
1155 |
+
finish();
|
1156 |
+
}
|
1157 |
+
}
|
1158 |
+
);
|
1159 |
+
}
|
1160 |
+
|
1161 |
+
// Finish
|
1162 |
+
function finish()
|
1163 |
+
{
|
1164 |
+
if (true === that.getLogs)
|
1165 |
+
{
|
1166 |
+
getLogs();
|
1167 |
+
}
|
1168 |
+
|
1169 |
+
if (true === that.isCancelled || true === that.isFinished)
|
1170 |
+
{
|
1171 |
+
cache.get("#wpstg-loader").hide();
|
1172 |
+
return false;
|
1173 |
+
}
|
1174 |
+
|
1175 |
+
ajax(
|
1176 |
+
{
|
1177 |
+
action: "wpstg_clone_finish",
|
1178 |
+
nonce: wpstg.nonce
|
1179 |
+
},
|
1180 |
+
function (response)
|
1181 |
+
{
|
1182 |
+
// Invalid response
|
1183 |
+
if ("object" !== typeof (response))
|
1184 |
+
{
|
1185 |
+
showError(
|
1186 |
+
"Couldn't finish the cloning process properly. " +
|
1187 |
+
"Your clone has been copied but failed to do clean up and " +
|
1188 |
+
"saving its records to the database." +
|
1189 |
+
"Please contact support and provide your logs."
|
1190 |
+
);
|
1191 |
+
|
1192 |
+
return;
|
1193 |
+
}
|
1194 |
+
|
1195 |
+
// Add Log
|
1196 |
+
if ("undefined" !== typeof (response.last_msg))
|
1197 |
+
{
|
1198 |
+
getLogs(response.last_msg);
|
1199 |
+
}
|
1200 |
+
|
1201 |
+
console.log("Cloning process finished");
|
1202 |
+
|
1203 |
+
var $link1 = cache.get("#wpstg-clone-url-1");
|
1204 |
+
var $link = cache.get("#wpstg-clone-url");
|
1205 |
+
|
1206 |
+
cache.get("#wpstg_staging_name").html(that.data.cloneID);
|
1207 |
+
cache.get("#wpstg-finished-result").show();
|
1208 |
+
cache.get("#wpstg-cancel-cloning").prop("disabled", true);
|
1209 |
+
cache.get("#wpstg-cancel-cloning-update").prop("disabled", true);
|
1210 |
+
$link1.attr("href", $link1.attr("href") + '/' + response.directoryName);
|
1211 |
+
$link1.append('/' + response.directoryName);
|
1212 |
+
$link.attr("href", $link.attr("href") + '/' + response.directoryName);
|
1213 |
+
cache.get("#wpstg-remove-clone").data("clone", that.data.cloneID);
|
1214 |
+
|
1215 |
+
// Finished
|
1216 |
+
that.isFinished = true;
|
1217 |
+
|
1218 |
+
finish();
|
1219 |
+
}
|
1220 |
+
);
|
1221 |
+
}
|
1222 |
+
});
|
1223 |
+
|
1224 |
+
|
1225 |
+
/**
|
1226 |
+
* Initiation
|
1227 |
+
* @type {Function}
|
1228 |
+
*/
|
1229 |
+
that.init = (function () {
|
1230 |
+
loadOverview();
|
1231 |
+
elements();
|
1232 |
+
//startUpdate();
|
1233 |
+
stepButtons();
|
1234 |
+
tabs();
|
1235 |
+
//optimizer();
|
1236 |
+
});
|
1237 |
+
|
1238 |
+
/**
|
1239 |
+
* Ajax call
|
1240 |
+
* @type {ajax}
|
1241 |
+
*/
|
1242 |
+
that.ajax = ajax;
|
1243 |
+
that.showError = showError;
|
1244 |
+
that.getLogs = getLogs;
|
1245 |
+
that.loadOverview = loadOverview;
|
1246 |
+
|
1247 |
+
return that;
|
1248 |
+
})(jQuery);
|
1249 |
+
|
1250 |
+
jQuery(document).ready(function () {
|
1251 |
+
WPStaging.init();
|
1252 |
});
|
apps/Backend/views/clone/ajax/scan.php
CHANGED
@@ -1,119 +1,129 @@
|
|
1 |
-
<label id="wpstg-clone-label" for="wpstg-new-clone">
|
2 |
-
<?php echo __('Staging Site Name:', 'wpstg')?>
|
3 |
-
<input type="text" id="wpstg-new-clone-id" value="<?php echo $options->current; ?>"<?php if (null !== $options->current) echo " disabled='disabled'"?>>
|
4 |
-
</label>
|
5 |
-
|
6 |
-
<span class="wpstg-error-msg" id="wpstg-clone-id-error" style="display:none;">
|
7 |
-
<?php echo __(
|
8 |
-
"<br>Probably not enough free disk space to create a staging site. ".
|
9 |
-
"<br> You can continue but its likely that the copying process will fail.",
|
10 |
-
"wpstg"
|
11 |
-
)?>
|
12 |
-
</span>
|
13 |
-
|
14 |
-
<div class="wpstg-tabs-wrapper">
|
15 |
-
<a href="#" class="wpstg-tab-header active" data-id="#wpstg-scanning-db">
|
16 |
-
<span class="wpstg-tab-triangle">►</span>
|
17 |
-
<?php echo __("DB Tables", "wpstg")?>
|
18 |
-
</a>
|
19 |
-
|
20 |
-
<div class="wpstg-tab-section" id="wpstg-scanning-db">
|
21 |
-
<?php do_action("wpstg_scanning_db")?>
|
22 |
-
<h4 style="margin:0">
|
23 |
-
<?php
|
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 |
-
</button>
|
118 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
<a href="#" id="wpstg-check-space"><?php _e('Check Disk Space', 'wpstg'); ?></a>
|
1 |
+
<label id="wpstg-clone-label" for="wpstg-new-clone">
|
2 |
+
<?php echo __('Staging Site Name:', 'wpstg')?>
|
3 |
+
<input type="text" id="wpstg-new-clone-id" value="<?php echo $options->current; ?>"<?php if (null !== $options->current) echo " disabled='disabled'"?>>
|
4 |
+
</label>
|
5 |
+
|
6 |
+
<span class="wpstg-error-msg" id="wpstg-clone-id-error" style="display:none;">
|
7 |
+
<?php echo __(
|
8 |
+
"<br>Probably not enough free disk space to create a staging site. ".
|
9 |
+
"<br> You can continue but its likely that the copying process will fail.",
|
10 |
+
"wpstg"
|
11 |
+
)?>
|
12 |
+
</span>
|
13 |
+
|
14 |
+
<div class="wpstg-tabs-wrapper">
|
15 |
+
<a href="#" class="wpstg-tab-header active" data-id="#wpstg-scanning-db">
|
16 |
+
<span class="wpstg-tab-triangle">►</span>
|
17 |
+
<?php echo __("DB Tables", "wpstg")?>
|
18 |
+
</a>
|
19 |
+
|
20 |
+
<div class="wpstg-tab-section" id="wpstg-scanning-db">
|
21 |
+
<?php do_action("wpstg_scanning_db")?>
|
22 |
+
<h4 style="margin:0">
|
23 |
+
<?php
|
24 |
+
|
25 |
+
echo __(
|
26 |
+
"Uncheck the tables you do not want to copy. Usually you should select tables with prefix '{$scan->prefix}', only.",
|
27 |
+
"wpstg"
|
28 |
+
)?>
|
29 |
+
</h4>
|
30 |
+
<div style="margin-top:10px;margin-bottom:10px;">
|
31 |
+
<a href="#" class="wpstg-button-unselect button"> None </a>
|
32 |
+
<a href="#" class="wpstg-button-select button"> <?php _e(WPStaging\WPStaging::getTablePrefix(), 'wpstg'); ?> </a>
|
33 |
+
</div>
|
34 |
+
<?php
|
35 |
+
//print_r( $options->excludedTables);
|
36 |
+
foreach ($options->tables as $table):
|
37 |
+
$attributes = in_array($table->name, $options->excludedTables) ? '' : "checked";
|
38 |
+
$attributes .= in_array($table->name, $options->clonedTables) ? " disabled" : '';
|
39 |
+
?>
|
40 |
+
<div class="wpstg-db-table">
|
41 |
+
<label>
|
42 |
+
<input class="wpstg-db-table-checkboxes" type="checkbox" name="<?php echo $table->name?>" <?php echo $attributes?>>
|
43 |
+
<?php echo $table->name?>
|
44 |
+
</label>
|
45 |
+
<span class="wpstg-size-info">
|
46 |
+
<?php echo $scan->formatSize($table->size)?>
|
47 |
+
</span>
|
48 |
+
</div>
|
49 |
+
<?php endforeach ?>
|
50 |
+
<div style="margin-top:10px;">
|
51 |
+
<a href="#" class="wpstg-button-unselect button"> None </a>
|
52 |
+
<a href="#" class="wpstg-button-select button"> <?php _e(WPStaging\WPStaging::getTablePrefix(), 'wpstg'); ?> </a>
|
53 |
+
</div>
|
54 |
+
</div>
|
55 |
+
|
56 |
+
<a href="#" class="wpstg-tab-header" data-id="#wpstg-scanning-files">
|
57 |
+
<span class="wpstg-tab-triangle">►</span>
|
58 |
+
<?php echo __("Files", "wpstg")?>
|
59 |
+
</a>
|
60 |
+
|
61 |
+
<div class="wpstg-tab-section" id="wpstg-scanning-files">
|
62 |
+
<h4 style="margin:0">
|
63 |
+
<?php echo __("Uncheck the folders you do not want to copy. Click on them for expanding!", "wpstg")?>
|
64 |
+
</h4>
|
65 |
+
|
66 |
+
<?php echo $scan->directoryListing()?>
|
67 |
+
|
68 |
+
<h4 style="margin:10px 0 10px 0">
|
69 |
+
<?php echo __("Extra directories to copy", "wpstg")?>
|
70 |
+
</h4>
|
71 |
+
|
72 |
+
<textarea id="wpstg_extraDirectories" name="wpstg_extraDirectories" style="width:100%;height:250px;"></textarea>
|
73 |
+
<p>
|
74 |
+
<span>
|
75 |
+
<?php
|
76 |
+
echo __(
|
77 |
+
"Enter one folder path per line.<br>".
|
78 |
+
"Folders must start with absolute path: " . $options->root,
|
79 |
+
"wpstg"
|
80 |
+
)
|
81 |
+
?>
|
82 |
+
</span>
|
83 |
+
</p>
|
84 |
+
|
85 |
+
<p>
|
86 |
+
<span>
|
87 |
+
<?php
|
88 |
+
if (isset($options->clone)){
|
89 |
+
echo __("All files will be copied to: ", "wpstg") . $options->root . $options->clone;
|
90 |
+
}
|
91 |
+
?>
|
92 |
+
</span>
|
93 |
+
</p>
|
94 |
+
</div>
|
95 |
+
|
96 |
+
<a href="#" class="wpstg-tab-header" data-id="#wpstg-advanced-settings">
|
97 |
+
<span class="wpstg-tab-triangle">►</span>
|
98 |
+
<?php echo __("Advanced Options", "wpstg")?>
|
99 |
+
</a>
|
100 |
+
|
101 |
+
<div class="wpstg-tab-section" id="wpstg-advanced-settings">
|
102 |
+
Coming Soon...
|
103 |
+
</div>
|
104 |
+
|
105 |
+
</div>
|
106 |
+
|
107 |
+
<button type="button" class="wpstg-prev-step-link wpstg-link-btn button-primary">
|
108 |
+
<?php _e("Back", "wpstg")?>
|
109 |
+
</button>
|
110 |
+
|
111 |
+
<?php
|
112 |
+
if (null !== $options->current)
|
113 |
+
{
|
114 |
+
$label = __("Update Clone", "wpstg");
|
115 |
+
$action = 'wpstg_update';
|
116 |
+
|
117 |
+
echo '<button type="button" id="wpstg-start-updating" class="wpstg-next-step-link wpstg-link-btn button-primary" data-action="'.$action.'">'.$label.'</button>';
|
118 |
+
}
|
119 |
+
else
|
120 |
+
{
|
121 |
+
$label = __("Start Cloning", "wpstg");
|
122 |
+
$action = 'wpstg_cloning';
|
123 |
+
|
124 |
+
echo '<button type="button" id="wpstg-start-cloning" class="wpstg-next-step-link wpstg-link-btn button-primary" data-action="'.$action.'">'.$label.'</button>';
|
125 |
+
|
126 |
+
}
|
127 |
+
?>
|
128 |
+
|
129 |
<a href="#" id="wpstg-check-space"><?php _e('Check Disk Space', 'wpstg'); ?></a>
|
apps/Backend/views/clone/ajax/single-overview.php
CHANGED
@@ -1,49 +1,56 @@
|
|
1 |
-
<div id="wpstg-step-1">
|
2 |
-
<button id="wpstg-new-clone" class="wpstg-next-step-link wpstg-link-btn button-primary" data-action="wpstg_scanning">
|
3 |
-
<?php echo __("Create new staging site", "wpstg")?>
|
4 |
-
</button>
|
5 |
-
</div>
|
6 |
-
|
7 |
-
<?php if (isset($availableClones) && !empty($availableClones)):?>
|
8 |
-
<!-- Existing Clones -->
|
9 |
-
<div id="wpstg-existing-clones">
|
10 |
-
<h3>
|
11 |
-
<?php _e("Your Staging Sites:", "wpstg")?>
|
12 |
-
</h3>
|
13 |
-
<?php //wp_die(var_dump($availableClones)); ?>
|
14 |
-
<?php foreach ($availableClones as $name => $data):?>
|
15 |
-
<div id="<?php echo $data["directoryName"]; ?>" class="wpstg-clone">
|
16 |
-
|
17 |
-
<?php $urlLogin = $data["url"] . "/wp-login.php"?>
|
18 |
-
|
19 |
-
<a href="<?php echo $urlLogin?>" class="wpstg-clone-title" target="_blank">
|
20 |
-
<?php //echo $name?>
|
21 |
-
<?php echo $data["directoryName"]; ?>
|
22 |
-
</a>
|
23 |
-
|
24 |
-
<?php echo apply_filters("wpstg_before_stage_buttons", $html = '', $name, $data)?>
|
25 |
-
|
26 |
-
<a href="<?php echo $urlLogin?>" class="wpstg-open-clone wpstg-clone-action" target="_blank">
|
27 |
-
<?php _e("Open", "wpstg")?>
|
28 |
-
</a>
|
29 |
-
|
30 |
-
<a href="#" class="wpstg-execute-clone wpstg-clone-action" data-clone="<?php echo $name?>">
|
31 |
-
<?php _e("
|
32 |
-
</a>
|
33 |
-
|
34 |
-
<a href="#" class="wpstg-remove-clone wpstg-clone-action" data-clone="<?php echo $name?>">
|
35 |
-
<?php _e("Delete", "wpstg")?>
|
36 |
-
</a>
|
37 |
-
|
38 |
-
<?php echo apply_filters("wpstg_after_stage_buttons", $html = '', $name, $data)?>
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
<!-- /Remove Clone -->
|
1 |
+
<div id="wpstg-step-1">
|
2 |
+
<button id="wpstg-new-clone" class="wpstg-next-step-link wpstg-link-btn button-primary" data-action="wpstg_scanning">
|
3 |
+
<?php echo __("Create new staging site", "wpstg")?>
|
4 |
+
</button>
|
5 |
+
</div>
|
6 |
+
|
7 |
+
<?php if (isset($availableClones) && !empty($availableClones)):?>
|
8 |
+
<!-- Existing Clones -->
|
9 |
+
<div id="wpstg-existing-clones">
|
10 |
+
<h3>
|
11 |
+
<?php _e("Your Staging Sites:", "wpstg")?>
|
12 |
+
</h3>
|
13 |
+
<?php //wp_die(var_dump($availableClones)); ?>
|
14 |
+
<?php foreach ($availableClones as $name => $data):?>
|
15 |
+
<div id="<?php echo $data["directoryName"]; ?>" class="wpstg-clone">
|
16 |
+
|
17 |
+
<?php $urlLogin = $data["url"] . "/wp-login.php"?>
|
18 |
+
|
19 |
+
<a href="<?php echo $urlLogin?>" class="wpstg-clone-title" target="_blank">
|
20 |
+
<?php //echo $name?>
|
21 |
+
<?php echo $data["directoryName"]; ?>
|
22 |
+
</a>
|
23 |
+
|
24 |
+
<?php echo apply_filters("wpstg_before_stage_buttons", $html = '', $name, $data)?>
|
25 |
+
|
26 |
+
<a href="<?php echo $urlLogin?>" class="wpstg-open-clone wpstg-clone-action" target="_blank">
|
27 |
+
<?php _e("Open", "wpstg"); ?>
|
28 |
+
</a>
|
29 |
+
|
30 |
+
<a href="#" class="wpstg-execute-clone wpstg-clone-action" data-clone="<?php echo $name?>">
|
31 |
+
<?php _e("Update", "wpstg"); ?>
|
32 |
+
</a>
|
33 |
+
|
34 |
+
<a href="#" class="wpstg-remove-clone wpstg-clone-action" data-clone="<?php echo $name?>">
|
35 |
+
<?php _e("Delete", "wpstg"); ?>
|
36 |
+
</a>
|
37 |
+
|
38 |
+
<?php echo apply_filters("wpstg_after_stage_buttons", $html = '', $name, $data)?>
|
39 |
+
<div class="wpstg-staging-info">
|
40 |
+
<?php
|
41 |
+
$prefix = isset ($data['prefix']) ? __("DB prefix: <span class='wpstg-bold'>" . $data['prefix'], "wpstg") . '</span> ' : ' ';
|
42 |
+
//$path = isset ($data['directoryName']) ? __("Subdir: <span class='wpstg-bold'>" . $data['directoryName'], "wpstg") . '</span>' : '';
|
43 |
+
echo $prefix;
|
44 |
+
?>
|
45 |
+
</div>
|
46 |
+
</div>
|
47 |
+
<?php endforeach?>
|
48 |
+
</div>
|
49 |
+
<!-- /Existing Clones -->
|
50 |
+
<?php endif?>
|
51 |
+
|
52 |
+
<!-- Remove Clone -->
|
53 |
+
<div id="wpstg-removing-clone">
|
54 |
+
|
55 |
+
</div>
|
56 |
<!-- /Remove Clone -->
|
apps/Backend/views/clone/ajax/update.php
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class=successfullying-section">
|
2 |
+
<?php echo __("Copy Database Tables", "wpstg")?>
|
3 |
+
<div class="wpstg-progress-bar">
|
4 |
+
<div class="wpstg-progress" id="wpstg-db-progress" style="width:0"></div>
|
5 |
+
</div>
|
6 |
+
</div>
|
7 |
+
|
8 |
+
<div class="wpstg-cloning-section">
|
9 |
+
<?php echo __("Prepare Directories", "wpstg")?>
|
10 |
+
<div class="wpstg-progress-bar">
|
11 |
+
<div class="wpstg-progress" id="wpstg-directories-progress" style="width:0"></div>
|
12 |
+
</div>
|
13 |
+
</div>
|
14 |
+
|
15 |
+
<div class="wpstg-cloning-section">
|
16 |
+
<?php echo __("Copy Files", "wpstg")?>
|
17 |
+
<div class="wpstg-progress-bar">
|
18 |
+
<div class="wpstg-progress" id="wpstg-files-progress" style="width:0"></div>
|
19 |
+
</div>
|
20 |
+
</div>
|
21 |
+
|
22 |
+
<div class="wpstg-cloning-section">
|
23 |
+
<?php echo __("Replace Data", "wpstg")?>
|
24 |
+
<div class="wpstg-progress-bar">
|
25 |
+
<div class="wpstg-progress" id="wpstg-links-progress" style="width:0"></div>
|
26 |
+
</div>
|
27 |
+
</div>
|
28 |
+
|
29 |
+
<button type="button" id="wpstg-cancel-cloning-update" class="wpstg-link-btn button-primary">
|
30 |
+
<?php echo __("Cancel Update", "wpstg")?>
|
31 |
+
</button>
|
32 |
+
|
33 |
+
<button type="button" id="wpstg-show-log-button" class="button" data-clone="<?php echo $cloning->getOptions()->clone?>" style="margin-top: 5px;display:none;">
|
34 |
+
<?php _e('Display working log', 'wpstg')?>
|
35 |
+
</button>
|
36 |
+
|
37 |
+
<div>
|
38 |
+
<span id="wpstg-cloning-result"></span>
|
39 |
+
</div>
|
40 |
+
|
41 |
+
|
42 |
+
<div id="wpstg-error-wrapper">
|
43 |
+
<div id="wpstg-error-details"></div>
|
44 |
+
</div>
|
45 |
+
|
46 |
+
<div id="wpstg-log-details"></div>
|
apps/Core/WPStaging.php
CHANGED
@@ -1,425 +1,429 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace WPStaging;
|
4 |
-
|
5 |
-
// No Direct Access
|
6 |
-
if( !defined( "WPINC" ) ) {
|
7 |
-
die;
|
8 |
-
}
|
9 |
-
|
10 |
-
// Ensure to include autoloader class
|
11 |
-
require_once __DIR__ . DIRECTORY_SEPARATOR . "Utils" . DIRECTORY_SEPARATOR . "Autoloader.php";
|
12 |
-
|
13 |
-
use WPStaging\Backend\Administrator;
|
14 |
-
use WPStaging\DTO\Settings;
|
15 |
-
use WPStaging\Frontend\Frontend;
|
16 |
-
use WPStaging\Utils\Autoloader;
|
17 |
-
use WPStaging\Utils\Cache;
|
18 |
-
use WPStaging\Utils\Loader;
|
19 |
-
use WPStaging\Utils\Logger;
|
20 |
-
use WPStaging\DI\InjectionAware;
|
21 |
-
use WPStaging\Cron\Cron;
|
22 |
-
|
23 |
-
/**
|
24 |
-
* Class WPStaging
|
25 |
-
* @package WPStaging
|
26 |
-
*/
|
27 |
-
final class WPStaging {
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Plugin version
|
31 |
-
*/
|
32 |
-
const VERSION = "2.1.
|
33 |
-
|
34 |
-
/**
|
35 |
-
* Plugin name
|
36 |
-
*/
|
37 |
-
const NAME = "WP Staging";
|
38 |
-
|
39 |
-
/**
|
40 |
-
* Plugin slug
|
41 |
-
*/
|
42 |
-
const SLUG = "wp-staging";
|
43 |
-
|
44 |
-
/**
|
45 |
-
* Compatible WP Version
|
46 |
-
*/
|
47 |
-
const WP_COMPATIBLE = "4.8.4";
|
48 |
-
|
49 |
-
/**
|
50 |
-
* Slug: Either wp-staging or wp-staging-pro
|
51 |
-
* @var string
|
52 |
-
*/
|
53 |
-
public $slug;
|
54 |
-
|
55 |
-
/**
|
56 |
-
* Absolute plugin path
|
57 |
-
* @var string
|
58 |
-
*/
|
59 |
-
public $pluginPath;
|
60 |
-
|
61 |
-
/**
|
62 |
-
* Services
|
63 |
-
* @var array
|
64 |
-
*/
|
65 |
-
private $services;
|
66 |
-
|
67 |
-
/**
|
68 |
-
* Singleton instance
|
69 |
-
* @var WPStaging
|
70 |
-
*/
|
71 |
-
private static $instance;
|
72 |
-
|
73 |
-
/**
|
74 |
-
* WPStaging constructor.
|
75 |
-
*/
|
76 |
-
private function __construct() {
|
77 |
-
|
78 |
-
$file = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . self::SLUG . DIRECTORY_SEPARATOR . self::SLUG . ".php";
|
79 |
-
|
80 |
-
$this->registerMain();
|
81 |
-
$this->registerNamespaces();
|
82 |
-
$this->loadLanguages();
|
83 |
-
$this->loadDependencies();
|
84 |
-
$this->defineHooks();
|
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 |
-
$autoloader
|
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 |
-
case "
|
358 |
-
$cpuLoad =
|
359 |
-
break;
|
360 |
-
|
361 |
-
case "
|
362 |
-
$cpuLoad =
|
363 |
-
break;
|
364 |
-
|
365 |
-
case "
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
$languagesDirectory =
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
$
|
386 |
-
|
387 |
-
//
|
388 |
-
$
|
389 |
-
$
|
390 |
-
|
391 |
-
//
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
//
|
396 |
-
|
397 |
-
load_textdomain( "wpstg", $moFileGlobal );
|
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 |
-
}
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPStaging;
|
4 |
+
|
5 |
+
// No Direct Access
|
6 |
+
if( !defined( "WPINC" ) ) {
|
7 |
+
die;
|
8 |
+
}
|
9 |
+
|
10 |
+
// Ensure to include autoloader class
|
11 |
+
require_once __DIR__ . DIRECTORY_SEPARATOR . "Utils" . DIRECTORY_SEPARATOR . "Autoloader.php";
|
12 |
+
|
13 |
+
use WPStaging\Backend\Administrator;
|
14 |
+
use WPStaging\DTO\Settings;
|
15 |
+
use WPStaging\Frontend\Frontend;
|
16 |
+
use WPStaging\Utils\Autoloader;
|
17 |
+
use WPStaging\Utils\Cache;
|
18 |
+
use WPStaging\Utils\Loader;
|
19 |
+
use WPStaging\Utils\Logger;
|
20 |
+
use WPStaging\DI\InjectionAware;
|
21 |
+
use WPStaging\Cron\Cron;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Class WPStaging
|
25 |
+
* @package WPStaging
|
26 |
+
*/
|
27 |
+
final class WPStaging {
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Plugin version
|
31 |
+
*/
|
32 |
+
const VERSION = "2.1.3";
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Plugin name
|
36 |
+
*/
|
37 |
+
const NAME = "WP Staging";
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Plugin slug
|
41 |
+
*/
|
42 |
+
const SLUG = "wp-staging";
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Compatible WP Version
|
46 |
+
*/
|
47 |
+
const WP_COMPATIBLE = "4.8.4";
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Slug: Either wp-staging or wp-staging-pro
|
51 |
+
* @var string
|
52 |
+
*/
|
53 |
+
public $slug;
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Absolute plugin path
|
57 |
+
* @var string
|
58 |
+
*/
|
59 |
+
public $pluginPath;
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Services
|
63 |
+
* @var array
|
64 |
+
*/
|
65 |
+
private $services;
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Singleton instance
|
69 |
+
* @var WPStaging
|
70 |
+
*/
|
71 |
+
private static $instance;
|
72 |
+
|
73 |
+
/**
|
74 |
+
* WPStaging constructor.
|
75 |
+
*/
|
76 |
+
private function __construct() {
|
77 |
+
|
78 |
+
$file = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . self::SLUG . DIRECTORY_SEPARATOR . self::SLUG . ".php";
|
79 |
+
|
80 |
+
$this->registerMain();
|
81 |
+
$this->registerNamespaces();
|
82 |
+
$this->loadLanguages();
|
83 |
+
$this->loadDependencies();
|
84 |
+
$this->defineHooks();
|
85 |
+
// Licensing stuff be loaded in wpstg core to make cron hook available from frontpage
|
86 |
+
$this->initLicensing();
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Method to be executed upon activation of the plugin
|
91 |
+
*/
|
92 |
+
public function onActivation() {
|
93 |
+
$Activation = new \WPStaging\Backend\Activation\Activation();
|
94 |
+
$Activation->install_dependancies();
|
95 |
+
}
|
96 |
+
|
97 |
+
public function registerMain() {
|
98 |
+
// Slug of the plugin
|
99 |
+
$this->slug = plugin_basename( dirname( dirname( dirname( __FILE__ ) ) ) );
|
100 |
+
|
101 |
+
// absolute path to the main plugin dir
|
102 |
+
$this->pluginPath = plugin_dir_path( dirname( dirname( __FILE__ ) ) );
|
103 |
+
|
104 |
+
// URL to apps folder
|
105 |
+
$this->url = plugin_dir_url( dirname( __FILE__ ) );
|
106 |
+
|
107 |
+
// URL to backend public folder folder
|
108 |
+
$this->backend_url = plugin_dir_url( dirname( __FILE__ ) ) . "Backend/public/";
|
109 |
+
|
110 |
+
// URL to frontend public folder folder
|
111 |
+
$this->frontend_url = plugin_dir_url( dirname( __FILE__ ) ) . "Frontend/public/";
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Define Hooks
|
116 |
+
*/
|
117 |
+
public function defineHooks() {
|
118 |
+
$loader = $this->get( "loader" );
|
119 |
+
$loader->addAction( "admin_enqueue_scripts", $this, "enqueueElements", 100 );
|
120 |
+
$loader->addAction( "wp_enqueue_scripts", $this, "enqueueElements", 100 );
|
121 |
+
$this->addIntervals();
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Add new cron time event "weekly"
|
126 |
+
*/
|
127 |
+
public function addIntervals(){
|
128 |
+
$interval = new Cron();
|
129 |
+
}
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Scripts and Styles
|
133 |
+
* @param string $hook
|
134 |
+
*/
|
135 |
+
public function enqueueElements( $hook ) {
|
136 |
+
|
137 |
+
// Load this css file on frontend and backend on all pages if current site is a staging site
|
138 |
+
if( $this->isStagingSite() ) {
|
139 |
+
wp_enqueue_style( "wpstg-admin-bar", $this->backend_url . "css/wpstg-admin-bar.css", $this->getVersion() );
|
140 |
+
}
|
141 |
+
|
142 |
+
$availablePages = array(
|
143 |
+
"toplevel_page_wpstg_clone",
|
144 |
+
"wp-staging_page_wpstg-settings",
|
145 |
+
"wp-staging_page_wpstg-tools",
|
146 |
+
"wp-staging_page_wpstg-license",
|
147 |
+
"wp-staging_page_wpstg-welcome",
|
148 |
+
);
|
149 |
+
|
150 |
+
// Load these css and js files only on wp staging admin pages
|
151 |
+
if( !in_array( $hook, $availablePages ) || !is_admin() ) {
|
152 |
+
return;
|
153 |
+
}
|
154 |
+
|
155 |
+
// Load admin js files
|
156 |
+
wp_enqueue_script(
|
157 |
+
"wpstg-admin-script", $this->backend_url . "js/wpstg-admin.js", array("jquery"), $this->getVersion(), false
|
158 |
+
);
|
159 |
+
|
160 |
+
// Load admin css files
|
161 |
+
wp_enqueue_style(
|
162 |
+
"wpstg-admin", $this->backend_url . "css/wpstg-admin.css", $this->getVersion()
|
163 |
+
);
|
164 |
+
|
165 |
+
wp_localize_script( "wpstg-admin-script", "wpstg", array(
|
166 |
+
"nonce" => wp_create_nonce( "wpstg_ajax_nonce" ),
|
167 |
+
"mu_plugin_confirmation" => __(
|
168 |
+
"If confirmed we will install an additional WordPress 'Must Use' plugin. "
|
169 |
+
. "This plugin will allow us to control which plugins are loaded during "
|
170 |
+
. "WP Staging specific operations. Do you wish to continue?", "wpstg"
|
171 |
+
),
|
172 |
+
"plugin_compatibility_settings_problem" => __(
|
173 |
+
"A problem occurred when trying to change the plugin compatibility setting.", "wpstg"
|
174 |
+
),
|
175 |
+
"saved" => __( "Saved", "The settings were saved successfully", "wpstg" ),
|
176 |
+
"status" => __( "Status", "Current request status", "wpstg" ),
|
177 |
+
"response" => __( "Response", "The message the server responded with", "wpstg" ),
|
178 |
+
"blacklist_problem" => __(
|
179 |
+
"A problem occurred when trying to add plugins to backlist.", "wpstg"
|
180 |
+
),
|
181 |
+
"cpuLoad" => $this->getCPULoadSetting(),
|
182 |
+
"settings" => ( object ) array(), // TODO add settings?
|
183 |
+
"tblprefix" => self::getTablePrefix()
|
184 |
+
) );
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Get table prefix of the current site
|
189 |
+
* @return string
|
190 |
+
*/
|
191 |
+
public static function getTablePrefix(){
|
192 |
+
$wpDB = WPStaging::getInstance()->get("wpdb");
|
193 |
+
return $wpDB->prefix;
|
194 |
+
}
|
195 |
+
|
196 |
+
/**
|
197 |
+
* Caching and logging folder
|
198 |
+
*
|
199 |
+
* @return string
|
200 |
+
*/
|
201 |
+
public static function getContentDir() {
|
202 |
+
$wp_upload_dir = wp_upload_dir();
|
203 |
+
$path = $wp_upload_dir['basedir'] . '/wp-staging';
|
204 |
+
wp_mkdir_p( $path );
|
205 |
+
return apply_filters( 'wpstg_get_upload_dir', $path . DIRECTORY_SEPARATOR );
|
206 |
+
}
|
207 |
+
|
208 |
+
/**
|
209 |
+
* Register used namespaces
|
210 |
+
*/
|
211 |
+
private function registerNamespaces() {
|
212 |
+
$autoloader = new Autoloader();
|
213 |
+
$this->set( "autoloader", $autoloader );
|
214 |
+
|
215 |
+
// Autoloader
|
216 |
+
$autoloader->registerNamespaces( array(
|
217 |
+
"WPStaging" => array(
|
218 |
+
$this->pluginPath . 'apps' . DIRECTORY_SEPARATOR,
|
219 |
+
$this->pluginPath . 'apps' . DIRECTORY_SEPARATOR . 'Core' . DIRECTORY_SEPARATOR,
|
220 |
+
)
|
221 |
+
) );
|
222 |
+
|
223 |
+
// Register namespaces
|
224 |
+
$autoloader->register();
|
225 |
+
}
|
226 |
+
|
227 |
+
/**
|
228 |
+
* Get Instance
|
229 |
+
* @return WPStaging
|
230 |
+
*/
|
231 |
+
public static function getInstance() {
|
232 |
+
if( null === static::$instance ) {
|
233 |
+
static::$instance = new static();
|
234 |
+
}
|
235 |
+
|
236 |
+
return static::$instance;
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Prevent cloning
|
241 |
+
* @return void
|
242 |
+
*/
|
243 |
+
private function __clone() {
|
244 |
+
|
245 |
+
}
|
246 |
+
|
247 |
+
/**
|
248 |
+
* Prevent unserialization
|
249 |
+
* @return void
|
250 |
+
*/
|
251 |
+
private function __wakeup() {
|
252 |
+
|
253 |
+
}
|
254 |
+
|
255 |
+
/**
|
256 |
+
* Load Dependencies
|
257 |
+
*/
|
258 |
+
private function loadDependencies() {
|
259 |
+
// Set loader
|
260 |
+
$this->set( "loader", new Loader() );
|
261 |
+
|
262 |
+
// Set cache
|
263 |
+
$this->set( "cache", new Cache() );
|
264 |
+
|
265 |
+
// Set logger
|
266 |
+
$this->set( "logger", new Logger() );
|
267 |
+
|
268 |
+
// Set settings
|
269 |
+
$this->set( "settings", new Settings() );
|
270 |
+
|
271 |
+
// Set Administrator
|
272 |
+
if( is_admin() ) {
|
273 |
+
new Administrator( $this );
|
274 |
+
} else {
|
275 |
+
new Frontend( $this );
|
276 |
+
}
|
277 |
+
}
|
278 |
+
|
279 |
+
/**
|
280 |
+
* Execute Plugin
|
281 |
+
*/
|
282 |
+
public function run() {
|
283 |
+
$this->get( "loader" )->run();
|
284 |
+
}
|
285 |
+
|
286 |
+
/**
|
287 |
+
* Set a variable to DI with given name
|
288 |
+
* @param string $name
|
289 |
+
* @param mixed $variable
|
290 |
+
* @return $this
|
291 |
+
*/
|
292 |
+
public function set( $name, $variable ) {
|
293 |
+
// It is a function
|
294 |
+
if( is_callable( $variable ) )
|
295 |
+
$variable = $variable();
|
296 |
+
|
297 |
+
// Add it to services
|
298 |
+
$this->services[$name] = $variable;
|
299 |
+
|
300 |
+
return $this;
|
301 |
+
}
|
302 |
+
|
303 |
+
/**
|
304 |
+
* Get given name index from DI
|
305 |
+
* @param string $name
|
306 |
+
* @return mixed|null
|
307 |
+
*/
|
308 |
+
public function get( $name ) {
|
309 |
+
return (isset( $this->services[$name] )) ? $this->services[$name] : null;
|
310 |
+
}
|
311 |
+
|
312 |
+
/**
|
313 |
+
* @return string
|
314 |
+
*/
|
315 |
+
public function getVersion() {
|
316 |
+
return self::VERSION;
|
317 |
+
}
|
318 |
+
|
319 |
+
/**
|
320 |
+
* @return string
|
321 |
+
*/
|
322 |
+
public function getName() {
|
323 |
+
return self::NAME;
|
324 |
+
}
|
325 |
+
|
326 |
+
/**
|
327 |
+
* @return string
|
328 |
+
*/
|
329 |
+
public static function getSlug() {
|
330 |
+
return plugin_basename( dirname( dirname( dirname( __FILE__ ) ) ) );
|
331 |
+
}
|
332 |
+
|
333 |
+
/**
|
334 |
+
* Get path to main plugin file
|
335 |
+
* @return string
|
336 |
+
*/
|
337 |
+
public function getPath() {
|
338 |
+
return dirname( dirname( __FILE__ ) );
|
339 |
+
}
|
340 |
+
|
341 |
+
/**
|
342 |
+
* Get main plugin url
|
343 |
+
* @return type
|
344 |
+
*/
|
345 |
+
public function getUrl() {
|
346 |
+
return plugin_dir_url( dirname( __FILE__ ) );
|
347 |
+
}
|
348 |
+
|
349 |
+
/**
|
350 |
+
* @return array|mixed|object
|
351 |
+
*/
|
352 |
+
public function getCPULoadSetting() {
|
353 |
+
$options = $this->get( "settings" );
|
354 |
+
$setting = $options->getCpuLoad();
|
355 |
+
|
356 |
+
switch ( $setting ) {
|
357 |
+
case "high":
|
358 |
+
$cpuLoad = 0;
|
359 |
+
break;
|
360 |
+
|
361 |
+
case "medium":
|
362 |
+
$cpuLoad = 1000;
|
363 |
+
break;
|
364 |
+
|
365 |
+
case "low":
|
366 |
+
$cpuLoad = 3000;
|
367 |
+
break;
|
368 |
+
|
369 |
+
case "default":
|
370 |
+
default:
|
371 |
+
$cpuLoad = 1000;
|
372 |
+
}
|
373 |
+
|
374 |
+
return $cpuLoad;
|
375 |
+
}
|
376 |
+
|
377 |
+
/**
|
378 |
+
* Load language file
|
379 |
+
*/
|
380 |
+
public function loadLanguages() {
|
381 |
+
$languagesDirectory = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . self::SLUG . DIRECTORY_SEPARATOR;
|
382 |
+
$languagesDirectory.= "vars" . DIRECTORY_SEPARATOR . "languages" . DIRECTORY_SEPARATOR;
|
383 |
+
|
384 |
+
// Set filter for plugins languages directory
|
385 |
+
$languagesDirectory = apply_filters( "wpstg_languages_directory", $languagesDirectory );
|
386 |
+
|
387 |
+
// Traditional WP plugin locale filter
|
388 |
+
$locale = apply_filters( "plugin_locale", get_locale(), "wpstg" );
|
389 |
+
$moFile = sprintf( '%1$s-%2$s.mo', "wpstg", $locale );
|
390 |
+
|
391 |
+
// Setup paths to current locale file
|
392 |
+
$moFileLocal = $languagesDirectory . $moFile;
|
393 |
+
$moFileGlobal = WP_LANG_DIR . DIRECTORY_SEPARATOR . "wpstg" . DIRECTORY_SEPARATOR . $moFile;
|
394 |
+
|
395 |
+
// Global file (/wp-content/languages/WPSTG)
|
396 |
+
if( file_exists( $moFileGlobal ) ) {
|
397 |
+
load_textdomain( "wpstg", $moFileGlobal );
|
398 |
+
}
|
399 |
+
// Local file (/wp-content/plugins/wp-staging/languages/)
|
400 |
+
elseif( file_exists( $moFileLocal ) ) {
|
401 |
+
load_textdomain( "wpstg", $moFileGlobal );
|
402 |
+
}
|
403 |
+
// Default file
|
404 |
+
else {
|
405 |
+
load_plugin_textdomain( "wpstg", false, $languagesDirectory );
|
406 |
+
}
|
407 |
+
}
|
408 |
+
|
409 |
+
/**
|
410 |
+
* Check if it is a staging site
|
411 |
+
* @return bool
|
412 |
+
*/
|
413 |
+
private function isStagingSite() {
|
414 |
+
return ("true" === get_option( "wpstg_is_staging_site" ));
|
415 |
+
}
|
416 |
+
|
417 |
+
/**
|
418 |
+
* Initialize licensing functions
|
419 |
+
* @return boolean
|
420 |
+
*/
|
421 |
+
public function initLicensing() {
|
422 |
+
// Add licensing stuff if class exists
|
423 |
+
if( class_exists( 'WPStaging\Backend\Pro\Licensing\Licensing' ) ) {
|
424 |
+
$licensing = new Backend\Pro\Licensing\Licensing();
|
425 |
+
}
|
426 |
+
return false;
|
427 |
+
}
|
428 |
+
|
429 |
+
}
|
readme.txt
CHANGED
@@ -9,7 +9,7 @@ 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: 4.8
|
12 |
-
Stable tag: 2.1.
|
13 |
|
14 |
A duplicator plugin! Clone, duplicate and migrate live sites to independent staging and development sites that are available only to administrators.
|
15 |
|
@@ -139,6 +139,15 @@ https://wp-staging.com
|
|
139 |
|
140 |
== Changelog ==
|
141 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
142 |
= 2.1.2 =
|
143 |
* Fix: Remove LOCK_EX parameter in file_put_contents(). LOCK_EX is not working on several systems which results in cloning process timeouts
|
144 |
* Fix: Huge Performance improvement in copying process by removing duplicate file entries in the cache file. This also prevents weird timeout issues on some hosted websites
|
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: 4.8
|
12 |
+
Stable tag: 2.1.3
|
13 |
|
14 |
A duplicator plugin! Clone, duplicate and migrate live sites to independent staging and development sites that are available only to administrators.
|
15 |
|
139 |
|
140 |
== Changelog ==
|
141 |
|
142 |
+
= 2.1.3 =
|
143 |
+
* New: Add more details to tools->system info log for better debugging
|
144 |
+
* New: Add buttons to select all default wp tables with one click
|
145 |
+
* New: Show used db table in list of staging sites
|
146 |
+
* Fix: Delete staging site not possible if db prefix is same as one of the live site
|
147 |
+
* Fix: Edit/Update clone function is duplicating tables.
|
148 |
+
* Fix: Other staging site can be overwritten when Edit/Update clone function is executed
|
149 |
+
* Fix: Several improvements to improve reliability and prevent timeouts and fatal errors during cloning
|
150 |
+
|
151 |
= 2.1.2 =
|
152 |
* Fix: Remove LOCK_EX parameter in file_put_contents(). LOCK_EX is not working on several systems which results in cloning process timeouts
|
153 |
* Fix: Huge Performance improvement in copying process by removing duplicate file entries in the cache file. This also prevents weird timeout issues on some hosted websites
|
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.1.
|
11 |
* Text Domain: wpstg
|
12 |
* Domain Path: /languages/
|
13 |
|
7 |
* Author: WP-Staging
|
8 |
* Author URI: https://wp-staging.com
|
9 |
* Contributors: ReneHermi, ilgityildirim
|
10 |
+
* Version: 2.1.3
|
11 |
* Text Domain: wpstg
|
12 |
* Domain Path: /languages/
|
13 |
|