PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backups, Restore, Migration & Clone / 4.9.5
WP STAGING – WordPress Backups, Restore, Migration & Clone v4.9.5
4.9.5 4.9.4 4.9.3 4.9.2 4.9.1 4.9.0 4.8.1 trunk 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.10.0 3.2.0 3.3.1 3.3.2 3.3.3 3.4.1 3.4.3 3.5.0 3.6.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.9.0 3.9.1 3.9.2 3.9.3 3.9.4 4.0.0 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.8.0
wp-staging / Backend / Modules / Jobs / CloningProcess.php
wp-staging / Backend / Modules / Jobs Last commit date
Cleaners 4 months ago Exceptions 5 years ago Cancel.php 8 months ago CancelUpdate.php 8 months ago Cloning.php 6 days ago CloningProcess.php 6 days ago Data.php 8 months ago Database.php 6 days ago Delete.php 6 days ago Directories.php 5 months ago Files.php 1 month ago Finish.php 6 days ago Job.php 6 days ago JobExecutable.php 8 months ago Logs.php 3 years ago PreserveDataFirstStep.php 2 months ago PreserveDataSecondStep.php 2 months ago ProcessLock.php 1 year ago Scan.php 3 weeks ago SearchReplace.php 6 months ago TotalStepsAreNumberOfTables.php 5 years ago Updating.php 6 days ago
CloningProcess.php
167 lines
1 <?php
2
3 namespace WPStaging\Backend\Modules\Jobs;
4
5 use WPStaging\Core\WPStaging;
6 use WPStaging\Framework\Adapter\Database\DatabaseException;
7
8 /**
9 * Initializes database handles used by legacy staging clone, update, reset, and push jobs.
10 */
11 abstract class CloningProcess extends JobExecutable
12 {
13 /**
14 * Can be local or external \wpdb object
15 * @var \wpdb
16 */
17 protected $stagingDb;
18
19 /**
20 * Always be the local \wpdb object
21 * @var \wpdb
22 */
23 protected $productionDb;
24
25 /**
26 * @return void
27 */
28 protected function setupMemoryExhaustFile()
29 {
30 $this->memoryExhaustErrorTmpFile = $this->getMemoryExhaustErrorTmpFile(Cloning::WPSTG_REQUEST);
31 }
32
33 protected function initializeDbObjects()
34 {
35 $this->productionDb = WPStaging::getInstance()->get("wpdb");
36
37 if ($this->isExternalDatabase()) {
38 $this->setExternalDatabase();
39 } else {
40 $this->setLocalDatabase();
41 }
42 }
43
44 protected function setLocalDatabase()
45 {
46 $this->stagingDb = WPStaging::getInstance()->get("wpdb");
47 }
48
49 /**
50 * @return bool
51 */
52 protected function setExternalDatabase()
53 {
54 if (!$this->validateExternalDatabaseConnectionData()) {
55 return false;
56 }
57
58 if ($this->options->databaseSsl && !defined('MYSQL_CLIENT_FLAGS')) {
59 // phpcs:disable PHPCompatibility.Constants.NewConstants.mysqli_client_ssl_dont_verify_server_certFound
60 define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL | MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT);
61 }
62
63 $this->stagingDb = new \wpdb($this->options->databaseUser, str_replace("\\\\", "\\", $this->options->databasePassword), $this->options->databaseDatabase, $this->options->databaseServer);
64
65 if (!is_object($this->stagingDb)) {
66 $this->returnException('Can not create database object.');
67 return false;
68 }
69
70 // Check if there were any error when connecting
71 if (
72 property_exists($this->stagingDb, 'error') &&
73 $this->stagingDb->error instanceof \WP_Error
74 ) {
75 /** @var \WP_Error $wp_error */
76 $wp_error = $this->stagingDb->error;
77 if ($wp_error->get_error_code() === 'db_connect_fail') {
78 $this->returnException(sprintf(
79 __('Can not connect to external database: %1$s. %2$s', 'wp-staging'),
80 $this->getExternalDatabaseLabel(),
81 $this->getExternalDatabaseConnectionFailureMessage($wp_error)
82 ));
83
84 return false;
85 }
86 }
87
88 $this->stagingDb->select($this->options->databaseDatabase);
89 if (!$this->stagingDb->ready) {
90 if (
91 property_exists($this->stagingDb, 'error') &&
92 $this->stagingDb->error instanceof \WP_Error
93 ) {
94 /** @var \WP_Error $wp_error */
95 $wp_error = $this->stagingDb->error;
96 if ($wp_error->get_error_code() === 'db_select_fail') {
97 $message = $this->normalizeDatabaseErrorMessage($wp_error->get_error_message());
98 $this->returnException($message !== '' ? $message : sprintf('Error: Can\'t select database %s. Either it does not exist or you don\'t have privileges to access it.', $this->options->databaseDatabase));
99 exit;
100 }
101
102 // Generic error
103 $this->returnException(sprintf('Error: Can\'t select database %s. Either it does not exist or you don\'t have privileges to access it.', $this->options->databaseDatabase));
104 exit;
105 }
106
107 // Generic error
108 $this->returnException(sprintf('Error: Can\'t select database %s. Either it does not exist or you don\'t have privileges to access it.', $this->options->databaseDatabase));
109 exit;
110 }
111
112 return true;
113 }
114
115 /**
116 * @return bool
117 */
118 protected function validateExternalDatabaseConnectionData(): bool
119 {
120 try {
121 $this->externalDatabaseConfiguration->validateConnectionTarget($this->options);
122 } catch (DatabaseException $exception) {
123 $this->returnException($exception->getMessage());
124 return false;
125 }
126
127 return true;
128 }
129
130 /**
131 * @return string
132 */
133 private function getExternalDatabaseLabel(): string
134 {
135 $databaseName = isset($this->options->databaseDatabase) ? trim((string)$this->options->databaseDatabase) : '[Not Set]';
136
137 return $databaseName;
138 }
139
140 /**
141 * @param \WP_Error $wpError
142 * @return string
143 */
144 private function getExternalDatabaseConnectionFailureMessage(\WP_Error $wpError): string
145 {
146 $message = $this->normalizeDatabaseErrorMessage($wpError->get_error_message());
147 if ($message === '' || stripos($message, 'Error establishing a database connection') !== false) {
148 return __('Verify the database host, database name, database user, and password, and make sure the database server is reachable.', 'wp-staging');
149 }
150
151 return sprintf(__('Reason: %s', 'wp-staging'), $message);
152 }
153
154 /**
155 * @param string $message
156 * @return string
157 */
158 private function normalizeDatabaseErrorMessage(string $message): string
159 {
160 $message = html_entity_decode($message, ENT_QUOTES, 'UTF-8');
161 $message = wp_strip_all_tags($message, true);
162 $message = preg_replace('/\s+/', ' ', $message);
163
164 return is_string($message) ? trim($message) : '';
165 }
166 }
167