PluginProbe
Elementor Website Builder – more than just a page builder / 3.6.0-dev1
Elementor Website Builder – more than just a page builder v3.6.0-dev1
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
elementor / trunk / core / logger / manager.php

manager.php in Elementor Website Builder – more than just a page builder 3.6.0-dev1, at trunk/core/logger/manager.php

264 lines 6.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor\Core\Logger;
3
4 use Elementor\Core\Base\Module as BaseModule;
5 use Elementor\Core\Common\Modules\Ajax\Module;
6 use Elementor\Core\Logger\Loggers\Logger_Interface;
7 use Elementor\Core\Logger\Items\PHP;
8 use Elementor\Core\Logger\Items\JS;
9 use Elementor\Plugin;
10 use Elementor\Modules\System_Info\Module as System_Info;
11 use Elementor\Utils;
12
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit; // Exit if accessed directly
15 }
16
17 class Manager extends BaseModule {
18
19 protected $loggers = [];
20
21 protected $default_logger = '';
22
23 public function get_name() {
24 return 'log';
25 }
26
27 public function shutdown( $last_error = null, $should_exit = false ) {
28 if ( ! $last_error ) {
29 $last_error = error_get_last();
30 }
31
32 if ( ! $last_error ) {
33 return;
34 }
35
36 if ( empty( $last_error['file'] ) ) {
37 return;
38 }
39
40 if ( ! Utils::is_elementor_path( $last_error['file'] ) ) {
41 return;
42 }
43
44 $last_error['type'] = $this->get_log_type_from_php_error( $last_error['type'] );
45 $last_error['trace'] = true;
46
47 $item = new PHP( $last_error );
48
49 $this->get_logger()->log( $item );
50
51 if ( $should_exit ) {
52 exit;
53 }
54 }
55
56 public function rest_error_handler( $error_number, $error_message, $error_file, $error_line ) {
57 $error = new \WP_Error( $error_number, $error_message, [
58 'type' => $error_number,
59 'message' => $error_message,
60 'file' => $error_file,
61 'line' => $error_line,
62 ] );
63
64 if ( ! Utils::is_elementor_path( $error_file ) ) {
65 // Do execute PHP internal error handler.
66 return false;
67 }
68
69 $error_data = $error->get_error_data();
70
71 // TODO: This part should be modular, temporary hard-coded.
72 // Notify $e.data.
73 if ( ! headers_sent() ) {
74 header( 'Content-Type: application/json; charset=UTF-8' );
75
76 http_response_code( 500 );
77
78 if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
79 echo wp_json_encode( $error_data );
80 } else {
81 echo wp_json_encode( [
82 'message' => 'Server error, see Elementor => System Info',
83 ] );
84 }
85 }
86
87 $this->shutdown( $error_data, true );
88 }
89
90 public function register_error_handler() {
91 set_error_handler( [ $this, 'rest_error_handler' ], E_ALL );
92 }
93
94 public function add_system_info_report() {
95 System_Info::add_report(
96 'log', [
97 'file_name' => __DIR__ . '/log-reporter.php',
98 'class_name' => __NAMESPACE__ . '\Log_Reporter',
99 ]
100 );
101 }
102
103 /**
104 * Javascript log.
105 *
106 * Log Elementor errors and save them in the database.
107 *
108 * Fired by `wp_ajax_elementor_js_log` action.
109 *
110 */
111 public function js_log() {
112 /** @var Module $ajax */
113 $ajax = Plugin::$instance->common->get_component( 'ajax' );
114
115 // PHPCS ignore is added throughout this method because nonce verification happens in the $ajax->verify_request_nonce() method.
116 if ( ! $ajax->verify_request_nonce() || empty( $_POST['data'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
117 wp_send_json_error();
118 }
119
120 // PHPCS - See comment above.
121 array_walk_recursive( $_POST['data'], function( &$value ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
122 $value = sanitize_text_field( $value );
123 } );
124
125 // PHPCS - See comment above.
126 foreach ( $_POST['data'] as $error ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
127 $error['type'] = Logger_Interface::LEVEL_ERROR;
128
129 if ( ! empty( $error['customFields'] ) ) {
130 $error['meta'] = $error['customFields'];
131 }
132
133 $item = new JS( $error );
134 $this->get_logger()->log( $item );
135 }
136
137 wp_send_json_success();
138 }
139
140 public function register_logger( $name, $class ) {
141 $this->loggers[ $name ] = $class;
142 }
143
144 public function set_default_logger( $name ) {
145 if ( ! empty( $this->loggers[ $name ] ) ) {
146 $this->default_logger = $name;
147 }
148 }
149
150 public function register_default_loggers() {
151 $this->register_logger( 'db', 'Elementor\Core\Logger\Loggers\Db' );
152 $this->set_default_logger( 'db' );
153 }
154
155 /**
156 * @param string $name
157 *
158 * @return Logger_Interface
159 */
160 public function get_logger( $name = '' ) {
161 $this->register_loggers();
162
163 if ( empty( $name ) || ! isset( $this->loggers[ $name ] ) ) {
164 $name = $this->default_logger;
165 }
166
167 if ( ! $this->get_component( $name ) ) {
168 $this->add_component( $name, new $this->loggers[ $name ]() );
169 }
170
171 return $this->get_component( $name );
172 }
173
174 /**
175 * @param string $message
176 * @param array $args
177 *
178 * @return void
179 */
180 public function log( $message, $args = [] ) {
181 $this->get_logger()->log( $message, $args );
182 }
183
184 /**
185 * @param string $message
186 * @param array $args
187 *
188 * @return void
189 */
190 public function info( $message, $args = [] ) {
191 $this->get_logger()->info( $message, $args );
192 }
193
194 /**
195 * @param string $message
196 * @param array $args
197 *
198 * @return void
199 */
200 public function notice( $message, $args = [] ) {
201 $this->get_logger()->notice( $message, $args );
202 }
203
204 /**
205 * @param string $message
206 * @param array $args
207 *
208 * @return void
209 */
210 public function warning( $message, $args = [] ) {
211 $this->get_logger()->warning( $message, $args );
212 }
213
214 /**
215 * @param string $message
216 * @param array $args
217 *
218 * @return void
219 */
220 public function error( $message, $args = [] ) {
221 $this->get_logger()->error( $message, $args );
222 }
223
224 private function get_log_type_from_php_error( $type ) {
225 $error_map = [
226 E_CORE_ERROR => Logger_Interface::LEVEL_ERROR,
227 E_ERROR => Logger_Interface::LEVEL_ERROR,
228 E_USER_ERROR => Logger_Interface::LEVEL_ERROR,
229 E_COMPILE_ERROR => Logger_Interface::LEVEL_ERROR,
230 E_RECOVERABLE_ERROR => Logger_Interface::LEVEL_ERROR,
231 E_PARSE => Logger_Interface::LEVEL_ERROR,
232 E_STRICT => Logger_Interface::LEVEL_ERROR,
233
234 E_WARNING => Logger_Interface::LEVEL_WARNING,
235 E_USER_WARNING => Logger_Interface::LEVEL_WARNING,
236 E_CORE_WARNING => Logger_Interface::LEVEL_WARNING,
237 E_COMPILE_WARNING => Logger_Interface::LEVEL_WARNING,
238
239 E_NOTICE => Logger_Interface::LEVEL_NOTICE,
240 E_USER_NOTICE => Logger_Interface::LEVEL_NOTICE,
241 E_DEPRECATED => Logger_Interface::LEVEL_NOTICE,
242 E_USER_DEPRECATED => Logger_Interface::LEVEL_NOTICE,
243 ];
244
245 return isset( $error_map[ $type ] ) ? $error_map[ $type ] : Logger_Interface::LEVEL_ERROR;
246 }
247
248 private function register_loggers() {
249 if ( ! did_action( 'elementor/loggers/register' ) ) {
250 do_action( 'elementor/loggers/register', $this );
251 }
252 }
253
254 public function __construct() {
255 register_shutdown_function( [ $this, 'shutdown' ] );
256
257 add_action( 'admin_init', [ $this, 'add_system_info_report' ], 80 );
258
259 add_action( 'wp_ajax_elementor_js_log', [ $this, 'js_log' ] );
260
261 add_action( 'elementor/loggers/register', [ $this, 'register_default_loggers' ] );
262 }
263 }
264