PluginProbe
Elementor Website Builder – more than just a page builder / 3.8.0
Elementor Website Builder – more than just a page builder v3.8.0
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 / core / logger / manager.php

manager.php in Elementor Website Builder – more than just a page builder 3.8.0, at core/logger/manager.php

275 lines 6.7 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 // Temporary solution until all PHP notices will be fixed in the core and pro.
58 if ( Utils::is_wp_cli() ) {
59 return null;
60 }
61
62 $error = new \WP_Error( $error_number, $error_message, [
63 'type' => $error_number,
64 'message' => $error_message,
65 'file' => $error_file,
66 'line' => $error_line,
67 ] );
68
69 if ( ! Utils::is_elementor_path( $error_file ) ) {
70 // Do execute PHP internal error handler.
71 return false;
72 }
73
74 $is_an_error = in_array( // It can be notice or warning
75 $error_number,
76 [ E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR ],
77 true
78 );
79
80 $error_data = $error->get_error_data();
81
82 // TODO: This part should be modular, temporary hard-coded.
83 // Notify $e.data.
84 if ( $is_an_error && ! headers_sent() ) {
85 header( 'Content-Type: application/json; charset=UTF-8' );
86
87 http_response_code( 500 );
88
89 if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
90 echo wp_json_encode( $error_data );
91 } else {
92 echo wp_json_encode( [
93 'message' => 'Server error, see Elementor => System Info',
94 ] );
95 }
96 }
97
98 $this->shutdown( $error_data, $is_an_error );
99 }
100
101 public function register_error_handler() {
102 set_error_handler( [ $this, 'rest_error_handler' ], E_ALL );
103 }
104
105 public function add_system_info_report() {
106 System_Info::add_report(
107 'log', [
108 'file_name' => __DIR__ . '/log-reporter.php',
109 'class_name' => __NAMESPACE__ . '\Log_Reporter',
110 ]
111 );
112 }
113
114 /**
115 * Javascript log.
116 *
117 * Log Elementor errors and save them in the database.
118 *
119 * Fired by `wp_ajax_elementor_js_log` action.
120 *
121 */
122 public function js_log() {
123 /** @var Module $ajax */
124 $ajax = Plugin::$instance->common->get_component( 'ajax' );
125
126 // PHPCS ignore is added throughout this method because nonce verification happens in the $ajax->verify_request_nonce() method.
127 if ( ! $ajax->verify_request_nonce() || empty( $_POST['data'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
128 wp_send_json_error();
129 }
130
131 // PHPCS - See comment above.
132 array_walk_recursive( $_POST['data'], function( &$value ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
133 $value = sanitize_text_field( $value );
134 } );
135
136 // PHPCS - See comment above.
137 foreach ( $_POST['data'] as $error ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
138 $error['type'] = Logger_Interface::LEVEL_ERROR;
139
140 if ( ! empty( $error['customFields'] ) ) {
141 $error['meta'] = $error['customFields'];
142 }
143
144 $item = new JS( $error );
145 $this->get_logger()->log( $item );
146 }
147
148 wp_send_json_success();
149 }
150
151 public function register_logger( $name, $class ) {
152 $this->loggers[ $name ] = $class;
153 }
154
155 public function set_default_logger( $name ) {
156 if ( ! empty( $this->loggers[ $name ] ) ) {
157 $this->default_logger = $name;
158 }
159 }
160
161 public function register_default_loggers() {
162 $this->register_logger( 'db', 'Elementor\Core\Logger\Loggers\Db' );
163 $this->set_default_logger( 'db' );
164 }
165
166 /**
167 * @param string $name
168 *
169 * @return Logger_Interface
170 */
171 public function get_logger( $name = '' ) {
172 $this->register_loggers();
173
174 if ( empty( $name ) || ! isset( $this->loggers[ $name ] ) ) {
175 $name = $this->default_logger;
176 }
177
178 if ( ! $this->get_component( $name ) ) {
179 $this->add_component( $name, new $this->loggers[ $name ]() );
180 }
181
182 return $this->get_component( $name );
183 }
184
185 /**
186 * @param string $message
187 * @param array $args
188 *
189 * @return void
190 */
191 public function log( $message, $args = [] ) {
192 $this->get_logger()->log( $message, $args );
193 }
194
195 /**
196 * @param string $message
197 * @param array $args
198 *
199 * @return void
200 */
201 public function info( $message, $args = [] ) {
202 $this->get_logger()->info( $message, $args );
203 }
204
205 /**
206 * @param string $message
207 * @param array $args
208 *
209 * @return void
210 */
211 public function notice( $message, $args = [] ) {
212 $this->get_logger()->notice( $message, $args );
213 }
214
215 /**
216 * @param string $message
217 * @param array $args
218 *
219 * @return void
220 */
221 public function warning( $message, $args = [] ) {
222 $this->get_logger()->warning( $message, $args );
223 }
224
225 /**
226 * @param string $message
227 * @param array $args
228 *
229 * @return void
230 */
231 public function error( $message, $args = [] ) {
232 $this->get_logger()->error( $message, $args );
233 }
234
235 private function get_log_type_from_php_error( $type ) {
236 $error_map = [
237 E_CORE_ERROR => Logger_Interface::LEVEL_ERROR,
238 E_ERROR => Logger_Interface::LEVEL_ERROR,
239 E_USER_ERROR => Logger_Interface::LEVEL_ERROR,
240 E_COMPILE_ERROR => Logger_Interface::LEVEL_ERROR,
241 E_RECOVERABLE_ERROR => Logger_Interface::LEVEL_ERROR,
242 E_PARSE => Logger_Interface::LEVEL_ERROR,
243 E_STRICT => Logger_Interface::LEVEL_ERROR,
244
245 E_WARNING => Logger_Interface::LEVEL_WARNING,
246 E_USER_WARNING => Logger_Interface::LEVEL_WARNING,
247 E_CORE_WARNING => Logger_Interface::LEVEL_WARNING,
248 E_COMPILE_WARNING => Logger_Interface::LEVEL_WARNING,
249
250 E_NOTICE => Logger_Interface::LEVEL_NOTICE,
251 E_USER_NOTICE => Logger_Interface::LEVEL_NOTICE,
252 E_DEPRECATED => Logger_Interface::LEVEL_NOTICE,
253 E_USER_DEPRECATED => Logger_Interface::LEVEL_NOTICE,
254 ];
255
256 return isset( $error_map[ $type ] ) ? $error_map[ $type ] : Logger_Interface::LEVEL_ERROR;
257 }
258
259 private function register_loggers() {
260 if ( ! did_action( 'elementor/loggers/register' ) ) {
261 do_action( 'elementor/loggers/register', $this );
262 }
263 }
264
265 public function __construct() {
266 register_shutdown_function( [ $this, 'shutdown' ] );
267
268 add_action( 'admin_init', [ $this, 'add_system_info_report' ], 80 );
269
270 add_action( 'wp_ajax_elementor_js_log', [ $this, 'js_log' ] );
271
272 add_action( 'elementor/loggers/register', [ $this, 'register_default_loggers' ] );
273 }
274 }
275