Exemple de formulaire

Date de naissance
Genre

Création de composants réutilisables

Le but est ici de créer des composants PHP facilitant la génération de code HTML.

Voici les étapes pour atteindre ce but :

  1. Créer une classe Input permettant de générer un champ de saisie avec les attributs suivants :
    • label
    • type (dont les valeurs seront définies par des constantes)
    • id
    • name
    • value
    • checked
  2. Le constructeur permettra d'initialiser ces attributs. Une méthode render permettra de générer le code HTML (en retour de la méthode). Cette méthode générera une balise input ainsi que la balise label associée.
  3. Créer une classe Option permettant de générer un élément de liste déroulante avec les attributs suivants :
    • label
    • value
    • selected
  4. Le constructeur permettra d'initialiser ces attributs. Une méthode render permettra de générer le code HTML (en retour de la méthode). Cette méthode générera une balise option.
  5. Créer une classe Select permettant de générer une liste déroulante avec les attributs suivants :
    • name
    • options
  6. Le constructeur permettra d'initialiser ces attributs. Une méthode render permettra de générer le code HTML (en retour de la méthode). Cette méthode générera une balise select ainsi que les balises options.
  7. Une méthode addOption permettra d'ajouter un élément dans la liste déroulante
  8. Créer une classe Fieldset permettant de générer une liste déroulante avec les attributs suivants :
    • legend
    • elements
  9. Le constructeur permettra d'initialiser ces attributs. Une méthode render permettra de générer le code HTML (en retour de la méthode). Cette méthode générera une balise fieldset, la balise legend associée ainsi que tous les champs contenus dans le fieldset
  10. Une méthode addElement permettra d'ajouter un élément dans le groupe de champs
  11. Créer une classe Form permettant de générer un formulaire avec les attributs suivants :
    • action
    • method
    • name
    • encType
    • acceptCharset
    • elements
  12. Le constructeur permettra d'initialiser ces attributs. Une méthode render permettra de générer le code HTML (en retour de la méthode). Cette méthode générera une balise fieldset ainsi que la balise legend associée.
  13. Une méthode addElement permettra d'ajouter un élément dans le groupe de champs

Mise en oeuvre des composants

Recréer le formulaire ci-dessus en utilisant uniquement des composants PHP (objectif zéro HTML pour le formulaire).

Factorisation du code

Méthode render

Tous les composants ci-desssus ont une méthode render qui renvoie une chaine de caractères contenant du code HTML. Quel principe de la programmation objet pourrait s'appliquer ici ? Faire les modifications nécessaires.

Attribut elements

Plusieurs composants contiennent une liste de sous éléments Quel principe de la programmation objet pourrait s'appliquer ici pour éviter de définir plusieurs fois ce comportement ? Faire les modifications nécessaires.

Option.php

<?php
namespace App\GereckeFr\CoursBundle\POO\Ex04;

class Option implements HtmlElement
{
    /* var $label string */
    private $label;
    /* var $value string */
    private $value;
    /* var $selected string */
    private $selected;


    /**
     * Option constructor.
     * @param $label string
     * @param $value string
     * @param $selected string
     */
    public function __construct($label, $value, $selected = null)
    {
        $this->label = $label;
        $this->value = $value;
        $this->selected = $selected;
    }

    /*
     * @return string
     */
    public function render()
    {
        $content = '<option value="' . $this->value .'"';
        if($this->getSelected() != null) $content .= ' selected="' . $this->getSelected() . '"';
        $content .= '>' . $this->getLabel() . "</option>\n";

        return $content;
    }

    /**
     * @return string
     */
    public function getValue()
    {
        return $this->value;
    }

    /**
     * @param string $value
     */
    public function setValue($value)
    {
        $this->value = $value;
    }

    /**
     * @return null|string
     */
    public function getSelected()
    {
        return $this->selected;
    }

    /**
     * @param null|string $selected
     */
    public function setSelected($selected)
    {
        $this->selected = $selected;
    }

    /**
     * @return string
     */
    public function getLabel()
    {
        return $this->label;
    }

    /**
     * @param string $label
     */
    public function setLabel($label)
    {
        $this->label = $label;
    }


}
    

ComplexElement.php

<?php
namespace App\GereckeFr\CoursBundle\POO\Ex04;

abstract class ComplexElement implements HtmlElement
{
    /** var $elements HtmlElement[] */
    protected $elements;

    /**
     * @return null
     */
    public function getElements()
    {
        return $this->elements;
    }

    /**
     * @param HtmlElement $element
     */
    public function addElement($element)
    {
        if (!isset($this->elements)) $this->elements = array();
        $this->elements[] = $element;
    }
}
    

Select.php

<?php
namespace App\GereckeFr\CoursBundle\POO\Ex04;

class Select extends ComplexElement
{
    /* var $name string */
    private $name;

    /**
     * Select constructor.
     * @param $name string
     * @param $options Option[]
     */
    public function __construct($name, $options)
    {
        $this->name = $name;
        $this->elements = $options;
    }

    /*
     * @return string
     */
    public function render()
    {
        $content = '<div class="form-group col-md-2"><select class="form-control" name="' . $this->name . '">';
        foreach ($this->elements as $option)
        {
            $content .= $option->render();
        }
        $content .= "</select></div>\n";

        return $content;
    }


    /**
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @param string $name
     */
    public function setName($name)
    {
        $this->name = $name;
    }

    /**
     * @return Option[]
     */
    public function getOptions()
    {
        return $this->elements;
    }

    /**
     * @param Option[] $options
     */
    public function addOption($option)
    {
        $this->addElement($option);
    }
}
    

Group.php

<?php
namespace App\GereckeFr\CoursBundle\POO\Ex04;

class Group extends ComplexElement
{
    /**
     * @var string $cssClass
     */
    private $cssClass;

    /**
     * Group constructor.
     * @param string $cssClass
     * @param HtmlElement[] $elements
     */
    public function __construct($cssClass, $elements=null)
    {
        $this->cssClass = $cssClass;
        $this->elements = $elements;
    }

    /**
     * @return mixed
     */
    public function render()
    {
        $content = '<div class="' . $this->cssClass . '">';
        foreach ($this->elements as $element)
        {
            $content .= $element->render();
        }
        $content .= '</div>';
        return $content;
    }
}
    

Form.php

<?php
namespace App\GereckeFr\CoursBundle\POO\Ex04;

class Form extends ComplexElement
{
    const POST = "post";
    const GET = "get";

    /** @var $action string */
    private $action;
    /** @var $method string */
    private $method;
    /** @var $name string */
    private $name;
    /** @var $enctype string */
    private $enctype;
    /** @var $accept-charset string */
    private $acceptCharset;

    /**
     * Form constructor.
     * @param string $action
     * @param string $method
     * @param string $name
     * @param string $enctype
     * @param $acceptCharset
     * @param HtmlElement[] $elements
     */
    public function __construct($action, $method, $name, $enctype = null, $acceptCharset = null, array $elements = null)
    {
        $this->action = $action;
        $this->method = $method;
        $this->name = $name;
        $this->enctype = $enctype;
        $this->acceptCharset = $acceptCharset;
        $this->elements = $elements;
    }

    /**
     * @return string
     */
    public function render()
    {
        $content = '<form action="' . $this->getAction() . '"';
        $content .= ' method="' . $this->getMethod() . '"';
        $content .= ' name="' . $this->getAction() . '"';
        if($this->getEnctype() != null) $content .= ' enctype="' . $this->getEnctype() . '"';
        if($this->getAcceptCharset() != null) $content .= ' accept-charset="' . $this->getAcceptCharset() . '"';
        $content .= ">\n";
        if ($this->getElements() != null) {
            foreach ($this->elements as $element) {
                $content .= $element->render();
            }
        }
        $content .= "</form>\n";

        return $content;
    }

    /**
     * @return string
     */
    public function getAction()
    {
        return $this->action;
    }

    /**
     * @param string $action
     */
    public function setAction($action)
    {
        $this->action = $action;
    }

    /**
     * @return string
     */
    public function getMethod()
    {
        return $this->method;
    }

    /**
     * @param string $method
     */
    public function setMethod($method)
    {
        $this->method = $method;
    }

    /**
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @param string $name
     */
    public function setName($name)
    {
        $this->name = $name;
    }

    /**
     * @return string
     */
    public function getEnctype()
    {
        return $this->enctype;
    }

    /**
     * @param string $enctype
     */
    public function setEnctype($enctype)
    {
        $this->enctype = $enctype;
    }

    /**
     * @return mixed
     */
    public function getAcceptCharset()
    {
        return $this->acceptCharset;
    }

    /**
     * @param mixed $acceptCharset
     */
    public function setAcceptCharset($acceptCharset)
    {
        $this->acceptCharset = $acceptCharset;
    }
}
    

Input.php

<?php
namespace App\GereckeFr\CoursBundle\POO\Ex04;

use function GuzzleHttp\Psr7\_caseless_remove;

class Input implements HtmlElement
{
    const TEXT = "text";
    const BUTTON = "button";
    const CHECKBOX = "button";
    const PASSWORD = "password";
    const RADIO = "radio";
    const RESET = "reset";
    const SUBMIT = "submit";

    /* var $label string */
    private $label;
    /* var $type string */
    private $type;
    /* var $id string */
    private $id;
    /* var $name string */
    private $name;
    /* var $value string */
    private $value;
    /* var $checked string */
    private $checked;

    /**
     * Input constructor.
     * @param $label string
     * @param $type string
     * @param $id string
     * @param $name string
     * @param $value string
     * @param $checked string
     */
    public function __construct($label, $type, $id, $name, $value = null, $checked = null)
    {
        $this->label = $label;
        $this->type = $type;
        $this->id = $id;
        $this->name = $name;
        $this->value = $value;
        $this->checked = $checked;
    }

    /*
     * @return string
     */
    public function render()
    {
        switch ($this->type){
            case Input::TEXT:
                $mainClass = "form-group row";
                $labelClass = "col-sm-2 col-form-label";
                break;
            case Input::RADIO:
                $mainClass = "form-check";
                $labelClass = "form-check-label";
                break;
            default:
                $mainClass = "";
                $labelClass = "";
        }

        $label = '<label class="' . $labelClass . '" for="' . $this->getId() . '">' . $this->getLabel() . "</label>";

        $content = '<div class="' . $mainClass . '">';
        if($this->type == Input::TEXT) $content .= $label . '<div class="col-sm-10">';
        $content .= '<input class="form-check-input" type="' . $this->getType() .'"';
        $content .= ' id="' . $this->getId() . '"';
        $content .= ' name="' . $this->getName() . '"';
        if($this->value != null) $content .= ' value="' . $this->getValue() . '"';
        if($this->checked != null) $content .= ' checked="' . $this->getChecked() . '"';
        $content .= '>';
        if($this->type == Input::TEXT) $content .= '</div>';
        else $content .= $label;
        $content .= '</div>';


        return $content;
    }

    /**
     * @return string
     */
    public function getLabel()
    {
        return $this->label;
    }

    /**
     * @param string $label
     */
    public function setLabel($label)
    {
        $this->label = $label;
    }

    /**
     * @return string
     */
    public function getType()
    {
        return $this->type;
    }

    /**
     * @param string $type
     */
    public function setType($type)
    {
        $this->type = $type;
    }

    /**
     * @return string
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @param string $id
     */
    public function setId($id)
    {
        $this->id = $id;
    }

    /**
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @param string $name
     */
    public function setName($name)
    {
        $this->name = $name;
    }

    /**
     * @return null|string
     */
    public function getValue()
    {
        return $this->value;
    }

    /**
     * @param null|string $value
     */
    public function setValue($value)
    {
        $this->value = $value;
    }

    /**
     * @return null|string
     */
    public function getChecked()
    {
        return $this->checked;
    }

    /**
     * @param null|string $checked
     */
    public function setChecked($checked)
    {
        $this->checked = $checked;
    }

}
?>

    

Fieldset.php

<?php
namespace App\GereckeFr\CoursBundle\POO\Ex04;

class Fieldset extends ComplexElement
{
    /** var $legend string */
    private $legend;

    /**
     * Fieldset constructor.
     * @param $legend string
     * @param $elements HtmlElement[]
     */
    public function __construct($legend, $elements = null)
    {
        $this->legend = $legend;
        $this->elements = $elements;
    }

    /**
     * @return string
     */
    public function render()
    {
        $content = "<fieldset class='form-group'><div class='row'>\n<legend class='col-form-label col-sm-2 pt-0'>" . $this->getLegend() . "</legend>\n";
        if ($this->getElements() != null) {
            foreach ($this->elements as $element) {
                $content .= $element->render();
            }
        }
        $content .= "</div></fieldset>\n";

        return $content;
    }

    /**
     * @return mixed
     */
    public function getLegend()
    {
        return $this->legend;
    }

    /**
     * @param mixed $legend
     */
    public function setLegend($legend)
    {
        $this->legend = $legend;
    }
}
    

SimpleElement.php

<?php
namespace App\GereckeFr\CoursBundle\POO\Ex04;

class SimpleElement implements HtmlElement
{
    /** @var $content string */
    private $content;

    /**
     * HtmlContent constructor.
     * @param string $content
     */
    public function __construct($content)
    {
        $this->content = $content;
    }

    public function render()
    {
        return $this->content . "\n";
    }
}
    

HtmlElement.php

<?php
namespace App\GereckeFr\CoursBundle\POO\Ex04;

Interface HtmlElement
{
    /*
     * @return string
     */
    public function render();
}