WP Staging – DB & File Duplicator & Migration - Version 2.2.1

Version Description

  • New: Option to set Custom Login Link if there is one
  • New: Set meta noindex for staging site to make it non indexable for search engines
  • New: Better multiple folder selection. Allows to unselect a parent folder without collapsing all child folders
  • New: Sorted list of folders to copy
  • Fix: Can not login to staging site if plugin All In One WP Security & Firewall is used
  • Fix: Staging site not reachable because permalinks are not disabled under certain conditions
Download this release

Release Info

Developer ReneHermi
Plugin Icon 128x128 WP Staging – DB & File Duplicator & Migration
Version 2.2.1
Comparing to
See all releases

Code changes from version 2.1.9 to 2.2.1

apps/Backend/Administrator.php CHANGED
@@ -173,7 +173,7 @@ class Administrator extends InjectionAware {
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
@@ -214,6 +214,7 @@ class Administrator extends InjectionAware {
214
  // Forms
215
  ->set( "forms", new FormSettings( $tabs ) );
216
 
 
217
  require_once "{$this->path}views/settings/index.php";
218
  }
219
 
@@ -394,6 +395,7 @@ class Administrator extends InjectionAware {
394
  public function ajaxScan() {
395
  check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
396
 
 
397
  // Scan
398
  $scan = new Scan();
399
  $scan->start();
@@ -430,25 +432,6 @@ class Administrator extends InjectionAware {
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
  */
@@ -465,7 +448,6 @@ class Administrator extends InjectionAware {
465
 
466
  wp_die();
467
 
468
- //wp_send_json( $cloning->start() );
469
  }
470
  /**
471
  * Ajax Start Clone (Basically just layout and saving data)
@@ -668,7 +650,7 @@ class Administrator extends InjectionAware {
668
  }
669
 
670
  /**
671
- * Ajax Start Pushing. Needs wp quads pro)
672
  */
673
  public function ajaxPushProcessing() {
674
  check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
173
 
174
  // Page: Clone
175
  add_submenu_page(
176
+ "wpstg_clone", __( "WP Staging Jobs", "wpstg" ), __( "Sites / Start", "wpstg" ), "manage_options", "wpstg_clone", array($this, "getClonePage")
177
  );
178
 
179
  // Page: Settings
214
  // Forms
215
  ->set( "forms", new FormSettings( $tabs ) );
216
 
217
+
218
  require_once "{$this->path}views/settings/index.php";
219
  }
220
 
395
  public function ajaxScan() {
396
  check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
397
 
398
+
399
  // Scan
400
  $scan = new Scan();
401
  $scan->start();
432
  echo wp_send_json( array("status" => "success") );
433
  }
434
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
435
  /**
436
  * Ajax Start Updating Clone (Basically just layout and saving data)
437
  */
448
 
449
  wp_die();
450
 
 
451
  }
452
  /**
453
  * Ajax Start Clone (Basically just layout and saving data)
650
  }
651
 
652
  /**
653
+ * Ajax Start Pushing. Needs wp quads pro
654
  */
655
  public function ajaxPushProcessing() {
656
  check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
apps/Backend/Modules/Jobs/Data.php CHANGED
@@ -49,7 +49,7 @@ class Data extends JobExecutable
49
  */
50
  protected function calculateTotalSteps()
51
  {
52
- $this->options->totalSteps = 6;
53
  }
54
 
55
  /**
@@ -363,12 +363,7 @@ class Data extends JobExecutable
363
  */
364
  protected function step6()
365
  {
366
- // No settings, all good
367
- // if (!isset($this->settings->wpSubDirectory) || "1" !== $this->settings->wpSubDirectory)
368
- // {
369
- // $this->log("Search & Replace: WP installation is not in a subdirectory! All good, skipping this step");
370
- // return true;
371
- // }
372
  if (!$this->isSubDir())
373
  {
374
  $this->debugLog("Search & Replace: WP installation is not in a subdirectory! All good, skipping this step");
@@ -413,7 +408,6 @@ class Data extends JobExecutable
413
  return false;
414
  }
415
  $this->Log("Search & Replace: Finished Step 6 successfully");
416
-
417
  return true;
418
  }
419
 
@@ -440,6 +434,7 @@ class Data extends JobExecutable
440
  // All good
441
  if ($result)
442
  {
 
443
  return true;
444
  }
445
 
@@ -447,6 +442,67 @@ class Data extends JobExecutable
447
  return true;
448
  }
449
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
450
  /**
451
  * Check if WP is installed in subdir
452
  * @return boolean
49
  */
50
  protected function calculateTotalSteps()
51
  {
52
+ $this->options->totalSteps = 8;
53
  }
54
 
55
  /**
363
  */
364
  protected function step6()
365
  {
366
+
 
 
 
 
 
367
  if (!$this->isSubDir())
368
  {
369
  $this->debugLog("Search & Replace: WP installation is not in a subdirectory! All good, skipping this step");
408
  return false;
409
  }
410
  $this->Log("Search & Replace: Finished Step 6 successfully");
 
411
  return true;
412
  }
413
 
434
  // All good
435
  if ($result)
436
  {
437
+ $this->Log("Search & Replace: Finished Step 7 successfully");
438
  return true;
439
  }
440
 
442
  return true;
443
  }
444
 
445
+ /**
446
+ * Update permalink_structure
447
+ * @return bool
448
+ */
449
+ protected function step8()
450
+ {
451
+
452
+ $this->log("Search & Replace: Updating permalink_structure in {$this->prefix}options {$this->db->last_error}");
453
+
454
+ if( false === $this->isTable( $this->prefix . 'options' ) ) {
455
+ return true;
456
+ }
457
+
458
+ $result = $this->db->query(
459
+ $this->db->prepare(
460
+ "UPDATE {$this->prefix}options SET option_value = %s WHERE option_name = 'permalink_structure'",
461
+ ' '
462
+ )
463
+ );
464
+
465
+ // All good
466
+ if ($result)
467
+ {
468
+ $this->Log("Search & Replace: Finished Step 8 successfully");
469
+ return true;
470
+ }
471
+
472
+ $this->log("Failed to update permalink_structure in {$this->prefix}options {$this->db->last_error}", Logger::TYPE_ERROR);
473
+ return true;
474
+ }
475
+ /**
476
+ * Update blog_public option to not allow staging site to be indexed by search engines
477
+ * @return bool
478
+ */
479
+ protected function step9()
480
+ {
481
+
482
+ $this->log("Search & Replace: Updating blog_public in {$this->prefix}options {$this->db->last_error}");
483
+
484
+ if( false === $this->isTable( $this->prefix . 'options' ) ) {
485
+ return true;
486
+ }
487
+
488
+ $result = $this->db->query(
489
+ $this->db->prepare(
490
+ "UPDATE {$this->prefix}options SET option_value = %s WHERE option_name = 'blog_public'",
491
+ '0'
492
+ )
493
+ );
494
+
495
+ // All good
496
+ if ($result)
497
+ {
498
+ $this->Log("Search & Replace: Finished Step 9 successfully");
499
+ return true;
500
+ }
501
+
502
+ $this->log("Failed to update blog_public in {$this->prefix}options {$this->db->last_error}", Logger::TYPE_ERROR);
503
+ return true;
504
+ }
505
+
506
  /**
507
  * Check if WP is installed in subdir
508
  * @return boolean
apps/Backend/Modules/Jobs/Files.php CHANGED
@@ -127,7 +127,7 @@ class Files extends JobExecutable {
127
 
128
 
129
  $file = $this->file->fgets();
130
- $this->debugLog('copy file ' . $file, Logger::TYPE_DEBUG);
131
  $this->copyFile($file);
132
  }
133
 
127
 
128
 
129
  $file = $this->file->fgets();
130
+ //$this->debugLog('copy file ' . $file, Logger::TYPE_DEBUG);
131
  $this->copyFile($file);
132
  }
133
 
apps/Backend/Modules/Jobs/Scan.php CHANGED
@@ -131,6 +131,9 @@ class Scan extends Job
131
  $directories = $this->directories;
132
  }
133
 
 
 
 
134
  $output = '';
135
  foreach ($directories as $name => $directory)
136
  {
131
  $directories = $this->directories;
132
  }
133
 
134
+ // Sort results
135
+ uksort($directories, 'strcasecmp');
136
+
137
  $output = '';
138
  foreach ($directories as $name => $directory)
139
  {
apps/Backend/Modules/Views/Forms/Settings.php CHANGED
@@ -1,10 +1,12 @@
1
  <?php
 
2
  namespace WPStaging\Backend\Modules\Views\Forms;
3
 
4
  use WPStaging\Forms\Elements\Check;
5
  use WPStaging\Forms\Elements\Numerical;
6
  use WPStaging\Forms\Elements\Select;
7
  use WPStaging\Forms\Elements\SelectMultiple;
 
8
  use WPStaging\Forms\Form;
9
  use WPStaging\Backend\Modules\Views\Tabs\Tabs;
10
 
@@ -12,209 +14,196 @@ use WPStaging\Backend\Modules\Views\Tabs\Tabs;
12
  * Class Settings
13
  * @package WPStaging\Backend\Modules\Views\Forms
14
  */
15
- class Settings
16
- {
17
-
18
- /**
19
- * @var array
20
- */
21
- private $form = array();
22
-
23
- /**
24
- * @var Tabs
25
- */
26
- private $tabs;
27
-
28
- /**
29
- * Settings constructor.
30
- * @param Tabs $tabs
31
- */
32
- public function __construct($tabs)
33
- {
34
- $this->tabs = $tabs;
35
-
36
- foreach ($this->tabs->get() as $id => $name)
37
- {
38
- if (!method_exists($this, $id))
39
- {
40
- continue;
41
- }
42
-
43
- $this->{$id}();
44
- }
45
- }
46
-
47
- private function general()
48
- {
49
- $this->form["general"] = new Form();
50
-
51
- $settings = json_decode(json_encode(get_option("wpstg_settings", array())));
52
-
53
- // DB Copy Query Limit
54
- $element = new Numerical(
55
- "wpstg_settings[queryLimit]",
56
- array(
57
- "class" => "medium-text",
58
- "step" => 1,
59
- "max" => 999999,
60
- "min" => 0
61
- )
62
- );
63
-
64
- $this->form["general"]->add(
65
- $element->setLabel("DB Copy Query Limit")
66
- ->setDefault(isset($settings->queryLimit) ? $settings->queryLimit : 5000)
67
- );
68
-
69
- $options = array('1' => '1', '250' => '250' ,'500' => '500', '1000' => '1000');
70
- // DB Copy Query Limit
71
- $element = new Select(
72
- "wpstg_settings[fileLimit]",
73
- $options,
74
- array(
75
- "class" => "medium-text",
76
- "step" => 1,
77
- "max" => 999999,
78
- "min" => 0
79
- )
80
- );
81
-
82
- $this->form["general"]->add(
83
- $element->setLabel("File Copy Limit")->setDefault(isset($settings->fileLimit) ? $settings->fileLimit : 250)
84
- );
85
-
86
-
87
- // File Copy Batch Size
88
- $element = new Numerical(
89
- "wpstg_settings[batchSize]",
90
- array(
91
- "class" => "medium-text",
92
- "step" => 1,
93
- "max" => 999999,
94
- "min" => 0
95
- )
96
- );
97
-
98
- $this->form["general"]->add(
99
- $element->setLabel("File Copy Batch Size")
100
- ->setDefault(isset($settings->batchSize) ? $settings->batchSize : 2)
101
- );
102
-
103
- // CPU load priority
104
- $element = new Select(
105
- "wpstg_settings[cpuLoad]",
106
- array(
107
- "high" => "High (fast)",
108
- "medium" => "Medium (average)",
109
- "low" => "Low (slow)"
110
- )
111
- );
112
-
113
- $this->form["general"]->add(
114
- $element->setLabel("CPU load priority")
115
- ->setDefault(isset($settings->cpuLoad) ? $settings->cpuLoad : "fast")
116
- );
117
-
118
-
119
- // Optimizer
120
- $element = new Check(
121
- "wpstg_settings[optimizer]",
122
- array('1' => "Select the plugins you wish to disable during clone process")
123
- );
124
-
125
- $this->form["general"]->add(
126
- $element->setLabel("Optimizer")
127
- ->setDefault((isset($settings->optimizer)) ? $settings->optimizer : null)
128
- );
129
-
130
- // Plugins
131
- $plugins = array();
132
-
133
- foreach (get_plugins() as $key => $data)
134
- {
135
- if ("wp-staging/wp-staging.php" === $key)
136
- {
137
- continue;
138
- }
139
-
140
- $plugins[$key] = $data["Name"];
141
- }
142
-
143
- $element = new Select(
144
- "wpstg_settings[blackListedPlugins][]",
145
- $plugins,
146
- array(
147
- "multiple" => "multiple",
148
- "style" => "min-height:400px;"
149
- )
150
- );
151
-
152
- $this->form["general"]->add(
153
- $element->setDefault((isset($settings->blackListedPlugins)) ? $settings->blackListedPlugins : null)
154
- );
155
-
156
- // Disable admin authorization
157
- $element = new Check(
158
- "wpstg_settings[disableAdminLogin]",
159
- array('1' => '')
160
- );
161
-
162
- $this->form["general"]->add(
163
- $element->setLabel("Disable admin authorization")
164
- ->setDefault((isset($settings->disableAdminLogin)) ? $settings->disableAdminLogin : null)
165
- );
166
-
167
- // WordPress in subdirectory
168
- $element = new Check(
169
- "wpstg_settings[wpSubDirectory]",
170
- array('1' => '')
171
- );
172
-
173
- $this->form["general"]->add(
174
- $element->setLabel("Wordpress in subdirectory")
175
- ->setDefault((isset($settings->wpSubDirectory)) ? $settings->wpSubDirectory : null)
176
- );
177
-
178
- // Debug Mode
179
- $element = new Check(
180
- "wpstg_settings[debugMode]",
181
- array('1' => '')
182
- );
183
-
184
- $this->form["general"]->add(
185
- $element->setLabel("Debug Mode")
186
- ->setDefault((isset($settings->debugMode)) ? $settings->debugMode : null)
187
- );
188
-
189
- // Remove Data on Uninstall?
190
- $element = new Check(
191
- "wpstg_settings[unInstallOnDelete]",
192
- array('1' => '')
193
- );
194
-
195
- $this->form["general"]->add(
196
- $element->setLabel("Remove Data on Uninstall?")
197
- ->setDefault((isset($settings->unInstallOnDelete)) ? $settings->unInstallOnDelete : null)
198
- );
199
-
200
- // Check Directory Sizes
201
- $element = new Check(
202
- "wpstg_settings[checkDirectorySize]",
203
- array('1' => '')
204
- );
205
-
206
- $this->form["general"]->add(
207
- $element->setLabel("Check Directory Size")
208
- ->setDefault((isset($settings->checkDirectorySize)) ? $settings->checkDirectorySize : null)
209
- );
210
- }
211
-
212
- /**
213
- * @param string $name
214
- * @return array|Form
215
- */
216
- public function get($name = null)
217
- {
218
- return (null === $name) ? $this->form : $this->form[$name];
219
- }
220
- }
1
  <?php
2
+
3
  namespace WPStaging\Backend\Modules\Views\Forms;
4
 
5
  use WPStaging\Forms\Elements\Check;
6
  use WPStaging\Forms\Elements\Numerical;
7
  use WPStaging\Forms\Elements\Select;
8
  use WPStaging\Forms\Elements\SelectMultiple;
9
+ use WPStaging\Forms\Elements\Text;
10
  use WPStaging\Forms\Form;
11
  use WPStaging\Backend\Modules\Views\Tabs\Tabs;
12
 
14
  * Class Settings
15
  * @package WPStaging\Backend\Modules\Views\Forms
16
  */
17
+ class Settings {
18
+
19
+ /**
20
+ * @var array
21
+ */
22
+ private $form = array();
23
+
24
+ /**
25
+ * @var Tabs
26
+ */
27
+ private $tabs;
28
+
29
+ /**
30
+ * Settings constructor.
31
+ * @param Tabs $tabs
32
+ */
33
+ public function __construct( $tabs ) {
34
+ $this->tabs = $tabs;
35
+
36
+ foreach ( $this->tabs->get() as $id => $name ) {
37
+ if( !method_exists( $this, $id ) ) {
38
+ continue;
39
+ }
40
+
41
+ $this->{$id}();
42
+ }
43
+ }
44
+
45
+ private function general() {
46
+ $this->form["general"] = new Form();
47
+
48
+ $settings = json_decode( json_encode( get_option( "wpstg_settings", array() ) ) );
49
+
50
+ // DB Copy Query Limit
51
+ $element = new Numerical(
52
+ "wpstg_settings[queryLimit]", array(
53
+ "class" => "medium-text",
54
+ "step" => 1,
55
+ "max" => 999999,
56
+ "min" => 0
57
+ )
58
+ );
59
+
60
+ $this->form["general"]->add(
61
+ $element->setLabel( "DB Copy Query Limit" )
62
+ ->setDefault( isset( $settings->queryLimit ) ? $settings->queryLimit : 5000 )
63
+ );
64
+
65
+ $options = array('1' => '1', '10' => '10', '50' => '50', '250' => '250', '500' => '500', '1000' => '1000');
66
+ // DB Copy Query Limit
67
+ $element = new Select(
68
+ "wpstg_settings[fileLimit]", $options, array(
69
+ "class" => "medium-text",
70
+ "step" => 1,
71
+ "max" => 999999,
72
+ "min" => 0
73
+ )
74
+ );
75
+
76
+ $this->form["general"]->add(
77
+ $element->setLabel( "File Copy Limit" )
78
+ ->setDefault( isset( $settings->fileLimit ) ? $settings->fileLimit : 1 )
79
+ );
80
+
81
+
82
+ // File Copy Batch Size
83
+ $element = new Numerical(
84
+ "wpstg_settings[batchSize]", array(
85
+ "class" => "medium-text",
86
+ "step" => 1,
87
+ "max" => 999999,
88
+ "min" => 0
89
+ )
90
+ );
91
+
92
+ $this->form["general"]->add(
93
+ $element->setLabel( "File Copy Batch Size" )
94
+ ->setDefault( isset( $settings->batchSize ) ? $settings->batchSize : 2 )
95
+ );
96
+
97
+ // CPU load priority
98
+ $element = new Select(
99
+ "wpstg_settings[cpuLoad]", array(
100
+ "high" => "High (fast)",
101
+ "medium" => "Medium (average)",
102
+ "low" => "Low (slow)"
103
+ )
104
+ );
105
+
106
+ $this->form["general"]->add(
107
+ $element->setLabel( "CPU load priority" )
108
+ ->setDefault( isset( $settings->cpuLoad ) ? $settings->cpuLoad : "fast" )
109
+ );
110
+
111
+
112
+ // Optimizer
113
+ $element = new Check(
114
+ "wpstg_settings[optimizer]", array('1' => "")
115
+ );
116
+
117
+ $this->form["general"]->add(
118
+ $element->setLabel( "Optimizer" )
119
+ ->setDefault( (isset( $settings->optimizer )) ? $settings->optimizer : null )
120
+ );
121
+
122
+ // Plugins
123
+ $plugins = array();
124
+
125
+ foreach ( get_plugins() as $key => $data ) {
126
+ if( "wp-staging/wp-staging.php" === $key ) {
127
+ continue;
128
+ }
129
+
130
+ $plugins[$key] = $data["Name"];
131
+ }
132
+
133
+ $element = new Select(
134
+ "wpstg_settings[blackListedPlugins][]", $plugins, array(
135
+ "multiple" => "multiple",
136
+ "style" => "min-height:400px;"
137
+ )
138
+ );
139
+
140
+ $this->form["general"]->add(
141
+ $element->setDefault( (isset( $settings->blackListedPlugins )) ? $settings->blackListedPlugins : null )
142
+ );
143
+
144
+ // Disable admin authorization
145
+ $element = new Check(
146
+ "wpstg_settings[disableAdminLogin]", array('1' => '')
147
+ );
148
+
149
+ $this->form["general"]->add(
150
+ $element->setLabel( "Disable admin authorization" )
151
+ ->setDefault( (isset( $settings->disableAdminLogin )) ? $settings->disableAdminLogin : null )
152
+ );
153
+
154
+ // WordPress in subdirectory
155
+ $element = new Check(
156
+ "wpstg_settings[wpSubDirectory]", array('1' => '')
157
+ );
158
+
159
+ $this->form["general"]->add(
160
+ $element->setLabel( "Wordpress in subdirectory" )
161
+ ->setDefault( (isset( $settings->wpSubDirectory )) ? $settings->wpSubDirectory : null )
162
+ );
163
+
164
+ // Debug Mode
165
+ $element = new Check(
166
+ "wpstg_settings[debugMode]", array('1' => '')
167
+ );
168
+
169
+ $this->form["general"]->add(
170
+ $element->setLabel( "Debug Mode" )
171
+ ->setDefault( (isset( $settings->debugMode )) ? $settings->debugMode : null )
172
+ );
173
+
174
+ // Remove Data on Uninstall?
175
+ $element = new Check(
176
+ "wpstg_settings[unInstallOnDelete]", array('1' => '')
177
+ );
178
+
179
+ $this->form["general"]->add(
180
+ $element->setLabel( "Remove Data on Uninstall?" )
181
+ ->setDefault( (isset( $settings->unInstallOnDelete )) ? $settings->unInstallOnDelete : null )
182
+ );
183
+
184
+ // Check Directory Sizes
185
+ $element = new Check(
186
+ "wpstg_settings[checkDirectorySize]", array('1' => '')
187
+ );
188
+
189
+ $this->form["general"]->add(
190
+ $element->setLabel( "Check Directory Size" )
191
+ ->setDefault( (isset( $settings->checkDirectorySize )) ? $settings->checkDirectorySize : null )
192
+ );
193
+
194
+ // Set login post id
195
+ $element = new Text( 'wpstg_settings[loginSlug]', array() );
196
+ $this->form["general"]->add(
197
+ $element->setLabel( "Login Custom Link" )->setDefault( isset( $settings->loginSlug ) ? $settings->loginSlug : '' )
198
+ );
199
+ }
200
+
201
+ /**
202
+ * @param string $name
203
+ * @return array|Form
204
+ */
205
+ public function get( $name = null ) {
206
+ return (null === $name) ? $this->form : $this->form[$name];
207
+ }
208
+
209
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
apps/Backend/Upgrade/Upgrade.php CHANGED
@@ -5,6 +5,7 @@ namespace WPStaging\Backend\Upgrade;
5
  use WPStaging\WPStaging;
6
  use WPStaging\Utils\Logger;
7
 
 
8
  /**
9
  * Upgrade Class
10
  * This must be loaded on every page init to ensure all settings are
@@ -34,7 +35,7 @@ class Upgrade {
34
  * Clone data
35
  * @var obj
36
  */
37
- private $clonesBeta;
38
 
39
  /**
40
  * Cron data
@@ -47,31 +48,107 @@ class Upgrade {
47
  * @var obj
48
  */
49
  private $logger;
 
 
 
 
 
 
 
50
 
51
  public function __construct() {
52
-
53
  // add wpstg_weekly_event to cron events
54
  $this->cron = new \WPStaging\Cron\Cron;
55
-
56
  // Previous version
57
- $this->previousVersion = preg_replace( '/[^0-9.].*/', '', get_option( 'wpstg_version' ) );
58
 
59
  // Options earlier than version 2.0.0
60
- $this->clones = get_option( "wpstg_existing_clones", array() );
61
-
62
- // Current options
63
- $this->clonesBeta = get_option( "wpstg_existing_clones_beta", array() );
64
-
65
  // Logger
66
- $this->logger = new Logger;
67
- }
 
 
 
68
 
69
- public function doUpgrade() {
70
  $this->upgrade2_0_3();
71
- //$this->upgrade2_0_4();
72
  $this->upgrade2_1_2();
 
73
  $this->setVersion();
74
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
  /**
77
  * Upgrade method 2.0.3
@@ -137,8 +214,8 @@ class Upgrade {
137
  */
138
  private function upgradeClonesBeta() {
139
 
140
- // Copy old data to new option
141
- //update_option( 'wpstg_existing_clones_beta', $this->clones );
142
 
143
  $new = array();
144
 
@@ -159,6 +236,8 @@ class Upgrade {
159
  $new[$value]['url'] = get_home_url() . "/" . $value;
160
  $new[$value]['number'] = $key + 1;
161
  $new[$value]['version'] = $this->previousVersion;
 
 
162
  }
163
  unset( $value );
164
 
@@ -171,32 +250,35 @@ class Upgrade {
171
  * Convert clone data from wpstg 1.x to wpstg 2.x
172
  * Only use this later when wpstg 2.x is ready for production
173
  */
174
- private function upgradeClones() {
175
-
176
- $new = array();
177
-
178
- if( empty( $this->clones ) ) {
179
- return false;
180
- }
181
-
182
- foreach ( $this->clones as $key => &$value ) {
183
-
184
- // Skip the rest of the loop if data is already compatible to wpstg 2.0.1
185
- if( isset( $value['directoryName'] ) || !empty( $value['directoryName'] ) ) {
186
- continue;
187
- }
188
- $new[$value]['directoryName'] = $value;
189
- $new[$value]['path'] = get_home_path() . $value;
190
- $new[$value]['url'] = get_home_url() . "/" . $value;
191
- $new[$value]['number'] = $key + 1;
192
- $new[$value]['version'] = $this->previousVersion;
193
- }
194
- unset( $value );
195
-
196
- if( empty( $new ) || false === update_option( 'wpstg_existing_clones', $new ) ) {
197
- $this->logger->log( 'Failed to upgrade clone data from ' . $this->previousVersion . ' to ' . \WPStaging\WPStaging::VERSION );
198
- }
199
- }
 
 
 
200
 
201
  /**
202
  * Upgrade Notices db options from wpstg 1.3 -> 2.0.1
@@ -217,5 +299,18 @@ class Upgrade {
217
  update_option( 'wpstg_rating', 'no' );
218
  }
219
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
220
 
221
  }
5
  use WPStaging\WPStaging;
6
  use WPStaging\Utils\Logger;
7
 
8
+
9
  /**
10
  * Upgrade Class
11
  * This must be loaded on every page init to ensure all settings are
35
  * Clone data
36
  * @var obj
37
  */
38
+ //private $clonesBeta;
39
 
40
  /**
41
  * Cron data
48
  * @var obj
49
  */
50
  private $logger;
51
+
52
+ /**
53
+ * db object
54
+ * @var obj
55
+ */
56
+ private $db;
57
+
58
 
59
  public function __construct() {
60
+
61
  // add wpstg_weekly_event to cron events
62
  $this->cron = new \WPStaging\Cron\Cron;
63
+
64
  // Previous version
65
+ $this->previousVersion = preg_replace( '/[^0-9.].*/', '', get_option( 'wpstg_version' ) );
66
 
67
  // Options earlier than version 2.0.0
68
+ //$this->clones = get_option( "wpstg_existing_clones", array() );
69
+
 
 
 
70
  // Logger
71
+ $this->logger = new Logger;
72
+
73
+ // db
74
+ $this->db = WPStaging::getInstance()->get( "wpdb" );
75
+ }
76
 
77
+ public function doUpgrade() {
78
  $this->upgrade2_0_3();
 
79
  $this->upgrade2_1_2();
80
+ $this->upgrade2_2_0();
81
  $this->setVersion();
82
  }
83
+
84
+ /**
85
+ * Upgrade method 2.2.0
86
+ */
87
+ public function upgrade2_2_0(){
88
+ // Previous version lower than 2.2.0
89
+ if( version_compare( $this->previousVersion, '2.2.0', '<' ) ) {
90
+ $this->upgradeElements();
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Add missing elements
96
+ */
97
+ private function upgradeElements() {
98
+ // Current options
99
+ $sites = get_option( "wpstg_existing_clones_beta", array() );
100
+
101
+ if (false === $sites){
102
+ return;
103
+ }
104
+
105
+ // Check if key prefix is missing and add it
106
+ foreach ( $sites as $key => $value ) {
107
+ if (empty( $sites[$key]['directoryName'] )){
108
+ continue;
109
+ }
110
+ //!empty( $sites[$key]['prefix'] ) ? $sites[$key]['prefix'] = $value['prefix'] : $sites[$key]['prefix'] = $key . '_';
111
+ !empty( $sites[$key]['prefix'] ) ?
112
+ $sites[$key]['prefix'] = $value['prefix'] :
113
+ $sites[$key]['prefix'] = $this->getStagingPrefix( $sites[$key]['directoryName'] );
114
+ }
115
+
116
+ if( !empty($sites) ) {
117
+ update_option( 'wpstg_existing_clones_beta', $sites );
118
+ }
119
+ }
120
+
121
+
122
+
123
+ /**
124
+ * Check and return prefix of the staging site
125
+ * @param string $directory
126
+ * @return string
127
+ */
128
+ private function getStagingPrefix( $directory ) {
129
+ // Try to get staging prefix from wp-config.php of staging site
130
+
131
+ $path = ABSPATH . $directory . "/wp-config.php";
132
+ if( false === ($content = @file_get_contents( $path )) ) {
133
+ $prefix = "";
134
+ } else {
135
+ // Get prefix from wp-config.php
136
+ preg_match( "/table_prefix\s*=\s*'(\w*)';/", $content, $matches );
137
+
138
+ if( !empty( $matches[1] ) ) {
139
+ $prefix = $matches[1];
140
+ } else {
141
+ $prefix = "";
142
+ }
143
+ }
144
+ // return result: Check if staging prefix is the same as the live prefix
145
+ if( $this->db->prefix != $prefix ) {
146
+ return $prefix;
147
+ } else {
148
+ return "";
149
+ }
150
+ }
151
+
152
 
153
  /**
154
  * Upgrade method 2.0.3
214
  */
215
  private function upgradeClonesBeta() {
216
 
217
+ // Get options
218
+ $this->clones = get_option( "wpstg_existing_clones", array() );
219
 
220
  $new = array();
221
 
236
  $new[$value]['url'] = get_home_url() . "/" . $value;
237
  $new[$value]['number'] = $key + 1;
238
  $new[$value]['version'] = $this->previousVersion;
239
+ //$new[$value]['prefix'] = $value . '_';
240
+
241
  }
242
  unset( $value );
243
 
250
  * Convert clone data from wpstg 1.x to wpstg 2.x
251
  * Only use this later when wpstg 2.x is ready for production
252
  */
253
+ // private function upgradeClones() {
254
+ //
255
+ // $new = array();
256
+ //
257
+ // // Get options
258
+ // $this->clones = get_option( "wpstg_existing_clones", array() );
259
+ //
260
+ // if( empty( $this->clones ) ) {
261
+ // return false;
262
+ // }
263
+ //
264
+ // foreach ( $this->clones as $key => &$value ) {
265
+ //
266
+ // // Skip the rest of the loop if data is already compatible to wpstg 2.0.1
267
+ // if( isset( $value['directoryName'] ) || !empty( $value['directoryName'] ) ) {
268
+ // continue;
269
+ // }
270
+ // $new[$value]['directoryName'] = $value;
271
+ // $new[$value]['path'] = get_home_path() . $value;
272
+ // $new[$value]['url'] = get_home_url() . "/" . $value;
273
+ // $new[$value]['number'] = $key + 1;
274
+ // $new[$value]['version'] = $this->previousVersion;
275
+ // }
276
+ // unset( $value );
277
+ //
278
+ // if( empty( $new ) || false === update_option( 'wpstg_existing_clones', $new ) ) {
279
+ // $this->logger->log( 'Failed to upgrade clone data from ' . $this->previousVersion . ' to ' . \WPStaging\WPStaging::VERSION );
280
+ // }
281
+ // }
282
 
283
  /**
284
  * Upgrade Notices db options from wpstg 1.3 -> 2.0.1
299
  update_option( 'wpstg_rating', 'no' );
300
  }
301
  }
302
+
303
+ /**
304
+ * Throw a errror message via json and stop further execution
305
+ * @param string $message
306
+ */
307
+ private function returnException($message = ''){
308
+ wp_die( json_encode(array(
309
+ 'job' => isset($this->options->currentJob) ? $this->options->currentJob : '',
310
+ 'status' => false,
311
+ 'message' => $message,
312
+ 'error' => true
313
+ )));
314
+ }
315
 
316
  }
apps/Backend/public/js/wpstg-admin.js CHANGED
@@ -93,7 +93,6 @@ var WPStaging = (function ($)
93
  }
94
  })
95
  .on("click", ".wpstg-button-select", function (e) {
96
- console.log('test1');
97
 
98
  e.preventDefault();
99
 
@@ -117,8 +116,8 @@ var WPStaging = (function ($)
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)
@@ -132,7 +131,25 @@ var WPStaging = (function ($)
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
93
  }
94
  })
95
  .on("click", ".wpstg-button-select", function (e) {
 
96
 
97
  e.preventDefault();
98
 
116
  $this.siblings(".wpstg-subdir").slideToggle();
117
  }
118
  })
119
+ // When a directory checkbox is Selected
120
+ .on("change", "input.wpstg-check-dir", function () {
121
  var $directory = $(this).parent(".wpstg-dir");
122
 
123
  if (this.checked)
131
  $directory.find(".wpstg-dir .wpstg-check-dir").prop("checked", false);
132
  $directory.find(".wpstg-expand-dirs, .wpstg-check-subdirs").addClass("disabled");
133
  $directory.find(".wpstg-check-subdirs").data("action", "check").text("check");
134
+ //$directory.children(".wpstg-subdir").slideUp();
135
+ }
136
+ })
137
+ // When a directory name is Selected
138
+ .on("change", "href.wpstg-check-dir", function () {
139
+ var $directory = $(this).parent(".wpstg-dir");
140
+
141
+ if (this.checked)
142
+ {
143
+ $directory.parents(".wpstg-dir").children(".wpstg-check-dir").prop("checked", true);
144
+ $directory.find(".wpstg-expand-dirs").removeClass("disabled");
145
+ $directory.find(".wpstg-subdir .wpstg-check-dir").prop("checked", true);
146
+ }
147
+ else
148
+ {
149
+ $directory.find(".wpstg-dir .wpstg-check-dir").prop("checked", false);
150
+ $directory.find(".wpstg-expand-dirs, .wpstg-check-subdirs").addClass("disabled");
151
+ $directory.find(".wpstg-check-subdirs").data("action", "check").text("check");
152
+ //$directory.children(".wpstg-subdir").slideUp();
153
  }
154
  })
155
  // Check the max length of the clone name and if the clone name already exists
apps/Backend/views/_includes/messages/rating.php CHANGED
@@ -1,29 +1,31 @@
1
- <div class="wpstg_fivestar updated" style="box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);">
2
- <p>
3
- Awesome, you've been using <strong>WP Staging </strong> for more than 1 week.
4
- May I ask you to give it a <strong>5-star</strong> rating on Wordpress?
5
  <br><br>
6
- P.S. Looking for a way to copy plugins and theme files from staging to live site? Try out <a href="https://wp-staging.com" target="_blank">WP Staging Pro</a> <br>
7
- </p>
8
-
 
 
9
  <p>
10
- <strong>Regards,<br>René Hermenau</strong>
11
  </p>
12
 
13
  <ul>
14
  <li>
15
- <a href="https://wordpress.org/support/plugin/wp-staging/reviews/?filter=5#new-post" class="thankyou" target="_new" title="Ok, you deserved it" style="font-weight:bold;">
16
- Ok, you deserved it
17
  </a>
18
  </li>
19
  <li>
20
  <a href="javascript:void(0);" class="wpstg_hide_rating" title="I already did" style="font-weight:bold;">
21
  I already did
 
22
  </a>
23
  </li>
24
  <li>
25
  <a href="javascript:void(0);" class="wpstg_hide_rating" title="No, not good enough" style="font-weight:bold;">
26
- No, not good enough
27
  </a>
28
  </li>
29
  </ul>
1
+ <div class="wpstg_fivestar updated" style="box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);border-left:none;background-color:#59a7f7;color:white;">
2
+ <p><?php _e(' Awesome, you\'ve been using <strong>WP Staging </strong> for more than 1 week.
3
+ May I ask you to give it a <strong>5-star</strong> rating on Wordpress?', 'wpstg'); ?>
 
4
  <br><br>
5
+ <?php echo sprintf(__('P.S. Looking for a way to migrate the staging site database and copy plugins and theme files from staging to live site?<br/>
6
+ Try out <a href="%1$s" target="_blank" style="color:white;font-weight:bold;">WP Staging Pro</a>
7
+ ', 'wpstg'), 'https://wp-staging.com/?utm_source=wpstg_admin&utm_medium=rating_screen&utm_campaign=admin_notice');?>
8
+ <br>
9
+ </p>
10
  <p>
11
+ Cheers,<br>René Hermenau
12
  </p>
13
 
14
  <ul>
15
  <li>
16
+ <a href="https://wordpress.org/support/plugin/wp-staging/reviews/?filter=5#new-post" class="thankyou button" target="_new" title="Ok, you deserved it" style="font-weight:bold;">
17
+ <?php _e('Ok, you deserved it','wpstg')?>
18
  </a>
19
  </li>
20
  <li>
21
  <a href="javascript:void(0);" class="wpstg_hide_rating" title="I already did" style="font-weight:bold;">
22
  I already did
23
+ <?php _e('I already did','wpstg')?>
24
  </a>
25
  </li>
26
  <li>
27
  <a href="javascript:void(0);" class="wpstg_hide_rating" title="No, not good enough" style="font-weight:bold;">
28
+ <?php _e('No, not good enough','wpstg')?>
29
  </a>
30
  </li>
31
  </ul>
apps/Backend/views/clone/ajax/scan.php CHANGED
@@ -95,11 +95,24 @@
95
 
96
  <a href="#" class="wpstg-tab-header" data-id="#wpstg-advanced-settings">
97
  <span class="wpstg-tab-triangle">&#9658;</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>
95
 
96
  <a href="#" class="wpstg-tab-header" data-id="#wpstg-advanced-settings">
97
  <span class="wpstg-tab-triangle">&#9658;</span>
98
+ <?php echo __("Login Options", "wpstg")?>
99
  </a>
100
 
101
  <div class="wpstg-tab-section" id="wpstg-advanced-settings">
102
+ <p>
103
+ <?php
104
+ _e('<strong>Important:</strong> Are you using a custom login url?', 'wpstg');
105
+ echo '<br/>';
106
+ echo sprintf(__('Set up first <a href="%1$s"><strong>Login Custom Link</strong></a> if login to the admin dashboard is not reachable from the default url <pre>%2$s</pre>', 'wpstg'),
107
+ admin_url() . '/admin.php?page=wpstg-settings#wpstg_settings[loginSlug]',
108
+ admin_url()
109
+ );
110
+ _e('<strong>If you do not do that step, the staging site will not be accessable!</strong>', 'wpstg');
111
+ //$form = $this->di->get("forms")->get("general");
112
+ //echo $form->label("wpstg_settings['loginPostId']");
113
+ //echo $form->render("wpstg_settings['loginPostId']");
114
+ ?>
115
+ </p>
116
  </div>
117
 
118
  </div>
apps/Backend/views/clone/ajax/single-overview.php CHANGED
@@ -14,7 +14,8 @@
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?>
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
+ <?php $urlLogin = $data["url"] . "/?";?>
19
 
20
  <a href="<?php echo $urlLogin?>" class="wpstg-clone-title" target="_blank">
21
  <?php //echo $name?>
apps/Backend/views/clone/ajax/start.php CHANGED
@@ -66,23 +66,20 @@
66
  </h3>
67
  <ul>
68
  <li>
69
- <strong>1. Permalinks on your <span style="font-style:italic;">staging site</span> will be disabled for technical reasons! </strong>
70
  <br>
71
- Usually this is no problem for a staging website and you do not need to use permalinks!
72
  <br>
73
  <p>
74
- If you really want permalinks on your staging site you need to do several modifications to your .htaccess (Apache) or *.conf (Nginx).
 
 
 
75
  <br>
76
- WP Staging can not do this modification automatically.
77
  </p>
78
  <p>
79
- <strong>Read more:</strong>
80
- <a href="http://stackoverflow.com/questions/5564881/htaccess-to-rewrite-wordpress-subdirectory-with-permalinks-to-root" target="_blank">
81
- Changes .htaccess
82
- </a> |
83
- <a href="http://robido.com/nginx/nginx-wordpress-subdirectory-configuration-example/" target="_blank">
84
- Changes nginx conf
85
- </a>
86
  </p>
87
  </li>
88
  <li>
@@ -92,7 +89,7 @@
92
  <br>
93
  it´s easy to get confused.
94
  <p>
95
- To assist you we changed the name of the dashboard link to
96
  <strong style="font-style:italic;">
97
  "STAGING - <span class="wpstg-clone-name"><?php echo get_bloginfo("name")?></span>"
98
  </strong>.
66
  </h3>
67
  <ul>
68
  <li>
69
+ <strong>1. Permalinks on your <span style="font-style:italic;">staging site</span> are disabled for technical reasons. </strong>
70
  <br>
71
+ Usually this is absolutely ok for a staging website and you do not need to use permalinks at all.
72
  <br>
73
  <p>
74
+ If your site is executed by the Apache webserver there is a good chance that permalinks are working without less efforts.
75
+ In that case, try to activate the permalinks at <a href="<?php echo admin_url() . 'options-permalink.php'; ?>">settings > permalinks</a>
76
+ <br/>
77
+ If that does not work or you are using Nginx webserver you need to do a few modifications to the .htaccess (Apache) or *.conf (Nginx).
78
  <br>
79
+ WP Staging can not do these modifications automatically.
80
  </p>
81
  <p>
82
+ <strong><a href="https://wp-staging.com/docs/activate-permalinks-staging-site/?utm_source=wpstg_admin&utm_medium=finish_screen&utm_campaign=tutorial" target="_blank">Read here</a> how to activate permalinks.</strong>
 
 
 
 
 
 
83
  </p>
84
  </li>
85
  <li>
89
  <br>
90
  it´s easy to get confused.
91
  <p>
92
+ To assist you we changed the color of the admin bar and the name of the dashboard link to
93
  <strong style="font-style:italic;">
94
  "STAGING - <span class="wpstg-clone-name"><?php echo get_bloginfo("name")?></span>"
95
  </strong>.
apps/Backend/views/settings/index.php CHANGED
@@ -1,59 +1,59 @@
1
  <div class="wpstg_admin">
2
  <span class="wp-staginglogo">
3
- <img src="<?php echo $this->url . "img/logo_clean_small_212_25.png"?>">
4
  </span>
5
 
6
  <span class="wpstg-version">
7
- <?php if (\WPStaging\WPStaging::SLUG === "wp-staging-pro") echo "Pro" ?> Version <?php echo \WPStaging\WPStaging::VERSION ?>
8
  </span>
9
 
10
  <div class="wpstg-header">
11
- <div class='wpstg-share-button-container'>
12
- <div class='wpstg-share-button wpstg-share-button-twitter' data-share-url="https://wordpress.org/plugins/wp-staging">
13
- <div clas='box'>
14
- <a href="https://twitter.com/intent/tweet?button_hashtag=wpstaging&text=Check%20out%20this%20plugin%20for%20creating%20a%20one%20click%20WordPress%20testing%20site&via=wpstg" target='_blank'>
15
- <span class='wpstg-share'><?php echo __('Tweet #wpstaging','wpstg'); ?></span>
16
- </a>
 
17
  </div>
18
- </div>
19
- <div class="wpstg-share-button wpstg-share-button-twitter">
20
- <div class="box">
21
- <a href="https://twitter.com/intent/follow?original_referer=http%3A%2F%2Fsrc.wordpress-develop.dev%2Fwp-admin%2Fadmin.php%3Fpage%3Dwpstg-settings&ref_src=twsrc%5Etfw&region=follow_link&screen_name=renehermenau&tw_p=followbutton" target="_blank">
22
- <span class='wpstg-share'><?php echo __('Follow @wpstaging','wpstg'); ?></span>
23
- </a>
24
  </div>
25
- </div>
26
- <div class="wpstg-share-button wpstg-share-button-facebook" data-share-url="https://wordpress.org/plugins/wp-staging">
27
- <div class="box">
28
- <a href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fwordpress.org%2Fplugins%2Fwp-staging" target="_blank">
29
- <span class='wpstg-share'><?php echo __('Share on Facebook','wpstg'); ?></span>
30
- </a>
31
  </div>
32
  </div>
33
  </div>
34
- </div>
35
 
36
  <ul class="nav-tab-wrapper">
37
  <?php
38
- $tabs = $this->di->get("tabs")->get();
39
- $activeTab = (isset($_GET["tab"]) && array_key_exists($_GET["tab"], $tabs)) ? $_GET["tab"] : "general";
40
 
41
  # Loop through tabs
42
- foreach ($tabs as $id => $name):
43
- $url = esc_url(add_query_arg(array(
44
- "settings-updated" => false,
45
- "tab" => $id
46
- )));
47
 
48
- $activeClass = ($activeTab === $id) ? " nav-tab-active" : '';
49
- ?>
50
- <li>
51
- <a href="<?php echo $url?>" title="<?php echo esc_attr($name)?>" class="nav-tab<?php echo $activeClass?>">
52
- <?php echo esc_html($name)?>
53
- </a>
54
- </li>
55
- <?php
56
- unset($url, $activeClass);
57
  endforeach;
58
  ?>
59
  </ul>
@@ -63,223 +63,247 @@
63
  <div class="panel-container">
64
  <form method="post" action="options.php">
65
  <?php
66
- settings_fields("wpstg_settings");
67
 
68
- foreach ($tabs as $id => $name):
69
- $form = $this->di->get("forms")->get($id);
70
 
71
- if (null === $form)
72
- {
73
- continue;
74
- }
75
- ?>
76
- <div id="<?php echo $id?>__wpstg_header">
77
- <table class="form-table">
78
- <thead>
79
- <tr class="row">
80
- <th class="row th" colspan="2">
81
- <div class="col-title">
82
- <strong><?php echo $name?></strong>
83
- <span class="description"></span>
84
- </div>
85
- </th>
86
- </tr>
87
- </thead>
88
 
89
- <tbody>
90
- <tr class="row">
91
- <td class="row th">
92
- <div class="col-title">
93
- <?php
94
- echo $form->label("wpstg_settings[queryLimit]")
95
- ?>
96
- <span class="description">
97
- Number of DB rows, that will be copied within one ajax request.
98
- The higher the value the faster the database copy process.
99
- To find out the highest possible values try a high value like 1.000 or more. If you get timeout issues, lower it
100
- until you get no more errors during copying process.
101
- <br>
102
- <strong> Default: 5000 </strong>
103
- </span>
104
- </div>
105
- </td>
106
- <td>
107
- <?php echo $form->render("wpstg_settings[queryLimit]")?>
108
- </td>
109
- </tr>
110
 
111
- <tr class="row">
112
- <td class="row th">
113
- <div class="col-title">
114
- <?php
115
- echo $form->label("wpstg_settings[fileLimit]")
116
- ?>
117
- <span class="description">
118
- Number of files to copy that will be copied within one ajax request.
119
- The higher the value the faster the file copy process.
120
- To find out the highest possible values try a high value like 500 or more. If you get timeout issues, lower it
121
- until you get no more errors during copying process.
122
- <br>
123
- <strong> Default: 500 </strong>
124
- </span>
125
- </div>
126
- </td>
127
- <td>
128
- <?php echo $form->render("wpstg_settings[fileLimit]")?>
129
- </td>
130
- </tr>
131
 
132
- <tr class="row">
133
- <td class="row th">
134
- <div class="col-title">
135
- <?php echo $form->label("wpstg_settings[batchSize]")?>
136
- <span class="description">
137
- Buffer size for the file copy process in megabyte.
138
- The higher the value the faster large files will be copied.
139
- To find out the highest possible values try a high one and lower it until
140
- you get no errors during file copy process. Usually this value correlates directly
141
- with the memory consumption of php so make sure that
142
- it does not exceed any php.ini max_memory limits.
143
- <br>
144
- <strong>Default:</strong> 2
145
- </span>
146
- </div>
147
- </td>
148
- <td>
149
- <?php echo $form->render("wpstg_settings[batchSize]")?>
150
- </td>
151
- </tr>
152
 
153
- <tr class="row">
154
- <td class="row th">
155
- <div class="col-title">
156
- <?php echo $form->label("wpstg_settings[cpuLoad]")?>
157
- <span class="description">
158
- Using high will result in fast as possible processing but the cpu load
159
- increases and it's also possible that staging process gets interrupted because of too many ajax requests
160
- (e.g. <strong>authorization error</strong>).
161
- Using a lower value results in lower cpu load on your server but also slower staging site creation.
162
- <br>
163
- <strong>Default: </strong> Medium
164
- </span>
165
- </div>
166
- </td>
167
- <td>
168
- <?php echo $form->render("wpstg_settings[cpuLoad]")?>
169
- </td>
170
- </tr>
171
- <!-- Deactivated -->
172
- <tr class="row" style="display:none;">
173
- <td class="row th">
174
- <div class="col-title">
175
- <?php echo $form->label("wpstg_settings[optimizer]")?>
176
- <span class="description">
177
- Select the plugins that should be disabled during build process of the staging site.
178
- Some plugins slow down the copy process and add overhead to each request, requiring extra CPU and memory consumption.
179
- Some of them can interfere with cloning process and cause them to fail, so we recommend to select all plugins here.
180
 
181
- <br><br>
182
- <strong>Note:</strong> This does not disable plugins on your staging site. You have to disable them there separately.
183
- </span>
184
- </div>
185
- </td>
186
- <td>
187
- <?php echo $form->render("wpstg_settings[optimizer]")?>
188
- <div id="wpstg_pluginListing" style="display:none">
189
- <?php echo $form->render("wpstg_settings[blackListedPlugins][]")?>
190
- </div>
191
- </td>
192
- </tr>
193
 
194
- <tr class="row">
195
- <td class="row th">
196
- <div class="col-title">
197
- <?php echo $form->label("wpstg_settings[disableAdminLogin]")?>
198
- <span class="description">
199
- If you want to remove the requirement to login to the staging site you can deactivate it here.
200
- <strong>Note:</strong> If you disable authentication everyone can see your staging sites including search engines and this can lead to "duplicate content" in search engines.
201
- </span>
202
- </div>
203
- </td>
204
- <td>
205
- <?php echo $form->render("wpstg_settings[disableAdminLogin]")?>
206
- </td>
207
- </tr>
208
 
209
- <tr class="row">
210
- <td class="row th">
211
- <div class="col-title">
212
- <?php echo $form->label("wpstg_settings[wpSubDirectory]")?>
213
- <span class="description">
214
- Use this option when you gave wordpress its own subdirectory.
215
- if you enable this, WP Staging will reset the index.php of the clone site to the originally one.
216
- <br>
217
- <a href="https://codex.wordpress.org/Giving_WordPress_Its_Own_Directory" target="_blank">Read more in the WordPress Codex</a>
218
- </span>
219
- </div>
220
- </td>
221
- <td>
222
- <?php echo $form->render("wpstg_settings[wpSubDirectory]")?>
223
- </td>
224
- </tr>
225
- <!-- Deactivated -->
226
- <tr class="row">
227
- <td class="row th">
228
- <div class="col-title">
229
- <?php echo $form->label("wpstg_settings[debugMode]")?>
230
- <span class="description">
231
- This will enable an extended debug mode which creates additional entries
232
- in <strong>wp-content/uploads/wp-staging/logs/logfile.log</strong>.
233
- Please enable this when we ask you to do so.
234
- </span>
235
- </div>
236
- </td>
237
- <td>
238
- <?php echo $form->render("wpstg_settings[debugMode]")?>
239
- </td>
240
- </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
241
 
242
- <tr class="row">
243
- <td class="row th">
244
- <div class="col-title">
245
- <?php echo $form->label("wpstg_settings[unInstallOnDelete]")?>
246
- <span class="description">
247
- Check this box if you like WP Staging to completely remove all of its data when the plugin is deleted.
248
- This will not remove staging sites files or database tables.
249
- </span>
250
- </div>
251
- </td>
252
- <td>
253
- <?php echo $form->render("wpstg_settings[unInstallOnDelete]")?>
254
- </td>
255
- </tr>
256
 
257
- <tr class="row">
258
- <td class="row th">
259
- <div class="col-title">
260
- <?php echo $form->label("wpstg_settings[checkDirectorySize]")?>
261
- <span class="description">
262
- Check this box if you like WP Staging to check sizes of each directory on scanning process.
263
- <br>
264
- Warning this might cause timeout problems in big directory / file structures.
265
- </span>
266
- </div>
267
- </td>
268
- <td>
269
- <?php echo $form->render("wpstg_settings[checkDirectorySize]")?>
270
- </td>
271
- </tr>
272
- </tbody>
273
- </table>
274
- </div>
275
- <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
276
  endforeach;
277
  // Show submit button any tab but add-ons
278
- if ($activeTab !== "add-ons")
279
- {
280
- submit_button();
281
  }
282
- unset($tabs);
283
  ?>
284
  </form>
285
  </div>
1
  <div class="wpstg_admin">
2
  <span class="wp-staginglogo">
3
+ <img src="<?php echo $this->url . "img/logo_clean_small_212_25.png" ?>">
4
  </span>
5
 
6
  <span class="wpstg-version">
7
+ <?php if( \WPStaging\WPStaging::SLUG === "wp-staging-pro" ) echo "Pro" ?> Version <?php echo \WPStaging\WPStaging::VERSION ?>
8
  </span>
9
 
10
  <div class="wpstg-header">
11
+ <div class='wpstg-share-button-container'>
12
+ <div class='wpstg-share-button wpstg-share-button-twitter' data-share-url="https://wordpress.org/plugins/wp-staging">
13
+ <div clas='box'>
14
+ <a href="https://twitter.com/intent/tweet?button_hashtag=wpstaging&text=Check%20out%20this%20plugin%20for%20creating%20a%20one%20click%20WordPress%20testing%20site&via=wpstg" target='_blank'>
15
+ <span class='wpstg-share'><?php echo __( 'Tweet #wpstaging', 'wpstg' ); ?></span>
16
+ </a>
17
+ </div>
18
  </div>
19
+ <div class="wpstg-share-button wpstg-share-button-twitter">
20
+ <div class="box">
21
+ <a href="https://twitter.com/intent/follow?original_referer=http%3A%2F%2Fsrc.wordpress-develop.dev%2Fwp-admin%2Fadmin.php%3Fpage%3Dwpstg-settings&ref_src=twsrc%5Etfw&region=follow_link&screen_name=renehermenau&tw_p=followbutton" target="_blank">
22
+ <span class='wpstg-share'><?php echo __( 'Follow @wpstaging', 'wpstg' ); ?></span>
23
+ </a>
24
+ </div>
25
  </div>
26
+ <div class="wpstg-share-button wpstg-share-button-facebook" data-share-url="https://wordpress.org/plugins/wp-staging">
27
+ <div class="box">
28
+ <a href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fwordpress.org%2Fplugins%2Fwp-staging" target="_blank">
29
+ <span class='wpstg-share'><?php echo __( 'Share on Facebook', 'wpstg' ); ?></span>
30
+ </a>
31
+ </div>
32
  </div>
33
  </div>
34
  </div>
 
35
 
36
  <ul class="nav-tab-wrapper">
37
  <?php
38
+ $tabs = $this->di->get( "tabs" )->get();
39
+ $activeTab = (isset( $_GET["tab"] ) && array_key_exists( $_GET["tab"], $tabs )) ? $_GET["tab"] : "general";
40
 
41
  # Loop through tabs
42
+ foreach ( $tabs as $id => $name ):
43
+ $url = esc_url( add_query_arg( array(
44
+ "settings-updated" => false,
45
+ "tab" => $id
46
+ ) ) );
47
 
48
+ $activeClass = ($activeTab === $id) ? " nav-tab-active" : '';
49
+ ?>
50
+ <li>
51
+ <a href="<?php echo $url ?>" title="<?php echo esc_attr( $name ) ?>" class="nav-tab<?php echo $activeClass ?>">
52
+ <?php echo esc_html( $name ) ?>
53
+ </a>
54
+ </li>
55
+ <?php
56
+ unset( $url, $activeClass );
57
  endforeach;
58
  ?>
59
  </ul>
63
  <div class="panel-container">
64
  <form method="post" action="options.php">
65
  <?php
66
+ settings_fields( "wpstg_settings" );
67
 
68
+ foreach ( $tabs as $id => $name ):
69
+ $form = $this->di->get( "forms" )->get( $id );
70
 
71
+ if( null === $form ) {
72
+ continue;
73
+ }
74
+ ?>
75
+ <div id="<?php echo $id ?>__wpstg_header">
76
+ <table class="form-table">
77
+ <thead>
78
+ <tr class="row">
79
+ <th class="row th" colspan="2">
80
+ <div class="col-title">
81
+ <strong><?php echo $name ?></strong>
82
+ <span class="description"></span>
83
+ </div>
84
+ </th>
85
+ </tr>
86
+ </thead>
 
87
 
88
+ <tbody>
89
+ <tr class="row">
90
+ <td class="row th">
91
+ <div class="col-title">
92
+ <?php
93
+ echo $form->label( "wpstg_settings[queryLimit]" )
94
+ ?>
95
+ <span class="description">
96
+ Number of DB rows, that will be copied within one ajax request.
97
+ The higher the value the faster the database copy process.
98
+ To find out the highest possible values try a high value like 1.000 or more. If you get timeout issues, lower it
99
+ until you get no more errors during copying process.
100
+ <br>
101
+ <strong> Default: 5000 </strong>
102
+ </span>
103
+ </div>
104
+ </td>
105
+ <td>
106
+ <?php echo $form->render( "wpstg_settings[queryLimit]" ) ?>
107
+ </td>
108
+ </tr>
109
 
110
+ <tr class="row">
111
+ <td class="row th">
112
+ <div class="col-title">
113
+ <?php
114
+ echo $form->label( "wpstg_settings[fileLimit]" )
115
+ ?>
116
+ <span class="description">
117
+ Number of files to copy that will be copied within one ajax request.
118
+ The higher the value the faster the file copy process.
119
+ To find out the highest possible values try a high value like 500 or more. If you get timeout issues, lower it
120
+ until you get no more errors during copying process.
121
+ <br>
122
+ <strong> Default: 1 </strong>
123
+ </span>
124
+ </div>
125
+ </td>
126
+ <td>
127
+ <?php echo $form->render( "wpstg_settings[fileLimit]" ) ?>
128
+ </td>
129
+ </tr>
130
 
131
+ <tr class="row">
132
+ <td class="row th">
133
+ <div class="col-title">
134
+ <?php echo $form->label( "wpstg_settings[batchSize]" ) ?>
135
+ <span class="description">
136
+ Buffer size for the file copy process in megabyte.
137
+ The higher the value the faster large files will be copied.
138
+ To find out the highest possible values try a high one and lower it until
139
+ you get no errors during file copy process. Usually this value correlates directly
140
+ with the memory consumption of php so make sure that
141
+ it does not exceed any php.ini max_memory limits.
142
+ <br>
143
+ <strong>Default:</strong> 2
144
+ </span>
145
+ </div>
146
+ </td>
147
+ <td>
148
+ <?php echo $form->render( "wpstg_settings[batchSize]" ) ?>
149
+ </td>
150
+ </tr>
151
 
152
+ <tr class="row">
153
+ <td class="row th">
154
+ <div class="col-title">
155
+ <?php echo $form->label( "wpstg_settings[cpuLoad]" ) ?>
156
+ <span class="description">
157
+ Using high will result in fast as possible processing but the cpu load
158
+ increases and it's also possible that staging process gets interrupted because of too many ajax requests
159
+ (e.g. <strong>authorization error</strong>).
160
+ Using a lower value results in lower cpu load on your server but also slower staging site creation.
161
+ <br>
162
+ <strong>Default: </strong> Medium
163
+ </span>
164
+ </div>
165
+ </td>
166
+ <td>
167
+ <?php echo $form->render( "wpstg_settings[cpuLoad]" ) ?>
168
+ </td>
169
+ </tr>
170
+ <!-- Deactivated -->
171
+ <tr class="row" style="display:none;">
172
+ <td class="row th">
173
+ <div class="col-title">
174
+ <?php echo $form->label( "wpstg_settings[optimizer]" ) ?>
175
+ <span class="description">
176
+ Select the plugins that should be disabled during build process of the staging site.
177
+ Some plugins slow down the copy process and add overhead to each request, requiring extra CPU and memory consumption.
178
+ Some of them can interfere with cloning process and cause them to fail, so we recommend to select all plugins here.
179
 
180
+ <br><br>
181
+ <strong>Note:</strong> This does not disable plugins on your staging site. You have to disable them there separately.
182
+ </span>
183
+ </div>
184
+ </td>
185
+ <td>
186
+ <?php echo $form->render( "wpstg_settings[optimizer]" ) ?>
187
+ <div id="wpstg_pluginListing" style="display:none">
188
+ <?php echo $form->render( "wpstg_settings[blackListedPlugins][]" ) ?>
189
+ </div>
190
+ </td>
191
+ </tr>
192
 
193
+ <tr class="row">
194
+ <td class="row th">
195
+ <div class="col-title">
196
+ <?php echo $form->label( "wpstg_settings[disableAdminLogin]" ) ?>
197
+ <span class="description">
198
+ If you want to remove the requirement to login to the staging site you can deactivate it here.
199
+ <strong>Note:</strong> The staging site discourages search engines from indexing the site by setting the 'noindex' tag into header of the staging site.
200
+ </span>
201
+ </div>
202
+ </td>
203
+ <td>
204
+ <?php echo $form->render( "wpstg_settings[disableAdminLogin]" ) ?>
205
+ </td>
206
+ </tr>
207
 
208
+ <tr class="row">
209
+ <td class="row th">
210
+ <div class="col-title">
211
+ <?php echo $form->label( "wpstg_settings[wpSubDirectory]" ) ?>
212
+ <span class="description">
213
+ Use this option when you gave wordpress its own subdirectory.
214
+ if you enable this, WP Staging will reset the index.php of the clone site to the originally one.
215
+ <br>
216
+ <a href="https://codex.wordpress.org/Giving_WordPress_Its_Own_Directory" target="_blank">Read more in the WordPress Codex</a>
217
+ </span>
218
+ </div>
219
+ </td>
220
+ <td>
221
+ <?php echo $form->render( "wpstg_settings[wpSubDirectory]" ) ?>
222
+ </td>
223
+ </tr>
224
+ <!-- Deactivated -->
225
+ <tr class="row">
226
+ <td class="row th">
227
+ <div class="col-title">
228
+ <?php echo $form->label( "wpstg_settings[debugMode]" ) ?>
229
+ <span class="description">
230
+ This will enable an extended debug mode which creates additional entries
231
+ in <strong>wp-content/uploads/wp-staging/logs/logfile.log</strong>.
232
+ Please enable this when we ask you to do so.
233
+ </span>
234
+ </div>
235
+ </td>
236
+ <td>
237
+ <?php echo $form->render( "wpstg_settings[debugMode]" ) ?>
238
+ </td>
239
+ </tr>
240
+ <tr class="row">
241
+ <td class="row th">
242
+ <div class="col-title">
243
+ <?php echo $form->label( "wpstg_settings[optimizer]" ) ?>
244
+ <span class="description">
245
+ The Optimizer is a mu plugin which disables all other plugins during WP Staging processing. Usually this makes the cloning process more reliable. If you experience issues, disable the Optimizer.
246
+ </span>
247
+ </div>
248
+ </td>
249
+ <td>
250
+ <?php echo $form->render( "wpstg_settings[optimizer]" ) ?>
251
+ </td>
252
+ </tr>
253
 
254
+ <tr class="row">
255
+ <td class="row th">
256
+ <div class="col-title">
257
+ <?php echo $form->label( "wpstg_settings[unInstallOnDelete]" ) ?>
258
+ <span class="description">
259
+ Check this box if you like WP Staging to completely remove all of its data when the plugin is deleted.
260
+ This will not remove staging sites files or database tables.
261
+ </span>
262
+ </div>
263
+ </td>
264
+ <td>
265
+ <?php echo $form->render( "wpstg_settings[unInstallOnDelete]" ) ?>
266
+ </td>
267
+ </tr>
268
 
269
+ <tr class="row">
270
+ <td class="row th">
271
+ <div class="col-title">
272
+ <?php echo $form->label( "wpstg_settings[checkDirectorySize]" ) ?>
273
+ <span class="description">
274
+ Check this box if you like WP Staging to check sizes of each directory on scanning process.
275
+ <br>
276
+ Warning this might cause timeout problems in big directory / file structures.
277
+ </span>
278
+ </div>
279
+ </td>
280
+ <td>
281
+ <?php echo $form->render( "wpstg_settings[checkDirectorySize]" ) ?>
282
+ </td>
283
+ </tr>
284
+ <tr class="row">
285
+ <td class="row th">
286
+ <div class="col-title">
287
+ <?php echo $form->label( "wpstg_settings[loginSlug]" ) ?>
288
+ <span class="description">
289
+ <?php _e( 'Enter the string which links to your login page if you are using a custom login page instead the default WordPress login. <br/><br/><strong>This does not affect already existing staging sites.</strong><br/> You need to create a new staging site if you like to change the login url of a staging site.', 'wpstg' ); ?>
290
+ </span>
291
+ </div>
292
+ </td>
293
+ <td>
294
+ <?php echo get_home_url() . '/?' . $form->render( "wpstg_settings[loginSlug]" ); ?>
295
+ </td>
296
+ </tr>
297
+ </tbody>
298
+ </table>
299
+ </div>
300
+ <?php
301
  endforeach;
302
  // Show submit button any tab but add-ons
303
+ if( $activeTab !== "add-ons" ) {
304
+ submit_button();
 
305
  }
306
+ unset( $tabs );
307
  ?>
308
  </form>
309
  </div>
apps/Core/WPStaging.php CHANGED
@@ -29,7 +29,7 @@ final class WPStaging {
29
  /**
30
  * Plugin version
31
  */
32
- const VERSION = "2.1.9";
33
 
34
  /**
35
  * Plugin name
29
  /**
30
  * Plugin version
31
  */
32
+ const VERSION = "2.2.1";
33
 
34
  /**
35
  * Plugin name
apps/Frontend/Frontend.php CHANGED
@@ -1,128 +1,143 @@
1
  <?php
 
2
  namespace WPStaging\Frontend;
3
 
4
  use WPStaging\DI\InjectionAware;
 
 
5
  /**
6
  * Class Frontend
7
  * @package WPStaging\Frontend
8
  */
9
- class Frontend extends InjectionAware
10
- {
11
-
12
- /**
13
- * @var object
14
- */
15
- private $settings;
16
-
17
- /**
18
- * Frontend initialization.
19
- */
20
- public function initialize()
21
- {
22
- $this->defineHooks();
23
-
24
- $this->settings = json_decode(json_encode(get_option("wpstg_settings", array())));
25
-
26
- }
27
-
28
- /**
29
- * Define Hooks
30
- */
31
- private function defineHooks()
32
- {
33
- // Get loader
34
- $loader = $this->di->get("loader");
35
-
36
- $loader->addAction("init", $this, "checkPermissions");
37
- $loader->addFilter("wp_before_admin_bar_render", $this, "changeSiteName");
38
- }
39
-
40
- /**
41
- * Change admin_bar site_name
42
- *
43
- * @global object $wp_admin_bar
44
- * @return void
45
- */
46
- public function changeSiteName() {
47
- global $wp_admin_bar;
48
- if( $this->isStagingSite() ) {
49
- // Main Title
50
- $wp_admin_bar->add_menu( array(
51
- 'id' => 'site-name',
52
- 'title' => is_admin() ? ('STAGING - ' . get_bloginfo( 'name' ) ) : ( 'STAGING - ' . get_bloginfo( 'name' ) . ' Dashboard' ),
53
- 'href' => is_admin() ? home_url( '/' ) : admin_url(),
54
- ) );
55
- }
56
- }
57
-
58
- /**
59
- * Load css files
60
- */
61
- // public function enqueueElements() {
62
- // if( $this->isStagingSite() ) {
63
- // wp_enqueue_style( "wpstg-admin-bar", $this->admin_url . "/css/wpstg-admin-bar.css", $this->di->getVersion() );
64
- // }
65
- // }
66
-
67
- /**
68
- * Check permissions for the page to decide whether or not to disable the page
69
- */
70
- public function checkPermissions()
71
- {
72
- if ($this->shouldDisableLogin())
73
- {
74
- wp_die( sprintf ( __('Access denied. You need to <a href="%1$s" target="_blank">Login</a> first','wpstg'), wp_login_url() ) );
75
- }
76
-
77
- $this->resetPermaLinks();
78
- }
79
-
80
- /**
81
- * Check if the page should be blocked
82
- * @return bool
83
- */
84
- private function shouldDisableLogin()
85
- {
86
- return (
87
- $this->isStagingSite() &&
88
- (!isset($this->settings->disableAdminLogin) || '1' !== $this->settings->disableAdminLogin) &&
89
- (!current_user_can("administrator") && !$this->isLoginPage() && !is_admin())
90
- );
91
- }
92
-
93
- /**
94
- * Check if it is a staging site
95
- * @return bool
96
- */
97
- private function isStagingSite()
98
- {
99
- return ("true" === get_option("wpstg_is_staging_site"));
100
- }
101
-
102
- /**
103
- * Check if it is the login page
104
- * @return bool
105
- */
106
- private function isLoginPage()
107
- {
108
- return (in_array($GLOBALS["pagenow"], array("wp-login.php")));
109
- }
110
-
111
- /**
112
- * Reset permalink structure of the clone to default; index.php?p=123
113
- */
114
- private function resetPermaLinks()
115
- {
116
- if (!$this->isStagingSite() || "true" === get_option("wpstg_rmpermalinks_executed"))
117
- {
118
- return;
119
- }
120
- // $wp_redirect is not available before the init hook. So we need to use the global declaration
121
- global $wp_rewrite;
122
- $wp_rewrite->set_permalink_structure(null);
123
-
124
- flush_rewrite_rules();
125
-
126
- update_option("wpstg_rmpermalinks_executed", "true");
127
- }
128
- }
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
+
3
  namespace WPStaging\Frontend;
4
 
5
  use WPStaging\DI\InjectionAware;
6
+ use WPStaging\Frontend\loginForm;
7
+
8
  /**
9
  * Class Frontend
10
  * @package WPStaging\Frontend
11
  */
12
+ class Frontend extends InjectionAware {
13
+
14
+ /**
15
+ * @var object
16
+ */
17
+ private $settings;
18
+
19
+ /**
20
+ * Frontend initialization.
21
+ */
22
+ public function initialize() {
23
+ $this->defineHooks();
24
+
25
+ $this->settings = json_decode( json_encode( get_option( "wpstg_settings", array() ) ) );
26
+ }
27
+
28
+ /**
29
+ * Define Hooks
30
+ */
31
+ private function defineHooks() {
32
+ // Get loader
33
+ $loader = $this->di->get( "loader" );
34
+ $loader->addAction( "init", $this, "checkPermissions" );
35
+ $loader->addFilter( "wp_before_admin_bar_render", $this, "changeSiteName" );
36
+ }
37
+
38
+ /**
39
+ * Change admin_bar site_name
40
+ *
41
+ * @global object $wp_admin_bar
42
+ * @return void
43
+ */
44
+ public function changeSiteName() {
45
+ global $wp_admin_bar;
46
+ if( $this->isStagingSite() ) {
47
+ // Main Title
48
+ $wp_admin_bar->add_menu( array(
49
+ 'id' => 'site-name',
50
+ 'title' => is_admin() ? ('STAGING - ' . get_bloginfo( 'name' ) ) : ( 'STAGING - ' . get_bloginfo( 'name' ) . ' Dashboard' ),
51
+ 'href' => is_admin() ? home_url( '/' ) : admin_url(),
52
+ ) );
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Check permissions for the page to decide whether or not to disable the page
58
+ */
59
+ public function checkPermissions() {
60
+ $this->resetPermaLinks();
61
+
62
+ if( $this->disableLogin() ) {
63
+ wp_die( sprintf( __( 'Access denied. <a href="%1$s" target="_blank">Login</a> first to access this site', 'wpstg' ), $this->getLoginUrl() ) );
64
+
65
+ /**
66
+ * Lines below are not used at the moment but are fully functional
67
+ */
68
+ //$login = new loginForm();
69
+ //$login->renderForm();
70
+ //die();
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Get login link
76
+ * @return string
77
+ */
78
+ private function getLoginUrl() {
79
+ if( empty( $this->settings->loginSlug ) ) {
80
+ return wp_login_url();
81
+ }
82
+
83
+ return get_home_url() . '/?' . $this->settings->loginSlug;
84
+ }
85
+
86
+ /**
87
+ * Check if the page should be blocked
88
+ * @return bool
89
+ */
90
+ private function disableLogin() {
91
+ // Is not staging site
92
+ if( !$this->isStagingSite() ) {
93
+ return false;
94
+ }
95
+
96
+ // Allow access for user role administrator in any case
97
+ if( current_user_can( 'administrator' ) ) {
98
+ return false;
99
+ }
100
+
101
+ return (
102
+ (!isset( $this->settings->disableAdminLogin ) || '1' !== $this->settings->disableAdminLogin) &&
103
+ (!current_user_can( "administrator" ) && !$this->isLoginPage() && !is_admin())
104
+ );
105
+ }
106
+
107
+ /**
108
+ * Check if it is a staging site
109
+ * @return bool
110
+ */
111
+ private function isStagingSite() {
112
+ return ("true" === get_option( "wpstg_is_staging_site" ));
113
+ }
114
+
115
+ /**
116
+ * Check if it is the login page
117
+ * @return bool
118
+ */
119
+ private function isLoginPage() {
120
+ return (
121
+ in_array( $GLOBALS["pagenow"], array("wp-login.php") ) ||
122
+ in_array( $this->settings->loginSlug, $_GET ) ||
123
+ array_key_exists( $this->settings->loginSlug, $_GET )
124
+ );
125
+ }
126
+
127
+ /**
128
+ * Reset permalink structure of the clone to default; index.php?p=123
129
+ */
130
+ private function resetPermaLinks() {
131
+ if( !$this->isStagingSite() || "true" === get_option( "wpstg_rmpermalinks_executed" ) ) {
132
+ return;
133
+ }
134
+ // $wp_rewrite is not available before the init hook. So we need to use the global declaration
135
+ global $wp_rewrite;
136
+ $wp_rewrite->set_permalink_structure( null );
137
+
138
+ flush_rewrite_rules();
139
+
140
+ update_option( "wpstg_rmpermalinks_executed", "true" );
141
+ }
142
+
143
+ }
apps/Frontend/loginForm.php ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WPStaging\Frontend;
4
+
5
+ class loginForm {
6
+
7
+ public function renderForm(){
8
+ $this->getHeader();
9
+ $this->getLoginForm();
10
+ $this->getFooter();
11
+ }
12
+
13
+ private function getHeader() {
14
+ ?>
15
+
16
+ <!DOCTYPE html>
17
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
18
+ <head>
19
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
20
+ <meta name="viewport" content="width=device-width">
21
+ <meta name='robots' content='noindex,follow' />
22
+ <title>WordPress &rsaquo; Error</title>
23
+ <style type="text/css">
24
+ html {
25
+ background: #f1f1f1;
26
+ }
27
+ body {
28
+ background: #fff;
29
+ color: #444;
30
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
31
+ margin: 2em auto;
32
+ padding: 1em 2em;
33
+ max-width: 700px;
34
+ -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.13);
35
+ box-shadow: 0 1px 3px rgba(0,0,0,0.13);
36
+ }
37
+ h1 {
38
+ border-bottom: 1px solid #dadada;
39
+ clear: both;
40
+ color: #666;
41
+ font-size: 24px;
42
+ margin: 30px 0 0 0;
43
+ padding: 0;
44
+ padding-bottom: 7px;
45
+ }
46
+ #error-page {
47
+ margin-top: 50px;
48
+ }
49
+ #error-page p {
50
+ font-size: 14px;
51
+ line-height: 1.5;
52
+ margin: 25px 0 20px;
53
+ }
54
+ #error-page code {
55
+ font-family: Consolas, Monaco, monospace;
56
+ }
57
+ ul li {
58
+ margin-bottom: 10px;
59
+ font-size: 14px ;
60
+ }
61
+ a {
62
+ color: #0073aa;
63
+ }
64
+ a:hover,
65
+ a:active {
66
+ color: #00a0d2;
67
+ }
68
+ a:focus {
69
+ color: #124964;
70
+ -webkit-box-shadow:
71
+ 0 0 0 1px #5b9dd9,
72
+ 0 0 2px 1px rgba(30, 140, 190, .8);
73
+ box-shadow:
74
+ 0 0 0 1px #5b9dd9,
75
+ 0 0 2px 1px rgba(30, 140, 190, .8);
76
+ outline: none;
77
+ }
78
+ .button {
79
+ background: #f7f7f7;
80
+ border: 1px solid #ccc;
81
+ color: #555;
82
+ display: inline-block;
83
+ text-decoration: none;
84
+ font-size: 13px;
85
+ line-height: 26px;
86
+ height: 28px;
87
+ margin: 0;
88
+ padding: 0 10px 1px;
89
+ cursor: pointer;
90
+ -webkit-border-radius: 3px;
91
+ -webkit-appearance: none;
92
+ border-radius: 3px;
93
+ white-space: nowrap;
94
+ -webkit-box-sizing: border-box;
95
+ -moz-box-sizing: border-box;
96
+ box-sizing: border-box;
97
+
98
+ -webkit-box-shadow: 0 1px 0 #ccc;
99
+ box-shadow: 0 1px 0 #ccc;
100
+ vertical-align: top;
101
+ }
102
+
103
+ .button.button-large {
104
+ height: 30px;
105
+ line-height: 28px;
106
+ padding: 0 12px 2px;
107
+ }
108
+
109
+ .button:hover,
110
+ .button:focus {
111
+ background: #fafafa;
112
+ border-color: #999;
113
+ color: #23282d;
114
+ }
115
+
116
+ .button:focus {
117
+ border-color: #5b9dd9;
118
+ -webkit-box-shadow: 0 0 3px rgba( 0, 115, 170, .8 );
119
+ box-shadow: 0 0 3px rgba( 0, 115, 170, .8 );
120
+ outline: none;
121
+ }
122
+
123
+ .button:active {
124
+ background: #eee;
125
+ border-color: #999;
126
+ -webkit-box-shadow: inset 0 2px 5px -3px rgba( 0, 0, 0, 0.5 );
127
+ box-shadow: inset 0 2px 5px -3px rgba( 0, 0, 0, 0.5 );
128
+ -webkit-transform: translateY(1px);
129
+ -ms-transform: translateY(1px);
130
+ transform: translateY(1px);
131
+ }
132
+
133
+ </style>
134
+ </head>
135
+ <?php
136
+ }
137
+
138
+ /**
139
+ * Render login form by using native wp function wp_login_form
140
+ * return string
141
+ */
142
+ private function getLoginForm() {
143
+ $this->getHeader();
144
+ echo '<body id="error-page">';
145
+ echo __( 'Access denied. Login to access this site', 'wpstg' );
146
+
147
+ $args = array(
148
+ 'redirect' => admin_url(),
149
+ 'redirect' => admin_url(),
150
+ 'form_id' => 'wpstg-loginform',
151
+ 'label_username' => __( 'Username', 'wpstg' ),
152
+ 'label_password' => __( 'Password', 'wpstg' ),
153
+ 'label_remember' => __( 'Remember Me' ),
154
+ 'label_log_in' => __( 'Log In Staging Site' ),
155
+ 'remember' => true
156
+ );
157
+ wp_login_form( $args );
158
+ $this->getFooter();
159
+ }
160
+
161
+ private function getFooter() {
162
+ echo '</html>';
163
+ }
164
+
165
+ }
166
+
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.9
12
- Stable tag: 2.1.9
13
 
14
  A duplicator plugin! Clone, duplicate and migrate live sites to independent staging and development sites that are available only to administrators.
15
 
@@ -48,7 +48,8 @@ WP Staging helps you to prevent your website from being broken or unavailable be
48
  <strong>More safe:</strong>
49
  <br>
50
  * Admin bar reflects that you are working on a staging site
51
- * Extensive logging if duplication and migration process fails.
 
52
 
53
  = What does not work or is not tested when running wordpress migration? =
54
 
@@ -109,11 +110,9 @@ Please open a [support request](https://wordpress.org/support/plugin/wp-staging/
109
 
110
  = Important =
111
 
112
- Per default the staging site will have permalinks disabled because the staging site will be cloned into a subfolder and regular permalinks are not working
113
- without doing changes to your .htaccess or nginx.conf.
114
- In the majority of cases this is abolutely fine for a staging platform and you still will be able to test new plugins and do some theme changes on your staging platform.
115
- If you need the same permalink stucture on your staging platform as you have in your prodcution website you have to create a custom .htaccess for apache webserver
116
- or to adjust your nginx.conf.
117
 
118
 
119
  = How to install and setup? =
@@ -123,14 +122,19 @@ After installation goto the settings page 'Staging' and do your adjustments ther
123
 
124
  == Frequently Asked Questions ==
125
 
 
 
 
 
 
126
 
127
  == Official Site ==
128
  https://wp-staging.com
129
 
130
  == Installation ==
131
- 1. Download the file "wp-staging" , unzip and place it in your wp-content/plugins/wp-staging folder. You can alternatively upload and install it via the WordPress plugin backend.
132
- 2. Activate the plugin through the 'Plugins' menu in WordPress.
133
- 3. Start Plugins->Staging
134
 
135
  == Screenshots ==
136
 
@@ -141,6 +145,17 @@ https://wp-staging.com
141
 
142
  == Changelog ==
143
 
 
 
 
 
 
 
 
 
 
 
 
144
  = 2.1.9 =
145
  * New: Performance improvement increase db query limit to 5000
146
  * New: Detect automatically if WordPress is installed in sub folder
@@ -209,106 +224,9 @@ https://wp-staging.com
209
  * Fix: Access to staging site not working, if WP_SITEURL and WP_HOME is defined in wp-config.php
210
  * Tweak: Exclude wp-content/cache folder from copying process
211
 
212
-
213
- = 2.0.9 =
214
- * Skip Version
215
-
216
- = 2.0.8 =
217
- * Fix: After update from wpstg 1.6.x to 2.x previous settings were not imported resulting in cancelation of cloning process. Still not fixed in 2.0.7
218
-
219
- = 2.0.7 =
220
- * Fix: After update from wpstg 1.6.x to 2.x previous settings were not imported resulting in cancelation of cloning process
221
-
222
-
223
- = 2.0.6 =
224
- * Fix: Cancel Cloning button not working
225
- * Fix: Limit max execution time to a maximum of 30sec to prevent high memory consumption and script timeouts
226
-
227
-
228
- = 2.0.5 =
229
- * New: Major version - Complete rewrite of the code base
230
- * New: Batch processing allows to clone even huge sites without any timeouts
231
- * New: Preparation for WP QUADS PRO with ability to copy file changes back to live site
232
- * New: Bypass (broken) third party plugins during wp staging related ajax requests to prevent processing errors. Use a mu plugin for this.
233
-
234
- = 1.1.6 =
235
- * New: Add download link to WP Staging Beta Version 2.0.1
236
-
237
- = 1.1.5 =
238
- * Fix: Admin notice is throwing a false positive write permission error
239
- * New: Move log folder to wp-content/uploads/wp-staging/logs
240
- * New: Tested up to WP 4.7.3
241
-
242
- = 1.1.4 =
243
- * Fix: Fatal error Unsupported operand types
244
-
245
- = 1.1.3 =
246
- * New: Tested up to wp 4.7.2
247
- * Fix: Arrows in drop down for folder selection are distorted
248
- * Tweak: Show working log as default to make debugging easier
249
-
250
- = 1.1.2 =
251
- * Fix: Settings are not deleted when plugin is removed
252
- * Fix: Staging site is available for non administrators
253
-
254
- = 1.1.1 =
255
- * Fix: Change rating url
256
-
257
- = 1.1.0 =
258
- * New: Tested up to WP 4.6
259
- * New: Create a poll and ask what feature is most required
260
-
261
- = 1.0.9 =
262
- * Fix: Undefined WPSTG() warning
263
- * Fix: Change compatibility version to wp 4.5.3
264
-
265
- = 1.0.8 =
266
- * Tested up to WP 4.5.2
267
-
268
- = 1.0.7 =
269
- * Fix: Activation hook is not fired and staging site is not working properly
270
- * Performance: Increase default query copy limit to 1000
271
-
272
- = 1.0.6 =
273
- * Fix: Uninstalling plugin throwing error
274
- * Fix: Error permission admin notice although permission issues are correct
275
-
276
-
277
- = 1.0.5 =
278
- * New: Tested up to WP 4.5
279
- * Fix: Download system log not working
280
- * Fix: Click on Optimizer "Select all | none | invert" links leads to jumping
281
- * Tweak: Make clear that unselecting a checkbox will exlude table or file from copy process
282
- * Tweak: Remove unnecessary text
283
- * Tweak: Change beta notice in dashboard. WP Staging is stable
284
- * Tweak: Change twitter handle to @wpstg
285
-
286
- = 1.0.3 =
287
- * Fix: Missing const MASHFS_VERSION
288
- * Fix: Remove error "table XY has been created, BUT inserting rows failed."
289
- * Fix: Not tested up to 4.4.2 message shown although it's tested up to WP 4.4.2
290
- * New: Disable either free or pro version and does not allow to have both version enabled at the same time
291
-
292
- = 1.0.2 =
293
- * Tweak: Change setting description of uninstall option
294
- * Tweak: Lower tags in readme.txt
295
-
296
- = 1.0.1 =
297
- * New: Orange colored admin bar on staging site for better visualization and comparision between production live site and staging site
298
- * Tweak: Remove contact link on multisite notification
299
-
300
- = 1.0.0 =
301
- * Fix: Do not follow symlinks during file copy process
302
- * Fix: css error
303
- * Fix: Show "not-compatible" notice only when blog version is higher than plugin tested version.
304
- * Fix: undefined var $size
305
- * Fix: Check if $path is null before writing to remaining_files.json
306
- * Fix: $db_helper undefined message
307
- * Fix: Skip non utf8 encoded files during copying process
308
-
309
  Complete changelog: [https://wp-staging.com/changelog.txt](https://wp-staging.com/changelog.txt)
310
 
311
  == Upgrade Notice ==
312
 
313
- = 2.1.7 =
314
- 2.1.7 * Update for WordPress 4.9.1. Preparations for Database Migration
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.9
12
+ Stable tag: 2.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
 
48
  <strong>More safe:</strong>
49
  <br>
50
  * Admin bar reflects that you are working on a staging site
51
+ * Extensive logging if duplication or migration process should fail.
52
+ * New: Compatible to All In One WP Security & Firewall
53
 
54
  = What does not work or is not tested when running wordpress migration? =
55
 
110
 
111
  = Important =
112
 
113
+ Permalinks are disabled on the staging site because the staging site is cloned into a subfolder and permalinks are not working on all systems
114
+ without doing changes to the .htaccess (Apache server) or nginx.conf (Nginx Server).
115
+ [Read here](https://wp-staging.com/docs/activate-permalinks-staging-site/ "activate permalinks on staging site") how to activate permalinks on the staging site.
 
 
116
 
117
 
118
  = How to install and setup? =
122
 
123
  == Frequently Asked Questions ==
124
 
125
+ * I can not login to the staging site
126
+ If you are using a security plugin like All In One WP Security & Firewall you need to install latest version of WP Staging.
127
+ Go to WP Staging > Settings and add the slug to the custom login page which you set up in All In One WP Security & Firewall plugin.
128
+
129
+
130
 
131
  == Official Site ==
132
  https://wp-staging.com
133
 
134
  == Installation ==
135
+ 1. Download the file "wp-staging.zip":
136
+ 2. Upload and install it via the WordPress plugin backend wp-admin > plugins > add new > uploads
137
+ 3. Activate the plugin through the 'Plugins' menu in WordPress.
138
 
139
  == Screenshots ==
140
 
145
 
146
  == Changelog ==
147
 
148
+ = 2.2.1 =
149
+ * New: Option to set Custom Login Link if there is one
150
+ * New: Set meta noindex for staging site to make it non indexable for search engines
151
+ * New: Better multiple folder selection. Allows to unselect a parent folder without collapsing all child folders
152
+ * New: Sorted list of folders to copy
153
+ * Fix: Can not login to staging site if plugin All In One WP Security & Firewall is used
154
+ * Fix: Staging site not reachable because permalinks are not disabled under certain conditions
155
+
156
+ = 2.2.0 =
157
+ * Fix: Old staging site is not listed and pushing is not working properly if plugin is updated from wp staging version 1.6 and lower
158
+
159
  = 2.1.9 =
160
  * New: Performance improvement increase db query limit to 5000
161
  * New: Detect automatically if WordPress is installed in sub folder
224
  * Fix: Access to staging site not working, if WP_SITEURL and WP_HOME is defined in wp-config.php
225
  * Tweak: Exclude wp-content/cache folder from copying process
226
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  Complete changelog: [https://wp-staging.com/changelog.txt](https://wp-staging.com/changelog.txt)
228
 
229
  == Upgrade Notice ==
230
 
231
+ = 2.2.1 =
232
+ 2.2.1 * Compatible to All In One WP Security & Firewall
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.9
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.2.1
11
  * Text Domain: wpstg
12
  * Domain Path: /languages/
13