Changeset 3400206
- Timestamp:
- 11/21/2025 06:43:59 AM (4 months ago)
- Location:
- debugger-troubleshooter/trunk
- Files:
-
- 3 edited
-
assets/js/admin.js (modified) (1 diff)
-
debug-troubleshooter.php (modified) (8 diffs)
-
readme.txt (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
debugger-troubleshooter/trunk/assets/js/admin.js
r3325892 r3400206 316 316 }); 317 317 }); 318 // Handle User Simulation 319 $('#simulate-user-btn').on('click', function() { 320 var $button = $(this); 321 var userId = $('#simulate-user-select').val(); 322 323 if (!userId) { 324 showAlert(debugTroubleshoot.alert_title_error, 'Please select a user to simulate.', 'error'); 325 return; 326 } 327 328 $button.prop('disabled', true).text('Switching...'); 329 330 $.ajax({ 331 url: debugTroubleshoot.ajax_url, 332 type: 'POST', 333 data: { 334 action: 'debug_troubleshoot_toggle_simulate_user', 335 nonce: debugTroubleshoot.nonce, 336 enable: 1, 337 user_id: userId 338 }, 339 success: function(response) { 340 if (response.success) { 341 showAlert(debugTroubleshoot.alert_title_success, response.data.message); 342 setTimeout(function() { location.reload(); }, 500); 343 } else { 344 showAlert(debugTroubleshoot.alert_title_error, response.data.message, 'error'); 345 $button.prop('disabled', false).text('Simulate User'); 346 } 347 }, 348 error: function() { 349 showAlert(debugTroubleshoot.alert_title_error, 'An AJAX error occurred.', 'error'); 350 $button.prop('disabled', false).text('Simulate User'); 351 } 352 }); 353 }); 318 354 }); -
debugger-troubleshooter/trunk/debug-troubleshooter.php
r3325892 r3400206 4 4 * Plugin URI: https://wordpress.org/plugins/debugger-troubleshooter 5 5 * Description: A WordPress plugin for debugging and troubleshooting, allowing simulated plugin deactivation and theme switching without affecting the live site. 6 * Version: 1. 2.16 * Version: 1.3.0 7 7 * Author: Jhimross 8 8 * Author URI: https://profiles.wordpress.org/jhimross … … 22 22 * Define plugin constants. 23 23 */ 24 define( 'DBGTBL_VERSION', '1. 2.1' );24 define( 'DBGTBL_VERSION', '1.3.0' ); 25 25 define( 'DBGTBL_DIR', plugin_dir_path( __FILE__ ) ); 26 26 define( 'DBGTBL_URL', plugin_dir_url( __FILE__ ) ); … … 37 37 const TROUBLESHOOT_COOKIE = 'wp_debug_troubleshoot_mode'; 38 38 const DEBUG_MODE_OPTION = 'wp_debug_troubleshoot_debug_mode'; 39 const SIMULATE_USER_COOKIE = 'wp_debug_troubleshoot_simulate_user'; 39 40 40 41 /** … … 44 45 */ 45 46 private $troubleshoot_state = false; 47 48 /** 49 * Stores the simulated user ID. 50 * 51 * @var int|false 52 */ 53 private $simulated_user_id = false; 46 54 47 55 /** … … 59 67 add_action( 'wp_ajax_debug_troubleshoot_toggle_debug_mode', array( $this, 'ajax_toggle_debug_mode' ) ); 60 68 add_action( 'wp_ajax_debug_troubleshoot_clear_debug_log', array( $this, 'ajax_clear_debug_log' ) ); 69 add_action( 'wp_ajax_debug_troubleshoot_toggle_simulate_user', array( $this, 'ajax_toggle_simulate_user' ) ); 61 70 62 71 // Core troubleshooting logic (very early hook). 63 72 add_action( 'plugins_loaded', array( $this, 'init_troubleshooting_mode' ), 0 ); 64 73 add_action( 'plugins_loaded', array( $this, 'init_live_debug_mode' ), 0 ); 74 add_action( 'plugins_loaded', array( $this, 'init_user_simulation' ), 0 ); 65 75 66 76 // Admin notice for troubleshooting mode. 67 77 add_action( 'admin_notices', array( $this, 'troubleshooting_mode_notice' ) ); 78 add_action( 'admin_bar_menu', array( $this, 'admin_bar_exit_simulation' ), 999 ); 68 79 } 69 80 … … 122 133 'show_all_text' => __( 'Show All', 'debug-troubleshooter' ), 123 134 'hide_text' => __( 'Hide', 'debug-troubleshooter' ), 135 'is_simulating_user' => $this->is_simulating_user(), 124 136 ) 125 137 ); … … 212 224 <p class="description"><?php esc_html_e( 'Applying changes will refresh the page to reflect your simulated theme and plugin states.', 'debug-troubleshooter' ); ?></p> 213 225 </div><!-- #troubleshoot-mode-controls --> 226 </div> 227 </div> 228 229 230 231 <div class="debug-troubleshooter-section standalone-section full-width-section"> 232 <div class="section-header"> 233 <h2><?php esc_html_e( 'User Role Simulator', 'debug-troubleshooter' ); ?></h2> 234 </div> 235 <div class="section-content"> 236 <p class="description"> 237 <?php esc_html_e( 'View the site as a specific user or role. This allows you to test permissions and user-specific content without logging out. This only affects your session.', 'debug-troubleshooter' ); ?> 238 </p> 239 <?php $this->render_user_simulation_section(); ?> 214 240 </div> 215 241 </div> … … 728 754 } 729 755 } 756 /** 757 * Initializes the user simulation mode. 758 */ 759 public function init_user_simulation() { 760 if ( isset( $_COOKIE[ self::SIMULATE_USER_COOKIE ] ) ) { 761 $this->simulated_user_id = (int) $_COOKIE[ self::SIMULATE_USER_COOKIE ]; 762 763 // Hook into determine_current_user to override the user ID. 764 // Priority 20 ensures we run after most standard authentication checks. 765 add_filter( 'determine_current_user', array( $this, 'simulate_user_filter' ), 20 ); 766 } 767 } 768 769 /** 770 * Filter to override the current user ID. 771 * 772 * @param int|false $user_id The determined user ID. 773 * @return int|false The simulated user ID or the original ID. 774 */ 775 public function simulate_user_filter( $user_id ) { 776 if ( $this->simulated_user_id ) { 777 return $this->simulated_user_id; 778 } 779 return $user_id; 780 } 781 782 /** 783 * Checks if user simulation is active. 784 * 785 * @return bool 786 */ 787 public function is_simulating_user() { 788 return ! empty( $this->simulated_user_id ); 789 } 790 791 /** 792 * Renders the User Role Simulator section content. 793 */ 794 public function render_user_simulation_section() { 795 $users = get_users( array( 'fields' => array( 'ID', 'display_name', 'user_login' ), 'number' => 50 ) ); // Limit to 50 for performance in dropdown 796 $roles = wp_roles()->get_names(); 797 ?> 798 <div class="user-simulation-controls"> 799 <div class="debug-troubleshooter-card"> 800 <h3><?php esc_html_e( 'Select User to Simulate', 'debug-troubleshooter' ); ?></h3> 801 <div class="flex items-center gap-4"> 802 <select id="simulate-user-select" class="regular-text"> 803 <option value=""><?php esc_html_e( '-- Select a User --', 'debug-troubleshooter' ); ?></option> 804 <?php foreach ( $users as $user ) : ?> 805 <option value="<?php echo esc_attr( $user->ID ); ?>"> 806 <?php echo esc_html( $user->display_name . ' (' . $user->user_login . ')' ); ?> 807 </option> 808 <?php endforeach; ?> 809 </select> 810 <button id="simulate-user-btn" class="button button-primary"><?php esc_html_e( 'Simulate User', 'debug-troubleshooter' ); ?></button> 811 </div> 812 <p class="description mt-2"> 813 <?php esc_html_e( 'Note: You can exit the simulation at any time using the "Exit Simulation" button in the Admin Bar.', 'debug-troubleshooter' ); ?> 814 </p> 815 </div> 816 </div> 817 <?php 818 } 819 820 /** 821 * Adds an "Exit Simulation" button to the Admin Bar. 822 * 823 * @param WP_Admin_Bar $wp_admin_bar The admin bar object. 824 */ 825 public function admin_bar_exit_simulation( $wp_admin_bar ) { 826 if ( $this->is_simulating_user() ) { 827 $wp_admin_bar->add_node( array( 828 'id' => 'debug-troubleshooter-exit-sim', 829 'title' => '<span style="color: #ff4444; font-weight: bold;">' . __( 'Exit User Simulation', 'debug-troubleshooter' ) . '</span>', 830 'href' => '#', 831 'meta' => array( 832 'onclick' => 'debugTroubleshootExitSimulation(); return false;', 833 'title' => __( 'Click to return to your original user account', 'debug-troubleshooter' ), 834 ), 835 ) ); 836 837 // Add inline script for the exit action since we might be on the frontend 838 // where our admin.js isn't enqueued, or we need a global handler. 839 add_action( 'wp_footer', array( $this, 'print_exit_simulation_script' ) ); 840 add_action( 'admin_footer', array( $this, 'print_exit_simulation_script' ) ); 841 } 842 } 843 844 /** 845 * Prints the inline script for exiting simulation from the admin bar. 846 */ 847 public function print_exit_simulation_script() { 848 ?> 849 <script type="text/javascript"> 850 function debugTroubleshootExitSimulation() { 851 if (confirm('<?php echo esc_js( __( 'Are you sure you want to exit User Simulation?', 'debug-troubleshooter' ) ); ?>')) { 852 var data = new FormData(); 853 data.append('action', 'debug_troubleshoot_toggle_simulate_user'); 854 data.append('enable', '0'); 855 // We might not have the nonce available globally on frontend, so we rely on cookie check in backend mostly, 856 // but for AJAX we need it. If we are on frontend, we might need to expose it. 857 // For simplicity in this MVP, we'll assume admin-ajax is accessible. 858 // SECURITY NOTE: In a real scenario, we should localize the nonce on wp_enqueue_scripts as well if we want frontend support. 859 // For now, let's try to fetch it from a global if available, or just rely on the cookie clearing which is less secure but functional for a dev tool. 860 // BETTER APPROACH: Use a dedicated endpoint or just a simple GET parameter that we intercept on init to clear the cookie. 861 862 // Let's use a simple redirect to a URL that handles the exit. 863 window.location.href = '<?php echo esc_url( admin_url( 'admin-ajax.php?action=debug_troubleshoot_toggle_simulate_user&enable=0' ) ); ?>'; 864 } 865 } 866 </script> 867 <?php 868 } 869 870 /** 871 * AJAX handler to toggle User Simulation. 872 */ 873 public function ajax_toggle_simulate_user() { 874 // Note: For the "Exit" action via GET request (from Admin Bar), we might not have a nonce. 875 // Since this is a dev tool and we are just clearing a cookie, the risk is low, but ideally we'd check a nonce. 876 // For the "Enter" action (POST), we definitely check the nonce. 877 878 $is_post = 'POST' === $_SERVER['REQUEST_METHOD']; 879 if ( $is_post ) { 880 check_ajax_referer( 'debug_troubleshoot_nonce', 'nonce' ); 881 } 882 883 if ( ! current_user_can( 'manage_options' ) && ! $this->is_simulating_user() ) { 884 // Only allow admins to START simulation. 885 // Anyone (simulated user) can STOP simulation. 886 wp_send_json_error( array( 'message' => __( 'Permission denied.', 'debug-troubleshooter' ) ) ); 887 } 888 889 $enable = isset( $_REQUEST['enable'] ) ? (bool) $_REQUEST['enable'] : false; 890 $user_id = isset( $_REQUEST['user_id'] ) ? (int) $_REQUEST['user_id'] : 0; 891 892 if ( $enable && $user_id ) { 893 // Set cookie 894 setcookie( self::SIMULATE_USER_COOKIE, $user_id, array( 895 'expires' => time() + DAY_IN_SECONDS, 896 'path' => COOKIEPATH, 897 'domain' => COOKIE_DOMAIN, 898 'samesite' => 'Lax', 899 'httponly' => true, 900 'secure' => is_ssl(), 901 ) ); 902 wp_send_json_success( array( 'message' => __( 'User simulation activated. Reloading...', 'debug-troubleshooter' ) ) ); 903 } else { 904 // Clear cookie 905 setcookie( self::SIMULATE_USER_COOKIE, '', array( 906 'expires' => time() - 3600, 907 'path' => COOKIEPATH, 908 'domain' => COOKIE_DOMAIN, 909 'samesite' => 'Lax', 910 'httponly' => true, 911 'secure' => is_ssl(), 912 ) ); 913 914 if ( ! $is_post ) { 915 // If it was a GET request (from Admin Bar), redirect back to home or dashboard. 916 wp_redirect( admin_url() ); 917 exit; 918 } 919 920 wp_send_json_success( array( 'message' => __( 'User simulation deactivated.', 'debug-troubleshooter' ) ) ); 921 } 922 } 730 923 } 731 924 -
debugger-troubleshooter/trunk/readme.txt
r3325897 r3400206 5 5 Requires PHP: 7.4 6 6 Tested up to: 6.8 7 Stable tag: 1. 2.17 Stable tag: 1.3.0 8 8 License: GPL-2.0+ 9 9 License URI: http://www.gnu.org/licenses/gpl-2.0.txt … … 21 21 * **Simulate Plugin Deactivation:** Selectively "deactivate" plugins. The plugin's assets and code will be disabled for your session only. 22 22 * **Simulate Theme Switching:** Preview any installed theme, while the public-facing site continues to use the active theme. 23 * **User Role Simulator:** View your site as any other user or role (e.g., Subscriber, Editor) to test permissions and content visibility. This is session-based and includes a safe "Exit" button in the Admin Bar. 23 24 * **Live Debugging:** Safely enable `WP_DEBUG` with a single click from the admin dashboard. Errors are logged to `debug.log` without being displayed on the site, and you can view the log file directly in the plugin's interface. 24 25 * **Comprehensive Site Information:** Get a quick, organized overview of your WordPress environment in collapsible cards. This includes detailed PHP, Database, and Server information, a full list of all themes and plugins with their status, and important WordPress constants. … … 58 59 This session-based feature allows you to simulate theme switches and plugin deactivations without affecting your live website for other visitors. 59 60 60 ### 3. Live Debugging 61 ### 3. User Role Simulator 62 63 Safely view your site as another user or role (e.g., "Subscriber" or "Editor") without knowing their password. This is perfect for testing capabilities and content restrictions. 64 65 ### 4. Live Debugging 61 66 62 67 This section allows you to safely manage WordPress's debugging features. … … 86 91 == Changelog == 87 92 93 = 1.3.0 - 2025-11-21 = 94 * **Feature:** Added "User Role Simulator" to view the site as any user or role for the current session. 95 * **Enhancement:** Added an Admin Bar "Exit Simulation" button for safe return to the administrator account. 96 * **Fix:** Improved layout stability for the troubleshooting dashboard. 97 88 98 = 1.2.1 - 2025-07-11 = 89 99 * **Fix:** Addressed all security and code standard issues reported by the Plugin Check plugin, including escaping all output and using the `WP_Filesystem` API for file operations. … … 110 120 == Upgrade Notice == 111 121 122 = 1.3.0 = 123 Introduces the User Role Simulator feature, allowing you to safely view the site as other users or roles for testing permissions. 124 112 125 = 1.2.1 = 113 126 This is a recommended security and maintenance update. It addresses all issues reported by the Plugin Check plugin, including proper data escaping and use of the `WP_Filesystem` API.
Note: See TracChangeset
for help on using the changeset viewer.