PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backups, Restore, Migration & Clone / 4.11.0
WP STAGING – WordPress Backups, Restore, Migration & Clone v4.11.0
4.11.0 4.10.0 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 / Backup / Service / UpdateProtectionHealth.php
wp-staging / Backup / Service Last commit date
Compression 1 day ago Database 1 day ago DirectoryExplorer 1 day ago AbstractBackgroundBackupRequest.php 1 day ago AbstractBackupsFinder.php 1 day ago AbstractExtractor.php 1 day ago AbstractServiceProvider.php 1 day ago Archiver.php 1 day ago BackupAssets.php 1 day ago BackupContent.php 1 day ago BackupMetadataEditor.php 1 day ago BackupMetadataReader.php 1 day ago BackupSigner.php 1 day ago BackupsDirectoryResolver.php 1 day ago BackupsFinder.php 1 day ago BeforeUpdateBackupRequest.php 1 day ago BeforeUpdateBackupsService.php 1 day ago Extractor.php 1 day ago FileBackupService.php 1 day ago FileBackupServiceProvider.php 1 day ago ServiceInterface.php 1 day ago TmpBackupCleaner.php 1 day ago UpdateProtectionHealth.php 1 day ago UpdateProtectionSettings.php 1 day ago ZlibCompressor.php 1 day ago
UpdateProtectionHealth.php
175 lines
1 <?php
2
3 namespace WPStaging\Backup\Service;
4
5
6
7
8
9
10
11
12
13
14
15
16
17 class UpdateProtectionHealth
18 {
19
20 const OPTION_NAME = 'wpstg_update_protection_health';
21
22
23 const REASON_DISK_SPACE = 'disk_space';
24 const REASON_PERMISSIONS = 'permissions';
25
26
27 const REASON_STALLED = 'stalled';
28
29 const REASON_UNKNOWN = 'unknown';
30
31
32 const PERSISTENT_REASONS = [self::REASON_DISK_SPACE, self::REASON_PERMISSIONS];
33
34
35
36
37
38 const FAILURES_BEFORE_PAUSE = 2;
39
40
41
42
43
44 const PAUSE_DURATION_IN_SECONDS = DAY_IN_SECONDS;
45
46
47
48
49 public function isPaused(): bool
50 {
51 $state = $this->read();
52
53 return !empty($state['paused_until']) && (int)$state['paused_until'] > time();
54 }
55
56
57
58
59 public function getReason(): string
60 {
61 $state = $this->read();
62
63 return isset($state['reason']) ? (string)$state['reason'] : '';
64 }
65
66
67
68
69 public function getMessage(): string
70 {
71 $state = $this->read();
72
73 return isset($state['message']) ? (string)$state['message'] : '';
74 }
75
76
77
78
79
80
81
82
83
84 public function recordFailure(string $message, string $reason = ''): string
85 {
86 $reason = $reason !== '' ? $reason : $this->classify($message);
87 $state = $this->read();
88 $failures = (int)(isset($state['failures']) ? $state['failures'] : 0) + 1;
89
90 $shouldPause = in_array($reason, self::PERSISTENT_REASONS, true) || $failures >= self::FAILURES_BEFORE_PAUSE;
91
92 $this->write([
93 'failures' => $failures,
94 'reason' => $reason,
95 'message' => $message,
96 'failed_at' => time(),
97 'paused_until' => $shouldPause ? time() + self::PAUSE_DURATION_IN_SECONDS : 0,
98 ]);
99
100 return $reason;
101 }
102
103
104
105
106
107
108
109
110 public function recordSuccess()
111 {
112 if ($this->read() === []) {
113 return;
114 }
115
116 delete_option(self::OPTION_NAME);
117 }
118
119
120
121
122
123
124
125 public function resume()
126 {
127 delete_option(self::OPTION_NAME);
128 }
129
130
131
132
133
134 public function classify(string $message): string
135 {
136 if ($message === '') {
137 return self::REASON_UNKNOWN;
138 }
139
140 $haystack = strtolower($message);
141
142 if (strpos($haystack, 'disk space') !== false || strpos($haystack, 'no space left') !== false) {
143 return self::REASON_DISK_SPACE;
144 }
145
146 $permissionMarkers = ['not writable', 'not writeable', 'write permission', 'could not write', 'cannot write', 'permission denied'];
147 foreach ($permissionMarkers as $marker) {
148 if (strpos($haystack, $marker) !== false) {
149 return self::REASON_PERMISSIONS;
150 }
151 }
152
153 return self::REASON_UNKNOWN;
154 }
155
156
157
158
159 private function read(): array
160 {
161 $state = get_option(self::OPTION_NAME, []);
162
163 return is_array($state) ? $state : [];
164 }
165
166
167
168
169
170 private function write(array $state)
171 {
172 update_option(self::OPTION_NAME, $state, false);
173 }
174 }
175