Formulaire - ne pas pouvoir modifier un champ

Eléphant du PHP | 88 Messages

23 mars 2021, 14:23

bonjour !
voici mon petit souci : j'ai une class pour mes input et un formulaire pour mes posts et mes comments :

je souhaite que mon champs SLUG ne soit pas modifiable !!!
<form method="POST" enctype="multipart/form-data">
    <?= $form->input('name', 'Titre'); ?>
    <?= $form->input('slug', 'Slug'); ?>
    <?= $form->input('chapo', 'Chapo'); ?>
    <div class="row">
        <div class="col-md-9">
            <?= $form->file('image', 'Image à la une'); ?>
        </div>
        <div class="col-md-3">
            <?php if ($post->getImage()) : ?>
            <img src="<?= $post->getImageURL('small') ?>" alt="" style="width: 100%;">
            <?php endif ?>
        </div>
    </div>
    <?= $form->textarea('content', 'Contenu'); ?>
    <?= $form->input('author', 'Auteur (e)'); ?>
    <?= $form->input('created_at', 'Modifié ou crée le'); ?>
    <div class="d-flex justify-content-center">
        <button class="btn btn-secondary" type="submit">
            <?php if ($post->getID() !== null) : ?>
            Modifier
            <?php else : ?>
            Créer
            <?php endif ?>
        </button>
    </div>
    <br>
</form>
j'ai ma class :
class Form
{
    private $data;

    private $errors;

    public function __construct($data, array $errors)
    {
        $this->data = $data;
        $this->errors = $errors;
    }

    public function input(string $key, string $label): string
    {
        $value = $this->getValue($key);

        $type = $key === "password" ? "password" : "text";
        return <<<HTML
        <div class="form-group">
            <label for="field{$key}">{$label}</label>
            <input type="{$type}" id="field{$key}" class="{$this->getInputClass($key)}" name="{$key}"  value="{$value}" required>
            {$this->getErrorFeedback($key)}
        </div>
HTML;
    }
    public function file(string $key, string $label): string
    {
        return <<<HTML
        <div class="form-group">
            <label for="field{$key}">{$label}</label>
            <input type="file" id="field{$key}" class="{$this->getInputClass($key)}" name="{$key}">
            {$this->getErrorFeedback($key)}
        </div>
HTML;
    }

    public function textarea(string $key, string $label): string
    {
        $value = $this->getValue($key);
        return <<<HTML
        <div class="form-group">
            <label for="field{$key}">{$label}</label>
            <textarea type="text" id="field{$key}" class="{$this->getInputClass($key)}" name="{$key}">{$value}</textarea>
            {$this->getErrorFeedback($key)}
        </div>
HTML;
    }

    public function select(string $key, string $label, array $options = []): string
    {
        $optionsHTML = [];
        $value = $this->getValue($key);
        foreach ($options as $k => $v) {
            $selected = in_array($k, $value) ? " selected" : "";
            $optionsHTML[] = "<option value=\"$k\"$selected>$v</option>";
        }

        $optionsHTML = implode('', $optionsHTML);
        return <<<HTML
        <div class="form-group">
            <label for="field{$key}">{$label}</label>
            <select id="field{$key}" class="{$this->getInputClass($key)}" name="{$key}[]"  required multiple>{$optionsHTML}</select>
            {$this->getErrorFeedback($key)}
        </div>
HTML;
    }



    private function getValue(string $key)
    {
        if (is_array($this->data)) {
            return $this->data[$key] ?? null;
        }
        $method = 'get' .  str_replace(' ', '', ucwords(str_replace('_', ' ', $key)));
        $value = $this->data->$method();
        if ($value instanceof \DateTimeInterface) {
            return $value->format('Y-m-d H:i:s');
        }
        return $value;
    }

    private function getInputClass(string $key): string
    {
        $inputClass = 'form-control';
        if (isset($this->errors[$key])) {
            $inputClass .= ' is-invalid';
        }
        return $inputClass;
    }

    private function getErrorFeedback(string $key): string
    {
        if (isset($this->errors[$key])) {
            if (is_array($this->errors[$key])) {
                $error = implode(' <br>', $this->errors[$key]);
            } else {
                $error = $this->errors[$key];
            }
            return '<div class="invalid-feedback">' .  $error . '</div>';
        }
        return '';
    }
}
Alors malgré mes recherches et je l'avoue ca aurait ete bien plus simple sans la class,
j'aimerai que mon champ SLUG ne puisse pas etre modifier ! alors que ce soit hidden, disable !!! mais ou je peux inserer ce code?


merci pour votre aide
merci

Avatar du membre
Mammouth du PHP | 1564 Messages

23 mars 2021, 14:36

Rajoute un paramètre optionnel à ta fonction input():
public function input(string $key, string $label, bool $disabled=false): string

Mammouth du PHP | 2703 Messages

23 mars 2021, 14:47

en enlevant la ligne :
<?= $form->input('slug', 'Slug'); ?>

Eléphant du PHP | 88 Messages

23 mars 2021, 16:32

euh j'ai fait les 2 :
    public function input(string $key, string $label, bool $disabled=false): string
    {
        $value = $this->getValue($key);

        $type = $key === "password" ? "password" : "text";
        return <<<HTML
        <div class="form-group">
            <label for="field{$key}">{$label}</label>
            <input type="{$type}" id="field{$key}" class="{$this->getInputClass($key)}" name="{$key}"  value="{$value}" required>
            {$this->getErrorFeedback($key)}
        </div>
HTML;
    }
nan ca ne marche pas ( mais ils sont grisés il faut initialiser la varirable? )

et puis en supprimant la ligne
  <?= $form->input('slug', 'Slug'); ?>
ca ne fait qu'enlever le champs et pas empecher sa modif!!!

Mammouth du PHP | 2703 Messages

23 mars 2021, 16:35

et puis en supprimant la ligne
  <?= $form->input('slug', 'Slug'); ?>
ca ne fait qu'enlever le champs et pas empecher sa modif!!!
si le script de sauvegarde des changements ne sauve pas le slug dans la requete sql, il n'y a pas de modification possible du slug.

Eléphant du PHP | 88 Messages

23 mars 2021, 16:41

et bien pourtant je l'ai :
public function updatePost(Post $post): void
    {
        $this->update([
      'name' => $post->getName(),
      'slug' => $post->getSlug(),
      'chapo' => $post->getChapo(),
      'content' => $post->getContent(),
      'image' => $post->getImage(),
      'created_at' => $post->getCreatedAt()->format('Y-m-d H:i:s'),
      'author' => $post->getAuthor(),
    ], $post->getID());
    }

Avatar du membre
Mammouth du PHP | 1564 Messages

23 mars 2021, 18:40

Soit tu fait un foreach des input des envoyés pour modifier que ce qui est déclaré dans le form, soit tu met un disabled et évidement qu'il faut le déclarer dans le code, les sites ne se font pas tout seul encore :mrgreen:
Par exemple si $disabled vaut true tu rajoute une condition dans ton <input type="... disabled>
input('slug','Slug',true);//sera disabled si dans ton code tu fais une condition pour qu'il le soit

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

23 mars 2021, 19:47

Euh.... s'il ne doit jamais être modifié, quel intérêt de l'avoir dans l'update ?

En fait tu as plusieurs options :

* Au niveau de l'affichage :
- ne pas proposer le champ (si je peux pas le voir, je vais difficilement pouvoir le modifier)
- afficher la valeur, sans afficher de champ (je peux le voir, mais je ne peux toujours pas le modifier)
- afficher la valeur dans un champ avec un attribut disabled="disabled" ou readonly="readonly" (je peux le voir, éventuellement le copier, mais en théorie, pas le modifier). L'intérêt de passer un paramètre supplémentaire à la fonction qui génère le code de ton input, c'est justement de pouvoir y ajouter cet attribut ou non selon le contexte.

* Au niveau du traitement
- ne pas le mettre à jour. Jamais. Peu importe ce qui se passe côté affichage. Ce n'est pas parce qu'un champ est en disabled ou readonly qu'on ne peut pas le modifier et l'envoyer malgré tout (c'est juste un peu plus compliqué) et la règle numéro un en informatique c'est "ne jamais faire confiance à l'utilisateur".
- s'il faut que dans certains cas cette valeur soit modifiable, par un admin ou autre, gérer la modification avec une condition pour savoir si tu dois utiliser la valeur envoyée en post pour ce champ ou pas.
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphant du PHP | 88 Messages

23 mars 2021, 19:53

oki merci
public function input(string $key, string $label, bool $disabled=false): string
    {
        $value = $this->getValue($key);
      

        $type = $key === "password" ? "password" : "text";
        return <<<HTML
        <div class="form-group">
            <label for="field{$key}">{$label}</label>
            <input type="{$type}" id="field{$key}" class="{$this->getInputClass($key)}" name="{$key}"  value=" disabled " disabled>
            {$this->getErrorFeedback($key)}
        </div>
j'ai mes 3 champs qui sont non modifiables
pfff pas facile :(

Eléphant du PHP | 88 Messages

23 mars 2021, 20:03

Ryle hello

merci c'est bien clair !
alors oui c'est vrai je me suis posee la question dans l update !
mais c'est que j'avais pas vu cette consigne tout de suite !

donc là je vais la supprimer dans mon update
 public function updatePost(Post $post): void
    {
        $this->update([
      'name' => $post->getName(),
      'chapo' => $post->getChapo(),
      'content' => $post->getContent(),
      'image' => $post->getImage(),
      'created_at' => $post->getCreatedAt()->format('Y-m-d H:i:s'),
      'author' => $post->getAuthor(),
    ], $post->getID());
    }
mais dans mon affichage : c' est le meme pour la creation de mon post que pour modifier un post
donc voilà pourquoi il me faut le conserver et pas le supprimer ! sachant qu'en plus l'admi lui peut modifier.


et puis alors je peux donc essayer de supprimer dans mon hydratation le slug!!!
if (!empty($_POST)) {
    $data = array_merge($_POST, $_FILES);
    $v = new PostValidator($data, $postManager, $post->getID());
    ObjectHelper::hydrate($post, $data, ['name', 'content', 'slug', 'author', 'chapo', 'created_at', 'image']);
    
    if ($v->validate()) {
        PostAttachment::upload($post);
        $postManager->updatePost($post);
        $success = true;
        $_SESSION['message_section'] = 'post_modif';
        
    } else {
        $errors = $v->errors();
    }
}
$form = new Form($post, $errors);
Merci Ryle c'est toujours tres pedagogique tes explications MERCI
Merci à Or1 et Two3d qui veulent aussi bcp m'aider
mais j'ai le cervolant ! :)

Avatar du membre
Mammouth du PHP | 1564 Messages

23 mars 2021, 21:16

Il te manque quelques bases en HTML, voilà un tuto sur les form/input:

https://developer.mozilla.org/fr/docs/W ... ment/Input (très bon site au passage et explications en Français pour la plupart des pages, c'est la doc officielle de chez Firefox)

Il te faut savoir que ta fonction input est affichée à chaque fois que tu l'appel, donc si le code de ta fonction est "Bonjour, ça va ?", tu affichera tout le temps "Bonjour, ça va ?", sauf si par exemple tu lui donne des consignes, par exemple pour le disabled prenons l'idée qu'on veuille affiche différent texte après "Bonjour, (ici)", on fera:
function bonjour($texte=null){
   return "Bonjour, ".($texte?$texte:"ça va ?");
}
//exemples:
echo bonjour($texte="comment allez-vous ?");//affichera "Bonjour, comment allez-vous ?"
echo bonjour();//affichera "Bonjour, ça va ?"