diff --git a/.env.dist b/.env.dist index ef7cf9ef270c344df7e7c6c0b52c990b37623057..8f09c773c8419fb3bc1b9f497b417409f95281c8 100644 --- a/.env.dist +++ b/.env.dist @@ -3,6 +3,9 @@ # https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration ###> DOCKER ### +DOCKER_IMAGE_PHP=registry.gitlab.com/soluris/madis/php:1.0 +DOCKER_IMAGE_NGINX=registry.gitlab.com/soluris/madis/nginx:1.0 + HTTPD_PORT=8888 MYSQL_DATABASE=madis MYSQL_USER=user @@ -34,8 +37,14 @@ APP_DPO_JOB="Chargé de mission Solutions Documentaires Electroniques" APP_DPO_MAIL=m.edlich@soluris.fr APP_DPO_PHONE_NUMBER=0546923905 APP_ENV=dev +APP_FOOTER_PROVIDER_NAME=SOLURIS +APP_FOOTER_PROVIDER_URL="https://example.fr" +APP_IMAGE_FAVICON_PATH="favicon.ico" +APP_IMAGE_SIDEBAR_BOTTOM_TARGET_URL="htpps//example.fr" +APP_IMAGE_SIDEBAR_BOTTOM_PATH="images/soluris-logo-white.png" +APP_IMAGE_SIDEBAR_REDUCED_PATH="images/icon-32x32.png" APP_MAIL_RECEIVER_DEV=~ -APP_MAIL_SENDER_EMAIL=ne-pas-repondre@soluris.fr +APP_MAIL_SENDER_EMAIL=ne-pas-repondre@awkan.fr APP_MAIL_SENDER_NAME="Madis" APP_SECRET=a98f56b9ea67f189df8ed6a39c548503 #TRUSTED_PROXIES=127.0.0.1,127.0.0.2 diff --git a/.env.test b/.env.test index c6fada0cd046481434fefad6dec98ec68534a184..919ffacd4c61d0c42cda117bb59ec2afbdd148d5 100644 --- a/.env.test +++ b/.env.test @@ -3,6 +3,9 @@ # https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration ###> DOCKER ### +DOCKER_IMAGE_PHP=registry.gitlab.com/soluris/madis/php:1.0 +DOCKER_IMAGE_NGINX=registry.gitlab.com/soluris/madis/nginx:1.0 + HTTPD_PORT=8888 MYSQL_DATABASE=rgpd MYSQL_USER=user @@ -20,6 +23,9 @@ DATABASE_URL=mysql://user:user_pass@db:3306/rgpd ###> symfony/framework-bundle ### APP_APPLICATION_NAME="Gestion RGPD" APP_DEFAULT_REFERENT="Référent RGPD" +APP_DPO_ADDRESS_CITY="Saintes" +APP_DPO_ADDRESS_STREET="2 rue des Rochers" +APP_DPO_ADDRESS_ZIP_CODE="17100" APP_DPO_CIVILITY=m APP_DPO_FIRST_NAME=Michaël APP_DPO_LAST_NAME=Edlich @@ -28,8 +34,14 @@ APP_DPO_JOB="Chargé de mission Solutions Documentaires Electroniques" APP_DPO_MAIL=m.edlich@soluris.fr APP_DPO_PHONE_NUMBER=0546923905 APP_ENV=dev +APP_FOOTER_PROVIDER_NAME=SOLURIS +APP_FOOTER_PROVIDER_URL="https://example.fr" +APP_IMAGE_FAVICON_PATH="favicon.ico" +APP_IMAGE_SIDEBAR_BOTTOM_TARGET_URL="https://example.fr" +APP_IMAGE_SIDEBAR_BOTTOM_PATH="images/soluris-logo-white.png" +APP_IMAGE_SIDEBAR_REDUCED_PATH="images/icon-32x32.png" APP_MAIL_RECEIVER_DEV=~ -APP_MAIL_SENDER_EMAIL=ne-pas-repondre@soluris.fr +APP_MAIL_SENDER_EMAIL=ne-pas-repondre@awkan.fr APP_MAIL_SENDER_NAME="Madis" APP_SECRET=a98f56b9ea67f189df8ed6a39c548503 #TRUSTED_PROXIES=127.0.0.1,127.0.0.2 diff --git a/.git-hooks/hooks/pre-commit-scripts/pre-commit-php b/.git-hooks/hooks/pre-commit-scripts/pre-commit-php index ab358321c1af2f5e95755441cd086519650ce869..ada15b1881fa5656c431cd346376494dae813612 100644 --- a/.git-hooks/hooks/pre-commit-scripts/pre-commit-php +++ b/.git-hooks/hooks/pre-commit-scripts/pre-commit-php @@ -1,11 +1,5 @@ #!/bin/bash -# PHP CodeSniffer pre-commit hook for git -# -# @author Soenke Ruempler <soenke@ruempler.eu> -# @author Sebastian Kaspari <s.kaspari@googlemail.com> -# Updated to BiiG usage by Elisabeth Blancon - function checkFile { echo "Checking file: $1" diff --git a/.gitignore b/.gitignore index 83eb39a8891388e73f90200da9c79aa1df1004b7..7044a5fc5c55f0d82d978d5c0e38e4dd4be1b5c8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ ###> symfony/framework-bundle ### /.env /public/bundles/ +/public/custom/ /public/uploads/ /var/ /vendor/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..e20f52765cf663ecd40283c0c417f3e4b6f77ad4 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,43 @@ +variables: + DOCKER_IMAGE_PHP: registry.gitlab.com/soluris/madis/php:1.0 + DOCKER_IMAGE_NGINX: registry.gitlab.com/soluris/madis/nginx:1.0 + +stages: + - cache + - tests + +create_cache: + image: ${DOCKER_IMAGE_PHP} + script: + - composer install --prefer-dist --no-interaction --optimize-autoloader --no-scripts + cache: + key: "$CI_PROJECT_PATH-php" + paths: + - vendor + policy: push + tags: + - docker + stage: cache + +unit_tests: + image: docker:stable + services: + - docker:dind + coverage: '/^\s*Lines:\s*\d+.\d+\%/' + artifacts: + paths: + - var/artefacts/coverage/ + script: + - docker login --username gitlab-ci-token --password $CI_JOB_TOKEN $CI_REGISTRY + # re-install vendors to prevent from ci cache failure + - docker run --rm --env-file=./.env.dist --env-file=.env.test -v ${PWD}:/var/www/gestion-rgpd $DOCKER_IMAGE_PHP composer install --prefer-dist --no-interaction --optimize-autoloader --no-scripts + # PHPUnit + - docker run --rm --env-file=./.env.dist --env-file=.env.test -v ${PWD}:/var/www/gestion-rgpd $DOCKER_IMAGE_PHP vendor/bin/phpunit + cache: + key: "$CI_PROJECT_PATH-php" + paths: + - vendor + policy: pull + tags: + - docker + stage: tests diff --git a/CHANGELOG.md b/CHANGELOG.md index 5917a5edc37f80d4331ac97f6e9cadf798705045..a6e44b804f5983e37fc5645f9b6adbb9744f2933 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,29 @@ ## [UNRELEASED] +## [1.4.0] - 2019-04-03 +### Ajout +- [USER] Pouvoir modifier son mot de passe dans son profil, #135 +- [CHARTE] Possibilité de cliquer sur un icone "oeil" dans les champs mot de passe pour le voir en clair, #126 +- [TRAITEMENT] Ajout d'un champ "Observations", #121 +- [TRAITEMENT] Ajout d'un champ "Origine des données", #117 +- [LOGO] Pouvoir configurer les logos/le fournisseur de service et l'URL associé, #99 +### Changement +- [TECH] Mise à jour Symfony 4.2.2 en 4.2.4 + autres packages (dont vulnérabilité Twig), #148 +- [USER] Ré-agencement des blocs du formulaire "Utilisateurs" pour les admins, #135 +- [CONNEXION] Passage du temps de connexion de 4h à 1h30, #125 +- [TRAITEMENT] Passage en BDD de la liste des catégories de données (table `registry_treatment_data_category`), #105 +- [TRAITEMENT] Remplacement de la catégorie de données "Etat civil" par "Nom, prénom", "Date et lieu de naissance", "Situation pro", #105 +### Fix +- [TRAITEMENT] Le champ de formulaire "Délai de conservation" n'était pas bien aligné, #149 +- [USER] Lors de la création d'un utilisateur, la saisie de son mot de passe n'était pas prise en compte, #147 +- [TRAITEMENT] Le champ "Autre délai" ne s'affichait pas dans la visualisation d'un traitement, #144 +- [TRAITEMENT] Le champ "Délai de conservation" n'étais pas traduit sur le word (on pouvait lire "month" par exemple), #144 +- [USER] Modifier uniquement un mot de passe ne fonctionnait pas, #139 +- [GLOBAL] La sidebar se décalait lorsque nous allions sur l'onglet "Ma collectivité", #139 +- [USER] Le lecteur ne pouvait pas accéder aux infos de sa collectivité et son profil, #139 +- [VIOLATION] Erreur d'affichage lors de la visualisation d'une violation qui n'a pas de champ notification renseigné, #139 + ## [1.3.1] - 2019-01-31 ### Changement - [TECH] Mise à jour Symfony 4.2.1 à 4.2.2, #133 diff --git a/README.md b/README.md index 84cdf93ab6dd963a54f632daeeab35643741c749..4dfbb1261c95be3fb7955b28bc8c1ede0c7c00ce 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# CACF - Team Flow +# SOLURIS - Madis ## Getting Started These instructions will get you a copy of the project diff --git a/UPGRADE.md b/UPGRADE.md index 9cd248b2e9af2193a28e69942310db658ab1f31b..e85a7062468af3de383ac72fdb7769c2f493c243 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -9,9 +9,46 @@ De ce fait, répertoriez-vous à ce qui est écrit ci-dessous. que vous souhaitez installer, c'est que vous n'avez rien à faire._** -# Version v1.3 --> v1.3.1 -**Ajout de l'adresse du DPD moral / par défaut** + +# Passage en v1.4 + +### Possibilité de configurer les logos & le fournisseur de service + +Dans le `.env` vous pouvez modifier les informations des logos et +du fournisseur de service MADIS (si vous ne souhaitez modifier les +informations, copiez les variables comme affichées dans l'exemple) + +Ajoutez les variables suivantes dans votre `.env`. + +```text +APP_FOOTER_PROVIDER_NAME=SOLURIS +APP_FOOTER_PROVIDER_URL="https://soluris.fr" +APP_IMAGE_FAVICON_PATH="favicon.ico" +APP_IMAGE_SIDEBAR_BOTTOM_TARGET_URL="https://soluris.fr" +APP_IMAGE_SIDEBAR_BOTTOM_PATH="images/soluris-logo-white.png" +APP_IMAGE_SIDEBAR_REDUCED_PATH="images/icon-32x32.png" +``` + +_Note: Vous pourrez venir modifier ces variables plus tard._ + +Si vous souhaitez ajouter vos propres images, le dossier `public/custom` +n'est pas versionné dans GIT. +De ce fait, si vous souhaitez ajouter un favicon dans +`public/custom/images/favicon.ico` par exemple, il vous suffira de changer +`APP_IMAGE_FAVICON_PATH="favicon.ico"` par `APP_IMAGE_FAVICON_PATH="custom/images/favicon.ico"` +(le dossier `public` étant déjà ciblé par défaut). + +Finissez par lancer la commande `bin/console cache:clear` pour que ces +données soient appliquées + + + + + +# Passage en v1.3.1 + +### Ajout de l'adresse du DPD moral / par défaut Modifier le fichier `.env` pour y ajouter les 3 champs suivants, dans la section `symfony/framework-bundle` comme montré ci-dessous. diff --git a/assets/css/app.scss b/assets/css/app.scss index bb72d69166ad1a539d179845274a45c0c5ccd8ad..67d8b833f0b7ad09250cc2418169dfea5e430985 100644 --- a/assets/css/app.scss +++ b/assets/css/app.scss @@ -1,12 +1,17 @@ -/* Sidebar */ +/* Header */ +.main-header .logo-mini img { + max-width: 2em; + max-height: 2em; +} + .main-header .sidebar-toggle:before { content: ""; } +/* Sidebar */ .sidebar-logo { & img { - padding: 20px 5px 12px 0; - width: 190px; + width: 195px; height: auto; } } @@ -22,25 +27,28 @@ text-align: left; width: 100%; } -.delay-group .one-line { - vertical-align: middle; - > div { - display: inline-block; vertical-align: middle; - } - > div:nth-child(1) { - width: 25%; - } - > div:nth-child(2) { - width: 20%; +.delay-group { + .one-line { + vertical-align: middle; + + > div { + display: inline-block; + vertical-align: middle; + } } } +.has-feedback .form-control-feedback { + pointer-events: auto; + cursor: pointer; +} + /* Pages */ div.action-bar { margin-bottom: 1em; } /* Show */ -body.show ul { +body.show .content ul { -webkit-padding-start: 15px; } diff --git a/assets/js/app.js b/assets/js/app.js index abeee4ea50b3ee665b85a9ac76ab076391c25fbe..b22830d33d82ea595c52888b04e53bba8f5f9b58 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -1,4 +1,16 @@ $(document).ready(function(){ + + $('input[type=password]').each(function() { + let input = $(this); + let span = $(this).parent().find('span'); + span.on('mousedown', function() { + input.attr('type', 'text'); + }); + span.on('mouseup', function() { + input.attr('type', 'password'); + }); + }); + $('.complex-choice-group').each(function(idx) { var check = $(this).find('.check input'); var comment = $(this).find('.comment input'); @@ -18,6 +30,10 @@ $(document).ready(function(){ var period = $(this).find('select[id$="period"]'); var check = $(this).find('input[id$="otherDelay"]'); var comment = $(this).find('textarea[id$="comment"]'); + console.log(number); + console.log(period); + console.log(check); + console.log(comment); // Disable comment on unchecked line number.prop('disabled', check.is(':checked')); diff --git a/composer.json b/composer.json index 172b797bab8725cf06412d0e792f1930b2f901e0..292c4579a5f306c51c4e452344a07a77deb3bf16 100644 --- a/composer.json +++ b/composer.json @@ -10,6 +10,7 @@ ], "require": { "php": "^7.1", + "ext-json": "*", "ircmaxell/random-lib": "^1.2", "knplabs/dictionary-bundle": "^2.1", "knplabs/knp-gaufrette-bundle": "^0.5.3", diff --git a/composer.lock b/composer.lock index 37b2141340a0e5b1f3c9baf1ab0c623766242826..7be1a367bfbdb3c3e310bb61bef2b15f975aa0bc 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "efd46eeae3b82ce9fb62c293bb7f2fb5", + "content-hash": "da6b5ebb7ed579006cbd37bc0ff446c5", "packages": [ { "name": "behat/transliterator", @@ -425,16 +425,16 @@ }, { "name": "doctrine/doctrine-bundle", - "version": "1.10.1", + "version": "1.10.2", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineBundle.git", - "reference": "98551d71f515692c2278073e0d483763ac70b341" + "reference": "1f99e6645030542079c57d4680601a4a8778a1bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/98551d71f515692c2278073e0d483763ac70b341", - "reference": "98551d71f515692c2278073e0d483763ac70b341", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/1f99e6645030542079c57d4680601a4a8778a1bd", + "reference": "1f99e6645030542079c57d4680601a4a8778a1bd", "shasum": "" }, "require": { @@ -506,7 +506,7 @@ "orm", "persistence" ], - "time": "2019-01-07T15:31:08+00:00" + "time": "2019-02-06T13:18:04+00:00" }, { "name": "doctrine/doctrine-cache-bundle", @@ -1525,20 +1525,20 @@ }, { "name": "knplabs/dictionary-bundle", - "version": "v2.2.0", + "version": "v2.3.0", "source": { "type": "git", "url": "https://github.com/KnpLabs/DictionaryBundle.git", - "reference": "ccb9b90b5b99c39dbda39fe0a6d669ab0efe682e" + "reference": "e888879de4accd6cf648265e876ef6e7a87846e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/KnpLabs/DictionaryBundle/zipball/ccb9b90b5b99c39dbda39fe0a6d669ab0efe682e", - "reference": "ccb9b90b5b99c39dbda39fe0a6d669ab0efe682e", + "url": "https://api.github.com/repos/KnpLabs/DictionaryBundle/zipball/e888879de4accd6cf648265e876ef6e7a87846e2", + "reference": "e888879de4accd6cf648265e876ef6e7a87846e2", "shasum": "" }, "require": { - "php": ">=7.0", + "php": ">=7.1", "symfony/config": "~3.3 || ~4.0", "symfony/dependency-injection": "~3.3 || ~4.0", "symfony/form": "~3.3 || ~4.0", @@ -1550,11 +1550,9 @@ "require-dev": { "beberlei/assert": "^3.0", "fzaninotto/faker": "~1.3", - "leanphp/phpspec-code-coverage": "^4.1", "pedrotroller/php-cs-custom-fixer": "^2.15", "pedrotroller/symfony-integration-checker": "~2.0.0", - "phpspec/phpspec": "~4.3", - "phpspec/prophecy": ">=1.7.2", + "phpspec/phpspec": "~5.0", "sebastian/comparator": "~1.2.4" }, "suggest": { @@ -1589,7 +1587,7 @@ "keywords": [ "dictionary" ], - "time": "2018-10-29T10:47:28+00:00" + "time": "2019-03-11T09:40:00+00:00" }, { "name": "knplabs/gaufrette", @@ -1743,16 +1741,16 @@ }, { "name": "ocramius/package-versions", - "version": "1.3.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/Ocramius/PackageVersions.git", - "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f" + "reference": "a4d4b60d0e60da2487bd21a2c6ac089f85570dbb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/4489d5002c49d55576fa0ba786f42dbb009be46f", - "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f", + "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/a4d4b60d0e60da2487bd21a2c6ac089f85570dbb", + "reference": "a4d4b60d0e60da2487bd21a2c6ac089f85570dbb", "shasum": "" }, "require": { @@ -1761,6 +1759,7 @@ }, "require-dev": { "composer/composer": "^1.6.3", + "doctrine/coding-standard": "^5.0.1", "ext-zip": "*", "infection/infection": "^0.7.1", "phpunit/phpunit": "^7.0.0" @@ -1788,7 +1787,7 @@ } ], "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", - "time": "2018-02-05T13:05:30+00:00" + "time": "2019-02-21T12:16:21+00:00" }, { "name": "ocramius/proxy-manager", @@ -2458,16 +2457,16 @@ }, { "name": "rollerworks/password-strength-validator", - "version": "v1.1.4", + "version": "v1.1.5", "source": { "type": "git", "url": "https://github.com/rollerworks/PasswordStrengthValidator.git", - "reference": "90459659cf9f3554029c4ff8206bbf20b79fd259" + "reference": "e94ae9c089d780e08e5a5bcb14bb4bad3c58f85c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rollerworks/PasswordStrengthValidator/zipball/90459659cf9f3554029c4ff8206bbf20b79fd259", - "reference": "90459659cf9f3554029c4ff8206bbf20b79fd259", + "url": "https://api.github.com/repos/rollerworks/PasswordStrengthValidator/zipball/e94ae9c089d780e08e5a5bcb14bb4bad3c58f85c", + "reference": "e94ae9c089d780e08e5a5bcb14bb4bad3c58f85c", "shasum": "" }, "require": { @@ -2475,6 +2474,7 @@ "psr/container": "^1.0", "psr/log": "^1.0", "symfony/polyfill-mbstring": "^1.5.0", + "symfony/translation": "^2.8.9 || ^3.3.6 | ^4.0", "symfony/validator": "^2.8.9 || ^3.3.6 || ^4.0" }, "require-dev": { @@ -2522,7 +2522,7 @@ "symfony", "validator" ], - "time": "2018-08-21T15:01:59+00:00" + "time": "2019-03-04T14:52:59+00:00" }, { "name": "stof/doctrine-extensions-bundle", @@ -2591,25 +2591,28 @@ }, { "name": "swiftmailer/swiftmailer", - "version": "v6.1.3", + "version": "v6.2.0", "source": { "type": "git", "url": "https://github.com/swiftmailer/swiftmailer.git", - "reference": "8ddcb66ac10c392d3beb54829eef8ac1438595f4" + "reference": "6fa3232ff9d3f8237c0fae4b7ff05e1baa4cd707" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/8ddcb66ac10c392d3beb54829eef8ac1438595f4", - "reference": "8ddcb66ac10c392d3beb54829eef8ac1438595f4", + "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/6fa3232ff9d3f8237c0fae4b7ff05e1baa4cd707", + "reference": "6fa3232ff9d3f8237c0fae4b7ff05e1baa4cd707", "shasum": "" }, "require": { "egulias/email-validator": "~2.0", - "php": ">=7.0.0" + "php": ">=7.0.0", + "symfony/polyfill-iconv": "^1.0", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" }, "require-dev": { "mockery/mockery": "~0.9.1", - "symfony/phpunit-bridge": "~3.3@dev" + "symfony/phpunit-bridge": "^3.4.19|^4.1.8" }, "suggest": { "ext-intl": "Needed to support internationalized email addresses", @@ -2618,7 +2621,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "6.1-dev" + "dev-master": "6.2-dev" } }, "autoload": { @@ -2646,20 +2649,20 @@ "mail", "mailer" ], - "time": "2018-09-11T07:12:52+00:00" + "time": "2019-03-10T07:52:41+00:00" }, { "name": "symfony/asset", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/asset.git", - "reference": "fdbf4375f1692c227ff07e2d577bb4c2ea214016" + "reference": "7eee96a8630f9448304ae4f0e3b474ea4e033664" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/asset/zipball/fdbf4375f1692c227ff07e2d577bb4c2ea214016", - "reference": "fdbf4375f1692c227ff07e2d577bb4c2ea214016", + "url": "https://api.github.com/repos/symfony/asset/zipball/7eee96a8630f9448304ae4f0e3b474ea4e033664", + "reference": "7eee96a8630f9448304ae4f0e3b474ea4e033664", "shasum": "" }, "require": { @@ -2702,20 +2705,20 @@ ], "description": "Symfony Asset Component", "homepage": "https://symfony.com", - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-01-16T20:35:37+00:00" }, { "name": "symfony/cache", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "dd223d4bb9a2f9a4b4992851800b349739c40860" + "reference": "b5c650406953f2f44a37c4f3ac66152fafc22c66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/dd223d4bb9a2f9a4b4992851800b349739c40860", - "reference": "dd223d4bb9a2f9a4b4992851800b349739c40860", + "url": "https://api.github.com/repos/symfony/cache/zipball/b5c650406953f2f44a37c4f3ac66152fafc22c66", + "reference": "b5c650406953f2f44a37c4f3ac66152fafc22c66", "shasum": "" }, "require": { @@ -2779,20 +2782,20 @@ "caching", "psr6" ], - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-02-23T15:17:42+00:00" }, { "name": "symfony/config", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "a7a7d0a0244cfc82f040729ccf769e6cf55a78fb" + "reference": "7f70d79c7a24a94f8e98abb988049403a53d7b31" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/a7a7d0a0244cfc82f040729ccf769e6cf55a78fb", - "reference": "a7a7d0a0244cfc82f040729ccf769e6cf55a78fb", + "url": "https://api.github.com/repos/symfony/config/zipball/7f70d79c7a24a94f8e98abb988049403a53d7b31", + "reference": "7f70d79c7a24a94f8e98abb988049403a53d7b31", "shasum": "" }, "require": { @@ -2842,20 +2845,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-02-23T15:17:42+00:00" }, { "name": "symfony/console", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "b0a03c1bb0fcbe288629956cf2f1dd3f1dc97522" + "reference": "9dc2299a016497f9ee620be94524e6c0af0280a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/b0a03c1bb0fcbe288629956cf2f1dd3f1dc97522", - "reference": "b0a03c1bb0fcbe288629956cf2f1dd3f1dc97522", + "url": "https://api.github.com/repos/symfony/console/zipball/9dc2299a016497f9ee620be94524e6c0af0280a9", + "reference": "9dc2299a016497f9ee620be94524e6c0af0280a9", "shasum": "" }, "require": { @@ -2867,6 +2870,9 @@ "symfony/dependency-injection": "<3.4", "symfony/process": "<3.3" }, + "provide": { + "psr/log-implementation": "1.0" + }, "require-dev": { "psr/log": "~1.0", "symfony/config": "~3.4|~4.0", @@ -2876,7 +2882,7 @@ "symfony/process": "~3.4|~4.0" }, "suggest": { - "psr/log-implementation": "For using the console logger", + "psr/log": "For using the console logger", "symfony/event-dispatcher": "", "symfony/lock": "", "symfony/process": "" @@ -2911,7 +2917,7 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2019-01-04T15:13:53+00:00" + "time": "2019-02-23T15:17:42+00:00" }, { "name": "symfony/contracts", @@ -2983,16 +2989,16 @@ }, { "name": "symfony/debug", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "64cb33c81e37d19b7715d4a6a4d49c1c382066dd" + "reference": "de73f48977b8eaf7ce22814d66e43a1662cc864f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/64cb33c81e37d19b7715d4a6a4d49c1c382066dd", - "reference": "64cb33c81e37d19b7715d4a6a4d49c1c382066dd", + "url": "https://api.github.com/repos/symfony/debug/zipball/de73f48977b8eaf7ce22814d66e43a1662cc864f", + "reference": "de73f48977b8eaf7ce22814d66e43a1662cc864f", "shasum": "" }, "require": { @@ -3035,20 +3041,20 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-03-03T18:11:24+00:00" }, { "name": "symfony/dependency-injection", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "a28dda9df1d5494367454cad91e44751ac53921c" + "reference": "cdadb3765df7c89ac93628743913b92bb91f1704" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/a28dda9df1d5494367454cad91e44751ac53921c", - "reference": "a28dda9df1d5494367454cad91e44751ac53921c", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/cdadb3765df7c89ac93628743913b92bb91f1704", + "reference": "cdadb3765df7c89ac93628743913b92bb91f1704", "shasum": "" }, "require": { @@ -3108,20 +3114,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2019-01-05T16:37:49+00:00" + "time": "2019-02-23T15:17:42+00:00" }, { "name": "symfony/doctrine-bridge", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "9dd24388fad8ae89b3f97a6eec70a18aabf3f7db" + "reference": "94b24ac0b65c0c623d454f0583e1caf4913dee84" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/9dd24388fad8ae89b3f97a6eec70a18aabf3f7db", - "reference": "9dd24388fad8ae89b3f97a6eec70a18aabf3f7db", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/94b24ac0b65c0c623d454f0583e1caf4913dee84", + "reference": "94b24ac0b65c0c623d454f0583e1caf4913dee84", "shasum": "" }, "require": { @@ -3196,20 +3202,20 @@ ], "description": "Symfony Doctrine Bridge", "homepage": "https://symfony.com", - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-02-23T15:17:42+00:00" }, { "name": "symfony/dotenv", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/dotenv.git", - "reference": "36e4e4750a88f52a5542bd8a54a947cb57039ece" + "reference": "9a3bdfcd7a0d9602754894d76c614d15ca366535" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dotenv/zipball/36e4e4750a88f52a5542bd8a54a947cb57039ece", - "reference": "36e4e4750a88f52a5542bd8a54a947cb57039ece", + "url": "https://api.github.com/repos/symfony/dotenv/zipball/9a3bdfcd7a0d9602754894d76c614d15ca366535", + "reference": "9a3bdfcd7a0d9602754894d76c614d15ca366535", "shasum": "" }, "require": { @@ -3253,20 +3259,20 @@ "env", "environment" ], - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-01-24T21:39:51+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "887de6d34c86cf0cb6cbf910afb170cdb743cb5e" + "reference": "3354d2e6af986dd71f68b4e5cf4a933ab58697fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/887de6d34c86cf0cb6cbf910afb170cdb743cb5e", - "reference": "887de6d34c86cf0cb6cbf910afb170cdb743cb5e", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3354d2e6af986dd71f68b4e5cf4a933ab58697fb", + "reference": "3354d2e6af986dd71f68b4e5cf4a933ab58697fb", "shasum": "" }, "require": { @@ -3317,20 +3323,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2019-01-05T16:37:49+00:00" + "time": "2019-02-23T15:17:42+00:00" }, { "name": "symfony/expression-language", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/expression-language.git", - "reference": "78a427af5e08eba1b391ddfbcaebb6dc6ab715be" + "reference": "a69b153996a13ffdb05395e8724c7217a8448e9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/expression-language/zipball/78a427af5e08eba1b391ddfbcaebb6dc6ab715be", - "reference": "78a427af5e08eba1b391ddfbcaebb6dc6ab715be", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/a69b153996a13ffdb05395e8724c7217a8448e9e", + "reference": "a69b153996a13ffdb05395e8724c7217a8448e9e", "shasum": "" }, "require": { @@ -3368,20 +3374,20 @@ ], "description": "Symfony ExpressionLanguage Component", "homepage": "https://symfony.com", - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-01-16T20:31:39+00:00" }, { "name": "symfony/filesystem", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "c2ffd9a93f2d6c5be2f68a0aa7953cc229f871f8" + "reference": "e16b9e471703b2c60b95f14d31c1239f68f11601" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/c2ffd9a93f2d6c5be2f68a0aa7953cc229f871f8", - "reference": "c2ffd9a93f2d6c5be2f68a0aa7953cc229f871f8", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/e16b9e471703b2c60b95f14d31c1239f68f11601", + "reference": "e16b9e471703b2c60b95f14d31c1239f68f11601", "shasum": "" }, "require": { @@ -3418,20 +3424,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-02-07T11:40:08+00:00" }, { "name": "symfony/finder", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "9094d69e8c6ee3fe186a0ec5a4f1401e506071ce" + "reference": "267b7002c1b70ea80db0833c3afe05f0fbde580a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/9094d69e8c6ee3fe186a0ec5a4f1401e506071ce", - "reference": "9094d69e8c6ee3fe186a0ec5a4f1401e506071ce", + "url": "https://api.github.com/repos/symfony/finder/zipball/267b7002c1b70ea80db0833c3afe05f0fbde580a", + "reference": "267b7002c1b70ea80db0833c3afe05f0fbde580a", "shasum": "" }, "require": { @@ -3467,20 +3473,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-02-23T15:42:05+00:00" }, { "name": "symfony/flex", - "version": "v1.1.8", + "version": "v1.2.0", "source": { "type": "git", "url": "https://github.com/symfony/flex.git", - "reference": "955774ecf07b10230bb5b44e150ba078b45f68fa" + "reference": "7f04fb50c5da6d020e4df743b4c764c188bb24bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/flex/zipball/955774ecf07b10230bb5b44e150ba078b45f68fa", - "reference": "955774ecf07b10230bb5b44e150ba078b45f68fa", + "url": "https://api.github.com/repos/symfony/flex/zipball/7f04fb50c5da6d020e4df743b4c764c188bb24bf", + "reference": "7f04fb50c5da6d020e4df743b4c764c188bb24bf", "shasum": "" }, "require": { @@ -3489,12 +3495,14 @@ }, "require-dev": { "composer/composer": "^1.0.2", - "symfony/phpunit-bridge": "^3.2.8" + "symfony/dotenv": "^3.4|^4.0", + "symfony/phpunit-bridge": "^3.4.19|^4.1.8", + "symfony/process": "^2.7|^3.0|^4.0" }, "type": "composer-plugin", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-master": "1.2-dev" }, "class": "Symfony\\Flex\\Flex" }, @@ -3514,20 +3522,20 @@ } ], "description": "Composer plugin for Symfony", - "time": "2018-11-15T06:11:38+00:00" + "time": "2019-02-21T11:31:25+00:00" }, { "name": "symfony/form", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/form.git", - "reference": "3361332a168850dc8b3abd133553f66c0cb28b1c" + "reference": "d44ad1ac671fb79fe5b3093b61779476da8b63f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/form/zipball/3361332a168850dc8b3abd133553f66c0cb28b1c", - "reference": "3361332a168850dc8b3abd133553f66c0cb28b1c", + "url": "https://api.github.com/repos/symfony/form/zipball/d44ad1ac671fb79fe5b3093b61779476da8b63f9", + "reference": "d44ad1ac671fb79fe5b3093b61779476da8b63f9", "shasum": "" }, "require": { @@ -3596,20 +3604,20 @@ ], "description": "Symfony Form Component", "homepage": "https://symfony.com", - "time": "2019-01-05T16:37:49+00:00" + "time": "2019-02-23T15:42:05+00:00" }, { "name": "symfony/framework-bundle", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", - "reference": "6cba25ea9489d62addb9971a4bdcf42a5639e641" + "reference": "50227854eb9863a1cae38952baff4d80953e7336" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/6cba25ea9489d62addb9971a4bdcf42a5639e641", - "reference": "6cba25ea9489d62addb9971a4bdcf42a5639e641", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/50227854eb9863a1cae38952baff4d80953e7336", + "reference": "50227854eb9863a1cae38952baff4d80953e7336", "shasum": "" }, "require": { @@ -3655,7 +3663,7 @@ "symfony/css-selector": "~3.4|~4.0", "symfony/dom-crawler": "~3.4|~4.0", "symfony/expression-language": "~3.4|~4.0", - "symfony/form": "^4.2", + "symfony/form": "^4.2.3", "symfony/lock": "~3.4|~4.0", "symfony/messenger": "^4.2", "symfony/polyfill-intl-icu": "~1.0", @@ -3715,20 +3723,20 @@ ], "description": "Symfony FrameworkBundle", "homepage": "https://symfony.com", - "time": "2019-01-05T16:37:49+00:00" + "time": "2019-02-24T02:12:10+00:00" }, { "name": "symfony/http-foundation", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "a633d422a09242064ba24e44a6e1494c5126de86" + "reference": "850a667d6254ccf6c61d853407b16f21c4579c77" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/a633d422a09242064ba24e44a6e1494c5126de86", - "reference": "a633d422a09242064ba24e44a6e1494c5126de86", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/850a667d6254ccf6c61d853407b16f21c4579c77", + "reference": "850a667d6254ccf6c61d853407b16f21c4579c77", "shasum": "" }, "require": { @@ -3769,20 +3777,20 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2019-01-05T16:37:49+00:00" + "time": "2019-02-26T08:03:39+00:00" }, { "name": "symfony/http-kernel", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "83de6543328917c18d5498eeb6bb6d36f7aab31b" + "reference": "895ceccaa8149f9343e6134e607c21da42d73b7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/83de6543328917c18d5498eeb6bb6d36f7aab31b", - "reference": "83de6543328917c18d5498eeb6bb6d36f7aab31b", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/895ceccaa8149f9343e6134e607c21da42d73b7a", + "reference": "895ceccaa8149f9343e6134e607c21da42d73b7a", "shasum": "" }, "require": { @@ -3858,20 +3866,20 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2019-01-06T16:19:23+00:00" + "time": "2019-03-03T19:38:09+00:00" }, { "name": "symfony/inflector", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/inflector.git", - "reference": "9f64271222922ef1a10e43f77d88baf72bf22b0e" + "reference": "275e54941a4f17a471c68d2a00e2513fc1fd4a78" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/inflector/zipball/9f64271222922ef1a10e43f77d88baf72bf22b0e", - "reference": "9f64271222922ef1a10e43f77d88baf72bf22b0e", + "url": "https://api.github.com/repos/symfony/inflector/zipball/275e54941a4f17a471c68d2a00e2513fc1fd4a78", + "reference": "275e54941a4f17a471c68d2a00e2513fc1fd4a78", "shasum": "" }, "require": { @@ -3916,20 +3924,20 @@ "symfony", "words" ], - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-01-16T20:31:39+00:00" }, { "name": "symfony/intl", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/intl.git", - "reference": "9bc515dfd1f02bcf64309ab5fd86bace4f43b86d" + "reference": "b2af5ce379781fd4811f79746512fc1934333fbb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/intl/zipball/9bc515dfd1f02bcf64309ab5fd86bace4f43b86d", - "reference": "9bc515dfd1f02bcf64309ab5fd86bace4f43b86d", + "url": "https://api.github.com/repos/symfony/intl/zipball/b2af5ce379781fd4811f79746512fc1934333fbb", + "reference": "b2af5ce379781fd4811f79746512fc1934333fbb", "shasum": "" }, "require": { @@ -3991,20 +3999,20 @@ "l10n", "localization" ], - "time": "2019-01-05T16:37:49+00:00" + "time": "2019-02-23T15:17:42+00:00" }, { "name": "symfony/options-resolver", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "fbcb106aeee72f3450298bf73324d2cc00d083d1" + "reference": "3896e5a7d06fd15fa4947694c8dcdd371ff147d1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/fbcb106aeee72f3450298bf73324d2cc00d083d1", - "reference": "fbcb106aeee72f3450298bf73324d2cc00d083d1", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/3896e5a7d06fd15fa4947694c8dcdd371ff147d1", + "reference": "3896e5a7d06fd15fa4947694c8dcdd371ff147d1", "shasum": "" }, "require": { @@ -4045,7 +4053,7 @@ "configuration", "options" ], - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-02-23T15:17:42+00:00" }, { "name": "symfony/orm-pack", @@ -4133,6 +4141,68 @@ ], "time": "2018-08-06T14:22:27+00:00" }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.10.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "89de1d44f2c059b266f22c9cc9124ddc4cd0987a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/89de1d44f2c059b266f22c9cc9124ddc4cd0987a", + "reference": "89de1d44f2c059b266f22c9cc9124ddc4cd0987a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/polyfill-mbstring": "^1.3", + "symfony/polyfill-php72": "^1.9" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + }, + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "time": "2018-09-30T16:36:12+00:00" + }, { "name": "symfony/polyfill-mbstring", "version": "v1.10.0", @@ -4192,18 +4262,73 @@ ], "time": "2018-09-21T13:07:52+00:00" }, + { + "name": "symfony/polyfill-php72", + "version": "v1.10.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", + "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2018-09-21T13:07:52+00:00" + }, { "name": "symfony/property-access", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "a21d40670000f61a1a4b90a607d54696aad914cd" + "reference": "d5e10532c51db0b657b1e25b2bd70acbcd13bbf9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/a21d40670000f61a1a4b90a607d54696aad914cd", - "reference": "a21d40670000f61a1a4b90a607d54696aad914cd", + "url": "https://api.github.com/repos/symfony/property-access/zipball/d5e10532c51db0b657b1e25b2bd70acbcd13bbf9", + "reference": "d5e10532c51db0b657b1e25b2bd70acbcd13bbf9", "shasum": "" }, "require": { @@ -4257,20 +4382,20 @@ "property path", "reflection" ], - "time": "2019-01-05T16:37:49+00:00" + "time": "2019-02-23T15:17:42+00:00" }, { "name": "symfony/routing", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "e69b7a13a0b58af378a49b49dd7084462de16cee" + "reference": "ff03eae644e6b1e26d4a04b2385fe3a1a7f04e42" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/e69b7a13a0b58af378a49b49dd7084462de16cee", - "reference": "e69b7a13a0b58af378a49b49dd7084462de16cee", + "url": "https://api.github.com/repos/symfony/routing/zipball/ff03eae644e6b1e26d4a04b2385fe3a1a7f04e42", + "reference": "ff03eae644e6b1e26d4a04b2385fe3a1a7f04e42", "shasum": "" }, "require": { @@ -4334,7 +4459,7 @@ "uri", "url" ], - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-02-23T15:17:42+00:00" }, { "name": "symfony/security", @@ -4419,16 +4544,16 @@ }, { "name": "symfony/security-bundle", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/security-bundle.git", - "reference": "404bb89be12ba0e493e05f0a3196f07915bd155f" + "reference": "d382808b206f01235053d6d1981beef325a7345b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-bundle/zipball/404bb89be12ba0e493e05f0a3196f07915bd155f", - "reference": "404bb89be12ba0e493e05f0a3196f07915bd155f", + "url": "https://api.github.com/repos/symfony/security-bundle/zipball/d382808b206f01235053d6d1981beef325a7345b", + "reference": "d382808b206f01235053d6d1981beef325a7345b", "shasum": "" }, "require": { @@ -4501,20 +4626,20 @@ ], "description": "Symfony SecurityBundle", "homepage": "https://symfony.com", - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-03-03T18:11:24+00:00" }, { "name": "symfony/skeleton", - "version": "v4.2.2.1", + "version": "v4.2.4.1", "source": { "type": "git", "url": "https://github.com/symfony/skeleton.git", - "reference": "b50325e93f886d2fe8f7f239551dde8dec8a3458" + "reference": "e8b61ac3757a2cc829bbdd38574b9adefb97425d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/skeleton/zipball/b50325e93f886d2fe8f7f239551dde8dec8a3458", - "reference": "b50325e93f886d2fe8f7f239551dde8dec8a3458", + "url": "https://api.github.com/repos/symfony/skeleton/zipball/e8b61ac3757a2cc829bbdd38574b9adefb97425d", + "reference": "e8b61ac3757a2cc829bbdd38574b9adefb97425d", "shasum": "" }, "require": { @@ -4555,20 +4680,20 @@ "MIT" ], "description": "A minimal Symfony project recommended to create bare bones applications", - "time": "2019-01-12T16:12:14+00:00" + "time": "2019-03-09T16:16:09+00:00" }, { "name": "symfony/stopwatch", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "af62b35760fc92c8dbdce659b4eebdfe0e6a0472" + "reference": "b1a5f646d56a3290230dbc8edf2a0d62cda23f67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/af62b35760fc92c8dbdce659b4eebdfe0e6a0472", - "reference": "af62b35760fc92c8dbdce659b4eebdfe0e6a0472", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/b1a5f646d56a3290230dbc8edf2a0d62cda23f67", + "reference": "b1a5f646d56a3290230dbc8edf2a0d62cda23f67", "shasum": "" }, "require": { @@ -4605,7 +4730,7 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com", - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-01-16T20:31:39+00:00" }, { "name": "symfony/swiftmailer-bundle", @@ -4669,28 +4794,101 @@ "homepage": "http://symfony.com", "time": "2019-01-05T11:51:59+00:00" }, + { + "name": "symfony/translation", + "version": "v4.2.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "748464177a77011f8f4cdd076773862ce4915f8f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/748464177a77011f8f4cdd076773862ce4915f8f", + "reference": "748464177a77011f8f4cdd076773862ce4915f8f", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/contracts": "^1.0.2", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/config": "<3.4", + "symfony/dependency-injection": "<3.4", + "symfony/yaml": "<3.4" + }, + "provide": { + "symfony/translation-contracts-implementation": "1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/console": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/finder": "~2.8|~3.0|~4.0", + "symfony/intl": "~3.4|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "psr/log-implementation": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "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 Translation Component", + "homepage": "https://symfony.com", + "time": "2019-02-27T03:31:50+00:00" + }, { "name": "symfony/twig-bridge", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/twig-bridge.git", - "reference": "bf9379a4fae77a05a2446880bc7867651e8b2a87" + "reference": "ac6f9fa8a49ddc0afb52e59808d15f98e9a84bcf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/bf9379a4fae77a05a2446880bc7867651e8b2a87", - "reference": "bf9379a4fae77a05a2446880bc7867651e8b2a87", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/ac6f9fa8a49ddc0afb52e59808d15f98e9a84bcf", + "reference": "ac6f9fa8a49ddc0afb52e59808d15f98e9a84bcf", "shasum": "" }, "require": { "php": "^7.1.3", "symfony/contracts": "^1.0.2", - "twig/twig": "^1.35|^2.4.4" + "twig/twig": "^1.37.1|^2.6.2" }, "conflict": { "symfony/console": "<3.4", - "symfony/form": "<4.2", + "symfony/form": "<4.2.4", "symfony/translation": "<4.2" }, "require-dev": { @@ -4699,7 +4897,7 @@ "symfony/dependency-injection": "~3.4|~4.0", "symfony/expression-language": "~3.4|~4.0", "symfony/finder": "~3.4|~4.0", - "symfony/form": "^4.2", + "symfony/form": "^4.2.4", "symfony/http-foundation": "~3.4|~4.0", "symfony/http-kernel": "~3.4|~4.0", "symfony/polyfill-intl-icu": "~1.0", @@ -4759,20 +4957,20 @@ ], "description": "Symfony Twig Bridge", "homepage": "https://symfony.com", - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-02-23T15:17:42+00:00" }, { "name": "symfony/twig-bundle", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/twig-bundle.git", - "reference": "28066429877c23536cd74feec17154e8089d87f5" + "reference": "eb32e41993f59de82406e918a55b503b2374b991" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/28066429877c23536cd74feec17154e8089d87f5", - "reference": "28066429877c23536cd74feec17154e8089d87f5", + "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/eb32e41993f59de82406e918a55b503b2374b991", + "reference": "eb32e41993f59de82406e918a55b503b2374b991", "shasum": "" }, "require": { @@ -4835,20 +5033,20 @@ ], "description": "Symfony TwigBundle", "homepage": "https://symfony.com", - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-01-16T20:35:37+00:00" }, { "name": "symfony/validator", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "f89d2fab883a6a20d0d0093537392763cf52f0ba" + "reference": "ba50866242d992f0dd818e2c34c5088f163c974d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/f89d2fab883a6a20d0d0093537392763cf52f0ba", - "reference": "f89d2fab883a6a20d0d0093537392763cf52f0ba", + "url": "https://api.github.com/repos/symfony/validator/zipball/ba50866242d992f0dd818e2c34c5088f163c974d", + "reference": "ba50866242d992f0dd818e2c34c5088f163c974d", "shasum": "" }, "require": { @@ -4924,20 +5122,20 @@ ], "description": "Symfony Validator Component", "homepage": "https://symfony.com", - "time": "2019-01-06T14:13:54+00:00" + "time": "2019-03-03T18:11:24+00:00" }, { "name": "symfony/var-exporter", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "51bd782120fa2bfed89452f142d2a47c4b51101c" + "reference": "d8bf4424c232b55f4c1816037d3077a89258557e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/51bd782120fa2bfed89452f142d2a47c4b51101c", - "reference": "51bd782120fa2bfed89452f142d2a47c4b51101c", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/d8bf4424c232b55f4c1816037d3077a89258557e", + "reference": "d8bf4424c232b55f4c1816037d3077a89258557e", "shasum": "" }, "require": { @@ -4984,7 +5182,7 @@ "instantiate", "serialize" ], - "time": "2019-01-03T09:09:06+00:00" + "time": "2019-01-16T20:35:37+00:00" }, { "name": "symfony/webpack-encore-pack", @@ -5019,16 +5217,16 @@ }, { "name": "symfony/yaml", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "d0aa6c0ea484087927b49fd513383a7d36190ca6" + "reference": "761fa560a937fd7686e5274ff89dcfa87a5047df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/d0aa6c0ea484087927b49fd513383a7d36190ca6", - "reference": "d0aa6c0ea484087927b49fd513383a7d36190ca6", + "url": "https://api.github.com/repos/symfony/yaml/zipball/761fa560a937fd7686e5274ff89dcfa87a5047df", + "reference": "761fa560a937fd7686e5274ff89dcfa87a5047df", "shasum": "" }, "require": { @@ -5074,7 +5272,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-02-23T15:17:42+00:00" }, { "name": "twig/extensions", @@ -5133,16 +5331,16 @@ }, { "name": "twig/twig", - "version": "v2.6.2", + "version": "v2.7.2", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "7d7342c8a4059fefb9b8d07db0cc14007021f9b7" + "reference": "70c59531da43afe598c66135e39cac39475a2f51" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/7d7342c8a4059fefb9b8d07db0cc14007021f9b7", - "reference": "7d7342c8a4059fefb9b8d07db0cc14007021f9b7", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/70c59531da43afe598c66135e39cac39475a2f51", + "reference": "70c59531da43afe598c66135e39cac39475a2f51", "shasum": "" }, "require": { @@ -5158,7 +5356,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { @@ -5196,7 +5394,7 @@ "keywords": [ "templating" ], - "time": "2019-01-14T15:00:48+00:00" + "time": "2019-03-12T18:48:26+00:00" }, { "name": "zendframework/zend-code", @@ -5552,16 +5750,16 @@ }, { "name": "composer/ca-bundle", - "version": "1.1.3", + "version": "1.1.4", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "8afa52cd417f4ec417b4bfe86b68106538a87660" + "reference": "558f321c52faeb4828c03e7dc0cfe39a09e09a2d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/8afa52cd417f4ec417b4bfe86b68106538a87660", - "reference": "8afa52cd417f4ec417b4bfe86b68106538a87660", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/558f321c52faeb4828c03e7dc0cfe39a09e09a2d", + "reference": "558f321c52faeb4828c03e7dc0cfe39a09e09a2d", "shasum": "" }, "require": { @@ -5604,7 +5802,7 @@ "ssl", "tls" ], - "time": "2018-10-18T06:09:13+00:00" + "time": "2019-01-28T09:30:10+00:00" }, { "name": "composer/semver", @@ -5670,16 +5868,16 @@ }, { "name": "composer/xdebug-handler", - "version": "1.3.1", + "version": "1.3.2", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "dc523135366eb68f22268d069ea7749486458562" + "reference": "d17708133b6c276d6e42ef887a877866b909d892" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/dc523135366eb68f22268d069ea7749486458562", - "reference": "dc523135366eb68f22268d069ea7749486458562", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/d17708133b6c276d6e42ef887a877866b909d892", + "reference": "d17708133b6c276d6e42ef887a877866b909d892", "shasum": "" }, "require": { @@ -5710,7 +5908,7 @@ "Xdebug", "performance" ], - "time": "2018-11-29T10:59:02+00:00" + "time": "2019-01-28T20:25:53+00:00" }, { "name": "container-interop/container-interop", @@ -5855,16 +6053,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v2.14.0", + "version": "v2.14.2", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "b788ea0af899cedc8114dca7db119c93b6685da2" + "reference": "ff401e58261ffc5934a58f795b3f95b355e276cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/b788ea0af899cedc8114dca7db119c93b6685da2", - "reference": "b788ea0af899cedc8114dca7db119c93b6685da2", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/ff401e58261ffc5934a58f795b3f95b355e276cb", + "reference": "ff401e58261ffc5934a58f795b3f95b355e276cb", "shasum": "" }, "require": { @@ -5885,9 +6083,6 @@ "symfony/process": "^3.0 || ^4.0", "symfony/stopwatch": "^3.0 || ^4.0" }, - "conflict": { - "hhvm": "*" - }, "require-dev": { "johnkary/phpunit-speedtrap": "^1.1 || ^2.0 || ^3.0", "justinrainbow/json-schema": "^5.0", @@ -5911,11 +6106,6 @@ "php-cs-fixer" ], "type": "application", - "extra": { - "branch-alias": { - "dev-master": "2.14-dev" - } - }, "autoload": { "psr-4": { "PhpCsFixer\\": "src/" @@ -5947,7 +6137,7 @@ } ], "description": "A tool to automatically fix PHP code style", - "time": "2019-01-04T18:29:47+00:00" + "time": "2019-02-17T17:44:13+00:00" }, { "name": "fzaninotto/faker", @@ -6198,16 +6388,16 @@ }, { "name": "nelmio/alice", - "version": "v3.5.3", + "version": "v3.5.5", "source": { "type": "git", "url": "https://github.com/nelmio/alice.git", - "reference": "e8f6cc331eca745ccc155402500901cebfc1444f" + "reference": "b1b2a519f0e3fdffa81a051fea72b33d3c6c9c21" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nelmio/alice/zipball/e8f6cc331eca745ccc155402500901cebfc1444f", - "reference": "e8f6cc331eca745ccc155402500901cebfc1444f", + "url": "https://api.github.com/repos/nelmio/alice/zipball/b1b2a519f0e3fdffa81a051fea72b33d3c6c9c21", + "reference": "b1b2a519f0e3fdffa81a051fea72b33d3c6c9c21", "shasum": "" }, "require": { @@ -6274,7 +6464,7 @@ "faker", "test" ], - "time": "2018-12-22T21:25:49+00:00" + "time": "2019-03-14T21:21:21+00:00" }, { "name": "phar-io/manifest", @@ -6800,16 +6990,16 @@ }, { "name": "phpunit/php-timer", - "version": "2.0.0", + "version": "2.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f" + "reference": "8b389aebe1b8b0578430bda0c7c95a829608e059" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b8454ea6958c3dee38453d3bd571e023108c91f", - "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b389aebe1b8b0578430bda0c7c95a829608e059", + "reference": "8b389aebe1b8b0578430bda0c7c95a829608e059", "shasum": "" }, "require": { @@ -6821,7 +7011,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "2.1-dev" } }, "autoload": { @@ -6845,7 +7035,7 @@ "keywords": [ "timer" ], - "time": "2018-02-01T13:07:23+00:00" + "time": "2019-02-20T10:12:59+00:00" }, { "name": "phpunit/php-token-stream", @@ -6898,16 +7088,16 @@ }, { "name": "phpunit/phpunit", - "version": "7.5.2", + "version": "7.5.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "7c89093bd00f7d5ddf0ab81dee04f801416b4944" + "reference": "eb343b86753d26de07ecba7868fa983104361948" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7c89093bd00f7d5ddf0ab81dee04f801416b4944", - "reference": "7c89093bd00f7d5ddf0ab81dee04f801416b4944", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/eb343b86753d26de07ecba7868fa983104361948", + "reference": "eb343b86753d26de07ecba7868fa983104361948", "shasum": "" }, "require": { @@ -6925,7 +7115,7 @@ "phpunit/php-code-coverage": "^6.0.7", "phpunit/php-file-iterator": "^2.0.1", "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^2.0", + "phpunit/php-timer": "^2.1", "sebastian/comparator": "^3.0", "sebastian/diff": "^3.0", "sebastian/environment": "^4.0", @@ -6978,7 +7168,7 @@ "testing", "xunit" ], - "time": "2019-01-15T08:19:08+00:00" + "time": "2019-03-16T07:31:17+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -7091,23 +7281,23 @@ }, { "name": "sebastian/diff", - "version": "3.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "366541b989927187c4ca70490a35615d3fef2dce" + "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/366541b989927187c4ca70490a35615d3fef2dce", - "reference": "366541b989927187c4ca70490a35615d3fef2dce", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29", + "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "^7.0", + "phpunit/phpunit": "^7.5 || ^8.0", "symfony/process": "^2 || ^3.3 || ^4" }, "type": "library", @@ -7143,32 +7333,35 @@ "unidiff", "unified diff" ], - "time": "2018-06-10T07:54:39+00:00" + "time": "2019-02-04T06:01:07+00:00" }, { "name": "sebastian/environment", - "version": "4.0.1", + "version": "4.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "febd209a219cea7b56ad799b30ebbea34b71eb8f" + "reference": "6fda8ce1974b62b14935adc02a9ed38252eca656" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/febd209a219cea7b56ad799b30ebbea34b71eb8f", - "reference": "febd209a219cea7b56ad799b30ebbea34b71eb8f", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6fda8ce1974b62b14935adc02a9ed38252eca656", + "reference": "6fda8ce1974b62b14935adc02a9ed38252eca656", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "^7.4" + "phpunit/phpunit": "^7.5" + }, + "suggest": { + "ext-posix": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "4.1-dev" } }, "autoload": { @@ -7193,7 +7386,7 @@ "environment", "hhvm" ], - "time": "2018-11-25T09:31:21+00:00" + "time": "2019-02-01T05:27:49+00:00" }, { "name": "sebastian/exporter", @@ -7591,16 +7784,16 @@ }, { "name": "symfony/class-loader", - "version": "v3.4.21", + "version": "v3.4.23", "source": { "type": "git", "url": "https://github.com/symfony/class-loader.git", - "reference": "4513348012c25148f8cbc3a7761a1d1e60ca3e87" + "reference": "4459eef5298dedfb69f771186a580062b8516497" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/class-loader/zipball/4513348012c25148f8cbc3a7761a1d1e60ca3e87", - "reference": "4513348012c25148f8cbc3a7761a1d1e60ca3e87", + "url": "https://api.github.com/repos/symfony/class-loader/zipball/4459eef5298dedfb69f771186a580062b8516497", + "reference": "4459eef5298dedfb69f771186a580062b8516497", "shasum": "" }, "require": { @@ -7643,20 +7836,20 @@ ], "description": "Symfony ClassLoader Component", "homepage": "https://symfony.com", - "time": "2019-01-01T13:45:19+00:00" + "time": "2019-01-16T09:39:14+00:00" }, { "name": "symfony/debug-bundle", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/debug-bundle.git", - "reference": "be5cf5e46533de3e9325a2442fb4075787545140" + "reference": "f50fe0cff269d6fb6cb4bcd3bc98e499319b093f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug-bundle/zipball/be5cf5e46533de3e9325a2442fb4075787545140", - "reference": "be5cf5e46533de3e9325a2442fb4075787545140", + "url": "https://api.github.com/repos/symfony/debug-bundle/zipball/f50fe0cff269d6fb6cb4bcd3bc98e499319b093f", + "reference": "f50fe0cff269d6fb6cb4bcd3bc98e499319b093f", "shasum": "" }, "require": { @@ -7709,7 +7902,7 @@ ], "description": "Symfony DebugBundle", "homepage": "https://symfony.com", - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-01-16T20:31:39+00:00" }, { "name": "symfony/debug-pack", @@ -7743,16 +7936,16 @@ }, { "name": "symfony/monolog-bridge", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/monolog-bridge.git", - "reference": "8fa559511f1d215ca81e22f222d50eb029f93902" + "reference": "2da647858fb9a13c425e6897c829c2ae97d9e5c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/8fa559511f1d215ca81e22f222d50eb029f93902", - "reference": "8fa559511f1d215ca81e22f222d50eb029f93902", + "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/2da647858fb9a13c425e6897c829c2ae97d9e5c3", + "reference": "2da647858fb9a13c425e6897c829c2ae97d9e5c3", "shasum": "" }, "require": { @@ -7807,7 +8000,7 @@ ], "description": "Symfony Monolog Bridge", "homepage": "https://symfony.com", - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-02-23T15:17:42+00:00" }, { "name": "symfony/monolog-bundle", @@ -7872,73 +8065,18 @@ ], "time": "2018-11-04T09:58:13+00:00" }, - { - "name": "symfony/polyfill-php72", - "version": "v1.10.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", - "reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.9-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2018-09-21T13:07:52+00:00" - }, { "name": "symfony/process", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "ea043ab5d8ed13b467a9087d81cb876aee7f689a" + "reference": "6c05edb11fbeff9e2b324b4270ecb17911a8b7ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/ea043ab5d8ed13b467a9087d81cb876aee7f689a", - "reference": "ea043ab5d8ed13b467a9087d81cb876aee7f689a", + "url": "https://api.github.com/repos/symfony/process/zipball/6c05edb11fbeff9e2b324b4270ecb17911a8b7ad", + "reference": "6c05edb11fbeff9e2b324b4270ecb17911a8b7ad", "shasum": "" }, "require": { @@ -7974,7 +8112,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2019-01-03T14:48:52+00:00" + "time": "2019-01-24T22:05:03+00:00" }, { "name": "symfony/profiler-pack", @@ -8004,91 +8142,18 @@ "description": "A pack for the Symfony web profiler", "time": "2018-12-10T12:11:44+00:00" }, - { - "name": "symfony/translation", - "version": "v4.2.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/translation.git", - "reference": "939fb792d73f2ce80e6ae9019d205fc480f1c9a0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/939fb792d73f2ce80e6ae9019d205fc480f1c9a0", - "reference": "939fb792d73f2ce80e6ae9019d205fc480f1c9a0", - "shasum": "" - }, - "require": { - "php": "^7.1.3", - "symfony/contracts": "^1.0.2", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "symfony/config": "<3.4", - "symfony/dependency-injection": "<3.4", - "symfony/yaml": "<3.4" - }, - "provide": { - "symfony/translation-contracts-implementation": "1.0" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~3.4|~4.0", - "symfony/console": "~3.4|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/finder": "~2.8|~3.0|~4.0", - "symfony/intl": "~3.4|~4.0", - "symfony/yaml": "~3.4|~4.0" - }, - "suggest": { - "psr/log-implementation": "To use logging capability in translator", - "symfony/config": "", - "symfony/yaml": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.2-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Translation\\": "" - }, - "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 Translation Component", - "homepage": "https://symfony.com", - "time": "2019-01-03T09:07:35+00:00" - }, { "name": "symfony/var-dumper", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "85bde661b178173d85c6f11ea9d03b61d1212bb2" + "reference": "9f87189ac10b42edf7fb8edc846f1937c6d157cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/85bde661b178173d85c6f11ea9d03b61d1212bb2", - "reference": "85bde661b178173d85c6f11ea9d03b61d1212bb2", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/9f87189ac10b42edf7fb8edc846f1937c6d157cf", + "reference": "9f87189ac10b42edf7fb8edc846f1937c6d157cf", "shasum": "" }, "require": { @@ -8151,20 +8216,20 @@ "debug", "dump" ], - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-02-23T15:17:42+00:00" }, { "name": "symfony/web-profiler-bundle", - "version": "v4.2.2", + "version": "v4.2.4", "source": { "type": "git", "url": "https://github.com/symfony/web-profiler-bundle.git", - "reference": "03ea366e5485089e7f4aeee7386dea07fe655454" + "reference": "30c2fa17ddb2bcea4f4c8cb56427a2374533115f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/03ea366e5485089e7f4aeee7386dea07fe655454", - "reference": "03ea366e5485089e7f4aeee7386dea07fe655454", + "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/30c2fa17ddb2bcea4f4c8cb56427a2374533115f", + "reference": "30c2fa17ddb2bcea4f4c8cb56427a2374533115f", "shasum": "" }, "require": { @@ -8217,7 +8282,7 @@ ], "description": "Symfony WebProfilerBundle", "homepage": "https://symfony.com", - "time": "2019-01-03T09:07:35+00:00" + "time": "2019-02-28T14:59:23+00:00" }, { "name": "theofidry/alice-data-fixtures", @@ -8396,7 +8461,8 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^7.1" + "php": "^7.1", + "ext-json": "*" }, "platform-dev": [] } diff --git a/config/domain/registry/translations/messages.fr.yaml b/config/domain/registry/translations/messages.fr.yaml index a2fec1335517322820519ecb78e1eeeb635a8137..a9da581f39046f726c18e74602d801951062e5b4 100644 --- a/config/domain/registry/translations/messages.fr.yaml +++ b/config/domain/registry/translations/messages.fr.yaml @@ -290,6 +290,7 @@ registry: data_crossing: Croisement de données data_category: Catégorie de données data_category_other: Autres catégories + data_origin: Origine des données delay: Délai de conservation goal: Finalités large_scale_collection: Collecte à large échelle @@ -297,6 +298,7 @@ registry: legal_basis_justification: Justification de la base légale manager: Gestionnaire name: Nom + observation: Observations paper_processing: Traitement papier recipient_category: Catégorie de destinataires security_access_control: Contrôle d'accès @@ -331,6 +333,7 @@ registry: data_crossing: Croisement de données data_category: Catégorie de données data_category_other: Autres catégories + data_origin: Origine des données delay: Délai de conservation goal: Finalités large_scale_collection: Collecte à large échelle @@ -338,6 +341,7 @@ registry: legal_basis_justification: Justification de la base légale manager: Gestionnaire name: Nom + observation: Observations paper_processing: Traitement papier recipient_category: Catégorie de destinataires security_access_control: Contrôle d'accès diff --git a/config/domain/user/translations/messages.fr.yaml b/config/domain/user/translations/messages.fr.yaml index 264d42e76bd6d38c60587e7b175585ac8f765e44..1e1fb00d653775db52cdf653d469a752a95526be 100644 --- a/config/domain/user/translations/messages.fr.yaml +++ b/config/domain/user/translations/messages.fr.yaml @@ -102,6 +102,9 @@ user: form_user: tab: general: Vos informations + optional: Informations facultatives + help: + password: À remplir uniquement si vous souhaitez définir un nouveau mot de passe pour cet utilisateur title: collectivity_edit: Éditer ma collectivité @@ -148,7 +151,7 @@ user: enabled: Actif first_name: Prénom help: - password: A remplir uniquement si vous souhaitez définir un nouveau mot de passe pour cet utilisateur + password: À remplir uniquement si vous souhaitez définir un nouveau mot de passe pour cet utilisateur last_name: Nom password: Mot de passe password_repeat: Répéter le mot de passe diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml index 91169f6640542d7bb9d390ae145c0f1e2952c90f..88bac757c888b430eac74086dc020892eb9d2a49 100644 --- a/config/packages/framework.yaml +++ b/config/packages/framework.yaml @@ -1,5 +1,5 @@ parameters: - app.version: 1.3.1 + app.version: 1.4.0 framework: secret: '%env(APP_SECRET)%' @@ -14,7 +14,7 @@ framework: # Remove or comment this section to explicitly disable session support. session: handler_id: ~ - cookie_lifetime: 14400 # 4 hours in seconds + cookie_lifetime: 5400 # 1.5hours in seconds #esi: true #fragments: true diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml index a1fc040f2c61a0d7d5c403eed4a7cdbc279a4170..96621597bfde29bea1d9e033dd9eeabd660814df 100644 --- a/config/packages/twig.yaml +++ b/config/packages/twig.yaml @@ -5,6 +5,7 @@ twig: form_themes: - 'bootstrap_3_horizontal_layout.html.twig' + - '_Utils/form_theme.html.twig' date: format: d/m/Y H:i @@ -13,6 +14,12 @@ twig: globals: app_name: '%env(APP_APPLICATION_NAME)%' app_version: '%app.version%' + app_footer_provider_name: '%env(APP_FOOTER_PROVIDER_NAME)%' + app_footer_provider_url: '%env(APP_FOOTER_PROVIDER_URL)%' + app_image_favicon_path: '%env(APP_IMAGE_FAVICON_PATH)%' + app_image_sidebar_bottom_target_url: '%env(APP_IMAGE_SIDEBAR_BOTTOM_TARGET_URL)%' + app_image_sidebar_bottom_path: '%env(APP_IMAGE_SIDEBAR_BOTTOM_PATH)%' + app_image_sidebar_reduced_path: '%env(APP_IMAGE_SIDEBAR_REDUCED_PATH)%' default_dpo_civility: '%env(APP_DPO_CIVILITY)%' default_dpo_firstName: '%env(APP_DPO_FIRST_NAME)%' default_dpo_lastName: '%env(APP_DPO_LAST_NAME)%' diff --git a/config/parameters.yaml b/config/parameters.yaml index 4021e2b946ad19cf642b0ac17eb7d6b1b5178990..1ec8d94622df31bd505841dca732d6747fb93dcd 100644 --- a/config/parameters.yaml +++ b/config/parameters.yaml @@ -7,6 +7,7 @@ parameters: # Re declared in order to use ParameterBagInterface in DI APP_DEFAULT_REFERENT: "%env(APP_DEFAULT_REFERENT)%" + # DPO APP_DPO_ADDRESS_CITY: '%env(APP_DPO_ADDRESS_CITY)%' APP_DPO_ADDRESS_STREET: '%env(APP_DPO_ADDRESS_STREET)%' APP_DPO_ADDRESS_ZIP_CODE: '%env(APP_DPO_ADDRESS_ZIP_CODE)%' @@ -18,3 +19,10 @@ parameters: APP_DPO_MAIL: '%env(APP_DPO_MAIL)%' APP_DPO_PHONE_NUMBER: '%env(APP_DPO_PHONE_NUMBER)%' + # PROVIDER & LOGO configuration + APP_FOOTER_PROVIDER_NAME: '%env(APP_FOOTER_PROVIDER_NAME)%' + APP_FOOTER_PROVIDER_URL: '%env(APP_FOOTER_PROVIDER_URL)%' + APP_IMAGE_FAVICON_PATH: '%env(APP_IMAGE_FAVICON_PATH)%' + APP_IMAGE_SIDEBAR_BOTTOM_TARGET_URL: '%env(APP_IMAGE_SIDEBAR_BOTTOM_TARGET_URL)%' + APP_IMAGE_SIDEBAR_BOTTOM_PATH: '%env(APP_IMAGE_SIDEBAR_BOTTOM_PATH)%' + APP_IMAGE_SIDEBAR_REDUCED_PATH: '%env(APP_IMAGE_SIDEBAR_REDUCED_PATH)%' diff --git a/docker-compose.yml b/docker-compose.yml index 12aad2a0b1c323922e8a88eb5fff064c82757b09..5d32b81e7e7336ea197ae688f654517629086707 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,6 +8,7 @@ services: nginx: build: docker/nginx + image: $DOCKER_IMAGE_NGINX container_name: nginx ports: - ${HTTPD_PORT}:8080 @@ -19,6 +20,7 @@ services: php-fpm: build: docker/php-fpm + image: $DOCKER_IMAGE_PHP container_name: php-fpm ports: - ${PHP_FPM_PORT}:9000 diff --git a/docker-service b/docker-service index db4943b79e7ec3ab36afbbf250397ce41bb10e98..9a2df644cb7abcfc0461563a5493ad493c657cb9 100755 --- a/docker-service +++ b/docker-service @@ -5,6 +5,8 @@ set -o errexit # Reset in case getopts has been used previously in the shell. OPTIND=1 +source .env + # Initialize variables env='' @@ -38,7 +40,7 @@ if [ "$env" == '' ]; then # Common operations initialize() { down - build + pullImages start install populate @@ -94,14 +96,14 @@ csFixer() { if [ "$#" -ge 1 ]; then paths="$1" - docker run --rm --user www-data --env-file=.env.test -v ${PWD}/:/var/www/gestion-rgpd/ -w /var/www/gestion-rgpd/ php-fpm bash -c "php -l $paths" + docker run --rm --user www-data --env-file=.env.test -v ${PWD}/:/var/www/gestion-rgpd/ -w /var/www/gestion-rgpd/ $DOCKER_IMAGE_PHP bash -c "php -l $paths" if [ "$#" -eq 2 ]; then config="$2" fi fi - docker run --rm --user www-data --env-file=.env.test -v ${PWD}/:/var/www/gestion-rgpd/ -w /var/www/gestion-rgpd/ php-fpm bash -c "vendor/bin/php-cs-fixer fix --config=$config $paths -vv" + docker run --rm --user www-data --env-file=.env.test -v ${PWD}/:/var/www/gestion-rgpd/ -w /var/www/gestion-rgpd/ $DOCKER_IMAGE_PHP bash -c "vendor/bin/php-cs-fixer fix --config=$config $paths -vv" } # Tests @@ -167,6 +169,29 @@ debug(){ docker-compose -f docker-compose"$env".yml run -T --user=www-data --no-deps --entrypoint="/bin/bash -c" -e XDEBUG_CONFIG="idekey=PHPSTORM" -e PHP_IDE_CONFIG="serverName=localhost" php-fpm "php -dxdebug.remote_host=docker.for.mac.host.internal $@" } +# Images management +pushImages() { + pushImagePhp + pushImageNginx +} + +pushImagePhp() { + docker pull $DOCKER_IMAGE_PHP || true + docker build --cache-from $DOCKER_IMAGE_PHP -t $DOCKER_IMAGE_PHP docker/php-fpm + docker push $DOCKER_IMAGE_PHP +} + +pushImageNginx() { + docker pull $DOCKER_IMAGE_NGINX || true + docker build --cache-from $DOCKER_IMAGE_NGINX -t $DOCKER_IMAGE_NGINX docker/nginx + docker push $DOCKER_IMAGE_NGINX +} + +pullImages() { + docker pull $DOCKER_IMAGE_PHP + docker pull $DOCKER_IMAGE_NGINX +} + # Usage info show_help() { cat << EOF @@ -189,6 +214,10 @@ Commands: unitTests Run unit tests qualityTests Run quality tests functionalTests Run functional tests + pushImages Update registry image + pushImagePhp Update registry php image + pushImageNginx Update registry nginx api image + pullImages Pull latest images from private repository EOF } @@ -255,6 +284,18 @@ case "$1" in csFixer $2 fi ;; + pushImages) + pushImages + ;; + pushImagePhp) + pushImagePhp + ;; + pushImageNginx) + pushImageNginx + ;; + pullImages) + pullImages + ;; *) show_help >&2 exit 1 diff --git a/docker/php-fpm/Dockerfile b/docker/php-fpm/Dockerfile index 99ca12a3cba8ef023e1bb97401b838eea766f935..b8f65954ca67f0700639c553ca1c2b904faa5245 100755 --- a/docker/php-fpm/Dockerfile +++ b/docker/php-fpm/Dockerfile @@ -41,6 +41,10 @@ RUN echo "xdebug.remote_enable=1" >> /etc/php/7.1/fpm/conf.d/20-xdebug.ini \ RUN echo "export PATH=$PATH\":$HOME/bin\"" >> /root/.bashrc +RUN mkdir -p /var/www/gestion-grpd + USER www-data +WORKDIR /var/www/gestion-rgpd + CMD ["/usr/sbin/php-fpm7.1", "-F"] diff --git a/fixtures/2-registry-0-treatmentDataCategory.yaml b/fixtures/2-registry-0-treatmentDataCategory.yaml new file mode 100644 index 0000000000000000000000000000000000000000..74a8a834a7c27a5a791727a9667cf42ee4af2de3 --- /dev/null +++ b/fixtures/2-registry-0-treatmentDataCategory.yaml @@ -0,0 +1,133 @@ +App\Domain\Registry\Model\TreatmentDataCategory: + registry_treatment_data_category_family_situation: + __construct: + - 'family-situation' + - 'Situation familiale' + - 2 + - false + registry_treatment_data_category_filiation: + __construct: + - 'filiation' + - 'Filiation' + - 3 + - false + registry_treatment_data_category_postal: + __construct: + - 'postal' + - 'Coordonnées postales' + - 4 + - false + registry_treatment_data_category_phone: + __construct: + - 'phone' + - 'Coordonnées téléphoniques' + - 5 + - false + registry_treatment_data_category_bank: + __construct: + - 'bank' + - 'Information bancaire' + - 6 + - false + registry_treatment_data_category_bank_situation: + __construct: + - 'bank-situation' + - 'Situation bancaire' + - 7 + - false + registry_treatment_data_category_heritage: + __construct: + - 'heritage' + - 'Patrimoine' + - 8 + - false + registry_treatment_data_category_tax_situation: + __construct: + - 'tax-situation' + - 'Situation fiscale' + - 9 + - false + registry_treatment_data_category_earning: + __construct: + - 'earning' + - 'Revenus' + - 10 + - false + registry_treatment_data_category_email: + __construct: + - 'email' + - 'Emails' + - 11 + - false + registry_treatment_data_category_ip: + __construct: + - 'ip' + - 'Adresse IP' + - 12 + - false + registry_treatment_data_category_connexion: + __construct: + - 'connexion' + - 'Connexion' + - 13 + - false + registry_treatment_data_category_geo: + __construct: + - 'geo' + - 'Géolocalisation' + - 14 + - false + registry_treatment_data_category_caf: + __construct: + - 'caf' + - 'Numéro de CAF' + - 15 + - false + registry_treatment_data_category_health: + __construct: + - 'health' + - 'Santé' + - 16 + - true + registry_treatment_data_category_social_security_number: + __construct: + - 'social-security-number' + - 'Numéro de Sécurité Sociale' + - 17 + - true + registry_treatment_data_category_identity: + __construct: + - 'identity' + - "Pièces d'identité" + - 18 + - false + registry_treatment_data_category_picture: + __construct: + - 'picture' + - 'Photos-vidéos' + - 19 + - false + registry_treatment_data_category_syndicate: + __construct: + - 'syndicate' + - 'Appartenance Syndicale' + - 20 + - true + registry_treatment_data_category_public_religious_opinion: + __construct: + - 'public-religious-opinion' + - 'Opinion politique ou religieuse' + - 21 + - true + registry_treatment_data_category_racial_ethnic_opinion: + __construct: + - 'racial-ethnic_opinion' + - "Origine raciale ou ethnique" + - 22 + - true + registry_treatment_data_category_sex_life: + __construct: + - 'sex-life' + - 'Vie sexuelle' + - 23 + - true diff --git a/fixtures/2-registry-2-treatment.yaml b/fixtures/2-registry-2-treatment.yaml index e6b1df25ad8e0fe77e7423a39fc434923ced07a4..caea765d3c9793f3889a909e4a7ac953e45b96e9 100644 --- a/fixtures/2-registry-2-treatment.yaml +++ b/fixtures/2-registry-2-treatment.yaml @@ -6,8 +6,10 @@ App\Domain\Registry\Model\Treatment: software: '50%? <word()>' legalBasis: '<(App\Domain\Registry\Dictionary\TreatmentLegalBasisDictionary::BASE_LEGAL_OBLIGATION)>' legalBasisJustification: '50%? <text()>' + dataCategories: ['@registry_treatment_data_category_filiation', '@registry_treatment_data_category_social_security_number'] dataCategoryOther: <text()> recipientCategory: <text()> + concernedPeople: ['<(App\Domain\Registry\Dictionary\TreatmentConcernedPeopleDictionary::TYPE_AGENT)>'] contractors: ['@registry_contractor_awkan_1', '@registry_contractor_awkan_3'] active: '80%? 1 : 0' collectivity: '@user_collectivity_awkan' @@ -19,8 +21,10 @@ App\Domain\Registry\Model\Treatment: software: '50%? <word()>' legalBasis: '<(App\Domain\Registry\Dictionary\TreatmentLegalBasisDictionary::BASE_PUBLIC_INTEREST_MISSION)>' legalBasisJustification: '50%? <text()>' + dataCategories: ['@registry_treatment_data_category_health'] dataCategoryOther: <text()> recipientCategory: <text()> + concernedPeople: ['<(App\Domain\Registry\Dictionary\TreatmentConcernedPeopleDictionary::TYPE_AGENT)>'] contractors: ['@registry_contractor_soluris_3'] active: '80%? 1 : 0' collectivity: '@user_collectivity_soluris' diff --git a/src/Application/Controller/CRUDController.php b/src/Application/Controller/CRUDController.php index e5afe668c52f128c7167091bf0ecb4b10be6e6d6..be73bb85f28679975e310a4342dd1da49a8647ea 100644 --- a/src/Application/Controller/CRUDController.php +++ b/src/Application/Controller/CRUDController.php @@ -100,7 +100,7 @@ abstract class CRUDController extends Controller * * @param string $type The flashbag type * @param string|null $template The related template to use - * @param null|mixed $object The object to use to generate flashbag (eg. show object name) + * @param mixed|null $object The object to use to generate flashbag (eg. show object name) * * @return string The generated flashbag */ diff --git a/src/Application/Controller/ControllerHelper.php b/src/Application/Controller/ControllerHelper.php index 94e6907f9382f19ad0ebe5a180f4d79b94026177..b1cc964c6aecfdb01c9623a86603c81141509f4e 100644 --- a/src/Application/Controller/ControllerHelper.php +++ b/src/Application/Controller/ControllerHelper.php @@ -132,7 +132,7 @@ class ControllerHelper * Create a FormType. * * @param string $type The FormType name - * @param null|object $data The data to use to create FormType + * @param object|null $data The data to use to create FormType * @param array $options The FormType options * * @return FormInterface The generated FormType diff --git a/src/Application/Doctrine/Repository/CRUDRepository.php b/src/Application/Doctrine/Repository/CRUDRepository.php index 0c4a90352a427298517519cae8e2a8b39fe23e44..581daa49ec4819f8fb0de5a481041fcee42b2202 100644 --- a/src/Application/Doctrine/Repository/CRUDRepository.php +++ b/src/Application/Doctrine/Repository/CRUDRepository.php @@ -122,7 +122,7 @@ abstract class CRUDRepository implements CRUDRepositoryInterface * * @param string $id The ID to find * - * @return null|object + * @return object|null */ public function findOneById(string $id) { diff --git a/src/Application/Migrations/Version20190303165343.php b/src/Application/Migrations/Version20190303165343.php new file mode 100644 index 0000000000000000000000000000000000000000..ce406d8965e1cbc0a5454b09938b5bbccfc44a53 --- /dev/null +++ b/src/Application/Migrations/Version20190303165343.php @@ -0,0 +1,35 @@ +<?php + +declare(strict_types=1); + +namespace DoctrineMigrations; + +use Doctrine\DBAL\Schema\Schema; +use Doctrine\Migrations\AbstractMigration; + +/** + * Auto-generated Migration: Please modify to your needs! + */ +final class Version20190303165343 extends AbstractMigration +{ + public function getDescription(): string + { + return ''; + } + + public function up(Schema $schema): void + { + // this up() migration is auto-generated, please modify it to your needs + $this->abortIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\'.'); + + $this->addSql('ALTER TABLE registry_treatment ADD data_origin VARCHAR(255) DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->abortIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\'.'); + + $this->addSql('ALTER TABLE registry_treatment DROP data_origin'); + } +} diff --git a/src/Application/Migrations/Version20190303175529.php b/src/Application/Migrations/Version20190303175529.php new file mode 100644 index 0000000000000000000000000000000000000000..22dfa2b41db17be5465ade59bb664707cc077427 --- /dev/null +++ b/src/Application/Migrations/Version20190303175529.php @@ -0,0 +1,35 @@ +<?php + +declare(strict_types=1); + +namespace DoctrineMigrations; + +use Doctrine\DBAL\Schema\Schema; +use Doctrine\Migrations\AbstractMigration; + +/** + * Auto-generated Migration: Please modify to your needs! + */ +final class Version20190303175529 extends AbstractMigration +{ + public function getDescription(): string + { + return ''; + } + + public function up(Schema $schema): void + { + // this up() migration is auto-generated, please modify it to your needs + $this->abortIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\'.'); + + $this->addSql('ALTER TABLE registry_treatment ADD observation LONGTEXT DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->abortIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\'.'); + + $this->addSql('ALTER TABLE registry_treatment DROP observation'); + } +} diff --git a/src/Application/Migrations/Version20190308115517.php b/src/Application/Migrations/Version20190308115517.php new file mode 100644 index 0000000000000000000000000000000000000000..28d4273e35ea88d59e4e210afc9de51c72141fe7 --- /dev/null +++ b/src/Application/Migrations/Version20190308115517.php @@ -0,0 +1,220 @@ +<?php + +declare(strict_types=1); + +namespace DoctrineMigrations; + +use Doctrine\DBAL\Schema\Schema; +use Doctrine\Migrations\AbstractMigration; + +/** + * Auto-generated Migration: Please modify to your needs! + */ +final class Version20190308115517 extends AbstractMigration +{ + public function getDescription(): string + { + return ''; + } + + public function up(Schema $schema): void + { + // this up() migration is auto-generated, please modify it to your needs + $this->abortIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\'.'); + + $this->addSql('CREATE TABLE registry_treatment_data_category (code VARCHAR(50) NOT NULL, name VARCHAR(255) NOT NULL, position INT NOT NULL, sensible TINYINT(1) NOT NULL, PRIMARY KEY(code)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB'); + $this->addSql('CREATE TABLE registry_assoc_treatment_data_category (treatment_id CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', treatment_data_category_code VARCHAR(50) NOT NULL, INDEX IDX_DB9E371A471C0366 (treatment_id), INDEX IDX_DB9E371A6E5DCE39 (treatment_data_category_code), PRIMARY KEY(treatment_id, treatment_data_category_code)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB'); + $this->addSql('ALTER TABLE registry_assoc_treatment_data_category ADD CONSTRAINT FK_DB9E371A471C0366 FOREIGN KEY (treatment_id) REFERENCES registry_treatment (id)'); + $this->addSql('ALTER TABLE registry_assoc_treatment_data_category ADD CONSTRAINT FK_DB9E371A6E5DCE39 FOREIGN KEY (treatment_data_category_code) REFERENCES registry_treatment_data_category (code)'); + + $isDataCategoriesInitialized = false; + + $treatmentResult = $this->connection->query('SELECT id, data_category from registry_treatment')->fetchAll(); + foreach ($treatmentResult as $treatment) { + $categories = \json_decode($treatment['data_category'], true); + + foreach ($categories as $categoryItem) { + if (false === $isDataCategoriesInitialized) { + // Only initialize data if needed for migration (this let eg. fixtures enabling for dev mode) + $this->initializeDataCategories(); + $isDataCategoriesInitialized = true; + } + $this->addSql("INSERT INTO registry_assoc_treatment_data_category(treatment_id, treatment_data_category_code) VALUES ('{$treatment['id']}', '{$categoryItem}')"); + } + } + + $this->addSql('ALTER TABLE registry_treatment DROP data_category'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->abortIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\'.'); + + $this->addSql('ALTER TABLE registry_treatment ADD data_category JSON NOT NULL COMMENT \'(DC2Type:json_array)\''); + + $treatmentResult = $this->connection->query('SELECT id from registry_treatment')->fetchAll(); + foreach ($treatmentResult as $treatment) { + $dataCategories = $this->connection->query("SELECT treatment_data_category_code FROM registry_assoc_treatment_data_category WHERE treatment_id='{$treatment['id']}'")->fetchAll(); + $codes = []; + foreach ($dataCategories as $category) { + $codes[] = $category['treatment_data_category_code']; + } + $encodedCodes = \json_encode($codes); + $this->addSql("UPDATE registry_treatment SET data_category = '$encodedCodes' WHERE id = '{$treatment['id']}'"); + } + + $this->addSql('DROP TABLE registry_assoc_treatment_data_category'); + $this->addSql('DROP TABLE registry_treatment_data_category'); + } + + protected function initializeDataCategories(): void + { + $data = [ + [ + 'code' => 'civility', + 'name' => 'État civil', + 'position' => 1, + 'sensible' => 0, + ], + // Split Etat civil + [ + 'code' => 'family-situation', + 'name' => 'Situation familiale', + 'position' => 3, + 'sensible' => 0, + ], + [ + 'code' => 'filiation', + 'name' => 'Filiation', + 'position' => 4, + 'sensible' => 0, + ], + [ + 'code' => 'postal', + 'name' => 'Coordonnées postales', + 'position' => 5, + 'sensible' => 0, + ], + [ + 'code' => 'phone', + 'name' => 'Coordonnées téléphoniques', + 'position' => 6, + 'sensible' => 0, + ], + [ + 'code' => 'bank', + 'name' => 'Information bancaire', + 'position' => 7, + 'sensible' => 0, + ], + [ + 'code' => 'bank-situation', + 'name' => 'Situation bancaire', + 'position' => 8, + 'sensible' => 0, + ], + [ + 'code' => 'heritage', + 'name' => 'Patrimoine', + 'position' => 9, + 'sensible' => 0, + ], + [ + 'code' => 'tax-situation', + 'name' => 'Situation fiscale', + 'position' => 10, + 'sensible' => 0, + ], + // Situation pro + [ + 'code' => 'earning', + 'name' => 'Revenus', + 'position' => 12, + 'sensible' => 0, + ], + [ + 'code' => 'email', + 'name' => 'Emails', + 'position' => 13, + 'sensible' => 0, + ], + [ + 'code' => 'ip', + 'name' => 'Adresse IP', + 'position' => 14, + 'sensible' => 0, + ], + [ + 'code' => 'connexion', + 'name' => 'Connexion', + 'position' => 15, + 'sensible' => 0, + ], + [ + 'code' => 'geo', + 'name' => 'Géolocalisation', + 'position' => 16, + 'sensible' => 0, + ], + [ + 'code' => 'caf', + 'name' => 'Numéro de CAF', + 'position' => 17, + 'sensible' => 0, + ], + [ + 'code' => 'health', + 'name' => 'Santé', + 'position' => 18, + 'sensible' => 1, + ], + [ + 'code' => 'social-security-number', + 'name' => 'Numéro de Sécurité Sociale', + 'position' => 19, + 'sensible' => 1, + ], + [ + 'code' => 'identity', + 'name' => 'Pièces d’identité', + 'position' => 20, + 'sensible' => 0, + ], + [ + 'code' => 'picture', + 'name' => 'Photos-vidéos', + 'position' => 21, + 'sensible' => 0, + ], + [ + 'code' => 'syndicate', + 'name' => 'Appartenance Syndicale', + 'position' => 22, + 'sensible' => 1, + ], + [ + 'code' => 'public-religious-opinion', + 'name' => 'Opinion politique ou religieuse', + 'position' => 23, + 'sensible' => 1, + ], + [ + 'code' => 'racial-ethnic-opinion', + 'name' => 'Origine raciale ou ethnique', + 'position' => 24, + 'sensible' => 1, + ], + [ + 'code' => 'sex-life', + 'name' => 'Vie sexuelle', + 'position' => 25, + 'sensible' => 1, + ], + ]; + + foreach ($data as $item) { + $this->addSql("INSERT INTO registry_treatment_data_category(code, name, position, sensible) VALUES ('{$item['code']}', '{$item['name']}', {$item['position']}, {$item['sensible']})"); + } + } +} diff --git a/src/Application/Migrations/Version20190308151033.php b/src/Application/Migrations/Version20190308151033.php new file mode 100644 index 0000000000000000000000000000000000000000..fcb99c518be3302cf22adb7aa4a24e95e593ec54 --- /dev/null +++ b/src/Application/Migrations/Version20190308151033.php @@ -0,0 +1,89 @@ +<?php + +declare(strict_types=1); + +namespace DoctrineMigrations; + +use Doctrine\DBAL\Schema\Schema; +use Doctrine\Migrations\AbstractMigration; + +/** + * Auto-generated Migration: Please modify to your needs! + */ +final class Version20190308151033 extends AbstractMigration +{ + public function getDescription(): string + { + return ''; + } + + public function up(Schema $schema): void + { + // this up() migration is auto-generated, please modify it to your needs + $this->abortIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\'.'); + + $existingRows = $this->connection->query("SELECT code FROM registry_treatment_data_category WHERE code = 'civility'")->rowCount(); + + // REPLACE 'civility' BY 'name', 'birth', 'professional-situation' + // Don't transform civility if not exists in database + if (0 === $existingRows) { + return; + } + + $data = [ + [ + 'code' => 'name', + 'name' => 'Nom, Prénom', + 'position' => 1, + 'sensible' => 0, + ], + [ + 'code' => 'birth', + 'name' => 'Date, lieu de naissance', + 'position' => 2, + 'sensible' => 0, + ], + [ + 'code' => 'professional-situation', + 'name' => 'Situation professionnelle', + 'position' => 11, + 'sensible' => 0, + ], + ]; + foreach ($data as $item) { + $this->addSql("INSERT INTO registry_treatment_data_category(code, name, position, sensible) VALUES ('{$item['code']}', '{$item['name']}', {$item['position']}, {$item['sensible']})"); + } + + $rowsToUpdate = $this->connection->query("SELECT treatment_id FROM registry_assoc_treatment_data_category WHERE treatment_data_category_code = 'civility'")->fetchAll(); + foreach ($rowsToUpdate as $row) { + $this->addSql("INSERT INTO registry_assoc_treatment_data_category VALUES ('{$row['treatment_id']}', 'name'), ('{$row['treatment_id']}', 'birth'), ('{$row['treatment_id']}', 'professional-situation')"); + $this->addSql("DELETE FROM registry_assoc_treatment_data_category WHERE treatment_id = '{$row['treatment_id']}' AND treatment_data_category_code = 'civility'"); + } + + $this->addSql("DELETE FROM registry_treatment_data_category WHERE code = 'civility'"); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->abortIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\'.'); + + $existingRows = $this->connection->query("SELECT code FROM registry_treatment_data_category WHERE code in ('name', 'birth', 'professional-situation')")->rowCount(); + + // REPLACE 'name', 'birth', 'professional-situation' BY 'civility' + // Don't transform to civility if their replacement values don't exist in database + if (0 === $existingRows) { + return; + } + + $this->addSql("INSERT INTO registry_treatment_data_category(code, name, position, sensible) VALUES ('civility', 'État civil', 1, 0)"); + + $rowsToUpdate = $this->connection->query("SELECT DISTINCT treatment_id FROM registry_assoc_treatment_data_category WHERE treatment_data_category_code in ('name', 'birth', 'professional-situation')")->fetchAll(); + foreach ($rowsToUpdate as $row) { + $this->addSql("INSERT INTO registry_assoc_treatment_data_category VALUES ('{$row['treatment_id']}', 'civility')"); + $this->addSql("DELETE FROM registry_assoc_treatment_data_category WHERE treatment_id = '{$row['treatment_id']}' AND treatment_data_category_code in ('name', 'birth', 'professional-situation')"); + } + + $this->addSql("DELETE FROM registry_treatment_data_category WHERE code in ('name', 'birth', 'professional-situation')"); + } +} diff --git a/src/Application/Symfony/Security/UserProvider.php b/src/Application/Symfony/Security/UserProvider.php index 18db14df47010d10da80e9d6023626cc1cbda847..3d9af9c124f425a684c817510c7a9223672af35a 100644 --- a/src/Application/Symfony/Security/UserProvider.php +++ b/src/Application/Symfony/Security/UserProvider.php @@ -25,7 +25,7 @@ class UserProvider * - User is anonymous: return null * - User is connected: return UserInterface instance. * - * @return null|UserInterface + * @return UserInterface|null */ public function getAuthenticatedUser(): ?UserInterface { diff --git a/src/Domain/Registry/Calculator/Completion/TreatmentCompletion.php b/src/Domain/Registry/Calculator/Completion/TreatmentCompletion.php index 509636be7857467e7617ad7bce888467c93caa61..36f3def157c951a88d871f8a035c532a9dec20c0 100644 --- a/src/Domain/Registry/Calculator/Completion/TreatmentCompletion.php +++ b/src/Domain/Registry/Calculator/Completion/TreatmentCompletion.php @@ -56,7 +56,7 @@ class TreatmentCompletion extends AbstractCompletion ++$points; } - if (!empty($object->getDataCategory())) { + if (!empty($object->getDataCategories())) { ++$points; } diff --git a/src/Domain/Registry/Dictionary/TreatmentDataCategoryDictionary.php b/src/Domain/Registry/Dictionary/TreatmentDataCategoryDictionary.php deleted file mode 100644 index a351a3db7a1e09981132f86f77243464ac1c7bc1..0000000000000000000000000000000000000000 --- a/src/Domain/Registry/Dictionary/TreatmentDataCategoryDictionary.php +++ /dev/null @@ -1,92 +0,0 @@ -<?php - -/** - * This file is part of the SOLURIS - RGPD Management application. - * - * (c) Donovan Bourlard <donovan@awkan.fr> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -declare(strict_types=1); - -namespace App\Domain\Registry\Dictionary; - -use Knp\DictionaryBundle\Dictionary\SimpleDictionary; - -class TreatmentDataCategoryDictionary extends SimpleDictionary -{ - const CATEGORY_CIVILITY = 'civility'; - const CATEGORY_POSTAL = 'postal'; - const CATEGORY_PHONE = 'phone'; - const CATEGORY_EMAIL = 'email'; - const CATEGORY_IP = 'ip'; - const CATEGORY_GEO = 'geo'; - const CATEGORY_PICTURE = 'picture'; - const CATEGORY_FAMILY_SITUATION = 'family-situation'; - const CATEGORY_FILIATION = 'filiation'; - const CATEGORY_HEALTH = 'health'; - const CATEGORY_SOCIAL_NUM = 'social-security-number'; - const CATEGORY_CAF_NUM = 'caf'; - const CATEGORY_SYNDICATE = 'syndicate'; - const CATEGORY_CONNEXION = 'connexion'; - const CATEGORY_BANK = 'bank'; - const CATEGORY_HERITAGE = 'heritage'; - const CATEGORY_EARNING = 'earning'; - const CATEGORY_TAX_SITUATION = 'tax-situation'; - const CATEGORY_BANK_SITUATION = 'bank-situation'; - const CATEGORY_IDENTITY = 'identity'; - const CATEGORY_PUBLIC_RELIGIOUS_OPINION = 'public-religious-opinion'; - const CATEGORY_RACIAL_ETHNIC_OPINION = 'racial-ethnic-opinion'; - const CATEGORY_SEX_LIFE = 'sex-life'; - - public function __construct() - { - parent::__construct('registry_treatment_data_category', self::getCategories()); - } - - /** - * Get an array of Basis. - * - * @return array - */ - public static function getCategories() - { - return [ - self::CATEGORY_CIVILITY => 'État civil', - self::CATEGORY_POSTAL => 'Coordonnées postales', - self::CATEGORY_PHONE => 'Coordonnées téléphoniques', - self::CATEGORY_EMAIL => 'Emails', - self::CATEGORY_IP => 'Adresse IP', - self::CATEGORY_GEO => 'Géolocalisation', - self::CATEGORY_PICTURE => 'Photos-vidéos', - self::CATEGORY_FAMILY_SITUATION => 'Situation familiale', - self::CATEGORY_FILIATION => 'Filiation', - self::CATEGORY_HEALTH => 'Santé', - self::CATEGORY_SOCIAL_NUM => 'Numéro de Sécurité Sociale', - self::CATEGORY_CAF_NUM => 'Numéro de CAF', - self::CATEGORY_SYNDICATE => 'Appartenance Syndicale', - self::CATEGORY_CONNEXION => 'Connexion', - self::CATEGORY_BANK => 'Information bancaire', - self::CATEGORY_HERITAGE => 'Patrimoine', - self::CATEGORY_EARNING => 'Revenus', - self::CATEGORY_TAX_SITUATION => 'Situation fiscale', - self::CATEGORY_BANK_SITUATION => 'Situation bancaire', - self::CATEGORY_IDENTITY => 'Pièces d’identité', - self::CATEGORY_PUBLIC_RELIGIOUS_OPINION => 'Opinion politique ou religieuse', - self::CATEGORY_RACIAL_ETHNIC_OPINION => 'Origine raciale ou ethnique', - self::CATEGORY_SEX_LIFE => 'Vie sexuelle', - ]; - } - - /** - * Get keys of the Basis array. - * - * @return array - */ - public static function getCategoryKeys() - { - return \array_keys(self::getCategories()); - } -} diff --git a/src/Domain/Registry/Form/Type/TreatmentType.php b/src/Domain/Registry/Form/Type/TreatmentType.php index bb9d56918fe863495bae18b9aa04939812b35549..73e4a3ed32137f9dd55069d492833d8a6e2b29a4 100644 --- a/src/Domain/Registry/Form/Type/TreatmentType.php +++ b/src/Domain/Registry/Form/Type/TreatmentType.php @@ -18,6 +18,8 @@ use App\Domain\Registry\Form\Type\Embeddable\ComplexChoiceType; use App\Domain\Registry\Form\Type\Embeddable\DelayType; use App\Domain\Registry\Model\Contractor; use App\Domain\Registry\Model\Treatment; +use App\Domain\Registry\Model\TreatmentDataCategory; +use Doctrine\Common\Collections\Criteria; use Doctrine\ORM\EntityRepository; use Knp\DictionaryBundle\Form\Type\DictionaryType; use Symfony\Bridge\Doctrine\Form\Type\EntityType; @@ -78,6 +80,13 @@ class TreatmentType extends AbstractType 'label' => 'registry.treatment.form.legal_basis_justification', 'required' => false, ]) + ->add('observation', TextareaType::class, [ + 'label' => 'registry.treatment.form.observation', + 'required' => false, + 'attr' => [ + 'rows' => 2, + ], + ]) ->add('concernedPeople', DictionaryType::class, [ 'label' => 'registry.treatment.form.concerned_people', 'name' => 'registry_treatment_concerned_people', @@ -85,12 +94,28 @@ class TreatmentType extends AbstractType 'expanded' => true, 'multiple' => true, ]) - ->add('dataCategory', DictionaryType::class, [ - 'label' => 'registry.treatment.form.data_category', - 'name' => 'registry_treatment_data_category', - 'required' => false, - 'expanded' => false, - 'multiple' => true, + ->add('dataCategories', EntityType::class, [ + 'label' => 'registry.treatment.form.data_category', + 'class' => TreatmentDataCategory::class, + 'required' => false, + 'expanded' => false, + 'multiple' => true, + 'query_builder' => function (EntityRepository $er) { + return $er->createQueryBuilder('dc') + ->orderBy('dc.position', Criteria::ASC); + }, + 'choice_attr' => function (TreatmentDataCategory $model) { + if ($model->isSensible()) { + return [ + 'style' => 'font-weight: bold;', + ]; + } + + return []; + }, + 'attr' => [ + 'size' => 6, + ], ]) ->add('dataCategoryOther', TextareaType::class, [ 'label' => 'registry.treatment.form.data_category_other', @@ -99,6 +124,10 @@ class TreatmentType extends AbstractType 'rows' => 3, ], ]) + ->add('dataOrigin', TextType::class, [ + 'label' => 'registry.treatment.form.data_origin', + 'required' => false, + ]) ->add('recipientCategory', TextareaType::class, [ 'label' => 'registry.treatment.form.recipient_category', 'required' => false, diff --git a/src/Domain/Registry/Model/Treatment.php b/src/Domain/Registry/Model/Treatment.php index 4b47d064decd51be286fa71cd05136227979b3bc..58d465d2a61ac606e6b65ea2a2f2deabc30cbaa6 100644 --- a/src/Domain/Registry/Model/Treatment.php +++ b/src/Domain/Registry/Model/Treatment.php @@ -77,10 +77,15 @@ class Treatment /** * FR: Justification de la base légale. * - * @var string + * @var string|null */ private $legalBasisJustification; + /** + * @var string|null + */ + private $observation; + /** * FR: Personnes concernées. * @@ -89,11 +94,9 @@ class Treatment private $concernedPeople; /** - * FR: Catégories de données. - * - * @var array + * @var iterable */ - private $dataCategory; + private $dataCategories; /** * FR: Autres catégories. @@ -102,6 +105,13 @@ class Treatment */ private $dataCategoryOther; + /** + * FR: Origine des données. + * + * @var string|null + */ + private $dataOrigin; + /** * FR: Destinataire des données. * @@ -209,7 +219,7 @@ class Treatment $this->id = Uuid::uuid4(); $this->paperProcessing = false; $this->concernedPeople = []; - $this->dataCategory = []; + $this->dataCategories = []; $this->contractors = new ArrayCollection(); $this->delay = new Delay(); $this->securityAccessControl = new ComplexChoice(); @@ -359,6 +369,22 @@ class Treatment $this->legalBasisJustification = $legalBasisJustification; } + /** + * @return string|null + */ + public function getObservation(): ?string + { + return $this->observation; + } + + /** + * @param string|null $observation + */ + public function setObservation(?string $observation): void + { + $this->observation = $observation; + } + /** * @return array */ @@ -376,19 +402,19 @@ class Treatment } /** - * @return array + * @return iterable */ - public function getDataCategory(): array + public function getDataCategories(): iterable { - return $this->dataCategory; + return $this->dataCategories; } /** - * @param array $dataCategory + * @param iterable $dataCategories */ - public function setDataCategory(array $dataCategory): void + public function setDataCategories(iterable $dataCategories): void { - $this->dataCategory = $dataCategory; + $this->dataCategories = $dataCategories; } /** @@ -407,6 +433,22 @@ class Treatment $this->dataCategoryOther = $dataCategoryOther; } + /** + * @return string|null + */ + public function getDataOrigin(): ?string + { + return $this->dataOrigin; + } + + /** + * @param string|null $dataOrigin + */ + public function setDataOrigin(?string $dataOrigin): void + { + $this->dataOrigin = $dataOrigin; + } + /** * @return string|null */ diff --git a/src/Domain/Registry/Model/TreatmentDataCategory.php b/src/Domain/Registry/Model/TreatmentDataCategory.php new file mode 100644 index 0000000000000000000000000000000000000000..3c41062843e649cd116c812cd701bff3886b797e --- /dev/null +++ b/src/Domain/Registry/Model/TreatmentDataCategory.php @@ -0,0 +1,76 @@ +<?php + +declare(strict_types=1); + +namespace App\Domain\Registry\Model; + +class TreatmentDataCategory +{ + /** + * @var string + */ + private $code; + + /** + * @var string + */ + private $name; + + /** + * @var int + */ + private $position; + + /** + * @var bool + */ + private $sensible; + + public function __construct(string $code, string $name, int $position, bool $sensible = false) + { + $this->code = $code; + $this->name = $name; + $this->position = $position; + $this->sensible = $sensible; + } + + /** + * @return string + */ + public function __toString(): string + { + return $this->name; + } + + /** + * @return string + */ + public function getCode(): string + { + return $this->code; + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * @return int + */ + public function getPosition(): int + { + return $this->position; + } + + /** + * @return bool + */ + public function isSensible(): bool + { + return $this->sensible; + } +} diff --git a/src/Domain/Reporting/Generator/Word/AbstractGenerator.php b/src/Domain/Reporting/Generator/Word/AbstractGenerator.php index 2f7566d81fb6ea8e619ac960b99db1a5771518dc..4ee410e2b19341a8dfefe3e47b954bba86bd2885 100644 --- a/src/Domain/Reporting/Generator/Word/AbstractGenerator.php +++ b/src/Domain/Reporting/Generator/Word/AbstractGenerator.php @@ -353,7 +353,18 @@ abstract class AbstractGenerator implements GeneratorInterface if (0 != $key) { $textrun->addTextBreak(); } - $textrun->addText($item); + + // If item is simple text, there is no other configuration + if (!\is_array($item)) { + $textrun->addText($item); + continue; + } + + // If item is array, then there is specific contiguration + $textrun->addText( + $item['text'] ?? '', + $item['style'] ?? [] + ); } } } diff --git a/src/Domain/Reporting/Generator/Word/TreatmentGenerator.php b/src/Domain/Reporting/Generator/Word/TreatmentGenerator.php index 795ea774b9581a193b40395ba1f282476a0b264d..67c042b461eddb28597d15c1a7e1d9388c08d3f0 100644 --- a/src/Domain/Reporting/Generator/Word/TreatmentGenerator.php +++ b/src/Domain/Reporting/Generator/Word/TreatmentGenerator.php @@ -13,8 +13,8 @@ declare(strict_types=1); namespace App\Domain\Reporting\Generator\Word; +use App\Domain\Registry\Dictionary\DelayPeriodDictionary; use App\Domain\Registry\Dictionary\TreatmentConcernedPeopleDictionary; -use App\Domain\Registry\Dictionary\TreatmentDataCategoryDictionary; use App\Domain\Registry\Dictionary\TreatmentLegalBasisDictionary; use PhpOffice\PhpWord\Element\Section; use PhpOffice\PhpWord\Shared\Converter; @@ -208,28 +208,45 @@ class TreatmentGenerator extends AbstractGenerator implements ImpressionGenerato 'Justification de la base légale', $treatment->getLegalBasisJustification() ? \preg_split('/\R/', $treatment->getLegalBasisJustification()) : null, ], + [ + 'Observations', + $treatment->getObservation() ? \preg_split('/\R/', $treatment->getObservation()) : null, + ], ]; $detailsData = [ - [ + 0 => [ 'Personnes référentes', // Values are added below ], - [ + 1 => [ 'Logiciel', \is_string($treatment->getSoftware()) ? $treatment->getSoftware() : null, ], - [ + 2 => [ 'Gestion papier', $treatment->isPaperProcessing() ? 'Oui' : 'Non', ], - [ + 3 => [ 'Délai de conservation', - $treatment->getDelay()->getComment() - ? \preg_split('/\R/', $treatment->getDelay()->getComment()) - : "{$treatment->getDelay()->getNumber()} {$treatment->getDelay()->getPeriod()}", + // Defined below + ], + 4 => [ + 'Origine des données', + $treatment->getDataOrigin(), ], ]; + + // "Délai de conservation" + $delayContent = ''; + if (null !== $treatment->getDelay()->getComment()) { + $delayContent = $treatment->getDelay()->getComment(); + } elseif (null !== $treatment->getDelay()->getPeriod()) { + $period = DelayPeriodDictionary::getPeriods()[$treatment->getDelay()->getPeriod()]; + $delayContent = "{$treatment->getDelay()->getNumber()} {$period}"; + } + $detailsData[3][] = $delayContent; + // Add Concerned people $concernedPeople = []; foreach ($treatment->getConcernedPeople() as $people) { @@ -249,8 +266,13 @@ class TreatmentGenerator extends AbstractGenerator implements ImpressionGenerato ]; // Add data categories $dataCategories = []; - foreach ($treatment->getDataCategory() as $category) { - $dataCategories[] = TreatmentDataCategoryDictionary::getCategories()[$category]; + foreach ($treatment->getDataCategories() as $category) { + $dataCategories[] = [ + 'text' => $category->getName(), + 'style' => [ + 'bold' => $category->isSensible() ? true : false, + ], + ]; } $categoryData[0][] = $dataCategories; diff --git a/src/Domain/User/Form/Type/UserType.php b/src/Domain/User/Form/Type/UserType.php index 11a73beb4a6d717aeaeccbc04cc4af67c67da2c6..2c2782d963384a0de7fd1bcb05af1b097570170f 100644 --- a/src/Domain/User/Form/Type/UserType.php +++ b/src/Domain/User/Form/Type/UserType.php @@ -26,8 +26,11 @@ use Symfony\Component\Form\Extension\Core\Type\PasswordType; use Symfony\Component\Form\Extension\Core\Type\RepeatedType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\Form\FormEvent; +use Symfony\Component\Form\FormEvents; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; +use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface; class UserType extends AbstractType { @@ -36,26 +39,26 @@ class UserType extends AbstractType */ private $authorizationChecker; - public function __construct(AuthorizationCheckerInterface $authorizationChecker) - { + /** + * @var EncoderFactoryInterface + */ + private $encoderFactory; + + public function __construct( + AuthorizationCheckerInterface $authorizationChecker, + EncoderFactoryInterface $encoderFactory + ) { $this->authorizationChecker = $authorizationChecker; + $this->encoderFactory = $encoderFactory; } public function buildForm(FormBuilderInterface $builder, array $options) { + $encoderFactory = $this->encoderFactory; + // Add collectivity general information only for admins if ($this->authorizationChecker->isGranted('ROLE_ADMIN')) { $builder - ->add('plainPassword', RepeatedType::class, [ - 'type' => PasswordType::class, - 'first_options' => [ - 'label' => 'user.user.form.password', - ], - 'second_options' => [ - 'label' => 'user.user.form.password_repeat', - ], - 'required' => false, - ]) ->add('collectivity', EntityType::class, [ 'class' => Collectivity::class, 'label' => 'user.user.form.collectivity', @@ -98,7 +101,28 @@ class UserType extends AbstractType 'label' => 'user.user.form.email', 'required' => true, ]) + ->add('plainPassword', RepeatedType::class, [ + 'type' => PasswordType::class, + 'first_options' => [ + 'label' => 'user.user.form.password', + ], + 'second_options' => [ + 'label' => 'user.user.form.password_repeat', + ], + 'required' => false, + ]) ; + + $builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) use ($encoderFactory) { + $user = $event->getData(); + if (null === $user->getPlainPassword()) { + return; + } + + $encoder = $encoderFactory->getEncoder($user); + $user->setPassword($encoder->encodePassword($user->getPlainPassword(), '')); // No salt with bcrypt + $user->eraseCredentials(); + }); } public function configureOptions(OptionsResolver $resolver) diff --git a/src/Domain/User/Symfony/EventSubscriber/DefinePasswordSubscriber.php b/src/Domain/User/Symfony/EventSubscriber/DefinePasswordSubscriber.php index a4e93fa40db17c8c810a452ad1a58543ed7b803f..5e70a0031ac7285d8f0fa18e0e196d9a305a4ba2 100644 --- a/src/Domain/User/Symfony/EventSubscriber/DefinePasswordSubscriber.php +++ b/src/Domain/User/Symfony/EventSubscriber/DefinePasswordSubscriber.php @@ -54,7 +54,7 @@ class DefinePasswordSubscriber implements EventSubscriber } // No password is set, randomize one - if (\is_null($model->getPlainPassword())) { + if (\is_null($model->getPlainPassword()) && \is_null($model->getPassword())) { $model->setPlainPassword($this->tokenGenerator->generateToken()); } } diff --git a/src/Domain/User/Symfony/EventSubscriber/EncodePasswordSubscriber.php b/src/Domain/User/Symfony/EventSubscriber/EncodePasswordSubscriber.php index adeb6ee60b371b9a448f27dcdc09e95eec1fb81d..20d25758ba4fa46d69773bc82c5af2f24983b378 100644 --- a/src/Domain/User/Symfony/EventSubscriber/EncodePasswordSubscriber.php +++ b/src/Domain/User/Symfony/EventSubscriber/EncodePasswordSubscriber.php @@ -52,7 +52,7 @@ class EncodePasswordSubscriber implements EventSubscriber return; } - $this->process($args); + $this->encodePassword($args); } /** @@ -69,7 +69,7 @@ class EncodePasswordSubscriber implements EventSubscriber return; } - $this->process($args); + $this->encodePassword($args); } /** @@ -77,13 +77,14 @@ class EncodePasswordSubscriber implements EventSubscriber * * @param LifecycleEventArgs $args */ - private function process(LifecycleEventArgs $args): void + public function encodePassword(LifecycleEventArgs $args): void { - /** - * @var User - */ $model = $args->getObject(); + if (!$model instanceof User) { + return; + } + if (\is_null($model->getPlainPassword())) { return; } diff --git a/src/Infrastructure/ORM/Registry/Mapping/Treatment.orm.xml b/src/Infrastructure/ORM/Registry/Mapping/Treatment.orm.xml index d67f0b9ee11743585a5b57c65b673af7ed68c45a..de1dc1758ecea1838b46bef9806285f57cc9744b 100644 --- a/src/Infrastructure/ORM/Registry/Mapping/Treatment.orm.xml +++ b/src/Infrastructure/ORM/Registry/Mapping/Treatment.orm.xml @@ -17,9 +17,10 @@ <field name="paperProcessing" column="paper_processing" type="boolean"/> <field name="legalBasis" column="legal_basis" type="json_array"/> <field name="legalBasisJustification" column="legal_basis_justification" type="text" nullable="true"/> + <field name="observation" column="observation" type="text" nullable="true"/> <field name="concernedPeople" column="concerned_people" type="json_array"/> - <field name="dataCategory" column="data_category" type="json_array"/> <field name="dataCategoryOther" column="data_category_other" type="text" nullable="true"/> + <field name="dataOrigin" column="data_origin" nullable="true"/> <field name="recipientCategory" column="recipient_category" type="text" nullable="true"/> <field name="systematicMonitoring" column="systematic_monitoring" type="boolean"/> <field name="largeScaleCollection" column="large_scale_collection" type="boolean"/> @@ -47,7 +48,20 @@ </inverse-join-columns> </join-table> <order-by> - <order-by-field name="name" direction="ASC"/> + <order-by-field name="name"/> + </order-by> + </many-to-many> + <many-to-many field="dataCategories" target-entity="App\Domain\Registry\Model\TreatmentDataCategory"> + <join-table name="registry_assoc_treatment_data_category"> + <join-columns> + <join-column/> + </join-columns> + <inverse-join-columns> + <join-column referenced-column-name="code"/> + </inverse-join-columns> + </join-table> + <order-by> + <order-by-field name="position" direction="ASC"/> </order-by> </many-to-many> diff --git a/src/Infrastructure/ORM/Registry/Mapping/TreatmentDataCategory.orm.xml b/src/Infrastructure/ORM/Registry/Mapping/TreatmentDataCategory.orm.xml new file mode 100644 index 0000000000000000000000000000000000000000..960bc87808724df35cc56f6849b70d6a9f02ddb1 --- /dev/null +++ b/src/Infrastructure/ORM/Registry/Mapping/TreatmentDataCategory.orm.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" ?> +<doctrine-mapping + xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping + https://raw.github.com/doctrine/doctrine2/master/doctrine-mapping.xsd"> + + <entity name="App\Domain\Registry\Model\TreatmentDataCategory" table="registry_treatment_data_category"> + + <id name="code" column="code" length="50"/> + + <field name="name" column="name"/> + <field name="position" column="position" type="integer"/> + <field name="sensible" column="sensible" type="boolean"/> + + </entity> + +</doctrine-mapping> diff --git a/src/Infrastructure/ORM/Registry/Repository/Proof.php b/src/Infrastructure/ORM/Registry/Repository/Proof.php index 05866ac2ccd7ababf1c3f7c0c622eb5925159d82..4513b4f3680246fd4f583ba144ad48900a0332b5 100644 --- a/src/Infrastructure/ORM/Registry/Repository/Proof.php +++ b/src/Infrastructure/ORM/Registry/Repository/Proof.php @@ -111,7 +111,7 @@ class Proof implements Repository\Proof * * @param string $id The ID to find * - * @return null|object + * @return object|null */ public function findOneById(string $id) { diff --git a/src/Infrastructure/ORM/Registry/Repository/Request.php b/src/Infrastructure/ORM/Registry/Repository/Request.php index 44d6759045cd6ecaa8afeb68c604797c40416dc8..e60761fcbc57001d5b24e1038ac711c543665f6e 100644 --- a/src/Infrastructure/ORM/Registry/Repository/Request.php +++ b/src/Infrastructure/ORM/Registry/Repository/Request.php @@ -111,7 +111,7 @@ class Request implements Repository\Request * * @param string $id The ID to find * - * @return null|object + * @return object|null */ public function findOneById(string $id) { diff --git a/src/Infrastructure/ORM/Registry/Repository/Violation.php b/src/Infrastructure/ORM/Registry/Repository/Violation.php index 3bbee1fadfa92b14addd88428859a85d53d2c22e..93466cf269ab5ad40ed55d662f84eb6455f66114 100644 --- a/src/Infrastructure/ORM/Registry/Repository/Violation.php +++ b/src/Infrastructure/ORM/Registry/Repository/Violation.php @@ -111,7 +111,7 @@ class Violation implements Repository\Violation * * @param string $id The ID to find * - * @return null|object + * @return object|null */ public function findOneById(string $id) { diff --git a/symfony.lock b/symfony.lock index 240c6dc1699d11d5c11014984be1e6261610ee8c..9633ae24211d77c4a5b31f6a784e53a096758883 100644 --- a/symfony.lock +++ b/symfony.lock @@ -434,6 +434,9 @@ "symfony/polyfill-intl-icu": { "version": "v1.8.0" }, + "symfony/polyfill-intl-idn": { + "version": "v1.10.0" + }, "symfony/polyfill-mbstring": { "version": "v1.8.0" }, diff --git a/templates/Registry/Treatment/_form.html.twig b/templates/Registry/Treatment/_form.html.twig index c405c92acd6964afb56b4e0fabcb619b80bcf137..b02d87082b3c297cea3e091e3a6212ca0ac338ad 100644 --- a/templates/Registry/Treatment/_form.html.twig +++ b/templates/Registry/Treatment/_form.html.twig @@ -24,6 +24,7 @@ {{ form_row(form.active) }} {{ form_row(form.legalBasis) }} {{ form_row(form.legalBasisJustification) }} + {{ form_row(form.observation) }} </div> </div> @@ -31,7 +32,7 @@ <div class="box box-solid box-warning"> <div class="box-header with-border"><h3 class="box-title">{{ 'registry.treatment.tab.data_category'|trans }}</h3></div> <div class="box-body"> - {{ form_row(form.dataCategory) }} + {{ form_row(form.dataCategories) }} {{ form_row(form.dataCategoryOther) }} </div> </div> @@ -55,14 +56,17 @@ {{ form_row(form.software) }} {{ form_row(form.paperProcessing) }} <div class="delay-group"> - <div class="one-line"> - <div>{{ form_label(form.delay) }}</div> - <div>{{ form_row(form.delay.number) }}</div> - <div>{{ form_row(form.delay.period) }}</div> + <div class="form-group" style="margin-bottom: 0;"> + {{ form_label(form.delay) }} + <div class="col-sm-10 one-line"> + <div>{{ form_widget(form.delay.number) }}</div> + <div>{{ form_widget(form.delay.period) }}</div> + </div> </div> - {{ form_row(form.delay.otherDelay) }} - {{ form_row(form.delay.comment) }} + <div>{{ form_row(form.delay.otherDelay) }}</div> + <div>{{ form_row(form.delay.comment) }}</div> </div> + {{ form_row(form.dataOrigin) }} </div> </div> diff --git a/templates/Registry/Treatment/show.html.twig b/templates/Registry/Treatment/show.html.twig index f0b6418a2c8400760723a6b9590e6bc765223070..ae9678ab3f3e270d283e373237dd9acc1bdeca9e 100644 --- a/templates/Registry/Treatment/show.html.twig +++ b/templates/Registry/Treatment/show.html.twig @@ -78,6 +78,10 @@ <td><strong>{{ 'registry.treatment.show.legal_basis_justification'|trans }}</strong></td> <td>{{ object.legalBasisJustification|nl2br }}</td> </tr> + <tr> + <td><strong>{{ 'registry.treatment.show.observation'|trans }}</strong></td> + <td>{{ object.observation|nl2br }}</td> + </tr> </tbody> </table> </div> @@ -93,8 +97,12 @@ <td><strong>{{ 'registry.treatment.show.data_category'|trans }}</strong></td> <td> <ul> - {% for category in object.dataCategory %} - <li>{{ category|dictionary('registry_treatment_data_category') }}</li> + {% for category in object.dataCategories %} + <li> + {% if category.sensible %}<strong>{% endif %} + {{ category.name }} + {% if category.sensible %}</strong>{% endif %} + </li> {% endfor %} </ul> </td> @@ -206,9 +214,15 @@ <td> {% if object.delay.number and object.delay.period %} {{ object.delay.number }} {{ object.delay.period|dictionary('registry_delay_period') }} + {% elseif object.delay.otherDelay %} + {{ object.delay.comment }} {% endif %} </td> </tr> + <tr> + <td><strong>{{ 'registry.treatment.show.data_origin'|trans }}</strong></td> + <td>{{ object.dataOrigin }}</td> + </tr> </table> </div> </div> diff --git a/templates/Registry/Violation/show.html.twig b/templates/Registry/Violation/show.html.twig index 4ece381ec2d289c75d273b88f901c80c4cd02db0..c1f1d3c552def713fac8433a5c80cae0bc3dd051 100644 --- a/templates/Registry/Violation/show.html.twig +++ b/templates/Registry/Violation/show.html.twig @@ -186,7 +186,11 @@ </tr> <tr> <td><strong>{{ 'registry.violation.show.notification'|trans }}</strong></td> - <td>{{ object.notification|dictionary('registry_violation_notification') }}</td> + <td> + {% if object.notification %} + {{ object.notification|dictionary('registry_violation_notification') }} + {% endif %} + </td> </tr> <tr> <td><strong>{{ 'registry.violation.show.notification_details'|trans }}</strong></td> diff --git a/templates/User/Profile/user_edit.html.twig b/templates/User/Profile/user_edit.html.twig index 3263677b9eb708eb9dbd07e9ad0f788fac33f54e..2a49870ade1a46dacc374820dfbd83eb507c7d03 100644 --- a/templates/User/Profile/user_edit.html.twig +++ b/templates/User/Profile/user_edit.html.twig @@ -22,8 +22,14 @@ {% endblock %} {% block body %} + <div class="row"> + {{ form_start(form) }} + + {# LEFT #} <div class="col-md-6"> + + {# General #} <div class="box box-solid box-primary"> <div class="box-header">{{ 'user.profile.form_user.tab.general'|trans }}</div> {{ form_start(form) }} @@ -33,9 +39,23 @@ {{ form_row(form.email) }} </div> </div> + + {# Reset password #} + <div class="box box-solid box-danger"> + <div class="box-header"><h3 class="box-title">{{ 'user.profile.form_user.tab.optional'|trans }}</h3></div> + <div class="box-body"> + <blockquote> + <small>{{ 'user.user.form.help.password'|trans }}</small> + </blockquote> + {{ form_row(form.plainPassword) }} + </div> + </div> </div> + {# RIGHT #} <div class="col-md-6"> + + {# Information #} <div class="box box-solid box-primary"> <div class="box-header">{{ 'label.for_your_information'|trans }}</div> <div class="box-body"> @@ -49,13 +69,18 @@ </div> </div> </div> - </div> - <div class="row"></div> - <div class="box box-solid"> - <div class="box-body text-center"> - <input type="submit" class="btn btn-primary" value="{{ submitValue }}"> + <div class="col-md-12"> + <div class="box box-solid"> + <div class="box-body text-center"> + <a href="{{ path('registry_contractor_list') }}" class="btn btn-default"> + {{ 'registry.contractor.action.back_to_list'|trans }} + </a> + <input type="submit" class="btn btn-primary" value="{{ submitValue }}"> + </div> + </div> </div> + {{ form_end(form) }} </div> {% endblock %} diff --git a/templates/User/Security/base.html.twig b/templates/User/Security/base.html.twig index 12b324ccf33f95d54795722ada8f7e1c6de7461a..0b6aaeb9e3d6d57f556d0c0b99226229450cf3d6 100644 --- a/templates/User/Security/base.html.twig +++ b/templates/User/Security/base.html.twig @@ -20,6 +20,8 @@ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/admin-lte/2.4.3/css/skins/_all-skins.min.css"> + <link rel="stylesheet" href="{{ asset('build/css/app.css') }}"> + {% block stylesheets %}{% endblock %} <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> @@ -37,5 +39,6 @@ <div class="login-box"> {% block body %}{% endblock %} </div> +<script src="{{ asset('build/js/app.js') }}"></script> </body> </html> diff --git a/templates/User/Security/login.html.twig b/templates/User/Security/login.html.twig index 01c0b5d596f8040e7c2e441253fe339ecab6940f..b9a529146506c731d84c34e2f0a838dbbc26c820 100644 --- a/templates/User/Security/login.html.twig +++ b/templates/User/Security/login.html.twig @@ -18,13 +18,12 @@ {% endif %} {{ include('_flashbag.html.twig') }} - <div class="form-group has-feedback"> + <div class="form-group"> <input type="email" id="username" name="_username" class="form-control" placeholder="{{ 'user.security.login.username'|trans }}" value="{{ last_username }}" /> - <span class="glyphicon glyphicon-envelope form-control-feedback"></span> </div> <div class="form-group has-feedback"> <input type="password" id="password" name="_password" class="form-control" placeholder="{{ 'user.security.login.password'|trans }}" /> - <span class="glyphicon glyphicon-lock form-control-feedback"></span> + <span class="glyphicon glyphicon-eye-open form-control-feedback"></span> </div> <div class="form-group has-feedback text-center"> diff --git a/templates/User/User/_form.html.twig b/templates/User/User/_form.html.twig index 23d798d94b327b7c28bc0c8c0203f32a3b90717b..ae9563dcace0592836d3b0e8177e8c5dd05a1da4 100644 --- a/templates/User/User/_form.html.twig +++ b/templates/User/User/_form.html.twig @@ -1,36 +1,46 @@ {% set submitValue = submitValue|default('action.submit'|trans) %} -<div class="box box-solid box-primary"> - <div class="box-header">{{ 'user.user.tab.general'|trans }}</div> +<div class="row"> {{ form_start(form) }} - <div class="box-body"> - {{ form_row(form.firstName) }} - {{ form_row(form.lastName) }} - {{ form_row(form.email) }} - {{ form_row(form.collectivity) }} - {{ form_row(form.roles) }} - {{ form_row(form.enabled) }} + + {# LEFT #} + <div class="col-md-6"> + <div class="box box-solid box-primary"> + <div class="box-header with-border"><h3 class="box-title">{{ 'user.user.tab.general'|trans }}</h3></div> + <div class="box-body"> + {{ form_row(form.firstName) }} + {{ form_row(form.lastName) }} + {{ form_row(form.email) }} + {{ form_row(form.collectivity) }} + {{ form_row(form.roles) }} + {{ form_row(form.enabled) }} + </div> + </div> </div> -</div> -<div class="box box-solid box-danger"> - <div class="box-header">{{ 'user.user.tab.optional'|trans }}</div> - <div class="box-body"> - <blockquote> - <small>{{ 'user.user.form.help.password'|trans }}</small> - </blockquote> - {{ form_row(form.plainPassword) }} + {# RIGHT #} + <div class="col-md-6"> + <div class="box box-solid box-danger"> + <div class="box-header with-border"><h3 class="box-title">{{ 'user.user.tab.optional'|trans }}</h3></div> + <div class="box-body"> + <blockquote> + <small>{{ 'user.user.form.help.password'|trans }}</small> + </blockquote> + {{ form_row(form.plainPassword) }} + </div> + </div> </div> -</div> -<div class="box box-solid"> - <div class="box-body text-center"> - <a href="{{ path('user_user_list') }}" class="btn btn-default"> - {{ 'user.user.action.back_to_list'|trans }} - </a> - <input type="submit" class="btn btn-primary" value="{{ submitValue }}"> + <div class="col-md-12"> + <div class="box box-solid"> + <div class="box-body text-center"> + <a href="{{ path('user_user_list') }}" class="btn btn-default"> + {{ 'user.user.action.back_to_list'|trans }} + </a> + <input type="submit" class="btn btn-primary" value="{{ submitValue }}"> + </div> + </div> </div> + {{ form_end(form) }} </div> - - diff --git a/templates/_Utils/form_theme.html.twig b/templates/_Utils/form_theme.html.twig new file mode 100644 index 0000000000000000000000000000000000000000..e8d0f18738e1f17047cbce73971f6e86270ff083 --- /dev/null +++ b/templates/_Utils/form_theme.html.twig @@ -0,0 +1,31 @@ +{% use "bootstrap_3_horizontal_layout.html.twig" %} + +{%- block form_widget_simple -%} + {%- set type = type|default('text') -%} + + {{- parent() -}} + + {%- if type == 'password' -%} + <span class="glyphicon glyphicon-eye-open form-control-feedback"></span> + {%- endif -%} +{%- endblock form_widget_simple -%} + +{% block form_group_class -%} + col-sm-10 +{%- endblock form_group_class %} + +{# Override form_row only for password type #} +{% block password_row -%} + {%- set widget_attr = {} -%} + {%- if help is not empty -%} + {%- set widget_attr = {attr: {'aria-describedby': id ~"_help"}} -%} + {%- endif -%} + <div class="form-group{% if (not compound or force_error|default(false)) and not valid %} has-error{% endif %}"> + {{- form_label(form) -}} + <div class="{{ block('form_group_class') }} has-feedback"> + {{- form_widget(form, widget_attr) -}} + {{- form_help(form) -}} + {{- form_errors(form) -}} + </div> + </div> +{%- endblock password_row %} diff --git a/templates/_footer.html.twig b/templates/_footer.html.twig index bb479ed495c64d0305d0f988abb4521be2ef0240..306cc9300f8bdc94b262afcdcd838022c0b6934f 100644 --- a/templates/_footer.html.twig +++ b/templates/_footer.html.twig @@ -1,5 +1,6 @@ <footer class="main-footer"> - <strong>© 2018 <a href="http://www.soluris.fr/" target="_blank" rel="nofollow noreferrer noopener">SOLURIS</a></strong> : {{ app.user.collectivity }} + + <strong>© 2018 <a href="{{ app_footer_provider_url }}" target="_blank" rel="nofollow noreferrer noopener">{{ app_footer_provider_name }}</a></strong> : {{ app.user.collectivity }} <div class="pull-right hidden-xs"> <a href="{{ path('page_credit') }}">Crédit</a> diff --git a/templates/_sidebar.html.twig b/templates/_sidebar.html.twig index cc08e5d6fb8abe48866cdda8b34dcea5ac9f4a5c..b4eed5c8a674d02b594ef18bbf63bb94d388715d 100644 --- a/templates/_sidebar.html.twig +++ b/templates/_sidebar.html.twig @@ -90,7 +90,7 @@ </a> </li> {# If not an admin & is write granted, let user edit informations #} - {% elseif is_granted('ROLE_USER') %} + {% else %} <li {% if menuItem == 'user_profile_collectivity' %}class="active"{% endif %}> <a href="{{ path('user_profile_collectivity_show') }}"> <i class="fa fa-home"></i> @@ -106,8 +106,8 @@ {% endif %} <li class="sidebar-logo"> - <a href="http://www.soluris.fr/" target="_blank" rel="nofollow noreferrer noopener"> - <img src="{{ asset('images/soluris-logo-white.png') }}" alt="Logo SOLURIS" /> + <a href="{{ app_image_sidebar_bottom_target_url }}" target="_blank" rel="nofollow noreferrer noopener"> + <img src="{{ asset(app_image_sidebar_bottom_path) }}" alt="Logo du provider Madis" /> </a> </li> diff --git a/templates/base.html.twig b/templates/base.html.twig index 961f9d137bb09a40555631085e1bead5d9d03f1b..e1f02d3add20a9a37f94f8e4084bce926b997730 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -8,7 +8,7 @@ <title>{% block title %}Madis{% endblock %}</title> - <link rel="icon" href="{{ asset('favicon.ico') }}" /> + <link rel="icon" href="{{ asset(app_image_favicon_path) }}" /> {# Normal import #} {# diff --git a/tests/Domain/Registry/Dictionary/TreatmentDataCategoryDictionaryTest.php b/tests/Domain/Registry/Dictionary/TreatmentDataCategoryDictionaryTest.php deleted file mode 100644 index d7076eeea77598616dd586dbee8c52dff1747c67..0000000000000000000000000000000000000000 --- a/tests/Domain/Registry/Dictionary/TreatmentDataCategoryDictionaryTest.php +++ /dev/null @@ -1,96 +0,0 @@ -<?php - -/** - * This file is part of the SOLURIS - RGPD Management application. - * - * (c) Donovan Bourlard <donovan.bourlard@outlook.fr> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -declare(strict_types=1); - -namespace App\Tests\Domain\Registry\Dictionary; - -use App\Domain\Registry\Dictionary\TreatmentDataCategoryDictionary; -use Knp\DictionaryBundle\Dictionary\SimpleDictionary; -use PHPUnit\Framework\TestCase; - -class TreatmentDataCategoryDictionaryTest extends TestCase -{ - public function testInstanceOf() - { - $this->assertInstanceOf(SimpleDictionary::class, new TreatmentDataCategoryDictionary()); - } - - public function testConstruct() - { - $dictionary = new TreatmentDataCategoryDictionary(); - - $this->assertEquals('registry_treatment_data_category', $dictionary->getName()); - $this->assertEquals(TreatmentDataCategoryDictionary::getCategories(), $dictionary->getValues()); - } - - public function testGetRoles() - { - $data = [ - TreatmentDataCategoryDictionary::CATEGORY_CIVILITY => 'État civil', - TreatmentDataCategoryDictionary::CATEGORY_POSTAL => 'Coordonnées postales', - TreatmentDataCategoryDictionary::CATEGORY_PHONE => 'Coordonnées téléphoniques', - TreatmentDataCategoryDictionary::CATEGORY_EMAIL => 'Emails', - TreatmentDataCategoryDictionary::CATEGORY_IP => 'Adresse IP', - TreatmentDataCategoryDictionary::CATEGORY_GEO => 'Géolocalisation', - TreatmentDataCategoryDictionary::CATEGORY_PICTURE => 'Photos-vidéos', - TreatmentDataCategoryDictionary::CATEGORY_FAMILY_SITUATION => 'Situation familiale', - TreatmentDataCategoryDictionary::CATEGORY_FILIATION => 'Filiation', - TreatmentDataCategoryDictionary::CATEGORY_HEALTH => 'Santé', - TreatmentDataCategoryDictionary::CATEGORY_SOCIAL_NUM => 'Numéro de Sécurité Sociale', - TreatmentDataCategoryDictionary::CATEGORY_CAF_NUM => 'Numéro de CAF', - TreatmentDataCategoryDictionary::CATEGORY_SYNDICATE => 'Appartenance Syndicale', - TreatmentDataCategoryDictionary::CATEGORY_CONNEXION => 'Connexion', - TreatmentDataCategoryDictionary::CATEGORY_BANK => 'Information bancaire', - TreatmentDataCategoryDictionary::CATEGORY_HERITAGE => 'Patrimoine', - TreatmentDataCategoryDictionary::CATEGORY_EARNING => 'Revenus', - TreatmentDataCategoryDictionary::CATEGORY_TAX_SITUATION => 'Situation fiscale', - TreatmentDataCategoryDictionary::CATEGORY_BANK_SITUATION => 'Situation bancaire', - TreatmentDataCategoryDictionary::CATEGORY_IDENTITY => 'Pièces d’identité', - TreatmentDataCategoryDictionary::CATEGORY_PUBLIC_RELIGIOUS_OPINION => 'Opinion politique ou religieuse', - TreatmentDataCategoryDictionary::CATEGORY_RACIAL_ETHNIC_OPINION => 'Origine raciale ou ethnique', - TreatmentDataCategoryDictionary::CATEGORY_SEX_LIFE => 'Vie sexuelle', - ]; - - $this->assertEquals($data, TreatmentDataCategoryDictionary::getCategories()); - } - - public function testGetRolesKeys() - { - $data = [ - TreatmentDataCategoryDictionary::CATEGORY_CIVILITY, - TreatmentDataCategoryDictionary::CATEGORY_POSTAL, - TreatmentDataCategoryDictionary::CATEGORY_PHONE, - TreatmentDataCategoryDictionary::CATEGORY_EMAIL, - TreatmentDataCategoryDictionary::CATEGORY_IP, - TreatmentDataCategoryDictionary::CATEGORY_GEO, - TreatmentDataCategoryDictionary::CATEGORY_PICTURE, - TreatmentDataCategoryDictionary::CATEGORY_FAMILY_SITUATION, - TreatmentDataCategoryDictionary::CATEGORY_FILIATION, - TreatmentDataCategoryDictionary::CATEGORY_HEALTH, - TreatmentDataCategoryDictionary::CATEGORY_SOCIAL_NUM, - TreatmentDataCategoryDictionary::CATEGORY_CAF_NUM, - TreatmentDataCategoryDictionary::CATEGORY_SYNDICATE, - TreatmentDataCategoryDictionary::CATEGORY_CONNEXION, - TreatmentDataCategoryDictionary::CATEGORY_BANK, - TreatmentDataCategoryDictionary::CATEGORY_HERITAGE, - TreatmentDataCategoryDictionary::CATEGORY_EARNING, - TreatmentDataCategoryDictionary::CATEGORY_TAX_SITUATION, - TreatmentDataCategoryDictionary::CATEGORY_BANK_SITUATION, - TreatmentDataCategoryDictionary::CATEGORY_IDENTITY, - TreatmentDataCategoryDictionary::CATEGORY_PUBLIC_RELIGIOUS_OPINION, - TreatmentDataCategoryDictionary::CATEGORY_RACIAL_ETHNIC_OPINION, - TreatmentDataCategoryDictionary::CATEGORY_SEX_LIFE, - ]; - - $this->assertEquals($data, TreatmentDataCategoryDictionary::getCategoryKeys()); - } -} diff --git a/tests/Domain/Registry/Form/Type/TreatmentTypeTest.php b/tests/Domain/Registry/Form/Type/TreatmentTypeTest.php index 913488dec827419c3bdb4bdb17b06a3c0d988951..de94df280fb71062a36029c9bb8e452a13af7294 100644 --- a/tests/Domain/Registry/Form/Type/TreatmentTypeTest.php +++ b/tests/Domain/Registry/Form/Type/TreatmentTypeTest.php @@ -64,9 +64,11 @@ class TreatmentTypeTest extends FormTypeHelper 'paperProcessing' => CheckboxType::class, 'legalBasis' => DictionaryType::class, 'legalBasisJustification' => TextareaType::class, + 'observation' => TextareaType::class, 'concernedPeople' => DictionaryType::class, - 'dataCategory' => DictionaryType::class, + 'dataCategories' => EntityType::class, 'dataCategoryOther' => TextareaType::class, + 'dataOrigin' => TextType::class, 'recipientCategory' => TextareaType::class, 'contractors' => EntityType::class, 'delay' => DelayType::class, diff --git a/tests/Domain/Registry/Model/TreatmentTest.php b/tests/Domain/Registry/Model/TreatmentTest.php index 72657b40d3ea60982d7af365dc9864d504b3287f..9cfbd0f9ef90b2cc0870555825a35c794354f07f 100644 --- a/tests/Domain/Registry/Model/TreatmentTest.php +++ b/tests/Domain/Registry/Model/TreatmentTest.php @@ -31,7 +31,7 @@ class TreatmentTest extends TestCase $this->assertInstanceOf(UuidInterface::class, $model->getId()); $this->assertEquals([], $model->getConcernedPeople()); - $this->assertEquals([], $model->getDataCategory()); + $this->assertEquals([], $model->getDataCategories()); $this->assertInstanceOf(ArrayCollection::class, $model->getContractors()); $this->assertInstanceOf(Delay::class, $model->getDelay()); $this->assertInstanceOf(ComplexChoice::class, $model->getSecurityAccessControl()); diff --git a/tests/Domain/User/Form/Type/UserTypeTest.php b/tests/Domain/User/Form/Type/UserTypeTest.php index c35c03782863b84552515d3a28108430bc1c834f..4e3dbacc91451f10fc5774014d52e0af2a8072c5 100644 --- a/tests/Domain/User/Form/Type/UserTypeTest.php +++ b/tests/Domain/User/Form/Type/UserTypeTest.php @@ -25,8 +25,11 @@ use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\EmailType; use Symfony\Component\Form\Extension\Core\Type\RepeatedType; use Symfony\Component\Form\Extension\Core\Type\TextType; +use Symfony\Component\Form\FormEvents; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; +use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface; +use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface; class UserTypeTest extends FormTypeHelper { @@ -35,6 +38,16 @@ class UserTypeTest extends FormTypeHelper */ private $authorizationCheckerProphecy; + /** + * @var EncoderFactoryInterface + */ + private $encoderFactoryProphecy; + + /** + * @var PasswordEncoderInterface + */ + private $encoderProphecy; + /** * @var UserType */ @@ -43,9 +56,14 @@ class UserTypeTest extends FormTypeHelper protected function setUp() { $this->authorizationCheckerProphecy = $this->prophesize(AuthorizationCheckerInterface::class); + $this->encoderFactoryProphecy = $this->prophesize(EncoderFactoryInterface::class); + $this->encoderProphecy = $this->prophesize(PasswordEncoderInterface::class); + + $this->encoderFactoryProphecy->getEncoder(Argument::any())->willReturn($this->encoderProphecy->reveal()); $this->formType = new UserType( - $this->authorizationCheckerProphecy->reveal() + $this->authorizationCheckerProphecy->reveal(), + $this->encoderFactoryProphecy->reveal() ); } @@ -75,6 +93,11 @@ class UserTypeTest extends FormTypeHelper ->shouldBeCalled() ; + $builderProphecy + ->addEventListener(FormEvents::POST_SUBMIT, Argument::any()) + ->shouldBeCalled() + ; + $this->formType->buildForm($builderProphecy->reveal(), []); } @@ -84,6 +107,7 @@ class UserTypeTest extends FormTypeHelper 'firstName' => TextType::class, 'lastName' => TextType::class, 'email' => EmailType::class, + 'plainPassword' => RepeatedType::class, ]; $this->authorizationCheckerProphecy->isGranted('ROLE_ADMIN')->shouldBeCalled()->willReturn(false); @@ -93,6 +117,11 @@ class UserTypeTest extends FormTypeHelper $builderProphecy->get('roles')->shouldNotBeCalled(); $builderProphecy->addModelTransformer(Argument::cetera())->shouldNotBeCalled(); + $builderProphecy + ->addEventListener(FormEvents::POST_SUBMIT, Argument::any()) + ->shouldBeCalled() + ; + $this->formType->buildForm($builderProphecy->reveal(), []); } diff --git a/tests/Domain/User/Symfony/EventSubscriber/DefinePasswordSubscriberTest.php b/tests/Domain/User/Symfony/EventSubscriber/DefinePasswordSubscriberTest.php index 1f0b906b462eba61d025819a19cb1f39640f3f2c..82a09447f79b4c64097d51375fc961e8fa7a811c 100644 --- a/tests/Domain/User/Symfony/EventSubscriber/DefinePasswordSubscriberTest.php +++ b/tests/Domain/User/Symfony/EventSubscriber/DefinePasswordSubscriberTest.php @@ -75,13 +75,14 @@ class DefinePasswordSubscriberTest extends TestCase /** * Test prePersist - * plainPassword is null. + * plainPassword and password are null. */ - public function testPrePersistPlainPasswordIsNull() + public function testPrePersistPlainPasswordAndPasswordAreNull() { $token = 'token'; $userProphecy = $this->prophesize(Model\User::class); $userProphecy->getPlainPassword()->shouldBeCalled()->willReturn(null); + $userProphecy->getPassword()->shouldBeCalled()->willReturn(null); $userProphecy->setPlainPassword($token)->shouldBeCalled(); $this->lifeCycleEventArgsProphecy->getObject()->shouldBeCalled()->willReturn($userProphecy->reveal()); @@ -107,4 +108,22 @@ class DefinePasswordSubscriberTest extends TestCase $this->subscriber->prePersist($this->lifeCycleEventArgsProphecy->reveal()); } + + /** + * Test prePersist + * plainPassword is not set but password is set. + */ + public function testPrePersistPlainPasswordIsNotSetButPasswordIsSet() + { + $userProphecy = $this->prophesize(Model\User::class); + $userProphecy->getPlainPassword()->shouldBeCalled()->willReturn(null); + $userProphecy->getPassword()->shouldBeCalled()->willReturn('plainPassword'); + $userProphecy->setPlainPassword(Argument::any())->shouldNotBeCalled(); + + $this->lifeCycleEventArgsProphecy->getObject()->shouldBeCalled()->willReturn($userProphecy->reveal()); + // since password is set, no token is generated + $this->tokenGeneratorProphecy->generateToken()->shouldNotBeCalled(); + + $this->subscriber->prePersist($this->lifeCycleEventArgsProphecy->reveal()); + } }