PluginProbe
SuperFrete / 3.3.2
SuperFrete v3.3.2
trunk 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 2.0.0 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 3.2.1 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4
superfrete / app / Controllers / Admin / WebhookAdmin.php

WebhookAdmin.php in SuperFrete 3.3.2, at app/Controllers/Admin/WebhookAdmin.php

352 lines 15.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace SuperFrete_API\Admin;
4
5 use SuperFrete_API\Controllers\WebhookRetryManager;
6 use SuperFrete_API\Helpers\Logger;
7
8 if (!defined('ABSPATH')) {
9 exit; // Security check
10 }
11
12 class WebhookAdmin
13 {
14
15 public function __construct()
16 {
17 add_action('admin_menu', [$this, 'add_admin_menu']);
18 add_action('wp_ajax_superfrete_manual_retry', [$this, 'handle_manual_retry']);
19 add_action('wp_ajax_superfrete_clear_webhook_logs', [$this, 'handle_clear_logs']);
20 }
21
22 /**
23 * Add admin menu for webhook management
24 */
25 public function add_admin_menu()
26 {
27 add_submenu_page(
28 'woocommerce',
29 'SuperFrete Webhooks',
30 'SuperFrete Webhooks',
31 'manage_woocommerce',
32 'superfrete-webhooks',
33 [$this, 'webhook_admin_page']
34 );
35 }
36
37 /**
38 * Display the webhook admin page
39 */
40 public function webhook_admin_page()
41 {
42 $retry_manager = new WebhookRetryManager();
43 $stats = $retry_manager->get_retry_stats();
44 $recent_retries = $retry_manager->get_recent_retries(20);
45 $recent_logs = $this->get_recent_webhook_logs(20);
46
47 ?>
48 <div class="wrap">
49 <h1>SuperFrete Webhooks</h1>
50
51 <div class="superfrete-webhook-stats" style="display: flex; gap: 20px; margin: 20px 0;">
52 <div class="stat-card" style="background: #fff; padding: 15px; border: 1px solid #ddd; border-radius: 5px; min-width: 150px;">
53 <h3 style="margin: 0 0 10px 0;">Total (30 dias)</h3>
54 <p style="font-size: 24px; margin: 0; color: #0073aa;"><?php echo esc_html($stats['total']); ?></p>
55 </div>
56 <div class="stat-card" style="background: #fff; padding: 15px; border: 1px solid #ddd; border-radius: 5px; min-width: 150px;">
57 <h3 style="margin: 0 0 10px 0;">Pendentes</h3>
58 <p style="font-size: 24px; margin: 0; color: #d63638;"><?php echo esc_html($stats['pending']); ?></p>
59 </div>
60 <div class="stat-card" style="background: #fff; padding: 15px; border: 1px solid #ddd; border-radius: 5px; min-width: 150px;">
61 <h3 style="margin: 0 0 10px 0;">Completados</h3>
62 <p style="font-size: 24px; margin: 0; color: #00a32a;"><?php echo esc_html($stats['completed']); ?></p>
63 </div>
64 <div class="stat-card" style="background: #fff; padding: 15px; border: 1px solid #ddd; border-radius: 5px; min-width: 150px;">
65 <h3 style="margin: 0 0 10px 0;">Falharam</h3>
66 <p style="font-size: 24px; margin: 0; color: #d63638;"><?php echo esc_html($stats['failed']); ?></p>
67 </div>
68 </div>
69
70 <div class="superfrete-webhook-actions" style="margin: 20px 0;">
71 <button id="manual-retry-btn" class="button button-primary">Processar Tentativas Manuais</button>
72 <button id="clear-logs-btn" class="button button-secondary">Limpar Logs Antigos</button>
73 </div>
74
75 <h2>Tentativas de Webhook (Últimas 20)</h2>
76 <table class="wp-list-table widefat fixed striped">
77 <thead>
78 <tr>
79 <th>ID</th>
80 <th>Pedido</th>
81 <th>SuperFrete ID</th>
82 <th>Evento</th>
83 <th>Status</th>
84 <th>Tentativas</th>
85 <th>Próxima Tentativa</th>
86 <th>Criado em</th>
87 </tr>
88 </thead>
89 <tbody>
90 <?php if (empty($recent_retries)): ?>
91 <tr>
92 <td colspan="8" style="text-align: center;">Nenhuma tentativa de webhook encontrada.</td>
93 </tr>
94 <?php else: ?>
95 <?php foreach ($recent_retries as $retry): ?>
96 <tr>
97 <td><?php echo esc_html($retry->id); ?></td>
98 <td>
99 <?php if ($retry->order_id): ?>
100 <a href="<?php echo esc_url(admin_url('post.php?post=' . $retry->order_id . '&action=edit')); ?>">
101 #<?php echo esc_html($retry->order_id); ?>
102 </a>
103 <?php else: ?>
104 N/A
105 <?php endif; ?>
106 </td>
107 <td><?php echo esc_html($retry->superfrete_id); ?></td>
108 <td><?php echo esc_html($retry->event_type); ?></td>
109 <td>
110 <span class="status-<?php echo esc_attr($retry->status); ?>" style="
111 padding: 2px 8px;
112 border-radius: 3px;
113 color: white;
114 background: <?php
115 switch($retry->status) {
116 case 'pending': echo '#d63638'; break;
117 case 'completed': echo '#00a32a'; break;
118 case 'failed': echo '#8c8f94'; break;
119 default: echo '#0073aa';
120 }
121 ?>;
122 ">
123 <?php echo esc_html(ucfirst($retry->status)); ?>
124 </span>
125 </td>
126 <td><?php echo esc_html($retry->retry_count . '/' . $retry->max_retries); ?></td>
127 <td>
128 <?php
129 if ($retry->next_retry_at && $retry->status === 'pending') {
130 echo esc_html(date('d/m/Y H:i', strtotime($retry->next_retry_at)));
131 } else {
132 echo '-';
133 }
134 ?>
135 </td>
136 <td><?php echo esc_html(date('d/m/Y H:i', strtotime($retry->created_at))); ?></td>
137 </tr>
138 <?php endforeach; ?>
139 <?php endif; ?>
140 </tbody>
141 </table>
142
143 <h2>Logs de Webhook (Últimos 20)</h2>
144 <table class="wp-list-table widefat fixed striped">
145 <thead>
146 <tr>
147 <th>ID</th>
148 <th>Webhook ID</th>
149 <th>Pedido</th>
150 <th>Evento</th>
151 <th>Status</th>
152 <th>HTTP Status</th>
153 <th>Tempo (ms)</th>
154 <th>Criado em</th>
155 </tr>
156 </thead>
157 <tbody>
158 <?php if (empty($recent_logs)): ?>
159 <tr>
160 <td colspan="8" style="text-align: center;">Nenhum log de webhook encontrado.</td>
161 </tr>
162 <?php else: ?>
163 <?php foreach ($recent_logs as $log): ?>
164 <tr>
165 <td><?php echo esc_html($log->id); ?></td>
166 <td><?php echo esc_html(substr($log->webhook_id, 0, 8)); ?>...</td>
167 <td>
168 <?php if ($log->order_id): ?>
169 <a href="<?php echo esc_url(admin_url('post.php?post=' . $log->order_id . '&action=edit')); ?>">
170 #<?php echo esc_html($log->order_id); ?>
171 </a>
172 <?php else: ?>
173 N/A
174 <?php endif; ?>
175 </td>
176 <td><?php echo esc_html($log->event_type); ?></td>
177 <td>
178 <span class="status-<?php echo esc_attr($log->status); ?>" style="
179 padding: 2px 8px;
180 border-radius: 3px;
181 color: white;
182 background: <?php
183 switch($log->status) {
184 case 'success': echo '#00a32a'; break;
185 case 'error': echo '#d63638'; break;
186 case 'received': echo '#0073aa'; break;
187 default: echo '#8c8f94';
188 }
189 ?>;
190 ">
191 <?php echo esc_html(ucfirst($log->status)); ?>
192 </span>
193 </td>
194 <td><?php echo esc_html($log->http_status_code ?: '-'); ?></td>
195 <td><?php echo esc_html($log->processing_time_ms ?: '-'); ?></td>
196 <td><?php echo esc_html(date('d/m/Y H:i', strtotime($log->created_at))); ?></td>
197 </tr>
198 <?php endforeach; ?>
199 <?php endif; ?>
200 </tbody>
201 </table>
202 </div>
203
204 <script>
205 jQuery(document).ready(function($) {
206 $('#manual-retry-btn').click(function() {
207 var button = $(this);
208 var originalText = button.text();
209
210 button.text('Processando...').prop('disabled', true);
211
212 $.ajax({
213 url: ajaxurl,
214 type: 'POST',
215 data: {
216 action: 'superfrete_manual_retry',
217 nonce: '<?php echo wp_create_nonce('superfrete_webhook_admin_nonce'); ?>'
218 },
219 success: function(response) {
220 if (response.success) {
221 alert('Tentativas processadas com sucesso!');
222 location.reload();
223 } else {
224 alert('Erro: ' + response.data);
225 }
226 },
227 error: function() {
228 alert('Erro de comunicação com o servidor.');
229 },
230 complete: function() {
231 button.text(originalText).prop('disabled', false);
232 }
233 });
234 });
235
236 $('#clear-logs-btn').click(function() {
237 if (confirm('Tem certeza que deseja limpar os logs antigos?')) {
238 var button = $(this);
239 var originalText = button.text();
240
241 button.text('Limpando...').prop('disabled', true);
242
243 $.ajax({
244 url: ajaxurl,
245 type: 'POST',
246 data: {
247 action: 'superfrete_clear_webhook_logs',
248 nonce: '<?php echo wp_create_nonce('superfrete_webhook_admin_nonce'); ?>'
249 },
250 success: function(response) {
251 if (response.success) {
252 alert('Logs limpos com sucesso!');
253 location.reload();
254 } else {
255 alert('Erro: ' + response.data);
256 }
257 },
258 error: function() {
259 alert('Erro de comunicação com o servidor.');
260 },
261 complete: function() {
262 button.text(originalText).prop('disabled', false);
263 }
264 });
265 }
266 });
267 });
268 </script>
269 <?php
270 }
271
272 /**
273 * Get recent webhook logs
274 */
275 private function get_recent_webhook_logs($limit = 50)
276 {
277 global $wpdb;
278
279 $table_name = $wpdb->prefix . 'superfrete_webhook_logs';
280
281 return $wpdb->get_results($wpdb->prepare(
282 "SELECT * FROM $table_name
283 ORDER BY created_at DESC
284 LIMIT %d",
285 $limit
286 ));
287 }
288
289 /**
290 * Handle manual retry processing
291 */
292 public function handle_manual_retry()
293 {
294 // Verify nonce
295 if (!wp_verify_nonce($_POST['nonce'], 'superfrete_webhook_admin_nonce')) {
296 wp_die('Security check failed');
297 }
298
299 // Check permissions
300 if (!current_user_can('manage_woocommerce')) {
301 wp_die('Insufficient permissions');
302 }
303
304 try {
305 $retry_manager = new WebhookRetryManager();
306 $retry_manager->manual_process_retries();
307 wp_send_json_success('Tentativas processadas manualmente.');
308 } catch (Exception $e) {
309 wp_send_json_error('Erro: ' . $e->getMessage());
310 }
311 }
312
313 /**
314 * Handle clearing old logs
315 */
316 public function handle_clear_logs()
317 {
318 // Verify nonce
319 if (!wp_verify_nonce($_POST['nonce'], 'superfrete_webhook_admin_nonce')) {
320 wp_die('Security check failed');
321 }
322
323 // Check permissions
324 if (!current_user_can('manage_woocommerce')) {
325 wp_die('Insufficient permissions');
326 }
327
328 try {
329 global $wpdb;
330
331 $logs_table = $wpdb->prefix . 'superfrete_webhook_logs';
332 $retries_table = $wpdb->prefix . 'superfrete_webhook_retries';
333
334 // Delete logs older than 7 days
335 $deleted_logs = $wpdb->query($wpdb->prepare(
336 "DELETE FROM $logs_table WHERE created_at < DATE_SUB(NOW(), INTERVAL 7 DAY)"
337 ));
338
339 // Delete completed retries older than 7 days
340 $deleted_retries = $wpdb->query($wpdb->prepare(
341 "DELETE FROM $retries_table WHERE status IN ('completed', 'failed') AND updated_at < DATE_SUB(NOW(), INTERVAL 7 DAY)"
342 ));
343
344 Logger::log('SuperFrete', "Manual cleanup: {$deleted_logs} logs and {$deleted_retries} retries deleted");
345
346 wp_send_json_success("Logs limpos: {$deleted_logs} logs e {$deleted_retries} tentativas removidos.");
347 } catch (Exception $e) {
348 wp_send_json_error('Erro: ' . $e->getMessage());
349 }
350 }
351 }
352