PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backup, Restore, Migration & Clone / 3.0.4
WP STAGING – WordPress Backup, Restore, Migration & Clone v3.0.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 / Framework / Filesystem / DebugLogReader.php
wp-staging / Framework / Filesystem Last commit date
Filters 2 years ago Scanning 5 years ago DebugLogReader.php 2 years ago DirectoryListing.php 3 years ago DiskWriteCheck.php 3 years ago FileObject.php 2 years ago Filesystem.php 2 years ago FilesystemExceptions.php 5 years ago FilterableDirectoryIterator.php 3 years ago LogCleanup.php 2 years ago MissingFileException.php 3 years ago PathChecker.php 2 years ago PathIdentifier.php 2 years ago Permissions.php 5 years ago WpUploadsFolderSymlinker.php 5 years ago
DebugLogReader.php
148 lines
1 <?php
2
3 namespace WPStaging\Framework\Filesystem;
4
5 use WPStaging\Framework\Security\Capabilities;
6
7 class DebugLogReader
8 {
9 protected $filesystem;
10
11 public function __construct(Filesystem $filesystem)
12 {
13 $this->filesystem = $filesystem;
14 }
15
16 /**
17 * Deletes a log file if requested.
18 */
19 public function listenDeleteLogRequest()
20 {
21 if (!isset($_GET['deleteLog']) || !isset($_GET['deleteLogNonce'])) {
22 return;
23 }
24
25 if (!current_user_can((new Capabilities())->manageWPSTG()) || !wp_verify_nonce($_GET['deleteLogNonce'], 'wpstgDeleteLogNonce')) {
26 return;
27 }
28
29 if ($_GET['deleteLog'] === 'wpstaging') {
30 $this->deleteWpStagingDebugLogFile();
31 }
32
33 if ($_GET['deleteLog'] === 'php') {
34 $this->deletePhpDebugLogFile();
35 }
36
37 // Redirect to prevent refresh from deleting the log again
38 wp_redirect(admin_url() . 'admin.php?page=wpstg-tools&tab=system-info');
39 exit;
40 }
41
42 /**
43 * @return bool|null Whether the log file was deleted or not.
44 */
45 public function deletePhpDebugLogFile()
46 {
47 $phpDebugLogFile = ini_get('error_log');
48
49 if (file_exists($phpDebugLogFile) && is_writable($phpDebugLogFile)) {
50 return unlink($phpDebugLogFile);
51 }
52
53 return null;
54 }
55
56 /**
57 * @return bool|null
58 */
59 public function deleteWpStagingDebugLogFile()
60 {
61 if (file_exists(WPSTG_DEBUG_LOG_FILE) && is_writable(WPSTG_DEBUG_LOG_FILE)) {
62 return unlink(WPSTG_DEBUG_LOG_FILE);
63 }
64
65 return null;
66 }
67
68 /**
69 * @param int $maxSizeEach Max size in bytes to fetch from each log.
70 * @param bool $withWpstgDebugLog Whether to include WP STAGING custom log entries.
71 * @param bool $withPhpDebugLog Whether to include PHP error_log entries.
72 *
73 * @return string A formatted text with the last log entries from the debug log files.
74 */
75 public function getLastLogEntries($maxSizeEach, $withWpstgDebugLog = true, $withPhpDebugLog = true)
76 {
77 $errors = '';
78
79 if ($withWpstgDebugLog) {
80 if (defined('WPSTG_DEBUG_LOG_FILE')) {
81 if ($this->filesystem->isReadableFile(WPSTG_DEBUG_LOG_FILE)) {
82 $errors .= sprintf(
83 "--- WP STAGING Debug Logs\nFile: %s\nTotal file size: %s\nShowing last: %s\n\n=== START ===\n\n",
84 WPSTG_DEBUG_LOG_FILE,
85 size_format(filesize(WPSTG_DEBUG_LOG_FILE)),
86 size_format($maxSizeEach)
87 );
88 $errors .= $this->getDebugLogLines(WPSTG_DEBUG_LOG_FILE, $maxSizeEach);
89 $errors .= "=== END ===\n\n";
90 } else {
91 $errors .= "\n=== File WPSTG_DEBUG_LOG_FILE is not readable or does not exist ===\n";
92 }
93 } else {
94 $errors .= "\n=== WPSTG_DEBUG_LOG_FILE NOT DEFINED ===\n";
95 }
96 }
97
98 if ($withPhpDebugLog) {
99 /** @see \wp_debug_mode to understand why it uses ini_get() */
100 $phpDebugLogFile = ini_get('error_log');
101
102 if ($this->filesystem->isReadableFile($phpDebugLogFile)) {
103 $errors .= sprintf(
104 "--- PHP debug.log \nFile: %s\nTotal file size: %s\nShowing last: %s\n\n=== START ===\n\n",
105 $phpDebugLogFile,
106 size_format(filesize($phpDebugLogFile)),
107 size_format($maxSizeEach)
108 );
109 $errors .= $this->getDebugLogLines($phpDebugLogFile, $maxSizeEach);
110 $errors .= "=== END ===\n\n";
111 } else {
112 $errors .= "\n=== PHP DEBUG LOG FILE IS NOT A FILE OR IS NOT READABLE ===\n";
113 }
114 }
115
116 return $errors;
117 }
118
119 protected function getDebugLogLines($debugLogPath, $maxSize)
120 {
121 if (!is_file($debugLogPath) || !is_readable($debugLogPath)) {
122 return '';
123 }
124
125 try {
126 $debugFile = new FileObject($debugLogPath, 'r');
127
128 $negativeOffset = $maxSize;
129
130 // Set the pointer to the end of the file, minus the negative offset for which to start looking for errors.
131 $debugFile->fseek(max($debugFile->getSize() - $negativeOffset, 0), SEEK_SET);
132
133 $debugLines = [];
134
135 do {
136 $line = trim($debugFile->readAndMoveNext());
137 $line = html_entity_decode($line);
138 $line = sanitize_text_field($line);
139 $debugLines[] = $line;
140 } while ($debugFile->valid());
141
142 return implode("\n", $debugLines);
143 } catch (\Exception $e) {
144 return '';
145 }
146 }
147 }
148