Changeset 3473905
- Timestamp:
- 03/03/2026 06:06:38 PM (4 weeks ago)
- Location:
- rc-site-manager-optimization/trunk
- Files:
-
- 3 edited
-
includes/admin.php (modified) (7 diffs)
-
rc-site-manager-optimization.php (modified) (2 diffs)
-
readme.txt (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
rc-site-manager-optimization/trunk/includes/admin.php
r3472200 r3473905 1 1 <?php 2 2 if (!defined('ABSPATH')) exit; 3 4 function rc_sm_is_plugin_page() { 5 return isset($_GET['page']) && strpos($_GET['page'], 'rc_sm_') === 0; 6 } 3 7 4 8 function rc_sm_admin_bar_css() { 5 9 ?> 6 10 <style> 7 #wp-admin-bar-imagify, 8 #wp-admin-bar-elementor_notes, 9 #wp-admin-bar-ccb-admin-menu, 10 #wp-admin-bar-docs, #wp-admin-bar-faq, #wp-admin-bar-support, 11 #wp-admin-bar-purge-all, #wp-admin-bar-clean-saas, #wp-admin-bar-clear-performance-hints, 12 #wp-admin-bar-admin-notification-popup 13 { display: none !important; } 14 15 #wp-admin-bar-rc-site-manager > .ab-item, #toplevel_page_rc_sm_dashboard > a { background-color: #e74c3c !important; color: #fff !important; } 16 #wp-admin-bar-rc-site-manager > .ab-item .ab-icon:before { color: #fff !important; } 17 #wp-admin-bar-rc-site-manager > a { padding-left: 20px !important; padding-right: 20px !important; } 18 #wp-admin-bar-rc-site-manager .ab-icon { font-size: 16px !important; padding-top: 8px !important; } 11 #wp-admin-bar-wp-logo, 12 #wp-admin-bar-new-content, 13 #wp-admin-bar-admin-notification-popup, 14 #wp-admin-bar-imagify, 15 #wp-admin-bar-elementor_notes, 16 #wp-admin-bar-ccb-admin-menu, 17 #wp-admin-bar-wp-rocket, 18 #wp-admin-bar-updraft_admin_node, 19 #wp-admin-bar-wpseo-menu, 20 #wp-admin-bar-google-site-kit, 21 #wp-admin-bar-rank-math, 22 #wp-admin-bar-thegem-theme-root, 23 #wp-admin-bar-avia, 24 #wp-admin-bar-avia_ext, 25 #wp-admin-bar-gform-forms 26 { display: none !important; } 27 28 #wp-admin-bar-rc-site-manager > .ab-item { background-color: #e74c3c !important; color: #fff !important; } 29 #wp-admin-bar-rc-site-manager > .ab-item .ab-icon:before { color: #fff !important; } 30 #wp-admin-bar-rc-site-manager > a { padding-left: 20px !important; padding-right: 20px !important; } 31 #wp-admin-bar-rc-site-manager .ab-icon { font-size: 16px !important; padding-top: 8px !important; } 32 33 #wp-admin-bar-rc-sm-wp-rocket-sep { border-top: 1px solid #ccc !important; margin: 4px 0 !important; pointer-events: none; height: 1px; padding: 0 !important; } 34 #wp-admin-bar-rc-sm-wp-rocket-sep .ab-item { display: none !important; } 35 #wp-admin-bar-rc-sm-wp-rocket-title .ab-item { color: #999 !important; font-size: 11px !important; text-transform: uppercase; letter-spacing: 1px; cursor: default; pointer-events: none; } 19 36 </style> 20 37 <?php … … 24 41 25 42 43 function rc_sm_clear_cache_css() { 44 ?> 45 <style> 46 :root { 47 --rc-uv-color-success: #28a745; 48 --rc-uv-color-error: #c62828; 49 --rc-uv-color-warning: #f57c00; 50 --rc-uv-color-info: #2196f3; 51 --rc-uv-color-light: #aaaaaa; 52 } 53 [class*="rc_sm_notice_"] { padding: 10px 20px; border-radius: 0; } 54 .rc_sm_notice_fly { position: fixed; top: calc(32px + 20px); right: 20px; z-index: 99999; display: flex; flex-direction: column; align-items: flex-end; gap: 10px; pointer-events: none; } 55 .rc_sm_notice_fly_container { width: 400px; display: flex; overflow: hidden; border-radius: 5px; font-size: 14px; font-weight: 500; box-shadow: 0 2px 12px rgba(0,0,0,0.15); opacity: 0; transform: translateY(-10px); animation: rc_sm_notice_fly_active 0.3s ease-out forwards; pointer-events: auto; font-family: 'Poppins', sans-serif; padding: 0; } 56 .rc_sm_notice_fly_container[class*="rc_sm_notice_"] { padding: 0; } 57 .rc_sm_notice_fly_icon { width: 70px; min-height: 60px; display: flex; align-items: center; justify-content: center; color: #fff; font-size: 30px; padding: 0; flex-shrink: 0; } 58 .rc_sm_notice_fly_message { flex: 1; padding: 10px 16px; background: #fff; color: #333; line-height: 1.4; display: flex; align-items: center; } 59 .rc_sm_notice_fly_success .rc_sm_notice_fly_icon { background-color: var(--rc-uv-color-success); } 60 .rc_sm_notice_fly_error .rc_sm_notice_fly_icon { background-color: var(--rc-uv-color-error); } 61 .rc_sm_notice_fly_warning .rc_sm_notice_fly_icon { background-color: var(--rc-uv-color-warning); } 62 .rc_sm_notice_fly_info .rc_sm_notice_fly_icon { background-color: var(--rc-uv-color-info); } 63 .rc_sm_notice_fly_info .rc_sm_notice_fly_icon::before { animation: rc_sm_alert_loader_spin 1s linear infinite; display: inline-block; } 64 @keyframes rc_sm_notice_fly_active { to { opacity: 1; transform: translateY(0); } } 65 @keyframes rc_sm_alert_loader_spin { to { transform: rotate(360deg); } } 66 @media screen and (max-width: 782px) { .rc_sm_notice_fly { top: calc(46px + 20px); } } 67 #rc_sm_modal_clear_all { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 9999; } 68 #rc_sm_modal_clear_all .rc_sm_modal_window { background: #fff; width: 90%; max-width: 600px !important; margin: 10% auto; padding: 24px; border-radius: 8px; position: relative; font-family: 'Poppins', sans-serif; } 69 #rc_sm_modal_clear_all .rc_sm_modal_title { font-size: 22px; font-weight: 600; margin: 0 0 20px 0; color: #444; } 70 #rc_sm_modal_clear_all .rc_sm_modal_body { font-size: 20px; line-height: 2; margin-top: 30px; margin-bottom: 50px; color: #444; } 71 #rc_sm_modal_clear_all .rc_sm_modal_footer { display: flex; justify-content: space-between; border-top: 1px solid #c3c4c7; padding-top: 20px; } 72 #rc_sm_modal_clear_all .rc_sm_button { display: inline-block; font-size: 16px; padding: 7px 22px; font-weight: 500; color: #fff !important; text-transform: none !important; line-height: 2; border: 0; text-decoration: none; border-radius: 100px; cursor: pointer; outline: none; box-shadow: none; font-family: 'Poppins', sans-serif; } 73 #rc_sm_modal_clear_all .rc_sm_button:hover { filter: brightness(1.1); } 74 #rc_sm_modal_clear_all .rc_sm_bg_light { background-color: #aaaaaa !important; } 75 #rc_sm_modal_clear_all .rc_sm_bg_warning { background-color: #f57c00 !important; } 76 </style> 77 <?php 78 } 79 80 add_action('admin_head', function() { 81 if ( ! defined('WP_ROCKET_VERSION') ) return; 82 if ( rc_sm_is_plugin_page() ) return; 83 rc_sm_clear_cache_css(); 84 }); 85 86 add_action('wp_head', function() { 87 if ( ! is_user_logged_in() ) return; 88 if ( ! defined('WP_ROCKET_VERSION') ) return; 89 rc_sm_clear_cache_css(); 90 }); 26 91 27 92 … … 37 102 'id' => 'rc-site-manager-dashboard', 38 103 'parent' => 'rc-site-manager', 39 'title' => 'Dashboard',104 'title' => __('Dashboard', 'rc-site-manager-optimization'), 40 105 'href' => admin_url('admin.php?page=rc_sm_dashboard'), 41 106 ]); … … 44 109 'id' => 'rc-site-manager-seo', 45 110 'parent' => 'rc-site-manager', 46 'title' => 'SEO',111 'title' => __('SEO', 'rc-site-manager-optimization'), 47 112 'href' => admin_url('admin.php?page=rc_sm_pg_seo'), 48 ]);49 50 $wp_admin_bar->add_node([51 'id' => 'rc-site-manager-wp-rocket',52 'parent' => 'rc-site-manager',53 'title' => 'WP Rocket',54 'href' => admin_url('admin.php?page=rc_sm_pg_wp_rocket'),55 113 ]); 56 114 … … 58 116 'id' => 'rc-site-manager-media', 59 117 'parent' => 'rc-site-manager', 60 'title' => 'Media',118 'title' => __('Media', 'rc-site-manager-optimization'), 61 119 'href' => admin_url('admin.php?page=rc_sm_media'), 62 120 ]); 63 121 64 $email = wp_get_current_user()->user_email;122 $email = wp_get_current_user()->user_email; 65 123 $is_dev = strpos($email, 'radames.dicembrino@') !== false || strpos($email, 'r.dicembrino@') !== false; 66 124 … … 69 127 'id' => 'rc-site-manager-ultra-speed', 70 128 'parent' => 'rc-site-manager', 71 'title' => 'Ultra Speed',129 'title' => __('Ultra Speed', 'rc-site-manager-optimization'), 72 130 'href' => admin_url('admin.php?page=rc_sm_premium_ultra_speed'), 73 131 ]); … … 78 136 'id' => 'rc-site-manager-custom-software-1', 79 137 'parent' => 'rc-site-manager', 80 'title' => 'Custom Software 1',138 'title' => __('Custom Software 1', 'rc-site-manager-optimization'), 81 139 'href' => admin_url('admin.php?page=rc_sm_premium_custom_software_1'), 82 140 ]); 83 141 } 84 142 85 }, 999); 143 if ( defined('WP_ROCKET_VERSION') ) { 144 $wp_admin_bar->add_node([ 145 'id' => 'rc-sm-wp-rocket-sep', 146 'parent' => 'rc-site-manager', 147 'title' => '', 148 'href' => false, 149 ]); 150 151 $wp_admin_bar->add_node([ 152 'id' => 'rc-sm-wp-rocket-title', 153 'parent' => 'rc-site-manager', 154 'title' => 'WP Rocket', 155 'href' => false, 156 'meta' => ['class' => 'rc-sm-wp-rocket-title'], 157 ]); 158 159 $wp_admin_bar->add_node([ 160 'id' => 'rc-site-manager-wp-rocket', 161 'parent' => 'rc-site-manager', 162 'title' => __('Used CSS', 'rc-site-manager-optimization'), 163 'href' => admin_url('admin.php?page=rc_sm_pg_wp_rocket'), 164 ]); 165 166 if ( is_admin() ) { 167 $screen = get_current_screen(); 168 $post_id = isset($_GET['post']) ? intval($_GET['post']) : 0; 169 if ( $screen && $screen->base === 'post' && $post_id ) { 170 $wp_admin_bar->add_node([ 171 'id' => 'rc-sm-clear-page-cache', 172 'parent' => 'rc-site-manager', 173 'title' => __('Clear this page', 'rc-site-manager-optimization'), 174 'href' => '#', 175 'meta' => ['class' => 'rc-sm-clear-page-cache'], 176 ]); 177 } 178 } 179 180 if ( ! is_admin() && is_user_logged_in() ) { 181 $wp_admin_bar->add_node([ 182 'id' => 'rc-sm-clear-page-cache', 183 'parent' => 'rc-site-manager', 184 'title' => __('Clear this page', 'rc-site-manager-optimization'), 185 'href' => '#', 186 'meta' => ['class' => 'rc-sm-clear-page-cache'], 187 ]); 188 } 189 190 $wp_admin_bar->add_node([ 191 'id' => 'rc-sm-clear-all-cache', 192 'parent' => 'rc-site-manager', 193 'title' => __('Clear all pages', 'rc-site-manager-optimization'), 194 'href' => '#', 195 'meta' => ['class' => 'rc-sm-clear-all-cache'], 196 ]); 197 } 198 199 }, 31); 200 201 202 function rc_sm_clear_cache_js() { 203 $td = 'rc-site-manager-optimization'; 204 ?> 205 <div class="rc_sm_notice_fly"></div> 206 207 <div id="rc_sm_modal_clear_all"> 208 <div class="rc_sm_modal_window"> 209 <div class="rc_sm_modal_title"><?php _e('Clear all pages', $td); ?></div> 210 <div class="rc_sm_modal_body"><?php _e('Are you sure you want to clear the cache of <strong>all pages</strong>?<br>The process may take a few seconds.', $td); ?></div> 211 <div class="rc_sm_modal_footer"> 212 <button type="button" class="rc_sm_button rc_sm_bg_light" id="rc_sm_modal_clear_all_cancel"><?php _e('Cancel', $td); ?></button> 213 <button type="button" class="rc_sm_button rc_sm_bg_warning" id="rc_sm_modal_clear_all_confirm"><?php _e('Yes, clear all', $td); ?></button> 214 </div> 215 </div> 216 </div> 217 218 <script> 219 var rc_sm_i18n = { 220 clearing_page: '<?php echo __('Clearing cache for this URL.<br>Please wait a few seconds.', $td); ?>', 221 clearing_all: '<?php echo __('Clearing all cache.<br>This may take up to 30 seconds.', $td); ?>', 222 ajax_error: '<?php echo esc_js(__('AJAX error.', $td)); ?>', 223 done: '<?php echo esc_js(__('Done.', $td)); ?>' 224 }; 225 226 function rc_sm_notice_fly_show(msg, type, persist) { 227 var icons = { success: 'yes', error: 'no', warning: 'warning', info: 'update' }; 228 var icon = icons[type] || 'info'; 229 var container = document.querySelector('.rc_sm_notice_fly'); 230 if ( ! container ) return null; 231 var el = document.createElement('div'); 232 el.className = 'rc_sm_notice_fly_container rc_sm_notice_fly_' + (type || 'success'); 233 el.innerHTML = '<div class="rc_sm_notice_fly_icon dashicons dashicons-' + icon + '"></div><div class="rc_sm_notice_fly_message">' + msg + '</div>'; 234 container.prepend(el); 235 if ( ! persist ) { 236 setTimeout(function() { 237 jQuery(el).fadeOut(400, function() { jQuery(el).remove(); }); 238 }, 4000); 239 } 240 return el; 241 } 242 243 var elPage = document.getElementById('wp-admin-bar-rc-sm-clear-page-cache'); 244 if ( elPage ) { 245 elPage.addEventListener('click', function(e) { 246 e.preventDefault(); 247 var infoEl = rc_sm_notice_fly_show(rc_sm_i18n.clearing_page, 'info', true); 248 var data = { 249 action: 'rc_sm_clear_page_cache', 250 nonce: window.rc_sm_nonce 251 }; 252 if ( window.rc_sm_post_id ) { 253 data.post_id = window.rc_sm_post_id; 254 } else { 255 data.url = window.location.href; 256 } 257 jQuery.post(window.rc_sm_ajax_url, data, function(response) { 258 jQuery(infoEl).remove(); 259 var msg = response.data && response.data.msg ? response.data.msg : rc_sm_i18n.done; 260 rc_sm_notice_fly_show(msg, response.success ? 'success' : 'error', false); 261 }).fail(function() { 262 jQuery(infoEl).remove(); 263 rc_sm_notice_fly_show(rc_sm_i18n.ajax_error, 'error', false); 264 }); 265 }, true); 266 } 267 268 var elAll = document.getElementById('wp-admin-bar-rc-sm-clear-all-cache'); 269 if ( elAll ) { 270 elAll.addEventListener('click', function(e) { 271 e.preventDefault(); 272 document.getElementById('rc_sm_modal_clear_all').style.display = 'block'; 273 }, true); 274 } 275 276 document.getElementById('rc_sm_modal_clear_all_cancel').addEventListener('click', function() { 277 document.getElementById('rc_sm_modal_clear_all').style.display = 'none'; 278 }); 279 280 document.getElementById('rc_sm_modal_clear_all').addEventListener('click', function(e) { 281 if ( e.target === this ) { 282 this.style.display = 'none'; 283 } 284 }); 285 286 document.getElementById('rc_sm_modal_clear_all_confirm').addEventListener('click', function() { 287 document.getElementById('rc_sm_modal_clear_all').style.display = 'none'; 288 var infoEl = rc_sm_notice_fly_show(rc_sm_i18n.clearing_all, 'info', true); 289 jQuery.post(window.rc_sm_ajax_url, { 290 action: 'rc_sm_clear_all_cache', 291 nonce: window.rc_sm_nonce 292 }, function(response) { 293 jQuery(infoEl).remove(); 294 var msg = response.data && response.data.msg ? response.data.msg : rc_sm_i18n.done; 295 rc_sm_notice_fly_show(msg, response.success ? 'success' : 'error', false); 296 }).fail(function() { 297 jQuery(infoEl).remove(); 298 rc_sm_notice_fly_show(rc_sm_i18n.ajax_error, 'error', false); 299 }); 300 }); 301 </script> 302 <?php 303 } 304 305 306 // JS admin 307 add_action('admin_footer', function() { 308 if ( ! defined('WP_ROCKET_VERSION') ) return; 309 $post_id = isset($_GET['post']) ? intval($_GET['post']) : 0; 310 ?> 311 <script> 312 window.rc_sm_ajax_url = '<?php echo esc_js(admin_url('admin-ajax.php')); ?>'; 313 window.rc_sm_nonce = '<?php echo esc_js(wp_create_nonce('rc_sm_ajax_nonce')); ?>'; 314 window.rc_sm_post_id = <?php echo intval($post_id); ?>; 315 </script> 316 <?php 317 rc_sm_clear_cache_js(); 318 }, 20); 319 320 321 // JS front end 322 add_action('wp_footer', function() { 323 if ( ! is_user_logged_in() ) return; 324 if ( ! defined('WP_ROCKET_VERSION') ) return; 325 ?> 326 <script> 327 window.rc_sm_ajax_url = '<?php echo esc_js(admin_url('admin-ajax.php')); ?>'; 328 window.rc_sm_nonce = '<?php echo esc_js(wp_create_nonce('rc_sm_ajax_nonce')); ?>'; 329 window.rc_sm_post_id = 0; 330 </script> 331 <?php 332 rc_sm_clear_cache_js(); 333 }, 20); 334 335 336 // AJAX - clear this page 337 add_action('wp_ajax_rc_sm_clear_page_cache', function() { 338 if ( ! rc_sm_security_ajax_verify() ) return; 339 340 global $wpdb; 341 $td = 'rc-site-manager-optimization'; 342 343 $post_id = rc_sm_security_ajax_get_int('post_id'); 344 $url_param = rc_sm_security_ajax_get_param('url'); 345 346 if ( $post_id ) { 347 $front_page_id = (int) get_option('page_on_front'); 348 $url = ( $post_id === $front_page_id ) 349 ? rtrim(home_url(), '/') 350 : rtrim(get_permalink($post_id), '/'); 351 } elseif ( $url_param ) { 352 $url = rtrim(esc_url_raw($url_param), '/'); 353 } else { 354 wp_send_json_error(['msg' => __('Missing parameters.', $td)]); 355 } 356 357 if ( ! $url ) { 358 wp_send_json_error(['msg' => __('URL not found.', $td)]); 359 } 360 361 $table = esc_sql($wpdb->prefix . 'wpr_rucss_used_css'); 362 $records = $wpdb->get_results($wpdb->prepare( 363 "SELECT id, url, is_mobile FROM {$table} WHERE url = %s", 364 $url 365 )); 366 367 $success_count = 0; 368 369 if ( ! empty($records) ) { 370 foreach ( $records as $row ) { 371 $wpdb->delete($table, ['id' => absint($row->id)]); 372 373 if ( defined('WP_ROCKET_VERSION') ) { 374 rocket_clean_files([esc_url_raw($row->url)]); 375 376 $user_agent = ($row->is_mobile === '1') 377 ? 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15A372 Safari/604.1' 378 : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.0.0 Safari/537.36'; 379 380 usleep(100000); 381 382 wp_remote_get(esc_url_raw($row->url), [ 383 'timeout' => 30, 384 'blocking' => false, 385 'sslverify' => false, 386 'headers' => ['User-Agent' => $user_agent], 387 ]); 388 389 $success_count++; 390 } 391 } 392 } else { 393 if ( defined('WP_ROCKET_VERSION') ) { 394 rocket_clean_files([$url]); 395 } 396 } 397 398 if ( $success_count > 0 ) { 399 $msg = sprintf(__('Cache cleared and regenerated (%s records).', $td), $success_count); 400 } else { 401 $msg = __('HTML cache cleared.', $td); 402 } 403 404 wp_send_json_success(['msg' => $msg]); 405 }); 406 407 408 // AJAX - clear all pages 409 add_action('wp_ajax_rc_sm_clear_all_cache', function() { 410 if ( ! rc_sm_security_ajax_verify() ) return; 411 412 global $wpdb; 413 $td = 'rc-site-manager-optimization'; 414 415 $table = esc_sql($wpdb->prefix . 'wpr_rucss_used_css'); 416 $records = $wpdb->get_results("SELECT id, url, is_mobile FROM {$table}"); 417 418 if ( defined('WP_ROCKET_VERSION') ) { 419 rocket_clean_domain(); 420 } 421 422 $success_count = 0; 423 424 if ( ! empty($records) ) { 425 $wpdb->query("TRUNCATE TABLE {$table}"); 426 427 foreach ( $records as $row ) { 428 $user_agent = ($row->is_mobile === '1') 429 ? 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15A372 Safari/604.1' 430 : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.0.0 Safari/537.36'; 431 432 usleep(100000); 433 434 wp_remote_get(esc_url_raw($row->url), [ 435 'timeout' => 30, 436 'blocking' => false, 437 'sslverify' => false, 438 'headers' => ['User-Agent' => $user_agent], 439 ]); 440 441 $success_count++; 442 } 443 } 444 445 if ( $success_count > 0 ) { 446 $msg = sprintf(__('Cache cleared and regenerated (%s records).', $td), $success_count); 447 } else { 448 $msg = __('Domain cache cleared.', $td); 449 } 450 451 wp_send_json_success(['msg' => $msg]); 452 }); -
rc-site-manager-optimization/trunk/rc-site-manager-optimization.php
r3472502 r3473905 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.3. 35 * Version: 2.3.4 6 6 * Author: Rocket Comunicazione 7 7 * Author URI: https://www.rocketcomunicazione.com … … 18 18 19 19 20 define('RC_SM_PLUGIN_VERSION', '2.3. 3');20 define('RC_SM_PLUGIN_VERSION', '2.3.4'); 21 21 22 22 define( 'RC_SM_SITE_URL', home_url() ); -
rc-site-manager-optimization/trunk/readme.txt
r3472502 r3473905 5 5 Tested up to: 6.9 6 6 Requires PHP: 8.1 7 Stable tag: 2.3. 37 Stable tag: 2.3.4 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.3.4 - March 3, 2026 = 164 * Minor bug fixes and improvement 162 165 163 166 = 2.3.3 - March 2, 2026 = … … 277 280 == Upgrade Notice == 278 281 282 = 2.3.4 - March 3, 2026 = 283 Minor bug fixes. 284 279 285 = 2.3.3 - March 2, 2026 = 280 286 Minor bug fixes.
Note: See TracChangeset
for help on using the changeset viewer.