feat: AutoBooking initial commit — PHP WordPress Plugin (REST API, wpdb, WP_User_Query)
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
/**
|
||||
* Plugin Name: AutoBooking Nav Guard
|
||||
* Version: 1.1.0
|
||||
* Description: Protege páginas por token de navegación. Redirige al login/home si no hay token válido.
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/* ── Páginas protegidas: destino => URL ────────────────────────────── */
|
||||
define('AB_NAV_PAGES', [
|
||||
'driver' => '/driver-dashboard-2/',
|
||||
'passenger' => '/customer-dashboard/',
|
||||
'corporate' => '/corporate-dashboard/',
|
||||
]);
|
||||
|
||||
/* ── Session ───────────────────────────────────────────────────────── */
|
||||
add_action('init', function () {
|
||||
if (!session_id() && !headers_sent()) session_start();
|
||||
}, 1);
|
||||
|
||||
/* ── Roles permitidos por destino ───────────────────────────────────── */
|
||||
function ab_nav_allowed_roles() {
|
||||
return [
|
||||
'driver' => ['driver', 'driver_pending'],
|
||||
'passenger' => ['subscriber', 'customer'],
|
||||
'corporate' => ['corporate_admin'],
|
||||
];
|
||||
}
|
||||
|
||||
/* ── Protección via template_redirect (antes de cualquier output) ──── */
|
||||
add_action('template_redirect', function () {
|
||||
global $post;
|
||||
if (!$post) return;
|
||||
|
||||
$dest = get_post_meta($post->ID, '_ab_nav_page', true);
|
||||
if (!$dest) return;
|
||||
|
||||
if (!is_user_logged_in()) {
|
||||
wp_redirect(wp_login_url(get_permalink()));
|
||||
exit;
|
||||
}
|
||||
|
||||
$uid = get_current_user_id();
|
||||
$user = wp_get_current_user();
|
||||
$roles = (array) $user->roles;
|
||||
|
||||
// Admins y manage_autobooking: acceso siempre sin token
|
||||
if (in_array('administrator', $roles) || user_can($uid, 'manage_autobooking')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!session_id()) session_start();
|
||||
$token = $_SESSION['ab_nav'][$dest] ?? null;
|
||||
|
||||
// Token válido → pasar
|
||||
if ($token && $token['user'] === $uid && $token['exp'] >= time()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Sin token pero tiene el rol correcto → auto-token y pasar
|
||||
$allowed = ab_nav_allowed_roles()[$dest] ?? [];
|
||||
if (array_intersect($roles, $allowed)) {
|
||||
$_SESSION['ab_nav'][$dest] = ['user' => $uid, 'exp' => time() + 300];
|
||||
return;
|
||||
}
|
||||
|
||||
// Rol incorrecto para esta página → home
|
||||
wp_redirect(home_url('/'));
|
||||
exit;
|
||||
});
|
||||
|
||||
/* ── Auto-token en login → acceso directo al dashboard ─────────────── */
|
||||
add_action('wp_login', function ($login, $user) {
|
||||
if (!session_id()) session_start();
|
||||
$roles = (array) $user->roles;
|
||||
$exp = time() + 300;
|
||||
|
||||
$role_map = [
|
||||
'driver' => 'driver',
|
||||
'driver_pending' => 'driver',
|
||||
'subscriber' => 'passenger',
|
||||
'customer' => 'passenger',
|
||||
'corporate_admin' => 'corporate',
|
||||
];
|
||||
foreach ($role_map as $role => $dest) {
|
||||
if (in_array($role, $roles, true)) {
|
||||
$_SESSION['ab_nav'][$dest] = ['user' => $user->ID, 'exp' => $exp];
|
||||
}
|
||||
}
|
||||
if (user_can($user->ID, 'manage_autobooking') || in_array('administrator', $roles, true)) {
|
||||
foreach (array_keys(AB_NAV_PAGES) as $dest) {
|
||||
$_SESSION['ab_nav'][$dest] = ['user' => $user->ID, 'exp' => $exp];
|
||||
}
|
||||
}
|
||||
}, 10, 2);
|
||||
|
||||
/* ── Redirect post-login al dashboard según rol ────────────────────── */
|
||||
add_filter('login_redirect', function ($redirect, $request, $user) {
|
||||
if (is_wp_error($user)) return $redirect;
|
||||
$roles = (array) $user->roles;
|
||||
|
||||
if (in_array('driver', $roles) || in_array('driver_pending', $roles))
|
||||
return home_url(AB_NAV_PAGES['driver']);
|
||||
if (in_array('corporate_admin', $roles))
|
||||
return home_url(AB_NAV_PAGES['corporate']);
|
||||
if (in_array('subscriber', $roles) || in_array('customer', $roles))
|
||||
return home_url(AB_NAV_PAGES['passenger']);
|
||||
|
||||
return $redirect;
|
||||
}, 10, 3);
|
||||
|
||||
/* ── REST: generar token desde JS ───────────────────────────────────── */
|
||||
add_action('rest_api_init', function () {
|
||||
register_rest_route('ab/v1', '/nav-token', [
|
||||
'methods' => 'POST',
|
||||
'callback' => function (WP_REST_Request $req) {
|
||||
$dest = sanitize_text_field($req->get_param('destination'));
|
||||
if (!$dest) return new WP_Error('missing', 'destination required', ['status' => 400]);
|
||||
if (!session_id()) session_start();
|
||||
$_SESSION['ab_nav'][$dest] = ['user' => get_current_user_id(), 'exp' => time() + 300];
|
||||
return rest_ensure_response(['ok' => true, 'destination' => $dest]);
|
||||
},
|
||||
'permission_callback' => fn() => is_user_logged_in(),
|
||||
]);
|
||||
});
|
||||
|
||||
/* ── JS helper global ───────────────────────────────────────────────── */
|
||||
add_action('wp_footer', function () {
|
||||
if (!is_user_logged_in()) return;
|
||||
echo '<script>window.ab_nav_go=function(dest,url){'
|
||||
. 'fetch(' . json_encode(rest_url('ab/v1/nav-token')) . ','
|
||||
. '{method:"POST",headers:{"Content-Type":"application/json","X-WP-Nonce":' . json_encode(wp_create_nonce('wp_rest')) . '},'
|
||||
. 'body:JSON.stringify({destination:dest})})'
|
||||
. '.then(r=>r.json()).then(d=>{if(d.ok)window.location.href=url||"/"});'
|
||||
. '};</script>';
|
||||
});
|
||||
|
||||
/* ── Limpieza de tokens expirados ───────────────────────────────────── */
|
||||
add_action('init', function () {
|
||||
if (!session_id() || empty($_SESSION['ab_nav'])) return;
|
||||
$now = time();
|
||||
foreach ($_SESSION['ab_nav'] as $k => $d) {
|
||||
if ($d['exp'] < $now) unset($_SESSION['ab_nav'][$k]);
|
||||
}
|
||||
}, 5);
|
||||
Reference in New Issue
Block a user