PluginProbe
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! / 3.8.0
Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! v3.8.0
3.8.0 3.7.5 3.7.4 3.7.3 3.7.2 1-final 3.7.1 3.7.0 3.6.8 3.6.7 3.6.6 3.6.5 3.6.4 3.6.3 3.6.2 3.6.1 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 All 112 releases
templately / modules / full-site-import / Utils / LogHandler.php

LogHandler.php in Templately – Elementor & Gutenberg Template Library: 6500+ Free & Pro Ready Templates And Cloud! 3.8.0, at modules/full-site-import/Utils/LogHandler.php

142 lines 4.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Templately\Modules\FullSiteImport\Utils;
3
4 use Templately\Modules\FullSiteImport\FullSiteImport;
5 use Templately\Utils\Helper;
6
7 class LogHandler {
8
9 /**
10 * How many import logs to retain. Support needs the last few runs; the
11 * count, not an age, is the right rule here — an age window would delete
12 * the log of a week-old failure someone is still asking about and keep
13 * hundreds from one busy afternoon.
14 */
15 const KEEP_LOGS = 10;
16
17 public static function get_log_dir() {
18 // Import logs carry pack and session detail and sit in web-served
19 // wp-uploads, so the root gets its access guards on the way past.
20 $log_dir = Helper::upload_dir('log');
21 return $log_dir;
22 }
23
24 public static function get_log_file_path() {
25 $session_id = SessionData::get_session_id();
26 $log_dir = self::get_log_dir();
27 return trailingslashit($log_dir) . "fsi-$session_id.log";
28 }
29
30 public static function create_log_dir() {
31 $upload_dir = wp_upload_dir();
32 $log_dir = self::get_log_dir();
33
34 if (!$log_dir) {
35 return false;
36 }
37
38 if (!is_writable($upload_dir['basedir'])) {
39 return false;
40 }
41
42 if ($session_id = SessionData::get_session_id()) {
43 SessionData::set($session_id, 'log_type', 'file');
44 }
45
46 if (!is_dir($log_dir)) {
47 wp_mkdir_p($log_dir);
48 } else {
49 self::prune_import_logs($log_dir);
50 }
51 }
52
53 /**
54 * Keep only the newest {@see self::KEEP_LOGS} import logs.
55 *
56 * SCOPED TO `fsi-*.log` ON PURPOSE. This used to enumerate the whole
57 * directory (`scandir` minus `.`/`..`), sort by mtime and unlink everything
58 * past the tenth entry — but this directory also holds the access guards
59 * written by `Utils\Log\LogFile::ensure_guards()` (an `.htaccess` deny rule
60 * and a blank `index.php`), the plugin's own hash-named log and its rotated
61 * generation, and the developer HTTP inspector's JSONL file. The guards are
62 * written once and never touched, so they carried the OLDEST mtimes and
63 * were deleted FIRST: after ~11 import sessions an Apache site silently lost
64 * `Require all denied` on a web-reachable directory.
65 *
66 * Counting entries rather than import logs was the second half of the bug —
67 * every guard file present shrank the number of logs actually retained.
68 *
69 * @param string $log_dir Trailing-slashed log directory.
70 * @return void
71 */
72 private static function prune_import_logs($log_dir) {
73 $files = glob($log_dir . 'fsi-*.log');
74
75 if (!is_array($files) || count($files) <= self::KEEP_LOGS) {
76 return;
77 }
78
79 usort($files, function($a, $b) {
80 return filemtime($a) - filemtime($b);
81 });
82
83 foreach (array_slice($files, 0, count($files) - self::KEEP_LOGS) as $file) {
84 unlink($file);
85 }
86 }
87
88 public static function sse_log_file($log) {
89 $file_path = self::get_log_file_path();
90
91 // Write to the log file
92 return file_put_contents($file_path, json_encode($log) . PHP_EOL, FILE_APPEND);
93 }
94
95 public static function read_log_file($start_line = 0) {
96 $file_path = self::get_log_file_path();
97
98 $log = [];
99
100 // Check if SplFileObject exists
101 if (class_exists('SplFileObject')) {
102 try {
103 $file = new \SplFileObject($file_path);
104
105 // Seek to the specified line number (0-indexed in SplFileObject)
106 $file->seek($start_line);
107 while (!$file->eof()) {
108 $line = trim($file->current());
109 if ($line) {
110 $log[] = json_decode($line, true); // JSON decode each line
111 }
112 $file->next();
113 }
114 } catch (\Exception $e) {
115 // Handle exception if file operations fail
116 Helper::log("Failed to read log file: " . $e->getMessage(), 'fsi_log_handler', 'error');
117 }
118 } else {
119 // Fallback if SplFileObject doesn't exist
120 $current_line = 1;
121 $handle = fopen($file_path, "r");
122 if ($handle) {
123 while (($line = fgets($handle)) !== false) {
124 if ($current_line >= $start_line) {
125 $line = trim($line);
126 if ($line) {
127 $log[] = json_decode($line, true); // JSON decode each line
128 }
129 }
130 $current_line++;
131 }
132 fclose($handle);
133 } else {
134 // Handle error if file can't be opened
135 Helper::log("Failed to open log file: $file_path", 'fsi_log_handler', 'error');
136 }
137 }
138
139 return $log;
140 }
141 }
142