PluginProbe
Translate and Go multilingual – Automatic AI translation – wpLingua / 2.10.0
Translate and Go multilingual – Automatic AI translation – wpLingua v2.10.0
2.16.6 2.16.5 2.16.4 2.16.3 2.16.2 2.16.1 2.16.0 2.15.2 2.15.1 2.15.0 2.14.3 2.14.2 2.14.1 2.14.0 2.13.1 2.13.0 2.12.3 2.12.2 2.12.1 trunk 1.0.3 1.0.4 1.0.5 1.1.0 1.1.1 All 111 releases
wplingua / inc / util.php

util.php in Translate and Go multilingual – Automatic AI translation – wpLingua 2.10.0, at inc/util.php

375 lines 8.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // If this file is called directly, abort.
4 if ( ! defined( 'WPINC' ) ) {
5 die;
6 }
7
8
9 /**
10 * Check if substring is contained in string
11 *
12 * @param string $haystack String to check
13 * @param string $needle Sub-string
14 *
15 * @return bool
16 */
17 function wplng_str_contains( $haystack, $needle ) {
18 return ( strpos( $haystack, $needle ) !== false );
19 }
20
21
22 /**
23 * Check if string starts by sub_string
24 *
25 * @param string $haystack String to check
26 * @param string $needle Sub-string
27 *
28 * @return bool
29 */
30 function wplng_str_starts_with( $haystack, $needle ) {
31
32 if ( ! is_string( $haystack ) || ! is_string( $needle ) ) {
33 return false;
34 }
35
36 return substr_compare( $haystack, $needle, 0, strlen( $needle ) ) === 0;
37 }
38
39
40 /**
41 * Check if string ends by sub_string
42 *
43 * @param string $haystack String to check
44 * @param string $needle Sub-string
45 *
46 * @return bool
47 */
48 function wplng_str_ends_with( $haystack, $needle ) {
49
50 if ( ! is_string( $haystack ) || ! is_string( $needle ) ) {
51 return false;
52 }
53
54 return substr_compare( $haystack, $needle, -strlen( $needle ) ) === 0;
55 }
56
57 /**
58 * Return true is $str is an URL
59 *
60 * @param string $str
61 * @return bool
62 */
63 function wplng_str_is_url( $str ) {
64
65 $parsed = wp_parse_url( $str );
66 $is_url = false;
67
68 if ( is_string( $str )
69 && ( '' !== trim( $str ) )
70 && wplng_str_contains( $str, '/' )
71 && ! wplng_str_starts_with( $str, 'wpgb-content-block/' ) // Plugin: WP Grid Builder
72 && ! wplng_str_starts_with( $str, '/wc/store/v1' ) // Plugin: WooCommerce
73 && ! wplng_str_starts_with( $str, 'GlotPress/' ) // Plugin: WooCommerce
74 ) {
75 if ( isset( $parsed['scheme'] )
76 && (
77 ( 'https' === $parsed['scheme'] )
78 || ( 'http' === $parsed['scheme'] )
79 )
80 ) {
81 // URL has http/https/...
82 $is_url = ! ( filter_var( $str, FILTER_VALIDATE_URL ) === false );
83 } else {
84 // PHP filter_var does not support relative urls, so we simulate a full URL
85 $is_url = ( filter_var( 'https://website.com/' . ltrim( $str, '/' ), FILTER_VALIDATE_URL ) !== false );
86 }
87 }
88
89 return $is_url;
90 }
91
92
93 /**
94 * Return true is $str is a translatable text
95 * Return false if $str is a number, mail addredd, symbol, ...
96 *
97 * @param string $text
98 * @return bool
99 */
100 function wplng_text_is_translatable( $text ) {
101
102 $text = trim( $text );
103
104 if ( '' === $text ) {
105 return false;
106 }
107
108 // Check special no translate tag
109 if ( wplng_str_contains( $text, '_wplingua_no_translate_' ) ) {
110 return false;
111 }
112
113 // Check for better plugin compatibility
114 if ( wplng_str_contains( $text, 'presto_player' )
115 || wplng_str_contains( $text, 'presto-player' )
116 ) {
117 return false;
118 }
119
120 // Check if it's a email address
121 if ( filter_var( $text, FILTER_VALIDATE_EMAIL ) ) {
122 return false;
123 }
124
125 // Check bad HTML tags and templating tags
126 if ( wplng_str_starts_with( $text, '<' )
127 && wplng_str_ends_with( $text, '>' )
128 ) {
129 return false;
130 }
131
132 // Check JS tags
133 if ( wplng_str_starts_with( $text, '{{' )
134 && wplng_str_ends_with( $text, '}}' )
135 ) {
136 return false;
137 }
138
139 // Get letters only
140 $letters = $text;
141 $letters = html_entity_decode( $letters );
142 $letters = preg_replace( '#[^\p{L}\p{N}]#u', '', $letters );
143 $letters = preg_replace( '#[\d\s]#u', '', $letters );
144
145 return ! empty( $letters );
146 }
147
148
149 /**
150 * Escape texte (used for comparison)
151 *
152 * @param string $text String to escape
153 * @return string Escape texte for comparison
154 */
155 function wplng_text_esc( $text ) {
156
157 $text = html_entity_decode( $text );
158 $text = esc_html( $text );
159 $text = esc_attr( $text );
160
161 $text = wp_specialchars_decode(
162 $text,
163 ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401
164 );
165
166 $text = str_replace( '\\', '', $text );
167 $text = preg_replace( '/\s+/u', ' ', $text );
168 $text = trim( $text );
169
170 return $text;
171 }
172
173
174 /**
175 * Escape texte (used for editor)
176 *
177 * @param string $text String to escape
178 * @return string Escape texte for editor
179 */
180 function wplng_text_esc_displayed( $text ) {
181
182 $search = array( '<', '&lt;', '>', '&gt;' );
183 $replace = array( '[', '[', ']', ']' );
184
185 $text = str_replace(
186 $search,
187 $replace,
188 $text
189 );
190
191 return $text;
192 }
193
194
195 /**
196 * Return true if $str is HTML
197 *
198 * @param string $str String to check
199 * @return bool true if $str is HTML
200 */
201 function wplng_str_is_html( $str ) {
202 return wplng_str_contains( $str, '<' )
203 && wplng_str_contains( $str, '>' )
204 && ( $str !== wp_strip_all_tags( $str ) );
205 }
206
207
208 /**
209 * Checks whether a string is a valid XML.
210 *
211 * @param string $str The string to validate.
212 * @return bool Returns true if the string is valid XML, false otherwise.
213 */
214 function wplng_str_is_xml( $str ) {
215 // Return false if the input is empty or not a string.
216 if ( empty( $str ) || ! is_string( $str ) ) {
217 return false;
218 }
219
220 // Suppress XML parsing errors to avoid warnings/notices.
221 libxml_use_internal_errors( true );
222
223 // Try to load the string as XML.
224 $xml = simplexml_load_string( $str );
225
226 // Determine if parsing was successful.
227 $is_valid_xml = ( $xml !== false );
228
229 // Clear any accumulated libxml errors.
230 libxml_clear_errors();
231 libxml_use_internal_errors( false );
232
233 return $is_valid_xml;
234 }
235
236
237 /**
238 * Return true if $str is a local ID
239 * Ex: fr_FR, fr, FR, ...
240 *
241 * @param string $str String to check
242 * @return bool true if $str is a local ID
243 */
244 function wplng_str_is_locale_id( $str ) {
245
246 $locale = get_locale();
247 $locales = array(
248 $locale, // Ex: fr_FR
249 strtolower( $locale ), // Ex: fr_fr
250 str_replace( '_', '-', $locale ), // Ex: fr-FR
251 strtolower( str_replace( '_', '-', $locale ) ), // Ex: fr-fr
252 substr( $locale, 0, 2 ), // Ex: FR
253 strtolower( substr( $locale, 0, 2 ) ), // Ex: fr
254 );
255
256 return in_array( $str, $locales );
257 }
258
259
260 /**
261 * Return true if $str contains sub-strings present in the i18n script
262 *
263 * @param string $str String to check
264 * @return bool String is a i18n script
265 */
266 function wplng_str_is_script_i18n( $str ) {
267
268 $str = trim( $str );
269
270 return wplng_str_contains( $str, 'wp.i18n.setLocaleData' )
271 && wplng_str_contains( $str, 'translations.locale_data.messages' )
272 // Check if $str ends with ");"
273 && wplng_str_ends_with( $str, ');' )
274 // Check if $str starts with "( function( domain, translations ) {"
275 && ( preg_match( '#^\(\s*function\s*\(\s*domain\s*,\s*translations\s*\)\s*\{#', $str ) === 1 );
276 }
277
278
279 /**
280 * Return true is $str is a JSON
281 *
282 * @param string $str String to check
283 * @return bool true is $str is a JSON
284 */
285 function wplng_str_is_json( $str ) {
286 $decoded = json_decode( $str, true );
287 return ( json_last_error() === JSON_ERROR_NONE ) && is_array( $decoded );
288 }
289
290
291 /**
292 * Checks if a JSON element should be excluded based on defined exclusion rules.
293 *
294 * @param mixed $element The JSON element to check.
295 * @param array $parents The parent elements of the JSON element.
296 *
297 * @return bool True if the element matches any exclusion rule, false otherwise.
298 */
299 function wplng_json_element_is_excluded( $element, $parents ) {
300
301 $rules = wplng_data_json_rules_exclusion();
302
303 foreach ( $rules as $rule ) {
304 if ( $rule( $element, $parents ) === true ) {
305 return true;
306 }
307 }
308
309 return false;
310 }
311
312
313 /**
314 * Checks if a JSON element should be included based on defined inclusion rules.
315 *
316 * @param mixed $element The JSON element to check.
317 * @param array $parents The parent elements of the JSON element.
318 *
319 * @return bool True if the element matches any inclusion rule, false otherwise.
320 */
321 function wplng_json_element_is_included( $element, $parents ) {
322
323 $rules = wplng_data_json_rules_inclusion();
324
325 foreach ( $rules as $rule ) {
326 if ( $rule( $element, $parents ) === true ) {
327 return true;
328 }
329 }
330
331 return false;
332 }
333
334
335 /**
336 * Get the context
337 *
338 * @return string Context
339 */
340 function wplng_get_context() {
341
342 $context = 'UNKNOW';
343
344 if ( defined( 'DOING_AJAX' )
345 && DOING_AJAX
346 && ! empty( $_SERVER['HTTP_REFERER'] )
347 ) {
348 $context = $_SERVER['HTTP_REFERER'];
349 $context = sanitize_url( $context );
350 } elseif ( isset( $_SERVER['HTTPS'] )
351 && isset( $_SERVER['HTTP_HOST'] )
352 && isset( $_SERVER['REQUEST_URI'] )
353 ) {
354 $context = ( empty( $_SERVER['HTTPS'] ) ? 'http' : 'https' );
355 $context .= '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
356 $context = sanitize_url( $context );
357 }
358
359 return apply_filters(
360 'wplng_api_call_translate_context',
361 $context
362 );
363 }
364
365
366 /**
367 * Return true is website is in sub folder
368 *
369 * @return bool
370 */
371 function wplng_website_in_sub_folder() {
372 $parsed = wp_parse_url( get_home_url() );
373 return ! empty( $parsed['path'] );
374 }
375