PluginProbe ʕ •ᴥ•ʔ
JetBackup – Backup, Restore & Migrate / trunk
JetBackup – Backup, Restore & Migrate vtrunk
3.1.22.3 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.8.1 1.4.9 1.5.0 1.5.1 1.5.1.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.10 1.6.11 1.6.12 1.6.13 1.6.15 1.6.5.1 1.6.8.8 1.6.9 1.6.9.1 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7.5 2.0.8.7 2.0.9.11 2.0.9.14 2.0.9.15 2.0.9.6 2.0.9.7 2.0.9.9 3.1.10.7 3.1.11.1 3.1.12.3 3.1.13.4 3.1.14.17 3.1.15.4 3.1.16.1 3.1.17.5 3.1.18.10 3.1.18.8 3.1.18.9 3.1.19.8 3.1.20.3 3.1.21.3 3.1.7.9 3.1.9.2 trunk 1.1.90 1.1.91 1.2.0 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2
backup / src / JetBackup / Settings / General.php
backup / src / JetBackup / Settings Last commit date
.htaccess 1 year ago Automation.php 10 months ago General.php 3 months ago Integrations.php 4 months ago Logging.php 4 months ago Maintenance.php 4 months ago Notifications.php 4 months ago Performance.php 3 months ago Restore.php 1 year ago Security.php 1 day ago Settings.php 4 months ago Updates.php 4 months ago index.html 1 year ago web.config 1 year ago
General.php
275 lines
1 <?php
2
3 namespace JetBackup\Settings;
4
5 use Exception;
6 use JetBackup\Config\Config;
7 use JetBackup\Entities\Util;
8 use JetBackup\Exception\DBException;
9 use JetBackup\Exception\FieldsValidationException;
10 use JetBackup\Exception\JetBackupLinuxException;
11 use JetBackup\Factory;
12 use JetBackup\JetBackup;
13 use JetBackup\JetBackupLinux\JetBackupLinux;
14 use JetBackup\License\License;
15 use JetBackup\Wordpress\Helper;
16 use JetBackup\Wordpress\Wordpress;
17 use SleekDB\Exceptions\InvalidArgumentException;
18 use SleekDB\Exceptions\IOException;
19
20 if (!defined( '__JETBACKUP__')) die('Direct access is not allowed');
21
22 class General extends Settings {
23
24 const SECTION = 'general';
25
26 const TIMEZONE = 'TIMEZONE';
27 const JETBACKUP_INTEGRATION = 'JETBACKUP_INTEGRATION';
28 const JETBACKUP_SOCKET_API_STATUS = 'JETBACKUP_SOCKET_API_STATUS';
29 const JETBACKUP_SOCKET_API_ERROR_MESSAGE = 'JETBACKUP_SOCKET_API_ERROR_MESSAGE';
30 const ADMIN_TOP_MENU_INTEGRATION = 'ADMIN_TOP_MENU_INTEGRATION';
31 const DISPLAY_LOCAL_FREE_DISK_SPACE = 'DISPLAY_LOCAL_FREE_DISK_SPACE';
32 const COMMUNITY_LANGUAGES = 'COMMUNITY_LANGUAGES';
33 const MANUAL_BACKUPS_RETENTION = 'MANUAL_BACKUPS_RETENTION';
34 const IMPORTED_BACKUPS_RETENTION = 'IMPORTED_BACKUPS_RETENTION';
35 const PHP_CLI_LOCATION = 'PHP_CLI_LOCATION';
36 const ALTERNATE_WP_CONFIG_LOCATION = 'ALTERNATE_WP_CONFIG_LOCATION';
37 const MYSQL_DEFAULT_PORT = 'MYSQL_DEFAULT_PORT';
38 const PHP_DEFAULT_BINARY = 'php';
39 const DEFAULT_TIMEZONE = 'UTC';
40 const WORDPRESS_TIMEZONE = 'WORDPRESS_TIMEZONE';
41 const LICENSE_STATUS = 'LICENSE_STATUS';
42
43 private ?bool $socketApiStatus = null;
44 private ?string $socketApiErrMsg = null;
45 /**
46 * @throws InvalidArgumentException
47 * @throws DBException
48 * @throws IOException
49 */
50 public function __construct() {
51 parent::__construct(self::SECTION);
52 }
53
54 /**
55 * @return string
56 */
57 public function getTimeZone():string {
58 $timezone = $this->get(self::TIMEZONE, self::WORDPRESS_TIMEZONE);
59 if ($timezone == self::WORDPRESS_TIMEZONE) return Wordpress::getOption('timezone_string') ?: self::DEFAULT_TIMEZONE;
60 return $timezone;
61 }
62
63 private function getTimeZoneDisplay() {return $this->get(self::TIMEZONE, self::WORDPRESS_TIMEZONE);}
64 /**
65 * @param $value
66 *
67 * @return void
68 */
69 public function setTimeZone($value):void { $this->set(self::TIMEZONE, $value); }
70
71 /**
72 * @return bool
73 */
74 public function isJBIntegrationEnabled():bool { return (bool) $this->get(self::JETBACKUP_INTEGRATION, false); }
75 private function _getSocketApiStatus():bool {
76
77 if ($this->socketApiStatus === null) {
78 if ($this->isJBIntegrationEnabled()) {
79 $this->socketApiStatus = true;
80 } else {
81 try {
82 JetBackupLinux::checkRequirements();
83 JetBackupLinux::getAccountInfo();
84 $this->socketApiStatus = true;
85 } catch (\Exception $e) {
86 $this->socketApiErrMsg = $e->getMessage();
87 $this->socketApiStatus = false;
88 }
89 }
90 }
91 return $this->socketApiStatus;
92
93 }
94
95 private function _getSocketApiErrorMessage():?string {
96 return $this->socketApiErrMsg ?? null;
97 }
98
99 public function isAdminTopMenuIntegrationEnabled():bool { return (bool) $this->get(self::ADMIN_TOP_MENU_INTEGRATION, false); }
100 public function isDisplayLocalDiskSpaceEnabled():bool { return (bool) $this->get(self::DISPLAY_LOCAL_FREE_DISK_SPACE, false); }
101
102 /**
103 * @param bool $value
104 *
105 * @return void
106 */
107 public function setJBIntegrationEnabled(bool $value):void { $this->set(self::JETBACKUP_INTEGRATION, $value); }
108 public function setAdminTopMenuIntegration(bool $value):void { $this->set(self::ADMIN_TOP_MENU_INTEGRATION, $value); }
109 public function setDisplayLocalDiskSpace(bool $value):void { $this->set(self::DISPLAY_LOCAL_FREE_DISK_SPACE, $value); }
110
111 /**
112 * @return bool
113 */
114 public function isCommunityLanguages():bool { return (bool) $this->get(self::COMMUNITY_LANGUAGES, true); }
115
116 /**
117 * @param bool $value
118 *
119 * @return void
120 */
121 public function setCommunityLanguages(bool $value):void { $this->set(self::COMMUNITY_LANGUAGES, $value); }
122
123 /**
124 * @return int
125 */
126 public function getManualBackupsRetention():int { return (int) $this->get(self::MANUAL_BACKUPS_RETENTION, 0); }
127
128 /**
129 * @param int $value
130 *
131 * @return void
132 */
133 public function setManualBackupsRetention(int $value):void { $this->set(self::MANUAL_BACKUPS_RETENTION, $value); }
134
135 /**
136 * @return int
137 */
138 public function getImportedBackupsRetention():int { return (int) $this->get(self::IMPORTED_BACKUPS_RETENTION, 10); }
139
140 /**
141 * @param int $value
142 *
143 * @return void
144 */
145 public function setImportedBackupsRetention(int $value):void { $this->set(self::IMPORTED_BACKUPS_RETENTION, $value); }
146
147 /**
148 * @return string
149 */
150 public function getPHPCLILocation():string { return $this->get(self::PHP_CLI_LOCATION, self::PHP_DEFAULT_BINARY); }
151 public function getAlternateWpConfigLocation():string {
152 $config = $this->get(trim(self::ALTERNATE_WP_CONFIG_LOCATION, ''));
153 if($config == "" || !$config) $config = JetBackup::WP_ROOT_PATH . JetBackup::SEP . 'wp-config.php'; // we cannot put this is the default response if I add to db and then remove
154 return $config;
155 }
156
157 public function getMysqlDefaultPort():int { return $this->get(self::MYSQL_DEFAULT_PORT, 3306); }
158
159 /**
160 * @param $value
161 *
162 * @return void
163 */
164 public function setPHPCLILocation($value):void { $this->set(self::PHP_CLI_LOCATION, $value); }
165 public function setAlternateWpConfigLocation($value):void { $this->set(self::ALTERNATE_WP_CONFIG_LOCATION, $value); }
166 public function setMysqlDefaultPort($value):void { $this->set(self::MYSQL_DEFAULT_PORT, $value); }
167
168 /**
169 * @return array
170 * @throws Exception
171 */
172 public function getDisplay():array {
173
174 return [
175 Config::LICENSE_KEY => str_repeat('*', max(0, strlen(Factory::getConfig()->getLicenseKey()) - 6)) . substr(Factory::getConfig()->getLicenseKey(), -4),
176 self::LICENSE_STATUS => License::getLicenseStatus(),
177 self::TIMEZONE => $this->getTimeZoneDisplay(),
178 self::COMMUNITY_LANGUAGES => $this->isCommunityLanguages() ? 1 : 0,
179 self::JETBACKUP_INTEGRATION => $this->_getSocketApiStatus() ? ($this->isJBIntegrationEnabled() ? 1 : 0) : 0,
180 self::JETBACKUP_SOCKET_API_STATUS => $this->_getSocketApiStatus() ? 1 : 0,
181 self::JETBACKUP_SOCKET_API_ERROR_MESSAGE => $this->_getSocketApiErrorMessage(),
182 self::ADMIN_TOP_MENU_INTEGRATION => $this->isAdminTopMenuIntegrationEnabled() ? 1 : 0,
183 self::DISPLAY_LOCAL_FREE_DISK_SPACE => $this->isDisplayLocalDiskSpaceEnabled() ? 1 : 0,
184 self::MANUAL_BACKUPS_RETENTION => $this->getManualBackupsRetention(),
185 self::IMPORTED_BACKUPS_RETENTION => $this->getImportedBackupsRetention(),
186 self::PHP_CLI_LOCATION => $this->getPHPCLILocation(),
187 self::ALTERNATE_WP_CONFIG_LOCATION => $this->getAlternateWpConfigLocation(),
188 self::MYSQL_DEFAULT_PORT => $this->getMySQLDefaultPort(),
189 ];
190 }
191
192 /**
193 * @return array
194 * @throws Exception
195 */
196 public function getDisplayCLI():array {
197
198 return [
199 'License Key' => str_repeat('*', max(0, strlen(Factory::getConfig()->getLicenseKey()) - 6)) . substr(Factory::getConfig()->getLicenseKey(), -4),
200 'License Status' => License::getLicenseStatus(),
201 'Timezone' => $this->getTimeZoneDisplay(),
202 'Community Languages' => $this->isCommunityLanguages() ? "Yes" : "No",
203 'JetBackup Integration' => $this->_getSocketApiStatus() ? ($this->isJBIntegrationEnabled() ? "Yes" : "No") : "No",
204 'JetBackup Socket API Enabled' => $this->_getSocketApiStatus() ? "Yes" : "No",
205 'JetBackup Socket API Error' => $this->_getSocketApiErrorMessage(),
206 'Admin bar top menu integration' => $this->isAdminTopMenuIntegrationEnabled() ? "Yes" : "No",
207 'Display Local Disk Space' => $this->isDisplayLocalDiskSpaceEnabled() ? "Yes" : "No",
208 'Manual Backup Retain' => $this->getManualBackupsRetention(),
209 'Imported Backup Retain' => $this->getImportedBackupsRetention(),
210 'PHP CLI Location' => $this->getPHPCLILocation(),
211 'Alternate wp-config.php Location' => $this->getAlternateWpConfigLocation(),
212 'MySQL Default Port' => $this->getMysqlDefaultPort(),
213 ];
214 }
215
216 /**
217 * @return void
218 * @throws FieldsValidationException
219 * @throws Exception
220 */
221 public function validateFields():void {
222
223 $changedFields = self::getChangedFields($this->getData(), (new General())->getData());
224
225 if(in_array(self::ALTERNATE_WP_CONFIG_LOCATION, $changedFields) && $this->getAlternateWpConfigLocation()) {
226
227 $alternateLocation = JetBackup::SEP. trim($this->getAlternateWpConfigLocation(), JetBackup::SEP);
228 $homedir = JetBackup::SEP . trim(Helper::getUserHomedir() ?? dirname(Wordpress::getAbsPath()), JetBackup::SEP) . JetBackup::SEP;
229
230 if(!str_starts_with($alternateLocation, $homedir)) throw new FieldsValidationException("Alternate location '$alternateLocation' cannot be outside of " . $homedir);
231 if(!is_file($alternateLocation)) throw new FieldsValidationException("Alternate location '$alternateLocation' is not a file or does not exist");
232 if(!is_readable($alternateLocation)) throw new FieldsValidationException("Alternate location '$alternateLocation' is not readable or does not exist");
233
234 try {
235
236 $config = Factory::getWPHelper()::parseWpConfig();
237
238 if(!isset($config->db_name)) throw new FieldsValidationException("Couldn't find database name in configuration");
239 if(!isset($config->db_user)) throw new FieldsValidationException("Couldn't find database user in configuration");
240 if(!isset($config->db_password)) throw new FieldsValidationException("Couldn't find database password in configuration");
241 if(!isset($config->db_host)) throw new FieldsValidationException("Couldn't find database host in configuration");
242 if(!isset($config->db_port)) throw new FieldsValidationException("Couldn't find database port in configuration");
243 if(!isset($config->table_prefix)) throw new FieldsValidationException("Couldn't find database table prefix in configuration");
244
245
246 if($config->db_name != DB_NAME) throw new FieldsValidationException("Database name from alternate config doesn't match runtime database name");
247 if($config->db_user != DB_USER) throw new FieldsValidationException("Database user from alternate config doesn't match runtime database user");
248 if($config->db_password != DB_PASSWORD) throw new FieldsValidationException("Database password from alternate config doesn't match runtime database password");
249
250 } catch (Exception $e) {
251 throw new FieldsValidationException($e->getMessage());
252 }
253 }
254
255 if(in_array(self::TIMEZONE, $changedFields)) {
256 if (!$this->getTimeZone() || ($this->getTimeZone() != self::DEFAULT_TIMEZONE && $this->getTimeZone() != self::WORDPRESS_TIMEZONE && !isset(Util::generateTimeZoneList()[$this->getTimeZone()])))
257 throw new FieldsValidationException("Timezone " . $this->getTimeZone() . " is not valid");
258 }
259
260 if(in_array(self::PHP_CLI_LOCATION, $changedFields)) {
261 if((!$this->getPHPCLILocation() || strtolower($this->getPHPCLILocation()) != self::PHP_DEFAULT_BINARY) && !is_executable(trim($this->getPHPCLILocation())))
262 throw new FieldsValidationException("PHP CLI location ".$this->getPHPCLILocation()." is not executable");
263 }
264
265 if(in_array(self::JETBACKUP_INTEGRATION, $changedFields)) {
266 if($this->isJBIntegrationEnabled()) {
267 try {
268 JetBackupLinux::checkRequirements();
269 } catch(JetBackupLinuxException $e) {
270 throw new FieldsValidationException($e->getMessage());
271 }
272 }
273 }
274 }
275 }