Voici les commandes pour initialiser un projet symfony, avec un admin sécurisé.
On commence par installer le skeleton du projet.
composer
create-project symfony/skeleton nom-du-projet
On rajoute les briques nécessaires :
cd nom-du-projet
composer require symfony/debug-pack --no-update
composer require symfony/maker-bundle --dev --no-update
composer require sonata-project/doctrine-orm-admin-bundle --no-update
composer require templating --no-update
composer require symfony/translation --no-update
composer require doctrine/doctrine-fixtures-bundle --dev --no-update
composer require sonata-project/notification-bundle --no-update
composer require jms/serializer-bundle --no-update
composer require sonata-project/user-bundle --no-update
composer require sonata-project/doctrine-orm-admin-bundle --no-update
composer require symfony/serializer-pack --no-update
composer require swiftmailer-bundle --no-update
composer require symfony/apache-pack --no-update
composer require migrations --no-update
composer require symfony/var-dumper --no-update
composer require phpoffice/phpspreadsheet --no-update
composer require pixassociates/sortable-behavior-bundle --no-update
composer require sonata-project/media-bundle --no-update
composer require liip/imagine-bundle --no-update
composer require sonata-project/intl-bundle --no-update
composer require sonata-project/formatter-bundle --no-update
composer require annotations --no-update
composer update
composer dump-autoload
Ensuite dans /config/packages/framework.yaml ajouter
framework:
secret: '%env(APP_SECRET)%'
#csrf_protection: true
#http_method_override: true
# Enables session support. Note that the session will ONLY be started if you read or write from it.
# Remove or comment this section to explicitly disable session support.
session:
handler_id: null
cookie_secure: auto
cookie_samesite: lax
#esi: true
#fragments: true
php_errors:
log: true
translator: { fallbacks: ['%locale%'] }
serializer:
enabled: true
templating:
engines: ['twig', 'php']
Ensuite dans /config/packages/doctrine.yaml ajouter
doctrine:
dbal:
url: '%env(resolve:DATABASE_URL)%'
types:
json: Sonata\Doctrine\Types\JsonType
# IMPORTANT: You MUST configure your server version,
# either here or in the DATABASE_URL env var (see .env file)
#server_version: '5.7'
orm:
auto_generate_proxy_classes: true
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
auto_mapping: true
mappings:
ApplicationSonataMediaBundle: ~
SonataMediaBundle: ~
App:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
Dans /config/packages/sonata_media.yaml ajouter
sonata_media:
class:
media: App\Application\Sonata\MediaBundle\Entity\Media
gallery: App\Application\Sonata\MediaBundle\Entity\Gallery
gallery_has_media: App\Application\Sonata\MediaBundle\Entity\GalleryHasMedia
db_driver: doctrine_orm
default_context: default
contexts:
default:
providers:
- sonata.media.provider.dailymotion
- sonata.media.provider.youtube
- sonata.media.provider.image
- sonata.media.provider.file
- sonata.media.provider.vimeo
formats:
small: { width: 100 , quality: 70}
big: { width: 500 , quality: 70}
cdn:
server:
path: /upload/media
filesystem:
local:
# Directory for uploads should be writable
directory: "%kernel.project_dir%/public/upload/media"
create: false
providers:
file:
allowed_extensions: ['pdf', 'txt', 'rtf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'odt', 'odg', 'odp', 'ods', 'odc', 'odf', 'odb', 'odt', 'odp', 'csv', 'jpg', 'png', 'jpeg', 'svg']
allowed_mime_types: ['application/pdf', 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', 'application/vnd.ms-word.document.macroEnabled.12', 'application/vnd.ms-word.template.macroEnabled.12', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', 'application/vnd.ms-excel.sheet.macroEnabled.12','application/vnd.ms-excel.template.macroEnabled.12', 'application/vnd.ms-excel.addin.macroEnabled.12', 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', 'application/vnd.ms-powerpoint', 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/vnd.openxmlformats-officedocument.presentationml.template', 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', 'application/vnd.ms-powerpoint.addin.macroEnabled.12', 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', 'application/vnd.ms-powerpoint.template.macroEnabled.12', 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', 'application/vnd.ms-access', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/x-pdf', 'application/rtf', 'text/html', 'text/rtf', 'text/plain', 'application/vnd.ms-powerpoint', 'image/svg+xml', 'image/gif', 'image/jpeg', 'image/pjpeg', 'image/png']
service: sonata.media.provider.file
resizer: false
filesystem: sonata.media.filesystem.local
cdn: sonata.media.cdn.server
generator: sonata.media.generator.default
thumbnail: sonata.media.thumbnail.liip_imagine
image:
allowed_extensions: ['gif', 'svg', 'jpg', 'jpeg', 'png']
allowed_mime_types: ['image/svg+xml', 'image/gif', 'image/jpeg', 'image/pjpeg', 'image/png']
#thumbnail: sonata.media.thumbnail.format # default value
#thumbnail: sonata.media.thumbnail.consumer.format # can be used to dispatch the resize action to async task
thumbnail: sonata.media.thumbnail.liip_imagine # use the LiipImagineBundle to resize the image
resizer:
simple:
mode: outbound
pixlr:
enabled: false
referrer: Sonata Project
liip_imagine:
# valid drivers options include "gd" or "gmagick" or "imagick"
driver: "imagick"
filter_sets:
test_banner:
quality: 75
filters:
relative_resize: { widen: 898, heighten: 610 }
crop: {size: [ 898, 610 ], start: [ 0, 0 ] }
background : { size : [898, 610], position : center, color : '#FFFFFF' }
test_thumb_gallery:
quality: 100
filters:
thumbnail: { size: [288, 192], mode: outbound, allow_upscale: true}
crop: {size: [288, 192], start: [ 0, 0 ] }
background : { size : [288, 192], position : center, color : '#FFFFFF' }
test_small_center:
quality: 75
filters:
thumbnail: { size: [319, 207], mode: outbound, allow_upscale: true}
crop: {size: [ 319, 207 ], start: [ 0, 0 ] }
background : { size : [319, 207], position : center, color : '#FFFFFF' }
test_medium_center_background:
quality: 75
filters:
background : { size : [141, 93], position : center, color : '#FFFFFF' }
thumbnail: { size: [141, 93], mode: outbound, allow_upscale: true}
crop: {size: [ 141, 93 ], start: [ 0, 0 ] }
test_widden:
quality: 75
filters:
relative_resize: {widen: 796}
Ajouter la configuration du formatter
#config/packages/sonata_formatter.yml
sonata_formatter:
default_formatter: richhtml
formatters:
markdown:
service: sonata.formatter.text.markdown
extensions:
- sonata.formatter.twig.control_flow
- sonata.formatter.twig.gist
# - sonata.media.formatter.twig #keep this commented unless you are using media bundle.
text:
service: sonata.formatter.text.text
extensions:
- sonata.formatter.twig.control_flow
- sonata.formatter.twig.gist
# - sonata.media.formatter.twig
rawhtml:
service: sonata.formatter.text.raw
extensions:
- sonata.formatter.twig.control_flow
- sonata.formatter.twig.gist
# - sonata.media.formatter.twig
richhtml:
service: sonata.formatter.text.raw
extensions:
- sonata.formatter.twig.control_flow
- sonata.formatter.twig.gist
# - sonata.media.formatter.twig
twig:
service: sonata.formatter.text.twigengine
extensions: [] # Twig formatter cannot have extensions
ckeditor:
templates:
browser: '@App/Ckeditor/browser.html.twig'
upload: '@App/Ckeditor/upload.html.twig'
fos_ck_editor:
default_config: default
configs:
default:
# default toolbar plus Format button
toolbar:
- [Bold, Italic, Underline, -, 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock' ,-, Cut, Copy, Paste, PasteText, PasteFromWord, -, Undo, Redo, -, NumberedList, BulletedList, -, Outdent, Indent, -,Blockquote, -, Image, Link, Unlink, Table]
- [Format, Maximize, Source, Iframe]
Et pour terminer l’implémentation de CKeditor il faut ajouter le theme dans twig
#twig.yaml
twig:
default_path: '%kernel.project_dir%/templates'
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
exception_controller: null
form_themes:
- '@SonataFormatter/Form/formatter.html.twig'
Ajouter les routes de media bundle dans config/routes.yaml
#index:
# path: /
# controller: App\Controller\DefaultController::index
gallery:
resource: '@SonataMediaBundle/Resources/config/routing/gallery.xml'
prefix: /media/gallery
media:
resource: '@SonataMediaBundle/Resources/config/routing/media.xml'
prefix: /media
#for 3.x change admin with admin_area
admin:
resource: "@SonataAdminBundle/Resources/config/routing/sonata_admin.xml"
prefix: /admin
_sonata_admin:
resource: .
type: sonata_admin
prefix: /admin
Ensuite dans /config/routes/sonata_admin.yaml ajouter
sonata_user_admin_security:
resource: '@SonataUserBundle/Resources/config/routing/admin_security.xml'
prefix: /admin
sonata_user_admin_resetting:
resource: '@SonataUserBundle/Resources/config/routing/admin_resetting.xml'
prefix: /admin/resetting
admin_area:
resource: "@SonataAdminBundle/Resources/config/routing/sonata_admin.xml"
prefix: /admin
_sonata_admin:
resource: .
type: sonata_admin
prefix: /admin
Ensuite dans /config/packages/sonata_user.yaml ajouter
sonata_user:
security_acl: false
manager_type: orm # can be orm or mongodb
class:
user: App\Application\Sonata\UserBundle\Entity\User
group: App\Application\Sonata\UserBundle\Entity\Group
Ensuite dans /config/packages/security.yaml ajouter
security:
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
providers:
in_memory: { memory: null }
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
# Disabling the security for the web debug toolbar, the profiler and Assetic.
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
# -> custom firewall for the admin area of the URL
admin:
pattern: /admin(.*)
context: user
form_login:
provider: fos_userbundle
login_path: /admin/login
use_forward: false
check_path: /admin/login_check
failure_path: null
logout:
path: /admin/logout
target: /admin/login
anonymous: true
# -> end custom configuration
# default login area for standard users
# This firewall is used to handle the public login area
# This part is handled by the FOS User Bundle
main:
pattern: .*
context: user
form_login:
provider: fos_userbundle
login_path: /login
use_forward: false
check_path: /login_check
failure_path: null
logout: true
anonymous: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
# Admin login page needs to be accessed without credential
- { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/login_check$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
# Secured part of the site
# This config requires being logged for the whole site and having the admin role for the admin part.
# Change these rules to adapt them to your needs
- { path: ^/admin/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN, ROLE_SUPER_ADMIN] }
- { path: ^/.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
Ensuite dans /config/packages/swiftmailer.yaml ajouter
swiftmailer:
url: '%env(MAILER_URL)%'
#pour envoyer directement un email sans attendre
#spool: { type: 'memory' }
#pour utiliser le spooler d'envois.
#dans ce cas, inscrire une cron :
#* * * * * cd /var/www/monprojet/ && APP_ENV=prod php bin/console swiftmailer:spool:send --message-limit=3
spool:
type: file
path: '%kernel.project_dir%/var/spool'
Ensuite dans /config/packages/fos_user.yaml ajouter
fos_user:
db_driver: orm # can be orm or odm
firewall_name: main
#user_class: Sonata\UserBundle\Entity\BaseUser
user_class: App\Application\Sonata\UserBundle\Entity\User
group:
#group_class: Sonata\UserBundle\Entity\BaseGroup
group_class: App\Application\Sonata\UserBundle\Entity\Group
group_manager: sonata.user.orm.group_manager # If you're using doctrine orm (use sonata.user.mongodb.group_manager for mongodb)
service:
user_manager: sonata.user.orm.user_manager
from_email:
address: "tbourdin@partitech.com"
sender_name: "tbourdin@partitech.com"
Configurer les locales pour avoir l’interface en français dans /config/packages/translation.yaml
framework:
default_locale: fr
translator:
default_path: '%kernel.project_dir%/translations'
fallbacks:
- en
Puis configurer le timezone :
#config/packages/sonata_intl.yaml
sonata_intl:
timezone:
default: Europe/Paris
locales:
fr: Europe/Paris
en_UK: Europe/London
Il faut ensuite étendre le bundle :
bin/console sonata:easy-extends:generate SonataUserBundle --dest=src --namespace_prefix=App
Il faut aussi générer les entity de média bundle
bin/console sonata:easy-extends:generate --dest=src SonataMediaBundle --namespace_prefix=App
Et l’enregistrer dans les bundle à loader (/config/bundles.php) ajouter l’appel à ApplicationSonataUserBundle :
<?php
return [
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
Sonata\DatagridBundle\SonataDatagridBundle::class => ['all' => true],
Sonata\CoreBundle\SonataCoreBundle::class => ['all' => true],
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
Sonata\BlockBundle\SonataBlockBundle::class => ['all' => true],
Knp\Bundle\MenuBundle\KnpMenuBundle::class => ['all' => true],
Sonata\AdminBundle\SonataAdminBundle::class => ['all' => true],
Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
Sonata\DoctrineORMAdminBundle\SonataDoctrineORMAdminBundle::class => ['all' => true],
Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
Sonata\EasyExtendsBundle\SonataEasyExtendsBundle::class => ['all' => true],
Sonata\NotificationBundle\SonataNotificationBundle::class => ['all' => true],
FOS\UserBundle\FOSUserBundle::class => ['all' => true],
Sonata\UserBundle\SonataUserBundle::class => ['all' => true],
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true, 'test' => true],
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle::class => ['all' => true],
Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
JMS\SerializerBundle\JMSSerializerBundle::class => ['all' => true],
Pix\SortableBehaviorBundle\PixSortableBehaviorBundle::class => ['all' => true],
Sonata\MediaBundle\SonataMediaBundle::class => ['all' => true],
App\Application\Sonata\UserBundle\ApplicationSonataUserBundle::class => ['all' => true],
App\Application\Sonata\MediaBundle\ApplicationSonataMediaBundle::class => ['all' => true],
Liip\ImagineBundle\LiipImagineBundle::class => ['all' => true],
Sonata\IntlBundle\SonataIntlBundle::class => ['all' => true],
];
Il faut exclure le répertoire Application de l’autowireing des services
# config/services.yaml
services:
App\:
resource: '../src/*'
exclude: '../src/{Entity,Tests,Application}'
Derniers points, configurer la base de donnée dans le fichier .env
DATABASE_URL=mysql://root:toor@127.0.0.1:3306/delef?serverVersion=5.7
Lancer la création des tables :
php bin/console doctrine:schema:update --force
Installer les assets :
php bin/console assets:install
php bin/console ckeditor:install
Créer le répertoire de stockage des fichiers
mkdir -p public/uploads/media
Vider le cache :
php bin/console cache:clear
Et créez l’utilisateur admin
php bin/console fos:user:create admin mail@mail.com p@ssword --super-admin