Contrôleurs

Un contrôleur est une classe PHP héritant de Ubiquity\controllers\Controller et fournissant un point d’entrée dans l’application.
Les contrôleurs et leurs méthodes définissent les URLs accessibles.

Création de contrôleur

La méthode la plus facile pour créer un contrôleur est de le faire depuis les devtools.

A partir de l’invite de commande, aller dans le dossier du projet.
Pour créer le contrôleur Products, utiliser la commande :

Ubiquity controller Products

Le contrôleur Products.php créé dans le dossier app/controllers du projet.

app/controllers/Products.php
1namespace controllers;
2/**
3 * Controller Products
4 */
5class Products extends ControllerBase{
6
7public function index(){}
8
9}

Il est maintenant possible d’accéder à l’URL (la méthode index est sollicitée par défaut) :

example.com/Products
example.com/Products/index

Note

Un contrôleur peut être créé manuellement. Dans ce cas, il doit respecter les règles suivantes :

  • La classe doit être définie dans le dossier app/controllers

  • Le nom de la classe doit correspondre au nom du fichier php

  • La classe doit hériter de ControllerBase et doit être définie dans le namespace controllers

  • Elle doit surdéfinir la méthode abstraite index

Méthodes

public

Le second segment de l’URL détermine la méthode publique du contrôleur sollicitée.
La méthode « index » est appelée par défaut, si le second segment est vide.

app/controllers/First.php
1namespace controllers;
2class First extends ControllerBase{
3
4   public function hello(){
5      echo "Hello world!";
6   }
7
8}

La méthode hello du contrôleur First met à disposition les URL suivantes :

example.com/First/hello

Arguments de méthode

Les arguments d’une méthode doivent être passés dans l’url, excepté s’ils sont optionnels.

app/controllers/First.php
namespace controllers;
class First extends ControllerBase{

public function says($what,$who='world') {
   echo $what.' '.$who;
}

}

La méthode hello du contrôleur First met à disposition les URL suivantes :

example.com/First/says/hello (says hello world)
example.com/First/says/Hi/everyone (says Hi everyone)

private

Les méthodes privées ou protégées ne sont pas accessibles depuis l’URL.

Contrôleur par défaut

Le contrôleur par défaut peut être défini par le biais du Router, dans le fichier services.php

app/config/services.php
Router::start();
Router::addRoute("_default", "controllers\First");

Dans ce cas, l’accès à l’URL « exemple.com/ » charge le contrôleur First et appelle la méthode par défaut index.

Chargement des vues

chargement

Les vues sont stockées dans le dossier app/views. Elles sont chargées à partir des méthodes du contrôleur.
Par défaut, il est possible de créer des vues en php, ou avec twig.
Twig est le moteur de template par défaut pour les fichiers html.

Chargement des vues php

Si l’extension du fichier n’est pas spécifiée, la méthode loadView charge un fichier php.

app/controllers/First.php
namespace controllers;
class First extends ControllerBase{
   public function displayPHP(){
      //loads the view app/views/index.php
      $this->loadView('index');
   }
}

Chargement des vues twig

Si l’extension du fichier est html, la méthode loadView charge un fichier twig html.

app/controllers/First.php
namespace controllers;
class First extends ControllerBase{
   public function displayTwig(){
      //loads the view app/views/index.html
      $this->loadView("index.html");
   }
}

Chargement par défaut de vue

Si vous utilisez la méthode de dénomination des vues par défaut :
La vue par défaut associée à une action dans un contrôleur est située dans le dossier views/controller-name/action-name :

views
           Users
          info.html
app/controllers/Users.php
1 namespace controllers;
2
3 class Users extends BaseController{
4   ...
5   public function info(){
6      $this->loadDefaultView();
7   }
8}

Variables associées à une vue

Une des missions du contrôleur est de passer des variables à la vue.
Ceci peut être fait au chargement de la vue, à partir d’un tableau associatif :

app/controllers/First.php
class First extends ControllerBase{
   public function displayTwigWithVar($name){
      $message="hello";
      //loads the view app/views/index.html
      $this->loadView('index.html', ['recipient'=>$name, 'message'=>$message]);
   }
}

Les clés du tableau associatif créent des variables du même nom dans la vue.
Utilisation de ces variables dans Twig :

app/views/index.html
<h1>{{message}} {{recipient}}</h1>

Les variables peuvent également être passées avant le chargement de la vue :

//passing one variable
$this->view->setVar('title','Message');
//passing an array of 2 variables
$this->view->setVars(['message'=>$message,'recipient'=>$name]);
//loading the view that now contains 3 variables
$this->loadView('First/index.html');

retour de l’affichage d’une vue dans une chaîne

Il est possible de charger une vue, et de retourner le résultat dans une chaîne, en mettant à true le 3ème paramètre de la méthode loadview :

$viewResult=$this->loadView("First/index.html",[],true);
echo $viewResult;

chargement de plusieurs vues

Une action peut charger plusieurs vues

app/controllers/Products.php
namespace controllers;
class Products extends ControllerBase{
   public function all(){
      $this->loadView('Main/header.html', ['title'=>'Products']);
      $this->loadView('Products/index.html',['products'=>$this->products]);
      $this->loadView('Main/footer.html');
   }
}

Important

Une vue est souvent partielle. Il est donc important de ne pas intégrer systématiquement les balises html et body définissant une page html complète.

organisation des vues

Il est conseillé d’organiser les vues en dossiers. La méthode la plus recommandée est de créer un dossier par contrôleur, et d’y stocker les vues associées.
Pour charger la vue index.html, stockée dans app/views/First :

$this->loadView("First/index.html");

initialize et finalize

La méthode initialize est automatiquement appelée avant chaque action sollicitée, la méthode finalize après chaque action.

Exemple d’utilisation des méthodes initialize et finalize créées automatiquement au sein d’un nouveau projet :

app/controllers/ControllerBase.php
namespace controllers;

use Ubiquity\controllers\Controller;
use Ubiquity\utils\http\URequest;

/**
 * ControllerBase.
 */
abstract class ControllerBase extends Controller{
   protected $headerView = "@activeTheme/main/vHeader.html";
   protected $footerView = "@activeTheme/main/vFooter.html";

   public function initialize() {
      if (! URequest::isAjax ()) {
         $this->loadView ( $this->headerView );
      }
   }

   public function finalize() {
      if (! URequest::isAjax ()) {
         $this->loadView ( $this->footerView );
      }
   }
}

Contrôle d’accès

Le contrôle d’accès à un contrôleur peut être effectué manuellement, à l’aide des méthodes isValid et onInvalidControl.

La méthode isValid doit retourner un booléen permettant de définir si l’action sollicitée passée en paramètre est accessible.

Dans l’exemple suivant, l’accès aux actions du contrôleur IndexController n’est possible que si une variable de session activeUser existe :

app/controllers/IndexController.php
class IndexController extends ControllerBase{
...
   public function isValid($action){
      return USession::exists('activeUser');
   }
}

Si la variable activeUser n’existe pas, une erreur unauthorized 401 est renvoyée.

La méthode onInvalidControl permet de personnalisé le comportement de l’accès non autorisé :

app/controllers/IndexController.php
class IndexController extends ControllerBase{
   ...
   public function isValid($action){
      return USession::exists('activeUser');
   }

   public function onInvalidControl(){
      $this->initialize();
      $this->loadView('unauthorized.html');
      $this->finalize();
   }
}
app/views/unauthorized.html
<div class="ui container">
   <div class="ui brown icon message">
      <i class="ui ban icon"></i>
      <div class="content">
         <div class="header">
            Error 401
         </div>
         <p>You are not authorized to access to <b>{{app.getController() ~ "::" ~ app.getAction()}}</b>.</p>
      </div>
   </div>
</div>

Il est aussi possible de gérer le contrôle d’accès à partir des AuthControllers

Redirection

Une redirection n’est pas un simple appel à une action d’un contrôleur.
La redirection sollicite également les méthodes initialize et finalize, ainsi que le contrôle d’accès.

La méthode forward peut être invoquée sans la sollicitation des méthodes initialize et finalize.

Il est possible d’effectuer une redirection vers une route par son nom.

Injection de dépendances

Voir Dependency injection

namespaces

Le namespace des contrôleurs est défini par défaut à controllers dans le fichier app/config/config.php.

Classe de base

L’héritage peut être utiliser pour factoriser le comportement des contrôleurs.
La classe BaseController est créée par défaut au sein des nouveaux projets dans cette logique.

Classe de base contrôleur spécifiques

Classe contrôleur

rôle

Contrôleur

Classe de base pour tous les contrôleurs

SimpleViewController

Classe de base associée à un moteur de template php basique (pour utilisation avec des micro-services)

SimpleViewAsyncController

Classe de base associée avec un moteur de template php pour les serveurs asynchrones