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) }}
{{ 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_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"