Bonsoir, alors ça parait simple mais avec les or && || je comence a ne plus avoir de cheuveux

en gros je veut afficher un lien pour l'édition d'un topic et je dois jonglé entre l'user qui l'a créer l'admin et le modo

Pour ce faire j'ai mes variable

la auth autorisation peut être égal a 3 qui est le rang max Admin, et le rang 2 qui est le Modo

$_SESSION['auth']->id == $reps->userid
$_SESSION["auth"]->authorization

Le membre peut modifier son topic et sa réponse uniquement les sienne, le modo et l'admin peuvent aussi le modifié et la ça me rend fou.

voila ou je me suis arreter

          <?php 
            if (isset($_SESSION['auth']->id) 
            && !empty($_SESSION['auth']->id == $reps->userid) 
            or isset($_SESSION["auth"]->authorization) 
            && !empty($_SESSION["auth"]->authorization == 3)
            or isset($_SESSION["auth"]->authorization)
            && !empty($_SESSION["auth"]->authorization == 2)
            ) { 
          ?>
          <a class="p-2 bd-highlight" href="<?= $router->generate('editerep', ['id' => $reps->topicsrep]) ?>"><i class="far fa-edit"></i> Editer</a>
          <?php } ?>

Bonne soirée.

7 réponses


popotte
Réponse acceptée

Alors, quand c'est pas bon tu fais un redirect? dans ce cas tu peux mettre un coup de propre à ton code :p

// Si y a pas de session -> ça dégage !
if (!isset($_SESSION['auth'])){
    setFlash('Vous devez être connecté pour acceder a cette page','orange');
    redirect('forum');
}

// On récup le topic
$firstTopic = $db->prepare("SELECT id, f_topic_content, f_user_id FROM f_topics WHERE id = ? ");
$firstTopic->execute([intval($match['params']['id'])]);
$topic = $firstTopic->fetch();

// Si le mec n'est ni auteur ni modo ni admin -> ça dégage !
if($_SESSION['auth']->id != $topic->f_user_id or !in_array($_SESSION["auth"]->authorization, [2, 3]) {
    setFlash("Vous n'avez pas le bon rang pour editer ce topic ou ce topic n'est pas le votre",'orange');
    redirect('forum');
}

// Si y a pas de topic trouvé -> ça dégage !
if(!isset($_POST['topics'])){
    redirect('forum');
}

/**
* Après avoir passé toutes les conditions, c'est bon on peut commencer à coder à partir de la
* La sauvegarde
**/
checkCsrf();//on verifie les faille csrf
$content = trim($_POST['f_topic_content']);
$error = '';

if(grapheme_strlen($content) < 100){
    // Euh la ça veut dire que même si le message est ok tu auras un champ dans $error, du coup la condition suivante elle va etre à false vu que c'est pas empty nan?
    $error .= errors(['content ok']);
}

if(empty($error)){
    $u = [$content, intval($params['id'])];
    $db->prepare("UPDATE f_topics SET f_topic_content = ? WHERE id = ?")->execute($u);

    setFlash('Votre message a bien été modifié');
    redirect($router->generate('viewtopic', ['id' => $params['id']]));
}

/*
Bon dans l'exemple en gros c'est un standard de bonne pratique, au lieux d'imbriquer les if, tu cales tous les if négatifs en haut, et ensuite tu fais proprement ton code sans que ce soit imbriqué dans pleins de if

Et dans mon exemple j'ai répondu à ta question: Oui tu peux faire un ``in_array``, mais tu l'implémentes pas come il faut, en gros toi tu as mis:
if($_SESSION["auth"]->authorization == in_array($_SESSION["auth"]->authorization, [2,3]))

la fonction in_array return soit true soit false, du coup dans les deux cas ça marchera pas:
if($_SESSION["auth"]->authorization == true) -> false
if($_SESSION["auth"]->authorization == false) -> false

Il faut utiliser in_array tout seul:
if(in_array($_SESSION["auth"]->authorization, [2,3])) qui retournera true ou false

Et yep in array c'est mieux :p
*/

bonsoir
déjà on ne fais pas de comparaison a une fonction ton empty.

on va simplifier la chose.
on vérifie dans un 1er temps que ma session auth ne soit pas vide. je suppose qu'il aura une autorisation à 0 ou 1 par défaut.

il faut pour modifier un post que l'utilisateur est une autorisation superieur ou égale à 2 OU qu'il soit l'auteur du post

Hello :)

Alors pour les conditions... Disons que c'est entièrement à refaire :p

Bon, le mieux serait de prendre une logique de php orienté objet mais en procédural:

<?php

// En POO ce serait un modèle, j'ai reproduis un tableau, et je fais retourner false si il n'y a pas de session auth
function current_user($reps) {
    if (!isset($_SESSION['auth'])) return false;
    $auth = $_SESSION['auth'];
    $role = $auth?->authorisation;
    $id = $auth?->id;
    $user_id = $reps->userid;

    return [
        $auth,
        $role,
        $id,
        $user_id,
    ];
}

// On vérifie que le user est l'auteur
function is_owner($user) {
    return $user['id'] == $user['user_id'];
}

// On vérifie si le user est un admin ou un modo
function is_elevated($user) {
    return in_array($user['role'], [2, 3]);
}

// On vérifie si la personne peut éditer, la fontion utilise les deux fonctions précédentes
function can_edit($user) {
    return is_owner($user) || is_elevated($user);
}

// On enregistre le current user dans une variable, plus pratique
$user = current_user();

// Et on attaque la condition
if ($user && can_edit($user)) {

?>

<a class="p-2 bd-highlight" href="<?= $router->generate('editerep', ['id' => $reps->topicsrep]) ?>">
    <i class="far fa-edit"></i> Editer
</a>

<?php } ?>

Voila, il y a beaucoup plus de code mais au moins c'est lisible, du coup plus simple à débugger en cas de problème :p

D'aileurs regardes des cours PHP sur le MVC, ça va pas mal te faciliter la gestion des users, et même la POO (class, interfaces, traits, contracts)

neecride
Auteur

Bonjour,

Cette condition semble être correcte ?

en tout cas elle fontionne, je suis bête de vérifiez 3 et 4 (sauf si je peut le faire avec un array) alors qu'il suffit de faire supérieur ou égal et je vérifie la session avant, vue comme ça je peut mieux comprendre la version POO car j'ai 2 version de la même app une procédural et une poo (qui est en pause a cause de mon router j'ai pas compris comme l'utiliser dans mes class et en dehors).

juste pour savoir, ça || est egal a OR et && et egale a AND ?

          <?php 
            if (isset($_SESSION['auth'])){
              if($_SESSION['auth']->id == $topic->usersid or $_SESSION["auth"]->authorization >= 3) { 
          ?>
            <a class="p-2 bd-highlight" href="<?= $router->generate('editetopic', ['id' => $topic->topicsid]) ?>"><i class="far fa-edit"></i> Editer</a> 
            <?php 
              }
            } 
          ?>

Alors ça parrait bien, si tu utilises PHP8 tu peux encore plus simplifier ta condition en virant le isset:

<?php 
    if($_SESSION['auth']?->id == $topic->usersid or $_SESSION["auth"]?->authorization >= 3) { 
?>

<a class="p-2 bd-highlight" href="<?= $router->generate('editetopic', ['id' => $topic->topicsid]) ?>"><i class="far fa-edit"></i> Editer</a> 

<?php 
} 
?>

Le ? il sert de isset, si ça n'existe pas ça renverra null, et dans un if le null est traité comme un false (enfin sauf si tu fais une comparaison strict avec ===)

Ensuite dans ta condition faudrait pas mettre >= 2 au lieux de 3 pour autoriser les modos?

Et oui, || c'est OR et && c'est AND :p

neecride
Auteur

Alors je suis en php 7 car html purifier 4.15 ne fonctionne pas en php 8 et donc le ? ne fonctionne pas non plus.

Par contre on est d'accord pour dire que si je post un topic ou édite un topic et une réponse c'est pareil je dois vérifié si on a une session et si l'utilisateur est un membre un modo ou admin

Pour ce faire j'ai fais cette vérif car ça sert a rien d'afficher un lien ou non si le script n'est pas sur.

if (isset($_SESSION['auth'])){

     $firstTopic = $db->prepare("SELECT id, f_topic_content, f_user_id FROM f_topics WHERE id = ? ");

    $firstTopic->execute([intval($match['params']['id'])]);

    $topic = $firstTopic->fetch();

    if($_SESSION['auth']->id == $topic->f_user_id or $_SESSION["auth"]->authorization >= 2){

        /**
        * La sauvegarde
        **/
        if(isset($_POST['topics'])){
            checkCsrf();//on verifie les faille csrf
            $content = trim($_POST['f_topic_content']);
            $error = '';
            if(grapheme_strlen($content) < 100){

                $error .= errors(['content ok']);

            }
            if(empty($error)){

                $u = [$content, intval($params['id'])];

                $db->prepare("UPDATE f_topics SET f_topic_content = ? WHERE id = ?")->execute($u);

                    setFlash('Votre message a bien étais modifier');

                    redirect($router->generate('viewtopic', ['id' => $params['id']]));
            }

        }

    }else{

        setFlash("Vous n'avez pas le bon rang pour editer ce topic ou ce topic n'est pas le votre",'orange');
        redirect('forum');
    }
}else{

    setFlash('Vous devez être connecter pour acceder a cette page','orange');
    redirect('forum');
}

Dernière chose, peut-on faire une vérification comme ceci ? if($_SESSION["auth"]->authorization == in_array($_SESSION["auth"]->authorization, [2,3])) ça parait plus facile a maintenir et au moins ça vérifie seulement si 2 et 3 exist

neecride
Auteur

C'est vrai que toutes mes imbrication c'est pas fameux !

je remet tout mon code au propre donc c'est l'occation de mieux faire, je met des redirection pour évité de retrouver les token en get, a la base c'est ce que je faisait mais j'utilise AltoRouter maintenant ce qui change pas mal de chose par exemple j'ai plus besoin de vérifié si j'ai un id en get il le gère tout seul, j'ai juste fais une condition avec les fonctions

is_array($match) is_callable($match['target']) call_user_func_array($match['target'], $match['params'])

si la route ne match pas je redirige tout vers la page d'erreur, ça gère même GET|POST

$router->map('GET'     , '/forum-[*:slug]-[i:id]', 'viewforums','forum-tags');
$match = $router->match();

et pour cette condition que tu souligne

if(grapheme_strlen($content) < 100){
    // Euh la ça veut dire que même si le message est ok tu auras un champ dans $error, du coup la condition suivante elle va etre à false vu que c'est pas empty nan?
    $error .= errors(['content ok']);
}

dans un premier j'ai mis grapheme parce que 1 smiley ça fait plusieurs octets d'où l'utilisation de utf8_mb4 et donc ça peut valoir plus qu'un caractères le simple strlen faisait pas la différence, et ça fonctionne comme c'est censé fonctionner si quelqu'un post du vide ou moins de 100 caractères ça me fait l'erreur, voilà pourquoi je vérifie pas empty ça me parait pas pertinant vu que la fonction vérifie le nombre de caractères je ne vérifie que dans le value du formulaire, mais est-ce que les espaces sont des caractères ??

J'ai plus qu'a géré les redirections avec les maxpage et j'aurais fini il me manque juste la page qui va se créer quand le max perpage atteind sa limite l'ors de la création d'une réponse, ensuite je passe a poo a 100%.