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 / Concerns / LogHelper.php

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

222 lines 6.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Templately\Modules\FullSiteImport\Concerns;
4
5 use Templately\Modules\FullSiteImport\Utils\LogHandler;
6 use Templately\Modules\FullSiteImport\Utils\SessionData;
7 use Templately\Modules\FullSiteImport\Utils\Utils;
8 use Templately\Modules\FullSiteImport\Exception\RetryableErrorException;
9 use Templately\Utils\Helper;
10
11 trait LogHelper {
12 private static $ai_last_progress = 0;
13 private $log_types = [
14 ''
15 ];
16
17 /**
18 * The SINGLE producer of an SSE error frame (spec 043 / PRD PHP-4).
19 *
20 * There were three ad-hoc error frames built inline, which is why they had
21 * drifted apart — one hardcoded `retry => true` regardless of whether the
22 * failure could ever succeed on a second attempt, so the UI offered Retry for
23 * terminal errors and the user pressed it to reach the same wall.
24 * Retryability now comes from the exception type.
25 *
26 * It also PERSISTS the error, which is the LiteSpeed fix. LiteSpeed buffers
27 * SSE, so those clients never receive the stream at all — they fall back to
28 * polling `import_status()`, which returned only logs. An import could fail and
29 * the client would poll a silent endpoint forever with no error and no end.
30 * The frame is stored under `templately_fsi_last_error_{session_id}` and
31 * `import_status()` returns it.
32 *
33 * The message is the exception's user-facing text. The TRACE is never included
34 * — it goes to `Helper::log()` (034 FR-003 / 043 FR-008).
35 *
36 * @param \Throwable $error
37 * @param string|null $message Overrides the exception message when the caller
38 * has friendlier copy.
39 * @return void
40 */
41 public function sse_error( $error, $message = null ) {
42 $retry = $error instanceof RetryableErrorException;
43
44 $frame = [
45 'action' => 'error',
46 'status' => 'error',
47 'type' => 'error',
48 'retry' => $retry,
49 'title' => __( 'Oops!', 'templately' ),
50 'message' => $message !== null ? $message : $error->getMessage(),
51 ];
52
53 $this->persist_last_error( $frame );
54
55 $this->sse_message( $frame );
56 }
57
58 /**
59 * Store the last error so a polling (LiteSpeed) client can still learn the
60 * import failed. Best-effort: a storage failure must not mask the error we are
61 * in the middle of reporting.
62 *
63 * @param array $frame
64 * @return void
65 */
66 protected function persist_last_error( array $frame ) {
67 $session_id = isset( $this->session_id ) ? $this->session_id : '';
68
69 if ( empty( $session_id ) ) {
70 return;
71 }
72
73 update_option( 'templately_fsi_last_error_' . $session_id, $frame, false );
74 }
75
76 /**
77 * Read (and clear) the persisted error for a session.
78 *
79 * Cleared on read so a later, successful import of the same session cannot
80 * report a stale failure.
81 *
82 * @param string $session_id
83 * @return array|null
84 */
85 public static function take_last_error( $session_id ) {
86 if ( empty( $session_id ) ) {
87 return null;
88 }
89
90 $key = 'templately_fsi_last_error_' . $session_id;
91 $error = get_option( $key, null );
92
93 if ( ! empty( $error ) ) {
94 delete_option( $key );
95 return $error;
96 }
97
98 return null;
99 }
100
101 public function sse_log( $type, $message, $progress = 1, $action = 'updateLog', $status = null ) {
102 $data = [
103 'action' => $action,
104 'type' => $type,
105 'progress' => $progress,
106 'message' => $message
107 ];
108
109 if ( $progress == 100 && $status == null ) {
110 $data['status'] = 'complete';
111 } elseif ( $status != null ) {
112 $data['status'] = $status;
113 }
114
115 $this->sse_message( $data );
116 }
117
118 public function removeLog( $type ) {
119 $this->sse_message( [
120 'action' => 'removeLog',
121 'type' => $type,
122 'progress' => 100
123 ] );
124 }
125
126 public function sse_message( $data, $ai_content = true ) {
127 // Log the data into debug log file
128 $this->sse_log_file( $data );
129
130 if(Helper::should_flush()){
131 echo "event: message\n";
132 echo 'data: ' . wp_json_encode( $data ) . "\n\n";
133
134 // Extra padding.
135 echo esc_html( ':' . str_repeat( ' ', 2048 ) . "\n\n" );
136
137 flush();
138 if (ob_get_level() > 0) {
139 ob_flush();
140 }
141 }
142
143 // $data = Utils::get_session_data_by_id();
144 // if($ai_content && !empty($data['process_id']) && $data['process_id'] !== 'undefined' && "null" !== $data['process_id']){
145
146 // // wp_cache_delete( 'templately_ai_processed_pages', 'options' );
147 // global $wpdb;
148 // $value = $wpdb->get_var( $wpdb->prepare( "SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1", 'templately_ai_processed_pages' ) );
149 // // You might need to manually unserialize the value if it was serialized
150 // $processed_pages = maybe_unserialize( $value );
151 // // $processed_pages = get_option( "templately_ai_processed_pages", [] );
152
153 // $updated_ids = $processed_pages[$data['process_id']]['pages'] ?? [];
154 // $ai_page_ids = array_reduce($data['ai_page_ids'], 'array_merge', array());
155
156 // // $ai_page_ids = array_filter(array_map('intval', explode(',', $data['ai_page_ids'] ?? '')));
157 // // Calculate progress percentage
158
159 // $total_pages = count($ai_page_ids);
160 // $updated_pages = count($updated_ids);
161 // $progress_percentage = $total_pages > 0 ? round(($updated_pages / $total_pages) * 100) : 0;
162
163 // if( $progress_percentage != self::$ai_last_progress ) {
164 // self::$ai_last_progress = $progress_percentage;
165 // $this->sse_message( [
166 // 'type' => 'ai-content',
167 // 'action' => 'updateLog',
168 // 'progress' => $progress_percentage,
169 // // 'name' => method_exists($runner, 'get_name') ? $runner->get_name() : '',
170 // 'processed_pages' => $processed_pages,
171 // // 'asdfg' => $updated_ids,
172 // ], false );
173 // }
174 // }
175 // else {
176 // $log = get_option( 'templately_fsi_log' ) ?: [];
177 // $log[] = $data;
178 // update_option( 'templately_fsi_log', $log );
179 // }
180 // else if($data['action'] === 'complete' || $data['action'] === 'downloadComplete' || $data['action'] === 'error'){
181 // wp_send_json( $data );
182 // }
183 }
184
185 /**
186 * Printing Error Logs in debug.log file or in option.
187 *
188 * @param mixed $log
189 * @return void
190 */
191 public function sse_log_file( $log ){
192 $session_id = SessionData::get_session_id();
193 $request_params = $session_id ? SessionData::get_data($session_id) : [];
194
195 if (is_array($log)) {
196 $log['timestamp'] = date('Y-m-d H:i:s');
197 }
198
199 if (isset($request_params['log_type']) && $request_params['log_type'] == 'file') {
200 LogHandler::sse_log_file($log);
201 } else {
202 $_log = get_option('templately_fsi_log') ?: [];
203 $_log[] = $log;
204 update_option('templately_fsi_log', $_log, false);
205 }
206 }
207 /**
208 * Printing Error Logs in debug.log file.
209 *
210 * @param mixed $log
211 * @return void
212 */
213 public function debug_log( $log ){
214 if ( defined('TEMPLATELY_EVENT_LOG') && TEMPLATELY_EVENT_LOG === true ) {
215
216 if ( is_array( $log ) || is_object( $log ) || $log ) {
217 Helper::log( $log, 'fsi_event' );
218 }
219
220 }
221 }
222 }