Browse Source

Initialisation projet default symfony 5.2

develop
Fab 3 years ago
parent
commit
fc1cfda844
56 changed files with 4188 additions and 215 deletions
  1. +1
    -1
      .env
  2. +4
    -0
      .idea/encodings.xml
  3. +119
    -0
      .idea/laclic.iml
  4. +8
    -0
      .idea/modules.xml
  5. +117
    -0
      .idea/php.xml
  6. +6
    -0
      .idea/symfony2.xml
  7. +6
    -0
      .idea/vcs.xml
  8. +214
    -0
      .idea/workspace.xml
  9. +4
    -1
      composer.json
  10. +2165
    -203
      composer.lock
  11. +3
    -0
      config/bundles.php
  12. +2
    -0
      config/packages/doctrine.yaml
  13. +5
    -0
      config/packages/fos_ckeditor.yaml
  14. +19
    -4
      config/packages/security.yaml
  15. +11
    -0
      config/packages/stof_doctrine_extensions.yaml
  16. +10
    -0
      config/routes.yaml
  17. +31
    -0
      migrations/Version20201222170752.php
  18. +31
    -0
      migrations/Version20201222184037.php
  19. +33
    -0
      migrations/Version20201222234607.php
  20. +31
    -0
      migrations/Version20201224104808.php
  21. BIN
      public/assets/img/laclic.png
  22. BIN
      public/uploads/d83278b80c722bc4e8befdcd519321cb.jpg
  23. BIN
      public/uploads/tinternet-logo.png
  24. +17
    -0
      readme.md
  25. +138
    -0
      src/Command/CreateUserCommand.php
  26. +22
    -0
      src/Controller/Admin/AbstractCrudController.php
  27. +60
    -0
      src/Controller/Admin/DashboardController.php
  28. +38
    -0
      src/Controller/Admin/PageCrudController.php
  29. +71
    -0
      src/Controller/Admin/SecurityController.php
  30. +29
    -0
      src/Entity/Page.php
  31. +167
    -0
      src/Entity/User.php
  32. +9
    -0
      src/IModel/BlameableInterface.php
  33. +11
    -0
      src/IModel/ImageInterface.php
  34. +10
    -0
      src/IModel/SeoInterface.php
  35. +8
    -0
      src/IModel/SluggableInterface.php
  36. +8
    -0
      src/IModel/SortableInterface.php
  37. +8
    -0
      src/IModel/StatusInterface.php
  38. +9
    -0
      src/IModel/TimestampableInterface.php
  39. +22
    -0
      src/IModel/TreeInterface.php
  40. +8
    -0
      src/IModel/UserInterface.php
  41. +78
    -0
      src/Model/AbstractDocumentEntity.php
  42. +51
    -0
      src/Model/BlameableTrait.php
  43. +52
    -0
      src/Model/ImageTrait.php
  44. +63
    -0
      src/Model/SeoTrait.php
  45. +27
    -0
      src/Model/SluggableTrait.php
  46. +34
    -0
      src/Model/SortableTrait.php
  47. +25
    -0
      src/Model/StatusTrait.php
  48. +46
    -0
      src/Model/TimestampableTrait.php
  49. +11
    -0
      src/Model/TreeTrait.php
  50. +50
    -0
      src/Repository/PageRepository.php
  51. +67
    -0
      src/Repository/UserRepository.php
  52. +107
    -0
      src/Security/LoginFormAuthenticator.php
  53. +48
    -6
      symfony.lock
  54. +11
    -0
      templates/registration/confirmation_email.html.twig
  55. +21
    -0
      templates/registration/register.html.twig
  56. +42
    -0
      templates/security/login.html.twig

+ 1
- 1
.env View File

@@ -19,7 +19,7 @@ APP_SECRET=730296c1ebb1c7bc2a3ba2eeaadb0f6e
###< symfony/framework-bundle ###

###> symfony/mailer ###
# MAILER_DSN=smtp://localhost
MAILER_DSN=smtp://localhost
###< symfony/mailer ###

###> doctrine/doctrine-bundle ###

+ 4
- 0
.idea/encodings.xml View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with NO BOM" />
</project>

+ 119
- 0
.idea/laclic.iml View File

@@ -0,0 +1,119 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="App\" />
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="App\Tests\" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/service-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-idn" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/serializer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/debug-bundle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/routing" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/error-handler" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/flex" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/notifier" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/cache-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/property-info" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/console" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/framework-bundle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/process" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-normalizer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/intl" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/filesystem" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/twig-bridge" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-client" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/dotenv" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/form" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-mbstring" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/monolog-bridge" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/asset" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-foundation" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/config" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/stopwatch" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sensio/framework-extra-bundle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/webmozart/assert" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-docblock" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/type-resolver" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-common" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/cache" />
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/event-manager" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/annotations" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/lexer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/doctrine-bundle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/common" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/collections" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/instantiator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/monolog/monolog" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/inflector" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/persistence" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/doctrine-migrations-bundle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/orm" />
<excludeFolder url="file://$MODULE_DIR$/vendor/egulias/email-validator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/nikic/php-parser" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/yaml" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/dbal" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/sql-formatter" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/phpunit-bridge" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/var-dumper" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/migrations" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/container" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/cache" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/event-dispatcher" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/log" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/link" />
<excludeFolder url="file://$MODULE_DIR$/vendor/laminas/laminas-zendframework-bridge" />
<excludeFolder url="file://$MODULE_DIR$/vendor/laminas/laminas-eventmanager" />
<excludeFolder url="file://$MODULE_DIR$/vendor/laminas/laminas-code" />
<excludeFolder url="file://$MODULE_DIR$/vendor/twig/twig" />
<excludeFolder url="file://$MODULE_DIR$/vendor/twig/extra-bundle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/security-guard" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/deprecation-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/security-bundle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/dependency-injection" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/mime" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/validator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/browser-kit" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php80" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-client-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/dom-crawler" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/css-selector" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/property-access" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/monolog-bundle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-grapheme" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-icu" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/cache" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/options-resolver" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/doctrine-bridge" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/twig-bundle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php73" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-kernel" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/mailer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/finder" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/security-csrf" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/expression-language" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/maker-bundle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/security-core" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/security-http" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/web-link" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/var-exporter" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/web-profiler-bundle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/string" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-uuid" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/uid" />
<excludeFolder url="file://$MODULE_DIR$/vendor/easycorp/easyadmin-bundle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/behat/transliterator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/gedmo/doctrine-extensions" />
<excludeFolder url="file://$MODULE_DIR$/vendor/friendsofsymfony/ckeditor-bundle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/stof/doctrine-extensions-bundle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/friendsofphp/proxy-manager-lts" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

+ 8
- 0
.idea/modules.xml View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/laclic.iml" filepath="$PROJECT_DIR$/.idea/laclic.iml" />
</modules>
</component>
</project>

+ 117
- 0
.idea/php.xml View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PhpIncludePathManager">
<include_path>
<path value="$PROJECT_DIR$/vendor/symfony/service-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-idn" />
<path value="$PROJECT_DIR$/vendor/symfony/serializer" />
<path value="$PROJECT_DIR$/vendor/symfony/debug-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/routing" />
<path value="$PROJECT_DIR$/vendor/symfony/error-handler" />
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher" />
<path value="$PROJECT_DIR$/vendor/symfony/flex" />
<path value="$PROJECT_DIR$/vendor/symfony/notifier" />
<path value="$PROJECT_DIR$/vendor/symfony/cache-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/property-info" />
<path value="$PROJECT_DIR$/vendor/symfony/console" />
<path value="$PROJECT_DIR$/vendor/symfony/framework-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/process" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-normalizer" />
<path value="$PROJECT_DIR$/vendor/symfony/intl" />
<path value="$PROJECT_DIR$/vendor/symfony/filesystem" />
<path value="$PROJECT_DIR$/vendor/symfony/twig-bridge" />
<path value="$PROJECT_DIR$/vendor/symfony/http-client" />
<path value="$PROJECT_DIR$/vendor/symfony/dotenv" />
<path value="$PROJECT_DIR$/vendor/symfony/form" />
<path value="$PROJECT_DIR$/vendor/symfony/translation" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-mbstring" />
<path value="$PROJECT_DIR$/vendor/symfony/monolog-bridge" />
<path value="$PROJECT_DIR$/vendor/symfony/asset" />
<path value="$PROJECT_DIR$/vendor/symfony/translation-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/http-foundation" />
<path value="$PROJECT_DIR$/vendor/symfony/config" />
<path value="$PROJECT_DIR$/vendor/symfony/stopwatch" />
<path value="$PROJECT_DIR$/vendor/sensio/framework-extra-bundle" />
<path value="$PROJECT_DIR$/vendor/webmozart/assert" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-docblock" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/type-resolver" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-common" />
<path value="$PROJECT_DIR$/vendor/doctrine/cache" />
<path value="$PROJECT_DIR$/vendor/composer" />
<path value="$PROJECT_DIR$/vendor/doctrine/event-manager" />
<path value="$PROJECT_DIR$/vendor/doctrine/annotations" />
<path value="$PROJECT_DIR$/vendor/doctrine/lexer" />
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-bundle" />
<path value="$PROJECT_DIR$/vendor/doctrine/common" />
<path value="$PROJECT_DIR$/vendor/doctrine/collections" />
<path value="$PROJECT_DIR$/vendor/doctrine/instantiator" />
<path value="$PROJECT_DIR$/vendor/monolog/monolog" />
<path value="$PROJECT_DIR$/vendor/doctrine/inflector" />
<path value="$PROJECT_DIR$/vendor/doctrine/persistence" />
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-migrations-bundle" />
<path value="$PROJECT_DIR$/vendor/doctrine/orm" />
<path value="$PROJECT_DIR$/vendor/egulias/email-validator" />
<path value="$PROJECT_DIR$/vendor/nikic/php-parser" />
<path value="$PROJECT_DIR$/vendor/symfony/yaml" />
<path value="$PROJECT_DIR$/vendor/doctrine/dbal" />
<path value="$PROJECT_DIR$/vendor/doctrine/sql-formatter" />
<path value="$PROJECT_DIR$/vendor/symfony/phpunit-bridge" />
<path value="$PROJECT_DIR$/vendor/symfony/var-dumper" />
<path value="$PROJECT_DIR$/vendor/doctrine/migrations" />
<path value="$PROJECT_DIR$/vendor/psr/container" />
<path value="$PROJECT_DIR$/vendor/psr/cache" />
<path value="$PROJECT_DIR$/vendor/psr/event-dispatcher" />
<path value="$PROJECT_DIR$/vendor/psr/log" />
<path value="$PROJECT_DIR$/vendor/psr/link" />
<path value="$PROJECT_DIR$/vendor/laminas/laminas-zendframework-bridge" />
<path value="$PROJECT_DIR$/vendor/laminas/laminas-eventmanager" />
<path value="$PROJECT_DIR$/vendor/laminas/laminas-code" />
<path value="$PROJECT_DIR$/vendor/twig/twig" />
<path value="$PROJECT_DIR$/vendor/twig/extra-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/security-guard" />
<path value="$PROJECT_DIR$/vendor/symfony/deprecation-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/security-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/dependency-injection" />
<path value="$PROJECT_DIR$/vendor/symfony/mime" />
<path value="$PROJECT_DIR$/vendor/symfony/validator" />
<path value="$PROJECT_DIR$/vendor/symfony/browser-kit" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php80" />
<path value="$PROJECT_DIR$/vendor/symfony/http-client-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/dom-crawler" />
<path value="$PROJECT_DIR$/vendor/symfony/css-selector" />
<path value="$PROJECT_DIR$/vendor/symfony/property-access" />
<path value="$PROJECT_DIR$/vendor/symfony/monolog-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-grapheme" />
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-icu" />
<path value="$PROJECT_DIR$/vendor/symfony/cache" />
<path value="$PROJECT_DIR$/vendor/symfony/options-resolver" />
<path value="$PROJECT_DIR$/vendor/symfony/doctrine-bridge" />
<path value="$PROJECT_DIR$/vendor/symfony/twig-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php73" />
<path value="$PROJECT_DIR$/vendor/symfony/http-kernel" />
<path value="$PROJECT_DIR$/vendor/symfony/mailer" />
<path value="$PROJECT_DIR$/vendor/symfony/finder" />
<path value="$PROJECT_DIR$/vendor/symfony/security-csrf" />
<path value="$PROJECT_DIR$/vendor/symfony/expression-language" />
<path value="$PROJECT_DIR$/vendor/symfony/maker-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/security-core" />
<path value="$PROJECT_DIR$/vendor/symfony/security-http" />
<path value="$PROJECT_DIR$/vendor/symfony/web-link" />
<path value="$PROJECT_DIR$/vendor/symfony/var-exporter" />
<path value="$PROJECT_DIR$/vendor/symfony/web-profiler-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/string" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-uuid" />
<path value="$PROJECT_DIR$/vendor/symfony/uid" />
<path value="$PROJECT_DIR$/vendor/easycorp/easyadmin-bundle" />
<path value="$PROJECT_DIR$/vendor/behat/transliterator" />
<path value="$PROJECT_DIR$/vendor/gedmo/doctrine-extensions" />
<path value="$PROJECT_DIR$/vendor/friendsofsymfony/ckeditor-bundle" />
<path value="$PROJECT_DIR$/vendor/stof/doctrine-extensions-bundle" />
<path value="$PROJECT_DIR$/vendor/friendsofphp/proxy-manager-lts" />
</include_path>
</component>
<component name="PhpProjectSharedConfiguration" php_language_level="7.2">
<option name="suggestChangeDefaultLanguageLevel" value="false" />
</component>
</project>

+ 6
- 0
.idea/symfony2.xml View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Symfony2PluginSettings">
<option name="pluginEnabled" value="true" />
</component>
</project>

+ 6
- 0
.idea/vcs.xml View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

+ 214
- 0
.idea/workspace.xml View File

@@ -0,0 +1,214 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="6c084521-9606-4ed0-8fb0-1d6c8abbf313" name="Default Changelist" comment="">
<change afterPath="$PROJECT_DIR$/public/assets/img/laclic.png" afterDir="false" />
<change afterPath="$PROJECT_DIR$/readme.md" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/Command/CreateUserCommand.php" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/Controller/Admin/AbstractCrudController.php" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/IModel/BlameableInterface.php" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/IModel/ImageInterface.php" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/IModel/SeoInterface.php" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/IModel/SluggableInterface.php" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/IModel/SortableInterface.php" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/IModel/StatusInterface.php" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/IModel/TimestampableInterface.php" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/IModel/TreeInterface.php" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/IModel/UserInterface.php" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/Model/AbstractDocumentEntity.php" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/Model/BlameableTrait.php" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/Model/ImageTrait.php" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/Model/SeoTrait.php" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/Model/SluggableTrait.php" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/Model/SortableTrait.php" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/Model/StatusTrait.php" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/Model/TimestampableTrait.php" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/Model/TreeTrait.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.env" beforeDir="false" afterPath="$PROJECT_DIR$/.env" afterDir="false" />
<change beforePath="$PROJECT_DIR$/composer.json" beforeDir="false" afterPath="$PROJECT_DIR$/composer.json" afterDir="false" />
<change beforePath="$PROJECT_DIR$/composer.lock" beforeDir="false" afterPath="$PROJECT_DIR$/composer.lock" afterDir="false" />
<change beforePath="$PROJECT_DIR$/config/bundles.php" beforeDir="false" afterPath="$PROJECT_DIR$/config/bundles.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/config/packages/doctrine.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/config/packages/doctrine.yaml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/config/packages/security.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/config/packages/security.yaml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/config/routes.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/config/routes.yaml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/symfony.lock" beforeDir="false" afterPath="$PROJECT_DIR$/symfony.lock" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="ComposerSettings" doNotAsk="true" synchronizationState="SYNCHRONIZE">
<pharConfigPath>$PROJECT_DIR$/composer.json</pharConfigPath>
<execution />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="composer.json" />
</list>
</option>
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="PhpWorkspaceProjectConfiguration">
<include_path>
<path value="$PROJECT_DIR$/vendor/symfony/service-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-idn" />
<path value="$PROJECT_DIR$/vendor/symfony/serializer" />
<path value="$PROJECT_DIR$/vendor/symfony/debug-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/routing" />
<path value="$PROJECT_DIR$/vendor/symfony/error-handler" />
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher" />
<path value="$PROJECT_DIR$/vendor/symfony/flex" />
<path value="$PROJECT_DIR$/vendor/symfony/notifier" />
<path value="$PROJECT_DIR$/vendor/symfony/cache-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/property-info" />
<path value="$PROJECT_DIR$/vendor/symfony/console" />
<path value="$PROJECT_DIR$/vendor/symfony/framework-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/process" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-normalizer" />
<path value="$PROJECT_DIR$/vendor/symfony/intl" />
<path value="$PROJECT_DIR$/vendor/symfony/filesystem" />
<path value="$PROJECT_DIR$/vendor/symfony/twig-bridge" />
<path value="$PROJECT_DIR$/vendor/symfony/http-client" />
<path value="$PROJECT_DIR$/vendor/symfony/dotenv" />
<path value="$PROJECT_DIR$/vendor/symfony/form" />
<path value="$PROJECT_DIR$/vendor/symfony/translation" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-mbstring" />
<path value="$PROJECT_DIR$/vendor/symfony/monolog-bridge" />
<path value="$PROJECT_DIR$/vendor/symfony/asset" />
<path value="$PROJECT_DIR$/vendor/symfony/translation-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/http-foundation" />
<path value="$PROJECT_DIR$/vendor/symfony/config" />
<path value="$PROJECT_DIR$/vendor/symfony/stopwatch" />
<path value="$PROJECT_DIR$/vendor/sensio/framework-extra-bundle" />
<path value="$PROJECT_DIR$/vendor/webmozart/assert" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-docblock" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/type-resolver" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-common" />
<path value="$PROJECT_DIR$/vendor/doctrine/cache" />
<path value="$PROJECT_DIR$/vendor/composer" />
<path value="$PROJECT_DIR$/vendor/doctrine/event-manager" />
<path value="$PROJECT_DIR$/vendor/doctrine/annotations" />
<path value="$PROJECT_DIR$/vendor/doctrine/lexer" />
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-bundle" />
<path value="$PROJECT_DIR$/vendor/doctrine/common" />
<path value="$PROJECT_DIR$/vendor/doctrine/collections" />
<path value="$PROJECT_DIR$/vendor/doctrine/instantiator" />
<path value="$PROJECT_DIR$/vendor/monolog/monolog" />
<path value="$PROJECT_DIR$/vendor/doctrine/inflector" />
<path value="$PROJECT_DIR$/vendor/doctrine/persistence" />
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-migrations-bundle" />
<path value="$PROJECT_DIR$/vendor/doctrine/orm" />
<path value="$PROJECT_DIR$/vendor/egulias/email-validator" />
<path value="$PROJECT_DIR$/vendor/nikic/php-parser" />
<path value="$PROJECT_DIR$/vendor/symfony/yaml" />
<path value="$PROJECT_DIR$/vendor/doctrine/dbal" />
<path value="$PROJECT_DIR$/vendor/doctrine/sql-formatter" />
<path value="$PROJECT_DIR$/vendor/symfony/phpunit-bridge" />
<path value="$PROJECT_DIR$/vendor/symfony/var-dumper" />
<path value="$PROJECT_DIR$/vendor/doctrine/migrations" />
<path value="$PROJECT_DIR$/vendor/psr/container" />
<path value="$PROJECT_DIR$/vendor/psr/cache" />
<path value="$PROJECT_DIR$/vendor/psr/event-dispatcher" />
<path value="$PROJECT_DIR$/vendor/psr/log" />
<path value="$PROJECT_DIR$/vendor/psr/link" />
<path value="$PROJECT_DIR$/vendor/laminas/laminas-zendframework-bridge" />
<path value="$PROJECT_DIR$/vendor/laminas/laminas-eventmanager" />
<path value="$PROJECT_DIR$/vendor/laminas/laminas-code" />
<path value="$PROJECT_DIR$/vendor/twig/twig" />
<path value="$PROJECT_DIR$/vendor/twig/extra-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/security-guard" />
<path value="$PROJECT_DIR$/vendor/symfony/deprecation-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/security-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/dependency-injection" />
<path value="$PROJECT_DIR$/vendor/symfony/mime" />
<path value="$PROJECT_DIR$/vendor/symfony/validator" />
<path value="$PROJECT_DIR$/vendor/symfony/browser-kit" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php80" />
<path value="$PROJECT_DIR$/vendor/symfony/http-client-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/dom-crawler" />
<path value="$PROJECT_DIR$/vendor/symfony/css-selector" />
<path value="$PROJECT_DIR$/vendor/symfony/property-access" />
<path value="$PROJECT_DIR$/vendor/symfony/monolog-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-grapheme" />
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-icu" />
<path value="$PROJECT_DIR$/vendor/symfony/cache" />
<path value="$PROJECT_DIR$/vendor/symfony/options-resolver" />
<path value="$PROJECT_DIR$/vendor/symfony/doctrine-bridge" />
<path value="$PROJECT_DIR$/vendor/symfony/twig-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php73" />
<path value="$PROJECT_DIR$/vendor/symfony/http-kernel" />
<path value="$PROJECT_DIR$/vendor/symfony/mailer" />
<path value="$PROJECT_DIR$/vendor/symfony/finder" />
<path value="$PROJECT_DIR$/vendor/symfony/security-csrf" />
<path value="$PROJECT_DIR$/vendor/symfony/expression-language" />
<path value="$PROJECT_DIR$/vendor/symfony/maker-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/security-core" />
<path value="$PROJECT_DIR$/vendor/symfony/security-http" />
<path value="$PROJECT_DIR$/vendor/symfony/web-link" />
<path value="$PROJECT_DIR$/vendor/symfony/var-exporter" />
<path value="$PROJECT_DIR$/vendor/symfony/web-profiler-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/string" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-uuid" />
<path value="$PROJECT_DIR$/vendor/symfony/uid" />
<path value="$PROJECT_DIR$/vendor/easycorp/easyadmin-bundle" />
<path value="$PROJECT_DIR$/vendor/behat/transliterator" />
<path value="$PROJECT_DIR$/vendor/gedmo/doctrine-extensions" />
<path value="$PROJECT_DIR$/vendor/friendsofsymfony/ckeditor-bundle" />
<path value="$PROJECT_DIR$/vendor/stof/doctrine-extensions-bundle" />
<path value="$PROJECT_DIR$/vendor/friendsofphp/proxy-manager-lts" />
</include_path>
</component>
<component name="ProjectId" id="1m1BcMe50p9F5XNhv8F7W5EKD8L" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/config/packages" />
<property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
<property name="nodejs_npm_path_reset_for_default_project" value="true" />
<property name="nodejs_package_manager_path" value="npm" />
<property name="vue.rearranger.settings.migration" value="true" />
</component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/config/packages" />
<recent name="$PROJECT_DIR$/src/Controller/Admin" />
<recent name="$PROJECT_DIR$/src/Entity" />
<recent name="$PROJECT_DIR$/src/IModel" />
<recent name="$PROJECT_DIR$/src/Model" />
</key>
<key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/src" />
<recent name="$PROJECT_DIR$/src/Controller/Admin" />
</key>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="6c084521-9606-4ed0-8fb0-1d6c8abbf313" name="Default Changelist" comment="" />
<created>1608651294985</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1608651294985</updated>
<workItem from="1608651296410" duration="46000" />
<workItem from="1608651368896" duration="2728000" />
<workItem from="1608654621074" duration="15245000" />
<workItem from="1608803957962" duration="6833000" />
<workItem from="1610017072502" duration="1791000" />
<workItem from="1610099290999" duration="602000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
</project>

+ 4
- 1
composer.json View File

@@ -12,8 +12,11 @@
"doctrine/doctrine-bundle": "^2.2",
"doctrine/doctrine-migrations-bundle": "^3.0",
"doctrine/orm": "^2.8",
"easycorp/easyadmin-bundle": "^3.1",
"friendsofsymfony/ckeditor-bundle": "^2.2",
"phpdocumentor/reflection-docblock": "^5.2",
"sensio/framework-extra-bundle": "^5.1",
"stof/doctrine-extensions-bundle": "^1.5",
"symfony/asset": "5.2.*",
"symfony/console": "5.2.*",
"symfony/dotenv": "5.2.*",
@@ -25,7 +28,7 @@
"symfony/intl": "5.2.*",
"symfony/mailer": "5.2.*",
"symfony/mime": "5.2.*",
"symfony/monolog-bundle": "^3.1",
"symfony/monolog-bundle": "^3.6",
"symfony/notifier": "5.2.*",
"symfony/process": "5.2.*",
"symfony/property-access": "5.2.*",

+ 2165
- 203
composer.lock
File diff suppressed because it is too large
View File


+ 3
- 0
config/bundles.php View File

@@ -12,4 +12,7 @@ return [
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true, 'test' => true],
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
EasyCorp\Bundle\EasyAdminBundle\EasyAdminBundle::class => ['all' => true],
FOS\CKEditorBundle\FOSCKEditorBundle::class => ['all' => true],
Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true],
];

+ 2
- 0
config/packages/doctrine.yaml View File

@@ -16,3 +16,5 @@ doctrine:
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
resolve_target_entities:
App\IModel\UserInterface: App\Entity\User

+ 5
- 0
config/packages/fos_ckeditor.yaml View File

@@ -0,0 +1,5 @@
# Read the documentation: https://symfony.com/doc/current/bundles/FOSCKEditorBundle/index.html

twig:
form_themes:
- '@FOSCKEditor/Form/ckeditor_widget.html.twig'

+ 19
- 4
config/packages/security.yaml View File

@@ -1,7 +1,15 @@
security:
encoders:
App\Entity\User:
algorithm: auto

# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
users_in_memory: { memory: null }
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: App\Entity\User
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
@@ -9,7 +17,14 @@ security:
main:
anonymous: true
lazy: true
provider: users_in_memory
provider: app_user_provider
guard:
authenticators:
- App\Security\LoginFormAuthenticator
logout:
path: logout
# where to redirect after logout
# target: app_any_route

# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#firewalls-authentication
@@ -20,5 +35,5 @@ security:
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }
- { path: ^/admin, roles: [ROLE_ADMIN, ROLE_SUPER_ADMIN] }
- { path: ^/profile, roles: ROLE_USER }

+ 11
- 0
config/packages/stof_doctrine_extensions.yaml View File

@@ -0,0 +1,11 @@
# Read the documentation: https://symfony.com/doc/current/bundles/StofDoctrineExtensionsBundle/index.html
# See the official DoctrineExtensions documentation for more details: https://github.com/Atlantic18/DoctrineExtensions/tree/master/doc/
stof_doctrine_extensions:
default_locale: fr_FR
orm:
default:
tree: true
timestampable: true # not needed: listeners are not enabled by default
sluggable: true
blameable: true


+ 10
- 0
config/routes.yaml View File

@@ -1,3 +1,13 @@
#index:
# path: /
# controller: App\Controller\DefaultController::index

lc_admin_dashboard:
path: /admin
controller: App\Controller\Admin\DashboardController::index
login:
path: /login
controller: App\Controller\Admin\SecurityController::login
logout:
path: /logout
controller: App\Controller\Admin\SecurityController::logout

+ 31
- 0
migrations/Version20201222170752.php View File

@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20201222170752 extends AbstractMigration
{
public function getDescription() : string
{
return '';
}

public function up(Schema $schema) : void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE user (id INT AUTO_INCREMENT NOT NULL, email VARCHAR(180) NOT NULL, roles LONGTEXT NOT NULL COMMENT \'(DC2Type:json)\', password VARCHAR(255) NOT NULL, lastname VARCHAR(255) DEFAULT NULL, firstname VARCHAR(255) DEFAULT NULL, UNIQUE INDEX UNIQ_8D93D649E7927C74 (email), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
}

public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('DROP TABLE user');
}
}

+ 31
- 0
migrations/Version20201222184037.php View File

@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20201222184037 extends AbstractMigration
{
public function getDescription() : string
{
return '';
}

public function up(Schema $schema) : void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE user ADD is_verified TINYINT(1) NOT NULL');
}

public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE user DROP is_verified');
}
}

+ 33
- 0
migrations/Version20201222234607.php View File

@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20201222234607 extends AbstractMigration
{
public function getDescription() : string
{
return '';
}

public function up(Schema $schema) : void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE page (id INT AUTO_INCREMENT NOT NULL, created_by_id INT NOT NULL, updated_by_id INT NOT NULL, title VARCHAR(255) NOT NULL, description LONGTEXT DEFAULT NULL, dev_alias VARCHAR(255) DEFAULT NULL, meta_title VARCHAR(255) DEFAULT NULL, meta_description LONGTEXT DEFAULT NULL, old_urls LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:array)\', slug VARCHAR(255) NOT NULL, position DOUBLE PRECISION NOT NULL, status DOUBLE PRECISION NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, INDEX IDX_140AB620B03A8386 (created_by_id), INDEX IDX_140AB620896DBBDE (updated_by_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('ALTER TABLE page ADD CONSTRAINT FK_140AB620B03A8386 FOREIGN KEY (created_by_id) REFERENCES user (id)');
$this->addSql('ALTER TABLE page ADD CONSTRAINT FK_140AB620896DBBDE FOREIGN KEY (updated_by_id) REFERENCES user (id)');
}

public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('DROP TABLE page');
}
}

+ 31
- 0
migrations/Version20201224104808.php View File

@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20201224104808 extends AbstractMigration
{
public function getDescription() : string
{
return '';
}

public function up(Schema $schema) : void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE page ADD image VARCHAR(255) DEFAULT NULL');
}

public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE page DROP image');
}
}

BIN
public/assets/img/laclic.png View File

Before After
Width: 523  |  Height: 106  |  Size: 9.8KB

BIN
public/uploads/d83278b80c722bc4e8befdcd519321cb.jpg View File

Before After
Width: 300  |  Height: 300  |  Size: 23KB

BIN
public/uploads/tinternet-logo.png View File

Before After
Width: 1365  |  Height: 347  |  Size: 64KB

+ 17
- 0
readme.md View File

@@ -0,0 +1,17 @@
# Lc AdminBundle
Une administration simple avec symfony 5.2 basé sur le Bundle EasyAadmin 3, développé par <a href="https://laclic.fr">La clic !</a>

## Installation

LcAdminBundle requiert PHP 7.2 ou plus symfony 5.2 ou plus.

$ composer require easycorp/easyadmin-bundle

php bin/console ckeditor:install


## Requirement

- "friendsofsymfony/ckeditor-bundle": "^2.2"
- "gedmo/doctrine-extensions": "^3.0",
- "easycorp/easyadmin-bundle": "^3.1",

+ 138
- 0
src/Command/CreateUserCommand.php View File

@@ -0,0 +1,138 @@
<?php

namespace App\Command;

// Adapter App\Entity\User selon la classe réelle de votre utilisateur
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;

class CreateUserCommand extends Command
{
private $passwordEncoder;
private $entityManager;

public function __construct(UserPasswordEncoderInterface $passwordEncoder, EntityManagerInterface $entityManager)
{
parent::__construct();

$this->passwordEncoder = $passwordEncoder;
$this->entityManager = $entityManager;
}

/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('user:create')
->setDescription('Create a user.')
->setDefinition(array(
new InputArgument('email', InputArgument::REQUIRED, 'The email'),
new InputArgument('password', InputArgument::REQUIRED, 'The password'),
new InputArgument('role', InputArgument::REQUIRED, 'ROLE'),
))
->setHelp(<<<'EOT'
The <info>user:create</info> command creates a user:

<info>php %command.full_name% romaric@netinfluence.ch</info>

This interactive shell will ask you for a password.

You can create a super admin via the super-admin flag:

<info>php %command.full_name% admin --super-admin</info>
EOT
);
}

/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$email = $input->getArgument('email');
$password = $input->getArgument('password');
$role = $input->getArgument('role');

$user = (new User())
->setEmail($email)
->setRoles(array($role))
;

$password = $this->passwordEncoder->encodePassword($user, $password);

$user->setPassword($password);

$this->entityManager->persist($user);
$this->entityManager->flush();

$output->writeln(sprintf('Created user <comment>%s</comment>', $email));
return Command::SUCCESS;
}

/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$questions = array();

if (!$input->getArgument('email')) {
$question = new Question('Email : ');
$question->setValidator(function ($password) {
if (empty($password)) {
throw new \Exception('Email can not be empty');
}

return $password;
});
$questions['email'] = $question;
}

if (!$input->getArgument('password')) {
$question = new Question('Password : ');
$question->setValidator(function ($password) {
if (empty($password)) {
throw new \Exception('Password can not be empty');
}

return $password;
});
$question->setHidden(true);
$questions['password'] = $question;
}

if (!$input->getArgument('role')) {
$question = new Question('Rôle [admin/superadmin/user] : ');
$question->setValidator(function ($role) {
if ($role == 'admin') {
$role = 'ROLE_ADMIN';
}else if ($role == 'superadmin') {
$role = 'ROLE_SUPER_ADMIN';
}else if ($role == 'user') {
$role = 'ROLE_USER';
}else{
throw new \Exception('Choose a role');

}
return $role;
});
$questions['role'] = $question;
}



foreach ($questions as $name => $question) {
$answer = $this->getHelper('question')->ask($input, $output, $question);
$input->setArgument($name, $answer);
}
}
}

+ 22
- 0
src/Controller/Admin/AbstractCrudController.php View File

@@ -0,0 +1,22 @@
<?php

namespace App\Controller\Admin;

use App\Entity\Page;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController as ModelAbstractCrudController;

abstract class AbstractCrudController extends ModelAbstractCrudController
{

/*
public function configureFields(string $pageName): iterable
{
return [
IdField::new('id'),
TextField::new('title'),
TextEditorField::new('description'),
];
}
*/
}

+ 60
- 0
src/Controller/Admin/DashboardController.php View File

@@ -0,0 +1,60 @@
<?php

namespace App\Controller\Admin;

use App\Entity\Page;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard;
use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class DashboardController extends AbstractDashboardController
{

public function index(): Response
{
return parent::index();
}

public function configureDashboard(): Dashboard
{
return Dashboard::new()
// the name visible to end users
->setTitle('LA CLIC !')
// you can include HTML contents too (e.g. to link to an image)
->setTitle('<img src="assets/img/laclic.png" width="100px">')
// the path defined in this method is passed to the Twig asset() function
->setFaviconPath('favicon.svg')
// the domain used by default is 'messages'
->setTranslationDomain('lcadmin');
}

public function configureCrud(): Crud
{
$crud = Crud::new();
return $crud
->addFormTheme('@FOSCKEditor/Form/ckeditor_widget.html.twig');
}

public function configureMenuItems(): iterable
{
return [
MenuItem::linkToDashboard('Tableau de bord', 'fa fa-home'),
MenuItem::linkToCrud('Pages', 'fa fa-tags', Page::class),


/*
MenuItem::section('Blog'),
MenuItem::linkToCrud('Categories', 'fa fa-tags', Category::class),
MenuItem::linkToCrud('Blog Posts', 'fa fa-file-text', BlogPost::class),

MenuItem::section('Users'),
MenuItem::linkToCrud('Comments', 'fa fa-comment', Comment::class),
MenuItem::linkToCrud('Users', 'fa fa-user', User::class),*/

//MenuItem::linkToLogout('Déconnexion', 'fa fa-exit'),
];
}
}

+ 38
- 0
src/Controller/Admin/PageCrudController.php View File

@@ -0,0 +1,38 @@
<?php

namespace App\Controller\Admin;

use App\Entity\Page;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField;
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField;
use EasyCorp\Bundle\EasyAdminBundle\Field\ImageField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;

class PageCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return Page::class;
}


public function configureFields(string $pageName): iterable
{
return [
TextField::new('title'),
TextEditorField::new('description'),
ImageField::new('image')
->setBasePath('/uploads/')
->setUploadDir('public/uploads/'),
TextField::new('devAlias'),
ChoiceField::new('status')
->setChoices(['En ligne'=> 1, 'Hors ligne'=>0])
->setFormTypeOption('expanded', true)
->setFormTypeOption('multiple', false)
->setCustomOption('widget', false)
];
}

}

+ 71
- 0
src/Controller/Admin/SecurityController.php View File

@@ -0,0 +1,71 @@
<?php

namespace App\Controller\Admin;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;

class SecurityController extends AbstractController
{

public function login(AuthenticationUtils $authenticationUtils): Response
{
if ($this->getUser()) {
return $this->redirectToRoute('lc_');
}

// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();

return $this->render('@EasyAdmin/page/login.html.twig', [
// parameters usually defined in Symfony login forms
'error' => $error,
'last_username' => $lastUsername,

// OPTIONAL parameters to customize the login form:

// the translation_domain to use (define this option only if you are
// rendering the login template in a regular Symfony controller; when
// rendering it from an EasyAdmin Dashboard this is automatically set to
// the same domain as the rest of the Dashboard)
'translation_domain' => 'admin',

// the title visible above the login form (define this option only if you are
// rendering the login template in a regular Symfony controller; when rendering
// it from an EasyAdmin Dashboard this is automatically set as the Dashboard title)
'page_title' => '<img src="assets/img/laclic.png" >',

// the string used to generate the CSRF token. If you don't define
// this parameter, the login form won't include a CSRF token
'csrf_token_intention' => 'authenticate',

// the URL users are redirected to after the login (default: '/admin')
'target_path' => $this->generateUrl('lc_admin_dashboard'),

// the label displayed for the username form field (the |trans filter is applied to it)
'username_label' => 'Your username',

// the label displayed for the password form field (the |trans filter is applied to it)
'password_label' => 'Your password',

// the label displayed for the Sign In form button (the |trans filter is applied to it)
'sign_in_label' => 'Log in',

// the 'name' HTML attribute of the <input> used for the username field (default: '_username')
'username_parameter' => 'email',

// the 'name' HTML attribute of the <input> used for the password field (default: '_password')
'password_parameter' => 'password',
]);
}


public function logout()
{
throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
}
}

+ 29
- 0
src/Entity/Page.php View File

@@ -0,0 +1,29 @@
<?php

namespace App\Entity;

use App\IModel\ImageInterface;
use App\Model\AbstractDocumentEntity;
use App\Model\ImageTrait;
use App\Repository\PageRepository;
use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity(repositoryClass=PageRepository::class)
*/
class Page extends AbstractDocumentEntity implements ImageInterface
{
use ImageTrait;

/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;

public function getId(): ?int
{
return $this->id;
}
}

+ 167
- 0
src/Entity/User.php View File

@@ -0,0 +1,167 @@
<?php

namespace App\Entity;

use App\Repository\UserRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface;

/**
* @ORM\Entity(repositoryClass=UserRepository::class)
* @UniqueEntity(fields={"email"}, message="There is already an account with this email")
*/
class User implements UserInterface
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;

/**
* @ORM\Column(type="string", length=180, unique=true)
*/
private $email;

/**
* @ORM\Column(type="json")
*/
private $roles = [];

/**
* @var string The hashed password
* @ORM\Column(type="string")
*/
private $password;

/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $lastname;

/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $firstname;

/**
* @ORM\Column(type="boolean")
*/
private $isVerified = false;

public function getId(): ?int
{
return $this->id;
}

public function getEmail(): ?string
{
return $this->email;
}

public function setEmail(string $email): self
{
$this->email = $email;

return $this;
}

/**
* A visual identifier that represents this user.
*
* @see UserInterface
*/
public function getUsername(): string
{
return (string) $this->email;
}

/**
* @see UserInterface
*/
public function getRoles(): array
{
$roles = $this->roles;
// guarantee every user at least has ROLE_USER
$roles[] = 'ROLE_USER';

return array_unique($roles);
}

public function setRoles(array $roles): self
{
$this->roles = $roles;

return $this;
}

/**
* @see UserInterface
*/
public function getPassword(): string
{
return (string) $this->password;
}

public function setPassword(string $password): self
{
$this->password = $password;

return $this;
}

/**
* @see UserInterface
*/
public function getSalt()
{
// not needed when using the "bcrypt" algorithm in security.yaml
}

/**
* @see UserInterface
*/
public function eraseCredentials()
{
// If you store any temporary, sensitive data on the user, clear it here
// $this->plainPassword = null;
}

public function getLastname(): ?string
{
return $this->lastname;
}

public function setLastname(?string $lastname): self
{
$this->lastname = $lastname;

return $this;
}

public function getFirstname(): ?string
{
return $this->firstname;
}

public function setFirstname(?string $firstname): self
{
$this->firstname = $firstname;

return $this;
}

public function isVerified(): bool
{
return $this->isVerified;
}

public function setIsVerified(bool $isVerified): self
{
$this->isVerified = $isVerified;

return $this;
}
}

+ 9
- 0
src/IModel/BlameableInterface.php View File

@@ -0,0 +1,9 @@
<?php

namespace App\IModel;

interface BlameableInterface
{

}

+ 11
- 0
src/IModel/ImageInterface.php View File

@@ -0,0 +1,11 @@
<?php

namespace App\IModel;


interface ImageInterface
{



}

+ 10
- 0
src/IModel/SeoInterface.php View File

@@ -0,0 +1,10 @@
<?php

namespace App\IModel;

interface SeoInterface
{



}

+ 8
- 0
src/IModel/SluggableInterface.php View File

@@ -0,0 +1,8 @@
<?php

namespace App\IModel;

interface SluggableInterface
{

}

+ 8
- 0
src/IModel/SortableInterface.php View File

@@ -0,0 +1,8 @@
<?php

namespace App\IModel;

interface SortableInterface
{

}

+ 8
- 0
src/IModel/StatusInterface.php View File

@@ -0,0 +1,8 @@
<?php

namespace App\IModel;

interface StatusInterface
{

}

+ 9
- 0
src/IModel/TimestampableInterface.php View File

@@ -0,0 +1,9 @@
<?php

namespace App\IModel;

interface TimestampableInterface
{


}

+ 22
- 0
src/IModel/TreeInterface.php View File

@@ -0,0 +1,22 @@
<?php

namespace App\IModel;

interface TreeInterface
{
/**
* Retourne le parent d'une entité
*
* @return entity
*/
public function getParent();


/**
* Retourne les enfants d'une entité
*
* @return entity
*/

public function getChildrens();
}

+ 8
- 0
src/IModel/UserInterface.php View File

@@ -0,0 +1,8 @@
<?php

namespace App\IModel;

interface UserInterface
{

}

+ 78
- 0
src/Model/AbstractDocumentEntity.php View File

@@ -0,0 +1,78 @@
<?php

namespace App\Model;

use App\IModel\BlameableInterface;
use App\IModel\SeoInterface;
use App\IModel\SluggableInterface;
use App\IModel\SortableInterface;
use App\IModel\TimestampableInterface;
use App\IModel\StatusInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\MappedSuperclass
*/
abstract class AbstractDocumentEntity implements BlameableInterface, SeoInterface, SluggableInterface, SortableInterface, StatusInterface, TimestampableInterface
{

use BlameableTrait;
use SeoTrait;
use SluggableTrait;
use SortableTrait;
use StatusTrait;
use TimestampableTrait;

/**
* @ORM\Column(type="string", length=255)
*/
protected $title;

/**
* @ORM\Column(type="text", nullable=true)
*/
protected $description;

/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
protected $devAlias;


public function getTitle(): ?string
{
return $this->title;
}

public function setTitle(string $title): self
{
$this->title = $title;

return $this;
}


public function getDescription(): ?string
{
return $this->description;
}

public function setDescription(?string $description): self
{
$this->description = $description;

return $this;
}

public function getDevAlias(): ?string
{
return $this->devAlias;
}

public function setDevAlias(?string $devAlias): self
{
$this->devAlias = $devAlias;

return $this;
}

}

+ 51
- 0
src/Model/BlameableTrait.php View File

@@ -0,0 +1,51 @@
<?php

namespace App\Model;

use App\IModel\UserInterface;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;

trait BlameableTrait
{

/**
* @Gedmo\Blameable(on="create")
* @ORM\ManyToOne(targetEntity="App\Entity\User")
* @ORM\JoinColumn(nullable=false)
*/
protected $createdBy;

/**
* @Gedmo\Blameable(on="update")
* @ORM\ManyToOne(targetEntity="App\Entity\User")
* @ORM\JoinColumn(nullable=false)
*/
protected $updatedBy;


public function getCreatedBy(): ?UserInterface
{
return $this->createdBy;
}

public function setCreatedBy(?UserInterface $createdBy): self
{
$this->createdBy = $createdBy;

return $this;
}

public function getUpdatedBy(): ?UserInterface
{
return $this->updatedBy;
}

public function setUpdatedBy(?UserInterface $updatedBy): self
{
$this->updatedBy = $updatedBy;

return $this;
}

}

+ 52
- 0
src/Model/ImageTrait.php View File

@@ -0,0 +1,52 @@
<?php

namespace App\Model;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;

trait ImageTrait
{
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
protected $image;

/* /**
* @Vich\UploadableField(mapping="images", fileNameProperty="image")
* @var File
*/
//protected $imageFile;*/
/*
public function setImageFile(File $image = null)
{
$this->imageFile = $image;

// VERY IMPORTANT:
// It is required that at least one field changes if you are using Doctrine,
// otherwise the event listeners won't be called and the file is lost
if ($image) {
// if 'updatedAt' is not defined in your entity, use another property
$this->updatedAt = new \DateTime('now');
}
}

public function getImageFile()
{
return $this->imageFile;
}*/

public function getImage(): ?string
{
return $this->image;
}

public function setImage(?string $image): self
{
$this->image = $image;

return $this;
}


}

+ 63
- 0
src/Model/SeoTrait.php View File

@@ -0,0 +1,63 @@
<?php

namespace App\Model;

use Doctrine\ORM\Mapping as ORM;

trait SeoTrait
{
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
protected $metaTitle;


/**
* @ORM\Column(type="text", nullable=true)
*/
protected $metaDescription;


/**
* @var array
* @ORM\Column(type="array", nullable=true)
*/
protected $oldUrls;


public function getMetaTitle(): ?string
{
return $this->metaTitle;
}

public function setMetaTitle(?string $metaTitle): self
{
$this->metaTitle = $metaTitle;

return $this;
}

public function getMetaDescription(): ?string
{
return $this->metaDescription;
}

public function setMetaDescription(?string $metaDescription): self
{
$this->metaDescription = $metaDescription;

return $this;
}

public function setOldUrls($oldUrls): self
{
$this->oldUrls = $oldUrls;

return $this;
}

public function getOldUrls(): ?array
{
return $this->oldUrls;
}
}

+ 27
- 0
src/Model/SluggableTrait.php View File

@@ -0,0 +1,27 @@
<?php

namespace App\Model;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;

trait SluggableTrait
{
/**
* @ORM\Column(type="string", length=255)
* @Gedmo\Slug(fields={"title"})
*/
protected $slug;

public function getSlug(): ?string
{
return $this->slug;
}

public function setSlug(?string $slug): self
{
$this->slug = $slug;

return $this;
}
}

+ 34
- 0
src/Model/SortableTrait.php View File

@@ -0,0 +1,34 @@
<?php

namespace App\Model;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;


trait SortableTrait
{
/**
* @var string
* @ORM\Column(type="float")
*/
protected $position = 0;

/**
* @return float
*/
public function getPosition(): float
{
return $this->position;
}

/**
* @param float $position
* @return $this
*/
public function setPosition(float $position): self
{
$this->position = $position;
return $this;
}
}

+ 25
- 0
src/Model/StatusTrait.php View File

@@ -0,0 +1,25 @@
<?php

namespace App\Model;

use Doctrine\ORM\Mapping as ORM;

trait StatusTrait
{
/**
* @ORM\Column(type="float")
*/
protected $status;

public function getStatus(): ?float
{
return $this->status;
}

public function setStatus(float $status): self
{
$this->status = $status;

return $this;
}
}

+ 46
- 0
src/Model/TimestampableTrait.php View File

@@ -0,0 +1,46 @@
<?php

namespace App\Model;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;

trait TimestampableTrait
{
/**
* @ORM\Column(type="datetime")
* @Gedmo\Timestampable(on="create")
*/
protected $createdAt;

/**
* @ORM\Column(type="datetime")
* @Gedmo\Timestampable(on="update")
*/
protected $updatedAt;

public function getCreatedAt(): ?\DateTimeInterface
{
return $this->createdAt;
}

public function setCreatedAt(\DateTimeInterface $createdAt): self
{
$this->createdAt = $createdAt;

return $this;
}

public function getUpdatedAt(): ?\DateTimeInterface
{
return $this->updatedAt;
}

public function setUpdatedAt(\DateTimeInterface $updatedAt): self
{
$this->updatedAt = $updatedAt;

return $this;
}

}

+ 11
- 0
src/Model/TreeTrait.php View File

@@ -0,0 +1,11 @@
<?php

namespace App\Model;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

trait TreeTrait
{

}

+ 50
- 0
src/Repository/PageRepository.php View File

@@ -0,0 +1,50 @@
<?php

namespace App\Repository;

use App\Entity\Page;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

/**
* @method Page|null find($id, $lockMode = null, $lockVersion = null)
* @method Page|null findOneBy(array $criteria, array $orderBy = null)
* @method Page[] findAll()
* @method Page[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class PageRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Page::class);
}

// /**
// * @return Page[] Returns an array of Page objects
// */
/*
public function findByExampleField($value)
{
return $this->createQueryBuilder('p')
->andWhere('p.exampleField = :val')
->setParameter('val', $value)
->orderBy('p.id', 'ASC')
->setMaxResults(10)
->getQuery()
->getResult()
;
}
*/

/*
public function findOneBySomeField($value): ?Page
{
return $this->createQueryBuilder('p')
->andWhere('p.exampleField = :val')
->setParameter('val', $value)
->getQuery()
->getOneOrNullResult()
;
}
*/
}

+ 67
- 0
src/Repository/UserRepository.php View File

@@ -0,0 +1,67 @@
<?php

namespace App\Repository;

use App\Entity\User;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
use Symfony\Component\Security\Core\User\UserInterface;

/**
* @method User|null find($id, $lockMode = null, $lockVersion = null)
* @method User|null findOneBy(array $criteria, array $orderBy = null)
* @method User[] findAll()
* @method User[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class UserRepository extends ServiceEntityRepository implements PasswordUpgraderInterface
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, User::class);
}

/**
* Used to upgrade (rehash) the user's password automatically over time.
*/
public function upgradePassword(UserInterface $user, string $newEncodedPassword): void
{
if (!$user instanceof User) {
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', \get_class($user)));
}

$user->setPassword($newEncodedPassword);
$this->_em->persist($user);
$this->_em->flush();
}

// /**
// * @return User[] Returns an array of User objects
// */
/*
public function findByExampleField($value)
{
return $this->createQueryBuilder('u')
->andWhere('u.exampleField = :val')
->setParameter('val', $value)
->orderBy('u.id', 'ASC')
->setMaxResults(10)
->getQuery()
->getResult()
;
}
*/

/*
public function findOneBySomeField($value): ?User
{
return $this->createQueryBuilder('u')
->andWhere('u.exampleField = :val')
->setParameter('val', $value)
->getQuery()
->getOneOrNullResult()
;
}
*/
}

+ 107
- 0
src/Security/LoginFormAuthenticator.php View File

@@ -0,0 +1,107 @@
<?php

namespace App\Security;

use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
use Symfony\Component\Security\Guard\PasswordAuthenticatedInterface;
use Symfony\Component\Security\Http\Util\TargetPathTrait;

class LoginFormAuthenticator extends AbstractFormLoginAuthenticator implements PasswordAuthenticatedInterface
{
use TargetPathTrait;

public const LOGIN_ROUTE = 'login';

private $entityManager;
private $urlGenerator;
private $csrfTokenManager;
private $passwordEncoder;

public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager, UserPasswordEncoderInterface $passwordEncoder)
{
$this->entityManager = $entityManager;
$this->urlGenerator = $urlGenerator;
$this->csrfTokenManager = $csrfTokenManager;
$this->passwordEncoder = $passwordEncoder;
}

public function supports(Request $request)
{
return self::LOGIN_ROUTE === $request->attributes->get('_route')
&& $request->isMethod('POST');
}

public function getCredentials(Request $request)
{
$credentials = [
'email' => $request->request->get('email'),
'password' => $request->request->get('password'),
'csrf_token' => $request->request->get('_csrf_token'),
];
$request->getSession()->set(
Security::LAST_USERNAME,
$credentials['email']
);

return $credentials;
}

public function getUser($credentials, UserProviderInterface $userProvider)
{
$token = new CsrfToken('authenticate', $credentials['csrf_token']);
if (!$this->csrfTokenManager->isTokenValid($token)) {
throw new InvalidCsrfTokenException();
}
dump($credentials);
$user = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $credentials['email']]);

if (!$user) {
die('ncncn');
// fail authentication with a custom error
throw new CustomUserMessageAuthenticationException('Email could not be found.');
}

return $user;
}

public function checkCredentials($credentials, UserInterface $user)
{
return $this->passwordEncoder->isPasswordValid($user, $credentials['password']);
}

/**
* Used to upgrade (rehash) the user's password automatically over time.
*/
public function getPassword($credentials): ?string
{
return $credentials['password'];
}

public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey)
{
if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
return new RedirectResponse($targetPath);
}

return new RedirectResponse($this->urlGenerator->generate('lc_admin_dashboard'));
}

protected function getLoginUrl()
{
return $this->urlGenerator->generate(self::LOGIN_ROUTE);
}
}

+ 48
- 6
symfony.lock View File

@@ -1,4 +1,7 @@
{
"behat/transliterator": {
"version": "v1.3.0"
},
"composer/package-versions-deprecated": {
"version": "1.11.99.1"
},
@@ -78,9 +81,36 @@
"doctrine/sql-formatter": {
"version": "1.1.1"
},
"easycorp/easyadmin-bundle": {
"version": "3.0",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "master",
"version": "3.0",
"ref": "b131e6cbfe1b898a508987851963fff485986285"
}
},
"egulias/email-validator": {
"version": "2.1.24"
},
"friendsofphp/proxy-manager-lts": {
"version": "v1.0.0"
},
"friendsofsymfony/ckeditor-bundle": {
"version": "2.0",
"recipe": {
"repo": "github.com/symfony/recipes-contrib",
"branch": "master",
"version": "2.0",
"ref": "8eb1cd0962ded6a6d6e1e5a9b6d3e888f9f94ff6"
},
"files": [
"config/packages/fos_ckeditor.yaml"
]
},
"gedmo/doctrine-extensions": {
"version": "v3.0.0"
},
"laminas/laminas-code": {
"version": "3.5.1"
},
@@ -96,9 +126,6 @@
"nikic/php-parser": {
"version": "v4.10.4"
},
"ocramius/proxy-manager": {
"version": "2.8.0"
},
"php": {
"version": "7.4"
},
@@ -138,6 +165,18 @@
"config/packages/sensio_framework_extra.yaml"
]
},
"stof/doctrine-extensions-bundle": {
"version": "1.2",
"recipe": {
"repo": "github.com/symfony/recipes-contrib",
"branch": "master",
"version": "1.2",
"ref": "6c1ceb662f8997085f739cd089bfbef67f245983"
},
"files": [
"config/packages/stof_doctrine_extensions.yaml"
]
},
"symfony/asset": {
"version": "v5.2.1"
},
@@ -362,6 +401,9 @@
"symfony/polyfill-php80": {
"version": "v1.20.0"
},
"symfony/polyfill-uuid": {
"version": "v1.20.0"
},
"symfony/process": {
"version": "v5.2.1"
},
@@ -466,6 +508,9 @@
"symfony/twig-pack": {
"version": "v1.0.1"
},
"symfony/uid": {
"version": "v5.2.1"
},
"symfony/validator": {
"version": "4.3",
"recipe": {
@@ -511,9 +556,6 @@
"twig/twig": {
"version": "v3.1.1"
},
"webimpress/safe-writer": {
"version": "2.1.0"
},
"webmozart/assert": {
"version": "1.9.1"
}

+ 11
- 0
templates/registration/confirmation_email.html.twig View File

@@ -0,0 +1,11 @@
<h1>Hi! Please confirm your email!</h1>

<p>
Please confirm your email address by clicking the following link: <br><br>
<a href="{{ signedUrl|raw }}">Confirm my Email</a>.
This link will expire in {{ expiresAtMessageKey|trans(expiresAtMessageData, 'VerifyEmailBundle') }}.
</p>

<p>
Cheers!
</p>

+ 21
- 0
templates/registration/register.html.twig View File

@@ -0,0 +1,21 @@
{% extends 'base.html.twig' %}

{% block title %}Register{% endblock %}

{% block body %}
{% for flashError in app.flashes('verify_email_error') %}
<div class="alert alert-danger" role="alert">{{ flashError }}</div>
{% endfor %}

<h1>Register</h1>

{{ form_start(registrationForm) }}
{{ form_row(registrationForm.email) }}
{{ form_row(registrationForm.plainPassword, {
label: 'Password'
}) }}
{{ form_row(registrationForm.agreeTerms) }}

<button type="submit" class="btn">Register</button>
{{ form_end(registrationForm) }}
{% endblock %}

+ 42
- 0
templates/security/login.html.twig View File

@@ -0,0 +1,42 @@
{% extends 'base.html.twig' %}

{% block title %}Log in!{% endblock %}

{% block body %}
<form method="post">
{% if error %}
<div class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}

{% if app.user %}
<div class="mb-3">
You are logged in as {{ app.user.username }}, <a href="{{ path('app_logout') }}">Logout</a>
</div>
{% endif %}

<h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
<label for="inputEmail">Email</label>
<input type="email" value="{{ last_username }}" name="email" id="inputEmail" class="form-control" required autofocus>
<label for="inputPassword">Password</label>
<input type="password" name="password" id="inputPassword" class="form-control" required>

<input type="hidden" name="_csrf_token"
value="{{ csrf_token('authenticate') }}"
>

{#
Uncomment this section and add a remember_me option below your firewall to activate remember me functionality.
See https://symfony.com/doc/current/security/remember_me.html

<div class="checkbox mb-3">
<label>
<input type="checkbox" name="_remember_me"> Remember me
</label>
</div>
#}

<button class="btn btn-lg btn-primary" type="submit">
Sign in
</button>
</form>
{% endblock %}

Loading…
Cancel
Save