Plugin Directory

Changeset 3400206


Ignore:
Timestamp:
11/21/2025 06:43:59 AM (4 months ago)
Author:
jhimross
Message:

version 1.3.0

Location:
debugger-troubleshooter/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • debugger-troubleshooter/trunk/assets/js/admin.js

    r3325892 r3400206  
    316316        });
    317317    });
     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    });
    318354});
  • debugger-troubleshooter/trunk/debug-troubleshooter.php

    r3325892 r3400206  
    44 * Plugin URI:        https://wordpress.org/plugins/debugger-troubleshooter
    55 * Description:       A WordPress plugin for debugging and troubleshooting, allowing simulated plugin deactivation and theme switching without affecting the live site.
    6  * Version:           1.2.1
     6 * Version:           1.3.0
    77 * Author:            Jhimross
    88 * Author URI:        https://profiles.wordpress.org/jhimross
     
    2222 * Define plugin constants.
    2323 */
    24 define( 'DBGTBL_VERSION', '1.2.1' );
     24define( 'DBGTBL_VERSION', '1.3.0' );
    2525define( 'DBGTBL_DIR', plugin_dir_path( __FILE__ ) );
    2626define( 'DBGTBL_URL', plugin_dir_url( __FILE__ ) );
     
    3737    const TROUBLESHOOT_COOKIE = 'wp_debug_troubleshoot_mode';
    3838    const DEBUG_MODE_OPTION   = 'wp_debug_troubleshoot_debug_mode';
     39    const SIMULATE_USER_COOKIE = 'wp_debug_troubleshoot_simulate_user';
    3940
    4041    /**
     
    4445     */
    4546    private $troubleshoot_state = false;
     47
     48    /**
     49     * Stores the simulated user ID.
     50     *
     51     * @var int|false
     52     */
     53    private $simulated_user_id = false;
    4654
    4755    /**
     
    5967        add_action( 'wp_ajax_debug_troubleshoot_toggle_debug_mode', array( $this, 'ajax_toggle_debug_mode' ) );
    6068        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' ) );
    6170
    6271        // Core troubleshooting logic (very early hook).
    6372        add_action( 'plugins_loaded', array( $this, 'init_troubleshooting_mode' ), 0 );
    6473        add_action( 'plugins_loaded', array( $this, 'init_live_debug_mode' ), 0 );
     74        add_action( 'plugins_loaded', array( $this, 'init_user_simulation' ), 0 );
    6575
    6676        // Admin notice for troubleshooting mode.
    6777        add_action( 'admin_notices', array( $this, 'troubleshooting_mode_notice' ) );
     78        add_action( 'admin_bar_menu', array( $this, 'admin_bar_exit_simulation' ), 999 );
    6879    }
    6980
     
    122133                'show_all_text'       => __( 'Show All', 'debug-troubleshooter' ),
    123134                'hide_text'           => __( 'Hide', 'debug-troubleshooter' ),
     135                'is_simulating_user'  => $this->is_simulating_user(),
    124136            )
    125137        );
     
    212224                            <p class="description"><?php esc_html_e( 'Applying changes will refresh the page to reflect your simulated theme and plugin states.', 'debug-troubleshooter' ); ?></p>
    213225                        </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(); ?>
    214240                    </div>
    215241                </div>
     
    728754        }
    729755    }
     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    }
    730923}
    731924
  • debugger-troubleshooter/trunk/readme.txt

    r3325897 r3400206  
    55Requires PHP: 7.4
    66Tested up to: 6.8
    7 Stable tag: 1.2.1
     7Stable tag: 1.3.0
    88License: GPL-2.0+
    99License URI: http://www.gnu.org/licenses/gpl-2.0.txt
     
    2121    * **Simulate Plugin Deactivation:** Selectively "deactivate" plugins. The plugin's assets and code will be disabled for your session only.
    2222    * **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.
    2324* **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.
    2425* **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.
     
    5859This session-based feature allows you to simulate theme switches and plugin deactivations without affecting your live website for other visitors.
    5960
    60 ### 3. Live Debugging
     61### 3. User Role Simulator
     62
     63Safely 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
    6166
    6267This section allows you to safely manage WordPress's debugging features.
     
    8691== Changelog ==
    8792
     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
    8898= 1.2.1 - 2025-07-11 =
    8999* **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.
     
    110120== Upgrade Notice ==
    111121
     122= 1.3.0 =
     123Introduces the User Role Simulator feature, allowing you to safely view the site as other users or roles for testing permissions.
     124
    112125= 1.2.1 =
    113126This 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.