upskill-event-manager/includes/class-hvac-access-control.php
bengizmo 81190ec4a0 Fix legacy URL redirects being intercepted by access control
- Added is_legacy_url() check in access control to allow redirects to happen first
- Legacy URLs like /hvac-dashboard/ now properly redirect to /trainer/dashboard/
- Prevents authentication check from blocking legacy URL redirects

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-28 19:45:43 -03:00

288 lines
No EOL
8.6 KiB
PHP

<?php
/**
* HVAC Community Events - Access Control
*
* Handles page access restrictions based on trainer status
*
* @package HVAC_Community_Events
* @since 1.0.0
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class HVAC_Access_Control
*
* Manages access control for trainer pages based on account status
*/
class HVAC_Access_Control {
/**
* Pages that require authentication but no specific status
*/
private static $public_pages = array(
'trainer/registration',
'registration-pending',
'community-login',
'training-login',
'trainer-account-pending',
'trainer-account-disabled',
);
/**
* Pages that require trainer to be active or inactive
*/
private static $trainer_pages = array(
'trainer/dashboard',
'trainer/event/manage',
'trainer/generate-certificates',
'trainer/certificate-reports',
'trainer/event-summary',
'trainer/email-attendees',
'trainer/communication-templates',
'edit-profile',
);
/**
* Constructor
*/
public function __construct() {
// Hook into template_redirect for access control
add_action( 'template_redirect', array( $this, 'check_page_access' ), 10 );
}
/**
* Check page access based on user status
*/
public function check_page_access() {
// Get current page path
$current_path = trim( parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH ), '/' );
// Check if this is a legacy URL that will be redirected
if ( $this->is_legacy_url( $current_path ) ) {
// Allow the redirect to happen first
return;
}
// Check if this is a public page
if ( $this->is_public_page( $current_path ) ) {
return;
}
// Check if this is a trainer page
if ( $this->is_trainer_page( $current_path ) ) {
$this->check_trainer_access( $current_path );
}
}
/**
* Check if current URL is a legacy URL that should be redirected
*
* @param string $path Current page path
* @return bool
*/
private function is_legacy_url( $path ) {
// Get the route manager instance
if ( ! class_exists( 'HVAC_Route_Manager' ) ) {
return false;
}
$route_manager = HVAC_Route_Manager::instance();
// Check if this path needs a redirect
return $route_manager->needs_redirect( $path ) !== false;
}
/**
* Check if current page is public
*
* @param string $path Current page path
* @return bool
*/
private function is_public_page( $path ) {
foreach ( self::$public_pages as $public_page ) {
if ( $path === $public_page || strpos( $path, $public_page ) === 0 ) {
return true;
}
}
return false;
}
/**
* Check if current page is a trainer page
*
* @param string $path Current page path
* @return bool
*/
private function is_trainer_page( $path ) {
foreach ( self::$trainer_pages as $trainer_page ) {
if ( $path === $trainer_page || strpos( $path, $trainer_page ) === 0 ) {
return true;
}
}
// Also check for pages that start with 'trainer/'
if ( strpos( $path, 'trainer/' ) === 0 ) {
return true;
}
return false;
}
/**
* Check trainer access to protected pages
*
* @param string $path Current page path
*/
private function check_trainer_access( $path ) {
// First check if user is logged in
if ( ! is_user_logged_in() ) {
wp_safe_redirect( home_url( '/community-login/' ) );
exit;
}
$user_id = get_current_user_id();
$user = wp_get_current_user();
// Allow administrators full access
if ( current_user_can( 'manage_options' ) ) {
return;
}
// Check if user has trainer role
if ( ! in_array( 'hvac_trainer', $user->roles ) && ! in_array( 'hvac_master_trainer', $user->roles ) ) {
// Not a trainer, show access denied
$this->show_access_denied();
return;
}
// Get trainer status
if ( ! class_exists( 'HVAC_Trainer_Status' ) ) {
require_once HVAC_PLUGIN_DIR . 'includes/class-hvac-trainer-status.php';
}
$status = HVAC_Trainer_Status::get_trainer_status( $user_id );
// Handle based on status
switch ( $status ) {
case HVAC_Trainer_Status::STATUS_PENDING:
// Redirect to pending page
if ( $path !== 'trainer-account-pending' && strpos( $path, 'trainer-account-pending' ) !== 0 ) {
wp_safe_redirect( home_url( '/trainer-account-pending/' ) );
exit;
}
break;
case HVAC_Trainer_Status::STATUS_DISABLED:
// Redirect to disabled page
if ( $path !== 'trainer-account-disabled' && strpos( $path, 'trainer-account-disabled' ) !== 0 ) {
wp_safe_redirect( home_url( '/trainer-account-disabled/' ) );
exit;
}
break;
case HVAC_Trainer_Status::STATUS_APPROVED:
case HVAC_Trainer_Status::STATUS_ACTIVE:
case HVAC_Trainer_Status::STATUS_INACTIVE:
// Allow access
break;
default:
// Unknown status, treat as pending
wp_safe_redirect( home_url( '/trainer-account-pending/' ) );
exit;
}
}
/**
* Show access denied page
*/
private function show_access_denied() {
get_header();
?>
<style>
.hvac-access-denied {
max-width: 600px;
margin: 60px auto;
padding: 40px;
text-align: center;
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.hvac-access-denied h1 {
color: #d63638;
margin-bottom: 20px;
}
.hvac-access-denied p {
margin-bottom: 15px;
color: #666;
line-height: 1.6;
}
.hvac-access-denied .button {
background: #0073aa;
color: white;
padding: 12px 24px;
text-decoration: none;
border-radius: 4px;
display: inline-block;
margin-top: 20px;
}
.hvac-access-denied .button:hover {
background: #005a87;
color: white;
}
</style>
<div class="content-area primary ast-container">
<main class="site-main">
<div class="hvac-access-denied">
<h1><?php _e( 'Access Denied', 'hvac-community-events' ); ?></h1>
<p><?php _e( 'You do not have permission to access this page.', 'hvac-community-events' ); ?></p>
<p><?php _e( 'If you believe this is an error, please contact an administrator.', 'hvac-community-events' ); ?></p>
<a href="<?php echo esc_url( home_url() ); ?>" class="button"><?php _e( 'Return to Home', 'hvac-community-events' ); ?></a>
</div>
</main>
</div>
<?php
get_footer();
exit;
}
/**
* Add custom pages that require specific access
*
* @param string $page Page path
* @param string $type 'public' or 'trainer'
*/
public static function add_custom_page( $page, $type = 'trainer' ) {
if ( $type === 'public' ) {
self::$public_pages[] = $page;
} else {
self::$trainer_pages[] = $page;
}
}
/**
* Remove a page from access control
*
* @param string $page Page path
* @param string $type 'public' or 'trainer'
*/
public static function remove_custom_page( $page, $type = 'trainer' ) {
if ( $type === 'public' ) {
$key = array_search( $page, self::$public_pages );
if ( $key !== false ) {
unset( self::$public_pages[$key] );
}
} else {
$key = array_search( $page, self::$trainer_pages );
if ( $key !== false ) {
unset( self::$trainer_pages[$key] );
}
}
}
}