PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backup, Restore, Migration & Clone / 4.9.0
WP STAGING – WordPress Backup, Restore, Migration & Clone v4.9.0
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 / Request / Logs.php
wp-staging / Backup / Request Last commit date
Logs.php 1 year ago
Logs.php
174 lines
1 <?php
2
3 namespace WPStaging\Backup\Request;
4
5 use WPStaging\Core\WPStaging;
6 use WPStaging\Framework\Adapter\Directory;
7 use WPStaging\Framework\Filesystem\DebugLogReader;
8 use WPStaging\Framework\Filesystem\FileObject;
9 use WPStaging\Framework\Filesystem\Filesystem;
10 use WPStaging\Framework\Security\Capabilities;
11 use WPStaging\Framework\Security\Nonce;
12 use WPStaging\Backup\Entity\BackupMetadata;
13 use WPStaging\Backup\Service\BackupsFinder;
14 use WPStaging\Backend\Modules\SystemInfo;
15
16 class Logs
17 {
18 /** @var BackupsFinder */
19 private $backupsFinder;
20
21 /** @var Nonce */
22 private $nonce;
23
24 /** @var string */
25 private $logsDir;
26
27 public function __construct(BackupsFinder $backupsFinder, Nonce $nonce)
28 {
29 $this->backupsFinder = $backupsFinder;
30 $this->nonce = $nonce;
31 }
32
33 public function download()
34 {
35 if (!current_user_can(WPStaging::make(Capabilities::class)->manageWPSTG())) {
36 return;
37 }
38
39 if (!$this->nonce->requestHasValidNonce('wpstg_log_nonce')) {
40 return;
41 }
42
43 $md5 = isset($_REQUEST['md5']) ? sanitize_text_field($_REQUEST['md5']) : '';
44
45 if (strlen($md5) !== 32) {
46 return;
47 }
48
49 $backups = $this->backupsFinder->findBackups();
50
51 // Early bail: No backups found, nothing to delete
52 if (empty($backups)) {
53 return;
54 }
55
56 /** @var \SplFileInfo $backup */
57 foreach ($backups as $backup) {
58 if ($md5 === md5($backup->getBasename())) {
59 $this->downloadLogs($backup);
60 }
61 }
62 }
63
64 /** @param \SplFileInfo $backup */
65 protected function downloadLogs($backup)
66 {
67 $file = new FileObject($backup->getPathname(), FileObject::MODE_APPEND_AND_READ);
68 /** @var BackupMetadata */
69 $metaData = (new BackupMetadata())->hydrateByFile($file);
70 $id = $metaData->getId();
71 if (empty($id)) {
72 $id = $this->extractIdFromBackup($backup->getBasename('.wpstg'));
73 }
74
75 /**
76 * Lazy loaded
77 * @var Directory
78 */
79 $directory = WPStaging::make(Directory::class);
80 $this->logsDir = $directory->getLogDirectory();
81
82 $logFile = $this->getBackupLogFileName($id);
83
84 $logPath = $this->logsDir . $logFile;
85
86 $this->downloadHeader($metaData->getName() . '_' . $id);
87 $this->downloadSystemInfo();
88 echo esc_html("\n\n" . str_repeat("-", 25) . "\n\n");
89 print('WP STAGING Backup Log: ' . esc_html($id) . PHP_EOL . PHP_EOL);
90 if (!empty($logFile) && file_exists($logPath)) {
91 readfile($logPath);
92 }
93
94 if (file_exists(WPSTG_DEBUG_LOG_FILE)) {
95 print(PHP_EOL . PHP_EOL);
96 $this->readDebugLog(8 * 1024 * 2014);
97 }
98
99 die();
100 }
101
102 private function downloadHeader($backupName)
103 {
104 header('Content-Description: File Download');
105 header('Content-Type: text/plain');
106 header('Content-Disposition: attachment; filename="' . $backupName . '"_logs.log');
107 header('Expires: 0');
108 header('Cache-Control: must-revalidate');
109 header('Pragma: public');
110 flush(); // Flush system output buffer
111 }
112
113 protected function readDebugLog($size)
114 {
115 /** @var DebugLogReader */
116 $debugLog = WPStaging::make(DebugLogReader::class);
117
118 $errors = $debugLog->getLastLogEntries($size, true, false);
119
120 echo str_replace(['&quot;', '&#039;', '&amp;'], ['"', "'", "&"], esc_html($errors)); // phpcs:ignore WPStagingCS.Security.EscapeOutput.OutputNotEscaped
121 }
122
123 /**
124 * @param string $backupName
125 * @return string
126 */
127 protected function extractIdFromBackup($backupName)
128 {
129 $backupMeta = explode('_', $backupName);
130 return trim($backupMeta[count($backupMeta) - 1]);
131 }
132
133 /**
134 * @param string $backupId
135 * @return string
136 */
137 protected function getBackupLogFileName($backupId)
138 {
139 /** @var Filesystem */
140 $filesystem = WPStaging::make(Filesystem::class);
141
142 $iterator = $filesystem->setRecursive(false)
143 ->setDirectory(rtrim($this->logsDir, '/'))
144 ->get();
145
146 /** @var \SplFileInfo $item */
147 foreach ($iterator as $item) {
148 if ($item->getExtension() !== 'log') {
149 continue;
150 }
151
152 $logFile = $item->getBasename('.log');
153 if (strpos($logFile, 'backup_job_') !== 0) {
154 continue;
155 }
156
157 if (strpos(strrev($logFile), strrev($backupId) . '__') === 0) {
158 return $item->getFilename();
159 }
160 }
161
162 return '';
163 }
164
165 /**
166 * @return void
167 */
168 private function downloadSystemInfo()
169 {
170 $systemInfo = WPStaging::make(SystemInfo::class)->get("systemInfo");
171 echo str_replace(['&quot;', '&#039;', '&amp;'], ['"', "'", "&"], esc_html(wp_strip_all_tags($systemInfo))); // phpcs:ignore WPStagingCS.Security.EscapeOutput.OutputNotEscaped
172 }
173 }
174