Training #2 : Avancement de PHPresentation

PHPresentation a bien avancé ces derniers jours. Le confinement me permet d’avancer un peu et mon job est en stand-by… Il y a de quoi faire !

J’ai donc passé un peu de temps sur PHPresentation. Il me manquait deux choses avant de pouvoir prétendre à une version fonctionnelle :

  • Ordonner le rendu des composants dans l’ordre d’ajout
  • Ajouter quelques options pour personnaliser les composants

J’ai donc ajouté ces éléments dans les derniers commits et essayé de trouver une syntaxe assez intuitive pour les options.

La première page avec la nouvelle option de personnalisation qui permet de définir un logo pour votre présentation.

Les options

Il y a pas mal d’options par objet. Je les détailles précisément dans la documentation (nouvellement créée). Voici la syntaxe que j’ai choisie pour ajouter les options. Ca ressemble un peu aux forms de Symfony :

->button('https://github.com/JuGid/PHPresentation', 'PHPresentation',[
               'new_tab'=>true,
               'badge'=>'badge',
               'bacolor'=>'warning'
             ])

J’obtiens un tableau avec les options et leurs valeurs. En utilisant cela, je le vérifie en fonctions des options autorisées.

Vérification des options

Chaque composant dépend de la classe abstraite “PHPComponent”. Cette classe définie la méthode suivante :

/**
  * Define all valid options for validation
  *
  * @return array Array of options with ['option_name'=> ['valid_values']] or ['option_name'=>null] if it doesn't need values
  */
  abstract public function options();

Qui est ensuite redéfinie dans les composants qui en héritent (en clair, tous)

public function options() {
    return [
      'content'=>null,
      'text_align'=>['center', 'right', 'left']
    ];
  }

Cette méthode permet de définir les options disponibles et leurs valeurs autorisées. Null correspond à une option qui a une valeur qui n’est pas prédéfinie.

Exemple de composants block avec l’utilisation de différentes options.

Lors de la vérification, il suffit de vérifier que l’option et la valeur passée est bien valide.

  /**
  * Verify if the passed options are valid.
  *
  */
  public function verify() {
    $valid_options = $this->options();

    foreach($this->options['options'] as $option=>$value) {
      if(!array_key_exists($option, $valid_options)) {
        throw new \Exception('The option '.$option. ' is not a valid option name for '.get_class($this));
      }

      if(null !== $valid_options[$option] && !in_array($value, $valid_options[$option])) {
        throw new \Exception('The value '.$value.' is not a valid value for option '. $option . ' for '.get_class($this));
      }

    }
    return true;
  }

Ce n’est peut-être pas la manière la plus maintenable, mais elle fonctionne parfaitement bien et n’a pas lieu de changer dans les futures versions.

Ordonner le rendu des composants

Lors du rendu des composants, j’utilise la classe PHPComponentBuilder qui permet de créer les composants sur un slide. Ce builder utilisait deux variables :

  • $components : qui stock les composants déjà instanciés
  • $unresolved_components : qui stock les composants au format “texte”.

Lorsqu’une fonction est appelée comme “button” ou “text”, les composants sont ajoutés au builder du slide dans $unresolved_components. Par contre, un beginGrid() ou beginRow() permet d’ajouter un objet PHPGrid ou PHPRow directement dans le builder et directement instanciés.

De ce fait, lorsque je lançais le build, les composants “unresolved” étaient ajoutés à “components” et render suivant l’ordre de “components”. Pour synthétiser, si vous ajoutiez un text puis un bouton, puis vous ajoutiez une grille, alors la grille passait avant le texte et le bouton.

Aujourd’hui, tous les composants sont stockés dans un tableau “$ordered_components” puis, s’ils ne sont pas instanciés, vont le devenir dans la variable “$components”.

Vous pouvez voir le code en entier sur le Github.

  public function add($type, $options) {
    if(null === $type && !$type instanceof PHPComponentInterface && !is_string($type)) {
      throw new \Exception('Unexpected type for the component.');
    }

    $this->ordered_components[] = [$type, $options];
  }

public function createViews() {
    if($this->notBuildedComponentExists()) {
      $this->create();
    }

    $views = array();
    foreach($this->components as $comp) {
      $views[] = $comp->render();
    }
    return $views;
  }

public function create() {
    foreach($this->ordered_components as $component) {
      if(!$component[0] instanceof PHPComponentInterface) {
        $this->addComponent($this->factory->buildComponent($component));
      } else {
        $this->addComponent($component[0]);
      }
    }
  }

D’autres options et features vont arriver dans les prochains jours. Je me concentre maintenant sur la responsivité des slides, mais aussi sur le fait de bloquer l’ajout de composants possibles sur un même slide et ce pour éviter des mauvaises surprises.

La page d’exemple des boutons avec un exemple de PHPGrid

Laisser un commentaire