Changeset 3487409
- Timestamp:
- 03/20/2026 06:47:46 PM (8 days ago)
- Location:
- rc-site-manager-optimization/trunk
- Files:
-
- 11 edited
-
assets/scripts/script.js (modified) (1 diff)
-
assets/styles/style.css (modified) (1 diff)
-
crons/pagespeed.php (modified) (1 diff)
-
rc-site-manager-optimization.php (modified) (5 diffs)
-
readme.txt (modified) (3 diffs)
-
settings/settings_function.php (modified) (1 diff)
-
settings/settings_script.js (modified) (2 diffs)
-
settings/tab_premium.php (modified) (1 diff)
-
settings/tab_premium_fn.php (modified) (1 diff)
-
utility/tab_log.php (modified) (1 diff)
-
utility/tab_system_fn.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
rc-site-manager-optimization/trunk/assets/scripts/script.js
r3482178 r3487409 408 408 : 'Copied!'; 409 409 const tooltip = $(`<span class="rc_sm_tooltip_copy_action">${copiedText}</span>`); 410 $btn.after(tooltip); 410 if ($btn.hasClass('rc_sm_tooltip_sx')) { 411 $btn.before(tooltip); 412 } else { 413 $btn.after(tooltip); 414 } 411 415 setTimeout(() => { 412 416 tooltip.fadeOut(300, () => tooltip.remove()); -
rc-site-manager-optimization/trunk/assets/styles/style.css
r3485061 r3487409 413 413 font-size: 12px; 414 414 margin-left: 5px; 415 margin-right: 5px; 415 416 z-index: 1000; 416 417 white-space: nowrap; -
rc-site-manager-optimization/trunk/crons/pagespeed.php
r3482478 r3487409 133 133 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=%s&key=%s&strategy=%s&category=PERFORMANCE&category=ACCESSIBILITY&category=BEST_PRACTICES&category=SEO', 134 134 urlencode($url), 135 RC_SM_ PAGESPEED_API_KEY,135 RC_SM_API_KEY_GOOGLE_CLOUD, 136 136 $strategy 137 137 ); -
rc-site-manager-optimization/trunk/rc-site-manager-optimization.php
r3487089 r3487409 3 3 * Plugin Name: RC Site Manager & Optimization 4 4 * Description: All-in-one Wordpress manager: control WooCommerce, SEO, caching, media, and multilingual tools from one dashboard. 5 * Version: 2.4. 65 * Version: 2.4.7 6 6 * Author: Rocket Comunicazione 7 7 * Author URI: https://www.rocketcomunicazione.com … … 14 14 15 15 16 define('RC_SM_PLUGIN_VERSION', '2.4. 6');16 define('RC_SM_PLUGIN_VERSION', '2.4.7'); 17 17 18 18 define( 'RC_SM_SITE_URL', home_url() ); … … 41 41 include plugin_dir_path(__FILE__) . 'includes/functions/index.php'; 42 42 include plugin_dir_path(__FILE__) . 'includes/security.php'; 43 include plugin_dir_path(__FILE__) . 'includes/database.php'; 43 44 44 45 define('RC_SM_PAGINATION_ORDER_OFFSET', 50); … … 48 49 define('RC_SM_TABLE_PREMIUM_CUSTOM_SOFTWARE', $wpdb->prefix . 'rc_sm_tb_premium_custom_software'); 49 50 define('RC_SM_TABLE_PAGESPEED', $wpdb->prefix . 'rc_sm_tb_pagespeed'); 50 define('RC_SM_PAGESPEED_API_KEY', 'AIzaSyAou3gnyHfrzOQeXNin-vG7KGDXLRmHxT4'); 51 52 if (RC_SM_SITE_URL === 'https://www.rocketcomunicazione.com') { 53 define('RC_SM_TABLE_AGENCY_CONTROL', $wpdb->prefix . 'rc_sm_tb_agency_control'); 54 } 51 52 define( 'RC_SM_API_KEY_GOOGLE_CLOUD', rc_sm_tb_settings_value( 'google_cloud', 'api_keys' )['key'] ?? '' ); 55 53 56 54 define('RC_SM_YEAR_START_SUBSCRIBER', rc_sm_fn_year_start('subscriber')); … … 58 56 define('RC_SM_YEAR_START_ORDER', rc_sm_fn_year_start('order')); 59 57 60 61 include plugin_dir_path(__FILE__) . 'includes/database.php'; 58 if (RC_SM_SITE_URL === 'https://www.rocketcomunicazione.com') { 59 define('RC_SM_TABLE_AGENCY_CONTROL', $wpdb->prefix . 'rc_sm_tb_agency_control'); 60 } 61 62 62 include plugin_dir_path(__FILE__) . 'includes/language.php'; 63 64 65 63 include plugin_dir_path(__FILE__) . 'crons/index.php'; 66 64 -
rc-site-manager-optimization/trunk/readme.txt
r3487089 r3487409 5 5 Tested up to: 6.9 6 6 Requires PHP: 8.1 7 Stable tag: 2.4. 67 Stable tag: 2.4.7 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 160 160 == Changelog == 161 161 162 163 = 2.4.7 - March 20, 2026 = 164 * Minor bug fixes and improvement 162 165 163 166 = 2.4.6 - March 20, 2026 = … … 316 319 == Upgrade Notice == 317 320 321 = 2.4.7 - March 20, 2026 = 322 Minor bug fixes. 323 318 324 = 2.4.6 - March 20, 2026 = 319 325 Minor bug fixes. -
rc-site-manager-optimization/trunk/settings/settings_function.php
r3438010 r3487409 210 210 wp_die(); 211 211 }); 212 213 // ─── AJAX: verifica API Key ─────────────────────────────────────────────────── 214 215 add_action('wp_ajax_rc_sm_api_key_verify', function () { 216 217 if (!rc_sm_security_ajax_verify()) return; 218 219 $slug = rc_sm_security_ajax_get_param('slug', ''); 220 $api_key = rc_sm_security_ajax_get_param('api_key', ''); 221 222 if (empty($slug) || empty($api_key)) { 223 wp_send_json_error(array('message' => __('Missing required parameters.', 'rc-site-manager-optimization'))); 224 return; 225 } 226 227 if ($slug === 'google_cloud') { 228 229 $response = wp_remote_get( 230 add_query_arg(array( 231 'url' => home_url('/'), 232 'key' => $api_key, 233 'strategy' => 'mobile', 234 'category' => 'performance', 235 ), 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed'), 236 array('timeout' => 20) 237 ); 238 239 if (is_wp_error($response)) { 240 wp_send_json_error(array('message' => __('Connection error. Please try again.', 'rc-site-manager-optimization'))); 241 return; 242 } 243 244 $body = json_decode(wp_remote_retrieve_body($response), true); 245 $http_code = (int) wp_remote_retrieve_response_code($response); 246 247 if ($http_code === 200 && isset($body['lighthouseResult'])) { 248 rc_sm_api_key_save($slug, $api_key); 249 wp_send_json_success(array('message' => __('API Key valid and active.', 'rc-site-manager-optimization'))); 250 } else { 251 $error_msg = isset($body['error']['message']) 252 ? $body['error']['message'] 253 : __('Invalid API Key.', 'rc-site-manager-optimization'); 254 rc_sm_api_key_delete($slug); 255 wp_send_json_error(array('message' => $error_msg)); 256 } 257 258 } else { 259 wp_send_json_error(array('message' => __('Unknown API Key type.', 'rc-site-manager-optimization'))); 260 } 261 262 wp_die(); 263 }); 264 265 266 // ─── Helpers API Keys ───────────────────────────────────────────────────────── 267 268 function rc_sm_api_key_save($slug, $key) { 269 $saved = rc_sm_tb_settings_get_value('api_keys'); 270 if (empty($saved)) $saved = array(); 271 272 $saved[$slug] = array( 273 'key' => $key, 274 'valid' => true, 275 'verified_at' => current_time('mysql'), 276 ); 277 278 rc_sm_api_key_db_save($saved); 279 } 280 281 function rc_sm_api_key_delete($slug) { 282 $saved = rc_sm_tb_settings_get_value('api_keys'); 283 if (empty($saved)) return; 284 unset($saved[$slug]); 285 rc_sm_api_key_db_save($saved); 286 } 287 288 function rc_sm_api_key_db_save($keys) { 289 global $wpdb; 290 $table = esc_sql(RC_SM_TABLE_SETTINGS); 291 292 $exists = $wpdb->get_var($wpdb->prepare( 293 "SELECT COUNT(*) FROM {$table} WHERE action = %s", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared 294 'api_keys' 295 )); 296 297 if ($exists) { 298 $wpdb->update( 299 $table, 300 array('value' => wp_json_encode($keys), 'date' => current_time('mysql')), 301 array('action' => 'api_keys'), 302 array('%s', '%s'), 303 array('%s') 304 ); 305 } else { 306 $wpdb->insert( 307 $table, 308 array('action' => 'api_keys', 'value' => wp_json_encode($keys), 'date' => current_time('mysql')), 309 array('%s', '%s', '%s') 310 ); 311 } 312 } 313 314 315 // ─── AJAX: verifica licenza salvata da DB (auto-check, nessuna chiave in HTML) ─ 316 317 add_action( 'wp_ajax_rc_sm_premium_verify_saved_licence', function () { 318 319 if ( ! rc_sm_security_ajax_verify() ) return; 320 321 $slug = rc_sm_security_ajax_get_param( 'slug', '' ); 322 323 if ( empty( $slug ) ) { 324 wp_send_json_error( array( 'message' => __( 'Missing required parameters.', 'rc-site-manager-optimization' ) ) ); 325 return; 326 } 327 328 $saved_licences = rc_sm_tb_settings_get_value( 'premium_licences' ); 329 $saved_key = isset( $saved_licences[ $slug ]['key'] ) ? $saved_licences[ $slug ]['key'] : ''; 330 331 if ( empty( $saved_key ) ) { 332 wp_send_json_error( array( 'message' => __( 'No licence key saved.', 'rc-site-manager-optimization' ) ) ); 333 return; 334 } 335 336 $result = rc_sm_premium_licence_verify( $slug, $saved_key ); 337 338 if ( $result['valid'] ) { 339 wp_send_json_success( array( 'message' => $result['message'] ) ); 340 } else { 341 wp_send_json_error( array( 'message' => $result['message'] ) ); 342 } 343 344 wp_die(); 345 } ); 346 347 348 // ─── AJAX: verifica API key salvata da DB (auto-check, nessuna chiave in HTML) ─ 349 350 add_action( 'wp_ajax_rc_sm_api_key_verify_saved', function () { 351 352 if ( ! rc_sm_security_ajax_verify() ) return; 353 354 $slug = rc_sm_security_ajax_get_param( 'slug', '' ); 355 356 if ( empty( $slug ) ) { 357 wp_send_json_error( array( 'message' => __( 'Missing required parameters.', 'rc-site-manager-optimization' ) ) ); 358 return; 359 } 360 361 $saved_keys = rc_sm_tb_settings_get_value( 'api_keys' ); 362 $saved_key = isset( $saved_keys[ $slug ]['key'] ) ? $saved_keys[ $slug ]['key'] : ''; 363 364 if ( empty( $saved_key ) ) { 365 wp_send_json_error( array( 'message' => __( 'No API key saved.', 'rc-site-manager-optimization' ) ) ); 366 return; 367 } 368 369 // Riusa la stessa logica di verifica 370 $response = wp_remote_get( 371 add_query_arg( array( 372 'url' => home_url( '/' ), 373 'key' => $saved_key, 374 'strategy' => 'mobile', 375 'category' => 'performance', 376 ), 'https://www.googleapis.com/pagespeedonline/v5/runPagespeed' ), 377 array( 'timeout' => 20 ) 378 ); 379 380 if ( is_wp_error( $response ) ) { 381 wp_send_json_error( array( 'message' => __( 'Connection error. Please try again.', 'rc-site-manager-optimization' ) ) ); 382 return; 383 } 384 385 $body = json_decode( wp_remote_retrieve_body( $response ), true ); 386 $http_code = (int) wp_remote_retrieve_response_code( $response ); 387 388 if ( $http_code === 200 && isset( $body['lighthouseResult'] ) ) { 389 wp_send_json_success( array( 'message' => __( 'API Key valid and active.', 'rc-site-manager-optimization' ) ) ); 390 } else { 391 $error_msg = isset( $body['error']['message'] ) 392 ? $body['error']['message'] 393 : __( 'Invalid API Key.', 'rc-site-manager-optimization' ); 394 wp_send_json_error( array( 'message' => $error_msg ) ); 395 } 396 397 wp_die(); 398 } ); -
rc-site-manager-optimization/trunk/settings/settings_script.js
r3438010 r3487409 110 110 // Rimuove listener precedente 111 111 $(document).off('click.premium_verify', '.rc_sm_licence_verify_btn'); 112 113 // Auto-check licenze al caricamento (silenzioso) 114 $('.rc_sm_licence_item[data-has-key="1"]').each(function() { 112 $(document).off('input.licence_unmask', '.rc_sm_licence_input'); 113 114 // Reset data-is-masked quando l'utente digita una nuova chiave 115 $(document).on('input.licence_unmask', '.rc_sm_licence_input', function () { 116 $(this).attr('data-is-masked', '0'); 117 }); 118 119 // Auto-check al caricamento: server-side, nessuna chiave in JS 120 $('.rc_sm_licence_item[data-has-key="1"]').each(function () { 115 121 var $item = $(this); 116 var slug = $item.data('slug'); 117 var $input = $item.find('.rc_sm_licence_input'); 118 var licenceKey = $input.val().trim(); 119 120 if (licenceKey) { 121 verifyLicence(slug, licenceKey, $item, null, true); 122 } 123 }); 124 125 // Handle licence verification click 126 $(document).on('click.premium_verify', '.rc_sm_licence_verify_btn', function(e) { 122 var slug = $item.data('slug'); 123 verifyLicenceSaved(slug, $item, null, true); 124 }); 125 126 // Click su Verify 127 $(document).on('click.premium_verify', '.rc_sm_licence_verify_btn', function (e) { 127 128 e.preventDefault(); 128 129 var btn = this; 130 var $btn = $(btn); 131 var slug = $btn.data('slug'); 132 var $item = $btn.closest('.rc_sm_licence_item'); 133 var $input = $item.find('.rc_sm_licence_input'); 134 var licenceKey = $input.val().trim(); 135 136 if (!licenceKey) { 137 var $message = $item.find('.rc_sm_licence_message'); 138 $message.html('<div class="rc_sm_notice" style="margin-bottom: 30px;"><div class="rc_sm_notice_error">Please enter a licence key.</div></div>').show(); 139 setTimeout(function() { 140 $btn.removeClass('rc_sm_loader_active'); 141 $btn.prop('disabled', false); 142 $btn.next('.rc_sm_button_loader_ico').remove(); 143 $btn.prev('.rc_sm_button_loader_ico').remove(); 144 }, 100); 145 return; 146 } 147 148 verifyLicence(slug, licenceKey, $item, function() { 149 setTimeout(function() { 150 $(btn).removeClass('rc_sm_loader_active'); 151 $(btn).prop('disabled', false); 129 130 var btn = this; 131 var $btn = $(btn); 132 var slug = $btn.data('slug'); 133 var $item = $btn.closest('.rc_sm_licence_item'); 134 var $input = $item.find('.rc_sm_licence_input'); 135 var isMasked = $input.attr('data-is-masked') === '1'; 136 137 var resetBtn = function () { 138 setTimeout(function () { 139 $(btn).removeClass('rc_sm_loader_active').prop('disabled', false); 152 140 $(btn).next('.rc_sm_button_loader_ico').remove(); 153 141 $(btn).prev('.rc_sm_button_loader_ico').remove(); 154 142 }, 100); 155 }, false); 156 }); 157 158 // Funzione verifica licenza (silent = true nasconde messaggi) 143 }; 144 145 if (isMasked) { 146 // Chiave mascherata: verifica server-side senza inviarla 147 verifyLicenceSaved(slug, $item, resetBtn, false); 148 return; 149 } 150 151 var licenceKey = $input.val().trim(); 152 if (!licenceKey) { 153 $item.find('.rc_sm_licence_message') 154 .html('<div class="rc_sm_notice" style="margin-bottom:30px;"><div class="rc_sm_notice_error">Please enter a licence key.</div></div>').show(); 155 resetBtn(); 156 return; 157 } 158 159 verifyLicence(slug, licenceKey, $item, resetBtn, false); 160 }); 161 162 // Verifica licenza salvata nel DB (server-side, nessuna chiave in JS) 163 function verifyLicenceSaved(slug, $item, callback, silent) { 164 var $message = $item.find('.rc_sm_licence_message'); 165 var $status = $item.find('.rc_sm_licence_status'); 166 167 if (!silent) { $message.hide(); } 168 169 $.ajax({ 170 url: rc_sm_ajax.ajax_url, 171 type: 'POST', 172 data: { action: 'rc_sm_premium_verify_saved_licence', nonce: rc_sm_ajax.nonce, slug: slug } 173 }).done(function (response) { 174 if (response && response.success) { 175 $status.html('<span class="rc_sm_color_success"><span class="dashicons dashicons-marker" style="line-height:inherit;"></span> Active</span>'); 176 if (!silent) { 177 $message.html('<div class="rc_sm_notice" style="margin-bottom:30px;"><div class="rc_sm_notice_success">' + (response.data.message || 'Licence valid and active.') + '</div></div>').show(); 178 rc_sm_js_notice_fly_show(response.data.message || 'Licence valid and active.', 'success'); 179 } 180 } else { 181 var errMsg = (response && response.data && response.data.message) ? response.data.message : 'Invalid licence key.'; 182 $status.html('<span class="rc_sm_color_error"><span class="dashicons dashicons-marker" style="line-height:inherit;"></span> Not activated</span>'); 183 if (!silent) { 184 $message.html('<div class="rc_sm_notice" style="margin-bottom:30px;"><div class="rc_sm_notice_error">' + errMsg + '</div></div>').show(); 185 rc_sm_js_notice_fly_show(errMsg, 'error'); 186 } 187 } 188 if (typeof callback === 'function') callback(); 189 }).fail(function () { 190 if (!silent) { 191 $item.find('.rc_sm_licence_message').html('<div class="rc_sm_notice" style="margin-bottom:30px;"><div class="rc_sm_notice_error">Connection error. Please try again.</div></div>').show(); 192 rc_sm_js_notice_fly_show('Connection error. Please try again.', 'error'); 193 } 194 if (typeof callback === 'function') callback(); 195 }); 196 } 197 198 // Verifica nuova chiave licenza (inviata dal client) 159 199 function verifyLicence(slug, licenceKey, $item, callback, silent) { 160 200 var $message = $item.find('.rc_sm_licence_message'); 161 var $status = $item.find('.rc_sm_licence_status'); 162 163 if (!silent) { 164 $message.hide(); 165 } 166 201 var $status = $item.find('.rc_sm_licence_status'); 202 203 if (!silent) { $message.hide(); } 204 167 205 $.ajax({ 168 url: rc_sm_ajax.ajax_url,206 url: rc_sm_ajax.ajax_url, 169 207 type: 'POST', 170 208 data: { 171 action: 'rc_sm_premium_verify_licence',172 nonce: rc_sm_ajax.nonce,173 slug: slug,209 action: 'rc_sm_premium_verify_licence', 210 nonce: rc_sm_ajax.nonce, 211 slug: slug, 174 212 licence_key: licenceKey 175 213 } 176 }).done(function (response) {214 }).done(function (response) { 177 215 if (response && response.success) { 178 216 $status.html('<span class="rc_sm_color_success"><span class="dashicons dashicons-marker" style="line-height:inherit;"></span> Active</span>'); 179 217 if (!silent) { 180 $message.html('<div class="rc_sm_notice" style="margin-bottom: 30px;"><div class="rc_sm_notice_success">' + (response.data.message || 'Licence valid and active') + '</div></div>').show();218 $message.html('<div class="rc_sm_notice" style="margin-bottom:30px;"><div class="rc_sm_notice_success">' + (response.data.message || 'Licence valid and active.') + '</div></div>').show(); 181 219 rc_sm_js_notice_fly_show(response.data.message || 'Licence activated successfully.', 'success'); 182 220 } 183 221 } else { 184 var err orMsg = (response && response.data && response.data.message) ? response.data.message : 'Invalid licence key.';222 var errMsg = (response && response.data && response.data.message) ? response.data.message : 'Invalid licence key.'; 185 223 $status.html('<span class="rc_sm_color_error"><span class="dashicons dashicons-marker" style="line-height:inherit;"></span> Not activated</span>'); 186 224 if (!silent) { 187 $message.html('<div class="rc_sm_notice" style="margin-bottom: 30px;"><div class="rc_sm_notice_error">' + errorMsg + '</div></div>').show();188 rc_sm_js_notice_fly_show(err orMsg, 'error');189 } 190 } 191 if (typeof callback === 'function') callback(); 192 }).fail(function () {225 $message.html('<div class="rc_sm_notice" style="margin-bottom:30px;"><div class="rc_sm_notice_error">' + errMsg + '</div></div>').show(); 226 rc_sm_js_notice_fly_show(errMsg, 'error'); 227 } 228 } 229 if (typeof callback === 'function') callback(); 230 }).fail(function () { 193 231 if (!silent) { 194 $ message.html('<div class="rc_sm_notice" style="margin-bottom:30px;"><div class="rc_sm_notice_error">Connection error. Please try again.</div></div>').show();232 $item.find('.rc_sm_licence_message').html('<div class="rc_sm_notice" style="margin-bottom:30px;"><div class="rc_sm_notice_error">Connection error. Please try again.</div></div>').show(); 195 233 rc_sm_js_notice_fly_show('Connection error. Please try again.', 'error'); 196 234 } … … 202 240 203 241 }); 242 243 jQuery(function ($) { 244 $(document).on('rc_sm_tab_loaded', function (e, tabId) { 245 if (tabId !== 'tab_settings_premium') return; 246 247 // Rimuove listener precedente 248 $(document).off('click.api_key_verify', '.rc_sm_api_key_verify_btn'); 249 $(document).off('input.api_key_unmask', '.rc_sm_api_key_input'); 250 251 // Reset data-is-masked quando l'utente digita una nuova chiave 252 $(document).on('input.api_key_unmask', '.rc_sm_api_key_input', function () { 253 $(this).attr('data-is-masked', '0'); 254 }); 255 256 // Auto-check al caricamento: server-side, nessuna chiave in JS 257 $('.rc_sm_api_key_item[data-has-key="1"]').each(function () { 258 var $item = $(this); 259 var slug = $item.data('slug'); 260 verifyApiKeySaved(slug, $item, null, true); 261 }); 262 263 // Click su Verify 264 $(document).on('click.api_key_verify', '.rc_sm_api_key_verify_btn', function (e) { 265 e.preventDefault(); 266 267 var btn = this; 268 var $btn = $(btn); 269 var slug = $btn.data('slug'); 270 var $item = $btn.closest('.rc_sm_api_key_item'); 271 var $input = $item.find('.rc_sm_api_key_input'); 272 var isMasked = $input.attr('data-is-masked') === '1'; 273 274 var resetBtn = function () { 275 setTimeout(function () { 276 $(btn).removeClass('rc_sm_loader_active').prop('disabled', false); 277 $(btn).next('.rc_sm_button_loader_ico').remove(); 278 $(btn).prev('.rc_sm_button_loader_ico').remove(); 279 }, 100); 280 }; 281 282 if (isMasked) { 283 verifyApiKeySaved(slug, $item, resetBtn, false); 284 return; 285 } 286 287 var key = $input.val().trim(); 288 if (!key) { 289 $item.find('.rc_sm_api_key_message') 290 .html('<div class="rc_sm_notice" style="margin-bottom:30px;"><div class="rc_sm_notice_error">Please enter an API key.</div></div>').show(); 291 resetBtn(); 292 return; 293 } 294 295 verifyApiKey(slug, key, $item, resetBtn, false); 296 }); 297 298 // Verifica API key salvata nel DB (server-side, nessuna chiave in JS) 299 function verifyApiKeySaved(slug, $item, callback, silent) { 300 var $message = $item.find('.rc_sm_api_key_message'); 301 var $status = $item.find('.rc_sm_api_key_status'); 302 303 if (!silent) { $message.hide(); } 304 305 $.ajax({ 306 url: rc_sm_ajax.ajax_url, 307 type: 'POST', 308 data: { action: 'rc_sm_api_key_verify_saved', nonce: rc_sm_ajax.nonce, slug: slug } 309 }).done(function (response) { 310 if (response && response.success) { 311 $status.html('<span class="rc_sm_color_success"><span class="dashicons dashicons-marker" style="line-height:inherit;"></span> Active</span>'); 312 if (!silent) { 313 $message.html('<div class="rc_sm_notice" style="margin-bottom:30px;"><div class="rc_sm_notice_success">' + (response.data.message || 'API Key valid and active.') + '</div></div>').show(); 314 rc_sm_js_notice_fly_show(response.data.message || 'API Key valid and active.', 'success'); 315 } 316 } else { 317 var errMsg = (response && response.data && response.data.message) ? response.data.message : 'Invalid API Key.'; 318 $status.html('<span class="rc_sm_color_error"><span class="dashicons dashicons-marker" style="line-height:inherit;"></span> Not activated</span>'); 319 if (!silent) { 320 $message.html('<div class="rc_sm_notice" style="margin-bottom:30px;"><div class="rc_sm_notice_error">' + errMsg + '</div></div>').show(); 321 rc_sm_js_notice_fly_show(errMsg, 'error'); 322 } 323 } 324 if (typeof callback === 'function') callback(); 325 }).fail(function () { 326 if (!silent) { 327 $item.find('.rc_sm_api_key_message').html('<div class="rc_sm_notice" style="margin-bottom:30px;"><div class="rc_sm_notice_error">Connection error. Please try again.</div></div>').show(); 328 rc_sm_js_notice_fly_show('Connection error. Please try again.', 'error'); 329 } 330 if (typeof callback === 'function') callback(); 331 }); 332 } 333 334 // Verifica nuova API key (inviata dal client) 335 function verifyApiKey(slug, key, $item, callback, silent) { 336 var $message = $item.find('.rc_sm_api_key_message'); 337 var $status = $item.find('.rc_sm_api_key_status'); 338 339 if (!silent) { $message.hide(); } 340 341 $.ajax({ 342 url: rc_sm_ajax.ajax_url, 343 type: 'POST', 344 data: { 345 action: 'rc_sm_api_key_verify', 346 nonce: rc_sm_ajax.nonce, 347 slug: slug, 348 api_key: key 349 } 350 }).done(function (response) { 351 if (response && response.success) { 352 $status.html('<span class="rc_sm_color_success"><span class="dashicons dashicons-marker" style="line-height:inherit;"></span> Active</span>'); 353 if (!silent) { 354 $message.html('<div class="rc_sm_notice" style="margin-bottom:30px;"><div class="rc_sm_notice_success">' + (response.data.message || 'API Key valid and active.') + '</div></div>').show(); 355 rc_sm_js_notice_fly_show(response.data.message || 'API Key activated successfully.', 'success'); 356 } 357 } else { 358 var errMsg = (response && response.data && response.data.message) ? response.data.message : 'Invalid API Key.'; 359 $status.html('<span class="rc_sm_color_error"><span class="dashicons dashicons-marker" style="line-height:inherit;"></span> Not activated</span>'); 360 if (!silent) { 361 $message.html('<div class="rc_sm_notice" style="margin-bottom:30px;"><div class="rc_sm_notice_error">' + errMsg + '</div></div>').show(); 362 rc_sm_js_notice_fly_show(errMsg, 'error'); 363 } 364 } 365 if (typeof callback === 'function') callback(); 366 }).fail(function () { 367 if (!silent) { 368 $message.html('<div class="rc_sm_notice" style="margin-bottom:30px;"><div class="rc_sm_notice_error">Connection error. Please try again.</div></div>').show(); 369 rc_sm_js_notice_fly_show('Connection error. Please try again.', 'error'); 370 } 371 if (typeof callback === 'function') callback(); 372 }); 373 } 374 375 }); 376 }); -
rc-site-manager-optimization/trunk/settings/tab_premium.php
r3438010 r3487409 21 21 </div> 22 22 23 </div><div class="rc_sm_bs_col_6"> 24 25 <div class="rc_sm_box_wrap rc_sm_box_form"> 26 27 <h3><?php echo esc_html__('API Keys', 'rc-site-manager-optimization'); ?></h3> 28 29 <p><?php echo esc_html__('Enter your API keys to enable external integrations.', 'rc-site-manager-optimization'); ?></p> 30 31 <div class="rc_sm_api_keys_wrap"> 32 <?php 33 echo rc_sm_api_keys_form(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Function handles escaping internally 34 ?> 35 </div> 36 37 </div> 38 23 39 </div> 24 40 -
rc-site-manager-optimization/trunk/settings/tab_premium_fn.php
r3472200 r3487409 2 2 if ( ! defined( 'ABSPATH' ) ) exit; 3 3 4 /** 5 * Maschera una chiave mostrando i primi 10 e gli ultimi 5 caratteri. 6 * La chiave completa non viene mai emessa nell'HTML. 7 */ 8 function rc_sm_mask_key( $key ) { 9 $len = strlen( $key ); 10 if ( $len <= 15 ) { 11 return str_repeat( '*', $len ); 12 } 13 return substr( $key, 0, 10 ) . str_repeat( '*', $len - 15 ) . substr( $key, -5 ); 14 } 15 4 16 function rc_sm_premium_form() { 5 6 // Definizione servizi premium 17 7 18 $services = array( 8 19 'sus' => array( 9 'name' => 'RC Site Ultra Speed',20 'name' => 'RC Site Ultra Speed', 10 21 'prefix' => 'rc_sus_' 11 22 ), 12 23 'cs1' => array( 13 'name' => 'RC Custom Software 1',24 'name' => 'RC Custom Software 1', 14 25 'prefix' => 'rc_cs1_' 15 26 ) 16 27 ); 17 18 // Recupera licenze salvate dal database 19 $saved_licences = rc_sm_tb_settings_get_value('premium_licences'); 20 if (empty($saved_licences)) { 28 29 $saved_licences = rc_sm_tb_settings_get_value( 'premium_licences' ); 30 if ( empty( $saved_licences ) ) { 21 31 $saved_licences = array(); 22 32 } 23 33 24 34 $html = ''; 25 26 foreach ( $services as $slug => $service) {27 35 36 foreach ( $services as $slug => $service ) { 37 28 38 $field_name = 'licence_' . $slug; 29 $saved_key = isset($saved_licences[$slug]['key']) ? $saved_licences[$slug]['key'] : ''; 30 31 $html .= '<div class="rc_sm_form_divider rc_sm_licence_item" data-slug="' . esc_attr($slug) . '" data-has-key="' . (!empty($saved_key) ? '1' : '0') . '">'; 32 33 // Titolo servizio con stato di fianco 39 $saved_key = isset( $saved_licences[ $slug ]['key'] ) ? $saved_licences[ $slug ]['key'] : ''; 40 $has_key = ! empty( $saved_key ) ? '1' : '0'; 41 $display = ! empty( $saved_key ) ? rc_sm_mask_key( $saved_key ) : ''; 42 43 $html .= '<div class="rc_sm_form_divider rc_sm_licence_item" data-slug="' . esc_attr( $slug ) . '" data-has-key="' . $has_key . '">'; 44 34 45 $html .= '<div class="rc_sm_bs_row">'; 35 46 $html .= '<div class="rc_sm_bs_col_6">'; 36 $html .= '<h4 style="margin-top:0;">' . esc_html( $service['name']) . '</h4>';47 $html .= '<h4 style="margin-top:0;">' . esc_html( $service['name'] ) . '</h4>'; 37 48 $html .= '</div>'; 38 49 $html .= '<div class="rc_sm_bs_col_6 rc_sm_bs_col_align">'; 39 50 $html .= '<div class="rc_sm_licence_status" style="margin-top:0;">'; 40 $html .= '<span class="rc_sm_color_warning"><span class="dashicons dashicons-update" style="line-height:inherit;"></span> ' . esc_html__( 'Checking', 'rc-site-manager-optimization') . '...</span>';51 $html .= '<span class="rc_sm_color_warning"><span class="dashicons dashicons-update" style="line-height:inherit;"></span> ' . esc_html__( 'Checking', 'rc-site-manager-optimization' ) . '...</span>'; 41 52 $html .= '</div>'; 42 53 $html .= '</div>'; 43 54 $html .= '</div>'; 44 45 // Area messaggio (sempre nascosta inizialmente) 55 46 56 $html .= '<div class="rc_sm_licence_message" style="display:none;"></div>'; 47 48 // Campo input licenza con bottone verifica 57 49 58 $html .= '<div class="rc_sm_licence_input_wrap">'; 50 59 $html .= '<div class="rc_sm_bs_row">'; 51 60 $html .= '<div class="rc_sm_bs_col_10">'; 52 $html .= '<input type="text" name="' . esc_attr( $field_name) . '" class="rc_sm_licence_input" placeholder="' . esc_attr($service['prefix']) . 'xxxxxxxxxx..." value="' . esc_attr($saved_key) . '">';53 $html .= '<div class="rc_sm_form_help rc_sm_color_light">' . esc_html__( 'Prefix', 'rc-site-manager-optimization') . ' "' . esc_attr($service['prefix']) . '" ' . esc_html__('+ "50 alphanumeric characters"', 'rc-site-manager-optimization') . '</div>';61 $html .= '<input type="text" name="' . esc_attr( $field_name ) . '" class="rc_sm_licence_input" placeholder="' . esc_attr( $service['prefix'] ) . 'xxxxxxxxxx..." value="' . esc_attr( $display ) . '" data-is-masked="' . $has_key . '" autocomplete="off">'; 62 $html .= '<div class="rc_sm_form_help rc_sm_color_light">' . esc_html__( 'Prefix', 'rc-site-manager-optimization' ) . ' "' . esc_attr( $service['prefix'] ) . '" ' . esc_html__( '+ "50 alphanumeric characters"', 'rc-site-manager-optimization' ) . '</div>'; 54 63 $html .= '</div>'; 55 64 $html .= '<div class="rc_sm_bs_col_2 rc_sm_bs_col_align_right">'; 56 $html .= '<button type="button" class="rc_sm_button rc_sm_bg_success rc_sm_size_lg rc_sm_button_loader rc_sm_button_loader_left rc_sm_licence_verify_btn" data-slug="' . esc_attr( $slug) . '">' . esc_html__('Verify', 'rc-site-manager-optimization') . '</button>';65 $html .= '<button type="button" class="rc_sm_button rc_sm_bg_success rc_sm_size_lg rc_sm_button_loader rc_sm_button_loader_left rc_sm_licence_verify_btn" data-slug="' . esc_attr( $slug ) . '">' . esc_html__( 'Verify', 'rc-site-manager-optimization' ) . '</button>'; 57 66 $html .= '</div>'; 58 67 $html .= '</div>'; 59 68 $html .= '</div>'; 60 69 61 70 $html .= '</div>'; 62 71 } 63 72 64 73 return $html; 65 74 } 75 76 function rc_sm_api_keys_form() { 77 78 $api_keys_config = array( 79 'google_cloud' => array( 80 'name' => 'Google Cloud API Key', 81 'placeholder' => 'AIzaSy...', 82 'help' => __( 'Used for: PageSpeed Insights, Google Maps, YouTube Data API, Google Translate, Google Vision, Google Search Console API, Google Analytics Data API', 'rc-site-manager-optimization' ), 83 ) 84 ); 85 86 $saved_keys = rc_sm_tb_settings_get_value( 'api_keys' ); 87 if ( empty( $saved_keys ) ) { 88 $saved_keys = array(); 89 } 90 91 $html = ''; 92 93 foreach ( $api_keys_config as $slug => $config ) { 94 95 $saved_key = isset( $saved_keys[ $slug ]['key'] ) ? $saved_keys[ $slug ]['key'] : ''; 96 $has_key = ! empty( $saved_key ) ? '1' : '0'; 97 $display = ! empty( $saved_key ) ? rc_sm_mask_key( $saved_key ) : ''; 98 99 $html .= '<div class="rc_sm_form_divider rc_sm_api_key_item" data-slug="' . esc_attr( $slug ) . '" data-has-key="' . $has_key . '">'; 100 101 $html .= '<div class="rc_sm_bs_row">'; 102 $html .= '<div class="rc_sm_bs_col_6"><h4 style="margin-top:0;">' . esc_html( $config['name'] ) . '</h4></div>'; 103 $html .= '<div class="rc_sm_bs_col_6 rc_sm_bs_col_align">'; 104 $html .= '<div class="rc_sm_api_key_status" style="margin-top:0;">'; 105 $html .= '<span class="rc_sm_color_warning"><span class="dashicons dashicons-update" style="line-height:inherit;"></span> ' . esc_html__( 'Checking', 'rc-site-manager-optimization' ) . '...</span>'; 106 $html .= '</div>'; 107 $html .= '</div>'; 108 $html .= '</div>'; 109 110 $html .= '<div class="rc_sm_api_key_message" style="display:none;"></div>'; 111 112 $html .= '<div class="rc_sm_api_key_input_wrap">'; 113 $html .= '<div class="rc_sm_bs_row">'; 114 $html .= '<div class="rc_sm_bs_col_10">'; 115 $html .= '<input type="text" name="api_key_' . esc_attr( $slug ) . '" class="rc_sm_api_key_input" placeholder="' . esc_attr( $config['placeholder'] ) . '" value="' . esc_attr( $display ) . '" data-is-masked="' . $has_key . '" autocomplete="off">'; 116 $html .= '<div class="rc_sm_form_help rc_sm_color_light">' . esc_html( $config['help'] ) . '</div>'; 117 $html .= '</div>'; 118 $html .= '<div class="rc_sm_bs_col_2 rc_sm_bs_col_align_right">'; 119 $html .= '<button type="button" class="rc_sm_button rc_sm_bg_success rc_sm_size_lg rc_sm_button_loader rc_sm_button_loader_left rc_sm_api_key_verify_btn" data-slug="' . esc_attr( $slug ) . '">' . esc_html__( 'Verify', 'rc-site-manager-optimization' ) . '</button>'; 120 $html .= '</div>'; 121 $html .= '</div>'; 122 $html .= '</div>'; 123 124 $html .= '</div>'; 125 } 126 127 return $html; 128 } -
rc-site-manager-optimization/trunk/utility/tab_log.php
r3480548 r3487409 28 28 $type = esc_attr($key); 29 29 $file_key = esc_attr($log['file_key']); 30 $file_exists = file_exists($path) && strpos($path, '/dev/') === false;31 30 32 $size = file_exists($path) ? filesize($path) : 0; 31 $is_same_as_debug = $key === 'php_errorlog' && ( empty( $path ) || strpos( $path, 'debug.log' ) !== false ); 32 $file_exists = !$is_same_as_debug && file_exists($path) && strpos($path, '/dev/') === false; 33 34 $size = $file_exists ? filesize($path) : 0; 33 35 $size_mb = $size / (1024 * 1024); 34 36 ?> 35 37 <div class="rc_sm_bs_col_6"> 36 38 <div class="rc_sm_box_wrap"> 37 <h3><?php echo esc_html($label); ?> 38 <?php if ($file_exists): ?> 39 - <?php echo wp_kses(rc_sm_file_size_html($size), [ 40 'span' => [ 41 'class' => [], 42 ], 43 ]); ?> 44 <?php endif; ?> 45 <?php echo wp_kses_post(rc_sm_help_link('utility_log', '?')); ?> 46 </h3> 39 <div class="rc_sm_bs_row rc_sm_title_filter"> 40 <div class="rc_sm_bs_col_6"> 41 <h3 style="padding-top: 0px;"><?php echo esc_html($label); ?> 42 <?php if ($file_exists): ?> 43 - <?php echo wp_kses(rc_sm_file_size_html($size), ['span' => ['class' => []]]); ?> 44 <?php endif; ?> 45 <?php echo wp_kses_post(rc_sm_help_link('utility_log', '?')); ?> 46 </h3> 47 </div> 48 <?php if ($file_exists && $size_mb < 5): ?> 49 <div class="rc_sm_bs_col_6 rc_sm_bs_col_align"> 50 <div class="rc_sm_bs_col_align_right"> 51 <a href="#" class="rc_sm_tooltip_copy rc_sm_tooltip_sx rc_sm_button rc_sm_bg_primary" data-tooltip-copy-class="<?php echo esc_attr($id); ?>"> 52 <?php echo esc_html__( 'Copy Code', 'rc-site-manager-optimization' ); ?> 53 </a> 54 </div> 55 </div> 56 <?php endif; ?> 57 </div> 47 58 48 <?php if ($file_exists): ?> 59 <?php if ($is_same_as_debug): ?> 60 <p><?php echo esc_html__( 'Same as debug.log', 'rc-site-manager-optimization' ); ?></p> 61 <?php elseif ($file_exists): ?> 49 62 <?php if ($size_mb < 5): ?> 50 63 <textarea class="<?php echo esc_attr($id); ?>" readonly rows="20" style="width:100%; background:#fff; border:1px solid #ccc; padding:10px;"><?php echo esc_textarea(file_get_contents($path)); ?></textarea> -
rc-site-manager-optimization/trunk/utility/tab_system_fn.php
r3487089 r3487409 176 176 $data = []; 177 177 foreach ( $files as $label => $path ) { 178 if ( $label === 'php_errorlog' && ( empty( $path ) || strpos( $path, 'debug.log' ) !== false ) ) { 179 $data[ $label ] = [ 'value' => 'N/A', 'source' => esc_html__( 'Same as debug.log', 'rc-site-manager-optimization' ) ]; 180 continue; 181 } 178 182 if ( $path && file_exists( $path ) ) { 179 183 $size = filesize( $path );
Note: See TracChangeset
for help on using the changeset viewer.