PluginProbe ʕ •ᴥ•ʔ
CloudSecure WP Security / 1.3.13
CloudSecure WP Security v1.3.13
1.4.10 1.4.9 trunk 0.9.0 1.0.2 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.3.1 1.3.10 1.3.11 1.3.12 1.3.13 1.3.14 1.3.15 1.3.16 1.3.17 1.3.18 1.3.19 1.3.2 1.3.20 1.3.21 1.3.22 1.3.23 1.3.24 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8
cloudsecure-wp-security / modules / server-error-notification.php
cloudsecure-wp-security / modules Last commit date
admin 1 year ago lib 1 year ago captcha.php 2 years ago cloudsecure-wp.php 1 year ago common.php 1 year ago config.php 2 years ago disable-access-system-file.php 1 year ago disable-author-query.php 2 years ago disable-login.php 1 year ago disable-restapi.php 1 year ago disable-xmlrpc.php 1 year ago htaccess.php 1 year ago login-log.php 1 year ago login-notification.php 1 year ago rename-login-page.php 1 year ago restrict-admin-page.php 1 year ago server-error-notification.php 1 year ago two-factor-authentication.php 1 year ago unify-messages.php 2 years ago update-notice.php 2 years ago waf-engine.php 1 year ago waf.php 1 year ago
server-error-notification.php
262 lines
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit;
5 }
6
7 class CloudSecureWP_Server_Error_Notification extends CloudSecureWP_Common {
8 private const KEY_FEATURE = 'server_error_notification';
9 private const TABLE_NAME = 'cloudsecurewp_server_error';
10 private const MAX_ITEMS = 10000;
11
12 private $config;
13
14 function __construct( array $info, CloudSecureWP_Config $config ) {
15 parent::__construct( $info );
16 $this->config = $config;
17 }
18
19 /**
20 * 機能毎のKEY取得
21 *
22 * @return string
23 */
24 public function get_feature_key(): string {
25 return self::KEY_FEATURE;
26 }
27
28 /**
29 * テーブル名取得
30 *
31 * @return string
32 */
33 public function get_table_name(): string {
34 global $wpdb;
35
36 return $wpdb->prefix . self::TABLE_NAME;
37 }
38
39 /**
40 * サーバーエラーを追加
41 *
42 * @param array $error
43 *
44 * @return void
45 */
46 private function insert_error( array $error ): void {
47 global $wpdb;
48 $table_name = $wpdb->prefix . self::TABLE_NAME;
49 $max_items = self::MAX_ITEMS;
50 $error['created_at'] = current_time( 'mysql' );
51
52 if ( is_null( $error['message'] ) ) {
53 $error['message'] = '';
54 }
55
56 if ( is_null( $error['file'] ) ) {
57 $error['file'] = '';
58 }
59
60 if ( mb_strlen( $error['message'], 'UTF-8' ) > 65535 ) {
61 $error['message'] = mb_substr( $error['message'], 0, 65535, 'UTF-8' );
62 }
63
64 if ( mb_strlen( $error['file'], 'UTF-8' ) > 65535 ) {
65 $error['file'] = mb_substr( $error['file'], 0, 65535, 'UTF-8' );
66 }
67
68 $wpdb->query( 'START TRANSACTION' );
69 $wpdb->insert( $table_name, $error );
70 $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}cloudsecurewp_server_error WHERE id <= (SELECT id FROM (SELECT id FROM {$wpdb->prefix}cloudsecurewp_server_error ORDER BY id DESC LIMIT 1 OFFSET %d) tmp)", $max_items ) );
71 $wpdb->query( 'COMMIT' );
72 }
73
74 /**
75 * サーバーエラーを取得
76 *
77 * @param string $orderby
78 * @param string $order
79 * @param int $per_page
80 * @param int $offset
81 *
82 * @return array
83 */
84 public function get_server_errors( string $orderby, string $order, int $per_page, int $offset ): array {
85 global $wpdb;
86 $table_name = $wpdb->prefix . self::TABLE_NAME;
87 $sanitized_orderby = sanitize_sql_orderby( "$orderby $order" );
88 $sql = "SELECT * FROM $table_name ORDER BY $sanitized_orderby LIMIT %d OFFSET %d";
89
90 return array(
91 $wpdb->get_results( $wpdb->prepare( $sql, $per_page, $offset ), ARRAY_A ),
92 $wpdb->get_var( "SELECT count(*) FROM {$wpdb->prefix}cloudsecurewp_server_error" ),
93 );
94 }
95
96 /**
97 * 有効無効判定
98 *
99 * @return bool
100 */
101 public function is_enabled(): bool {
102 return $this->config->get( $this->get_feature_key() ) === 't';
103 }
104
105 /**
106 * 初期設定値取得
107 *
108 * @return array
109 */
110 public function get_default(): array {
111 return array( self::KEY_FEATURE => $this->check_environment() ? 't' : 'f' );
112 }
113
114 /**
115 * 設定値取得
116 */
117 public function get_settings(): array {
118 $settings = array();
119 $default = $this->get_default();
120
121 foreach ( $default as $key => $val ) {
122 $settings[ $key ] = $this->config->get( $key );
123 }
124
125 return $settings;
126 }
127
128 /**
129 * 設定値保存
130 *
131 * @param array $settings
132 *
133 * @return void
134 */
135 public function save_settings( array $settings ): void {
136 $default = $this->get_default();
137
138 foreach ( $default as $key => $val ) {
139 $this->config->set( $key, $settings[ $key ] ?? '' );
140 }
141
142 $this->config->save();
143 }
144
145 /**
146 * エラータイプ名称を取得
147 *
148 * @param int $error_type
149 *
150 * @return string
151 */
152 private function get_error_type_name( int $error_type ): string {
153 // 下記のコードを参考にさせていただきました。
154 // https://github.com/WordPress/WordPress/blob/aac1b7c487c9a5fd206f6845e4eba4164b02f02b/wp-includes/error-protection.php#L48
155 $constants = get_defined_constants( true );
156 $constants = $constants['Core'] ?? $constants['internal'];
157
158 foreach ( $constants as $constant => $value ) {
159 if ( 0 === strpos( $constant, 'E_' ) && $error_type === $value ) {
160 return $constant;
161 }
162 }
163
164 return '';
165 }
166
167 /**
168 * メール本文取得
169 *
170 * @param array{ type: int , message: string, file: string, line: int } $error
171 *
172 * @return string
173 */
174 private function get_body( array $error ): string {
175 $date = $this->get_date();
176 $time = $this->get_time();
177
178 $text = "$date $time にサーバーエラーが発生しました。" . PHP_EOL;
179 $text .= PHP_EOL;
180 $text .= '【サーバーエラー�
181 報】' . PHP_EOL;
182 $text .= PHP_EOL;
183 $text .= "・エラータイプ:{$error['type']}" . PHP_EOL;
184 $text .= PHP_EOL;
185 $text .= "・エラーメッセージ:{$error['message']}" . PHP_EOL;
186 $text .= PHP_EOL;
187 $text .= "・エラー箇所:{$error['file']}:{$error['line']}" . PHP_EOL;
188 $text .= PHP_EOL;
189 $text .= '--' . PHP_EOL;
190 $text .= 'CloudSecure WP Security' . PHP_EOL;
191
192 return $text;
193 }
194
195 /**
196 * 通知
197 */
198 public function notification( $args, $error ) {
199
200 $error['type'] = $this->get_error_type_name( $error['type'] );
201
202 $this->insert_error( $error );
203
204 $enable_email_server_error_notification = get_option( 'cloudsecurewp_enable_email_server_error_notification', 't' );
205 if ( 't' === $enable_email_server_error_notification ) {
206 $option_name = "cloudsecurewp_error_type_{$error['type']}_email_last_sent";
207 $last_sent = get_option( $option_name );
208 if ( ! $last_sent || time() > $last_sent + HOUR_IN_SECONDS ) {
209 update_option( $option_name, time() );
210 $to = get_option( 'admin_email' );
211 $this->wp_send_mail( $to, esc_html( 'サーバーエラー通知' ), $this->get_body( $error ) );
212 }
213 }
214
215 return $args;
216 }
217
218 /**
219 * 有効化
220 *
221 * @return void
222 */
223 public function activate(): void {
224 $this->save_settings( $this->get_default() );
225
226 global $wpdb;
227 $table_name = $this->get_table_name();
228 $table = $wpdb->get_var( "SHOW TABLES LIKE '{$table_name}'" );
229 $charset_collate = $wpdb->get_charset_collate();
230
231 if ( ! is_null( $table ) ) {
232 $sql = "ALTER TABLE {$table_name} ALTER message DROP DEFAULT";
233 $sql2 = "ALTER TABLE {$table_name} ALTER file DROP DEFAULT";
234 $wpdb->query( $sql );
235 $wpdb->query( $sql2 );
236
237 } else {
238 $sql = "CREATE TABLE {$table_name} (
239 id BIGINT( 20 ) UNSIGNED NOT NULL AUTO_INCREMENT,
240 type VARCHAR( 31 ) NOT NULL DEFAULT 0,
241 message VARCHAR( 65535 ) NOT NULL,
242 file VARCHAR( 65535 ) NOT NULL,
243 line INT NOT NULL DEFAULT 0,
244 created_at DATETIME,
245 UNIQUE KEY id ( id )
246 ) {$charset_collate}";
247
248 $wpdb->query( $sql );
249 }
250 }
251
252 /**
253 * 無効化
254 *
255 * @return void
256 */
257 public function deactivate(): void {
258 $this->config->set( $this->get_feature_key(), 'f' );
259 $this->config->save();
260 }
261 }
262