Changeset 3135855
- Timestamp:
- 08/15/2024 01:44:12 AM (8 months ago)
- Location:
- fluentc-translation
- Files:
-
- 371 added
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
fluentc-translation/trunk/bootstrap.php
r3122693 r3135855 47 47 '\FluentC\Services\Connect', 48 48 '\FluentC\Services\Html', 49 '\FluentC\Services\Scan', 50 '\FluentC\Services\TranslationProcessor', 49 51 50 52 ); … … 60 62 'FluentC\Actions\Wordpress', 61 63 'FluentC\Actions\Admin', 64 'FluentC\Actions\Translationstatus', 62 65 ); 63 66 -
fluentc-translation/trunk/fluentc_settings.php
r3122693 r3135855 4 4 } 5 5 ?> 6 <div class="wrap"> 7 <style> 8 .nav-tab-wrapper { 9 margin-bottom: 20px; 10 } 6 <div class="wrap fluentc-translations-page"> 7 <div class="fluentc-header"> 8 <img src="<?php echo plugin_dir_url(__FILE__) . '/src/includes/fluentc-logo.png'; ?>" alt="FluentC Logo" class="fluentc-logo"> 9 <h1><?php _e('FluentC Translation Settings', 'fluentc-translation'); ?></h1> 10 <div class="fluentc-header-button"> 11 <?php if ( $this->fluentc_get_settings() ) { ?> 12 <a href="https://dashboard.fluentc.ai/manage/<?php echo esc_attr( $this->fluentc_get_settings() ); ?>?redirect=<?php echo esc_url( admin_url( 'admin.php?page=fluentc-settings' ) ); ?>" class="button button-primary"><?php _e( 'Manage Account', 'fluentc-translation' ); ?></a> 13 <?php } else { ?> 14 <a href="https://dashboard.fluentc.ai/sites?instruction=connect&redirect=<?php echo esc_url( admin_url( 'admin.php?page=fluentc-settings' ) ); ?>" class="button button-primary"><?php _e( 'Connect to FluentC', 'fluentc-translation' ); ?></a> 15 <?php } ?> 16 </div> 17 </div> 11 18 12 .tab-content { 13 display: none; 14 } 19 <div class="fluentc-description"> 20 <p><?php _e('Manage your FluentC translation settings, connect your account, and configure language options.', 'fluentc-translation'); ?></p> 21 </div> 15 22 16 .tab-content.current { 17 display: block; 18 } 19 23 <div class="nav-tab-wrapper"> 24 <a href="#tab-1" class="nav-tab nav-tab-active" data-tab="tab-1"><?php _e( 'Connect', 'fluentc-translation' ); ?></a> 25 <a href="#tab-2" class="nav-tab" data-tab="tab-2"><?php _e( 'Languages', 'fluentc-translation' ); ?></a> 26 <a href="#tab-3" class="nav-tab" data-tab="tab-3"><?php _e( 'Advanced', 'fluentc-translation' ); ?></a> 27 </div> 20 28 21 #e-admin-top-bar-root { 22 right: 0; 23 font-family: var(--e-a-font-family); 24 background: var(--e-a-bg-default); 25 box-shadow: 0 4px 6px rgba(0,0,0,.03); 26 display: none; 27 top: 0; 28 width: calc(100%); 29 z-index: 1 30 } 29 <div id="tab-1" class="tab-content current"> 30 <p><?php _e( 'To use FluentC, you need an active subscription.', 'fluentc-translation' ); ?></p> 31 <?php if ( $this->fluentc_get_settings() ) { ?> 32 <a href="https://dashboard.fluentc.ai/manage/<?php echo esc_attr( $this->fluentc_get_settings() ); ?>?redirect=<?php echo esc_url( admin_url( 'admin.php?page=fluentc-settings' ) ); ?>" class="button button-primary"><?php _e( 'Manage FluentC Account and Languages', 'fluentc-translation' ); ?></a> 33 <?php } else { ?> 34 <a href="https://dashboard.fluentc.ai/sites?instruction=connect&redirect=<?php echo esc_url( admin_url( 'admin.php?page=fluentc-settings' ) ); ?>" class="button button-primary"><?php _e( 'Sign Up and Connect to FluentC', 'fluentc-translation' ); ?></a> 35 <h2><?php _e( 'Three steps to have translation on your site', 'fluentc-translation' ); ?></h2> 36 <ol> 37 <li><?php _e( 'Click the link above to link your site to FluentC', 'fluentc-translation' ); ?></li> 38 <li><?php _e( 'Subscribe to Languages', 'fluentc-translation' ); ?></li> 39 <li><?php _e( 'Add the html tag if you choose to display the languages as dropdown or list', 'fluentc-translation' ); ?></li> 40 </ol> 41 <?php } ?> 42 </div> 31 43 32 body.folded #e-admin-top-bar-root { 33 width: calc(100% - 36px)34 } 44 <div id="tab-2" class="tab-content"> 45 <?php do_action( 'fluentc_admin_settings_page' ); ?> 46 </div> 35 47 36 #e-admin-top-bar-root .e-admin-top-bar { 37 display: flex; 38 height: 50px; 39 justify-content: space-between; 40 padding: 0 16px 41 } 48 <div id="tab-3" class="tab-content"> 49 <form method="post" action='<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>'> 50 <?php wp_nonce_field( 'fluentc_save_settings_action', 'fluentc_settings_nonce_field' ); ?> 51 <input type="hidden" name="action" value="fluentc_save_settings_action"> 52 <table class="form-table"> 53 <tbody> 54 <tr> 55 <th scope="row"><label for="fluentc_api_key"><?php _e( 'FluentC API Key', 'fluentc-translation' ); ?></label></th> 56 <td><input name="fluentc_api_key" type="text" id="fluentc_api_key" 57 value="<?php echo esc_attr( $this->fluentc_get_settings() ); ?>" class="regular-text"> 58 </td> 59 </tr> 60 </tbody> 61 </table> 62 <p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" 63 value="<?php _e( 'Save Changes', 'fluentc-translation' ); ?>"></p> 64 </form> 42 65 43 #e-admin-top-bar-root .page-title-action { 44 font-size: 12px; 45 font-weight: 500; 46 line-height: 1.2; 47 text-transform: uppercase; 48 text-decoration: none; 49 padding: 8px 16px; 50 outline: none; 51 border: none; 52 border-radius: var(--e-a-border-radius); 53 background-color: var(--e-a-btn-bg); 54 color: var(--e-a-btn-color-invert); 55 transition: var(--e-a-transition-hover) 56 } 66 <?php do_action( 'fluentc_admin_tab_three_page' ); ?> 67 <?php do_action( 'fluentc_activation_setup' ); ?> 68 </div> 57 69 58 #e-admin-top-bar-root .page-title-action:hover { 59 background-color: var(--e-a-btn-bg-hover); 60 color: var(--e-a-btn-color-invert) 61 } 70 <p class="fluentc-footer"><?php _e( 'For any assistance please contact FluentC', 'fluentc-translation' ); ?> | <a href="https://www.fluentc.ai/" target="_blank"><?php _e( 'Help and Support', 'fluentc-translation' ); ?></a></p> 71 </div> 62 72 63 #e-admin-top-bar-root .e-admin-top-bar__heading { 64 margin-inline-end:40px} 73 <script> 74 jQuery(document).ready(function ($) { 75 $('.nav-tab').click(function (e) { 76 e.preventDefault(); 77 $('.nav-tab').removeClass('nav-tab-active'); 78 $('.tab-content').removeClass('current'); 65 79 66 #e-admin-top-bar-root .e-admin-top-bar__heading,#e-admin-top-bar-root .e-admin-top-bar__main-area { 67 display: inline-flex; 68 align-items: center; 69 justify-content: center 70 } 71 72 #e-admin-top-bar-root .e-admin-top-bar__main-area button { 73 margin: 0 4px 74 } 75 76 #e-admin-top-bar-root .e-admin-top-bar__secondary-area { 77 display: inline-flex; 78 align-items: center; 79 justify-content: center 80 } 81 82 #e-admin-top-bar-root .e-admin-top-bar__heading-title { 83 color: var(--e-a-color-txt); 84 font-size: 15px; 85 font-weight: 700; 86 padding: 0 8px; 87 line-height: normal 88 } 89 90 #e-admin-top-bar-root .e-admin-top-bar__main-area-buttons { 91 display: inline-flex; 92 gap: 5px 93 } 94 95 #e-admin-top-bar-root.e-admin-top-bar--active { 96 display: block 97 } 98 99 #e-admin-top-bar-root.e-admin-top-bar--active~#wpbody #wpbody-content { 100 margin-block-start:50px} 101 102 #e-admin-top-bar-root.e-admin-top-bar--active~#wpbody .wrap { 103 clear: both; 104 padding-block-start:10px} 105 106 #e-admin-top-bar-root.e-admin-top-bar--active~#wpbody .wrap h1 { 107 display: none 108 } 109 110 #e-admin-top-bar-root:not(.e-admin-top-bar--active)~#wpbody .wrap .page-title-action,#e-admin-top-bar-root:not(.e-admin-top-bar--active)~#wpbody .wrap h1 { 111 display: inline-block 112 } 113 114 #e-admin-top-bar-root .e-admin-top-bar__bar-button { 115 align-items: center; 116 cursor: pointer; 117 display: inline-flex; 118 justify-content: center; 119 margin: 0 10px; 120 text-decoration: none; 121 color: var(--e-a-color-txt) 122 } 123 124 #e-admin-top-bar-root .e-admin-top-bar__bar-button.accent,#e-admin-top-bar-root .e-admin-top-bar__bar-button.accent:hover .e-admin-top-bar__bar-button-icon,#e-admin-top-bar-root .e-admin-top-bar__bar-button.accent:hover .e-admin-top-bar__bar-button-title { 125 color: var(--e-a-color-accent) 126 } 127 128 #e-admin-top-bar-root .e-admin-top-bar__bar-button .crown-icon { 129 font-size: 14px 130 } 131 132 #e-admin-top-bar-root .e-admin-top-bar__bar-button .e-admin-top-bar__bar-button-icon { 133 margin: 0 4px 134 } 135 136 #e-admin-top-bar-root .e-admin-top-bar__bar-button:hover .e-admin-top-bar__bar-button-icon,#e-admin-top-bar-root .e-admin-top-bar__bar-button:hover .e-admin-top-bar__bar-button-title { 137 color: var(--e-a-color-txt-hover) 138 } 139 140 #e-admin-top-bar-root .e-admin-top-bar__bar-button-title { 141 font-size: 13px; 142 font-weight: 500; 143 margin: 0 4px; 144 line-height: normal 145 } 146 147 #e-admin-top-bar-root~#wpbody .wrap .page-title-action,#e-admin-top-bar-root~#wpbody .wrap h1 { 148 display: none 149 } 150 151 @media screen and (max-width: 960px) { 152 #e-admin-top-bar-root { 153 width:calc(100% - 36px) 154 } 155 } 156 157 @media screen and (max-width: 782px) { 158 #e-admin-top-bar-root { 159 width:100% 160 } 161 } 162 163 @media screen and (max-width: 600px) { 164 #e-admin-top-bar-root { 165 top:46px 166 } 167 } 168 169 @media (max-width: 768px) { 170 #e-admin-top-bar-root { 171 display:inline-flex; 172 align-items: center; 173 justify-content: center 174 } 175 176 #e-admin-top-bar-root .e-admin-top-bar__main-area-buttons { 177 position: absolute; 178 top: calc(100% + 10px) 179 } 180 181 #e-admin-top-bar-root .e-admin-top-bar__secondary-area .e-admin-top-bar__secondary-area-buttons,#e-admin-top-bar-root .e-admin-top-bar__secondary-area>.e-admin-top-bar__bar-button .e-admin-top-bar__bar-button-title { 182 display: none 183 } 184 } 185 186 @media (min-width: 768px) { 187 #e-admin-top-bar-root .e-admin-top-bar__secondary-area .e-admin-top-bar__secondary-area-buttons { 188 display:flex 189 } 190 } 191 .nav-tab-wrapper { 192 margin-bottom: 20px; 193 } 194 195 .tab-content { 196 display: none; 197 } 198 199 .tab-content.current { 200 display: block; 201 } 202 203 /* Added table styles */ 204 table { 205 width: 100%; 206 border-collapse: collapse; 207 } 208 209 th, td { 210 border: 1px solid #ddd; 211 padding: 8px; 212 word-wrap: break-word; /* Ensure long text wraps within the cell */ 213 } 214 215 tr:nth-child(even) { 216 background-color: #f2f2f2; 217 } 218 219 th { 220 padding-top: 12px; 221 padding-bottom: 12px; 222 text-align: left; 223 } 224 </style> 225 <div id="e-admin-top-bar-root" class="e-admin-top-bar--active"> 226 <div class="e-admin-top-bar"> 227 <div class="e-admin-top-bar__main-area"> 228 <div class="e-admin-top-bar__heading"> 229 <span class="e-admin-top-bar__heading-title">FluentC Translation</span> 230 </div> 231 <div class="e-admin-top-bar__main-area-buttons"></div> 232 </div> 233 234 <div class="e-admin-top-bar__secondary-area"> 235 <div class="e-admin-top-bar__secondary-area-buttons"> 236 237 238 <?php if ( $this->fluentc_get_settings() ) { ?> 239 <form method="GET" action="https://dashboard.fluentc.ai/manage/<?php echo esc_attr( $this->fluentc_get_settings() ); ?>"> 240 <input type="hidden" name="redirect" 241 value="<?php echo esc_url( admin_url( 'admin.php?page=fluentc-settings' ) ); ?>" /> 242 <input type="submit" class="button button-primary" 243 value="<?php _e( 'Manage Account', 'fluentc-translation' ); ?>" /> 244 </form> 245 <?php } else { ?> 246 <form method="GET" action="https://dashboard.fluentc.ai/sites"> 247 <input type="submit" class="button button-primary" value="<?php _e( 'Connect to FluentC', 'fluentc-translation' ); ?>" /> 248 <input type="hidden" name="instruction" value="connect" /> 249 <input type="hidden" name="redirect" 250 value="<?php echo esc_url( admin_url( 'admin.php?page=fluentc-settings' ) ); ?>" /> 251 </form> 252 <?php } ?> 253 254 </div> 255 </div> 256 </div> 257 </div> 258 <div class="nav-tab-wrapper"> 259 <a href="#tab-1" class="nav-tab nav-tab-active" data-tab="tab-1"><?php _e( 'Connect', 'fluentc-translation' ); ?></a> 260 <a href="#tab-2" class="nav-tab" data-tab="tab-2"><?php _e( 'Languages', 'fluentc-translation' ); ?></a> 261 <a href="#tab-3" class="nav-tab" data-tab="tab-3"><?php _e( 'Advanced', 'fluentc-translation' ); ?></a> 262 </div> 263 <div id="tab-1" class="tab-content current"> 264 <p><?php _e( 'To use the FluentC, you need an active subscription.', 'fluentc-translation' ); ?></p> 265 <table class="wp-list-table widefat fixed"> 266 <tbody> 267 <tr> 268 <th scope="row"> 269 <?php if ( $this->fluentc_get_settings() ) { ?> 270 <form method="GET" 271 action="https://dashboard.fluentc.ai/manage/<?php echo esc_attr( $this->fluentc_get_settings() ); ?>"> 272 <input type="hidden" name="redirect" 273 value="<?php echo esc_url( admin_url( 'admin.php?page=fluentc-settings' ) ); ?>" /> 274 <input type="submit" class="button button-primary" 275 value="<?php _e( 'Manage FluentC Account and Languages', 'fluentc-translation' ); ?>" /> 276 </form> 277 <?php } else { ?> 278 <form method="GET" action="https://dashboard.fluentc.ai/sites"> 279 <input type="submit" class="button button-primary" value="<?php _e( 'Sign Up and Connect to FluentC', 'fluentc-translation' ); ?>" /> 280 <input type="hidden" name="instruction" value="connect" /> 281 <input type="hidden" name="redirect" 282 value="<?php echo esc_url( admin_url( 'admin.php?page=fluentc-settings' ) ); ?>" /> 283 </form> 284 <?php } ?> 285 </th> 286 287 </tr> 288 </tbody> 289 </table> 290 <?php if ( $this->fluentc_get_settings() ) { ?> 291 292 <?php } else { ?> 293 <h2><?php _e( 'Three steps have translation on your site', 'fluentc-translation' ); ?><h2> 294 <ol> 295 <li><?php _e( 'Click the link above to link your site to FluentC', 'fluentc-translation' ); ?></li> 296 <li><?php _e( 'Subscribe to Languages', 'fluentc-translation' ); ?></li> 297 <li><?php _e( 'Add the html tag if you choose to display the languages as dropdown or list', 'fluentc-translation' ); ?></li> 298 </ol> 299 <?php } ?> 300 301 </div> 302 <div id="tab-2" class="tab-content"> 303 <?php do_action( 'fluentc_admin_settings_page' ); ?> 304 305 </div> 306 <div id="tab-3" class="tab-content"> 307 308 <form method="post" action='<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>'> 309 <?php wp_nonce_field( 'fluentc_save_settings_action', 'fluentc_settings_nonce_field' ); ?> 310 <input type="hidden" name="action" value="fluentc_save_settings_action"> 311 <table class="form-table"> 312 <tbody> 313 <tr> 314 <th scope="row"><label for="fluentc_api_key"><?php _e( 'FluentC API Key', 'fluentc-translation' ); ?></label></th> 315 <td><input name="fluentc_api_key" type="text" id="fluentc_api_key" 316 value="<?php echo esc_attr( $this->fluentc_get_settings() ); ?>" class="regular-text"> 317 </td> 318 </tr> 319 </tbody> 320 </table> 321 <p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" 322 value="<?php _e( 'Save Changes', 'fluentc-translation' ); ?>"></p> 323 </form> 324 325 <?php do_action( 'fluentc_admin_tab_three_page' ); ?> 326 <?php do_action( 'fluentc_activation_setup' ); ?> 327 </div> 328 </div> 329 <script> 330 jQuery(document).ready(function ($) { 331 $('.nav-tab').click(function (e) { 332 e.preventDefault(); 333 $('.nav-tab').removeClass('nav-tab-active'); 334 $('.tab-content').removeClass('current'); 335 336 $(this).addClass('nav-tab-active'); 337 $("#" + $(this).data('tab')).addClass('current'); 338 }); 339 }); 80 $(this).addClass('nav-tab-active'); 81 $("#" + $(this).data('tab')).addClass('current'); 82 }); 83 }); 340 84 </script> 341 342 343 344 <p><?php _e( 'For any assistance please contact FluentC', 'fluentc-translation' ); ?> | <a href="https://www.fluentc.ai/" target="_blank"><?php _e( 'Help and Support', 'fluentc-translation' ); ?></a></p>345 </div> -
fluentc-translation/trunk/fluentc_wordpress_plugin.php
r3130715 r3135855 7 7 * Plugin URI: https://github.com/fluentc/wordpress-plugin 8 8 * Description: A plugin that enables website owners to easily install the FluentC Translation on their WordPress site. 9 * Version: 1.6 9 * Version: 1.6.1 10 10 * Author: FluentC 11 11 * Author URI: https://www.fluentc.ai … … 17 17 define( 'FLUENTC_DIR', __DIR__ ); 18 18 define( 'FLUENTC_SLUG', 'fluentc_translation' ); 19 define( 'FLUENTC_TRANSLATION_VERSION', "1.6.1" ); 20 define( 'FLUENTC_TRANSLATION_PLUGIN_DIR', plugin_dir_path(__FILE__) ); 21 define( 'FLUENTC_TRANSLATION_PLUGIN_URL', plugin_dir_url(__FILE__) ); 19 22 20 23 -
fluentc-translation/trunk/src/actions/class-admin.php
r3130715 r3135855 99 99 add_action('wp_ajax_fluentc_inline_edit', array($this->translations, 'handle_inline_edit')); 100 100 add_action('wp_ajax_fluentc_delete_translation', array($this->translations, 'handle_delete_translation')); 101 add_action('wp_ajax_fluentc_search_translations', array($this->translations, 'handle_search_translations')); 102 add_action('wp_ajax_fluentc_get_translations', array($this->translations, 'handle_get_translations')); 101 103 } 102 104 /** … … 121 123 */ 122 124 public function enqueue_admin_scripts($hook) { 123 if ('fluentc_page_fluentc-manage-translations' === $hook) {125 124 126 $this->translations->enqueue_scripts(); 125 }127 126 128 } 127 129 /** -
fluentc-translation/trunk/src/actions/class-aioseo.php
r3080561 r3135855 77 77 // If language code is set, modify the output accordingly. 78 78 $text = $this->fluentc_connenct->get_translation_text( $widgetapikey, substr( $site_language, 0, 2 ), $language_code, $description ); 79 return $text->data->translateSite->body[0]->translatedText; 79 if(isset($text->data->translateSite->body[0]) && isset($text->data->translateSite->body[0]->translatedText)) { 80 return $text->data->translateSite->body[0]->translatedText; 81 } 82 else { 83 // If no translation , return the default output. 84 return $description; 85 } 80 86 } else { 81 87 // If no language code, return the default output. -
fluentc-translation/trunk/src/actions/class-wordpress.php
r3130715 r3135855 112 112 // If language code is set, modify the output accordingly. 113 113 if ( ! is_null( $block_content ) && '' !== $block_content ) { 114 $html = mb_convert_encoding( $block_content, 'HTML-ENTITIES', 'UTF-8' );114 $html = html_entity_decode( $block_content, ENT_QUOTES | ENT_XML1, 'UTF-8' ); 115 115 $doc = new \DOMDocument(); 116 116 $doc->encoding = 'UTF-8'; … … 230 230 // If language code is set, modify the output accordingly. 231 231 if ( ! is_null( $block_content ) && '' !== $block_content ) { 232 $html = mb_convert_encoding( $block_content, 'HTML-ENTITIES', 'UTF-8' );232 $html = html_entity_decode( $block_content, ENT_QUOTES | ENT_XML1, 'UTF-8' ); 233 233 234 234 // Check if $html is empty to avoid DOMDocument errors … … 374 374 // If language code is set, modify the output accordingly. 375 375 if ( ! is_null( $content ) && '' !== $content ) { 376 $html = mb_convert_encoding( $content, 'HTML-ENTITIES', 'UTF-8' );376 $html = html_entity_decode( $content, ENT_QUOTES | ENT_XML1, 'UTF-8' ); 377 377 378 378 // Check if $html is empty to avoid DOMDocument errors -
fluentc-translation/trunk/src/includes/js/translations.js
r3130715 r3135855 1 1 jQuery(document).ready(function($) { 2 $('.edit-translation').on('click', function() { 3 var row = $(this).closest('tr'); 4 row.find('.translation-display').hide(); 5 row.find('.translation-edit').show(); 6 row.find('.edit-translation').hide(); 7 row.find('.save-translation, .cancel-edit').show(); 2 function attachEventListeners() { 3 $('.edit-translation').off('click').on('click', function() { 4 var row = $(this).closest('tr'); 5 row.find('.translation-display').hide(); 6 row.find('.translation-edit').show(); 7 row.find('.edit-translation').hide(); 8 row.find('.save-translation, .cancel-edit').show(); 9 }); 10 11 $('.cancel-edit').off('click').on('click', function() { 12 var row = $(this).closest('tr'); 13 row.find('.translation-display').show(); 14 row.find('.translation-edit').hide(); 15 row.find('.edit-translation').show(); 16 row.find('.save-translation, .cancel-edit').hide(); 17 }); 18 19 $('.save-translation').off('click').on('click', function() { 20 var row = $(this).closest('tr'); 21 var translationId = row.attr('id').replace('translation-', ''); 22 var newTranslation = row.find('.translation-edit').val(); 23 24 $.ajax({ 25 url: fluentcTranslations.ajaxurl, 26 type: 'POST', 27 data: { 28 action: 'fluentc_inline_edit', 29 translation_id: translationId, 30 new_translation: newTranslation, 31 fluentc_nonce: fluentcTranslations.nonce 32 }, 33 success: function(response) { 34 if (response.success) { 35 row.find('.translation-display').text(newTranslation).show(); 36 row.find('.translation-edit').hide(); 37 row.find('.edit-translation').show(); 38 row.find('.save-translation, .cancel-edit').hide(); 39 } else { 40 alert('Failed to update translation: ' + response.data); 41 } 42 }, 43 error: function() { 44 alert('An error occurred while updating the translation'); 45 } 46 }); 47 }); 48 49 $('.delete-translation').off('click').on('click', function() { 50 var row = $(this).closest('tr'); 51 var translationId = row.attr('id').replace('translation-', ''); 52 53 if (confirm('Are you sure you want to delete this translation?')) { 54 $.ajax({ 55 url: fluentcTranslations.ajaxurl, 56 type: 'POST', 57 data: { 58 action: 'fluentc_delete_translation', 59 translation_id: translationId, 60 fluentc_nonce: fluentcTranslations.nonce 61 }, 62 success: function(response) { 63 if (response.success) { 64 row.fadeOut(400, function() { 65 $(this).remove(); 66 }); 67 } else { 68 alert('Failed to delete translation: ' + response.data); 69 } 70 }, 71 error: function() { 72 alert('An error occurred while deleting the translation'); 73 } 74 }); 75 } 76 }); 77 } 78 79 var currentPage = 1; 80 var searchTerm = ''; 81 var isSearchActive = false; 82 83 $('#translation-search-form').on('submit', function(e) { 84 e.preventDefault(); 85 searchTerm = $('#translation-search').val(); 86 currentPage = 1; 87 isSearchActive = true; 88 performSearch(); 8 89 }); 9 90 10 $('.cancel-edit').on('click', function() { 11 var row = $(this).closest('tr'); 12 row.find('.translation-display').show(); 13 row.find('.translation-edit').hide(); 14 row.find('.edit-translation').show(); 15 row.find('.save-translation, .cancel-edit').hide(); 91 $('#clear-search').on('click', function() { 92 searchTerm = ''; 93 currentPage = 1; 94 isSearchActive = false; 95 $('#translation-search').val(''); 96 $(this).hide(); 97 loadDefaultTranslations(); 16 98 }); 17 99 18 $('.save-translation').on('click', function() { 19 var row = $(this).closest('tr'); 20 var translationId = row.attr('id').replace('translation-', ''); 21 var newTranslation = row.find('.translation-edit').val(); 22 100 function performSearch() { 101 $('#search-loading').show(); 102 $('#translations-table').css('opacity', '0.5'); 103 23 104 $.ajax({ 24 105 url: fluentcTranslations.ajaxurl, 25 106 type: 'POST', 26 107 data: { 27 action: 'fluentc_ inline_edit',28 translation_id: translationId,29 new_translation: newTranslation,108 action: 'fluentc_search_translations', 109 search: searchTerm, 110 page: currentPage, 30 111 fluentc_nonce: fluentcTranslations.nonce 31 112 }, 32 113 success: function(response) { 33 114 if (response.success) { 34 row.find('.translation-display').text(newTranslation).show(); 35 row.find('.translation-edit').hide(); 36 row.find('.edit-translation').show(); 37 row.find('.save-translation, .cancel-edit').hide(); 115 if (response.data.translations.length > 0) { 116 updateTable(response.data.translations); 117 } else { 118 showNoResults(); 119 } 120 $('#clear-search').show(); 121 updatePagination(response.data); 38 122 } else { 39 alert(' Failed to update translation: ' + response.data);123 alert('Search failed: ' + response.data); 40 124 } 41 125 }, 42 126 error: function() { 43 alert('An error occurred while updating the translation'); 44 } 45 }); 127 alert('An error occurred while searching'); 128 }, 129 complete: function() { 130 $('#search-loading').hide(); 131 $('#translations-table').css('opacity', '1'); 132 } 133 }); 134 } 135 136 function updateTable(translations) { 137 var tableBody = $('#translations-table tbody'); 138 tableBody.empty(); 139 140 translations.forEach(function(translation) { 141 var row = ` 142 <tr id="translation-${translation.id}"> 143 <td>${translation.sourceLanguage}</td> 144 <td>${translation.targetLanguage}</td> 145 <td>${translation.originalText}</td> 146 <td class="translation-text"> 147 <span class="translation-display">${translation.translatedText}</span> 148 <input type="text" class="translation-edit" value="${translation.translatedText}" style="display: none;"> 149 </td> 150 <td> 151 <button class="button edit-translation">Edit</button> 152 <button class="button save-translation" style="display: none;">Save</button> 153 <button class="button cancel-edit" style="display: none;">Cancel</button> 154 <button class="button delete-translation">Delete</button> 155 </td> 156 </tr> 157 `; 158 tableBody.append(row); 159 }); 160 161 attachEventListeners(); // Reattach event listeners after updating the table 162 } 163 164 function loadDefaultTranslations() { 165 $('#search-loading').show(); 166 $('#translations-table').css('opacity', '0.5'); 167 168 $.ajax({ 169 url: fluentcTranslations.ajaxurl, 170 type: 'POST', 171 data: { 172 action: 'fluentc_get_translations', 173 page: currentPage, 174 fluentc_nonce: fluentcTranslations.nonce 175 }, 176 success: function(response) { 177 if (response.success) { 178 updateTable(response.data.translations); 179 updatePagination(response.data); 180 } else { 181 alert('Failed to load translations: ' + response.data); 182 } 183 }, 184 error: function() { 185 alert('An error occurred while loading translations'); 186 }, 187 complete: function() { 188 $('#search-loading').hide(); 189 $('#translations-table').css('opacity', '1'); 190 } 191 }); 192 } 193 194 function showNoResults() { 195 var tableBody = $('#translations-table tbody'); 196 tableBody.empty(); 197 tableBody.append('<tr><td colspan="5">No results found</td></tr>'); 198 } 199 200 function updatePagination(data) { 201 var totalPages = data.totalPages; 202 var currentPage = data.page; 203 204 if (totalPages <= 1) { 205 $('#pagination').empty(); 206 return; 207 } 208 209 var paginationHtml = '<div class="tablenav bottom"><div class="tablenav-pages">'; 210 211 function addLink(page, text, classes) { 212 if (page < 1 || page > totalPages) { 213 return `<span class="tablenav-pages-navspan button disabled" aria-hidden="true">${text}</span>`; 214 } 215 return `<a class="page-numbers ${classes}" href="#" data-page="${page}">${text}</a>`; 216 } 217 218 // Previous button 219 paginationHtml += addLink(currentPage - 1, '‹', 'prev-page'); 220 221 var startPage = Math.max(1, currentPage - 2); 222 var endPage = Math.min(totalPages, startPage + 4); 223 startPage = Math.max(1, endPage - 4); 224 225 if (startPage > 1) { 226 paginationHtml += addLink(1, '1', ''); 227 if (startPage > 2) { 228 paginationHtml += '<span class="page-numbers dots">…</span>'; 229 } 230 } 231 232 for (var i = startPage; i <= endPage; i++) { 233 if (i === currentPage) { 234 paginationHtml += `<span aria-current="page" class="page-numbers current">${i}</span>`; 235 } else { 236 paginationHtml += addLink(i, i, ''); 237 } 238 } 239 240 if (endPage < totalPages) { 241 if (endPage < totalPages - 1) { 242 paginationHtml += '<span class="page-numbers dots">…</span>'; 243 } 244 paginationHtml += addLink(totalPages, totalPages, ''); 245 } 246 247 // Next button 248 paginationHtml += addLink(currentPage + 1, '›', 'next-page'); 249 250 paginationHtml += '</div></div>'; 251 252 $('#pagination').html(paginationHtml); 253 } 254 255 $(document).on('click', '#pagination a.page-numbers', function(e) { 256 e.preventDefault(); 257 currentPage = $(this).data('page'); 258 if (isSearchActive) { 259 performSearch(); 260 } else { 261 loadDefaultTranslations(); 262 } 46 263 }); 47 $('.delete-translation').on('click', function() { 48 var row = $(this).closest('tr'); 49 var translationId = row.attr('id').replace('translation-', ''); 50 51 if (confirm('Are you sure you want to delete this translation?')) { 52 $.ajax({ 53 url: fluentcTranslations.ajaxurl, 54 type: 'POST', 55 data: { 56 action: 'fluentc_delete_translation', 57 translation_id: translationId, 58 fluentc_nonce: fluentcTranslations.nonce 59 }, 60 success: function(response) { 61 if (response.success) { 62 row.fadeOut(400, function() { 63 $(this).remove(); 64 }); 65 } else { 66 alert('Failed to delete translation: ' + response.data); 67 } 68 }, 69 error: function() { 70 alert('An error occurred while deleting the translation'); 71 } 72 }); 73 } 74 }); 264 265 loadDefaultTranslations(); 266 attachEventListeners(); // Attach event listeners on initial load 75 267 }); -
fluentc-translation/trunk/src/services/class-cache.php
r3130715 r3135855 261 261 } 262 262 } 263 264 public function search_fluentc_transients($search_term, $offset = 0, $limit = 20) { 265 global $wpdb; 266 267 $like = '%' . $wpdb->esc_like($search_term) . '%'; 268 $sql = $wpdb->prepare( 269 "SELECT option_name, option_value 270 FROM {$wpdb->options} 271 WHERE option_name LIKE %s 272 AND option_value LIKE %s 273 LIMIT %d, %d", 274 $wpdb->esc_like('_transient_fluentc') . '%', 275 $like, 276 $offset, 277 $limit 278 ); 279 280 $results = $wpdb->get_results($sql); 281 $translations = []; 282 283 foreach ($results as $result) { 284 $transient_name = str_replace('_transient_', '', $result->option_name); 285 $raw_data = maybe_unserialize($result->option_value); 286 $data = json_decode($raw_data, true); 287 288 if (is_array($data) && isset($data['data']['translateSite']['body'])) { 289 foreach ($data['data']['translateSite']['body'] as $index => $translation) { 290 $originalText = html_entity_decode($translation['originalText'], ENT_QUOTES | ENT_XML1, 'UTF-8'); 291 $translatedText = html_entity_decode($translation['translatedText'], ENT_QUOTES | ENT_XML1, 'UTF-8'); 292 293 if ($originalText !== $translatedText && 294 (mb_stripos($originalText, $search_term) !== false || 295 mb_stripos($translatedText, $search_term) !== false)) { 296 $translations[] = [ 297 'id' => $transient_name . '-' . $index, 298 'sourceLanguage' => $translation['sourceLanguage'], 299 'targetLanguage' => $translation['targetLanguage'], 300 'originalText' => $originalText, 301 'translatedText' => $translatedText 302 ]; 303 } 304 } 305 } 306 } 307 308 return $translations; 309 } 310 311 public function count_search_results($search_term) { 312 global $wpdb; 313 314 $like = '%' . $wpdb->esc_like($search_term) . '%'; 315 $sql = $wpdb->prepare( 316 "SELECT COUNT(*) 317 FROM {$wpdb->options} 318 WHERE option_name LIKE %s 319 AND option_value LIKE %s", 320 $wpdb->esc_like('_transient_fluentc') . '%', 321 $like 322 ); 323 324 return $wpdb->get_var($sql); 325 } 263 326 } -
fluentc-translation/trunk/src/services/class-fluentc-translations.php
r3130715 r3135855 38 38 $translations = []; 39 39 $count = 0; 40 $processed_ids = []; // To keep track of processed translations40 $processed_ids = []; // Now an associative array 41 41 42 42 foreach ($all_transients as $transient_name => $transient_data) { … … 51 51 $unique_id = md5($transient_name . $originalText . $translatedText); 52 52 53 // Only include the translation if originalText and translatedText are different 54 // and if we haven't processed this unique translation before 55 if ($originalText !== $translatedText && !in_array($unique_id, $processed_ids)) { 53 // Check if we've processed this unique translation before 54 if ($originalText !== $translatedText && !isset($processed_ids[$unique_id])) { 56 55 if ($count >= $offset && count($translations) < $limit) { 57 56 $translations[] = [ … … 64 63 } 65 64 $count++; 66 $processed_ids[ ] = $unique_id; // Mark this translation as processed65 $processed_ids[$unique_id] = true; // Mark this translation as processed 67 66 68 67 if (count($translations) >= $limit) { … … 83 82 84 83 $count = 0; 85 $processed_ids = []; 84 $processed_ids = []; // Now an associative array. 86 85 foreach ($all_transients as $transient_name => $transient_data) { 87 86 if (is_string($transient_data)) { … … 94 93 $unique_id = md5($transient_name . $originalText . $translatedText); 95 94 96 if ($originalText !== $translatedText && !i n_array($unique_id, $processed_ids)) {95 if ($originalText !== $translatedText && !isset($processed_ids[$unique_id])) { 97 96 $count++; 98 $processed_ids[ ] = $unique_id;97 $processed_ids[$unique_id] = true; 99 98 } 100 99 } … … 133 132 } 134 133 134 public function handle_search_translations() { 135 if (!isset($_POST['action']) || $_POST['action'] !== 'fluentc_search_translations') { 136 wp_send_json_error('Invalid action'); 137 } 138 139 // Verify nonce 140 check_admin_referer('fluentc_inline_edit', 'fluentc_nonce'); 141 142 $search_term = isset($_POST['search']) ? sanitize_text_field($_POST['search']) : ''; 143 $page = isset($_POST['page']) ? intval($_POST['page']) : 1; 144 145 if (empty($search_term)) { 146 wp_send_json_error('Empty search term'); 147 } 148 149 $fluentc_cache = new \FluentC\Services\Cache(); 150 $limit = 20; 151 $offset = ($page - 1) * $limit; 152 153 $results = $fluentc_cache->search_fluentc_transients($search_term, $offset, $limit); 154 $total_results = $fluentc_cache->count_search_results($search_term); 155 156 wp_send_json_success([ 157 'translations' => $results, 158 'total' => $total_results, 159 'page' => $page, 160 'totalPages' => ceil($total_results / $limit) 161 ]); 162 } 163 164 135 165 public function handle_delete_translation() { 136 166 if (!isset($_POST['action']) || $_POST['action'] !== 'fluentc_delete_translation') { … … 163 193 'nonce' => wp_create_nonce('fluentc_inline_edit') 164 194 )); 195 wp_enqueue_style('fluentc-translations', plugin_dir_url(__FILE__) . '../includes/css/fluentc-translations.css'); 196 } 197 198 public function handle_get_translations() { 199 if (!isset($_POST['action']) || $_POST['action'] !== 'fluentc_get_translations') { 200 wp_send_json_error('Invalid action'); 201 } 202 203 // Verify nonce 204 check_admin_referer('fluentc_inline_edit', 'fluentc_nonce'); 205 206 $page = isset($_POST['page']) ? intval($_POST['page']) : 1; 207 208 $limit = 20; 209 $offset = ($page - 1) * $limit; 210 211 $translations = $this->get_paginated_translations($offset, $limit); 212 $total_translations = $this->get_total_translations_count(); 213 214 wp_send_json_success([ 215 'translations' => $translations, 216 'total' => $total_translations, 217 'page' => $page, 218 'totalPages' => ceil($total_translations / $limit) 219 ]); 165 220 } 166 221 } -
fluentc-translation/trunk/src/services/class-html.php
r3129167 r3135855 111 111 public function get_text_from_html( $html ) { 112 112 // Ensure the HTML input is correctly encoded. 113 $html = mb_convert_encoding( $html, 'HTML-ENTITIES', 'UTF-8' );113 $html = html_entity_decode( $html, ENT_QUOTES | ENT_XML1, 'UTF-8' ); 114 114 115 115 $doc = new \DOMDocument(); … … 275 275 * @param string $url url to process. 276 276 */ 277 public function get_fluentc_language_from_url( $url, $regex_lang ) { 278 277 public function get_fluentc_language_from_url( $url = null, $regex_lang ) { 278 279 // Ensure $url is a string. If not, default it to an empty string. 280 $url = is_string($url) ? $url : ''; 281 279 282 $pattern = '/\/(' . $regex_lang . ')(\/|$|\?|#)/'; 280 283 $language_code = null; // Default initialization to null for safety. 284 281 285 if (preg_match($pattern, wp_unslash($url), $matches)) { 282 286 if (isset($matches[1])) { … … 285 289 // Handle the case where $matches[1] is not set. 286 290 do_action( 'qm/info', 'Language code not found in matches.' ); 287 288 291 } 289 292 } else { 290 293 // Handle the case where the pattern does not match. 291 do_action( 'qm/info', 'Pattern did not match the input string.' ); 292 } 294 do_action( 'qm/info', 'Pattern did not match the URL.' ); 295 } 296 293 297 return $language_code; 294 298 } -
fluentc-translation/trunk/src/services/class-url.php
r3065579 r3135855 101 101 // Parse the URL and get the path part. 102 102 $parsed_url = wp_parse_url( $url ); 103 $path = $parsed_url['path'];104 105 // Check if the path starts with the current prefix.106 if ( substr( $path, 0, strlen( $prefixes ) ) === $prefixes ) {103 $path = isset($parsed_url['path']) ? $parsed_url['path'] : ''; 104 105 // Check if $prefixes is not null and the path starts with the current prefix. 106 if ( $prefixes !== null && !empty($path) && substr( $path, 0, strlen( $prefixes ) ) === $prefixes ) { 107 107 // Remove the prefix from the path. 108 109 108 $path = substr( $path, strlen( $prefixes ) ); 110 111 109 } 112 if ( substr( $path, 0, strlen( $language ) ) === $language ) { 113 // Remove the prefix from the path. 114 110 111 // Check if $language is not null and the path starts with the language. 112 if ( $language !== null && !empty($path) && substr( $path, 0, strlen( $language ) ) === $language ) { 113 // Remove the language from the path. 115 114 $path = substr( $path, strlen( $language ) ); 116 117 115 } 118 116 119 117 // Reconstruct and return the modified URL. 120 return ( isset( $parsed_url['scheme'] ) ? $parsed_url['scheme'] . '://' : '' )118 return ( isset( $parsed_url['scheme'] ) ? $parsed_url['scheme'] . '://' : '' ) 121 119 . ( isset( $parsed_url['host'] ) ? $parsed_url['host'] : '' ) 122 120 . $path … … 140 138 141 139 // Check if the path starts with the current prefix. 142 if ( substr( $path, 0, strlen( $prefix ) ) === $prefix ) { 140 // Check if $prefixes is not null and the path starts with the current prefix. 141 if ( $prefix !== null && !empty($path) && substr( $path, 0, strlen( $prefix ) ) === $prefix ) { 143 142 // Remove the prefix from the path. 144 143 $path = substr( $path, strlen( $prefix ) ); 145 144 } 146 if ( substr( $path, 0, strlen( $language ) ) === $language ) { 147 // Remove the prefix from the path. 148 145 146 // Check if $language is not null and the path starts with the language. 147 if ( $language !== null && !empty($path) && substr( $path, 0, strlen( $language ) ) === $language ) { 148 // Remove the language from the path. 149 149 $path = substr( $path, strlen( $language ) ); 150 150 } -
fluentc-translation/trunk/src/templates/manage-translations-page.php
r3130715 r3135855 1 <?php 2 /** 3 * FluentC Translation Management File. 4 * 5 * This file contains the functions for managing translations 6 * 7 * @category Translation 8 * @package FluentCPlugin 9 * @author FluentC <[email protected]> 10 * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 11 * @link https://www.fluentc.ai 12 */ 1 <div class="wrap fluentc-translations-page"> 2 <div class="fluentc-header"> 3 <img src="<?php echo plugin_dir_url(__FILE__) . '../includes/fluentc-logo.png'; ?>" alt="FluentC Logo" class="fluentc-logo"> 4 <h1>FluentC Translations Management</h1> 5 </div> 13 6 14 if ( ! defined( 'ABSPATH' ) ) { 15 exit; 16 } 7 <div class="fluentc-description"> 8 <p>Here you can manage your translations. Search for specific translations, edit them, or delete unnecessary ones. Use the search function to find translations quickly.</p> 9 </div> 17 10 18 ?> 19 <div class="wrap"> 20 <h1><?php echo esc_html(get_admin_page_title()); ?></h1> 11 <div class="fluentc-search-box"> 12 <form id="translation-search-form"> 13 <input type="text" id="translation-search" name="search" placeholder="Search translations..."> 14 <button type="submit" class="button button-primary">Search</button> 15 <button type="button" id="clear-search" class="button">Clear</button> 16 </form> 17 <div id="search-loading" style="display: none;">Searching...</div> 18 </div> 21 19 22 <div class="wrap"> 23 <h1><?php echo esc_html(get_admin_page_title()); ?></h1> 20 <table id="translations-table" class="wp-list-table widefat fixed striped"> 21 <thead> 22 <tr> 23 <th class="column-language">From</th> 24 <th class="column-language">To</th> 25 <th>Original Text</th> 26 <th>Translated Text</th> 27 <th>Actions</th> 28 </tr> 29 </thead> 30 <tbody> 31 <!-- Table content will be dynamically populated --> 32 </tbody> 33 </table> 24 34 25 <table class="wp-list-table widefat fixed striped"> 26 <thead> 27 <tr> 28 <th>Source Language</th> 29 <th>Target Language</th> 30 <th>Original Text</th> 31 <th>Translated Text</th> 32 <th>Actions</th> 33 </tr> 34 </thead> 35 <tbody> 36 <?php foreach ($translations as $translation): ?> 37 <tr id="translation-<?php echo esc_attr($translation['id']); ?>"> 38 <td><?php echo esc_html($translation['sourceLanguage']); ?></td> 39 <td><?php echo esc_html($translation['targetLanguage']); ?></td> 40 <td><?php echo esc_html($translation['originalText']); ?></td> 41 <td class="translation-text"> 42 <span class="translation-display"><?php echo esc_html($translation['translatedText']); ?></span> 43 <input type="text" class="translation-edit" value="<?php echo esc_attr($translation['translatedText']); ?>" style="display: none;"> 44 </td> 45 <td> 46 <button class="button edit-translation">Edit</button> 47 <button class="button save-translation" style="display: none;">Save</button> 48 <button class="button cancel-edit" style="display: none;">Cancel</button> 49 <button class="button delete-translation">Delete</button> 50 </td> 51 </tr> 52 <?php endforeach; ?> 53 </tbody> 54 </table> 55 56 57 <?php 58 $total_pages = ceil($total_items / $this->items_per_page); 59 if ($total_pages > 1) { 60 echo '<div class="tablenav bottom">'; 61 echo '<div class="tablenav-pages">'; 62 echo paginate_links(array( 63 'base' => add_query_arg('paged', '%#%'), 64 'format' => '', 65 'prev_text' => __('«'), 66 'next_text' => __('»'), 67 'total' => $total_pages, 68 'current' => $current_page 69 )); 70 echo '</div>'; 71 echo '</div>'; 72 } 73 ?> 35 <div id="pagination"></div> 74 36 </div> -
fluentc-translation/trunk/src/utils/class-language.php
r3122693 r3135855 88 88 } else { 89 89 // Handle the case where the pattern does not match. 90 do_action( 'qm/info', 'Pattern did not match the input string.' );91 90 } 92 91 } else { … … 105 104 */ 106 105 public function get_fluentc_language_url() { 107 106 $language_code = null; 108 107 $pattern = '/\/(' . $this->regex_lang . ')(\/|$|\?|#)/'; 109 if ( isset( $_SERVER['REQUEST_URI'] ) ) { 108 109 if (isset($_SERVER['REQUEST_URI'])) { 110 110 $sanitize_uri_raw = sanitize_url($_SERVER['REQUEST_URI']); 111 preg_match( $pattern, wp_unslash( $sanitize_uri_raw ), $matches ); 112 $language_code = $matches[0]; 113 } else { 114 $error = 'set'; 111 if (preg_match($pattern, wp_unslash($sanitize_uri_raw), $matches)) { 112 $language_code = $matches[0] ?? null; 113 } 115 114 } 115 116 116 return $language_code; 117 117 } -
fluentc-translation/trunk/vendor/paquettg/php-html-parser/src/PHPHtmlParser/Dom/Node/Collection.php
r3129167 r3135855 131 131 * @return mixed 132 132 */ 133 #[\ReturnTypeWillChange] 133 134 public function offsetGet($offset) 134 135 {
Note: See TracChangeset
for help on using the changeset viewer.