PluginProbe
Meow Gallery / 5.5.5
Meow Gallery v5.5.5
5.5.5 5.5.4 5.5.3 5.5.2 5.5.1 5.5.0 5.4.9 5.4.8 5.4.7 4.1.5 4.1.6 4.1.7 4.1.8 4.1.9 4.2.0 4.2.1 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.2.7 4.2.8 4.2.9 4.3.0 All 157 releases
← All changes | common/helpers.php +273 -169 4.2.45.5.5 View file →
@@ -1,196 +1,300 @@
1 1 <?php
2 2
3 -if ( !class_exists( 'MeowCommon_Helpers' ) ) {
3 +if ( !class_exists( 'MeowKit_MGL_Helpers' ) ) {
4 4
5 - class MeowCommon_Helpers {
6 -
7 - //public static $version = MeowCommon_Admin::version;
8 - private static $startTimes = array();
9 - private static $startQueries = array();
5 + class MeowKit_MGL_Helpers {
6 + //public static $version = MeowKit_MGL_Admin::version;
7 + private static $startTimes = [];
8 + private static $startQueries = [];
10 9
11 - static function is_divi_builder() {
12 - return isset( $_GET['et_fb'] ) && $_GET['et_fb'] === '1';
13 - }
10 + public static function is_divi_builder() {
11 + return isset( $_GET['et_fb'] ) && $_GET['et_fb'] === '1';
12 + }
14 13
15 - static function is_cornerstone_builder() {
16 - return isset( $_GET['cs-render'] ) && $_GET['cs-render'] === '1';
17 - }
14 + public static function is_beaver_builder() {
15 + return isset( $_GET['fl_builder'] );
16 + }
18 17
19 - static function is_pagebuilder_request() {
20 - return self::is_divi_builder() || self::is_cornerstone_builder();
21 - }
18 + public static function is_cornerstone_builder() {
19 + return isset( $_GET['cs-render'] ) && $_GET['cs-render'] === '1';
20 + }
22 21
23 - static function is_asynchronous_request() {
24 - return self::is_ajax_request() || self::is_woocommerce_ajax_request() || self::is_rest();
25 - }
22 + public static function is_pagebuilder_request() {
23 + return self::is_divi_builder() || self::is_cornerstone_builder() || self::is_beaver_builder();
24 + }
26 25
27 - static function is_ajax_request() {
28 - return wp_doing_ajax();
29 - }
26 + public static function is_asynchronous_request() {
27 + return self::is_ajax_request() || self::is_woocommerce_ajax_request() || self::is_rest();
28 + }
30 29
31 - static function is_woocommerce_ajax_request() {
32 - return !empty( $_GET['wc-ajax'] );
33 - }
30 + public static function is_ajax_request() {
31 + return wp_doing_ajax();
32 + }
34 33
35 - // Originally created by matzeeable, modified by jordymeow
36 - static function is_rest() {
34 + public static function is_woocommerce_ajax_request() {
35 + return !empty( $_GET['wc-ajax'] );
36 + }
37 37
38 - // WP_REST_Request init.
39 - $is_rest_request = defined('REST_REQUEST') && REST_REQUEST;
40 - if ( $is_rest_request ) {
41 - MeowCommon_Rest::init_once();
42 - return true;
43 - }
38 + // This function makes sure that only the allowed HTML element names,
39 + // attribute names, attribute values, and HTML entities will occur in the given text string.
40 + public static function wp_kses( $html ) {
41 + return wp_kses( $html, [
42 + 'style' => [],
43 + 'script' => [],
44 + 'div' => [
45 + 'class' => [],
46 + 'data-rating-date' => [],
47 + 'style' => [],
48 + ],
49 + 'img' => [
50 + 'src' => [],
51 + 'decoding' => [],
52 + 'class' => [],
53 + 'style' => [],
54 + ],
55 + 'p' => [
56 + 'style' => [],
57 + ],
58 + 'h2' => [
59 + 'class' => [],
60 + ],
61 + 'br' => [],
62 + 'label' => [],
63 + 'b' => [],
64 + 'small' => [],
65 + 'a' => [
66 + 'href' => [],
67 + 'target' => [],
68 + 'class' => [],
69 + 'style' => [],
70 + ],
71 + 'form' => [
72 + 'method' => [],
73 + 'action' => [],
74 + 'class' => [],
75 + 'style' => [],
76 + ],
77 + 'input' => [
78 + 'type' => [],
79 + 'checked' => [],
80 + 'name' => [],
81 + 'value' => [],
82 + 'id' => [],
83 + 'class' => [],
84 + ],
85 + ] );
86 + }
44 87
45 - // Plain permalinks.
46 - $prefix = rest_get_url_prefix();
47 - $request_contains_rest = isset( $_GET['rest_route'] ) && strpos( trim( $_GET['rest_route'], '\\/' ), $prefix , 0 ) === 0;
48 - if ( $request_contains_rest) {
49 - MeowCommon_Rest::init_once();
50 - return true;
51 - }
88 + // Diff between two strings
89 + public static function diff( $first, $second ) {
90 + $first = explode( ' ', $first );
91 + $second = explode( ' ', $second );
92 + $diff = array_diff( $first, $second );
93 + return implode( ' ', $diff );
94 + }
52 95
53 - // It can happen that WP_Rewrite is not yet initialized, so better to do it.
54 - global $wp_rewrite;
55 - if ( $wp_rewrite === null ) {
56 - $wp_rewrite = new WP_Rewrite();
57 - }
58 - $rest_url = wp_parse_url( trailingslashit( rest_url() ) );
59 - $current_url = wp_parse_url( add_query_arg( array() ) );
60 - if ( !$rest_url || !$current_url )
61 - return false;
96 + // From August 2025: The New 'is_rest' function, more reliable, much cleaner.
97 + public static function is_rest() {
62 98
63 - // URL Path begins with wp-json.
64 - if ( !empty( $current_url['path'] ) && !empty( $rest_url['path'] ) ) {
65 - $request_contains_rest = strpos( $current_url['path'], $rest_url['path'], 0 ) === 0;
66 - if ( $request_contains_rest) {
67 - MeowCommon_Rest::init_once();
68 - return true;
69 - }
70 - }
99 + // WP 6.5+: only reliable after parse_request; otherwise skip this branch.
100 + if ( function_exists( 'wp_is_serving_rest_request' ) && did_action( 'parse_request' ) && wp_is_serving_rest_request() ) {
101 + MeowKit_MGL_Rest::init_once();
102 + return true;
103 + }
71 104
72 - return false;
73 - }
105 + // Classic flag set during REST bootstrap (safe at any time).
106 + if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
107 + MeowKit_MGL_Rest::init_once();
108 + return true;
109 + }
74 110
75 - static function test_error( $error = 'timeout', $diceSides = 1 ) {
76 - if ( rand( 1, $diceSides ) === 1 ) {
77 - if ( $error === 'timeout' ) {
78 - header("HTTP/1.0 408 Request Timeout");
79 - die();
80 - }
81 - else {
82 - trigger_error( "Error", E_USER_ERROR);
83 - }
84 - }
85 - }
111 + // Plain permalinks: ?rest_route=/... (route does NOT include the prefix).
112 + if ( isset( $_GET['rest_route'] ) ) {
113 + MeowKit_MGL_Rest::init_once();
114 + return true;
115 + }
86 116
87 - static function php_error_logs() {
88 - $errorpath = ini_get( 'error_log' );
89 - $output_lines = array();
90 - if ( !empty( $errorpath ) && file_exists( $errorpath ) ) {
91 - try {
92 - $file = new SplFileObject( $errorpath, 'r' );
93 - $file->seek( PHP_INT_MAX );
94 - $last_line = $file->key();
95 - $iterator = new LimitIterator( $file, $last_line > 3500 ? $last_line - 3500 : 0, $last_line );
96 - $lines = iterator_to_array( $iterator );
97 - $previous_line = null;
98 - foreach ( $lines as $line ) {
117 + // Pretty permalinks: compare request PATH to the site's REST base path, without using rest_url().
118 + // This works early in the bootstrap (no dependency on $wp_rewrite).
119 + $req_path = isset( $_SERVER['REQUEST_URI'] ) ? wp_parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH ) : null;
120 + if ( $req_path ) {
121 + $prefix = rest_get_url_prefix(); // e.g. 'wp-json' or custom
99 122
100 - // Parse the date
101 - $date = '';
102 - try {
103 - $dateArr = [];
104 - preg_match( '~^\[(.*?)\]~', $line, $dateArr );
105 - if ( isset( $dateArr[0] ) ) {
106 - $line = str_replace( $dateArr[0], '', $line );
107 - $line = trim( $line );
108 - $date = new DateTime( $dateArr[1] );
109 - $date = get_date_from_gmt( $date->format('Y-m-d H:i:s'), 'Y-m-d H:i:s' );
110 - }
111 - else {
112 - continue;
113 - }
114 - }
115 - catch ( Exception $e ) {
116 - continue;
117 - }
123 + // Check if the path contains /wp-json/ or /index.php/wp-json/
124 + // This handles multilingual plugins (WPML, Polylang) that add language prefixes like /fr/wp-json/
125 + $path = trailingslashit( $req_path );
126 + $rest_pattern = '/' . trim( $prefix, '/' ) . '/';
127 + $rest_pattern_index = '/index.php/' . trim( $prefix, '/' ) . '/';
118 128
119 - // Parse the error
120 - $type = '';
121 - if ( preg_match( '/PHP Fatal error/', $line ) ) {
122 - $line = trim( str_replace( 'PHP Fatal error:', '', $line ) );
123 - $type = 'fatal';
124 - }
125 - else if ( preg_match( '/PHP Warning/', $line ) ) {
126 - $line = trim( str_replace( 'PHP Warning:', '', $line ) );
127 - $type = 'warning';
128 - }
129 - else if ( preg_match( '/PHP Notice/', $line ) ) {
130 - $line = trim( str_replace( 'PHP Notice:', '', $line ) );
131 - $type = 'notice';
132 - }
133 - else if ( preg_match( '/PHP Parse error/', $line ) ) {
134 - $line = trim( str_replace( 'PHP Parse error:', '', $line ) );
135 - $type = 'parse';
136 - }
137 - else if ( preg_match( '/PHP Exception/', $line ) ) {
138 - $line = trim( str_replace( 'PHP Exception:', '', $line ) );
139 - $type = 'exception';
140 - }
141 - else {
142 - continue;
143 - }
129 + if ( strpos( $path, $rest_pattern ) !== false || strpos( $path, $rest_pattern_index ) !== false ) {
130 + MeowKit_MGL_Rest::init_once();
131 + return true;
132 + }
133 + }
144 134
145 - // Skip the error if is the same as before.
146 - if ( $line !== $previous_line ) {
147 - array_push( $output_lines, array( 'date' => $date, 'type' => $type, 'content' => $line ) );
148 - $previous_line = $line;
149 - }
150 - }
151 - }
152 - catch ( OutOfBoundsException $e ) {
153 - error_log( $e->getMessage() );
154 - return array();
155 - }
156 - }
157 - return $output_lines;
135 + return false;
136 + }
158 137
159 - // else {
160 - // $output_lines = array_reverse( $output_lines );
161 - // $html = '';
162 - // $previous = '';
163 - // foreach ( $output_lines as $line ) {
164 - // // Let's avoid similar errors, since it's not useful. We should also make this better
165 - // // and not only theck this depending on tie.
166 - // if ( preg_replace( '/\[.*\] PHP/', '', $previous ) !== preg_replace( '/\[.*\] PHP/', '', $line ) ) {
167 - // $html .= $line;
168 - // $previous = $line;
169 - // }
170 - // }
171 - // return $html;
172 - // }
173 - }
138 + // Originally created by matzeeable, modified by jordymeow
139 + // public static function is_rest() {
174 140
175 - static function timer_start( $timerName = 'default' ) {
176 - MeowCommon_Helpers::$startQueries[ $timerName ] = get_num_queries();
177 - MeowCommon_Helpers::$startTimes[ $timerName ] = microtime( true );
178 - }
141 + // // WP_REST_Request init.
142 + // $is_rest_request = defined( 'REST_REQUEST' ) && REST_REQUEST;
143 + // if ( $is_rest_request ) {
144 + // MeowKit_MGL_Rest::init_once();
145 + // return true;
146 + // }
179 147
180 - static function timer_elapsed( $timerName = 'default' ) {
181 - return microtime( true ) - MeowCommon_Helpers::$startTimes[ $timerName ];
182 - }
148 + // // Plain permalinks.
149 + // $prefix = rest_get_url_prefix();
150 + // $request_contains_rest = isset( $_GET['rest_route'] ) && strpos( trim( $_GET['rest_route'], '\\/' ), $prefix, 0 ) === 0;
151 + // if ( $request_contains_rest ) {
152 + // MeowKit_MGL_Rest::init_once();
153 + // return true;
154 + // }
183 155
184 - static function timer_log_elapsed( $timerName = 'default' ) {
185 - $elapsed = MeowCommon_Helpers::timer_elapsed( $timerName );
186 - $queries = get_num_queries() - MeowCommon_Helpers::$startQueries[ $timerName ];
187 - error_log( $timerName . ": " . $elapsed . "ms (" . $queries . " queries)" );
188 - }
189 - }
156 + // // It can happen that WP_Rewrite is not yet initialized, so better to do it.
157 + // global $wp_rewrite;
158 + // if ( $wp_rewrite === null ) {
159 + // $wp_rewrite = new WP_Rewrite();
160 + // }
161 + // $rest_url = wp_parse_url( trailingslashit( get_rest_url() ) );
162 + // $current_url = wp_parse_url( add_query_arg( [] ) );
163 + // if ( !$rest_url || !$current_url ) {
164 + // return false;
165 + // }
190 166
191 - // Asked by WP Security Team to remove this.
167 + // // URL Path begins with wp-json.
168 + // if ( !empty( $current_url['path'] ) && !empty( $rest_url['path'] ) ) {
169 + // $request_contains_rest = strpos( $current_url['path'], $rest_url['path'], 0 ) === 0;
170 + // if ( $request_contains_rest ) {
171 + // MeowKit_MGL_Rest::init_once();
172 + // return true;
173 + // }
174 + // }
192 175
193 - // if ( MeowCommon_Helpers::is_rest() ) {
194 - // ini_set( 'display_errors', 0 );
195 - // }
176 + // return false;
177 + // }
178 +
179 + public static function test_error( $error = 'timeout', $diceSides = 1 ) {
180 + if ( mt_rand( 1, $diceSides ) === 1 ) {
181 + if ( $error === 'timeout' ) {
182 + header( 'HTTP/1.0 408 Request Timeout' );
183 + die();
184 + }
185 + else {
186 + trigger_error( 'Error', E_USER_ERROR );
187 + }
188 + }
189 + }
190 +
191 + public static function php_error_logs() {
192 + $errorpath = ini_get( 'error_log' );
193 + $output_lines = [];
194 + if ( !empty( $errorpath ) && file_exists( $errorpath ) ) {
195 + try {
196 + $file = new SplFileObject( $errorpath, 'r' );
197 + $file->seek( PHP_INT_MAX );
198 + $last_line = $file->key();
199 + $iterator = new LimitIterator( $file, $last_line > 3500 ? $last_line - 3500 : 0, $last_line );
200 + $lines = iterator_to_array( $iterator );
201 + $previous_line = null;
202 + foreach ( $lines as $line ) {
203 +
204 + // Parse the date
205 + $date = '';
206 + try {
207 + $dateArr = [];
208 + preg_match( '~^\[(.*?)\]~', $line, $dateArr );
209 + if ( isset( $dateArr[0] ) ) {
210 + $line = str_replace( $dateArr[0], '', $line );
211 + $line = trim( $line );
212 + $date = new DateTime( $dateArr[1] );
213 + $date = get_date_from_gmt( $date->format( 'Y-m-d H:i:s' ), 'Y-m-d H:i:s' );
214 + }
215 + else {
216 + continue;
217 + }
218 + }
219 + catch ( Exception $e ) {
220 + continue;
221 + }
222 +
223 + // Parse the error
224 + $type = '';
225 + if ( preg_match( '/PHP Fatal error/', $line ) ) {
226 + $line = trim( str_replace( 'PHP Fatal error:', '', $line ) );
227 + $type = 'fatal';
228 + }
229 + else if ( preg_match( '/PHP Warning/', $line ) ) {
230 + $line = trim( str_replace( 'PHP Warning:', '', $line ) );
231 + $type = 'warning';
232 + }
233 + else if ( preg_match( '/PHP Notice/', $line ) ) {
234 + $line = trim( str_replace( 'PHP Notice:', '', $line ) );
235 + $type = 'notice';
236 + }
237 + else if ( preg_match( '/PHP Parse error/', $line ) ) {
238 + $line = trim( str_replace( 'PHP Parse error:', '', $line ) );
239 + $type = 'parse';
240 + }
241 + else if ( preg_match( '/PHP Exception/', $line ) ) {
242 + $line = trim( str_replace( 'PHP Exception:', '', $line ) );
243 + $type = 'exception';
244 + }
245 + else {
246 + continue;
247 + }
248 +
249 + // Skip the error if is the same as before.
250 + if ( $line !== $previous_line ) {
251 + array_push( $output_lines, [ 'date' => $date, 'type' => $type, 'content' => $line ] );
252 + $previous_line = $line;
253 + }
254 + }
255 + }
256 + catch ( OutOfBoundsException $e ) {
257 + error_log( $e->getMessage() );
258 + return [];
259 + }
260 + }
261 + return $output_lines;
262 +
263 + // else {
264 + // $output_lines = array_reverse( $output_lines );
265 + // $html = '';
266 + // $previous = '';
267 + // foreach ( $output_lines as $line ) {
268 + // // Let's avoid similar errors, since it's not useful. We should also make this better
269 + // // and not only theck this depending on tie.
270 + // if ( preg_replace( '/\[.*\] PHP/', '', $previous ) !== preg_replace( '/\[.*\] PHP/', '', $line ) ) {
271 + // $html .= $line;
272 + // $previous = $line;
273 + // }
274 + // }
275 + // return $html;
276 + // }
277 + }
278 +
279 + public static function timer_start( $timerName = 'default' ) {
280 + MeowKit_MGL_Helpers::$startQueries[ $timerName ] = get_num_queries();
281 + MeowKit_MGL_Helpers::$startTimes[ $timerName ] = microtime( true );
282 + }
283 +
284 + public static function timer_elapsed( $timerName = 'default' ) {
285 + return microtime( true ) - MeowKit_MGL_Helpers::$startTimes[ $timerName ];
286 + }
287 +
288 + public static function timer_log_elapsed( $timerName = 'default' ) {
289 + $elapsed = MeowKit_MGL_Helpers::timer_elapsed( $timerName );
290 + $queries = get_num_queries() - MeowKit_MGL_Helpers::$startQueries[ $timerName ];
291 + error_log( $timerName . ': ' . $elapsed . 'ms (' . $queries . ' queries)' );
292 + }
293 + }
294 +
295 + // Asked by WP Security Team to remove this.
296 +
297 + // if ( MeowKit_MGL_Helpers::is_rest() ) {
298 + // ini_set( 'display_errors', 0 );
299 + // }
196 300 }