diff --git a/README.md b/README.md index 881bcd66..fe223752 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,16 @@ In Kooperation mit der [Professur "Datenschutz und Compliance"](https://www.unib Durch die Mitarbeitenden von @verdigado wurde der VVT Assistent und die Vererbung implemntiert. +# Dev Setup + +1. Abhängigkeiten installieren mit `composer install` und `npm install` +1. Starte docker container für Datenbank und Keycloak `docker compose -f docker-compose.dev.yml up -d` +1. Mit Account `admin` und Passwort `admin` im Keycloak anmelden +1. Unter `http://localhost:8080/admin/master/console/#/opendatenschutzcenter/users/add-user` Nutzer für open-datenschutzcenter realm anlegen +1. Passwort für neuen Nutzer festlegen und die beiden opendatenschutzcenter client roles `uma_protection` und `odc-super-admin` zuweisen +1. Führe Migrationen der Datenbank aus `symfony console doctrine:migrations:migrate` +1. Starte den dev Server mit `symfony serve -d` + # Lizenz Die aktuelle Version von Open Datenschutzcenter wird unter der AGPL-3.0 License bereitgestellt. Weitere Informationen finden Sie in der LICENSE Datei in diesem Repo. Copyright (c) 2020 H2 invent diff --git a/assets/js/app.js b/assets/js/app.js new file mode 100644 index 00000000..8b6e0c2a --- /dev/null +++ b/assets/js/app.js @@ -0,0 +1,135 @@ +/* + * Welcome to your app's main JavaScript file! + * + */ +import '../css/app.css'; + + +import $ from 'jquery'; +import 'datatables.net-dt'; +import 'summernote/dist/summernote-bs4'; +import * as h2Button from 'h2-invent-apps'; +import {initFreeFields} from './freeField'; + +global.$ = global.jQuery = $; + +import ('jszip'); +import('datatables.net'); +import ('datatables.net-buttons-dt'); +require('datatables.net-buttons/js/buttons.flash.js')(window, $); +require('datatables.net-buttons/js/buttons.html5.js')(window, $); +import('moment'); +import('bootstrap-select'); + +$(document).ready(function () { + h2Button.init("https://www3.h2-invent.com/appsv2.json"); + setTimeout(function () { + $('#snackbar').addClass('show'); + setTimeout(function () { + $('#snackbar').removeClass('show'); + }, 3000); + }, 500); + + $('#dismiss, .overlay').on('click', function () { + // hide sidebar + $('#sidebar').removeClass('active'); + // hide overlay + $('.overlay').removeClass('active'); + }); + + $('#sidebarCollapse').on('click', function () { + // open sidebar + $('#sidebar').addClass('active'); + // fade in the overlay + $('.overlay').addClass('active'); + $('.collapse.in').toggleClass('in'); + $('a[aria-expanded=true]').attr('aria-expanded', 'false'); + }); + + $('#data-table').DataTable({ + dom: 'Bfrtip', + buttons: [ + { + extend: 'csv', + exportOptions: { + columns: ':not(.hide-in-export)' + } + }, + { + extend: 'excel', + exportOptions: { + columns: ':not(.hide-in-export)' + } + } + ] + }); + + $('.data-table').DataTable({ + dom: 'Bfrtip', + buttons: [ + { + extend: 'csv', + exportOptions: { + columns: ':not(.hide-in-export)' + } + }, + { + extend: 'excel', + exportOptions: { + columns: ':not(.hide-in-export)' + } + } + ] + }); + + $('.summernote').summernote({ + placeholder: 'Gebe hier den Text ein', + tabsize: 2, + height: 200, + focus: false, + lang: 'de-DE', + toolbar: [ + ['style', ['pre']], + ['font', ['bold', 'underline', 'clear']], + ['color', []], + ['para', ['ul', 'ol', 'paragraph']], + ['table', ['table']], + ['insert', ['link']], + ['view', ['fullscreen']] + ], + callbacks: { + onPaste: function (e) { + var bufferText = ((e.originalEvent || e).clipboardData || window.clipboardData).getData('Text'); + e.preventDefault(); + document.execCommand('insertText', false, bufferText); + } + } + }); + + $('.summernote-disable').each(function () { + $(this).summernote('disable'); + }); + + $('.checkboxSelect').on('change', function () { + if ($(this).prop("checked") === true) { + $('.sendButton').removeClass('disabled'); + } else if ($(this).prop("checked") === false) { + $('.sendButton').addClass('disabled'); + } + }); + + initFreeFields(); +}); + +$(document).on('click', '.loadContent', function (e) { + e.preventDefault(); + var url = $(this).attr('href'); + $('#loadContentModal').load(url, function () { + $('#loadContentModal ').modal('show'); + + }); +}); + +$(".clickable-row").click(function () { + window.location = $(this).data("href"); +}); \ No newline at end of file diff --git a/assets/styles/tailmater.css b/assets/styles/tailmater.css index 79d94442..623373d2 100644 --- a/assets/styles/tailmater.css +++ b/assets/styles/tailmater.css @@ -1183,7 +1183,7 @@ trix-editor ol, .editor-output ol, ol.initial { } ol.item-history { - @apply text-sm card-outlined w-full max-w-2xl; + @apply text-sm card-outlined w-full w-full ; list-style: decimal; list-style-position: outside; } diff --git a/composer.json b/composer.json index c017668e..ee025db7 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,7 @@ "doctrine/doctrine-migrations-bundle": "^3.2", "doctrine/orm": "^2.10", "knplabs/knp-menu-bundle": "^3.2", + "gedmo/doctrine-extensions": "^3.11", "knpuniversity/oauth2-client-bundle": "^2.5", "laminas/laminas-code": "^4.5", "laminas/laminas-escaper": "^2.6", @@ -23,6 +24,7 @@ "phpstan/phpdoc-parser": "^1.2", "sensio/framework-extra-bundle": "^6.2", "stevenmaguire/oauth2-keycloak": "^2.2", + "stof/doctrine-extensions-bundle": "^1.7", "symfony/apache-pack": "^1.0", "symfony/asset": "6.2.*", "symfony/console": "6.2.*", diff --git a/composer.lock b/composer.lock index b4a7f090..8d96745c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,57 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "447dc6250d4e3163dc97da0c080908b5", + "content-hash": "032e3f507e51377d9a60572e16ee7f34", "packages": [ + { + "name": "behat/transliterator", + "version": "v1.5.0", + "source": { + "type": "git", + "url": "https://github.com/Behat/Transliterator.git", + "reference": "baac5873bac3749887d28ab68e2f74db3a4408af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Behat/Transliterator/zipball/baac5873bac3749887d28ab68e2f74db3a4408af", + "reference": "baac5873bac3749887d28ab68e2f74db3a4408af", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "require-dev": { + "chuyskywalker/rolling-curl": "^3.1", + "php-yaoi/php-yaoi": "^1.0", + "phpunit/phpunit": "^8.5.25 || ^9.5.19" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Behat\\Transliterator\\": "src/Behat/Transliterator" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Artistic-1.0" + ], + "description": "String transliterator", + "keywords": [ + "i18n", + "slug", + "transliterator" + ], + "support": { + "issues": "https://github.com/Behat/Transliterator/issues", + "source": "https://github.com/Behat/Transliterator/tree/v1.5.0" + }, + "time": "2022-03-30T09:27:43+00:00" + }, { "name": "composer/package-versions-deprecated", "version": "1.11.99.5", @@ -250,16 +299,16 @@ }, { "name": "doctrine/collections", - "version": "2.1.2", + "version": "2.1.4", "source": { "type": "git", "url": "https://github.com/doctrine/collections.git", - "reference": "db8cda536a034337f7dd63febecc713d4957f9ee" + "reference": "72328a11443a0de79967104ad36ba7b30bded134" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/db8cda536a034337f7dd63febecc713d4957f9ee", - "reference": "db8cda536a034337f7dd63febecc713d4957f9ee", + "url": "https://api.github.com/repos/doctrine/collections/zipball/72328a11443a0de79967104ad36ba7b30bded134", + "reference": "72328a11443a0de79967104ad36ba7b30bded134", "shasum": "" }, "require": { @@ -267,12 +316,12 @@ "php": "^8.1" }, "require-dev": { - "doctrine/coding-standard": "^10.0", + "doctrine/coding-standard": "^12", "ext-json": "*", "phpstan/phpstan": "^1.8", "phpstan/phpstan-phpunit": "^1.0", "phpunit/phpunit": "^9.5", - "vimeo/psalm": "^4.22" + "vimeo/psalm": "^5.11" }, "type": "library", "autoload": { @@ -316,7 +365,7 @@ ], "support": { "issues": "https://github.com/doctrine/collections/issues", - "source": "https://github.com/doctrine/collections/tree/2.1.2" + "source": "https://github.com/doctrine/collections/tree/2.1.4" }, "funding": [ { @@ -332,7 +381,7 @@ "type": "tidelift" } ], - "time": "2022-12-27T23:41:38+00:00" + "time": "2023-10-03T09:22:33+00:00" }, { "name": "doctrine/common", @@ -427,16 +476,16 @@ }, { "name": "doctrine/dbal", - "version": "3.6.2", + "version": "3.7.2", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "b4bd1cfbd2b916951696d82e57d054394d84864c" + "reference": "0ac3c270590e54910715e9a1a044cc368df282b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/b4bd1cfbd2b916951696d82e57d054394d84864c", - "reference": "b4bd1cfbd2b916951696d82e57d054394d84864c", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/0ac3c270590e54910715e9a1a044cc368df282b2", + "reference": "0ac3c270590e54910715e9a1a044cc368df282b2", "shasum": "" }, "require": { @@ -449,13 +498,14 @@ "psr/log": "^1|^2|^3" }, "require-dev": { - "doctrine/coding-standard": "11.1.0", + "doctrine/coding-standard": "12.0.0", "fig/log-test": "^1", - "jetbrains/phpstorm-stubs": "2022.3", - "phpstan/phpstan": "1.10.9", + "jetbrains/phpstorm-stubs": "2023.1", + "phpstan/phpstan": "1.10.42", "phpstan/phpstan-strict-rules": "^1.5", - "phpunit/phpunit": "9.6.6", + "phpunit/phpunit": "9.6.13", "psalm/plugin-phpunit": "0.18.4", + "slevomat/coding-standard": "8.13.1", "squizlabs/php_codesniffer": "3.7.2", "symfony/cache": "^5.4|^6.0", "symfony/console": "^4.4|^5.4|^6.0", @@ -519,7 +569,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.6.2" + "source": "https://github.com/doctrine/dbal/tree/3.7.2" }, "funding": [ { @@ -535,29 +585,33 @@ "type": "tidelift" } ], - "time": "2023-04-14T07:25:38+00:00" + "time": "2023-11-19T08:06:58+00:00" }, { "name": "doctrine/deprecations", - "version": "v1.1.0", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "8cffffb2218e01f3b370bf763e00e81697725259" + "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/8cffffb2218e01f3b370bf763e00e81697725259", - "reference": "8cffffb2218e01f3b370bf763e00e81697725259", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/4f2d4f2836e7ec4e7a8625e75c6aa916004db931", + "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931", "shasum": "" }, "require": { - "php": "^7.1|^8.0" + "php": "^7.1 || ^8.0" }, "require-dev": { "doctrine/coding-standard": "^9", - "phpunit/phpunit": "^7.5|^8.5|^9.5", - "psr/log": "^1|^2|^3" + "phpstan/phpstan": "1.4.10 || 1.10.15", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "0.18.4", + "psr/log": "^1 || ^2 || ^3", + "vimeo/psalm": "4.30.0 || 5.12.0" }, "suggest": { "psr/log": "Allows logging deprecations via PSR-3 logger implementation" @@ -576,62 +630,65 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/v1.1.0" + "source": "https://github.com/doctrine/deprecations/tree/1.1.2" }, - "time": "2023-05-29T18:55:17+00:00" + "time": "2023-09-27T20:04:15+00:00" }, { "name": "doctrine/doctrine-bundle", - "version": "2.9.1", + "version": "2.11.1", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineBundle.git", - "reference": "7539b3c8bd620f7df6c2c6d510204bd2ce0064e3" + "reference": "4089f1424b724786c062aea50aae5f773449b94b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/7539b3c8bd620f7df6c2c6d510204bd2ce0064e3", - "reference": "7539b3c8bd620f7df6c2c6d510204bd2ce0064e3", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/4089f1424b724786c062aea50aae5f773449b94b", + "reference": "4089f1424b724786c062aea50aae5f773449b94b", "shasum": "" }, "require": { "doctrine/cache": "^1.11 || ^2.0", - "doctrine/dbal": "^3.6.0", + "doctrine/dbal": "^3.7.0 || ^4.0", "doctrine/persistence": "^2.2 || ^3", "doctrine/sql-formatter": "^1.0.1", "php": "^7.4 || ^8.0", - "symfony/cache": "^5.4 || ^6.0", - "symfony/config": "^5.4 || ^6.0", - "symfony/console": "^5.4 || ^6.0", - "symfony/dependency-injection": "^5.4 || ^6.0", + "symfony/cache": "^5.4 || ^6.0 || ^7.0", + "symfony/config": "^5.4 || ^6.0 || ^7.0", + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0", "symfony/deprecation-contracts": "^2.1 || ^3", - "symfony/doctrine-bridge": "^5.4.19 || ^6.0.7", - "symfony/framework-bundle": "^5.4 || ^6.0", + "symfony/doctrine-bridge": "^5.4.19 || ^6.0.7 || ^7.0", + "symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0", + "symfony/polyfill-php80": "^1.15", "symfony/service-contracts": "^1.1.1 || ^2.0 || ^3" }, "conflict": { "doctrine/annotations": ">=3.0", - "doctrine/orm": "<2.11 || >=3.0", + "doctrine/orm": "<2.14 || >=4.0", "twig/twig": "<1.34 || >=2.0 <2.4" }, "require-dev": { "doctrine/annotations": "^1 || ^2", - "doctrine/coding-standard": "^9.0", + "doctrine/coding-standard": "^12", "doctrine/deprecations": "^1.0", - "doctrine/orm": "^2.11 || ^3.0", + "doctrine/orm": "^2.14 || ^3.0", "friendsofphp/proxy-manager-lts": "^1.0", "phpunit/phpunit": "^9.5.26 || ^10.0", "psalm/plugin-phpunit": "^0.18.4", "psalm/plugin-symfony": "^4", "psr/log": "^1.1.4 || ^2.0 || ^3.0", - "symfony/phpunit-bridge": "^6.1", - "symfony/property-info": "^5.4 || ^6.0", - "symfony/proxy-manager-bridge": "^5.4 || ^6.0", - "symfony/security-bundle": "^5.4 || ^6.0", - "symfony/twig-bridge": "^5.4 || ^6.0", - "symfony/validator": "^5.4 || ^6.0", - "symfony/web-profiler-bundle": "^5.4 || ^6.0", - "symfony/yaml": "^5.4 || ^6.0", + "symfony/phpunit-bridge": "^6.1 || ^7.0", + "symfony/property-info": "^5.4 || ^6.0 || ^7.0", + "symfony/proxy-manager-bridge": "^5.4 || ^6.0 || ^7.0", + "symfony/security-bundle": "^5.4 || ^6.0 || ^7.0", + "symfony/string": "^5.4 || ^6.0 || ^7.0", + "symfony/twig-bridge": "^5.4 || ^6.0 || ^7.0", + "symfony/validator": "^5.4 || ^6.0 || ^7.0", + "symfony/var-exporter": "^5.4 || ^6.2 || ^7.0", + "symfony/web-profiler-bundle": "^5.4 || ^6.0 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0", "twig/twig": "^1.34 || ^2.12 || ^3.0", "vimeo/psalm": "^4.30" }, @@ -678,7 +735,7 @@ ], "support": { "issues": "https://github.com/doctrine/DoctrineBundle/issues", - "source": "https://github.com/doctrine/DoctrineBundle/tree/2.9.1" + "source": "https://github.com/doctrine/DoctrineBundle/tree/2.11.1" }, "funding": [ { @@ -694,38 +751,44 @@ "type": "tidelift" } ], - "time": "2023-04-14T05:39:34+00:00" + "time": "2023-11-15T20:01:50+00:00" }, { "name": "doctrine/doctrine-migrations-bundle", - "version": "3.2.3", + "version": "3.3.0", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineMigrationsBundle.git", - "reference": "05490c74141ecd285ac7d38cef1047ed0abadc47" + "reference": "1dd42906a5fb9c5960723e2ebb45c68006493835" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineMigrationsBundle/zipball/05490c74141ecd285ac7d38cef1047ed0abadc47", - "reference": "05490c74141ecd285ac7d38cef1047ed0abadc47", + "url": "https://api.github.com/repos/doctrine/DoctrineMigrationsBundle/zipball/1dd42906a5fb9c5960723e2ebb45c68006493835", + "reference": "1dd42906a5fb9c5960723e2ebb45c68006493835", "shasum": "" }, "require": { - "doctrine/doctrine-bundle": "~1.0|~2.0", + "doctrine/doctrine-bundle": "^2.4", "doctrine/migrations": "^3.2", "php": "^7.2|^8.0", - "symfony/framework-bundle": "~3.4|~4.0|~5.0|~6.0" + "symfony/deprecation-contracts": "^2.1 || ^3", + "symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0" }, "require-dev": { - "doctrine/coding-standard": "^9", - "doctrine/orm": "^2.6", - "doctrine/persistence": "^1.3||^2.0", + "doctrine/coding-standard": "^12", + "doctrine/orm": "^2.6 || ^3", + "doctrine/persistence": "^2.0 || ^3 ", "phpstan/phpstan": "^1.4", "phpstan/phpstan-deprecation-rules": "^1", "phpstan/phpstan-phpunit": "^1", "phpstan/phpstan-strict-rules": "^1.1", + "phpstan/phpstan-symfony": "^1.3", "phpunit/phpunit": "^8.5|^9.5", - "vimeo/psalm": "^4.22" + "psalm/plugin-phpunit": "^0.18.4", + "psalm/plugin-symfony": "^3 || ^5", + "symfony/phpunit-bridge": "^6.3 || ^7", + "symfony/var-exporter": "^5.4 || ^6 || ^7", + "vimeo/psalm": "^4.30 || ^5.15" }, "type": "symfony-bundle", "autoload": { @@ -763,7 +826,7 @@ ], "support": { "issues": "https://github.com/doctrine/DoctrineMigrationsBundle/issues", - "source": "https://github.com/doctrine/DoctrineMigrationsBundle/tree/3.2.3" + "source": "https://github.com/doctrine/DoctrineMigrationsBundle/tree/3.3.0" }, "funding": [ { @@ -779,7 +842,7 @@ "type": "tidelift" } ], - "time": "2023-05-02T13:24:05+00:00" + "time": "2023-11-13T19:44:41+00:00" }, { "name": "doctrine/event-manager", @@ -874,28 +937,28 @@ }, { "name": "doctrine/inflector", - "version": "2.0.6", + "version": "2.0.8", "source": { "type": "git", "url": "https://github.com/doctrine/inflector.git", - "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024" + "reference": "f9301a5b2fb1216b2b08f02ba04dc45423db6bff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/d9d313a36c872fd6ee06d9a6cbcf713eaa40f024", - "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/f9301a5b2fb1216b2b08f02ba04dc45423db6bff", + "reference": "f9301a5b2fb1216b2b08f02ba04dc45423db6bff", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^10", + "doctrine/coding-standard": "^11.0", "phpstan/phpstan": "^1.8", "phpstan/phpstan-phpunit": "^1.1", "phpstan/phpstan-strict-rules": "^1.3", "phpunit/phpunit": "^8.5 || ^9.5", - "vimeo/psalm": "^4.25" + "vimeo/psalm": "^4.25 || ^5.4" }, "type": "library", "autoload": { @@ -945,7 +1008,7 @@ ], "support": { "issues": "https://github.com/doctrine/inflector/issues", - "source": "https://github.com/doctrine/inflector/tree/2.0.6" + "source": "https://github.com/doctrine/inflector/tree/2.0.8" }, "funding": [ { @@ -961,7 +1024,7 @@ "type": "tidelift" } ], - "time": "2022-10-20T09:10:12+00:00" + "time": "2023-06-16T13:40:37+00:00" }, { "name": "doctrine/instantiator", @@ -1113,47 +1176,47 @@ }, { "name": "doctrine/migrations", - "version": "3.6.0", + "version": "3.7.2", "source": { "type": "git", "url": "https://github.com/doctrine/migrations.git", - "reference": "e542ad8bcd606d7a18d0875babb8a6d963c9c059" + "reference": "47af29eef49f29ebee545947e8b2a4b3be318c8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/migrations/zipball/e542ad8bcd606d7a18d0875babb8a6d963c9c059", - "reference": "e542ad8bcd606d7a18d0875babb8a6d963c9c059", + "url": "https://api.github.com/repos/doctrine/migrations/zipball/47af29eef49f29ebee545947e8b2a4b3be318c8a", + "reference": "47af29eef49f29ebee545947e8b2a4b3be318c8a", "shasum": "" }, "require": { "composer-runtime-api": "^2", - "doctrine/dbal": "^3.5.1", + "doctrine/dbal": "^3.5.1 || ^4", "doctrine/deprecations": "^0.5.3 || ^1", "doctrine/event-manager": "^1.2 || ^2.0", "php": "^8.1", "psr/log": "^1.1.3 || ^2 || ^3", - "symfony/console": "^4.4.16 || ^5.4 || ^6.0", - "symfony/stopwatch": "^4.4 || ^5.4 || ^6.0", - "symfony/var-exporter": "^6.2" + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0", + "symfony/var-exporter": "^6.2 || ^7.0" }, "conflict": { - "doctrine/orm": "<2.12" + "doctrine/orm": "<2.12 || >=4" }, "require-dev": { - "doctrine/coding-standard": "^9", - "doctrine/orm": "^2.13", + "doctrine/coding-standard": "^12", + "doctrine/orm": "^2.13 || ^3", "doctrine/persistence": "^2 || ^3", "doctrine/sql-formatter": "^1.0", "ext-pdo_sqlite": "*", - "phpstan/phpstan": "^1.5", - "phpstan/phpstan-deprecation-rules": "^1", - "phpstan/phpstan-phpunit": "^1.1", - "phpstan/phpstan-strict-rules": "^1.1", - "phpstan/phpstan-symfony": "^1.1", - "phpunit/phpunit": "^9.5.24", - "symfony/cache": "^4.4 || ^5.4 || ^6.0", - "symfony/process": "^4.4 || ^5.4 || ^6.0", - "symfony/yaml": "^4.4 || ^5.4 || ^6.0" + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-deprecation-rules": "^1.1", + "phpstan/phpstan-phpunit": "^1.3", + "phpstan/phpstan-strict-rules": "^1.4", + "phpstan/phpstan-symfony": "^1.3", + "phpunit/phpunit": "^10.3", + "symfony/cache": "^5.4 || ^6.0 || ^7.0", + "symfony/process": "^5.4 || ^6.0 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" }, "suggest": { "doctrine/sql-formatter": "Allows to generate formatted SQL with the diff command.", @@ -1195,7 +1258,7 @@ ], "support": { "issues": "https://github.com/doctrine/migrations/issues", - "source": "https://github.com/doctrine/migrations/tree/3.6.0" + "source": "https://github.com/doctrine/migrations/tree/3.7.2" }, "funding": [ { @@ -1211,20 +1274,20 @@ "type": "tidelift" } ], - "time": "2023-02-15T18:49:46+00:00" + "time": "2023-12-05T11:35:05+00:00" }, { "name": "doctrine/orm", - "version": "2.15.1", + "version": "2.17.1", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "9bc6f5b4ac6f1e7d4248b2efbd01a748782075bc" + "reference": "1a4fe6e0bb67762370937a7e6cee3da40a9122d1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/9bc6f5b4ac6f1e7d4248b2efbd01a748782075bc", - "reference": "9bc6f5b4ac6f1e7d4248b2efbd01a748782075bc", + "url": "https://api.github.com/repos/doctrine/orm/zipball/1a4fe6e0bb67762370937a7e6cee3da40a9122d1", + "reference": "1a4fe6e0bb67762370937a7e6cee3da40a9122d1", "shasum": "" }, "require": { @@ -1242,7 +1305,7 @@ "ext-ctype": "*", "php": "^7.1 || ^8.0", "psr/cache": "^1 || ^2 || ^3", - "symfony/console": "^4.2 || ^5.0 || ^6.0", + "symfony/console": "^4.2 || ^5.0 || ^6.0 || ^7.0", "symfony/polyfill-php72": "^1.23", "symfony/polyfill-php80": "^1.16" }, @@ -1253,14 +1316,14 @@ "doctrine/annotations": "^1.13 || ^2", "doctrine/coding-standard": "^9.0.2 || ^12.0", "phpbench/phpbench": "^0.16.10 || ^1.0", - "phpstan/phpstan": "~1.4.10 || 1.10.14", + "phpstan/phpstan": "~1.4.10 || 1.10.35", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6", "psr/log": "^1 || ^2 || ^3", "squizlabs/php_codesniffer": "3.7.2", "symfony/cache": "^4.4 || ^5.4 || ^6.0", "symfony/var-exporter": "^4.4 || ^5.4 || ^6.2", "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0", - "vimeo/psalm": "4.30.0 || 5.11.0" + "vimeo/psalm": "4.30.0 || 5.15.0" }, "suggest": { "ext-dom": "Provides support for XSD validation for XML mapping files", @@ -1310,9 +1373,9 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/2.15.1" + "source": "https://github.com/doctrine/orm/tree/2.17.1" }, - "time": "2023-05-07T18:56:25+00:00" + "time": "2023-11-17T06:25:40+00:00" }, { "name": "doctrine/persistence", @@ -1535,16 +1598,16 @@ }, { "name": "egulias/email-validator", - "version": "4.0.1", + "version": "4.0.2", "source": { "type": "git", "url": "https://github.com/egulias/EmailValidator.git", - "reference": "3a85486b709bc384dae8eb78fb2eec649bdb64ff" + "reference": "ebaaf5be6c0286928352e054f2d5125608e5405e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/3a85486b709bc384dae8eb78fb2eec649bdb64ff", - "reference": "3a85486b709bc384dae8eb78fb2eec649bdb64ff", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ebaaf5be6c0286928352e054f2d5125608e5405e", + "reference": "ebaaf5be6c0286928352e054f2d5125608e5405e", "shasum": "" }, "require": { @@ -1553,8 +1616,8 @@ "symfony/polyfill-intl-idn": "^1.26" }, "require-dev": { - "phpunit/phpunit": "^9.5.27", - "vimeo/psalm": "^4.30" + "phpunit/phpunit": "^10.2", + "vimeo/psalm": "^5.12" }, "suggest": { "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" @@ -1590,7 +1653,7 @@ ], "support": { "issues": "https://github.com/egulias/EmailValidator/issues", - "source": "https://github.com/egulias/EmailValidator/tree/4.0.1" + "source": "https://github.com/egulias/EmailValidator/tree/4.0.2" }, "funding": [ { @@ -1598,7 +1661,7 @@ "type": "github" } ], - "time": "2023-01-14T14:17:03+00:00" + "time": "2023-10-06T06:47:41+00:00" }, { "name": "firebase/php-jwt", @@ -1729,24 +1792,151 @@ ], "time": "2023-05-24T07:17:17+00:00" }, + { + "name": "gedmo/doctrine-extensions", + "version": "v3.14.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine-extensions/DoctrineExtensions.git", + "reference": "3b5b5cba476b4ae32a55ef69ef2e59d64d5893cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine-extensions/DoctrineExtensions/zipball/3b5b5cba476b4ae32a55ef69ef2e59d64d5893cf", + "reference": "3b5b5cba476b4ae32a55ef69ef2e59d64d5893cf", + "shasum": "" + }, + "require": { + "behat/transliterator": "^1.2", + "doctrine/annotations": "^1.13 || ^2.0", + "doctrine/collections": "^1.2 || ^2.0", + "doctrine/common": "^2.13 || ^3.0", + "doctrine/event-manager": "^1.2 || ^2.0", + "doctrine/persistence": "^2.2 || ^3.0", + "php": "^7.4 || ^8.0", + "psr/cache": "^1 || ^2 || ^3", + "symfony/cache": "^5.4 || ^6.0 || ^7.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0" + }, + "conflict": { + "doctrine/dbal": "<3.2", + "doctrine/mongodb-odm": "<2.3", + "doctrine/orm": "<2.14.0 || 2.16.0 || 2.16.1", + "sebastian/comparator": "<2.0" + }, + "require-dev": { + "doctrine/cache": "^1.11 || ^2.0", + "doctrine/dbal": "^3.2", + "doctrine/doctrine-bundle": "^2.3", + "doctrine/mongodb-odm": "^2.3", + "doctrine/orm": "^2.14.0", + "friendsofphp/php-cs-fixer": "^3.14.0", + "nesbot/carbon": "^2.71 || 3.x-dev as 3.0", + "phpstan/phpstan": "^1.10.2", + "phpstan/phpstan-doctrine": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^9.6", + "rector/rector": "^0.18", + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/phpunit-bridge": "^6.0 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" + }, + "suggest": { + "doctrine/mongodb-odm": "to use the extensions with the MongoDB ODM", + "doctrine/orm": "to use the extensions with the ORM" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.13-dev" + } + }, + "autoload": { + "psr-4": { + "Gedmo\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gediminas Morkevicius", + "email": "gediminas.morkevicius@gmail.com" + }, + { + "name": "Gustavo Falco", + "email": "comfortablynumb84@gmail.com" + }, + { + "name": "David Buchmann", + "email": "david@liip.ch" + } + ], + "description": "Doctrine behavioral extensions", + "homepage": "http://gediminasm.org/", + "keywords": [ + "Blameable", + "behaviors", + "doctrine", + "extensions", + "gedmo", + "loggable", + "nestedset", + "odm", + "orm", + "sluggable", + "sortable", + "timestampable", + "translatable", + "tree", + "uploadable" + ], + "support": { + "email": "gediminas.morkevicius@gmail.com", + "issues": "https://github.com/doctrine-extensions/DoctrineExtensions/issues", + "source": "https://github.com/doctrine-extensions/DoctrineExtensions/tree/v3.14.0", + "wiki": "https://github.com/Atlantic18/DoctrineExtensions/tree/main/doc" + }, + "funding": [ + { + "url": "https://github.com/l3pp4rd", + "type": "github" + }, + { + "url": "https://github.com/mbabker", + "type": "github" + }, + { + "url": "https://github.com/phansys", + "type": "github" + }, + { + "url": "https://github.com/stof", + "type": "github" + } + ], + "time": "2023-12-03T09:10:34+00:00" + }, { "name": "guzzlehttp/guzzle", - "version": "7.7.0", + "version": "7.8.1", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "fb7566caccf22d74d1ab270de3551f72a58399f5" + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/fb7566caccf22d74d1ab270de3551f72a58399f5", - "reference": "fb7566caccf22d74d1ab270de3551f72a58399f5", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104", + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.5.3 || ^2.0", - "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", + "guzzlehttp/promises": "^1.5.3 || ^2.0.1", + "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" @@ -1755,11 +1945,11 @@ "psr/http-client-implementation": "1.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.1", + "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", "php-http/message-factory": "^1.1", - "phpunit/phpunit": "^8.5.29 || ^9.5.23", + "phpunit/phpunit": "^8.5.36 || ^9.6.15", "psr/log": "^1.1 || ^2.0 || ^3.0" }, "suggest": { @@ -1837,7 +2027,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.7.0" + "source": "https://github.com/guzzle/guzzle/tree/7.8.1" }, "funding": [ { @@ -1853,28 +2043,28 @@ "type": "tidelift" } ], - "time": "2023-05-21T14:04:53+00:00" + "time": "2023-12-03T20:35:24+00:00" }, { "name": "guzzlehttp/promises", - "version": "2.0.0", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "3a494dc7dc1d7d12e511890177ae2d0e6c107da6" + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/3a494dc7dc1d7d12e511890177ae2d0e6c107da6", - "reference": "3a494dc7dc1d7d12e511890177ae2d0e6c107da6", + "url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223", + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223", "shasum": "" }, "require": { "php": "^7.2.5 || ^8.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.1", - "phpunit/phpunit": "^8.5.29 || ^9.5.23" + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.36 || ^9.6.15" }, "type": "library", "extra": { @@ -1920,7 +2110,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/2.0.0" + "source": "https://github.com/guzzle/promises/tree/2.0.2" }, "funding": [ { @@ -1936,20 +2126,20 @@ "type": "tidelift" } ], - "time": "2023-05-21T13:50:22+00:00" + "time": "2023-12-03T20:19:20+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.5.0", + "version": "2.6.2", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "b635f279edd83fc275f822a1188157ffea568ff6" + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/b635f279edd83fc275f822a1188157ffea568ff6", - "reference": "b635f279edd83fc275f822a1188157ffea568ff6", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221", + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221", "shasum": "" }, "require": { @@ -1963,9 +2153,9 @@ "psr/http-message-implementation": "1.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.1", + "bamarni/composer-bin-plugin": "^1.8.2", "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.29 || ^9.5.23" + "phpunit/phpunit": "^8.5.36 || ^9.6.15" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" @@ -2036,7 +2226,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.5.0" + "source": "https://github.com/guzzle/psr7/tree/2.6.2" }, "funding": [ { @@ -2052,7 +2242,7 @@ "type": "tidelift" } ], - "time": "2023-04-17T16:11:26+00:00" + "time": "2023-12-03T20:05:35+00:00" }, { "name": "jms/metadata", @@ -2193,28 +2383,29 @@ }, { "name": "knplabs/knp-menu-bundle", - "version": "v3.2.0", + "version": "v3.3.0", "source": { "type": "git", "url": "https://github.com/KnpLabs/KnpMenuBundle.git", - "reference": "a0b4224f872d74ae939589eb1ccf0e11291370a9" + "reference": "02a2c68a2d6247a21c1d5ed185e2e3e3d9e7dfb5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/KnpLabs/KnpMenuBundle/zipball/a0b4224f872d74ae939589eb1ccf0e11291370a9", - "reference": "a0b4224f872d74ae939589eb1ccf0e11291370a9", + "url": "https://api.github.com/repos/KnpLabs/KnpMenuBundle/zipball/02a2c68a2d6247a21c1d5ed185e2e3e3d9e7dfb5", + "reference": "02a2c68a2d6247a21c1d5ed185e2e3e3d9e7dfb5", "shasum": "" }, "require": { - "knplabs/knp-menu": "^3.1", - "php": "^7.2 || ^8.0", - "symfony/framework-bundle": "^3.4 | ^4.4 | ^5.0 | ^6.0" + "knplabs/knp-menu": "^3.3", + "php": "^8.0", + "symfony/deprecation-contracts": "^2.5 | ^3.3", + "symfony/framework-bundle": "^5.4 | ^6.0 | ^7.0" }, "require-dev": { - "phpunit/phpunit": "^8.5 | ^9.5", - "symfony/expression-language": "^3.4 | ^4.4 | ^5.0 | ^6.0", - "symfony/phpunit-bridge": "^5.2 | ^6.0", - "symfony/templating": "^3.4 | ^4.4 | ^5.0 | ^6.0" + "phpunit/phpunit": "^9.6 | ^10.1", + "symfony/expression-language": "^5.4 | ^6.0 | ^7.0", + "symfony/phpunit-bridge": "^6.0 | ^7.0", + "symfony/templating": "^5.4 | ^6.0 | ^7.0" }, "type": "symfony-bundle", "extra": { @@ -2251,38 +2442,38 @@ ], "support": { "issues": "https://github.com/KnpLabs/KnpMenuBundle/issues", - "source": "https://github.com/KnpLabs/KnpMenuBundle/tree/v3.2.0" + "source": "https://github.com/KnpLabs/KnpMenuBundle/tree/v3.3.0" }, - "time": "2021-10-24T07:53:34+00:00" + "time": "2023-11-01T09:25:40+00:00" }, { "name": "knpuniversity/oauth2-client-bundle", - "version": "v2.15.0", + "version": "v2.17.0", "source": { "type": "git", "url": "https://github.com/knpuniversity/oauth2-client-bundle.git", - "reference": "9df0736d02eb20b953ec8e9986743611747d9ed9" + "reference": "7966f17c964dbcf5a53da60d342c11a590b149e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/knpuniversity/oauth2-client-bundle/zipball/9df0736d02eb20b953ec8e9986743611747d9ed9", - "reference": "9df0736d02eb20b953ec8e9986743611747d9ed9", + "url": "https://api.github.com/repos/knpuniversity/oauth2-client-bundle/zipball/7966f17c964dbcf5a53da60d342c11a590b149e2", + "reference": "7966f17c964dbcf5a53da60d342c11a590b149e2", "shasum": "" }, "require": { "league/oauth2-client": "^2.0", "php": ">=7.4", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/framework-bundle": "^4.4|^5.0|^6.0", - "symfony/http-foundation": "^4.4|^5.0|^6.0", - "symfony/routing": "^4.4|^5.0|^6.0" + "symfony/dependency-injection": "^4.4|^5.0|^6.0|^7.0", + "symfony/framework-bundle": "^4.4|^5.0|^6.0|^7.0", + "symfony/http-foundation": "^4.4|^5.0|^6.0|^7.0", + "symfony/routing": "^4.4|^5.0|^6.0|^7.0" }, "require-dev": { "league/oauth2-facebook": "^1.1|^2.0", "phpstan/phpstan": "^0.12", - "symfony/phpunit-bridge": "^5.3.1|^6.0", - "symfony/security-guard": "^4.4|^5.0|^6.0", - "symfony/yaml": "^4.4|^5.0|^6.0" + "symfony/phpunit-bridge": "^5.3.1|^6.0|^7.0", + "symfony/security-guard": "^4.4|^5.0|^6.0|^7.0", + "symfony/yaml": "^4.4|^5.0|^6.0|^7.0" }, "suggest": { "symfony/security-guard": "For integration with Symfony's Guard Security layer" @@ -2311,35 +2502,35 @@ ], "support": { "issues": "https://github.com/knpuniversity/oauth2-client-bundle/issues", - "source": "https://github.com/knpuniversity/oauth2-client-bundle/tree/v2.15.0" + "source": "https://github.com/knpuniversity/oauth2-client-bundle/tree/v2.17.0" }, - "time": "2023-05-03T16:44:38+00:00" + "time": "2023-11-28T19:03:31+00:00" }, { "name": "laminas/laminas-code", - "version": "4.11.0", + "version": "4.13.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-code.git", - "reference": "169123b3ede20a9193480c53de2a8194f8c073ec" + "reference": "7353d4099ad5388e84737dd16994316a04f48dbf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-code/zipball/169123b3ede20a9193480c53de2a8194f8c073ec", - "reference": "169123b3ede20a9193480c53de2a8194f8c073ec", + "url": "https://api.github.com/repos/laminas/laminas-code/zipball/7353d4099ad5388e84737dd16994316a04f48dbf", + "reference": "7353d4099ad5388e84737dd16994316a04f48dbf", "shasum": "" }, "require": { - "php": "~8.1.0 || ~8.2.0" + "php": "~8.1.0 || ~8.2.0 || ~8.3.0" }, "require-dev": { - "doctrine/annotations": "^2.0.0", + "doctrine/annotations": "^2.0.1", "ext-phar": "*", - "laminas/laminas-coding-standard": "^2.3.0", - "laminas/laminas-stdlib": "^3.6.1", - "phpunit/phpunit": "^10.0.9", + "laminas/laminas-coding-standard": "^2.5.0", + "laminas/laminas-stdlib": "^3.17.0", + "phpunit/phpunit": "^10.3.3", "psalm/plugin-phpunit": "^0.18.4", - "vimeo/psalm": "^5.7.1" + "vimeo/psalm": "^5.15.0" }, "suggest": { "doctrine/annotations": "Doctrine\\Common\\Annotations >=1.0 for annotation features", @@ -2376,37 +2567,37 @@ "type": "community_bridge" } ], - "time": "2023-05-14T12:05:38+00:00" + "time": "2023-10-18T10:00:55+00:00" }, { "name": "laminas/laminas-escaper", - "version": "2.12.0", + "version": "2.13.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-escaper.git", - "reference": "ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490" + "reference": "af459883f4018d0f8a0c69c7a209daef3bf973ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490", - "reference": "ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490", + "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/af459883f4018d0f8a0c69c7a209daef3bf973ba", + "reference": "af459883f4018d0f8a0c69c7a209daef3bf973ba", "shasum": "" }, "require": { "ext-ctype": "*", "ext-mbstring": "*", - "php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0" + "php": "~8.1.0 || ~8.2.0 || ~8.3.0" }, "conflict": { "zendframework/zend-escaper": "*" }, "require-dev": { - "infection/infection": "^0.26.6", - "laminas/laminas-coding-standard": "~2.4.0", + "infection/infection": "^0.27.0", + "laminas/laminas-coding-standard": "~2.5.0", "maglnet/composer-require-checker": "^3.8.0", - "phpunit/phpunit": "^9.5.18", - "psalm/plugin-phpunit": "^0.17.0", - "vimeo/psalm": "^4.22.0" + "phpunit/phpunit": "^9.6.7", + "psalm/plugin-phpunit": "^0.18.4", + "vimeo/psalm": "^5.9" }, "type": "library", "autoload": { @@ -2438,20 +2629,20 @@ "type": "community_bridge" } ], - "time": "2022-10-10T10:11:09+00:00" + "time": "2023-10-10T08:35:13+00:00" }, { "name": "league/flysystem", - "version": "3.15.1", + "version": "3.23.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "a141d430414fcb8bf797a18716b09f759a385bed" + "reference": "d4ad81e2b67396e33dc9d7e54ec74ccf73151dcc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/a141d430414fcb8bf797a18716b09f759a385bed", - "reference": "a141d430414fcb8bf797a18716b09f759a385bed", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/d4ad81e2b67396e33dc9d7e54ec74ccf73151dcc", + "reference": "d4ad81e2b67396e33dc9d7e54ec74ccf73151dcc", "shasum": "" }, "require": { @@ -2460,6 +2651,8 @@ "php": "^8.0.2" }, "conflict": { + "async-aws/core": "<1.19.0", + "async-aws/s3": "<1.14.0", "aws/aws-sdk-php": "3.209.31 || 3.210.0", "guzzlehttp/guzzle": "<7.0", "guzzlehttp/ringphp": "<1.1.1", @@ -2467,8 +2660,8 @@ "symfony/http-client": "<5.2" }, "require-dev": { - "async-aws/s3": "^1.5", - "async-aws/simple-s3": "^1.1", + "async-aws/s3": "^1.5 || ^2.0", + "async-aws/simple-s3": "^1.1 || ^2.0", "aws/aws-sdk-php": "^3.220.0", "composer/semver": "^3.0", "ext-fileinfo": "*", @@ -2477,9 +2670,9 @@ "friendsofphp/php-cs-fixer": "^3.5", "google/cloud-storage": "^1.23", "microsoft/azure-storage-blob": "^1.1", - "phpseclib/phpseclib": "^3.0.14", - "phpstan/phpstan": "^0.12.26", - "phpunit/phpunit": "^9.5.11", + "phpseclib/phpseclib": "^3.0.34", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.5.11|^10.0", "sabre/dav": "^4.3.1" }, "type": "library", @@ -2514,7 +2707,7 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/3.15.1" + "source": "https://github.com/thephpleague/flysystem/tree/3.23.0" }, "funding": [ { @@ -2526,20 +2719,20 @@ "type": "github" } ], - "time": "2023-05-04T09:04:26+00:00" + "time": "2023-12-04T10:16:17+00:00" }, { "name": "league/flysystem-local", - "version": "3.15.0", + "version": "3.23.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem-local.git", - "reference": "543f64c397fefdf9cfeac443ffb6beff602796b3" + "reference": "5cf046ba5f059460e86a997c504dd781a39a109b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/543f64c397fefdf9cfeac443ffb6beff602796b3", - "reference": "543f64c397fefdf9cfeac443ffb6beff602796b3", + "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/5cf046ba5f059460e86a997c504dd781a39a109b", + "reference": "5cf046ba5f059460e86a997c504dd781a39a109b", "shasum": "" }, "require": { @@ -2574,7 +2767,7 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem-local/issues", - "source": "https://github.com/thephpleague/flysystem-local/tree/3.15.0" + "source": "https://github.com/thephpleague/flysystem-local/tree/3.23.0" }, "funding": [ { @@ -2586,30 +2779,30 @@ "type": "github" } ], - "time": "2023-05-02T20:02:14+00:00" + "time": "2023-12-04T10:14:46+00:00" }, { "name": "league/mime-type-detection", - "version": "1.11.0", + "version": "1.14.0", "source": { "type": "git", "url": "https://github.com/thephpleague/mime-type-detection.git", - "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd" + "reference": "b6a5854368533df0295c5761a0253656a2e52d9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ff6248ea87a9f116e78edd6002e39e5128a0d4dd", - "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/b6a5854368533df0295c5761a0253656a2e52d9e", + "reference": "b6a5854368533df0295c5761a0253656a2e52d9e", "shasum": "" }, "require": { "ext-fileinfo": "*", - "php": "^7.2 || ^8.0" + "php": "^7.4 || ^8.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.2", "phpstan/phpstan": "^0.12.68", - "phpunit/phpunit": "^8.5.8 || ^9.3" + "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0" }, "type": "library", "autoload": { @@ -2630,7 +2823,7 @@ "description": "Mime-type detection for Flysystem", "support": { "issues": "https://github.com/thephpleague/mime-type-detection/issues", - "source": "https://github.com/thephpleague/mime-type-detection/tree/1.11.0" + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.14.0" }, "funding": [ { @@ -2642,7 +2835,7 @@ "type": "tidelift" } ], - "time": "2022-04-17T13:12:02+00:00" + "time": "2023-10-17T14:13:20+00:00" }, { "name": "league/oauth2-client", @@ -2716,16 +2909,16 @@ }, { "name": "lorenzo/pinky", - "version": "1.0.9", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/lorenzo/pinky.git", - "reference": "f890472e4a25f89591f176aa03d9588a9d3332a7" + "reference": "e1b1bdb2c132b8a7ba32bca64d2443f646ddbd17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lorenzo/pinky/zipball/f890472e4a25f89591f176aa03d9588a9d3332a7", - "reference": "f890472e4a25f89591f176aa03d9588a9d3332a7", + "url": "https://api.github.com/repos/lorenzo/pinky/zipball/e1b1bdb2c132b8a7ba32bca64d2443f646ddbd17", + "reference": "e1b1bdb2c132b8a7ba32bca64d2443f646ddbd17", "shasum": "" }, "require": { @@ -2763,9 +2956,9 @@ ], "support": { "issues": "https://github.com/lorenzo/pinky/issues", - "source": "https://github.com/lorenzo/pinky/tree/1.0.9" + "source": "https://github.com/lorenzo/pinky/tree/1.1.0" }, - "time": "2023-01-12T16:15:52+00:00" + "time": "2023-07-31T13:36:50+00:00" }, { "name": "michaeldegroot/doctrine-encrypt-bundle", @@ -2827,16 +3020,16 @@ }, { "name": "monolog/monolog", - "version": "3.3.1", + "version": "3.5.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "9b5daeaffce5b926cac47923798bba91059e60e2" + "reference": "c915e2634718dbc8a4a15c61b0e62e7a44e14448" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/9b5daeaffce5b926cac47923798bba91059e60e2", - "reference": "9b5daeaffce5b926cac47923798bba91059e60e2", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c915e2634718dbc8a4a15c61b0e62e7a44e14448", + "reference": "c915e2634718dbc8a4a15c61b0e62e7a44e14448", "shasum": "" }, "require": { @@ -2851,7 +3044,7 @@ "doctrine/couchdb": "~1.0@dev", "elasticsearch/elasticsearch": "^7 || ^8", "ext-json": "*", - "graylog2/gelf-php": "^1.4.2 || ^2@dev", + "graylog2/gelf-php": "^1.4.2 || ^2.0", "guzzlehttp/guzzle": "^7.4.5", "guzzlehttp/psr7": "^2.2", "mongodb/mongodb": "^1.8", @@ -2859,7 +3052,7 @@ "phpstan/phpstan": "^1.9", "phpstan/phpstan-deprecation-rules": "^1.0", "phpstan/phpstan-strict-rules": "^1.4", - "phpunit/phpunit": "^9.5.26", + "phpunit/phpunit": "^10.1", "predis/predis": "^1.1 || ^2", "ruflin/elastica": "^7", "symfony/mailer": "^5.4 || ^6", @@ -2912,7 +3105,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/3.3.1" + "source": "https://github.com/Seldaek/monolog/tree/3.5.0" }, "funding": [ { @@ -2924,7 +3117,7 @@ "type": "tidelift" } ], - "time": "2023-02-06T13:46:10+00:00" + "time": "2023-10-27T15:32:31+00:00" }, { "name": "nicoswd/php-gpg", @@ -3065,16 +3258,16 @@ }, { "name": "oneup/flysystem-bundle", - "version": "4.7.0", + "version": "4.9.0", "source": { "type": "git", "url": "https://github.com/1up-lab/OneupFlysystemBundle.git", - "reference": "0f0d1ff58cbcae59fd4f083bcd1f4ec8160aa9f6" + "reference": "9e317a1345533eb45a61fa68ec9933dd4a3436c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/1up-lab/OneupFlysystemBundle/zipball/0f0d1ff58cbcae59fd4f083bcd1f4ec8160aa9f6", - "reference": "0f0d1ff58cbcae59fd4f083bcd1f4ec8160aa9f6", + "url": "https://api.github.com/repos/1up-lab/OneupFlysystemBundle/zipball/9e317a1345533eb45a61fa68ec9933dd4a3436c5", + "reference": "9e317a1345533eb45a61fa68ec9933dd4a3436c5", "shasum": "" }, "require": { @@ -3149,9 +3342,9 @@ ], "support": { "issues": "https://github.com/1up-lab/OneupFlysystemBundle/issues", - "source": "https://github.com/1up-lab/OneupFlysystemBundle/tree/4.7.0" + "source": "https://github.com/1up-lab/OneupFlysystemBundle/tree/4.9.0" }, - "time": "2023-05-14T10:52:16+00:00" + "time": "2023-08-08T07:51:09+00:00" }, { "name": "paragonie/constant_time_encoding", @@ -3631,16 +3824,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.7.2", + "version": "1.7.3", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "b2fe4d22a5426f38e014855322200b97b5362c0d" + "reference": "3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b2fe4d22a5426f38e014855322200b97b5362c0d", - "reference": "b2fe4d22a5426f38e014855322200b97b5362c0d", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419", + "reference": "3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419", "shasum": "" }, "require": { @@ -3683,9 +3876,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.7.2" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.7.3" }, - "time": "2023-05-30T18:13:47+00:00" + "time": "2023-08-12T11:01:26+00:00" }, { "name": "phpoffice/phpword", @@ -3797,16 +3990,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "2.0.42", + "version": "2.0.45", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "665d289f59e646a259ebf13f29be7f6f54cab24b" + "reference": "28d8f438a0064c9de80857e3270d071495544640" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/665d289f59e646a259ebf13f29be7f6f54cab24b", - "reference": "665d289f59e646a259ebf13f29be7f6f54cab24b", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/28d8f438a0064c9de80857e3270d071495544640", + "reference": "28d8f438a0064c9de80857e3270d071495544640", "shasum": "" }, "require": { @@ -3887,7 +4080,7 @@ ], "support": { "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/2.0.42" + "source": "https://github.com/phpseclib/phpseclib/tree/2.0.45" }, "funding": [ { @@ -3903,26 +4096,27 @@ "type": "tidelift" } ], - "time": "2023-03-06T12:45:53+00:00" + "time": "2023-09-15T20:55:47+00:00" }, { "name": "phpstan/phpdoc-parser", - "version": "1.21.3", + "version": "1.24.4", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "b0c366dd2cea79407d635839d25423ba07c55dd6" + "reference": "6bd0c26f3786cd9b7c359675cb789e35a8e07496" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/b0c366dd2cea79407d635839d25423ba07c55dd6", - "reference": "b0c366dd2cea79407d635839d25423ba07c55dd6", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/6bd0c26f3786cd9b7c359675cb789e35a8e07496", + "reference": "6bd0c26f3786cd9b7c359675cb789e35a8e07496", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "require-dev": { + "doctrine/annotations": "^2.0", "nikic/php-parser": "^4.15", "php-parallel-lint/php-parallel-lint": "^1.2", "phpstan/extension-installer": "^1.0", @@ -3947,9 +4141,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.21.3" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.4" }, - "time": "2023-05-29T19:31:28+00:00" + "time": "2023-11-26T18:29:22+00:00" }, { "name": "psr/cache", @@ -4105,16 +4299,16 @@ }, { "name": "psr/http-client", - "version": "1.0.2", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/php-fig/http-client.git", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31" + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31", - "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", "shasum": "" }, "require": { @@ -4151,9 +4345,9 @@ "psr-18" ], "support": { - "source": "https://github.com/php-fig/http-client/tree/1.0.2" + "source": "https://github.com/php-fig/http-client" }, - "time": "2023-04-10T20:12:12+00:00" + "time": "2023-09-23T14:17:50+00:00" }, { "name": "psr/http-factory", @@ -4604,6 +4798,81 @@ }, "time": "2021-06-21T10:16:52+00:00" }, + { + "name": "stof/doctrine-extensions-bundle", + "version": "v1.9.0", + "source": { + "type": "git", + "url": "https://github.com/stof/StofDoctrineExtensionsBundle.git", + "reference": "eb677bf8aa05d741029dc4874e1884498236d531" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/stof/StofDoctrineExtensionsBundle/zipball/eb677bf8aa05d741029dc4874e1884498236d531", + "reference": "eb677bf8aa05d741029dc4874e1884498236d531", + "shasum": "" + }, + "require": { + "gedmo/doctrine-extensions": "^3.5.0", + "php": "^7.2.5 || ^8.0", + "symfony/cache": "^5.4 || ^6.0", + "symfony/config": "^5.4 || ^6.0", + "symfony/dependency-injection": "^5.4 || ^6.0", + "symfony/event-dispatcher": "^5.4 || ^6.0", + "symfony/http-kernel": "^5.4 || ^6.0" + }, + "require-dev": { + "symfony/mime": "^5.4 || ^6.0", + "symfony/phpunit-bridge": "^v5.4 || ^6.0", + "symfony/security-core": "^5.4 || ^6.0" + }, + "suggest": { + "doctrine/doctrine-bundle": "to use the ORM extensions", + "doctrine/mongodb-odm-bundle": "to use the MongoDB ODM extensions", + "symfony/mime": "To use the Mime component integration for Uploadable" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Stof\\DoctrineExtensionsBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christophe Coevoet", + "email": "stof@notk.org" + } + ], + "description": "Integration of the gedmo/doctrine-extensions with Symfony", + "homepage": "https://github.com/stof/StofDoctrineExtensionsBundle", + "keywords": [ + "behaviors", + "doctrine2", + "extensions", + "gedmo", + "loggable", + "nestedset", + "sluggable", + "sortable", + "timestampable", + "translatable", + "tree" + ], + "support": { + "issues": "https://github.com/stof/StofDoctrineExtensionsBundle/issues", + "source": "https://github.com/stof/StofDoctrineExtensionsBundle/tree/v1.9.0" + }, + "time": "2023-08-31T08:08:51+00:00" + }, { "name": "symfony/apache-pack", "version": "v1.0.1", @@ -4704,16 +4973,16 @@ }, { "name": "symfony/cache", - "version": "v6.2.10", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "1ce7ed8e7ca6948892b6a3a52bb60cf2b04f7c94" + "reference": "c47f4a9e9d172359516c35490d6b649d2d44c50d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/1ce7ed8e7ca6948892b6a3a52bb60cf2b04f7c94", - "reference": "1ce7ed8e7ca6948892b6a3a52bb60cf2b04f7c94", + "url": "https://api.github.com/repos/symfony/cache/zipball/c47f4a9e9d172359516c35490d6b649d2d44c50d", + "reference": "c47f4a9e9d172359516c35490d6b649d2d44c50d", "shasum": "" }, "require": { @@ -4780,7 +5049,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v6.2.10" + "source": "https://github.com/symfony/cache/tree/v6.2.13" }, "funding": [ { @@ -4796,20 +5065,20 @@ "type": "tidelift" } ], - "time": "2023-04-21T15:42:15+00:00" + "time": "2023-07-27T16:12:47+00:00" }, { "name": "symfony/cache-contracts", - "version": "v3.3.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/cache-contracts.git", - "reference": "ad945640ccc0ae6e208bcea7d7de4b39b569896b" + "reference": "1d74b127da04ffa87aa940abe15446fa89653778" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/ad945640ccc0ae6e208bcea7d7de4b39b569896b", - "reference": "ad945640ccc0ae6e208bcea7d7de4b39b569896b", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/1d74b127da04ffa87aa940abe15446fa89653778", + "reference": "1d74b127da04ffa87aa940abe15446fa89653778", "shasum": "" }, "require": { @@ -4856,7 +5125,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/cache-contracts/tree/v3.3.0" + "source": "https://github.com/symfony/cache-contracts/tree/v3.4.0" }, "funding": [ { @@ -4872,20 +5141,20 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2023-09-25T12:52:38+00:00" }, { "name": "symfony/config", - "version": "v6.2.7", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "249271da6f545d6579e0663374f8249a80be2893" + "reference": "26a3db700baf625d86d0ec669d893ed9da3fa868" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/249271da6f545d6579e0663374f8249a80be2893", - "reference": "249271da6f545d6579e0663374f8249a80be2893", + "url": "https://api.github.com/repos/symfony/config/zipball/26a3db700baf625d86d0ec669d893ed9da3fa868", + "reference": "26a3db700baf625d86d0ec669d893ed9da3fa868", "shasum": "" }, "require": { @@ -4933,7 +5202,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v6.2.7" + "source": "https://github.com/symfony/config/tree/v6.2.13" }, "funding": [ { @@ -4949,20 +5218,20 @@ "type": "tidelift" } ], - "time": "2023-02-14T08:44:56+00:00" + "time": "2023-07-19T20:22:10+00:00" }, { "name": "symfony/console", - "version": "v6.2.11", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "5aa03db8ef0a5457c316ec580e69562d97734c77" + "reference": "e30dfbceadb96cb67605b69b1277c41332fae185" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/5aa03db8ef0a5457c316ec580e69562d97734c77", - "reference": "5aa03db8ef0a5457c316ec580e69562d97734c77", + "url": "https://api.github.com/repos/symfony/console/zipball/e30dfbceadb96cb67605b69b1277c41332fae185", + "reference": "e30dfbceadb96cb67605b69b1277c41332fae185", "shasum": "" }, "require": { @@ -5029,7 +5298,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.2.11" + "source": "https://github.com/symfony/console/tree/v6.2.13" }, "funding": [ { @@ -5045,20 +5314,20 @@ "type": "tidelift" } ], - "time": "2023-05-26T08:16:21+00:00" + "time": "2023-07-19T20:17:04+00:00" }, { "name": "symfony/css-selector", - "version": "v6.2.7", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "aedf3cb0f5b929ec255d96bbb4909e9932c769e0" + "reference": "61444c8e4cbe80217a233364d8254fa6df247f50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/aedf3cb0f5b929ec255d96bbb4909e9932c769e0", - "reference": "aedf3cb0f5b929ec255d96bbb4909e9932c769e0", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/61444c8e4cbe80217a233364d8254fa6df247f50", + "reference": "61444c8e4cbe80217a233364d8254fa6df247f50", "shasum": "" }, "require": { @@ -5094,7 +5363,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v6.2.7" + "source": "https://github.com/symfony/css-selector/tree/v6.2.13" }, "funding": [ { @@ -5110,20 +5379,20 @@ "type": "tidelift" } ], - "time": "2023-02-14T08:44:56+00:00" + "time": "2023-07-12T15:50:46+00:00" }, { "name": "symfony/dependency-injection", - "version": "v6.2.11", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "2dff40fdc5ff1647c5561eb8e4fe574bc58c849d" + "reference": "d977404486b419bedf450739a9f8992a88c1d6e3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/2dff40fdc5ff1647c5561eb8e4fe574bc58c849d", - "reference": "2dff40fdc5ff1647c5561eb8e4fe574bc58c849d", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/d977404486b419bedf450739a9f8992a88c1d6e3", + "reference": "d977404486b419bedf450739a9f8992a88c1d6e3", "shasum": "" }, "require": { @@ -5181,7 +5450,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v6.2.11" + "source": "https://github.com/symfony/dependency-injection/tree/v6.2.13" }, "funding": [ { @@ -5197,11 +5466,11 @@ "type": "tidelift" } ], - "time": "2023-05-05T15:52:57+00:00" + "time": "2023-07-19T20:17:04+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.3.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", @@ -5248,7 +5517,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" }, "funding": [ { @@ -5268,16 +5537,16 @@ }, { "name": "symfony/doctrine-bridge", - "version": "v6.2.11", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "db48a583e5e38e152af8a60c2677c8de76367701" + "reference": "98b275bff5fe26a6b450172b1f28956aed6c3422" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/db48a583e5e38e152af8a60c2677c8de76367701", - "reference": "db48a583e5e38e152af8a60c2677c8de76367701", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/98b275bff5fe26a6b450172b1f28956aed6c3422", + "reference": "98b275bff5fe26a6b450172b1f28956aed6c3422", "shasum": "" }, "require": { @@ -5301,7 +5570,7 @@ "symfony/property-info": "<5.4", "symfony/security-bundle": "<5.4", "symfony/security-core": "<6.0", - "symfony/validator": "<5.4" + "symfony/validator": "<5.4.25|>=6,<6.2.12|>=6.3,<6.3.1" }, "require-dev": { "doctrine/annotations": "^1.10.4|^2", @@ -5325,7 +5594,7 @@ "symfony/stopwatch": "^5.4|^6.0", "symfony/translation": "^5.4|^6.0", "symfony/uid": "^5.4|^6.0", - "symfony/validator": "^5.4|^6.0", + "symfony/validator": "^5.4.25|~6.2.12|^6.3.1", "symfony/var-dumper": "^5.4|^6.0" }, "suggest": { @@ -5362,7 +5631,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v6.2.11" + "source": "https://github.com/symfony/doctrine-bridge/tree/v6.2.13" }, "funding": [ { @@ -5378,7 +5647,7 @@ "type": "tidelift" } ], - "time": "2023-05-25T13:08:43+00:00" + "time": "2023-07-20T14:50:55+00:00" }, { "name": "symfony/dotenv", @@ -5456,16 +5725,16 @@ }, { "name": "symfony/error-handler", - "version": "v6.2.11", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "e847ba47e7a8f9708082990cb40ab4ff0440a11e" + "reference": "69f92a208efc45a98fa240d0792d210ef5eef987" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/e847ba47e7a8f9708082990cb40ab4ff0440a11e", - "reference": "e847ba47e7a8f9708082990cb40ab4ff0440a11e", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/69f92a208efc45a98fa240d0792d210ef5eef987", + "reference": "69f92a208efc45a98fa240d0792d210ef5eef987", "shasum": "" }, "require": { @@ -5507,7 +5776,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.2.11" + "source": "https://github.com/symfony/error-handler/tree/v6.2.13" }, "funding": [ { @@ -5523,20 +5792,20 @@ "type": "tidelift" } ], - "time": "2023-05-05T11:55:01+00:00" + "time": "2023-07-16T16:55:01+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v6.2.8", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "04046f35fd7d72f9646e721fc2ecb8f9c67d3339" + "reference": "a6e533212c6c298c6a4d1e892e4cdbf45ea21f1c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/04046f35fd7d72f9646e721fc2ecb8f9c67d3339", - "reference": "04046f35fd7d72f9646e721fc2ecb8f9c67d3339", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a6e533212c6c298c6a4d1e892e4cdbf45ea21f1c", + "reference": "a6e533212c6c298c6a4d1e892e4cdbf45ea21f1c", "shasum": "" }, "require": { @@ -5590,7 +5859,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.2.8" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.2.13" }, "funding": [ { @@ -5606,11 +5875,11 @@ "type": "tidelift" } ], - "time": "2023-03-20T16:06:02+00:00" + "time": "2023-07-06T06:53:05+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.3.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", @@ -5666,7 +5935,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.3.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.0" }, "funding": [ { @@ -5749,16 +6018,16 @@ }, { "name": "symfony/filesystem", - "version": "v6.2.10", + "version": "v6.2.12", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "fd588debf7d1bc16a2c84b4b3b71145d9946b894" + "reference": "b0818e7203e53540f2a5c9a5017d97897df1e9bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/fd588debf7d1bc16a2c84b4b3b71145d9946b894", - "reference": "fd588debf7d1bc16a2c84b4b3b71145d9946b894", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/b0818e7203e53540f2a5c9a5017d97897df1e9bb", + "reference": "b0818e7203e53540f2a5c9a5017d97897df1e9bb", "shasum": "" }, "require": { @@ -5792,7 +6061,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.2.10" + "source": "https://github.com/symfony/filesystem/tree/v6.2.12" }, "funding": [ { @@ -5808,20 +6077,20 @@ "type": "tidelift" } ], - "time": "2023-04-18T13:46:08+00:00" + "time": "2023-06-01T08:29:37+00:00" }, { "name": "symfony/finder", - "version": "v6.2.7", + "version": "v6.2.14", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "20808dc6631aecafbe67c186af5dcb370be3a0eb" + "reference": "8ccb900489183bd5ec3d04f92e28ee0c0af543dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/20808dc6631aecafbe67c186af5dcb370be3a0eb", - "reference": "20808dc6631aecafbe67c186af5dcb370be3a0eb", + "url": "https://api.github.com/repos/symfony/finder/zipball/8ccb900489183bd5ec3d04f92e28ee0c0af543dd", + "reference": "8ccb900489183bd5ec3d04f92e28ee0c0af543dd", "shasum": "" }, "require": { @@ -5856,7 +6125,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v6.2.7" + "source": "https://github.com/symfony/finder/tree/v6.2.14" }, "funding": [ { @@ -5872,20 +6141,20 @@ "type": "tidelift" } ], - "time": "2023-02-16T09:57:23+00:00" + "time": "2023-07-31T10:27:17+00:00" }, { "name": "symfony/flex", - "version": "v1.20.0", + "version": "v1.21.3", "source": { "type": "git", "url": "https://github.com/symfony/flex.git", - "reference": "49059a10127ac8270957e116a2251ae535d202ac" + "reference": "f96b8bf5390bb073aff773ee2aa39c64fb60e59d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/flex/zipball/49059a10127ac8270957e116a2251ae535d202ac", - "reference": "49059a10127ac8270957e116a2251ae535d202ac", + "url": "https://api.github.com/repos/symfony/flex/zipball/f96b8bf5390bb073aff773ee2aa39c64fb60e59d", + "reference": "f96b8bf5390bb073aff773ee2aa39c64fb60e59d", "shasum": "" }, "require": { @@ -5921,7 +6190,7 @@ "description": "Composer plugin for Symfony", "support": { "issues": "https://github.com/symfony/flex/issues", - "source": "https://github.com/symfony/flex/tree/v1.20.0" + "source": "https://github.com/symfony/flex/tree/v1.21.3" }, "funding": [ { @@ -5937,20 +6206,20 @@ "type": "tidelift" } ], - "time": "2023-05-26T16:25:26+00:00" + "time": "2023-12-05T14:09:05+00:00" }, { "name": "symfony/form", - "version": "v6.2.11", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/form.git", - "reference": "494e21cc84781e7557682617e7ef80f598da20dc" + "reference": "14276bc6226f75ef0482dd17a22dd773149f6af3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/form/zipball/494e21cc84781e7557682617e7ef80f598da20dc", - "reference": "494e21cc84781e7557682617e7ef80f598da20dc", + "url": "https://api.github.com/repos/symfony/form/zipball/14276bc6226f75ef0482dd17a22dd773149f6af3", + "reference": "14276bc6226f75ef0482dd17a22dd773149f6af3", "shasum": "" }, "require": { @@ -6024,7 +6293,7 @@ "description": "Allows to easily create, process and reuse HTML forms", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/form/tree/v6.2.11" + "source": "https://github.com/symfony/form/tree/v6.2.13" }, "funding": [ { @@ -6040,20 +6309,20 @@ "type": "tidelift" } ], - "time": "2023-05-25T13:08:43+00:00" + "time": "2023-07-26T17:38:53+00:00" }, { "name": "symfony/framework-bundle", - "version": "v6.2.11", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", - "reference": "c02f2298d03ab083d4036cf18b151d131a113ccd" + "reference": "331d13a47e5f1d95c0064cfa043421051af7c56b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/c02f2298d03ab083d4036cf18b151d131a113ccd", - "reference": "c02f2298d03ab083d4036cf18b151d131a113ccd", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/331d13a47e5f1d95c0064cfa043421051af7c56b", + "reference": "331d13a47e5f1d95c0064cfa043421051af7c56b", "shasum": "" }, "require": { @@ -6174,7 +6443,7 @@ "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/framework-bundle/tree/v6.2.11" + "source": "https://github.com/symfony/framework-bundle/tree/v6.2.13" }, "funding": [ { @@ -6190,20 +6459,20 @@ "type": "tidelift" } ], - "time": "2023-05-25T13:08:43+00:00" + "time": "2023-07-26T17:38:53+00:00" }, { "name": "symfony/http-client", - "version": "v6.2.11", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "39f679c12648cc43bd9f0db12cc69b82041b91a1" + "reference": "297374a399ce6852d5905d92a1351df00bb9dd10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/39f679c12648cc43bd9f0db12cc69b82041b91a1", - "reference": "39f679c12648cc43bd9f0db12cc69b82041b91a1", + "url": "https://api.github.com/repos/symfony/http-client/zipball/297374a399ce6852d5905d92a1351df00bb9dd10", + "reference": "297374a399ce6852d5905d92a1351df00bb9dd10", "shasum": "" }, "require": { @@ -6263,7 +6532,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v6.2.11" + "source": "https://github.com/symfony/http-client/tree/v6.2.13" }, "funding": [ { @@ -6279,20 +6548,20 @@ "type": "tidelift" } ], - "time": "2023-05-12T08:48:34+00:00" + "time": "2023-07-03T12:13:45+00:00" }, { "name": "symfony/http-client-contracts", - "version": "v3.3.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "3b66325d0176b4ec826bffab57c9037d759c31fb" + "reference": "1ee70e699b41909c209a0c930f11034b93578654" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/3b66325d0176b4ec826bffab57c9037d759c31fb", - "reference": "3b66325d0176b4ec826bffab57c9037d759c31fb", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/1ee70e699b41909c209a0c930f11034b93578654", + "reference": "1ee70e699b41909c209a0c930f11034b93578654", "shasum": "" }, "require": { @@ -6341,7 +6610,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v3.3.0" + "source": "https://github.com/symfony/http-client-contracts/tree/v3.4.0" }, "funding": [ { @@ -6357,20 +6626,20 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2023-07-30T20:28:31+00:00" }, { "name": "symfony/http-foundation", - "version": "v6.2.11", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "df27f4191a4292d01fd062296e09cbc8b657cb57" + "reference": "d64109065a5283c96f1ccbe2f2eeedf75ef7d490" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/df27f4191a4292d01fd062296e09cbc8b657cb57", - "reference": "df27f4191a4292d01fd062296e09cbc8b657cb57", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/d64109065a5283c96f1ccbe2f2eeedf75ef7d490", + "reference": "d64109065a5283c96f1ccbe2f2eeedf75ef7d490", "shasum": "" }, "require": { @@ -6419,7 +6688,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.2.11" + "source": "https://github.com/symfony/http-foundation/tree/v6.2.13" }, "funding": [ { @@ -6435,20 +6704,20 @@ "type": "tidelift" } ], - "time": "2023-05-19T12:39:53+00:00" + "time": "2023-07-23T21:58:00+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.2.11", + "version": "v6.2.14", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "954a1a3b178309b216261eedc735c079709e4ab3" + "reference": "d05cebbc07478d37ff1e0f0079f06298a096b870" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/954a1a3b178309b216261eedc735c079709e4ab3", - "reference": "954a1a3b178309b216261eedc735c079709e4ab3", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/d05cebbc07478d37ff1e0f0079f06298a096b870", + "reference": "d05cebbc07478d37ff1e0f0079f06298a096b870", "shasum": "" }, "require": { @@ -6531,7 +6800,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.2.11" + "source": "https://github.com/symfony/http-kernel/tree/v6.2.14" }, "funding": [ { @@ -6547,20 +6816,20 @@ "type": "tidelift" } ], - "time": "2023-05-27T21:12:52+00:00" + "time": "2023-07-31T10:40:35+00:00" }, { "name": "symfony/intl", - "version": "v6.2.10", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/intl.git", - "reference": "860c99e53149d22df1900d3aefdaeb17adb7669d" + "reference": "9f95c845f49d4467d7a8471cadd4c7c0fd2ad7a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/intl/zipball/860c99e53149d22df1900d3aefdaeb17adb7669d", - "reference": "860c99e53149d22df1900d3aefdaeb17adb7669d", + "url": "https://api.github.com/repos/symfony/intl/zipball/9f95c845f49d4467d7a8471cadd4c7c0fd2ad7a9", + "reference": "9f95c845f49d4467d7a8471cadd4c7c0fd2ad7a9", "shasum": "" }, "require": { @@ -6568,7 +6837,8 @@ }, "require-dev": { "symfony/filesystem": "^5.4|^6.0", - "symfony/finder": "^5.4|^6.0" + "symfony/finder": "^5.4|^6.0", + "symfony/var-exporter": "^5.4|^6.0" }, "type": "library", "autoload": { @@ -6612,7 +6882,7 @@ "localization" ], "support": { - "source": "https://github.com/symfony/intl/tree/v6.2.10" + "source": "https://github.com/symfony/intl/tree/v6.2.13" }, "funding": [ { @@ -6628,20 +6898,20 @@ "type": "tidelift" } ], - "time": "2023-04-14T16:23:31+00:00" + "time": "2023-07-13T14:28:09+00:00" }, { "name": "symfony/mailer", - "version": "v6.2.8", + "version": "v6.2.12", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "bfcfa015c67e19c6fdb7ca6fe70700af1e740a17" + "reference": "47cfaeba096eec5d1aee117f2acbab8e8a8573e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/bfcfa015c67e19c6fdb7ca6fe70700af1e740a17", - "reference": "bfcfa015c67e19c6fdb7ca6fe70700af1e740a17", + "url": "https://api.github.com/repos/symfony/mailer/zipball/47cfaeba096eec5d1aee117f2acbab8e8a8573e5", + "reference": "47cfaeba096eec5d1aee117f2acbab8e8a8573e5", "shasum": "" }, "require": { @@ -6691,7 +6961,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v6.2.8" + "source": "https://github.com/symfony/mailer/tree/v6.2.12" }, "funding": [ { @@ -6707,20 +6977,20 @@ "type": "tidelift" } ], - "time": "2023-03-14T15:00:05+00:00" + "time": "2023-05-29T12:46:33+00:00" }, { "name": "symfony/mime", - "version": "v6.2.10", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "b6c137fc53a9f7c4c951cd3f362b3734c7a97723" + "reference": "32f2c5f8114fd778ed00fc54f684e805d7e48508" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/b6c137fc53a9f7c4c951cd3f362b3734c7a97723", - "reference": "b6c137fc53a9f7c4c951cd3f362b3734c7a97723", + "url": "https://api.github.com/repos/symfony/mime/zipball/32f2c5f8114fd778ed00fc54f684e805d7e48508", + "reference": "32f2c5f8114fd778ed00fc54f684e805d7e48508", "shasum": "" }, "require": { @@ -6733,7 +7003,7 @@ "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", "symfony/mailer": "<5.4", - "symfony/serializer": "<6.2" + "symfony/serializer": "<6.2.13|>=6.3,<6.3.2" }, "require-dev": { "egulias/email-validator": "^2.1.10|^3.1|^4", @@ -6742,7 +7012,7 @@ "symfony/dependency-injection": "^5.4|^6.0", "symfony/property-access": "^5.4|^6.0", "symfony/property-info": "^5.4|^6.0", - "symfony/serializer": "^6.2" + "symfony/serializer": "~6.2.13|^6.3.2" }, "type": "library", "autoload": { @@ -6774,7 +7044,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v6.2.10" + "source": "https://github.com/symfony/mime/tree/v6.2.13" }, "funding": [ { @@ -6790,7 +7060,7 @@ "type": "tidelift" } ], - "time": "2023-04-19T09:54:16+00:00" + "time": "2023-07-27T06:30:34+00:00" }, { "name": "symfony/monolog-bridge", @@ -6877,30 +7147,30 @@ }, { "name": "symfony/monolog-bundle", - "version": "v3.8.0", + "version": "v3.10.0", "source": { "type": "git", "url": "https://github.com/symfony/monolog-bundle.git", - "reference": "a41bbcdc1105603b6d73a7d9a43a3788f8e0fb7d" + "reference": "414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/monolog-bundle/zipball/a41bbcdc1105603b6d73a7d9a43a3788f8e0fb7d", - "reference": "a41bbcdc1105603b6d73a7d9a43a3788f8e0fb7d", + "url": "https://api.github.com/repos/symfony/monolog-bundle/zipball/414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181", + "reference": "414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181", "shasum": "" }, "require": { - "monolog/monolog": "^1.22 || ^2.0 || ^3.0", - "php": ">=7.1.3", - "symfony/config": "~4.4 || ^5.0 || ^6.0", - "symfony/dependency-injection": "^4.4 || ^5.0 || ^6.0", - "symfony/http-kernel": "~4.4 || ^5.0 || ^6.0", - "symfony/monolog-bridge": "~4.4 || ^5.0 || ^6.0" + "monolog/monolog": "^1.25.1 || ^2.0 || ^3.0", + "php": ">=7.2.5", + "symfony/config": "^5.4 || ^6.0 || ^7.0", + "symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0", + "symfony/http-kernel": "^5.4 || ^6.0 || ^7.0", + "symfony/monolog-bridge": "^5.4 || ^6.0 || ^7.0" }, "require-dev": { - "symfony/console": "~4.4 || ^5.0 || ^6.0", - "symfony/phpunit-bridge": "^5.2 || ^6.0", - "symfony/yaml": "~4.4 || ^5.0 || ^6.0" + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/phpunit-bridge": "^6.3 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" }, "type": "symfony-bundle", "extra": { @@ -6938,7 +7208,7 @@ ], "support": { "issues": "https://github.com/symfony/monolog-bundle/issues", - "source": "https://github.com/symfony/monolog-bundle/tree/v3.8.0" + "source": "https://github.com/symfony/monolog-bundle/tree/v3.10.0" }, "funding": [ { @@ -6954,7 +7224,7 @@ "type": "tidelift" } ], - "time": "2022-05-10T14:24:36+00:00" + "time": "2023-11-06T17:08:13+00:00" }, { "name": "symfony/options-resolver", @@ -7097,16 +7367,16 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354" + "reference": "875e90aeea2777b6f135677f618529449334a612" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612", + "reference": "875e90aeea2777b6f135677f618529449334a612", "shasum": "" }, "require": { @@ -7118,7 +7388,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -7158,7 +7428,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0" }, "funding": [ { @@ -7174,20 +7444,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-intl-icu", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-icu.git", - "reference": "a3d9148e2c363588e05abbdd4ee4f971f0a5330c" + "reference": "e46b4da57951a16053cd751f63f4a24292788157" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/a3d9148e2c363588e05abbdd4ee4f971f0a5330c", - "reference": "a3d9148e2c363588e05abbdd4ee4f971f0a5330c", + "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/e46b4da57951a16053cd751f63f4a24292788157", + "reference": "e46b4da57951a16053cd751f63f4a24292788157", "shasum": "" }, "require": { @@ -7199,7 +7469,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -7245,7 +7515,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.28.0" }, "funding": [ { @@ -7261,20 +7531,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-03-21T17:27:24+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "639084e360537a19f9ee352433b84ce831f3d2da" + "reference": "ecaafce9f77234a6a449d29e49267ba10499116d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/639084e360537a19f9ee352433b84ce831f3d2da", - "reference": "639084e360537a19f9ee352433b84ce831f3d2da", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/ecaafce9f77234a6a449d29e49267ba10499116d", + "reference": "ecaafce9f77234a6a449d29e49267ba10499116d", "shasum": "" }, "require": { @@ -7288,7 +7558,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -7332,7 +7602,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.28.0" }, "funding": [ { @@ -7348,20 +7618,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:30:37+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", "shasum": "" }, "require": { @@ -7373,7 +7643,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -7416,7 +7686,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0" }, "funding": [ { @@ -7432,20 +7702,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + "reference": "42292d99c55abe617799667f454222c54c60e229" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", + "reference": "42292d99c55abe617799667f454222c54c60e229", "shasum": "" }, "require": { @@ -7460,7 +7730,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -7499,7 +7769,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" }, "funding": [ { @@ -7515,20 +7785,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-07-28T09:04:16+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "869329b1e9894268a8a61dabb69153029b7a8c97" + "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97", - "reference": "869329b1e9894268a8a61dabb69153029b7a8c97", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/70f4aebd92afca2f865444d30a4d2151c13c3179", + "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179", "shasum": "" }, "require": { @@ -7537,7 +7807,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -7575,7 +7845,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-php72/tree/v1.28.0" }, "funding": [ { @@ -7591,20 +7861,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", "shasum": "" }, "require": { @@ -7613,7 +7883,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -7658,7 +7928,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" }, "funding": [ { @@ -7674,20 +7944,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/process", - "version": "v6.2.11", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "97ae9721bead9d1a39b5650e2f4b7834b93b539c" + "reference": "1603ae32487981c11b8d0bf5d7551b8b00f5a99b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/97ae9721bead9d1a39b5650e2f4b7834b93b539c", - "reference": "97ae9721bead9d1a39b5650e2f4b7834b93b539c", + "url": "https://api.github.com/repos/symfony/process/zipball/1603ae32487981c11b8d0bf5d7551b8b00f5a99b", + "reference": "1603ae32487981c11b8d0bf5d7551b8b00f5a99b", "shasum": "" }, "require": { @@ -7719,7 +7989,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.2.11" + "source": "https://github.com/symfony/process/tree/v6.2.13" }, "funding": [ { @@ -7735,20 +8005,20 @@ "type": "tidelift" } ], - "time": "2023-05-19T07:42:48+00:00" + "time": "2023-07-12T15:50:46+00:00" }, { "name": "symfony/property-access", - "version": "v6.2.11", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "77442a960c3bc2cacc3d1cd300908a31a2eb30ad" + "reference": "9b118241be87010f4cec8dbc26879994e29bff3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/77442a960c3bc2cacc3d1cd300908a31a2eb30ad", - "reference": "77442a960c3bc2cacc3d1cd300908a31a2eb30ad", + "url": "https://api.github.com/repos/symfony/property-access/zipball/9b118241be87010f4cec8dbc26879994e29bff3e", + "reference": "9b118241be87010f4cec8dbc26879994e29bff3e", "shasum": "" }, "require": { @@ -7799,7 +8069,7 @@ "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v6.2.11" + "source": "https://github.com/symfony/property-access/tree/v6.2.13" }, "funding": [ { @@ -7815,7 +8085,7 @@ "type": "tidelift" } ], - "time": "2023-05-09T22:46:35+00:00" + "time": "2023-07-13T15:25:49+00:00" }, { "name": "symfony/property-info", @@ -7974,16 +8244,16 @@ }, { "name": "symfony/routing", - "version": "v6.2.8", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "69062e2823f03b82265d73a966999660f0e1e404" + "reference": "1e54cc8e769d9aba461f0848bcbd17c81696bec9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/69062e2823f03b82265d73a966999660f0e1e404", - "reference": "69062e2823f03b82265d73a966999660f0e1e404", + "url": "https://api.github.com/repos/symfony/routing/zipball/1e54cc8e769d9aba461f0848bcbd17c81696bec9", + "reference": "1e54cc8e769d9aba461f0848bcbd17c81696bec9", "shasum": "" }, "require": { @@ -8042,7 +8312,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v6.2.8" + "source": "https://github.com/symfony/routing/tree/v6.2.13" }, "funding": [ { @@ -8058,20 +8328,20 @@ "type": "tidelift" } ], - "time": "2023-03-14T15:00:05+00:00" + "time": "2023-07-24T13:51:53+00:00" }, { "name": "symfony/runtime", - "version": "v6.2.8", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/runtime.git", - "reference": "f8b0751b33888329be8f8f0481bb81d279ec4157" + "reference": "ed451a8863b33b487ae328cf3a6fae8d4f004e7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/runtime/zipball/f8b0751b33888329be8f8f0481bb81d279ec4157", - "reference": "f8b0751b33888329be8f8f0481bb81d279ec4157", + "url": "https://api.github.com/repos/symfony/runtime/zipball/ed451a8863b33b487ae328cf3a6fae8d4f004e7e", + "reference": "ed451a8863b33b487ae328cf3a6fae8d4f004e7e", "shasum": "" }, "require": { @@ -8083,7 +8353,7 @@ }, "require-dev": { "composer/composer": "^1.0.2|^2.0", - "symfony/console": "^5.4|^6.0", + "symfony/console": "^5.4.9|^6.0.9", "symfony/dotenv": "^5.4|^6.0", "symfony/http-foundation": "^5.4|^6.0", "symfony/http-kernel": "^5.4|^6.0" @@ -8121,7 +8391,7 @@ "runtime" ], "support": { - "source": "https://github.com/symfony/runtime/tree/v6.2.8" + "source": "https://github.com/symfony/runtime/tree/v6.2.13" }, "funding": [ { @@ -8137,20 +8407,20 @@ "type": "tidelift" } ], - "time": "2023-03-14T15:48:35+00:00" + "time": "2023-07-16T16:55:01+00:00" }, { "name": "symfony/security-bundle", - "version": "v6.2.11", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/security-bundle.git", - "reference": "43faa9bc3c7ee7e97ffa53320947a074971d159b" + "reference": "76ebbcda13831c183642fca36ee601c9f1255d15" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-bundle/zipball/43faa9bc3c7ee7e97ffa53320947a074971d159b", - "reference": "43faa9bc3c7ee7e97ffa53320947a074971d159b", + "url": "https://api.github.com/repos/symfony/security-bundle/zipball/76ebbcda13831c183642fca36ee601c9f1255d15", + "reference": "76ebbcda13831c183642fca36ee601c9f1255d15", "shasum": "" }, "require": { @@ -8221,7 +8491,7 @@ "description": "Provides a tight integration of the Security component into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-bundle/tree/v6.2.11" + "source": "https://github.com/symfony/security-bundle/tree/v6.2.13" }, "funding": [ { @@ -8237,7 +8507,7 @@ "type": "tidelift" } ], - "time": "2023-05-26T15:38:40+00:00" + "time": "2023-06-29T10:01:21+00:00" }, { "name": "symfony/security-core", @@ -8332,16 +8602,16 @@ }, { "name": "symfony/security-csrf", - "version": "v6.2.7", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/security-csrf.git", - "reference": "6cce7efdce68e0670d2f19acebc21dcd0798e333" + "reference": "5f2850e2dcd003424f2bb36f11522c5820fea561" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-csrf/zipball/6cce7efdce68e0670d2f19acebc21dcd0798e333", - "reference": "6cce7efdce68e0670d2f19acebc21dcd0798e333", + "url": "https://api.github.com/repos/symfony/security-csrf/zipball/5f2850e2dcd003424f2bb36f11522c5820fea561", + "reference": "5f2850e2dcd003424f2bb36f11522c5820fea561", "shasum": "" }, "require": { @@ -8383,7 +8653,7 @@ "description": "Symfony Security Component - CSRF Library", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-csrf/tree/v6.2.7" + "source": "https://github.com/symfony/security-csrf/tree/v6.2.13" }, "funding": [ { @@ -8399,20 +8669,20 @@ "type": "tidelift" } ], - "time": "2023-02-16T09:57:23+00:00" + "time": "2023-07-05T08:41:15+00:00" }, { "name": "symfony/security-http", - "version": "v6.2.11", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/security-http.git", - "reference": "ef5d875c6d0d141c7247fab24bd55a94e02b8478" + "reference": "d6231dbabc17f24caa7ae174a9e37518caaf987a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-http/zipball/ef5d875c6d0d141c7247fab24bd55a94e02b8478", - "reference": "ef5d875c6d0d141c7247fab24bd55a94e02b8478", + "url": "https://api.github.com/repos/symfony/security-http/zipball/d6231dbabc17f24caa7ae174a9e37518caaf987a", + "reference": "d6231dbabc17f24caa7ae174a9e37518caaf987a", "shasum": "" }, "require": { @@ -8468,7 +8738,7 @@ "description": "Symfony Security Component - HTTP Integration", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-http/tree/v6.2.11" + "source": "https://github.com/symfony/security-http/tree/v6.2.13" }, "funding": [ { @@ -8484,20 +8754,20 @@ "type": "tidelift" } ], - "time": "2023-05-19T15:58:23+00:00" + "time": "2023-07-13T14:28:09+00:00" }, { "name": "symfony/serializer", - "version": "v6.2.11", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "7777df2b00dd2f3ee332b4b000c4b21743df64b7" + "reference": "19083104e606ecf8a48baa8ed310c7a073887037" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/7777df2b00dd2f3ee332b4b000c4b21743df64b7", - "reference": "7777df2b00dd2f3ee332b4b000c4b21743df64b7", + "url": "https://api.github.com/repos/symfony/serializer/zipball/19083104e606ecf8a48baa8ed310c7a073887037", + "reference": "19083104e606ecf8a48baa8ed310c7a073887037", "shasum": "" }, "require": { @@ -8510,7 +8780,7 @@ "phpdocumentor/type-resolver": "<1.4.0", "symfony/dependency-injection": "<5.4", "symfony/property-access": "<5.4", - "symfony/property-info": "<5.4", + "symfony/property-info": "<5.4.24|>=6,<6.2.11", "symfony/uid": "<5.4", "symfony/yaml": "<5.4" }, @@ -8527,7 +8797,7 @@ "symfony/http-kernel": "^5.4|^6.0", "symfony/mime": "^5.4|^6.0", "symfony/property-access": "^5.4|^6.0", - "symfony/property-info": "^5.4|^6.0", + "symfony/property-info": "^5.4.24|^6.2.11", "symfony/uid": "^5.4|^6.0", "symfony/validator": "^5.4|^6.0", "symfony/var-dumper": "^5.4|^6.0", @@ -8569,7 +8839,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v6.2.11" + "source": "https://github.com/symfony/serializer/tree/v6.2.13" }, "funding": [ { @@ -8585,20 +8855,20 @@ "type": "tidelift" } ], - "time": "2023-05-19T07:59:25+00:00" + "time": "2023-07-27T16:18:16+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.3.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4" + "reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", - "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/b3313c2dbffaf71c8de2934e2ea56ed2291a3838", + "reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838", "shasum": "" }, "require": { @@ -8651,7 +8921,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.3.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.4.0" }, "funding": [ { @@ -8667,20 +8937,20 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2023-07-30T20:28:31+00:00" }, { "name": "symfony/stimulus-bundle", - "version": "v2.13.2", + "version": "v2.13.3", "source": { "type": "git", "url": "https://github.com/symfony/stimulus-bundle.git", - "reference": "d7190749571a7a02664b677dab37f8949315b4d5" + "reference": "40a4416e6d8da7deb18a75bb9b8e7ce955cf653d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stimulus-bundle/zipball/d7190749571a7a02664b677dab37f8949315b4d5", - "reference": "d7190749571a7a02664b677dab37f8949315b4d5", + "url": "https://api.github.com/repos/symfony/stimulus-bundle/zipball/40a4416e6d8da7deb18a75bb9b8e7ce955cf653d", + "reference": "40a4416e6d8da7deb18a75bb9b8e7ce955cf653d", "shasum": "" }, "require": { @@ -8720,7 +8990,7 @@ "symfony-ux" ], "support": { - "source": "https://github.com/symfony/stimulus-bundle/tree/v2.13.2" + "source": "https://github.com/symfony/stimulus-bundle/tree/v2.13.3" }, "funding": [ { @@ -8736,7 +9006,7 @@ "type": "tidelift" } ], - "time": "2023-11-11T01:20:31+00:00" + "time": "2023-11-30T20:29:09+00:00" }, { "name": "symfony/stopwatch", @@ -8802,16 +9072,16 @@ }, { "name": "symfony/string", - "version": "v6.2.8", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef" + "reference": "d0a29e15c4225c128d8de89241f923345393c0cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/193e83bbd6617d6b2151c37fff10fa7168ebddef", - "reference": "193e83bbd6617d6b2151c37fff10fa7168ebddef", + "url": "https://api.github.com/repos/symfony/string/zipball/d0a29e15c4225c128d8de89241f923345393c0cf", + "reference": "d0a29e15c4225c128d8de89241f923345393c0cf", "shasum": "" }, "require": { @@ -8868,7 +9138,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.2.8" + "source": "https://github.com/symfony/string/tree/v6.2.13" }, "funding": [ { @@ -8884,7 +9154,7 @@ "type": "tidelift" } ], - "time": "2023-03-20T16:06:02+00:00" + "time": "2023-07-05T08:41:15+00:00" }, { "name": "symfony/templating", @@ -9054,16 +9324,16 @@ }, { "name": "symfony/translation-contracts", - "version": "v3.3.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "02c24deb352fb0d79db5486c0c79905a85e37e86" + "reference": "dee0c6e5b4c07ce851b462530088e64b255ac9c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/02c24deb352fb0d79db5486c0c79905a85e37e86", - "reference": "02c24deb352fb0d79db5486c0c79905a85e37e86", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/dee0c6e5b4c07ce851b462530088e64b255ac9c5", + "reference": "dee0c6e5b4c07ce851b462530088e64b255ac9c5", "shasum": "" }, "require": { @@ -9112,7 +9382,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.3.0" + "source": "https://github.com/symfony/translation-contracts/tree/v3.4.0" }, "funding": [ { @@ -9128,20 +9398,20 @@ "type": "tidelift" } ], - "time": "2023-05-30T17:17:10+00:00" + "time": "2023-07-25T15:08:44+00:00" }, { "name": "symfony/twig-bridge", - "version": "v6.2.8", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/twig-bridge.git", - "reference": "30e3ad6ae749b2d2700ecf9b4a1a9d5c96b18927" + "reference": "14fd236ede61bd5559c5eecb2fd8309d8c3e6d7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/30e3ad6ae749b2d2700ecf9b4a1a9d5c96b18927", - "reference": "30e3ad6ae749b2d2700ecf9b4a1a9d5c96b18927", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/14fd236ede61bd5559c5eecb2fd8309d8c3e6d7f", + "reference": "14fd236ede61bd5559c5eecb2fd8309d8c3e6d7f", "shasum": "" }, "require": { @@ -9236,7 +9506,7 @@ "description": "Provides integration for Twig with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bridge/tree/v6.2.8" + "source": "https://github.com/symfony/twig-bridge/tree/v6.2.13" }, "funding": [ { @@ -9252,7 +9522,7 @@ "type": "tidelift" } ], - "time": "2023-03-31T09:14:44+00:00" + "time": "2023-07-20T16:42:25+00:00" }, { "name": "symfony/twig-bundle", @@ -9341,16 +9611,16 @@ }, { "name": "symfony/validator", - "version": "v6.2.11", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "14998e41b1e65e15cbe23466e5a5c2edd8ad3584" + "reference": "f7c4a05e3f5bcbef2fb8a02bc41a2f4121cb3b79" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/14998e41b1e65e15cbe23466e5a5c2edd8ad3584", - "reference": "14998e41b1e65e15cbe23466e5a5c2edd8ad3584", + "url": "https://api.github.com/repos/symfony/validator/zipball/f7c4a05e3f5bcbef2fb8a02bc41a2f4121cb3b79", + "reference": "f7c4a05e3f5bcbef2fb8a02bc41a2f4121cb3b79", "shasum": "" }, "require": { @@ -9428,7 +9698,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v6.2.11" + "source": "https://github.com/symfony/validator/tree/v6.2.13" }, "funding": [ { @@ -9444,20 +9714,20 @@ "type": "tidelift" } ], - "time": "2023-05-25T13:08:43+00:00" + "time": "2023-07-26T17:38:53+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.2.11", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "7d10f2a5a452bda385692fc7d38cd6eccfebe756" + "reference": "297051faddf4fd701dea09df1bf9da47a387346c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/7d10f2a5a452bda385692fc7d38cd6eccfebe756", - "reference": "7d10f2a5a452bda385692fc7d38cd6eccfebe756", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/297051faddf4fd701dea09df1bf9da47a387346c", + "reference": "297051faddf4fd701dea09df1bf9da47a387346c", "shasum": "" }, "require": { @@ -9470,6 +9740,7 @@ "require-dev": { "ext-iconv": "*", "symfony/console": "^5.4|^6.0", + "symfony/http-kernel": "^5.4|^6.0", "symfony/process": "^5.4|^6.0", "symfony/uid": "^5.4|^6.0", "twig/twig": "^2.13|^3.0.4" @@ -9515,7 +9786,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.2.11" + "source": "https://github.com/symfony/var-dumper/tree/v6.2.13" }, "funding": [ { @@ -9531,20 +9802,20 @@ "type": "tidelift" } ], - "time": "2023-05-25T13:08:43+00:00" + "time": "2023-07-21T07:04:05+00:00" }, { "name": "symfony/var-exporter", - "version": "v6.2.10", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "9a07920c2058bafee921ce4d90aeef2193837d63" + "reference": "e14c23915fdb9dfb4343d82e0094dec41a466c0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/9a07920c2058bafee921ce4d90aeef2193837d63", - "reference": "9a07920c2058bafee921ce4d90aeef2193837d63", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/e14c23915fdb9dfb4343d82e0094dec41a466c0a", + "reference": "e14c23915fdb9dfb4343d82e0094dec41a466c0a", "shasum": "" }, "require": { @@ -9589,7 +9860,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v6.2.10" + "source": "https://github.com/symfony/var-exporter/tree/v6.2.13" }, "funding": [ { @@ -9605,7 +9876,7 @@ "type": "tidelift" } ], - "time": "2023-04-21T08:33:05+00:00" + "time": "2023-07-26T17:35:55+00:00" }, { "name": "symfony/web-link", @@ -9893,16 +10164,16 @@ }, { "name": "twig/cssinliner-extra", - "version": "v3.6.0", + "version": "v3.7.1", "source": { "type": "git", "url": "https://github.com/twigphp/cssinliner-extra.git", - "reference": "85c8f3d7712bab57f6162f9637613df0511f207b" + "reference": "59d107afea4ca58be35ae1386bd90b53424f3b34" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/cssinliner-extra/zipball/85c8f3d7712bab57f6162f9637613df0511f207b", - "reference": "85c8f3d7712bab57f6162f9637613df0511f207b", + "url": "https://api.github.com/repos/twigphp/cssinliner-extra/zipball/59d107afea4ca58be35ae1386bd90b53424f3b34", + "reference": "59d107afea4ca58be35ae1386bd90b53424f3b34", "shasum": "" }, "require": { @@ -9911,7 +10182,7 @@ "twig/twig": "^2.7|^3.0" }, "require-dev": { - "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" + "symfony/phpunit-bridge": "^5.4|^6.3" }, "type": "library", "autoload": { @@ -9942,7 +10213,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/cssinliner-extra/tree/v3.6.0" + "source": "https://github.com/twigphp/cssinliner-extra/tree/v3.7.1" }, "funding": [ { @@ -9954,31 +10225,31 @@ "type": "tidelift" } ], - "time": "2023-02-09T06:45:16+00:00" + "time": "2023-07-29T15:34:56+00:00" }, { "name": "twig/extra-bundle", - "version": "v3.6.0", + "version": "v3.7.1", "source": { "type": "git", "url": "https://github.com/twigphp/twig-extra-bundle.git", - "reference": "4a9674e775f49a9df5e26da66546e8f3364afe67" + "reference": "f10baafe6eb0ecd615d52d5cbfb713a39f68e8f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/4a9674e775f49a9df5e26da66546e8f3364afe67", - "reference": "4a9674e775f49a9df5e26da66546e8f3364afe67", + "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/f10baafe6eb0ecd615d52d5cbfb713a39f68e8f3", + "reference": "f10baafe6eb0ecd615d52d5cbfb713a39f68e8f3", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/framework-bundle": "^4.4|^5.0|^6.0", - "symfony/twig-bundle": "^4.4|^5.0|^6.0", + "symfony/framework-bundle": "^5.4|^6.0", + "symfony/twig-bundle": "^5.4|^6.0", "twig/twig": "^2.7|^3.0" }, "require-dev": { "league/commonmark": "^1.0|^2.0", - "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0", + "symfony/phpunit-bridge": "^5.4|^6.3", "twig/cache-extra": "^3.0", "twig/cssinliner-extra": "^2.12|^3.0", "twig/html-extra": "^2.12|^3.0", @@ -10016,7 +10287,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.6.0" + "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.7.1" }, "funding": [ { @@ -10028,20 +10299,20 @@ "type": "tidelift" } ], - "time": "2023-04-14T11:03:02+00:00" + "time": "2023-07-29T15:34:56+00:00" }, { "name": "twig/inky-extra", - "version": "v3.6.0", + "version": "v3.7.1", "source": { "type": "git", "url": "https://github.com/twigphp/inky-extra.git", - "reference": "907abf7046082cc151a3ee01f268dbf5f5f28eab" + "reference": "c6145677b63b3fcd27b1b3bbae9e64edbf12a273" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/inky-extra/zipball/907abf7046082cc151a3ee01f268dbf5f5f28eab", - "reference": "907abf7046082cc151a3ee01f268dbf5f5f28eab", + "url": "https://api.github.com/repos/twigphp/inky-extra/zipball/c6145677b63b3fcd27b1b3bbae9e64edbf12a273", + "reference": "c6145677b63b3fcd27b1b3bbae9e64edbf12a273", "shasum": "" }, "require": { @@ -10050,7 +10321,7 @@ "twig/twig": "^2.7|^3.0" }, "require-dev": { - "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" + "symfony/phpunit-bridge": "^5.4|^6.3" }, "type": "library", "autoload": { @@ -10082,7 +10353,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/inky-extra/tree/v3.6.0" + "source": "https://github.com/twigphp/inky-extra/tree/v3.7.1" }, "funding": [ { @@ -10094,7 +10365,7 @@ "type": "tidelift" } ], - "time": "2023-02-09T06:45:16+00:00" + "time": "2023-07-29T15:34:56+00:00" }, { "name": "twig/string-extra", @@ -10165,16 +10436,16 @@ }, { "name": "twig/twig", - "version": "v2.15.5", + "version": "v2.15.6", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "fc02a6af3eeb97c4bf5650debc76c2eda85ac22e" + "reference": "ad637405a828601a56f32ccab9a85541c4b66c9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/fc02a6af3eeb97c4bf5650debc76c2eda85ac22e", - "reference": "fc02a6af3eeb97c4bf5650debc76c2eda85ac22e", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/ad637405a828601a56f32ccab9a85541c4b66c9d", + "reference": "ad637405a828601a56f32ccab9a85541c4b66c9d", "shasum": "" }, "require": { @@ -10185,7 +10456,7 @@ }, "require-dev": { "psr/container": "^1.0", - "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" + "symfony/phpunit-bridge": "^5.4.9|^6.3" }, "type": "library", "extra": { @@ -10229,7 +10500,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v2.15.5" + "source": "https://github.com/twigphp/Twig/tree/v2.15.6" }, "funding": [ { @@ -10241,7 +10512,7 @@ "type": "tidelift" } ], - "time": "2023-05-03T17:49:41+00:00" + "time": "2023-11-21T17:34:48+00:00" }, { "name": "vich/uploader-bundle", @@ -10413,16 +10684,16 @@ "packages-dev": [ { "name": "masterminds/html5", - "version": "2.8.0", + "version": "2.8.1", "source": { "type": "git", "url": "https://github.com/Masterminds/html5-php.git", - "reference": "3c5d5a56d56f48a1ca08a0670f0f80c1dad368f3" + "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/3c5d5a56d56f48a1ca08a0670f0f80c1dad368f3", - "reference": "3c5d5a56d56f48a1ca08a0670f0f80c1dad368f3", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f47dcf3c70c584de14f21143c55d9939631bc6cf", + "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf", "shasum": "" }, "require": { @@ -10474,9 +10745,9 @@ ], "support": { "issues": "https://github.com/Masterminds/html5-php/issues", - "source": "https://github.com/Masterminds/html5-php/tree/2.8.0" + "source": "https://github.com/Masterminds/html5-php/tree/2.8.1" }, - "time": "2023-04-26T07:27:39+00:00" + "time": "2023-05-10T11:58:31+00:00" }, { "name": "myclabs/deep-copy", @@ -10539,16 +10810,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.15.5", + "version": "v4.17.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "11e2663a5bc9db5d714eedb4277ee300403b4a9e" + "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/11e2663a5bc9db5d714eedb4277ee300403b4a9e", - "reference": "11e2663a5bc9db5d714eedb4277ee300403b4a9e", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", "shasum": "" }, "require": { @@ -10589,9 +10860,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.5" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1" }, - "time": "2023-05-19T20:20:00+00:00" + "time": "2023-08-13T19:53:39+00:00" }, { "name": "phar-io/manifest", @@ -10706,16 +10977,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.26", + "version": "9.2.29", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1" + "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/443bc6912c9bd5b409254a40f4b0f4ced7c80ea1", - "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76", + "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76", "shasum": "" }, "require": { @@ -10771,7 +11042,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.26" + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.29" }, "funding": [ { @@ -10779,7 +11051,7 @@ "type": "github" } ], - "time": "2023-03-06T12:58:08+00:00" + "time": "2023-09-19T04:57:46+00:00" }, { "name": "phpunit/php-file-iterator", @@ -11024,16 +11296,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.8", + "version": "9.6.15", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "17d621b3aff84d0c8b62539e269e87d8d5baa76e" + "reference": "05017b80304e0eb3f31d90194a563fd53a6021f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/17d621b3aff84d0c8b62539e269e87d8d5baa76e", - "reference": "17d621b3aff84d0c8b62539e269e87d8d5baa76e", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/05017b80304e0eb3f31d90194a563fd53a6021f1", + "reference": "05017b80304e0eb3f31d90194a563fd53a6021f1", "shasum": "" }, "require": { @@ -11048,7 +11320,7 @@ "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", "php": ">=7.3", - "phpunit/php-code-coverage": "^9.2.13", + "phpunit/php-code-coverage": "^9.2.28", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", "phpunit/php-text-template": "^2.0.3", @@ -11107,7 +11379,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.8" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.15" }, "funding": [ { @@ -11123,7 +11395,7 @@ "type": "tidelift" } ], - "time": "2023-05-11T05:14:45+00:00" + "time": "2023-12-01T16:55:19+00:00" }, { "name": "sebastian/cli-parser", @@ -11631,16 +11903,16 @@ }, { "name": "sebastian/global-state", - "version": "5.0.5", + "version": "5.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" + "reference": "bde739e7565280bda77be70044ac1047bc007e34" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bde739e7565280bda77be70044ac1047bc007e34", + "reference": "bde739e7565280bda77be70044ac1047bc007e34", "shasum": "" }, "require": { @@ -11683,7 +11955,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.6" }, "funding": [ { @@ -11691,7 +11963,7 @@ "type": "github" } ], - "time": "2022-02-14T08:28:10+00:00" + "time": "2023-08-02T09:26:13+00:00" }, { "name": "sebastian/lines-of-code", @@ -12162,16 +12434,16 @@ }, { "name": "symfony/debug-bundle", - "version": "v6.2.7", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/debug-bundle.git", - "reference": "8ff6c96d09c462beade7512137899e400c76d994" + "reference": "f48bf7c1bd1b5ac946599970b94b1087cfebed5e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug-bundle/zipball/8ff6c96d09c462beade7512137899e400c76d994", - "reference": "8ff6c96d09c462beade7512137899e400c76d994", + "url": "https://api.github.com/repos/symfony/debug-bundle/zipball/f48bf7c1bd1b5ac946599970b94b1087cfebed5e", + "reference": "f48bf7c1bd1b5ac946599970b94b1087cfebed5e", "shasum": "" }, "require": { @@ -12220,7 +12492,7 @@ "description": "Provides a tight integration of the Symfony VarDumper component and the ServerLogCommand from MonologBridge into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/debug-bundle/tree/v6.2.7" + "source": "https://github.com/symfony/debug-bundle/tree/v6.2.13" }, "funding": [ { @@ -12236,20 +12508,20 @@ "type": "tidelift" } ], - "time": "2023-02-14T08:44:56+00:00" + "time": "2023-07-13T14:28:09+00:00" }, { "name": "symfony/dom-crawler", - "version": "v6.2.9", + "version": "v6.2.12", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "328bc3795059651d2d4e462e8febdf7ec2d7a626" + "reference": "dde84bcbe9d39958b34ee6065d2fb82170552039" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/328bc3795059651d2d4e462e8febdf7ec2d7a626", - "reference": "328bc3795059651d2d4e462e8febdf7ec2d7a626", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/dde84bcbe9d39958b34ee6065d2fb82170552039", + "reference": "dde84bcbe9d39958b34ee6065d2fb82170552039", "shasum": "" }, "require": { @@ -12290,7 +12562,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v6.2.9" + "source": "https://github.com/symfony/dom-crawler/tree/v6.2.12" }, "funding": [ { @@ -12306,20 +12578,20 @@ "type": "tidelift" } ], - "time": "2023-04-11T16:03:19+00:00" + "time": "2023-06-05T15:29:05+00:00" }, { "name": "symfony/maker-bundle", - "version": "v1.48.0", + "version": "v1.50.0", "source": { "type": "git", "url": "https://github.com/symfony/maker-bundle.git", - "reference": "2e428e8432e9879187672fe08f1cc335e2a31dd6" + "reference": "a1733f849b999460c308e66f6392fb09b621fa86" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/2e428e8432e9879187672fe08f1cc335e2a31dd6", - "reference": "2e428e8432e9879187672fe08f1cc335e2a31dd6", + "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/a1733f849b999460c308e66f6392fb09b621fa86", + "reference": "a1733f849b999460c308e66f6392fb09b621fa86", "shasum": "" }, "require": { @@ -12333,7 +12605,8 @@ "symfony/filesystem": "^5.4.7|^6.0", "symfony/finder": "^5.4.3|^6.0", "symfony/framework-bundle": "^5.4.7|^6.0", - "symfony/http-kernel": "^5.4.7|^6.0" + "symfony/http-kernel": "^5.4.7|^6.0", + "symfony/process": "^5.4.7|^6.0" }, "conflict": { "doctrine/doctrine-bundle": "<2.4", @@ -12345,9 +12618,8 @@ "doctrine/doctrine-bundle": "^2.4", "doctrine/orm": "^2.10.0", "symfony/http-client": "^5.4.7|^6.0", - "symfony/phpunit-bridge": "^5.4.7|^6.0", + "symfony/phpunit-bridge": "^5.4.17|^6.0", "symfony/polyfill-php80": "^1.16.0", - "symfony/process": "^5.4.7|^6.0", "symfony/security-core": "^5.4.7|^6.0", "symfony/yaml": "^5.4.3|^6.0", "twig/twig": "^2.0|^3.0" @@ -12377,13 +12649,14 @@ "homepage": "https://symfony.com/doc/current/bundles/SymfonyMakerBundle/index.html", "keywords": [ "code generator", + "dev", "generator", "scaffold", "scaffolding" ], "support": { "issues": "https://github.com/symfony/maker-bundle/issues", - "source": "https://github.com/symfony/maker-bundle/tree/v1.48.0" + "source": "https://github.com/symfony/maker-bundle/tree/v1.50.0" }, "funding": [ { @@ -12399,20 +12672,20 @@ "type": "tidelift" } ], - "time": "2022-11-14T10:48:46+00:00" + "time": "2023-07-10T18:21:57+00:00" }, { "name": "symfony/phpunit-bridge", - "version": "v6.3.0", + "version": "v6.4.1", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "f8d75b4d9bf7243979b2c2e5e6cd73f03e10579f" + "reference": "cca5373a41d45edbeaf38b7b67f376da2205ff95" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/f8d75b4d9bf7243979b2c2e5e6cd73f03e10579f", - "reference": "f8d75b4d9bf7243979b2c2e5e6cd73f03e10579f", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/cca5373a41d45edbeaf38b7b67f376da2205ff95", + "reference": "cca5373a41d45edbeaf38b7b67f376da2205ff95", "shasum": "" }, "require": { @@ -12423,7 +12696,7 @@ }, "require-dev": { "symfony/deprecation-contracts": "^2.5|^3.0", - "symfony/error-handler": "^5.4|^6.0", + "symfony/error-handler": "^5.4|^6.0|^7.0", "symfony/polyfill-php81": "^1.27" }, "bin": [ @@ -12464,7 +12737,7 @@ "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v6.3.0" + "source": "https://github.com/symfony/phpunit-bridge/tree/v6.4.1" }, "funding": [ { @@ -12480,20 +12753,20 @@ "type": "tidelift" } ], - "time": "2023-05-30T09:01:24+00:00" + "time": "2023-12-01T09:25:07+00:00" }, { "name": "symfony/web-profiler-bundle", - "version": "v6.2.11", + "version": "v6.2.13", "source": { "type": "git", "url": "https://github.com/symfony/web-profiler-bundle.git", - "reference": "1338ad6486f7ce22401a1c0d799ccb5f499b7f8f" + "reference": "89a78db2bd961d7fa63865e52f79c7d505702427" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/1338ad6486f7ce22401a1c0d799ccb5f499b7f8f", - "reference": "1338ad6486f7ce22401a1c0d799ccb5f499b7f8f", + "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/89a78db2bd961d7fa63865e52f79c7d505702427", + "reference": "89a78db2bd961d7fa63865e52f79c7d505702427", "shasum": "" }, "require": { @@ -12542,7 +12815,7 @@ "description": "Provides a development tool that gives detailed information about the execution of any request", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/web-profiler-bundle/tree/v6.2.11" + "source": "https://github.com/symfony/web-profiler-bundle/tree/v6.2.13" }, "funding": [ { @@ -12558,20 +12831,20 @@ "type": "tidelift" } ], - "time": "2023-05-05T15:52:57+00:00" + "time": "2023-07-19T20:17:04+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.1", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96", + "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96", "shasum": "" }, "require": { @@ -12600,7 +12873,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + "source": "https://github.com/theseer/tokenizer/tree/1.2.2" }, "funding": [ { @@ -12608,7 +12881,7 @@ "type": "github" } ], - "time": "2021-07-28T10:34:58+00:00" + "time": "2023-11-20T00:12:19+00:00" } ], "aliases": [], @@ -12622,5 +12895,5 @@ "ext-iconv": "*" }, "platform-dev": [], - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.3.0" } diff --git a/config/bundles.php b/config/bundles.php index f2d55dcb..dfb9b289 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -20,4 +20,5 @@ Ambta\DoctrineEncryptBundle\AmbtaDoctrineEncryptBundle::class => ['all' => true], Knp\Bundle\MenuBundle\KnpMenuBundle::class => ['all' => true], Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true], + Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true], ]; diff --git a/config/packages/stof_doctrine_extensions.yaml b/config/packages/stof_doctrine_extensions.yaml new file mode 100644 index 00000000..b258add3 --- /dev/null +++ b/config/packages/stof_doctrine_extensions.yaml @@ -0,0 +1,4 @@ +# Read the documentation: https://symfony.com/doc/current/bundles/StofDoctrineExtensionsBundle/index.html +# See the official DoctrineExtensions documentation for more details: https://github.com/doctrine-extensions/DoctrineExtensions/tree/main/doc +stof_doctrine_extensions: + default_locale: en_US diff --git a/config/services.yaml b/config/services.yaml index 5a33a848..4442d7f5 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -45,3 +45,10 @@ services: - { name: knp_menu.menu_builder, method: createAcademyMenu, alias: academy } - { name: knp_menu.menu_builder, method: createTeamAdminMenu, alias: teamAdmin } - { name: knp_menu.menu_builder, method: createAdminMenu, alias: admin } + + Gedmo\Tree\TreeListener: + tags: + - name: doctrine.event_subscriber + connection: default + calls: + - [ setAnnotationReader, [ "@annotation_reader" ] ] diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 00000000..8b03571d --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,42 @@ +version: '3' +services: +###> doctrine/doctrine-bundle ### + database: + image: 'mariadb:10.5' + environment: + MYSQL_ROOT_PASSWORD: password + MYSQL_DATABASE: main + TZ: Europe/Berlin + ports: + # To allow the host machine to access the ports below, modify the lines below. + # For example, to allow the host to connect to port 3306 on the container, you would change + # "3306" to "3306:3306". Where the first port is exposed to the host and the second is the container port. + # See https://docs.docker.com/compose/compose-file/compose-file-v3/#ports for more information. + - '3306' + # You may use a bind-mounted host directory instead, so that it is harder to accidentally remove the volume and lose all your data! + # - ./docker/db/data:/var/lib/postgresql/data:rw +###< doctrine/doctrine-bundle ### + keycloak: + image: quay.io/keycloak/keycloak:latest + container_name: "keycloak" + volumes: + - ./keycloak/opendatenschutzcenter-realm.json:/opt/keycloak/data/import/opendatenschutzcenter-realm.json + command: + - --verbose + - start-dev + - --import-realm + environment: + KEYCLOAK_ADMIN: admin + KEYCLOAK_ADMIN_PASSWORD: admin + PROXY_ADDRESS_FORWARDING: true + VIRTUAL_HOST: dev-keycloak.mydomain.com + VIRTUAL_PORT: 8080 + LETSENCRYPT_HOST: dev-keycloak.mydomain.com + TZ: Europe/Berlin + ports: + - '8080:8080' + +volumes: +###> doctrine/doctrine-bundle ### + db-data: +###< doctrine/doctrine-bundle ### \ No newline at end of file diff --git a/keycloak/opendatenschutzcenter-realm.json b/keycloak/opendatenschutzcenter-realm.json new file mode 100644 index 00000000..531f3ebc --- /dev/null +++ b/keycloak/opendatenschutzcenter-realm.json @@ -0,0 +1,1883 @@ +{ + "id" : "opendatenschutzcenter", + "realm" : "opendatenschutzcenter", + "notBefore" : 0, + "defaultSignatureAlgorithm" : "RS256", + "revokeRefreshToken" : false, + "refreshTokenMaxReuse" : 0, + "accessTokenLifespan" : 300, + "accessTokenLifespanForImplicitFlow" : 900, + "ssoSessionIdleTimeout" : 1800, + "ssoSessionMaxLifespan" : 36000, + "ssoSessionIdleTimeoutRememberMe" : 0, + "ssoSessionMaxLifespanRememberMe" : 0, + "offlineSessionIdleTimeout" : 2592000, + "offlineSessionMaxLifespanEnabled" : false, + "offlineSessionMaxLifespan" : 5184000, + "clientSessionIdleTimeout" : 0, + "clientSessionMaxLifespan" : 0, + "clientOfflineSessionIdleTimeout" : 0, + "clientOfflineSessionMaxLifespan" : 0, + "accessCodeLifespan" : 60, + "accessCodeLifespanUserAction" : 300, + "accessCodeLifespanLogin" : 1800, + "actionTokenGeneratedByAdminLifespan" : 43200, + "actionTokenGeneratedByUserLifespan" : 300, + "oauth2DeviceCodeLifespan" : 600, + "oauth2DevicePollingInterval" : 5, + "enabled" : true, + "sslRequired" : "external", + "registrationAllowed" : true, + "registrationEmailAsUsername" : true, + "rememberMe" : true, + "verifyEmail" : false, + "loginWithEmailAllowed" : true, + "duplicateEmailsAllowed" : false, + "resetPasswordAllowed" : true, + "editUsernameAllowed" : false, + "bruteForceProtected" : false, + "permanentLockout" : false, + "maxFailureWaitSeconds" : 900, + "minimumQuickLoginWaitSeconds" : 60, + "waitIncrementSeconds" : 60, + "quickLoginCheckMilliSeconds" : 1000, + "maxDeltaTimeSeconds" : 43200, + "failureFactor" : 30, + "roles" : { + "realm" : [ { + "id" : "1e39316e-9362-40fd-b36e-98cdbaa88206", + "name" : "default-roles-opendatenschutzcenter", + "description" : "${role_default-roles}", + "composite" : true, + "composites" : { + "realm" : [ "offline_access", "uma_authorization" ], + "client" : { + "opendatenschutzcenter" : [ "uma_protection", "odc-super-admin" ], + "account" : [ "view-profile", "manage-account" ] + } + }, + "clientRole" : false, + "containerId" : "opendatenschutzcenter", + "attributes" : { } + }, { + "id" : "b5758b7c-d11f-488b-89ed-11acd496b5a3", + "name" : "uma_authorization", + "description" : "${role_uma_authorization}", + "composite" : false, + "clientRole" : false, + "containerId" : "opendatenschutzcenter", + "attributes" : { } + }, { + "id" : "abed3730-b96d-43fa-a01a-a9b6de82386c", + "name" : "offline_access", + "description" : "${role_offline-access}", + "composite" : false, + "clientRole" : false, + "containerId" : "opendatenschutzcenter", + "attributes" : { } + } ], + "client" : { + "opendatenschutzcenter" : [ { + "id" : "2cc14124-40db-418c-8343-625d5171671e", + "name" : "uma_protection", + "composite" : false, + "clientRole" : true, + "containerId" : "e0d7a685-a075-4834-a6ca-cb40d734f4af", + "attributes" : { } + }, { + "id" : "b0ae121e-dd3e-473a-bde5-b54d390bb984", + "name" : "odc-super-admin", + "description" : "", + "composite" : false, + "clientRole" : true, + "containerId" : "e0d7a685-a075-4834-a6ca-cb40d734f4af", + "attributes" : { } + } ], + "realm-management" : [ { + "id" : "38d7208c-fb9b-4df7-a424-41724e3429a9", + "name" : "view-realm", + "description" : "${role_view-realm}", + "composite" : false, + "clientRole" : true, + "containerId" : "cc776261-d979-4bc0-ac55-758f7d7c6d25", + "attributes" : { } + }, { + "id" : "5478251e-264f-4eb8-8cd0-2e53c044654e", + "name" : "create-client", + "description" : "${role_create-client}", + "composite" : false, + "clientRole" : true, + "containerId" : "cc776261-d979-4bc0-ac55-758f7d7c6d25", + "attributes" : { } + }, { + "id" : "bf17a3ce-ed84-4395-8955-b73e37f29d05", + "name" : "query-groups", + "description" : "${role_query-groups}", + "composite" : false, + "clientRole" : true, + "containerId" : "cc776261-d979-4bc0-ac55-758f7d7c6d25", + "attributes" : { } + }, { + "id" : "e50dffff-9e6c-432a-bbea-cf041fab6f2f", + "name" : "query-realms", + "description" : "${role_query-realms}", + "composite" : false, + "clientRole" : true, + "containerId" : "cc776261-d979-4bc0-ac55-758f7d7c6d25", + "attributes" : { } + }, { + "id" : "044225f4-3e61-449a-a3a8-97ac3f85f266", + "name" : "view-clients", + "description" : "${role_view-clients}", + "composite" : true, + "composites" : { + "client" : { + "realm-management" : [ "query-clients" ] + } + }, + "clientRole" : true, + "containerId" : "cc776261-d979-4bc0-ac55-758f7d7c6d25", + "attributes" : { } + }, { + "id" : "8a0c305f-29f9-4466-96c5-4d2490b496fa", + "name" : "manage-realm", + "description" : "${role_manage-realm}", + "composite" : false, + "clientRole" : true, + "containerId" : "cc776261-d979-4bc0-ac55-758f7d7c6d25", + "attributes" : { } + }, { + "id" : "763c2817-554d-4cc6-b6f0-7c70db458c6f", + "name" : "manage-identity-providers", + "description" : "${role_manage-identity-providers}", + "composite" : false, + "clientRole" : true, + "containerId" : "cc776261-d979-4bc0-ac55-758f7d7c6d25", + "attributes" : { } + }, { + "id" : "e85936e0-da6a-48fe-bce8-a4b2ec065c6a", + "name" : "view-authorization", + "description" : "${role_view-authorization}", + "composite" : false, + "clientRole" : true, + "containerId" : "cc776261-d979-4bc0-ac55-758f7d7c6d25", + "attributes" : { } + }, { + "id" : "1672e14d-d431-4166-9463-17d71bb79997", + "name" : "view-identity-providers", + "description" : "${role_view-identity-providers}", + "composite" : false, + "clientRole" : true, + "containerId" : "cc776261-d979-4bc0-ac55-758f7d7c6d25", + "attributes" : { } + }, { + "id" : "aac81c3d-dfbd-4220-8abc-16744384d1ce", + "name" : "manage-clients", + "description" : "${role_manage-clients}", + "composite" : false, + "clientRole" : true, + "containerId" : "cc776261-d979-4bc0-ac55-758f7d7c6d25", + "attributes" : { } + }, { + "id" : "79669483-b6a7-4b05-a9d8-20c3dba7bc3a", + "name" : "query-clients", + "description" : "${role_query-clients}", + "composite" : false, + "clientRole" : true, + "containerId" : "cc776261-d979-4bc0-ac55-758f7d7c6d25", + "attributes" : { } + }, { + "id" : "34236bf4-7681-4fc8-984e-f1a248025a41", + "name" : "view-events", + "description" : "${role_view-events}", + "composite" : false, + "clientRole" : true, + "containerId" : "cc776261-d979-4bc0-ac55-758f7d7c6d25", + "attributes" : { } + }, { + "id" : "df5c1e5d-dc53-4a15-bd4b-742b02305acd", + "name" : "manage-users", + "description" : "${role_manage-users}", + "composite" : false, + "clientRole" : true, + "containerId" : "cc776261-d979-4bc0-ac55-758f7d7c6d25", + "attributes" : { } + }, { + "id" : "4aa69096-01bb-4ae2-8d80-7481e2c2f6ca", + "name" : "query-users", + "description" : "${role_query-users}", + "composite" : false, + "clientRole" : true, + "containerId" : "cc776261-d979-4bc0-ac55-758f7d7c6d25", + "attributes" : { } + }, { + "id" : "53a73235-04b2-4db8-a686-49c8baf716a4", + "name" : "impersonation", + "description" : "${role_impersonation}", + "composite" : false, + "clientRole" : true, + "containerId" : "cc776261-d979-4bc0-ac55-758f7d7c6d25", + "attributes" : { } + }, { + "id" : "5f306975-1694-465b-823f-51557a183fd8", + "name" : "realm-admin", + "description" : "${role_realm-admin}", + "composite" : true, + "composites" : { + "client" : { + "realm-management" : [ "view-realm", "create-client", "query-groups", "view-clients", "query-realms", "manage-realm", "manage-identity-providers", "view-authorization", "view-identity-providers", "view-events", "query-clients", "manage-clients", "manage-users", "query-users", "impersonation", "manage-authorization", "manage-events", "view-users" ] + } + }, + "clientRole" : true, + "containerId" : "cc776261-d979-4bc0-ac55-758f7d7c6d25", + "attributes" : { } + }, { + "id" : "79bd5266-7e33-4883-876f-35767980453b", + "name" : "manage-authorization", + "description" : "${role_manage-authorization}", + "composite" : false, + "clientRole" : true, + "containerId" : "cc776261-d979-4bc0-ac55-758f7d7c6d25", + "attributes" : { } + }, { + "id" : "29daccc2-5362-449b-8da1-5c7609e77d25", + "name" : "manage-events", + "description" : "${role_manage-events}", + "composite" : false, + "clientRole" : true, + "containerId" : "cc776261-d979-4bc0-ac55-758f7d7c6d25", + "attributes" : { } + }, { + "id" : "b915a638-f8c4-4950-be07-852d34ab4169", + "name" : "view-users", + "description" : "${role_view-users}", + "composite" : true, + "composites" : { + "client" : { + "realm-management" : [ "query-groups", "query-users" ] + } + }, + "clientRole" : true, + "containerId" : "cc776261-d979-4bc0-ac55-758f7d7c6d25", + "attributes" : { } + } ], + "security-admin-console" : [ ], + "admin-cli" : [ ], + "account-console" : [ ], + "broker" : [ { + "id" : "359ce66a-2b57-4c14-9e13-099e101b2b6a", + "name" : "read-token", + "description" : "${role_read-token}", + "composite" : false, + "clientRole" : true, + "containerId" : "4a5b0cfb-560f-410f-98ce-85371bc14188", + "attributes" : { } + } ], + "account" : [ { + "id" : "74fd6684-2ee1-4ea9-adc9-58736b395f10", + "name" : "view-profile", + "description" : "${role_view-profile}", + "composite" : false, + "clientRole" : true, + "containerId" : "170f55bf-4418-47f9-a248-4010687f6214", + "attributes" : { } + }, { + "id" : "5399f61d-a67d-40b9-9958-8dc4df28caee", + "name" : "view-applications", + "description" : "${role_view-applications}", + "composite" : false, + "clientRole" : true, + "containerId" : "170f55bf-4418-47f9-a248-4010687f6214", + "attributes" : { } + }, { + "id" : "4ed60b11-a624-493f-b92a-9db11af4c553", + "name" : "view-groups", + "description" : "${role_view-groups}", + "composite" : false, + "clientRole" : true, + "containerId" : "170f55bf-4418-47f9-a248-4010687f6214", + "attributes" : { } + }, { + "id" : "a3c0bcac-750d-477e-9806-72af93de5c2a", + "name" : "manage-consent", + "description" : "${role_manage-consent}", + "composite" : true, + "composites" : { + "client" : { + "account" : [ "view-consent" ] + } + }, + "clientRole" : true, + "containerId" : "170f55bf-4418-47f9-a248-4010687f6214", + "attributes" : { } + }, { + "id" : "10e9cb15-37b9-4825-830f-3329d81b0421", + "name" : "delete-account", + "description" : "${role_delete-account}", + "composite" : false, + "clientRole" : true, + "containerId" : "170f55bf-4418-47f9-a248-4010687f6214", + "attributes" : { } + }, { + "id" : "dc93a52d-30bd-48df-b303-56a83fe72bca", + "name" : "manage-account-links", + "description" : "${role_manage-account-links}", + "composite" : false, + "clientRole" : true, + "containerId" : "170f55bf-4418-47f9-a248-4010687f6214", + "attributes" : { } + }, { + "id" : "e0f3ee32-5e3a-46c7-bbf1-5df3dee4cf0f", + "name" : "manage-account", + "description" : "${role_manage-account}", + "composite" : true, + "composites" : { + "client" : { + "account" : [ "manage-account-links" ] + } + }, + "clientRole" : true, + "containerId" : "170f55bf-4418-47f9-a248-4010687f6214", + "attributes" : { } + }, { + "id" : "fa19b2a4-60e0-4f6f-8738-9b1c8da777c7", + "name" : "view-consent", + "description" : "${role_view-consent}", + "composite" : false, + "clientRole" : true, + "containerId" : "170f55bf-4418-47f9-a248-4010687f6214", + "attributes" : { } + } ] + } + }, + "groups" : [ { + "id" : "ff65e179-38ca-4ca7-a244-ef80b160e3df", + "name" : "all", + "path" : "/all", + "attributes" : { }, + "realmRoles" : [ ], + "clientRoles" : { }, + "subGroups" : [ ] + } ], + "defaultRole" : { + "id" : "1e39316e-9362-40fd-b36e-98cdbaa88206", + "name" : "default-roles-opendatenschutzcenter", + "description" : "${role_default-roles}", + "composite" : true, + "clientRole" : false, + "containerId" : "opendatenschutzcenter" + }, + "defaultGroups" : [ "/all" ], + "requiredCredentials" : [ "password" ], + "otpPolicyType" : "totp", + "otpPolicyAlgorithm" : "HmacSHA1", + "otpPolicyInitialCounter" : 0, + "otpPolicyDigits" : 6, + "otpPolicyLookAheadWindow" : 1, + "otpPolicyPeriod" : 30, + "otpPolicyCodeReusable" : false, + "otpSupportedApplications" : [ "totpAppFreeOTPName", "totpAppGoogleName", "totpAppMicrosoftAuthenticatorName" ], + "webAuthnPolicyRpEntityName" : "keycloak", + "webAuthnPolicySignatureAlgorithms" : [ "ES256" ], + "webAuthnPolicyRpId" : "", + "webAuthnPolicyAttestationConveyancePreference" : "not specified", + "webAuthnPolicyAuthenticatorAttachment" : "not specified", + "webAuthnPolicyRequireResidentKey" : "not specified", + "webAuthnPolicyUserVerificationRequirement" : "not specified", + "webAuthnPolicyCreateTimeout" : 0, + "webAuthnPolicyAvoidSameAuthenticatorRegister" : false, + "webAuthnPolicyAcceptableAaguids" : [ ], + "webAuthnPolicyPasswordlessRpEntityName" : "keycloak", + "webAuthnPolicyPasswordlessSignatureAlgorithms" : [ "ES256" ], + "webAuthnPolicyPasswordlessRpId" : "", + "webAuthnPolicyPasswordlessAttestationConveyancePreference" : "not specified", + "webAuthnPolicyPasswordlessAuthenticatorAttachment" : "not specified", + "webAuthnPolicyPasswordlessRequireResidentKey" : "not specified", + "webAuthnPolicyPasswordlessUserVerificationRequirement" : "not specified", + "webAuthnPolicyPasswordlessCreateTimeout" : 0, + "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister" : false, + "webAuthnPolicyPasswordlessAcceptableAaguids" : [ ], + "scopeMappings" : [ { + "clientScope" : "offline_access", + "roles" : [ "offline_access" ] + } ], + "clientScopeMappings" : { + "account" : [ { + "client" : "account-console", + "roles" : [ "manage-account", "view-groups" ] + } ] + }, + "clients" : [ { + "id" : "170f55bf-4418-47f9-a248-4010687f6214", + "clientId" : "account", + "name" : "${client_account}", + "rootUrl" : "${authBaseUrl}", + "baseUrl" : "/realms/opendatenschutzcenter/account/", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ "/realms/opendatenschutzcenter/account/*" ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "post.logout.redirect.uris" : "+" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ ], + "optionalClientScopes" : [ ] + }, { + "id" : "43a8c6a3-475d-4dd6-8f11-03a955ebe93e", + "clientId" : "account-console", + "name" : "${client_account-console}", + "rootUrl" : "${authBaseUrl}", + "baseUrl" : "/realms/opendatenschutzcenter/account/", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ "/realms/opendatenschutzcenter/account/*" ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "post.logout.redirect.uris" : "+", + "pkce.code.challenge.method" : "S256" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "0eae0606-9ec8-425a-82f6-297b63b7cf45", + "name" : "audience resolve", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-audience-resolve-mapper", + "consentRequired" : false, + "config" : { } + } ], + "defaultClientScopes" : [ ], + "optionalClientScopes" : [ ] + }, { + "id" : "0cb22b97-aa3f-4d34-88f9-3a7677ffe2d7", + "clientId" : "admin-cli", + "name" : "${client_admin-cli}", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : false, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : true, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "post.logout.redirect.uris" : "+" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ ], + "optionalClientScopes" : [ ] + }, { + "id" : "4a5b0cfb-560f-410f-98ce-85371bc14188", + "clientId" : "broker", + "name" : "${client_broker}", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : true, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "post.logout.redirect.uris" : "+" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ ], + "optionalClientScopes" : [ ] + }, { + "id" : "e0d7a685-a075-4834-a6ca-cb40d734f4af", + "clientId" : "opendatenschutzcenter", + "name" : "", + "description" : "", + "rootUrl" : "http://localhost:8000", + "adminUrl" : "http://localhost:8000", + "baseUrl" : "", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "secret" : "YBpDk2g9Jacdvq6CHvtgIfUi87OoAI31", + "redirectUris" : [ "http://localhost:8000/*" ], + "webOrigins" : [ "http://localhost:8000" ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : true, + "serviceAccountsEnabled" : true, + "authorizationServicesEnabled" : true, + "publicClient" : false, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "saml.force.post.binding" : "false", + "saml.multivalued.roles" : "false", + "post.logout.redirect.uris" : "+", + "oauth2.device.authorization.grant.enabled" : "false", + "backchannel.logout.revoke.offline.tokens" : "false", + "saml.server.signature.keyinfo.ext" : "false", + "use.refresh.tokens" : "true", + "oidc.ciba.grant.enabled" : "false", + "backchannel.logout.session.required" : "true", + "client_credentials.use_refresh_token" : "false", + "require.pushed.authorization.requests" : "false", + "saml.client.signature" : "false", + "id.token.as.detached.signature" : "false", + "saml.assertion.signature" : "false", + "saml.encrypt" : "false", + "saml.server.signature" : "false", + "exclude.session.state.from.auth.response" : "false", + "saml.artifact.binding" : "false", + "saml_force_name_id_format" : "false", + "tls.client.certificate.bound.access.tokens" : "false", + "acr.loa.map" : "{}", + "saml.authnstatement" : "false", + "display.on.consent.screen" : "false", + "token.response.type.bearer.lower-case" : "false", + "saml.onetimeuse.condition" : "false" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : true, + "nodeReRegistrationTimeout" : -1, + "protocolMappers" : [ { + "id" : "bb473a9a-7933-413f-ae10-e8bbae9419ab", + "name" : "Client ID", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usersessionmodel-note-mapper", + "consentRequired" : false, + "config" : { + "user.session.note" : "client_id", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "client_id", + "jsonType.label" : "String" + } + }, { + "id" : "cbe7355e-b032-4878-b0e8-c35d0210d7fc", + "name" : "Client Host", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usersessionmodel-note-mapper", + "consentRequired" : false, + "config" : { + "user.session.note" : "clientHost", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "clientHost", + "jsonType.label" : "String" + } + }, { + "id" : "0cc67f74-b265-4f99-a970-372509263d1d", + "name" : "client roles", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-client-role-mapper", + "consentRequired" : false, + "config" : { + "multivalued" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "foo", + "id.token.claim" : "false", + "access.token.claim" : "true", + "claim.name" : "resource_access.${client_id}.roles", + "jsonType.label" : "String", + "usermodel.clientRoleMapping.clientId" : "opendatenschutzcenter" + } + }, { + "id" : "78b1be70-6c65-4db5-9ddd-5f50ce9c05a8", + "name" : "Client IP Address", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usersessionmodel-note-mapper", + "consentRequired" : false, + "config" : { + "user.session.note" : "clientAddress", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "clientAddress", + "jsonType.label" : "String" + } + } ], + "defaultClientScopes" : [ "web-origins", "roles", "profile", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "cc776261-d979-4bc0-ac55-758f7d7c6d25", + "clientId" : "realm-management", + "name" : "${client_realm-management}", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ ], + "webOrigins" : [ ], + "notBefore" : 0, + "bearerOnly" : true, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "post.logout.redirect.uris" : "+" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "defaultClientScopes" : [ ], + "optionalClientScopes" : [ ] + }, { + "id" : "779d8bf9-8e3b-4e00-8b44-079a4b5c27b9", + "clientId" : "security-admin-console", + "name" : "${client_security-admin-console}", + "rootUrl" : "${authAdminUrl}", + "baseUrl" : "/admin/opendatenschutzcenter/console/", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "redirectUris" : [ "/admin/opendatenschutzcenter/console/*" ], + "webOrigins" : [ "+" ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : false, + "protocol" : "openid-connect", + "attributes" : { + "post.logout.redirect.uris" : "+", + "pkce.code.challenge.method" : "S256" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : false, + "nodeReRegistrationTimeout" : 0, + "protocolMappers" : [ { + "id" : "abb12e85-ae2f-4ca7-9e47-c0db54a1c164", + "name" : "locale", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "locale", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "locale", + "jsonType.label" : "String" + } + } ], + "defaultClientScopes" : [ ], + "optionalClientScopes" : [ ] + } ], + "clientScopes" : [ { + "id" : "d1e51b56-4cf7-4648-96a6-03c02b828ee1", + "name" : "web-origins", + "description" : "OpenID Connect scope for add allowed web origins to the access token", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "false", + "display.on.consent.screen" : "false", + "consent.screen.text" : "" + }, + "protocolMappers" : [ { + "id" : "2ee97b5d-5971-4557-bea6-aae326580504", + "name" : "allowed web origins", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-allowed-origins-mapper", + "consentRequired" : false, + "config" : { } + } ] + }, { + "id" : "1377be77-6e7a-404d-92ee-2424a34016c5", + "name" : "offline_access", + "description" : "OpenID Connect built-in scope: offline_access", + "protocol" : "openid-connect", + "attributes" : { + "consent.screen.text" : "${offlineAccessScopeConsentText}", + "display.on.consent.screen" : "true" + } + }, { + "id" : "30ce5b0d-fa54-4497-8e5c-55e17edafc25", + "name" : "microprofile-jwt", + "description" : "Microprofile - JWT built-in scope", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "false" + }, + "protocolMappers" : [ { + "id" : "a3fd6226-f310-4795-a2e2-e082f0867c51", + "name" : "upn", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "upn", + "jsonType.label" : "String" + } + }, { + "id" : "7c1f72fe-ab1a-4544-9e7d-33a76d6b839f", + "name" : "groups", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-realm-role-mapper", + "consentRequired" : false, + "config" : { + "multivalued" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "foo", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "groups", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "e0f5b044-94b8-4d54-9c21-4b0ee7d146ae", + "name" : "acr", + "description" : "OpenID Connect scope for add acr (authentication context class reference) to the token", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "false", + "display.on.consent.screen" : "false" + }, + "protocolMappers" : [ { + "id" : "c78fd3d3-ae71-4493-aae6-a1c3ddd72e51", + "name" : "acr loa level", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-acr-mapper", + "consentRequired" : false, + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true" + } + } ] + }, { + "id" : "cc24231d-19a4-4375-8df4-3afa4e09cc8f", + "name" : "email", + "description" : "OpenID Connect built-in scope: email", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "true", + "consent.screen.text" : "${emailScopeConsentText}" + }, + "protocolMappers" : [ { + "id" : "fa56b862-c2f5-4c1e-a6f7-8294be24a9bc", + "name" : "email verified", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "emailVerified", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email_verified", + "jsonType.label" : "boolean" + } + }, { + "id" : "a8638bdd-1652-4319-bfa0-251e133a6278", + "name" : "email", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "email", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "email", + "jsonType.label" : "String" + } + } ] + }, { + "id" : "7d8f1686-2e2d-4bd9-ad19-d5a1fd31ee9f", + "name" : "roles", + "description" : "OpenID Connect scope for add user roles to the access token", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "true", + "gui.order" : "", + "consent.screen.text" : "${rolesScopeConsentText}" + }, + "protocolMappers" : [ { + "id" : "6385b6b7-1363-4532-8cd6-b60c21d260d7", + "name" : "client roles", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-client-role-mapper", + "consentRequired" : false, + "config" : { + "multivalued" : "true", + "userinfo.token.claim" : "true", + "user.attribute" : "foo", + "id.token.claim" : "false", + "access.token.claim" : "true", + "claim.name" : "resource_access.${client_id}.roles", + "jsonType.label" : "String" + } + }, { + "id" : "736fe3f8-b7ce-4af6-ac4f-2ef41022cd0e", + "name" : "realm roles", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-realm-role-mapper", + "consentRequired" : false, + "config" : { + "multivalued" : "true", + "userinfo.token.claim" : "false", + "user.attribute" : "foo", + "id.token.claim" : "false", + "access.token.claim" : "true", + "claim.name" : "realm_access.roles", + "jsonType.label" : "String" + } + }, { + "id" : "ea35eb38-2f08-4c4c-a6f8-ee1a148a6bdd", + "name" : "audience resolve", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-audience-resolve-mapper", + "consentRequired" : false, + "config" : { } + } ] + }, { + "id" : "e79f5230-f1fd-42c6-9b66-6e24a255d3df", + "name" : "role_list", + "description" : "SAML role list", + "protocol" : "saml", + "attributes" : { + "consent.screen.text" : "${samlRoleListScopeConsentText}", + "display.on.consent.screen" : "true" + }, + "protocolMappers" : [ { + "id" : "a9d5375c-46be-463a-9893-aa20c91adf40", + "name" : "role list", + "protocol" : "saml", + "protocolMapper" : "saml-role-list-mapper", + "consentRequired" : false, + "config" : { + "single" : "false", + "attribute.nameformat" : "Basic", + "attribute.name" : "Role" + } + } ] + }, { + "id" : "90b95398-a629-4ad5-b985-d85a61580cc3", + "name" : "phone", + "description" : "OpenID Connect built-in scope: phone", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "true", + "consent.screen.text" : "${phoneScopeConsentText}" + }, + "protocolMappers" : [ { + "id" : "9fd40c6d-260b-4a19-bcd1-e73b145dfb2d", + "name" : "phone number", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "phoneNumber", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "phone_number", + "jsonType.label" : "String" + } + }, { + "id" : "1a550077-2a56-4985-aa90-df56b4ac3588", + "name" : "phone number verified", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "phoneNumberVerified", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "phone_number_verified", + "jsonType.label" : "boolean" + } + } ] + }, { + "id" : "eb03e9fa-ff70-42ec-a3ea-eb379638d14a", + "name" : "address", + "description" : "OpenID Connect built-in scope: address", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "true", + "consent.screen.text" : "${addressScopeConsentText}" + }, + "protocolMappers" : [ { + "id" : "1fcb2b05-6983-4398-9261-983e0cce9c16", + "name" : "address", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-address-mapper", + "consentRequired" : false, + "config" : { + "user.attribute.formatted" : "formatted", + "user.attribute.country" : "country", + "user.attribute.postal_code" : "postal_code", + "userinfo.token.claim" : "true", + "user.attribute.street" : "street", + "id.token.claim" : "true", + "user.attribute.region" : "region", + "access.token.claim" : "true", + "user.attribute.locality" : "locality" + } + } ] + }, { + "id" : "9d9c21a1-0e86-4e5f-9d4e-bdd6b6cec8ab", + "name" : "profile", + "description" : "OpenID Connect built-in scope: profile", + "protocol" : "openid-connect", + "attributes" : { + "include.in.token.scope" : "true", + "display.on.consent.screen" : "true", + "consent.screen.text" : "${profileScopeConsentText}" + }, + "protocolMappers" : [ { + "id" : "4743649d-3337-4669-a6b4-53213195a6e2", + "name" : "zoneinfo", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "zoneinfo", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "zoneinfo", + "jsonType.label" : "String" + } + }, { + "id" : "b7609383-ed87-4ff6-a122-d2b390912699", + "name" : "username", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "username", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "preferred_username", + "jsonType.label" : "String" + } + }, { + "id" : "b3fb62b1-2880-416a-b810-1bbc6bc71cb3", + "name" : "profile", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "profile", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "profile", + "jsonType.label" : "String" + } + }, { + "id" : "f204f321-8507-4310-91a4-c48cd4d8ae8e", + "name" : "family name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "lastName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "family_name", + "jsonType.label" : "String" + } + }, { + "id" : "a9259364-f3b2-4ce2-9e99-72491c213ea9", + "name" : "updated at", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "updatedAt", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "updated_at", + "jsonType.label" : "String" + } + }, { + "id" : "084aedd5-2214-4385-9c56-ca9eb13f474b", + "name" : "locale", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "locale", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "locale", + "jsonType.label" : "String" + } + }, { + "id" : "70374f36-6d5d-4a0d-8d09-b873ce03269b", + "name" : "middle name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "middleName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "middle_name", + "jsonType.label" : "String" + } + }, { + "id" : "25f58448-5e6f-4aa7-bc07-4c80cf8a1419", + "name" : "nickname", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "nickname", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "nickname", + "jsonType.label" : "String" + } + }, { + "id" : "6afd06e2-48b2-4876-9d4b-a07d9fc08a4d", + "name" : "gender", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "gender", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "gender", + "jsonType.label" : "String" + } + }, { + "id" : "f2bc5c3f-d5b0-42ae-82f6-14b231243121", + "name" : "picture", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "picture", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "picture", + "jsonType.label" : "String" + } + }, { + "id" : "f6c11e6f-d74e-439f-a657-b0077b0e01a3", + "name" : "given name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-property-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "firstName", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "given_name", + "jsonType.label" : "String" + } + }, { + "id" : "9e79ea6c-fe2f-42c4-9aac-625e497e4601", + "name" : "full name", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-full-name-mapper", + "consentRequired" : false, + "config" : { + "id.token.claim" : "true", + "access.token.claim" : "true", + "userinfo.token.claim" : "true" + } + }, { + "id" : "f14c621f-deb5-4ddb-be0d-c3975258ed42", + "name" : "birthdate", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "birthdate", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "birthdate", + "jsonType.label" : "String" + } + }, { + "id" : "088a543c-3e84-41b9-84f5-4cc526145ac4", + "name" : "website", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usermodel-attribute-mapper", + "consentRequired" : false, + "config" : { + "userinfo.token.claim" : "true", + "user.attribute" : "website", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "website", + "jsonType.label" : "String" + } + } ] + } ], + "defaultDefaultClientScopes" : [ "profile", "email", "web-origins", "role_list", "acr", "roles" ], + "defaultOptionalClientScopes" : [ "offline_access", "microprofile-jwt", "phone", "address" ], + "browserSecurityHeaders" : { + "contentSecurityPolicyReportOnly" : "", + "xContentTypeOptions" : "nosniff", + "referrerPolicy" : "no-referrer", + "xRobotsTag" : "none", + "xFrameOptions" : "SAMEORIGIN", + "contentSecurityPolicy" : "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", + "xXSSProtection" : "1; mode=block", + "strictTransportSecurity" : "max-age=31536000; includeSubDomains" + }, + "smtpServer" : { + "password" : "password", + "starttls" : "false", + "auth" : "true", + "port" : "587", + "host" : "localhost", + "from" : "test@local.de", + "ssl" : "false", + "user" : "username" + }, + "eventsEnabled" : false, + "eventsListeners" : [ "jboss-logging" ], + "enabledEventTypes" : [ ], + "adminEventsEnabled" : false, + "adminEventsDetailsEnabled" : false, + "identityProviders" : [ ], + "identityProviderMappers" : [ ], + "components" : { + "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy" : [ { + "id" : "efe2a0c8-5a0f-473a-a778-bd0a9c376165", + "name" : "Allowed Client Scopes", + "providerId" : "allowed-client-templates", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { + "allow-default-scopes" : [ "true" ] + } + }, { + "id" : "f93bad93-3cf7-4d9e-b2f8-6a8ddc88159e", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "oidc-usermodel-property-mapper", "saml-role-list-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-attribute-mapper", "oidc-full-name-mapper", "saml-user-attribute-mapper", "saml-user-property-mapper", "oidc-address-mapper" ] + } + }, { + "id" : "2c3b38fe-fb23-4a41-b49f-a4638b0f62c9", + "name" : "Max Clients Limit", + "providerId" : "max-clients", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "max-clients" : [ "200" ] + } + }, { + "id" : "ad5c9eaa-95c9-4596-af58-cc2edb68c48f", + "name" : "Full Scope Disabled", + "providerId" : "scope", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + }, { + "id" : "7eda31ba-422f-4920-a8a2-f72f012ceb73", + "name" : "Allowed Protocol Mapper Types", + "providerId" : "allowed-protocol-mappers", + "subType" : "authenticated", + "subComponents" : { }, + "config" : { + "allowed-protocol-mapper-types" : [ "oidc-full-name-mapper", "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-property-mapper", "saml-user-attribute-mapper", "oidc-usermodel-property-mapper", "oidc-usermodel-attribute-mapper", "saml-role-list-mapper" ] + } + }, { + "id" : "b8993997-ec44-432c-8e52-bc9df863b9a8", + "name" : "Allowed Client Scopes", + "providerId" : "allowed-client-templates", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "allow-default-scopes" : [ "true" ] + } + }, { + "id" : "c7f9cc26-79d1-452e-a77a-dc3828e341af", + "name" : "Trusted Hosts", + "providerId" : "trusted-hosts", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { + "host-sending-registration-request-must-match" : [ "true" ], + "client-uris-must-match" : [ "true" ] + } + }, { + "id" : "d2e987b2-8f9a-4339-8664-7f0c3cc50f48", + "name" : "Consent Required", + "providerId" : "consent-required", + "subType" : "anonymous", + "subComponents" : { }, + "config" : { } + } ], + "org.keycloak.userprofile.UserProfileProvider" : [ { + "id" : "ca74e147-e17a-4942-83df-d3a0f75c1036", + "providerId" : "declarative-user-profile", + "subComponents" : { }, + "config" : { } + } ], + "org.keycloak.keys.KeyProvider" : [ { + "id" : "6e15cea5-b658-41d7-b296-eb6d53b8eb4f", + "name" : "aes-generated", + "providerId" : "aes-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "fb133405-b6cb-4256-8185-dcdaf3af1d53" ], + "secret" : [ "5IhMcVYhRKxRvrADXsEjNw" ], + "priority" : [ "100" ] + } + }, { + "id" : "c800a710-09d2-45eb-b031-9974f4a28f65", + "name" : "rsa-enc-generated", + "providerId" : "rsa-enc-generated", + "subComponents" : { }, + "config" : { + "privateKey" : [ "MIIEogIBAAKCAQEAnMLw/Zyj9hANLvPWAnxMuu1ggIdFV4+3Rxp9ahyxo63vucAAzD98p9A0EGUOOa2L2O9aW3awBGG6zZ1KJEHerdmTMPSTxnp7GyOnEuBBU3+l0xbYpmD04TvQKMR4+xktj73jrMMBKjL6RR4n+7bKqa8HJzbxfPnNS2ml+pBBVAmdL2UInul1zWcSwARpC20jBwNZvd5HBYcj7F9rBzYQ9LLnJqUMV8pU76H//zpbmjQtN8Y6GazC6inr/NLgAiQqOrQ7h8cVOAb+K3Ggo+p2bSW528dHzlC93PNIKv3Zwe+GR1D9PIYPjOzyRk9IRARLhzv/WG2Wnts/V/eKglePWQIDAQABAoIBAAjP3IQlHgJi/Jq7EjipjBal6VrQP9GgPok8r/gbDNFKocMrS+AvYW59ga+6PoZ3fvj+23Fwxow4giu0v8ox+baEGIYT+Yqar/jilC23dXSgJE4tZphTsvBGUHk6MiLLU4hVAEth2troarEf9Ndtew72y8wkhoaj9CpdEft3yHRUz36zS4YSiOPjWY21yFOM+a+VecGAhn2Jq6wIpVIgWSTTU+v75tO1Rkoqz6P1PLAOVv1GdZhxvswGKoZ4gi801Cl1FKy9JBojYlXMvTQhMDqDI25LCe5340LnrUJKFcJSumBRGNOOW8NhGCBG27pIjCGUyJ5HG1hn8Ne4q2lr9UECgYEAy7qjLtl2Kx6XrC4RZCnTm2jBQUAOsh18Hb3j+YH/xGDxfxI9x27LH6OBfRhCVbMHfT/Z04fansWovGffMg6qRc95ZXu1Kh09+XOUkFxUfs58kLjtcnEP+EQBC2krz5x7nrN09twZ9VT3fztWj3zSNq1/Mn7UlXSMMWSO2BTrYI0CgYEAxPtfk6FzXSNCGPIrTZ0hpMPXRDO3Hy++x4W9Obxo8DabRjdwPxmh9AQPJvvBOGbTQEF7WZTsmZif3LS00Lc6SJplfl0blqe++qEin142UxbIb1w3fWyxOZcTBmsklwsDSF+jzDzmc5m9nTKDJRpJQx8p4piTDfw3noNJWQ6utP0CgYB2Bk7pIkRKILP/pMSggXa8rshek8yvtVMlK9A5yO0yiHL/icLOmcoFL0UiAn7ThR8OmYIJAMhPePUTCR4Nst9ECDks6KkAl+ZCcIodw8+Tku4pLWkqBoQY8NSmFqyx3tbjDtXw+Xv0W9/yDp9MCyUBViu9RirD1rwtFTOHzT67NQKBgDFtll0YLTeYylQyKFWQcUnD7rdpdrD3rRqp34KmWXq1aR8keCENUItHnXm9wI1jl+zOwaIH8ZrVJoAeRCT/ZTukqoUb3fle3FhNqL9ux5jv5Zmz/SSW6p214AtDRWo1VDyL6zErsvQdBux0KV5dCzcxkbQPbw8aU+aNsREM0yANAoGAMirI3lGUx80sgxi1SwqwBWgBQKiuuqzzVbzWslbvPexlcbb4yDKxkDdcr/2JIFzVhRQUBZ3vV2Utr8W3d04AgQazJluFWcKZnzG1RAlIiWdvenQmpUbNvXcAZab6BAnVksIx5q+Dd+puQvwZ1RsfUojzZdxtqqSAmjDfrKwYlkc=" ], + "certificate" : [ "MIICuTCCAaECBgGJbVjz/zANBgkqhkiG9w0BAQsFADAgMR4wHAYDVQQDDBVvcGVuZGF0ZW5zY2h1dHpjZW50ZXIwHhcNMjMwNzE5MDg0OTUzWhcNMzMwNzE5MDg1MTMzWjAgMR4wHAYDVQQDDBVvcGVuZGF0ZW5zY2h1dHpjZW50ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCcwvD9nKP2EA0u89YCfEy67WCAh0VXj7dHGn1qHLGjre+5wADMP3yn0DQQZQ45rYvY71pbdrAEYbrNnUokQd6t2ZMw9JPGensbI6cS4EFTf6XTFtimYPThO9AoxHj7GS2PveOswwEqMvpFHif7tsqprwcnNvF8+c1LaaX6kEFUCZ0vZQie6XXNZxLABGkLbSMHA1m93kcFhyPsX2sHNhD0sucmpQxXylTvof//OluaNC03xjoZrMLqKev80uACJCo6tDuHxxU4Bv4rcaCj6nZtJbnbx0fOUL3c80gq/dnB74ZHUP08hg+M7PJGT0hEBEuHO/9YbZae2z9X94qCV49ZAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAEzWDeeF+YaorA1rSukMniMq0986YyjpzFCquyGLJljMVI9vIWe28a5dVipdtnmE92L8m90GgsoNLteBcPk0rnnlacKt5/QKRmHeVGAYi61ADgaBPnEoTu91MExrIEf54+J7A21YrgCPKMU1zQwZH+g3GTIqXaQKHtrYAhUVQlbcSNj5bS8mQmQ9fj8WlE2gVej6W6uJAQbbTuPEFXc3uH0mFoAo5RCertzNmKW9dUsg+E/3D+gWIljWYcnsilry2MmcEObDx/PZDw0YfNbF/NEkHDI0+vOr3jTV6BPG/vqn7q9kvLcPNaygCu546xkxu8+fBWKiNH1XVxQF++kihsU=" ], + "priority" : [ "100" ], + "algorithm" : [ "RSA-OAEP" ] + } + }, { + "id" : "ff7d8edf-f47b-4683-9619-705786944f15", + "name" : "hmac-generated", + "providerId" : "hmac-generated", + "subComponents" : { }, + "config" : { + "kid" : [ "05e76b22-7985-4085-94d2-2421477c0944" ], + "secret" : [ "j-6QsueBrgXi4j1m2k1tEm3fAZocVIAgVaVl7TYXs8AyPxfh9chiKpBN6e5TCzpjNDit2shtuaKBWvgfjAw6gg" ], + "priority" : [ "100" ], + "algorithm" : [ "HS256" ] + } + }, { + "id" : "0aa46395-bdac-4eeb-b562-13089a3ba49f", + "name" : "rsa-generated", + "providerId" : "rsa-generated", + "subComponents" : { }, + "config" : { + "privateKey" : [ "MIIEpAIBAAKCAQEAzb+AMNjrizv8msrg5uIvC7M8CU4gKkqXfvPXE/I4YAJuucvSkc5fzPw/RdAdvqaxNI7jJeR+eirg8UoVLhIHPYsOjtIZxvVqMKF/5mCz0L8QKMZrboJ7H5DaC9mUtiBkdeRvUI1jtLGv4aHVJRUgbycaN2uNJ18plhT/4bddY0YhW1cFSGxCmCs+QqCwFaBrrzfPXtBgAH8VMZ+VodM0Iq6G0/Rk19VBnXB9waWjS4gkkOLG8MdO/9rpHzY/lSFbt1f8SY6ghrIeQlWqM/S+l5kJrB8+KTnWw0PatckzrkSGFTOkzslN6z4Jtx14vKtWTd46H3yKZj1BlZOwhO0lqwIDAQABAoIBAA9plli9EdKkSQ/vaAQ4/VKLDVGadfO1Er7X1Uy74FfmLBU5nNR/Tn3fMijbUN8Z7ZGvrSRcMX1FU68U4EagjcT2cxNlJGPbDnwGHRFM59YYpJqUAog3Y1xspWjYgQ4DmdhFpxu0UREVc8TF3V73GNmQEaQFJ9XDMyz4SxLFgaFmBPZani637LeYcVrWdSDxSwBn00AQIR66QT7u4S8vs+bWU/TQTKOGWjXdrUCr/e8MzLkQdbW+qQ2i79FY0AIonZeKYYe9BOFXGAVIadkVMDLR4XkawOEQz8PKlyF+zJHLjQKzCZPdZJjrh6vwPMwH7Sh+9RqFDdA206eYRBMymIECgYEA++vz5yE0yqa5ImCC8cTYf8sQtqb8/E5DZYauBSI51NkyqZKdij/RfJzd/tgOq4hb79JlYXGdtsBDW7944J73I5Hvn7/pHSMjXQf2wdY03kWncspH5zMDoa/f9tdIaqd66VvyWR++LiMiMInWcfuP85crhSvPzkBo3fz4M4LWSZkCgYEA0RQwZ4ElErx5kX3eDtwOoj4c5Ns/X5WNCOEHh2vyNM/5Ac1I32Z+iLXn2hRajToPpGCiuiK9wDYROAyNU4sPZQ192/DDB7czUyV9Z/DH3+cKiNIviT1R1gAT65UNDbBKBamKE5AWgKbeN1hACQjkHmprosw1r8Z5Ym1LwfAU2+MCgYEA1/oQHuVvFxYcvoYzfQcf/V+gspczaTPHwDDY3HndTsfvEUYrXi0cclMiV6vv18uN1mtwkzwO1HC8ztm2zgw7IPmqkDC9sEdBuC5ttPzqUm0xA868GlC4GlRoFH25DgcL7yju+s2mBHQGicqCWTIs1c+Sdhd7jv3VagvI1pCjGnECgYAFmU/OhcPTY56xybgXl8cAiz9E1aY1zhBvy27jLn3W8jbN2Ix6BwmeaZii22atX3+pvDi/WUzRh+EgKh3ivdeUsi7Lo//lBf/m2xsnnGgN0+cRUOea+jxlyay+40ftNOpWinq7GWGw4kcTHlbgpw9MzTbCrktFwL/hZeHgeKhmVwKBgQC5YW269iGBKLGMqMPcoLkRCTHxjknLsBUQfE/QegKH7uKX6uE6i6v3rDkWOD0u/3BYtZ1rEaigSjGk2oRlybCO3QkwXns+eg9zn/l0O3JluYSisVa3NEc5OsYo17mbDtvVNmOPuXPZoOgFjy2lG1RFVkUoCbM8nlgbgdkaelJwxA==" ], + "certificate" : [ "MIICuTCCAaECBgGJbVj0ZTANBgkqhkiG9w0BAQsFADAgMR4wHAYDVQQDDBVvcGVuZGF0ZW5zY2h1dHpjZW50ZXIwHhcNMjMwNzE5MDg0OTUzWhcNMzMwNzE5MDg1MTMzWjAgMR4wHAYDVQQDDBVvcGVuZGF0ZW5zY2h1dHpjZW50ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNv4Aw2OuLO/yayuDm4i8LszwJTiAqSpd+89cT8jhgAm65y9KRzl/M/D9F0B2+prE0juMl5H56KuDxShUuEgc9iw6O0hnG9WowoX/mYLPQvxAoxmtugnsfkNoL2ZS2IGR15G9QjWO0sa/hodUlFSBvJxo3a40nXymWFP/ht11jRiFbVwVIbEKYKz5CoLAVoGuvN89e0GAAfxUxn5Wh0zQirobT9GTX1UGdcH3BpaNLiCSQ4sbwx07/2ukfNj+VIVu3V/xJjqCGsh5CVaoz9L6XmQmsHz4pOdbDQ9q1yTOuRIYVM6TOyU3rPgm3HXi8q1ZN3joffIpmPUGVk7CE7SWrAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAI+JeDCkDDAwTfKkiqMUcWvf4C1xiDMLhSeqZyDMO3fP72kqNUJsjdIRxfz8oRHwmCDIFt2A8ijciYC43PtziztP9GBws5W3F4FYA3VeK7FkTwtWgVQzijJzOupKoxnIaEilKTVJzxUyFRVNWjMzCNy7bfyNQOowE2HqB+8qY7Z31EbSjW9qLOKohxaAX0Act6hLCD4iMsrTPTJp+Q2Bp9o/tB1ZT2i1ggbL4eTxGnC/r9w97EsnY9bUkKk+1phCnh89/LNJSP3dEt1JZ6kb8hx+WdwFXOitk0E6fhuKJ3gr8cINxSYEtxnn2CjPa5Syex3g4PcStI3pNOMDchqXzXk=" ], + "priority" : [ "100" ] + } + } ] + }, + "internationalizationEnabled" : false, + "supportedLocales" : [ ], + "authenticationFlows" : [ { + "id" : "d9d8201c-1284-43fe-8ee7-f0e5adbb331f", + "alias" : "Account verification options", + "description" : "Method with which to verity the existing account", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "idp-email-verification", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "ALTERNATIVE", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "Verify Existing Account by Re-authentication", + "userSetupAllowed" : false + } ] + }, { + "id" : "d8e6dd83-3e08-44ed-89e7-b717ffab3d9f", + "alias" : "Browser - Conditional OTP", + "description" : "Flow to determine if the OTP is required for the authentication", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "conditional-user-configured", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "auth-otp-form", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "8cc003d8-4ded-4d60-959c-5bb7d74c51f7", + "alias" : "Direct Grant - Conditional OTP", + "description" : "Flow to determine if the OTP is required for the authentication", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "conditional-user-configured", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "direct-grant-validate-otp", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "511a4157-43dc-4f5a-a4ee-66b8ba25e251", + "alias" : "First broker login - Conditional OTP", + "description" : "Flow to determine if the OTP is required for the authentication", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "conditional-user-configured", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "auth-otp-form", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "012aa6f2-077e-494c-b864-d1d2550116da", + "alias" : "Handle Existing Account", + "description" : "Handle what to do if there is existing account with same email/username like authenticated identity provider", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "idp-confirm-link", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "Account verification options", + "userSetupAllowed" : false + } ] + }, { + "id" : "f0c9c65c-f0ef-4878-aee1-63cd78451e85", + "alias" : "Reset - Conditional OTP", + "description" : "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "conditional-user-configured", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "reset-otp", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "86aa1500-3463-4129-a0d8-f27c35b76e58", + "alias" : "User creation or linking", + "description" : "Flow for the existing/non-existing user alternatives", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticatorConfig" : "create unique user config", + "authenticator" : "idp-create-user-if-unique", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "ALTERNATIVE", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "Handle Existing Account", + "userSetupAllowed" : false + } ] + }, { + "id" : "9ebd92e3-9e6f-4d3b-b17a-6e4f18e8ed57", + "alias" : "Verify Existing Account by Re-authentication", + "description" : "Reauthentication of existing account", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "idp-username-password-form", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "CONDITIONAL", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "First broker login - Conditional OTP", + "userSetupAllowed" : false + } ] + }, { + "id" : "6ce4da9d-e6b4-45b3-b171-93fefe8c973f", + "alias" : "browser", + "description" : "browser based authentication", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "auth-cookie", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "auth-spnego", + "authenticatorFlow" : false, + "requirement" : "DISABLED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "identity-provider-redirector", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 25, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "ALTERNATIVE", + "priority" : 30, + "autheticatorFlow" : true, + "flowAlias" : "forms", + "userSetupAllowed" : false + } ] + }, { + "id" : "152ab148-f034-4163-a8d5-4674282dbee3", + "alias" : "clients", + "description" : "Base authentication for clients", + "providerId" : "client-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "client-secret", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "client-jwt", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "client-secret-jwt", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 30, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "client-x509", + "authenticatorFlow" : false, + "requirement" : "ALTERNATIVE", + "priority" : 40, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "97f5d15c-e9b8-4bfc-90fc-3498b433677c", + "alias" : "direct grant", + "description" : "OpenID Connect Resource Owner Grant", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "direct-grant-validate-username", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "direct-grant-validate-password", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "CONDITIONAL", + "priority" : 30, + "autheticatorFlow" : true, + "flowAlias" : "Direct Grant - Conditional OTP", + "userSetupAllowed" : false + } ] + }, { + "id" : "2a43f720-d624-47a4-94be-d92ebe1c9fcf", + "alias" : "docker auth", + "description" : "Used by Docker clients to authenticate against the IDP", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "docker-http-basic-authenticator", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "03970b51-ff94-4c61-8141-58df327c78c7", + "alias" : "first broker login", + "description" : "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticatorConfig" : "review profile config", + "authenticator" : "idp-review-profile", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "User creation or linking", + "userSetupAllowed" : false + } ] + }, { + "id" : "55592003-83a5-41cc-bac4-81e6c08ad8ad", + "alias" : "forms", + "description" : "Username, password, otp and other auth forms.", + "providerId" : "basic-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "auth-username-password-form", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "CONDITIONAL", + "priority" : 20, + "autheticatorFlow" : true, + "flowAlias" : "Browser - Conditional OTP", + "userSetupAllowed" : false + } ] + }, { + "id" : "aa8b7525-4e90-4684-926b-90a71ccf4828", + "alias" : "registration", + "description" : "registration flow", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "registration-page-form", + "authenticatorFlow" : true, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : true, + "flowAlias" : "registration form", + "userSetupAllowed" : false + } ] + }, { + "id" : "63ada0c0-27d5-4550-b804-aeccfbec4d18", + "alias" : "registration form", + "description" : "registration form", + "providerId" : "form-flow", + "topLevel" : false, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "registration-user-creation", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "registration-profile-action", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 40, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "registration-password-action", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 50, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "registration-recaptcha-action", + "authenticatorFlow" : false, + "requirement" : "DISABLED", + "priority" : 60, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + }, { + "id" : "e33ebd5c-8923-4924-93c8-5ecffb68ac0e", + "alias" : "reset credentials", + "description" : "Reset credentials for a user if they forgot their password or something", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "reset-credentials-choose-user", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "reset-credential-email", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 20, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticator" : "reset-password", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 30, + "autheticatorFlow" : false, + "userSetupAllowed" : false + }, { + "authenticatorFlow" : true, + "requirement" : "CONDITIONAL", + "priority" : 40, + "autheticatorFlow" : true, + "flowAlias" : "Reset - Conditional OTP", + "userSetupAllowed" : false + } ] + }, { + "id" : "a2ef0068-8769-46e6-b3ff-c006dfa3f6a2", + "alias" : "saml ecp", + "description" : "SAML ECP Profile Authentication Flow", + "providerId" : "basic-flow", + "topLevel" : true, + "builtIn" : true, + "authenticationExecutions" : [ { + "authenticator" : "http-basic-authenticator", + "authenticatorFlow" : false, + "requirement" : "REQUIRED", + "priority" : 10, + "autheticatorFlow" : false, + "userSetupAllowed" : false + } ] + } ], + "authenticatorConfig" : [ { + "id" : "6b4de39e-3e9f-4f7f-9551-ff1b3479c179", + "alias" : "create unique user config", + "config" : { + "require.password.update.after.registration" : "false" + } + }, { + "id" : "d581541f-5322-408c-bea7-0dff2df1752d", + "alias" : "review profile config", + "config" : { + "update.profile.on.first.login" : "missing" + } + } ], + "requiredActions" : [ { + "alias" : "CONFIGURE_TOTP", + "name" : "Configure OTP", + "providerId" : "CONFIGURE_TOTP", + "enabled" : true, + "defaultAction" : false, + "priority" : 10, + "config" : { } + }, { + "alias" : "TERMS_AND_CONDITIONS", + "name" : "Terms and Conditions", + "providerId" : "TERMS_AND_CONDITIONS", + "enabled" : false, + "defaultAction" : false, + "priority" : 20, + "config" : { } + }, { + "alias" : "UPDATE_PASSWORD", + "name" : "Update Password", + "providerId" : "UPDATE_PASSWORD", + "enabled" : true, + "defaultAction" : false, + "priority" : 30, + "config" : { } + }, { + "alias" : "UPDATE_PROFILE", + "name" : "Update Profile", + "providerId" : "UPDATE_PROFILE", + "enabled" : true, + "defaultAction" : false, + "priority" : 40, + "config" : { } + }, { + "alias" : "VERIFY_EMAIL", + "name" : "Verify Email", + "providerId" : "VERIFY_EMAIL", + "enabled" : true, + "defaultAction" : false, + "priority" : 50, + "config" : { } + }, { + "alias" : "delete_account", + "name" : "Delete Account", + "providerId" : "delete_account", + "enabled" : false, + "defaultAction" : false, + "priority" : 60, + "config" : { } + }, { + "alias" : "update_user_locale", + "name" : "Update User Locale", + "providerId" : "update_user_locale", + "enabled" : true, + "defaultAction" : false, + "priority" : 1000, + "config" : { } + } ], + "browserFlow" : "browser", + "registrationFlow" : "registration", + "directGrantFlow" : "direct grant", + "resetCredentialsFlow" : "reset credentials", + "clientAuthenticationFlow" : "clients", + "dockerAuthenticationFlow" : "docker auth", + "attributes" : { + "cibaBackchannelTokenDeliveryMode" : "poll", + "cibaExpiresIn" : "120", + "cibaAuthRequestedUserHint" : "login_hint", + "oauth2DeviceCodeLifespan" : "600", + "clientOfflineSessionMaxLifespan" : "0", + "oauth2DevicePollingInterval" : "5", + "clientSessionIdleTimeout" : "0", + "parRequestUriLifespan" : "60", + "clientSessionMaxLifespan" : "0", + "clientOfflineSessionIdleTimeout" : "0", + "cibaInterval" : "5", + "realmReusableOtpCode" : "false" + }, + "keycloakVersion" : "22.0.1", + "userManagedAccessAllowed" : false, + "clientProfiles" : { + "profiles" : [ ] + }, + "clientPolicies" : { + "policies" : [ ] + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index d6bb3d19..cffff372 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "open-datenschutzcenter", + "name": "html", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/src/Controller/AssignController.php b/src/Controller/AssignController.php index 96f86728..4bac52a9 100644 --- a/src/Controller/AssignController.php +++ b/src/Controller/AssignController.php @@ -17,10 +17,17 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Contracts\Translation\TranslatorInterface; #[Route(path: '/assign', name: 'assign')] class AssignController extends BaseController { + public function __construct( + private readonly TranslatorInterface $translator, + ) + { + } + #[Route(path: '/audit', name: '_audit')] public function assignAudit( Request $request, @@ -30,13 +37,16 @@ public function assignAudit( AuditTomRepository $auditTomRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $audit = $auditTomRepository->find($request->get('id')); if ($securityService->teamDataCheck($audit, $team) === false) { return $this->redirectToRoute('audit_tom'); } - $assignService->assignAudit($request, $audit); + $success = $assignService->assignAudit($request, $audit); + if (!$success) { + $this->addErrorMessage($this->translator->trans(id: 'assignError', domain: 'base')); + } return $this->redirect($request->headers->get('referer')); } @@ -49,13 +59,16 @@ public function assignDataTransfer( DatenweitergabeRepository $dataTransferRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $daten = $dataTransferRepository->find($request->get('id')); if ($securityService->teamDataCheck($daten, $team) === false) { return $this->redirectToRoute('datenweitergabe'); } - $assignService->assignDatenweitergabe($request, $daten); + $success = $assignService->assignDatenweitergabe($request, $daten); + if (!$success) { + $this->addErrorMessage($this->translator->trans(id: 'assignError', domain: 'base')); + } return $this->redirect($request->headers->get('referer')); } @@ -68,13 +81,15 @@ public function assignDsfa( VVTDsfaRepository $impactAssessmentRepository ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $impactAssessment = $impactAssessmentRepository->find($request->get('id')); if ($securityService->teamDataCheck($impactAssessment->getVvt(), $team)) { - $assignService->assignDsfa($request, $impactAssessment); + $success = $assignService->assignDsfa($request, $impactAssessment); + if (!$success) { + $this->addErrorMessage($this->translator->trans(id: 'assignError', domain: 'base')); + } return $this->redirect($request->headers->get('referer')); } - return $this->redirectToRoute('vvt'); } @@ -87,13 +102,16 @@ public function assignForm( FormsRepository $formsRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $form = $formsRepository->find($request->get('id')); if ($securityService->teamDataCheck($form, $team) === false) { return $this->redirectToRoute('forms'); } - $res = $assignService->assignForm($request, $form); + $success = $assignService->assignForm($request, $form); + if (!$success) { + $this->addErrorMessage($this->translator->trans(id: 'assignError', domain: 'base')); + } return $this->redirect($request->headers->get('referer')); } @@ -106,13 +124,16 @@ public function assignPolicy( PoliciesRepository $policiesRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $policy = $policiesRepository->find($request->get('id')); if ($securityService->teamDataCheck($policy, $team) === false) { return $this->redirectToRoute('policies'); } - $assignService->assignPolicy($request, $policy); + $success = $assignService->assignPolicy($request, $policy); + if (!$success) { + $this->addErrorMessage($this->translator->trans(id: 'assignError', domain: 'base')); + } return $this->redirect($request->headers->get('referer')); } @@ -125,13 +146,16 @@ public function assignSoftware( SoftwareRepository $softwareRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $software = $softwareRepository->find($request->get('id')); if ($securityService->teamDataCheck($software, $team) === false) { return $this->redirectToRoute('software'); } - $assignService->assignSoftware($request, $software); + $success = $assignService->assignSoftware($request, $software); + if (!$success) { + $this->addErrorMessage($this->translator->trans(id: 'assignError', domain: 'base')); + } return $this->redirect($request->headers->get('referer')); } @@ -144,13 +168,16 @@ public function assignTask( TaskRepository $taskRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $task = $taskRepository->find($request->get('id')); if ($securityService->teamDataCheck($task, $team) === false) { return $this->redirectToRoute('tasks'); } - $assignService->assignTask($request, $task); + $success = $assignService->assignTask($request, $task); + if (!$success) { + $this->addErrorMessage($this->translator->trans(id: 'assignError', domain: 'base')); + } return $this->redirect($request->headers->get('referer')); } @@ -163,13 +190,16 @@ public function assignVorfall( VorfallRepository $vorfallRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $vorfall = $vorfallRepository->find($request->get('id')); if ($securityService->teamDataCheck($vorfall, $team) === false) { return $this->redirectToRoute('vorfall'); } - $assignService->assignVorfall($request, $vorfall); + $success = $assignService->assignVorfall($request, $vorfall); + if (!$success) { + $this->addErrorMessage($this->translator->trans(id: 'assignError', domain: 'base')); + } return $this->redirect($request->headers->get('referer')); } @@ -182,20 +212,23 @@ public function assignVvt( VVTRepository $vvtRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $vvt = $vvtRepository->find($request->get('id')); if ($securityService->teamDataCheck($vvt, $team) === false) { return $this->redirectToRoute('vvt'); } - $assignService->assignVvt($request, $vvt); + $success = $assignService->assignVvt($request, $vvt); + if (!$success) { + $this->addErrorMessage($this->translator->trans(id: 'assignError', domain: 'base')); + } return $this->redirect($request->headers->get('referer')); } #[Route(path: '', name: '')] public function index(CurrentTeamService $currentTeamService, DatenweitergabeRepository $transferRepository, - VVTRepository $processingRepository, + VVTRepository $processRepository, AuditTomRepository $auditRepository, VVTDsfaRepository $impactAssessmentRepository, FormsRepository $formRepository, @@ -205,11 +238,11 @@ public function index(CurrentTeamService $currentTeamService, ): Response { $user = $this->getUser(); - $currentTeam = $currentTeamService->getTeamFromSession($user); + $currentTeam = $currentTeamService->getCurrentTeam($user); $assignedDataTransfers = $transferRepository->findActiveByTeamAndUser($currentTeam, $user); - $assignedProcessings = $processingRepository->findActiveByTeamAndUser($currentTeam, $user); + $assignedProcesses = $processRepository->findActiveByTeamAndUser($currentTeam, $user); $assignedAudits = $auditRepository->findActiveByTeamAndUser($currentTeam, $user); - $assignImpactAssessments = $impactAssessmentRepository->findActiveByTeamAndUser($currentTeam, $user); + $assignedImpactAssessments = $impactAssessmentRepository->findActiveByTeamAndUser($currentTeam, $user); $assignedForms = $formRepository->findActiveByTeamAndUser($currentTeam, $user); $assignedPolicies = $policyRepository->findActiveByTeamAndUser($currentTeam, $user); $assignedSoftware = $softwareRepository->findActiveByTeamAndUser($currentTeam, $user); @@ -218,9 +251,9 @@ public function index(CurrentTeamService $currentTeamService, return $this->render('assign/index.html.twig', [ 'currentTeam' => $currentTeam, 'dataTransfers' => $assignedDataTransfers, - 'processings' => $assignedProcessings, + 'processes' => $assignedProcesses, 'audits' => $assignedAudits, - 'impactAssessments' => $assignImpactAssessments, + 'impactAssessments' => $assignedImpactAssessments, 'forms' => $assignedForms, 'policies' => $assignedPolicies, 'software' => $assignedSoftware, diff --git a/src/Controller/AssistantController.php b/src/Controller/AssistantController.php index 9bf6fc68..d5d302c8 100644 --- a/src/Controller/AssistantController.php +++ b/src/Controller/AssistantController.php @@ -20,12 +20,18 @@ #[Route(path: '/assistant', name: 'assistant')] class AssistantController extends BaseController { + public function __construct( + private readonly TranslatorInterface $translator, + ) + { + } + #[Route('', name: '')] public function index(SecurityService $securityService, CurrentTeamService $currentTeamService, ): RedirectResponse|Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if (!$securityService->teamCheck($team)) { return $this->redirectToRoute('dashboard'); @@ -46,7 +52,7 @@ public function step(int $step, EntityManagerInterface $entityManager, ): RedirectResponse|Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if (!$securityService->teamCheck($team)) { return $this->redirectToRoute('dashboard'); @@ -66,15 +72,9 @@ public function step(int $step, if ($step == $assistantService->getStepCount()) { $assistantService->clear(); - $this->addFlash( - 'success', - 'assistant.finished' - ); + $this->addSuccessMessage($this->translator->trans(id: 'assistant.finished', domain: 'assistant')); } else { - $this->addFlash( - 'danger', - 'step.error' - ); + $this->addSuccessMessage($this->translator->trans(id: 'step.error', domain: 'assistant')); } return $this->redirectToRoute('assistant'); @@ -83,11 +83,7 @@ public function step(int $step, #[Route('/cancel', name: '_cancel')] public function cancel(AssistantService $assistantService) : Response { - $assistantService->clear(); - $this->addFlash( - 'info', - 'assistant.aborted' - ); + $this->addInfoMessage($this->translator->trans(id: 'assistant.aborted', domain: 'assistant')); return $this->redirectToRoute('assistant'); } @@ -147,7 +143,7 @@ public function select(Request $request, AssistantService $assistantService, ) : Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('dashboard'); } @@ -158,10 +154,7 @@ public function select(Request $request, if ($selected) { $assistantService->saveToSession(step: $step, data: $selected); } elseif (!$assistantService->getPropertyForStep($step, AssistantService::PROPERTY_SKIP)) { - $this->addFlash( - 'danger', - 'assistant.noneSelected' - ); + $this->addErrorMessage($this->translator->trans(id: 'assistant.noneSelected', domain: 'assistant')); return $this->redirectToRoute('assistant_step', ['step' => $step]); } return $this->redirectToRoute('assistant_step', ['step' => $step + 1]); diff --git a/src/Controller/AuditTomController.php b/src/Controller/AuditTomController.php index f2670f0b..0ed48b31 100644 --- a/src/Controller/AuditTomController.php +++ b/src/Controller/AuditTomController.php @@ -49,7 +49,7 @@ public function addAuditTom( AuditTomAbteilungRepository $auditTomAbteilungRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('audit_tom'); @@ -63,8 +63,8 @@ public function addAuditTom( $audit->setCreatedAt($today); $audit->setUser($this->getUser()); $status = $auditTomStatusRepository->findAll(); - $ziele = $auditTomZieleRepository->findByTeam($team); - $abteilungen = $auditTomAbteilungRepository->findAllByTeam($team); + $ziele = $auditTomZieleRepository->findActiveByTeam($team); + $abteilungen = $auditTomAbteilungRepository->findActiveByTeam($team); $form = $this->createForm( AuditTomType::class, @@ -108,7 +108,7 @@ public function cloneAuditTom( AuditTomRepository $auditTomRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('audit_tom'); } @@ -149,7 +149,7 @@ public function editAuditTom( AuditTomZieleRepository $auditTomZieleRepository, ) { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $audit = $auditTomRepository->find($request->get('tom')); if ($securityService->teamDataCheck($audit, $team) === false) { @@ -158,8 +158,8 @@ public function editAuditTom( $today = new DateTime(); $status = $auditTomStatusRepository->findAll(); - $abteilungen = $auditTomAbteilungRepository->findAllByTeam($team); - $ziele = $auditTomZieleRepository->findByTeam($team); + $abteilungen = $auditTomAbteilungRepository->findActiveByTeam($team); + $ziele = $auditTomZieleRepository->findActiveByTeam($team); $allAudits = array_reverse($auditTomRepository->findAllByTeam($team)); @@ -239,7 +239,7 @@ public function index( AuditTomRepository $auditTomRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $audit = $auditTomRepository->findAllByTeam($team); if ($securityService->teamCheck($team) === false) { diff --git a/src/Controller/BerichtController.php b/src/Controller/BerichtController.php index f7c54ec5..bc61c6fb 100644 --- a/src/Controller/BerichtController.php +++ b/src/Controller/BerichtController.php @@ -56,7 +56,7 @@ public function backupSoftware( VVTRepository $vvtRepository, ) { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $software = $softwareRepository->findBy(['team' => $team, 'activ' => true], ['createdAt' => 'DESC']); $vvt = $vvtRepository->findActiveByTeam($team); @@ -95,7 +95,7 @@ public function recoverySoftware( SoftwareRepository $softwareRepository, ) { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $software = $softwareRepository->findBy(['team' => $team, 'activ' => true], ['createdAt' => 'DESC']); if (count($software) < 1) { @@ -129,7 +129,7 @@ public function report( CurrentTeamService $currentTeamService, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); // Center Team authentication if (!$team) { @@ -172,7 +172,7 @@ public function reportAudit( $req = $request->get('id'); - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($req) { $audit = $auditTomRepository->findBy(array('id' => $req)); @@ -215,7 +215,7 @@ public function reportDataTransfer( ) { $id = $request->get('id'); - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($id) { $daten = $dataTransferRepository->findBy(['id'=>$id]); @@ -263,7 +263,7 @@ public function reportDeletionConcept( ini_set('max_execution_time', '900'); ini_set('memory_limit', '512M'); - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $doc = $this->translator->trans(id: 'deletionConcept.plural', domain: 'loeschkonzept'); @@ -299,7 +299,7 @@ public function reportGenerateReports( ReportRepository $reportRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $data = $request->get('report_export'); $qb = $reportRepository->createQueryBuilder('s'); @@ -405,7 +405,7 @@ public function reportGlobalTom( AuditTomRepository $auditTomRepository, ) { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $audit = $auditTomRepository->findAllByTeam($team); if (count($audit) < 1) { @@ -442,7 +442,7 @@ public function reportIncident( { $id = $request->get('id'); - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($id) { $daten = $vorfallRepository->findBy(['id'=>$id]); @@ -484,7 +484,7 @@ public function reportPolicy( ) { $id = $request->get('id'); - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($id) { $policies = $policiesRepository->findBy(['id'=>$id]); @@ -527,7 +527,7 @@ public function reportRequest( { $id = $request->get('id'); - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($id) { $clientRequest = $clientRequestRepository->findBy(['id'=>$id]); @@ -568,7 +568,7 @@ public function reportSoftware( ) { $id = $request->get('id'); - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($id) { $software = $softwareRepository->findBy(['id'=>$id]); @@ -610,7 +610,7 @@ public function reportTom( { $req = $request->get('id'); - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($req) { $tom = $tomRepository->findBy(array('id' => $req)); @@ -653,7 +653,7 @@ public function reportVvt( ini_set('memory_limit', '512M'); $req = $request->get('id'); - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $doc = $this->translator->trans(id: 'processing.directory', domain: 'vvt'); if ($req) { @@ -695,7 +695,7 @@ public function reports( ReportRepository $reportRepository, ) { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $users = $team->getMembers(); $members = []; diff --git a/src/Controller/ClientRequestController.php b/src/Controller/ClientRequestController.php index 8505f4ea..6b715fd9 100644 --- a/src/Controller/ClientRequestController.php +++ b/src/Controller/ClientRequestController.php @@ -40,7 +40,7 @@ public function allClientRequests( ClientRequestRepository $clientRequestRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $client = $clientRequestRepository->findBy(['team' => $team, 'emailValid' => true]); if ($securityService->teamCheck($team) === false) { @@ -84,7 +84,7 @@ public function clientRequestComment( ): Response { $clientRequest = $clientRequestRepository->find($request->get('clientRequest')); - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamDataCheck($clientRequest, $team) === false) { return $this->redirectToRoute('client_requests'); } @@ -111,7 +111,7 @@ public function closeRequest( { $clientRequest = $clientRequestRepository->find($request->get('id')); $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); if ($securityService->teamDataCheck($clientRequest, $team) && $securityService->adminCheck($user, $team)) { $clientRequestService->closeRequest($clientRequest, $this->getUser()); @@ -134,7 +134,7 @@ public function editClientRequests( ) { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); $clientRequest = $clientRequestRepository->find($request->get('id')); if ($securityService->teamDataCheck($clientRequest, $team) && $securityService->adminCheck($user, $team)) { @@ -145,7 +145,7 @@ public function editClientRequests( $this->translator->trans(id: 'reason', domain: 'general') . ': ' . $clientRequest->getItemString(), $this->translator->trans(id: 'description', domain: 'general') . ': ' . $clientRequest->getDescription(), $this->translator->trans(id: 'additionalInformation', domain: 'general') . ': ' . $clientRequest->getFirstname() . ' ' . $clientRequest->getLastname(), - $this->translator->trans(id: 'birthday', domain: 'general') . ': ' . $clientRequest->getBirthday()->format('d.m.Y'), + $this->translator->trans(id: 'birthday', domain: 'general') . ': ' . $clientRequest->getBirthday()?->format('d.m.Y'), $this->translator->trans(id: 'address', domain: 'general') . ': ' . $clientRequest->getStreet() . ' ' . $clientRequest->getCity(), ]; $content = implode(' | ', $contentArray); @@ -220,7 +220,7 @@ public function internalNoteClientRequests( ClientRequestRepository $clientRequestRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $clientRequest = $clientRequestRepository->find($request->get('id')); if ($securityService->teamDataCheck($clientRequest, $team) === false) { @@ -270,7 +270,7 @@ public function makeInternalRequest( { $clientRequest = $clientRequestRepository->find($request->get('id')); $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); if ($securityService->teamDataCheck($clientRequest, $team) && $securityService->adminCheck($user, $team)) { if ($clientRequestService->interalRequest($clientRequest)) { @@ -350,7 +350,7 @@ public function showClientRequests( ClientRequestRepository $clientRequestRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $clientRequest = $clientRequestRepository->find($request->get('id')); if ($securityService->teamDataCheck($clientRequest, $team) === false) { @@ -433,7 +433,7 @@ public function validateUserRequest( { $clientRequest = $clientRequestRepository->find($request->get('id')); $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); if ($securityService->teamDataCheck($clientRequest, $team) && $securityService->adminCheck($user, $team)) { $clientRequestService->userValid($clientRequest, $user); diff --git a/src/Controller/DashboardController.php b/src/Controller/DashboardController.php index 9769a3e5..36af45e8 100644 --- a/src/Controller/DashboardController.php +++ b/src/Controller/DashboardController.php @@ -44,7 +44,7 @@ public function dashboard(Request $request, SecurityService $securityService, TeamRepository $teamRepository, DatenweitergabeRepository $transferRepository, - VVTRepository $procedureRepository, + VVTRepository $processRepository, AuditTomRepository $auditRepository, VVTDsfaRepository $impactAssessmentRepository, FormsRepository $formRepository, @@ -66,7 +66,7 @@ public function dashboard(Request $request, // else get team for current user $user = $this->getUser(); - $currentTeam = $currentTeamService->getTeamFromSession($user); + $currentTeam = $currentTeamService->getCurrentTeam($user); if ($currentTeam === null) { if ($securityService->superAdminCheck($this->getUser())) { @@ -84,9 +84,9 @@ public function dashboard(Request $request, $audit = $auditRepository->findAllByTeam($currentTeam); $daten = $transferRepository->findActiveTransfersByTeam($currentTeam); $av = $transferRepository->findActiveOrderProcessingsByTeam($currentTeam); - $vvt = $procedureRepository->findActiveByTeam($currentTeam); + $processes = $processRepository->findActiveByTeam($currentTeam); $vvtDsfa = $impactAssessmentRepository->findActiveByTeam($currentTeam); - $kontakte = $contactRepository->findActiveByTeam($currentTeam); + $contacts = $contactRepository->findActiveByTeam($currentTeam); $tom = $tomRepository->findActiveByTeam($currentTeam); $forms = $formRepository->findPublicByTeam($currentTeam); $policies = $policyRepository->findPublicByTeam($currentTeam); @@ -95,11 +95,11 @@ public function dashboard(Request $request, $loeschkonzepte = $deletionConceptRepository->findByTeam($currentTeam); $vvtdatenkategorien = $dataCategoryRepository->findByTeam($currentTeam); $kritischeAudits = $auditRepository->findCriticalByTeam($currentTeam); - $kritischeVvts = $procedureRepository->findCriticalByTeam($currentTeam); + $criticalProcesses = $processRepository->findCriticalByTeam($currentTeam); $openDsfa = $impactAssessmentRepository->findActiveAndOpenByTeam($currentTeam); $buchungen = $bookingRepository->findActiveByUser($user); - $assignVvt = $procedureRepository->findActiveByTeamAndUser($currentTeam, $user); + $assignVvt = $processRepository->findActiveByTeamAndUser($currentTeam, $user); $assignAudit = $auditRepository->findActiveByTeamAndUser($currentTeam, $user); $assignDsfa = $impactAssessmentRepository->findActiveByTeamAndUser($currentTeam, $user); $assignDatenweitergabe = $transferRepository->findActiveByTeamAndUser($currentTeam, $user); @@ -109,11 +109,11 @@ public function dashboard(Request $request, 'currentTeam' => $currentTeam, 'audit' => $audit, 'daten' => $daten, - 'vvt' => $vvt, + 'vvt' => $processes, 'dsfa' => $vvtDsfa, - 'kontakte' => $kontakte, + 'kontakte' => $contacts, 'kAudit' => $kritischeAudits, - 'kVvt' => $kritischeVvts, + 'kVvt' => $criticalProcesses, 'openDsfa' => $openDsfa, 'tom' => $tom, 'av' => $av, diff --git a/src/Controller/DatenweitergabeController.php b/src/Controller/DatenweitergabeController.php index 3ce2f166..37b6b4c0 100644 --- a/src/Controller/DatenweitergabeController.php +++ b/src/Controller/DatenweitergabeController.php @@ -9,7 +9,9 @@ namespace App\Controller; use App\Entity\Datenweitergabe; +use App\Entity\Team; use App\Repository\DatenweitergabeRepository; +use App\Repository\TeamRepository; use App\Service\ApproveService; use App\Service\AssignService; use App\Service\CurrentTeamService; @@ -46,7 +48,7 @@ public function addAuftragsverarbeitung( ): Response { set_time_limit(600); - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('dashboard'); } @@ -95,7 +97,7 @@ public function addDatenweitergabe( ): Response { set_time_limit(600); - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('dashboard'); } @@ -144,7 +146,7 @@ public function approveDatenweitergabe( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); $daten = $dataTransferRepository->find($request->get('id')); if ($securityService->teamDataCheck($daten, $team) && $securityService->adminCheck($user, $team)) { @@ -184,7 +186,7 @@ public function disableDatenweitergabe( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); $daten = $dataTransferRepository->find($request->get('id')); if ($securityService->teamDataCheck($daten, $team) && $securityService->adminCheck($user, $team) && !$daten->getApproved()) { @@ -208,7 +210,7 @@ public function downloadArticleReference( ): Response { $stream = $datenFilesystem->read($datenweitergabe->getUpload()); - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamDataCheck($datenweitergabe, $team) === false) { $logger->error( 'DOWNLOAD', @@ -256,24 +258,23 @@ public function editDatenweitergabe( ): Response { set_time_limit(600); - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $daten = $dataTransferRepository->find($request->get('id')); - - if ($securityService->teamDataCheck($daten, $team) === false) { - if ($daten->getArt() === 1) { - return $this->redirectToRoute('datenweitergabe'); - } - return $this->redirectToRoute('auftragsverarbeitung'); + if (!$this->checkAccess($securityService, $daten, $team)) { + $redirectRoute = $daten->getArt() === 1 ? 'datenweitergabe' : 'auftragsverarbeitung'; + return $this->redirectToRoute($redirectRoute); } $newDaten = $datenweitergabeService->cloneDatenweitergabe($daten, $this->getUser()); - $form = $datenweitergabeService->createForm($newDaten, $team); + $isEditable = $daten->getTeam() === $team; + $form = $datenweitergabeService->createForm($newDaten, $team, ['disabled' => !$isEditable]); $form->remove('nummer'); $form->handleRequest($request); - $assign = $assignService->createForm($daten, $team); + $assign = $assignService->createForm($daten, $team, ['disabled' => !$isEditable]); + $title = $daten->getArt() == 1 ? 'dataTransfer.edit' : 'orderProcessing.edit'; $errors = array(); - if ($form->isSubmitted() && $form->isValid() && $daten->getActiv() && !$daten->getApproved()) { + if ($form->isSubmitted() && $form->isValid() && $daten->getActiv() && !$daten->getApproved() && $isEditable) { $daten->setActiv(false); @@ -310,10 +311,12 @@ public function editDatenweitergabe( 'form' => $form->createView(), 'assignForm' => $assign->createView(), 'errors' => $errors, - 'title' => $this->translator->trans(id: 'dataTransfer.edit', domain: 'datenweitergabe'), + 'title' => $this->translator->trans(id: $title, domain: 'datenweitergabe'), 'daten' => $daten, 'activ' => $daten->getActiv(), 'activNummer' => false, + 'isEditable' => $isEditable, + 'currentTeam' => $team, ]); } @@ -321,18 +324,18 @@ public function editDatenweitergabe( public function indexAuftragsverarbeitung( SecurityService $securityService, CurrentTeamService $currentTeamService, - DatenweitergabeRepository $dataTransferRepository, + DatenweitergabeRepository $transferRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('dashboard'); } - $daten = $dataTransferRepository->findBy(array('team' => $team, 'activ' => true, 'art' => 2)); + $daten = $transferRepository->findAllOrderProcessingsByTeam($team); return $this->render('datenweitergabe/indexAuftragsverarbeitung.html.twig', [ 'table' => $daten, - 'titel' => $this->translator->trans(id: 'dataTransfer.disclaimer', domain: 'datenweitergabe'), + 'title' => $this->translator->trans(id: 'orderProcessing.disclaimer', domain: 'datenweitergabe'), 'currentTeam' => $team, ]); } @@ -341,19 +344,34 @@ public function indexAuftragsverarbeitung( public function indexDataTransfer( SecurityService $securityService, CurrentTeamService $currentTeamService, - DatenweitergabeRepository $dataTransferRepository, + DatenweitergabeRepository $transferRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('dashboard'); } - $daten = $dataTransferRepository->findBy(array('team' => $team, 'activ' => true, 'art' => 1)); + $daten = $transferRepository->findAllTransfersByTeam($team); return $this->render('datenweitergabe/index.html.twig', [ 'table' => $daten, - 'titel' => $this->translator->trans(id: 'dataTransfer.disclaimer', domain: 'datenweitergabe'), + 'title' => $this->translator->trans(id: 'dataTransfer.disclaimer', domain: 'datenweitergabe'), 'currentTeam' => $team, ]); } + + private function checkAccess(SecurityService $securityService, ?Datenweitergabe $transfer, Team $team): bool + { + if (!$transfer) { + $this->addErrorMessage($this->translator->trans(id: 'elementDoesNotExistError', domain: 'base')); + return false; + } + + if (!$securityService->checkTeamAccessToTransfer($transfer, $team)) { + $this->addErrorMessage($this->translator->trans(id: 'accessDeniedError', domain: 'base')); + return false; + } + + return true; + } } diff --git a/src/Controller/DsfaController.php b/src/Controller/DsfaController.php index 8e0d2616..60985091 100644 --- a/src/Controller/DsfaController.php +++ b/src/Controller/DsfaController.php @@ -35,7 +35,7 @@ public function index(): Response { return $this->render('dsfa/index.html.twig', [ 'title' => $this->translator->trans(id: 'dataProtectionImpactAssessment.word_plural', domain: 'vvt'), - 'dsfas' => $this->repo->findAllByTeam($this->getTeam()), + 'dsfas' => $this->repo->findActiveByTeam($this->getTeam()), ]); } @@ -48,7 +48,7 @@ public function new(ValidatorInterface $validator, Request $request): Response return $this->redirectToRoute('vvt'); } - $dsfa = $this->VVTService->newDsfa($team, $this->getUser(), $vvt); + $dsfa = $this->VVTService->newDsfa($this->getUser(), $vvt); $form = $this->createForm(VvtDsfaType::class,$dsfa ); $form->handleRequest($request); $errors = array(); @@ -81,6 +81,7 @@ public function edit(ValidatorInterface $validator, Request $request, AssignServ { $team = $this->getTeam(); $dsfa = $this->repo->find($request->get('dsfa')); + $isEditable = $dsfa->getVvt()->getTeam() === $team; if ($this->securityService->teamDataCheck($dsfa->getVvt(), $team) === false) { return $this->redirectToRoute('vvt'); @@ -118,11 +119,12 @@ public function edit(ValidatorInterface $validator, Request $request, AssignServ 'title' => $this->translator->trans(id: 'dataPrivacyFollowUpEstimation.edit', domain: 'vvt'), 'dsfa' => $dsfa, 'activ' => $dsfa->getActiv(), + 'isEditable' => $isEditable, ]); } private function getTeam(): ?Team { - return $this->currentTeamService->getTeamFromSession($this->getUser()); + return $this->currentTeamService->getCurrentTeam($this->getUser()); } } diff --git a/src/Controller/ExternalController.php b/src/Controller/ExternalController.php index 0b7681df..f95e6289 100644 --- a/src/Controller/ExternalController.php +++ b/src/Controller/ExternalController.php @@ -15,7 +15,7 @@ public function index( CurrentTeamService $currentTeamService, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('dashboard'); } diff --git a/src/Controller/FormsController.php b/src/Controller/FormsController.php index a080d569..880e2cad 100644 --- a/src/Controller/FormsController.php +++ b/src/Controller/FormsController.php @@ -40,7 +40,7 @@ public function addForms( CurrentTeamService $currentTeamService, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('dashboard'); @@ -85,7 +85,7 @@ public function approvePolicy( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); $forms = $formsRepository->find($request->get('id')); if ($securityService->teamDataCheck($forms, $team) && $securityService->adminCheck($user, $team)) { @@ -108,7 +108,7 @@ public function disable( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); $forms = $formsRepository->find($request->get('id')); if ($securityService->teamDataCheck($forms, $team) && $securityService->adminCheck($user, $team) && !$forms->getApproved()) { @@ -130,7 +130,7 @@ public function downloadArticleReference( { $stream = $formsFilesystem->read($forms->getUpload()); - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamDataCheck($forms, $team) === false) { $logger->error( 'DOWNLOAD', @@ -178,7 +178,7 @@ public function editFormulare( FormsRepository $formsRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $forms = $formsRepository->find($request->get('id')); if ($securityService->teamDataCheck($forms, $team) === false) { @@ -232,7 +232,7 @@ public function indexForms( FormsRepository $formsRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('dashboard'); } diff --git a/src/Controller/KontaktController.php b/src/Controller/KontaktController.php index df13cd95..8b91f491 100644 --- a/src/Controller/KontaktController.php +++ b/src/Controller/KontaktController.php @@ -11,6 +11,7 @@ use App\Entity\Kontakte; use App\Form\Type\KontaktType; use App\Repository\KontakteRepository; +use App\Repository\TeamRepository; use App\Service\ApproveService; use App\Service\CurrentTeamService; use App\Service\DisableService; @@ -40,7 +41,7 @@ public function addKontakt( CurrentTeamService $currentTeamService, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('dashboard'); } @@ -70,6 +71,8 @@ public function addKontakt( 'errors' => $errors, 'title' => $this->translator->trans(id: 'contact.create', domain: 'kontakt'), 'new' => true, + 'isEditable' => true, + 'currentTeam' => $team, ]); } @@ -83,7 +86,7 @@ public function approve( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); $kontakt = $contactRepository->find($request->get('id')); if ($securityService->teamDataCheck($kontakt, $team) && $securityService->adminCheck($user, $team)) { @@ -106,7 +109,7 @@ public function disable( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); $kontakt = $contactRepository->find($request->get('id')); if ($securityService->teamDataCheck($kontakt, $team) && $securityService->adminCheck($user, $team) && !$kontakt->getApproved()) { @@ -122,20 +125,22 @@ public function editKontakt( Request $request, SecurityService $securityService, CurrentTeamService $currentTeamService, - KontakteRepository $contactRepository, + KontakteRepository $contactRepository ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); - $kontakt = $contactRepository->find($request->get('id')); - if ($securityService->teamDataCheck($kontakt, $team) === false) { - return $this->redirectToRoute('kurse'); + $team = $currentTeamService->getCurrentTeam($this->getUser()); + $contact = $contactRepository->find($request->get('id')); + if (!$securityService->checkTeamAccessToContact($contact, $team)) { + $this->addErrorMessage($this->translator->trans(id: 'accessDeniedError', domain: 'base')); + return $this->redirectToRoute('kontakt'); } - $form = $this->createForm(KontaktType::class, $kontakt); + $isEditable = $contact->getTeam() === $team; + $form = $this->createForm(KontaktType::class, $contact, ['disabled' => !$isEditable]); $form->handleRequest($request); $errors = array(); - if ($form->isSubmitted() && $form->isValid()) { + if ($form->isSubmitted() && $form->isValid() && $isEditable) { $data = $form->getData(); $errors = $validator->validate($data); if (count($errors) == 0) { @@ -145,7 +150,7 @@ public function editKontakt( return $this->redirectToRoute( 'kontakt_edit', [ - 'id' => $kontakt->getId(), + 'id' => $contact->getId(), ] ); } @@ -155,9 +160,11 @@ public function editKontakt( return $this->render('kontakt/edit.html.twig', [ 'form' => $form->createView(), - 'kontakt' => $kontakt, + 'kontakt' => $contact, 'errors' => $errors, - 'title' => $this->translator->trans(id: 'contact.create', domain: 'kontakt'), + 'title' => $this->translator->trans(id: 'contact.edit', domain: 'kontakt'), + 'isEditable' => $isEditable, + 'currentTeam' => $team, ]); } @@ -168,15 +175,15 @@ public function index( KontakteRepository $contactRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('dashboard'); } - $kontakte = $contactRepository->findBy(['team' => $team, 'activ' => true]); + $contacts = $contactRepository->findAllByTeam($team); return $this->render('kontakt/index.html.twig', [ - 'kontakte' => $kontakte, + 'kontakte' => $contacts, 'title' => $this->translator->trans(id: 'contact', domain: 'general'), 'currentTeam' => $team, ]); diff --git a/src/Controller/KursController.php b/src/Controller/KursController.php index f2535fff..cb790203 100644 --- a/src/Controller/KursController.php +++ b/src/Controller/KursController.php @@ -87,7 +87,7 @@ public function editKurs( { $this->setBackButton($this->generateUrl('akademie_admin') . '#tab-courses'); $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); $kurs = $academyLessonRepository->find($request->get('id')); if ($securityService->teamArrayDataCheck($kurs, $team) === false) { @@ -133,7 +133,7 @@ public function kursAnmelden( { $this->setBackButton($this->generateUrl('akademie_admin') . '#tab-courses'); $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); $kurs = $academyLessonRepository->find($request->get('id')); if ($securityService->teamArrayDataCheck($kurs, $team) === false) { @@ -168,7 +168,7 @@ public function kursDeaktivieren( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); $kurs = $academyLessonRepository->find($request->get('id')); if (!$securityService->teamArrayDataCheck($kurs, $team)) { diff --git a/src/Controller/LoeschkonzeptController.php b/src/Controller/LoeschkonzeptController.php index ace436ba..f497ffe5 100644 --- a/src/Controller/LoeschkonzeptController.php +++ b/src/Controller/LoeschkonzeptController.php @@ -31,7 +31,7 @@ public function delete( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); if ($securityService->teamCheck($team) && $securityService->adminCheck($user, $team)) { $loeschkonzept->setActiv(false); $entityManager->persist($loeschkonzept); @@ -52,7 +52,7 @@ public function edit( CurrentTeamService $currentTeamService, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('app_loeschkonzept_index'); } @@ -103,7 +103,7 @@ public function index( CurrentTeamService $currentTeamService, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('dashboard'); } @@ -144,7 +144,7 @@ public function new( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('dashboard'); @@ -177,12 +177,14 @@ public function new( } #[Route(path: '/{id}/details', name: 'app_loeschkonzept_show', methods: ['GET'])] - public function show(Loeschkonzept $loeschkonzept): Response + public function show(Loeschkonzept $loeschkonzept, CurrentTeamService $teamService): Response { $this->setBackButton($this->generateUrl('app_loeschkonzept_index')); + $currentTeam = $teamService->getCurrentTeam($this->getUser()); return $this->render('loeschkonzept/show.html.twig', [ 'loeschkonzept' => $loeschkonzept, + 'current_team' => $currentTeam, ]); } } diff --git a/src/Controller/PoliciesController.php b/src/Controller/PoliciesController.php index 2fc94740..8028b2b8 100644 --- a/src/Controller/PoliciesController.php +++ b/src/Controller/PoliciesController.php @@ -4,6 +4,7 @@ use App\Entity\Policies; use App\Repository\PoliciesRepository; +use App\Repository\TeamRepository; use App\Service\ApproveService; use App\Service\AssignService; use App\Service\CurrentTeamService; @@ -40,7 +41,7 @@ public function addPolicy( CurrentTeamService $currentTeamService, ) { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('policies'); @@ -86,7 +87,7 @@ public function approvePolicy( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); $policy = $policiesRepository->find($request->get('id')); if ($securityService->teamDataCheck($policy, $team) && $securityService->adminCheck($user, $team)) { @@ -109,7 +110,7 @@ public function disable( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); $policy = $policiesRepository->find($request->get('id')); if ($securityService->teamDataCheck($policy, $team) && $securityService->adminCheck($user, $team) && !$policy->getApproved()) { @@ -132,7 +133,7 @@ public function downloadArticleReference( $stream = $policiesFilesystem->read($policies->getUpload()); - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamDataCheck($policies, $team) === false) { $logger->error( 'DOWNLOAD', @@ -180,19 +181,21 @@ public function editPolicy( PoliciesRepository $policiesRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $policy = $policiesRepository->find($request->get('id')); - if ($securityService->teamDataCheck($policy, $team) === false) { + if (!$securityService->checkTeamAccessToPolicy($policy, $team)) { + $this->addErrorMessage($this->translator->trans(id: 'accessDeniedError', domain: 'base')); return $this->redirectToRoute('policies'); } $newPolicy = $policiesService->clonePolicy($policy, $this->getUser()); - $form = $policiesService->createForm($newPolicy, $team); + $isEditable = $policy->getTeam() === $team; + $form = $policiesService->createForm($newPolicy, $team, ['disabled' => !$isEditable]); $form->handleRequest($request); - $assign = $assignService->createForm($policy, $team); + $assign = $assignService->createForm($policy, $team, ['disabled' => !$isEditable]); $errors = array(); - if ($form->isSubmitted() && $form->isValid() && $policy->getActiv() && !$policy->getApproved()) { + if ($form->isSubmitted() && $form->isValid() && $policy->getActiv() && !$policy->getApproved() && $isEditable) { $policy->setActiv(false); $newPolicy = $form->getData(); $errors = $validator->validate($newPolicy); @@ -219,6 +222,8 @@ public function editPolicy( 'title' => $this->translator->trans(id: 'policies.edit', domain: 'policies'), 'policy' => $policy, 'activ' => $policy->getActiv(), + 'isEditable' => $isEditable, + 'currentTeam' => $team, ]); } @@ -229,14 +234,15 @@ public function index( PoliciesRepository $policiesRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('dashboard'); } - $polcies = $policiesRepository->findActiveByTeam($team); + + $policies = $policiesRepository->findAllByTeam($team); return $this->render('policies/index.html.twig', [ - 'data' => $polcies, + 'data' => $policies, 'currentTeam' => $team, ]); } diff --git a/src/Controller/QuestionnaireController.php b/src/Controller/QuestionnaireController.php index 4c0be0f2..d459dbfe 100644 --- a/src/Controller/QuestionnaireController.php +++ b/src/Controller/QuestionnaireController.php @@ -186,6 +186,6 @@ private function getCurrentTeam(): Team /** @var User&UserInterface $user */ $user = $this->getUser(); - return $this->currentTeamService->getTeamFromSession($user); + return $this->currentTeamService->getCurrentTeam($user); } -} \ No newline at end of file +} diff --git a/src/Controller/ReportController.php b/src/Controller/ReportController.php index 3f3c51e1..bdebe78d 100644 --- a/src/Controller/ReportController.php +++ b/src/Controller/ReportController.php @@ -33,7 +33,7 @@ public function addReport( CurrentTeamService $currentTeamService, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('report'); } @@ -74,7 +74,7 @@ public function deleteReport( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); $report = $reportRepository->find($request->get('id')); if ($securityService->teamDataCheck($report, $team) && $securityService->adminCheck($user, $team)) { @@ -96,7 +96,7 @@ public function editReport( ReportRepository $reportRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $report = $reportRepository->find($request->get('id')); if ($securityService->teamDataCheck($report, $team) === false) { @@ -146,7 +146,7 @@ public function index( ReportRepository $reportRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $report = $reportRepository->findActiveByTeam($team); if ($securityService->teamCheck($team) === false) { @@ -167,7 +167,7 @@ public function invoiceReport( ReportRepository $reportRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $report = $reportRepository->find($request->get('id')); if ($securityService->teamDataCheck($report, $team) === true) { diff --git a/src/Controller/SoftwareController.php b/src/Controller/SoftwareController.php index d7d29237..e756c1b0 100644 --- a/src/Controller/SoftwareController.php +++ b/src/Controller/SoftwareController.php @@ -2,9 +2,12 @@ namespace App\Controller; +use App\Entity\Software; use App\Entity\SoftwareConfig; +use App\Entity\Team; use App\Repository\SoftwareConfigRepository; use App\Repository\SoftwareRepository; +use App\Repository\TeamRepository; use App\Service\ApproveService; use App\Service\AssignService; use App\Service\CurrentTeamService; @@ -41,7 +44,7 @@ public function addConfig( ) { //Requests: id: SoftwareID, config: ConfigID - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $software = $softwareRepository->find($request->get('id')); if ($securityService->teamDataCheck($software, $team) === false) { @@ -104,7 +107,7 @@ public function addSoftware( CurrentTeamService $currentTeamService, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('software'); @@ -149,7 +152,7 @@ public function approveSoftware( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); $software = $softwareRepository->find($request->get('id')); if ($securityService->teamDataCheck($software, $team) && $securityService->adminCheck($user, $team)) { @@ -183,7 +186,7 @@ public function deleteConfig( { // Request: config: ConfigID $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); $config = $softwareConfigRepository->find($request->get('config')); if ($securityService->teamDataCheck($config->getSoftware(), $team) && $securityService->adminCheck($user, $team)) { @@ -210,7 +213,7 @@ public function downloadArticleReference( CurrentTeamService $currentTeamService, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $path = $this->getParameter('kernel.project_dir') . "/data/software/" . $softwareConfig->getUpload(); if ($securityService->teamDataCheck($softwareConfig->getSoftware(), $team) === false) { @@ -229,22 +232,24 @@ public function editSoftware( SecurityService $securityService, AssignService $assignService, CurrentTeamService $currentTeamService, - SoftwareRepository $softwareRepository, + SoftwareRepository $softwareRepository ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + //Request: id: SoftwareID, snack:Snack Notice + $team = $currentTeamService->getCurrentTeam($this->getUser()); $software = $softwareRepository->find($request->get('id')); - if ($securityService->teamDataCheck($software, $team) === false) { + if (!$this->checkAccess($securityService, $software, $team)) { return $this->redirectToRoute('software'); } $newSoftware = $softwareService->cloneSoftware($software, $this->getUser()); - $form = $softwareService->createForm($newSoftware, $team); + $isEditable = $software->getTeam() === $team; + $form = $softwareService->createForm($newSoftware, $team, ['disabled' => !$isEditable]); $form->handleRequest($request); - $assign = $assignService->createForm($software, $team); + $assign = $assignService->createForm($software, $team, ['disabled' => !$isEditable]); $errors = array(); - if ($form->isSubmitted() && $form->isValid() && $software->getActiv() && !$software->getApproved()) { + if ($form->isSubmitted() && $form->isValid() && $software->getActiv() && !$software->getApproved() && $isEditable) { $software->setActiv(false); $newSoftware = $form->getData(); @@ -278,6 +283,8 @@ public function editSoftware( 'title' => $this->translator->trans(id: 'software.edit', domain: 'software'), 'software' => $software, 'activ' => $software->getActiv(), + 'isEditable' => $isEditable, + 'currentTeam' => $team, ]); } @@ -289,11 +296,12 @@ public function index( SoftwareRepository $softwareRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + //Request: snack: Snack Notice + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('dashboard'); } - $software = $softwareRepository->findActiveByTeam($team); + $software = $softwareRepository->findAllByTeam($team); return $this->render('software/index.html.twig', [ 'data' => $software, @@ -301,4 +309,19 @@ public function index( 'currentTeam' => $team, ]); } + + private function checkAccess(SecurityService $securityService, ?Software $software, Team $team): bool + { + if (!$software) { + $this->addErrorMessage($this->translator->trans(id: 'elementDoesNotExistError', domain: 'base')); + return false; + } + + if (!$securityService->checkTeamAccessToSoftware($software, $team)) { + $this->addErrorMessage($this->translator->trans(id: 'elementDoesNotExistError', domain: 'base')); + return false; + } + + return true; + } } diff --git a/src/Controller/TaskController.php b/src/Controller/TaskController.php index 873a24f2..e86076a1 100644 --- a/src/Controller/TaskController.php +++ b/src/Controller/TaskController.php @@ -35,7 +35,7 @@ public function addTask( CurrentTeamService $currentTeamService, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('tasks'); } @@ -77,7 +77,7 @@ public function disable( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); $task = $taskRepository->find($request->get('id')); if ($securityService->teamDataCheck($task, $team) && $securityService->adminCheck($user, $team)) { @@ -103,7 +103,7 @@ public function done( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); $task = $taskRepository->find($request->get('id')); if ($securityService->teamDataCheck($task, $team) && $securityService->adminCheck($user, $team)) { @@ -129,7 +129,7 @@ public function editTask( TaskRepository $taskRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $task = $taskRepository->find($request->get('id')); if ($securityService->teamDataCheck($task, $team) === false) { @@ -184,7 +184,7 @@ public function index( TaskRepository $taskRepository, ) { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($request->get('all')) { $tasks = $taskRepository->findActiveByTeam($team); $all = true; diff --git a/src/Controller/TeamController.php b/src/Controller/TeamController.php index 8bd02a85..116d67ee 100644 --- a/src/Controller/TeamController.php +++ b/src/Controller/TeamController.php @@ -20,10 +20,11 @@ use App\Repository\TeamRepository; use App\Repository\VVTStatusRepository; use App\Service\CurrentTeamService; +use App\Service\InheritanceService; use App\Service\SecurityService; use App\Service\TeamService; use Doctrine\ORM\EntityManagerInterface; -use Proxies\__CG__\App\Entity\DatenweitergabeStand; +use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -55,7 +56,7 @@ public function abteilungenAdd( return $this->redirectToRoute('dashboard'); } - $departments = $departmentRepository->findAllByTeam($team); + $departments = $departmentRepository->findActiveByTeam($team); if ($request->get('id')) { $department = $departmentRepository->find($request->get('id')); @@ -99,7 +100,7 @@ public function abteilungenRemove( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); if ($securityService->adminCheck($user, $team) === false) { return $this->redirectToRoute('team_abteilungen'); @@ -120,13 +121,25 @@ public function create( ValidatorInterface $validator, EntityManagerInterface $em, Request $request, - CurrentTeamService $teamService, + SecurityService $securityService, + TeamRepository $teamRepository, ): Response { $user = $this->getUser(); + + if ($securityService->superAdminCheck($user) === false) { + return $this->redirectToRoute('dashboard'); + } + + $teams = $teamRepository->findAll(); + $team = new Team(); $team->setActiv(true); - $form = $this->createForm(TeamType::class, $team); + $form = $this->createForm( + TeamType::class, + $team, + ['teams' => $teams,] + ); $form->remove('video'); $form->remove('externalLink'); $form->handleRequest($request); @@ -171,7 +184,7 @@ public function customCreate( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); if ($securityService->adminCheck($user, $team) === false) { return $this->redirectToRoute('dashboard'); @@ -203,19 +216,16 @@ public function customCreate( } #[Route(path: '/team_custom/vvtStatus/network', name: 'team_custom_network_vvtstatus')] - public function customvvtStatusToogleNetwork( + public function customvvtStatusToggleNetwork( Request $request, SecurityService $securityService, - EntityManagerInterface $em, - TeamService $teamService, - ValidatorInterface $validator, CurrentTeamService $currentTeamService, VVTStatusRepository $VVTStatusRepository, EntityManagerInterface $entityManager, ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); if ($securityService->adminCheck($user, $team) === false) { return $this->redirectToRoute('dashboard'); @@ -231,19 +241,16 @@ public function customvvtStatusToogleNetwork( } #[Route(path: '/team_custom/datenweitergabeStatus/network', name: 'team_custom_network_datenweitergabestatus')] - public function customdatenweitergabeToogleNetwork( + public function customdatenweitergabeToggleNetwork( Request $request, SecurityService $securityService, - EntityManagerInterface $em, - TeamService $teamService, - ValidatorInterface $validator, CurrentTeamService $currentTeamService, DatenweitergabeStandRepository $datenweitergabeStandRepository, EntityManagerInterface $entityManager, ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); if ($securityService->adminCheck($user, $team) === false) { return $this->redirectToRoute('dashboard'); @@ -268,7 +275,7 @@ public function customDeactivate( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); if ($securityService->adminCheck($user, $team) === false) { return $this->redirectToRoute('team_custom'); @@ -319,6 +326,7 @@ public function edit( SecurityService $securityService, CurrentTeamService $currentTeamService, TeamRepository $teamRepository, + LoggerInterface $logger, ): Response { $user = $this->getUser(); @@ -332,11 +340,18 @@ public function edit( $currentTeam = $team; } + // only admins can edit if (!$team || (!$securityService->adminCheck($user, $team))) { return $this->redirectToRoute('dashboard'); } - $form = $this->createForm(TeamType::class, $team); + $availableTeams = $currentTeamService->getTeamsWithoutCurrentHierarchy($user, $team); + + $form = $this->createForm( + TeamType::class, + $team, + ['teams' => $availableTeams,] + ); $form->handleRequest($request); $errors = array(); @@ -345,6 +360,10 @@ public function edit( $errors = $validator->validate($nTeam); if (count($errors) == 0) { $em->persist($nTeam); + if($teamRepository->verify() !== true) { + $logger->alert('Tree invalid, attempting recovery', $teamRepository->verify()); + $teamRepository->recover(); + } $em->flush(); if ($teamId) { return $this->redirectToRoute('team_edit', ['id' => $teamId]); @@ -450,4 +469,43 @@ public function teamDelete( ]); } } + + #[Route(path: '/team_custom/ignore', name: 'preset_set_ignored', methods: 'PUT|POST')] + public function setPresetIgnored( + Request $request, + UrlGeneratorInterface $urlGenerator, + TeamRepository $teamRepository, + EntityManagerInterface $em, + InheritanceService $inheritanceService, + SecurityService $securityService + ): RedirectResponse + { + $user = $this->getUser(); + $team = $request->get('team'); + $preset = $request->get('preset'); + $type = $request->get('type'); + $ignored = $request->get('set'); + + if (is_numeric($team)) { + $team = $teamRepository->find($team); + } + + if (is_numeric($preset)) { + $preset = $em->getRepository($type)->find($preset); + } + + if ($securityService->adminCheck($user, $team) === false) { + return $this->redirectToRoute('dashboard'); + } + + if ($team && $preset) { + $inheritanceService->setIgnored($preset, $team, $ignored); + $em->persist($preset); + $em->persist($team); + $em->flush(); + } + + $referer = $request->headers->get('referer'); + return new RedirectResponse($referer ?: $urlGenerator->generate('dashboard')); + } } diff --git a/src/Controller/TeamMemberController.php b/src/Controller/TeamMemberController.php index a62afe3f..11495bd7 100644 --- a/src/Controller/TeamMemberController.php +++ b/src/Controller/TeamMemberController.php @@ -39,7 +39,7 @@ public function academyAdmin( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); // Admin Route only if (!$securityService->adminCheck($user, $team)) { @@ -157,7 +157,7 @@ public function dsbRemove( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); if ($securityService->adminCheck($user, $team) === false) { return $this->redirectToRoute('dashboard'); @@ -199,6 +199,7 @@ public function mitgliederAdd( $currentTeam = null; $settings = $settingsRepository->findOne(); $useKeycloakGroups = $settings ? $settings->getUseKeycloakGroups() : false; + $this->setBackButton($this->generateUrl('manage_teams')); if ($teamId) { $team = $teamRepository->find($teamId); diff --git a/src/Controller/TomController.php b/src/Controller/TomController.php index f98c5340..149dc0e8 100644 --- a/src/Controller/TomController.php +++ b/src/Controller/TomController.php @@ -10,6 +10,7 @@ use App\Form\Type\TomType; use App\Repository\AuditTomRepository; +use App\Repository\TeamRepository; use App\Repository\TomRepository; use App\Service\ApproveService; use App\Service\CurrentTeamService; @@ -43,7 +44,7 @@ public function addAuditTom( CurrentTeamService $currentTeamService, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('tom'); } @@ -74,6 +75,7 @@ public function addAuditTom( 'tom' => $tom, 'activ' => $tom->getActiv(), 'activTitel' => true, + 'isEditable' => true, ]); } @@ -87,7 +89,7 @@ public function approve( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); $tom = $tomRepository->find($request->get('id')); if ($securityService->teamDataCheck($tom, $team) && $securityService->adminCheck($user, $team)) { @@ -107,7 +109,7 @@ public function cloneTom( AuditTomRepository $auditTomRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($team === null) { return $this->redirectToRoute('dashboard'); } @@ -144,7 +146,7 @@ public function disable( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); $tom = $tomRepository->find($request->get('id')); if ($securityService->teamDataCheck($tom, $team) && $securityService->adminCheck($user, $team)) { @@ -164,20 +166,22 @@ public function editTom( TomRepository $tomRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $tom = $tomRepository->find($request->get('tom')); - if ($securityService->teamDataCheck($tom, $team) === false) { + if ($securityService->checkTeamAccessToTom($tom, $team) === false) { + $this->addErrorMessage($this->translator->trans(id: 'accessDeniedError', domain: 'base')); return $this->redirectToRoute('tom'); } $newTom = $tomService->cloneTom($tom, $this->getUser()); - $form = $this->createForm(TomType::class, $newTom); + $isEditable = $tom->getTeam() === $team; + $form = $this->createForm(TomType::class, $newTom, ['disabled' => !$isEditable]); $form->remove('titel'); $form->handleRequest($request); $errors = []; - if ($form->isSubmitted() && $form->isValid() && $tom->getActiv() === 1 && !$tom->getApproved()) { + if ($form->isSubmitted() && $form->isValid() && $tom->getActiv() === 1 && !$tom->getApproved() && $isEditable) { $tom->setActiv(false); $newTom = $form->getData(); @@ -206,6 +210,7 @@ public function editTom( 'activ' => $tom->getActiv(), 'activTitel' => false, 'currentTeam' => $team, + 'isEditable' => $isEditable, ]); } @@ -216,13 +221,13 @@ public function index( TomRepository $tomRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); - $tom = $tomRepository->findActiveByTeam($team); - + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('dashboard'); } + $tom = $tomRepository->findAllByTeam($team); + return $this->render('tom/index.html.twig', [ 'tom' => $tom, 'currentTeam' => $team diff --git a/src/Controller/VVTDatenkategorieController.php b/src/Controller/VVTDatenkategorieController.php index b1d49357..34a5e566 100644 --- a/src/Controller/VVTDatenkategorieController.php +++ b/src/Controller/VVTDatenkategorieController.php @@ -31,7 +31,7 @@ public function delete( CurrentTeamService $currentTeamService, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === true) { if ($this->isCsrfTokenValid('delete' . $vVTDatenkategorie->getId(), $request->request->get('_token'))) { @@ -54,7 +54,7 @@ public function edit( CurrentTeamService $currentTeamService, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('app_vvtdatenkategorie_index'); } @@ -96,7 +96,7 @@ public function index( CurrentTeamService $currentTeamService, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('dashboard'); } @@ -116,7 +116,7 @@ public function new( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('dashboard'); } @@ -140,12 +140,14 @@ public function new( } #[Route(path: '/show/{id}', name: 'app_vvtdatenkategorie_show', methods: ['GET'])] - public function show(VVTDatenkategorie $vVTDatenkategorie): Response + public function show(VVTDatenkategorie $vVTDatenkategorie, CurrentTeamService $teamService): Response { $this->setBackButton($this->generateUrl('app_vvtdatenkategorie_index')); + $currentTeam = $teamService->getCurrentTeam($this->getUser()); return $this->render('vvt_datenkategorie/show.html.twig', [ 'vvtdatenkategorie' => $vVTDatenkategorie, + 'current_team' => $currentTeam, ]); } } diff --git a/src/Controller/VorfallController.php b/src/Controller/VorfallController.php index 3980e8eb..8c1b1314 100644 --- a/src/Controller/VorfallController.php +++ b/src/Controller/VorfallController.php @@ -40,7 +40,7 @@ public function addVorfall( CurrentTeamService $currentTeamService, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('dashboard'); } @@ -82,7 +82,7 @@ public function approve( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); $vorfall = $incidentRepository->find($request->get('id')); if ($securityService->teamDataCheck($vorfall, $team) && $securityService->adminCheck($user, $team)) { @@ -106,7 +106,7 @@ public function editVorfall( VorfallRepository $incidentRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $vorgang = $incidentRepository->find($request->get('id')); if ($securityService->teamDataCheck($vorgang, $team) === false) { @@ -157,7 +157,7 @@ public function index( VorfallRepository $incidentRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('dashboard'); diff --git a/src/Controller/VvtController.php b/src/Controller/VvtController.php index 1bf2b54b..f1f4219e 100644 --- a/src/Controller/VvtController.php +++ b/src/Controller/VvtController.php @@ -9,6 +9,7 @@ namespace App\Controller; use App\Form\Type\VvtDsfaType; +use App\Repository\TeamRepository; use App\Repository\VVTDsfaRepository; use App\Repository\VVTRepository; use App\Service\ApproveService; @@ -19,9 +20,11 @@ use App\Service\VVTDatenkategorieService; use App\Service\VVTService; use Doctrine\ORM\EntityManagerInterface; +use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Validator\Validator\ValidatorInterface; use Symfony\Contracts\Translation\TranslatorInterface; @@ -45,7 +48,7 @@ public function addVvt( CurrentTeamService $currentTeamService, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('vvt'); @@ -86,6 +89,7 @@ public function addVvt( 'vvt' => $vvt, 'activ' => $vvt->getActiv(), 'CTA' => false, + 'isEditable' => true, ]); } @@ -98,7 +102,7 @@ public function approveVvt( VVTRepository $vvtRepository, ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $vvt = $vvtRepository->find($request->get('id')); if ($securityService->teamDataCheck($vvt, $team) === false) { @@ -146,7 +150,7 @@ public function cloneVvt( ): Response { $vvt = $vvtRepository->find($request->get('id')); - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamDataCheck($vvt, $team) === false) { return $this->redirectToRoute('vvt'); @@ -186,6 +190,7 @@ public function cloneVvt( 'vvt' => $newVvt, 'activ' => $newVvt->getActiv(), 'CTA' => false, + 'isEditable' => true, ]); } @@ -199,7 +204,7 @@ public function disableVvt( ): Response { $user = $this->getUser(); - $team = $currentTeamService->getTeamFromSession($user); + $team = $currentTeamService->getCurrentTeam($user); $vvt = $vvtRepository->find($request->get('id')); if ($securityService->teamDataCheck($vvt, $team) && $securityService->adminCheck($user, $team) && !$vvt->getApproved()) { @@ -216,37 +221,51 @@ public function editVvt( VVTService $VVTService, SecurityService $securityService, AssignService $assignService, - VVTDatenkategorieService $VVTDatenkategorieService, + VVTDatenkategorieService $vvtDatenkategorieService, CurrentTeamService $currentTeamService, - VVTRepository $vvtRepository, + VVTRepository $vvtRepository ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); $vvt = $vvtRepository->find($request->get('id')); - if ($securityService->teamDataCheck($vvt, $team) === false) { + if ($securityService->checkTeamAccessToProcess($vvt, $team) === false) { + $this->addErrorMessage($this->translator->trans(id: 'accessDeniedError', domain: 'base')); return $this->redirectToRoute('vvt'); } $newVvt = $VVTService->cloneVvt($vvt, $this->getUser()); + $latestCategories = []; - foreach ($vvt->getKategorien() as $cloneKat) {//hier haben wir die geklonten KAtegorien - $newVvt->addKategorien($VVTDatenkategorieService->findLatestKategorie($cloneKat->getCloneOf()));//wir hängen die neueste gültige Datenkategorie an den VVT clone an. + foreach ($vvt->getKategorien() as $category) {//hier haben wir die geklonten Kategorien + $cloneOf = $category->getCloneOf() ?: $category; //wir hängen die neueste gültige Datenkategorie an den VVT clone an. + $latestCategory = $vvtDatenkategorieService->findLatestKategorie($cloneOf); + $newVvt->addKategorien($latestCategory); + $latestCategories[] = $latestCategory; } - $form = $VVTService->createForm($newVvt, $team); + $isEditable = $vvt->getTeam() === $team; + $form = $VVTService->createForm($newVvt, $team, ['disabled' => !$isEditable]); $form->remove('nummer'); $form->handleRequest($request); $assign = $assignService->createForm($vvt, $team); $errors = array(); - if ($form->isSubmitted() && $form->isValid() && $vvt->getActiv() && !$vvt->getApproved()) { + $inheritedEntities = []; + + if (!$isEditable) { + // This vvt was inherited by ancestor team. + // In this case we want inherited categories and deletion concepts available by links inside the vvt form. + $inheritedEntities = $vvtDatenkategorieService->getInheritedEntities($latestCategories); + } + + if ($form->isSubmitted() && $form->isValid() && $vvt->getActiv() && !$vvt->getApproved() && $isEditable) { $vvt->setActiv(false); $newVvt = $form->getData(); $errors = $validator->validate($newVvt); if (count($errors) == 0) { foreach ($newVvt->getKategorien() as $kategorie) { // wir haben die fiktiven neuesten Kategories - $tmp = $VVTDatenkategorieService->createChild($kategorie);//wir klonen die kategorie damit diese revisionssicher ist + $tmp = $vvtDatenkategorieService->createChild($kategorie);//wir klonen die kategorie damit diese revisionssicher ist $newVvt->removeKategorien($kategorie);//wir entferenen die fiktive neues kategorie $newVvt->addKategorien($tmp);//wir fügen die geklonte kategorie an } @@ -292,6 +311,9 @@ public function editVvt( 'vvt' => $vvt, 'activ' => $vvt->getActiv(), 'activNummer' => false, + 'isEditable' => $isEditable, + 'currentTeam' => $team, + 'inheritedEntities' => $inheritedEntities, ]); } @@ -300,18 +322,53 @@ public function index( SecurityService $securityService, Request $request, CurrentTeamService $currentTeamService, - VVTRepository $vvtRepository, + VVTRepository $vvtRepository ): Response { - $team = $currentTeamService->getTeamFromSession($this->getUser()); + $team = $currentTeamService->getCurrentTeam($this->getUser()); if ($securityService->teamCheck($team) === false) { return $this->redirectToRoute('dashboard'); } - $vvt = $vvtRepository->findActiveByTeam($team); + $vvt = $vvtRepository->findAllByTeam($team); return $this->render('vvt/index.html.twig', [ 'vvt' => $vvt, 'currentTeam' => $team, ]); } + + #[Route(path: '/vvt/ignore', name: 'vvt_set_ignored')] + public function setVvtIgnored( + Request $request, + UrlGeneratorInterface $urlGenerator, + TeamRepository $teamRepository, + VVTRepository $vvtRepository, + ): RedirectResponse + { + $team = $request->get('team'); + $vvt = $request->get('vvt'); + $active = $request->get('set'); + + if (is_numeric($team)) { + $team = $teamRepository->find($team); + } + + if (is_numeric($vvt)) { + $vvt = $vvtRepository->find($vvt); + } + + if($team && $vvt) { + if ($active) { + $team->removeIgnoredInheritance($vvt); + } else { + $team->addIgnoredInheritance($vvt); + } + $this->em->persist($vvt); + $this->em->persist($team); + $this->em->flush(); + } + + $referer = $request->headers->get('referer'); + return new RedirectResponse($referer ?: $urlGenerator->generate('dashboard')); + } } diff --git a/src/DataTypes/InheritedEntity.php b/src/DataTypes/InheritedEntity.php new file mode 100644 index 00000000..b1b9772b --- /dev/null +++ b/src/DataTypes/InheritedEntity.php @@ -0,0 +1,41 @@ +category = null; + $this->deletionConcept = null; + } + + public function getCategory(): ?VVTDatenkategorie + { + return $this->category; + } + + public function setCategory(?VVTDatenkategorie $category): InheritedEntity + { + $this->category = $category; + return $this; + } + + public function getDeletionConcept(): ?Loeschkonzept + { + return $this->deletionConcept; + } + + public function setDeletionConcept(?Loeschkonzept $deletionConcept): InheritedEntity + { + $this->deletionConcept = $deletionConcept; + return $this; + } +} diff --git a/src/Entity/AuditTomZiele.php b/src/Entity/AuditTomZiele.php index b9f52353..9b1139c3 100644 --- a/src/Entity/AuditTomZiele.php +++ b/src/Entity/AuditTomZiele.php @@ -3,10 +3,11 @@ namespace App\Entity; use App\Repository\AuditTomZieleRepository; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity(repositoryClass: AuditTomZieleRepository::class)] -class AuditTomZiele +class AuditTomZiele extends Preset { #[ORM\Id] #[ORM\GeneratedValue] @@ -23,6 +24,9 @@ class AuditTomZiele #[ORM\Column(type: 'boolean')] private $activ; + #[ORM\ManyToMany(targetEntity: Team::class, inversedBy: 'ignoredAuditGoals')] + protected $ignoredInTeams; + public function getId(): ?int { return $this->id; diff --git a/src/Entity/DatenweitergabeGrundlagen.php b/src/Entity/DatenweitergabeGrundlagen.php index 0d6c762d..0a5d769e 100644 --- a/src/Entity/DatenweitergabeGrundlagen.php +++ b/src/Entity/DatenweitergabeGrundlagen.php @@ -3,10 +3,11 @@ namespace App\Entity; use App\Repository\DatenweitergabeGrundlagenRepository; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity(repositoryClass: DatenweitergabeGrundlagenRepository::class)] -class DatenweitergabeGrundlagen +class DatenweitergabeGrundlagen extends Preset { #[ORM\Id] #[ORM\GeneratedValue] @@ -22,6 +23,9 @@ class DatenweitergabeGrundlagen #[ORM\Column(type: 'boolean')] private $activ = true; + #[ORM\ManyToMany(targetEntity: Team::class, inversedBy: 'ignoredDWGrounds')] + protected $ignoredInTeams; + public function getId(): ?int { return $this->id; diff --git a/src/Entity/DatenweitergabeStand.php b/src/Entity/DatenweitergabeStand.php index 19cd2e18..00cb39e2 100644 --- a/src/Entity/DatenweitergabeStand.php +++ b/src/Entity/DatenweitergabeStand.php @@ -3,10 +3,11 @@ namespace App\Entity; use App\Repository\DatenweitergabeStandRepository; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity(repositoryClass: DatenweitergabeStandRepository::class)] -class DatenweitergabeStand +class DatenweitergabeStand extends Preset { #[ORM\Id] #[ORM\GeneratedValue] @@ -25,6 +26,9 @@ class DatenweitergabeStand #[ORM\Column(type: 'boolean')] private $activ; + #[ORM\ManyToMany(targetEntity: Team::class, inversedBy: 'ignoredDWStates')] + protected $ignoredInTeams; + public function getId(): ?int { return $this->id; diff --git a/src/Entity/Preset.php b/src/Entity/Preset.php new file mode 100644 index 00000000..1f386a31 --- /dev/null +++ b/src/Entity/Preset.php @@ -0,0 +1,57 @@ +inherited; + } + + public function setInherited(bool $inherited): self + { + $this->inherited = $inherited; + + return $this; + } + + /** + * @return Collection|null + */ + public function getIgnoredInTeams(): ?Collection + { + return $this->ignoredInTeams; + } + + public function addIgnoredInTeam(Team $team): self + { + if (!$this->ignoredInTeams->contains($team)) { + $this->ignoredInTeams[] = $team; + } + + return $this; + } + + public function removeIgnoredInTeam(Team $team): self + { + if ($this->ignoredInTeams->contains($team)) { + $this->ignoredInTeams->removeElement($team); + } + + return $this; + } + + public function getClass(): string + { + return (new \ReflectionClass($this))->getName(); + } +} diff --git a/src/Entity/Produkte.php b/src/Entity/Produkte.php index 6116963f..2d0c89c9 100644 --- a/src/Entity/Produkte.php +++ b/src/Entity/Produkte.php @@ -8,7 +8,7 @@ use Doctrine\ORM\Mapping as ORM; #[ORM\Entity(repositoryClass: ProdukteRepository::class)] -class Produkte +class Produkte extends Preset { #[ORM\Id] #[ORM\GeneratedValue] @@ -28,6 +28,9 @@ class Produkte #[ORM\ManyToMany(targetEntity: VVT::class, mappedBy: 'produkt')] private $Vvts; + #[ORM\ManyToMany(targetEntity: Team::class, inversedBy: 'ignoredProducts')] + protected $ignoredInTeams; + public function __construct() { $this->Vvts = new ArrayCollection(); diff --git a/src/Entity/Team.php b/src/Entity/Team.php index 3b3eedab..3dee97e8 100644 --- a/src/Entity/Team.php +++ b/src/Entity/Team.php @@ -9,14 +9,17 @@ namespace App\Entity; use Ambta\DoctrineEncryptBundle\Configuration\Encrypted; -use App\Repository\TeamRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; +use Gedmo\Tree\Entity\Repository\NestedTreeRepository; +use phpDocumentor\Reflection\Types\Boolean; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Component\Validator\Constraints as Assert; +use Gedmo\Mapping\Annotation as Gedmo; -#[ORM\Entity(repositoryClass: TeamRepository::class)] +#[Gedmo\Tree(type: 'nested')] +#[ORM\Entity(repositoryClass: NestedTreeRepository::class)] #[UniqueEntity('slug')] class Team { @@ -162,21 +165,74 @@ class Team #[ORM\Column(type: 'text', nullable: true)] private $specialty; - #[ORM\OneToMany(targetEntity: VVTStatus::class, mappedBy: 'team')] + #[ORM\OneToMany(mappedBy: 'team', targetEntity: VVTStatus::class)] private Collection $vVTStatuses; - #[ORM\OneToMany(targetEntity: DatenweitergabeGrundlagen::class, mappedBy: 'team')] + #[ORM\OneToMany(mappedBy: 'team', targetEntity: DatenweitergabeGrundlagen::class)] private Collection $datenweitergabeGrundlagens; - #[ORM\OneToMany(targetEntity: DatenweitergabeStand::class, mappedBy: 'team')] + #[ORM\OneToMany(mappedBy: 'team', targetEntity: DatenweitergabeStand::class)] private Collection $datenweitergabeStands; - #[ORM\OneToMany(targetEntity: Loeschkonzept::class, mappedBy: 'team')] + #[ORM\OneToMany(mappedBy: 'team', targetEntity: Loeschkonzept::class)] private Collection $loeschkonzepts; - - #[ORM\OneToMany(targetEntity: Questionnaire::class, mappedBy: 'team')] + + #[ORM\OneToMany(mappedBy: 'team', targetEntity: Questionnaire::class)] private Collection $questionnaires; + #[Gedmo\TreeLevel] + #[ORM\Column(name: 'lvl', type: 'integer', nullable: true)] + private $lvl; + + #[Gedmo\TreeRoot] + #[ORM\ManyToOne(targetEntity: Team::class)] + #[ORM\JoinColumn(name: 'tree_root', referencedColumnName: 'id', nullable: true, onDelete: 'CASCADE')] + private $root; + + #[Gedmo\TreeParent] + #[ORM\ManyToOne(targetEntity: Team::class, inversedBy: 'children')] + #[ORM\JoinColumn(name: 'parent_id', referencedColumnName: 'id', onDelete: 'CASCADE')] + private $parent; + + #[Gedmo\TreeLeft] + #[ORM\Column(name: 'lft', type: 'integer', nullable: true)] + private $lft; + + #[Gedmo\TreeRight] + #[ORM\Column(name: 'rgt', type: 'integer', nullable: true)] + private $rgt; + + #[ORM\OneToMany(mappedBy: 'parent', targetEntity: Team::class)] + private $children; + + // inherited VVTs can be deactivated for individual child teams + #[ORM\ManyToMany(targetEntity: VVT::class, mappedBy: 'ignoredInTeams')] + private $ignoredInheritances; + + #[ORM\ManyToMany(targetEntity: VVTPersonen::class, mappedBy: 'ignoredInTeams')] + private $ignoredVVTPersons; + + #[ORM\ManyToMany(targetEntity: VVTRisiken::class, mappedBy: 'ignoredInTeams')] + private $ignoredVVTRisks; + + #[ORM\ManyToMany(targetEntity: VVTGrundlage::class, mappedBy: 'ignoredInTeams')] + private $ignoredVVTGrounds; + + #[ORM\ManyToMany(targetEntity: VVTStatus::class, mappedBy: 'ignoredInTeams')] + private $ignoredVVTStates; + + #[ORM\ManyToMany(targetEntity: Produkte::class, mappedBy: 'ignoredInTeams')] + private $ignoredProducts; + + #[ORM\ManyToMany(targetEntity: DatenweitergabeStand::class, mappedBy: 'ignoredInTeams')] + private $ignoredDWStates; + + #[ORM\ManyToMany(targetEntity: DatenweitergabeGrundlagen::class, mappedBy: 'ignoredInTeams')] + private $ignoredDWGrounds; + + #[ORM\ManyToMany(targetEntity: AuditTomZiele::class, mappedBy: 'ignoredInTeams')] + private $ignoredAuditGoals; + public function __construct() { $this->members = new ArrayCollection(); @@ -203,6 +259,7 @@ public function __construct() $this->vVTRisikens = new ArrayCollection(); $this->vVTGrundlages = new ArrayCollection(); $this->vVTStatuses = new ArrayCollection(); + $this->ignoredInheritances = new ArrayCollection(); $this->datenweitergabeGrundlagens = new ArrayCollection(); $this->datenweitergabeStands = new ArrayCollection(); $this->loeschkonzepts = new ArrayCollection(); @@ -1330,4 +1387,276 @@ public function getDeleteBlockers(): array if (count($this->loeschkonzepts)) $blockers[] = 'deleteConcepts'; return $blockers; } + + public function getRoot(): ?self + { + return $this->root; + } + + public function setParent(self $parent = null): void + { + $this->parent = $parent; + } + + public function getParent(): ?self + { + return $this->parent; + } + + public function getChildren(): ?Collection + { + return $this->children; + } + + /** + * @return Collection + */ + public function getIgnoredInheritances(): Collection + { + return $this->ignoredInheritances; + } + + public function addIgnoredInheritance(VVT $vvt): self + { + if (!$this->ignoredInheritances->contains($vvt)) { + $this->ignoredInheritances[] = $vvt; + $vvt->addIgnoredInTeam($this); + } + + return $this; + } + + public function removeIgnoredInheritance(VVT $vvt): self + { + if ($this->ignoredInheritances->contains($vvt)) { + $this->ignoredInheritances->removeElement($vvt); + $vvt->removeIgnoredInTeam($this); + } + + return $this; + } + + /** + * @return Collection + */ + public function getIgnoredVVTPersons(): Collection + { + return $this->ignoredVVTPersons; + } + + public function addIgnoredVVTPerson(VVTPersonen $person): self + { + if (!$this->ignoredVVTPersons->contains($person)) { + $this->ignoredVVTPersons[] = $person; + $person->addIgnoredInTeam($this); + } + + return $this; + } + + public function removeIgnoredVVTPerson(VVTPersonen $person): self + { + if ($this->ignoredVVTPersons->contains($person)) { + $this->ignoredVVTPersons->removeElement($person); + $person->removeIgnoredInTeam($this); + } + + return $this; + } + + /** + * @return Collection + */ + public function getIgnoredVVTStates(): Collection + { + return $this->ignoredVVTStates; + } + + public function addIgnoredVVTState(VVTStatus $state): self + { + if (!$this->ignoredVVTStates->contains($state)) { + $this->ignoredVVTStates[] = $state; + $state->addIgnoredInTeam($this); + } + + return $this; + } + + public function removeIgnoredVVTState(VVTStatus $state): self + { + if ($this->ignoredVVTStates->contains($state)) { + $this->ignoredVVTStates->removeElement($state); + $state->removeIgnoredInTeam($this); + } + + return $this; + } + + /** + * @return Collection + */ + public function getIgnoredVVTGrounds(): Collection + { + return $this->ignoredVVTGrounds; + } + + public function addIgnoredVVTGround(VVTGrundlage $ground): self + { + if (!$this->ignoredVVTGrounds->contains($ground)) { + $this->ignoredVVTGrounds[] = $ground; + $ground->addIgnoredInTeam($this); + } + + return $this; + } + + public function removeIgnoredVVTGround(VVTGrundlage $ground): self + { + if ($this->ignoredVVTGrounds->contains($ground)) { + $this->ignoredVVTGrounds->removeElement($ground); + $ground->removeIgnoredInTeam($this); + } + + return $this; + } + + /** + * @return Collection + */ + public function getIgnoredVVTRisks(): Collection + { + return $this->ignoredVVTRisks; + } + + public function addIgnoredVVTRisk(VVTRisiken $risk): self + { + if (!$this->ignoredVVTRisks->contains($risk)) { + $this->ignoredVVTRisks[] = $risk; + $risk->addIgnoredInTeam($this); + } + + return $this; + } + + public function removeIgnoredVVTRisk(VVTRisiken $risk): self + { + if ($this->ignoredVVTRisks->contains($risk)) { + $this->ignoredVVTRisks->removeElement($risk); + $risk->removeIgnoredInTeam($this); + } + + return $this; + } + + /** + * @return Collection + */ + public function getIgnoredAuditGoals(): Collection + { + return $this->ignoredAuditGoals; + } + + public function addIgnoredAuditGoal(AuditTomZiele $goal): self + { + if (!$this->ignoredAuditGoals->contains($goal)) { + $this->ignoredAuditGoals[] = $goal; + $goal->addIgnoredInTeam($this); + } + + return $this; + } + + public function removeIgnoredAuditGoal(AuditTomZiele $goal): self + { + if ($this->ignoredAuditGoals->contains($goal)) { + $this->ignoredAuditGoals->removeElement($goal); + $goal->removeIgnoredInTeam($this); + } + + return $this; + } + + /** + * @return Collection + */ + public function getIgnoredDWGrounds(): Collection + { + return $this->ignoredDWGrounds; + } + + public function addIgnoredDWGround(DatenweitergabeGrundlagen $ground): self + { + if (!$this->ignoredDWGrounds->contains($ground)) { + $this->ignoredDWGrounds[] = $ground; + $ground->addIgnoredInTeam($this); + } + + return $this; + } + + public function removeIgnoredDWGround(DatenweitergabeGrundlagen $ground): self + { + if ($this->ignoredDWGrounds->contains($ground)) { + $this->ignoredDWGrounds->removeElement($ground); + $ground->removeIgnoredInTeam($this); + } + + return $this; + } + + /** + * @return Collection + */ + public function getIgnoredDWStates(): Collection + { + return $this->ignoredDWStates; + } + + public function addIgnoredDWState(DatenweitergabeStand $state): self + { + if (!$this->ignoredDWStates->contains($state)) { + $this->ignoredDWStates[] = $state; + $state->addIgnoredInTeam($this); + } + + return $this; + } + + public function removeIgnoredDWState(DatenweitergabeStand $state): self + { + if ($this->ignoredDWStates->contains($state)) { + $this->ignoredDWStates->removeElement($state); + $state->removeIgnoredInTeam($this); + } + + return $this; + } + + /** + * @return Collection + */ + public function getIgnoredProducts(): Collection + { + return $this->ignoredProducts; + } + + public function addIgnoredProduct(Produkte $product): self + { + if (!$this->ignoredProducts->contains($product)) { + $this->ignoredProducts[] = $product; + $product->addIgnoredInTeam($this); + } + + return $this; + } + + public function removeIgnoredProduct(Produkte $product): self + { + if ($this->ignoredProducts->contains($product)) { + $this->ignoredProducts->removeElement($product); + $product->removeIgnoredInTeam($this); + } + + return $this; + } } diff --git a/src/Entity/VVT.php b/src/Entity/VVT.php index c741f382..0335a603 100644 --- a/src/Entity/VVT.php +++ b/src/Entity/VVT.php @@ -146,9 +146,6 @@ class VVT #[ORM\ManyToMany(targetEntity: Produkte::class, inversedBy: 'Vvts')] private $produkt; - private $beurteilungEintrittString; - private $beurteilungSchadenString; - #[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'assignedVvts')] private $assignedUser; @@ -168,11 +165,18 @@ class VVT private $source; /** - * @Encrypted() + * @Encrypted() */ #[ORM\Column(type: 'text', nullable: true)] private $loeschfrist; + #[ORM\Column(type: 'boolean')] + private $inherited = false; + + // inherited VVTs can be deactivated for individual child teams + #[ORM\ManyToMany(targetEntity: Team::class, inversedBy: 'ignoredInheritances')] + private $ignoredInTeams; + public function __construct() { $this->grundlage = new ArrayCollection(); @@ -832,7 +836,45 @@ public function setLoeschfrist(?string $loeschfrist): self $this->loeschfrist = $loeschfrist; return $this; - } + } + + public function isInherited(): bool + { + return $this->inherited; + } + + public function setInherited(bool $inherited): self + { + $this->inherited = $inherited; + + return $this; + } + + /** + * @return Collection + */ + public function getIgnoredInTeams(): Collection + { + return $this->ignoredInTeams; + } + + public function addIgnoredInTeam(Team $team): self + { + if (!$this->ignoredInTeams->contains($team)) { + $this->ignoredInTeams[] = $team; + } + + return $this; + } + + public function removeIgnoredInTeam(Team $team): self + { + if ($this->ignoredInTeams->contains($team)) { + $this->ignoredInTeams->removeElement($team); + } + + return $this; + } public function __clone() { diff --git a/src/Entity/VVTGrundlage.php b/src/Entity/VVTGrundlage.php index 0a4abfa2..137783a3 100644 --- a/src/Entity/VVTGrundlage.php +++ b/src/Entity/VVTGrundlage.php @@ -3,10 +3,11 @@ namespace App\Entity; use App\Repository\VVTGrundlageRepository; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity(repositoryClass: VVTGrundlageRepository::class)] -class VVTGrundlage +class VVTGrundlage extends Preset { #[ORM\Id] #[ORM\GeneratedValue] @@ -22,6 +23,9 @@ class VVTGrundlage #[ORM\ManyToOne(targetEntity: Team::class, inversedBy: 'vVTGrundlages')] private $team; + #[ORM\ManyToMany(targetEntity: Team::class, inversedBy: 'ignoredVVTGrounds')] + protected $ignoredInTeams; + public function getId(): ?int { return $this->id; diff --git a/src/Entity/VVTPersonen.php b/src/Entity/VVTPersonen.php index a951177a..f128e815 100644 --- a/src/Entity/VVTPersonen.php +++ b/src/Entity/VVTPersonen.php @@ -3,10 +3,11 @@ namespace App\Entity; use App\Repository\VVTPersonenRepository; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity(repositoryClass: VVTPersonenRepository::class)] -class VVTPersonen +class VVTPersonen extends Preset { #[ORM\Id] #[ORM\GeneratedValue] @@ -22,6 +23,9 @@ class VVTPersonen #[ORM\Column(type: 'boolean')] private $activ; + #[ORM\ManyToMany(targetEntity: Team::class, inversedBy: 'ignoredVVTPersons')] + protected $ignoredInTeams; + public function getId(): ?int { return $this->id; diff --git a/src/Entity/VVTRisiken.php b/src/Entity/VVTRisiken.php index 52895b8c..b3d4441e 100644 --- a/src/Entity/VVTRisiken.php +++ b/src/Entity/VVTRisiken.php @@ -3,10 +3,11 @@ namespace App\Entity; use App\Repository\VVTRisikenRepository; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity(repositoryClass: VVTRisikenRepository::class)] -class VVTRisiken +class VVTRisiken extends Preset { #[ORM\Id] #[ORM\GeneratedValue] @@ -22,6 +23,9 @@ class VVTRisiken #[ORM\Column(type: 'boolean')] private $activ; + #[ORM\ManyToMany(targetEntity: Team::class, inversedBy: 'ignoredVVTRisks')] + protected $ignoredInTeams; + public function getId(): ?int { return $this->id; diff --git a/src/Entity/VVTStatus.php b/src/Entity/VVTStatus.php index 7b863278..5a247dcb 100644 --- a/src/Entity/VVTStatus.php +++ b/src/Entity/VVTStatus.php @@ -3,10 +3,12 @@ namespace App\Entity; use App\Repository\VVTStatusRepository; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity(repositoryClass: VVTStatusRepository::class)] -class VVTStatus +class VVTStatus extends Preset { #[ORM\Id] #[ORM\GeneratedValue] @@ -28,6 +30,9 @@ class VVTStatus #[ORM\Column(type: 'boolean')] private $activ = true; + #[ORM\ManyToMany(targetEntity: Team::class, inversedBy: 'ignoredVVTStates')] + protected $ignoredInTeams; + public function getId(): ?int { return $this->id; diff --git a/src/Form/Type/AssignType.php b/src/Form/Type/AssignType.php index 1e607701..35bb68c4 100644 --- a/src/Form/Type/AssignType.php +++ b/src/Form/Type/AssignType.php @@ -30,7 +30,11 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'multiple' => false, 'required' => false ]) - ->add('submit', SubmitType::class, ['attr' => array('class' => 'btn btn-sm'), 'label' => 'assign', 'translation_domain' => 'form']); + ->add('submit', SubmitType::class, [ + 'attr' => array('class' => 'btn btn-sm'), + 'label' => 'assign', + 'translation_domain' => 'form' + ]); } public function configureOptions(OptionsResolver $resolver) diff --git a/src/Form/Type/NewType.php b/src/Form/Type/NewType.php index 770ff4bf..e3ddbd08 100644 --- a/src/Form/Type/NewType.php +++ b/src/Form/Type/NewType.php @@ -9,6 +9,7 @@ namespace App\Form\Type; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; @@ -20,9 +21,9 @@ class NewType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options) { - $builder - ->add('name', TextType::class, ['label' => 'new', 'required' => true, 'translation_domain' => 'form']) - ->add('save', SubmitType::class, ['attr' => array('class' => 'btn'), 'label' => 'save', 'translation_domain' => 'form']); + $builder->add('name', TextType::class, ['label' => 'title', 'required' => true, 'translation_domain' => 'form']); + $builder->add('inherited', CheckboxType::class, ['label' => 'inherited', 'required' => false, 'translation_domain' => 'form']); + $builder->add('save', SubmitType::class, ['attr' => array('class' => 'btn'), 'label' => 'save', 'translation_domain' => 'form']); } public function configureOptions(OptionsResolver $resolver) diff --git a/src/Form/Type/PolicyType.php b/src/Form/Type/PolicyType.php index 78f9d23e..deb4ce8f 100644 --- a/src/Form/Type/PolicyType.php +++ b/src/Form/Type/PolicyType.php @@ -27,13 +27,40 @@ class PolicyType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { + $summernoteClass = 'summernote'; + if ($options['disabled']) { + $summernoteClass .= ' summernote-disable'; + } $builder - ->add('title', TextType::class, ['label' => 'policyName', 'required' => true, 'translation_domain' => 'form']) - ->add('scope', TextareaType::class, ['attr' => ['class' => 'summernote'], 'label' => 'policyScope', 'required' => true, 'translation_domain' => 'form']) - ->add('risk', TextareaType::class, ['attr' => ['class' => 'summernote'], 'label' => 'policyPotentialDangers', 'required' => true, 'translation_domain' => 'form']) - ->add('foundation', TextareaType::class, ['attr' => ['class' => 'summernote'], 'label' => 'policyLegislation', 'required' => true, 'translation_domain' => 'form']) - ->add('reference', TextType::class, ['label' => 'fileNumber', 'required' => false, 'translation_domain' => 'form']) + ->add('title', TextType::class, [ + 'label' => 'policyName', + 'required' => true, + 'translation_domain' => 'form' + ]) + ->add('scope', TextareaType::class, [ + 'attr' => ['class' => $summernoteClass], + 'label' => 'policyScope', + 'required' => true, + 'translation_domain' => 'form' + ]) + ->add('risk', TextareaType::class, [ + 'attr' => ['class' => $summernoteClass], + 'label' => 'policyPotentialDangers', + 'required' => true, + 'translation_domain' => 'form' + ]) + ->add('foundation', TextareaType::class, [ + 'attr' => ['class' => $summernoteClass], + 'label' => 'policyLegislation', + 'required' => true, + 'translation_domain' => 'form' + ]) + ->add('reference', TextType::class, [ + 'label' => 'fileNumber', + 'required' => false, + 'translation_domain' => 'form' + ]) ->add('processes', EntityType::class, [ 'choice_label' => 'name', 'class' => VVT::class, @@ -48,10 +75,30 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'data-live-search' => 'true' ] ]) - ->add('protection', TextareaType::class, ['attr' => ['class' => 'summernote'], 'label' => 'policySafetyMeasures', 'required' => false, 'translation_domain' => 'form']) - ->add('notes', TextareaType::class, ['attr' => ['class' => 'summernote'], 'label' => 'policyTrainingOffer', 'required' => false, 'translation_domain' => 'form']) - ->add('consequences', TextareaType::class, ['attr' => ['class' => 'summernote'], 'label' => 'policyNoncomplianceConsequences', 'required' => false, 'translation_domain' => 'form']) - ->add('contact', TextareaType::class, ['attr' => ['row' => 5], 'label' => 'policyContacts', 'required' => false, 'translation_domain' => 'form']) + ->add('protection', TextareaType::class, [ + 'attr' => ['class' => $summernoteClass], + 'label' => 'policySafetyMeasures', + 'required' => false, + 'translation_domain' => 'form' + ]) + ->add('notes', TextareaType::class, [ + 'attr' => ['class' => $summernoteClass], + 'label' => 'policyTrainingOffer', + 'required' => false, + 'translation_domain' => 'form' + ]) + ->add('consequences', TextareaType::class, [ + 'attr' => ['class' => $summernoteClass], + 'label' => 'policyNoncomplianceConsequences', + 'required' => false, + 'translation_domain' => 'form' + ]) + ->add('contact', TextareaType::class, [ + 'attr' => ['row' => 5], + 'label' => 'policyContacts', + 'required' => false, + 'translation_domain' => 'form' + ]) ->add('people', EntityType::class, [ 'choice_label' => 'name', 'class' => VVTPersonen::class, diff --git a/src/Form/Type/TeamType.php b/src/Form/Type/TeamType.php index f10c340b..7de8f0a0 100644 --- a/src/Form/Type/TeamType.php +++ b/src/Form/Type/TeamType.php @@ -10,6 +10,7 @@ use App\Entity\Team; use App\Repository\SettingsRepository; +use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; @@ -35,6 +36,25 @@ public function buildForm(FormBuilderInterface $builder, array $options) $builder->add('keycloakGroup', TextType::class, ['label' => 'keycloakGroup', 'help' => 'keycloakGroupHelp', 'required' => false, 'translation_domain' => 'form']); } + if ($options['teams'] !== null) { + $builder + ->add('parent', EntityType::class, [ + 'choice_label' => 'name', + 'class' => Team::class, + 'choices' => $options['teams'], + 'label' => 'parentTeam.word', + 'placeholder' => 'nothingSelected', + 'required' => false, + 'translation_domain' => 'form', + 'multiple' => false, + 'help' => 'parentTeam.help', + 'attr' => [ + 'class' => 'selectpicker', + 'data-live-search' => 'true' + ], + ]); + } + $builder ->add('strasse', TextType::class, ['label' => 'street', 'required' => true, 'translation_domain' => 'form']) ->add('plz', TextType::class, ['label' => 'postcode', 'required' => true, 'translation_domain' => 'form']) @@ -56,6 +76,7 @@ public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => Team::class, + 'teams' => array(), ]); } } diff --git a/src/Form/Type/TomType.php b/src/Form/Type/TomType.php index ae91b286..e7285b20 100644 --- a/src/Form/Type/TomType.php +++ b/src/Form/Type/TomType.php @@ -8,15 +8,8 @@ namespace App\Form\Type; -use App\Entity\AuditTom; -use App\Entity\AuditTomAbteilung; -use App\Entity\AuditTomStatus; -use App\Entity\AuditTomZiele; -use App\Entity\Team; use App\Entity\Tom; -use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\Extension\Core\Type\TextType; @@ -29,26 +22,120 @@ public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('titel', TextType::class, ['label' => 'tomTitle', 'required' => true, 'translation_domain' => 'form']) - ->add('beschreibung', TextareaType::class, ['attr' => ['class' => 'summernote', 'rows' => 8],'label' => 'descriptionOfMeasures', 'required' => true, 'translation_domain' => 'form']) - ->add('tomPseudo', TextareaType::class, ['attr' => ['class' => 'summernote', 'rows' => 8],'label' => 'tomEncryption', 'required' => true, 'translation_domain' => 'form']) - ->add('tomZutrittskontrolle', TextareaType::class, ['attr' => ['class' => 'summernote', 'rows' => 8],'label' => 'tomPhysicalAccess', 'required' => true, 'translation_domain' => 'form']) - ->add('tomZugangskontrolle', TextareaType::class, ['attr' => ['class' => 'summernote', 'rows' => 8],'label' => 'tomAuthenticatedAccess', 'required' => true, 'translation_domain' => 'form']) - ->add('tomZugriffskontrolle', TextareaType::class, ['attr' => ['class' => 'summernote', 'rows' => 8],'label' => 'tomPrivilegedAccess', 'required' => true, 'translation_domain' => 'form']) - ->add('tomBenutzerkontrolle', TextareaType::class, ['attr' => ['class' => 'summernote', 'rows' => 8],'label' => 'tomUserControl', 'required' => true, 'translation_domain' => 'form']) - ->add('tomSpeicherkontrolle', TextareaType::class, ['attr' => ['class' => 'summernote', 'rows' => 8],'label' => 'tomStorageControl', 'required' => true, 'translation_domain' => 'form']) - ->add('tomTrennbarkeit', TextareaType::class, ['attr' => ['class' => 'summernote', 'rows' => 8],'label' => 'tomSeparability', 'required' => true, 'translation_domain' => 'form']) - ->add('tomDatenintegritaet', TextareaType::class, ['attr' => ['class' => 'summernote', 'rows' => 8],'label' => 'tomDataIntegrity', 'required' => true, 'translation_domain' => 'form']) - ->add('tomTransportkontrolle', TextareaType::class, ['attr' => ['class' => 'summernote', 'rows' => 8],'label' => 'tomTransportControl', 'required' => true, 'translation_domain' => 'form']) - ->add('tomUebertragungskontrolle', TextareaType::class, ['attr' => ['class' => 'summernote', 'rows' => 8],'label' => 'tomTransferControl', 'required' => true, 'translation_domain' => 'form']) - ->add('tomEingabekontrolle', TextareaType::class, ['attr' => ['class' => 'summernote', 'rows' => 8],'label' => 'tomInputControl', 'required' => true, 'translation_domain' => 'form']) - ->add('tomZuverlaessigkeit', TextareaType::class, ['attr' => ['class' => 'summernote', 'rows' => 8],'label' => 'tomReliability', 'required' => true, 'translation_domain' => 'form']) - ->add('tomAuftragskontrolle', TextareaType::class, ['attr' => ['class' => 'summernote', 'rows' => 8],'label' => 'tomAssignmentControl', 'required' => true, 'translation_domain' => 'form']) - ->add('tomVerfuegbarkeitskontrolle', TextareaType::class, ['attr' => ['class' => 'summernote', 'rows' => 8],'label' => 'tomAvailabilityControl', 'required' => true, 'translation_domain' => 'form']) - ->add('tomWiederherstellbarkeit', TextareaType::class, ['attr' => ['class' => 'summernote', 'rows' => 8],'label' => 'tomRecoverability', 'required' => true, 'translation_domain' => 'form']) - ->add('tomAudit', TextareaType::class, ['attr' => ['class' => 'summernote', 'rows' => 8],'label' => 'tomAuditProcedure', 'required' => true, 'translation_domain' => 'form']) + ->add('titel', TextType::class, [ + 'attr' => ['class' => 'summernote', 'rows' => 8], + 'label' => 'tomTitle', + 'required' => true, + 'translation_domain' => 'form' + ]) + ->add('beschreibung', TextareaType::class, [ + 'attr' => ['class' => 'summernote', 'rows' => 8], + 'label' => 'descriptionOfMeasures', + 'required' => true, + 'translation_domain' => 'form' + ]) + ->add('tomPseudo', TextareaType::class, [ + 'attr' => ['class' => 'summernote', 'rows' => 8], + 'label' => 'tomEncryption', + 'required' => true, + 'translation_domain' => 'form' + ]) + ->add('tomZutrittskontrolle', TextareaType::class, [ + 'attr' => ['class' => 'summernote', 'rows' => 8], + 'label' => 'tomPhysicalAccess', + 'required' => true, + 'translation_domain' => 'form' + ]) + ->add('tomZugangskontrolle', TextareaType::class, [ + 'attr' => ['class' => 'summernote', 'rows' => 8], + 'label' => 'tomAuthenticatedAccess', + 'required' => true, + 'translation_domain' => 'form' + ]) + ->add('tomZugriffskontrolle', TextareaType::class, [ + 'attr' => ['class' => 'summernote', 'rows' => 8], + 'label' => 'tomPrivilegedAccess', + 'required' => true, + 'translation_domain' => 'form' + ]) + ->add('tomBenutzerkontrolle', TextareaType::class, [ + 'attr' => ['class' => 'summernote', 'rows' => 8], + 'label' => 'tomUserControl', + 'required' => true, + 'translation_domain' => 'form' + ]) + ->add('tomSpeicherkontrolle', TextareaType::class, [ + 'attr' => ['class' => 'summernote', 'rows' => 8], + 'label' => 'tomStorageControl', + 'required' => true, + 'translation_domain' => 'form' + ]) + ->add('tomTrennbarkeit', TextareaType::class, [ + 'attr' => ['class' => 'summernote', 'rows' => 8], + 'label' => 'tomSeparability', + 'required' => true, + 'translation_domain' => 'form' + ]) + ->add('tomDatenintegritaet', TextareaType::class, [ + 'attr' => ['class' => 'summernote', 'rows' => 8], + 'label' => 'tomDataIntegrity', + 'required' => true, + 'translation_domain' => 'form' + ]) + ->add('tomTransportkontrolle', TextareaType::class, [ + 'attr' => ['class' => 'summernote', 'rows' => 8], + 'label' => 'tomTransportControl', + 'required' => true, + 'translation_domain' => 'form' + ]) + ->add('tomUebertragungskontrolle', TextareaType::class, [ + 'attr' => ['class' => 'summernote', 'rows' => 8], + 'label' => 'tomTransferControl', + 'required' => true, + 'translation_domain' => 'form' + ]) + ->add('tomEingabekontrolle', TextareaType::class, [ + 'attr' => ['class' => 'summernote', 'rows' => 8], + 'label' => 'tomInputControl', + 'required' => true, + 'translation_domain' => 'form' + ]) + ->add('tomZuverlaessigkeit', TextareaType::class, [ + 'attr' => ['class' => 'summernote', 'rows' => 8], + 'label' => 'tomReliability', + 'required' => true, + 'translation_domain' => 'form' + ]) + ->add('tomAuftragskontrolle', TextareaType::class, [ + 'attr' => ['class' => 'summernote', 'rows' => 8], + 'label' => 'tomAssignmentControl', + 'required' => true, + 'translation_domain' => 'form' + ]) + ->add('tomVerfuegbarkeitskontrolle', TextareaType::class, [ + 'attr' => ['class' => 'summernote', 'rows' => 8], + 'label' => 'tomAvailabilityControl', + 'required' => true, + 'translation_domain' => 'form' + ]) + ->add('tomWiederherstellbarkeit', TextareaType::class, [ + 'attr' => ['class' => 'summernote', 'rows' => 8], + 'label' => 'tomRecoverability', + 'required' => true, + 'translation_domain' => 'form' + ]) + ->add('tomAudit', TextareaType::class, [ + 'attr' => ['class' => 'summernote', 'rows' => 8], + 'label' => 'tomAuditProcedure', + 'required' => true, + 'translation_domain' => 'form' + ]) - ->add('save', SubmitType::class, ['attr' => array('class' => 'btn'),'label' => 'save', 'translation_domain' => 'form']); + ->add('save', SubmitType::class, [ + 'attr' => array('class' => 'btn'), + 'label' => 'save', + 'translation_domain' => 'form' + ]); } public function configureOptions(OptionsResolver $resolver) diff --git a/src/Form/Type/VVTType.php b/src/Form/Type/VVTType.php index 3c23611c..b0a68fb7 100644 --- a/src/Form/Type/VVTType.php +++ b/src/Form/Type/VVTType.php @@ -40,8 +40,18 @@ class VVTType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { + $summernoteClass = 'summernote'; + if ($options['disabled']) { + $summernoteClass .= ' summernote-disable'; + } $builder + ->add('inherited', CheckboxType::class, [ + 'label' => 'inherited', + 'required' => false, + 'translation_domain' => 'form', + 'help' => 'inheritedHelp' + ]) ->add('nummer', TextType::class, [ 'label' => 'procedureNumber', 'required' => true, @@ -82,7 +92,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'help' => 'procedureUsedSOftwareHelp' ]) ->add('zweck', TextareaType::class, [ - 'attr' => ['class' => 'summernote'], + 'attr' => ['class' => $summernoteClass], 'label' => 'procedurePurpose', 'required' => true, 'translation_domain' => 'form', @@ -101,7 +111,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'help' => 'isContractHelp' ]) ->add('speicherung', TextareaType::class, [ - 'attr' => ['class' => 'summernote'], + 'attr' => ['class' => $summernoteClass], 'label' => 'procedureDataStorage', 'required' => true, 'translation_domain' => 'form', @@ -115,7 +125,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'help' => 'deleteDeadlineHelp' ]) ->add('weitergabe', TextareaType::class, [ - 'attr' => ['class' => 'summernote'], + 'attr' => ['class' => $summernoteClass], 'label' => 'procedureDataTransferPartners', 'required' => false, 'translation_domain' => 'form', @@ -192,7 +202,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'help' => 'procedureTOM' ]) ->add('tom', TextareaType::class, [ - 'attr' => ['class' => 'summernote'], + 'attr' => ['class' => $summernoteClass], 'label' => 'procedureFurtherMeasures', 'required' => false, 'translation_domain' => 'form', @@ -245,14 +255,14 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'help' => 'procedureDataCollectionHelp' ]) ->add('informationspflicht', TextareaType::class, [ - 'attr' => ['class' => 'summernote'], + 'attr' => ['class' => $summernoteClass], 'label' => 'informationObligation', 'required' => false, 'translation_domain' => 'form', 'help' => 'informationObligationHelp' ]) ->add('dsb', TextareaType::class, [ - 'attr' => ['class' => 'summernote'], + 'attr' => ['class' => $summernoteClass], 'label' => 'dsbComment', 'required' => false, 'translation_domain' => 'form', @@ -327,7 +337,7 @@ public function configureOptions(OptionsResolver $resolver) 'tom' => array(), 'abteilung' => array(), 'produkte' => array(), - 'software' => array() + 'software' => array(), ]); } } diff --git a/src/Form/Type/VvtDsfaType.php b/src/Form/Type/VvtDsfaType.php index e63d09df..7f14c6c1 100644 --- a/src/Form/Type/VvtDsfaType.php +++ b/src/Form/Type/VvtDsfaType.php @@ -19,16 +19,63 @@ class VvtDsfaType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { + $summernoteClass = 'summernote'; + if ($options['disabled']) { + $summernoteClass .= ' summernote-disable'; + } $builder - ->add('beschreibung', TextareaType::class, ['attr' => ['class' => 'summernote'], 'label' => 'Systematische Beschreibung der geplanten Verarbeitungsvorgänge', 'required' => true, 'help' => 'Welche Verarbeitung ist geplant?, Welche Zuständigkeiten bestehen für die Verarbeitung?, Gibt es Normen oder Standards für die Verarbeitung?, Welche Daten werden verarbeitetet?, Wie verläuft der Lebenszyklus von Daten und Prozessen?, Mit Hilfe welcher Betriebsmittel erfolgt die Datenverarbeitung?', 'translation_domain' => 'form']) - ->add('notwendigkeit', TextareaType::class, ['attr' => ['class' => 'summernote'], 'label' => 'Bewertung der Notwendigkeit', 'required' => true, 'help' => 'Sind die Verarbeitungszwecke eindeutig definiert und rechtmäßig?, Aufgrund welcher Rechtsgrundlage erfolgt die Verarbeitung?, Sind die erhobenen Daten erforderlich, relevant und auf das für die Datenverarbeitung Notwendige beschränkt?, Sind die Daten korrekt und auf dem neuesten Stand?', 'translation_domain' => 'form']) - ->add('risiko', TextareaType::class, ['attr' => ['class' => 'summernote'], 'label' => 'Bewertung der Risiken', 'required' => true, 'help' => 'Was sind die Hauptbedrohungen, die zu dem Risiko führen könnten?, Was sind die Risikoquellen?, Was könnten die wesentlichen Auswirkungen für die betroffenen Personen sein, wenn das Risiko eintritt?', 'translation_domain' => 'form']) - ->add('abhilfe', TextareaType::class, ['attr' => ['class' => 'summernote'], 'label' => 'Zur Bewältigung der Risiken geplante Abhilfemaßnahmen (Garantie, Sicherheitskopien,...)', 'required' => true, 'help' => 'Datentrennung, Datensicherung, Verschlüsselung, Anonymisierung, Datentrennung, Zugangskontrolle, Zugriffskontrolle, Protokollierung, Archivierung, Datenminimierung, Betriebssicherheit, Papierdokumentensicherung', 'translation_domain' => 'form']) - ->add('standpunkt', TextareaType::class, ['attr' => ['class' => 'summernote'], 'label' => 'Standpunkt von weiteren Organen (z.B. Betriebsrat)', 'required' => true, 'translation_domain' => 'form']) - ->add('dsb', TextareaType::class, ['attr' => ['class' => 'summernote'], 'label' => 'Standpunkt des Datenschutzbeauftragten', 'required' => false, 'translation_domain' => 'form']) - ->add('ergebnis', TextareaType::class, ['attr' => ['class' => 'summernote'], 'label' => 'Ergebnis der Datenschutz-Folgenabschätzung', 'required' => false, 'translation_domain' => 'form']) - ->add('save', SubmitType::class, ['attr' => array('class' => 'btn'),'label' => 'Speichern', 'translation_domain' => 'form']); + ->add('beschreibung', TextareaType::class, [ + 'attr' => ['class' => $summernoteClass], + 'label' => 'dpiaDescription.label', + 'required' => true, + 'help' => 'dpiaDescription.help', + 'translation_domain' => 'form' + ]) + ->add('notwendigkeit', TextareaType::class, [ + 'attr' => ['class' => $summernoteClass], + 'label' => 'needAssessment.label', + 'required' => true, + 'help' => 'needAssessment.help', + 'translation_domain' => 'form' + ]) + ->add('risiko', TextareaType::class, [ + 'attr' => ['class' => $summernoteClass], + 'label' => 'riskAssessment.label', + 'required' => true, + 'help' => 'riskAssessment.help', + 'translation_domain' => 'form' + ]) + ->add('abhilfe', TextareaType::class, [ + 'attr' => ['class' => $summernoteClass], + 'label' => 'correctiveActions.label', + 'required' => true, + 'help' => 'correctiveActions.help', + 'translation_domain' => 'form' + ]) + ->add('standpunkt', TextareaType::class, [ + 'attr' => ['class' => $summernoteClass], + 'label' => 'positionOtherInstitutions', + 'required' => true, + 'translation_domain' => 'form' + ]) + ->add('dsb', TextareaType::class, [ + 'attr' => ['class' => $summernoteClass], + 'label' => 'positionDataProtectionOfficer', + 'required' => false, + 'translation_domain' => 'form' + ]) + ->add('ergebnis', TextareaType::class, [ + 'attr' => ['class' => $summernoteClass], + 'label' => 'dpiaResult', + 'required' => false, + 'translation_domain' => 'form' + ]) + ->add('save', SubmitType::class, [ + 'attr' => array('class' => 'btn'), + 'label' => 'save', + 'translation_domain' => 'form' + ]); } public function configureOptions(OptionsResolver $resolver) diff --git a/src/Kernel.php b/src/Kernel.php index 54b472ea..779cd1f2 100644 --- a/src/Kernel.php +++ b/src/Kernel.php @@ -3,14 +3,9 @@ namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; -use Symfony\Component\Config\Loader\LoaderInterface; -use Symfony\Component\Config\Resource\FileResource; -use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Kernel as BaseKernel; -use Symfony\Component\Routing\RouteCollectionBuilder; class Kernel extends BaseKernel { use MicroKernelTrait; - } diff --git a/src/Migrations/Version20230704152545.php b/src/Migrations/Version20230704152545.php new file mode 100644 index 00000000..0526935c --- /dev/null +++ b/src/Migrations/Version20230704152545.php @@ -0,0 +1,60 @@ +addSql('ALTER TABLE answer CHANGE question_id question_id INT NOT NULL'); + $this->addSql('ALTER TABLE participation CHANGE akademie_buchungen_id akademie_buchungen_id INT DEFAULT NULL, CHANGE passed passed TINYINT(1) NOT NULL, CHANGE state state VARCHAR(255) NOT NULL'); + $this->addSql('ALTER TABLE participation_answer CHANGE participation_id participation_id INT NOT NULL, CHANGE questionnaire_id questionnaire_id INT NOT NULL, CHANGE question_id question_id INT NOT NULL, CHANGE answer_id answer_id INT NOT NULL'); + $this->addSql('ALTER TABLE question CHANGE eval_value eval_value DOUBLE PRECISION NOT NULL'); + $this->addSql('ALTER TABLE questionnaire CHANGE description description TEXT DEFAULT NULL'); + $this->addSql('ALTER TABLE team ADD tree_root INT DEFAULT NULL, ADD parent_id INT DEFAULT NULL, ADD lvl INT DEFAULT NULL, ADD lft INT DEFAULT NULL, ADD rgt INT DEFAULT NULL'); + $this->addSql('ALTER TABLE team ADD CONSTRAINT FK_C4E0A61FA977936C FOREIGN KEY (tree_root) REFERENCES team (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE team ADD CONSTRAINT FK_C4E0A61F727ACA70 FOREIGN KEY (parent_id) REFERENCES team (id) ON DELETE CASCADE'); + $this->addSql('CREATE INDEX IDX_C4E0A61FA977936C ON team (tree_root)'); + $this->addSql('CREATE INDEX IDX_C4E0A61F727ACA70 ON team (parent_id)'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE question CHANGE eval_value eval_value DOUBLE PRECISION DEFAULT \'1\' NOT NULL'); + $this->addSql('ALTER TABLE participation_answer CHANGE participation_id participation_id INT DEFAULT NULL, CHANGE questionnaire_id questionnaire_id INT DEFAULT NULL, CHANGE question_id question_id INT DEFAULT NULL, CHANGE answer_id answer_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE participation CHANGE akademie_buchungen_id akademie_buchungen_id INT NOT NULL, CHANGE state state VARCHAR(255) DEFAULT \'assigned\' NOT NULL, CHANGE passed passed TINYINT(1) DEFAULT NULL'); + $this->addSql('ALTER TABLE questionnaire CHANGE description description VARCHAR(255) DEFAULT NULL'); + $this->addSql('ALTER TABLE answer CHANGE question_id question_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE team DROP FOREIGN KEY FK_C4E0A61FA977936C'); + $this->addSql('ALTER TABLE team DROP FOREIGN KEY FK_C4E0A61F727ACA70'); + $this->addSql('DROP INDEX IDX_C4E0A61FA977936C ON team'); + $this->addSql('DROP INDEX IDX_C4E0A61F727ACA70 ON team'); + $this->addSql('ALTER TABLE team DROP tree_root, DROP parent_id, DROP lvl, DROP lft, DROP rgt'); + } + + public function postUp(Schema $schema): void + { + $this->connection->createQueryBuilder() + ->update('team', 't') + ->set('t.tree_root', 't.id') + ->set('t.lvl', 0) + ->set('t.lft', 1) + ->set('t.rgt', 2) + ->executeStatement(); + } +} diff --git a/src/Migrations/Version20230801184610.php b/src/Migrations/Version20230801184610.php new file mode 100644 index 00000000..dbd7a652 --- /dev/null +++ b/src/Migrations/Version20230801184610.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE vvt ADD inherited TINYINT(1) NOT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE vvt DROP inherited'); + } +} diff --git a/src/Migrations/Version20230802134800.php b/src/Migrations/Version20230802134800.php new file mode 100644 index 00000000..d4070bce --- /dev/null +++ b/src/Migrations/Version20230802134800.php @@ -0,0 +1,35 @@ +addSql('CREATE TABLE vvt_team (vvt_id INT NOT NULL, team_id INT NOT NULL, INDEX IDX_4FF1CCA1677671F9 (vvt_id), INDEX IDX_4FF1CCA1296CD8AE (team_id), PRIMARY KEY(vvt_id, team_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->addSql('ALTER TABLE vvt_team ADD CONSTRAINT FK_4FF1CCA1677671F9 FOREIGN KEY (vvt_id) REFERENCES vvt (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE vvt_team ADD CONSTRAINT FK_4FF1CCA1296CD8AE FOREIGN KEY (team_id) REFERENCES team (id) ON DELETE CASCADE'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE vvt_team DROP FOREIGN KEY FK_4FF1CCA1677671F9'); + $this->addSql('ALTER TABLE vvt_team DROP FOREIGN KEY FK_4FF1CCA1296CD8AE'); + $this->addSql('DROP TABLE vvt_team'); + } +} diff --git a/src/Migrations/Version20240108154236.php b/src/Migrations/Version20240108154236.php new file mode 100644 index 00000000..81938e3d --- /dev/null +++ b/src/Migrations/Version20240108154236.php @@ -0,0 +1,93 @@ +addSql('CREATE TABLE audit_tom_ziele_team (audit_tom_ziele_id INT NOT NULL, team_id INT NOT NULL, INDEX IDX_69170ACF24B29C5F (audit_tom_ziele_id), INDEX IDX_69170ACF296CD8AE (team_id), PRIMARY KEY(audit_tom_ziele_id, team_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->addSql('CREATE TABLE datenweitergabe_grundlagen_team (datenweitergabe_grundlagen_id INT NOT NULL, team_id INT NOT NULL, INDEX IDX_1D5E1D65832C7682 (datenweitergabe_grundlagen_id), INDEX IDX_1D5E1D65296CD8AE (team_id), PRIMARY KEY(datenweitergabe_grundlagen_id, team_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->addSql('CREATE TABLE datenweitergabe_stand_team (datenweitergabe_stand_id INT NOT NULL, team_id INT NOT NULL, INDEX IDX_105357981361291D (datenweitergabe_stand_id), INDEX IDX_10535798296CD8AE (team_id), PRIMARY KEY(datenweitergabe_stand_id, team_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->addSql('CREATE TABLE produkte_team (produkte_id INT NOT NULL, team_id INT NOT NULL, INDEX IDX_4E9D9226F5AB0B87 (produkte_id), INDEX IDX_4E9D9226296CD8AE (team_id), PRIMARY KEY(produkte_id, team_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->addSql('CREATE TABLE vvtgrundlage_team (vvtgrundlage_id INT NOT NULL, team_id INT NOT NULL, INDEX IDX_B09EF10C80257D66 (vvtgrundlage_id), INDEX IDX_B09EF10C296CD8AE (team_id), PRIMARY KEY(vvtgrundlage_id, team_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->addSql('CREATE TABLE vvtpersonen_team (vvtpersonen_id INT NOT NULL, team_id INT NOT NULL, INDEX IDX_F430C11097064E08 (vvtpersonen_id), INDEX IDX_F430C110296CD8AE (team_id), PRIMARY KEY(vvtpersonen_id, team_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->addSql('CREATE TABLE vvtrisiken_team (vvtrisiken_id INT NOT NULL, team_id INT NOT NULL, INDEX IDX_ACD5CD76DF7C8617 (vvtrisiken_id), INDEX IDX_ACD5CD76296CD8AE (team_id), PRIMARY KEY(vvtrisiken_id, team_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->addSql('CREATE TABLE vvtstatus_team (vvtstatus_id INT NOT NULL, team_id INT NOT NULL, INDEX IDX_692A2281D4694B3A (vvtstatus_id), INDEX IDX_692A2281296CD8AE (team_id), PRIMARY KEY(vvtstatus_id, team_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->addSql('ALTER TABLE audit_tom_ziele_team ADD CONSTRAINT FK_69170ACF24B29C5F FOREIGN KEY (audit_tom_ziele_id) REFERENCES audit_tom_ziele (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE audit_tom_ziele_team ADD CONSTRAINT FK_69170ACF296CD8AE FOREIGN KEY (team_id) REFERENCES team (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE datenweitergabe_grundlagen_team ADD CONSTRAINT FK_1D5E1D65832C7682 FOREIGN KEY (datenweitergabe_grundlagen_id) REFERENCES datenweitergabe_grundlagen (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE datenweitergabe_grundlagen_team ADD CONSTRAINT FK_1D5E1D65296CD8AE FOREIGN KEY (team_id) REFERENCES team (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE datenweitergabe_stand_team ADD CONSTRAINT FK_105357981361291D FOREIGN KEY (datenweitergabe_stand_id) REFERENCES datenweitergabe_stand (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE datenweitergabe_stand_team ADD CONSTRAINT FK_10535798296CD8AE FOREIGN KEY (team_id) REFERENCES team (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE produkte_team ADD CONSTRAINT FK_4E9D9226F5AB0B87 FOREIGN KEY (produkte_id) REFERENCES produkte (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE produkte_team ADD CONSTRAINT FK_4E9D9226296CD8AE FOREIGN KEY (team_id) REFERENCES team (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE vvtgrundlage_team ADD CONSTRAINT FK_B09EF10C80257D66 FOREIGN KEY (vvtgrundlage_id) REFERENCES vvtgrundlage (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE vvtgrundlage_team ADD CONSTRAINT FK_B09EF10C296CD8AE FOREIGN KEY (team_id) REFERENCES team (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE vvtpersonen_team ADD CONSTRAINT FK_F430C11097064E08 FOREIGN KEY (vvtpersonen_id) REFERENCES vvtpersonen (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE vvtpersonen_team ADD CONSTRAINT FK_F430C110296CD8AE FOREIGN KEY (team_id) REFERENCES team (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE vvtrisiken_team ADD CONSTRAINT FK_ACD5CD76DF7C8617 FOREIGN KEY (vvtrisiken_id) REFERENCES vvtrisiken (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE vvtrisiken_team ADD CONSTRAINT FK_ACD5CD76296CD8AE FOREIGN KEY (team_id) REFERENCES team (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE vvtstatus_team ADD CONSTRAINT FK_692A2281D4694B3A FOREIGN KEY (vvtstatus_id) REFERENCES vvtstatus (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE vvtstatus_team ADD CONSTRAINT FK_692A2281296CD8AE FOREIGN KEY (team_id) REFERENCES team (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE audit_tom_ziele ADD inherited TINYINT(1) NOT NULL'); + $this->addSql('ALTER TABLE datenweitergabe_grundlagen ADD inherited TINYINT(1) NOT NULL'); + $this->addSql('ALTER TABLE datenweitergabe_stand ADD inherited TINYINT(1) NOT NULL'); + $this->addSql('ALTER TABLE produkte ADD inherited TINYINT(1) NOT NULL'); + $this->addSql('ALTER TABLE vvtgrundlage ADD inherited TINYINT(1) NOT NULL'); + $this->addSql('ALTER TABLE vvtpersonen ADD inherited TINYINT(1) NOT NULL'); + $this->addSql('ALTER TABLE vvtrisiken ADD inherited TINYINT(1) NOT NULL'); + $this->addSql('ALTER TABLE vvtstatus ADD inherited TINYINT(1) NOT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE audit_tom_ziele_team DROP FOREIGN KEY FK_69170ACF24B29C5F'); + $this->addSql('ALTER TABLE audit_tom_ziele_team DROP FOREIGN KEY FK_69170ACF296CD8AE'); + $this->addSql('ALTER TABLE datenweitergabe_grundlagen_team DROP FOREIGN KEY FK_1D5E1D65832C7682'); + $this->addSql('ALTER TABLE datenweitergabe_grundlagen_team DROP FOREIGN KEY FK_1D5E1D65296CD8AE'); + $this->addSql('ALTER TABLE datenweitergabe_stand_team DROP FOREIGN KEY FK_105357981361291D'); + $this->addSql('ALTER TABLE datenweitergabe_stand_team DROP FOREIGN KEY FK_10535798296CD8AE'); + $this->addSql('ALTER TABLE produkte_team DROP FOREIGN KEY FK_4E9D9226F5AB0B87'); + $this->addSql('ALTER TABLE produkte_team DROP FOREIGN KEY FK_4E9D9226296CD8AE'); + $this->addSql('ALTER TABLE vvtgrundlage_team DROP FOREIGN KEY FK_B09EF10C80257D66'); + $this->addSql('ALTER TABLE vvtgrundlage_team DROP FOREIGN KEY FK_B09EF10C296CD8AE'); + $this->addSql('ALTER TABLE vvtpersonen_team DROP FOREIGN KEY FK_F430C11097064E08'); + $this->addSql('ALTER TABLE vvtpersonen_team DROP FOREIGN KEY FK_F430C110296CD8AE'); + $this->addSql('ALTER TABLE vvtrisiken_team DROP FOREIGN KEY FK_ACD5CD76DF7C8617'); + $this->addSql('ALTER TABLE vvtrisiken_team DROP FOREIGN KEY FK_ACD5CD76296CD8AE'); + $this->addSql('ALTER TABLE vvtstatus_team DROP FOREIGN KEY FK_692A2281D4694B3A'); + $this->addSql('ALTER TABLE vvtstatus_team DROP FOREIGN KEY FK_692A2281296CD8AE'); + $this->addSql('DROP TABLE audit_tom_ziele_team'); + $this->addSql('DROP TABLE datenweitergabe_grundlagen_team'); + $this->addSql('DROP TABLE datenweitergabe_stand_team'); + $this->addSql('DROP TABLE produkte_team'); + $this->addSql('DROP TABLE vvtgrundlage_team'); + $this->addSql('DROP TABLE vvtpersonen_team'); + $this->addSql('DROP TABLE vvtrisiken_team'); + $this->addSql('DROP TABLE vvtstatus_team'); + $this->addSql('ALTER TABLE vvtrisiken DROP inherited'); + $this->addSql('ALTER TABLE vvtgrundlage DROP inherited'); + $this->addSql('ALTER TABLE vvtstatus DROP inherited'); + $this->addSql('ALTER TABLE audit_tom_ziele DROP inherited'); + $this->addSql('ALTER TABLE datenweitergabe_stand DROP inherited'); + $this->addSql('ALTER TABLE datenweitergabe_grundlagen DROP inherited'); + $this->addSql('ALTER TABLE vvtpersonen DROP inherited'); + $this->addSql('ALTER TABLE produkte DROP inherited'); + } +} diff --git a/src/Repository/AuditTomAbteilungRepository.php b/src/Repository/AuditTomAbteilungRepository.php index f3421b42..906ce66d 100644 --- a/src/Repository/AuditTomAbteilungRepository.php +++ b/src/Repository/AuditTomAbteilungRepository.php @@ -3,6 +3,7 @@ namespace App\Repository; use App\Entity\AuditTomAbteilung; +use App\Entity\Team; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; @@ -14,46 +15,22 @@ */ class AuditTomAbteilungRepository extends ServiceEntityRepository { - public function __construct(ManagerRegistry $registry) + public function __construct( + ManagerRegistry $registry, + private readonly TeamRepository $teamRepository, + ) { parent::__construct($registry, AuditTomAbteilung::class); } - // /** - // * @return AuditTomAbteilung[] Returns an array of AuditTomAbteilung objects - // */ - /* - public function findByExampleField($value) + public function findActiveByTeam(Team $team) { - return $this->createQueryBuilder('a') - ->andWhere('a.exampleField = :val') - ->setParameter('val', $value) - ->orderBy('a.id', 'ASC') - ->setMaxResults(10) - ->getQuery() - ->getResult() - ; - } - */ - - /* - public function findOneBySomeField($value): ?AuditTomAbteilung - { - return $this->createQueryBuilder('a') - ->andWhere('a.exampleField = :val') - ->setParameter('val', $value) - ->getQuery() - ->getOneOrNullResult() - ; - } - */ + $teamPath = $this->teamRepository->getPath($team); - public function findAllByTeam($value) - { return $this->createQueryBuilder('a') - ->Where('a.team = :val') + ->where('a.team IN (:teamPath)') ->andWhere('a.activ = 1') - ->setParameter('val', $value) + ->setParameter('teamPath', $teamPath) ->getQuery() ->getResult() ; diff --git a/src/Repository/AuditTomZieleRepository.php b/src/Repository/AuditTomZieleRepository.php index c1088894..f2ec2ca8 100644 --- a/src/Repository/AuditTomZieleRepository.php +++ b/src/Repository/AuditTomZieleRepository.php @@ -12,59 +12,13 @@ * @method AuditTomZiele[] findAll() * @method AuditTomZiele[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -class AuditTomZieleRepository extends ServiceEntityRepository +class AuditTomZieleRepository extends PresetRepository { - public function __construct(ManagerRegistry $registry) - { - parent::__construct($registry, AuditTomZiele::class); - } - - // /** - // * @return AuditTomZiele[] Returns an array of AuditTomZiele objects - // */ - /* - public function findByExampleField($value) - { - return $this->createQueryBuilder('a') - ->andWhere('a.exampleField = :val') - ->setParameter('val', $value) - ->orderBy('a.id', 'ASC') - ->setMaxResults(10) - ->getQuery() - ->getResult() - ; - } - */ - - /* - public function findOneBySomeField($value): ?AuditTomZiele - { - return $this->createQueryBuilder('a') - ->andWhere('a.exampleField = :val') - ->setParameter('val', $value) - ->getQuery() - ->getOneOrNullResult() - ; - } - */ - public function findByTeam($value) - { - return $this->createQueryBuilder('a') - ->where('a.team is null OR a.team = :val') - ->andWhere('a.activ = 1') - ->setParameter('val', $value) - ->getQuery() - ->getResult(); - } - - public function findActiveByTeam($value) - { - return $this->createQueryBuilder('a') - ->andWhere('a.team = :val') - ->andWhere('a.activ = 1') - ->setParameter('val', $value) - ->getQuery() - ->getResult() - ; + public function __construct( + protected readonly ManagerRegistry $registry, + protected readonly TeamRepository $teamRepository, +) +{ + parent::__construct($this->registry, $this->teamRepository, AuditTomZiele::class); } } diff --git a/src/Repository/DatenweitergabeGrundlagenRepository.php b/src/Repository/DatenweitergabeGrundlagenRepository.php index 8ee927f1..e475ec21 100644 --- a/src/Repository/DatenweitergabeGrundlagenRepository.php +++ b/src/Repository/DatenweitergabeGrundlagenRepository.php @@ -12,49 +12,13 @@ * @method DatenweitergabeGrundlagen[] findAll() * @method DatenweitergabeGrundlagen[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -class DatenweitergabeGrundlagenRepository extends ServiceEntityRepository +class DatenweitergabeGrundlagenRepository extends PresetRepository { - public function __construct(ManagerRegistry $registry) + public function __construct( + protected readonly ManagerRegistry $registry, + protected readonly TeamRepository $teamRepository, + ) { - parent::__construct($registry, DatenweitergabeGrundlagen::class); - } - - // /** - // * @return DatenweitergabeGrundlagen[] Returns an array of DatenweitergabeGrundlagen objects - // */ - /* - public function findByExampleField($value) - { - return $this->createQueryBuilder('d') - ->andWhere('d.exampleField = :val') - ->setParameter('val', $value) - ->orderBy('d.id', 'ASC') - ->setMaxResults(10) - ->getQuery() - ->getResult() - ; - } - */ - - /* - public function findOneBySomeField($value): ?DatenweitergabeGrundlagen - { - return $this->createQueryBuilder('d') - ->andWhere('d.exampleField = :val') - ->setParameter('val', $value) - ->getQuery() - ->getOneOrNullResult() - ; - } - */ - - public function findActiveByTeam($value) - { - return $this->createQueryBuilder('a') - ->where('a.team is null OR a.team = :val') - ->andWhere('a.activ = 1') - ->setParameter('val', $value) - ->getQuery() - ->getResult(); + parent::__construct($this->registry, $this->teamRepository, DatenweitergabeGrundlagen::class); } } diff --git a/src/Repository/DatenweitergabeRepository.php b/src/Repository/DatenweitergabeRepository.php index 636ea589..48f6f2db 100644 --- a/src/Repository/DatenweitergabeRepository.php +++ b/src/Repository/DatenweitergabeRepository.php @@ -3,7 +3,10 @@ namespace App\Repository; use App\Entity\Datenweitergabe; +use App\Entity\Team; +use App\Entity\User; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\ORM\QueryBuilder; use Doctrine\Persistence\ManagerRegistry; /** @@ -14,66 +17,96 @@ */ class DatenweitergabeRepository extends ServiceEntityRepository { - public function __construct(ManagerRegistry $registry) + public function __construct( + ManagerRegistry $registry, + private readonly TeamRepository $teamRepository, + ) { parent::__construct($registry, Datenweitergabe::class); } - public function findActiveByTeam($value) + public function findActiveByTeam(Team $team) { - return $this->createQueryBuilder('a') - ->andWhere('a.team = :val') - ->andWhere('a.activ = 1') - ->setParameter('val', $value) - ->getQuery() - ->getResult() - ; + $queryBuilder = $this->getBaseQueryBuilder($team); + return $queryBuilder->getQuery()->getResult(); + } + + public function findAllByTeam(Team $team) + { + $queryBuilder = $this->getBaseQueryBuilder(team: $team, all: true); + return $queryBuilder->getQuery()->getResult(); } /** - * @param $value + * @param Team $team * @return int|mixed|string * find transfers of type Datenweitergabe */ - public function findActiveTransfersByTeam($value) + public function findActiveTransfersByTeam(Team $team): mixed { - return $this->createQueryBuilder('a') - ->andWhere('a.team = :val') - ->andWhere('a.activ = 1') - ->andWhere('a.art = 1') - ->setParameter('val', $value) - ->getQuery() - ->getResult() - ; + $queryBuilder = $this->getBaseQueryBuilder(team: $team); + $queryBuilder->andWhere('a.art = 1'); + return $queryBuilder->getQuery()->getResult(); + } + + public function findAllTransfersByTeam(Team $team): mixed + { + $queryBuilder = $this->getBaseQueryBuilder(team: $team, all: true); + $queryBuilder->andWhere('a.art = 1'); + return $queryBuilder->getQuery()->getResult(); } /** - * @param $value + * @param Team $team * @return int|mixed|string * find transfers of type Auftragsverarbeitung */ - public function findActiveOrderProcessingsByTeam($value) + public function findActiveOrderProcessingsByTeam(Team $team): mixed { - return $this->createQueryBuilder('a') - ->andWhere('a.team = :val') - ->andWhere('a.activ = 1') - ->andWhere('a.art = 2') - ->setParameter('val', $value) - ->getQuery() - ->getResult() - ; + $queryBuilder = $this->getBaseQueryBuilder(team: $team); + $queryBuilder->andWhere('a.art = 2'); + return $queryBuilder->getQuery()->getResult(); } - public function findActiveByTeamAndUser($team, $user) + public function findAllOrderProcessingsByTeam(Team $team): mixed { - return $this->createQueryBuilder('a') - ->andWhere('a.team = :team') + $queryBuilder = $this->getBaseQueryBuilder(team: $team, all: true); + $queryBuilder->andWhere('a.art = 2'); + return $queryBuilder->getQuery()->getResult(); + } + + public function findActiveByTeamAndUser(Team $team, User $user) + { + $queryBuilder = $this->getBaseQueryBuilder(team: $team); + $queryBuilder ->andWhere('a.assignedUser = :user') + ->setParameter('user', $user) + ; + return $queryBuilder->getQuery()->getResult(); + } + + private function getBaseQueryBuilder(Team $team, bool $all = false) :QueryBuilder + { + $teamPath = $this->teamRepository->getPath(node: $team); + + $queryBuilder = $this->createQueryBuilder('a') + ->leftJoin('a.verfahren', 'process') + ->andWhere('a.team = :team OR process.inherited = 1 AND process.activ = 1 AND process.team IN (:teamPath)') ->andWhere('a.activ = 1') + ->setParameter('teamPath', $teamPath) ->setParameter('team', $team) - ->setParameter('user', $user) ->orderBy('a.createdAt', 'DESC') - ->getQuery() - ->getResult(); + ; + + if (!$all) { + $ignored = $team->getIgnoredInheritances(); + if (count($ignored)) { + $queryBuilder + ->andWhere('process NOT IN (:ignored) OR a.team = :team') + ->setParameter('ignored', $ignored); + } + } + + return $queryBuilder; } } diff --git a/src/Repository/DatenweitergabeStandRepository.php b/src/Repository/DatenweitergabeStandRepository.php index cedbf47f..6345e54f 100644 --- a/src/Repository/DatenweitergabeStandRepository.php +++ b/src/Repository/DatenweitergabeStandRepository.php @@ -3,6 +3,7 @@ namespace App\Repository; use App\Entity\DatenweitergabeStand; +use App\Entity\Team; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; @@ -12,49 +13,13 @@ * @method DatenweitergabeStand[] findAll() * @method DatenweitergabeStand[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -class DatenweitergabeStandRepository extends ServiceEntityRepository +class DatenweitergabeStandRepository extends PresetRepository { - public function __construct(ManagerRegistry $registry) + public function __construct( + protected readonly ManagerRegistry $registry, + protected readonly TeamRepository $teamRepository, + ) { - parent::__construct($registry, DatenweitergabeStand::class); - } - - // /** - // * @return DatenweitergabeStand[] Returns an array of DatenweitergabeStand objects - // */ - /* - public function findByExampleField($value) - { - return $this->createQueryBuilder('d') - ->andWhere('d.exampleField = :val') - ->setParameter('val', $value) - ->orderBy('d.id', 'ASC') - ->setMaxResults(10) - ->getQuery() - ->getResult() - ; - } - */ - - /* - public function findOneBySomeField($value): ?DatenweitergabeStand - { - return $this->createQueryBuilder('d') - ->andWhere('d.exampleField = :val') - ->setParameter('val', $value) - ->getQuery() - ->getOneOrNullResult() - ; - } - */ - - public function findActiveByTeam($value) - { - return $this->createQueryBuilder('a') - ->where('a.team is null OR a.team = :val') - ->andWhere('a.activ = 1') - ->setParameter('val', $value) - ->getQuery() - ->getResult(); + parent::__construct($this->registry, $this->teamRepository, DatenweitergabeStand::class); } } diff --git a/src/Repository/KontakteRepository.php b/src/Repository/KontakteRepository.php index 060a0cda..d03c144c 100644 --- a/src/Repository/KontakteRepository.php +++ b/src/Repository/KontakteRepository.php @@ -3,7 +3,9 @@ namespace App\Repository; use App\Entity\Kontakte; +use App\Entity\Team; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\ORM\QueryBuilder; use Doctrine\Persistence\ManagerRegistry; /** @@ -14,48 +16,84 @@ */ class KontakteRepository extends ServiceEntityRepository { - public function __construct(ManagerRegistry $registry) + public function __construct( + ManagerRegistry $registry, + private readonly TeamRepository $teamRepository, + ) { parent::__construct($registry, Kontakte::class); } - // /** - // * @return Kontakte[] Returns an array of Kontakte objects - // */ - /* - public function findByExampleField($value) + public function findActiveByTeam(Team $team) { - return $this->createQueryBuilder('k') - ->andWhere('k.exampleField = :val') - ->setParameter('val', $value) - ->orderBy('k.id', 'ASC') - ->setMaxResults(10) - ->getQuery() - ->getResult() - ; + $queryBuilder = $this->getBaseQueryBuilder(); + $this->filterByTeam(queryBuilder: $queryBuilder, team: $team); + return $queryBuilder->getQuery()->getResult(); } - */ - /* - public function findOneBySomeField($value): ?Kontakte + public function findAllByTeam(Team $team) { - return $this->createQueryBuilder('k') - ->andWhere('k.exampleField = :val') - ->setParameter('val', $value) - ->getQuery() - ->getOneOrNullResult() - ; + $queryBuilder = $this->getBaseQueryBuilder(); + $this->filterByTeam(queryBuilder: $queryBuilder, team: $team, all: true); + return $queryBuilder->getQuery()->getResult(); + } + + public function findIsInheritedById(string $id) : bool + { + $queryBuilder = $this->getBaseQueryBuilder(); + $this->filterById(queryBuilder: $queryBuilder, id: $id); + $this->filterByInherited(queryBuilder: $queryBuilder); + $result = $queryBuilder->getQuery()->getResult(); + return count($result) > 0; } - */ - public function findActiveByTeam($value) + public function findIsUsedByTeamAndId(Team $team, string $id) : bool { - return $this->createQueryBuilder('a') - ->andWhere('a.team = :val') - ->andWhere('a.activ = 1') - ->setParameter('val', $value) - ->getQuery() - ->getResult() + $queryBuilder = $this->getBaseQueryBuilder(); + $this->filterByTeam(queryBuilder: $queryBuilder, team: $team); + $this->filterById(queryBuilder: $queryBuilder, id: $id); + $result = $queryBuilder->getQuery()->getResult(); + return count($result) > 0; + } + + private function getBaseQueryBuilder() :QueryBuilder + { + return $this->createQueryBuilder('c') + ->leftJoin('c.datenweitergaben', 'dw') + ->leftJoin('dw.verfahren', 'process') + ->andWhere('c.activ = 1') ; } + + private function filterByTeam(QueryBuilder $queryBuilder, Team $team, bool $all = false) :void + { + $teamPath = $this->teamRepository->getPath($team); + $queryBuilder + ->andWhere('c.team = :team OR (process.activ = 1 AND process.inherited = 1 AND process.team IN (:teamPath))') + ->setParameter('teamPath', $teamPath) + ->setParameter('team', $team) + ; + + if (!$all) { + $ignored = $team->getIgnoredInheritances(); + if (count($ignored)) { + $queryBuilder + ->andWhere('process NOT IN (:ignored) OR c.team = :team') + ->setParameter('ignored', $ignored); + } + } + } + + private function filterById(QueryBuilder $queryBuilder, string $id) :void + { + $queryBuilder + ->andWhere('c.id = :id') + ->setParameter('id', $id); + } + + private function filterByInherited(QueryBuilder $queryBuilder) :void + { + $queryBuilder + ->andWhere('process.activ = 1 AND process.inherited = 1'); + } } diff --git a/src/Repository/PoliciesRepository.php b/src/Repository/PoliciesRepository.php index ab88ce81..80e34646 100644 --- a/src/Repository/PoliciesRepository.php +++ b/src/Repository/PoliciesRepository.php @@ -3,7 +3,9 @@ namespace App\Repository; use App\Entity\Policies; +use App\Entity\Team; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\ORM\QueryBuilder; use Doctrine\Persistence\ManagerRegistry; /** @@ -14,42 +16,67 @@ */ class PoliciesRepository extends ServiceEntityRepository { - public function __construct(ManagerRegistry $registry) + public function __construct( + ManagerRegistry $registry, + private readonly TeamRepository $teamRepository, + ) { parent::__construct($registry, Policies::class); } - public function findActiveByTeam($value) + public function findActiveByTeam(Team $team) { - return $this->createQueryBuilder('a') - ->andWhere('a.team = :val') - ->andWhere('a.activ = 1') - ->setParameter('val', $value) - ->getQuery() - ->getResult(); + $queryBuilder = $this->getBaseQueryBuilder(team: $team); + $this->excludeIgnored(team: $team, queryBuilder: $queryBuilder); + return $queryBuilder->getQuery()->getResult(); } - public function findPublicByTeam($value) + public function findAllByTeam(Team $team) { - return $this->createQueryBuilder('a') - ->andWhere('a.team = :val') - ->andWhere('a.activ = 1') - ->andWhere('a.status != 4') - ->setParameter('val', $value) - ->getQuery() - ->getResult(); + $queryBuilder = $this->getBaseQueryBuilder(team: $team); + return $queryBuilder->getQuery()->getResult(); + } + + public function findPublicByTeam(Team $team) + { + $queryBuilder = $this->getBaseQueryBuilder(team: $team); + $this->excludeIgnored(team: $team, queryBuilder: $queryBuilder); + $queryBuilder->andWhere('a.status != 4'); + return $queryBuilder->getQuery()->getResult(); } public function findActiveByTeamAndUser($team, $user) { - return $this->createQueryBuilder('a') - ->andWhere('a.team = :team') + $queryBuilder = $this->getBaseQueryBuilder(team: $team); + $this->excludeIgnored(team: $team, queryBuilder: $queryBuilder); + $queryBuilder ->andWhere('a.assignedUser = :user') + ->setParameter('user', $user) + ; + return $queryBuilder->getQuery()->getResult(); + } + + private function excludeIgnored(Team $team, QueryBuilder $queryBuilder) :void + { + $ignored = $team->getIgnoredInheritances(); + if (count($ignored)) { + $queryBuilder + ->andWhere('process NOT IN (:ignored)') + ->setParameter('ignored', $ignored); + } + } + + private function getBaseQueryBuilder(Team $team) :QueryBuilder + { + $teamPath = $this->teamRepository->getPath($team); + + return $this->createQueryBuilder('a') + ->leftJoin('a.processes', 'process') + ->andWhere('a.team = :team OR process.inherited = 1 AND process.activ = 1 AND process.team IN (:teamPath)') ->andWhere('a.activ = 1') + ->setParameter('teamPath', $teamPath) ->setParameter('team', $team) - ->setParameter('user', $user) ->orderBy('a.createdAt', 'DESC') - ->getQuery() - ->getResult(); + ; } } diff --git a/src/Repository/PresetRepository.php b/src/Repository/PresetRepository.php new file mode 100644 index 00000000..2bd7ef73 --- /dev/null +++ b/src/Repository/PresetRepository.php @@ -0,0 +1,93 @@ +getBaseQueryBuilder(); + $this->filterByTeam(queryBuilder: $queryBuilder, team: $team); + return $queryBuilder->getQuery()->getResult(); + } + + public function findAllByTeam(Team $team) + { + $queryBuilder = $this->getBaseQueryBuilder(); + $this->filterByTeam(queryBuilder: $queryBuilder, team: $team, all: true); + return $queryBuilder->getQuery()->getResult(); + } + + private function getBaseQueryBuilder() :QueryBuilder + { + return $this->createQueryBuilder('a')->andWhere('a.activ = 1'); + } + + private function filterByTeam(QueryBuilder $queryBuilder, Team $team, bool $all = false) :void + { + $teamPath = $this->teamRepository->getPath($team); + $queryBuilder + ->andWhere('a.team is null OR a.team = :team OR (a.team IN (:teamPath) AND a.inherited = 1)') + ->setParameter('teamPath', $teamPath) + ->setParameter('team', $team) + ; + + if (!$all) { + $ignored = $this->getIgnored($team); + if (count($ignored)) { + $queryBuilder + ->andWhere('a NOT IN (:ignored)') + ->setParameter('ignored', $ignored); + } + } + } + + private function getIgnored(Team $team) { + switch ($this->getEntityName()) { + case VVTStatus::class: + return $team->getIgnoredVVTStates(); + case VVTGrundlage::class: + return $team->getIgnoredVVTGrounds(); + case VVTPersonen::class: + return $team->getIgnoredVVTPersons(); + case VVTRisiken::class: + return $team->getIgnoredVVTRisks(); + case AuditTomZiele::class: + return $team->getIgnoredAuditGoals(); + case DatenweitergabeGrundlagen::class: + return $team->getIgnoredDWGrounds(); + case DatenweitergabeStand::class: + return $team->getIgnoredDwStates(); + case Produkte::class: + return $team->getIgnoredProducts(); + } + } +} diff --git a/src/Repository/ProdukteRepository.php b/src/Repository/ProdukteRepository.php index 274206a3..a7c54052 100644 --- a/src/Repository/ProdukteRepository.php +++ b/src/Repository/ProdukteRepository.php @@ -3,6 +3,7 @@ namespace App\Repository; use App\Entity\Produkte; +use App\Entity\Team; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; @@ -12,50 +13,13 @@ * @method Produkte[] findAll() * @method Produkte[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -class ProdukteRepository extends ServiceEntityRepository +class ProdukteRepository extends PresetRepository { - public function __construct(ManagerRegistry $registry) + public function __construct( + protected readonly ManagerRegistry $registry, + protected readonly TeamRepository $teamRepository, + ) { - parent::__construct($registry, Produkte::class); - } - - // /** - // * @return Produkte[] Returns an array of Produkte objects - // */ - /* - public function findByExampleField($value) - { - return $this->createQueryBuilder('p') - ->andWhere('p.exampleField = :val') - ->setParameter('val', $value) - ->orderBy('p.id', 'ASC') - ->setMaxResults(10) - ->getQuery() - ->getResult() - ; - } - */ - - /* - public function findOneBySomeField($value): ?Produkte - { - return $this->createQueryBuilder('p') - ->andWhere('p.exampleField = :val') - ->setParameter('val', $value) - ->getQuery() - ->getOneOrNullResult() - ; - } - */ - - public function findActiveByTeam($value) - { - return $this->createQueryBuilder('a') - ->andWhere('a.team = :val') - ->andWhere('a.activ = 1') - ->setParameter('val', $value) - ->getQuery() - ->getResult() - ; + parent::__construct($this->registry, $this->teamRepository, Produkte::class); } } diff --git a/src/Repository/SoftwareRepository.php b/src/Repository/SoftwareRepository.php index 1e77ac4a..b7722b3a 100644 --- a/src/Repository/SoftwareRepository.php +++ b/src/Repository/SoftwareRepository.php @@ -3,8 +3,13 @@ namespace App\Repository; use App\Entity\Software; +use App\Entity\Team; +use App\Entity\User; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\ORM\Query; +use Doctrine\ORM\QueryBuilder; use Doctrine\Persistence\ManagerRegistry; +use phpDocumentor\Reflection\Types\Boolean; /** * @method Software|null find($id, $lockMode = null, $lockVersion = null) @@ -14,31 +19,101 @@ */ class SoftwareRepository extends ServiceEntityRepository { - public function __construct(ManagerRegistry $registry) + public function __construct( + ManagerRegistry $registry, + private readonly TeamRepository $teamRepository, + ) { parent::__construct($registry, Software::class); } - public function findActiveByTeam($value) + public function findActiveByTeam(Team $team) { - return $this->createQueryBuilder('a') - ->andWhere('a.team = :val') - ->andWhere('a.activ = 1') - ->setParameter('val', $value) - ->getQuery() - ->getResult(); + $queryBuilder = $this->getBaseQueryBuilder(); + $this->filterByTeam(queryBuilder: $queryBuilder, team: $team); + return $queryBuilder->getQuery()->getResult(); } public function findActiveByTeamAndUser($team, $user) { - return $this->createQueryBuilder('a') - ->andWhere('a.team = :team') - ->andWhere('a.assignedUser = :user') - ->andWhere('a.activ = 1') + $queryBuilder = $this->getBaseQueryBuilder(); + $this->filterByTeam(queryBuilder: $queryBuilder, team: $team); + $this->filterByUser(queryBuilder: $queryBuilder, user: $user); + return $queryBuilder->getQuery()->getResult(); + } + + public function findAllByTeam(Team $team) + { + $queryBuilder = $this->getBaseQueryBuilder(); + $this->filterByTeam(queryBuilder: $queryBuilder, team: $team, all: true); + return $queryBuilder->getQuery()->getResult(); + } + + public function findIsInheritedById(string $id) : bool + { + $queryBuilder = $this->getBaseQueryBuilder(); + $this->filterById(queryBuilder: $queryBuilder, id: $id); + $this->filterByInherited(queryBuilder: $queryBuilder); + $result = $queryBuilder->getQuery()->getResult(); + return count($result) > 0; + } + + public function findIsUsedByTeamAndId(Team $team, string $id) : bool + { + $queryBuilder = $this->getBaseQueryBuilder(); + $this->filterByTeam(queryBuilder: $queryBuilder, team: $team); + $this->filterById(queryBuilder: $queryBuilder, id: $id); + $result = $queryBuilder->getQuery()->getResult(); + return count($result) > 0; + } + + private function getBaseQueryBuilder() :QueryBuilder + { + return $this->createQueryBuilder('sw') + ->leftJoin('sw.vvts', 'sp') + ->leftJoin('sw.datenweitergabe', 'dw') + ->leftJoin('dw.verfahren', 'dp') + ->andWhere('sw.activ = 1') + ; + } + + private function filterByTeam(QueryBuilder $queryBuilder, Team $team, bool $all = false) :void + { + $teamPath = $this->teamRepository->getPath($team); + $queryBuilder + ->andWhere('sw.team = :team OR (sp.activ = 1 AND sp.inherited = 1 AND sp.team IN (:teamPath)) OR (dp.activ = 1 AND dp.inherited = 1 AND dp.team IN (:teamPath))') + ->setParameter('teamPath', $teamPath) ->setParameter('team', $team) + ; + + if (!$all) { + $ignored = $team->getIgnoredInheritances(); + if (count($ignored)) { + $queryBuilder + ->andWhere('(sp.activ = 1 AND sp.inherited = 1 AND sp NOT IN (:ignored)) OR (dp.activ = 1 AND dp.inherited = 1 AND dp NOT IN (:ignored)) OR sw.team = :team') + ->setParameter('ignored', $ignored); + } + } + } + + private function filterById(QueryBuilder $queryBuilder, string $id) :void + { + $queryBuilder + ->andWhere('sw.id = :id') + ->setParameter('id', $id); + } + + private function filterByInherited(QueryBuilder $queryBuilder) :void + { + $queryBuilder + ->andWhere('sp.activ = 1 AND sp.inherited = 1 OR dp.activ = 1 AND dp.inherited = 1'); + } + + private function filterByUser(QueryBuilder $queryBuilder, User $user) :void + { + $queryBuilder + ->andWhere('sw.assignedUser = :user') ->setParameter('user', $user) - ->orderBy('a.createdAt', 'DESC') - ->getQuery() - ->getResult(); + ; } } diff --git a/src/Repository/TeamRepository.php b/src/Repository/TeamRepository.php index d8780a64..99f1d3b6 100644 --- a/src/Repository/TeamRepository.php +++ b/src/Repository/TeamRepository.php @@ -3,8 +3,8 @@ namespace App\Repository; use App\Entity\Team; -use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; -use Doctrine\Persistence\ManagerRegistry; +use Doctrine\ORM\EntityManagerInterface; +use Gedmo\Tree\Entity\Repository\NestedTreeRepository; /** * @method Team|null find($id, $lockMode = null, $lockVersion = null) @@ -12,11 +12,11 @@ * @method Team[] findAll() * @method Team[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -class TeamRepository extends ServiceEntityRepository +class TeamRepository extends NestedTreeRepository { - public function __construct(ManagerRegistry $registry) + public function __construct(EntityManagerInterface $em) { - parent::__construct($registry, Team::class); + parent::__construct($em, $em->getClassMetadata(Team::class)); } // /** diff --git a/src/Repository/TomRepository.php b/src/Repository/TomRepository.php index 6b96bb51..bf27ff27 100644 --- a/src/Repository/TomRepository.php +++ b/src/Repository/TomRepository.php @@ -2,8 +2,10 @@ namespace App\Repository; +use App\Entity\Team; use App\Entity\Tom; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\ORM\QueryBuilder; use Doctrine\Persistence\ManagerRegistry; /** @@ -14,48 +16,48 @@ */ class TomRepository extends ServiceEntityRepository { - public function __construct(ManagerRegistry $registry) + public function __construct( + ManagerRegistry $registry, + private readonly TeamRepository $teamRepository, + ) { parent::__construct($registry, Tom::class); } - // /** - // * @return Tom[] Returns an array of Tom objects - // */ - /* - public function findByExampleField($value) + public function findActiveByTeam(Team $team) { - return $this->createQueryBuilder('t') - ->andWhere('t.exampleField = :val') - ->setParameter('val', $value) - ->orderBy('t.id', 'ASC') - ->setMaxResults(10) - ->getQuery() - ->getResult() - ; + $queryBuilder = $this->getBaseQueryBuilder($team); + $this->excludeIgnored($team, $queryBuilder); + return $queryBuilder->getQuery()->getResult(); } - */ - /* - public function findOneBySomeField($value): ?Tom + public function findAllByTeam(Team $team) { - return $this->createQueryBuilder('t') - ->andWhere('t.exampleField = :val') - ->setParameter('val', $value) - ->getQuery() - ->getOneOrNullResult() - ; + $queryBuilder = $this->getBaseQueryBuilder($team); + return $queryBuilder->getQuery()->getResult(); } - */ - public function findActiveByTeam($value) + private function excludeIgnored(Team $team, QueryBuilder $queryBuilder) :void { + $ignored = $team->getIgnoredInheritances(); + if (count($ignored)) { + $queryBuilder + ->andWhere('process NOT IN (:ignored)') + ->setParameter('ignored', $ignored); + } + } + + private function getBaseQueryBuilder(Team $team) :QueryBuilder + { + $teamPath = $this->teamRepository->getPath($team); + return $this->createQueryBuilder('a') - ->andWhere('a.team = :val AND a.activ = 1') - ->setParameter('val', $value) + ->leftJoin('a.vvts', 'process') + ->andWhere('a.team = :team OR process.inherited = 1 AND process.activ = 1 AND process.team IN (:teamPath)') + ->andWhere('a.activ = 1') + ->setParameter('teamPath', $teamPath) + ->setParameter('team', $team) ->orderBy('a.createdAt', 'DESC') - ->getQuery() - ->getResult() ; } } diff --git a/src/Repository/VVTDatenkategorieRepository.php b/src/Repository/VVTDatenkategorieRepository.php index 45ed62ef..1b27cbcb 100644 --- a/src/Repository/VVTDatenkategorieRepository.php +++ b/src/Repository/VVTDatenkategorieRepository.php @@ -8,6 +8,7 @@ namespace App\Repository; +use App\Entity\Team; use App\Entity\VVTDatenkategorie; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; @@ -21,7 +22,9 @@ */ class VVTDatenkategorieRepository extends ServiceEntityRepository { - public function __construct(ManagerRegistry $registry) + public function __construct( + ManagerRegistry $registry, + ) { parent::__construct($registry, VVTDatenkategorie::class); } @@ -38,43 +41,14 @@ public function add(VVTDatenkategorie $entity, bool $flush = true): void } } - // /** - // * @return VVTDatenkategorie[] Returns an array of VVTDatenkategorie objects - // */ - /* - public function findByExampleField($value) - { - return $this->createQueryBuilder('v') - ->andWhere('v.exampleField = :val') - ->setParameter('val', $value) - ->orderBy('v.id', 'ASC') - ->setMaxResults(10) - ->getQuery() - ->getResult() - ; - } - */ - - /* - public function findOneBySomeField($value): ?VVTDatenkategorie - { - return $this->createQueryBuilder('v') - ->andWhere('v.exampleField = :val') - ->setParameter('val', $value) - ->getQuery() - ->getOneOrNullResult() - ; - } - */ - - public function findByTeam($value) + public function findByTeam(Team $team) { $qb = $this->createQueryBuilder('a'); return $qb - ->andWhere('a.team is null OR a.team = :val') + ->andWhere('a.team is null OR a.team = :team') ->andWhere($qb->expr()->isNull('a.cloneOf')) ->andWhere('a.activ = 1') - ->setParameter('val', $value) + ->setParameter('team', $team) ->getQuery() ->getResult(); } diff --git a/src/Repository/VVTDsfaRepository.php b/src/Repository/VVTDsfaRepository.php index f4778a52..23c411a0 100644 --- a/src/Repository/VVTDsfaRepository.php +++ b/src/Repository/VVTDsfaRepository.php @@ -2,9 +2,10 @@ namespace App\Repository; -use App\Entity\VVTDsfa; use App\Entity\Team; +use App\Entity\VVTDsfa; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\ORM\QueryBuilder; use Doctrine\Persistence\ManagerRegistry; /** @@ -15,63 +16,54 @@ */ class VVTDsfaRepository extends ServiceEntityRepository { - public function __construct(ManagerRegistry $registry) + public function __construct( + ManagerRegistry $registry, + private readonly TeamRepository $teamRepository, + ) { parent::__construct($registry, VVTDsfa::class); } - public function findAllByTeam(Team $team): array - { - return $this->createQueryBuilder('d') - ->innerJoin('d.vvt', 'v') - ->andWhere('v.team = :team') - ->andWhere('d.activ = 1') - ->andWhere('v.activ = 1') - ->setParameter('team', $team) - ->orderBy('d.id', 'DESC') - ->getQuery() - ->getResult() - ; - } - - public function findActiveByTeam($value) + public function findActiveByTeam(Team $team) { - return $this->createQueryBuilder('a') - ->innerJoin('a.vvt', 'v') - ->andWhere('a.activ = 1') - ->andWhere('v.team = :val') - ->andWhere('v.activ = 1') - ->setParameter('val', $value) - ->getQuery() - ->getResult() - ; + $queryBuilder = $this->getBaseQueryBuilder($team); + return $queryBuilder->getQuery()->getResult(); } public function findActiveAndOpenByTeam($team) { - return $this->createQueryBuilder('dsfa') - ->innerJoin('dsfa.vvt', 'vvt') - ->andWhere('vvt.activ = 1') - ->andWhere('dsfa.activ = 1') - ->andWhere('dsfa.dsb IS NULL OR dsfa.ergebnis IS NULL') - ->andWhere('vvt.team = :team') - ->setParameter('team', $team) - ->getQuery() - ->getResult(); + $queryBuilder = $this->getBaseQueryBuilder($team); + $queryBuilder->andWhere('a.dsb IS NULL OR a.ergebnis IS NULL'); + return $queryBuilder->getQuery()->getResult(); } public function findActiveByTeamAndUser($team, $user) { - $query = $this->createQueryBuilder('dsfa') - ->innerJoin('dsfa.vvt', 'vvt') - ->andWhere('dsfa.assignedUser = :user') - ->andWhere('vvt.team = :team') - ->andWhere('vvt.activ = 1') - ->andWhere('dsfa.activ = 1') - ->setParameter('user', $user) - ->setParameter('team', $team) - ->getQuery() - ->getResult(); + $queryBuilder = $this->getBaseQueryBuilder($team); + $queryBuilder + ->andWhere('a.assignedUser = :user') + ->setParameter('user', $user); + return $queryBuilder->getQuery()->getResult(); + } - return $query; + private function getBaseQueryBuilder(Team $team) :QueryBuilder + { + $teamPath = $this->teamRepository->getPath($team); + $ignored = $team->getIgnoredInheritances(); + $queryBuilder = $this->createQueryBuilder('a') + ->innerJoin('a.vvt', 'process') + ->andWhere('process.activ = 1') + ->andWhere('a.activ = 1') + ->andWhere('process.team IN (:teamPath)') + ->andWhere('process.team = :team OR process.inherited = 1') + ->setParameter('teamPath', $teamPath) + ->setParameter('team', $team) + ->orderBy('a.id', 'DESC') + ; + if (count($ignored)) { + $queryBuilder + ->andWhere('process NOT IN (:ignored)') + ->setParameter('ignored', $ignored); + } + return $queryBuilder; } } diff --git a/src/Repository/VVTGrundlageRepository.php b/src/Repository/VVTGrundlageRepository.php index d0ff6ddc..d6f63e17 100644 --- a/src/Repository/VVTGrundlageRepository.php +++ b/src/Repository/VVTGrundlageRepository.php @@ -2,6 +2,7 @@ namespace App\Repository; +use App\Entity\Team; use App\Entity\VVTGrundlage; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; @@ -12,49 +13,13 @@ * @method VVTGrundlage[] findAll() * @method VVTGrundlage[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -class VVTGrundlageRepository extends ServiceEntityRepository +class VVTGrundlageRepository extends PresetRepository { - public function __construct(ManagerRegistry $registry) + public function __construct( + protected readonly ManagerRegistry $registry, + protected readonly TeamRepository $teamRepository, + ) { - parent::__construct($registry, VVTGrundlage::class); - } - - // /** - // * @return VVTGrundlage[] Returns an array of VVTGrundlage objects - // */ - /* - public function findByExampleField($value) - { - return $this->createQueryBuilder('v') - ->andWhere('v.exampleField = :val') - ->setParameter('val', $value) - ->orderBy('v.id', 'ASC') - ->setMaxResults(10) - ->getQuery() - ->getResult() - ; - } - */ - - /* - public function findOneBySomeField($value): ?VVTGrundlage - { - return $this->createQueryBuilder('v') - ->andWhere('v.exampleField = :val') - ->setParameter('val', $value) - ->getQuery() - ->getOneOrNullResult() - ; - } - */ - - public function findByTeam($value) - { - return $this->createQueryBuilder('a') - ->where('a.team is null OR a.team = :val') - ->andWhere('a.activ = 1') - ->setParameter('val', $value) - ->getQuery() - ->getResult(); + parent::__construct($this->registry, $this->teamRepository,VVTGrundlage::class); } } diff --git a/src/Repository/VVTPersonenRepository.php b/src/Repository/VVTPersonenRepository.php index e38075ab..31950f76 100644 --- a/src/Repository/VVTPersonenRepository.php +++ b/src/Repository/VVTPersonenRepository.php @@ -2,6 +2,7 @@ namespace App\Repository; +use App\Entity\Team; use App\Entity\VVTPersonen; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; @@ -12,48 +13,24 @@ * @method VVTPersonen[] findAll() * @method VVTPersonen[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -class VVTPersonenRepository extends ServiceEntityRepository +class VVTPersonenRepository extends PresetRepository { - public function __construct(ManagerRegistry $registry) + public function __construct( + protected readonly ManagerRegistry $registry, + protected readonly TeamRepository $teamRepository, + ) { - parent::__construct($registry, VVTPersonen::class); + parent::__construct($this->registry, $this->teamRepository, VVTPersonen::class); } - // /** - // * @return VVTPersonen[] Returns an array of VVTPersonen objects - // */ - /* - public function findByExampleField($value) + public function findByTeam(Team $team) { - return $this->createQueryBuilder('v') - ->andWhere('v.exampleField = :val') - ->setParameter('val', $value) - ->orderBy('v.id', 'ASC') - ->setMaxResults(10) - ->getQuery() - ->getResult() - ; - } - */ + $teamPath = $this->teamRepository->getPath($team); - /* - public function findOneBySomeField($value): ?VVTPersonen - { - return $this->createQueryBuilder('v') - ->andWhere('v.exampleField = :val') - ->setParameter('val', $value) - ->getQuery() - ->getOneOrNullResult() - ; - } - */ - - public function findByTeam($value) - { return $this->createQueryBuilder('a') - ->where('a.team is null OR a.team = :val') + ->where('a.team is null OR a.team IN (:teamPath)') ->andWhere('a.activ = 1') - ->setParameter('val', $value) + ->setParameter('teamPath', $teamPath) ->getQuery() ->getResult(); } diff --git a/src/Repository/VVTRepository.php b/src/Repository/VVTRepository.php index 8ec2b9a6..d53b6a66 100644 --- a/src/Repository/VVTRepository.php +++ b/src/Repository/VVTRepository.php @@ -5,6 +5,7 @@ use App\Entity\Team; use App\Entity\VVT; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\ORM\QueryBuilder; use Doctrine\Persistence\ManagerRegistry; /** @@ -15,43 +16,67 @@ */ class VVTRepository extends ServiceEntityRepository { - public function __construct(ManagerRegistry $registry) + public function __construct( + ManagerRegistry $registry, + private readonly TeamRepository $teamRepository, + ) { parent::__construct($registry, VVT::class); } - public function findActiveByTeam($value) + public function findActiveByTeam(Team $team) { - return $this->createQueryBuilder('a') - ->andWhere('a.team = :val') - ->andWhere('a.activ = 1') - ->setParameter('val', $value) - ->orderBy('a.CreatedAt', 'DESC') - ->getQuery() - ->getResult() - ; + $queryBuilder = $this->getBaseQueryBuilder($team); + $this->excludeIgnored($team, $queryBuilder); + return $queryBuilder->getQuery()->getResult(); + } + + // find current versions of vvts including inherited vvts which aren't used + public function findAllByTeam(Team $team) + { + $queryBuilder = $this->getBaseQueryBuilder($team); + return $queryBuilder->getQuery()->getResult(); } public function findCriticalByTeam(Team $team) { - return $this->createQueryBuilder('vvt') - ->andWhere('vvt.team = :team') - ->andWhere('vvt.activ = 1') - ->andWhere('vvt.status = 3') - ->orderBy('vvt.CreatedAt', 'DESC') - ->setParameter('team', $team) - ->getQuery() - ->getResult(); + $queryBuilder = $this->getBaseQueryBuilder($team); + $this->excludeIgnored($team, $queryBuilder); + $queryBuilder->andWhere('a.status = 3'); + return $queryBuilder->getQuery()->getResult(); } public function findActiveByTeamAndUser($team, $user) { - return $this->createQueryBuilder('a') - ->andWhere('a.team = :team') + $queryBuilder = $this->getBaseQueryBuilder($team); + $this->excludeIgnored($team, $queryBuilder); + $queryBuilder ->andWhere('a.assignedUser = :user') + ->setParameter('user', $user); + + return $queryBuilder->getQuery()->getResult(); + } + + private function excludeIgnored(Team $team, QueryBuilder $queryBuilder) :void + { + $ignored = $team->getIgnoredInheritances(); + if (count($ignored)) { + $queryBuilder + ->andWhere('a NOT IN (:ignored)') + ->setParameter('ignored', $ignored); + } + } + + private function getBaseQueryBuilder(Team $team) :QueryBuilder + { + $teamPath = $this->teamRepository->getPath($team); + + return $this->createQueryBuilder('a') + ->andWhere('a.team IN (:teamPath)') + ->andWhere('a.team = :team OR a.inherited = 1') ->andWhere('a.activ = 1') + ->setParameter('teamPath', $teamPath) ->setParameter('team', $team) - ->setParameter('user', $user) - ->getQuery() - ->getResult(); + ->orderBy('a.CreatedAt', 'DESC') + ; } } diff --git a/src/Repository/VVTRisikenRepository.php b/src/Repository/VVTRisikenRepository.php index 7dbaa02e..5225552d 100644 --- a/src/Repository/VVTRisikenRepository.php +++ b/src/Repository/VVTRisikenRepository.php @@ -12,49 +12,13 @@ * @method VVTRisiken[] findAll() * @method VVTRisiken[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -class VVTRisikenRepository extends ServiceEntityRepository +class VVTRisikenRepository extends PresetRepository { - public function __construct(ManagerRegistry $registry) + public function __construct( + protected readonly ManagerRegistry $registry, + protected readonly TeamRepository $teamRepository, + ) { - parent::__construct($registry, VVTRisiken::class); - } - - // /** - // * @return VVTRisiken[] Returns an array of VVTRisiken objects - // */ - /* - public function findByExampleField($value) - { - return $this->createQueryBuilder('v') - ->andWhere('v.exampleField = :val') - ->setParameter('val', $value) - ->orderBy('v.id', 'ASC') - ->setMaxResults(10) - ->getQuery() - ->getResult() - ; - } - */ - - /* - public function findOneBySomeField($value): ?VVTRisiken - { - return $this->createQueryBuilder('v') - ->andWhere('v.exampleField = :val') - ->setParameter('val', $value) - ->getQuery() - ->getOneOrNullResult() - ; - } - */ - - public function findByTeam($value) - { - return $this->createQueryBuilder('a') - ->where('a.team is null OR a.team = :val') - ->andWhere('a.activ = 1') - ->setParameter('val', $value) - ->getQuery() - ->getResult(); + parent::__construct($this->registry, $this->teamRepository, VVTRisiken::class); } } diff --git a/src/Repository/VVTStatusRepository.php b/src/Repository/VVTStatusRepository.php index 70af473c..c34f4c8c 100644 --- a/src/Repository/VVTStatusRepository.php +++ b/src/Repository/VVTStatusRepository.php @@ -2,8 +2,10 @@ namespace App\Repository; +use App\Entity\Team; use App\Entity\VVTStatus; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\ORM\QueryBuilder; use Doctrine\Persistence\ManagerRegistry; /** @@ -12,49 +14,13 @@ * @method VVTStatus[] findAll() * @method VVTStatus[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -class VVTStatusRepository extends ServiceEntityRepository +class VVTStatusRepository extends PresetRepository { - public function __construct(ManagerRegistry $registry) + public function __construct( + protected readonly ManagerRegistry $registry, + protected readonly TeamRepository $teamRepository, + ) { - parent::__construct($registry, VVTStatus::class); - } - - // /** - // * @return VVTStatus[] Returns an array of VVTStatus objects - // */ - /* - public function findByExampleField($value) - { - return $this->createQueryBuilder('v') - ->andWhere('v.exampleField = :val') - ->setParameter('val', $value) - ->orderBy('v.id', 'ASC') - ->setMaxResults(10) - ->getQuery() - ->getResult() - ; - } - */ - - /* - public function findOneBySomeField($value): ?VVTStatus - { - return $this->createQueryBuilder('v') - ->andWhere('v.exampleField = :val') - ->setParameter('val', $value) - ->getQuery() - ->getOneOrNullResult() - ; - } - */ - - public function findActiveByTeam($value) - { - return $this->createQueryBuilder('a') - ->where('a.team is null OR a.team = :val') - ->andWhere('a.activ = 1') - ->setParameter('val', $value) - ->getQuery() - ->getResult(); + parent::__construct($this->registry, $this->teamRepository, VVTStatus::class); } } diff --git a/src/Service/AkademieService.php b/src/Service/AkademieService.php index e406ea10..d9d3f717 100644 --- a/src/Service/AkademieService.php +++ b/src/Service/AkademieService.php @@ -56,7 +56,7 @@ public function addUser(AkademieKurse $kurs, $daten): void $this->em->persist($buchung); $this->em->flush(); if ($daten['invite'] === true) { - $team = $this->currentTeamService->getTeamFromSession($user); + $team = $this->currentTeamService->getCurrentTeam($user); $content = $this->twig->render('email/neuerKurs.html.twig', ['buchung' => $buchung, 'team' => $team]); $buchung->setInvitation(true); $this->notificationService->sendNotificationAkademie($buchung, $content); diff --git a/src/Service/AssignService.php b/src/Service/AssignService.php index 38302b50..08a8816f 100644 --- a/src/Service/AssignService.php +++ b/src/Service/AssignService.php @@ -325,7 +325,7 @@ public function assignVvt($request, VVT $vvt): bool } } - public function createForm($data, Team $team): FormInterface + public function createForm($data, Team $team, array $options = []): FormInterface { if (count($team->getMembers()) > 0) { $teamMembers = $team->getMembers(); @@ -337,7 +337,6 @@ public function createForm($data, Team $team): FormInterface } else { $teamMembers = array(); } - $form = $this->formBuilder->create(AssignType::class, $data, ['user' => $teamMembers]); - return $form; + return $this->formBuilder->create(AssignType::class, $data, array_merge(['user' => $teamMembers], $options)); } } diff --git a/src/Service/ClientRequestService.php b/src/Service/ClientRequestService.php index fe2fc153..c37a6464 100644 --- a/src/Service/ClientRequestService.php +++ b/src/Service/ClientRequestService.php @@ -45,7 +45,7 @@ public function closeRequest(ClientRequest $clientRequest, $user) $comment = $this->translator->trans(id: 'request.reopened', domain: 'client_request'); } - $team = $this->currentTeamService->getTeamFromSession($user); + $team = $this->currentTeamService->getCurrentTeam($user); $this->newComment($clientRequest, $comment, $team->getKeycloakGroup() . ' > ' . $user->getUsername(), 1); $this->em->persist($clientRequest); @@ -179,7 +179,7 @@ public function userValid(ClientRequest $clientRequest, $user) $comment = $this->translator->trans(id: 'user.comment.validation.success', domain: 'client_reqeust'); } - $team = $this->currentTeamService->getTeamFromSession($user); + $team = $this->currentTeamService->getCurrentTeam($user); $this->newComment($clientRequest, $comment, $team->getKeycloakGroup() . ' > ' . $user->getUsername(), 1); $this->em->persist($clientRequest); diff --git a/src/Service/CurrentTeamService.php b/src/Service/CurrentTeamService.php index ec665ce0..3123b0cc 100644 --- a/src/Service/CurrentTeamService.php +++ b/src/Service/CurrentTeamService.php @@ -4,27 +4,29 @@ use App\Entity\Team; use App\Entity\User; +use App\Repository\TeamRepository; use Doctrine\Common\Collections\Collection; use Symfony\Component\HttpFoundation\RequestStack; class CurrentTeamService { - private $requestStack; - - public function __construct(RequestStack $requestStack) + public function __construct( + private readonly RequestStack $requestStack, + private readonly SecurityService $securityService, + private readonly TeamRepository $teamRepository + ) { - $this->requestStack = $requestStack; + } public function getCurrentAdminTeam(User $user): ?Team { - return $this->findTeam($user->getAdminRoles()); + return $this->getCurrentTeamFromArray($user->getAdminRoles()); } - public function getTeamFromSession(User $user): ?Team + public function getCurrentTeam(User $user): ?Team { - - return $this->findTeam($user->getTeams()); + return $this->getCurrentTeamFromArray(availableTeams: $user->getTeams()); } public function switchToTeam(string $team): void @@ -33,23 +35,54 @@ public function switchToTeam(string $team): void $session->set('team', $team); } - private function findTeam(Collection $teams): ?Team + // only available for superadmins + public function getTeamsWithoutCurrentHierarchy($user, $current = null): ?array + { + if ($this->securityService->superAdminCheck($user)) { + $availableTeams = $this->teamRepository->findAll(); + $currentAndDescendants = $this->teamRepository->getChildren(node: $current, includeNode: true); + $result = []; + + if ($currentAndDescendants) { + for ($i = 0; $i < count($availableTeams); $i++) { + if (array_search($availableTeams[$i], $currentAndDescendants) === false) { + $result[] = $availableTeams[$i]; + } + } + } + + return $result; + } return null; + } + + private function getCurrentTeamFromArray($availableTeams) { + if (!count($availableTeams)){ + return null; + } + + $team = $this->getTeamFromSession(availableTeams: $availableTeams); + + if (!$team) { + $team = $availableTeams->get(0); + $this->switchToTeam($team); + } + + return $team; + } + + private function getTeamFromSession(Collection $availableTeams): ?Team { $session = $this->requestStack->getSession(); $id = $session->get('team'); if ($id) { - foreach ($teams as $team) { + foreach ($availableTeams as $team) { if (strval($team->getId()) === $id) { return $team; } } } - if (count($teams) === 0){ - return null; - } - $team = $teams->get(0); - $this->switchToTeam($team); - return $team; + + return null; } } diff --git a/src/Service/DatenweitergabeService.php b/src/Service/DatenweitergabeService.php index 0fdc2059..767153a9 100644 --- a/src/Service/DatenweitergabeService.php +++ b/src/Service/DatenweitergabeService.php @@ -18,6 +18,11 @@ use App\Entity\VVT; use App\Entity\VVTDsfa; use App\Form\Type\DatenweitergabeType; +use App\Repository\DatenweitergabeGrundlagenRepository; +use App\Repository\DatenweitergabeStandRepository; +use App\Repository\KontakteRepository; +use App\Repository\SoftwareRepository; +use App\Repository\VVTRepository; use DateTime; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Form\FormFactoryInterface; @@ -30,10 +35,13 @@ class DatenweitergabeService const PREFIX_TRANSFER = 'DW-'; public function __construct( - private EntityManagerInterface $em, - private FormFactoryInterface $formBuilder, - private CurrentTeamService $currentTeamService, - + private readonly FormFactoryInterface $formBuilder, + private readonly CurrentTeamService $currentTeamService, + private readonly VVTRepository $processRepository, + private readonly SoftwareRepository $softwareRepository, + private readonly DatenweitergabeStandRepository $transferStatusRepository, + private readonly DatenweitergabeGrundlagenRepository $transferBasisRepository, + private readonly KontakteRepository $contactRepository, ) { } @@ -60,23 +68,35 @@ function cloneDsfa(VVTDsfa $dsfa, User $user): VVTDsfa return $newDsfa; } - function createForm(Datenweitergabe $datenweitergabe, Team $team): FormInterface + function createForm(Datenweitergabe $transfer, Team $team, array $options = []): FormInterface { - $stand = $this->em->getRepository(DatenweitergabeStand::class)->findActiveByTeam($team); - $grundlagen = $this->em->getRepository(DatenweitergabeGrundlagen::class)->findActiveByTeam($team); - $verfahren = $this->em->getRepository(VVT::class)->findBy(array('team' => $team, 'activ' => true)); - $software = $this->em->getRepository(Software::class)->findBy(array('team' => $team, 'activ' => true)); - - $form = $this->formBuilder->create(DatenweitergabeType::class, $datenweitergabe, ['stand' => $stand, 'grundlage' => $grundlagen, 'kontakt' => $team->getKontakte(), 'verfahren' => $verfahren, 'software' => $software]); - - return $form; + if (array_key_exists('disabled', $options) && $options['disabled']) { + $processes = $this->processRepository->findAllByTeam($team); + $software = $this->softwareRepository->findAllByTeam($team); + $contacts = $this->contactRepository->findAllByTeam($team); + } else { + $processes = $this->processRepository->findActiveByTeam($team); + $software = $this->softwareRepository->findActiveByTeam($team); + $contacts = $this->contactRepository->findActiveByTeam($team); + } + + $transferStatuses = $this->transferStatusRepository->findActiveByTeam($team); + $transferReasons = $this->transferBasisRepository->findActiveByTeam($team); + + return $this->formBuilder->create(DatenweitergabeType::class, $transfer, array_merge([ + 'stand' => $transferStatuses, + 'grundlage' => $transferReasons, + 'kontakt' => $contacts, + 'verfahren' => $processes, + 'software' => $software + ], $options)); } function newDatenweitergabe(User $user, $type): Datenweitergabe { $data = new Datenweitergabe(); $prefix = $type === 1 ? self::PREFIX_TRANSFER : self::PREFIX_PROCESSING; - $data->setTeam($this->currentTeamService->getTeamFromSession($user)); + $data->setTeam($this->currentTeamService->getCurrentTeam($user)); $data->setNummer($prefix . hexdec(uniqid())); $data->setActiv(true); $data->setCreatedAt(new DateTime()); diff --git a/src/Service/FormsService.php b/src/Service/FormsService.php index 8e349fe3..d075e796 100644 --- a/src/Service/FormsService.php +++ b/src/Service/FormsService.php @@ -55,7 +55,7 @@ public function newForm(User $user): Forms { $form = new Forms(); $form->setStatus(0); - $form->setTeam($this->currentTeamService->getTeamFromSession($user)); + $form->setTeam($this->currentTeamService->getCurrentTeam($user)); $form->setActiv(true); $form->setCreatedAt(new DateTime()); $form->setUser($user); diff --git a/src/Service/InheritanceService.php b/src/Service/InheritanceService.php new file mode 100644 index 00000000..a043f5a8 --- /dev/null +++ b/src/Service/InheritanceService.php @@ -0,0 +1,177 @@ +softwareRepository->findIsInheritedById($software->getId()); + } + + public function checkTeamUsesSoftware(Team $team, Software $software): bool + { + return $this->softwareRepository->findIsUsedByTeamAndId($team, $software->getId()); + } + + public function checkTomIsInherited(Tom $tom): bool + { + return $this->isInheritedProcessInCollection(processes: $tom->getVvts()); + } + + public function checkTeamUsesTom(Team $team, Tom $tom): bool + { + return $this->isUsedByTeamInCollection(team: $team, processes: $tom->getVvts()); + } + + public function checkPolicyIsInherited(Policies $policy): bool + { + return $this->isInheritedProcessInCollection(processes: $policy->getProcesses()); + } + + public function checkTeamUsesPolicy(Team $team, Policies $policy): bool + { + return $this->isUsedByTeamInCollection(team: $team, processes: $policy->getProcesses()); + } + + public function checkContactIsInherited(Kontakte $contact): bool + { + if ($contact->getId()) { + return $this->contactRepository->findIsInheritedById($contact->getId()); + } + return false; + } + + public function checkTeamUsesContact(Team $team, Kontakte $contact): bool + { + if ($contact->getId()) { + return $this->contactRepository->findIsUsedByTeamAndId($team, $contact->getId()); + } + return false; + } + + public function checkTransferIsInherited(Datenweitergabe $transfer): bool + { + return $this->isInheritedProcessInCollection(processes: $transfer->getVerfahren()); + } + + public function checkTeamUsesTransfer(Team $team, Datenweitergabe $transfer): bool + { + return $this->isUsedByTeamInCollection(team: $team, processes: $transfer->getVerfahren()); + } + + // if there is a process in this collection which is inherited, return true + private function isInheritedProcessInCollection(Collection $processes): bool + { + foreach($processes as $process) { + if ($process->getActiv() && $process->isInherited()) { + return true; + } + } + return false; + } + + public function setIgnored(Preset $preset, Team $team, bool $ignored) + { + if ($ignored) { + $preset->addIgnoredInTeam($team); + $this->addIgnoredPresetToTeam($preset, $team); + } else { + $preset->removeIgnoredInTeam($team); + $this->removeIgnoredPresetFromTeam($preset, $team); + } + } + + private function addIgnoredPresetToTeam(Preset $preset, Team $team) { + switch ($preset->getClass()) { + case VVTStatus::class: + $team->addIgnoredVVTState($preset); + break; + case VVTRisiken::class: + $team->addIgnoredVVTRisk($preset); + break; + case DatenweitergabeGrundlagen::class: + $team->addIgnoredDWGround($preset); + break; + case DatenweitergabeStand::class: + $team->addIgnoredDWState($preset); + break; + case VVTPersonen::class: + $team->addIgnoredVVTPerson($preset); + break; + case VVTGrundlage::class: + $team->addIgnoredVVTGround($preset); + break; + case Produkte::class: + $team->addIgnoredProduct($preset); + break; + case AuditTomZiele::class: + $team->addIgnoredAuditGoal($preset); + } + } + + private function removeIgnoredPresetFromTeam(Preset $preset, Team $team) { + switch ($preset->getClass()) { + case VVTStatus::class: + $team->removeIgnoredVVTState($preset); + break; + case VVTRisiken::class: + $team->removeIgnoredVVTRisk($preset); + break; + case DatenweitergabeGrundlagen::class: + $team->removeIgnoredDWGround($preset); + break; + case DatenweitergabeStand::class: + $team->removeIgnoredDWState($preset); + break; + case VVTPersonen::class: + $team->removeIgnoredVVTPerson($preset); + break; + case VVTGrundlage::class: + $team->removeIgnoredVVTGround($preset); + break; + case Produkte::class: + $team->removeIgnoredProduct($preset); + break; + case AuditTomZiele::class: + $team->removeIgnoredAuditGoal($preset); + } + } + + // if there is a process in the collection which is not ignored, return true + private function isUsedByTeamInCollection(Team $team, Collection $processes): bool + { + foreach($processes as $process) { + if ($process->getActiv() && !$team->getIgnoredInheritances()->contains($process)) { + return true; + } + } + return false; + } +} diff --git a/src/Service/MenuService.php b/src/Service/MenuService.php index 44231b89..27bba0fa 100644 --- a/src/Service/MenuService.php +++ b/src/Service/MenuService.php @@ -18,7 +18,7 @@ class MenuService public function __construct(private FactoryInterface $factory, private TranslatorInterface $translator, private Security $security, private CurrentTeamService $currentTeamService, private RequestStack $requestStack) { $this->user = $this->security->getUser(); - $this->currentTeam = $this->currentTeamService->getTeamFromSession($this->user); + $this->currentTeam = $this->currentTeamService->getCurrentTeam($this->user); } public function createMainMenu(array $options): ItemInterface @@ -45,7 +45,7 @@ public function createMainMenu(array $options): ItemInterface public function createElementsMenu(array $options): ?ItemInterface { $menu = $this->factory->createItem('root'); - + if (!$this->user->getTeams()->isEmpty()) { $menu->addChild($this->trans('auditQuestions'), ['route' => 'audit_tom']); $menu->addChild($this->trans('dataCategories'), ['route' => 'app_vvtdatenkategorie_index']); @@ -178,4 +178,4 @@ private function standardizeRouteName(string $route): string return $route; } -} \ No newline at end of file +} diff --git a/src/Service/PoliciesService.php b/src/Service/PoliciesService.php index 28d859a9..402d2854 100644 --- a/src/Service/PoliciesService.php +++ b/src/Service/PoliciesService.php @@ -16,6 +16,9 @@ use App\Entity\VVTDatenkategorie; use App\Entity\VVTPersonen; use App\Form\Type\PolicyType; +use App\Repository\VVTDatenkategorieRepository; +use App\Repository\VVTPersonenRepository; +use App\Repository\VVTRepository; use DateTime; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Form\FormFactoryInterface; @@ -23,13 +26,13 @@ class PoliciesService { - private $em; - private $formBuilder; - - public function __construct(EntityManagerInterface $entityManager, FormFactoryInterface $formBuilder) + public function __construct( + private readonly FormFactoryInterface $formBuilder, + private readonly VVTRepository $processRepository, + private readonly VVTPersonenRepository $processPeopleRepository, + private readonly VVTDatenkategorieRepository $processCategoryRepository, + ) { - $this->em = $entityManager; - $this->formBuilder = $formBuilder; } function clonePolicy(Policies $policy, User $user) @@ -44,15 +47,23 @@ function clonePolicy(Policies $policy, User $user) return $newPolicy; } - function createForm(Policies $policies, Team $team) + function createForm(Policies $policies, Team $team, array $options = []) { - $personen = $this->em->getRepository(VVTPersonen::class)->findByTeam($team); - $kategorien = $this->em->getRepository(VVTDatenkategorie::class)->findByTeam($team); - $processes = $this->em->getRepository(VVT::class)->findActiveByTeam($team); + if (array_key_exists('disabled', $options) && $options['disabled']) { + $processes = $this->processRepository->findAllByTeam($team); + } else { + $processes = $this->processRepository->findActiveByTeam($team); + } - $form = $this->formBuilder->create(PolicyType::class, $policies, ['personen' => $personen, 'kategorien' => $kategorien, 'user' => $team->getMembers(), 'processes' => $processes]); + $people = $this->processPeopleRepository->findActiveByTeam($team); + $categories = $this->processCategoryRepository->findByTeam($team); - return $form; + return $this->formBuilder->create(PolicyType::class, $policies, array_merge([ + 'personen' => $people, + 'kategorien' => $categories, + 'user' => $team->getMembers(), + 'processes' => $processes + ], $options)); } function newPolicy(Team $team, User $user) diff --git a/src/Service/SecurityService.php b/src/Service/SecurityService.php index d379fb16..37dbf375 100644 --- a/src/Service/SecurityService.php +++ b/src/Service/SecurityService.php @@ -9,18 +9,36 @@ namespace App\Service; +use App\Entity\Datenweitergabe; +use App\Entity\Kontakte; +use App\Entity\Policies; +use App\Entity\Software; use App\Entity\Team; +use App\Entity\Tom; use App\Entity\User; +use App\Entity\VVT; +use App\Repository\DatenweitergabeRepository; +use App\Repository\KontakteRepository; +use App\Repository\PoliciesRepository; +use App\Repository\SoftwareRepository; +use App\Repository\TeamRepository; +use App\Repository\TomRepository; use Psr\Log\LoggerInterface; use Symfony\Contracts\Translation\TranslatorInterface; class SecurityService { - private $logger; - - public function __construct(LoggerInterface $logger, private TranslatorInterface $translator) + public function __construct( + private readonly LoggerInterface $logger, + private readonly TranslatorInterface $translator, + private readonly TeamRepository $teamRepository, + private readonly DatenweitergabeRepository $transferRepository, + private readonly TomRepository $tomRepository, + private readonly SoftwareRepository $softwareRepository, + private readonly KontakteRepository $contactRepository, + private readonly PoliciesRepository $policyRepository, + ) { - $this->logger = $logger; } public function adminCheck(User $user, Team $team): bool @@ -68,14 +86,7 @@ public function superAdminCheck(User $user): bool public function teamArrayDataCheck($data, $team): bool { - //Sicherheitsfunktion, dass ein Team vorhanden ist - if ($team === null) { - $message = [ - 'typ' => 'LOGIN', - 'error' => true, - 'hinweis' => $this->translator->trans(id: 'error.userWithoutTeam', domain: 'general'), - ]; - $this->logger->error($message['typ'], $message); + if (!$this->teamCheck($team)) { return false; } @@ -110,29 +121,89 @@ public function teamCheck($team): bool public function teamDataCheck($data, $team): bool { - //Sicherheitsfunktion, dass ein Team vorhanden ist - if ($team === null) { - $message = [ - 'typ' => 'LOGIN', - 'error' => true, - 'hinweis' => $this->translator->trans(id: 'error.userWithoutTeam', domain: 'general'), - ]; - $this->logger->error($message['typ'], $message); + if (!$this->teamCheck($team)) { return false; } //Sicherheitsfunktion, dass nur eigene Daten bearbeitet werden können if ($team !== $data->getTeam()) { - $message = [ - 'typ' => 'LOGIN', - 'error' => true, - 'hinweis' => $this->translator->trans(id: 'error.userNotInTeamAccessDenied', domain: 'general'), - 'team' => $team->getName(), - ]; - $this->logger->error($message['typ'], $message); + $this->logAccessDenied($team); return false; } return true; } + + public function checkTeamAccessToProcess(VVT $process, $team): bool + { + $teamPath = $team ? $this->teamRepository->getPath($team) : null; + $processTeam = $process->getTeam(); + + if ($processTeam === $team || in_array($processTeam, $teamPath) && $process->isInherited()) { + return true; + } + + $this->logAccessDenied($team); + return false; + } + + public function checkTeamAccessToTransfer(Datenweitergabe $transfer, Team $team): bool + { + if (in_array($transfer, $this->transferRepository->findAllByTeam($team))) { + return true; + } + + $this->logAccessDenied($team); + return false; + } + + public function checkTeamAccessToTom(Tom $tom, Team $team): bool + { + if (in_array($tom, $this->tomRepository->findAllByTeam($team))) { + return true; + } + + $this->logAccessDenied($team); + return false; + } + + public function checkTeamAccessToSoftware(Software $software, Team $team): bool + { + if (in_array($software, $this->softwareRepository->findAllByTeam($team))) { + return true; + } + + $this->logAccessDenied($team); + return false; + } + + public function checkTeamAccessToContact(Kontakte $contact, Team $team): bool + { + if (in_array($contact, $this->contactRepository->findAllByTeam($team))) { + return true; + } + + $this->logAccessDenied($team); + return false; + } + + public function checkTeamAccessToPolicy(Policies $policy, Team $team): bool + { + if (in_array($policy, $this->policyRepository->findAllByTeam($team))) { + return true; + } + + $this->logAccessDenied($team); + return false; + } + + private function logAccessDenied(Team $team): void { + $message = [ + 'typ' => 'LOGIN', + 'error' => true, + 'hinweis' => $this->translator->trans(id: 'error.userNotInTeamAccessDenied', domain: 'general'), + 'team' => $team->getName(), + ]; + $this->logger->error($message['typ'], $message); + } } diff --git a/src/Service/SoftwareService.php b/src/Service/SoftwareService.php index e72ecb47..e2e2c277 100644 --- a/src/Service/SoftwareService.php +++ b/src/Service/SoftwareService.php @@ -14,9 +14,10 @@ use App\Entity\SoftwareConfig; use App\Entity\Team; use App\Entity\User; -use App\Entity\VVT; use App\Form\Type\SoftwareConfigType; use App\Form\Type\SoftwareType; +use App\Repository\DatenweitergabeRepository; +use App\Repository\VVTRepository; use DateTime; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Form\FormFactoryInterface; @@ -25,13 +26,14 @@ class SoftwareService { - private $em; - private $formBuilder; - public function __construct(EntityManagerInterface $entityManager, FormFactoryInterface $formBuilder) + public function __construct( + private readonly EntityManagerInterface $em, + private readonly FormFactoryInterface $formBuilder, + private readonly VVTRepository $processRepository, + private readonly DatenweitergabeRepository $transferRepository, + ) { - $this->em = $entityManager; - $this->formBuilder = $formBuilder; } public function cloneSoftware(Software $software, User $user): Software @@ -51,14 +53,20 @@ public function createConfigForm(SoftwareConfig $softwareConfig): FormInterface return $form; } - public function createForm(Software $software, Team $team): FormInterface + public function createForm(Software $software, Team $team, array $options = []): FormInterface { - $processes = $this->em->getRepository(VVT::class)->findActiveByTeam($team); - $data = $this->em->getRepository(Datenweitergabe::class)->findBy(['team' => $team, 'activ' => true, 'art' => 1]); - - $form = $this->formBuilder->create(SoftwareType::class, $software, ['processes' => $processes, 'datenweitergabe' => $data]); - - return $form; + if (array_key_exists('disabled', $options) && $options['disabled']) { + $processes = $this->processRepository->findAllByTeam($team); + $transfers = $this->transferRepository->findAllByTeam($team); + } else { + $processes = $this->processRepository->findActiveByTeam($team); + $transfers = $this->transferRepository->findActiveByTeam($team); + } + + return $this->formBuilder->create(SoftwareType::class, $software, array_merge([ + 'processes' => $processes, + 'datenweitergabe' => $transfers + ], $options)); } public function newConfig(Software $software): SoftwareConfig diff --git a/src/Service/TeamService.php b/src/Service/TeamService.php index 9a96937b..0e340cd7 100644 --- a/src/Service/TeamService.php +++ b/src/Service/TeamService.php @@ -18,6 +18,14 @@ use App\Entity\VVTPersonen; use App\Entity\VVTRisiken; use App\Entity\VVTStatus; +use App\Repository\AuditTomZieleRepository; +use App\Repository\DatenweitergabeGrundlagenRepository; +use App\Repository\DatenweitergabeStandRepository; +use App\Repository\ProdukteRepository; +use App\Repository\VVTGrundlageRepository; +use App\Repository\VVTPersonenRepository; +use App\Repository\VVTRisikenRepository; +use App\Repository\VVTStatusRepository; use Doctrine\ORM\EntityManagerInterface; use Proxies\__CG__\App\Entity\DatenweitergabeGrundlagen; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; @@ -26,15 +34,21 @@ class TeamService { - private $em; - private $router; - private $translator; - - public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, TranslatorInterface $translator) + public function __construct( + private readonly EntityManagerInterface $em, + private readonly UrlGeneratorInterface $router, + private readonly TranslatorInterface $translator, + private readonly VVTStatusRepository $vVTstatusRepository, + private readonly VVTRisikenRepository $riskRepository, + private readonly VVTPersonenRepository $personRepository, + private readonly VVTGrundlageRepository $vVTGroundRepository, + private readonly ProdukteRepository $productRepository, + private readonly DatenweitergabeStandRepository $dwStatusRepository, + private readonly DatenweitergabeGrundlagenRepository $dwGroundRepository, + private readonly AuditTomZieleRepository $auditGoalRepository + ) { - $this->em = $entityManager; - $this->router = $urlGenerator; - $this->translator = $translator; + } public function create($type, $id, Team $team): object @@ -42,7 +56,7 @@ public function create($type, $id, Team $team): object switch ($type) { case 1: if ($id) { - $data1 = $this->em->getRepository(VVTPersonen::class)->find($id); + $data1 = $this->personRepository->find($id); } else { $data1 = new VVTPersonen(); } @@ -56,49 +70,49 @@ public function create($type, $id, Team $team): object break; case 3: if ($id) { - $data1 = $this->em->getRepository(VVTRisiken::class)->find($id); + $data1 = $this->riskRepository->find($id); } else { $data1 = new VVTRisiken(); } break; case 4: if ($id) { - $data1 = $this->em->getRepository(VVTGrundlage::class)->find($id); + $data1 = $this->vVTGroundRepository->find($id); } else { $data1 = new VVTGrundlage(); } break; case 5: if ($id) { - $data1 = $this->em->getRepository(Produkte::class)->find($id); + $data1 = $this->productRepository->find($id); } else { $data1 = new Produkte(); } break; case 6: if ($id) { - $data1 = $this->em->getRepository(VVTStatus::class)->find($id); + $data1 = $this->vVTstatusRepository->find($id); } else { $data1 = new VVTStatus(); } break; case 11: if ($id) { - $data1 = $this->em->getRepository(DatenweitergabeGrundlagen::class)->find($id); + $data1 = $this->dwGroundRepository->find($id); } else { $data1 = new DatenweitergabeGrundlagen(); } break; case 12: if ($id) { - $data1 = $this->em->getRepository(DatenweitergabeStand::class)->find($id); + $data1 = $this->dwStatusRepository->find($id); } else { $data1 = new DatenweitergabeStand(); } break; case 21: if ($id) { - $data1 = $this->em->getRepository(AuditTomZiele::class)->find($id); + $data1 = $this->auditGoalRepository->find($id); } else { $data1 = new AuditTomZiele(); } @@ -119,31 +133,31 @@ public function delete($type, $id): ?object { switch ($type) { case 1: - $data = $this->em->getRepository(VVTPersonen::class)->findOneBy(array('id' => $id)); + $data = $this->personRepository->findOneBy(array('id' => $id)); break; case 2: $data = $this->em->getRepository(VVTDatenkategorie::class)->findOneBy(array('id' => $id)); break; case 3: - $data = $this->em->getRepository(VVTRisiken::class)->findOneBy(array('id' => $id)); + $data = $this->riskRepository->findOneBy(array('id' => $id)); break; case 4: - $data = $this->em->getRepository(VVTGrundlage::class)->findOneBy(array('id' => $id)); + $data = $this->vVTGroundRepository->findOneBy(array('id' => $id)); break; case 5: - $data = $this->em->getRepository(Produkte::class)->findOneBy(array('id' => $id)); + $data = $this->productRepository->findOneBy(array('id' => $id)); break; case 6: - $data = $this->em->getRepository(VVTStatus::class)->findOneBy(array('id' => $id)); + $data = $this->vVTstatusRepository->findOneBy(array('id' => $id)); break; case 11: - $data = $this->em->getRepository(DatenweitergabeGrundlagen::class)->findOneBy(array('id' => $id)); + $data = $this->dwGroundRepository->findOneBy(array('id' => $id)); break; case 12: - $data = $this->em->getRepository(DatenweitergabeStand::class)->findOneBy(array('id' => $id)); + $data = $this->dwStatusRepository->findOneBy(array('id' => $id)); break; case 21: - $data = $this->em->getRepository(AuditTomZiele::class)->findOneBy(array('id' => $id)); + $data = $this->auditGoalRepository->findOneBy(array('id' => $id)); break; default: @@ -160,165 +174,149 @@ public function show(Team $team): array $data = array(); $id = 1; - $data1 = $this->em->getRepository(VVTPersonen::class)->findBy(array('activ' => true)); + $data1 = $this->personRepository->findAllByTeam($team); $data[$id]['title'] = $this->translator->trans(id: 'groupOfPeople.word', domain: 'service'); $data[$id]['titleNew'] = $this->translator->trans(id: 'groupOfPeople.add', domain: 'service'); $data[$id]['titleEdit'] = $this->translator->trans(id: 'groupOfPeople.edit', domain: 'service'); $data[$id]['newLink'] = $this->router->generate('team_custom_create', ['title' => $data[$id]['titleNew'], 'type' => $id]); $data[$id]['type'] = $id; foreach ($data1 as $item) { - if ($item->getTeam() === $team ) { - $data[$id]['data'][$item->getId()]['id'] = $item->getId(); - $data[$id]['data'][$item->getId()]['name'] = $item->getName(); - $data[$id]['data'][$item->getId()]['deactivate'] = $this->router->generate('team_custom_deativate', ['id' => $item->getId(), 'type' => $id]); - $data[$id]['data'][$item->getId()]['edit'] = $this->router->generate('team_custom_create', ['id' => $item->getId(), 'title' => $data[$id]['titleEdit'], 'type' => $id]); - $data[$id]['data'][$item->getId()]['default'] = false; - $data[$id]['data'][$item->getId()]['object'] = $item; - if ($item->getTeam() === null) { - $data[$id]['data'][$item->getId()]['default'] = true; - } + $data[$id]['data'][$item->getId()]['id'] = $item->getId(); + $data[$id]['data'][$item->getId()]['name'] = $item->getName(); + $data[$id]['data'][$item->getId()]['deactivate'] = $this->router->generate('team_custom_deativate', ['id' => $item->getId(), 'type' => $id]); + $data[$id]['data'][$item->getId()]['edit'] = $this->router->generate('team_custom_create', ['id' => $item->getId(), 'title' => $data[$id]['titleEdit'], 'type' => $id]); + $data[$id]['data'][$item->getId()]['default'] = false; + $data[$id]['data'][$item->getId()]['object'] = $item; + if ($item->getTeam() === null) { + $data[$id]['data'][$item->getId()]['default'] = true; } } $id = 3; - $data1 = $this->em->getRepository(VVTRisiken::class)->findBy(array('activ' => true)); + $data1 = $this->riskRepository->findAllByTeam($team); $data[$id]['title'] = $this->translator->trans(id: 'risk.processing', domain: 'service'); $data[$id]['titleNew'] = $this->translator->trans(id: 'risk.new', domain: 'service'); $data[$id]['titleEdit'] = $this->translator->trans(id: 'risk.edit', domain: 'service'); $data[$id]['newLink'] = $this->router->generate('team_custom_create', ['title' => $data[$id]['titleNew'], 'type' => $id]); foreach ($data1 as $item) { - if ($item->getTeam() === $team ) { - $data[$id]['data'][$item->getId()]['id'] = $item->getId(); - $data[$id]['data'][$item->getId()]['name'] = $item->getName(); - $data[$id]['data'][$item->getId()]['deactivate'] = $this->router->generate('team_custom_deativate', ['id' => $item->getId(), 'type' => $id]); - $data[$id]['data'][$item->getId()]['edit'] = $this->router->generate('team_custom_create', ['id' => $item->getId(), 'title' => $data[$id]['titleEdit'], 'type' => $id]); - $data[$id]['data'][$item->getId()]['default'] = false; - $data[$id]['data'][$item->getId()]['object'] = $item; - if ($item->getTeam() === null) { - $data[$id]['data'][$item->getId()]['default'] = true; - } + $data[$id]['data'][$item->getId()]['id'] = $item->getId(); + $data[$id]['data'][$item->getId()]['name'] = $item->getName(); + $data[$id]['data'][$item->getId()]['deactivate'] = $this->router->generate('team_custom_deativate', ['id' => $item->getId(), 'type' => $id]); + $data[$id]['data'][$item->getId()]['edit'] = $this->router->generate('team_custom_create', ['id' => $item->getId(), 'title' => $data[$id]['titleEdit'], 'type' => $id]); + $data[$id]['data'][$item->getId()]['default'] = false; + $data[$id]['data'][$item->getId()]['object'] = $item; + if ($item->getTeam() === null) { + $data[$id]['data'][$item->getId()]['default'] = true; } } $id = 4; - $data1 = $this->em->getRepository(VVTGrundlage::class)->findBy(array('activ' => true)); + $data1 = $this->vVTGroundRepository->findAllByTeam($team); $data[$id]['title'] = $this->translator->trans(id: 'legalBase.word', domain: 'service'); $data[$id]['titleNew'] = $this->translator->trans(id: 'legalBase.add', domain: 'service'); $data[$id]['titleEdit'] = $this->translator->trans(id: 'legalBase.edit', domain: 'service'); $data[$id]['newLink'] = $this->router->generate('team_custom_create', ['title' => $data[$id]['titleNew'], 'type' => $id]); foreach ($data1 as $item) { - if ($item->getTeam() === $team ) { - $data[$id]['data'][$item->getId()]['id'] = $item->getId(); - $data[$id]['data'][$item->getId()]['name'] = $item->getName(); - $data[$id]['data'][$item->getId()]['deactivate'] = $this->router->generate('team_custom_deativate', ['id' => $item->getId(), 'type' => $id]); - $data[$id]['data'][$item->getId()]['edit'] = $this->router->generate('team_custom_create', ['id' => $item->getId(), 'title' => $data[$id]['titleEdit'], 'type' => $id]); - $data[$id]['data'][$item->getId()]['default'] = false; - $data[$id]['data'][$item->getId()]['object'] = $item; - if ($item->getTeam() === null) { - $data[$id]['data'][$item->getId()]['default'] = true; - } + $data[$id]['data'][$item->getId()]['id'] = $item->getId(); + $data[$id]['data'][$item->getId()]['name'] = $item->getName(); + $data[$id]['data'][$item->getId()]['deactivate'] = $this->router->generate('team_custom_deativate', ['id' => $item->getId(), 'type' => $id]); + $data[$id]['data'][$item->getId()]['edit'] = $this->router->generate('team_custom_create', ['id' => $item->getId(), 'title' => $data[$id]['titleEdit'], 'type' => $id]); + $data[$id]['data'][$item->getId()]['default'] = false; + $data[$id]['data'][$item->getId()]['object'] = $item; + if ($item->getTeam() === null) { + $data[$id]['data'][$item->getId()]['default'] = true; } } $id = 5; - $data1 = $this->em->getRepository(Produkte::class)->findBy(array('activ' => true)); + $data1 = $this->productRepository->findAllByTeam($team); $data[$id]['title'] = $this->translator->trans(id: 'product.word', domain: 'service'); $data[$id]['titleNew'] = $this->translator->trans(id: 'product.add', domain: 'service'); $data[$id]['titleEdit'] = $this->translator->trans(id: 'product.edit', domain: 'service'); $data[$id]['newLink'] = $this->router->generate('team_custom_create', ['title' => $data[$id]['titleNew'], 'type' => $id]); foreach ($data1 as $item) { - if ($item->getTeam() === $team ) { - $data[$id]['data'][$item->getId()]['id'] = $item->getId(); - $data[$id]['data'][$item->getId()]['name'] = $item->getName(); - $data[$id]['data'][$item->getId()]['deactivate'] = $this->router->generate('team_custom_deativate', ['id' => $item->getId(), 'type' => $id]); - $data[$id]['data'][$item->getId()]['edit'] = $this->router->generate('team_custom_create', ['id' => $item->getId(), 'title' => $data[$id]['titleEdit'], 'type' => $id]); - $data[$id]['data'][$item->getId()]['default'] = false; - $data[$id]['data'][$item->getId()]['object'] = $item; - if ($item->getTeam() === null) { - $data[$id]['data'][$item->getId()]['default'] = true; - } + $data[$id]['data'][$item->getId()]['id'] = $item->getId(); + $data[$id]['data'][$item->getId()]['name'] = $item->getName(); + $data[$id]['data'][$item->getId()]['deactivate'] = $this->router->generate('team_custom_deativate', ['id' => $item->getId(), 'type' => $id]); + $data[$id]['data'][$item->getId()]['edit'] = $this->router->generate('team_custom_create', ['id' => $item->getId(), 'title' => $data[$id]['titleEdit'], 'type' => $id]); + $data[$id]['data'][$item->getId()]['default'] = false; + $data[$id]['data'][$item->getId()]['object'] = $item; + if ($item->getTeam() === null) { + $data[$id]['data'][$item->getId()]['default'] = true; } } $id = 6; - $data1 = $this->em->getRepository(VVTStatus::class)->findBy(array('activ' => true)); + $data1 = $this->vVTstatusRepository->findAllByTeam($team); $data[$id]['title'] = $this->translator->trans(id: 'processingState.word', domain: 'service'); $data[$id]['titleNew'] = $this->translator->trans(id: 'processingState.add', domain: 'service'); $data[$id]['titleEdit'] = $this->translator->trans(id: 'processingState.edit', domain: 'service'); $data[$id]['newLink'] = $this->router->generate('team_custom_create', ['title' => $data[$id]['titleNew'], 'type' => $id]); foreach ($data1 as $item) { - if ($item->getTeam() === $team ) { - $data[$id]['data'][$item->getId()]['id'] = $item->getId(); - $data[$id]['data'][$item->getId()]['name'] = $item->getName(); - $data[$id]['data'][$item->getId()]['deactivate'] = $this->router->generate('team_custom_deativate', ['id' => $item->getId(), 'type' => $id]); - $data[$id]['data'][$item->getId()]['edit'] = $this->router->generate('team_custom_create', ['id' => $item->getId(), 'title' => $data[$id]['titleEdit'], 'type' => $id]); - $data[$id]['data'][$item->getId()]['default'] = false; - $data[$id]['data'][$item->getId()]['object'] = $item; - if ($item->getTeam() === null) { - $data[$id]['data'][$item->getId()]['default'] = true; - } + $data[$id]['data'][$item->getId()]['id'] = $item->getId(); + $data[$id]['data'][$item->getId()]['name'] = $item->getName(); + $data[$id]['data'][$item->getId()]['deactivate'] = $this->router->generate('team_custom_deativate', ['id' => $item->getId(), 'type' => $id]); + $data[$id]['data'][$item->getId()]['edit'] = $this->router->generate('team_custom_create', ['id' => $item->getId(), 'title' => $data[$id]['titleEdit'], 'type' => $id]); + $data[$id]['data'][$item->getId()]['default'] = false; + $data[$id]['data'][$item->getId()]['object'] = $item; + if ($item->getTeam() === null) { + $data[$id]['data'][$item->getId()]['default'] = true; } } $id = 11; - $data1 = $this->em->getRepository(DatenweitergabeGrundlagen::class)->findBy(array('activ' => true)); + $data1 = $this->dwGroundRepository->findAllByTeam($team); $data[$id]['title'] = $this->translator->trans(id: 'dataTransfer.base.word', domain: 'service'); $data[$id]['titleNew'] = $this->translator->trans(id: 'dataTransfer.base.add', domain: 'service'); $data[$id]['titleEdit'] = $this->translator->trans(id: 'dataTransfer.base.edit', domain: 'service'); $data[$id]['newLink'] = $this->router->generate('team_custom_create', ['title' => $data[$id]['titleNew'], 'type' => $id]); foreach ($data1 as $item) { - if ($item->getTeam() === $team ) { - $data[$id]['data'][$item->getId()]['id'] = $item->getId(); - $data[$id]['data'][$item->getId()]['name'] = $item->getName(); - $data[$id]['data'][$item->getId()]['deactivate'] = $this->router->generate('team_custom_deativate', ['id' => $item->getId(), 'type' => $id]); - $data[$id]['data'][$item->getId()]['edit'] = $this->router->generate('team_custom_create', ['id' => $item->getId(), 'title' => $data[$id]['titleEdit'], 'type' => $id]); - $data[$id]['data'][$item->getId()]['default'] = false; - $data[$id]['data'][$item->getId()]['object'] = $item; - if ($item->getTeam() === null) { - $data[$id]['data'][$item->getId()]['default'] = true; - } + $data[$id]['data'][$item->getId()]['id'] = $item->getId(); + $data[$id]['data'][$item->getId()]['name'] = $item->getName(); + $data[$id]['data'][$item->getId()]['deactivate'] = $this->router->generate('team_custom_deativate', ['id' => $item->getId(), 'type' => $id]); + $data[$id]['data'][$item->getId()]['edit'] = $this->router->generate('team_custom_create', ['id' => $item->getId(), 'title' => $data[$id]['titleEdit'], 'type' => $id]); + $data[$id]['data'][$item->getId()]['default'] = false; + $data[$id]['data'][$item->getId()]['object'] = $item; + if ($item->getTeam() === null) { + $data[$id]['data'][$item->getId()]['default'] = true; } } $id = 12; - $data1 = $this->em->getRepository(DatenweitergabeStand::class)->findBy(array('activ' => true)); + $data1 = $this->dwStatusRepository->findAllByTeam($team); $data[$id]['title'] = $this->translator->trans(id: 'dataTransfer.state.word', domain: 'service'); $data[$id]['titleNew'] = $this->translator->trans(id: 'dataTransfer.state.add', domain: 'service'); $data[$id]['titleEdit'] = $this->translator->trans(id: 'dataTransfer.state.edit', domain: 'service'); $data[$id]['newLink'] = $this->router->generate('team_custom_create', ['title' => $data[$id]['titleNew'], 'type' => $id]); foreach ($data1 as $item) { - if ($item->getTeam() === $team ) { - $data[$id]['data'][$item->getId()]['id'] = $item->getId(); - $data[$id]['data'][$item->getId()]['name'] = $item->getName(); - $data[$id]['data'][$item->getId()]['deactivate'] = $this->router->generate('team_custom_deativate', ['id' => $item->getId(), 'type' => $id]); - $data[$id]['data'][$item->getId()]['edit'] = $this->router->generate('team_custom_create', ['id' => $item->getId(), 'title' => $data[$id]['titleEdit'], 'type' => $id]); - $data[$id]['data'][$item->getId()]['default'] = false; - $data[$id]['data'][$item->getId()]['object'] = $item; - if ($item->getTeam() === null) { - $data[$id]['data'][$item->getId()]['default'] = true; - } + $data[$id]['data'][$item->getId()]['id'] = $item->getId(); + $data[$id]['data'][$item->getId()]['name'] = $item->getName(); + $data[$id]['data'][$item->getId()]['deactivate'] = $this->router->generate('team_custom_deativate', ['id' => $item->getId(), 'type' => $id]); + $data[$id]['data'][$item->getId()]['edit'] = $this->router->generate('team_custom_create', ['id' => $item->getId(), 'title' => $data[$id]['titleEdit'], 'type' => $id]); + $data[$id]['data'][$item->getId()]['default'] = false; + $data[$id]['data'][$item->getId()]['object'] = $item; + if ($item->getTeam() === null) { + $data[$id]['data'][$item->getId()]['default'] = true; } } $id = 21; - $data1 = $this->em->getRepository(AuditTomZiele::class)->findBy(array('activ' => true)); + $data1 = $this->auditGoalRepository->findAllByTeam($team); $data[$id]['title'] = $this->translator->trans(id: 'auditGoal.word', domain: 'service'); $data[$id]['titleNew'] = $this->translator->trans(id: 'auditGoal.add', domain: 'service'); $data[$id]['titleEdit'] = $this->translator->trans(id: 'auditGoal.edit', domain: 'service'); $data[$id]['newLink'] = $this->router->generate('team_custom_create', ['title' => $data[$id]['titleNew'], 'type' => $id]); foreach ($data1 as $item) { - if ($item->getTeam() === $team) { - $data[$id]['data'][$item->getId()]['id'] = $item->getId(); - $data[$id]['data'][$item->getId()]['name'] = $item->getName(); - $data[$id]['data'][$item->getId()]['deactivate'] = $this->router->generate('team_custom_deativate', ['id' => $item->getId(), 'type' => $id]); - $data[$id]['data'][$item->getId()]['edit'] = $this->router->generate('team_custom_create', ['id' => $item->getId(), 'title' => $data[$id]['titleEdit'], 'type' => $id]); - $data[$id]['data'][$item->getId()]['default'] = false; - $data[$id]['data'][$item->getId()]['object'] = $item; - if ($item->getTeam() === null) { - $data[$id]['data'][$item->getId()]['default'] = true; - } + $data[$id]['data'][$item->getId()]['id'] = $item->getId(); + $data[$id]['data'][$item->getId()]['name'] = $item->getName(); + $data[$id]['data'][$item->getId()]['deactivate'] = $this->router->generate('team_custom_deativate', ['id' => $item->getId(), 'type' => $id]); + $data[$id]['data'][$item->getId()]['edit'] = $this->router->generate('team_custom_create', ['id' => $item->getId(), 'title' => $data[$id]['titleEdit'], 'type' => $id]); + $data[$id]['data'][$item->getId()]['default'] = false; + $data[$id]['data'][$item->getId()]['object'] = $item; + if ($item->getTeam() === null) { + $data[$id]['data'][$item->getId()]['default'] = true; } } diff --git a/src/Service/VVTDatenkategorieService.php b/src/Service/VVTDatenkategorieService.php index 08e83cee..0e568244 100644 --- a/src/Service/VVTDatenkategorieService.php +++ b/src/Service/VVTDatenkategorieService.php @@ -4,6 +4,7 @@ namespace App\Service; +use App\DataTypes\InheritedEntity; use App\Entity\Loeschkonzept; use App\Entity\Team; use App\Entity\User; @@ -100,4 +101,23 @@ function newVVTDatenkategorie(Team $team, User $user) return $vVTDatenkategorie; } + /** + * @param VVTDatenkategorie[] $categories + * @return array + */ + function getInheritedEntities(array $categories): array + { + $result = []; + foreach ($categories as $category) { + $inheritedEntity = new InheritedEntity(); + $inheritedEntity->setCategory($category); + $latestDeletionConcept = $category->getLastLoeschkonzept(); + if ($latestDeletionConcept && $latestDeletionConcept->getActiv()) { + $inheritedEntity->setDeletionConcept($latestDeletionConcept); + } + $result[] = $inheritedEntity; + } + return $result; + } + } diff --git a/src/Service/VVTService.php b/src/Service/VVTService.php index 45d6194e..43ffb9ee 100644 --- a/src/Service/VVTService.php +++ b/src/Service/VVTService.php @@ -24,20 +24,38 @@ use App\Entity\VVTRisiken; use App\Entity\VVTStatus; use App\Form\Type\VVTType; +use App\Repository\AuditTomAbteilungRepository; +use App\Repository\DatenweitergabeRepository; +use App\Repository\ProdukteRepository; +use App\Repository\SoftwareRepository; +use App\Repository\TomRepository; +use App\Repository\VVTDatenkategorieRepository; +use App\Repository\VVTGrundlageRepository; +use App\Repository\VVTPersonenRepository; +use App\Repository\VVTRisikenRepository; +use App\Repository\VVTStatusRepository; use DateTime; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Form\FormFactoryInterface; +use Symfony\Component\Form\FormInterface; class VVTService { - private $em; - private $formBuilder; - - public function __construct(EntityManagerInterface $entityManager, FormFactoryInterface $formBuilder) + public function __construct( + private readonly FormFactoryInterface $formBuilder, + private readonly TomRepository $tomRepository, + private readonly SoftwareRepository $softwareRepository, + private readonly DatenweitergabeRepository $transferRepository, + private readonly VVTStatusRepository $processStatusRepository, + private readonly VVTPersonenRepository $processPeopleRepository, + private readonly VVTDatenkategorieRepository $processCategoryRepository, + private readonly VVTGrundlageRepository $processBasisRepository, + private readonly VVTRisikenRepository $processRiskRepository, + private readonly AuditTomAbteilungRepository $departmentRepository, + private readonly ProdukteRepository $productRepository, + ) { - $this->em = $entityManager; - $this->formBuilder = $formBuilder; } function cloneDsfa(VVTDsfa $dsfa, User $user) @@ -62,37 +80,45 @@ function cloneVvt(VVT $vvt, User $user) return $newVvt; } - function createForm(VVT $VVT, Team $team) + function createForm(VVT $VVT, Team $team, array $options = []): FormInterface { - $status = $this->em->getRepository(VVTStatus::class)->findActiveByTeam($team); - $personen = $this->em->getRepository(VVTPersonen::class)->findByTeam($team); - $kategorien = $this->em->getRepository(VVTDatenkategorie::class)->findByTeam($team); - $risiken = $this->em->getRepository(VVTRisiken::class)->findByTeam($team); - $grundlagen = $this->em->getRepository(VVTGrundlage::class)->findByTeam($team); - $daten = $this->em->getRepository(Datenweitergabe::class)->findBy(array('team' => $team, 'activ' => true)); - $tom = $this->em->getRepository(Tom::class)->findBy(array('team' => $team, 'activ' => true)); - $abteilung = $this->em->getRepository(AuditTomAbteilung::class)->findBy(array('team' => $team, 'activ' => true)); - $produkte = $this->em->getRepository(Produkte::class)->findActiveByTeam($team); - $software = $this->em->getRepository(Software::class)->findActiveByTeam($team); - - $form = $this->formBuilder->create(VVTType::class, $VVT, [ - 'personen' => $personen, - 'kategorien' => $kategorien, - 'risiken' => $risiken, - 'status' => $status, - 'grundlage' => $grundlagen, - 'user' => $team->getMembers(), - 'daten' => $daten, - 'tom' => $tom, - 'abteilung' => $abteilung, - 'produkte' => $produkte, - 'software' => $software - ]); - - return $form; + if (array_key_exists('disabled', $options) && $options['disabled']) { + $tom = $this->tomRepository->findAllByTeam($team); + $software = $this->softwareRepository->findAllByTeam($team); + $transfers = $this->transferRepository->findAllByTeam($team); + } else { + $tom = $this->tomRepository->findActiveByTeam($team); + $software = $this->softwareRepository->findActiveByTeam($team); + $transfers = $this->transferRepository->findActiveByTeam($team); + } + + $statuses = $this->processStatusRepository->findActiveByTeam($team); + $people = $this->processPeopleRepository->findActiveByTeam($team); + $categories = $this->processCategoryRepository->findByTeam($team); + $bases = $this->processBasisRepository->findActiveByTeam($team); + $risks = $this->processRiskRepository->findActiveByTeam($team); + $departments = $this->departmentRepository->findActiveByTeam($team); + $products = $this->productRepository->findActiveByTeam($team); + + return $this->formBuilder->create(VVTType::class, $VVT, array_merge( + [ + 'personen' => $people, + 'kategorien' => $categories, + 'risiken' => $risks, + 'status' => $statuses, + 'grundlage' => $bases, + 'user' => $team->getMembers(), + 'daten' => $transfers, + 'tom' => $tom, + 'abteilung' => $departments, + 'produkte' => $products, + 'software' => $software + ], + $options + )); } - function newDsfa(Team $team, User $user, VVT $vvt) + function newDsfa(User $user, VVT $vvt): VVTDsfa { $dsfa = new VVTDsfa(); $dsfa->setVvt($vvt); @@ -103,7 +129,7 @@ function newDsfa(Team $team, User $user, VVT $vvt) return $dsfa; } - function newVvt(Team $team, User $user) + function newVvt(Team $team, User $user): VVT { $vvt = new VVT(); $vvt->setTeam($team); diff --git a/src/Service/VorfallService.php b/src/Service/VorfallService.php index 32bc181e..5a2d4812 100644 --- a/src/Service/VorfallService.php +++ b/src/Service/VorfallService.php @@ -43,7 +43,7 @@ function cloneVorfall(Vorfall $input, User $user) function createForm(Vorfall $vorfall, Team $team) { - $personen = $this->em->getRepository(VVTPersonen::class)->findByTeam($team); + $personen = $this->em->getRepository(VVTPersonen::class)->findActiveByTeam($team); $kategorien = $this->em->getRepository(VVTDatenkategorie::class)->findByTeam($team); $form = $this->formBuilder->create(VorfallType::class, $vorfall, ['personen' => $personen, 'daten' => $kategorien]); diff --git a/src/Twig/InheritanceExtension.php b/src/Twig/InheritanceExtension.php new file mode 100644 index 00000000..ad0359d3 --- /dev/null +++ b/src/Twig/InheritanceExtension.php @@ -0,0 +1,89 @@ +inheritanceService->checkSoftwareIsInherited(software: $software); + } + + public function checkTeamUsesSoftware(Team $team, Software $software): bool + { + return $this->inheritanceService->checkTeamUsesSoftware(team: $team, software: $software); + } + + public function checkTomIsInherited(Tom $tom): bool + { + return $this->inheritanceService->checkTomIsInherited(tom: $tom); + } + + public function checkTeamUsesTom(Team $team, Tom $tom): bool + { + return $this->inheritanceService->checkTeamUsesTom(team: $team, tom: $tom); + } + + public function checkPolicyIsInherited(Policies $policy): bool + { + return $this->inheritanceService->checkPolicyIsInherited(policy: $policy); + } + + public function checkTeamUsesPolicy(Team $team, Policies $policy): bool + { + return $this->inheritanceService->checkTeamUsesPolicy(team: $team, policy: $policy); + } + + public function checkContactIsInherited(Kontakte $contact): bool + { + return $this->inheritanceService->checkContactIsInherited(contact: $contact); + } + + public function checkTeamUsesContact(Team $team, Kontakte $contact): bool + { + return $this->inheritanceService->checkTeamUsesContact(team: $team, contact: $contact); + } + + public function checkTransferIsInherited(Datenweitergabe $transfer): bool + { + return $this->inheritanceService->checkTransferIsInherited(transfer: $transfer); + } + + public function checkTeamUsesTransfer(Team $team, Datenweitergabe $transfer): bool + { + return $this->inheritanceService->checkTeamUsesTransfer(team: $team, transfer: $transfer); + } +} diff --git a/symfony.lock b/symfony.lock index 467b8ba3..4329d2e8 100644 --- a/symfony.lock +++ b/symfony.lock @@ -341,6 +341,18 @@ "stevenmaguire/oauth2-keycloak": { "version": "2.2.1" }, + "stof/doctrine-extensions-bundle": { + "version": "1.7", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "main", + "version": "1.2", + "ref": "e805aba9eff5372e2d149a9ff56566769e22819d" + }, + "files": [ + "config/packages/stof_doctrine_extensions.yaml" + ] + }, "swiftmailer/swiftmailer": { "version": "v6.2.3" }, diff --git a/templates/Form/tailwind_3_layout.html.twig b/templates/Form/tailwind_3_layout.html.twig index 5faa67f2..44407387 100644 --- a/templates/Form/tailwind_3_layout.html.twig +++ b/templates/Form/tailwind_3_layout.html.twig @@ -16,10 +16,16 @@ {% block textarea_widget %} {% if form.vars.attr.class is defined and 'summernote' in form.vars.attr.class %} -
- -
- + {% if form.parent.vars.disabled %} +
+ {{ form.vars.value|raw }} +
+ {% else %} +
+ +
+ + {% endif %} {% else %} {{ form_widget(form) }} {% endif %} diff --git a/templates/assign/__assign.html.twig b/templates/assign/__assign.html.twig index 067d8922..7062e8cd 100644 --- a/templates/assign/__assign.html.twig +++ b/templates/assign/__assign.html.twig @@ -25,7 +25,7 @@ {% else %} -
+

{% trans from 'general' %}assignedTo{% endtrans %}: {{ data.assignedUser.email }} diff --git a/templates/assign/index.html.twig b/templates/assign/index.html.twig index 14e68d78..0b26f3f7 100644 --- a/templates/assign/index.html.twig +++ b/templates/assign/index.html.twig @@ -44,9 +44,9 @@ {% endfor %}

-
+
    - {% for a in processings %} + {% for a in processes %} {% if a.activ %}
  • {{ a.team.name }}: {{ a.name }} @@ -62,7 +62,8 @@ {% for a in impactAssessments %} {% if a.vvt.team == currentTeam %}
  • - {{ a.vvt.team.name }}: {{ a.beschreibung }} + {{ a.vvt.team.name }}: +
    {{ a.beschreibung|raw }}
    {{ a.vvt.name }}
    {{ a.createdAt|date('d.m.Y') }}
  • diff --git a/templates/assistant/index.html.twig b/templates/assistant/index.html.twig index 5c8ce699..b7dc8782 100644 --- a/templates/assistant/index.html.twig +++ b/templates/assistant/index.html.twig @@ -6,17 +6,8 @@ {% endblock %} {% block body %} - {% if app.request.hasPreviousSession %} - {% for type, messages in app.session.flashbag.all() %} - {% for message in messages %} -
    - {{ message | trans }} -
    - {% endfor %} - {% endfor %} - {% endif %}
    {% trans %}assistant.info{% endtrans %}

    {% trans %}assistant.start{% endtrans %}

    -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/templates/assistant/step.html.twig b/templates/assistant/step.html.twig index c4583837..693ad0d0 100644 --- a/templates/assistant/step.html.twig +++ b/templates/assistant/step.html.twig @@ -78,4 +78,4 @@ {{ form_end(form) }}
-{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/templates/base.html.twig b/templates/base.html.twig index 191416a3..5f44b97f 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -46,4 +46,4 @@ {% block javascripts %}{% endblock %} - \ No newline at end of file + diff --git a/templates/base/__approveBtn.html.twig b/templates/base/__approveBtn.html.twig index 76791edb..5cd671a8 100644 --- a/templates/base/__approveBtn.html.twig +++ b/templates/base/__approveBtn.html.twig @@ -1,13 +1,9 @@ {% trans_default_domain 'base' %} {% if data.team in app.user.adminRoles and not data.activ == 0 %} - - {% if data.approved %} - {% trans %}rescindApproval{% endtrans %} - {% else %} - {% trans %}approve{% endtrans %} - {% endif %} + + {{ data.approved ? 'rescindApproval'|trans : 'approve'|trans }} {% endif %} \ No newline at end of file diff --git a/templates/base/__approvedBy.html.twig b/templates/base/__approvedBy.html.twig index d4e3b123..1a3a8bfd 100644 --- a/templates/base/__approvedBy.html.twig +++ b/templates/base/__approvedBy.html.twig @@ -1,7 +1,5 @@ {% trans_default_domain 'base' %} {% if data.approved %} -
-

{% trans %}approvedBy{% endtrans %} {{ data.approvedBy.email }}

-
+ {% trans %}approvedBy{% endtrans %} {{ data.approvedBy.email }} {% endif %} diff --git a/templates/base/__inheritanceInfo.html.twig b/templates/base/__inheritanceInfo.html.twig new file mode 100644 index 00000000..66407b68 --- /dev/null +++ b/templates/base/__inheritanceInfo.html.twig @@ -0,0 +1,14 @@ +{% trans_default_domain domain|default('general') %} +{% if inherited %} + +{% endif %} diff --git a/templates/base/__inheritanceTCols.html.twig b/templates/base/__inheritanceTCols.html.twig new file mode 100644 index 00000000..f24a3dc6 --- /dev/null +++ b/templates/base/__inheritanceTCols.html.twig @@ -0,0 +1,21 @@ +{% trans_default_domain domain|default('general') %} +{% if currentTeam.children.count %}{# hide column in leaf teams #} + + {% if team == currentTeam %} + {% if inherited %}✅{% else %}❌{% endif %} + {% endif %} + +{% endif %} + +{% if currentTeam.root != currentTeam %}{# hide columns in root teams #} + + {% if team != currentTeam %}{{ team }}{% else %}{% endif %} + + {% if team != currentTeam and used %} + ✅ + {% elseif team != currentTeam %} + ❌ + {% else %} + + {% endif %} +{% endif %} diff --git a/templates/base/__inheritanceTHeaders.html.twig b/templates/base/__inheritanceTHeaders.html.twig new file mode 100644 index 00000000..3038832a --- /dev/null +++ b/templates/base/__inheritanceTHeaders.html.twig @@ -0,0 +1,8 @@ +{% trans_default_domain domain|default('general') %} +{% if currentTeam.children.count %}{# hide column in leaf teams #} + {% trans %}inheritance.isInherited{% endtrans %} +{% endif %} +{% if currentTeam.root != currentTeam %}{# hide columns in root teams #} + {% trans %}inheritance.fromTeam{% endtrans %} + {% trans %}inheritance.isActive{% endtrans %} +{% endif %} diff --git a/templates/base/__snack.html.twig b/templates/base/__snack.html.twig index 711f6299..6490913f 100644 --- a/templates/base/__snack.html.twig +++ b/templates/base/__snack.html.twig @@ -8,4 +8,4 @@ {% for flashMessage in app.session.flashbag.get('error') %} {{ include ('base/__snackItem.html.twig', {snackClass: 'error'}) }} -{% endfor %} \ No newline at end of file +{% endfor %} diff --git a/templates/base/__snackItem.html.twig b/templates/base/__snackItem.html.twig index 4be6fa7d..9816b980 100644 --- a/templates/base/__snackItem.html.twig +++ b/templates/base/__snackItem.html.twig @@ -1,4 +1,4 @@ -
+

{{ flashMessage }}

\ No newline at end of file +
diff --git a/templates/base/__teamToggle.html.twig b/templates/base/__teamToggle.html.twig index 8049fceb..6333202c 100644 --- a/templates/base/__teamToggle.html.twig +++ b/templates/base/__teamToggle.html.twig @@ -1,19 +1,26 @@ {% set teams = adminArea is defined and adminArea ? app.user.adminRoles : app.user.teams %} -{% if teams|length > 1 and currentTeam is defined and currentTeam %} +{% if currentTeam is defined and currentTeam %}
- - + {% if teams|length > 1 %} + + + {% else %} +
+ group + {{ currentTeam.name }} +
+ {% endif %}
-{% endif %} \ No newline at end of file +{% endif %} diff --git a/templates/dashboard/__assign.html.twig b/templates/dashboard/__assign.html.twig index 16416a76..3142e39c 100644 --- a/templates/dashboard/__assign.html.twig +++ b/templates/dashboard/__assign.html.twig @@ -66,7 +66,8 @@ {% for a in assignDsfa %} {% if a.activ %}
  • - {{ a.vvt.team.name }}: {{ a.beschreibung }} +
    {{ a.vvt.team.name }}:
    + {{ a.beschreibung|raw }}
    {{ a.createdAt|date('d.m.Y') }}
  • {% endif %} @@ -91,4 +92,4 @@

    {% trans %}showAllAssignments{% endtrans %}

    -
    \ No newline at end of file +
    diff --git a/templates/datenweitergabe/__indexTable.html.twig b/templates/datenweitergabe/__indexTable.html.twig index f097d981..8d32b03a 100644 --- a/templates/datenweitergabe/__indexTable.html.twig +++ b/templates/datenweitergabe/__indexTable.html.twig @@ -1,4 +1,5 @@ {% trans_default_domain 'datenweitergabe' %} + @@ -9,6 +10,7 @@ + {% include 'base/__inheritanceTHeaders.html.twig' with {currentTeam:currentTeam} %} @@ -21,7 +23,10 @@ + {% set inherited = transferInherited(t) %} + {% set used = teamUsesTransfer(currentTeam, t) %} + {% include 'base/__inheritanceTCols.html.twig' with {team:t.team, currentTeam:currentTeam, inherited:inherited, used:used} %} {% endfor %} -
    {% trans from 'general' %}contact{% endtrans %} {% trans from 'general' %}subscriptionDate{% endtrans %} {% trans from 'general' %}approved{% endtrans %}
    {{ t.kontakt.firma }} (id:{{ t.kontakt.id }}) {{ t.zeichnungsdatum|date('Y.m.d') }} {{ t.approved?'yes':'no' | trans( [], 'general') }}
    \ No newline at end of file + diff --git a/templates/datenweitergabe/edit.html.twig b/templates/datenweitergabe/edit.html.twig index 9b5e8f29..852a2c75 100644 --- a/templates/datenweitergabe/edit.html.twig +++ b/templates/datenweitergabe/edit.html.twig @@ -13,14 +13,19 @@ {% trans from 'general' %}pdf.createWithHistory{% endtrans %} - {{ include('base/__approveBtn.html.twig',{'data':daten,'dataLink':'datenweitergabe_approve'}) }} - {{ include('base/__disableBtn.html.twig',{'data':daten,'dataLink':'datenweitergabe_disable'}) }} + {% if isEditable %} + {{ include('base/__approveBtn.html.twig',{'data':daten,'dataLink':'datenweitergabe_approve'}) }} + {{ include('base/__disableBtn.html.twig',{'data':daten,'dataLink':'datenweitergabe_disable'}) }} + {% endif %} {{ include('base/__approvedBy.html.twig', {'data':daten}) }} {{ include('assign/__assign.html.twig',{'data':daten,'path':'assign_datenweitergabe'}) }} {% endif %} {% endblock %} {% block body %} + {% set inherited = transferInherited(daten) %} + {% set used = teamUsesTransfer(currentTeam, daten) %} + {% include 'base/__inheritanceInfo.html.twig' with {team:daten.team, currentTeam:currentTeam, used:used, inherited:inherited} %} {{ include('datenweitergabe/__form.html.twig') }}

    {% trans from 'general' %}createdAt{% endtrans %}: {{ daten.user.email }}

    {% if daten.previous %} @@ -29,4 +34,4 @@ {{ include('datenweitergabe/__history.html.twig', {'p':daten.previous}) }} {% endif %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/templates/datenweitergabe/index.html.twig b/templates/datenweitergabe/index.html.twig index 3d6831fc..3197bad9 100644 --- a/templates/datenweitergabe/index.html.twig +++ b/templates/datenweitergabe/index.html.twig @@ -3,7 +3,7 @@ {% set fullWidthLayout = true %} -{% block title %}{{ titel }}{% endblock %} +{% block title %}{{ title }}{% endblock %} {% block CTA %} diff --git a/templates/datenweitergabe/indexAuftragsverarbeitung.html.twig b/templates/datenweitergabe/indexAuftragsverarbeitung.html.twig index ef768f87..1955ab27 100644 --- a/templates/datenweitergabe/indexAuftragsverarbeitung.html.twig +++ b/templates/datenweitergabe/indexAuftragsverarbeitung.html.twig @@ -3,7 +3,7 @@ {% set fullWidthLayout = true %} -{% block title %}{{ titel }}{% endblock %} +{% block title %}{{ title }}{% endblock %} {% block CTA %} diff --git a/templates/dsfa/edit.html.twig b/templates/dsfa/edit.html.twig index d8fbb797..4bae7545 100644 --- a/templates/dsfa/edit.html.twig +++ b/templates/dsfa/edit.html.twig @@ -6,7 +6,7 @@ {% endblock %} {% block CTA %} - {% if assignForm is defined %}{{ include('assign/__assign.html.twig',{'data':dsfa,'path':'assign_dsfa'}) }}{% endif %} + {% if assignForm is defined and isEditable %}{{ include('assign/__assign.html.twig',{'data':dsfa,'path':'assign_dsfa'}) }}{% endif %} {% endblock %} {% block body %} @@ -35,4 +35,4 @@ {{ include('dsfa/__history.html.twig', {'p':dsfa.previous}) }} {% endif %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/templates/kontakt/edit.html.twig b/templates/kontakt/edit.html.twig index d75e5cb2..ad90b7e6 100644 --- a/templates/kontakt/edit.html.twig +++ b/templates/kontakt/edit.html.twig @@ -5,7 +5,7 @@ {% endblock %} {% block CTA %} - {% if new is not defined %} + {% if new is not defined and isEditable %} {{ include('base/__approveBtn.html.twig',{'data':kontakt,'dataLink':'kontakt_approve'}) }} {{ include('base/__disableBtn.html.twig',{'data':kontakt,'dataLink':'kontakt_disable'}) }} {% endif %} @@ -14,32 +14,35 @@ {% block body %} {{ include('base/__approvedBy.html.twig', {'data':kontakt}) }} + {% set inherited = contactInherited(kontakt) %} + {% set used = teamUsesContact(currentTeam, kontakt) %} + {% include 'base/__inheritanceInfo.html.twig' with {team:kontakt.team, currentTeam:currentTeam, used:used, inherited:inherited} %} - {{ form_start(form) }} -
    - {{ form_row(form.art) }} - {{ form_row(form.nummer) }} - {{ form_row(form.firma) }} -
    -
    - {{ form_row(form.anrede) }} - {{ form_row(form.vorname) }} - {{ form_row(form.nachname) }} -
    -
    - {{ form_row(form.strase) }} - {{ form_row(form.plz) }} - {{ form_row(form.ort) }} -
    -
    - {{ form_row(form.email) }} - {{ form_row(form.telefon) }} -
    -
    - {{ form_row(form.bemerkung) }} -
    - {{ form_row(form.save, {row_attr: {class: 'form-buttons'}}) }} - {{ form_end(form) }} + {{ form_start(form) }} +
    + {{ form_row(form.art) }} + {{ form_row(form.nummer) }} + {{ form_row(form.firma) }} +
    +
    + {{ form_row(form.anrede) }} + {{ form_row(form.vorname) }} + {{ form_row(form.nachname) }} +
    +
    + {{ form_row(form.strase) }} + {{ form_row(form.plz) }} + {{ form_row(form.ort) }} +
    +
    + {{ form_row(form.email) }} + {{ form_row(form.telefon) }} +
    +
    + {{ form_row(form.bemerkung) }} +
    + {{ form_row(form.save, {row_attr: {class: 'form-buttons'}}) }} + {{ form_end(form) }} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/templates/kontakt/index.html.twig b/templates/kontakt/index.html.twig index f0b85b64..88e25af6 100644 --- a/templates/kontakt/index.html.twig +++ b/templates/kontakt/index.html.twig @@ -20,6 +20,7 @@ {% trans from 'general' %}name{% endtrans %} {% trans %}location{% endtrans %} {% trans %}function{% endtrans %} + {% include 'base/__inheritanceTHeaders.html.twig' with {currentTeam:currentTeam} %} @@ -36,6 +37,9 @@ {% trans %}contractor{% endtrans %} {% endif %} + {% set inherited = contactInherited(k) %} + {% set used = teamUsesContact(currentTeam, k) %} + {% include 'base/__inheritanceTCols.html.twig' with {team:k.team, currentTeam:currentTeam, inherited:inherited, used:used} %} {% endfor %} diff --git a/templates/loeschkonzept/show.html.twig b/templates/loeschkonzept/show.html.twig index 3e7d9d22..76a23bf4 100644 --- a/templates/loeschkonzept/show.html.twig +++ b/templates/loeschkonzept/show.html.twig @@ -6,10 +6,12 @@ {% endblock %} {% block CTA %} -
    - {% trans from 'general' %}edit{% endtrans %} - - {{ include('loeschkonzept/_delete_form.html.twig') }} + {% if current_team == loeschkonzept.team %} + + {% trans from 'general' %}edit{% endtrans %} + + {{ include('loeschkonzept/_delete_form.html.twig') }} + {% endif %} {% endblock %} {% block body %} diff --git a/templates/policies/edit.html.twig b/templates/policies/edit.html.twig index 0a9e977e..ac14ca55 100644 --- a/templates/policies/edit.html.twig +++ b/templates/policies/edit.html.twig @@ -11,14 +11,21 @@ {% trans from 'general' %}pdf.createWithHistory{% endtrans %} - {{ include('base/__approveBtn.html.twig',{'data':policy,'dataLink':'policy_approve'}) }} - {{ include('base/__disableBtn.html.twig',{'data':policy,'dataLink':'policy_disable'}) }} - {{ include('assign/__assign.html.twig',{'data':policy,'path':'assign_policy'}) }} + {% if isEditable %} + {{ include('base/__approveBtn.html.twig',{'data':policy,'dataLink':'policy_approve'}) }} + {{ include('base/__disableBtn.html.twig',{'data':policy,'dataLink':'policy_disable'}) }} + {{ include('assign/__assign.html.twig',{'data':policy,'path':'assign_policy'}) }} + {% endif %} {% endif %} {% endblock %} {% block body %} {{ include('base/__approvedBy.html.twig', {'data':policy}) }} + + {% set inherited = policyInherited(policy) %} + {% set used = teamUsesPolicy(currentTeam, policy) %} + {% include 'base/__inheritanceInfo.html.twig' with {team:policy.team, currentTeam:currentTeam, used:used, inherited:inherited} %} + {{ include('policies/__form.html.twig') }}

    {% trans from 'general' %}createdBy{% endtrans %}: {{ policy.user.email }}

    {% if policy.previous %} @@ -28,4 +35,4 @@ {% endif %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/templates/policies/index.html.twig b/templates/policies/index.html.twig index 5fd586a1..8cadfb6a 100644 --- a/templates/policies/index.html.twig +++ b/templates/policies/index.html.twig @@ -22,6 +22,7 @@ {% trans %}scopes{% endtrans %} {% trans from 'general' %}processings{% endtrans %} {% trans from 'general' %}state{% endtrans %} + {% include 'base/__inheritanceTHeaders.html.twig' with {currentTeam:currentTeam} %} @@ -31,9 +32,15 @@ {{ d.title }} {{ d.scope|raw }} {% for p in d.processes | filter(p => p.activ) %}{{ p.name }}
    {% endfor %} - {% if d.approved %}{% trans from 'general' %}approved{% endtrans %}{% else %}{{ d.statusString }}{% endif %} + {% if d.approved %} + {% trans from 'general' %}approved{% endtrans %} + {% else %} + {{ d.statusString }} + {% endif %} + {% set inherited = policyInherited(d) %} + {% set used = teamUsesPolicy(currentTeam, d) %} + {% include 'base/__inheritanceTCols.html.twig' with {team:d.team, currentTeam:currentTeam, inherited:inherited, used:used} %} {% endfor %} diff --git a/templates/software/edit.html.twig b/templates/software/edit.html.twig index bb1cbb5e..e99d01dc 100644 --- a/templates/software/edit.html.twig +++ b/templates/software/edit.html.twig @@ -13,25 +13,69 @@ {% trans from 'general' %}pdf.createWithHistory{% endtrans %} - {{ include('base/__approveBtn.html.twig',{'data':software,'dataLink':'software_approve'}) }} - {{ include('assign/__assign.html.twig',{'data':software,'path':'assign_software'}) }} + {% if isEditable %} + {{ include('base/__approveBtn.html.twig',{'data':software,'dataLink':'software_approve'}) }} + {{ include('assign/__assign.html.twig',{'data':software,'path':'assign_software'}) }} + {% endif %} {% endif %} {% endblock %} {% block body %} - {{ include('base/__approvedBy.html.twig', {'data':software}) }} -
    -
    +
    +

    {% trans %}software.baseData{% endtrans %}

    {{ include('software/__form.html.twig') }}

    {% trans from 'general' %}createdBy{% endtrans %}: {{ software.user.email }}

    -
    +

    {% trans %}config.attached{% endtrans %}

    {{ include('software/__config.html.twig') }}
    +
    + {% set inherited = softwareInherited(software) %} + {% set used = teamUsesSoftware(currentTeam, software) %} + {% include 'base/__inheritanceInfo.html.twig' with {team:software.team, currentTeam:currentTeam, used:used, inherited:inherited} %} +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + {{ include('software/__form.html.twig') }} +

    {% trans from 'general' %}createdBy{% endtrans %}: {{ software.user.email }}

    +
    +
    +
    + {% if isEditable %} +
    +
    +
    + +
    +
    +
    +
    + {{ include('software/__config.html.twig') }} +
    +
    +
    + {% endif %}
    {% if software.previous %} @@ -43,4 +87,4 @@ -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/templates/software/index.html.twig b/templates/software/index.html.twig index f0d44815..554e5d5c 100644 --- a/templates/software/index.html.twig +++ b/templates/software/index.html.twig @@ -26,6 +26,7 @@ {% trans %}licence.word{% endtrans %} {% trans %}expiration.date{% endtrans %} {% trans from 'general' %}state{% endtrans %} + {% include 'base/__inheritanceTHeaders.html.twig' with {currentTeam:currentTeam} %} @@ -50,9 +51,11 @@ {{ d.statusString }} {% endif %} + {% set inherited = softwareInherited(d) %} + {% set used = teamUsesSoftware(currentTeam, d) %} + {% include 'base/__inheritanceTCols.html.twig' with {team:d.team, currentTeam:currentTeam, inherited:inherited, used:used} %} {% endfor %} - {% endblock %} diff --git a/templates/team/__togglePresetIgnore.html.twig b/templates/team/__togglePresetIgnore.html.twig new file mode 100644 index 00000000..3d8193c0 --- /dev/null +++ b/templates/team/__togglePresetIgnore.html.twig @@ -0,0 +1,12 @@ +{% trans_default_domain 'vvt' %} + +{% set used = team not in preset.ignoredInTeams %} +
    + +
    diff --git a/templates/team/custom.html.twig b/templates/team/custom.html.twig index eb0ef000..df2f8ea7 100644 --- a/templates/team/custom.html.twig +++ b/templates/team/custom.html.twig @@ -31,42 +31,63 @@
  • - {{ d.name }}{% if not d.default %} + + {{ d.name }} + + {% if d.default %} + + ({% trans %}default{% endtrans %}) + + {% elseif d.object.inherited %} + + {% if currentTeam == d.object.team %} + ({% trans from 'general' %}inheritance.isInherited{% endtrans %}) + {% else %} + ({% trans from 'general' %}inheritance.fromTeam{% endtrans %} {{ d.object.team }}) + {% endif %} + + {% endif %}

    -
    - - {% trans from 'general' %}edit{% endtrans %} - - - {% if checkClass(d.object,'App\\Entity\\VVTStatus') %} - - {% if d.object.network %} - {% trans from 'general' %}network.show.remove{% endtrans %} - {% else %} - {% trans from 'general' %}network.show.add{% endtrans %} - {% endif %} - - {% endif %} + {% if not d.default %} + + {% if checkClass(d.object,'App\\Entity\\DatenweitergabeStand') %} + + {% if d.object.network %} + {% trans from 'general' %}network.show.remove{% endtrans %} + {% else %} + {% trans from 'general' %}network.show.add{% endtrans %} + {% endif %} + + {% endif %} + {% if currentTeam == d.object.team %} + + {% trans from 'general' %}delete{% endtrans %} + + {% else %} + {{ include('team/__togglePresetIgnore.html.twig',{'preset':d.object,'team':currentTeam}) }} + {% endif %} +
    + {% endif %}
  • {% endfor %} diff --git a/templates/team/manage.html.twig b/templates/team/manage.html.twig index fc738c56..1b0a9e72 100644 --- a/templates/team/manage.html.twig +++ b/templates/team/manage.html.twig @@ -19,9 +19,10 @@ {% if useKeycloakGroups %} {% trans %}keycloakGroup{% endtrans %} {% endif %} + {% trans %}parentTeam{% endtrans %} {% trans %}memberCount{% endtrans %} {% trans %}admins{% endtrans %} - + @@ -31,13 +32,14 @@ {% if useKeycloakGroups %} {{ t.keycloakGroup }} {% endif %} + {{ t.parent }} {{ t.members | length }} {% for a in t.admins %} {{ a.firstName }} {{ a.lastName }} ({{ a.email }})
    {% endfor %} - + {% trans %}team.manageData{% endtrans %} diff --git a/templates/team/member.html.twig b/templates/team/member.html.twig index 38f4ecec..928465e6 100644 --- a/templates/team/member.html.twig +++ b/templates/team/member.html.twig @@ -126,4 +126,5 @@
    + {% endblock %} diff --git a/templates/team/modalView.html.twig b/templates/team/modalView.html.twig index f16fb5ae..b1543b37 100644 --- a/templates/team/modalView.html.twig +++ b/templates/team/modalView.html.twig @@ -2,6 +2,9 @@