Changeset 3381078
- Timestamp:
- 10/20/2025 07:06:14 AM (5 months ago)
- Location:
- easyling
- Files:
-
- 1 deleted
- 8 edited
- 12 copied
-
tags/2.4 (copied) (copied from easyling/trunk)
-
tags/2.4/assets (copied) (copied from easyling/trunk/assets)
-
tags/2.4/assets/.DS_Store (deleted)
-
tags/2.4/assets/css/admin.css (copied) (copied from easyling/trunk/assets/css/admin.css) (1 diff)
-
tags/2.4/assets/js/admin-menu.js (copied) (copied from easyling/trunk/assets/js/admin-menu.js)
-
tags/2.4/assets/js/admin.js (copied) (copied from easyling/trunk/assets/js/admin.js) (2 diffs)
-
tags/2.4/easyling.php (copied) (copied from easyling/trunk/easyling.php) (9 diffs)
-
tags/2.4/gpl-2.0.txt (copied) (copied from easyling/trunk/gpl-2.0.txt)
-
tags/2.4/inc (copied) (copied from easyling/trunk/inc)
-
tags/2.4/inc/admin.php (copied) (copied from easyling/trunk/inc/admin.php) (1 diff)
-
tags/2.4/inc/frontend.php (copied) (copied from easyling/trunk/inc/frontend.php) (6 diffs)
-
tags/2.4/inc/integration (copied) (copied from easyling/trunk/inc/integration)
-
tags/2.4/inc/integration/menus.php (modified) (2 diffs)
-
tags/2.4/readme.txt (copied) (copied from easyling/trunk/readme.txt) (2 diffs)
-
trunk/assets/css/admin.css (modified) (1 diff)
-
trunk/assets/js/admin.js (modified) (2 diffs)
-
trunk/easyling.php (modified) (9 diffs)
-
trunk/inc/admin.php (modified) (1 diff)
-
trunk/inc/frontend.php (modified) (6 diffs)
-
trunk/inc/integration/menus.php (modified) (2 diffs)
-
trunk/readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
easyling/tags/2.4/assets/css/admin.css
r3098777 r3381078 52 52 display: none; 53 53 } 54 #EasylingConnectionStatus { 55 overflow-x: auto; 56 max-width: 60vw; 57 } -
easyling/tags/2.4/assets/js/admin.js
r3236567 r3381078 42 42 if (data.status) { 43 43 $('#EasylingConnectionStatus').removeClass('notice-error').addClass('notice-success'); 44 45 // TODO: Add details 44 46 } else { 45 47 $('#EasylingConnectionStatus').removeClass('notice-success').addClass('notice-error'); … … 49 51 .fail(function onFail() { 50 52 console.log('onFail'); 51 $('#EasylingConnectionStatus').removeClass('notice-success').addClass('notice-error');53 $('#EasylingConnectionStatus').removeClass('notice-success').addClass('notice-error'); 52 54 $('#EasylingConnectionStatus').show().html( 'Unknown error occurred' ); 53 55 }) -
easyling/tags/2.4/easyling.php
r3236567 r3381078 4 4 Plugin URI: https://www.easyling.com/ 5 5 Description: One-click website translation solution from Easyling. 6 Version: 2. 36 Version: 2.4 7 7 Author: Easyling 8 8 Copyright: Easyling … … 80 80 private function __construct() { 81 81 $this->settings = array( 82 'version' => '2. 3',82 'version' => '2.4', 83 83 'path' => plugin_dir_path( __FILE__ ), 84 84 'url' => plugin_dir_url( __FILE__ ), … … 111 111 // Get from cache if not expired 112 112 $project_settings = defined('ENABLE_CACHE') ? wp_cache_get( 'project_settings', 'easyling' ) : get_transient( 'easyling_project_settings' ); 113 113 114 if ( ! empty( $project_settings ) && ! $ignore_cache ) { 114 115 // Settings are saved as encoded JSON string … … 133 134 $url = "https://{$location_host}/client/{$project_code}/0/stub.json?deployed={$deployed}"; 134 135 $response = wp_remote_get( $url, array( 'timeout' => 180 ) ); 136 135 137 $response_body = wp_remote_retrieve_body( $response ); 136 138 … … 184 186 185 187 /** 188 * Test connection of the configured project 189 */ 190 public function format_debug_array_values( $arr ) { 191 return sprintf( 192 '<span style="display: block; padding-left: 10px;">%s</span>', 193 implode( 194 '<br />', 195 array_map( 196 function( $key, $value ) { 197 $value = is_array( $value ) ? easyling()->format_debug_array_values( $value ) : $value; 198 return "{$key}: {$value}"; 199 }, 200 array_keys( $arr ), 201 array_values( $arr ) 202 ) 203 ) 204 ); 205 } 206 207 208 /** 209 * Test connection of the configured project 210 */ 211 public function test_connection_request() { 212 try { 213 $user_config = easyling()->get_user_config(); 214 215 $project_settings = easyling()->get_project_settings(); 216 if ( empty( $project_settings ) ) { 217 throw new Exception( __( 'Project settings are not saved yet', 'easyling' ), 1); 218 } 219 220 $subdir_locale_map = ! empty( $project_settings['subdir_locale_map'] ) ? $project_settings['subdir_locale_map'] : array(); 221 if ( empty( $subdir_locale_map ) ) { 222 throw new Exception( __( 'Languages are not configured', 'easyling' ), 1); 223 } 224 225 $location_host = $user_config['location_host'] === 'custom' ? $user_config['custom_location_host'] : $user_config['location_host']; 226 $location_host = ! empty( $location_host ) ? trim( $location_host ) : $location_host; 227 if ( empty( $location_host ) ) { 228 throw new Exception( __( 'Easyling location is invalid', 'easyling' ), 1); 229 } 230 $locale_prefix = array_key_first( $subdir_locale_map ); 231 $locale = $subdir_locale_map[ $locale_prefix ]; 232 233 $headers = easyling()->get_request_headers(); 234 235 $request_details = array(); 236 add_filter( 'pre_http_request', function( $preempt, $args, $url ) use ( &$request_details ) { 237 $request_details['preempt'] = $preempt; 238 $request_details['args'] = $args; 239 $request_details['url'] = $url; 240 return false; 241 }, 10, 3); 242 243 $result = easyling()->app_request( array( 244 'publishing_mode' => $user_config['publishing_mode'], 245 'locale' => $locale, 246 'project_code' => $user_config['project_code'], 247 'location_host' => $location_host, 248 'request_method' => 'GET', 249 'request_headers' => $headers, 250 'request_body' => null, 251 'request_uri' => "/{$locale_prefix}/", 252 'enforce_request_protocol' => "https", 253 ) ); 254 $response = $result['response']; 255 256 if ( is_wp_error( $response ) ) { 257 $error = sprintf( 258 __( 'Failed fetching %s, error: %s', 'easyling' ), 259 $result['proxy_url'], 260 $response->get_error_message() 261 ); 262 throw new Exception( $error, 1 ); 263 } 264 265 if ( $response['response']['code'] !== 200 ) { 266 $message = ''; 267 $message .= sprintf( 268 '<strong>%s</strong>', 269 __( 'Invalid response!', 'easyling' ) 270 ); 271 $message .= '<br />'; 272 $message .= '<br />'; 273 274 $message .= sprintf( '<strong>Request URL:</strong> %s<br />', $result['proxy_url'] ); 275 $message .= sprintf( 276 '<strong>Request arguments:</strong><br>%s<br>', 277 easyling()->format_debug_array_values( $result['proxy_request_args'] ) 278 ); 279 $message .= '<br />'; 280 $message .= '<br />'; 281 282 $message .= sprintf( '<strong>Status code:</strong> %s<br />', $response['response']['code'] ); 283 $message .= sprintf( 284 '<strong>Headers:</strong><br>%s<br>', 285 easyling()->format_debug_array_values( $response['headers']->getAll() ) 286 ); 287 $message .= '<br />'; 288 $message .= sprintf( '<strong>Body:</strong> <pre>%s</pre><br />', htmlspecialchars( $response['body'] ) ); 289 290 return array( 291 'status' => false, 292 'message' => $message, 293 ); 294 } 295 296 return array( 297 'request_details' => $request_details, 298 'response' => array( 299 'status' => $response['response']['code'], 300 'headers' => $response['headers']->getAll(), 301 'body' => $response['body'], 302 ), 303 'status' => true, 304 'message' => sprintf( 305 __( 'Successfully fetched %s, response code %s', 'easyling' ), 306 $result['proxy_url'], 307 $response['response']['code'] 308 ), 309 ); 310 } catch (Exception $e) { 311 return array( 312 'status' => false, 313 'message' => $e->getMessage(), 314 ); 315 } 316 } 317 318 319 /** 186 320 * Performs request to the app server 187 321 */ … … 199 333 200 334 // Prepare headers 335 $headers = ! empty( $request_headers ) ? $request_headers : array(); 201 336 $http_host = sanitize_text_field( $_SERVER['HTTP_HOST'] ); 337 338 // For GET requests remove headers implying a request body 339 if ($request_method === 'GET') { 340 $headers = easyling()->get_sanitized_request_headers( $headers ); 341 } 342 343 // Set required headers 202 344 $headers['Origin'] = $http_host; 203 345 $headers['Host'] = $proxy_host; … … 219 361 } 220 362 221 $request_scheme = ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) ? strtolower( sanitize_text_field( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) ) : strtolower( sanitize_text_field( $_SERVER['REQUEST_SCHEME'] ) ); 363 // Ensure the body is empty for the GET requests 364 if ( $request_method === 'GET' ) { 365 $proxy_request_args['body'] = null; 366 } 367 368 $forwarded_proto = ''; 369 if ( ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) ) { 370 $proto_raw = strtolower( sanitize_text_field( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) ); 371 if ( strpos( $proto_raw, ',' ) !== false ) { 372 $parts = array_map( 'trim', explode( ',', $proto_raw ) ); 373 if ( in_array( 'https', $parts, true ) ) { 374 $forwarded_proto = 'https'; 375 } elseif ( in_array( 'http', $parts, true ) ) { 376 $forwarded_proto = 'http'; 377 } else { 378 $forwarded_proto = reset( $parts ); 379 } 380 } else { 381 $forwarded_proto = $proto_raw; 382 } 383 } 384 385 $request_scheme = $forwarded_proto; 386 if ( empty( $request_scheme ) && ! empty( $_SERVER['REQUEST_SCHEME'] ) ) { 387 $request_scheme = strtolower( sanitize_text_field( $_SERVER['REQUEST_SCHEME'] ) ); 388 } 389 if ( empty( $request_scheme ) ) { 390 $request_scheme = is_ssl() ? 'https' : 'http'; 391 } 392 393 if ( !empty( $enforce_request_protocol) ) { 394 $request_scheme = $enforce_request_protocol; 395 } 396 222 397 $request_scheme = in_array( $request_scheme, array( 'http', 'https' ) ) ? $request_scheme : 'https'; 223 398 $proxy_url = "{$request_scheme}://{$proxy_host}{$request_uri}"; … … 225 400 // Proxy request 226 401 set_time_limit( $timeout + 10 ); 402 403 $response = wp_remote_request( $proxy_url, $proxy_request_args ); 227 404 228 405 return array( 229 406 'proxy_url' => $proxy_url, 230 407 'proxy_request_args' => $proxy_request_args, 231 'response' => wp_remote_request( $proxy_url, $proxy_request_args ),408 'response' => $response, 232 409 ); 410 } 411 412 413 /** 414 * Sanitize headers 415 */ 416 public function get_sanitized_request_headers( $headers = array() ) { 417 $disallowed_get_headers = array( 418 'Content-Type', 419 'Content-Length', 420 'Transfer-Encoding', 421 'Content-Encoding', 422 'Content-MD5', 423 ); 424 foreach ( $disallowed_get_headers as $header_name ) { 425 if ( isset( $headers[ $header_name ] ) ) { 426 unset( $headers[ $header_name ] ); 427 } 428 } 429 430 return $headers; 431 } 432 433 434 /** 435 * Parse all request headers 436 * Note: getallheaders works for apache only, but not nginx 437 */ 438 public function get_request_headers() { 439 $request_headers = array(); 440 foreach ( $_SERVER as $key => $value ) { 441 if ( empty( $value ) ) continue; 442 443 $is_http_key = strpos( $key, 'HTTP_' ) === 0; 444 $is_content_key = strpos( $key, 'CONTENT_' ) === 0; 445 if ( $is_http_key || $is_content_key ) { 446 $header_name = strtolower( $key ); 447 $header_name = preg_replace( '#^(HTTP_|CONTENT_)#i', '', $header_name ); 448 $header_name = str_replace( '_', ' ', $header_name ); 449 $header_name = ucwords( $header_name ); 450 $header_name = str_replace( ' ', '-', $header_name ); 451 $request_headers[ $header_name ] = $value; 452 } 453 } 454 455 return $request_headers; 233 456 } 234 457 … … 333 556 } 334 557 335 336 558 // initialize 337 559 easyling(); -
easyling/tags/2.4/inc/admin.php
r3236567 r3381078 407 407 check_ajax_referer( 'easyling_test_connection', 'nonce' ); 408 408 409 $user_config = easyling()->get_user_config(); 410 411 $project_settings = easyling()->get_project_settings(); 412 if ( empty( $project_settings ) ) { 413 throw new Exception( __( 'Project settings are not saved yet', 'easyling' ), 1); 414 } 415 416 $subdir_locale_map = ! empty( $project_settings['subdir_locale_map'] ) ? $project_settings['subdir_locale_map'] : array(); 417 if ( empty( $subdir_locale_map ) ) { 418 throw new Exception( __( 'Languages are not configured', 'easyling' ), 1); 419 } 420 421 $location_host = $user_config['location_host'] === 'custom' ? $user_config['custom_location_host'] : $user_config['location_host']; 422 $location_host = ! empty( $location_host ) ? trim( $location_host ) : $location_host; 423 if ( empty( $location_host ) ) { 424 throw new Exception( __( 'Easyling location is invalid', 'easyling' ), 1); 425 } 426 $locale_prefix = array_key_first( $subdir_locale_map ); 427 $locale = $subdir_locale_map[ $locale_prefix ]; 428 429 $result = easyling()->app_request( array( 430 'publishing_mode' => $user_config['publishing_mode'], 431 'locale' => $locale, 432 'project_code' => $user_config['project_code'], 433 'location_host' => $location_host, 434 'request_method' => 'GET', 435 'request_body' => null, 436 'request_uri' => "/{$locale_prefix}/", 437 ) ); 438 $response = $result['response']; 439 440 if ( is_wp_error( $response ) ) { 441 $error = sprintf( 442 __( 'Failed fetching %s, error: %s', 'easyling' ), 443 $result['proxy_url'], 444 $response->get_error_message() 445 ); 446 throw new Exception( $error, 1 ); 447 } 448 449 echo json_encode( array( 450 'result' => $result, 451 'status' => true, 452 'message' => sprintf( 453 __( 'Successfully fetched %s, response code %s', 'easyling' ), 454 $result['proxy_url'], 455 $response['response']['code'] 456 ), 457 ) ); 409 $test_connection_result = easyling()->test_connection_request(); 410 echo json_encode( $test_connection_result ); 458 411 } catch (Exception $e) { 459 412 echo json_encode( array( -
easyling/tags/2.4/inc/frontend.php
r3236567 r3381078 48 48 */ 49 49 public function handle_request() { 50 $headers = $this->get_request_headers();50 $headers = easyling()->get_request_headers(); 51 51 52 52 $user_config = easyling()->get_user_config(); … … 125 125 wp_enqueue_script( 'easyling-stub', "https://{$location_host}/client/{$project_code}/0/stub.js?deployed={$deployed_value}{$floating_language_selector_param}", array(), null, true ); 126 126 } if ( 'proxy' === $publishing_mode ) { 127 wp_enqueue_script( 'easyling-language-selector', "https://{$location_host}/_el/ext/js/languageSelector.js?code={$project_code}", array(), null, true ); 127 //wp_enqueue_script( 'easyling-language-selector', "https://{$location_host}/_el/ext/js/languageSelector.js?code={$project_code}", array(), null, true ); 128 wp_enqueue_script( 'easyling-language-selector', "https://{$location_host}/js/webtranslate/languageDropdown.js?crest=0&code={$project_code}&v=3", array(), null, true ); 128 129 } 129 130 } ); … … 236 237 237 238 $response = wp_remote_request( $prerender_url, $request_args ); 238 $response_body = wp_remote_retrieve_body( $response );239 $response_body = is_wp_error( $response_body ) ? '' : $response_body;239 $response_body = ! is_wp_error( $response ) ? wp_remote_retrieve_body( $response ) : ''; 240 $response_body = ! is_wp_error( $response_body ) ? $response_body : ''; 240 241 241 242 print( $response_body ); … … 252 253 'location_host' => $location_host, 253 254 'request_method' => $request_method, 255 'request_headers' => $headers, 254 256 'request_body' => $request_body, 255 257 'request_uri' => $server_request_uri, … … 257 259 $response = $result['response']; 258 260 $response_body = ! is_wp_error( $response ) ? wp_remote_retrieve_body( $response ) : ''; 259 $response_body = is_wp_error( $response_body ) ? '' : $response_body;261 $response_body = ! is_wp_error( $response_body ) ? $response_body : ''; 260 262 $proxy_response_headers = ! is_wp_error( $response ) && ! empty( $response['headers'] ) ? $response['headers']->getAll() : array(); 261 263 … … 326 328 327 329 return $should_prerender; 328 }329 330 331 /**332 * Parse all request headers333 * Note: getallheaders works for apache only, but not nginx334 */335 public function get_request_headers() {336 $request_headers = array();337 foreach ( $_SERVER as $key => $value ) {338 if ( empty( $value ) ) continue;339 340 $is_http_key = strpos( $key, 'HTTP_' ) === 0;341 $is_content_key = strpos( $key, 'CONTENT_' ) === 0;342 if ( $is_http_key || $is_content_key ) {343 $header_name = strtolower( $key );344 $header_name = preg_replace( '#^(HTTP_|CONTENT_)#i', '', $header_name );345 $header_name = str_replace( '_', ' ', $header_name );346 $header_name = ucwords( $header_name );347 $header_name = str_replace( ' ', '-', $header_name );348 $request_headers[ $header_name ] = $value;349 }350 }351 352 return $request_headers;353 330 } 354 331 -
easyling/tags/2.4/inc/integration/menus.php
r3035191 r3381078 80 80 <li> 81 81 <label class="menu-item-title"> 82 <input type="checkbox" class="menu-item-checkbox" name="menu-item[-1][menu-item-object-id]" value="-1" /> <?php echo esc_html( __(' Language Selector', 'easyling') ); ?>82 <input type="checkbox" class="menu-item-checkbox" name="menu-item[-1][menu-item-object-id]" value="-1" /> <?php echo esc_html( __('EL Language Selector', 'easyling') ); ?> 83 83 </label> 84 84 <input type="hidden" class="menu-item-type" name="menu-item[-1][menu-item-type]" value="custom" /> 85 <input type="hidden" class="menu-item-title" name="menu-item[-1][menu-item-title]" value="<?php echo esc_attr( __(' Language Selector', 'easyling') ); ?>" />85 <input type="hidden" class="menu-item-title" name="menu-item[-1][menu-item-title]" value="<?php echo esc_attr( __('EL Language Selector', 'easyling') ); ?>" /> 86 86 <input type="hidden" class="menu-item-url" name="menu-item[-1][menu-item-url]" value="#easyling-language-selector" /> 87 87 <input type="hidden" class="menu-item-classes" name="menu-item[-1][menu-item-classes]" /> … … 142 142 $items[] = array( 143 143 'id' => 'easyling_language_selector', 144 'title' => __(' Language Selector', 'easyling'),144 'title' => __('EL Language Selector', 'easyling'), 145 145 'type' => 'custom', 146 146 'url' => '#easyling-language-selector', -
easyling/tags/2.4/readme.txt
r3236567 r3381078 4 4 Requires at least: 4.7 5 5 Tested up to: 6.7 6 Stable tag: 2. 36 Stable tag: 2.4 7 7 Requires PHP: 7.0 8 8 License: GPLv2 or later … … 44 44 45 45 == Changelog == 46 = 2.4 = 47 Release Date: October 20th, 2025 48 49 Enhancements: 50 51 * Minor improvements to the frontend and admin 52 46 53 = 2.3 = 47 54 Release Date: February 7th, 2025 -
easyling/trunk/assets/css/admin.css
r3098777 r3381078 52 52 display: none; 53 53 } 54 #EasylingConnectionStatus { 55 overflow-x: auto; 56 max-width: 60vw; 57 } -
easyling/trunk/assets/js/admin.js
r3236567 r3381078 42 42 if (data.status) { 43 43 $('#EasylingConnectionStatus').removeClass('notice-error').addClass('notice-success'); 44 45 // TODO: Add details 44 46 } else { 45 47 $('#EasylingConnectionStatus').removeClass('notice-success').addClass('notice-error'); … … 49 51 .fail(function onFail() { 50 52 console.log('onFail'); 51 $('#EasylingConnectionStatus').removeClass('notice-success').addClass('notice-error');53 $('#EasylingConnectionStatus').removeClass('notice-success').addClass('notice-error'); 52 54 $('#EasylingConnectionStatus').show().html( 'Unknown error occurred' ); 53 55 }) -
easyling/trunk/easyling.php
r3236567 r3381078 4 4 Plugin URI: https://www.easyling.com/ 5 5 Description: One-click website translation solution from Easyling. 6 Version: 2. 36 Version: 2.4 7 7 Author: Easyling 8 8 Copyright: Easyling … … 80 80 private function __construct() { 81 81 $this->settings = array( 82 'version' => '2. 3',82 'version' => '2.4', 83 83 'path' => plugin_dir_path( __FILE__ ), 84 84 'url' => plugin_dir_url( __FILE__ ), … … 111 111 // Get from cache if not expired 112 112 $project_settings = defined('ENABLE_CACHE') ? wp_cache_get( 'project_settings', 'easyling' ) : get_transient( 'easyling_project_settings' ); 113 113 114 if ( ! empty( $project_settings ) && ! $ignore_cache ) { 114 115 // Settings are saved as encoded JSON string … … 133 134 $url = "https://{$location_host}/client/{$project_code}/0/stub.json?deployed={$deployed}"; 134 135 $response = wp_remote_get( $url, array( 'timeout' => 180 ) ); 136 135 137 $response_body = wp_remote_retrieve_body( $response ); 136 138 … … 184 186 185 187 /** 188 * Test connection of the configured project 189 */ 190 public function format_debug_array_values( $arr ) { 191 return sprintf( 192 '<span style="display: block; padding-left: 10px;">%s</span>', 193 implode( 194 '<br />', 195 array_map( 196 function( $key, $value ) { 197 $value = is_array( $value ) ? easyling()->format_debug_array_values( $value ) : $value; 198 return "{$key}: {$value}"; 199 }, 200 array_keys( $arr ), 201 array_values( $arr ) 202 ) 203 ) 204 ); 205 } 206 207 208 /** 209 * Test connection of the configured project 210 */ 211 public function test_connection_request() { 212 try { 213 $user_config = easyling()->get_user_config(); 214 215 $project_settings = easyling()->get_project_settings(); 216 if ( empty( $project_settings ) ) { 217 throw new Exception( __( 'Project settings are not saved yet', 'easyling' ), 1); 218 } 219 220 $subdir_locale_map = ! empty( $project_settings['subdir_locale_map'] ) ? $project_settings['subdir_locale_map'] : array(); 221 if ( empty( $subdir_locale_map ) ) { 222 throw new Exception( __( 'Languages are not configured', 'easyling' ), 1); 223 } 224 225 $location_host = $user_config['location_host'] === 'custom' ? $user_config['custom_location_host'] : $user_config['location_host']; 226 $location_host = ! empty( $location_host ) ? trim( $location_host ) : $location_host; 227 if ( empty( $location_host ) ) { 228 throw new Exception( __( 'Easyling location is invalid', 'easyling' ), 1); 229 } 230 $locale_prefix = array_key_first( $subdir_locale_map ); 231 $locale = $subdir_locale_map[ $locale_prefix ]; 232 233 $headers = easyling()->get_request_headers(); 234 235 $request_details = array(); 236 add_filter( 'pre_http_request', function( $preempt, $args, $url ) use ( &$request_details ) { 237 $request_details['preempt'] = $preempt; 238 $request_details['args'] = $args; 239 $request_details['url'] = $url; 240 return false; 241 }, 10, 3); 242 243 $result = easyling()->app_request( array( 244 'publishing_mode' => $user_config['publishing_mode'], 245 'locale' => $locale, 246 'project_code' => $user_config['project_code'], 247 'location_host' => $location_host, 248 'request_method' => 'GET', 249 'request_headers' => $headers, 250 'request_body' => null, 251 'request_uri' => "/{$locale_prefix}/", 252 'enforce_request_protocol' => "https", 253 ) ); 254 $response = $result['response']; 255 256 if ( is_wp_error( $response ) ) { 257 $error = sprintf( 258 __( 'Failed fetching %s, error: %s', 'easyling' ), 259 $result['proxy_url'], 260 $response->get_error_message() 261 ); 262 throw new Exception( $error, 1 ); 263 } 264 265 if ( $response['response']['code'] !== 200 ) { 266 $message = ''; 267 $message .= sprintf( 268 '<strong>%s</strong>', 269 __( 'Invalid response!', 'easyling' ) 270 ); 271 $message .= '<br />'; 272 $message .= '<br />'; 273 274 $message .= sprintf( '<strong>Request URL:</strong> %s<br />', $result['proxy_url'] ); 275 $message .= sprintf( 276 '<strong>Request arguments:</strong><br>%s<br>', 277 easyling()->format_debug_array_values( $result['proxy_request_args'] ) 278 ); 279 $message .= '<br />'; 280 $message .= '<br />'; 281 282 $message .= sprintf( '<strong>Status code:</strong> %s<br />', $response['response']['code'] ); 283 $message .= sprintf( 284 '<strong>Headers:</strong><br>%s<br>', 285 easyling()->format_debug_array_values( $response['headers']->getAll() ) 286 ); 287 $message .= '<br />'; 288 $message .= sprintf( '<strong>Body:</strong> <pre>%s</pre><br />', htmlspecialchars( $response['body'] ) ); 289 290 return array( 291 'status' => false, 292 'message' => $message, 293 ); 294 } 295 296 return array( 297 'request_details' => $request_details, 298 'response' => array( 299 'status' => $response['response']['code'], 300 'headers' => $response['headers']->getAll(), 301 'body' => $response['body'], 302 ), 303 'status' => true, 304 'message' => sprintf( 305 __( 'Successfully fetched %s, response code %s', 'easyling' ), 306 $result['proxy_url'], 307 $response['response']['code'] 308 ), 309 ); 310 } catch (Exception $e) { 311 return array( 312 'status' => false, 313 'message' => $e->getMessage(), 314 ); 315 } 316 } 317 318 319 /** 186 320 * Performs request to the app server 187 321 */ … … 199 333 200 334 // Prepare headers 335 $headers = ! empty( $request_headers ) ? $request_headers : array(); 201 336 $http_host = sanitize_text_field( $_SERVER['HTTP_HOST'] ); 337 338 // For GET requests remove headers implying a request body 339 if ($request_method === 'GET') { 340 $headers = easyling()->get_sanitized_request_headers( $headers ); 341 } 342 343 // Set required headers 202 344 $headers['Origin'] = $http_host; 203 345 $headers['Host'] = $proxy_host; … … 219 361 } 220 362 221 $request_scheme = ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) ? strtolower( sanitize_text_field( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) ) : strtolower( sanitize_text_field( $_SERVER['REQUEST_SCHEME'] ) ); 363 // Ensure the body is empty for the GET requests 364 if ( $request_method === 'GET' ) { 365 $proxy_request_args['body'] = null; 366 } 367 368 $forwarded_proto = ''; 369 if ( ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) ) { 370 $proto_raw = strtolower( sanitize_text_field( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) ); 371 if ( strpos( $proto_raw, ',' ) !== false ) { 372 $parts = array_map( 'trim', explode( ',', $proto_raw ) ); 373 if ( in_array( 'https', $parts, true ) ) { 374 $forwarded_proto = 'https'; 375 } elseif ( in_array( 'http', $parts, true ) ) { 376 $forwarded_proto = 'http'; 377 } else { 378 $forwarded_proto = reset( $parts ); 379 } 380 } else { 381 $forwarded_proto = $proto_raw; 382 } 383 } 384 385 $request_scheme = $forwarded_proto; 386 if ( empty( $request_scheme ) && ! empty( $_SERVER['REQUEST_SCHEME'] ) ) { 387 $request_scheme = strtolower( sanitize_text_field( $_SERVER['REQUEST_SCHEME'] ) ); 388 } 389 if ( empty( $request_scheme ) ) { 390 $request_scheme = is_ssl() ? 'https' : 'http'; 391 } 392 393 if ( !empty( $enforce_request_protocol) ) { 394 $request_scheme = $enforce_request_protocol; 395 } 396 222 397 $request_scheme = in_array( $request_scheme, array( 'http', 'https' ) ) ? $request_scheme : 'https'; 223 398 $proxy_url = "{$request_scheme}://{$proxy_host}{$request_uri}"; … … 225 400 // Proxy request 226 401 set_time_limit( $timeout + 10 ); 402 403 $response = wp_remote_request( $proxy_url, $proxy_request_args ); 227 404 228 405 return array( 229 406 'proxy_url' => $proxy_url, 230 407 'proxy_request_args' => $proxy_request_args, 231 'response' => wp_remote_request( $proxy_url, $proxy_request_args ),408 'response' => $response, 232 409 ); 410 } 411 412 413 /** 414 * Sanitize headers 415 */ 416 public function get_sanitized_request_headers( $headers = array() ) { 417 $disallowed_get_headers = array( 418 'Content-Type', 419 'Content-Length', 420 'Transfer-Encoding', 421 'Content-Encoding', 422 'Content-MD5', 423 ); 424 foreach ( $disallowed_get_headers as $header_name ) { 425 if ( isset( $headers[ $header_name ] ) ) { 426 unset( $headers[ $header_name ] ); 427 } 428 } 429 430 return $headers; 431 } 432 433 434 /** 435 * Parse all request headers 436 * Note: getallheaders works for apache only, but not nginx 437 */ 438 public function get_request_headers() { 439 $request_headers = array(); 440 foreach ( $_SERVER as $key => $value ) { 441 if ( empty( $value ) ) continue; 442 443 $is_http_key = strpos( $key, 'HTTP_' ) === 0; 444 $is_content_key = strpos( $key, 'CONTENT_' ) === 0; 445 if ( $is_http_key || $is_content_key ) { 446 $header_name = strtolower( $key ); 447 $header_name = preg_replace( '#^(HTTP_|CONTENT_)#i', '', $header_name ); 448 $header_name = str_replace( '_', ' ', $header_name ); 449 $header_name = ucwords( $header_name ); 450 $header_name = str_replace( ' ', '-', $header_name ); 451 $request_headers[ $header_name ] = $value; 452 } 453 } 454 455 return $request_headers; 233 456 } 234 457 … … 333 556 } 334 557 335 336 558 // initialize 337 559 easyling(); -
easyling/trunk/inc/admin.php
r3236567 r3381078 407 407 check_ajax_referer( 'easyling_test_connection', 'nonce' ); 408 408 409 $user_config = easyling()->get_user_config(); 410 411 $project_settings = easyling()->get_project_settings(); 412 if ( empty( $project_settings ) ) { 413 throw new Exception( __( 'Project settings are not saved yet', 'easyling' ), 1); 414 } 415 416 $subdir_locale_map = ! empty( $project_settings['subdir_locale_map'] ) ? $project_settings['subdir_locale_map'] : array(); 417 if ( empty( $subdir_locale_map ) ) { 418 throw new Exception( __( 'Languages are not configured', 'easyling' ), 1); 419 } 420 421 $location_host = $user_config['location_host'] === 'custom' ? $user_config['custom_location_host'] : $user_config['location_host']; 422 $location_host = ! empty( $location_host ) ? trim( $location_host ) : $location_host; 423 if ( empty( $location_host ) ) { 424 throw new Exception( __( 'Easyling location is invalid', 'easyling' ), 1); 425 } 426 $locale_prefix = array_key_first( $subdir_locale_map ); 427 $locale = $subdir_locale_map[ $locale_prefix ]; 428 429 $result = easyling()->app_request( array( 430 'publishing_mode' => $user_config['publishing_mode'], 431 'locale' => $locale, 432 'project_code' => $user_config['project_code'], 433 'location_host' => $location_host, 434 'request_method' => 'GET', 435 'request_body' => null, 436 'request_uri' => "/{$locale_prefix}/", 437 ) ); 438 $response = $result['response']; 439 440 if ( is_wp_error( $response ) ) { 441 $error = sprintf( 442 __( 'Failed fetching %s, error: %s', 'easyling' ), 443 $result['proxy_url'], 444 $response->get_error_message() 445 ); 446 throw new Exception( $error, 1 ); 447 } 448 449 echo json_encode( array( 450 'result' => $result, 451 'status' => true, 452 'message' => sprintf( 453 __( 'Successfully fetched %s, response code %s', 'easyling' ), 454 $result['proxy_url'], 455 $response['response']['code'] 456 ), 457 ) ); 409 $test_connection_result = easyling()->test_connection_request(); 410 echo json_encode( $test_connection_result ); 458 411 } catch (Exception $e) { 459 412 echo json_encode( array( -
easyling/trunk/inc/frontend.php
r3236567 r3381078 48 48 */ 49 49 public function handle_request() { 50 $headers = $this->get_request_headers();50 $headers = easyling()->get_request_headers(); 51 51 52 52 $user_config = easyling()->get_user_config(); … … 125 125 wp_enqueue_script( 'easyling-stub', "https://{$location_host}/client/{$project_code}/0/stub.js?deployed={$deployed_value}{$floating_language_selector_param}", array(), null, true ); 126 126 } if ( 'proxy' === $publishing_mode ) { 127 wp_enqueue_script( 'easyling-language-selector', "https://{$location_host}/_el/ext/js/languageSelector.js?code={$project_code}", array(), null, true ); 127 //wp_enqueue_script( 'easyling-language-selector', "https://{$location_host}/_el/ext/js/languageSelector.js?code={$project_code}", array(), null, true ); 128 wp_enqueue_script( 'easyling-language-selector', "https://{$location_host}/js/webtranslate/languageDropdown.js?crest=0&code={$project_code}&v=3", array(), null, true ); 128 129 } 129 130 } ); … … 236 237 237 238 $response = wp_remote_request( $prerender_url, $request_args ); 238 $response_body = wp_remote_retrieve_body( $response );239 $response_body = is_wp_error( $response_body ) ? '' : $response_body;239 $response_body = ! is_wp_error( $response ) ? wp_remote_retrieve_body( $response ) : ''; 240 $response_body = ! is_wp_error( $response_body ) ? $response_body : ''; 240 241 241 242 print( $response_body ); … … 252 253 'location_host' => $location_host, 253 254 'request_method' => $request_method, 255 'request_headers' => $headers, 254 256 'request_body' => $request_body, 255 257 'request_uri' => $server_request_uri, … … 257 259 $response = $result['response']; 258 260 $response_body = ! is_wp_error( $response ) ? wp_remote_retrieve_body( $response ) : ''; 259 $response_body = is_wp_error( $response_body ) ? '' : $response_body;261 $response_body = ! is_wp_error( $response_body ) ? $response_body : ''; 260 262 $proxy_response_headers = ! is_wp_error( $response ) && ! empty( $response['headers'] ) ? $response['headers']->getAll() : array(); 261 263 … … 326 328 327 329 return $should_prerender; 328 }329 330 331 /**332 * Parse all request headers333 * Note: getallheaders works for apache only, but not nginx334 */335 public function get_request_headers() {336 $request_headers = array();337 foreach ( $_SERVER as $key => $value ) {338 if ( empty( $value ) ) continue;339 340 $is_http_key = strpos( $key, 'HTTP_' ) === 0;341 $is_content_key = strpos( $key, 'CONTENT_' ) === 0;342 if ( $is_http_key || $is_content_key ) {343 $header_name = strtolower( $key );344 $header_name = preg_replace( '#^(HTTP_|CONTENT_)#i', '', $header_name );345 $header_name = str_replace( '_', ' ', $header_name );346 $header_name = ucwords( $header_name );347 $header_name = str_replace( ' ', '-', $header_name );348 $request_headers[ $header_name ] = $value;349 }350 }351 352 return $request_headers;353 330 } 354 331 -
easyling/trunk/inc/integration/menus.php
r3035191 r3381078 80 80 <li> 81 81 <label class="menu-item-title"> 82 <input type="checkbox" class="menu-item-checkbox" name="menu-item[-1][menu-item-object-id]" value="-1" /> <?php echo esc_html( __(' Language Selector', 'easyling') ); ?>82 <input type="checkbox" class="menu-item-checkbox" name="menu-item[-1][menu-item-object-id]" value="-1" /> <?php echo esc_html( __('EL Language Selector', 'easyling') ); ?> 83 83 </label> 84 84 <input type="hidden" class="menu-item-type" name="menu-item[-1][menu-item-type]" value="custom" /> 85 <input type="hidden" class="menu-item-title" name="menu-item[-1][menu-item-title]" value="<?php echo esc_attr( __(' Language Selector', 'easyling') ); ?>" />85 <input type="hidden" class="menu-item-title" name="menu-item[-1][menu-item-title]" value="<?php echo esc_attr( __('EL Language Selector', 'easyling') ); ?>" /> 86 86 <input type="hidden" class="menu-item-url" name="menu-item[-1][menu-item-url]" value="#easyling-language-selector" /> 87 87 <input type="hidden" class="menu-item-classes" name="menu-item[-1][menu-item-classes]" /> … … 142 142 $items[] = array( 143 143 'id' => 'easyling_language_selector', 144 'title' => __(' Language Selector', 'easyling'),144 'title' => __('EL Language Selector', 'easyling'), 145 145 'type' => 'custom', 146 146 'url' => '#easyling-language-selector', -
easyling/trunk/readme.txt
r3236567 r3381078 4 4 Requires at least: 4.7 5 5 Tested up to: 6.7 6 Stable tag: 2. 36 Stable tag: 2.4 7 7 Requires PHP: 7.0 8 8 License: GPLv2 or later … … 44 44 45 45 == Changelog == 46 = 2.4 = 47 Release Date: October 20th, 2025 48 49 Enhancements: 50 51 * Minor improvements to the frontend and admin 52 46 53 = 2.3 = 47 54 Release Date: February 7th, 2025
Note: See TracChangeset
for help on using the changeset viewer.