PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2.1
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2.1
6.2.2 6.2.1 6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 All 155 releases
← All changes | modules/api-backups/classes/class-api-backups-utility.php +701 -636 5.0.3.2 → 6.2.1 View file →
@@ -7,720 +7,785 @@
7 7 */
8 8
9 9 namespace MainWP\Dashboard\Module\ApiBackups;
10 10
11 +use MainWP\Dashboard\MainWP_Credential_Render;
11 12 use MainWP\Dashboard\MainWP_DB;
12 13 use MainWP\Dashboard\MainWP_Logger;
13 14 use MainWP\Dashboard\MainWP_System_Utility;
14 15
16 +// Exit if accessed directly.
17 +if ( ! defined( 'ABSPATH' ) ) {
18 + exit;
19 +}
20 +
21 +
15 22 /**
16 23 * Class Api_Backups_Utility
17 24 */
18 -class Api_Backups_Utility {
25 +class Api_Backups_Utility { //phpcs:ignore -- NOSONAR - multi methods.
19 26
20 - /**
21 - * Instance value.
22 - *
23 - * @var static Default null
24 - */
25 - public static $instance = null;
27 + /**
28 + * Instance value.
29 + *
30 + * @var static Default null
31 + */
32 + public static $instance = null;
26 33
27 - /**
28 - * Get Instance
29 - *
30 - * Creates public static instance.
31 - *
32 - * @static
33 - *
34 - * @return Api_Backups_Utility
35 - */
36 - public static function get_instance() {
37 - if ( null === self::$instance ) {
38 - self::$instance = new self();
39 - }
40 - return self::$instance;
41 - }
34 + /**
35 + * Get Instance
36 + *
37 + * Creates public static instance.
38 + *
39 + * @static
40 + *
41 + * @return Api_Backups_Utility
42 + */
43 + public static function get_instance() {
44 + if ( null === static::$instance ) {
45 + static::$instance = new self();
46 + }
47 + return static::$instance;
48 + }
42 49
43 - /**
44 - * Method __construct.
45 - */
46 - public function __construct() {
47 - // contructor.
48 - }
50 + /**
51 + * Method __construct.
52 + */
53 + public function __construct() {
54 + // contructor.
55 + }
49 56
50 - /**
51 - * Method count_child_sites().
52 - */
53 - public function count_child_sites() {
54 - $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_wp_for_current_user() );
57 + /**
58 + * Method count_child_sites().
59 + */
60 + public function count_child_sites() {
61 + $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_wp_for_current_user() );
55 62
56 - if ( ! empty( $websites ) ) {
57 - $sites_count = MainWP_DB::num_rows( $websites );
58 - }
59 - // Free result set.
60 - Api_Backups_Helper::free_result( $websites );
63 + if ( ! empty( $websites ) ) {
64 + $sites_count = MainWP_DB::num_rows( $websites );
65 + }
66 + // Free result set.
67 + Api_Backups_Helper::free_result( $websites );
61 68
62 - return $sites_count;
63 - }
69 + return $sites_count;
70 + }
64 71
65 - /**
66 - * Get timestamp.
67 - *
68 - * @param int $timestamp Holds Timestamp.
69 - *
70 - * @return float|int Return GMT offset.
71 - */
72 - public static function get_timestamp( $timestamp = false ) {
73 - if ( empty( $timestamp ) ) {
74 - $timestamp = time();
75 - }
76 - $gmtOffset = get_option( 'gmt_offset' );
72 + /**
73 + * Get timestamp.
74 + *
75 + * @param int $timestamp Holds Timestamp.
76 + *
77 + * @return float|int Return GMT offset.
78 + */
79 + public static function get_timestamp( $timestamp = false ) {
80 + if ( empty( $timestamp ) ) {
81 + $timestamp = time();
82 + }
83 + $gmtOffset = get_option( 'gmt_offset' );
77 84
78 - return ( $gmtOffset ? ( $gmtOffset * HOUR_IN_SECONDS ) + $timestamp : $timestamp );
79 - }
85 + return $gmtOffset ? ( $gmtOffset * HOUR_IN_SECONDS ) + $timestamp : $timestamp;
86 + }
80 87
81 - /**
82 - * Format timestamp.
83 - *
84 - * @param int $timestamp Holds Timestamp.
85 - * @param bool $gmt Whether to set as General mountain time. Default: FALSE.
86 - *
87 - * @return string Return Timestamp.
88 - */
89 - public static function format_timestamp( $timestamp, $gmt = false ) {
90 - return date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $timestamp, $gmt );
91 - }
88 + /**
89 + * Format timestamp.
90 + *
91 + * @param int $timestamp Holds Timestamp.
92 + * @param bool $gmt Whether to set as General mountain time. Default: FALSE.
93 + *
94 + * @return string Return Timestamp.
95 + */
96 + public static function format_timestamp( $timestamp, $gmt = false ) {
97 + return date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $timestamp, $gmt );
98 + }
92 99
93 - /**
94 - * Format datestamp.
95 - *
96 - * @param int $timestamp Holds Timestamp.
97 - * @param bool $gmt Whether to set as General mountain time. Default: FALSE.
98 - *
99 - * @return string Return Timestamp.
100 - */
101 - public static function format_datestamp( $timestamp, $gmt = false ) {
102 - return date_i18n( get_option( 'date_format' ), $timestamp, $gmt );
103 - }
100 + /**
101 + * Format datestamp.
102 + *
103 + * @param int $timestamp Holds Timestamp.
104 + * @param bool $gmt Whether to set as General mountain time. Default: FALSE.
105 + *
106 + * @return string Return Timestamp.
107 + */
108 + public static function format_datestamp( $timestamp, $gmt = false ) {
109 + return date_i18n( get_option( 'date_format' ), $timestamp, $gmt );
110 + }
104 111
105 - /**
106 - * Method map_fields()
107 - *
108 - * Map Site.
109 - *
110 - * @param mixed $website Website to map.
111 - * @param mixed $keys Keys to map.
112 - * @param bool $object_output Output format array|object.
113 - *
114 - * @return object $outputSite Mapped site.
115 - */
116 - public static function map_fields( &$website, $keys, $object_output = false ) {
117 - $outputSite = array();
118 - if ( ! empty( $website ) ) {
119 - if ( is_object( $website ) ) {
120 - foreach ( $keys as $key ) {
121 - if ( property_exists( $website, $key ) ) {
122 - $outputSite[ $key ] = $website->$key;
123 - }
124 - }
125 - } elseif ( is_array( $website ) ) {
126 - foreach ( $keys as $key ) {
127 - $outputSite[ $key ] = $website[ $key ];
128 - }
129 - }
130 - }
112 + /**
113 + * Method map_fields()
114 + *
115 + * Map Site.
116 + *
117 + * @param mixed $website Website to map.
118 + * @param mixed $keys Keys to map.
119 + * @param bool $object_output Output format array|object.
120 + *
121 + * @return object $outputSite Mapped site.
122 + */
123 + public static function map_fields( &$website, $keys, $object_output = false ) { //phpcs:ignore -- NOSONAR - complex.
124 + $outputSite = array();
125 + if ( ! empty( $website ) ) {
126 + if ( is_object( $website ) ) {
127 + foreach ( $keys as $key ) {
128 + if ( property_exists( $website, $key ) ) {
129 + $outputSite[ $key ] = $website->$key;
130 + }
131 + }
132 + } elseif ( is_array( $website ) ) {
133 + foreach ( $keys as $key ) {
134 + $outputSite[ $key ] = $website[ $key ];
135 + }
136 + }
137 + }
131 138
132 - if ( $object_output ) {
133 - return (object) $outputSite;
134 - } else {
135 - return $outputSite;
136 - }
137 - }
139 + if ( $object_output ) {
140 + return (object) $outputSite;
141 + } else {
142 + return $outputSite;
143 + }
144 + }
138 145
139 - /**
140 - * Method array_sort()
141 - *
142 - * Sort given array by given flags.
143 - *
144 - * @param mixed $arr Array to sort.
145 - * @param mixed $key Array key.
146 - * @param string $sort_flag Flags to sort by. Default = SORT_STRING.
147 - */
148 - public static function array_sort( &$arr, $key, $sort_flag = SORT_STRING ) {
149 - $sorter = array();
150 - $ret = array();
151 - reset( $arr );
152 - foreach ( $arr as $ii => $val ) {
153 - $sorter[ $ii ] = $val[ $key ];
154 - }
155 - asort( $sorter, $sort_flag );
156 - foreach ( $sorter as $ii => $val ) {
157 - $ret[ $ii ] = $arr[ $ii ];
158 - }
159 - $arr = $ret;
160 - }
146 + /**
147 + * Method array_sort()
148 + *
149 + * Sort given array by given flags.
150 + *
151 + * @param mixed $arr Array to sort.
152 + * @param mixed $key Array key.
153 + * @param string $sort_flag Flags to sort by. Default = SORT_STRING.
154 + */
155 + public static function array_sort( &$arr, $key, $sort_flag = SORT_STRING ) {
156 + $sorter = array();
157 + $ret = array();
158 + reset( $arr );
159 + foreach ( $arr as $ii => $val ) {
160 + $sorter[ $ii ] = $val[ $key ];
161 + }
162 + asort( $sorter, $sort_flag );
163 + foreach ( $sorter as $ii => $val ) {
164 + $ret[ $ii ] = $arr[ $ii ];
165 + }
166 + $arr = $ret;
167 + }
161 168
162 - /**
163 - * Debugging log info.
164 - *
165 - * Sets logging for debugging purpose
166 - *
167 - * @param string $message Log info message.
168 - */
169 - public static function log_info( $message ) {
170 - self::log_debug( $message, 2 );
171 - }
169 + /**
170 + * Debugging log info.
171 + *
172 + * Sets logging for debugging purpose
173 + *
174 + * @param string $message Log info message.
175 + */
176 + public static function log_info( $message ) {
177 + static::log_debug( $message, 2 );
178 + }
172 179
173 - /**
174 - * Debugging log.
175 - *
176 - * Sets logging for debugging purpose.
177 - *
178 - * @param string $message Log debug message.
179 - * @param int $log_color Log color.
180 - */
181 - public static function log_debug( $message, $log_color = 3 ) {
182 - if ( is_array( $message ) || is_object( $message ) ) {
183 - $message = print_r( $message, true ); //phpcs:ignore
184 - } elseif ( ! is_string( $message ) ) {
185 - $message = 'undefined';
186 - }
180 + /**
181 + * Debugging log.
182 + *
183 + * Sets logging for debugging purpose.
184 + *
185 + * @param string $message Log debug message.
186 + * @param int $log_color Log color.
187 + */
188 + public static function log_debug( $message, $log_color = 3 ) {
189 + if ( is_array( $message ) || is_object( $message ) ) {
190 + $message = print_r( $message, true ); //phpcs:ignore
191 + } elseif ( ! is_string( $message ) ) {
192 + $message = 'undefined';
193 + }
187 194
188 - if ( ! in_array( $log_color, array( 0, 1, 2, 3 ) ) ) {
189 - $log_color = 3;
190 - }
191 - do_action( 'mainwp_log_action', 'API Backups :: ' . $message, MainWP_Logger::API_BACKUPS_LOG_PRIORITY, $log_color );
192 - }
195 + if ( ! in_array( $log_color, array( 0, 1, 2, 3 ) ) ) {
196 + $log_color = 3;
197 + }
198 + do_action( 'mainwp_log_action', 'API Backups :: ' . $message, MainWP_Logger::API_BACKUPS_LOG_PRIORITY, $log_color );
199 + }
193 200
194 - /**
195 - *
196 - * Method save_lasttime_backup().
197 - *
198 - * @param int $site_id site id.
199 - * @param int $available_backups Available backups.
200 - * @param string $backup_api API backups provider.
201 - *
202 - * @return mixed
203 - */
204 - public static function save_lasttime_backup( $site_id, $available_backups, $backup_api ) { //phpcs:ignore -- complex method.
201 + /**
202 + *
203 + * Method save_lasttime_backup().
204 + *
205 + * @param int $site_id site id.
206 + * @param int $available_backups Available backups.
207 + * @param string $backup_api API backups provider.
208 + *
209 + * @return mixed
210 + */
211 + public static function save_lasttime_backup( $site_id, $available_backups, $backup_api ) { //phpcs:ignore -- NOSONAR - complex method.
205 212
206 - self::log_debug( 'save backup time :: [available backups=' . ( is_string( $available_backups ) ? $available_backups : 'is not string' ) . ']' );
213 + static::log_debug( 'save backup time :: [available backups=' . ( is_string( $available_backups ) ? $available_backups : 'is not string' ) . ']' );
207 214
208 - if ( empty( $available_backups ) ) {
209 - return;
210 - }
215 + if ( empty( $available_backups ) ) {
216 + return;
217 + }
211 218
212 - if ( is_string( $available_backups ) ) {
213 - $available_backups = json_decode( $available_backups );
214 - }
219 + if ( is_string( $available_backups ) ) {
220 + $available_backups = json_decode( $available_backups );
221 + }
215 222
216 - $primaryBackup = MainWP_System_Utility::get_primary_backup();
223 + $primaryBackup = MainWP_System_Utility::get_primary_backup();
217 224
218 - if ( 'module-api-backups' !== $primaryBackup ) {
219 - return;
220 - }
225 + $website = Api_Backups_Helper::get_website_by_id( $site_id );
221 226
222 - $lasttime_backup = 0;
223 - if ( 'plesk' === $backup_api ) {
224 - $available_backups = is_object( $available_backups ) && ! empty( $available_backups->value ) ? $available_backups->value : array();
225 - if ( is_array( $available_backups ) ) {
226 - foreach ( $available_backups as $backup ) {
227 - if ( is_object( $backup ) && ! empty( $backup->value->createdAt->value ) ) {
228 - $backup_time = strtotime( $backup->value->createdAt->value );
229 - if ( $backup_time > $lasttime_backup ) {
230 - $lasttime_backup = $backup_time;
231 - }
232 - }
233 - }
234 - }
235 - } elseif ( 'cpanel_auto' === $backup_api ) {
236 - if ( is_object( $available_backups ) && isset( $available_backups->data ) ) {
237 - $available_backups_automatic_list = $available_backups->data;
238 - } else {
239 - $available_backups_automatic_list = array();
240 - }
227 + $backup_method = '';
228 + if ( is_array( $website ) && isset( $website['primary_backup_method'] ) ) {
229 + if ( '' === $website['primary_backup_method'] || 'global' === $website['primary_backup_method'] ) {
230 + $backup_method = $primaryBackup;
231 + } else {
232 + $backup_method = $website['primary_backup_method'];
233 + }
234 + }
241 235
242 - if ( is_array( $available_backups_automatic_list ) ) {
243 - foreach ( $available_backups_automatic_list as $backup ) {
244 - if ( is_object( $backup ) && ! empty( $backup->backupID ) ) {
245 - $backup_time = strtotime( $backup->backupID );
246 - if ( $backup_time > $lasttime_backup ) {
247 - $lasttime_backup = $backup_time;
248 - }
249 - }
250 - }
251 - }
252 - } elseif ( 'cpanel_manual' === $backup_api ) {
253 - $available_backups_manual_list = $available_backups;
254 - if ( is_array( $available_backups_manual_list ) ) {
255 - foreach ( $available_backups_manual_list as $backup ) {
256 - if ( is_object( $backup ) && ! empty( $backup->timestamp ) ) {
257 - $backup_time = $backup->timestamp;
258 - if ( $backup_time > $lasttime_backup ) {
259 - $lasttime_backup = $backup_time;
260 - }
261 - }
262 - }
263 - }
264 - } elseif ( 'cpanel_wp_toolkit' === $backup_api ) {
265 - $available_backups_manual_list = $available_backups;
266 - if ( is_array( $available_backups_manual_list ) ) {
267 - foreach ( $available_backups_manual_list as $backup ) {
268 - if ( is_object( $backup ) && ! empty( $backup->value->createdAt->value ) ) {
269 - $backup_time = strtotime( $backup->value->createdAt->value );
270 - if ( $backup_time > $lasttime_backup ) {
271 - $lasttime_backup = $backup_time;
272 - }
273 - }
274 - }
275 - }
276 - } elseif ( 'gridpane' === $backup_api ) {
277 - if ( isset( $available_backups->automatic ) ) {
278 - $available_backups_automatic_list = explode( ',', $available_backups->automatic );
279 - } else {
280 - $available_backups_automatic_list = array();
281 - }
282 - if ( isset( $available_backups->manual ) ) {
283 - $available_backups_manual_list = explode( ',', $available_backups->manual );
284 - } else {
285 - $available_backups_manual_list = array();
286 - }
287 - // to do check date created: $api_response->backups->local.
236 + if ( 'module-api-backups' !== $backup_method ) {
237 + return;
238 + }
288 239
289 - if ( is_array( $available_backups_automatic_list ) ) {
290 - foreach ( $available_backups_automatic_list as $backup_name ) {
291 - $backup_time = substr( $backup_name, 0, 16 ); // get date time string in name.
292 - $backup_time = strtotime( $backup_time );
293 - if ( $backup_time > $lasttime_backup ) {
294 - $lasttime_backup = $backup_time;
295 - }
296 - }
297 - }
240 + $lasttime_backup = 0;
241 + if ( 'plesk' === $backup_api ) {
242 + $available_backups = is_object( $available_backups ) && ! empty( $available_backups->value ) ? $available_backups->value : array();
243 + if ( is_array( $available_backups ) ) {
244 + foreach ( $available_backups as $backup ) {
245 + if ( is_object( $backup ) && ! empty( $backup->value->createdAt->value ) ) {
246 + $backup_time = strtotime( $backup->value->createdAt->value );
247 + if ( $backup_time > $lasttime_backup ) {
248 + $lasttime_backup = $backup_time;
249 + }
250 + }
251 + }
252 + }
253 + } elseif ( 'kinsta' === $backup_api ) {
254 + $available_backups = is_array( $available_backups ) && ! empty( $available_backups ) ? $available_backups : array();
255 + if ( is_array( $available_backups ) ) {
256 + foreach ( $available_backups as $backup ) {
257 + if ( is_object( $backup ) && ! empty( $backup->created_at ) ) {
258 + $milliseconds = $backup->created_at;
259 + $epoch = $milliseconds / 1000;
260 + $backup_time = strtotime( $epoch );
261 + if ( $backup_time > $lasttime_backup ) {
262 + $lasttime_backup = $backup_time;
263 + }
264 + }
265 + }
266 + }
267 + } elseif ( 'cpanel_auto' === $backup_api ) {
268 + if ( is_object( $available_backups ) && isset( $available_backups->data ) ) {
269 + $available_backups_automatic_list = $available_backups->data;
270 + } else {
271 + $available_backups_automatic_list = array();
272 + }
298 273
299 - if ( is_array( $available_backups_manual_list ) ) {
300 - foreach ( $available_backups_manual_list as $backup_name ) {
301 - $backup_time = substr( $backup_name, 0, 16 ); // get date time string in name.
302 - $backup_time = strtotime( $backup_time );
303 - if ( $backup_time > $lasttime_backup ) {
304 - $lasttime_backup = $backup_time;
305 - }
306 - }
307 - }
308 - } elseif ( 'cloudways' === $backup_api ) {
309 - if ( isset( $available_backups->application_backup_exists ) && true === $available_backups->application_backup_exists ) {
310 - $available_backups = $available_backups->backup_dates;
311 - } else {
312 - $available_backups = array();
313 - }
274 + if ( is_array( $available_backups_automatic_list ) ) {
275 + foreach ( $available_backups_automatic_list as $backup ) {
276 + if ( is_object( $backup ) && ! empty( $backup->backupID ) ) {
277 + $backup_time = strtotime( $backup->backupID );
278 + if ( $backup_time > $lasttime_backup ) {
279 + $lasttime_backup = $backup_time;
280 + }
281 + }
282 + }
283 + }
284 + } elseif ( 'cpanel_manual' === $backup_api ) {
285 + $available_backups_manual_list = $available_backups;
286 + if ( is_array( $available_backups_manual_list ) ) {
287 + foreach ( $available_backups_manual_list as $backup ) {
288 + if ( is_object( $backup ) && ! empty( $backup->timestamp ) ) {
289 + $backup_time = $backup->timestamp;
290 + if ( $backup_time > $lasttime_backup ) {
291 + $lasttime_backup = $backup_time;
292 + }
293 + }
294 + }
295 + }
296 + } elseif ( 'cpanel_wp_toolkit' === $backup_api ) {
297 + $available_backups_manual_list = $available_backups;
298 + if ( is_array( $available_backups_manual_list ) ) {
299 + foreach ( $available_backups_manual_list as $backup ) {
300 + if ( is_object( $backup ) && ! empty( $backup->value->createdAt->value ) ) {
301 + $backup_time = strtotime( $backup->value->createdAt->value );
302 + if ( $backup_time > $lasttime_backup ) {
303 + $lasttime_backup = $backup_time;
304 + }
305 + }
306 + }
307 + }
308 + } elseif ( 'gridpane' === $backup_api ) {
309 + if ( isset( $available_backups->automatic ) ) {
310 + $available_backups_automatic_list = explode( ',', $available_backups->automatic );
311 + } else {
312 + $available_backups_automatic_list = array();
313 + }
314 + if ( isset( $available_backups->manual ) ) {
315 + $available_backups_manual_list = explode( ',', $available_backups->manual );
316 + } else {
317 + $available_backups_manual_list = array();
318 + }
319 + // to do check date created: $api_response->backups->local.
314 320
315 - if ( is_array( $available_backups ) ) {
316 - foreach ( $available_backups as $backup ) {
317 - $backup_time = strtotime( $backup );
318 - if ( $backup_time > $lasttime_backup ) {
319 - $lasttime_backup = $backup_time;
320 - }
321 - }
322 - }
323 - } elseif ( 'vultr' === $backup_api ) {
324 - if ( isset( $available_backups->snapshots ) ) {
325 - $available_snapshots_list = $available_backups->snapshots;
326 - } else {
327 - $available_snapshots_list = array();
328 - }
329 - if ( isset( $available_backups->backups ) ) {
330 - $available_backups_list = $available_backups->backups;
331 - } else {
332 - $available_backups_list = array();
333 - }
334 - if ( is_array( $available_snapshots_list ) ) {
335 - foreach ( $available_snapshots_list as $backup ) {
336 - if ( is_object( $backup ) && ! empty( $backup->date_created ) ) {
337 - $backup_time = strtotime( $backup->date_created );
338 - if ( $backup_time > $lasttime_backup ) {
339 - $lasttime_backup = $backup_time;
340 - }
341 - }
342 - }
343 - }
344 - if ( is_array( $available_backups_list ) ) {
345 - foreach ( $available_backups_list as $backup ) {
346 - if ( is_object( $backup ) && ! empty( $backup->date_created ) ) {
347 - $backup_time = strtotime( $backup->date_created );
348 - if ( $backup_time > $lasttime_backup ) {
349 - $lasttime_backup = $backup_time;
350 - }
351 - }
352 - }
353 - }
354 - } elseif ( 'linode' === $backup_api ) {
355 - // Automatic Backups.
356 - if ( isset( $available_backups->automatic ) ) {
357 - $available_backups_automatic_list = $available_backups->automatic;
358 - } else {
359 - $available_backups_automatic_list = array();
360 - }
361 - // Manual Backups.
362 - if ( isset( $available_backups->snapshot ) ) {
363 - $available_backups_snapshot_list = $available_backups->snapshot;
364 - } else {
365 - $available_backups_snapshot_list = array();
366 - }
367 - if ( is_array( $available_backups_automatic_list ) ) {
368 - foreach ( $available_backups_automatic_list as $backup ) {
369 - if ( is_object( $backup ) && ! empty( $backup->created ) ) {
370 - $backup_time = strtotime( $backup->created );
371 - if ( $backup_time > $lasttime_backup ) {
372 - $lasttime_backup = $backup_time;
373 - }
374 - }
375 - }
376 - }
377 - if ( is_array( $available_backups_snapshot_list ) ) {
378 - foreach ( $available_backups_snapshot_list as $backup ) {
379 - if ( is_object( $backup ) && ! empty( $backup->created ) ) {
380 - $backup_time = strtotime( $backup->created );
381 - if ( $backup_time > $lasttime_backup ) {
382 - $lasttime_backup = $backup_time;
383 - }
384 - }
385 - }
386 - }
387 - } elseif ( 'digitalocean' === $backup_api ) {
388 - if ( isset( $available_backups->snapshots ) ) {
389 - $available_backups = $available_backups->snapshots;
390 - }
391 - if ( is_array( $available_backups ) ) {
392 - foreach ( $available_backups as $backup ) {
393 - if ( is_object( $backup ) && ! empty( $backup->created_at ) ) {
394 - $backup_time = strtotime( $backup->created_at );
395 - if ( $backup_time > $lasttime_backup ) {
396 - $lasttime_backup = $backup_time;
397 - }
398 - }
399 - }
400 - }
401 - }
321 + if ( is_array( $available_backups_automatic_list ) ) {
322 + foreach ( $available_backups_automatic_list as $backup_name ) {
323 + $backup_time = substr( $backup_name, 0, 16 ); // get date time string in name.
324 + $backup_time = strtotime( $backup_time );
325 + if ( $backup_time > $lasttime_backup ) {
326 + $lasttime_backup = $backup_time;
327 + }
328 + }
329 + }
402 330
403 - if ( empty( $lasttime_backup ) ) {
404 - return;
405 - }
406 - $lastBackup = MainWP_DB::instance()->get_website_option( $site_id, 'primary_lasttime_backup' );
331 + if ( is_array( $available_backups_manual_list ) ) {
332 + foreach ( $available_backups_manual_list as $backup_name ) {
333 + $backup_time = substr( $backup_name, 0, 16 ); // get date time string in name.
334 + $backup_time = strtotime( $backup_time );
335 + if ( $backup_time > $lasttime_backup ) {
336 + $lasttime_backup = $backup_time;
337 + }
338 + }
339 + }
340 + } elseif ( 'cloudways' === $backup_api ) {
341 + if ( isset( $available_backups->application_backup_exists ) && true === $available_backups->application_backup_exists ) {
342 + $available_backups = $available_backups->backup_dates;
343 + } else {
344 + $available_backups = array();
345 + }
407 346
408 - if ( ! empty( $lastBackup ) && $lastBackup > $lasttime_backup ) {
409 - return;
410 - }
411 - self::log_debug( 'save backup time :: [site-id=' . $site_id . '] :: [backup time=' . gmdate( 'Y-m-d H:i:s', $lasttime_backup ) . '] :: [api-backups=' . $backup_api . ']' );
412 - $site = new \stdClass();
413 - $site->id = $site_id;
414 - MainWP_DB::instance()->update_website_option( $site, 'primary_lasttime_backup', $lasttime_backup );
415 - }
347 + if ( is_array( $available_backups ) ) {
348 + foreach ( $available_backups as $backup ) {
349 + $backup_time = strtotime( $backup );
350 + if ( $backup_time > $lasttime_backup ) {
351 + $lasttime_backup = $backup_time;
352 + }
353 + }
354 + }
355 + } elseif ( 'vultr' === $backup_api ) {
356 + if ( isset( $available_backups->snapshots ) ) {
357 + $available_snapshots_list = $available_backups->snapshots;
358 + } else {
359 + $available_snapshots_list = array();
360 + }
361 + if ( isset( $available_backups->backups ) ) {
362 + $available_backups_list = $available_backups->backups;
363 + } else {
364 + $available_backups_list = array();
365 + }
366 + if ( is_array( $available_snapshots_list ) ) {
367 + foreach ( $available_snapshots_list as $backup ) {
368 + if ( is_object( $backup ) && ! empty( $backup->date_created ) ) {
369 + $backup_time = strtotime( $backup->date_created );
370 + if ( $backup_time > $lasttime_backup ) {
371 + $lasttime_backup = $backup_time;
372 + }
373 + }
374 + }
375 + }
376 + if ( is_array( $available_backups_list ) ) {
377 + foreach ( $available_backups_list as $backup ) {
378 + if ( is_object( $backup ) && ! empty( $backup->date_created ) ) {
379 + $backup_time = strtotime( $backup->date_created );
380 + if ( $backup_time > $lasttime_backup ) {
381 + $lasttime_backup = $backup_time;
382 + }
383 + }
384 + }
385 + }
386 + } elseif ( 'linode' === $backup_api ) {
387 + // Automatic Backups.
388 + if ( isset( $available_backups->automatic ) ) {
389 + $available_backups_automatic_list = $available_backups->automatic;
390 + } else {
391 + $available_backups_automatic_list = array();
392 + }
393 + // Manual Backups.
394 + if ( isset( $available_backups->snapshot ) ) {
395 + $available_backups_snapshot_list = $available_backups->snapshot;
396 + } else {
397 + $available_backups_snapshot_list = array();
398 + }
399 + if ( is_array( $available_backups_automatic_list ) ) {
400 + foreach ( $available_backups_automatic_list as $backup ) {
401 + if ( is_object( $backup ) && ! empty( $backup->created ) ) {
402 + $backup_time = strtotime( $backup->created );
403 + if ( $backup_time > $lasttime_backup ) {
404 + $lasttime_backup = $backup_time;
405 + }
406 + }
407 + }
408 + }
409 + if ( is_array( $available_backups_snapshot_list ) ) {
410 + foreach ( $available_backups_snapshot_list as $backup ) {
411 + if ( is_object( $backup ) && ! empty( $backup->created ) ) {
412 + $backup_time = strtotime( $backup->created );
413 + if ( $backup_time > $lasttime_backup ) {
414 + $lasttime_backup = $backup_time;
415 + }
416 + }
417 + }
418 + }
419 + } elseif ( 'digitalocean' === $backup_api ) {
420 + if ( isset( $available_backups->snapshots ) ) {
421 + $available_backups = $available_backups->snapshots;
422 + }
423 + if ( is_array( $available_backups ) ) {
424 + foreach ( $available_backups as $backup ) {
425 + if ( is_object( $backup ) && ! empty( $backup->created_at ) ) {
426 + $backup_time = strtotime( $backup->created_at );
427 + if ( $backup_time > $lasttime_backup ) {
428 + $lasttime_backup = $backup_time;
429 + }
430 + }
431 + }
432 + }
433 + }
416 434
417 - /**
418 - * Show Info Messages
419 - *
420 - * Check whenther or not to show the MainWP Message.
421 - *
422 - * @param string $notice_id Notice ID.
423 - *
424 - * @return bool False if hidden, true to show.
425 - */
426 - public static function show_mainwp_message( $notice_id ) {
427 - $status = get_user_option( 'mainwp_notice_saved_status' );
428 - if ( ! is_array( $status ) ) {
429 - $status = array();
430 - }
431 - if ( isset( $status[ $notice_id ] ) ) {
432 - return false;
433 - }
434 - return true;
435 - }
435 + if ( empty( $lasttime_backup ) ) {
436 + return;
437 + }
438 + $lastBackup = MainWP_DB::instance()->get_website_option( $site_id, 'primary_lasttime_backup' );
436 439
440 + if ( ! empty( $lastBackup ) && $lastBackup > $lasttime_backup ) {
441 + return;
442 + }
443 + static::log_debug( 'save backup time :: [site-id=' . $site_id . '] :: [backup time=' . gmdate( 'Y-m-d H:i:s', $lasttime_backup ) . '] :: [api-backups=' . $backup_api . ']' );
444 + $site = new \stdClass();
445 + $site->id = $site_id;
446 + MainWP_DB::instance()->update_website_option( $site, 'primary_lasttime_backup', $lasttime_backup );
447 + }
437 448
438 - /**
439 - * Method human_filesize()
440 - *
441 - * Convert to human readable file size format,
442 - * (B|kB|MB|GB|TB|PB|EB|ZB|YB).
443 - *
444 - * @param mixed $bytes File in bytes.
445 - * @param integer $decimals Number of decimals to output.
446 - *
447 - * @return string Human readable file size.
448 - */
449 - public static function human_filesize( $bytes, $decimals = 2 ) {
450 - $size = array( 'B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB' );
451 - $factor = floor( ( strlen( $bytes ) - 1 ) / 3 );
449 + /**
450 + * Show Info Messages
451 + *
452 + * Check whenther or not to show the MainWP Message.
453 + *
454 + * @param string $notice_id Notice ID.
455 + *
456 + * @return bool False if hidden, true to show.
457 + */
458 + public static function show_mainwp_message( $notice_id ) {
459 + $status = get_user_option( 'mainwp_notice_saved_status' );
460 + if ( ! is_array( $status ) ) {
461 + $status = array();
462 + }
463 + if ( isset( $status[ $notice_id ] ) ) {
464 + return false;
465 + }
466 + return true;
467 + }
452 468
453 - return sprintf( "%.{$decimals}f", $bytes / pow( 1024, $factor ) ) . @$size[ $factor ]; //phpcs:ignore
454 - }
455 469
470 + /**
471 + * Method human_filesize()
472 + *
473 + * Convert to human readable file size format,
474 + * (B|kB|MB|GB|TB|PB|EB|ZB|YB).
475 + *
476 + * @param mixed $bytes File in bytes.
477 + * @param integer $decimals Number of decimals to output.
478 + *
479 + * @return string Human readable file size.
480 + */
481 + public static function human_filesize( $bytes, $decimals = 2 ) {
482 + $size = array( 'B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB' );
483 + $factor = floor( ( strlen( $bytes ) - 1 ) / 3 );
456 484
457 - /**
458 - * Get Color Code
459 - *
460 - * Returns CSS class to use correct color for the element.
461 - *
462 - * @param int $value value.
463 - *
464 - * @return string CSS class.
465 - */
466 - public static function color_code( $value ) {
467 - $color = '';
468 - if ( 5 < $value ) {
469 - $color = 'red';
470 - } elseif ( 0 < $value && 5 >= $value ) {
471 - $color = 'yellow';
472 - } else {
473 - $color = 'green';
474 - }
475 - return $color;
476 - }
485 + return sprintf( "%.{$decimals}f", $bytes / pow( 1024, $factor ) ) . @$size[ $factor ]; //phpcs:ignore
486 + }
477 487
478 - /**
479 - * Method update_option()
480 - *
481 - * Update option.
482 - *
483 - * @param mixed $option_name Option name.
484 - * @param mixed $option_value Option value.
485 - *
486 - * @return (boolean) False if value was not updated and true if value was updated.
487 - */
488 - public static function update_option( $option_name, $option_value ) {
489 - $success = add_option( $option_name, $option_value, '', 'no' );
490 488
491 - if ( ! $success ) {
492 - $success = update_option( $option_name, $option_value );
493 - }
489 + /**
490 + * Get Color Code
491 + *
492 + * Returns CSS class to use correct color for the element.
493 + *
494 + * @param int $value value.
495 + *
496 + * @return string CSS class.
497 + */
498 + public static function color_code( $value ) {
499 + $color = '';
500 + if ( 5 < $value ) {
501 + $color = 'red';
502 + } elseif ( 0 < $value && 5 >= $value ) {
503 + $color = 'yellow';
504 + } else {
505 + $color = 'green';
506 + }
507 + return $color;
508 + }
494 509
495 - return $success;
496 - }
510 + /**
511 + * Method update_option()
512 + *
513 + * Update option.
514 + *
515 + * @param mixed $option_name Option name.
516 + * @param mixed $option_value Option value.
517 + *
518 + * @return (boolean) False if value was not updated and true if value was updated.
519 + */
520 + public static function update_option( $option_name, $option_value ) {
521 + $success = add_option( $option_name, $option_value, '', 'no' );
497 522
523 + if ( ! $success ) {
524 + $success = update_option( $option_name, $option_value );
525 + }
498 526
499 - /**
500 - * Method encrypt_api_keys
501 - *
502 - * @param string $data data.
503 - * @param int $siteid site id.
504 - * @param string $file_key file key.
505 - * @param string $service_name service name.
506 - *
507 - * Encrypt data.
508 - */
509 - public function encrypt_api_keys( $data, $siteid = false, $file_key = false, $service_name = '' ) {
510 - if ( is_string( $data ) ) {
527 + return $success;
528 + }
511 529
512 - $prefix = 'apibackups_';
513 530
514 - if ( ! empty( $siteid ) ) {
515 - $prefix = $prefix . intval( $siteid ) . '_';
516 - }
531 + /**
532 + * Method encrypt_api_keys
533 + *
534 + * @param string $data data.
535 + * @param int $siteid site id.
536 + * @param string $file_key file key.
537 + * @param string $service_name service name.
538 + *
539 + * Encrypt data.
540 + */
541 + public function encrypt_api_keys( $data, $siteid = false, $file_key = false, $service_name = '' ) {
542 + if ( is_string( $data ) ) {
517 543
518 - if ( ! empty( $service_name ) && is_string( $service_name ) ) {
519 - $prefix = $prefix . $service_name . '_';
520 - }
544 + $prefix = 'apibackups_';
521 545
522 - $result = apply_filters( 'mainwp_encrypt_key_value', false, $data, $prefix, $file_key );
546 + if ( ! empty( $siteid ) ) {
547 + $prefix = $prefix . intval( $siteid ) . '_';
548 + }
523 549
524 - if ( is_array( $result ) && ! empty( $result['encrypted_val'] ) ) {
525 - return $result;
526 - }
527 - }
528 - return $data;
529 - }
550 + if ( ! empty( $service_name ) && is_string( $service_name ) ) {
551 + $prefix = $prefix . $service_name . '_';
552 + }
530 553
531 - /**
532 - * Method decrypt_api_keys
533 - *
534 - * @param mixed $encrypted_data encrypted data.
535 - * @param string $def_val default data.
536 - */
537 - public function decrypt_api_keys( $encrypted_data, $def_val = '' ) {
538 - if ( ! empty( $encrypted_data ) && is_array( $encrypted_data ) && ! empty( $encrypted_data['encrypted_val'] ) ) { // old format.
539 - $result = apply_filters( 'mainwp_decrypt_key_value', false, $encrypted_data, $def_val );
540 - if ( ! empty( $result ) && is_string( $result ) ) {
541 - return $result;
542 - }
543 - }
544 - return $def_val;
545 - }
554 + $result = apply_filters( 'mainwp_encrypt_key_value', false, $data, $prefix, $file_key );
546 555
547 - /**
548 - * Method get_compatible_site_api_key
549 - *
550 - * Encrypt data.
551 - *
552 - * @param string $name name data.
553 - * @param string $def_val default data.
554 - */
555 - public function get_api_key( $name, $def_val = '' ) {
556 + if ( is_array( $result ) && ! empty( $result['encrypted_val'] ) ) {
557 + return $result;
558 + }
559 + }
560 + return $data;
561 + }
556 562
557 - $names = array(
558 - 'vultr',
559 - 'gridpane',
560 - 'linode',
561 - 'digitalocean',
562 - 'cloudways',
563 - 'cpanel',
564 - 'plesk',
565 - );
563 + /**
564 + * Method decrypt_api_keys
565 + *
566 + * @param mixed $encrypted_data encrypted data.
567 + * @param string $def_val default data.
568 + */
569 + public function decrypt_api_keys( $encrypted_data, $def_val = '' ) {
570 + if ( ! empty( $encrypted_data ) && is_array( $encrypted_data ) && ! empty( $encrypted_data['encrypted_val'] ) ) { // old format.
571 + $result = apply_filters( 'mainwp_decrypt_key_value', false, $encrypted_data, $def_val );
572 + if ( ! empty( $result ) && is_string( $result ) ) {
573 + return $result;
574 + }
575 + }
576 + return $def_val;
577 + }
566 578
567 - if ( ! in_array( $name, $names ) ) {
568 - return $def_val;
569 - }
579 + /**
580 + * Method get_compatible_site_api_key
581 + *
582 + * Encrypt data.
583 + *
584 + * @param string $name name data.
585 + * @param string $def_val default data.
586 + * @param string $opt_name Option name.
587 + */
588 + public function get_api_key( $name, $def_val = '', $opt_name = '' ) {
570 589
571 - $encrypted = get_option( 'mainwp_api_backups_' . $name . '_api_key' );
572 - if ( is_array( $encrypted ) && ! empty( $encrypted['file_key'] ) ) {
573 - $key = $this->decrypt_api_keys( $encrypted );
574 - if ( ! empty( $key ) && is_string( $key ) ) {
575 - return $key;
576 - }
577 - }
578 - return $def_val;
579 - }
590 + $names = array(
591 + 'vultr',
592 + 'gridpane',
593 + 'linode',
594 + 'digitalocean',
595 + 'cloudways',
596 + 'cpanel',
597 + 'plesk',
598 + 'kinsta',
599 + );
580 600
581 - /**
582 - * Method update_compatible_site_api_key
583 - *
584 - * Encrypt data.
585 - *
586 - * @param string $name name data.
587 - * @param string $value value data.
588 - */
589 - public function update_api_key( $name, $value ) {
601 + if ( ! in_array( $name, $names ) ) {
602 + return $def_val;
603 + }
590 604
591 - $names = array(
592 - 'vultr',
593 - 'gridpane',
594 - 'linode',
595 - 'digitalocean',
596 - 'cloudways',
597 - 'cpanel',
598 - 'plesk',
599 - );
605 + if ( ! empty( $opt_name ) ) {
606 + $encrypted = get_option( 'mainwp_api_backups_' . $name . '_' . (string) $opt_name );
607 + } else {
608 + $encrypted = get_option( 'mainwp_api_backups_' . $name . '_api_key' );
609 + }
600 610
601 - if ( ! in_array( $name, $names ) ) {
602 - return false;
603 - }
611 + if ( is_array( $encrypted ) && ! empty( $encrypted['file_key'] ) ) {
612 + $key = $this->decrypt_api_keys( $encrypted );
613 + if ( ! empty( $key ) && is_string( $key ) ) {
614 + return $key;
615 + }
616 + }
617 + return $def_val;
618 + }
604 619
605 - $opt_name = 'mainwp_api_backups_' . $name . '_api_key';
606 - $current = get_option( $opt_name );
607 - $key_file = '';
620 + /**
621 + * Method update_compatible_site_api_key
622 + *
623 + * Encrypt data.
624 + *
625 + * @param string $name name data.
626 + * @param string $value value data.
627 + * @param string $opt_name Option name.
628 + */
629 + public function update_api_key( $name, $value, $opt_name = '' ) {
608 630
609 - if ( is_array( $current ) && ! empty( $current['file_key'] ) ) {
610 - $key_file = $current['file_key'];
611 - }
631 + $names = array(
632 + 'vultr',
633 + 'gridpane',
634 + 'linode',
635 + 'digitalocean',
636 + 'cloudways',
637 + 'cpanel',
638 + 'plesk',
639 + 'kinsta',
640 + );
612 641
613 - if ( empty( $value ) ) {
614 - delete_option( $opt_name );
615 - if ( ! empty( $key_file ) ) {
616 - do_action( 'mainwp_delete_key_file', $key_file );
617 - }
618 - return true;
619 - }
642 + if ( ! in_array( $name, $names ) ) {
643 + return false;
644 + }
620 645
621 - $encrypted = $this->encrypt_api_keys( $value, false, $key_file, $name );
622 - if ( is_array( $encrypted ) && ! empty( $encrypted['file_key'] ) ) {
623 - return update_option( $opt_name, $encrypted );
624 - }
646 + // MWP-1543: settings forms render the sentinel ('••••••••') in the
647 + // password input when a value is already stored. A submission that
648 + // returns the sentinel unchanged means "leave existing value alone";
649 + // short-circuit before delete_option / encrypt so no overwrite happens.
650 + if ( MainWP_Credential_Render::is_sentinel( $value ) ) {
651 + return true;
652 + }
625 653
626 - return false;
627 - }
654 + if ( ! empty( $opt_name ) ) {
655 + $opt_name = 'mainwp_api_backups_' . $name . '_' . (string) $opt_name;
656 + } else {
657 + $opt_name = 'mainwp_api_backups_' . $name . '_api_key';
658 + }
628 659
629 - /**
630 - * Method get child site key.
631 - *
632 - * Encrypt data.
633 - *
634 - * @param int $website_id name data.
635 - * @param string $name name data.
636 - * @param string $def_val default data.
637 - */
638 - public function get_child_api_key( $website_id, $name, $def_val = '' ) {
660 + $current = get_option( $opt_name );
661 + $key_file = '';
639 662
640 - $names = array(
641 - 'vultr',
642 - 'gridpane',
643 - 'linode',
644 - 'digitalocean',
645 - 'cloudways',
646 - 'cpanel',
647 - 'plesk',
648 - );
663 + if ( is_array( $current ) && ! empty( $current['file_key'] ) ) {
664 + $key_file = $current['file_key'];
665 + }
649 666
650 - if ( ! in_array( $name, $names ) ) {
651 - return $def_val;
652 - }
667 + if ( empty( $value ) ) {
668 + delete_option( $opt_name );
669 + if ( ! empty( $key_file ) ) {
670 + do_action( 'mainwp_delete_key_file', $key_file );
671 + }
672 + return true;
673 + }
653 674
654 - $opt_name = 'mainwp_api_backups_' . $name . '_api_key';
655 - $opt_encoded = Api_Backups_Helper::get_website_options( $website_id, array( $opt_name ) );
656 - if ( array_key_exists( $opt_name, $opt_encoded ) ) {
657 - $encrypted = json_decode( $opt_encoded[ $opt_name ], true );
658 - } else {
659 - $encrypted = '';
660 - }
675 + $encrypted = $this->encrypt_api_keys( $value, false, $key_file, $name );
676 + if ( is_array( $encrypted ) && ! empty( $encrypted['file_key'] ) ) {
677 + return update_option( $opt_name, $encrypted );
678 + }
661 679
662 - if ( is_array( $encrypted ) && ! empty( $encrypted['file_key'] ) ) {
663 - $key = $this->decrypt_api_keys( $encrypted );
680 + return false;
681 + }
664 682
665 - if ( ! empty( $key ) && is_string( $key ) ) {
666 - return $key;
667 - }
668 - }
669 - return $def_val;
670 - }
683 + /**
684 + * Method get child site key.
685 + *
686 + * Encrypt data.
687 + *
688 + * @param int $website_id name data.
689 + * @param string $name name data.
690 + * @param string $def_val default data.
691 + */
692 + public function get_child_api_key( $website_id, $name, $def_val = '' ) {
671 693
672 - /**
673 - * Method update child api key.
674 - *
675 - * Encrypt data.
676 - *
677 - * @param int $website_id name data.
678 - * @param string $name name data.
679 - * @param string $value value data.
680 - */
681 - public function update_child_api_key( $website_id, $name, $value ) {
694 + $names = array(
695 + 'vultr',
696 + 'gridpane',
697 + 'linode',
698 + 'digitalocean',
699 + 'cloudways',
700 + 'cpanel',
701 + 'plesk',
702 + 'kinsta',
703 + );
682 704
683 - $names = array(
684 - 'vultr',
685 - 'gridpane',
686 - 'linode',
687 - 'digitalocean',
688 - 'cloudways',
689 - 'cpanel',
690 - 'plesk',
691 - );
705 + if ( ! in_array( $name, $names ) ) {
706 + return $def_val;
707 + }
692 708
693 - if ( ! in_array( $name, $names ) ) {
694 - return false;
695 - }
709 + $opt_name = 'mainwp_api_backups_' . $name . '_api_key';
710 + $opt_encoded = Api_Backups_Helper::get_website_options( $website_id, array( $opt_name ) );
711 + if ( array_key_exists( $opt_name, $opt_encoded ) ) {
712 + $encrypted = json_decode( $opt_encoded[ $opt_name ], true );
713 + } else {
714 + $encrypted = '';
715 + }
696 716
697 - $opt_name = 'mainwp_api_backups_' . $name . '_api_key';
698 - $opt_encoded = Api_Backups_Helper::get_website_options( $website_id, array( $opt_name ) );
699 - if ( array_key_exists( $opt_name, $opt_encoded ) ) {
700 - $current = json_decode( $opt_encoded[ $opt_name ], true );
701 - } else {
702 - $current = '';
703 - }
704 - $key_file = '';
705 - if ( is_array( $current ) && ! empty( $current['file_key'] ) ) {
706 - $key_file = $current['file_key'];
707 - }
717 + if ( is_array( $encrypted ) && ! empty( $encrypted['file_key'] ) ) {
718 + $key = $this->decrypt_api_keys( $encrypted );
708 719
709 - // If post $value is empty, delete option.
710 - if ( empty( $value ) ) {
711 - delete_option( $opt_name );
712 - if ( ! empty( $key_file ) ) {
713 - do_action( 'mainwp_delete_key_file', $key_file );
714 - }
715 - return true;
716 - }
720 + if ( ! empty( $key ) && is_string( $key ) ) {
721 + return $key;
722 + }
723 + }
724 + return $def_val;
725 + }
717 726
718 - $encrypted = wp_json_encode( $this->encrypt_api_keys( $value, $website_id, $key_file, $name ) );
727 + /**
728 + * Method update child api key.
729 + *
730 + * Encrypt data.
731 + *
732 + * @param int $website_id name data.
733 + * @param string $name name data.
734 + * @param string $value value data.
735 + */
736 + public function update_child_api_key( $website_id, $name, $value ) {
719 737
720 - if ( ! empty( $encrypted ) ) {
721 - return Api_Backups_Helper::update_website_option( $website_id, $opt_name, $encrypted );
722 - }
738 + $names = array(
739 + 'vultr',
740 + 'gridpane',
741 + 'linode',
742 + 'digitalocean',
743 + 'cloudways',
744 + 'cpanel',
745 + 'plesk',
746 + 'kinsta',
747 + );
723 748
724 - return false;
725 - }
749 + if ( ! in_array( $name, $names ) ) {
750 + return false;
751 + }
752 +
753 + // MWP-1543: same sentinel short-circuit as update_api_key(); the
754 + // per-site Edit Site form renders the sentinel placeholder when a
755 + // value already exists, and an unchanged submission must not
756 + // overwrite the encrypted option with the sentinel string.
757 + if ( MainWP_Credential_Render::is_sentinel( $value ) ) {
758 + return true;
759 + }
760 +
761 + $opt_name = 'mainwp_api_backups_' . $name . '_api_key';
762 + $opt_encoded = Api_Backups_Helper::get_website_options( $website_id, array( $opt_name ) );
763 + if ( array_key_exists( $opt_name, $opt_encoded ) ) {
764 + $current = json_decode( $opt_encoded[ $opt_name ], true );
765 + } else {
766 + $current = '';
767 + }
768 + $key_file = '';
769 + if ( is_array( $current ) && ! empty( $current['file_key'] ) ) {
770 + $key_file = $current['file_key'];
771 + }
772 +
773 + // If post $value is empty, delete option.
774 + if ( empty( $value ) ) {
775 + // Delete the site serviceapi key.
776 + Api_Backups_Helper::update_website_option( $website_id, $opt_name, '' );
777 + if ( ! empty( $key_file ) ) {
778 + do_action( 'mainwp_delete_key_file', $key_file );
779 + }
780 + return true;
781 + }
782 +
783 + $encrypted = wp_json_encode( $this->encrypt_api_keys( $value, $website_id, $key_file, $name ) );
784 +
785 + if ( ! empty( $encrypted ) ) {
786 + return Api_Backups_Helper::update_website_option( $website_id, $opt_name, $encrypted );
787 + }
788 +
789 + return false;
790 + }
726 791 }