{{tag>tutoriel vetuste programmation mysql phpmyadmin apache}}
----
ERROR 2002 (HY000): Can't connect to local MySQL server through socket /var/run/mysqld/mysqld.sock' (2)
lancer MySQL avant de faire ces manipulations avec la commande suivante dans un terminal :
sudo /etc/init.d/mysql start
Exécutons le scripte de sécurisation avec la commande suivante dans un terminal :
sudo mysql_secure_installation
Des questions simples sont posées et il suffit d'y répondre puis de passer à la suivante.
À la question :
Enter current password for root (enter for none):
Il faut un mot de passe pour bien exécuter le script. Le mot de passe demandé précédemment en fin d'installation de MySQL est ce mot de passe root, il faut donc entrer celui-ci.
Validez votre entrée avec la touche "Entrée".
À la question :
Setting the root password ensures that nobody can log into the MySQL root user without the proper authorisation.
Set root password? [Y/n]
Appuyez sur la touche "Entrée" pour entrer un mot de passe.
New password:
Entrez le mot de passe de votre choix et validez par la touche "Entrée".
À la question :
By default, a MySQL installation has an anonymous user, allowing anyone
to log into MySQL without having to have a user account created for
them. This is intended only for testing, and to make the installation
go a bit smoother. You should remove them before moving into a
production environment.
Remove anonymous users? [Y/n]
Appuyez sur la touche « Entrée » pour supprimer l'utilisateur anonyme créé lors de l'installation.
À la question :
Normally, root should only be allowed to connect from 'localhost'. This
ensures that someone cannot guess at the root password from the network.
Disallow root login remotely? [Y/n]
Vous n'avez pas besoin d'administrer votre base de données à distance pour le moment, ce qui devrait être le cas de la plupart des utilisateurs. Validez par la touche "Entrée". Ainsi, l'utilisateur "root" ne pourra se connecter qu'en local. Sinon tapez la touche "n".
À la question :
Remove test database and access to it? [Y/n]
Validez par la touche "Entrée" pour supprimer la base de données de test créée lors de l'installation.
À la question :
Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.
Reload privilege tables now? [Y/n]
Validez par la touche "Entrée" pour prendre en compte les changements que vous venez de faire et les appliquer immédiatement.
==== Installer PhpMyAdmin ====
ATTENTION : Pendant l'installation de PhpMyAdmin, il vous sera demandé de choisir le serveur Web à configurer. Choisissez avec les touches Flèche vers le haut et Flèche vers le bas la ligne "apache2" et appuyant sur la barre d'espacement la sélectionné cette entrée.
[[:tutoriel:comment_installer_un_paquet|Installez]] [[apt://PhpMyAdmin|PhpMyAdmin]].
Pour vérifier le bon fonctionnement de PhpMyAdmin, rendez-vous à l'URL :
http://localhost/phpmyadmin/
si vous tombez sur une page (not found), Tapez la command
sudo kate /etc/apache2/apache2.conf
et ajoutez à la fin un nouveau ligne
Include /etc/phpmyadmin/apache.conf
Vous arriverez alors sur la page d'authentification de PhpMyAdmin. Entrez alors votre non de compte qui est
root
et le mot de passe choisi lors de la sécurisation de MySQL
Remarque : si votre compte est dupont ne pas mettre dupont comme utilisateur, mais "root" puis le mot de passe sinon vous risquez d'avoir l'erreur #1045 - Access denied for user 'root'@'localhost' en tentant d'accéder à vos bases de données.
- Si tout s'est bien passé, vous devriez être connecté à PhpMyAdmin et pouvoir créer et gérer vos bases de données.
- Si vous arrivez pas à vous connecter à PhpMyAdmin il faut créer un lien symbolique vers MyPhpAdmin, il faut juste faire la commande suivante: " sudo ln -s /usr/share/phpmyadmin /var/www/phpmyadmin "
Il existe déjà deux bases de données, n'y touchez pas. Elles servent au bon fonctionnement de MySQL.
Je vous suggère d'ajouter cette adresse à vos "Marque-pages" (Signets, favoris), vous en aurez besoin plus tard !
==== Modification des droits pour les fichiers du site Web ====
Cette section est utile seulement si vous mettez en ligne votre projet Web et que votre ordinateur devient un serveur en ligne sur Internet, ce qui n'est pas expliqué dans le présent tutoriel.
Le répertoire contenant les sites lus par Apache est par défaut le suivant :
/var/www/
Ses droits par défaut sont :
propriétaire=root
group=root
droits rwXr-Xr-X
Les X signifie droit x pour les répertoires, mais pas pour les fichiers.
Le groupe utilisateur pour Apache est "www-data".
Pour accéder aux fichiers qu'il doit lire, Apache utilise donc en standard le droit "r", mais seul root peut modifier ces fichiers, ce qui n'est pas très pratique. Un ajustement de la politique des droits permet de faciliter l'utilisation de ce répertoire.
Il faut commencer par s'ajouter au groupe d'Apache, le groupe "www-data", alors dans un terminal, on exécute la commande suivante :
sudo addgroup $USER www-data
Par la suite, on modifie les droits du dossier et des fichiers avec les commandes suivantes :
sudo chown -R www-data:www-data /var/www
sudo chmod -R 770 /var/www
Il faut actualiser fermer et rouvrir votre gestionnaire de fichiers (Dolpin ou Konqueror) pour que cela soit pris en compte.
Vous avez maintenant un serveur Apache gérant le PHP avec des bases de données MySQL.
==== Installer Symfony ====
[[:tutoriel:comment_installer_un_paquet|Installez]] [[apt://php5-symfony,php-pear,php5-cli php5-xsl|des paquets et dépendances pour le cadre de travail "framework" Symfony]].
Pour configurer Symfony avec PEAR, entrer les commandes :
sudo pear channel-discover pear.symfony-project.com
sudo pear install symfony/symfony
Si tout s'est bien passé, vous aurez le message suivant :
install ok: channel://pear.symfony-project.com/symfony-1.x.x
Tapez cette comand dans le terminal :
sudo pear install --alldeps http://phing.info/pear/phing-current.tgz
Nous avons un premier niveau d'aide pour Symfony avec la commande suivante :
symfony
La commande suivante nous donne la version installée de Symfony :
symfony -V
C'est tout ce qu'il faut pour Symfony !
===== Installer un nouveau projet =====
==== Préambule ====
Pour notre exemple, nous créons le projet "projet01", dans le dossier "projet01" de votre dossier utilisateur principal (/home/votre_nom_d'utilisateur/projet01).
sudo mkdir /home/votre_nom_d'utilisateur/projet01
Chez moi, cela pourrait donner comme chemin de dossier ce qui suit :
/home/rene/projet01
Si vous procédez différemment, vous prendrez soin d'adapter tout ce qui suit avec votre propre chemin de dossier.
==== Configurer un domaine local virtuel ====
Pour nous donner le plus de latitude possible et pour pouvoir travailler sur plusieurs projets à la fois, nous créons un domaine local virtuel pour chaque projet. Vous pourrez procéder de la même manière pour chacun de vos projets de site Web.
=== Configuration du serveur ===
Ouvrer le fichier /etc/hosts avec la commande suivante dans un terminal :
sudo kate /etc/hosts
Puis ajoutez à la fin de la ligne qui commence par "127.0.0.1", le nom de domaine de notre projet01 :
dev.projet01.com
=== Création du serveur virtuel ===
Créez un nouveau fichier "projet01" pour le serveur virtuel Apache avec la commande suivante dans un terminal :
sudo kate /etc/apache2/sites-available/projet01
Copiez-y les lignes suivantes en remplacent le mot "rene" par votre_nom_utilisateur et projet01 par votre_dossier_projet :
Activons ce nouveau domaine avec la commande suivante dans un terminal :
sudo a2ensite projet01
Pour que ces changements soient pris en compte, il faut relancer le serveur Apache avec la commande suivante :
sudo /etc/init.d/apache2 restart
Entrez l'adresse Web du nouveau projet dans votre navigateur préféré :
dev.projet01.com
Je vous suggère d'ajouter cette adresse à vos "Marque-pages" (Signets, favoris), vous en aurez besoin plus tard !
==== Initialisation du projet ====
Assurez-vous d'être à la racine du dossier "projet01" !
Créons maintenant le canevas de base avec Symfony avec la commande suivante dans le terminal :
sudo symfony generate:project projet01 --orm=Propel
Si vous avez un message d'avertissement pensez à avoir les droits (sudo) car symfony ne dit toujours qu'il faut avoir les permissions
Cette commande génère la structure par défaut des répertoires et crée les fichiers nécessaires d'un projet symfony.
^ Dossier ^ Description ^
| apps | Contient les applications du projet |
| cache | Les fichiers en cache |
| config | Les fichiers de configuration du projet |
| lib | Les librairies et classes du projet |
| log | Les fichiers de logs du framework |
| plugins | Les plugins installés |
| test | Les tests unitaires et fonctionnels |
| web | Le répertoire racine web (voir dessous) |
Pourquoi autant de fichiers ? Un des bénéfices est de standardiser les développements. Grâce à cette structure par défaut des fichiers et répertoires de symfony, n'importe quel développeur connaissant symfony peut reprendre n'importe quel projet. Il pourra naviguer dans le code, de fixer les bogues, et d'ajouter de nouvelles fonctionnalités, etc.
À la racine du projet, un raccourci la commande symfony y est pour faciliter l'écriture des commandes lorsque vous exécutez une tâche dans le terminal. Toutes les commandes symfony doivent maintenant être exécutées à partir du répertoire racine du projet, sauf indication contraire.
=== Création d'application ===
D’abord assurez vous que vous situés sous le répertoire projet symfone, dans notre cas projet01 :
cd /home/nomVotrePC/projet01
Créons l'application frontend en exécutant la commande suivante :
sudo symfony generate:app --escaping-strategy=on --csrf-secret=Unique$ecret frontend
Cette commande crée la structure par défaut des répertoires de l'application dans le dossier apps/frontend.
^ Dossier ^ Description ^
| config | Les fichiers de configuration de l'application |
| lib | Les librairies et classes de l'application |
| modules | Le code de l'application ( MVC ) |
| templates | Les gabarits principaux |
Avec cette commande nous avons passé deux paramètres en options pour la sécurité, "--escaping-strategy" pour activer les échappements pour prévenir des attaques XSS et "--csrf-secret" pour activer les jetons de sessions des formulaires pour prévenir des attaques CSRF.
En passant ces deux options, nous avons sécurisé le développement des deux plus courantes vulnérabilités trouvées sur le web. Symfony va automatiquement prendre les mesures de sécurité pour nous.
Lors de la portabilité du projet sur hébergement sur le Web, nous changerons le chemin absolu de l'installation de symfony par un chemin relatif.
Pour ce faire, vous ouvrirez le fichier requis avec la commande :
kate config/ProjectConfiguration.class.php
Remplacerez la ligne :
require_once '/usr/share/php/symfony/autoload/sfCoreAutoload.class.php';
Par la ligne suivante qui est un chemin relatif si vous y copier le dossier de l'archive de Symfony dans le dossier /home/rene/projet01/lib/vendor :
require_once dirname(__FILE__).'/../lib/vendor/symfony/lib/autoload/sfCoreAutoload.class.php';
De cette façon, nous pourrons déplacer le projet, cela fonctionnera toujours.
Si vous jetez un oeil au répertoire web/, vous trouvez deux fichiers PHP, soit index.php et frontend_dev.php. Ces fichiers sont appelés front controllers. Toutes les requêtes vers l'application sont faites en passant par eux.
Mais pourquoi avoir deux front controllers alors que nous n'avons qu'une seule application ?
Les deux fichiers pointent sur la même application, mais en utilisant deux environnements différents. Lorsque vous développez une application, sauf si vous développez directement sur le serveur de production, vous avez besoin de plusieurs environnements.
- L'environnement de développement. C'est l'environnement utilisé par le développeur pour ajouter de nouvelles fonctionnalités, fixer les bogues, etc.
- L'environnement de tests. C'est l'environnement pour tester automatiquement l'application.
- L'environnement de recette. C'est l'environnement utilisé par le client pour tester l'application et faire un retour sur les bogues.
- L'environnement de production. C'est l'environnement utilisé par l'utilisateur final.
Dans l'environnement de développement, l'application doit centraliser tous les détails d'une requête pour faciliter le débogage, elle doit afficher les exceptions dans le navigateur, mais le système de cache doit être désactivé, car les changements dans le code doivent être pris en compte tout de suite. Donc l'environnement de développement doit être optimisé pour le développeur.
Dans l'environnement de production, l'application doit afficher des messages d'erreur adaptés à la place d'exceptions PHP, et bien sûr, le cache doit être activé. Donc l'environnement de production doit être optimisé pour la performance et l'expérience utilisateur.
Dans Symfony un environnement est un jeu unique de paramètres de configuration et Symfony est installé avec trois d'entre eux : dev, test, et prod.
==== Création de la base du projet ====
Ouvrer fichier du schéma de la base de données avec la commande :
kate config/schema.yml
Copiez-y le texte suivant :
propel:
projet01_category:
id: ~
name: { type: varchar(255), required: true }
projet01_job:
id: ~
category_id: { type: integer, foreignTable: projet01_category, foreignReference: id, required: true }
type: { type: varchar(255) }
company: { type: varchar(255), required: true }
logo: { type: varchar(255) }
url: { type: varchar(255) }
position: { type: varchar(255), required: true }
location: { type: varchar(255), required: true }
description: { type: longvarchar, required: true }
how_to_apply: { type: longvarchar, required: true }
token: { type: varchar(255), required: true, index: unique }
is_public: { type: boolean, required: true, default: 1 }
is_activated: { type: boolean, required: true, default: 0 }
email: { type: varchar(255), required: true }
expires_at: { type: timestamp, required: true }
created_at: ~
updated_at: ~
projet01_affiliate:
id: ~
url: { type: varchar(255), required: true }
email: { type: varchar(255), required: true, index: unique }
token: { type: varchar(255), required: true }
is_active: { type: boolean, required: true, default: 0 }
created_at: ~
projet01_category_affiliate:
category_id: { type: integer, foreignTable: projet01_category, foreignReference: id, required: true, primaryKey: true, onDelete: cascade }
affiliate_id: { type: integer, foreignTable: projet01_affiliate, foreignReference: id, required: true, primaryKey: true, onDelete: cascade }
Avec mysqladmin, nous créons la base de données avec la commande suivante en prenant soin de modifier la commande. Si votre nom d'utilisateur MySQLAdmin est "1111" et que votre mot de passe MySQLAdmin est "22222222" le commande sera :
sudo mysqladmin -u1111 -p2222222 create projet01
Pour indiquer à Symfony la base de données que nous utilisons pour le projet, entrons la commande suivante en prenant soin de modifier la commande. Si votre nom d'utilisateur MySQLAdmin est "1111" et que votre mot de passe MySQLAdmin est "22222222" la commande sera :
sudo symfony configure:database "mysql:host=localhost;dbname=projet01" 1111 22222222
Avec la description de la base de données dans le fichier schema.yml, nous pouvons utiliser les tâches intégrées de l'ORM pour générer les déclarations SQL nécessaires pour créer des tables :
symfony propel:build-sql
Cette commande génère le déclarations SQL dans le répertoire data/sql, optimisées pour le moteur de base de données que nous avons configuré.
Pour créer les tables dans la base de données, entrer la commande suivante dans le terminal :
symfony propel:insert-sql --no-confirmation
L'ORM génère également les classes PHP qui font la correspondance entre les enregistrements des tables et les objets
Générer les fichiers PHP qui seront utilisés pour interagir avec la base de données dans le répertoire lib/model avec la commande suivante :
symfony propel:build-model
En navigant parmi les fichiers générés, vous avez probablement remarqué que Propel génère quatre classes par table.
Les valeurs des colonnes d'un enregistrement peuvent être manipulées par l'objet en utilisant un accesseur (accessors get*() méthode) ou un mutateur (mutators set*() méthode):
$job = new Projet01Job();
$job->setPosition('Web developer');
$job->save();
echo $job->getPosition();
$job->delete();
Vous pouvez également définir les clés étrangères en liant les objets entre eux :
$category = new Projet01Category();
$category->setName('Programming');
$job = new Projet01Job();
$job->setCategory($category);
La tâche propel:build-all est un raccourci pour exécuter les tâches que nous avons vues dans cette section et d'autres. Donc, exécutez cette tâche maintenant pour générer les formulaires et les validateurs du modèle des classes :
symfony propel:build-all
La tâche propel:build-all-load est un raccourci pour la tâche propel:build-all suivie de la tâche propel:data-load.
Comme nous le verrons un peu plus tard, Symfony charge automatiquement les classes PHP pour vous, ce qui signifie que vous n'avez jamais besoin d'utiliser require dans votre code. C'est une des nombreuses choses que Symfony automatise pour les développeurs, mais il y a une contre partie : Chaque fois que vous ajoutez une classe vous devez effacer le cache. Comme la tâche propel:build-model a créé de nouvelles classes, effaçons la cache :
symfony cache:clear
Une tâche Symfony est composée d'un espace de nom et d'un nom de tâche. Chaque tâche a un raccourci avec le moins d'ambiguïté avec les autres tâches. La commande suivante est équivalente à cache:clear:
symfony cc
==== Créer les données initiales ====
Les tables ont été créées dans la base de données, mais elles sont vides. Pour chaque application web, il y a trois types de données :
- Les données initiales : Les données initiales sont nécessaires pour que l'application fonctionne. Par exemple, notre projet01 a besoin de catégories, sinon personne ne pourra soumettre un poste. Nous avons également besoin d'un administrateur capable de s'authentifier au backend.
- Les données de test : Les données de test sont nécessaires pour tester l'application. Comme développeur vous allez écrire des tests pour être certain que tout se comporte comme prévu. Le meilleur moyen est d'écrire des tests automatiques. Donc à chaque fois que vous faites des tests, vous avez besoin d'une base de données propre avec des données actualisées.
- Les données utilisateurs : Les données utilisateurs sont créées par les utilisateurs pendant la vie normale de l'application.
Chaque fois que Symfony crée des tables dans la base de données, les données sont perdues. Pour envoyer des données initiales à la base nous pouvons écrire un script PHP, ou exécuter du code SQL avec le programme MySQL.
Mais comme le besoin est commun, il y a une meilleure méthode avec Symfony. Créez un fichier YAML dans le répertoire data/fixtures/ et utilisez la tâche propel:data-load pour les envoyer dans la base de données.
Créer les deux fichiers suivants avec leur contenu respectif dans le dossier data/fixtures/ :
Fichier 1) 010_categories.yml
Projet01Category:
design: { name: Design }
programming: { name: Programming }
manager: { name: Manager }
administrator: { name: Administrator }
Fichier 2) 020_jobs.yml
Projet01Job:
job_sensio_labs:
category_id: programming
type: full-time
company: Sensio Labs
logo: sensio_labs.png
url: http://www.sensiolabs.com/
position: Web Developer
location: Paris, France
description: |
You've already developed websites with symfony and you want to work
with Open-Source technologies. You have a minimum of 3 years
experience in web development with PHP or Java and you wish to
participate to development of Web 2.0 sites using the best
frameworks available.
how_to_apply: |
Send your resume to fabien.potencier [at] sensio.com
is_public: true
is_activated: true
token: job_sensio_labs
email: job@example.com
expires_at: 2010-10-10
job_extreme_sensio:
category_id: design
type: part-time
company: Extreme Sensio
logo: extreme_sensio.png
url: http://www.extreme-sensio.com/
position: Web Designer
location: Paris, France
description: |
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in.
Voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa
qui officia deserunt mollit anim id est laborum.
how_to_apply: |
Send your resume to fabien.potencier [at] sensio.com
is_public: true
is_activated: true
token: job_extreme_sensio
email: job@example.com
expires_at: 2010-10-10
Un fichier de jeu de données tests est écrit en YAML. Il utilise le modèle des objets avec un nom unique pour chaque enregistrement. Ce nom est utile pour lier les objets relationnels entre eux sans à avoir à définir une clé primaire (qui sont souvent des champs auto-incrémentés et ne peuvent être définis). Par exemple, le poste job_sensio_labs utilise la catégorie programming, ce qui correspond à la catégorie 'Programming' .
Un fichier de jeu de données peut contenir des objets d'un ou plusieurs modèles.
Remarquez le nombre qui préfixe le nom du fichier. C'est un moyen simple de contrôler l'ordre de chargement des données. Plus tard si nous avons besoin d'insérer un nouveau jeu, ce sera plus facile, car nous avons des numéros libres entre ceux existants.
Dans un fichier de jeu de données, vous n'avez pas besoin de définir toutes les valeurs de colonnes. Dans ce cas Symfony, va utiliser la valeur par défaut indiquée dans le schéma de la base de données. Et comme Symfony utilise un Propel pour charger les données en base, tous les comportements à la création (comme pour created_at ou updated_at) ou les comportements que vous aurez ajoutés au modèle sont activés.
Charger les données initiales dans la base de données est aussi simple que d'exécuter la commande suivante :
symfony propel:data-load
Le voir en action dans le navigateur
Nous avons beaucoup utilisé l'interface de ligne de commande, mais ce n'est pas vraiment excitant, surtout pour un projet web. Nous avons maintenant tout ce qu'il nous faut pour créer des pages web qui vont interagir avec la base de données.
Voyons comment afficher la liste des postes, comment éditer un poste existant, et comment l'effacer. Comme nous l'avons expliqué, un projet Symfony est fait d'application. Chacune d'entre elles est faite de module. Un module contient un jeu de code PHP qui représente une fonctionnalité de l'application (le module de l'API par exemple) ou un jeu de manipulation sur le modèle objet que peut faire un utilisateur (le module des postes par exemple).
Symfony est capable de générer automatiquement pour un modèle un module qui fournit des fonctionnalités basiques. Entrer les commandes suivantent pour les frontend affiliate, category et job :
symfony propel:generate-module --with-show --non-verbose-templates frontend affiliate Projet01Affiliate
symfony propel:generate-module --with-show --non-verbose-templates frontend category Projet01Category
symfony propel:generate-module --with-show --non-verbose-templates frontend category_affiliate Projet01CategoryAffiliate
symfony propel:generate-module --with-show --non-verbose-templates frontend job Projet01Job
Cette commande génère un module job dans l'application frontend sur le modèle de Projet01Job. Comme pour la plupart des tâches Symfony, des répertoires et des fichiers ont été créés pour vous dans le répertoire apps/frontend/modules/job :
^ Directory ^ Description ^
| actions | Les actions du module |
| templates | Les gabarits du module |
Le fichier actions/actions.class.php définit toutes les actions disponibles pour le module job :
^ Action name ^ Description ^
| index | Affiche les enregistrements de la table |
| show | Affiche les champs d'un enregistrement donné |
| new | Affiche un formulaire pour créer un nouvel enregistrement |
| create | Créer un nouvel enregistrement |
| edit | Affiche un formulaire pour éditer un enregistrement |
| update | Mise à jour d'un enregistrement avec les données soumises |
| delete | Efface un enregistrement donné |
Vous pouvez tester dès maintenant les modules dans votre navigateur :
http://dev.projet01.com/frontend_dev.php/affiliate
http://dev.projet01.com/frontend_dev.php/category
http://dev.projet01.com/frontend_dev.php/category_affiliate
http://dev.projet01.com/frontend_dev.php/job
Je vous suggère d'ajouter ces adresses à vos "Marque-pages" (Signets, favoris), vous en aurez besoin plus tard.
==== Modification du cadre global des pages ====
La mise en page par défaut d'une application est appelée layout.php et se trouve dans le dossier "apps/frontend/templates/". Ce dossier contient tous les templates globaux pour une application.
Avec la commande :
kate apps/frontend/templates/layout.php
Remplacez le contenu par défaut du fichier par le code suivant :
Un template Symfony n'est ni plus ni moins qu'un fichier PHP. Dans le template layout, vous trouverez des appels à des fonctions PHP et des références à des variables PHP. sf_content est la variable la plus intéressante : elle est définie par le framework lui-même et contient le code HTML généré par l'action.
Si vous parcourez le module job avec votre navigateur :
http://dev.projet01.com/frontend_dev.php/job
Vous verrez que toutes les actions sont mises en page selon le modèle défini dans le layout.
Nous utiliserons les images et les fichiers CSS du tutoriel Jobeet, sans les modifier pour ne pas alourdir le présent texte. Vous de jouer avec ces fichiers si le coeur vous en dit.
Télécharger et décompresser les archives et l'image suivantes :
http://www.symfony-project.org/get/jobeet/images.zip
Copier le dossier "images" sur le dossier "web/images"
http://www.symfony-project.org/get/jobeet/css.zip
Copier le dossier "css" sur le dossier "web/css"
http://www.symfony-project.org/images/jobeet/favicon.ico
Copier l'image "favicon.ico" dans le dossier "web/images"
Vider la cache avec la commande :
symfony cc
Recharger les pages pour les voir enjolivée des nouveaux ajouts.
http://dev.projet01.com/frontend_dev.php/affiliate
http://dev.projet01.com/frontend_dev.php/category
http://dev.projet01.com/frontend_dev.php/category_affiliate
http://dev.projet01.com/frontend_dev.php/job
===== Principes de configuration dans Symfony =====
Par défaut, la tâche generate:project a créé trois dossier pour le projet courant : web/images/ pour les images, web/css/ pour les feuilles de style, et web/js/ pour les fichiers Javascript. Ceci fait partie des nombreuses conventions définies par Symfony, mais vous pouvez évidemment les placer dans un autre dossier sous le répertoire web/, mais cela n'est pas recommandé.
Bien que le fichier main.css n'est défini nul part dans le layout par défaut, il est nécessairement présent dans le code HTML généré. Mais pas les autres. Comment est-ce possible ?
==== Les helper ====
La feuille de style a été inclue grâce à la fonction include_stylesheets() située entre les balises
# apps/frontend/config/view.yml
default:
http_metas:
content-type: text/html
metas:
#title: symfony project
#description: symfony project
#keywords: symfony, project
#language: en
#robots: index, follow
stylesheets: [main.css]
javascripts: []
has_layout: on
layout: layout
Le fichier view.yml contient les paramètres par défaut (default) pour tous les templates de l'application. Par exemple, l'entrée `stylesheets' définit un tableau de fichiers de feuilles de style à inclure pour toutes les pages de l'application (ceci grâce au helper vu ci-dessus).
Dans le fichier de configuration par défaut view.yml, le fichier référence est main.css, et non pas css/main.css. En fait, les deux définitions sont équivalentes. Symfony préfixe les chemin relatifs avec /css/.
Si plusieurs fichiers sont définis, Symfony les inclura dans le même ordre que celui dans lequel ils ont été définis :
stylesheets: [main.css, jobs.css, job.css]
Vous pouvez également définir l'attribut media et omettre le suffixe .css :
stylesheets: [main.css, jobs.css, job.css, print: { media: print }]
Cette configuration génèrera le code suivant :
Le fichier de configuration view.yml définit également le layout utilisé par défaut pour l'application. Par défaut, son nom est layout. Par conséquent, Symfony met en page chacune de vos pages à partir du fichier layout.php. Vous pouvez également désactiver cette mise en page en définissant l'entrée has_layout à false.
Tel quel, le site répond à nos attentes. Le fichier jobs.css est uniquement utile pour la page d'accueil, et le fichier job.css uniquement pour la page job. Il peut-être intéressant de faire en sorte que chaque fichier ne soit inclu que lorsqu'il est utile. Le fichier de configuration view.yml peut résoudre ce problème en le personnalisant par module.
Sous les sections indexSuccess et showSuccess (qui sont les noms des templates associés aux actions index et show, comme nous le verrons plus tard), vous pouvez personnaliser les entrées se trouvant sous la section default du fichier view.yml de l'application. Toutes les entrées spécifiques sont fusionnées avec celles de l'application. Vous pouvez également définir des paramètres pour toutes les actions d'un module avec la section spéciale all.
Pour beaucoup de fichiers de configuration de Symfony, un même paramètre peut être définit à différents niveaux :
- Au niveau du framework lui-même
- Au niveau du projet (dans le répertoire config/)
- A un niveau plus local, celui de l'application (dans le répertoire apps/APP/config/)
- Au niveau restreint au module (dans le répertoire apps/APP/modules/MODULE/config/)
Lors de l'exécution, le système de configuration fusionne tous les paramètres depuis les différents fichiers si ils existent et les met en cache pour de meilleurs performances.
En règle générale, quand quelque chose est configurable via un fichier de configuration, la même chose peut être faite avec du code PHP. Au lieu de créer un fichier view.yml pour le module job par exemple, vous pouvez aussi utiliser le helper use_stylesheet() pour inclure une feuille de style depuis un template avec par exemple la ligne :
Vous pouvez également utiliser ce helper dans le layout pour inclure une feuille de style globale à l'application.
Le choix entre une méthode ou l'autre est réellement une question de goût. Le fichier view.yml permet de définir quelque chose pour toutes les actions d'un module, ce qui n'est pas possible depuis un template. Cela dit, la configuration est plus statique. A l'inverse, le helper use_stylesheet() est plus flexible et plus encore, tout se trouve au même endroit : la définition des feuilles de style et le code HTML. Pour Projet01, nous allons utiliser le helper use_stylesheet(), et mettre à jour le template job avec les appels à use_stylesheet().
De la même manière, la configuration JavaScript est faite via l'entrée javascripts du fichier de configuration view.yml ou via le helper use_javascript() permettant d'inclure des fichiers JavaScript dans un template.
La page d'accueil Job
Comme déjà vu, la page d'accueil est générée par l'action index du module job. L'action index fait partie de la couche Contrôleur de la page et le template associé, indexSuccess.php, fait parti de la couche Vue :
apps/
frontend/
modules/
job/
actions/
actions.class.php
templates/
indexSuccess.php
==== L'action ====
Chaque action est représentée par une méthode de classe. Pour la page d'accueil de job, la classe est jobActions (le nom du module avec le suffixe Actions) et la méthode est executeIndex() (le nom de l'action avec le préfixe execute). Dans notre cas, cela renvoie tous les jobs de la BDD :
// apps/frontend/modules/job/actions/actions.class.php
class jobActions extends sfActions
{
public function executeIndex(sfWebRequest $request)
{
$this->projet01_job_list = Projet01JobPeer::doSelect(new Criteria());
}
// ...
}
Analysons de plus près le code : la méthode executeIndex() (couche Contrôleur) appelle la (couche) Modèle Projet01JobPeer pour renvoyer tous les jobs (new Criteria()). Le modèle renvoie un tableau d'objet de type Projet01Job que l'on affecte à la propriété projet01_job_list de l'objet courant.
Toutes les propriétés des objets sont automatiquement passées au template (la couche Vue). Pour transmettre des données du Contrôleur à la Vue, il vous suffit simplement de créer une nouvelle propriété :
public function executeFooBar(sfWebRequest $request)
{
$this->foo = 'bar';
$this->bar = array('bar', 'baz');
}
Cette méthode rendra les variables $foo et $bar accessibles depuis le template.
Le Template
Par défaut, le nom du template associé à l'action est déduit par symfony : le nom de l'action avec le suffixe Success.
Le template indexSuccess.php génère une table HTML pour tous les jobs :
Job List
Id
Category
Type
Created at
Updated at
getId() ?>
getCategoryId() ?>
getType() ?>
getCreatedAt() ?>
getUpdatedAt() ?>
New
Dans ce code, la boucle foreach parcourt la liste d'objets job ($projet01_job_list) et, pour chaque job, chaque colonne est affichée.
Souvenez-vous, pour accéder à la valeur d'une colonne (propriété), il suffit simplement de faire appel à un accesseur. Comme d'habitude, le nom de ces accesseurs suit une convention établit par Symfony : chaque accesseur commence par le préfixe get suivit du nom de la colonne (propriété) en camelCased (par exemple, la méthode getCreatedAt() permet d'accéder à la valeur de la colonne created_at de l'objet).
Faisons un peu de tri dans tout ça afin de n'afficher qu'une partie des propriétés :
$job): ?>
getLocation() ?>
getPosition() ?>
getCompany() ?>
La fonction url_for() utilisée dans ce template est un helper Symfony.
=== Le template de la page d'un job ===
Personnalisons maintenant le template de la page d'un job. Ouvrez le fichier showSuccess.php avec la commande
kate apps/frontend/modules/job/templates/showSuccess.php
Remplacez son contenu par le code suivant :
getCompany() ?>
getLocation() ?>
getPosition() ?>
- getType() ?>
getLogo()): ?>
getDescription()) ?>
How to apply?
getHowToApply() ?>
Ce template utilise la variable $job passée en paramètre par l'action servant à afficher les informations sur un job. Comme nous avons renommé la variable utilisée dans le template ($job au lieu de $projet01_job), vous devez également modifier le nom de la variable envoyée au template depuis l'action show (attention, elle s'y trouve deux fois). Remplacez le contenu par :
projet01_job_list = Projet01JobPeer::doSelect(new Criteria());
}
public function executeShow(sfWebRequest $request)
{
$this->job = Projet01JobPeer::retrieveByPk($request->getParameter('id'));
$this->forward404Unless($this->job);
}
public function executeNew(sfWebRequest $request)
{
$this->form = new Projet01JobForm();
}
public function executeCreate(sfWebRequest $request)
{
$this->forward404Unless($request->isMethod('post'));
$this->form = new Projet01JobForm();
$this->processForm($request, $this->form);
$this->setTemplate('new');
}
public function executeEdit(sfWebRequest $request)
{
$this->forward404Unless($projet01_job = Projet01JobPeer::retrieveByPk($request->getParameter('id')), sprintf('Object projet01_job does not exist (%s).', $request->getParameter('id')));
$this->form = new Projet01JobForm($projet01_job);
}
public function executeUpdate(sfWebRequest $request)
{
$this->forward404Unless($request->isMethod('post') || $request->isMethod('put'));
$this->forward404Unless($projet01_job = Projet01JobPeer::retrieveByPk($request->getParameter('id')), sprintf('Object projet01_job does not exist (%s).', $request->getParameter('id')));
$this->form = new Projet01JobForm($projet01_job);
$this->processForm($request, $this->form);
$this->setTemplate('edit');
}
public function executeDelete(sfWebRequest $request)
{
$request->checkCSRFProtection();
$this->forward404Unless($projet01_job = Projet01JobPeer::retrieveByPk($request->getParameter('id')), sprintf('Object projet01_job does not exist (%s).', $request->getParameter('id')));
$projet01_job->delete();
$this->redirect('job/index');
}
protected function processForm(sfWebRequest $request, sfForm $form)
{
$form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));
if ($form->isValid())
{
$projet01_job = $form->save();
$this->redirect('job/edit?id='.$projet01_job->getId());
}
}
}
Remarquez que certains accesseurs Propel prennent des paramètres. Comme nous avons défini la colonne created_at de type timestamp, l'accesseur getCreatedAt() prend en paramètre le format de la date à renvoyer :
$job->getCreatedAt('m/d/Y');
La description d'un job utilise le helper simple_format_text() afin de formater le texte en HTML, en remplaçant notamment les retours chariots par des balises