diff --git a/assets/css/app.css b/assets/css/app.css
index 7d624435..296d0bd5 100644
--- a/assets/css/app.css
+++ b/assets/css/app.css
@@ -811,7 +811,7 @@ div.dataTables_wrapper div.dataTables_info {
padding: 10px 10px;
margin: 0 0 10px;
font-size: 17.5px;
- border-left: 5px solid #eee;
+ border-left: 5px solid #aaa;
}
.darkmode-layer {
diff --git a/assets/js/app.js b/assets/js/app.js
index 24f55eef..73d6b603 100644
--- a/assets/js/app.js
+++ b/assets/js/app.js
@@ -91,6 +91,11 @@ require('./jquery.tristate.js');
require('darkmode-js');
+//Equation rendering
+require('katex');
+window.renderMathInElement = require('katex/contrib/auto-render/auto-render').default;
+import 'katex/dist/katex.css';
+
window.ClipboardJS = require('clipboard');
window.QRCode = require('qrcode');
diff --git a/assets/ts_src/event_listeners.ts b/assets/ts_src/event_listeners.ts
index 503ac074..99a0a032 100644
--- a/assets/ts_src/event_listeners.ts
+++ b/assets/ts_src/event_listeners.ts
@@ -465,6 +465,19 @@ $(document).on("ajaxUI:start", function () {
//Bootstrapify objects
$('table', this).addClass('table table-hover table-striped table-bordered');
});
+
+ //Latex rendering have to be done after markdown parsing
+ $('.latex').each(function(index, element) {
+ //@ts-ignore
+ window.renderMathInElement(element, {
+ delimiters: [
+ {left: "$$", right: "$$", display: true},
+ {left: "$", right: "$", display: false},
+ {left: "\\(", right: "\\)", display: false},
+ {left: "\\[", right: "\\]", display: true}
+ ]
+ });
+ });
}
//Configure markdown
@@ -552,6 +565,7 @@ $(document).on("ajaxUI:reload", function() {
})
});
+
//Need for proper body padding, with every navbar height
$(window).resize(function () {
let height : number = $('#navbar').height() + 10;
diff --git a/composer.json b/composer.json
index 52e3969c..fe3f211a 100644
--- a/composer.json
+++ b/composer.json
@@ -69,7 +69,7 @@
"symfony/maker-bundle": "^1.13",
"symfony/profiler-pack": "*",
"symfony/test-pack": "^1.0",
- "symplify/easy-coding-standard": "^7.1",
+ "symplify/easy-coding-standard": "7.2.3",
"vimeo/psalm": "^3.5"
},
"config": {
@@ -91,14 +91,6 @@
"App\\Tests\\": "tests/"
}
},
- "replace": {
- "paragonie/random_compat": "2.*",
- "symfony/polyfill-ctype": "*",
- "symfony/polyfill-iconv": "*",
- "symfony/polyfill-php71": "*",
- "symfony/polyfill-php70": "*",
- "symfony/polyfill-php56": "*"
- },
"scripts": {
"auto-scripts": {
"cache:clear": "symfony-cmd",
diff --git a/composer.lock b/composer.lock
index f6cf156e..352ce45c 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "6ebc8e9705e901be6f00f9f6418cf900",
+ "content-hash": "fd11975fb4135f47bdb119fec531a868",
"packages": [
{
"name": "beberlei/assert",
@@ -1022,16 +1022,16 @@
},
{
"name": "doctrine/orm",
- "version": "v2.7.1",
+ "version": "v2.7.2",
"source": {
"type": "git",
"url": "https://github.com/doctrine/orm.git",
- "reference": "445796af0e873d9bd04f2502d322a7d5009b6846"
+ "reference": "dafe298ce5d0b995ebe1746670704c0a35868a6a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/orm/zipball/445796af0e873d9bd04f2502d322a7d5009b6846",
- "reference": "445796af0e873d9bd04f2502d322a7d5009b6846",
+ "url": "https://api.github.com/repos/doctrine/orm/zipball/dafe298ce5d0b995ebe1746670704c0a35868a6a",
+ "reference": "dafe298ce5d0b995ebe1746670704c0a35868a6a",
"shasum": ""
},
"require": {
@@ -1102,20 +1102,20 @@
"database",
"orm"
],
- "time": "2020-02-15T14:35:56+00:00"
+ "time": "2020-03-19T06:41:02+00:00"
},
{
"name": "doctrine/persistence",
- "version": "1.3.6",
+ "version": "1.3.7",
"source": {
"type": "git",
"url": "https://github.com/doctrine/persistence.git",
- "reference": "5dd3ac5eebef2d0b074daa4440bb18f93132dee4"
+ "reference": "0af483f91bada1c9ded6c2cfd26ab7d5ab2094e0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/persistence/zipball/5dd3ac5eebef2d0b074daa4440bb18f93132dee4",
- "reference": "5dd3ac5eebef2d0b074daa4440bb18f93132dee4",
+ "url": "https://api.github.com/repos/doctrine/persistence/zipball/0af483f91bada1c9ded6c2cfd26ab7d5ab2094e0",
+ "reference": "0af483f91bada1c9ded6c2cfd26ab7d5ab2094e0",
"shasum": ""
},
"require": {
@@ -1123,7 +1123,7 @@
"doctrine/cache": "^1.0",
"doctrine/collections": "^1.0",
"doctrine/event-manager": "^1.0",
- "doctrine/reflection": "^1.1",
+ "doctrine/reflection": "^1.2",
"php": "^7.1"
},
"conflict": {
@@ -1185,20 +1185,20 @@
"orm",
"persistence"
],
- "time": "2020-01-16T22:06:23+00:00"
+ "time": "2020-03-21T15:13:52+00:00"
},
{
"name": "doctrine/reflection",
- "version": "v1.1.0",
+ "version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/reflection.git",
- "reference": "bc420ead87fdfe08c03ecc3549db603a45b06d4c"
+ "reference": "b699ecc7f2784d1e49924fd9858cf1078db6b0e2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/reflection/zipball/bc420ead87fdfe08c03ecc3549db603a45b06d4c",
- "reference": "bc420ead87fdfe08c03ecc3549db603a45b06d4c",
+ "url": "https://api.github.com/repos/doctrine/reflection/zipball/b699ecc7f2784d1e49924fd9858cf1078db6b0e2",
+ "reference": "b699ecc7f2784d1e49924fd9858cf1078db6b0e2",
"shasum": ""
},
"require": {
@@ -1219,7 +1219,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-master": "1.2.x-dev"
}
},
"autoload": {
@@ -1263,7 +1263,7 @@
"reflection",
"static"
],
- "time": "2020-01-08T19:53:19+00:00"
+ "time": "2020-03-21T11:34:59+00:00"
},
{
"name": "egulias/email-validator",
@@ -2573,6 +2573,51 @@
],
"time": "2019-11-06T19:20:29+00:00"
},
+ {
+ "name": "paragonie/random_compat",
+ "version": "v9.99.99",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/paragonie/random_compat.git",
+ "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95",
+ "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*|5.*",
+ "vimeo/psalm": "^1"
+ },
+ "suggest": {
+ "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
+ },
+ "type": "library",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com"
+ }
+ ],
+ "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
+ "keywords": [
+ "csprng",
+ "polyfill",
+ "pseudorandom",
+ "random"
+ ],
+ "time": "2018-07-02T15:55:56+00:00"
+ },
{
"name": "php-http/discovery",
"version": "1.7.4",
@@ -3459,16 +3504,16 @@
},
{
"name": "psr/log",
- "version": "1.1.2",
+ "version": "1.1.3",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
- "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801"
+ "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/log/zipball/446d54b4cb6bf489fc9d75f55843658e6f25d801",
- "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc",
+ "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc",
"shasum": ""
},
"require": {
@@ -3502,7 +3547,7 @@
"psr",
"psr-3"
],
- "time": "2019-11-01T11:05:21+00:00"
+ "time": "2020-03-23T09:12:05+00:00"
},
{
"name": "psr/simple-cache",
@@ -6143,6 +6188,64 @@
"description": "A pack for the Doctrine ORM",
"time": "2020-02-10T18:03:48+00:00"
},
+ {
+ "name": "symfony/polyfill-ctype",
+ "version": "v1.14.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-ctype.git",
+ "reference": "fbdeaec0df06cf3d51c93de80c7eb76e271f5a38"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/fbdeaec0df06cf3d51c93de80c7eb76e271f5a38",
+ "reference": "fbdeaec0df06cf3d51c93de80c7eb76e271f5a38",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.14-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Ctype\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Gert de Pagter",
+ "email": "BackEndTea@gmail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for ctype functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "ctype",
+ "polyfill",
+ "portable"
+ ],
+ "time": "2020-01-13T11:15:53+00:00"
+ },
{
"name": "symfony/polyfill-intl-icu",
"version": "v1.14.0",
@@ -8044,16 +8147,16 @@
},
{
"name": "thecodingmachine/safe",
- "version": "v1.0.3",
+ "version": "v1.1",
"source": {
"type": "git",
"url": "https://github.com/thecodingmachine/safe.git",
- "reference": "6662d0bef91fe5d44178cb2c38d51c5d16b65d23"
+ "reference": "f440677bad66c0ef42fa3f875bf05718028af5d3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thecodingmachine/safe/zipball/6662d0bef91fe5d44178cb2c38d51c5d16b65d23",
- "reference": "6662d0bef91fe5d44178cb2c38d51c5d16b65d23",
+ "url": "https://api.github.com/repos/thecodingmachine/safe/zipball/f440677bad66c0ef42fa3f875bf05718028af5d3",
+ "reference": "f440677bad66c0ef42fa3f875bf05718028af5d3",
"shasum": ""
},
"require": {
@@ -8172,7 +8275,7 @@
"MIT"
],
"description": "PHP core functions that throw exceptions instead of returning FALSE on error",
- "time": "2020-01-20T08:44:36+00:00"
+ "time": "2020-03-24T13:59:42+00:00"
},
{
"name": "tijsverkoyen/css-to-inline-styles",
@@ -10190,16 +10293,16 @@
},
{
"name": "phpstan/phpstan",
- "version": "0.12.14",
+ "version": "0.12.18",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
- "reference": "37bdd26a80235d0f9045b49f4151102b7831cbe2"
+ "reference": "1ce27fe29c8660a27926127d350d53d80c4d4286"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpstan/zipball/37bdd26a80235d0f9045b49f4151102b7831cbe2",
- "reference": "37bdd26a80235d0f9045b49f4151102b7831cbe2",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/1ce27fe29c8660a27926127d350d53d80c4d4286",
+ "reference": "1ce27fe29c8660a27926127d350d53d80c4d4286",
"shasum": ""
},
"require": {
@@ -10225,7 +10328,7 @@
"MIT"
],
"description": "PHPStan - PHP Static Analysis Tool",
- "time": "2020-03-02T22:29:43+00:00"
+ "time": "2020-03-22T16:51:47+00:00"
},
{
"name": "phpstan/phpstan-doctrine",
@@ -11245,16 +11348,16 @@
},
{
"name": "symplify/auto-bind-parameter",
- "version": "v7.2.4",
+ "version": "v7.2.8",
"source": {
"type": "git",
"url": "https://github.com/symplify/auto-bind-parameter.git",
- "reference": "ff9c5b60aba14f5a91449684f28a52e4411181c3"
+ "reference": "8b85fc72fddc953feda56c3d06252eb1fafb21ef"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symplify/auto-bind-parameter/zipball/ff9c5b60aba14f5a91449684f28a52e4411181c3",
- "reference": "ff9c5b60aba14f5a91449684f28a52e4411181c3",
+ "url": "https://api.github.com/repos/symplify/auto-bind-parameter/zipball/8b85fc72fddc953feda56c3d06252eb1fafb21ef",
+ "reference": "8b85fc72fddc953feda56c3d06252eb1fafb21ef",
"shasum": ""
},
"require": {
@@ -11262,7 +11365,7 @@
"php": "^7.2",
"symfony/dependency-injection": "^4.4|^5.0",
"symfony/http-kernel": "^4.4|^5.0",
- "symplify/package-builder": "^7.2.4"
+ "symplify/package-builder": "^7.2.8"
},
"require-dev": {
"phpunit/phpunit": "^8.5|^9.0"
@@ -11283,20 +11386,20 @@
"MIT"
],
"description": "Auto bind parameters for your Symfony applications",
- "time": "2020-03-12T09:43:53+00:00"
+ "time": "2020-03-18T23:25:54+00:00"
},
{
"name": "symplify/autowire-array-parameter",
- "version": "v7.2.4",
+ "version": "v7.2.8",
"source": {
"type": "git",
"url": "https://github.com/symplify/autowire-array-parameter.git",
- "reference": "3acb60ed2aa469a222f39dd79fcc12d64e30b6d5"
+ "reference": "53ae1541e9eca16bd5bae95d627a442092933585"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symplify/autowire-array-parameter/zipball/3acb60ed2aa469a222f39dd79fcc12d64e30b6d5",
- "reference": "3acb60ed2aa469a222f39dd79fcc12d64e30b6d5",
+ "url": "https://api.github.com/repos/symplify/autowire-array-parameter/zipball/53ae1541e9eca16bd5bae95d627a442092933585",
+ "reference": "53ae1541e9eca16bd5bae95d627a442092933585",
"shasum": ""
},
"require": {
@@ -11304,7 +11407,7 @@
"nette/utils": "^3.0",
"php": "^7.2",
"symfony/dependency-injection": "^4.4|^5.0",
- "symplify/package-builder": "^7.2.4"
+ "symplify/package-builder": "^7.2.8"
},
"require-dev": {
"phpunit/phpunit": "^8.5|^9.0"
@@ -11325,20 +11428,20 @@
"MIT"
],
"description": "Autowire array parameters for your Symfony applications",
- "time": "2020-03-12T09:43:53+00:00"
+ "time": "2020-03-18T23:25:54+00:00"
},
{
"name": "symplify/coding-standard",
- "version": "v7.2.4",
+ "version": "v7.2.8",
"source": {
"type": "git",
"url": "https://github.com/symplify/coding-standard.git",
- "reference": "9e994e7309cc8f1c80467eb91512538bc938b28a"
+ "reference": "084c7ba3b6cc62f8a271da3a4192f663bc12ff2e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symplify/coding-standard/zipball/9e994e7309cc8f1c80467eb91512538bc938b28a",
- "reference": "9e994e7309cc8f1c80467eb91512538bc938b28a",
+ "url": "https://api.github.com/repos/symplify/coding-standard/zipball/084c7ba3b6cc62f8a271da3a4192f663bc12ff2e",
+ "reference": "084c7ba3b6cc62f8a271da3a4192f663bc12ff2e",
"shasum": ""
},
"require": {
@@ -11348,15 +11451,15 @@
"php": "^7.2",
"phpstan/phpdoc-parser": "^0.4",
"squizlabs/php_codesniffer": "^3.5",
- "symplify/autowire-array-parameter": "^7.2.4",
- "symplify/package-builder": "^7.2.4",
- "symplify/smart-file-system": "^7.2.4"
+ "symplify/autowire-array-parameter": "^7.2.8",
+ "symplify/package-builder": "^7.2.8",
+ "symplify/smart-file-system": "^7.2.8"
},
"require-dev": {
"nette/application": "^3.0",
"phpunit/phpunit": "^8.5|^9.0",
- "symplify/easy-coding-standard-tester": "^7.2.4",
- "symplify/package-builder": "^7.2.4"
+ "symplify/easy-coding-standard-tester": "^7.2.8",
+ "symplify/package-builder": "^7.2.8"
},
"type": "library",
"extra": {
@@ -11375,20 +11478,20 @@
"MIT"
],
"description": "Set of Symplify rules for PHP_CodeSniffer and PHP CS Fixer.",
- "time": "2020-03-12T09:43:53+00:00"
+ "time": "2020-03-18T23:25:54+00:00"
},
{
"name": "symplify/easy-coding-standard",
- "version": "v7.2.0",
+ "version": "v7.2.3",
"source": {
"type": "git",
- "url": "https://github.com/Symplify/EasyCodingStandard.git",
- "reference": "efa1b57dd454af4d250d8ecd5aacca19a174a3ed"
+ "url": "https://github.com/symplify/easy-coding-standard.git",
+ "reference": "9dfbfc09994310ca43cec24ca86044aae7a5fe47"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Symplify/EasyCodingStandard/zipball/efa1b57dd454af4d250d8ecd5aacca19a174a3ed",
- "reference": "efa1b57dd454af4d250d8ecd5aacca19a174a3ed",
+ "url": "https://api.github.com/repos/symplify/easy-coding-standard/zipball/9dfbfc09994310ca43cec24ca86044aae7a5fe47",
+ "reference": "9dfbfc09994310ca43cec24ca86044aae7a5fe47",
"shasum": ""
},
"require": {
@@ -11409,16 +11512,19 @@
"symfony/finder": "^4.4|^5.0",
"symfony/http-kernel": "^4.4|^5.0",
"symfony/yaml": "^4.4|^5.0",
- "symplify/auto-bind-parameter": "^7.2",
- "symplify/autowire-array-parameter": "^7.2",
- "symplify/coding-standard": "^7.2",
- "symplify/package-builder": "^7.2",
- "symplify/set-config-resolver": "^7.2",
- "symplify/smart-file-system": "^7.2"
+ "symplify/auto-bind-parameter": "^7.2.3",
+ "symplify/autowire-array-parameter": "^7.2.3",
+ "symplify/coding-standard": "^7.2.3",
+ "symplify/package-builder": "^7.2.3",
+ "symplify/set-config-resolver": "^7.2.3",
+ "symplify/smart-file-system": "^7.2.3"
+ },
+ "replace": {
+ "symfony/polyfill-php70": "*"
},
"require-dev": {
- "phpunit/phpunit": "^8.4",
- "symplify/easy-coding-standard-tester": "^7.2"
+ "phpunit/phpunit": "^8.5|^9.0",
+ "symplify/easy-coding-standard-tester": "^7.2.3"
},
"bin": [
"bin/ecs"
@@ -11426,16 +11532,16 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "7.2-dev"
+ "dev-master": "7.3-dev"
}
},
"autoload": {
"psr-4": {
"Symplify\\EasyCodingStandard\\": "src",
- "Symplify\\EasyCodingStandard\\ChangedFilesDetector\\": "packages/ChangedFilesDetector/src",
- "Symplify\\EasyCodingStandard\\Configuration\\": "packages/Configuration/src",
- "Symplify\\EasyCodingStandard\\FixerRunner\\": "packages/FixerRunner/src",
- "Symplify\\EasyCodingStandard\\SniffRunner\\": "packages/SniffRunner/src"
+ "Symplify\\EasyCodingStandard\\ChangedFilesDetector\\": "packages/changed-files-detector/src",
+ "Symplify\\EasyCodingStandard\\Configuration\\": "packages/configuration/src",
+ "Symplify\\EasyCodingStandard\\FixerRunner\\": "packages/fixer-runner/src",
+ "Symplify\\EasyCodingStandard\\SniffRunner\\": "packages/sniff-runner/src"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -11443,20 +11549,20 @@
"MIT"
],
"description": "Use Coding Standard with 0-knowledge of PHP-CS-Fixer and PHP_CodeSniffer.",
- "time": "2020-01-05T09:25:47+00:00"
+ "time": "2020-02-27T16:45:59+00:00"
},
{
"name": "symplify/package-builder",
- "version": "v7.2.4",
+ "version": "v7.2.8",
"source": {
"type": "git",
"url": "https://github.com/symplify/package-builder.git",
- "reference": "819df91cdc61e901429746656acec37ef1f38aac"
+ "reference": "9d9b5f8f07058aaeb59ba53bfae52226b3b47236"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symplify/package-builder/zipball/819df91cdc61e901429746656acec37ef1f38aac",
- "reference": "819df91cdc61e901429746656acec37ef1f38aac",
+ "url": "https://api.github.com/repos/symplify/package-builder/zipball/9d9b5f8f07058aaeb59ba53bfae52226b3b47236",
+ "reference": "9d9b5f8f07058aaeb59ba53bfae52226b3b47236",
"shasum": ""
},
"require": {
@@ -11489,20 +11595,20 @@
"MIT"
],
"description": "Dependency Injection, Console and Kernel toolkit for Symplify packages.",
- "time": "2020-03-12T09:04:14+00:00"
+ "time": "2020-03-18T23:14:48+00:00"
},
{
"name": "symplify/set-config-resolver",
- "version": "v7.2.4",
+ "version": "v7.2.8",
"source": {
"type": "git",
"url": "https://github.com/symplify/set-config-resolver.git",
- "reference": "04b48cead95bf20d4091b44b71dbb346d70c8e90"
+ "reference": "561486147349cb07b5692708748ece68c31bf041"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symplify/set-config-resolver/zipball/04b48cead95bf20d4091b44b71dbb346d70c8e90",
- "reference": "04b48cead95bf20d4091b44b71dbb346d70c8e90",
+ "url": "https://api.github.com/repos/symplify/set-config-resolver/zipball/561486147349cb07b5692708748ece68c31bf041",
+ "reference": "561486147349cb07b5692708748ece68c31bf041",
"shasum": ""
},
"require": {
@@ -11511,7 +11617,7 @@
"symfony/console": "^4.4|^5.0",
"symfony/filesystem": "^4.4|^5.0",
"symfony/finder": "^4.4|^5.0",
- "symplify/smart-file-system": "^7.2.4"
+ "symplify/smart-file-system": "^7.2.8"
},
"require-dev": {
"phpunit/phpunit": "^8.5|^9.0"
@@ -11532,20 +11638,20 @@
"MIT"
],
"description": "Resolve config and sets from configs and cli opptions for CLI applications",
- "time": "2020-03-12T09:43:53+00:00"
+ "time": "2020-03-18T23:25:54+00:00"
},
{
"name": "symplify/smart-file-system",
- "version": "v7.2.4",
+ "version": "v7.2.8",
"source": {
"type": "git",
"url": "https://github.com/symplify/smart-file-system.git",
- "reference": "5e0fa2a90bae6174bc2de2f8a40ab216b0e38e50"
+ "reference": "9f6320c3b22c81e85f51aabf66c927bbf4d8c20f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symplify/smart-file-system/zipball/5e0fa2a90bae6174bc2de2f8a40ab216b0e38e50",
- "reference": "5e0fa2a90bae6174bc2de2f8a40ab216b0e38e50",
+ "url": "https://api.github.com/repos/symplify/smart-file-system/zipball/9f6320c3b22c81e85f51aabf66c927bbf4d8c20f",
+ "reference": "9f6320c3b22c81e85f51aabf66c927bbf4d8c20f",
"shasum": ""
},
"require": {
@@ -11575,20 +11681,20 @@
"MIT"
],
"description": "Sanitized FileInfo with safe getRealPath() and other handy methods",
- "time": "2020-03-02T16:35:33+00:00"
+ "time": "2020-03-18T23:14:48+00:00"
},
{
"name": "vimeo/psalm",
- "version": "3.9.5",
+ "version": "3.10.1",
"source": {
"type": "git",
"url": "https://github.com/vimeo/psalm.git",
- "reference": "0cfe565d0afbcd31eadcc281b9017b5692911661"
+ "reference": "eeed5ecccc10131397f0eb7ee6da810c0be3a7fc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/vimeo/psalm/zipball/0cfe565d0afbcd31eadcc281b9017b5692911661",
- "reference": "0cfe565d0afbcd31eadcc281b9017b5692911661",
+ "url": "https://api.github.com/repos/vimeo/psalm/zipball/eeed5ecccc10131397f0eb7ee6da810c0be3a7fc",
+ "reference": "eeed5ecccc10131397f0eb7ee6da810c0be3a7fc",
"shasum": ""
},
"require": {
@@ -11671,7 +11777,7 @@
"inspection",
"php"
],
- "time": "2020-03-09T22:59:56+00:00"
+ "time": "2020-03-23T11:40:30+00:00"
},
{
"name": "webmozart/glob",
diff --git a/config/banner.md b/config/banner.md
index 74b1d526..997ca15e 100644
--- a/config/banner.md
+++ b/config/banner.md
@@ -1,3 +1,14 @@
Welcome to Part-DB.
-If you want to change this banner, edit `config/banner.md` file or set the `BANNER` environment variable.
\ No newline at end of file
+If you want to change this banner, edit `config/banner.md` file or set the `BANNER` environment variable.
+
+
';
$tmp .= sprintf(
@@ -90,4 +88,4 @@ class RevertLogColumn extends AbstractColumn
return $tmp;
}
-}
\ No newline at end of file
+}
diff --git a/src/DataTables/LogDataTable.php b/src/DataTables/LogDataTable.php
index 9ae2b8db..53d15a6c 100644
--- a/src/DataTables/LogDataTable.php
+++ b/src/DataTables/LogDataTable.php
@@ -70,7 +70,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;
-use Symfony\Flex\Options;
class LogDataTable implements DataTableTypeInterface
{
@@ -92,12 +91,12 @@ class LogDataTable implements DataTableTypeInterface
$this->security = $security;
}
- public function configureOptions(OptionsResolver $optionsResolver)
+ public function configureOptions(OptionsResolver $optionsResolver): void
{
$optionsResolver->setDefaults([
- 'mode' => 'system_log',
- 'filter_elements' => [],
- ]);
+ 'mode' => 'system_log',
+ 'filter_elements' => [],
+ ]);
$optionsResolver->setAllowedValues('mode', ['system_log', 'element_history', 'last_activity']);
}
@@ -108,7 +107,6 @@ class LogDataTable implements DataTableTypeInterface
$this->configureOptions($resolver);
$options = $resolver->resolve($options);
-
$dataTable->add('symbol', TextColumn::class, [
'label' => '',
'render' => function ($value, AbstractLogEntry $context) {
@@ -179,7 +177,7 @@ class LogDataTable implements DataTableTypeInterface
$dataTable->add('level', TextColumn::class, [
'label' => $this->translator->trans('log.level'),
- 'visible' => $options['mode'] === 'system_log',
+ 'visible' => 'system_log' === $options['mode'],
'propertyPath' => 'levelString',
'render' => function (string $value, AbstractLogEntry $context) {
return $value;
@@ -220,7 +218,7 @@ class LogDataTable implements DataTableTypeInterface
'label' => $this->translator->trans('log.extra'),
]);
- $dataTable->add('timeTravel', IconLinkColumn::class,[
+ $dataTable->add('timeTravel', IconLinkColumn::class, [
'label' => '',
'icon' => 'fas fa-fw fa-eye',
'href' => function ($value, AbstractLogEntry $context) {
@@ -231,26 +229,25 @@ class LogDataTable implements DataTableTypeInterface
) {
try {
$target = $this->logRepo->getTargetElement($context);
- if($target !== null) {
- $str = $this->entityURLGenerator->timeTravelURL($target, $context->getTimestamp());
- return $str;
+ if (null !== $target) {
+ return $this->entityURLGenerator->timeTravelURL($target, $context->getTimestamp());
}
} catch (EntityNotSupportedException $exception) {
return null;
}
}
+
return null;
},
'disabled' => function ($value, AbstractLogEntry $context) {
return
- !$this->security->isGranted('@tools.timetravel')
- || !$this->security->isGranted('show_history', $context->getTargetClass());
- }
-
+ ! $this->security->isGranted('@tools.timetravel')
+ || ! $this->security->isGranted('show_history', $context->getTargetClass());
+ },
]);
$dataTable->add('actionRevert', RevertLogColumn::class, [
- 'label' => ''
+ 'label' => '',
]);
$dataTable->addOrderBy('timestamp', DataTable::SORT_DESCENDING);
@@ -270,12 +267,12 @@ class LogDataTable implements DataTableTypeInterface
->from(AbstractLogEntry::class, 'log')
->leftJoin('log.user', 'user');
- if ($options['mode'] === 'last_activity') {
- $builder->where('log INSTANCE OF ' . ElementCreatedLogEntry::class)
- ->orWhere('log INSTANCE OF ' . ElementDeletedLogEntry::class)
- ->orWhere('log INSTANCE OF ' . ElementEditedLogEntry::class)
- ->orWhere('log INSTANCE OF ' . CollectionElementDeleted::class)
- ->andWhere('log.target_type NOT IN (:disallowed)');;
+ if ('last_activity' === $options['mode']) {
+ $builder->where('log INSTANCE OF '.ElementCreatedLogEntry::class)
+ ->orWhere('log INSTANCE OF '.ElementDeletedLogEntry::class)
+ ->orWhere('log INSTANCE OF '.ElementEditedLogEntry::class)
+ ->orWhere('log INSTANCE OF '.CollectionElementDeleted::class)
+ ->andWhere('log.target_type NOT IN (:disallowed)');
$builder->setParameter('disallowed', [
AbstractLogEntry::targetTypeClassToID(User::class),
@@ -283,13 +280,13 @@ class LogDataTable implements DataTableTypeInterface
]);
}
- if (!empty($options['filter_elements'])) {
+ if (! empty($options['filter_elements'])) {
foreach ($options['filter_elements'] as $element) {
/** @var AbstractDBElement $element */
$target_type = AbstractLogEntry::targetTypeClassToID(get_class($element));
$target_id = $element->getID();
- $builder->orWhere("log.target_type = $target_type AND log.target_id = $target_id");
+ $builder->orWhere("log.target_type = ${target_type} AND log.target_id = ${target_id}");
}
}
}
diff --git a/src/DataTables/PartsDataTable.php b/src/DataTables/PartsDataTable.php
index 01751d2f..34dc669e 100644
--- a/src/DataTables/PartsDataTable.php
+++ b/src/DataTables/PartsDataTable.php
@@ -93,17 +93,17 @@ final class PartsDataTable implements DataTableTypeInterface
$this->attachmentURLGenerator = $attachmentURLGenerator;
}
- public function configureOptions(OptionsResolver $optionsResolver)
+ public function configureOptions(OptionsResolver $optionsResolver): void
{
$optionsResolver->setDefaults([
- 'category' => null,
- 'footprint' => null,
- 'manufacturer' => null,
- 'storelocation' => null,
- 'supplier' => null,
- 'tag' => null,
- 'search' => null,
- ]);
+ 'category' => null,
+ 'footprint' => null,
+ 'manufacturer' => null,
+ 'storelocation' => null,
+ 'supplier' => null,
+ 'tag' => null,
+ 'search' => null,
+ ]);
$optionsResolver->setAllowedTypes('category', ['null', Category::class]);
$optionsResolver->setAllowedTypes('footprint', ['null', Footprint::class]);
@@ -113,20 +113,20 @@ final class PartsDataTable implements DataTableTypeInterface
$optionsResolver->setAllowedTypes('search', ['null', 'string']);
//Configure search options
- $optionsResolver->setDefault('search_options', function (OptionsResolver $resolver) {
+ $optionsResolver->setDefault('search_options', function (OptionsResolver $resolver): void {
$resolver->setDefaults([
- 'name' => true,
- 'category' => true,
- 'description' => true,
- 'store_location' => true,
- 'comment' => true,
- 'ordernr' => true,
- 'supplier' => false,
- 'manufacturer' => false,
- 'footprint' => false,
- 'tags' => false,
- 'regex' => false,
- ]);
+ 'name' => true,
+ 'category' => true,
+ 'description' => true,
+ 'store_location' => true,
+ 'comment' => true,
+ 'ordernr' => true,
+ 'supplier' => false,
+ 'manufacturer' => false,
+ 'footprint' => false,
+ 'tags' => false,
+ 'regex' => false,
+ ]);
$resolver->setAllowedTypes('name', 'bool');
$resolver->setAllowedTypes('category', 'bool');
$resolver->setAllowedTypes('description', 'bool');
@@ -375,8 +375,8 @@ final class PartsDataTable implements DataTableTypeInterface
$builder->andWhere('part.tags LIKE :tag')->setParameter('tag', '%'.$options['tag'].'%');
}
- if (!empty($options['search'])) {
- if (!$options['search_options']['regex']) {
+ if (! empty($options['search'])) {
+ if (! $options['search_options']['regex']) {
//Dont show results, if no things are selected
$builder->andWhere('0=1');
$defined = false;
@@ -463,7 +463,6 @@ final class PartsDataTable implements DataTableTypeInterface
if ($defined) {
$builder->setParameter('search', $options['search']);
}
-
}
}
}
diff --git a/src/Entity/Attachments/Attachment.php b/src/Entity/Attachments/Attachment.php
index 6d97cae7..ff6cc8cd 100644
--- a/src/Entity/Attachments/Attachment.php
+++ b/src/Entity/Attachments/Attachment.php
@@ -365,7 +365,6 @@ abstract class Attachment extends AbstractNamedDBElement
/**
* Sets the element that is associated with this attachment.
*
- * @param AttachmentContainingDBElement $element
* @return $this
*/
public function setElement(AttachmentContainingDBElement $element): self
@@ -394,7 +393,6 @@ abstract class Attachment extends AbstractNamedDBElement
}
/**
- * @param AttachmentType $attachement_type
* @return $this
*/
public function setAttachmentType(AttachmentType $attachement_type): self
@@ -408,7 +406,6 @@ abstract class Attachment extends AbstractNamedDBElement
* Sets the url associated with this attachment.
* If the url is empty nothing is changed, to not override the file path.
*
- * @param string|null $url
* @return Attachment
*/
public function setURL(?string $url): self
diff --git a/src/Entity/Attachments/AttachmentContainingDBElement.php b/src/Entity/Attachments/AttachmentContainingDBElement.php
index e6df1976..87ca49f4 100644
--- a/src/Entity/Attachments/AttachmentContainingDBElement.php
+++ b/src/Entity/Attachments/AttachmentContainingDBElement.php
@@ -22,8 +22,8 @@ declare(strict_types=1);
namespace App\Entity\Attachments;
-use App\Entity\Base\MasterAttachmentTrait;
use App\Entity\Base\AbstractNamedDBElement;
+use App\Entity\Base\MasterAttachmentTrait;
use App\Entity\Contracts\HasAttachmentsInterface;
use App\Entity\Contracts\HasMasterAttachmentInterface;
use Doctrine\Common\Collections\ArrayCollection;
@@ -39,8 +39,8 @@ abstract class AttachmentContainingDBElement extends AbstractNamedDBElement impl
/**
* @var Attachment[]|Collection
- * //TODO
- * //@ORM\OneToMany(targetEntity="Attachment", mappedBy="element")
+ * //TODO
+ * //@ORM\OneToMany(targetEntity="Attachment", mappedBy="element")
*
* Mapping is done in sub classes like part
*/
@@ -51,6 +51,25 @@ abstract class AttachmentContainingDBElement extends AbstractNamedDBElement impl
$this->attachments = new ArrayCollection();
}
+ public function __clone()
+ {
+ if ($this->id) {
+ $attachments = $this->attachments;
+ $this->attachments = new ArrayCollection();
+ //Set master attachment is needed
+ foreach ($attachments as $attachment) {
+ $clone = clone $attachment;
+ if ($attachment === $this->master_picture_attachment) {
+ $this->setMasterPictureAttachment($clone);
+ }
+ $this->addAttachment($clone);
+ }
+ }
+
+ //Parent has to be last call, as it resets the ID
+ parent::__clone();
+ }
+
/********************************************************************************
*
* Getters
@@ -86,7 +105,6 @@ abstract class AttachmentContainingDBElement extends AbstractNamedDBElement impl
/**
* Removes the given attachment from this element.
*
- * @param Attachment $attachment
* @return $this
*/
public function removeAttachment(Attachment $attachment): self
@@ -95,23 +113,4 @@ abstract class AttachmentContainingDBElement extends AbstractNamedDBElement impl
return $this;
}
-
- public function __clone()
- {
- if ($this->id) {
- $attachments = $this->attachments;
- $this->attachments = new ArrayCollection();
- //Set master attachment is needed
- foreach ($attachments as $attachment) {
- $clone = clone $attachment;
- if ($attachment === $this->master_picture_attachment) {
- $this->setMasterPictureAttachment($clone);
- }
- $this->addAttachment($clone);
- }
- }
-
- //Parent has to be last call, as it resets the ID
- parent::__clone();
- }
}
diff --git a/src/Entity/Attachments/AttachmentType.php b/src/Entity/Attachments/AttachmentType.php
index 865651a1..9971e547 100644
--- a/src/Entity/Attachments/AttachmentType.php
+++ b/src/Entity/Attachments/AttachmentType.php
@@ -23,10 +23,12 @@ declare(strict_types=1);
namespace App\Entity\Attachments;
use App\Entity\Base\AbstractStructuralDBElement;
+use App\Entity\Parameters\AttachmentTypeParameter;
use App\Validator\Constraints\ValidFileFilter;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
+use Symfony\Component\Validator\Constraints as Assert;
/**
* Class AttachmentType.
@@ -56,9 +58,17 @@ class AttachmentType extends AbstractStructuralDBElement
/**
* @var Collection|AttachmentTypeAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\AttachmentTypeAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
+ * @Assert\Valid()
*/
protected $attachments;
+ /** @var AttachmentTypeParameter[]
+ * @ORM\OneToMany(targetEntity="App\Entity\Parameters\AttachmentTypeParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
+ * @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
+ * @Assert\Valid()
+ */
+ protected $parameters;
+
/**
* @var Collection|Attachment[]
* @ORM\OneToMany(targetEntity="Attachment", mappedBy="attachment_type")
diff --git a/src/Entity/Base/AbstractCompany.php b/src/Entity/Base/AbstractCompany.php
index 4dd214ac..e9912b9b 100644
--- a/src/Entity/Base/AbstractCompany.php
+++ b/src/Entity/Base/AbstractCompany.php
@@ -173,7 +173,7 @@ abstract class AbstractCompany extends AbstractPartsContainingDBElement
/**
* Set the addres.
*
- * @param string $new_address the new address (with "\n" as line break)
+ * @param string $new_address the new address (with "\n" as line break)
*
* @return $this
*/
@@ -188,6 +188,7 @@ abstract class AbstractCompany extends AbstractPartsContainingDBElement
* Set the phone number.
*
* @param string $new_phone_number the new phone number
+ *
* @return $this
*/
public function setPhoneNumber(string $new_phone_number): self
@@ -201,6 +202,7 @@ abstract class AbstractCompany extends AbstractPartsContainingDBElement
* Set the fax number.
*
* @param string $new_fax_number the new fax number
+ *
* @return $this
*/
public function setFaxNumber(string $new_fax_number): self
@@ -214,6 +216,7 @@ abstract class AbstractCompany extends AbstractPartsContainingDBElement
* Set the e-mail address.
*
* @param string $new_email_address the new e-mail address
+ *
* @return $this
*/
public function setEmailAddress(string $new_email_address): self
@@ -227,6 +230,7 @@ abstract class AbstractCompany extends AbstractPartsContainingDBElement
* Set the website.
*
* @param string $new_website the new website
+ *
* @return $this
*/
public function setWebsite(string $new_website): self
@@ -240,6 +244,7 @@ abstract class AbstractCompany extends AbstractPartsContainingDBElement
* Set the link to the website of an article.
*
* @param string $new_url the new URL with the placeholder %PARTNUMBER% for the part number
+ *
* @return $this
*/
public function setAutoProductUrl(string $new_url): self
diff --git a/src/Entity/Base/AbstractNamedDBElement.php b/src/Entity/Base/AbstractNamedDBElement.php
index d0531924..9356360e 100644
--- a/src/Entity/Base/AbstractNamedDBElement.php
+++ b/src/Entity/Base/AbstractNamedDBElement.php
@@ -57,6 +57,15 @@ abstract class AbstractNamedDBElement extends AbstractDBElement implements Named
return $this->getName();
}
+ public function __clone()
+ {
+ if ($this->id) {
+ //We create a new object, so give it a new creation date
+ $this->addedDate = null;
+ }
+ parent::__clone(); // TODO: Change the autogenerated stub
+ }
+
/********************************************************************************
*
* Getters
@@ -89,15 +98,7 @@ abstract class AbstractNamedDBElement extends AbstractDBElement implements Named
public function setName(string $new_name): self
{
$this->name = $new_name;
+
return $this;
}
-
- public function __clone()
- {
- if ($this->id) {
- //We create a new object, so give it a new creation date
- $this->addedDate = null;
- }
- parent::__clone(); // TODO: Change the autogenerated stub
- }
}
diff --git a/src/Entity/Base/AbstractStructuralDBElement.php b/src/Entity/Base/AbstractStructuralDBElement.php
index 687f0c3a..3bb3da16 100644
--- a/src/Entity/Base/AbstractStructuralDBElement.php
+++ b/src/Entity/Base/AbstractStructuralDBElement.php
@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace App\Entity\Base;
use App\Entity\Attachments\AttachmentContainingDBElement;
+use App\Entity\Parameters\ParametersTrait;
use App\Validator\Constraints\NoneOfItsChildren;
use function count;
use Doctrine\Common\Collections\ArrayCollection;
@@ -50,6 +51,8 @@ use Symfony\Component\Serializer\Annotation\Groups;
*/
abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement
{
+ use ParametersTrait;
+
public const ID_ROOT_ELEMENT = 0;
/**
@@ -101,6 +104,7 @@ abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement
{
parent::__construct();
$this->children = new ArrayCollection();
+ $this->parameters = new ArrayCollection();
}
/******************************************************************************
@@ -111,7 +115,7 @@ abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement
* Check if this element is a child of another element (recursive).
*
* @param AbstractStructuralDBElement $another_element the object to compare
- * IMPORTANT: both objects to compare must be from the same class (for example two "Device" objects)!
+ * IMPORTANT: both objects to compare must be from the same class (for example two "Device" objects)!
*
* @return bool True, if this element is child of $another_element.
*
@@ -312,13 +316,14 @@ abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement
}
/**
- * @param static[]|Collection $elements
+ * @param static[]|Collection $elements
+ *
* @return $this
*/
public function setChildren($elements): self
{
- if (!is_array($elements) && !$elements instanceof Collection) {
- throw new InvalidArgumentException('$elements must be an array or Collection!');
+ if (! is_array($elements) && ! $elements instanceof Collection) {
+ throw new InvalidArgumentException('$elements must be an array or Collection!');
}
$this->children = $elements;
@@ -327,7 +332,6 @@ abstract class AbstractStructuralDBElement extends AttachmentContainingDBElement
}
/**
- * @param bool $not_selectable
* @return AbstractStructuralDBElement
*/
public function setNotSelectable(bool $not_selectable): self
diff --git a/src/Entity/Base/MasterAttachmentTrait.php b/src/Entity/Base/MasterAttachmentTrait.php
index fc81ba02..4f1a2eb2 100644
--- a/src/Entity/Base/MasterAttachmentTrait.php
+++ b/src/Entity/Base/MasterAttachmentTrait.php
@@ -72,7 +72,6 @@ trait MasterAttachmentTrait
/**
* Sets the new master picture for this part.
*
- * @param Attachment|null $new_master_attachment
* @return $this
*/
public function setMasterPictureAttachment(?Attachment $new_master_attachment): self
diff --git a/src/Entity/Contracts/HasAttachmentsInterface.php b/src/Entity/Contracts/HasAttachmentsInterface.php
index f27d7b46..7214b15d 100644
--- a/src/Entity/Contracts/HasAttachmentsInterface.php
+++ b/src/Entity/Contracts/HasAttachmentsInterface.php
@@ -1,4 +1,7 @@
Orderdetail::class,
self::TARGET_TYPE_PRICEDETAIL => Pricedetail::class,
self::TARGET_TYPE_MEASUREMENTUNIT => MeasurementUnit::class,
+ self::TARGET_TYPE_PARAMETER => AbstractParameter::class,
];
/** @var User The user which has caused this log entry
@@ -203,7 +206,6 @@ abstract class AbstractLogEntry extends AbstractDBElement
/**
* Sets the user that caused the event.
*
- * @param User $user
* @return $this
*/
public function setUser(User $user): self
@@ -226,7 +228,6 @@ abstract class AbstractLogEntry extends AbstractDBElement
/**
* Sets the timestamp when the event happened.
*
- * @param DateTime $timestamp
* @return $this
*/
public function setTimestamp(DateTime $timestamp): self
@@ -255,7 +256,6 @@ abstract class AbstractLogEntry extends AbstractDBElement
/**
* Sets the new level of this log entry.
*
- * @param int $level
* @return $this
*/
public function setLevel(int $level): self
@@ -281,7 +281,6 @@ abstract class AbstractLogEntry extends AbstractDBElement
/**
* Sets the priority level of this log entry as PSR3 compatible string.
*
- * @param string $level
* @return $this
*/
public function setLevelString(string $level): self
@@ -370,12 +369,13 @@ abstract class AbstractLogEntry extends AbstractDBElement
/**
* Sets the target ID of the element associated with this element.
- * @param int $target_id
+ *
* @return $this
*/
public function setTargetElementID(int $target_id): self
{
$this->target_id = $target_id;
+
return $this;
}
diff --git a/src/Entity/LogSystem/CollectionElementDeleted.php b/src/Entity/LogSystem/CollectionElementDeleted.php
index 3d127e41..a37a8c8b 100644
--- a/src/Entity/LogSystem/CollectionElementDeleted.php
+++ b/src/Entity/LogSystem/CollectionElementDeleted.php
@@ -1,4 +1,7 @@
extra['i'];
}
- /**
- * @inheritDoc
- */
public function isUndoEvent(): bool
{
return isset($this->extra['u']);
}
- /**
- * @inheritDoc
- */
public function getUndoEventID(): ?int
{
return $this->extra['u'] ?? null;
}
- /**
- * @inheritDoc
- */
public function setUndoneEvent(AbstractLogEntry $event, string $mode = 'undo'): LogWithEventUndoInterface
{
$this->extra['u'] = $event->getID();
- if ($mode === 'undo') {
+ if ('undo' === $mode) {
$this->extra['um'] = 1;
- } elseif ($mode === 'revert') {
+ } elseif ('revert' === $mode) {
$this->extra['um'] = 2;
} else {
throw new \InvalidArgumentException('Passed invalid $mode!');
@@ -121,16 +118,13 @@ class CollectionElementDeleted extends AbstractLogEntry implements LogWithEventU
return $this;
}
- /**
- * @inheritDoc
- */
public function getUndoMode(): string
{
$mode_int = $this->extra['um'] ?? 1;
- if ($mode_int === 1) {
+ if (1 === $mode_int) {
return 'undo';
- } else {
- return 'revert';
}
+
+ return 'revert';
}
-}
\ No newline at end of file
+}
diff --git a/src/Entity/LogSystem/ConfigChangedLogEntry.php b/src/Entity/LogSystem/ConfigChangedLogEntry.php
index 480bd85a..19367439 100644
--- a/src/Entity/LogSystem/ConfigChangedLogEntry.php
+++ b/src/Entity/LogSystem/ConfigChangedLogEntry.php
@@ -55,6 +55,7 @@ class ConfigChangedLogEntry extends AbstractLogEntry
public function __construct()
{
parent::__construct();
+
throw new LogEntryObsoleteException();
}
}
diff --git a/src/Entity/LogSystem/ElementCreatedLogEntry.php b/src/Entity/LogSystem/ElementCreatedLogEntry.php
index cc591db3..3cbf53a3 100644
--- a/src/Entity/LogSystem/ElementCreatedLogEntry.php
+++ b/src/Entity/LogSystem/ElementCreatedLogEntry.php
@@ -88,57 +88,40 @@ class ElementCreatedLogEntry extends AbstractLogEntry implements LogWithCommentI
return null !== $this->getCreationInstockValue();
}
- /**
- * @inheritDoc
- */
public function hasComment(): bool
{
return isset($this->extra['m']);
}
- /**
- * @inheritDoc
- */
public function getComment(): ?string
{
return $this->extra['m'] ?? null;
}
- /**
- * @inheritDoc
- */
public function setComment(?string $new_comment): LogWithCommentInterface
{
$this->extra['m'] = $new_comment;
+
return $this;
}
- /**
- * @inheritDoc
- */
public function isUndoEvent(): bool
{
return isset($this->extra['u']);
}
- /**
- * @inheritDoc
- */
public function getUndoEventID(): ?int
{
return $this->extra['u'] ?? null;
}
- /**
- * @inheritDoc
- */
public function setUndoneEvent(AbstractLogEntry $event, string $mode = 'undo'): LogWithEventUndoInterface
{
$this->extra['u'] = $event->getID();
- if ($mode === 'undo') {
+ if ('undo' === $mode) {
$this->extra['um'] = 1;
- } elseif ($mode === 'revert') {
+ } elseif ('revert' === $mode) {
$this->extra['um'] = 2;
} else {
throw new \InvalidArgumentException('Passed invalid $mode!');
@@ -147,16 +130,13 @@ class ElementCreatedLogEntry extends AbstractLogEntry implements LogWithCommentI
return $this;
}
- /**
- * @inheritDoc
- */
public function getUndoMode(): string
{
$mode_int = $this->extra['um'] ?? 1;
- if ($mode_int === 1) {
+ if (1 === $mode_int) {
return 'undo';
- } else {
- return 'revert';
}
+
+ return 'revert';
}
}
diff --git a/src/Entity/LogSystem/ElementDeletedLogEntry.php b/src/Entity/LogSystem/ElementDeletedLogEntry.php
index c6e6c4f3..d3a7f47b 100644
--- a/src/Entity/LogSystem/ElementDeletedLogEntry.php
+++ b/src/Entity/LogSystem/ElementDeletedLogEntry.php
@@ -71,7 +71,6 @@ class ElementDeletedLogEntry extends AbstractLogEntry implements TimeTravelInter
}
/**
- * @inheritDoc
* @return $this
*/
public function setTargetElement(?AbstractDBElement $element): AbstractLogEntry
@@ -80,12 +79,14 @@ class ElementDeletedLogEntry extends AbstractLogEntry implements TimeTravelInter
if ($element instanceof NamedElementInterface) {
$this->setOldName($element->getName());
}
+
return $this;
}
public function setOldName(string $old_name): self
{
$this->extra['n'] = $old_name;
+
return $this;
}
@@ -96,82 +97,60 @@ class ElementDeletedLogEntry extends AbstractLogEntry implements TimeTravelInter
/**
* Sets the old data for this entry.
- * @param array $old_data
+ *
* @return $this
*/
public function setOldData(array $old_data): self
{
$this->extra['o'] = $old_data;
+
return $this;
}
- /**
- * @inheritDoc
- */
public function hasOldDataInformations(): bool
{
- return !empty($this->extra['o']);
+ return ! empty($this->extra['o']);
}
- /**
- * @inheritDoc
- */
public function getOldData(): array
{
return $this->extra['o'] ?? [];
}
- /**
- * @inheritDoc
- */
public function hasComment(): bool
{
return isset($this->extra['m']);
}
- /**
- * @inheritDoc
- */
public function getComment(): ?string
{
return $this->extra['m'] ?? null;
}
- /**
- * @inheritDoc
- */
public function setComment(?string $new_comment): LogWithCommentInterface
{
$this->extra['m'] = $new_comment;
+
return $this;
}
- /**
- * @inheritDoc
- */
public function isUndoEvent(): bool
{
return isset($this->extra['u']);
}
- /**
- * @inheritDoc
- */
public function getUndoEventID(): ?int
{
return $this->extra['u'] ?? null;
}
- /**
- * @inheritDoc
- */
public function setUndoneEvent(AbstractLogEntry $event, string $mode = 'undo'): LogWithEventUndoInterface
{
$this->extra['u'] = $event->getID();
- if ($mode === 'undo') {
+ if ('undo' === $mode) {
$this->extra['um'] = 1;
- } elseif ($mode === 'revert') {
+ } elseif ('revert' === $mode) {
$this->extra['um'] = 2;
} else {
throw new \InvalidArgumentException('Passed invalid $mode!');
@@ -180,15 +159,13 @@ class ElementDeletedLogEntry extends AbstractLogEntry implements TimeTravelInter
return $this;
}
- /**
- * @inheritDoc
- */
public function getUndoMode(): string
{
$mode_int = $this->extra['um'] ?? 1;
- if ($mode_int === 1) {
+ if (1 === $mode_int) {
return 'undo';
}
+
return 'revert';
}
}
diff --git a/src/Entity/LogSystem/ElementEditedLogEntry.php b/src/Entity/LogSystem/ElementEditedLogEntry.php
index 2d22edc9..2b4011f2 100644
--- a/src/Entity/LogSystem/ElementEditedLogEntry.php
+++ b/src/Entity/LogSystem/ElementEditedLogEntry.php
@@ -65,6 +65,7 @@ class ElementEditedLogEntry extends AbstractLogEntry implements TimeTravelInterf
/**
* Checks if this log contains infos about which fields has changed.
+ *
* @return bool
*/
public function hasChangedFieldsInfo(): bool
@@ -74,6 +75,7 @@ class ElementEditedLogEntry extends AbstractLogEntry implements TimeTravelInterf
/**
* Return the names of all fields that were changed during the change.
+ *
* @return string[]
*/
public function getChangedFields(): array
@@ -91,93 +93,74 @@ class ElementEditedLogEntry extends AbstractLogEntry implements TimeTravelInterf
/**
* Set the fields that were changed during this element change.
- * @param string[] $changed_fields The names of the fields that were changed during the elements
+ *
+ * @param string[] $changed_fields The names of the fields that were changed during the elements
+ *
* @return $this
*/
public function setChangedFields(array $changed_fields): self
{
$this->extra['f'] = $changed_fields;
+
return $this;
}
/**
* Sets the old data for this entry.
- * @param array $old_data
+ *
* @return $this
*/
public function setOldData(array $old_data): self
{
$this->extra['d'] = $old_data;
+
return $this;
}
- /**
- * @inheritDoc
- */
public function hasOldDataInformations(): bool
{
- return !empty($this->extra['d']);
+ return ! empty($this->extra['d']);
}
- /**
- * @inheritDoc
- */
public function getOldData(): array
{
return $this->extra['d'] ?? [];
}
- /**
- * @inheritDoc
- */
public function hasComment(): bool
{
return isset($this->extra['m']);
}
- /**
- * @inheritDoc
- */
public function getComment(): ?string
{
return $this->extra['m'] ?? null;
}
- /**
- * @inheritDoc
- */
public function setComment(?string $new_comment): LogWithCommentInterface
{
$this->extra['m'] = $new_comment;
+
return $this;
}
- /**
- * @inheritDoc
- */
public function isUndoEvent(): bool
{
return isset($this->extra['u']);
}
- /**
- * @inheritDoc
- */
public function getUndoEventID(): ?int
{
return $this->extra['u'] ?? null;
}
- /**
- * @inheritDoc
- */
public function setUndoneEvent(AbstractLogEntry $event, string $mode = 'undo'): LogWithEventUndoInterface
{
$this->extra['u'] = $event->getID();
- if ($mode === 'undo') {
+ if ('undo' === $mode) {
$this->extra['um'] = 1;
- } elseif ($mode === 'revert') {
+ } elseif ('revert' === $mode) {
$this->extra['um'] = 2;
} else {
throw new \InvalidArgumentException('Passed invalid $mode!');
@@ -186,16 +169,13 @@ class ElementEditedLogEntry extends AbstractLogEntry implements TimeTravelInterf
return $this;
}
- /**
- * @inheritDoc
- */
public function getUndoMode(): string
{
$mode_int = $this->extra['um'] ?? 1;
- if ($mode_int === 1) {
+ if (1 === $mode_int) {
return 'undo';
- } else {
- return 'revert';
}
+
+ return 'revert';
}
}
diff --git a/src/Entity/LogSystem/ExceptionLogEntry.php b/src/Entity/LogSystem/ExceptionLogEntry.php
index c21255f2..6f8c7d86 100644
--- a/src/Entity/LogSystem/ExceptionLogEntry.php
+++ b/src/Entity/LogSystem/ExceptionLogEntry.php
@@ -55,6 +55,7 @@ class ExceptionLogEntry extends AbstractLogEntry
public function __construct()
{
parent::__construct();
+
throw new LogEntryObsoleteException();
}
diff --git a/src/Entity/Parameters/AbstractParameter.php b/src/Entity/Parameters/AbstractParameter.php
new file mode 100644
index 00000000..095df7ee
--- /dev/null
+++ b/src/Entity/Parameters/AbstractParameter.php
@@ -0,0 +1,418 @@
+.
+ */
+
+namespace App\Entity\Parameters;
+
+use App\Entity\Base\AbstractDBElement;
+use App\Entity\Base\AbstractNamedDBElement;
+use Doctrine\ORM\Mapping as ORM;
+use InvalidArgumentException;
+use LogicException;
+use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
+use Symfony\Component\Validator\Constraints as Assert;
+
+/**
+ * @ORM\Entity()
+ * @ORM\Table("parameters")
+ * @ORM\InheritanceType("SINGLE_TABLE")
+ * @ORM\DiscriminatorColumn(name="type", type="smallint")
+ * @ORM\DiscriminatorMap({
+ * 0 = "CategoryParameter",
+ * 1 = "CurrencyParameter",
+ * 2 = "DeviceParameter",
+ * 3 = "FootprintParameter",
+ * 4 = "GroupParameter",
+ * 5 = "ManufacturerParameter",
+ * 6 = "MeasurementUnitParameter",
+ * 7 = "PartParameter",
+ * 8 = "StorelocationParameter",
+ * 9 = "SupplierParameter",
+ * 10 = "AttachmentTypeParameter"
+ * })
+ */
+abstract class AbstractParameter extends AbstractNamedDBElement
+{
+ /**
+ * @var string The class of the element that can be passed to this attachment. Must be overridden in subclasses.
+ */
+ public const ALLOWED_ELEMENT_CLASS = '';
+
+ /**
+ * @var string The mathematical symbol for this specification. Can be rendered pretty later. Should be short
+ * @Assert\Length(max=20)
+ * @ORM\Column(type="string", nullable=false)
+ */
+ protected $symbol = '';
+
+ /**
+ * @var float|null The guaranteed minimum value of this property.
+ * @Assert\Type({"float","null"})
+ * @Assert\LessThanOrEqual(propertyPath="value_typical", message="parameters.validator.min_lesser_typical")
+ * @Assert\LessThan(propertyPath="value_max", message="parameters.validator.min_lesser_max")
+ * @ORM\Column(type="float", nullable=true)
+ */
+ protected $value_min;
+
+ /**
+ * @var float|null The typical value of this property.
+ * @Assert\Type({"null", "float"})
+ * @ORM\Column(type="float", nullable=true)
+ */
+ protected $value_typical;
+
+ /**
+ * @var float|null The maximum value of this property.
+ * @Assert\Type({"float", "null"})
+ * @Assert\GreaterThanOrEqual(propertyPath="value_typical", message="parameters.validator.max_greater_typical")
+ * @ORM\Column(type="float", nullable=true)
+ */
+ protected $value_max;
+
+ /**
+ * @var string The unit in which the value values are given (e.g. V)
+ * @Assert\Length(max=5)
+ * @ORM\Column(type="string", nullable=false)
+ */
+ protected $unit = '';
+
+ /**
+ * @var string A text value for the given property.
+ * @ORM\Column(type="string", nullable=false)
+ */
+ protected $value_text = '';
+
+ /**
+ * @var string The group this parameter belongs to.
+ * @ORM\Column(type="string", nullable=false, name="param_group")
+ */
+ protected $group = '';
+
+ /**
+ * Mapping is done in sub classes.
+ *
+ * @var AbstractDBElement|null The element to which this parameter belongs to.
+ */
+ protected $element;
+
+ public function __construct()
+ {
+ if ('' === static::ALLOWED_ELEMENT_CLASS) {
+ throw new LogicException('An *Attachment class must override the ALLOWED_ELEMENT_CLASS const!');
+ }
+ }
+
+ /**
+ * Returns the name of the specification (e.g. "Collector-Base Voltage").
+ *
+ * @return string
+ */
+ public function getName(): string
+ {
+ return $this->name;
+ }
+
+ /**
+ * Returns the element this parameter belongs to.
+ *
+ * @return AbstractDBElement|null
+ */
+ public function getElement(): ?AbstractDBElement
+ {
+ return $this->element;
+ }
+
+ /**
+ * Return a formatted string version of the values of the string.
+ * Based on the set values it can return something like this: 34 V (12 V ... 50 V) [Text].
+ *
+ * @return string
+ */
+ public function getFormattedValue(): string
+ {
+ //If we just only have text value, return early
+ if (null === $this->value_typical && null === $this->value_min && null === $this->value_max) {
+ return $this->value_text;
+ }
+
+ $str = '';
+ $bracket_opened = false;
+ if ($this->value_typical) {
+ $str .= $this->getValueTypicalWithUnit();
+ if ($this->value_min || $this->value_max) {
+ $bracket_opened = true;
+ $str .= ' (';
+ }
+ }
+
+ if ($this->value_max && $this->value_min) {
+ $str .= $this->getValueMinWithUnit().' ... '.$this->getValueMaxWithUnit();
+ } elseif ($this->value_max) {
+ $str .= 'max. '.$this->getValueMaxWithUnit();
+ } elseif ($this->value_min) {
+ $str .= 'min. '.$this->getValueMinWithUnit();
+ }
+
+ //Add closing bracket
+ if ($bracket_opened) {
+ $str .= ')';
+ }
+
+ if ($this->value_text) {
+ $str .= ' ['.$this->value_text.']';
+ }
+
+ return $str;
+ }
+
+ /**
+ * Sets the element to which this parameter belongs to.
+ *
+ * @return $this
+ */
+ public function setElement(AbstractDBElement $element): self
+ {
+ if (! is_a($element, static::ALLOWED_ELEMENT_CLASS)) {
+ throw new InvalidArgumentException(sprintf('The element associated with a %s must be a %s!', static::class, static::ALLOWED_ELEMENT_CLASS));
+ }
+
+ $this->element = $element;
+
+ return $this;
+ }
+
+ /**
+ * Sets the name of the specification. This value is required.
+ *
+ * @return $this
+ */
+ public function setName(string $name): AbstractNamedDBElement
+ {
+ $this->name = $name;
+
+ return $this;
+ }
+
+ /**
+ * Returns the name of the group this parameter is associated to (e.g. Technical Parameters)
+ * @return string
+ */
+ public function getGroup(): string
+ {
+ return $this->group;
+ }
+
+ /**
+ * Sets the name of the group this parameter is associated to.
+ * @param string $group
+ * @return $this
+ */
+ public function setGroup(string $group): self
+ {
+ $this->group = $group;
+ return $this;
+ }
+
+ /**
+ * Returns the mathematical symbol for this specification (e.g. "V_CB").
+ *
+ * @return string
+ */
+ public function getSymbol(): string
+ {
+ return $this->symbol;
+ }
+
+ /**
+ * Sets the mathematical symbol for this specification (e.g. "V_CB").
+ *
+ * @return $this
+ */
+ public function setSymbol(string $symbol): self
+ {
+ $this->symbol = $symbol;
+
+ return $this;
+ }
+
+ /**
+ * Returns The guaranteed minimum value of this property.
+ *
+ * @return float|null
+ */
+ public function getValueMin(): ?float
+ {
+ return $this->value_min;
+ }
+
+ /**
+ * Sets the minimum value of this property.
+ *
+ * @return $this
+ */
+ public function setValueMin(?float $value_min): self
+ {
+ $this->value_min = $value_min;
+
+ return $this;
+ }
+
+ /**
+ * Returns the typical value of this property.
+ *
+ * @return float|null
+ */
+ public function getValueTypical(): ?float
+ {
+ return $this->value_typical;
+ }
+
+ /**
+ * Return a formatted version with the minimum value with the unit of this parameter.
+ *
+ * @return string
+ */
+ public function getValueTypicalWithUnit(): string
+ {
+ return $this->formatWithUnit($this->value_typical);
+ }
+
+ /**
+ * Return a formatted version with the maximum value with the unit of this parameter.
+ *
+ * @return string
+ */
+ public function getValueMaxWithUnit(): string
+ {
+ return $this->formatWithUnit($this->value_max);
+ }
+
+ /**
+ * Return a formatted version with the typical value with the unit of this parameter.
+ *
+ * @return string
+ */
+ public function getValueMinWithUnit(): string
+ {
+ return $this->formatWithUnit($this->value_min);
+ }
+
+ /**
+ * Sets the typical value of this property.
+ *
+ * @param float $value_typical
+ *
+ * @return $this
+ */
+ public function setValueTypical(?float $value_typical): self
+ {
+ $this->value_typical = $value_typical;
+
+ return $this;
+ }
+
+ /**
+ * Returns the guaranteed maximum value.
+ *
+ * @return float|null
+ */
+ public function getValueMax(): ?float
+ {
+ return $this->value_max;
+ }
+
+ /**
+ * Sets the guaranteed maximum value.
+ *
+ * @return $this
+ */
+ public function setValueMax(?float $value_max): self
+ {
+ $this->value_max = $value_max;
+
+ return $this;
+ }
+
+ /**
+ * Returns the unit used by the value (e.g. "V").
+ *
+ * @return string
+ */
+ public function getUnit(): string
+ {
+ return $this->unit;
+ }
+
+ /**
+ * Sets the unit used by the value.
+ *
+ * @return $this
+ */
+ public function setUnit(string $unit): self
+ {
+ $this->unit = $unit;
+
+ return $this;
+ }
+
+ /**
+ * Returns the text value.
+ *
+ * @return string
+ */
+ public function getValueText(): string
+ {
+ return $this->value_text;
+ }
+
+ /**
+ * Sets the text value.
+ *
+ * @return $this
+ */
+ public function setValueText(string $value_text): self
+ {
+ $this->value_text = $value_text;
+
+ return $this;
+ }
+
+ public function getIDString(): string
+ {
+ return 'PM'.sprintf('%09d', $this->getID());
+ }
+
+ /**
+ * Return a string representation and (if possible) with its unit.
+ *
+ * @return string
+ */
+ protected function formatWithUnit(float $value, string $format = '%g'): string
+ {
+ $str = \sprintf($format, $value);
+ if (! empty($this->unit)) {
+ return $str.' '.$this->unit;
+ }
+
+ return $str;
+ }
+}
diff --git a/src/Entity/Parameters/AttachmentTypeParameter.php b/src/Entity/Parameters/AttachmentTypeParameter.php
new file mode 100644
index 00000000..d1ad9094
--- /dev/null
+++ b/src/Entity/Parameters/AttachmentTypeParameter.php
@@ -0,0 +1,43 @@
+.
+ */
+
+namespace App\Entity\Parameters;
+
+use App\Entity\Attachments\AttachmentType;
+use Doctrine\ORM\Mapping as ORM;
+use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
+
+/**
+ * @ORM\Entity()
+ * @UniqueEntity(fields={"name", "group", "element"})
+ */
+class AttachmentTypeParameter extends AbstractParameter
+{
+ public const ALLOWED_ELEMENT_CLASS = AttachmentType::class;
+ /**
+ * @var AttachmentType the element this para is associated with
+ * @ORM\ManyToOne(targetEntity="App\Entity\Attachments\AttachmentType", inversedBy="parameters")
+ * @ORM\JoinColumn(name="element_id", referencedColumnName="id", nullable=false, onDelete="CASCADE").
+ */
+ protected $element;
+}
diff --git a/src/Entity/Parameters/CategoryParameter.php b/src/Entity/Parameters/CategoryParameter.php
new file mode 100644
index 00000000..86925755
--- /dev/null
+++ b/src/Entity/Parameters/CategoryParameter.php
@@ -0,0 +1,43 @@
+.
+ */
+
+namespace App\Entity\Parameters;
+
+use App\Entity\Parts\Category;
+use Doctrine\ORM\Mapping as ORM;
+use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
+
+/**
+ * @ORM\Entity()
+ * @UniqueEntity(fields={"name", "group", "element"})
+ */
+class CategoryParameter extends AbstractParameter
+{
+ public const ALLOWED_ELEMENT_CLASS = Category::class;
+ /**
+ * @var Category the element this para is associated with
+ * @ORM\ManyToOne(targetEntity="App\Entity\Parts\Category", inversedBy="parameters")
+ * @ORM\JoinColumn(name="element_id", referencedColumnName="id", nullable=false, onDelete="CASCADE").
+ */
+ protected $element;
+}
diff --git a/src/Entity/Parameters/CurrencyParameter.php b/src/Entity/Parameters/CurrencyParameter.php
new file mode 100644
index 00000000..28f3c934
--- /dev/null
+++ b/src/Entity/Parameters/CurrencyParameter.php
@@ -0,0 +1,46 @@
+.
+ */
+
+namespace App\Entity\Parameters;
+
+use App\Entity\PriceInformations\Currency;
+use Doctrine\ORM\Mapping as ORM;
+use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
+
+/**
+ * A attachment attached to a category element.
+ *
+ * @ORM\Entity()
+ * @UniqueEntity(fields={"name", "group", "element"})
+ */
+class CurrencyParameter extends AbstractParameter
+{
+ public const ALLOWED_ELEMENT_CLASS = Currency::class;
+
+ /**
+ * @var Currency the element this para is associated with
+ * @ORM\ManyToOne(targetEntity="App\Entity\PriceInformations\Currency", inversedBy="parameters")
+ * @ORM\JoinColumn(name="element_id", referencedColumnName="id", nullable=false, onDelete="CASCADE").
+ */
+ protected $element;
+}
diff --git a/src/Entity/Parameters/DeviceParameter.php b/src/Entity/Parameters/DeviceParameter.php
new file mode 100644
index 00000000..724ad3be
--- /dev/null
+++ b/src/Entity/Parameters/DeviceParameter.php
@@ -0,0 +1,44 @@
+.
+ */
+
+namespace App\Entity\Parameters;
+
+use App\Entity\Devices\Device;
+use Doctrine\ORM\Mapping as ORM;
+use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
+
+/**
+ * @ORM\Entity()
+ * @UniqueEntity(fields={"name", "group", "element"})
+ */
+class DeviceParameter extends AbstractParameter
+{
+ public const ALLOWED_ELEMENT_CLASS = Device::class;
+
+ /**
+ * @var Device the element this para is associated with
+ * @ORM\ManyToOne(targetEntity="App\Entity\Devices\Device", inversedBy="parameters")
+ * @ORM\JoinColumn(name="element_id", referencedColumnName="id", nullable=false, onDelete="CASCADE").
+ */
+ protected $element;
+}
diff --git a/src/Entity/Parameters/FootprintParameter.php b/src/Entity/Parameters/FootprintParameter.php
new file mode 100644
index 00000000..d92ed8cb
--- /dev/null
+++ b/src/Entity/Parameters/FootprintParameter.php
@@ -0,0 +1,44 @@
+.
+ */
+
+namespace App\Entity\Parameters;
+
+use App\Entity\Parts\Footprint;
+use Doctrine\ORM\Mapping as ORM;
+use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
+
+/**
+ * @ORM\Entity()
+ * @UniqueEntity(fields={"name", "group", "element"})
+ */
+class FootprintParameter extends AbstractParameter
+{
+ public const ALLOWED_ELEMENT_CLASS = Footprint::class;
+
+ /**
+ * @var Footprint the element this para is associated with
+ * @ORM\ManyToOne(targetEntity="App\Entity\Parts\Footprint", inversedBy="parameters")
+ * @ORM\JoinColumn(name="element_id", referencedColumnName="id", nullable=false, onDelete="CASCADE").
+ */
+ protected $element;
+}
diff --git a/src/Entity/Parameters/GroupParameter.php b/src/Entity/Parameters/GroupParameter.php
new file mode 100644
index 00000000..c6b62aa1
--- /dev/null
+++ b/src/Entity/Parameters/GroupParameter.php
@@ -0,0 +1,44 @@
+.
+ */
+
+namespace App\Entity\Parameters;
+
+use App\Entity\UserSystem\Group;
+use Doctrine\ORM\Mapping as ORM;
+use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
+
+/**
+ * @ORM\Entity()
+ * @UniqueEntity(fields={"name", "group", "element"})
+ */
+class GroupParameter extends AbstractParameter
+{
+ public const ALLOWED_ELEMENT_CLASS = Group::class;
+
+ /**
+ * @var Group the element this para is associated with
+ * @ORM\ManyToOne(targetEntity="App\Entity\UserSystem\Group", inversedBy="parameters")
+ * @ORM\JoinColumn(name="element_id", referencedColumnName="id", nullable=false, onDelete="CASCADE").
+ */
+ protected $element;
+}
diff --git a/src/Entity/Parameters/ManufacturerParameter.php b/src/Entity/Parameters/ManufacturerParameter.php
new file mode 100644
index 00000000..b06633f0
--- /dev/null
+++ b/src/Entity/Parameters/ManufacturerParameter.php
@@ -0,0 +1,44 @@
+.
+ */
+
+namespace App\Entity\Parameters;
+
+use App\Entity\Parts\Manufacturer;
+use Doctrine\ORM\Mapping as ORM;
+use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
+
+/**
+ * @ORM\Entity()
+ * @UniqueEntity(fields={"name", "group", "element"})
+ */
+class ManufacturerParameter extends AbstractParameter
+{
+ public const ALLOWED_ELEMENT_CLASS = Manufacturer::class;
+
+ /**
+ * @var Manufacturer the element this para is associated with
+ * @ORM\ManyToOne(targetEntity="App\Entity\Parts\Manufacturer", inversedBy="parameters")
+ * @ORM\JoinColumn(name="element_id", referencedColumnName="id", nullable=false, onDelete="CASCADE").
+ */
+ protected $element;
+}
diff --git a/src/Entity/Parameters/MeasurementUnitParameter.php b/src/Entity/Parameters/MeasurementUnitParameter.php
new file mode 100644
index 00000000..91ce5809
--- /dev/null
+++ b/src/Entity/Parameters/MeasurementUnitParameter.php
@@ -0,0 +1,44 @@
+.
+ */
+
+namespace App\Entity\Parameters;
+
+use App\Entity\Parts\MeasurementUnit;
+use Doctrine\ORM\Mapping as ORM;
+use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
+
+/**
+ * @ORM\Entity()
+ * @UniqueEntity(fields={"name", "group", "element"})
+ */
+class MeasurementUnitParameter extends AbstractParameter
+{
+ public const ALLOWED_ELEMENT_CLASS = MeasurementUnit::class;
+
+ /**
+ * @var MeasurementUnit the element this para is associated with
+ * @ORM\ManyToOne(targetEntity="App\Entity\Parts\MeasurementUnit", inversedBy="parameters")
+ * @ORM\JoinColumn(name="element_id", referencedColumnName="id", nullable=false, onDelete="CASCADE").
+ */
+ protected $element;
+}
diff --git a/src/Entity/Parameters/ParametersTrait.php b/src/Entity/Parameters/ParametersTrait.php
new file mode 100644
index 00000000..34d97a74
--- /dev/null
+++ b/src/Entity/Parameters/ParametersTrait.php
@@ -0,0 +1,78 @@
+.
+ */
+
+namespace App\Entity\Parameters;
+
+use Doctrine\Common\Collections\Collection;
+use Symfony\Component\Validator\Constraints as Assert;
+
+trait ParametersTrait
+{
+ /**
+ * Mapping done in subclasses.
+ *
+ * @var AbstractParameter[]|Collection
+ * @Assert\Valid()
+ */
+ protected $parameters;
+
+ /**
+ * Return all associated specifications.
+ *
+ * @return AbstractParameter[]|Collection
+ */
+ public function getParameters(): Collection
+ {
+ return $this->parameters;
+ }
+
+ /**
+ * Add a new parameter information.
+ *
+ * @return $this
+ */
+ public function addParameter(AbstractParameter $parameter): self
+ {
+ $parameter->setElement($this);
+ $this->parameters->add($parameter);
+
+ return $this;
+ }
+
+ public function removeParameter(AbstractParameter $parameter): self
+ {
+ $this->parameters->removeElement($parameter);
+
+ return $this;
+ }
+
+ public function getGroupedParameters(): array
+ {
+ $tmp = [];
+
+ foreach ($this->parameters as $parameter) {
+ $tmp[$parameter->getGroup()][] = $parameter;
+ }
+ return $tmp;
+ }
+}
diff --git a/src/Entity/Parameters/PartParameter.php b/src/Entity/Parameters/PartParameter.php
new file mode 100644
index 00000000..d7d08cfa
--- /dev/null
+++ b/src/Entity/Parameters/PartParameter.php
@@ -0,0 +1,44 @@
+.
+ */
+
+namespace App\Entity\Parameters;
+
+use App\Entity\Parts\Part;
+use Doctrine\ORM\Mapping as ORM;
+use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
+
+/**
+ * @ORM\Entity()
+ * @UniqueEntity(fields={"name", "group", "element"})
+ */
+class PartParameter extends AbstractParameter
+{
+ public const ALLOWED_ELEMENT_CLASS = Part::class;
+
+ /**
+ * @var Part the element this para is associated with
+ * @ORM\ManyToOne(targetEntity="App\Entity\Parts\Part", inversedBy="parameters")
+ * @ORM\JoinColumn(name="element_id", referencedColumnName="id", nullable=false, onDelete="CASCADE").
+ */
+ protected $element;
+}
diff --git a/src/Entity/Parameters/StorelocationParameter.php b/src/Entity/Parameters/StorelocationParameter.php
new file mode 100644
index 00000000..44077d48
--- /dev/null
+++ b/src/Entity/Parameters/StorelocationParameter.php
@@ -0,0 +1,44 @@
+.
+ */
+
+namespace App\Entity\Parameters;
+
+use App\Entity\Parts\Storelocation;
+use Doctrine\ORM\Mapping as ORM;
+use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
+
+/**
+ * @ORM\Entity()
+ * @UniqueEntity(fields={"name", "group", "element"})
+ */
+class StorelocationParameter extends AbstractParameter
+{
+ public const ALLOWED_ELEMENT_CLASS = Storelocation::class;
+
+ /**
+ * @var Storelocation the element this para is associated with
+ * @ORM\ManyToOne(targetEntity="App\Entity\Parts\Storelocation", inversedBy="parameters")
+ * @ORM\JoinColumn(name="element_id", referencedColumnName="id", nullable=false, onDelete="CASCADE").
+ */
+ protected $element;
+}
diff --git a/src/Entity/Parameters/SupplierParameter.php b/src/Entity/Parameters/SupplierParameter.php
new file mode 100644
index 00000000..e61137a0
--- /dev/null
+++ b/src/Entity/Parameters/SupplierParameter.php
@@ -0,0 +1,44 @@
+.
+ */
+
+namespace App\Entity\Parameters;
+
+use App\Entity\Parts\Supplier;
+use Doctrine\ORM\Mapping as ORM;
+use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
+
+/**
+ * @ORM\Entity()
+ * @UniqueEntity(fields={"name", "group", "element"})
+ */
+class SupplierParameter extends AbstractParameter
+{
+ public const ALLOWED_ELEMENT_CLASS = Supplier::class;
+
+ /**
+ * @var Supplier the element this para is associated with
+ * @ORM\ManyToOne(targetEntity="App\Entity\Parts\Supplier", inversedBy="parameters")
+ * @ORM\JoinColumn(name="element_id", referencedColumnName="id", nullable=false, onDelete="CASCADE").
+ */
+ protected $element;
+}
diff --git a/src/Entity/Parts/Category.php b/src/Entity/Parts/Category.php
index a5c98475..9c0a1a09 100644
--- a/src/Entity/Parts/Category.php
+++ b/src/Entity/Parts/Category.php
@@ -24,8 +24,10 @@ namespace App\Entity\Parts;
use App\Entity\Attachments\CategoryAttachment;
use App\Entity\Base\AbstractPartsContainingDBElement;
+use App\Entity\Parameters\CategoryParameter;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
+use Symfony\Component\Validator\Constraints as Assert;
/**
* Class AttachmentType.
@@ -101,9 +103,17 @@ class Category extends AbstractPartsContainingDBElement
/**
* @var Collection|CategoryAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\CategoryAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
+ * @Assert\Valid()
*/
protected $attachments;
+ /** @var CategoryParameter[]
+ * @ORM\OneToMany(targetEntity="App\Entity\Parameters\CategoryParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
+ * @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
+ * @Assert\Valid()
+ */
+ protected $parameters;
+
/**
* Returns the ID as an string, defined by the element class.
* This should have a form like P000014, for a part with ID 14.
@@ -121,7 +131,6 @@ class Category extends AbstractPartsContainingDBElement
}
/**
- * @param string $partname_hint
* @return Category
*/
public function setPartnameHint(string $partname_hint): self
@@ -137,7 +146,6 @@ class Category extends AbstractPartsContainingDBElement
}
/**
- * @param string $partname_regex
* @return Category
*/
public function setPartnameRegex(string $partname_regex): self
@@ -153,7 +161,6 @@ class Category extends AbstractPartsContainingDBElement
}
/**
- * @param bool $disable_footprints
* @return Category
*/
public function setDisableFootprints(bool $disable_footprints): self
@@ -169,7 +176,6 @@ class Category extends AbstractPartsContainingDBElement
}
/**
- * @param bool $disable_manufacturers
* @return Category
*/
public function setDisableManufacturers(bool $disable_manufacturers): self
@@ -185,7 +191,6 @@ class Category extends AbstractPartsContainingDBElement
}
/**
- * @param bool $disable_autodatasheets
* @return Category
*/
public function setDisableAutodatasheets(bool $disable_autodatasheets): self
@@ -201,7 +206,6 @@ class Category extends AbstractPartsContainingDBElement
}
/**
- * @param bool $disable_properties
* @return Category
*/
public function setDisableProperties(bool $disable_properties): self
@@ -217,7 +221,6 @@ class Category extends AbstractPartsContainingDBElement
}
/**
- * @param string $default_description
* @return Category
*/
public function setDefaultDescription(string $default_description): self
@@ -233,7 +236,6 @@ class Category extends AbstractPartsContainingDBElement
}
/**
- * @param string $default_comment
* @return Category
*/
public function setDefaultComment(string $default_comment): self
diff --git a/src/Entity/Parts/Footprint.php b/src/Entity/Parts/Footprint.php
index 8fb7b9bb..666aa95f 100644
--- a/src/Entity/Parts/Footprint.php
+++ b/src/Entity/Parts/Footprint.php
@@ -52,8 +52,10 @@ namespace App\Entity\Parts;
use App\Entity\Attachments\FootprintAttachment;
use App\Entity\Base\AbstractPartsContainingDBElement;
+use App\Entity\Parameters\FootprintParameter;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
+use Symfony\Component\Validator\Constraints as Assert;
/**
* Class Footprint.
@@ -81,6 +83,7 @@ class Footprint extends AbstractPartsContainingDBElement
/**
* @var Collection|FootprintAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\FootprintAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
+ * @Assert\Valid()
*/
protected $attachments;
@@ -91,6 +94,13 @@ class Footprint extends AbstractPartsContainingDBElement
*/
protected $footprint_3d;
+ /** @var FootprintParameter[]
+ * @ORM\OneToMany(targetEntity="App\Entity\Parameters\FootprintParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
+ * @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})@ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
+ * @Assert\Valid()
+ */
+ protected $parameters;
+
/**
* Returns the ID as an string, defined by the element class.
* This should have a form like P000014, for a part with ID 14.
diff --git a/src/Entity/Parts/Manufacturer.php b/src/Entity/Parts/Manufacturer.php
index 113e0a03..e61e3063 100644
--- a/src/Entity/Parts/Manufacturer.php
+++ b/src/Entity/Parts/Manufacturer.php
@@ -52,8 +52,10 @@ namespace App\Entity\Parts;
use App\Entity\Attachments\ManufacturerAttachment;
use App\Entity\Base\AbstractCompany;
+use App\Entity\Parameters\ManufacturerParameter;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
+use Symfony\Component\Validator\Constraints as Assert;
/**
* Class Manufacturer.
@@ -81,9 +83,17 @@ class Manufacturer extends AbstractCompany
/**
* @var Collection|ManufacturerAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\ManufacturerAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
+ * @Assert\Valid()
*/
protected $attachments;
+ /** @var ManufacturerParameter[]
+ * @ORM\OneToMany(targetEntity="App\Entity\Parameters\ManufacturerParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
+ * @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
+ * @Assert\Valid()
+ */
+ protected $parameters;
+
/**
* Returns the ID as an string, defined by the element class.
* This should have a form like P000014, for a part with ID 14.
diff --git a/src/Entity/Parts/MeasurementUnit.php b/src/Entity/Parts/MeasurementUnit.php
index 0a5213aa..78a4180d 100644
--- a/src/Entity/Parts/MeasurementUnit.php
+++ b/src/Entity/Parts/MeasurementUnit.php
@@ -44,6 +44,7 @@ namespace App\Entity\Parts;
use App\Entity\Attachments\MeasurementUnitAttachment;
use App\Entity\Base\AbstractPartsContainingDBElement;
+use App\Entity\Parameters\MeasurementUnitParameter;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
@@ -99,9 +100,17 @@ class MeasurementUnit extends AbstractPartsContainingDBElement
/**
* @var Collection|MeasurementUnitAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\MeasurementUnitAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
+ * @Assert\Valid()
*/
protected $attachments;
+ /** @var MeasurementUnitParameter[]
+ * @ORM\OneToMany(targetEntity="App\Entity\Parameters\MeasurementUnitParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
+ * @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
+ * @Assert\Valid()
+ */
+ protected $parameters;
+
/**
* Returns the ID as an string, defined by the element class.
* This should have a form like P000014, for a part with ID 14.
@@ -139,7 +148,6 @@ class MeasurementUnit extends AbstractPartsContainingDBElement
}
/**
- * @param bool $isInteger
* @return MeasurementUnit
*/
public function setIsInteger(bool $isInteger): self
@@ -155,7 +163,6 @@ class MeasurementUnit extends AbstractPartsContainingDBElement
}
/**
- * @param bool $usesSIPrefixes
* @return MeasurementUnit
*/
public function setUseSIPrefix(bool $usesSIPrefixes): self
diff --git a/src/Entity/Parts/Part.php b/src/Entity/Parts/Part.php
index e2cd7623..749c8af2 100644
--- a/src/Entity/Parts/Part.php
+++ b/src/Entity/Parts/Part.php
@@ -53,6 +53,8 @@ namespace App\Entity\Parts;
use App\Entity\Attachments\Attachment;
use App\Entity\Attachments\AttachmentContainingDBElement;
use App\Entity\Devices\Device;
+use App\Entity\Parameters\ParametersTrait;
+use App\Entity\Parameters\PartParameter;
use App\Entity\Parts\PartTraits\AdvancedPropertyTrait;
use App\Entity\Parts\PartTraits\BasicPropertyTrait;
use App\Entity\Parts\PartTraits\InstockTrait;
@@ -81,12 +83,21 @@ class Part extends AttachmentContainingDBElement
use InstockTrait;
use ManufacturerTrait;
use OrderTrait;
+ use ParametersTrait;
/**
* TODO.
*/
protected $devices = [];
+ /** @var PartParameter[]
+ * @Assert\Valid()
+ * @ORM\OneToMany(targetEntity="App\Entity\Parameters\PartParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
+ * @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
+ * @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
+ */
+ protected $parameters;
+
/**
* @ColumnSecurity(type="datetime")
* @ORM\Column(type="datetime", name="datetime_added", options={"default"="CURRENT_TIMESTAMP"})
@@ -132,6 +143,27 @@ class Part extends AttachmentContainingDBElement
parent::__construct();
$this->partLots = new ArrayCollection();
$this->orderdetails = new ArrayCollection();
+ $this->parameters = new ArrayCollection();
+ }
+
+ public function __clone()
+ {
+ if ($this->id) {
+ //Deep clone part lots
+ $lots = $this->partLots;
+ $this->partLots = new ArrayCollection();
+ foreach ($lots as $lot) {
+ $this->addPartLot(clone $lot);
+ }
+
+ //Deep clone order details
+ $orderdetails = $this->orderdetails;
+ $this->orderdetails = new ArrayCollection();
+ foreach ($orderdetails as $orderdetail) {
+ $this->addOrderdetail(clone $orderdetail);
+ }
+ }
+ parent::__clone();
}
/**
@@ -156,24 +188,4 @@ class Part extends AttachmentContainingDBElement
{
return $this->devices;
}
-
- public function __clone()
- {
- if ($this->id) {
- //Deep clone part lots
- $lots = $this->partLots;
- $this->partLots = new ArrayCollection();
- foreach ($lots as $lot) {
- $this->addPartLot(clone $lot);
- }
-
- //Deep clone order details
- $orderdetails = $this->orderdetails;
- $this->orderdetails = new ArrayCollection();
- foreach ($orderdetails as $orderdetail) {
- $this->addOrderdetail(clone $orderdetail);
- }
- }
- parent::__clone();
- }
}
diff --git a/src/Entity/Parts/PartLot.php b/src/Entity/Parts/PartLot.php
index e1fb6cc1..282e5545 100644
--- a/src/Entity/Parts/PartLot.php
+++ b/src/Entity/Parts/PartLot.php
@@ -119,6 +119,14 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface
*/
protected $part;
+ public function __clone()
+ {
+ if ($this->id) {
+ $this->addedDate = null;
+ }
+ parent::__clone();
+ }
+
/**
* Returns the ID as an string, defined by the element class.
* This should have a form like P000014, for a part with ID 14.
@@ -161,7 +169,6 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface
/**
* Sets the description of the part lot.
*
- * @param string $description
* @return PartLot
*/
public function setDescription(string $description): self
@@ -184,7 +191,6 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface
/**
* Sets the comment for this part lot.
*
- * @param string $comment
* @return PartLot
*/
public function setComment(string $comment): self
@@ -231,7 +237,6 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface
/**
* Sets the storage location, where this part lot is stored.
*
- * @param Storelocation|null $storage_location
* @return PartLot
*/
public function setStorageLocation(?Storelocation $storage_location): self
@@ -254,8 +259,6 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface
/**
* Sets the part that is stored in this part lot.
*
- * @param Part $part
- *
* @return PartLot
*/
public function setPart(Part $part): self
@@ -278,7 +281,6 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface
/**
* Set the unknown instock status of this part lot.
*
- * @param bool $instock_unknown
* @return PartLot
*/
public function setInstockUnknown(bool $instock_unknown): self
@@ -316,7 +318,6 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface
}
/**
- * @param bool $needs_refill
* @return PartLot
*/
public function setNeedsRefill(bool $needs_refill): self
@@ -325,12 +326,4 @@ class PartLot extends AbstractDBElement implements TimeStampableInterface
return $this;
}
-
- public function __clone()
- {
- if($this->id) {
- $this->addedDate = null;
- }
- parent::__clone();
- }
}
diff --git a/src/Entity/Parts/PartTraits/AdvancedPropertyTrait.php b/src/Entity/Parts/PartTraits/AdvancedPropertyTrait.php
index aeebd92a..111f92dc 100644
--- a/src/Entity/Parts/PartTraits/AdvancedPropertyTrait.php
+++ b/src/Entity/Parts/PartTraits/AdvancedPropertyTrait.php
@@ -106,6 +106,7 @@ trait AdvancedPropertyTrait
* Sets a comma separated list of tags, that are assigned to this part.
*
* @param string $tags The new tags
+ *
* @return $this
*/
public function setTags(string $tags): self
@@ -129,6 +130,7 @@ trait AdvancedPropertyTrait
* Sett to null, if the mass is unknown.
*
* @param float|null $mass the new mass
+ *
* @return $this
*/
public function setMass(?float $mass): self
diff --git a/src/Entity/Parts/PartTraits/BasicPropertyTrait.php b/src/Entity/Parts/PartTraits/BasicPropertyTrait.php
index db66b460..9eeab4ee 100644
--- a/src/Entity/Parts/PartTraits/BasicPropertyTrait.php
+++ b/src/Entity/Parts/PartTraits/BasicPropertyTrait.php
@@ -164,6 +164,7 @@ trait BasicPropertyTrait
* Sets the description of this part.
*
* @param string $new_description the new description
+ *
* @return $this
*/
public function setDescription(?string $new_description): self
@@ -177,6 +178,7 @@ trait BasicPropertyTrait
* Sets the comment property of this part.
*
* @param string $new_comment the new comment
+ *
* @return $this
*/
public function setComment(string $new_comment): self
@@ -191,6 +193,7 @@ trait BasicPropertyTrait
* The category property is required for every part, so you can not pass null like the other properties (footprints).
*
* @param Category $category The new category of this part
+ *
* @return $this
*/
public function setCategory(Category $category): self
@@ -205,6 +208,7 @@ trait BasicPropertyTrait
*
* @param Footprint|null $new_footprint The new footprint of this part. Set to null, if this part should not have
* a footprint.
+ *
* @return $this
*/
public function setFootprint(?Footprint $new_footprint): self
@@ -219,6 +223,7 @@ trait BasicPropertyTrait
*
* @param bool $new_favorite_status The new favorite status, that should be applied on this part.
* Set this to true, when the part should be a favorite.
+ *
* @return $this
*/
public function setFavorite(bool $new_favorite_status): self
diff --git a/src/Entity/Parts/PartTraits/InstockTrait.php b/src/Entity/Parts/PartTraits/InstockTrait.php
index 65423864..9678ac96 100644
--- a/src/Entity/Parts/PartTraits/InstockTrait.php
+++ b/src/Entity/Parts/PartTraits/InstockTrait.php
@@ -90,7 +90,7 @@ trait InstockTrait
/**
* Adds the given part lot, to the list of part lots.
* The part lot is assigned to this part.
- * @param PartLot $lot
+ *
* @return $this
*/
public function addPartLot(PartLot $lot): self
@@ -105,6 +105,7 @@ trait InstockTrait
* Removes the given part lot from the list of part lots.
*
* @param PartLot $lot the part lot that should be deleted
+ *
* @return $this
*/
public function removePartLot(PartLot $lot): self
@@ -126,7 +127,7 @@ trait InstockTrait
/**
* Sets the measurement unit in which the part's amount should be measured.
* Set to null, if the part should be measured in quantities.
- * @param MeasurementUnit|null $partUnit
+ *
* @return $this
*/
public function setPartUnit(?MeasurementUnit $partUnit): self
@@ -172,7 +173,6 @@ trait InstockTrait
* Part Lots that have unknown value or are expired, are not used for this value.
*
* @return float The amount of parts given in partUnit
- *
*/
public function getAmountSum(): float
{
@@ -199,6 +199,7 @@ trait InstockTrait
* See getPartUnit() for the associated unit.
*
* @param float $new_minamount the new count of parts which should be in stock at least
+ *
* @return $this
*/
public function setMinAmount(float $new_minamount): self
diff --git a/src/Entity/Parts/PartTraits/ManufacturerTrait.php b/src/Entity/Parts/PartTraits/ManufacturerTrait.php
index b393c843..0717e45e 100644
--- a/src/Entity/Parts/PartTraits/ManufacturerTrait.php
+++ b/src/Entity/Parts/PartTraits/ManufacturerTrait.php
@@ -136,7 +136,6 @@ trait ManufacturerTrait
* Sets the manufacturing status for this part
* See getManufacturingStatus() for valid values.
*
- * @param string $manufacturing_status
* @return Part
*/
public function setManufacturingStatus(string $manufacturing_status): self
@@ -167,7 +166,6 @@ trait ManufacturerTrait
/**
* Sets the manufacturer product number (MPN) for this part.
*
- * @param string $manufacturer_product_number
* @return Part
*/
public function setManufacturerProductNumber(string $manufacturer_product_number): self
@@ -182,6 +180,7 @@ trait ManufacturerTrait
* Set to "" if this part should use the automatically URL based on its manufacturer.
*
* @param string $new_url The new url
+ *
* @return $this
*/
public function setManufacturerProductURL(string $new_url): self
@@ -196,6 +195,7 @@ trait ManufacturerTrait
*
* @param Manufacturer|null $new_manufacturer The new Manufacturer of this part. Set to null, if this part should
* not have a manufacturer.
+ *
* @return $this
*/
public function setManufacturer(?Manufacturer $new_manufacturer): self
diff --git a/src/Entity/Parts/PartTraits/OrderTrait.php b/src/Entity/Parts/PartTraits/OrderTrait.php
index 20eb71dd..8b022e67 100644
--- a/src/Entity/Parts/PartTraits/OrderTrait.php
+++ b/src/Entity/Parts/PartTraits/OrderTrait.php
@@ -144,6 +144,7 @@ trait OrderTrait
* The orderdetail is assigned to this part.
*
* @param Orderdetail $orderdetail the orderdetail that should be added
+ *
* @return $this
*/
public function addOrderdetail(Orderdetail $orderdetail): self
@@ -156,7 +157,7 @@ trait OrderTrait
/**
* Removes the given orderdetail from the list of orderdetails.
- * @param Orderdetail $orderdetail
+ *
* @return $this
*/
public function removeOrderdetail(Orderdetail $orderdetail): self
@@ -177,6 +178,7 @@ trait OrderTrait
* (if the part has exactly one orderdetails,
* set this orderdetails as order orderdetails.
* Otherwise, set "no order orderdetails")
+ *
* @return $this
*/
public function setManualOrder(bool $new_manual_order, int $new_order_quantity = 1, ?Orderdetail $new_order_orderdetail = null): self
diff --git a/src/Entity/Parts/Storelocation.php b/src/Entity/Parts/Storelocation.php
index 6efe730f..3af60cbd 100644
--- a/src/Entity/Parts/Storelocation.php
+++ b/src/Entity/Parts/Storelocation.php
@@ -52,8 +52,10 @@ namespace App\Entity\Parts;
use App\Entity\Attachments\StorelocationAttachment;
use App\Entity\Base\AbstractPartsContainingDBElement;
+use App\Entity\Parameters\StorelocationParameter;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
+use Symfony\Component\Validator\Constraints as Assert;
/**
* Class Store location.
@@ -85,11 +87,18 @@ class Storelocation extends AbstractPartsContainingDBElement
* @ORM\ManyToMany(targetEntity="Part", fetch="EXTRA_LAZY")
* @ORM\JoinTable(name="part_lots",
* joinColumns={@ORM\JoinColumn(name="id_store_location", referencedColumnName="id")},
- * inverseJoinColumns={@ORM\JoinColumn(name="id_part", referencedColumnName="id")}
+ * inverseJoinColumns={@ORM\JoinColumn(name="id_part", referencedColumnName="id")}
* )
*/
protected $parts;
+ /** @var StorelocationParameter[]
+ * @ORM\OneToMany(targetEntity="App\Entity\Parameters\StorelocationParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
+ * @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
+ * @Assert\Valid()
+ */
+ protected $parameters;
+
/**
* @var bool
* @ORM\Column(type="boolean")
@@ -110,6 +119,7 @@ class Storelocation extends AbstractPartsContainingDBElement
/**
* @var Collection|StorelocationAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\StorelocationAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
+ * @Assert\Valid()
*/
protected $attachments;
@@ -143,7 +153,6 @@ class Storelocation extends AbstractPartsContainingDBElement
}
/**
- * @param bool $only_single_part
* @return Storelocation
*/
public function setOnlySinglePart(bool $only_single_part): self
@@ -164,7 +173,6 @@ class Storelocation extends AbstractPartsContainingDBElement
}
/**
- * @param bool $limit_to_existing_parts
* @return Storelocation
*/
public function setLimitToExistingParts(bool $limit_to_existing_parts): self
@@ -183,7 +191,6 @@ class Storelocation extends AbstractPartsContainingDBElement
}
/**
- * @param MeasurementUnit|null $storage_type
* @return Storelocation
*/
public function setStorageType(?MeasurementUnit $storage_type): self
diff --git a/src/Entity/Parts/Supplier.php b/src/Entity/Parts/Supplier.php
index 263b55f2..0ac3a1ed 100644
--- a/src/Entity/Parts/Supplier.php
+++ b/src/Entity/Parts/Supplier.php
@@ -52,6 +52,7 @@ namespace App\Entity\Parts;
use App\Entity\Attachments\SupplierAttachment;
use App\Entity\Base\AbstractCompany;
+use App\Entity\Parameters\SupplierParameter;
use App\Entity\PriceInformations\Currency;
use App\Validator\Constraints\Selectable;
use Doctrine\Common\Collections\Collection;
@@ -109,9 +110,17 @@ class Supplier extends AbstractCompany
/**
* @var Collection|SupplierAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\SupplierAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
+ * @Assert\Valid()
*/
protected $attachments;
+ /** @var SupplierParameter[]
+ * @ORM\OneToMany(targetEntity="App\Entity\Parameters\SupplierParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
+ * @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
+ * @Assert\Valid()
+ */
+ protected $parameters;
+
/**
* Gets the currency that should be used by default, when creating a orderdetail with this supplier.
*
@@ -125,7 +134,6 @@ class Supplier extends AbstractCompany
/**
* Sets the default currency.
*
- * @param Currency|null $default_currency
* @return Supplier
*/
public function setDefaultCurrency(?Currency $default_currency): self
diff --git a/src/Entity/PriceInformations/Currency.php b/src/Entity/PriceInformations/Currency.php
index a3dc0d62..3a985ce1 100644
--- a/src/Entity/PriceInformations/Currency.php
+++ b/src/Entity/PriceInformations/Currency.php
@@ -44,6 +44,7 @@ namespace App\Entity\PriceInformations;
use App\Entity\Attachments\CurrencyAttachment;
use App\Entity\Base\AbstractStructuralDBElement;
+use App\Entity\Parameters\CurrencyParameter;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
@@ -89,9 +90,17 @@ class Currency extends AbstractStructuralDBElement
/**
* @var Collection|CurrencyAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\CurrencyAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
+ * @Assert\Valid()
*/
protected $attachments;
+ /** @var CurrencyParameter[]
+ * @ORM\OneToMany(targetEntity="App\Entity\Parameters\CurrencyParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
+ * @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
+ * @Assert\Valid()
+ */
+ protected $parameters;
+
/**
* Returns the 3 letter ISO code of this currency.
*
diff --git a/src/Entity/PriceInformations/Orderdetail.php b/src/Entity/PriceInformations/Orderdetail.php
index 72962a37..404b50cc 100644
--- a/src/Entity/PriceInformations/Orderdetail.php
+++ b/src/Entity/PriceInformations/Orderdetail.php
@@ -117,6 +117,20 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface
$this->pricedetails = new ArrayCollection();
}
+ public function __clone()
+ {
+ if ($this->id) {
+ $this->addedDate = null;
+ $pricedetails = $this->pricedetails;
+ $this->pricedetails = new ArrayCollection();
+ //Set master attachment is needed
+ foreach ($pricedetails as $pricedetail) {
+ $this->addPricedetail(clone $pricedetail);
+ }
+ }
+ parent::__clone();
+ }
+
/**
* Returns the ID as an string, defined by the element class.
* This should have a form like P000014, for a part with ID 14.
@@ -228,7 +242,6 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface
/**
* Removes an pricedetail from this orderdetail.
*
- * @param Pricedetail $pricedetail
* @return Orderdetail
*/
public function removePricedetail(Pricedetail $pricedetail): self
@@ -276,7 +289,6 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface
/**
* Sets a new part with which this orderdetail is associated.
*
- * @param Part $part
* @return Orderdetail
*/
public function setPart(Part $part): self
@@ -289,7 +301,6 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface
/**
* Sets the new supplier associated with this orderdetail.
*
- * @param Supplier $new_supplier
* @return Orderdetail
*/
public function setSupplier(Supplier $new_supplier): self
@@ -348,18 +359,4 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface
return $this;
}
-
- public function __clone()
- {
- if ($this->id) {
- $this->addedDate = null;
- $pricedetails = $this->pricedetails;
- $this->pricedetails = new ArrayCollection();
- //Set master attachment is needed
- foreach ($pricedetails as $pricedetail) {
- $this->addPricedetail(clone $pricedetail);
- }
- }
- parent::__clone();
- }
}
diff --git a/src/Entity/PriceInformations/Pricedetail.php b/src/Entity/PriceInformations/Pricedetail.php
index 234bac54..35e05a4f 100644
--- a/src/Entity/PriceInformations/Pricedetail.php
+++ b/src/Entity/PriceInformations/Pricedetail.php
@@ -121,6 +121,14 @@ class Pricedetail extends AbstractDBElement implements TimeStampableInterface
bcscale(static::PRICE_PRECISION);
}
+ public function __clone()
+ {
+ if ($this->id) {
+ $this->addedDate = null;
+ }
+ parent::__clone();
+ }
+
/********************************************************************************
*
* Getters
@@ -230,7 +238,6 @@ class Pricedetail extends AbstractDBElement implements TimeStampableInterface
/**
* Sets the orderdetail to which this pricedetail belongs to.
*
- * @param Orderdetail $orderdetail
* @return $this
*/
public function setOrderdetail(Orderdetail $orderdetail): self
@@ -244,7 +251,6 @@ class Pricedetail extends AbstractDBElement implements TimeStampableInterface
* Sets the currency associated with the price informations.
* Set to null, to use the global base currency.
*
- * @param Currency|null $currency
* @return Pricedetail
*/
public function setCurrency(?Currency $currency): self
@@ -262,6 +268,7 @@ class Pricedetail extends AbstractDBElement implements TimeStampableInterface
* * This is the price for "price_related_quantity" parts!!
* * Example: if "price_related_quantity" is '10',
* you have to set here the price for 10 parts!
+ *
* @return $this
*/
public function setPrice(string $new_price): self
@@ -309,6 +316,7 @@ class Pricedetail extends AbstractDBElement implements TimeStampableInterface
* So the orderdetails would have three Pricedetails for one supplier.)
*
* @param float $new_min_discount_quantity the minimum discount quantity
+ *
* @return $this
*/
public function setMinDiscountQuantity(float $new_min_discount_quantity): self
@@ -328,12 +336,4 @@ class Pricedetail extends AbstractDBElement implements TimeStampableInterface
{
return 'PD'.sprintf('%06d', $this->getID());
}
-
- public function __clone()
- {
- if ($this->id) {
- $this->addedDate = null;
- }
- parent::__clone();
- }
}
diff --git a/src/Entity/UserSystem/Group.php b/src/Entity/UserSystem/Group.php
index 3da256ec..8ef9ec2a 100644
--- a/src/Entity/UserSystem/Group.php
+++ b/src/Entity/UserSystem/Group.php
@@ -44,10 +44,12 @@ namespace App\Entity\UserSystem;
use App\Entity\Attachments\GroupAttachment;
use App\Entity\Base\AbstractStructuralDBElement;
+use App\Entity\Parameters\GroupParameter;
use App\Security\Interfaces\HasPermissionsInterface;
use App\Validator\Constraints\ValidPermission;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
+use Symfony\Component\Validator\Constraints as Assert;
/**
* This entity represents an user group.
@@ -81,6 +83,7 @@ class Group extends AbstractStructuralDBElement implements HasPermissionsInterfa
/**
* @var Collection|GroupAttachment[]
* @ORM\OneToMany(targetEntity="App\Entity\Attachments\ManufacturerAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
+ * @Assert\Valid()
*/
protected $attachments;
@@ -90,6 +93,13 @@ class Group extends AbstractStructuralDBElement implements HasPermissionsInterfa
*/
protected $permissions;
+ /** @var GroupParameter[]
+ * @ORM\OneToMany(targetEntity="App\Entity\Parameters\GroupParameter", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true)
+ * @ORM\OrderBy({"group" = "ASC" ,"name" = "ASC"})
+ * @Assert\Valid()
+ */
+ protected $parameters;
+
public function __construct()
{
parent::__construct();
diff --git a/src/Entity/UserSystem/PermissionsEmbed.php b/src/Entity/UserSystem/PermissionsEmbed.php
index c6b01782..63fed4d8 100644
--- a/src/Entity/UserSystem/PermissionsEmbed.php
+++ b/src/Entity/UserSystem/PermissionsEmbed.php
@@ -235,6 +235,12 @@ class PermissionsEmbed
*/
protected $parts_prices = 0;
+ /**
+ * @var int
+ * @ORM\Column(type="smallint")
+ */
+ protected $parts_parameters = 0;
+
/**
* @var int
* @ORM\Column(type="smallint", name="parts_attachements")
diff --git a/src/Entity/UserSystem/U2FKey.php b/src/Entity/UserSystem/U2FKey.php
index ea4ee32d..151fa980 100644
--- a/src/Entity/UserSystem/U2FKey.php
+++ b/src/Entity/UserSystem/U2FKey.php
@@ -123,6 +123,7 @@ class U2FKey implements TwoFactorKeyInterface
public function setKeyHandle($keyHandle): self
{
$this->keyHandle = $keyHandle;
+
return $this;
}
@@ -134,6 +135,7 @@ class U2FKey implements TwoFactorKeyInterface
public function setPublicKey($publicKey): self
{
$this->publicKey = $publicKey;
+
return $this;
}
@@ -145,6 +147,7 @@ class U2FKey implements TwoFactorKeyInterface
public function setCertificate($certificate): self
{
$this->certificate = $certificate;
+
return $this;
}
@@ -156,6 +159,7 @@ class U2FKey implements TwoFactorKeyInterface
public function setCounter($counter): self
{
$this->counter = $counter;
+
return $this;
}
@@ -167,6 +171,7 @@ class U2FKey implements TwoFactorKeyInterface
public function setName($name): self
{
$this->name = $name;
+
return $this;
}
@@ -193,7 +198,6 @@ class U2FKey implements TwoFactorKeyInterface
/**
* Sets the user this U2F key belongs to.
*
- * @param User $new_user
* @return $this
*/
public function setUser(User $new_user): self
diff --git a/src/Entity/UserSystem/User.php b/src/Entity/UserSystem/User.php
index 63f003ec..1389711a 100644
--- a/src/Entity/UserSystem/User.php
+++ b/src/Entity/UserSystem/User.php
@@ -52,8 +52,8 @@ namespace App\Entity\UserSystem;
use App\Entity\Attachments\AttachmentContainingDBElement;
use App\Entity\Attachments\UserAttachment;
-use App\Entity\Base\MasterAttachmentTrait;
use App\Entity\Base\AbstractNamedDBElement;
+use App\Entity\Base\MasterAttachmentTrait;
use App\Entity\PriceInformations\Currency;
use App\Security\Interfaces\HasPermissionsInterface;
use App\Validator\Constraints\Selectable;
@@ -338,7 +338,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
/**
* Sets the password hash for this user.
*
- * @param string $password
* @return User
*/
public function setPassword(string $password): self
@@ -378,7 +377,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
/**
* Sets the currency the users prefers to see prices in.
*
- * @param Currency|null $currency
* @return User
*/
public function setCurrency(?Currency $currency): self
@@ -441,7 +439,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
/**
* Set the status, if the user needs a password change.
*
- * @param bool $need_pw_change
* @return User
*/
public function setNeedPwChange(bool $need_pw_change): self
@@ -464,7 +461,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
/**
* Sets the encrypted password reset token.
*
- * @param string|null $pw_reset_token
* @return User
*/
public function setPwResetToken(?string $pw_reset_token): self
@@ -487,7 +483,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
/**
* Sets the datetime when the password reset token expires.
*
- * @param DateTime $pw_reset_expires
* @return User
*/
public function setPwResetExpires(DateTime $pw_reset_expires): self
@@ -671,7 +666,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
/**
* Change the timezone of this user.
*
- * @param string|null $timezone
* @return $this
*/
public function setTimezone(?string $timezone): self
@@ -764,7 +758,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
/**
* Sets the secret used for Google Authenticator. Set to null to disable Google Authenticator.
*
- * @param string|null $googleAuthenticatorSecret
* @return $this
*/
public function setGoogleAuthenticatorSecret(?string $googleAuthenticatorSecret): self
@@ -881,7 +874,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
/**
* Add a U2F key to this user.
- * @param TwoFactorKeyInterface $key
*/
public function addU2FKey(TwoFactorKeyInterface $key): void
{
@@ -890,7 +882,6 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
/**
* Remove a U2F key from this user.
- * @param TwoFactorKeyInterface $key
*/
public function removeU2FKey(TwoFactorKeyInterface $key): void
{
diff --git a/src/EventSubscriber/EventLoggerSubscriber.php b/src/EventSubscriber/EventLoggerSubscriber.php
index 0053f688..f6c89e14 100644
--- a/src/EventSubscriber/EventLoggerSubscriber.php
+++ b/src/EventSubscriber/EventLoggerSubscriber.php
@@ -1,4 +1,7 @@
['part'],
Pricedetail::class => ['orderdetail'],
Attachment::class => ['element'],
+ AbstractParameter::class => ['element']
];
protected const MAX_STRING_LENGTH = 2000;
@@ -87,7 +89,7 @@ class EventLoggerSubscriber implements EventSubscriber
$this->save_removed_data = $save_removed_data;
}
- public function onFlush(OnFlushEventArgs $eventArgs)
+ public function onFlush(OnFlushEventArgs $eventArgs): void
{
$em = $eventArgs->getEntityManager();
$uow = $em->getUnitOfWork();
@@ -112,7 +114,7 @@ class EventLoggerSubscriber implements EventSubscriber
$uow->computeChangeSets();
}
- public function postPersist(LifecycleEventArgs $args)
+ public function postPersist(LifecycleEventArgs $args): void
{
//Create an log entry, we have to do this post persist, cause we have to know the ID
@@ -129,10 +131,10 @@ class EventLoggerSubscriber implements EventSubscriber
$log->setUndoneEvent($undoEvent, $this->eventUndoHelper->getMode());
- if($undoEvent instanceof ElementDeletedLogEntry && $undoEvent->getTargetClass() === $log->getTargetClass()) {
+ if ($undoEvent instanceof ElementDeletedLogEntry && $undoEvent->getTargetClass() === $log->getTargetClass()) {
$log->setTargetElementID($undoEvent->getTargetID());
}
- if($undoEvent instanceof CollectionElementDeleted && $undoEvent->getDeletedElementClass() === $log->getTargetClass()) {
+ if ($undoEvent instanceof CollectionElementDeleted && $undoEvent->getDeletedElementClass() === $log->getTargetClass()) {
$log->setTargetElementID($undoEvent->getDeletedElementID());
}
}
@@ -140,7 +142,7 @@ class EventLoggerSubscriber implements EventSubscriber
}
}
- public function postFlush(PostFlushEventArgs $args)
+ public function postFlush(PostFlushEventArgs $args): void
{
$em = $args->getEntityManager();
$uow = $em->getUnitOfWork();
@@ -154,6 +156,48 @@ class EventLoggerSubscriber implements EventSubscriber
$this->eventUndoHelper->clearUndoneEvent();
}
+ /**
+ * Check if the given element class has restrictions to its fields.
+ *
+ * @return bool True if there are restrictions, and further checking is needed
+ */
+ public function hasFieldRestrictions(AbstractDBElement $element): bool
+ {
+ foreach (static::FIELD_BLACKLIST as $class => $blacklist) {
+ if (is_a($element, $class)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Checks if the field of the given element should be saved (if it is not blacklisted).
+ *
+ * @return bool
+ */
+ public function shouldFieldBeSaved(AbstractDBElement $element, string $field_name): bool
+ {
+ foreach (static::FIELD_BLACKLIST as $class => $blacklist) {
+ if (is_a($element, $class) && in_array($field_name, $blacklist, true)) {
+ return false;
+ }
+ }
+
+ //By default allow every field.
+ return true;
+ }
+
+ public function getSubscribedEvents()
+ {
+ return[
+ Events::onFlush,
+ Events::postPersist,
+ Events::postFlush,
+ ];
+ }
+
protected function logElementDeleted(AbstractDBElement $entity, EntityManagerInterface $em): void
{
$log = new ElementDeletedLogEntry($entity);
@@ -179,7 +223,7 @@ class EventLoggerSubscriber implements EventSubscriber
if (is_a($entity, $class)) {
//Check names
foreach ($mappings as $field => $mapping) {
- if (in_array($field, $whitelist)) {
+ if (in_array($field, $whitelist, true)) {
$changed = $this->propertyAccessor->getValue($entity, $field);
$log = new CollectionElementDeleted($changed, $mapping['inversedBy'], $entity);
if ($this->eventUndoHelper->isUndo()) {
@@ -216,33 +260,16 @@ class EventLoggerSubscriber implements EventSubscriber
$this->logger->log($log);
}
- /**
- * Check if the given element class has restrictions to its fields
- * @param AbstractDBElement $element
- * @return bool True if there are restrictions, and further checking is needed
- */
- public function hasFieldRestrictions(AbstractDBElement $element): bool
- {
- foreach (static::FIELD_BLACKLIST as $class => $blacklist) {
- if (is_a($element, $class)) {
- return true;
- }
- }
-
- return false;
- }
-
/**
* Filter out every forbidden field and return the cleaned array.
- * @param AbstractDBElement $element
- * @param array $fields
+ *
* @return array
*/
protected function filterFieldRestrictions(AbstractDBElement $element, array $fields): array
{
unset($fields['lastModified']);
- if (!$this->hasFieldRestrictions($element)) {
+ if (! $this->hasFieldRestrictions($element)) {
return $fields;
}
@@ -256,29 +283,11 @@ class EventLoggerSubscriber implements EventSubscriber
}, ARRAY_FILTER_USE_BOTH);
}
- /**
- * Checks if the field of the given element should be saved (if it is not blacklisted).
- * @param AbstractDBElement $element
- * @param string $field_name
- * @return bool
- */
- public function shouldFieldBeSaved(AbstractDBElement $element, string $field_name): bool
- {
- foreach (static::FIELD_BLACKLIST as $class => $blacklist) {
- if (is_a($element, $class) && in_array($field_name, $blacklist)) {
- return false;
- }
- }
-
- //By default allow every field.
- return true;
- }
-
protected function saveChangeSet(AbstractDBElement $entity, AbstractLogEntry $logEntry, EntityManagerInterface $em, $element_deleted = false): void
{
$uow = $em->getUnitOfWork();
- if (!$logEntry instanceof ElementEditedLogEntry && !$logEntry instanceof ElementDeletedLogEntry) {
+ if (! $logEntry instanceof ElementEditedLogEntry && ! $logEntry instanceof ElementDeletedLogEntry) {
throw new \InvalidArgumentException('$logEntry must be ElementEditedLogEntry or ElementDeletedLogEntry!');
}
@@ -304,28 +313,16 @@ class EventLoggerSubscriber implements EventSubscriber
/**
* Check if the given entity can be logged.
- * @param object $entity
+ *
* @return bool True, if the given entity can be logged.
*/
protected function validEntity(object $entity): bool
{
//Dont log logentries itself!
- if ($entity instanceof AbstractDBElement && !$entity instanceof AbstractLogEntry) {
+ if ($entity instanceof AbstractDBElement && ! $entity instanceof AbstractLogEntry) {
return true;
}
return false;
}
-
- /**
- * @inheritDoc
- */
- public function getSubscribedEvents()
- {
- return[
- Events::onFlush,
- Events::postPersist,
- Events::postFlush
- ];
- }
-}
\ No newline at end of file
+}
diff --git a/src/EventSubscriber/U2FRegistrationSubscriber.php b/src/EventSubscriber/U2FRegistrationSubscriber.php
index 3a9014fc..12a70185 100644
--- a/src/EventSubscriber/U2FRegistrationSubscriber.php
+++ b/src/EventSubscriber/U2FRegistrationSubscriber.php
@@ -82,8 +82,8 @@ final class U2FRegistrationSubscriber implements EventSubscriberInterface
//Skip adding of U2F key on demo mode
if (! $this->demo_mode) {
$user = $event->getUser();
- if (!$user instanceof User) {
- throw new \InvalidArgumentException("Only User objects can be registered for U2F!");
+ if (! $user instanceof User) {
+ throw new \InvalidArgumentException('Only User objects can be registered for U2F!');
}
$registration = $event->getRegistration();
diff --git a/src/Form/AdminPages/BaseEntityAdminForm.php b/src/Form/AdminPages/BaseEntityAdminForm.php
index da9dfcfe..d1e029b9 100644
--- a/src/Form/AdminPages/BaseEntityAdminForm.php
+++ b/src/Form/AdminPages/BaseEntityAdminForm.php
@@ -45,7 +45,9 @@ namespace App\Form\AdminPages;
use App\Entity\Attachments\Attachment;
use App\Entity\Base\AbstractNamedDBElement;
use App\Entity\Base\AbstractStructuralDBElement;
+use App\Entity\Parameters\PartParameter;
use App\Form\AttachmentFormType;
+use App\Form\ParameterType;
use App\Form\Type\MasterPictureAttachmentType;
use App\Form\Type\StructuralEntityType;
use FOS\CKEditorBundle\Form\Type\CKEditorType;
@@ -74,8 +76,9 @@ class BaseEntityAdminForm extends AbstractType
public function configureOptions(OptionsResolver $resolver): void
{
- parent::configureOptions($resolver); // TODO: Change the autogenerated stub
+ parent::configureOptions($resolver);
$resolver->setRequired('attachment_class');
+ $resolver->setRequired('parameter_class');
}
public function buildForm(FormBuilderInterface $builder, array $options): void
@@ -151,6 +154,19 @@ class BaseEntityAdminForm extends AbstractType
'empty_data' => null,
]);
+ $builder->add('parameters', CollectionType::class, [
+ 'entry_type' => ParameterType::class,
+ 'allow_add' => $this->security->isGranted($is_new ? 'create' : 'edit', $entity),
+ 'allow_delete' => $this->security->isGranted($is_new ? 'create' : 'edit', $entity),
+ 'disabled' => ! $this->security->isGranted($is_new ? 'create' : 'edit', $entity),
+ 'label' => false,
+ 'by_reference' => false,
+ 'prototype_data' => new $options['parameter_class'](),
+ 'entry_options' => [
+ 'data_class' => $options['parameter_class'],
+ ],
+ ]);
+
//Buttons
$builder->add('save', SubmitType::class, [
'label' => $is_new ? 'entity.create' : 'entity.edit.save',
diff --git a/src/Form/ParameterType.php b/src/Form/ParameterType.php
new file mode 100644
index 00000000..8cd66abd
--- /dev/null
+++ b/src/Form/ParameterType.php
@@ -0,0 +1,126 @@
+.
+ */
+
+namespace App\Form;
+
+use App\Entity\Parameters\AbstractParameter;
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\Extension\Core\Type\NumberType;
+use Symfony\Component\Form\Extension\Core\Type\TextType;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+class ParameterType extends AbstractType
+{
+ public function buildForm(FormBuilderInterface $builder, array $options): void
+ {
+ $builder->add('name', TextType::class, [
+ 'label' => false,
+ 'empty_data' => '',
+ 'attr' => [
+ 'placeholder' => 'parameters.name.placeholder',
+ 'class' => 'form-control-sm',
+ ],
+ ]);
+ $builder->add('symbol', TextType::class, [
+ 'label' => false,
+ 'required' => false,
+ 'empty_data' => '',
+ 'attr' => [
+ 'placeholder' => 'parameters.symbol.placeholder',
+ 'class' => 'form-control-sm',
+ 'style' => 'max-width: 12ch;',
+ ],
+ ]);
+ $builder->add('value_text', TextType::class, [
+ 'label' => false,
+ 'required' => false,
+ 'empty_data' => '',
+ 'attr' => [
+ 'placeholder' => 'parameters.text.placeholder',
+ 'class' => 'form-control-sm',
+ ],
+ ]);
+
+ $builder->add('value_max', NumberType::class, [
+ 'label' => false,
+ 'required' => false,
+ 'html5' => true,
+ 'attr' => [
+ 'step' => 'any',
+ 'placeholder' => 'parameters.max.placeholder',
+ 'class' => 'form-control-sm',
+ 'style' => 'max-width: 12ch;',
+ ],
+ ]);
+ $builder->add('value_min', NumberType::class, [
+ 'label' => false,
+ 'required' => false,
+ 'html5' => true,
+ 'attr' => [
+ 'step' => 'any',
+ 'placeholder' => 'parameters.min.placeholder',
+ 'class' => 'form-control-sm',
+ 'style' => 'max-width: 12ch;',
+ ],
+ ]);
+ $builder->add('value_typical', NumberType::class, [
+ 'label' => false,
+ 'required' => false,
+ 'html5' => true,
+ 'attr' => [
+ 'step' => 'any',
+ 'placeholder' => 'parameters.typical.placeholder',
+ 'class' => 'form-control-sm',
+ 'style' => 'max-width: 12ch;',
+ ],
+ ]);
+ $builder->add('unit', TextType::class, [
+ 'label' => false,
+ 'required' => false,
+ 'empty_data' => '',
+ 'attr' => [
+ 'placeholder' => 'parameters.unit.placeholder',
+ 'class' => 'form-control-sm',
+ 'style' => 'max-width: 8ch;',
+ ],
+ ]);
+
+ $builder->add('group', TextType::class, [
+ 'label' => false,
+ 'required' => false,
+ 'empty_data' => '',
+ 'attr' => [
+ 'placeholder' => 'parameter.group.placeholder',
+ 'class' => 'form-control-sm',
+ ]
+ ]);
+ }
+
+ public function configureOptions(OptionsResolver $resolver): void
+ {
+ $resolver->setDefaults([
+ 'data_class' => AbstractParameter::class,
+ ]);
+ }
+}
diff --git a/src/Form/Part/PartBaseType.php b/src/Form/Part/PartBaseType.php
index cf30f988..1610afcf 100644
--- a/src/Form/Part/PartBaseType.php
+++ b/src/Form/Part/PartBaseType.php
@@ -44,6 +44,7 @@ namespace App\Form\Part;
use App\Entity\Attachments\Attachment;
use App\Entity\Attachments\PartAttachment;
+use App\Entity\Parameters\PartParameter;
use App\Entity\Parts\Category;
use App\Entity\Parts\Footprint;
use App\Entity\Parts\Manufacturer;
@@ -51,6 +52,8 @@ use App\Entity\Parts\MeasurementUnit;
use App\Entity\Parts\Part;
use App\Entity\PriceInformations\Orderdetail;
use App\Form\AttachmentFormType;
+use App\Form\ParameterGroupType;
+use App\Form\ParameterType;
use App\Form\Type\MasterPictureAttachmentType;
use App\Form\Type\SIUnitType;
use App\Form\Type\StructuralEntityType;
@@ -264,6 +267,19 @@ class PartBaseType extends AbstractType
],
]);
+ $builder->add('parameters', CollectionType::class, [
+ 'entry_type' => ParameterType::class,
+ 'allow_add' => $this->security->isGranted('parameters.create', $part),
+ 'allow_delete' => $this->security->isGranted('parameters.delete', $part),
+ 'label' => false,
+ 'by_reference' => false,
+ 'prototype_data' => new PartParameter(),
+ 'entry_options' => [
+ 'disabled' => ! $this->security->isGranted('parameters.edit', $part),
+ 'data_class' => PartParameter::class,
+ ],
+ ]);
+
$builder->add('log_comment', TextType::class, [
'label' => 'edit.log_comment',
'mapped' => false,
diff --git a/src/Form/Type/CurrencyEntityType.php b/src/Form/Type/CurrencyEntityType.php
index 2a992a5a..4e955316 100644
--- a/src/Form/Type/CurrencyEntityType.php
+++ b/src/Form/Type/CurrencyEntityType.php
@@ -67,6 +67,7 @@ class CurrencyEntityType extends StructuralEntityType
$resolver->setDefault('class', Currency::class);
$resolver->setDefault('disable_not_selectable', true);
+ $resolver->setDefault('choice_translation_domain', false);
// This options allows you to override the currency shown for the null value
$resolver->setDefault('base_currency', null);
@@ -87,7 +88,7 @@ class CurrencyEntityType extends StructuralEntityType
{
//Similar to StructuralEntityType, but we use the currency symbol instead if available
- if (!$choice instanceof Currency) {
+ if (! $choice instanceof Currency) {
throw new \InvalidArgumentException('$choice must be an currency object!');
}
diff --git a/src/Form/Type/MasterPictureAttachmentType.php b/src/Form/Type/MasterPictureAttachmentType.php
index 10dddd78..070bb80d 100644
--- a/src/Form/Type/MasterPictureAttachmentType.php
+++ b/src/Form/Type/MasterPictureAttachmentType.php
@@ -43,7 +43,6 @@ declare(strict_types=1);
namespace App\Form\Type;
use App\Entity\Attachments\Attachment;
-use App\Entity\Attachments\AttachmentContainingDBElement;
use App\Entity\Contracts\HasMasterAttachmentInterface;
use Doctrine\ORM\EntityRepository;
use ReflectionClass;
@@ -61,6 +60,7 @@ class MasterPictureAttachmentType extends AbstractType
$resolver->setDefaults([
'filter' => 'picture',
+ 'choice_translation_domain' => false,
'attr' => [
'class' => 'selectpicker',
],
diff --git a/src/Form/Type/SIUnitType.php b/src/Form/Type/SIUnitType.php
index 4b3493d9..1e14cf09 100644
--- a/src/Form/Type/SIUnitType.php
+++ b/src/Form/Type/SIUnitType.php
@@ -145,6 +145,7 @@ final class SIUnitType extends AbstractType implements DataMapperInterface
'm' => -3,
'µ' => -6,
],
+ 'choice_translation_domain' => false,
]);
}
diff --git a/src/Form/Type/StructuralEntityType.php b/src/Form/Type/StructuralEntityType.php
index bdbc0a08..73454038 100644
--- a/src/Form/Type/StructuralEntityType.php
+++ b/src/Form/Type/StructuralEntityType.php
@@ -108,6 +108,7 @@ class StructuralEntityType extends AbstractType
'choice_attr' => function ($choice, $key, $value) {
return $this->generateChoiceAttr($choice, $key, $value);
},
+ 'choice_translation_domain' => false, //Don't translate the entity names
]);
$resolver->setDefault('empty_message', null);
diff --git a/src/Form/UserAdminForm.php b/src/Form/UserAdminForm.php
index ec356710..e7ede3b1 100644
--- a/src/Form/UserAdminForm.php
+++ b/src/Form/UserAdminForm.php
@@ -79,6 +79,7 @@ class UserAdminForm extends AbstractType
{
parent::configureOptions($resolver); // TODO: Change the autogenerated stub
$resolver->setRequired('attachment_class');
+ $resolver->setDefault('parameter_class', false);
}
public function buildForm(FormBuilderInterface $builder, array $options): void
diff --git a/src/Migrations/Version20200311204104.php b/src/Migrations/Version20200311204104.php
new file mode 100644
index 00000000..0cd173d8
--- /dev/null
+++ b/src/Migrations/Version20200311204104.php
@@ -0,0 +1,51 @@
+abortIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\'.');
+
+ $this->addSql('CREATE TABLE parameters (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) NOT NULL, symbol VARCHAR(255) NOT NULL, value_min DOUBLE PRECISION DEFAULT NULL, value_typical DOUBLE PRECISION DEFAULT NULL, value_max DOUBLE PRECISION DEFAULT NULL, unit VARCHAR(255) NOT NULL, value_text VARCHAR(255) NOT NULL, param_group VARCHAR(255) NOT NULL, last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, type SMALLINT NOT NULL, element_id INT NOT NULL, INDEX IDX_69348FE1F1F2A24 (element_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
+ $this->addSql('ALTER TABLE `groups` ADD perms_parts_parameters SMALLINT NOT NULL');
+ $this->addSql('ALTER TABLE `users` ADD perms_parts_parameters SMALLINT NOT NULL');
+ $this->addSql('ALTER TABLE log CHANGE level level TINYINT');
+
+ $sql = 'UPDATE `groups`' .
+ 'SET perms_parts_parameters = 341 WHERE (id = 1 AND name = "admins") OR (id = 3 AND name = "users");';
+ $this->addSql($sql);
+
+ $sql = 'UPDATE `groups`' .
+ 'SET perms_parts_parameters = 681 WHERE (id = 2 AND name = "readonly");';
+ $this->addSql($sql);
+
+ $this->write('
[!!!] Permissions were updated! Please check if they fit your expectations!');
+ }
+
+ public function down(Schema $schema): void
+ {
+ // this down() migration is auto-generated, please modify it to your needs
+ $this->abortIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\'.');
+
+ $this->addSql('DROP TABLE parameters');
+ $this->addSql('ALTER TABLE `groups` DROP perms_parts_parameters');
+ $this->addSql('ALTER TABLE `users` DROP perms_parts_parameters');
+ $this->addSql('ALTER TABLE log CHANGE level level TINYINT(1) DEFAULT NULL');
+ }
+}
diff --git a/src/Repository/AttachmentRepository.php b/src/Repository/AttachmentRepository.php
index f8b78e41..76a14589 100644
--- a/src/Repository/AttachmentRepository.php
+++ b/src/Repository/AttachmentRepository.php
@@ -1,4 +1,7 @@
where('attachment.path LIKE :like');
$qb->setParameter('like', '\\%SECURE\\%%');
$query = $qb->getQuery();
+
return (int) $query->getSingleScalarResult();
}
/**
- * Gets the count of all external attachments (attachments only containing an URL)
+ * Gets the count of all external attachments (attachments only containing an URL).
+ *
* @return int
+ *
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
@@ -54,12 +58,15 @@ class AttachmentRepository extends DBElementRepository
$qb->setParameter('http', 'http://%');
$qb->setParameter('https', 'https://%');
$query = $qb->getQuery();
+
return (int) $query->getSingleScalarResult();
}
/**
* Gets the count of all attachments where an user uploaded an file.
+ *
* @return int
+ *
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
@@ -74,6 +81,7 @@ class AttachmentRepository extends DBElementRepository
$qb->setParameter('base', '\\%BASE\\%%');
$qb->setParameter('media', '\\%MEDIA\\%%');
$query = $qb->getQuery();
+
return (int) $query->getSingleScalarResult();
}
-}
\ No newline at end of file
+}
diff --git a/src/Repository/DBElementRepository.php b/src/Repository/DBElementRepository.php
index 94b19ec2..ae7a9da9 100644
--- a/src/Repository/DBElementRepository.php
+++ b/src/Repository/DBElementRepository.php
@@ -1,4 +1,7 @@
setField($element, 'id', $new_id);
}
- protected function setField(AbstractDBElement $element, string $field, $new_value)
+ protected function setField(AbstractDBElement $element, string $field, $new_value): void
{
$reflection = new \ReflectionClass(get_class($element));
$property = $reflection->getProperty($field);
$property->setAccessible(true);
$property->setValue($element, $new_value);
}
-}
\ No newline at end of file
+}
diff --git a/src/Repository/LogEntryRepository.php b/src/Repository/LogEntryRepository.php
index 53c9b4d9..313a57be 100644
--- a/src/Repository/LogEntryRepository.php
+++ b/src/Repository/LogEntryRepository.php
@@ -49,8 +49,6 @@ use App\Entity\LogSystem\ElementCreatedLogEntry;
use App\Entity\LogSystem\ElementDeletedLogEntry;
use App\Entity\LogSystem\ElementEditedLogEntry;
use App\Entity\UserSystem\User;
-use Doctrine\ORM\EntityRepository;
-use Doctrine\ORM\QueryBuilder;
class LogEntryRepository extends DBElementRepository
{
@@ -72,9 +70,9 @@ class LogEntryRepository extends DBElementRepository
* Find log entries associated with the given element (the history of the element).
*
* @param AbstractDBElement $element The element for which the history should be generated
- * @param string $order By default newest entries are shown first. Change this to ASC to show oldest entries first.
- * @param null $limit
- * @param null $offset
+ * @param string $order By default newest entries are shown first. Change this to ASC to show oldest entries first.
+ * @param null $limit
+ * @param null $offset
*
* @return AbstractLogEntry[]
*/
@@ -84,9 +82,11 @@ class LogEntryRepository extends DBElementRepository
}
/**
- * Try to get a log entry that contains the information to undete a given element
- * @param string $class The class of the element that should be undeleted
- * @param int $id The ID of the element that should be deleted
+ * Try to get a log entry that contains the information to undete a given element.
+ *
+ * @param string $class The class of the element that should be undeleted
+ * @param int $id The ID of the element that should be deleted
+ *
* @return ElementDeletedLogEntry
*/
public function getUndeleteDataForElement(string $class, int $id): ElementDeletedLogEntry
@@ -94,31 +94,34 @@ class LogEntryRepository extends DBElementRepository
$qb = $this->createQueryBuilder('log');
$qb->select('log')
//->where('log INSTANCE OF App\Entity\LogSystem\ElementEditedLogEntry')
- ->where('log INSTANCE OF ' . ElementDeletedLogEntry::class)
+ ->where('log INSTANCE OF '.ElementDeletedLogEntry::class)
->andWhere('log.target_type = :target_type')
->andWhere('log.target_id = :target_id')
->orderBy('log.timestamp', 'DESC')
->setMaxResults(1);
$qb->setParameters([
- 'target_type' => AbstractLogEntry::targetTypeClassToID($class),
- 'target_id' => $id,
- ]);
+ 'target_type' => AbstractLogEntry::targetTypeClassToID($class),
+ 'target_id' => $id,
+ ]);
- $query = $qb->getQuery();
+ $query = $qb->getQuery();
$results = $query->execute();
if (empty($results)) {
- throw new \RuntimeException("No undelete data could be found for this element");
+ throw new \RuntimeException('No undelete data could be found for this element');
}
+
return $results[0];
}
/**
- * Gets all log entries that are related to time travelling
- * @param AbstractDBElement $element The element for which the time travel data should be retrieved
- * @param \DateTime $until Back to which timestamp should the data be get (including the timestamp)
+ * Gets all log entries that are related to time travelling.
+ *
+ * @param AbstractDBElement $element The element for which the time travel data should be retrieved
+ * @param \DateTime $until Back to which timestamp should the data be get (including the timestamp)
+ *
* @return AbstractLogEntry[]
*/
public function getTimetravelDataForElement(AbstractDBElement $element, \DateTime $until): array
@@ -126,48 +129,49 @@ class LogEntryRepository extends DBElementRepository
$qb = $this->createQueryBuilder('log');
$qb->select('log')
//->where('log INSTANCE OF App\Entity\LogSystem\ElementEditedLogEntry')
- ->where('log INSTANCE OF ' . ElementEditedLogEntry::class)
- ->orWhere('log INSTANCE OF ' . CollectionElementDeleted::class)
+ ->where('log INSTANCE OF '.ElementEditedLogEntry::class)
+ ->orWhere('log INSTANCE OF '.CollectionElementDeleted::class)
->andWhere('log.target_type = :target_type')
->andWhere('log.target_id = :target_id')
->andWhere('log.timestamp >= :until')
->orderBy('log.timestamp', 'DESC');
$qb->setParameters([
- 'target_type' => AbstractLogEntry::targetTypeClassToID(get_class($element)),
- 'target_id' => $element->getID(),
- 'until' => $until
- ]);
+ 'target_type' => AbstractLogEntry::targetTypeClassToID(get_class($element)),
+ 'target_id' => $element->getID(),
+ 'until' => $until,
+ ]);
$query = $qb->getQuery();
+
return $query->execute();
}
/**
- * Check if the given element has existed at the given timestamp
- * @param AbstractDBElement $element
- * @param \DateTime $timestamp
+ * Check if the given element has existed at the given timestamp.
+ *
* @return bool True if the element existed at the given timestamp
*/
public function getElementExistedAtTimestamp(AbstractDBElement $element, \DateTime $timestamp): bool
{
$qb = $this->createQueryBuilder('log');
$qb->select('count(log)')
- ->where('log INSTANCE OF ' . ElementCreatedLogEntry::class)
+ ->where('log INSTANCE OF '.ElementCreatedLogEntry::class)
->andWhere('log.target_type = :target_type')
->andWhere('log.target_id = :target_id')
->andWhere('log.timestamp >= :until')
->orderBy('log.timestamp', 'DESC');
$qb->setParameters([
- 'target_type' => AbstractLogEntry::targetTypeClassToID(get_class($element)),
- 'target_id' => $element->getID(),
- 'until' => $timestamp
- ]);
+ 'target_type' => AbstractLogEntry::targetTypeClassToID(get_class($element)),
+ 'target_id' => $element->getID(),
+ 'until' => $timestamp,
+ ]);
$query = $qb->getQuery();
$count = $query->getSingleScalarResult();
- return !($count > 0);
+
+ return ! ($count > 0);
}
/**
@@ -187,9 +191,9 @@ class LogEntryRepository extends DBElementRepository
/**
* Gets the target element associated with the logentry.
*
- * @param AbstractLogEntry $logEntry
* @return AbstractDBElement|null Returns the associated DBElement or null if the log either has no target or the element
- * was deleted from DB.
+ * was deleted from DB.
+ *
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
* @throws \Doctrine\ORM\TransactionRequiredException
@@ -206,34 +210,9 @@ class LogEntryRepository extends DBElementRepository
return $this->getEntityManager()->find($class, $id);
}
- protected function getLastUser(AbstractDBElement $element, string $class)
- {
- $qb = $this->createQueryBuilder('log');
- $qb->select('log')
- //->where('log INSTANCE OF App\Entity\LogSystem\ElementEditedLogEntry')
- ->where('log INSTANCE OF ' . $class)
- ->andWhere('log.target_type = :target_type')
- ->andWhere('log.target_id = :target_id')
- ->orderBy('log.timestamp', 'DESC');
-
- $qb->setParameters([
- 'target_type' => AbstractLogEntry::targetTypeClassToID(get_class($element)),
- 'target_id' => $element->getID()
- ]);
-
- $query = $qb->getQuery();
- $query->setMaxResults(1);
- /** @var AbstractLogEntry[] $results */
- $results = $query->execute();
- if (isset($results[0])) {
- return $results[0]->getUser();
- }
- return null;
- }
-
/**
* Returns the last user that has edited the given element.
- * @param AbstractDBElement $element
+ *
* @return User|null A user object, or null if no user could be determined.
*/
public function getLastEditingUser(AbstractDBElement $element): ?User
@@ -243,11 +222,37 @@ class LogEntryRepository extends DBElementRepository
/**
* Returns the user that has created the given element.
- * @param AbstractDBElement $element
+ *
* @return User|null A user object, or null if no user could be determined.
*/
public function getCreatingUser(AbstractDBElement $element): ?User
{
return $this->getLastUser($element, ElementCreatedLogEntry::class);
}
+
+ protected function getLastUser(AbstractDBElement $element, string $class)
+ {
+ $qb = $this->createQueryBuilder('log');
+ $qb->select('log')
+ //->where('log INSTANCE OF App\Entity\LogSystem\ElementEditedLogEntry')
+ ->where('log INSTANCE OF '.$class)
+ ->andWhere('log.target_type = :target_type')
+ ->andWhere('log.target_id = :target_id')
+ ->orderBy('log.timestamp', 'DESC');
+
+ $qb->setParameters([
+ 'target_type' => AbstractLogEntry::targetTypeClassToID(get_class($element)),
+ 'target_id' => $element->getID(),
+ ]);
+
+ $query = $qb->getQuery();
+ $query->setMaxResults(1);
+ /** @var AbstractLogEntry[] $results */
+ $results = $query->execute();
+ if (isset($results[0])) {
+ return $results[0]->getUser();
+ }
+
+ return null;
+ }
}
diff --git a/src/Repository/NamedDBElementRepository.php b/src/Repository/NamedDBElementRepository.php
index 404efed0..eb2348e4 100644
--- a/src/Repository/NamedDBElementRepository.php
+++ b/src/Repository/NamedDBElementRepository.php
@@ -44,7 +44,6 @@ namespace App\Repository;
use App\Entity\Base\AbstractNamedDBElement;
use App\Helpers\Trees\TreeViewNode;
-use Doctrine\ORM\EntityRepository;
class NamedDBElementRepository extends DBElementRepository
{
diff --git a/src/Repository/PartRepository.php b/src/Repository/PartRepository.php
index 0ac94932..8b21d0b8 100644
--- a/src/Repository/PartRepository.php
+++ b/src/Repository/PartRepository.php
@@ -43,14 +43,15 @@ declare(strict_types=1);
namespace App\Repository;
use App\Entity\Parts\PartLot;
-use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
class PartRepository extends NamedDBElementRepository
{
/**
- * Gets the summed up instock of all parts (only parts without an measurent unit)
+ * Gets the summed up instock of all parts (only parts without an measurent unit).
+ *
* @return string
+ *
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
@@ -63,12 +64,15 @@ class PartRepository extends NamedDBElementRepository
->where('part.partUnit IS NULL');
$query = $qb->getQuery();
+
return $query->getSingleScalarResult();
}
/**
* Gets the number of parts that has price informations.
+ *
* @return int
+ *
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
@@ -81,6 +85,7 @@ class PartRepository extends NamedDBElementRepository
->where('pricedetail.price > 0.0');
$query = $qb->getQuery();
+
return (int) $query->getSingleScalarResult();
}
}
diff --git a/src/Security/EntityListeners/ElementPermissionListener.php b/src/Security/EntityListeners/ElementPermissionListener.php
index 4c6c0c82..80e51aa1 100644
--- a/src/Security/EntityListeners/ElementPermissionListener.php
+++ b/src/Security/EntityListeners/ElementPermissionListener.php
@@ -198,9 +198,9 @@ class ElementPermissionListener
* Checks if access to the property of the given element is granted.
* This function adds an additional cache layer, where the voters are called only once (to improve performance).
*
- * @param string $mode What operation should be checked. Must be 'read' or 'edit'
- * @param ColumnSecurity $annotation The annotation of the property that should be checked
- * @param AbstractDBElement $element The element that should for which should be checked
+ * @param string $mode What operation should be checked. Must be 'read' or 'edit'
+ * @param ColumnSecurity $annotation The annotation of the property that should be checked
+ * @param AbstractDBElement $element The element that should for which should be checked
*
* @return bool True if the user is allowed to read that property
*/
diff --git a/src/Security/Voter/AttachmentVoter.php b/src/Security/Voter/AttachmentVoter.php
index 07cc9c25..01b86fe5 100644
--- a/src/Security/Voter/AttachmentVoter.php
+++ b/src/Security/Voter/AttachmentVoter.php
@@ -53,7 +53,7 @@ class AttachmentVoter extends ExtendedVoter
* The current user (or the anonymous user) is passed by $user.
*
* @param string $attribute
- * @param mixed $subject
+ *
* @return bool
*/
protected function voteOnUser($attribute, $subject, User $user): bool
diff --git a/src/Security/Voter/ExtendedVoter.php b/src/Security/Voter/ExtendedVoter.php
index 2e612ed8..8630373b 100644
--- a/src/Security/Voter/ExtendedVoter.php
+++ b/src/Security/Voter/ExtendedVoter.php
@@ -91,7 +91,7 @@ abstract class ExtendedVoter extends Voter
* The current user (or the anonymous user) is passed by $user.
*
* @param string $attribute
- * @param mixed $subject
+ *
* @return bool
*/
abstract protected function voteOnUser($attribute, $subject, User $user): bool;
diff --git a/src/Security/Voter/GroupVoter.php b/src/Security/Voter/GroupVoter.php
index 0201cbe5..c6eb405f 100644
--- a/src/Security/Voter/GroupVoter.php
+++ b/src/Security/Voter/GroupVoter.php
@@ -52,7 +52,7 @@ class GroupVoter extends ExtendedVoter
* The current user (or the anonymous user) is passed by $user.
*
* @param string $attribute
- * @param mixed $subject
+ *
* @return bool
*/
protected function voteOnUser($attribute, $subject, User $user): bool
diff --git a/src/Security/Voter/OrderdetailVoter.php b/src/Security/Voter/OrderdetailVoter.php
index f214685e..256d406f 100644
--- a/src/Security/Voter/OrderdetailVoter.php
+++ b/src/Security/Voter/OrderdetailVoter.php
@@ -1,4 +1,7 @@
resolver->inherit($user, 'parts_orderdetails', $attribute) ?? false;
}
- /**
- * @inheritDoc
- */
protected function supports($attribute, $subject)
{
if (is_a($subject, Orderdetail::class, true)) {
@@ -56,4 +51,4 @@ class OrderdetailVoter extends ExtendedVoter
return false;
}
-}
\ No newline at end of file
+}
diff --git a/src/Security/Voter/PartLotVoter.php b/src/Security/Voter/PartLotVoter.php
index cf022a73..0e985e48 100644
--- a/src/Security/Voter/PartLotVoter.php
+++ b/src/Security/Voter/PartLotVoter.php
@@ -1,4 +1,7 @@
resolver->inherit($user, 'parts_lots', $attribute) ?? false;
}
- /**
- * @inheritDoc
- */
protected function supports($attribute, $subject)
{
if (is_a($subject, PartLot::class, true)) {
@@ -55,4 +51,4 @@ class PartLotVoter extends ExtendedVoter
return false;
}
-}
\ No newline at end of file
+}
diff --git a/src/Security/Voter/PartVoter.php b/src/Security/Voter/PartVoter.php
index f829f557..ed29cdba 100644
--- a/src/Security/Voter/PartVoter.php
+++ b/src/Security/Voter/PartVoter.php
@@ -83,6 +83,5 @@ class PartVoter extends ExtendedVoter
//Null concealing operator means, that no
return $this->resolver->inherit($user, 'parts', $attribute) ?? false;
-
}
}
diff --git a/src/Security/Voter/PermissionVoter.php b/src/Security/Voter/PermissionVoter.php
index 5564349f..32383a80 100644
--- a/src/Security/Voter/PermissionVoter.php
+++ b/src/Security/Voter/PermissionVoter.php
@@ -56,7 +56,6 @@ class PermissionVoter extends ExtendedVoter
* The current user (or the anonymous user) is passed by $user.
*
* @param string $attribute
- * @param mixed $subject
*/
protected function voteOnUser($attribute, $subject, User $user): bool
{
diff --git a/src/Security/Voter/PricedetailVoter.php b/src/Security/Voter/PricedetailVoter.php
index e4ec0251..d222df54 100644
--- a/src/Security/Voter/PricedetailVoter.php
+++ b/src/Security/Voter/PricedetailVoter.php
@@ -1,4 +1,7 @@
resolver->inherit($user, 'parts_prices', $attribute) ?? false;
}
- /**
- * @inheritDoc
- */
protected function supports($attribute, $subject)
{
if (is_a($subject, Pricedetail::class, true)) {
@@ -56,4 +51,4 @@ class PricedetailVoter extends ExtendedVoter
return false;
}
-}
\ No newline at end of file
+}
diff --git a/src/Security/Voter/StructureVoter.php b/src/Security/Voter/StructureVoter.php
index d5d6eb51..af01b75a 100644
--- a/src/Security/Voter/StructureVoter.php
+++ b/src/Security/Voter/StructureVoter.php
@@ -43,13 +43,11 @@ declare(strict_types=1);
namespace App\Security\Voter;
use App\Entity\Attachments\AttachmentType;
-use App\Entity\Base\AbstractStructuralDBElement;
use App\Entity\Devices\Device;
use App\Entity\Parts\Category;
use App\Entity\Parts\Footprint;
use App\Entity\Parts\Manufacturer;
use App\Entity\Parts\MeasurementUnit;
-use App\Entity\Parts\Part;
use App\Entity\Parts\Storelocation;
use App\Entity\Parts\Supplier;
use App\Entity\PriceInformations\Currency;
@@ -87,7 +85,7 @@ class StructureVoter extends ExtendedVoter
*/
protected function instanceToPermissionName($subject): ?string
{
- if (!is_string($subject)) {
+ if (! is_string($subject)) {
$class_name = get_class($subject);
} else {
$class_name = $subject;
@@ -121,7 +119,7 @@ class StructureVoter extends ExtendedVoter
* The current user (or the anonymous user) is passed by $user.
*
* @param string $attribute
- * @param mixed $subject
+ *
* @return bool
*/
protected function voteOnUser($attribute, $subject, User $user): bool
diff --git a/src/Security/Voter/UserVoter.php b/src/Security/Voter/UserVoter.php
index de7d165b..333c365d 100644
--- a/src/Security/Voter/UserVoter.php
+++ b/src/Security/Voter/UserVoter.php
@@ -73,7 +73,7 @@ class UserVoter extends ExtendedVoter
* The current user (or the anonymous user) is passed by $user.
*
* @param string $attribute
- * @param mixed $subject
+ *
* @return bool
*/
protected function voteOnUser($attribute, $subject, User $user): bool
diff --git a/src/Services/ElementTypeNameGenerator.php b/src/Services/ElementTypeNameGenerator.php
index 319d504d..64362435 100644
--- a/src/Services/ElementTypeNameGenerator.php
+++ b/src/Services/ElementTypeNameGenerator.php
@@ -45,9 +45,9 @@ namespace App\Services;
use App\Entity\Attachments\Attachment;
use App\Entity\Attachments\AttachmentType;
use App\Entity\Base\AbstractDBElement;
-use App\Entity\Base\AbstractNamedDBElement;
use App\Entity\Contracts\NamedElementInterface;
use App\Entity\Devices\Device;
+use App\Entity\Parameters\AbstractParameter;
use App\Entity\Parts\Category;
use App\Entity\Parts\Footprint;
use App\Entity\Parts\Manufacturer;
@@ -92,6 +92,7 @@ class ElementTypeNameGenerator
Pricedetail::class => $this->translator->trans('pricedetail.label'),
Group::class => $this->translator->trans('group.label'),
User::class => $this->translator->trans('user.label'),
+ AbstractParameter::class => $this->translator->trans('parameter.label'),
];
}
@@ -124,7 +125,7 @@ class ElementTypeNameGenerator
}
//When nothing was found throw an exception
- throw new EntityNotSupportedException(sprintf('No localized label for the element with type %s was found!', get_class($entity)));
+ throw new EntityNotSupportedException(sprintf('No localized label for the element with type %s was found!', is_object($entity) ? get_class($entity) : (string) $entity));
}
/**
@@ -133,7 +134,7 @@ class ElementTypeNameGenerator
* It uses getLocalizedLabel to determine the type.
*
* @param NamedElementInterface $entity the entity for which the string should be generated
- * @param bool $use_html If set to true, a html string is returned, where the type is set italic
+ * @param bool $use_html If set to true, a html string is returned, where the type is set italic
*
* @return string The localized string
*
diff --git a/src/Services/EntityExporter.php b/src/Services/EntityExporter.php
index d55e09ba..8afb3b8e 100644
--- a/src/Services/EntityExporter.php
+++ b/src/Services/EntityExporter.php
@@ -43,14 +43,6 @@ declare(strict_types=1);
namespace App\Services;
use App\Entity\Base\AbstractNamedDBElement;
-use Symfony\Component\Serializer\Encoder\CsvEncoder;
-use Symfony\Component\Serializer\Encoder\JsonEncoder;
-use Symfony\Component\Serializer\Encoder\XmlEncoder;
-use Symfony\Component\Serializer\Encoder\YamlEncoder;
-use Symfony\Component\Serializer\Normalizer\DataUriNormalizer;
-use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
-use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
-use Symfony\Component\Serializer\Serializer;
use function in_array;
use InvalidArgumentException;
use function is_array;
@@ -59,6 +51,13 @@ use ReflectionException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
+use Symfony\Component\Serializer\Encoder\CsvEncoder;
+use Symfony\Component\Serializer\Encoder\JsonEncoder;
+use Symfony\Component\Serializer\Encoder\XmlEncoder;
+use Symfony\Component\Serializer\Encoder\YamlEncoder;
+use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
+use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
+use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\SerializerInterface;
/**
diff --git a/src/Services/EntityImporter.php b/src/Services/EntityImporter.php
index 475b63db..f65aff3e 100644
--- a/src/Services/EntityImporter.php
+++ b/src/Services/EntityImporter.php
@@ -43,7 +43,6 @@ declare(strict_types=1);
namespace App\Services;
use App\Entity\Base\AbstractStructuralDBElement;
-use Symfony\Bundle\MakerBundle\Str;
use function count;
use Doctrine\ORM\EntityManagerInterface;
use InvalidArgumentException;
@@ -70,10 +69,10 @@ class EntityImporter
* Creates many entries at once, based on a (text) list of name.
* The created enties are not persisted to database yet, so you have to do it yourself.
*
- * @param string $lines The list of names seperated by \n
- * @param string $class_name The name of the class for which the entities should be created
+ * @param string $lines The list of names seperated by \n
+ * @param string $class_name The name of the class for which the entities should be created
* @param AbstractStructuralDBElement|null $parent the element which will be used as parent element for new elements
- * @param array $errors an associative array containing all validation errors
+ * @param array $errors an associative array containing all validation errors
*
* @return AbstractStructuralDBElement[] An array containing all valid imported entities (with the type $class_name)
*/
@@ -228,8 +227,8 @@ class EntityImporter
/**
* This functions corrects the parent setting based on the children value of the parent.
*
- * @param iterable $entities the list of entities that should be fixed
- * @param null|AbstractStructuralDBElement $parent the parent, to which the entity should be set
+ * @param iterable $entities the list of entities that should be fixed
+ * @param AbstractStructuralDBElement|null $parent the parent, to which the entity should be set
*/
protected function correctParentEntites(iterable $entities, $parent = null): void
{
diff --git a/src/Services/EntityURLGenerator.php b/src/Services/EntityURLGenerator.php
index 28d691e6..0f54e960 100644
--- a/src/Services/EntityURLGenerator.php
+++ b/src/Services/EntityURLGenerator.php
@@ -125,9 +125,8 @@ class EntityURLGenerator
}
/**
- * Gets the URL to view the given element at a given timestamp
- * @param AbstractDBElement $entity
- * @param \DateTime $dateTime
+ * Gets the URL to view the given element at a given timestamp.
+ *
* @return string
*/
public function timeTravelURL(AbstractDBElement $entity, \DateTime $dateTime): string
@@ -154,32 +153,32 @@ class EntityURLGenerator
$this->mapToController($map, $entity),
[
'id' => $entity->getID(),
- 'timestamp' => $dateTime->getTimestamp()
+ 'timestamp' => $dateTime->getTimestamp(),
]
);
} catch (EntityNotSupportedException $exception) {
if ($entity instanceof PartLot) {
return $this->urlGenerator->generate('part_info', [
'id' => $entity->getPart()->getID(),
- 'timestamp' => $dateTime->getTimestamp()
+ 'timestamp' => $dateTime->getTimestamp(),
]);
}
if ($entity instanceof PartAttachment) {
return $this->urlGenerator->generate('part_info', [
'id' => $entity->getElement()->getID(),
- 'timestamp' => $dateTime->getTimestamp()
+ 'timestamp' => $dateTime->getTimestamp(),
]);
}
if ($entity instanceof Orderdetail) {
return $this->urlGenerator->generate('part_info', [
'id' => $entity->getPart()->getID(),
- 'timestamp' => $dateTime->getTimestamp()
+ 'timestamp' => $dateTime->getTimestamp(),
]);
}
if ($entity instanceof Pricedetail) {
return $this->urlGenerator->generate('part_info', [
'id' => $entity->getOrderdetail()->getPart()->getID(),
- 'timestamp' => $dateTime->getTimestamp()
+ 'timestamp' => $dateTime->getTimestamp(),
]);
}
}
diff --git a/src/Services/LogSystem/EventCommentHelper.php b/src/Services/LogSystem/EventCommentHelper.php
index 6a7b25fc..04d8ce0a 100644
--- a/src/Services/LogSystem/EventCommentHelper.php
+++ b/src/Services/LogSystem/EventCommentHelper.php
@@ -1,4 +1,7 @@
message = mb_strimwidth($message, 0, self::MAX_MESSAGE_LENGTH, '...');
+ if ($message) {
+ $this->message = mb_strimwidth($message, 0, self::MAX_MESSAGE_LENGTH, '...');
+ } else {
+ $this->message = null;
+ }
}
/**
* Returns the currently set message, or null if no message is set yet.
+ *
* @return string|null
*/
public function getMessage(): ?string
@@ -63,10 +69,11 @@ class EventCommentHelper
/**
* Check if a message is currently set.
+ *
* @return bool
*/
public function isMessageSet(): bool
{
return is_string($this->message);
}
-}
\ No newline at end of file
+}
diff --git a/src/Services/LogSystem/EventUndoHelper.php b/src/Services/LogSystem/EventUndoHelper.php
index f61171e9..a9714f17 100644
--- a/src/Services/LogSystem/EventUndoHelper.php
+++ b/src/Services/LogSystem/EventUndoHelper.php
@@ -1,4 +1,7 @@
mode = $mode;
@@ -55,7 +57,6 @@ class EventUndoHelper
/**
* Set which event log is currently undone.
* After the flush this message is cleared.
- * @param AbstractLogEntry|null $undone_event
*/
public function setUndoneEvent(?AbstractLogEntry $undone_event): void
{
@@ -64,6 +65,7 @@ class EventUndoHelper
/**
* Returns event that is currently undone.
+ *
* @return AbstractLogEntry|null
*/
public function getUndoneEvent(): ?AbstractLogEntry
@@ -80,11 +82,12 @@ class EventUndoHelper
}
/**
- * Check if a event is undone
+ * Check if a event is undone.
+ *
* @return bool
*/
public function isUndo(): bool
{
- return ($this->undone_event instanceof AbstractLogEntry);
+ return $this->undone_event instanceof AbstractLogEntry;
}
-}
\ No newline at end of file
+}
diff --git a/src/Services/LogSystem/HistoryHelper.php b/src/Services/LogSystem/HistoryHelper.php
index 32ee98b8..88a209e4 100644
--- a/src/Services/LogSystem/HistoryHelper.php
+++ b/src/Services/LogSystem/HistoryHelper.php
@@ -1,4 +1,7 @@
getParameters()->toArray());
+ }
+
return $array;
}
-}
\ No newline at end of file
+}
diff --git a/src/Services/LogSystem/LogEntryExtraFormatter.php b/src/Services/LogSystem/LogEntryExtraFormatter.php
index b28623d8..74402f3c 100644
--- a/src/Services/LogSystem/LogEntryExtraFormatter.php
+++ b/src/Services/LogSystem/LogEntryExtraFormatter.php
@@ -56,7 +56,6 @@ use App\Entity\LogSystem\UserLoginLogEntry;
use App\Entity\LogSystem\UserLogoutLogEntry;
use App\Entity\LogSystem\UserNotAllowedLogEntry;
use App\Services\ElementTypeNameGenerator;
-use Doctrine\ORM\EntityManagerInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
@@ -64,12 +63,11 @@ use Symfony\Contracts\Translation\TranslatorInterface;
*/
class LogEntryExtraFormatter
{
+ protected const CONSOLE_SEARCH = ['
', '
', '', '
', ''];
+ protected const CONSOLE_REPLACE = ['→', '
', '', '
', ''];
protected $translator;
protected $elementTypeNameGenerator;
- protected const CONSOLE_SEARCH = ['
', '
', '', '
', '', ];
- protected const CONSOLE_REPLACE = ['→', '
', '', '
', ''];
-
public function __construct(TranslatorInterface $translator, ElementTypeNameGenerator $elementTypeNameGenerator)
{
$this->translator = $translator;
@@ -90,15 +88,40 @@ class LogEntryExtraFormatter
foreach ($arr as $key => $value) {
$str = '';
if (is_string($key)) {
- $str .= '
' . $this->translator->trans($key) . ': ';
+ $str .= '
'.$this->translator->trans($key).': ';
}
$str .= $value;
- if (!empty($str)) {
+ if (! empty($str)) {
$tmp[] = $str;
}
}
- return str_replace(static::CONSOLE_SEARCH, static::CONSOLE_REPLACE, implode("; ", $tmp));
+ return str_replace(static::CONSOLE_SEARCH, static::CONSOLE_REPLACE, implode('; ', $tmp));
+ }
+
+ /**
+ * Return a HTML formatted string containing a user viewable form of the Extra data.
+ *
+ * @return string
+ */
+ public function format(AbstractLogEntry $context): string
+ {
+ $arr = $this->getInternalFormat($context);
+ $tmp = [];
+
+ //Make an array with entries in the form "
Key: Value"
+ foreach ($arr as $key => $value) {
+ $str = '';
+ if (is_string($key)) {
+ $str .= '
'.$this->translator->trans($key).': ';
+ }
+ $str .= $value;
+ if (! empty($str)) {
+ $tmp[] = $str;
+ }
+ }
+
+ return implode('; ', $tmp);
}
protected function getInternalFormat(AbstractLogEntry $context): array
@@ -129,9 +152,9 @@ class LogEntryExtraFormatter
if ($context instanceof LogWithEventUndoInterface) {
if ($context->isUndoEvent()) {
- if ($context->getUndoMode() === 'undo') {
+ if ('undo' === $context->getUndoMode()) {
$array['log.undo_mode.undo'] = (string) $context->getUndoEventID();
- } elseif ($context->getUndoMode() === 'revert') {
+ } elseif ('revert' === $context->getUndoMode()) {
$array['log.undo_mode.revert'] = (string) $context->getUndoEventID();
}
}
@@ -146,7 +169,7 @@ class LogEntryExtraFormatter
}
if ($context instanceof ElementDeletedLogEntry) {
- if ($context->getOldName() !== null) {
+ if (null !== $context->getOldName()) {
$array['log.element_deleted.old_name'] = htmlspecialchars($context->getOldName());
} else {
$array['log.element_deleted.old_name'] = $this->translator->trans('log.element_deleted.old_name.unknown');
@@ -183,29 +206,4 @@ class LogEntryExtraFormatter
return $array;
}
-
- /**
- * Return a HTML formatted string containing a user viewable form of the Extra data.
- *
- * @return string
- */
- public function format(AbstractLogEntry $context): string
- {
- $arr = $this->getInternalFormat($context);
- $tmp = [];
-
- //Make an array with entries in the form "
Key: Value"
- foreach ($arr as $key => $value) {
- $str = '';
- if (is_string($key)) {
- $str .= '
' . $this->translator->trans($key) . ': ';
- }
- $str .= $value;
- if (!empty($str)) {
- $tmp[] = $str;
- }
- }
-
- return implode("; ", $tmp);
- }
}
diff --git a/src/Services/LogSystem/TimeTravel.php b/src/Services/LogSystem/TimeTravel.php
index 54e9fa72..f8548e83 100644
--- a/src/Services/LogSystem/TimeTravel.php
+++ b/src/Services/LogSystem/TimeTravel.php
@@ -1,4 +1,7 @@
setField($element, 'id', $id);
//Let database determine when it will be created
- $this->setField($element,'addedDate', null);
+ $this->setField($element, 'addedDate', null);
return $element;
}
/**
- * Revert the given element to the state it has on the given timestamp
- * @param AbstractDBElement $element
- * @param \DateTime $timestamp
- * @param AbstractLogEntry[] $reverted_elements
+ * Revert the given element to the state it has on the given timestamp.
+ *
+ * @param AbstractLogEntry[] $reverted_elements
+ *
* @throws \Exception
*/
- public function revertEntityToTimestamp(AbstractDBElement $element, \DateTime $timestamp, array $reverted_elements = [])
+ public function revertEntityToTimestamp(AbstractDBElement $element, \DateTime $timestamp, array $reverted_elements = []): void
{
- if (!$element instanceof TimeStampableInterface) {
+ if (! $element instanceof TimeStampableInterface) {
throw new \InvalidArgumentException('$element must have a Timestamp!');
}
@@ -84,7 +88,7 @@ class TimeTravel
}
//Skip this process if already were reverted...
- if (in_array($element, $reverted_elements)) {
+ if (in_array($element, $reverted_elements, true)) {
return;
}
$reverted_elements[] = $element;
@@ -122,35 +126,34 @@ class TimeTravel
$associations = $metadata->getAssociationMappings();
foreach ($associations as $field => $mapping) {
if (
- ($element instanceof AbstractStructuralDBElement && ($field === 'parts' || $field === 'children'))
- || ($element instanceof AttachmentType && $field === 'attachments')
+ ($element instanceof AbstractStructuralDBElement && ('parts' === $field || 'children' === $field))
+ || ($element instanceof AttachmentType && 'attachments' === $field)
) {
continue;
}
-
//Revert many to one association (one element in property)
if (
- $mapping['type'] === ClassMetadata::MANY_TO_ONE
- || $mapping['type'] === ClassMetadata::ONE_TO_ONE
+ ClassMetadata::MANY_TO_ONE === $mapping['type']
+ || ClassMetadata::ONE_TO_ONE === $mapping['type']
) {
$target_element = $this->getField($element, $field);
- if ($target_element !== null && $element->getLastModified() > $timestamp) {
+ if (null !== $target_element && $element->getLastModified() > $timestamp) {
$this->revertEntityToTimestamp($target_element, $timestamp, $reverted_elements);
}
} elseif ( //Revert *_TO_MANY associations (collection properties)
- ($mapping['type'] === ClassMetadata::MANY_TO_MANY
- || $mapping['type'] === ClassMetadata::ONE_TO_MANY)
- && $mapping['isOwningSide'] === false
+ (ClassMetadata::MANY_TO_MANY === $mapping['type']
+ || ClassMetadata::ONE_TO_MANY === $mapping['type'])
+ && false === $mapping['isOwningSide']
) {
$target_elements = $this->getField($element, $field);
- if ($target_elements === null || count($target_elements) > 10) {
+ if (null === $target_elements || count($target_elements) > 10) {
continue;
}
foreach ($target_elements as $target_element) {
- if ($target_element !== null && $element->getLastModified() >= $timestamp) {
+ if (null !== $target_element && $element->getLastModified() >= $timestamp) {
//Remove the element from collection, if it did not existed at $timestamp
- if (!$this->repo->getElementExistedAtTimestamp($target_element, $timestamp)) {
+ if (! $this->repo->getElementExistedAtTimestamp($target_element, $timestamp)) {
if ($target_elements instanceof Collection) {
$target_elements->removeElement($target_element);
}
@@ -159,23 +162,21 @@ class TimeTravel
}
}
}
-
}
}
/**
- * Apply the changeset in the given LogEntry to the element
- * @param AbstractDBElement $element
- * @param TimeTravelInterface $logEntry
+ * Apply the changeset in the given LogEntry to the element.
+ *
* @throws \Doctrine\ORM\Mapping\MappingException
*/
public function applyEntry(AbstractDBElement $element, TimeTravelInterface $logEntry): void
{
//Skip if this does not provide any info...
- if (!$logEntry->hasOldDataInformations()) {
+ if (! $logEntry->hasOldDataInformations()) {
return;
}
- if (!$element instanceof TimeStampableInterface) {
+ if (! $element instanceof TimeStampableInterface) {
return;
}
$metadata = $this->em->getClassMetadata(get_class($element));
@@ -204,14 +205,15 @@ class TimeTravel
$reflection = new \ReflectionClass(get_class($element));
$property = $reflection->getProperty($field);
$property->setAccessible(true);
+
return $property->getValue($element);
}
- protected function setField(AbstractDBElement $element, string $field, $new_value)
+ protected function setField(AbstractDBElement $element, string $field, $new_value): void
{
$reflection = new \ReflectionClass(get_class($element));
$property = $reflection->getProperty($field);
$property->setAccessible(true);
$property->setValue($element, $new_value);
}
-}
\ No newline at end of file
+}
diff --git a/src/Services/Parameters/ParameterExtractor.php b/src/Services/Parameters/ParameterExtractor.php
new file mode 100644
index 00000000..a01ce327
--- /dev/null
+++ b/src/Services/Parameters/ParameterExtractor.php
@@ -0,0 +1,97 @@
+.
+ */
+
+namespace App\Services\Parameters;
+
+
+use App\Entity\Parameters\AbstractParameter;
+use App\Entity\Parameters\PartParameter;
+
+class ParameterExtractor
+{
+ protected const ALLOWED_PARAM_SEPARATORS = [", ", "\n"];
+
+ protected const CHAR_LIMIT = 1000;
+
+ /**
+ * Tries to extract parameters from the given string.
+ * Useful for extraction from part description and comment.
+ * @param string $input
+ * @param string $class
+ * @return AbstractParameter[]
+ */
+ public function extractParameters(string $input, string $class = PartParameter::class): array
+ {
+ if (!is_a($class, AbstractParameter::class, true)) {
+ throw new \InvalidArgumentException('$class must be a child class of AbstractParameter!');
+ }
+
+ //Restrict search length
+ $input = mb_strimwidth($input,0,self::CHAR_LIMIT);
+
+ $parameters = [];
+
+ //Try to split the input string into different sub strings each containing a single parameter
+ $split = $this->splitString($input);
+ foreach ($split as $param_string) {
+ $tmp = $this->stringToParam($param_string, $class);
+ if ($tmp !== null) {
+ $parameters[] = $tmp;
+ }
+ }
+
+ return $parameters;
+ }
+
+ protected function stringToParam(string $input, string $class): ?AbstractParameter
+ {
+ $input = trim($input);
+ $regex = '/^(.*) *(?:=|:) *(.+)/u';
+
+ $matches = [];
+ \preg_match($regex, $input, $matches);
+ dump($matches);
+ if (!empty($matches)) {
+ [$raw, $name, $value] = $matches;
+ $value = trim($value);
+
+ //Dont allow empty names or values (these are a sign of an invalid extracted string)
+ if (empty($name) || empty($value)) {
+ return null;
+ }
+
+ /** @var AbstractParameter $parameter */
+ $parameter = new $class();
+ $parameter->setName(trim($name));
+ $parameter->setValueText($value);
+
+ return $parameter;
+ }
+
+ return null;
+ }
+
+ protected function splitString(string $input): array
+ {
+ //Allow comma as limiter (include space, to prevent splitting in german style numbers)
+ $input = str_replace(static::ALLOWED_PARAM_SEPARATORS, ";", $input);
+ return explode(";", $input);
+ }
+}
\ No newline at end of file
diff --git a/src/Services/PermissionResolver.php b/src/Services/PermissionResolver.php
index e26e06e8..15cb5845 100644
--- a/src/Services/PermissionResolver.php
+++ b/src/Services/PermissionResolver.php
@@ -50,7 +50,6 @@ use Symfony\Component\Config\ConfigCache;
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\DependencyInjection\ContainerInterface;
-use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Yaml\Yaml;
class PermissionResolver
diff --git a/src/Services/StatisticsHelper.php b/src/Services/StatisticsHelper.php
index c9305128..f5174bce 100644
--- a/src/Services/StatisticsHelper.php
+++ b/src/Services/StatisticsHelper.php
@@ -1,4 +1,7 @@
Currency::class,
];
- if (!isset($arr[$type])) {
+ if (! isset($arr[$type])) {
throw new \InvalidArgumentException('No count for the given type available!');
}
/** @var EntityRepository $repo */
$repo = $this->em->getRepository($arr[$type]);
+
return $repo->count([]);
}
/**
* Gets the count of all attachments.
+ *
* @return int
*/
public function getAttachmentsCount(): int
@@ -116,7 +124,8 @@ class StatisticsHelper
}
/**
- * Gets the count of all private/secure attachments
+ * Gets the count of all private/secure attachments.
+ *
* @return int
*/
public function getPrivateAttachmentsCount(): int
@@ -125,8 +134,10 @@ class StatisticsHelper
}
/**
- * Gets the count of all external (only containing an URL) attachments
+ * Gets the count of all external (only containing an URL) attachments.
+ *
* @return int
+ *
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
@@ -137,7 +148,9 @@ class StatisticsHelper
/**
* Gets the count of all attachments where the user uploaded an file.
+ *
* @return int
+ *
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
*/
@@ -145,4 +158,4 @@ class StatisticsHelper
{
return $this->attachment_repo->getUserUploadedAttachments();
}
-}
\ No newline at end of file
+}
diff --git a/src/Services/StructuralElementRecursionHelper.php b/src/Services/StructuralElementRecursionHelper.php
index f22c027c..23ad2f84 100644
--- a/src/Services/StructuralElementRecursionHelper.php
+++ b/src/Services/StructuralElementRecursionHelper.php
@@ -58,12 +58,12 @@ class StructuralElementRecursionHelper
* Executes an function (callable) recursivly for $element and every of its children.
*
* @param AbstractStructuralDBElement $element The element on which the func should be executed
- * @param callable $func The function which should be executed for each element.
- * $func has the signature function(StructuralDBElement $element) : void
- * @param int $max_depth The maximum depth for which should be recursivly called. So if this is set to 5, after the
- * 5th level the execution is stopped.
- * @param bool $call_from_bottom If set to true the bottom elements (elements with high level) will be called first.
- * Set to false if you want to call the top elements first.
+ * @param callable $func The function which should be executed for each element.
+ * $func has the signature function(StructuralDBElement $element) : void
+ * @param int $max_depth The maximum depth for which should be recursivly called. So if this is set to 5, after the
+ * 5th level the execution is stopped.
+ * @param bool $call_from_bottom If set to true the bottom elements (elements with high level) will be called first.
+ * Set to false if you want to call the top elements first.
*/
public function execute(AbstractStructuralDBElement $element, callable $func, int $max_depth = -1, $call_from_bottom = true): void
{
@@ -94,8 +94,8 @@ class StructuralElementRecursionHelper
* Deletes the $element and all its subelements recursivly.
*
* @param AbstractStructuralDBElement $element the element which should be deleted
- * @param bool $flush When set to true the changes will also be flushed to DB. Set to false if you want to flush
- * later.
+ * @param bool $flush When set to true the changes will also be flushed to DB. Set to false if you want to flush
+ * later.
*/
public function delete(AbstractStructuralDBElement $element, bool $flush = true): void
{
diff --git a/src/Services/Trees/NodesListBuilder.php b/src/Services/Trees/NodesListBuilder.php
index 361b4e0d..b108b315 100644
--- a/src/Services/Trees/NodesListBuilder.php
+++ b/src/Services/Trees/NodesListBuilder.php
@@ -69,7 +69,7 @@ class NodesListBuilder
* Gets a flattened hierachical tree. Useful for generating option lists.
* In difference to the Repository Function, the results here are cached.
*
- * @param string $class_name The class name of the entity you want to retrieve.
+ * @param string $class_name The class name of the entity you want to retrieve.
* @param AbstractStructuralDBElement|null $parent This entity will be used as root element. Set to null, to use global root
*
* @return AbstractStructuralDBElement[] A flattened list containing the tree elements.
diff --git a/src/Services/Trees/TreeViewGenerator.php b/src/Services/Trees/TreeViewGenerator.php
index e98a7f46..44334cf9 100644
--- a/src/Services/Trees/TreeViewGenerator.php
+++ b/src/Services/Trees/TreeViewGenerator.php
@@ -76,10 +76,10 @@ class TreeViewGenerator
/**
* Gets a TreeView list for the entities of the given class.
*
- * @param string $class The class for which the treeView should be generated
+ * @param string $class The class for which the treeView should be generated
* @param AbstractStructuralDBElement|null $parent The root nodes in the tree should have this element as parent (use null, if you want to get all entities)
- * @param string $href_type The link type that will be generated for the hyperlink section of each node (see EntityURLGenerator for possible values).
- * Set to empty string, to disable href field.
+ * @param string $href_type The link type that will be generated for the hyperlink section of each node (see EntityURLGenerator for possible values).
+ * Set to empty string, to disable href field.
* @param AbstractDBElement|null $selectedElement The element that should be selected. If set to null, no element will be selected.
*
* @return TreeViewNode[] An array of TreeViewNode[] elements of the root elements.
@@ -132,7 +132,7 @@ class TreeViewGenerator
* Gets a tree of TreeViewNode elements. The root elements has $parent as parent.
* The treeview is generic, that means the href are null and ID values are set.
*
- * @param string $class The class for which the tree should be generated
+ * @param string $class The class for which the tree should be generated
* @param AbstractStructuralDBElement|null $parent The parent the root elements should have.
*
* @return TreeViewNode[]
diff --git a/src/Twig/LastUserExtension.php b/src/Twig/LastUserExtension.php
index 25e4833f..524e8bad 100644
--- a/src/Twig/LastUserExtension.php
+++ b/src/Twig/LastUserExtension.php
@@ -1,4 +1,7 @@
repo, 'getLastEditingUser']),
- new TwigFunction('getCreatingUser', [$this->repo, 'getCreatingUser'])
+ new TwigFunction('getCreatingUser', [$this->repo, 'getCreatingUser']),
];
}
-}
\ No newline at end of file
+}
diff --git a/symfony.lock b/symfony.lock
index c1cc58e0..eca9c54a 100644
--- a/symfony.lock
+++ b/symfony.lock
@@ -277,6 +277,9 @@
"paragonie/constant_time_encoding": {
"version": "v2.3.0"
},
+ "paragonie/random_compat": {
+ "version": "v9.99.99"
+ },
"php": {
"version": "7.2.5"
},
@@ -650,6 +653,9 @@
"./tests/.gitignore"
]
},
+ "symfony/polyfill-ctype": {
+ "version": "v1.14.0"
+ },
"symfony/polyfill-intl-icu": {
"version": "v1.10.0"
},
diff --git a/templates/AdminPages/EntityAdminBase.html.twig b/templates/AdminPages/EntityAdminBase.html.twig
index f298b841..ef4d335c 100644
--- a/templates/AdminPages/EntityAdminBase.html.twig
+++ b/templates/AdminPages/EntityAdminBase.html.twig
@@ -85,6 +85,11 @@
{% trans %}admin.attachments{% endtrans %}
+ {% if entity.parameters is defined %}
+
+ {% trans %}admin.parameters{% endtrans %}
+
+ {% endif %}
@@ -113,6 +118,12 @@
{{ form_row(form.master_picture_attachment) }}
{% endblock %}
+
+ {% if entity.parameters is defined %}
+
+ {% include "AdminPages/_parameters.html.twig" %}
+
+ {% endif %}