From 9aff89e29ae872ff90f69a0cbb3795205f274384 Mon Sep 17 00:00:00 2001 From: darkelfe14728 Date: Thu, 9 Jul 2020 21:47:33 +0200 Subject: [PATCH] Add sign-up form --- .gitignore | 4 + .idea/giftopic.iml | 5 + .idea/php.xml | 5 + assets/css/layouts/form.scss | 15 +- assets/css/pages/security/sign-up.scss | 14 + assets/js/forms-file.js | 5 + assets/js/security/sign-up.js | 2 + composer.json | 4 +- composer.lock | 510 +++++++++++++++++++---- config/bundles.php | 24 +- config/packages/liip_imagine.yaml | 14 + config/packages/routing.yaml | 4 - config/packages/security.yaml | 2 +- config/packages/twig.yaml | 3 +- config/packages/vich_uploader.yaml | 9 + config/routes/liip_imagine.yaml | 2 + config/services.yaml | 3 + package.json | 5 +- src/Controller/SecurityController.php | 31 +- src/Doctrine/CryptPasswordListener.php | 105 +++++ src/Entity/Language.php | 36 -- src/Entity/User.php | 170 ++++++-- src/Form/AbstractBootstrapForm.php | 10 + src/Form/SecuritySignInForm.php | 6 + src/Form/SecuritySignUpForm.php | 128 ++++++ src/Migrations/Version20200707131948.php | 33 ++ src/Migrations/Version20200707135616.php | 38 ++ src/Migrations/Version20200709102824.php | 31 ++ src/Migrations/Version20200709103321.php | 31 ++ symfony.lock | 34 ++ templates/_form_browse.html.twig | 5 + templates/_header.html.twig | 2 +- templates/security/sign-in.html.twig | 4 +- templates/security/sign-up.html.twig | 46 ++ translations/messages+intl-icu.en.xlf | 25 +- translations/messages+intl-icu.fr.xlf | 9 + translations/security+intl-icu.en.xlf | 60 ++- translations/security+intl-icu.fr.xlf | 58 ++- translations/validators+intl-icu.en.xlf | 39 +- translations/validators+intl-icu.fr.xlf | 39 +- webpack.config.js | 1 + yarn.lock | 5 + 42 files changed, 1376 insertions(+), 200 deletions(-) create mode 100644 assets/css/pages/security/sign-up.scss create mode 100644 assets/js/forms-file.js create mode 100644 assets/js/security/sign-up.js create mode 100644 config/packages/liip_imagine.yaml create mode 100644 config/packages/vich_uploader.yaml create mode 100644 config/routes/liip_imagine.yaml create mode 100644 src/Doctrine/CryptPasswordListener.php delete mode 100644 src/Entity/Language.php create mode 100644 src/Form/SecuritySignUpForm.php create mode 100644 src/Migrations/Version20200707131948.php create mode 100644 src/Migrations/Version20200707135616.php create mode 100644 src/Migrations/Version20200709102824.php create mode 100644 src/Migrations/Version20200709103321.php create mode 100644 templates/_form_browse.html.twig create mode 100644 templates/security/sign-up.html.twig diff --git a/.gitignore b/.gitignore index 918ffe4..4497734 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,7 @@ npm-debug.log yarn-error.log ###< symfony/webpack-encore-bundle ### + +###> liip/imagine-bundle ### +/public/media/cache/ +###< liip/imagine-bundle ### diff --git a/.idea/giftopic.iml b/.idea/giftopic.iml index edf8334..160fb2d 100644 --- a/.idea/giftopic.iml +++ b/.idea/giftopic.iml @@ -25,9 +25,12 @@ + + + @@ -101,6 +104,7 @@ + @@ -116,6 +120,7 @@ + diff --git a/.idea/php.xml b/.idea/php.xml index cf5656e..26b2b73 100644 --- a/.idea/php.xml +++ b/.idea/php.xml @@ -114,6 +114,11 @@ + + + + + diff --git a/assets/css/layouts/form.scss b/assets/css/layouts/form.scss index 4aa1a06..750e34e 100644 --- a/assets/css/layouts/form.scss +++ b/assets/css/layouts/form.scss @@ -1,11 +1,24 @@ form { text-align: left; - label { + .col-form-label { text-align: right; } .form-buttons { text-align: center; } +} + +.invalid-feedback, .valid-feedback { + width: 600%; + text-align: left; +} + +.col-form-label.required { + color: rgb(200, 0, 0); + + &::before { + content: '* '; + } } \ No newline at end of file diff --git a/assets/css/pages/security/sign-up.scss b/assets/css/pages/security/sign-up.scss new file mode 100644 index 0000000..1aaa89a --- /dev/null +++ b/assets/css/pages/security/sign-up.scss @@ -0,0 +1,14 @@ +body { + text-align: center; +} + +#sign-up { + width: 50%; + border: 1px solid rgba(0, 0, 0, .25); + padding: 10px; + margin: 0 auto; + + fieldset { + margin-top: 20px; + } +} \ No newline at end of file diff --git a/assets/js/forms-file.js b/assets/js/forms-file.js new file mode 100644 index 0000000..da7b04e --- /dev/null +++ b/assets/js/forms-file.js @@ -0,0 +1,5 @@ +import bsCustomFileInput from 'bs-custom-file-input'; + +$(document).ready(function () { + bsCustomFileInput.init(); +}); \ No newline at end of file diff --git a/assets/js/security/sign-up.js b/assets/js/security/sign-up.js new file mode 100644 index 0000000..2cd0ae8 --- /dev/null +++ b/assets/js/security/sign-up.js @@ -0,0 +1,2 @@ +require('../../css/pages/security/sign-up.scss'); +require('../../js/forms-file.js'); \ No newline at end of file diff --git a/composer.json b/composer.json index eade95d..8ebcc61 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,7 @@ "doctrine/doctrine-bundle": "*", "doctrine/doctrine-migrations-bundle": "2.*.*", "doctrine/orm": "*", + "liip/imagine-bundle": "^2.3", "sensio/framework-extra-bundle": "^5.5", "symfony/apache-pack": "^1.0", "symfony/asset": "5.*.*", @@ -37,7 +38,8 @@ "symfony/validator": "5.*.*", "symfony/web-link": "5.*.*", "symfony/webpack-encore-bundle": "^1.7", - "symfony/yaml": "5.*.*" + "symfony/yaml": "5.*.*", + "vich/uploader-bundle": "^1.14" }, "require-dev": { "symfony/debug-pack": "*", diff --git a/composer.lock b/composer.lock index 702b694..e65709d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,23 +4,23 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b95652040ba10ba1825a39e3277a3516", + "content-hash": "bc0c41b59b1d77103f486d35f01f35ff", "packages": [ { - "name": "doctrine/annotations", - "version": "1.10.3", - "source": { + "name": "doctrine/annotations", + "version": "1.10.3", + "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", "reference": "5db60a4969eba0e0c197a19c077780aadbc43c5d" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/5db60a4969eba0e0c197a19c077780aadbc43c5d", + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/5db60a4969eba0e0c197a19c077780aadbc43c5d", "reference": "5db60a4969eba0e0c197a19c077780aadbc43c5d", - "shasum": "" + "shasum": "" }, - "require": { + "require": { "doctrine/lexer": "1.*", "ext-tokenizer": "*", "php": "^7.1 || ^8.0" @@ -1254,36 +1254,152 @@ } }, "notification-url": "https://packagist.org/downloads/", - "license": [ + "license": [ "MIT" ], - "authors": [ + "authors": [ { "name": "Eduardo Gulias Davis" } ], "description": "A library for validating emails against several RFCs", - "homepage": "https://github.com/egulias/EmailValidator", - "keywords": [ + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ "email", "emailvalidation", "emailvalidator", "validation", "validator" ], - "time": "2020-06-16T20:11:17+00:00" + "time": "2020-06-16T20:11:17+00:00" }, { - "name": "laminas/laminas-code", - "version": "3.4.1", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-code.git", + "name": "imagine/imagine", + "version": "1.2.3", + "source": { + "type": "git", + "url": "https://github.com/avalanche123/Imagine.git", + "reference": "cb2361e5bb4410b681462d8e4f912bc5dabf84ab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/avalanche123/Imagine/zipball/cb2361e5bb4410b681462d8e4f912bc5dabf84ab", + "reference": "cb2361e5bb4410b681462d8e4f912bc5dabf84ab", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "2.2.*", + "phpunit/phpunit": "^4.8 || ^5.7 || ^6.5 || ^7.5 || ^8.4" + }, + "suggest": { + "ext-gd": "to use the GD implementation", + "ext-gmagick": "to use the Gmagick implementation", + "ext-imagick": "to use the Imagick implementation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-develop": "0.7-dev" + } + }, + "autoload": { + "psr-4": { + "Imagine\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bulat Shakirzyanov", + "email": "mallluhuct@gmail.com", + "homepage": "http://avalanche123.com" + } + ], + "description": "Image processing for PHP 5.3", + "homepage": "http://imagine.readthedocs.org/", + "keywords": [ + "drawing", + "graphics", + "image manipulation", + "image processing" + ], + "time": "2019-12-04T09:55:33+00:00" + }, + { + "name": "jms/metadata", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/metadata.git", + "reference": "6eb35fce7142234946d58d13e1aa829e9b78b095" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/metadata/zipball/6eb35fce7142234946d58d13e1aa829e9b78b095", + "reference": "6eb35fce7142234946d58d13e1aa829e9b78b095", + "shasum": "" + }, + "require": { + "php": "^7.2" + }, + "require-dev": { + "doctrine/cache": "^1.0", + "doctrine/coding-standard": "^4.0", + "phpunit/phpunit": "^7.0", + "symfony/cache": "^3.1|^4.0|^5.0", + "symfony/dependency-injection": "^3.1|^4.0|^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Metadata\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Asmir Mustafic", + "email": "goetas@gmail.com" + } + ], + "description": "Class/method/property metadata management in PHP", + "keywords": [ + "annotations", + "metadata", + "xml", + "yaml" + ], + "time": "2020-06-06T16:52:59+00:00" + }, + { + "name": "laminas/laminas-code", + "version": "3.4.1", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-code.git", "reference": "1cb8f203389ab1482bf89c0e70a04849bacd7766" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-code/zipball/1cb8f203389ab1482bf89c0e70a04849bacd7766", + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-code/zipball/1cb8f203389ab1482bf89c0e70a04849bacd7766", "reference": "1cb8f203389ab1482bf89c0e70a04849bacd7766", "shasum": "" }, @@ -1423,7 +1539,7 @@ "module": "Laminas\\ZendFrameworkBridge" } }, - "autoload": { + "autoload": { "files": [ "src/autoload.php" ], @@ -1432,29 +1548,128 @@ } }, "notification-url": "https://packagist.org/downloads/", - "license": [ + "license": [ "BSD-3-Clause" ], - "description": "Alias legacy ZF class names to Laminas Project equivalents.", - "keywords": [ + "description": "Alias legacy ZF class names to Laminas Project equivalents.", + "keywords": [ "ZendFramework", "autoloading", "laminas", "zf" ], - "time": "2020-05-20T16:45:56+00:00" + "time": "2020-05-20T16:45:56+00:00" }, { - "name": "monolog/monolog", + "name": "liip/imagine-bundle", + "version": "2.3.1", + "source": { + "type": "git", + "url": "https://github.com/liip/LiipImagineBundle.git", + "reference": "d0819fc9b1cd4e9e16db204467b6fe1a5316a163" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/liip/LiipImagineBundle/zipball/d0819fc9b1cd4e9e16db204467b6fe1a5316a163", + "reference": "d0819fc9b1cd4e9e16db204467b6fe1a5316a163", + "shasum": "" + }, + "require": { + "imagine/imagine": "^0.7.1|^1.1", + "php": "^7.1", + "symfony/filesystem": "^3.4|^4.3|^5.0", + "symfony/finder": "^3.4|^4.3|^5.0", + "symfony/framework-bundle": "^3.4|^4.3|^5.0", + "symfony/mime": "^4.3|^5.0", + "symfony/options-resolver": "^3.4|^4.3|^5.0", + "symfony/process": "^3.4|^4.3|^5.0", + "symfony/templating": "^3.4|^4.3|^5.0", + "twig/twig": "^1.40|^2.9|^3.0" + }, + "require-dev": { + "amazonwebservices/aws-sdk-for-php": "^1.0", + "aws/aws-sdk-php": "^2.4", + "doctrine/cache": "^1.1", + "doctrine/orm": "^2.3", + "enqueue/enqueue-bundle": "^0.9|^0.10", + "ext-gd": "*", + "friendsofphp/php-cs-fixer": "^2.10", + "league/flysystem": "^1.0", + "psr/log": "^1.0", + "symfony/browser-kit": "^3.4|^4.3|^5.0", + "symfony/console": "^3.4|^4.3|^5.0", + "symfony/dependency-injection": "^3.4|^4.3|^5.0", + "symfony/form": "^3.4|^4.3|^5.0", + "symfony/phpunit-bridge": "^4.3|^5.0", + "symfony/validator": "^3.4|^4.3|^5.0", + "symfony/yaml": "^3.4|^4.3|^5.0" + }, + "suggest": { + "alcaeus/mongo-php-adapter": "required on PHP >= 7.0 to use mongo components with mongodb extension", + "amazonwebservices/aws-sdk-for-php": "required to use AWS version 1 cache resolver", + "aws/aws-sdk-php": "required to use AWS version 2/3 cache resolver", + "doctrine/mongodb-odm": "required to use mongodb-backed doctrine components", + "enqueue/enqueue-bundle": "^0.9 add if you like to process images in background", + "ext-exif": "required to read EXIF metadata from images", + "ext-gd": "required to use gd driver", + "ext-gmagick": "required to use gmagick driver", + "ext-imagick": "required to use imagick driver", + "ext-mongo": "required for mongodb components on PHP <7.0", + "ext-mongodb": "required for mongodb components on PHP >=7.0", + "league/flysystem": "required to use FlySystem data loader or cache resolver", + "monolog/monolog": "A psr/log compatible logger is required to enable logging" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-1.0": "1.7-dev", + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Liip\\ImagineBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Liip and other contributors", + "homepage": "https://github.com/liip/LiipImagineBundle/contributors" + } + ], + "description": "This bundle provides an image manipulation abstraction toolkit for Symfony-based projects.", + "homepage": "http://liip.ch", + "keywords": [ + "bundle", + "image", + "imagine", + "liip", + "manipulation", + "photos", + "pictures", + "symfony", + "transformation" + ], + "time": "2020-06-26T05:55:54+00:00" + }, + { + "name": "monolog/monolog", "version": "2.1.0", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/monolog.git", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", "reference": "38914429aac460e8e4616c8cb486ecb40ec90bb1" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/38914429aac460e8e4616c8cb486ecb40ec90bb1", + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/38914429aac460e8e4616c8cb486ecb40ec90bb1", "reference": "38914429aac460e8e4616c8cb486ecb40ec90bb1", "shasum": "" }, @@ -5544,16 +5759,72 @@ "time": "2020-06-11T12:16:36+00:00" }, { - "name": "symfony/translation", - "version": "v5.1.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/translation.git", + "name": "symfony/templating", + "version": "v5.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/templating.git", + "reference": "d3f0347e70029067ab690bfa9ff121c1c929ee4e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/templating/zipball/d3f0347e70029067ab690bfa9ff121c1c929ee4e", + "reference": "d3f0347e70029067ab690bfa9ff121c1c929ee4e", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8" + }, + "require-dev": { + "psr/log": "~1.0" + }, + "suggest": { + "psr/log-implementation": "For using debug logging in loaders" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Templating\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Templating Component", + "homepage": "https://symfony.com", + "time": "2020-05-28T08:20:44+00:00" + }, + { + "name": "symfony/translation", + "version": "v5.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", "reference": "d387f07d4c15f9c09439cf3f13ddbe0b2c5e8be2" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/d387f07d4c15f9c09439cf3f13ddbe0b2c5e8be2", + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/d387f07d4c15f9c09439cf3f13ddbe0b2c5e8be2", "reference": "d387f07d4c15f9c09439cf3f13ddbe0b2c5e8be2", "shasum": "" }, @@ -6393,18 +6664,18 @@ }, "require-dev": { "twig/cssinliner-extra": "^2.12|^3.0", - "twig/html-extra": "^2.12|^3.0", - "twig/inky-extra": "^2.12|^3.0", - "twig/intl-extra": "^2.12|^3.0", - "twig/markdown-extra": "^2.12|^3.0" + "twig/html-extra": "^2.12|^3.0", + "twig/inky-extra": "^2.12|^3.0", + "twig/intl-extra": "^2.12|^3.0", + "twig/markdown-extra": "^2.12|^3.0" }, - "type": "symfony-bundle", - "extra": { + "type": "symfony-bundle", + "extra": { "branch-alias": { "dev-master": "3.0-dev" } }, - "autoload": { + "autoload": { "psr-4": { "Twig\\Extra\\TwigExtraBundle\\": "src/" } @@ -6431,35 +6702,35 @@ "time": "2020-05-21T09:56:39+00:00" }, { - "name": "twig/twig", - "version": "v3.0.4", - "source": { + "name": "twig/twig", + "version": "v3.0.4", + "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", "reference": "582bdbdc173027ebfba3c93dc750a40b8f9ebc02" }, - "dist": { + "dist": { "type": "zip", "url": "https://api.github.com/repos/twigphp/Twig/zipball/582bdbdc173027ebfba3c93dc750a40b8f9ebc02", "reference": "582bdbdc173027ebfba3c93dc750a40b8f9ebc02", "shasum": "" }, - "require": { + "require": { "php": ">=7.2.5", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-mbstring": "^1.3" }, - "require-dev": { + "require-dev": { "psr/container": "^1.0", "symfony/phpunit-bridge": "^4.4.9|^5.0.9" }, - "type": "library", - "extra": { + "type": "library", + "extra": { "branch-alias": { "dev-master": "3.0-dev" } }, - "autoload": { + "autoload": { "psr-4": { "Twig\\": "src/" } @@ -6485,24 +6756,123 @@ "role": "Project Founder" } ], - "description": "Twig, the flexible, fast, and secure template language for PHP", - "homepage": "https://twig.symfony.com", - "keywords": [ + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "https://twig.symfony.com", + "keywords": [ "templating" ], - "time": "2020-07-05T13:18:14+00:00" + "time": "2020-07-05T13:18:14+00:00" }, { - "name": "webimpress/safe-writer", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/webimpress/safe-writer.git", + "name": "vich/uploader-bundle", + "version": "1.14.0", + "source": { + "type": "git", + "url": "https://github.com/dustin10/VichUploaderBundle.git", + "reference": "8e9b4402a959983fd7effddae1dd81d587687d96" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dustin10/VichUploaderBundle/zipball/8e9b4402a959983fd7effddae1dd81d587687d96", + "reference": "8e9b4402a959983fd7effddae1dd81d587687d96", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "jms/metadata": "^2.1", + "php": "^7.2", + "symfony/config": "^4.4 || ^5.0", + "symfony/console": "^4.4 || ^5.0", + "symfony/dependency-injection": "^4.4 || ^5.0", + "symfony/event-dispatcher-contracts": "^1.1 || ^2.0", + "symfony/form": "^4.4 || ^5.0", + "symfony/http-foundation": "^4.4 || ^5.0", + "symfony/http-kernel": "^4.4 || ^5.0", + "symfony/mime": "^4.4 || ^5.0", + "symfony/property-access": "^4.4 || ^5.0", + "symfony/string": "^5.0" + }, + "require-dev": { + "alcaeus/mongo-php-adapter": "^1.1", + "doctrine/doctrine-bundle": "^2.0.3", + "doctrine/mongodb-odm": "^1.2", + "doctrine/orm": "^2.7", + "ext-sqlite3": "*", + "knplabs/knp-gaufrette-bundle": "^0.7", + "kphoen/rusty": "dev-update-php-parser", + "league/flysystem-bundle": "^1.4", + "league/flysystem-memory": "^1.0", + "matthiasnoback/symfony-dependency-injection-test": "^4.1", + "mikey179/vfsstream": "^1.6", + "oneup/flysystem-bundle": "^3.3", + "phpunit/phpunit": "^8.5", + "symfony/asset": "^4.4 || ^5.0", + "symfony/browser-kit": "^4.4 || ^5.0", + "symfony/css-selector": "^4.4 || ^5.0", + "symfony/doctrine-bridge": "^4.4 || ^5.0", + "symfony/dom-crawler": "^4.4 || ^5.0", + "symfony/framework-bundle": "^4.4 || ^5.0", + "symfony/phpunit-bridge": "^4.3 || ^5.0", + "symfony/security-csrf": "^4.4 || ^5.0", + "symfony/translation": "^4.4 || ^5.0", + "symfony/twig-bridge": "^4.4 || ^5.0", + "symfony/twig-bundle": "^4.4 || ^5.0", + "symfony/validator": "^4.4 || ^5.0", + "symfony/var-dumper": "^4.4 || ^5.0", + "symfony/yaml": "^4.4 || ^5.0" + }, + "suggest": { + "doctrine/doctrine-bundle": "For integration with Doctrine", + "doctrine/mongodb-odm-bundle": "For integration with Doctrine ODM", + "doctrine/orm": "For integration with Doctrine ORM", + "doctrine/phpcr-odm": "For integration with Doctrine PHPCR", + "knplabs/knp-gaufrette-bundle": "For integration with Gaufrette", + "liip/imagine-bundle": "To generate image thumbnails", + "ocramius/proxy-manager": "To use lazy services", + "oneup/flysystem-bundle": "For integration with Flysystem", + "symfony/asset": "To generate better links", + "symfony/yaml": "To use YAML mapping" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "1.15.x-dev" + } + }, + "autoload": { + "psr-4": { + "Vich\\UploaderBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dustin Dobervich", + "email": "ddobervich@gmail.com" + } + ], + "description": "Ease file uploads attached to entities", + "homepage": "https://github.com/dustin10/VichUploaderBundle", + "keywords": [ + "file uploads", + "upload" + ], + "time": "2020-06-12T08:48:15+00:00" + }, + { + "name": "webimpress/safe-writer", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/webimpress/safe-writer.git", "reference": "d6e879960febb307c112538997316371f1e95b12" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webimpress/safe-writer/zipball/d6e879960febb307c112538997316371f1e95b12", + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webimpress/safe-writer/zipball/d6e879960febb307c112538997316371f1e95b12", "reference": "d6e879960febb307c112538997316371f1e95b12", "shasum": "" }, diff --git a/config/bundles.php b/config/bundles.php index 29d5d94..a6ff049 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -1,16 +1,18 @@ ['all' => true], - Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], - Twig\Extra\TwigExtraBundle\TwigExtraBundle::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], - Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], - Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true], + Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true], + Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], + Twig\Extra\TwigExtraBundle\TwigExtraBundle::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], + Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], + Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true], Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true], - Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], - Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true], - Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true], + Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], + Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true], + Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true], + Vich\UploaderBundle\VichUploaderBundle::class => ['all' => true], + Liip\ImagineBundle\LiipImagineBundle::class => ['all' => true], ]; diff --git a/config/packages/liip_imagine.yaml b/config/packages/liip_imagine.yaml new file mode 100644 index 0000000..823c20a --- /dev/null +++ b/config/packages/liip_imagine.yaml @@ -0,0 +1,14 @@ +liip_imagine: + driver: "gd" + + resolvers: + default: + web_path: ~ + + filter_sets: + cache: ~ + + user_avater: + filters: + scale: + dim: [120, 120] \ No newline at end of file diff --git a/config/packages/routing.yaml b/config/packages/routing.yaml index b45c1ce..7e97762 100644 --- a/config/packages/routing.yaml +++ b/config/packages/routing.yaml @@ -1,7 +1,3 @@ framework: router: utf8: true - - # Configure how to generate URLs in non-HTTP contexts, such as CLI commands. - # See https://symfony.com/doc/current/routing.html#generating-urls-in-commands - #default_uri: http://localhost diff --git a/config/packages/security.yaml b/config/packages/security.yaml index cf791d8..5bb2f11 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -1,7 +1,7 @@ security: encoders: App\Entity\User: - algorithm: auto + algorithm: bcrypt providers: app_user_provider: entity: diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml index 7030ebe..96dfabc 100644 --- a/config/packages/twig.yaml +++ b/config/packages/twig.yaml @@ -1,3 +1,4 @@ twig: default_path: '%kernel.project_dir%/templates' - form_themes: ['bootstrap_4_horizontal_layout.html.twig'] \ No newline at end of file + form_themes: + - 'bootstrap_4_horizontal_layout.html.twig' \ No newline at end of file diff --git a/config/packages/vich_uploader.yaml b/config/packages/vich_uploader.yaml new file mode 100644 index 0000000..6f9e5fa --- /dev/null +++ b/config/packages/vich_uploader.yaml @@ -0,0 +1,9 @@ +vich_uploader: + db_driver: orm + + mappings: + user_avatar: + namer: Vich\UploaderBundle\Naming\UniqidNamer + upload_destination: "%kernel.project_dir%/public/files/user_avatar" + uri_prefix: /files/user_avatar + inject_on_load: true \ No newline at end of file diff --git a/config/routes/liip_imagine.yaml b/config/routes/liip_imagine.yaml new file mode 100644 index 0000000..201cbd5 --- /dev/null +++ b/config/routes/liip_imagine.yaml @@ -0,0 +1,2 @@ +_liip_imagine: + resource: "@LiipImagineBundle/Resources/config/routing.yaml" diff --git a/config/services.yaml b/config/services.yaml index 611d2ff..dfe5ae4 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -26,3 +26,6 @@ services: # add more service definitions when explicit configuration is needed # please note that last definitions always *replace* previous ones + App\Doctrine\CryptPasswordListener: + tags: + - { name: 'doctrine.event_subscriber' } diff --git a/package.json b/package.json index a03ffd5..3a0a236 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,8 @@ }, "dependencies": { "@fortawesome/fontawesome-free": "^5.13.0", - "jquery": "^3.5.1", - "jquery-ui": "^1.12.1" + "bs-custom-file-input": "^1.3.4", + "jquery": "^3.5.1", + "jquery-ui": "^1.12.1" } } diff --git a/src/Controller/SecurityController.php b/src/Controller/SecurityController.php index cbb723f..57ac74e 100644 --- a/src/Controller/SecurityController.php +++ b/src/Controller/SecurityController.php @@ -2,9 +2,12 @@ namespace App\Controller; +use App\Entity\User; use App\Form\SecuritySignInForm; +use App\Form\SecuritySignUpForm; use Exception; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Http\Authentication\AuthenticationUtils; @@ -55,8 +58,34 @@ class SecurityController extends AbstractController { /** * Show inscription form * + * @param Request $request The request object + * + * @return Response Page response + * * @Route("/sign-up") */ - public function sign_up () { + public function sign_up (Request $request) { + $user = new User(); + $user->setLanguage($request->getLocale()); + + $form = $this->createForm(SecuritySignUpForm::class, $user); + + $form->handleRequest($request); + if ($form->isSubmitted() && $form->isValid()) { + $user = $form->getData(); + + $doctrine = $this->getDoctrine()->getManager(); + $doctrine->persist($user); + $doctrine->flush(); + + return $this->redirectToRoute('app_security_sign_in'); + } + + return $this->render( + 'security/sign-up.html.twig', + [ + 'form' => $form->createView(), + ] + ); } } diff --git a/src/Doctrine/CryptPasswordListener.php b/src/Doctrine/CryptPasswordListener.php new file mode 100644 index 0000000..ec0dd5e --- /dev/null +++ b/src/Doctrine/CryptPasswordListener.php @@ -0,0 +1,105 @@ +passwordEncoder = $passwordEncoder; + } + + /** + * @inheritDoc + */ + public function getSubscribedEvents (): array { + return [ + 'prePersist', + 'preUpdate', + ]; + } + + /** + * When entity is inserted in database + * + * Automatically called by Doctrine + * + * @param LifecycleEventArgs $eventArgs The event arguments + */ + public function prePersist (LifecycleEventArgs $eventArgs): void { + // Check if entity is a User, else do nothing + $entity = $eventArgs->getEntity(); + if (!$entity instanceof User) { + return; + } + + $this->encodePassword($entity); + } + /** + * When entity is updated in database + * + * Automatically called by Doctrine + * + * @param LifecycleEventArgs $eventArgs The event arguments + */ + public function preUpdate (LifecycleEventArgs $eventArgs): void { + // Check if entity is a User, else do nothing + $entity = $eventArgs->getEntity(); + if (!$entity instanceof User) { + return; + } + + $this->encodePassword($entity); + + // Force update of entity + $doctrine = $eventArgs->getEntityManager(); + $doctrine->getUnitOfWork()->recomputeSingleEntityChangeSet( + $doctrine->getClassMetadata(get_class($entity)), + $entity + ); + } + + /** + * Perform teh password encryption (if necessary) + * + * @param User $user The user + */ + private function encodePassword (User $user): void { + // Mot de passe modifié ? + if (empty($user->getPlainPassword())) { + return; + } + + // Crypt the password + $user->setPassword( + $this->passwordEncoder->encodePassword( + $user, + $user->getPlainPassword() + ) + ); + } +} \ No newline at end of file diff --git a/src/Entity/Language.php b/src/Entity/Language.php deleted file mode 100644 index b723952..0000000 --- a/src/Entity/Language.php +++ /dev/null @@ -1,36 +0,0 @@ -id; - } - - public function getName (): ?string { - return $this->name; - } - - public function setName (string $name): self { - $this->name = $name; - - return $this; - } -} diff --git a/src/Entity/User.php b/src/Entity/User.php index 1a3e5e3..a049194 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -1,16 +1,27 @@ email = ''; + $this->password = ''; + $this->plainPassword = ''; + + $this->name = ''; + $this->firstname = null; + $this->gender = null; + + $this->language = ''; + $this->avatar = new VichEmbeddedFile(); + $this->avatarFile = null; + $this->updatedAt = new DateTimeImmutable(); + $this->friends = new ArrayCollection(); $this->configNotifications = new ArrayCollection(); $this->notifications = new ArrayCollection(); @@ -133,7 +189,6 @@ class User implements UserInterface { $this->participations = new ArrayCollection(); $this->comments = new ArrayCollection(); } - public function getId (): ?int { return $this->id; } @@ -185,18 +240,30 @@ class User implements UserInterface { return $this; } + public function getPlainPassword (): string { + return (string)$this->plainPassword; + } + public function setPlainPassword (string $password): self { + $this->plainPassword = $password; + $this->password = ''; // Force update of user + + // The crypted password will be handled by Doctrine\CryptPasswordListener + + return $this; + } + /** * @see UserInterface */ public function getSalt () { - // not needed when using the "bcrypt" algorithm in security.yaml + // Security.yaml : use "bcrypt" which provide his own salt generator => nothing to do here } /** * @see UserInterface */ public function eraseCredentials () { - // If you store any temporary, sensitive data on the user, clear it here - // $this->plainPassword = null; + // Reset sensitive data, like clear password ! + $this->plainPassword = ''; } public function getName (): ?string { @@ -207,38 +274,59 @@ class User implements UserInterface { return $this; } - - public function getFistname (): ?string { - return $this->fist_name; + public function getFirstname (): ?string { + return $this->firstname; } - public function setFistname (?string $fist_name): self { - $this->fist_name = $fist_name; + public function setFirstname (?string $firstname): self { + $this->firstname = $firstname; return $this; } - public function getGender (): ?int { + public static function getGenders (): array { + return [ + 'male', + 'female', + 'genderqueer', + ]; + } + public function getGender (): ?string { return $this->gender; } - public function setGender (int $gender): self { + public function setGender (?string $gender): self { $this->gender = $gender; return $this; } - public function getAvatar (): ?string { + public function getAvatar (): ?VichEmbeddedFile { return $this->avatar; } - public function setAvatar (?string $avatar): self { + public function setAvatar (VichEmbeddedFile $avatar): self { $this->avatar = $avatar; return $this; } + public function getAvatarFile (): ?File { + return $this->avatarFile; + } + public function setAvatarFile (?File $avatar): self { + $this->avatarFile = $avatar; + if ($avatar !== null) { + $this->updatedAt = new DateTimeImmutable(); + } - public function getLanguage (): ?Language { + return $this; + } + + public function getLanguage (): string { return $this->language; } - public function setLanguage (?Language $language): self { + public function setLanguage (string $language): self { + if (mb_strlen($language, 'UTF-8') != 2) { + throw new InvalidArgumentException('The language code must have exactly 2 characters'); + } + $this->language = $language; return $this; diff --git a/src/Form/AbstractBootstrapForm.php b/src/Form/AbstractBootstrapForm.php index a9f1db9..1b375c3 100644 --- a/src/Form/AbstractBootstrapForm.php +++ b/src/Form/AbstractBootstrapForm.php @@ -5,7 +5,17 @@ namespace App\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\OptionsResolver\OptionsResolver; +/** + * FormType using the Bootstrap library + * + * Disable browser-validation and use Bootstrap client-side validation + * + * @package App\Form + */ abstract class AbstractBootstrapForm extends AbstractType { + /** + * @inheritDoc + */ public function configureOptions (OptionsResolver $resolver) { parent::configureOptions($resolver); diff --git a/src/Form/SecuritySignInForm.php b/src/Form/SecuritySignInForm.php index 5c74c62..9f7eea8 100644 --- a/src/Form/SecuritySignInForm.php +++ b/src/Form/SecuritySignInForm.php @@ -14,6 +14,9 @@ use Symfony\Component\OptionsResolver\OptionsResolver; * @package App\Form */ class SecuritySignInForm extends AbstractBootstrapForm { + /** + * @inheritDoc + */ public function buildForm (FormBuilderInterface $builder, array $options) { parent::buildForm($builder, $options); @@ -42,6 +45,9 @@ class SecuritySignInForm extends AbstractBootstrapForm { ); } + /** + * @inheritDoc + */ public function configureOptions (OptionsResolver $resolver) { parent::configureOptions($resolver); diff --git a/src/Form/SecuritySignUpForm.php b/src/Form/SecuritySignUpForm.php new file mode 100644 index 0000000..d679d5c --- /dev/null +++ b/src/Form/SecuritySignUpForm.php @@ -0,0 +1,128 @@ +translatorInterface = $translatorInterface; + } + + /** + * @inheritDoc + */ + public function buildForm (FormBuilderInterface $builder, array $options) { + parent::buildForm($builder, $options); + + $builder + ->add( + 'email', + EmailType::class, + [ + 'label_format' => 'user.email', + ] + ) + ->add( + 'plainPassword', + RepeatedType::class, + [ + 'type' => PasswordType::class, + 'first_options' => [ + 'label_format' => 'user.password', + ], + 'second_options' => [ + 'label_format' => 'user.password_confirm', + ], + ] + ) + ->add( + 'gender', + ChoiceType::class, + [ + 'choices' => User::getGenders(), + 'choice_label' => function (string $gender) { + return $gender ? $this->translatorInterface->trans('user.genders.' . $gender, [], 'security') : ''; + }, + 'choice_translation_domain' => false, + 'label_format' => 'user.gender', + 'required' => false, + ] + ) + ->add( + 'firstname', + TextType::class, + [ + 'label_format' => 'user.firstname', + 'required' => false, + ] + ) + ->add( + 'name', + TextType::class, + [ + 'label_format' => 'user.name', + ] + ) + ->add( + 'language', + LanguageType::class, + [ + 'choice_self_translation' => true, + 'label_format' => 'user.language', + ] + ) + ->add( + 'avatarFile', + VichImageType::class, + [ + 'label_format' => 'user.avatar', + 'translation_domain' => 'security', + 'required' => false, + 'imagine_pattern' => 'url_avatar', + 'storage_resolve_method' => VichImageType::STORAGE_RESOLVE_PATH_RELATIVE, + ] + ); + } + + /** + * @inheritDoc + */ + public function configureOptions (OptionsResolver $resolver) { + parent::configureOptions($resolver); + + $resolver->setDefaults( + [ + 'translation_domain' => 'security', + 'data_class' => User::class, + ] + ); + } +} \ No newline at end of file diff --git a/src/Migrations/Version20200707131948.php b/src/Migrations/Version20200707131948.php new file mode 100644 index 0000000..9dcb80a --- /dev/null +++ b/src/Migrations/Version20200707131948.php @@ -0,0 +1,33 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.'); + + $this->addSql('ALTER TABLE user ADD updated_at DATETIME NOT NULL, ADD avatar_original_name VARCHAR(255) DEFAULT NULL, ADD avatar_mime_type VARCHAR(255) DEFAULT NULL, ADD avatar_size INT DEFAULT NULL, ADD avatar_dimensions LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:simple_array)\', DROP inactive, CHANGE gender gender VARCHAR(25) DEFAULT NULL, CHANGE avatar avatar_name VARCHAR(255) DEFAULT NULL' + ); + } + + public function down (Schema $schema): void { + // this down() migration is auto-generated, please modify it to your needs + $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.'); + + $this->addSql('ALTER TABLE user ADD avatar varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, ADD inactive tinyint(1) NOT NULL, DROP updated_at, DROP avatar_name, DROP avatar_original_name, DROP avatar_mime_type, DROP avatar_size, DROP avatar_dimensions, CHANGE gender gender smallint NOT NULL' + ); + } +} diff --git a/src/Migrations/Version20200707135616.php b/src/Migrations/Version20200707135616.php new file mode 100644 index 0000000..035f593 --- /dev/null +++ b/src/Migrations/Version20200707135616.php @@ -0,0 +1,38 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.'); + + $this->addSql('ALTER TABLE user DROP FOREIGN KEY FK_8D93D64982F1BAF4'); + $this->addSql('DROP TABLE language'); + $this->addSql('DROP INDEX IDX_8D93D64982F1BAF4 ON user'); + $this->addSql('ALTER TABLE user ADD language varchar(2) NOT NULL, DROP language_id'); + } + + public function down (Schema $schema): void { + // this down() migration is auto-generated, please modify it to your needs + $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.'); + + $this->addSql('CREATE TABLE language (id int AUTO_INCREMENT NOT NULL, name varchar(50) CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_unicode_ci`, code varchar(2) CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_unicode_ci`, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB COMMENT = \'\' ' + ); + $this->addSql('ALTER TABLE user ADD language_id int DEFAULT NULL, DROP language'); + $this->addSql('ALTER TABLE user ADD CONSTRAINT FK_8D93D64982F1BAF4 FOREIGN KEY (language_id) REFERENCES language (id)'); + $this->addSql('CREATE INDEX IDX_8D93D64982F1BAF4 ON user (language_id)'); + } +} diff --git a/src/Migrations/Version20200709102824.php b/src/Migrations/Version20200709102824.php new file mode 100644 index 0000000..baba70b --- /dev/null +++ b/src/Migrations/Version20200709102824.php @@ -0,0 +1,31 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.'); + + $this->addSql('ALTER TABLE user CHANGE fist_name fistname varchar(255) DEFAULT NULL'); + } + + public function down (Schema $schema): void { + // this down() migration is auto-generated, please modify it to your needs + $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.'); + + $this->addSql('ALTER TABLE user CHANGE fistname fist_name varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`'); + } +} diff --git a/src/Migrations/Version20200709103321.php b/src/Migrations/Version20200709103321.php new file mode 100644 index 0000000..8f48d8d --- /dev/null +++ b/src/Migrations/Version20200709103321.php @@ -0,0 +1,31 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.'); + + $this->addSql('ALTER TABLE user CHANGE fistname firstname varchar(255) DEFAULT NULL'); + } + + public function down (Schema $schema): void { + // this down() migration is auto-generated, please modify it to your needs + $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.'); + + $this->addSql('ALTER TABLE user CHANGE firstname fistname varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`'); + } +} diff --git a/symfony.lock b/symfony.lock index a741e7a..c51984a 100644 --- a/symfony.lock +++ b/symfony.lock @@ -81,6 +81,12 @@ "egulias/email-validator": { "version": "2.1.18" }, + "imagine/imagine": { + "version": "1.2.3" + }, + "jms/metadata": { + "version": "2.3.0" + }, "laminas/laminas-code": { "version": "3.4.1" }, @@ -90,6 +96,19 @@ "laminas/laminas-zendframework-bridge": { "version": "1.0.4" }, + "liip/imagine-bundle": { + "version": "1.8", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "master", + "version": "1.8", + "ref": "5a5bdc2d0e2533ed6935d5ae562f2b318a8fc1ee" + }, + "files": [ + "config/packages/liip_imagine.yaml", + "config/routes/liip_imagine.yaml" + ] + }, "monolog/monolog": { "version": "2.1.0" }, @@ -441,6 +460,9 @@ "symfony/string": { "version": "v5.1.2" }, + "symfony/templating": { + "version": "v5.1.2" + }, "symfony/test-pack": { "version": "v1.0.6" }, @@ -544,6 +566,18 @@ "twig/twig": { "version": "v3.0.4" }, + "vich/uploader-bundle": { + "version": "1.5", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "master", + "version": "1.5", + "ref": "c4f5755b37fb65b9c6a3cbdae91205c15a137ed4" + }, + "files": [ + "config/packages/vich_uploader.yaml" + ] + }, "webimpress/safe-writer": { "version": "2.0.1" }, diff --git a/templates/_form_browse.html.twig b/templates/_form_browse.html.twig new file mode 100644 index 0000000..0162d2c --- /dev/null +++ b/templates/_form_browse.html.twig @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/templates/_header.html.twig b/templates/_header.html.twig index d2acc34..c1e089f 100644 --- a/templates/_header.html.twig +++ b/templates/_header.html.twig @@ -12,8 +12,8 @@ {% else %} - {#
  • {% trans from 'security' %}sign.up{% endtrans %}
  • #} {{ 'sign.in'|trans({}, 'security') }} + {{ 'sign.up'|trans({}, 'security') }} {% endif %} \ No newline at end of file diff --git a/templates/security/sign-in.html.twig b/templates/security/sign-in.html.twig index 50abb83..2ce0d79 100644 --- a/templates/security/sign-in.html.twig +++ b/templates/security/sign-in.html.twig @@ -20,12 +20,14 @@ {% endif %} {{ form_start(form) }} + {{ form_errors(form) }} + {{ form_row(form.email) }} {{ form_row(form.password) }} {{ form_row(form._remember_me) }}
    - {{ 'sign.up'|trans }} + {{ 'sign.up'|trans }}
    {{ form_end(form) }} diff --git a/templates/security/sign-up.html.twig b/templates/security/sign-up.html.twig new file mode 100644 index 0000000..91a9bc5 --- /dev/null +++ b/templates/security/sign-up.html.twig @@ -0,0 +1,46 @@ +{% trans_default_domain 'security' %} +{% extends 'base.html.twig' %} + +{% block title %}{{ 'sign.up'|trans }}{% endblock %} + +{% block stylesheets %} + {{ parent() }} + {{ encore_entry_link_tags('security/sign-up') }} + {% include '_form_browse.html.twig' %} +{% endblock %} + +{% block body %} +
    +

    {{ 'sign.up'|trans }}

    + + {{ form_start(form) }} + {{ form_errors(form) }} + +
    + {{ form_row(form.email) }} + {{ form_row(form.plainPassword.first) }} + {{ form_row(form.plainPassword.second) }} +
    + +
    + {{ form_row(form.gender) }} + {{ form_row(form.firstname) }} + {{ form_row(form.name) }} +
    + +
    + {{ form_row(form.language) }} + {{ form_row(form.avatarFile) }} +
    + +
    + +
    + {{ form_end(form) }} +
    +{% endblock %} + +{% block javascripts %} + {{ parent() }} + {{ encore_entry_script_tags('security/sign-up') }} +{% endblock %} \ No newline at end of file diff --git a/translations/messages+intl-icu.en.xlf b/translations/messages+intl-icu.en.xlf index f2e46cf..7e22f00 100644 --- a/translations/messages+intl-icu.en.xlf +++ b/translations/messages+intl-icu.en.xlf @@ -48,14 +48,23 @@ - - - - - - - - + + + + + + + + + + + + + + form.browse + Browse + + \ No newline at end of file diff --git a/translations/messages+intl-icu.fr.xlf b/translations/messages+intl-icu.fr.xlf index a8c2661..4029d76 100644 --- a/translations/messages+intl-icu.fr.xlf +++ b/translations/messages+intl-icu.fr.xlf @@ -57,5 +57,14 @@ + + + + + form.browse + Parcourir + + + \ No newline at end of file diff --git a/translations/security+intl-icu.en.xlf b/translations/security+intl-icu.en.xlf index 5d02174..7e59177 100644 --- a/translations/security+intl-icu.en.xlf +++ b/translations/security+intl-icu.en.xlf @@ -1,4 +1,4 @@ - + @@ -20,6 +20,7 @@ Sign out + sign.remember_me @@ -54,19 +55,60 @@ Password + + + user.password_confirm + Password confirm + + + + + user.gender + Gender + + + + + user.firstname + First name + + + + + user.name + Name + + + + + user.language + Language + + + + + user.avatar + Avatar + + - - - + + + + user.genders.male + Male + + + - user.invalid.email - You must provide a valid email + user.genders.female + Female - + - user.invalid.password - You must provide a password + user.genders.genderqueer + Genderqueer diff --git a/translations/security+intl-icu.fr.xlf b/translations/security+intl-icu.fr.xlf index 8db3b92..0f902f2 100644 --- a/translations/security+intl-icu.fr.xlf +++ b/translations/security+intl-icu.fr.xlf @@ -8,7 +8,6 @@ Connexion - sign.up @@ -21,6 +20,7 @@ Déconnexion + sign.remember_me @@ -55,18 +55,60 @@ Mot de passe + + + user.password_confirm + Confirmation mot de passe + + + + + user.gender + Genre + + + + + user.firstname + Prénom + + + + + user.name + Nom + + + + + user.language + Langue + + + + + user.avatar + Avatar + + - - + + - user.invalid.email - Vous devez renseigner une adresse mail valide + user.genders.male + Masculin - + + + user.genders.female + Féminin + + + - user.invalid.password - Vous devez renseigner un mot de passe + user.genders.genderqueer + Genderqueer / Non-Binaire diff --git a/translations/validators+intl-icu.en.xlf b/translations/validators+intl-icu.en.xlf index 4a70ba1..13fdd8a 100644 --- a/translations/validators+intl-icu.en.xlf +++ b/translations/validators+intl-icu.en.xlf @@ -1,6 +1,41 @@ - + - + + + + + + user.invalid.email + You must provide a valid email + + + + + user.invalid.password + You must provide a password + + + + + user.invalid.gender + You must provide a valid gender + + + + + user.invalid.name + You must provide a name + + + + + user.invalid.language + You must provide a valid language + + + + + This value should be false. diff --git a/translations/validators+intl-icu.fr.xlf b/translations/validators+intl-icu.fr.xlf index 8af25b1..19413b7 100644 --- a/translations/validators+intl-icu.fr.xlf +++ b/translations/validators+intl-icu.fr.xlf @@ -1,6 +1,41 @@ - + - + + + + + + user.invalid.email + Vous devez renseigner une adresse mail valide + + + + + user.invalid.password + Vous devez renseigner un mot de passe + + + + + user.invalid.gender + Vous devez renseigner un genre valide + + + + + user.invalid.name + Vous devez renseigner un nom + + + + + user.invalid.language + Vous devez choisir une langue valide + + + + + This value should be false. diff --git a/webpack.config.js b/webpack.config.js index 06a513f..07facca 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -45,6 +45,7 @@ Encore */ .addEntry('main', './assets/js/main.js') .addEntry('security/sign-in', './assets/js/security/sign-in.js') + .addEntry('security/sign-up', './assets/js/security/sign-up.js') // When enabled, Webpack "splits" your files into smaller pieces for greater optimization. .splitEntryChunks() diff --git a/yarn.lock b/yarn.lock index 96864ba..d09da9c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1504,6 +1504,11 @@ browserslist@^4.0.0, browserslist@^4.11.1, browserslist@^4.8.5: node-releases "^1.1.53" pkg-up "^2.0.0" +bs-custom-file-input@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/bs-custom-file-input/-/bs-custom-file-input-1.3.4.tgz#c275cb8d4f1c02ba026324292509fa9a747dbda8" + integrity sha512-NBsQzTnef3OW1MvdKBbMHAYHssCd613MSeJV7z2McXznWtVMnJCy7Ckyc+PwxV6Pk16cu6YBcYWh/ZE0XWNKCA== + buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"