plugin_name = $plugin_name;
$this->version = $version;
// Initialize auth manager with 30-minute timeout
if ( class_exists( 'Metasync_Auth_Manager' ) ) {
$this->auth = new Metasync_Auth_Manager( 'dev_panel', 1800 );
}
// Register hooks
add_action( 'admin_menu', array( $this, 'add_dev_panel_menu' ) );
add_action( 'admin_notices', array( $this, 'display_staging_mode_banner' ) );
add_action( 'wp_ajax_metasync_switch_endpoints', array( $this, 'ajax_switch_endpoints' ) );
add_action( 'wp_ajax_metasync_update_dev_password', array( $this, 'ajax_update_dev_password' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
}
/**
* Register the developer panel menu (hidden from menu, accessible via URL).
*/
public function add_dev_panel_menu() {
// Add hidden submenu page (no parent = hidden from menu)
// Accessible to admins only (developer tools)
add_submenu_page(
null,
'Developer Tools',
'Developer Tools',
'manage_options',
Metasync_Admin::$page_slug . '-dev-tools',
array( $this, 'render_dev_panel_page' )
);
}
/**
* Display staging mode banner on all admin pages.
*/
public function display_staging_mode_banner() {
// Only show if staging mode is active
if ( ! Metasync_Endpoint_Manager::is_staging_mode() ) {
return;
}
// Only show in admin area
if ( ! is_admin() ) {
return;
}
// Don't show on dev panel page itself
$current_page = isset( $_GET['page'] ) ? sanitize_text_field( $_GET['page'] ) : '';
if ( $current_page === Metasync_Admin::$page_slug . '-dev-tools' ) {
return;
}
$dev_panel_url = admin_url( 'admin.php?page=' . Metasync_Admin::$page_slug . '-dev-tools' );
?>
STAGING MODE ACTIVE
All API endpoints are currently pointing to STAGING servers. This is intended for development and testing only.
Open Developer Tools
render_password_setup_form();
return;
}
// Check authentication
if ( ! $this->auth || ! $this->auth->has_access() ) {
$this->render_password_form();
return;
}
// User is authenticated - show endpoint switcher
$this->render_endpoint_switcher();
}
/**
* Render the password setup form (first-time setup).
*/
private function render_password_setup_form() {
$setup_error = '';
// Handle password setup submission
if ( isset( $_POST['dev_panel_setup_submit'] ) ) {
if ( wp_verify_nonce( $_POST['dev_panel_setup_nonce'], 'metasync_dev_panel_setup' ) ) {
$new_password = sanitize_text_field( $_POST['dev_panel_new_password'] );
$confirm_password = sanitize_text_field( $_POST['dev_panel_confirm_password'] );
if ( empty( $new_password ) ) {
$setup_error = 'Password cannot be empty.';
} elseif ( $new_password !== $confirm_password ) {
$setup_error = 'Passwords do not match.';
} elseif ( strlen( $new_password ) < 6 ) {
$setup_error = 'Password must be at least 6 characters long.';
} else {
$result = update_option( self::PASSWORD_OPTION, $new_password );
if ( $result ) {
// Grant access immediately
if ( $this->auth ) {
$this->auth->grant_transient_access();
}
// Refresh to show authenticated state - add timestamp to prevent caching
wp_safe_redirect( add_query_arg( 'setup', 'complete', $_SERVER['REQUEST_URI'] ) );
exit;
} else {
$setup_error = 'Failed to save password. Please try again.';
}
}
}
}
?>
auth && $this->auth->verify_and_grant( $submitted_password, $saved_password, false ) ) {
// Refresh page to show authenticated state - add timestamp to prevent caching
wp_safe_redirect( add_query_arg( 'login', 'success', $_SERVER['REQUEST_URI'] ) );
exit;
} else {
$password_error = 'Incorrect password. Please try again.';
}
}
}
?>
auth ) {
$this->auth->revoke_access();
}
wp_safe_redirect( remove_query_arg( array( 'setup', 'login' ), $_SERVER['REQUEST_URI'] ) );
exit;
}
}
?>
'Insufficient permissions' ) );
return;
}
// Verify authentication
if ( ! $this->auth || ! $this->auth->has_access() ) {
wp_send_json_error( array( 'message' => 'Authentication required' ) );
return;
}
// Get and validate mode
$mode = isset( $_POST['endpoint_mode'] ) ? sanitize_text_field( $_POST['endpoint_mode'] ) : '';
if ( ! in_array( $mode, array( 'production', 'staging' ), true ) ) {
wp_send_json_error( array( 'message' => 'Invalid mode' ) );
return;
}
// Switch mode
$result = Metasync_Endpoint_Manager::set_mode( $mode );
if ( $result ) {
wp_send_json_success(
array(
'message' => "Successfully switched to {$mode} mode",
'mode' => $mode,
'endpoints' => Metasync_Endpoint_Manager::get_all_endpoints(),
)
);
} else {
wp_send_json_error( array( 'message' => 'Failed to switch endpoints' ) );
}
}
/**
* AJAX handler for updating dev panel password.
*/
public function ajax_update_dev_password() {
// Verify nonce
check_ajax_referer( 'metasync_update_dev_password', 'nonce' );
// Verify permissions (matches main plugin's access control)
if ( ! Metasync::current_user_has_plugin_access() ) {
wp_send_json_error( array( 'message' => 'Insufficient permissions' ) );
return;
}
// Verify authentication
if ( ! $this->auth || ! $this->auth->has_access() ) {
wp_send_json_error( array( 'message' => 'Authentication required' ) );
return;
}
// Get new password
$new_password = isset( $_POST['dev_panel_password'] ) ? sanitize_text_field( $_POST['dev_panel_password'] ) : '';
if ( empty( $new_password ) ) {
wp_send_json_error( array( 'message' => 'Password cannot be empty' ) );
return;
}
if ( strlen( $new_password ) < 6 ) {
wp_send_json_error( array( 'message' => 'Password must be at least 6 characters long' ) );
return;
}
$result = update_option( self::PASSWORD_OPTION, $new_password );
if ( $result ) {
wp_send_json_success( array( 'message' => 'Password updated successfully' ) );
} else {
wp_send_json_error( array( 'message' => 'Failed to update password' ) );
}
}
}