PluginProbe
Elementor Website Builder – more than just a page builder / 3.19.0-beta1
Elementor Website Builder – more than just a page builder v3.19.0-beta1
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.19.0-beta1, at core/logger/manager.php

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