Refactor event access management by replacing SQL views with inline queries

This commit removes the deprecated SQL views `v_eve_acces_actif` and `v_eve_acces_permissions`, replacing them with inline SQL queries in the PHP code. This change avoids issues with non-copiable DEFINER attributes in views and enhances the flexibility of access management. The new functions `fxEveAccesActifBody`, `fxEveAccesActifSql`, and `fxEveAccesPermSql` are introduced to encapsulate the SQL logic directly within the application, improving maintainability and performance.
This commit is contained in:
2026-06-25 18:24:39 -04:00
parent 683e2d69d0
commit 953775d9ca
5 changed files with 184 additions and 142 deletions

View File

@ -26,6 +26,48 @@ function fxEveAccesIsEnabled()
return $blnEnabled;
}
/**
* Corps SELECT des acces actifs (remplace l'ancienne vue v_eve_acces_actif).
* Pas de vue stockee : evite le DEFINER non copiable par Navicat / releve.
*/
function fxEveAccesActifBody()
{
return "SELECT ea.ea_id, ea.com_id, ea.eve_id, ea.role_id,
r.role_code, r.role_label_fr, r.role_label_en,
ea.ea_statut, ea.ea_expires_at, ea.ea_expire_days,
ea.ea_granted_by, ea.ea_created_at
FROM inscriptions_eve_acces ea
INNER JOIN inscriptions_eve_roles r
ON r.role_id = ea.role_id AND r.role_actif = 1
WHERE ea.ea_statut = 'actif'
AND (ea.ea_expires_at IS NULL OR ea.ea_expires_at > NOW())";
}
/** Sous-requete aliasee, equivalente a l'ancienne vue v_eve_acces_actif. */
function fxEveAccesActifSql()
{
return "(" . fxEveAccesActifBody() . ") v_eve_acces_actif";
}
/**
* Sous-requete aliasee, equivalente a l'ancienne vue v_eve_acces_permissions
* (kits via roles + permissions extra individuelles).
*/
function fxEveAccesPermSql()
{
return "((SELECT v.ea_id, v.com_id, v.eve_id, v.role_id, v.role_code,
erp.perm_key, p.perm_group, p.perm_scope, p.perm_label_fr, p.perm_phase
FROM (" . fxEveAccesActifBody() . ") v
INNER JOIN inscriptions_eve_role_permissions erp ON erp.role_id = v.role_id
INNER JOIN inscriptions_eve_permissions p ON p.perm_key = erp.perm_key AND p.perm_actif = 1)
UNION
(SELECT NULL AS ea_id, ae.com_id, ae.eve_id, NULL AS role_id, 'extra' AS role_code,
ae.perm_key, p.perm_group, p.perm_scope, p.perm_label_fr, p.perm_phase
FROM inscriptions_eve_acces_extra ae
INNER JOIN inscriptions_eve_permissions p ON p.perm_key = ae.perm_key AND p.perm_actif = 1
WHERE ae.ae_statut = 'actif')) v_eve_acces_permissions";
}
function fxEveAccesGetRoles($blnActifOnly = true)
{
global $objDatabase;
@ -76,7 +118,7 @@ function fxEveAccesComHasV2($intComId)
return false;
}
$sql = "SELECT COUNT(*) FROM v_eve_acces_actif WHERE com_id = " . intval($intComId);
$sql = "SELECT COUNT(*) FROM " . fxEveAccesActifSql() . " WHERE com_id = " . intval($intComId);
$intNb = $objDatabase->fxGetVar($sql);
return ($intNb != null && intval($intNb) > 0);
@ -90,7 +132,7 @@ function fxEveAccesComHasV2ForEvent($intComId, $intEveId)
return false;
}
$sql = "SELECT COUNT(*) FROM v_eve_acces_actif
$sql = "SELECT COUNT(*) FROM " . fxEveAccesActifSql() . "
WHERE com_id = " . intval($intComId) . "
AND eve_id = " . intval($intEveId);
$intNb = $objDatabase->fxGetVar($sql);
@ -106,7 +148,7 @@ function fxEveAccesGetEventIds($intComId)
return array();
}
$sql = "SELECT eve_id FROM v_eve_acces_actif WHERE com_id = " . intval($intComId);
$sql = "SELECT eve_id FROM " . fxEveAccesActifSql() . " WHERE com_id = " . intval($intComId);
$tab = $objDatabase->fxGetResults($sql);
$arrIds = array();
@ -132,7 +174,7 @@ function fxEveAccesHasInscrMobileWebAccess($intComId, $intEveId)
return false;
}
$sql = "SELECT COUNT(*) FROM v_eve_acces_permissions
$sql = "SELECT COUNT(*) FROM " . fxEveAccesPermSql() . "
WHERE com_id = " . intval($intComId) . "
AND eve_id = " . intval($intEveId) . "
AND perm_key LIKE 'inscriptions_mobile.%'";
@ -149,7 +191,7 @@ function fxEveAccesGetEventIdsWithInscrMobileAccess($intComId)
return array();
}
$sql = "SELECT DISTINCT eve_id FROM v_eve_acces_permissions
$sql = "SELECT DISTINCT eve_id FROM " . fxEveAccesPermSql() . "
WHERE com_id = " . intval($intComId) . "
AND (
perm_key IN ('registrations.view', 'inscriptions_mobile.view')
@ -176,7 +218,7 @@ function fxEveAccesHasPermission($intComId, $intEveId, $strPermKey)
return false;
}
$sql = "SELECT COUNT(*) FROM v_eve_acces_permissions
$sql = "SELECT COUNT(*) FROM " . fxEveAccesPermSql() . "
WHERE com_id = " . intval($intComId) . "
AND eve_id = " . intval($intEveId) . "
AND perm_key = '" . $objDatabase->fxEscape($strPermKey) . "'";
@ -198,7 +240,7 @@ function fxEveAccesHasAnyPermission($intComId, $intEveId, $arrPermKeys)
$arrEsc[] = "'" . $objDatabase->fxEscape($strKey) . "'";
}
$sql = "SELECT COUNT(*) FROM v_eve_acces_permissions
$sql = "SELECT COUNT(*) FROM " . fxEveAccesPermSql() . "
WHERE com_id = " . intval($intComId) . "
AND eve_id = " . intval($intEveId) . "
AND perm_key IN (" . implode(',', $arrEsc) . ")";
@ -220,7 +262,7 @@ function fxEveAccesGetEventIdsWithAnyPermission($intComId, $arrPermKeys)
$arrEsc[] = "'" . $objDatabase->fxEscape($strKey) . "'";
}
$sql = "SELECT DISTINCT eve_id FROM v_eve_acces_permissions
$sql = "SELECT DISTINCT eve_id FROM " . fxEveAccesPermSql() . "
WHERE com_id = " . intval($intComId) . "
AND perm_key IN (" . implode(',', $arrEsc) . ")
ORDER BY eve_id ASC";
@ -245,7 +287,7 @@ function fxEveAccesCanQrTest($intComId)
global $objDatabase;
$sql = "SELECT COUNT(*) FROM v_eve_acces_permissions
$sql = "SELECT COUNT(*) FROM " . fxEveAccesPermSql() . "
WHERE com_id = " . intval($intComId) . "
AND perm_key = 'tools.qr_test'";
$intNb = $objDatabase->fxGetVar($sql);
@ -609,7 +651,7 @@ function fxEveAccesGetPermissionsForComEvent($intComId, $intEveId)
}
$sql = "SELECT perm_key, perm_group, perm_label_fr
FROM v_eve_acces_permissions
FROM " . fxEveAccesPermSql() . "
WHERE com_id = " . intval($intComId) . "
AND eve_id = " . intval($intEveId) . "
ORDER BY perm_group, perm_key";

View File

@ -0,0 +1,26 @@
/* ------------------------------------------------------------------
MSIN — Suppression des vues acces v2
------------------------------------------------------------------
Les vues v_eve_acces_actif / v_eve_acces_permissions portaient un DEFINER
(compte@IP) que Navicat recopie tel quel et que MySQL refuse de recreer
sur un autre serveur / compte sans privilege SUPER (erreur 1227).
Resultat : la copie Navicat et la restauration sur la releve plantaient.
La logique de ces vues est desormais integree en sous-requetes dans le
code PHP (php/inc_fx_eve_acces.php et v3_ci4/app/Libraries/EventAccess.php).
On peut donc supprimer les vues sans rien casser : le module acces v2
continue de fonctionner a l'identique.
A executer sur CHAQUE base concernee (prod, preprod, releve, dev) :
- selectionner la base, puis lancer ce script.
Aucune donnee n'est touchee : seules 2 vues sont supprimees.
------------------------------------------------------------------ */
DROP VIEW IF EXISTS `v_eve_acces_permissions`;
DROP VIEW IF EXISTS `v_eve_acces_actif`;
/* Verification : doit retourner 0 ligne. */
SELECT TABLE_NAME
FROM information_schema.VIEWS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME IN ('v_eve_acces_actif', 'v_eve_acces_permissions');

View File

@ -116,46 +116,10 @@ CREATE TABLE IF NOT EXISTS `inscriptions_eve_acces_log` (
COMMENT='Audit acces v2';
/* 6. Vue acces actifs */
DROP VIEW IF EXISTS `v_eve_acces_actif`;
CREATE VIEW `v_eve_acces_actif` AS
SELECT
ea.ea_id,
ea.com_id,
ea.eve_id,
ea.role_id,
r.role_code,
r.role_label_fr,
r.role_label_en,
ea.ea_statut,
ea.ea_expires_at,
ea.ea_expire_days,
ea.ea_granted_by,
ea.ea_created_at
FROM inscriptions_eve_acces ea
INNER JOIN inscriptions_eve_roles r
ON r.role_id = ea.role_id
AND r.role_actif = 1
WHERE ea.ea_statut = 'actif'
AND (ea.ea_expires_at IS NULL OR ea.ea_expires_at > NOW());
/* 7. Vue permissions effectives */
/* 6-7. Plus de vues SQL.
Les anciennes vues v_eve_acces_actif / v_eve_acces_permissions portaient un
DEFINER non copiable par Navicat / la releve. La logique est desormais en
sous-requetes directement dans le code PHP (php/inc_fx_eve_acces.php et
v3_ci4/app/Libraries/EventAccess.php). On supprime les vues si elles existent. */
DROP VIEW IF EXISTS `v_eve_acces_permissions`;
CREATE VIEW `v_eve_acces_permissions` AS
SELECT
v.ea_id,
v.com_id,
v.eve_id,
v.role_id,
v.role_code,
erp.perm_key,
p.perm_group,
p.perm_label_fr,
p.perm_phase
FROM v_eve_acces_actif v
INNER JOIN inscriptions_eve_role_permissions erp
ON erp.role_id = v.role_id
INNER JOIN inscriptions_eve_permissions p
ON p.perm_key = erp.perm_key
AND p.perm_actif = 1;
DROP VIEW IF EXISTS `v_eve_acces_actif`;

View File

@ -16,9 +16,20 @@ SET NAMES utf8mb4;
/* ------------------------------------------------------------------
1. Niveau permission : page | action | api | report
------------------------------------------------------------------ */
ALTER TABLE `inscriptions_eve_permissions`
ADD COLUMN `perm_scope` enum('page','action','api','report') NOT NULL DEFAULT 'api'
AFTER `perm_group`;
/* Ajout idempotent : n'ajoute la colonne que si elle n'existe pas deja
(evite l'erreur 1060 - Duplicate column name si le script est relance). */
SET @col_exists := (
SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'inscriptions_eve_permissions'
AND COLUMN_NAME = 'perm_scope'
);
SET @ddl := IF(@col_exists = 0,
'ALTER TABLE `inscriptions_eve_permissions` ADD COLUMN `perm_scope` enum(''page'',''action'',''api'',''report'') NOT NULL DEFAULT ''api'' AFTER `perm_group`',
'DO 0');
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
UPDATE `inscriptions_eve_permissions` SET `perm_scope` = 'api'
WHERE `perm_group` = 'api';
@ -43,11 +54,33 @@ UPDATE `inscriptions_eve_permissions` SET `perm_scope` = 'action'
/* ------------------------------------------------------------------
2. Multi-kits : plusieurs roles par compte x evenement
------------------------------------------------------------------ */
ALTER TABLE `inscriptions_eve_acces`
DROP INDEX `uk_com_eve`;
/* Retrait idempotent de l'ancien index unique (evite 1091 si deja retire). */
SET @idx_old := (
SELECT COUNT(*) FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'inscriptions_eve_acces'
AND INDEX_NAME = 'uk_com_eve'
);
SET @ddl := IF(@idx_old > 0,
'ALTER TABLE `inscriptions_eve_acces` DROP INDEX `uk_com_eve`',
'DO 0');
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
ALTER TABLE `inscriptions_eve_acces`
ADD UNIQUE KEY `uk_com_eve_role` (`com_id`, `eve_id`, `role_id`);
/* Ajout idempotent du nouvel index unique (evite 1061 si deja present). */
SET @idx_new := (
SELECT COUNT(*) FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'inscriptions_eve_acces'
AND INDEX_NAME = 'uk_com_eve_role'
);
SET @ddl := IF(@idx_new = 0,
'ALTER TABLE `inscriptions_eve_acces` ADD UNIQUE KEY `uk_com_eve_role` (`com_id`, `eve_id`, `role_id`)',
'DO 0');
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
/* ------------------------------------------------------------------
@ -198,67 +231,12 @@ WHERE r.role_code = 'mobile_statut';
/* ------------------------------------------------------------------
6. Vues : union kits multiples + extras
6. Plus de vues SQL.
Les vues v_eve_acces_actif / v_eve_acces_permissions portaient un DEFINER
non copiable par Navicat / la releve. La logique (union kits multiples +
extras) est desormais en sous-requetes directement dans le code PHP
(php/inc_fx_eve_acces.php et v3_ci4/app/Libraries/EventAccess.php).
On supprime les vues si elles existent.
------------------------------------------------------------------ */
DROP VIEW IF EXISTS `v_eve_acces_permissions`;
DROP VIEW IF EXISTS `v_eve_acces_actif`;
CREATE VIEW `v_eve_acces_actif` AS
SELECT
ea.ea_id,
ea.com_id,
ea.eve_id,
ea.role_id,
r.role_code,
r.role_label_fr,
r.role_label_en,
ea.ea_statut,
ea.ea_expires_at,
ea.ea_expire_days,
ea.ea_granted_by,
ea.ea_created_at
FROM inscriptions_eve_acces ea
INNER JOIN inscriptions_eve_roles r
ON r.role_id = ea.role_id
AND r.role_actif = 1
WHERE ea.ea_statut = 'actif'
AND (ea.ea_expires_at IS NULL OR ea.ea_expires_at > NOW());
CREATE VIEW `v_eve_acces_permissions` AS
SELECT
v.ea_id,
v.com_id,
v.eve_id,
v.role_id,
v.role_code,
erp.perm_key,
p.perm_group,
p.perm_scope,
p.perm_label_fr,
p.perm_phase
FROM v_eve_acces_actif v
INNER JOIN inscriptions_eve_role_permissions erp
ON erp.role_id = v.role_id
INNER JOIN inscriptions_eve_permissions p
ON p.perm_key = erp.perm_key
AND p.perm_actif = 1
UNION
SELECT
NULL AS ea_id,
ae.com_id,
ae.eve_id,
NULL AS role_id,
'extra' AS role_code,
ae.perm_key,
p.perm_group,
p.perm_scope,
p.perm_label_fr,
p.perm_phase
FROM inscriptions_eve_acces_extra ae
INNER JOIN inscriptions_eve_permissions p
ON p.perm_key = ae.perm_key
AND p.perm_actif = 1
WHERE ae.ae_statut = 'actif';

View File

@ -16,6 +16,45 @@ class EventAccess
$this->db = Database::connect();
}
/**
* Corps SELECT des acces actifs (remplace l'ancienne vue v_eve_acces_actif).
* Pas de vue stockee : evite le DEFINER non copiable par Navicat / releve.
*/
protected function actifBody(): string
{
return "SELECT ea.ea_id, ea.com_id, ea.eve_id, ea.role_id,
r.role_code, r.role_label_fr, r.role_label_en,
ea.ea_statut, ea.ea_expires_at, ea.ea_expire_days,
ea.ea_granted_by, ea.ea_created_at
FROM inscriptions_eve_acces ea
INNER JOIN inscriptions_eve_roles r
ON r.role_id = ea.role_id AND r.role_actif = 1
WHERE ea.ea_statut = 'actif'
AND (ea.ea_expires_at IS NULL OR ea.ea_expires_at > NOW())";
}
/** Sous-requete aliasee, equivalente a l'ancienne vue v_eve_acces_actif. */
protected function actifSql(): string
{
return "(" . $this->actifBody() . ") v_eve_acces_actif";
}
/** Sous-requete aliasee, equivalente a l'ancienne vue v_eve_acces_permissions. */
protected function permSql(): string
{
return "((SELECT v.ea_id, v.com_id, v.eve_id, v.role_id, v.role_code,
erp.perm_key, p.perm_group, p.perm_scope, p.perm_label_fr, p.perm_phase
FROM (" . $this->actifBody() . ") v
INNER JOIN inscriptions_eve_role_permissions erp ON erp.role_id = v.role_id
INNER JOIN inscriptions_eve_permissions p ON p.perm_key = erp.perm_key AND p.perm_actif = 1)
UNION
(SELECT NULL AS ea_id, ae.com_id, ae.eve_id, NULL AS role_id, 'extra' AS role_code,
ae.perm_key, p.perm_group, p.perm_scope, p.perm_label_fr, p.perm_phase
FROM inscriptions_eve_acces_extra ae
INNER JOIN inscriptions_eve_permissions p ON p.perm_key = ae.perm_key AND p.perm_actif = 1
WHERE ae.ae_statut = 'actif')) v_eve_acces_permissions";
}
public function isEnabled(): bool
{
static $enabled = null;
@ -40,11 +79,10 @@ class EventAccess
return false;
}
$count = $this->db->table('v_eve_acces_actif')
->where('com_id', $comId)
->countAllResults();
$sql = "SELECT COUNT(*) AS n FROM " . $this->actifSql() . " WHERE com_id = ?";
$row = $this->db->query($sql, [$comId])->getRow();
return $count > 0;
return $row !== null && (int) $row->n > 0;
}
public function getEventIds(int $comId): array
@ -53,11 +91,8 @@ class EventAccess
return [];
}
$rows = $this->db->table('v_eve_acces_actif')
->select('eve_id')
->where('com_id', $comId)
->get()
->getResultArray();
$sql = "SELECT eve_id FROM " . $this->actifSql() . " WHERE com_id = ?";
$rows = $this->db->query($sql, [$comId])->getResultArray();
return array_map(static fn($r) => (string) $r['eve_id'], $rows);
}
@ -68,13 +103,11 @@ class EventAccess
return false;
}
$count = $this->db->table('v_eve_acces_permissions')
->where('com_id', $comId)
->where('eve_id', $eveId)
->where('perm_key', $permKey)
->countAllResults();
$sql = "SELECT COUNT(*) AS n FROM " . $this->permSql() . "
WHERE com_id = ? AND eve_id = ? AND perm_key = ?";
$row = $this->db->query($sql, [$comId, $eveId, $permKey])->getRow();
return $count > 0;
return $row !== null && (int) $row->n > 0;
}
public function canAccessEvent(int $comId, int $eveId): bool
@ -83,12 +116,11 @@ class EventAccess
return false;
}
$count = $this->db->table('v_eve_acces_actif')
->where('com_id', $comId)
->where('eve_id', $eveId)
->countAllResults();
$sql = "SELECT COUNT(*) AS n FROM " . $this->actifSql() . "
WHERE com_id = ? AND eve_id = ?";
$row = $this->db->query($sql, [$comId, $eveId])->getRow();
return $count > 0;
return $row !== null && (int) $row->n > 0;
}
/**