pagination curseur, layout 3 colonnes article, sidebar fixe
This commit is contained in:
+172
-1
@@ -21,15 +21,186 @@ function currentUserEmail(): ?string
|
||||
return $_SESSION['user_email'] ?? null;
|
||||
}
|
||||
|
||||
function currentUserName(): string
|
||||
{
|
||||
if (!isLoggedIn()) {
|
||||
return '';
|
||||
}
|
||||
if (isset($_SESSION['user_display_name']) && $_SESSION['user_display_name'] !== '') {
|
||||
return $_SESSION['user_display_name'];
|
||||
}
|
||||
$name = authorDisplayName(currentUserEmail() ?? '');
|
||||
$_SESSION['user_display_name'] = $name;
|
||||
return $name;
|
||||
}
|
||||
|
||||
function authorDisplayName(string $email): string
|
||||
{
|
||||
static $cache = [];
|
||||
$key = strtolower(trim($email));
|
||||
if ($key === '') {
|
||||
return '';
|
||||
}
|
||||
if (array_key_exists($key, $cache)) {
|
||||
return $cache[$key];
|
||||
}
|
||||
$pdo = dbPdo();
|
||||
if ($pdo) {
|
||||
try {
|
||||
$st = $pdo->prepare('SELECT display_name FROM user_profiles WHERE email = :e');
|
||||
$st->execute([':e' => $key]);
|
||||
$name = $st->fetchColumn();
|
||||
$cache[$key] = ($name !== false && $name !== '') ? $name : explode('@', $key)[0];
|
||||
return $cache[$key];
|
||||
} catch (\Throwable) {
|
||||
}
|
||||
}
|
||||
$cache[$key] = explode('@', $key)[0];
|
||||
return $cache[$key];
|
||||
}
|
||||
|
||||
function dbPdo(): ?PDO
|
||||
{
|
||||
static $pdo = null;
|
||||
static $failed = false;
|
||||
if ($failed) {
|
||||
return null;
|
||||
}
|
||||
if ($pdo !== null) {
|
||||
return $pdo;
|
||||
}
|
||||
$dsn = $_ENV['DB_DSN'] ?? (getenv('DB_DSN') ?: '');
|
||||
$user = $_ENV['DB_USER'] ?? (getenv('DB_USER') ?: '');
|
||||
$pass = $_ENV['DB_PASS'] ?? (getenv('DB_PASS') ?: '');
|
||||
if (!$dsn) {
|
||||
$failed = true;
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
$pdo = new PDO($dsn, $user ?: null, $pass ?: null, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
|
||||
} catch (\Throwable) {
|
||||
$failed = true;
|
||||
return null;
|
||||
}
|
||||
return $pdo;
|
||||
}
|
||||
|
||||
function currentUserRoles(): array
|
||||
{
|
||||
if (!isLoggedIn()) {
|
||||
return [];
|
||||
}
|
||||
if (isset($_SESSION['user_roles'])) {
|
||||
return $_SESSION['user_roles'];
|
||||
}
|
||||
$pdo = dbPdo();
|
||||
if (!$pdo) {
|
||||
$_SESSION['user_roles'] = [];
|
||||
return [];
|
||||
}
|
||||
try {
|
||||
$st = $pdo->prepare(
|
||||
'SELECT r.name FROM roles r
|
||||
JOIN user_roles ur ON ur.role_id = r.id
|
||||
WHERE ur.user_email = :e'
|
||||
);
|
||||
$st->execute([':e' => strtolower(currentUserEmail() ?? '')]);
|
||||
$_SESSION['user_roles'] = $st->fetchAll(PDO::FETCH_COLUMN) ?: [];
|
||||
} catch (\Throwable) {
|
||||
$_SESSION['user_roles'] = [];
|
||||
}
|
||||
return $_SESSION['user_roles'];
|
||||
}
|
||||
|
||||
function hasRole(string $role): bool
|
||||
{
|
||||
return in_array($role, currentUserRoles(), true);
|
||||
}
|
||||
|
||||
// Capacités connues — clé => label affiché dans l'admin
|
||||
const KNOWN_CAPABILITIES = [
|
||||
'view_sources_own' => 'Voir les sources de ses propres articles',
|
||||
'view_sources_all' => 'Voir les sources de tous les articles',
|
||||
'view_drafts_own' => 'Voir ses articles non publiés',
|
||||
'view_drafts_all' => 'Voir tous les articles non publiés',
|
||||
'edit_articles_own' => 'Modifier ses propres articles',
|
||||
'edit_articles_all' => 'Modifier tous les articles',
|
||||
'rate_articles' => 'Noter des articles',
|
||||
];
|
||||
|
||||
// Groupes pour l'interface d'administration
|
||||
// 'single' => pas de variante own/all
|
||||
const CAPABILITY_GROUPS = [
|
||||
['label' => 'Sources & métadonnées', 'own' => 'view_sources_own', 'all' => 'view_sources_all'],
|
||||
['label' => 'Articles non publiés', 'own' => 'view_drafts_own', 'all' => 'view_drafts_all'],
|
||||
['label' => 'Modification', 'own' => 'edit_articles_own', 'all' => 'edit_articles_all'],
|
||||
['label' => 'Noter des articles', 'single' => 'rate_articles'],
|
||||
];
|
||||
|
||||
function currentUserCapabilities(): array
|
||||
{
|
||||
if (!isLoggedIn()) {
|
||||
return [];
|
||||
}
|
||||
if (isset($_SESSION['user_capabilities'])) {
|
||||
return $_SESSION['user_capabilities'];
|
||||
}
|
||||
$pdo = dbPdo();
|
||||
if (!$pdo) {
|
||||
$_SESSION['user_capabilities'] = [];
|
||||
return [];
|
||||
}
|
||||
try {
|
||||
$st = $pdo->prepare(
|
||||
'SELECT DISTINCT rc.capability
|
||||
FROM role_capabilities rc
|
||||
JOIN user_roles ur ON ur.role_id = rc.role_id
|
||||
WHERE ur.user_email = :e'
|
||||
);
|
||||
$st->execute([':e' => strtolower(currentUserEmail() ?? '')]);
|
||||
$_SESSION['user_capabilities'] = $st->fetchAll(PDO::FETCH_COLUMN) ?: [];
|
||||
} catch (\Throwable) {
|
||||
$_SESSION['user_capabilities'] = [];
|
||||
}
|
||||
return $_SESSION['user_capabilities'];
|
||||
}
|
||||
|
||||
function hasCapability(string $cap): bool
|
||||
{
|
||||
if (isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
return in_array($cap, currentUserCapabilities(), true);
|
||||
}
|
||||
|
||||
function canDoOnArticle(string $baseCap, array $article): bool
|
||||
{
|
||||
if (isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
if (hasCapability($baseCap . '_all')) {
|
||||
return true;
|
||||
}
|
||||
if (hasCapability($baseCap . '_own')) {
|
||||
$owner = strtolower($article['author'] ?? '');
|
||||
return $owner !== '' && $owner === strtolower(currentUserEmail() ?? '');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isAdmin(): bool
|
||||
{
|
||||
$email = currentUserEmail();
|
||||
if (!$email) {
|
||||
return false;
|
||||
}
|
||||
// Fallback bootstrap : var d'env
|
||||
$rawAdmin = $_ENV['ADMIN_EMAIL'] ?? (getenv('ADMIN_EMAIL') ?: '');
|
||||
$allowed = array_filter(array_map('trim', explode(',', (string)$rawAdmin)));
|
||||
return in_array(strtolower($email), array_map('strtolower', $allowed), true);
|
||||
if (in_array(strtolower($email), array_map('strtolower', $allowed), true)) {
|
||||
return true;
|
||||
}
|
||||
return hasRole('admin');
|
||||
}
|
||||
|
||||
function ssoLogoutUrl(): string
|
||||
|
||||
Reference in New Issue
Block a user