debug.php 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <?php
  2. namespace Elementor\Debug;
  3. use Elementor\System_Info\Main;
  4. if ( ! defined( 'ABSPATH' ) ) {
  5. exit; // Exit if accessed directly.
  6. }
  7. /**
  8. * Elementor debug.
  9. *
  10. * Elementor debug handler class is responsible for logging errors and
  11. * generating debug reports.
  12. *
  13. * @since 1.4.0
  14. */
  15. class Debug {
  16. /**
  17. * Debug option name in the database.
  18. */
  19. const OPTION_NAME = 'elementor_debug_log';
  20. /**
  21. * Maximum debug logs to save in the database.
  22. */
  23. const MAX_LOGS_TO_SAVE = 10;
  24. /**
  25. * Debug report name.
  26. */
  27. const REPORT_NAME = 'debug';
  28. /**
  29. * Debug log.
  30. *
  31. * Log Elementor errors and save them in the database.
  32. *
  33. * Fired by `wp_ajax_elementor_debug_log` action.
  34. *
  35. * @since 1.4.0
  36. * @access public
  37. */
  38. public function debug_log() {
  39. if ( empty( $_POST['data'] ) ) {
  40. return;
  41. }
  42. $log = get_option( self::OPTION_NAME, [] );
  43. foreach ( $_POST['data'] as $error ) {
  44. $last_error = end( $log );
  45. $compare_fields = [
  46. 'type',
  47. 'message',
  48. 'url',
  49. 'line',
  50. 'column',
  51. ];
  52. if ( empty( $error['customFields'] ) ) {
  53. $error['customFields'] = [];
  54. }
  55. $all_fields_identical = false;
  56. if ( $last_error ) {
  57. $compare_fields_as_keys = array_flip( $compare_fields );
  58. $error_requires_equality_fields = array_intersect_key( $error, $compare_fields_as_keys );
  59. $last_error_requires_equality_fields = array_intersect_key( $last_error, $compare_fields_as_keys );
  60. $identical_fields = array_intersect( $error_requires_equality_fields, $last_error_requires_equality_fields );
  61. $all_fields_identical = count( $compare_fields ) === count( $identical_fields );
  62. if ( $all_fields_identical ) {
  63. $error_custom_fields_count = count( $error['customFields'] );
  64. if ( count( $last_error['customFields'] ) !== $error_custom_fields_count ) {
  65. $all_fields_identical = false;
  66. } else {
  67. $identical_custom_fields = array_intersect( $error['customFields'], $last_error['customFields'] );
  68. $all_fields_identical = count( $identical_custom_fields ) === $error_custom_fields_count;
  69. }
  70. }
  71. }
  72. if ( $last_error && $all_fields_identical ) {
  73. if ( empty( $last_error['times'] ) ) {
  74. $last_error['times'] = 2;
  75. } else {
  76. $last_error['times']++;
  77. }
  78. $last_error['timestamp'] = $error['timestamp'];
  79. $log[ key( $log ) ] = $last_error;
  80. } else {
  81. $log[] = $error;
  82. }
  83. }
  84. if ( self::MAX_LOGS_TO_SAVE && self::MAX_LOGS_TO_SAVE < count( $log ) ) {
  85. $log = array_splice( $log, -self::MAX_LOGS_TO_SAVE );
  86. }
  87. update_option( self::OPTION_NAME, $log );
  88. }
  89. /**
  90. * Add system info debug report.
  91. *
  92. * Create new system info debug report.
  93. *
  94. * @since 1.4.0
  95. * @access private
  96. */
  97. private function add_system_info_report() {
  98. Main::add_report(
  99. self::REPORT_NAME, [
  100. 'file_name' => __DIR__ . '/debug-reporter.php',
  101. 'class_name' => __NAMESPACE__ . '\Debug_Reporter',
  102. ]
  103. );
  104. }
  105. /**
  106. * Debug constructor.
  107. *
  108. * Initializing Elementor debug and logging errors.
  109. *
  110. * @since 1.4.0
  111. * @access public
  112. */
  113. public function __construct() {
  114. add_action( 'wp_ajax_elementor_debug_log', [ $this, 'debug_log' ] );
  115. if ( is_admin() ) {
  116. $this->add_system_info_report();
  117. }
  118. }
  119. }