Symfony en action I M V Controleur.

Slides:



Advertisements
Présentations similaires
PHP5 its a kind of magic. Chargement automatique function __autoload( $nom_classe ) { require_once('obj/'.$nom_classe.'.class.php'); } si on exécute le.
Advertisements

IChannelIPrivilegedIMultithreadedIServantICacheableIMimeResponse Type custom : les interfaces de programmations IChannel : canal standard, stateful 5 méthodes.
Séparation des préoccupations (c) 2004, Audrey Occello, LF8 MOC Seconde partie Un exemple de programmation orientée Aspect avec AspectJ.
PILOTE - Sous Projet PILOTE SOUS-PROJET 5 Cyril Carrez, Elie Najm, Alexandre Tauveron.
PILOTE - Sous Projet PILOTE SOUS-PROJET 5 Cyril Carrez, Elie Najm, Alexandre Tauveron.
Symfony generators. contexte Répétition de limplémentation des méthodes CRUD pour ls objets métier Commande symfony permettant dinitialiser un module.
Symfony i18n. terminologie internationalization = i18n –Un même contenu traduit en plusieurs langue, éventuellement converti en différents formats localization.
Symfony configuration.
Symfony Un projet français 1 ère version octobre 2005 Fabien Potencier PDG de sensio Lab développeur François Zanonitto écrit.
Symfony Liens & routing.
Symfony Formulaires.
Design Pattern MVC En PHP5.
PHP5 its a kind of magic. Chargement automatique function __autoload( $nom_classe ) { require_once('obj/'.$nom_classe.'.class.php'); } si on exécute le.
PHP mySQL Extension php_mysql. Connexion à une base de données Établir une connexion mysql_connect(string server, string username, string password) –permet.
Symfony
Jérôme CUTRONA PHP et bases de données Jérôme CUTRONA 01:07:51 Programmation Web
Bases de données Objet singleton pour la connexion
Windows XP Professionnel
Integration serveur Data Access Layer Web Service Service1.asmx BankAccess FinanceAccess CLIENTS Business Logic Layer Finance Portfolio SOURCE DE DONNEES.
Integration serveur Data Access Layer Web Service Service1.asmx BankAccess FinanceAccess CLIENTS Business Logic Layer Finance Portfolio SOURCE DE DONNEES.
High Frequency Trading Introduction. Séminaires de 30 minutes, une fois par semaine (8 en tout) Sujets abordés – Définition dun algorithme et introduction.
Les entrées /sorties en Java François Bonneville
Enesys RS Data Extension
Processworks / 3DQuikForm Présentation Denis AUGUSTE Lycée de Lorgues.
Bonnes pratiques ez publish
Connexion base de données
Techniques Internet de Base Licence 2 (Info, Maths, PC/PA) Université Jean Monnet Ruggero G. PENSA
10 Copyright © Oracle Corporation, Tous droits réservés. Autres concepts relatifs aux déclencheurs.
Le langage PHP 5.
Cours VHDL Chap 3: sémantique VHDL
Struts 1 & 2 Tlohi ibtissam Tabit boutaina Ilias bouras
Le langage ASP Les variables d'environnement HTTP avec Request.
Langages du Web Sémantique
La programmation objet Illustration de la POO en Pascal
Ecole Supérieure Privée de ingénierie et de technologie année universitaire :2013/2014 Cross-Plateform Cours JavaScript.
Historique de SystemC Regroupe 4 courants didées: SCENIC Project : Synopsys+UC Irvine Philips System-Level Data Types, VSIA SLD DWG IMEC, Hardware-Software.
1 Développement des Applications des Bases de Données Chapitre 6, Sections
Master 1 SIGLIS Java Lecteur Stéphane Tallard Chapitre 5 – Héritage, Interfaces et Listes génériques.
SQL Injection Réalisée par: BEN NASR Houssem GMATI Idriss HADDAD Mohamed Aymen HAKIM Youssef.
Structures de données IFT-2000 Abder Alikacem La librairie STL du C++ Département dinformatique et de génie logiciel Édition Septembre 2009.
BBoard Fonctionne pas. BBoard Copier le répertoire dézippé dans le répertoire modules de post nuke Renommer ce répertoire en yabbse. Entrer le chemin.
1 CSI 2532 Lab5 Installation de JDBC Février 13, 2012.
Database Management Systems 3ed, R. Ramakrishnan and J. Gehrke1 SQL: Contraintes et Triggers Chapitre 5,
MySQL Création des sites dynamiques
JSP (Java Server Pages)
AJAX.
Servlets. 2 H. Fauconnier M2-Internet Contenu dynamique Perl/cgi indépendant de la plateforme Extensions du serveur exemple ASP M2-Internet 3 H. Fauconnier.
Cours 11 Threads. Chapitre X threads threadPOO-L3 H. Fauconnier3 Threads threads: plusieurs activités qui coexistent et partagent des données exemples:
MODEX WEB BAPTISTE DESPREZ Un peu de sécurité. Avant dentrer dans le vif du sujet JavaScript Langage de script (comme PHP) Exécuté par votre navigateur.
Fabienne Boyer Laboratoire LIG (INRIA-UJF-INPG) Projet SARDES, INRIA Rhône-Alpes APACHE/VELOCITY.
Chapitre 3 Les bibliothèques de balises JSP et la JSTL
1 13/06/03DCI Présentation du groupe DCI Nicolas VialaAntoine Jacquet Projet site WEB DESS IF 2 ème itération.
JavaScript Nécessaire Web.
PHP 5° PARTIE : LES COOKIES
JDBC L'API JDBC est utilisée pour utilisée pour intéragir avec une base de données.
0 Objectifs de la session n°1  Revenir sur toutes les bases théoriques nécessaires pour devenir un développeur Web,  Découvrir l’ensemble des langages.
 Requêtes MySQL en PHP Introduction
Module 7 : Utilisation de requêtes élaborées
Struts.
Séminaire INGI 2591 Attaques Web Accardo Nicolas INFO 22 Blerot Olivier INFO 22 Couvreur Pascal INFO 22 Depry Fabian INFO 23.
 Formulaires HTML : traiter les entrées utilisateur
Protocole HTTP, cookies, sessions, authentification
Conception de Site Webs Interactifs Cours 7 Patrick Reuter
Initiation au web dynamique Licence Professionnelle.
Les Servlets Présentation Cycle de vie Principe de fonctionnement
3 Copyright © Oracle Corporation, Tous droits réservés. Créer des fonctions.
Les Java Server Pages Dans ce chapitre, nous allons :
Les bases de données Séance 8 Jointures.
APP-TSWD Apprentissage Par Problèmes Techniques des Sites Web Dynamiques Licence Professionnelle FNEPI Valérie Bellynck, Benjamin Brichet-Billet, Mazen.
Transcription de la présentation:

Symfony en action I M V Controleur

controleur couche contenant le code liant la partie logique et la présentation Décomposé en contrôleur principal (front controller) : unique point d'entrée de l'application chargement configuration Détermine les actions à effectuer actions : code applicatif Vérifient l'intégrité des requêtes préparent les données pour les templates (vues) Les requêtes, les réponses et les objets de sessions permettent l'accès à des informations particulières comme les headers des réponses et les données persistantes. souvent utilisées par le contrôleur principal. filtres : portions de codes exécutées à chaque requête, avant ou après l'action

Contrôleur principal Prend toutes les requêtes web en charge Utilise le système de routage pour déterminer le module et l’action à patir de l’URL http://localhost/index.php/mymodule/myaction appelle le script index.php (contrôleur principal) qui traduira l’url par un appel à l'action myaction du module mymodule

Séquences d’exécution du controleur principal Définir les constantes. Déterminer les chemins des bibliothèques Symfony. Charger et initialiser les classes du coeur du framework. Charger la configuration. Décoder la requête URL afin d'identifier les actions à effectuer et les paramètres de la requête. Si l'action n'existe pas, faire une redirection sur l'action 404 error. Activer les filtres (par exemple, si les requêtes nécessitent une authentification). Exécuter les filtres une première fois. Exécuter l'action et générer la présentation. Exécuter les filtres une seconde fois. Renvoyer la réponse

Code du controleur par défaut <?php define('SF_ROOT_DIR', realpath(dirname(__FILE__).'/..')); define('SF_APP', 'myapp'); define('SF_ENVIRONMENT', 'prod'); define('SF_DEBUG', false); require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR. 'apps'.DIRECTORY_SEPARATOR. SF_APP.DIRECTORY_SEPARATOR. 'config'.DIRECTORY_SEPARATOR. 'config.php‘); sfContext::getInstance()->getController()->dispatch(); Etape 1 Etape 2 à 4 Etape 5 à 7 Chaîne des filtres Etape 8 à 10

Un nouveau contrôleur pour un nouvel environnement Création d’un environnement staging Créer web/myapp_staging.php changer la valeur de la constante SF_ENVIRONMENT à staging Configuration spécifique à l’environnement staging dans app.yml staging: mail: webmaster: dummy@mysite.com contact: dummy@mysite.com all: webmaster: webmaster@mysite.com contact: contact@mysite.com

Les batchs scripts en ligne de commande (ou lancer via cron) accédant à l'ensemble des classes symfony, y compris celles spécifiques au projet. Similaire à un controleur principal de l’étape 1 à 4 Initialisation d’un batch symfony init-batch staging myapp script.php

Code typique d’un batch <?php define('SF_ROOT_DIR', realpath(dirname(__FILE__).'/..')); define('SF_APP', 'myapp'); define('SF_ENVIRONMENT', 'prod'); define('SF_DEBUG', false); require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR. 'apps'.DIRECTORY_SEPARATOR. SF_APP.DIRECTORY_SEPARATOR. 'config'.DIRECTORY_SEPARATOR. 'config.php‘);

Les actions Groupées par module dans /apps/myapp/modules/mymodule/actions/actions.class.php Contiennent la logique de l’application Utilisent le modèle Définissent les variables pour les templates Une URL définit une action d’un module ainsi que les paramètres avec lesquels elle sera exécutée http://localhost/index.php/myModule/myAction?var1=val1&...&varn=valn

Convention de nommage La classe contenant les actions de myModule se nomme myModuleActions et hérite de sfActions L’action myAction de myModule est une méthode de la classe myModuleActions nommée executeMyAction Si la taille d'une classe action grandit trop, il faudra probablement faire le refactoring de celle-ci et déplacer une partie de son code dans la couche modèle

Code générique Ajouter une action c’est ajouter une nouvelle méthode execute à l’objet sfActions /apps/myapp/modules/mymodule/actions/actions.class.php class myModuleActions extends sfActions { public function executeMyAction() … }

Syntaxe alternative possibilité d’avoir un fichier par action myapp/modules/mymodule/actions/myAction.class.php <?php class myAction extends sfAction { public function execute() ... }

Récupération d’informations via la classe action class myModuleActions extends sfActions { public function executeMyAction() $password = $this->getRequestParameter('password'); $moduleName = $this->getModuleName(); $actionName = $this->getactionName(); $request = $this->getRequest(); $userSession = $this->getUser(); $response = $this->getResponse(); $controller = $this->getController(); $context = $this->getContext(); $this->setVar('foo', 'bar'); $this->foo = 'bar'; }

Le contexte $this->getContext()  sfContext::getInstance() Accés à tous les objets du noyau symfony sfController: objet contrôleur (->getController()) sfRequest: objet requêtes (->getRequest()) sfResponse: objet réponse (->getResponse()) sfUser: objet session utilisateur (->getUser()) sfDatabaseConnection: connexion à la bdd (->getDatabaseConnection()) sfLogger: objet de log (->getLogger()) sfI18N: l'objet d'internationalisation (->getI18N()) sfContext::getInstance() est utilisable n’importe où dans le code(modèle, vue, controleur, helper, fichier de conf, etc …)

Terminaison d’une action La valeur retournée par une action (ici myAction) détermine le template à utiliser Constantes de classe sfView return sfView::SUCCESS; templates/myActionSuccess.php (implicite) return sfView::ERROR; templates/myActionError.php return sfView::NONE; Pas de template appelé (batch, AJAX, etc …) Template personnalisé Return ‘myResult’; templates/myActionMyResult.php

Terminaisons d’actions particulières Envoyer une réponse HTML sans passer par une vue public function executeIndex() { $this->getResponse()->setContent("<html><body>hi!</body></html>");   return sfView::NONE; } Équivalent à executeIndex() { return $this->renderText("<html><body>Hello, World!</body></html>");

Terminaisons d’actions particulières II Ne renvoyer que les en-têtes http public function executeRefresh() { $output = '<"title","My basic letter"],["name","Mr Brown">'; $this->getResponse()->setHttpHeader("X-JSON", '('.$output.')');   return sfView::HEADER_ONLY; } Renvoyer un template spécifique $this->setTemplate('myCustomTemplate'); Pas d’instruction return

Passer à une autre action Si l'action précède l'appel à la nouvelle action (conserve la même URL) $this->forward('otherModule', 'index'); Si le résultat de l'action est une redirection web: $this->redirect('otherModule/index'); $this->redirect('http://www.google.com/'); Methode post : redirect péréfrable pour éviter la ressoumission au refresh Redirection vers une erreur 404 $this->forward404(); $this->forward404If(); $this->forward404Unless();

Code partagé par les actions class mymoduleactions extends sfactions { public function preExecute() // Le code à insérer ici est executé au début de chaque appel d'action } public function executeList() $this->myCustomMethod(); public function postExecute() // Le code inséré ici est exécuté à la fin de chaque appel de l'action protected function myCustomMethod() //partagée à condition qu'elles ne débutent pas par le mot "execute", // déclarée protected ou private

valeurs de la requête Information sur la requête getMethod() méthode requête `sfRequest::GET` ou `sfRequest::POST` getMethodName() POST ou GET getHttpHeader('Server') Valeur d'une entête http donnée getCookie('foo') Valeur d'un cookie donné isXmlHttpRequest() Est-ce une requête AJAX? isSecure() Est-ce une requête SSL?

valeurs de la requête Paramètres de la requête hasParameter('foo') Y a-t-il un paramètre foo dans la requête? getParameter('foo' ) Quelle est la valeur du paramètre foo? getParameterHolder()->getAll() Tableau de tous les paramètres de la requête informations sur le navigateur getLanguages() Tableau des langages acceptés getCharsets() Tableau des charsets appelés getAcceptableContentTypes() Tableau des content-types acceptés

valeurs de la requête Information sur l’URI getUri() URI entière getPathInfo() information sur le path getReferer() L’url qui a mené à l’uri courante getHost() Nom de l’hôté getScriptName() Path du front controller et son nom

Petit rappel class mymoduleActions extends sfActions { public function executeIndex() $hasFoo = $this->getRequest()->hasParameter('foo'); $hasFoo = $this->hasRequestParameter('foo'); // Shorter $foo = $this->getRequest()->getParameter('foo'); $foo = $this->getRequestParameter('foo'); // Shorter }

Upload de fichier class mymoduleactions extends sfActions { public function executeUpload() if ($this->getRequest()->hasFiles()) foreach ($this->getRequest()->getFileNames() as $fileName) $fileSize = $this->getRequest()->getFileSize($fileName); $fileType = $this->getRequest()->getFileType($fileName); $fileError = $this->getRequest()->hasFileError($fileName); $uploadDir = sfConfig::get('sf_upload_dir'); $this->getRequest()->moveFile('file', $uploadDir.'/'.$fileName); }

Session utilisateur Les variable de sessions sont accessibles via l’objet sfUser lecture $this->getUser()->getAttribute('nickname'); écriture $this->getUser()->setAttribute('nickname‘,’mazenovi’); supression $this->getUser()->getAttributeHolder() ->remove('nickname'); suppression de toutes les variables $this->getUser()->getAttributeHolder()->clear(); Accessible dans les templates via la variable $sf_user $sf_user->getAttribute(‘nickname’) $sf_user->setAttribute(‘nickname’,’mazenovi’)

Attributs Flash attribut éphémère qui peut être défini puis oublié lecture $this->getFlash('attrib'); écriture $this->setFlash('attrib', $value); Accessible dans les templates via la variable $sf_flash $sf_flash->get (‘attrib’) $sf_flash->set (‘attrib’,$value))

Gestion des sessions Le cookie de session de symfony est appelé symfony (modifiable) apps/myapp/config/factories.yml all: storage: class: sfSessionStorage param: session_name: my_cookie_name

Configuration des sessions Pour passer la session via l’url (déconseillé), modifier le php.ini session.use_trans_sid = 1 Paramétrer la durée de vie d’une session apps/myapp/config/settings.yml default: .settings: timeout: 1800 # Session lifetime in seconds

Gérer les sessions avec MySQL Gérer dans des fichiers par défaut apps/myapp/config/factories.yml all: storage: class: sfMySQLSessionStorage param: db_table: SESSION_TABLE_NAME database: DATABASE_CONNECTION

Sécurisé une action apps/myapp/modules/mymodule/config/security.yml read: is_secure: off update: is_secure: on delete: credentials: admin all:

Autorisations complexes apps/myapp/modules/mymodule/config/security.yml editArticle: credentials: [ admin, editor ] # admin and editor publishArticle: credentials: [[ admin, superuser ]] # admin or superuser userManagement: credentials: [[root, [supplier, [owner, quasiowner]], accounts]] # root OR (supplier AND (owner OR quasiowner)) OR accounts

Authentification authentifier déconnecter vérifier l’authetification $this->getUser()->setAuthenticated(true); déconnecter $this->getUser()->setAuthenticated(false); vérifier l’authetification $this->getUser()->getAuthenticated();

Autorisation ajouter une autorisation ajouter des autorisations $this->getUser()->addCredential(‘foo’); ajouter des autorisations $this->getUser()->addCredentials(‘foo’,’bar’); tester une autorisation $this->getUser()->hasCredential(‘foo’); tester des autorisations $this->getUser()->hasCredential(array(‘foo’,’bar’)); supprimer une autorsiation $this->getUser()->removeCredential(‘foo’); supprimer toutes les autorsiations $this->getUser()->clearCredentials();

Validation d’une action au niveau controleur validateActionName: méthode de validation retournant true ou false. Si elle n'existe pas la méthode de l'action est directement exécutée. handleErrorActionName : méthode appelée quand la méthode de validation retourne false. Si elle n'existe pas, le template Error est affiché. executeActionName : méthode d'action. Elle doit exister pour toutes les actions.

Validation d’une action - code typique - class mymoduleactions extends sfActions { public function validateMyaction() return ($this->getRequestParameter('id') > 0); } public function handleErrorMyaction() $this->message = "Invalid parameters"; return sfView::SUCCESS; public function executeMyaction() $this->message = "The parameters are correct";

Processus de validation

Les filtres Classes de filtres permettant d’exécuter du code avant l’exécution de l’action ou avant l’envoie de la requête Similaire à preExecute et postExecute mais pour toute l’application Tout filtre hérite de la classe sfFilter et contient au moins une méthode execute qui prend un objet $filterChain en paramètre Le filtre devra appeler dans son code $filterChain->execute() afin de passer au filtre suivant de la chaîne Le code situé avant $filterChain->execute() est exécuté avant l’action Le code situé après $filterChain->execute() est exécuté après l’action

La chaîne de filtres par défaut myapp/config/filters.yml rendering: ~ web_debug: ~ security: ~ # Generally, you will want to insert your own filters here cache: ~ common: ~ flash: ~ execution: ~

Les filtres core Le ~ dans myapp/config/filters.yml signifie « héritage » des classes symfony $sf_symfony_data_dir/config/filters.yml rendering: class: sfRenderingFilter # Filter class param: # Filter parameters type: rendering

(dés)activation des filtres Désactiver un filtre web_debug: enabled: off Ne pas supprimer un filtre dans filters.yml (une exception sera levée) Les filtres personnalisés doivent obligatoirement être insérés entre les filtres rendering et execution Il est possible de redéfinir les filtres par défaut (notamment pour modifier le système de sécurité) Il est également possible de désactiver les filtres par défaut dans settings.yml (chaque filtre par défaut possède une condition calculée à partir de ces valeurs)

Filtres personnalisés apps/myapp/lib/rememberFilter.class.php class rememberFilter extends sfFilter { public function execute($filterChain) { // le filtre ne s’exécute qu’une fois même si redirect ou forward if ($this->isFirstCall()) $request = $this->getContext()->getRequest(); $user = $this->getContext()->getUser();   if ($request->getCookie('MyWebSite')) $user->setAuthenticated(true); } }   filter $filterChain->execute();

Filtres personnalisés II Pour passer à une autre action return $this->getContext()->getController()->forward('mymodule', 'myAction'); apps/myapp/config/filters.yml … security: ~ remember: # Filters need a unique name class: rememberFilter param: cookie_name: MyWebSite condition: %APP_ENABLE_REMEMBER_ME% cache: ~

Filtres personnalisés III Il est possible de faire passer des paramètres à un filtre (ici cookie_name) $request->getCookie($this->getParameter('cookie_name') Le paramètre condition détermine si le filtre doit être exécuté Pour être exécuté /apps/myapp/config/app.yml doit contenir all: enable_remember_me: on

Exemple de filtre personnalisé I class sfGoogleAnalyticsFilter extends sfFilter { public function execute($filterChain) { $filterChain->execute(); $googleCode = ' <script src="http://www.google- analytics.com/urchin.js" type="text/javascript"></script> <script type="text/javascript"> uacct="UA-'.$this->getParameter('google_id').'"; urchinTracker(); </script>'; $response = $this->getContext()->getResponse(); $response->setContent(str_ireplace('</body>', $googleCode.'</body>',$response->getContent())); }

Exemple de filtre personnalisé II class sfSecureFilter extends sfFilter { public function execute($filterChain) $context = $this->getContext(); $request = $context->getRequest();   if (!$request->isSecure()) $secure_url = str_replace('http', 'https', $request->getUri());   return $context->getController()->redirect($secure_url); } else $filterChain->execute();

Configuration des modules apps/myapp/modules/mymodule/config/module.yml all: # For all environments enabled: true is_internal: false view_class: sfPHP enabled : (dés)active toutes les actions du module is_internal : les appels aux actions ne se font qu’à parti de l’appli (mail) view_class : hérite de sfView par défaut, mais peuvent hérité d’un autre langage de template (Smarty)