PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.8.13
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.8.13
1.8.13 1.8.12.3 1.8.12.2 1.8.12.1 1.8.12 1.8.11.3 1.8.11.2 1.8.11.1 1.8.11 1.6.6 1.6.60 1.6.7 1.6.8 1.6.9 1.7.0 1.7.0.1 1.7.0.11 1.7.0.12 1.7.0.14 1.7.0.2 1.7.0.3 1.7.0.5 1.7.0.6 1.7.0.7 1.7.0.9 All 211 releases
charitable / assets / js / tools / system-info.js

system-info.js in Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) 1.8.13, at assets/js/tools/system-info.js

667 lines 19.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /* global wpchar */
2
3 /**
4 * System Info script.
5 *
6 * @since 1.8.1.6
7 */
8 const CharitableSystemInfo = window.CharitableSystemInfo || ( function( document, window, $ ) {
9 /**
10 * Public functions and properties.
11 *
12 * @since 1.8.1.6
13 */
14 const app = {
15
16 /**
17 * Start the engine.
18 *
19 * @since 1.8.1.6
20 */
21 init() {
22 $( app.ready );
23 },
24
25 /**
26 * Document ready.
27 *
28 * @since 1.8.1.6
29 */
30 ready() {
31 app.events();
32 },
33
34 /**
35 * Events.
36 *
37 * @since 1.8.1.6
38 */
39 events() {
40
41 // Copy system information to clipboard.
42 $( document ).on( 'click', '#charitable-system-information-copy', function( event ) {
43 event.preventDefault();
44 app.copySystemInformation();
45 } );
46
47 // Run SSL test.
48 $( document ).on( 'click', '#charitable-ssl-verify', function( event ) {
49 event.preventDefault();
50 app.verifySSLConnection();
51 } );
52
53 // Run email diagnostics.
54 $( document ).on( 'click', '#charitable-email-diagnostics', function( event ) {
55 event.preventDefault();
56 app.runEmailDiagnostics();
57 } );
58
59 // Send test email.
60 $( document ).on( 'click', '#charitable-send-test-email', function( event ) {
61 event.preventDefault();
62 app.sendTestEmail();
63 } );
64
65 // Copy email diagnostics results.
66 $( document ).on( 'click', '#charitable-email-diagnostics-copy', function( event ) {
67 event.preventDefault();
68 app.copyEmailDiagnostics();
69 } );
70
71 // Toggle error logs visibility.
72 $( document ).on( 'click', '#charitable-toggle-error-logs', function( event ) {
73 event.preventDefault();
74 app.toggleErrorLogs();
75 } );
76
77 // Clear error logs.
78 $( document ).on( 'click', '#charitable-clear-error-logs', function( event ) {
79 event.preventDefault();
80 app.clearErrorLogs();
81 } );
82
83 // Export error logs.
84 $( document ).on( 'click', '#charitable-export-error-logs', function( event ) {
85 event.preventDefault();
86 app.exportErrorLogs();
87 } );
88
89 // Run debug log scan.
90 $( document ).on( 'click', '#charitable-debug-log-scan', function( event ) {
91 event.preventDefault();
92 app.runDebugLogScan();
93 } );
94
95 // Handle debug format tab switching.
96 $( document ).on( 'click', '.charitable-format-tab', function( event ) {
97 event.preventDefault();
98 app.switchDebugFormat( $( this ) );
99 } );
100
101 // Copy debug log results.
102 $( document ).on( 'click', '#charitable-debug-copy', function( event ) {
103 event.preventDefault();
104 app.copyDebugResults();
105 } );
106 },
107
108 /**
109 * Copy system information to clipboard.
110 *
111 * @since 1.8.1.6
112 */
113 copySystemInformation() {
114 $( '#charitable-system-information' ).select();
115 document.execCommand( 'copy' );
116 },
117
118 /**
119 * Verify SSL connection.
120 *
121 * @since 1.8.1.6
122 *
123 * @return {void}
124 */
125 verifySSLConnection() {
126 const $btn = $( '#charitable-ssl-verify' );
127 const btnLabel = $btn.text();
128 const btnWidth = $btn.outerWidth();
129 const $settings = $btn.parent();
130
131 if ( typeof charitable_admin_tools !== "undefined" && typeof charitable_admin_tools.ajax_url !== "undefined" && typeof charitable_admin_tools.nonce !== "undefined" && typeof charitable_admin_tools.testing !== "undefined" ) {
132
133 $btn.css( 'width', btnWidth ).prop( 'disabled', true ).text( charitable_admin_tools.testing );
134
135 const data = {
136 action: 'charitable_verify_ssl',
137 nonce: charitable_admin_tools.nonce
138 };
139
140 // Trigger AJAX to test connection
141 $.post( charitable_admin_tools.ajax_url, data, function( res ) {
142
143 if ( typeof wpchar !== "undefined" ) {
144 wpchar.debug( res );
145 }
146
147 // Remove any previous alerts.
148 $settings.find( '.charitable-notice' ).remove();
149
150 if ( res.success ) {
151 $btn.before( '<div class="notice charitable-notice notice-success">' + res.data.msg + '</div>' );
152 }
153
154 if ( ! res.success && res.data.msg ) {
155 $btn.before( '<div class="notice charitable-notice notice-error">' + res.data.msg + '</div>' );
156 }
157
158 if ( ! res.success && res.data.debug ) {
159 $btn.before( '<div class="charitable-ssl-error pre-error">' + res.data.debug + '</div>' );
160 }
161
162 $btn.css( 'width', btnWidth ).prop( 'disabled', false ).text( btnLabel );
163 } );
164
165 }
166 },
167
168 /**
169 * Run email diagnostics.
170 *
171 * @since 1.8.9.2
172 *
173 * @return {void}
174 */
175 runEmailDiagnostics() {
176 const $btn = $( '#charitable-email-diagnostics' );
177 const $results = $( '#charitable-email-diagnostics-results' );
178 const $textarea = $results.find( 'textarea' );
179 const $copyBtn = $( '#charitable-email-diagnostics-copy' );
180 const btnLabel = $btn.text();
181 const btnWidth = $btn.outerWidth();
182
183 if ( typeof charitable_email_diagnostics !== "undefined" ) {
184
185 // Show loading state
186 $btn.css( 'width', btnWidth ).prop( 'disabled', true ).text( charitable_email_diagnostics.running_text );
187 $results.show();
188 $textarea.val( 'Running diagnostics, please wait...' );
189 $copyBtn.hide();
190
191 // Remove any previous notices
192 $btn.parent().find( '.charitable-notice' ).remove();
193
194 const data = {
195 action: 'charitable_email_diagnostics',
196 nonce: charitable_email_diagnostics.nonce
197 };
198
199 // Run diagnostics via AJAX
200 $.post( charitable_email_diagnostics.ajax_url, data, function( response ) {
201
202 if ( typeof wpchar !== "undefined" ) {
203 wpchar.debug( response );
204 }
205
206 if ( response.success && response.data.diagnostics ) {
207 // Show successful results
208 $textarea.val( response.data.diagnostics );
209 $copyBtn.show();
210
211 // Show success notice
212 $btn.before( '<div class="notice charitable-notice notice-success"><p>Email diagnostics completed successfully.</p></div>' );
213
214 } else {
215 // Show error
216 let errorMsg = charitable_email_diagnostics.error_text;
217 if ( response.data && response.data.message ) {
218 errorMsg = response.data.message;
219 }
220
221 $textarea.val( '### DIAGNOSTIC ERROR ###\n\n' + errorMsg );
222 $btn.before( '<div class="notice charitable-notice notice-error"><p>' + errorMsg + '</p></div>' );
223 }
224
225 // Restore button
226 $btn.css( 'width', btnWidth ).prop( 'disabled', false ).text( btnLabel );
227
228 } ).fail( function( xhr, status, error ) {
229 // Handle AJAX failure
230 const errorMsg = 'AJAX request failed: ' + status + ' - ' + error;
231 $textarea.val( '### DIAGNOSTIC ERROR ###\n\n' + errorMsg );
232 $btn.before( '<div class="notice charitable-notice notice-error"><p>Diagnostics request failed. Please try again.</p></div>' );
233 $btn.css( 'width', btnWidth ).prop( 'disabled', false ).text( btnLabel );
234
235 if ( typeof wpchar !== "undefined" ) {
236 wpchar.debug( { xhr: xhr, status: status, error: error } );
237 }
238 } );
239
240 } else {
241 // Show error if localized script not available
242 $btn.before( '<div class="notice charitable-notice notice-error"><p>Email diagnostics not properly loaded. Please refresh the page and try again.</p></div>' );
243 }
244 },
245
246 /**
247 * Send test email.
248 *
249 * @since 1.8.9.2
250 *
251 * @return {void}
252 */
253 sendTestEmail() {
254 const $btn = $( '#charitable-send-test-email' );
255 const $messageDiv = $( '#charitable-test-email-message' );
256 const $messageText = $( '#charitable-test-email-message-text' );
257 const btnLabel = $btn.text();
258
259 if ( typeof charitable_email_diagnostics !== "undefined" ) {
260
261 // Show loading state
262 $btn.prop( 'disabled', true ).text( charitable_email_diagnostics.sending_text || 'Sending...' );
263 $messageDiv.hide();
264
265 // Remove any previous notices
266 $btn.parent().find( '.charitable-notice' ).not( '#charitable-test-email-message .charitable-notice' ).remove();
267
268 const data = {
269 action: 'charitable_send_test_email',
270 nonce: charitable_email_diagnostics.test_email_nonce
271 };
272
273 // Send test email via AJAX
274 $.post( charitable_email_diagnostics.ajax_url, data, function( response ) {
275
276 if ( typeof wpchar !== "undefined" ) {
277 wpchar.debug( response );
278 }
279
280 if ( response.success && response.data.success ) {
281 // Show success message
282 $messageText.text( response.data.message );
283 $messageDiv.find( '.charitable-notice' ).removeClass( 'notice-error' ).addClass( 'notice-success' );
284 $messageDiv.show();
285
286 } else {
287 // Show error message
288 let errorMsg = 'Test email failed to send.';
289 if ( response.data && response.data.message ) {
290 errorMsg = response.data.message;
291 }
292
293 $messageText.text( errorMsg );
294 $messageDiv.find( '.charitable-notice' ).removeClass( 'notice-success' ).addClass( 'notice-error' );
295 $messageDiv.show();
296 }
297
298 // Restore button
299 $btn.prop( 'disabled', false ).text( btnLabel );
300
301 } ).fail( function( xhr, status, error ) {
302 // Handle AJAX failure
303 const errorMsg = 'Test email request failed. Please try again. If problems persist, contact support.';
304
305 $messageText.text( errorMsg );
306 $messageDiv.find( '.charitable-notice' ).removeClass( 'notice-success' ).addClass( 'notice-error' );
307 $messageDiv.show();
308
309 $btn.prop( 'disabled', false ).text( btnLabel );
310
311 if ( typeof wpchar !== "undefined" ) {
312 wpchar.debug( { xhr: xhr, status: status, error: error } );
313 }
314 } );
315
316 } else {
317 // Show error if localized script not available
318 $messageText.text( 'Test email functionality not properly loaded. Please refresh the page and try again.' );
319 $messageDiv.find( '.charitable-notice' ).removeClass( 'notice-success' ).addClass( 'notice-error' );
320 $messageDiv.show();
321 }
322 },
323
324 /**
325 * Copy email diagnostics to clipboard.
326 *
327 * @since 1.8.9.2
328 */
329 copyEmailDiagnostics() {
330 const $textarea = $( '#charitable-email-diagnostics-results textarea' );
331 if ( $textarea.length ) {
332 $textarea.select();
333 document.execCommand( 'copy' );
334
335 // Show temporary feedback
336 const $copyBtn = $( '#charitable-email-diagnostics-copy' );
337 const originalText = $copyBtn.text();
338 $copyBtn.text( 'Copied!' );
339 setTimeout( function() {
340 $copyBtn.text( originalText );
341 }, 2000 );
342 }
343 },
344
345 /**
346 * Toggle error logs visibility.
347 *
348 * @since 1.8.9.2
349 */
350 toggleErrorLogs() {
351 const $btn = $( '#charitable-toggle-error-logs' );
352 const $container = $( '#charitable-error-logs-container' );
353
354 if ( $container.is( ':visible' ) ) {
355 $container.hide();
356 $btn.text( 'Show Error Logs' );
357 } else {
358 $container.show();
359 $btn.text( 'Hide Error Logs' );
360 }
361 },
362
363 /**
364 * Clear error logs.
365 *
366 * @since 1.8.9.2
367 */
368 clearErrorLogs() {
369 const $btn = $( '#charitable-clear-error-logs' );
370 const $messageDiv = $( '#charitable-error-log-message' );
371 const $messageText = $( '#charitable-error-log-message-text' );
372 const btnLabel = $btn.text();
373
374 if ( ! confirm( 'Are you sure you want to clear all error logs? This action cannot be undone.' ) ) {
375 return;
376 }
377
378 if ( typeof charitable_admin_tools !== "undefined" && typeof charitable_admin_tools.ajax_url !== "undefined" && typeof charitable_admin_tools.nonce !== "undefined" ) {
379
380 // Show loading state
381 $btn.prop( 'disabled', true ).text( 'Clearing...' );
382 $messageDiv.hide();
383
384 const data = {
385 action: 'charitable_clear_error_logs',
386 nonce: charitable_admin_tools.nonce
387 };
388
389 // Clear logs via AJAX
390 $.post( charitable_admin_tools.ajax_url, data, function( response ) {
391
392 if ( typeof wpchar !== "undefined" ) {
393 wpchar.debug( response );
394 }
395
396 if ( response.success ) {
397 // Show success message and reload page
398 $messageText.text( response.data.message );
399 $messageDiv.find( '.charitable-notice' ).removeClass( 'notice-error' ).addClass( 'notice-success' );
400 $messageDiv.show();
401
402 // Reload page after 2 seconds to show updated logs
403 setTimeout( function() {
404 location.reload();
405 }, 2000 );
406
407 } else {
408 // Show error message
409 let errorMsg = 'Failed to clear error logs.';
410 if ( response.data && response.data.message ) {
411 errorMsg = response.data.message;
412 }
413
414 $messageText.text( errorMsg );
415 $messageDiv.find( '.charitable-notice' ).removeClass( 'notice-success' ).addClass( 'notice-error' );
416 $messageDiv.show();
417 }
418
419 // Restore button
420 $btn.prop( 'disabled', false ).text( btnLabel );
421
422 } ).fail( function( xhr, status, error ) {
423 // Handle AJAX failure
424 const errorMsg = 'Clear request failed. Please try again.';
425
426 $messageText.text( errorMsg );
427 $messageDiv.find( '.charitable-notice' ).removeClass( 'notice-success' ).addClass( 'notice-error' );
428 $messageDiv.show();
429
430 $btn.prop( 'disabled', false ).text( btnLabel );
431
432 if ( typeof wpchar !== "undefined" ) {
433 wpchar.debug( { xhr: xhr, status: status, error: error } );
434 }
435 } );
436
437 } else {
438 alert( 'Error log clearing not properly loaded. Please refresh the page and try again.' );
439 }
440 },
441
442 /**
443 * Export error logs.
444 *
445 * @since 1.8.9.2
446 */
447 exportErrorLogs() {
448 const $btn = $( '#charitable-export-error-logs' );
449 const $messageDiv = $( '#charitable-error-log-message' );
450 const $messageText = $( '#charitable-error-log-message-text' );
451 const btnLabel = $btn.text();
452
453 if ( typeof charitable_admin_tools !== "undefined" && typeof charitable_admin_tools.ajax_url !== "undefined" && typeof charitable_admin_tools.nonce !== "undefined" ) {
454
455 // Show loading state
456 $btn.prop( 'disabled', true ).text( 'Exporting...' );
457 $messageDiv.hide();
458
459 const data = {
460 action: 'charitable_export_error_logs',
461 nonce: charitable_admin_tools.nonce
462 };
463
464 // Export logs via AJAX
465 $.post( charitable_admin_tools.ajax_url, data, function( response ) {
466
467 if ( typeof wpchar !== "undefined" ) {
468 wpchar.debug( response );
469 }
470
471 if ( response.success && response.data.content ) {
472 // Create and download CSV file
473 const csvContent = atob( response.data.content );
474 const blob = new Blob( [csvContent], { type: 'text/csv;charset=utf-8;' } );
475 const link = document.createElement( 'a' );
476
477 if ( link.download !== undefined ) {
478 const url = URL.createObjectURL( blob );
479 link.setAttribute( 'href', url );
480 link.setAttribute( 'download', response.data.filename || 'error-logs.csv' );
481 link.style.visibility = 'hidden';
482 document.body.appendChild( link );
483 link.click();
484 document.body.removeChild( link );
485 }
486
487 // Show success message
488 $messageText.text( response.data.message );
489 $messageDiv.find( '.charitable-notice' ).removeClass( 'notice-error' ).addClass( 'notice-success' );
490 $messageDiv.show();
491
492 } else {
493 // Show error message
494 let errorMsg = 'Failed to export error logs.';
495 if ( response.data && response.data.message ) {
496 errorMsg = response.data.message;
497 }
498
499 $messageText.text( errorMsg );
500 $messageDiv.find( '.charitable-notice' ).removeClass( 'notice-success' ).addClass( 'notice-error' );
501 $messageDiv.show();
502 }
503
504 // Restore button
505 $btn.prop( 'disabled', false ).text( btnLabel );
506
507 } ).fail( function( xhr, status, error ) {
508 // Handle AJAX failure
509 const errorMsg = 'Export request failed. Please try again.';
510
511 $messageText.text( errorMsg );
512 $messageDiv.find( '.charitable-notice' ).removeClass( 'notice-success' ).addClass( 'notice-error' );
513 $messageDiv.show();
514
515 $btn.prop( 'disabled', false ).text( btnLabel );
516
517 if ( typeof wpchar !== "undefined" ) {
518 wpchar.debug( { xhr: xhr, status: status, error: error } );
519 }
520 } );
521
522 } else {
523 alert( 'Error log export not properly loaded. Please refresh the page and try again.' );
524 }
525 },
526
527 /**
528 * Run debug log scan.
529 *
530 * @since 1.8.9.3
531 */
532 runDebugLogScan() {
533 const $btn = $( '#charitable-debug-log-scan' );
534 const $results = $( '#charitable-debug-log-results' );
535 const $messageDiv = $( '#charitable-debug-log-message' );
536 const $messageText = $( '#charitable-debug-log-message-text' );
537 const btnLabel = $btn.text();
538 const btnWidth = $btn.outerWidth();
539
540 if ( typeof charitable_admin_tools !== "undefined" && typeof charitable_admin_tools.ajax_url !== "undefined" && typeof charitable_admin_tools.nonce !== "undefined" ) {
541
542 // Show loading state
543 $btn.css( 'width', btnWidth ).prop( 'disabled', true ).text( 'Scanning logs...' );
544 $results.show();
545 $( '.charitable-format-content' ).val( 'Scanning debug logs, please wait...' );
546 $messageDiv.hide();
547
548 // Remove any previous notices
549 $btn.parent().find( '.charitable-notice' ).remove();
550
551 const data = {
552 action: 'charitable_debug_log_scan',
553 nonce: charitable_admin_tools.nonce
554 };
555
556 // Run scan via AJAX
557 $.post( charitable_admin_tools.ajax_url, data, function( response ) {
558
559 if ( typeof wpchar !== "undefined" ) {
560 wpchar.debug( response );
561 }
562
563 if ( response.success && response.data.scan_results ) {
564 // Populate different format views
565 const results = response.data.scan_results;
566 $( '#charitable-debug-summary' ).val( results.summary || 'No summary available.' );
567 $( '#charitable-debug-technical' ).val( results.technical || 'No technical details available.' );
568 $( '#charitable-debug-forum' ).val( results.forum_ready || 'No forum format available.' );
569
570 // Show success notice
571 $messageText.text( 'Debug log scan completed successfully.' );
572 $messageDiv.find( '.charitable-notice' ).removeClass( 'notice-error' ).addClass( 'notice-success' );
573 $messageDiv.show();
574
575 // Initialize tab system
576 app.switchDebugFormat( $( '.charitable-format-tab[data-format="summary"]' ) );
577
578 } else {
579 // Show error
580 let errorMsg = 'Debug log scan failed.';
581 let detailedMsg = '';
582
583 if ( response.data && response.data.message ) {
584 errorMsg = response.data.message;
585 }
586
587 if ( response.data && response.data.detailed_message ) {
588 detailedMsg = response.data.detailed_message;
589 }
590
591 // Show detailed error message in text areas
592 const displayMsg = detailedMsg ? detailedMsg : ('### DEBUG LOG SCAN ERROR ###\n\n' + errorMsg);
593 $( '.charitable-format-content' ).val( displayMsg );
594
595 // Show basic error in notice
596 $messageText.text( errorMsg );
597 $messageDiv.find( '.charitable-notice' ).removeClass( 'notice-success' ).addClass( 'notice-error' );
598 $messageDiv.show();
599 }
600
601 // Restore button
602 $btn.css( 'width', btnWidth ).prop( 'disabled', false ).text( btnLabel );
603
604 } ).fail( function( xhr, status, error ) {
605 // Handle AJAX failure
606 const errorMsg = 'Debug log scan request failed: ' + status + ' - ' + error;
607 $( '.charitable-format-content' ).val( '### DEBUG LOG SCAN ERROR ###\n\n' + errorMsg );
608
609 $messageText.text( 'Scan request failed. Please try again.' );
610 $messageDiv.find( '.charitable-notice' ).removeClass( 'notice-success' ).addClass( 'notice-error' );
611 $messageDiv.show();
612
613 $btn.css( 'width', btnWidth ).prop( 'disabled', false ).text( btnLabel );
614
615 if ( typeof wpchar !== "undefined" ) {
616 wpchar.debug( { xhr: xhr, status: status, error: error } );
617 }
618 } );
619
620 } else {
621 alert( 'Debug log scanner not properly loaded. Please refresh the page and try again.' );
622 }
623 },
624
625 /**
626 * Switch debug log format display.
627 *
628 * @since 1.8.9.3
629 * @param {jQuery} $clickedTab The clicked tab element.
630 */
631 switchDebugFormat( $clickedTab ) {
632 const format = $clickedTab.data( 'format' );
633
634 // Update tab states
635 $( '.charitable-format-tab' ).removeClass( 'active' );
636 $clickedTab.addClass( 'active' );
637
638 // Show/hide content areas
639 $( '.charitable-format-content' ).hide();
640 $( '#charitable-debug-' + format ).show();
641 },
642
643 /**
644 * Copy debug log results to clipboard.
645 *
646 * @since 1.8.9.3
647 */
648 copyDebugResults() {
649 const $activeContent = $( '.charitable-format-content:visible' );
650 const $copyMessage = $( '#charitable-debug-copy-message' );
651
652 if ( $activeContent.length > 0 ) {
653 $activeContent.select();
654 document.execCommand( 'copy' );
655
656 // Show copy confirmation
657 $copyMessage.fadeIn( 200 ).delay( 1500 ).fadeOut( 200 );
658 }
659 }
660 };
661
662 return app;
663 }( document, window, jQuery ) );
664
665 // Initialize.
666 CharitableSystemInfo.init();
667