- Installation et configuration
- Generation d'un bundle
- Entités et schema de la base de données
- Controleur et vues twig
- Creation des contrôleurs : CRUD
- Le routage
- Les vues twig
- Gestion d'utilisateurs avec FOSUser
mkdir blog
cd blog
composer create-project symfony/framework-standard-edition . "3.4.*"
Lors de l'installation, certaines informations doivent être renseignées:
Some parameters are missing. Please provide them.
database_host (127.0.0.1):
database_port (null):
database_name (symfony):
database_user (root):
database_password (null):
mailer_transport (smtp):
mailer_host (127.0.0.1):
mailer_user (null):
mailer_password (null):
secret (ThisTokenIsNotSoSecretChangeIt): azerlkjazerlkjazerlkjazerlmkjazer
Utiliser la version "dev" pour avoir accès à l'inferface de débug de symfony:
Dans le fichier web/.htaccess, il faut remplacer toutes les occurences de
app.php par app_dev.php:
grep "app_dev" web/.htaccess public_html/blog
DirectoryIndex app_dev.php
RewriteRule ^app_dev\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L]
RewriteRule ^ %{ENV:BASE}/app_dev.php [L]un projet a au moins un bundle, les bundles sont créés en ligne de commande:
php bin/console generate:bundle
C'est une commande interactive, voici les réponses pour ce petit projet de test:
- le nom du bundle : BlogBundle
- installation dans le répertoire par défaut: src/
- le format de la configuration : yml
php bin/console generate:bundle public_html/blog master
Welcome to the Symfony bundle generator!
Are you planning on sharing this bundle across multiple applications? [no]: no
Your application code must be written in bundles. This command helps
you generate them easily.
Give your bundle a descriptive name, like BlogBundle.
Bundle name: BlogBundle
Bundles are usually generated into the src/ directory. Unless you're
doing something custom, hit enter to keep this default!
Target Directory [src/]:
What format do you want to use for your generated configuration?
Configuration format (annotation, yml, xml, php) [annotation]: yml
Bundle generation
...Un message d'erreur à l'issue de la création du bundle indique, que ce dernier n'est pas chargé par défaut:
The command was not able to configure everything automatically.
You'll need to make the following changes manually.
- Edit the composer.json file and register the bundle
namespace in the "autoload" section:
Il suffit d'ajouter dans la section autoload du fichier composer.json, une ligne pour référencer le nouveau bundle.
diff --git a/composer.json b/composer.json
index ba17155..06faed5 100755
--- a/composer.json
+++ b/composer.json
@@ -5,7 +5,8 @@
"description": "The \"Symfony Standard Edition\" distribution",
"autoload": {
"psr-4": {
- "AppBundle\\": "src/AppBundle"
+ "AppBundle\\": "src/AppBundle",
+ "BlogBundle\\": "src/BlogBundle"
},
"classmap": [ "app/AppKernel.php", "app/AppCache.php" ]
},après, il faut lancer la commande suivante afin de regénerer la liste des classes à charger automatiquement dans le projet:
composer dump-autoload
Si cette commande n'est pas lancée, toutes tentatives d'utiliser la console
php bin/console * ou d'accèder à la page d'accueil du blog, renverra un message
d'erreur du type:
Attempted to load class "BlogBundle" from namespace "BlogBundle"
Et bien sur cela ne fonctionne pas après. Il y a le message suivant quand on rafraichi la page:
Unable to find template "BlogBundle:Default:index.html.twig" (looked into: /home/cedlemo/public_html/blog/app/Resources/views, /home/cedlemo/public_html/blog/vendor/symfony/symfony/src/Symfony/Bridge/Twig/Resources/views/Form).
L'erreur vient du fichier : src/BlogBundle/Controller/DefaultController.php
<?php
namespace BlogBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
public function indexAction()
{
return $this->render('BlogBundle:Default:index.html.twig');
}
}C'est une sorte de bug. En gros depuis la version 3.4 de Symfony, les chemins
de fichiers twig du type 'BlogBundle:Default:index.html.twig' ne sont plus
supportés, le nouveau format est : @Blog/Default/index.html.twig. Il semble
que le probleme vienne de la commande generate:bundle qui n'a pas été mise à
jour.
source : https://stackoverflow.com/questions/47832977/symfony-3-4-use-view-inside-my-bundle?rq=1
diff --git a/src/BlogBundle/Controller/DefaultController.php b/src/BlogBundle/Controller/DefaultController.php
index 0e7ca62..7a062f2 100644
--- a/src/BlogBundle/Controller/DefaultController.php
+++ b/src/BlogBundle/Controller/DefaultController.php
@@ -8,6 +8,6 @@ class DefaultController extends Controller
{
public function indexAction()
{
- return $this->render('BlogBundle:Default:index.html.twig');
+ return $this->render('@Blog/Default/index.html.twig');
}
}La configuration de la base de données peut être retrouvée dans le fichier app/config/parameters.yml. Dans mon cas mon fichier ressemble à ceci:
# This file is auto-generated during the composer install
parameters:
database_host: 127.0.0.1
database_port: null
database_name: symfony_blog
database_user: root
database_password: null
mailer_transport: smtp
mailer_host: 127.0.0.1
mailer_user: null
mailer_password: null
secret: azerlkjazerlkjazerlkjazerlmkjazerAvant toutes choses, il faut créer la base de données. Les tables de cette base et leurs relations base seront ajoutées au fur et à mesure de leurs créations.
php bin/console doctrine:database:create
Created database `symfony_blog` for connection named defaultEn considérant que le blog repose sur une base de données contenant quatre tables principales:
- article
- category
- comment
- author
on créera donc 4 "entities" :
- Article
- Category
- Comment
- Author
Les champs de la table articles sont:
- title
- content
- publicationDate
- status
Donc pour créer une entité Article, on exécute la commande suivante:
php bin/console doctrine:generate:entity public_html/blog master
Welcome to the Doctrine2 entity generator
This command helps you generate Doctrine2 entities.
First, you need to give the entity name you want to generate.
You must use the shortcut notation like AcmeBlogBundle:Post.
The Entity shortcut name: BlogBundle:Article
Determine the format to use for the mapping information.
Configuration format (yml, xml, php, or annotation) [annotation]:
Instead of starting with a blank entity, you can add some fields now.
Note that the primary key will be added automatically (named id).
Available types: array, simple_array, json_array, object,
boolean, integer, smallint, bigint, string, text, datetime, datetimetz,
date, time, decimal, float, binary, blob, guid.
New field name (press <return> to stop adding fields): title
Field type [string]:
Field length [255]:
Is nullable [false]:
Unique [false]:
New field name (press <return> to stop adding fields): content
Field type [string]: text
Is nullable [false]:
Unique [false]:
New field name (press <return> to stop adding fields): publicationDate
Field type [string]: datetime
Is nullable [false]:
Unique [false]:
New field name (press <return> to stop adding fields): status
Field type [string]: boolean
Is nullable [false]:
Unique [false]:
New field name (press <return> to stop adding fields):
Entity generation
created ./src/BlogBundle/Entity/
created ./src/BlogBundle/Entity/Article.php
> Generating entity class src/BlogBundle/Entity/Article.php: OK!
> Generating repository class src/BlogBundle/Repository/ArticleRepository.php: OK!
Everything is OK! Now get to work :).Cette commande génère différents fichiers:
- src/BlogBundle/Entity/Article.php
- src/BlogBundle/Repository/ArticleRepository.php
Dans Article.php, se trouve une classe Article avec des variables privées
nommées selon les champs que l'on a rensignés ainsi que des getters/setters pour
ces variables. De plus on trouve en commentaire des annotations faisant le lien
entre les variables et les tables/colonnes à générer dans la base de données.
L'annotation suivante:
/**
* Article
*
* @ORM\Table(name="article")
* @ORM\Entity(repositoryClass="BlogBundle\Repository\ArticleRepository")
*/
class Article
{dit que la classe Article correspond à la table "article".
L'annotation:
/**
* @var string
*
* @ORM\Column(name="title", type="string", length=255)
*/
private $title;indique que la variable $title de la classe Article correspondra à une colonne
nommée "title" dans la table "article".
La création de cette entité se fait comme précédement:
New field name (press <return> to stop adding fields): name
Field type [string]:
Is nullable [false]:
Unique [false]:
New field name (press <return> to stop adding fields): name
Field type [string]:
Is nullable [false]:
Unique [false]:
New field name (press <return> to stop adding fields): biography
Field type [string]: text
Is nullable [false]:
Unique [false]:
New field name (press <return> to stop adding fields): email
Field type [string]:
Is nullable [false]:
Unique [false]:
New field name (press <return> to stop adding fields): content
Field type [string]: text
Is nullable [false]:
Unique [false]:
New field name (press <return> to stop adding fields): datePublication
Field type [string]: datetime
Is nullable [false]:
Unique [false]:
New field name (press <return> to stop adding fields): status
Field type [string]: boolean
Is nullable [false]:
Unique [false]:
Après chaque création d'"entity" ou après la création de toutes les "entities", il est possible de générer les tables correspondantes avec la commande suivante:
php bin/console doctrine:schema:udpate --forceAvant de créer les relations, il faut les identifier:
- Un article a un auteur, un auteur peut créer plusieurs articles.
Ici on se retrouve dans le même cas que dans l'exemple de la documentation. D'un point de vue de l'entité
Article, plusieurs articles peuvent être reliés à un auteur :ManyToOne. D'un
point de vue de l'entité Author, un auteur est lié à plusieurs articles : OneToMany.
Pour mettre en place cette relation bi-directionnelle, il faut:
- créer une variable
$authoret ses getter/setter dansArticleainsi que les annotations nécessaires pourdoctrine. - créer une variable
$articleset ses getter/setter dansAuthorainsi que les annotations nécessaires pourdoctrine.
Un bon diff vieux diff:
diff --git a/src/BlogBundle/Entity/Article.php b/src/BlogBundle/Entity/Article.php
index 8a86a61..a9ea99c 100644
--- a/src/BlogBundle/Entity/Article.php
+++ b/src/BlogBundle/Entity/Article.php
@@ -49,6 +49,10 @@ class Article
*/
private $status;
+ /**
+ * @ORM\ManyToOne(targetEntity="BlogBundle\Entity\Author", inversedBy="articles")
+ */
+ private $author;
/**
* Get id
@@ -155,5 +159,24 @@ class Article
{
return $this->status;
}
-}
+ /**
+ * Get author
+ * @return Author
+ */
+ public function getAuthor()
+ {
+ return $this->author;
+ }
+
+ /**
+ * Set author
+ * @param Author $author
+ * @return Article
+ */
+ public function setAuthor($author)
+ {
+ $this->author = $author;
+ return $this;
+ }
+}
diff --git a/src/BlogBundle/Entity/Author.php b/src/BlogBundle/Entity/Author.php
index 3eb009f..351f055 100644
--- a/src/BlogBundle/Entity/Author.php
+++ b/src/BlogBundle/Entity/Author.php
@@ -36,6 +36,11 @@ class Author
private $biography;
+ /**
+ * @ORM\OneToMany(targetEntity="BlogBundle\Entity\Article", mappedBy="author")
+ */
+ private $articles;
+
/**
* Get id
*
@@ -93,5 +98,24 @@ class Author
{
return $this->biography;
}
-}
+ /**
+ * Set articles
+ * @param mixed Article
+ * @return Author
+ */
+ public function setArticles($articles)
+ {
+ $this->articles = $articles;
+ return $this;
+ }
+
+ /**
+ * Get articles
+ * @return mixed Article
+ */
+ public function getArticles()
+ {
+ return $this->articles;
+ }
+}Pour générer la relation, il suffit de mettre à jour la base de données avec:
php bin/console doctrine:schema:update --force
- Un commentaire est lié à un article, un article peut avoir plusieurs commentaires.
On se trouve dans le même cas que précédement. D'un point de vue du commentaire,
plusieurs commentaires peuvent être liés à un article :
ManyToOneet un article peut avoir plusieur commentairesOneToMany.
Dans la classe Comment, on crée une variable privée $articles, ses setter/getter
ainsi que les annotations décrivant la relation avec la classe Article.
diff --git a/src/BlogBundle/Entity/Comment.php b/src/BlogBundle/Entity/Comment.php
index 9dd1e8b..c7f8034 100644
--- a/src/BlogBundle/Entity/Comment.php
+++ b/src/BlogBundle/Entity/Comment.php
@@ -49,6 +49,11 @@ class Comment
*/
private $status;
+ /**
+ * @var Article
+ * @ORM\ManyToOne(targetEntity="\BlogBundle\Entity\Article", inversedBy="comments")
+ */
+ private $article;
/**
* Get id
@@ -155,5 +160,24 @@ class Comment
{
return $this->status;
}
-}
+ /**
+ * Set article
+ * @param Article $article
+ * @return Comment
+ */
+ public function setArticle(Article $article)
+ {
+ $this->article = $article;
+ return $this;
+ }
+
+ /**
+ * Get article
+ * @return Article
+ */
+ public function getArticle()
+ {
+ return $this->article;
+ }
+}Dans la classe Article on ajoute la variable $comments, son getter, son
setter ainsi que les annotations nécessaires à la description de la relation
avec la classe Comment.
diff --git a/src/BlogBundle/Entity/Article.php b/src/BlogBundle/Entity/Article.php
index a9ea99c..ac7405b 100644
--- a/src/BlogBundle/Entity/Article.php
+++ b/src/BlogBundle/Entity/Article.php
@@ -54,6 +54,11 @@ class Article
*/
private $author;
+ /**
+ * @ORM\OneToMany(targetEntity="BlogBundle\Entity\Comment", mappedBy="article")
+ */
+ private $comments;
+
/**
* Get id
*
@@ -179,4 +184,24 @@ class Article
$this->author = $author;
return $this;
}
+
+ /**
+ * Get articles
+ * @return mixed Aricle
+ */
+ public function getArticles()
+ {
+ return $this->articles
+ }
+
+ /**
+ * Set articles
+ * @param mixed Article
+ * @return Article
+ */
+ public function setArticles($articles)
+ {
+ $this->articles = $articles;
+ return $this;
+ }
}Avant de mettre à jour la base de données, il est possible de valider les annotations:
php bin/console doctrine:schema:validateComme précédement les changements sur la base de données sont générés avec:
php bin/console doctrine:schema:update --force- un article peut avoir plusieurs catégories, une catégorie peut décrirent plusieurs articles.
La documentation relative a ces relations ManyToMany se trouve ici.
Dans ce type de relation, il va falloir décider quel entité va être responsable
de la relation. Ici c'est l'Article puisque l'on associe obligatoirement
une catégorie lors de la création d'un article.
Donc dans la classe Article, on ajoute une variable privée $categories avec
les fonctions qui vont bien et l'annotation suivante:
/**
* @ORM\ManyToMany(targetEntity="\BlogBundle\Entity\Category", inversedBy="articles")
*/Dans la classe Category, on ajoute la variables $articles avec ses setter/getter
et l'annotation suivante:
/**
* @ORM\ManyToMany(targetEntity="\BlogBundle\Entity\Article", mappedBy="categories")
*/Après vérification, on lance la mise à jour de la base de données.
php bin/console doctrine:schema:validate
php bin/console doctrine:schema:update --forceC'est dans le contrôleur que l'on trouvera la logique applicative concernant les actions réalisées par l'utilisateur. On peut tout à fait générer un à un les contrôleurs nécessaires avec la commande:
php bin/console doctrine:generate:controleur
Mais on peut aussi utiliser générer directement un ensemble de contrôleurs génériques pour les actions de base:
- Create
- Read
- Update
- Delete.
Dans cet exemple on considère que toutes les actions que l'on va générer, devront être accessible via les routes suivantes:
- /admin/article
- /admin/category
- /admin/author
- /admin/comment Cela permettra de séparer la gestion (suppression, édition, création ...) des éléments du site afin de faciliter l'authentification.
Avec la commande suivante pour l'entity BlogBundle:Category:
php bin/console doctrine:generate:crud
On choisira de générer les actions permettant d'écrire, d'insérer des données dans la base de données:
Do you want to generate the "write" actions [no]? yes
Ensuite les routes seront gérées via des fichiers yml:
Determine the format to use for the generated CRUD.
Configuration format (yml, xml, php, or annotation) [annotation]: yml
La commande va générer le contrôleur dans :
- src/BlogBundle/Controller/CategoryController.php
Des fichiers de vues twig et des formulaires pour la création et l'édition
de l'entité Category dans les répertoires:
- src/BlogBundle/Form/
- app/Resources/views/category/
Rien que avec cela, les urls suivantes sont fonctionnelles:
- http://blog.fr/admin/category/
- http://blog.fr/admin/category/new
- http://blog.fr/admin/category/1/show
- http://blog.fr/admin/category/1/delete
Même commande que précédement:
php bin/console doctrine:generate:crud
Si l'erreur suivante apparait:
- Import the bundle's routing resource in the bundle routing file
(/home/cedlemo/public_html/blog/src/BlogBundle/Resources/config/routing.yml).
blog_admin_article:
resource: "@BlogBundle/Resources/config/routing/article.yml"
prefix: /admin/article
C'est que l'import des routes n'a pu se faire. Il suffit de rajouter la partie
manquante dans le routing.yml du bundle.
diff --git a/src/BlogBundle/Resources/config/routing.yml b/src/BlogBundle/Resources/config/routing.yml
index 7ac2d32..ee41b2f 100644
--- a/src/BlogBundle/Resources/config/routing.yml
+++ b/src/BlogBundle/Resources/config/routing.yml
@@ -2,6 +2,10 @@ blog_admin_category:
resource: "@BlogBundle/Resources/config/routing/category.yml"
prefix: /admin/category
+blog_admin_article:
+ resource: "@BlogBundle/Resources/config/routing/article.yml"
+ prefix: /admin/article
+
blog_homepage:
path: /
defaults: { _controller: BlogBundle:Default:index }La generation peut se faire sans le côté interactif avec:
php bin/console doctrine:generate:crud BlogBundle:Comment -n --format=yml --with-write
php bin/console doctrine:generate:crud BlogBundle:Author -n --format=yml --with-write
La gestion des "routes", c'est à dire les urls correspondant aux contrôleurs et à leurs actions, se fait dans le fichier BlogBundle/Ressources/config/routing.yml. L'ajout des CRUD pour chaque entités a séparer les routes dans différents fichier.
tree Resources/config src/BlogBundle master
Resources/config
├── routing
│ ├── article.yml
│ ├── author.yml
│ ├── category.yml
│ └── comment.yml
├── routing.yml
Pour le cas Article, on le retrouve dans le fichier routing.yml :
blog_admin_article:
resource: "@BlogBundle/Resources/config/routing/article.yml"
prefix: /admin/article
On prefixe donc toutes les routes en lien avec la gestion des articles par /admin/article
et le fichier contenant le reste de ces routes est indiqué par le champ resource. Dans
ce fichier se trouve les routes en liens avec les actions du contrôleur ArticleController.:
admin_article_index:
path: /
defaults: { _controller: "BlogBundle:Article:index" }
methods: GET
admin_article_show:
path: /{id}/show
defaults: { _controller: "BlogBundle:Article:show" }
methods: GET
admin_article_new:
path: /new
defaults: { _controller: "BlogBundle:Article:new" }
methods: [GET, POST]
admin_article_edit:
path: /{id}/edit
defaults: { _controller: "BlogBundle:Article:edit" }
methods: [GET, POST]
admin_article_delete:
path: /{id}/delete
defaults: { _controller: "BlogBundle:Article:delete" }
methods: DELETEPar défaut, la génération des actions CRUD pour l'entité Article, a créé des
vues dans app/Resources/views:
- app/Resources/views/article/edit.html.twig
- app/Resources/views/article/index.html.twig
- app/Resources/views/article/new.html.twig
- app/Resources/views/article/show.html.twig
Ces vues sont appelées dans l'action associée. Par exemple, la vue index.html,
est appelée dans ArticleController, par:
/**
* Lists all article entities.
*
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$articles = $em->getRepository('BlogBundle:Article')->findAll();
return $this->render('article/index.html.twig', array(
'articles' => $articles,
));
}Il est plus intéressant d'avoir les vues en lien avec un bundle dans ce bundle. Donc il faut déplacer les vues de app/Resources/views à BlogBundle/Resources/views.
De plus, l'utilisation d'annotations pour faire le lien entre une vue et un
contrôleur permet de grandement simplifier le code. Exemple avec ArticleController.indexAction:
diff --git a/src/BlogBundle/Controller/ArticleController.php b/src/BlogBundle/Controller/ArticleController.php
index 14a97d5..7ca9ca6 100644
--- a/src/BlogBundle/Controller/ArticleController.php
+++ b/src/BlogBundle/Controller/ArticleController.php
@@ -5,6 +5,7 @@ namespace BlogBundle\Controller;
use BlogBundle\Entity\Article;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
+use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
/**
* Article controller.
@@ -15,6 +16,7 @@ class ArticleController extends Controller
/**
* Lists all article entities.
*
+ * @Template("@Blog/article/index.html.twig")
*/
public function indexAction()
{
@@ -22,9 +24,7 @@ class ArticleController extends Controller
$articles = $em->getRepository('BlogBundle:Article')->findAll();
- return $this->render('article/index.html.twig', array(
- 'articles' => $articles,
- ));
+ return ['articles' => $articles];
}
On notera que l'on peut ne pas indiquer d'argument avec @Template. Symfony fera
automatiquement le lien entre une action nommée trucAction et un fichier de
template nommé truc.html.twig.
Si l'on décide de ne pas utiliser l'annotation @Template, et que l'on décide
de mettre les vues dans le bundle, il faut utiliser une notation particulière
pour indiquer le chemin d'accès des vues.
Par exemple pour le bundle BlogBundle et les fichiers twig mis dans src/BlogBundle/Resources/views/ :
diff --git a/src/BlogBundle/Controller/CommentController.php b/src/BlogBundle/Controller/CommentController.php
index a53dac7..dc6d010 100644
--- a/src/BlogBundle/Controller/CommentController.php
+++ b/src/BlogBundle/Controller/CommentController.php
@@ -22,7 +22,7 @@ class CommentController extends Controller
$comments = $em->getRepository('BlogBundle:Comment')->findAll();
- return $this->render('comment/index.html.twig', array(
+ return $this->render('@Blog/comment/index.html.twig', array(
'comments' => $comments,
));
}
@@ -45,7 +45,7 @@ class CommentController extends Controller
return $this->redirectToRoute('comment_show', array('id' => $comment->getId()));
}
- return $this->render('comment/new.html.twig', array(
+ return $this->render('@Blog/comment/new.html.twig', array(
'comment' => $comment,
'form' => $form->createView(),
));
@@ -59,7 +59,7 @@ class CommentController extends Controller
{
$deleteForm = $this->createDeleteForm($comment);
- return $this->render('comment/show.html.twig', array(
+ return $this->render('@Blog/comment/show.html.twig', array(
'comment' => $comment,
'delete_form' => $deleteForm->createView(),
));
@@ -81,7 +81,7 @@ class CommentController extends Controller
return $this->redirectToRoute('comment_edit', array('id' => $comment->getId()));
}
- return $this->render('comment/edit.html.twig', array(
+ return $this->render('@Blog/comment/edit.html.twig', array(
'comment' => $comment,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),Symfony embarque des composants liés à la sécurité
permettant de facilement mettre en place une gestion d'utilisateur : authenfification et
restriction d'accès à toutes ou parties du site. Il existe un bundle installable
via composer simplifiant reposant entièrement sur le système security :
FOSUserBundle.
Ce bundle permet de mettre en place l'enregistrement d'utilisateur en base de donnée,
les fonctionnalités d'enregistrement/inscription d'utilisateurs, la création de
page de profile et le reset de mot de passe.
L'installation se fait via composer dans le répertoire blog:
composer require friendsofsymfony/user-bundle "~2.0"Ensuite on l'active dans app/AppKernel.php :
iff --git a/app/AppKernel.php b/app/AppKernel.php
index b6b11fe..20bb563 100755
--- a/app/AppKernel.php
+++ b/app/AppKernel.php
@@ -18,6 +18,7 @@ class AppKernel extends Kernel
new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
new AppBundle\AppBundle(),
new BlogBundle\BlogBundle(),
+ new FOS\UserBundle\FOSUserBundle(),
];
if (in_array($this->getEnvironment(), ['dev', 'test'], true)) {Etant donné que l'idée est d'enregistrer les utilisateurs en base de données,
il faut créer une classe User, cette classe va étendre la classe User
fournie par FOSUser dans le fichier vendor/friendsofsymfony/user-bundle/Model/User.php.
La classe de base User contient déjà la pluspart des champs nécessaires:
abstract class User implements UserInterface, GroupableInterface [491/693]
{
/**
* @var mixed
*/
protected $id;
/**
* @var string
*/
protected $username;
/**
* @var string
*/
protected $usernameCanonical;
/**
* @var string
*/
protected $email;
/**
* @var string
*/
protected $emailCanonical;
/**
* @var bool
*/
protected $enabled;
/**
* The salt to use for hashing.
*
* @var string
*/
protected $salt;
/**
* Encrypted password. Must be persisted.
*
* @var string
*/
protected $password;La création de la classe suivante dans src/BlogBundle/Entity/ est suffisante:
<?php
// src/AppBundle/Entity/User.php
namespace AppBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="fos_users")
*/
class User extends BaseUser
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
public function __construct()
{
parent::__construct();
// your own logic
}
}Maintenant, il faut adapter le fichier app/config/security.yml. Dans ce fichier,
on définit la façon dont on récupère les informations utilisateurs,
les rôles et la hiérarchie existant entre ces rôles ainsi que les règles d'accès
en fonction des roles.
security:
encoders:
AppBundle\Entity\User:
algorithm: bcrypt
# https://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded
providers:
database:
entity:
class: AppBundle:User
property: username
role_hierarchy:
ROLE_ADMIN: [ROLE_AUTHOR, ROLE_WRITER]
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: true
provider: database
form_login:
login_path: login
check_path: login
logout:
path: /logout
target: /
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, roles: [ROLE_AUTHOR, ROLE_WRITER]}- Les mots de passes sont chiffrés avec bcrypt.
- L'identification se fera sur la propriété username.
- il y a deux role ROLE_AUTHOR et ROLE_WRITER.
- seul ROLE_AUTHOR et ROLE_WRITER pourront avoir accès à la partie d'administration.
- les utilisateurs non authentifiés pourront accèder aux pages de login, d'enregistrement de "reset" de compte.