forked from mirror/Part-DB.Part-DB-server
Compare commits
38 commits
master
...
settings-b
Author | SHA1 | Date | |
---|---|---|---|
|
3d4e91fc69 | ||
|
97aed847b6 | ||
|
8750573724 | ||
|
1ac9641a04 | ||
|
ad47c8d8ed | ||
|
0dbf417866 | ||
|
a45bf22ac5 | ||
|
b5a6ba921c | ||
|
f6a2467eae | ||
|
79da0518c2 | ||
|
5e512f8935 | ||
|
99c10ffe85 | ||
|
47830dcd08 | ||
|
947cce78d7 | ||
|
74e555d25d | ||
|
e9973af8f4 | ||
|
2ab2b7f77d | ||
|
463812fb3d | ||
|
d2406726c6 | ||
|
1f04d1b993 | ||
|
2ef46cdd34 | ||
|
2bc50b2888 | ||
|
9e0f86788d | ||
|
2681c7ded3 | ||
|
5ab6a63492 | ||
|
6df7bc5f2a | ||
|
a0a7ca3c9c | ||
|
f88584e1ca | ||
|
3e657a7cac | ||
|
7cc67f8bb1 | ||
|
0772d85918 | ||
|
26d83af298 | ||
|
4876068cce | ||
|
08ae313dfe | ||
|
3967c53468 | ||
|
7ad077862c | ||
|
5a563e4f8f | ||
|
5a4b7c525b |
103 changed files with 2974 additions and 687 deletions
49
.env
49
.env
|
@ -32,36 +32,16 @@ DATABASE_EMULATE_NATURAL_SORT=0
|
||||||
###################################################################################
|
###################################################################################
|
||||||
|
|
||||||
# The language to use serverwide as default (en, de, ru, etc.)
|
# The language to use serverwide as default (en, de, ru, etc.)
|
||||||
DEFAULT_LANG="en"
|
#DEFAULT_LANG="en"
|
||||||
# The default timezone to use serverwide (e.g. Europe/Berlin)
|
# The default timezone to use serverwide (e.g. Europe/Berlin)
|
||||||
DEFAULT_TIMEZONE="Europe/Berlin"
|
#DEFAULT_TIMEZONE="Europe/Berlin"
|
||||||
# The currency that is used inside the DB (and is assumed when no currency is set). This can not be changed later, so be sure to set it the currency used in your country
|
# The currency that is used inside the DB (and is assumed when no currency is set). This can not be changed later, so be sure to set it the currency used in your country
|
||||||
BASE_CURRENCY="EUR"
|
#BASE_CURRENCY="EUR"
|
||||||
# The name of this installation. This will be shown as title in the browser and in the header of the website
|
|
||||||
INSTANCE_NAME="Part-DB"
|
|
||||||
# Allow users to download attachments to the server by providing an URL
|
|
||||||
# This could be a potential security issue, as the user can retrieve any file the server has access to (via internet)
|
|
||||||
ALLOW_ATTACHMENT_DOWNLOADS=0
|
|
||||||
# Set this to 1, if the "download external files" checkbox should be checked by default for new attachments
|
|
||||||
ATTACHMENT_DOWNLOAD_BY_DEFAULT=0
|
|
||||||
# Use gravatars for user avatars, when user has no own avatar defined
|
|
||||||
USE_GRAVATAR=0
|
|
||||||
# The maximum allowed size for attachment files in bytes (you can use M for megabytes and G for gigabytes)
|
|
||||||
# Please note that the php.ini setting upload_max_filesize also limits the maximum size of uploaded files
|
|
||||||
MAX_ATTACHMENT_FILE_SIZE="100M"
|
|
||||||
|
|
||||||
# The public reachable URL of this Part-DB installation. This is used for generating links in SAML and email templates
|
# The public reachable URL of this Part-DB installation. This is used for generating links in SAML and email templates
|
||||||
# This must end with a slash!
|
# This must end with a slash!
|
||||||
DEFAULT_URI="https://partdb.changeme.invalid/"
|
DEFAULT_URI="https://partdb.changeme.invalid/"
|
||||||
|
|
||||||
# With this option you can configure, where users are enforced to give a change reason, which will be logged
|
|
||||||
# This is a comma separated list of values, see documentation for available values
|
|
||||||
# Leave this empty, to make all change reasons optional
|
|
||||||
ENFORCE_CHANGE_COMMENTS_FOR=""
|
|
||||||
|
|
||||||
# Disable that if you do not want that Part-DB connects to GitHub to check for available updates, or if your server can not connect to the internet
|
|
||||||
CHECK_FOR_UPDATES=1
|
|
||||||
|
|
||||||
###################################################################################
|
###################################################################################
|
||||||
# Email settings
|
# Email settings
|
||||||
###################################################################################
|
###################################################################################
|
||||||
|
@ -78,21 +58,6 @@ EMAIL_SENDER_NAME="Part-DB Mailer"
|
||||||
# Set this to 1 to allow reset of a password per email
|
# Set this to 1 to allow reset of a password per email
|
||||||
ALLOW_EMAIL_PW_RESET=0
|
ALLOW_EMAIL_PW_RESET=0
|
||||||
|
|
||||||
######################################################################################
|
|
||||||
# History/Eventlog settings
|
|
||||||
######################################################################################
|
|
||||||
# If you want to use full timetrave functionality all values below have to be set to 1
|
|
||||||
|
|
||||||
# Save which fields were changed in a ElementEdited log entry
|
|
||||||
HISTORY_SAVE_CHANGED_FIELDS=1
|
|
||||||
# Save the old data in the ElementEdited log entry (warning this could increase the database size in short time)
|
|
||||||
HISTORY_SAVE_CHANGED_DATA=1
|
|
||||||
# Save the data of an element that gets removed into log entry. This allows to undelete an element
|
|
||||||
HISTORY_SAVE_REMOVED_DATA=1
|
|
||||||
# Save the new data of an element that gets changed or added. This allows an easy comparison of the old and new data on the detail page
|
|
||||||
# This option only becomes active when HISTORY_SAVE_CHANGED_DATA is set to 1
|
|
||||||
HISTORY_SAVE_NEW_DATA=1
|
|
||||||
|
|
||||||
###################################################################################
|
###################################################################################
|
||||||
# Error pages settings
|
# Error pages settings
|
||||||
###################################################################################
|
###################################################################################
|
||||||
|
@ -107,10 +72,10 @@ ERROR_PAGE_SHOW_HELP=1
|
||||||
##################################################################################
|
##################################################################################
|
||||||
|
|
||||||
# The default page size for the part table (set to -1 to show all parts on one page)
|
# The default page size for the part table (set to -1 to show all parts on one page)
|
||||||
TABLE_DEFAULT_PAGE_SIZE=50
|
#TABLE_DEFAULT_PAGE_SIZE=50
|
||||||
# Configure which columns will be visible by default in the parts table (and in which order).
|
# Configure which columns will be visible by default in the parts table (and in which order).
|
||||||
# This is a comma separated list of column names. See documentation for available values.
|
# This is a comma separated list of column names. See documentation for available values.
|
||||||
TABLE_PARTS_DEFAULT_COLUMNS=name,description,category,footprint,manufacturer,storage_location,amount
|
#TABLE_PARTS_DEFAULT_COLUMNS=name,description,category,footprint,manufacturer,storage_location,amount
|
||||||
|
|
||||||
##################################################################################
|
##################################################################################
|
||||||
# Info provider settings
|
# Info provider settings
|
||||||
|
@ -221,8 +186,8 @@ PROVIDER_OEMSECRETS_SORT_CRITERIA=C
|
||||||
|
|
||||||
# This value determines the depth of the category tree, that is visible inside KiCad
|
# This value determines the depth of the category tree, that is visible inside KiCad
|
||||||
# 0 means that only the top level categories are visible. Set to a value > 0 to show more levels.
|
# 0 means that only the top level categories are visible. Set to a value > 0 to show more levels.
|
||||||
# Set to -1, to show all parts of Part-DB inside a single category in KiCad
|
# Set to -1, to show all parts of Part-DB inside a sigle cnategory in KiCad
|
||||||
EDA_KICAD_CATEGORY_DEPTH=0
|
#EDA_KICAD_CATEGORY_DEPTH=0
|
||||||
|
|
||||||
###################################################################################
|
###################################################################################
|
||||||
# SAML Single sign on-settings
|
# SAML Single sign on-settings
|
||||||
|
|
|
@ -11,3 +11,5 @@ DATABASE_URL="sqlite:///%kernel.project_dir%/var/app_test.db"
|
||||||
|
|
||||||
# Disable update checks, as tests would fail, when github is not reachable
|
# Disable update checks, as tests would fail, when github is not reachable
|
||||||
CHECK_FOR_UPDATES=0
|
CHECK_FOR_UPDATES=0
|
||||||
|
|
||||||
|
INSTANCE_NAME="Part-DB"
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,6 +2,7 @@
|
||||||
/.env.local
|
/.env.local
|
||||||
/.env.local.php
|
/.env.local.php
|
||||||
/.env.*.local
|
/.env.*.local
|
||||||
|
/.env.local.bak
|
||||||
/config/secrets/prod/prod.decrypt.private.php
|
/config/secrets/prod/prod.decrypt.private.php
|
||||||
/public/bundles/
|
/public/bundles/
|
||||||
/var/
|
/var/
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
1.15.1
|
2.0.0-dev
|
|
@ -40,6 +40,7 @@ export default class extends Controller {
|
||||||
|
|
||||||
|
|
||||||
let settings = {
|
let settings = {
|
||||||
|
plugins: ["clear_button"],
|
||||||
allowEmptyOption: true,
|
allowEmptyOption: true,
|
||||||
selectOnTab: true,
|
selectOnTab: true,
|
||||||
maxOptions: null,
|
maxOptions: null,
|
||||||
|
@ -50,7 +51,24 @@ export default class extends Controller {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//Load the drag_drop plugin if the select is ordered
|
||||||
|
if (this.element.dataset.orderedValue) {
|
||||||
|
settings.plugins.push('drag_drop');
|
||||||
|
settings.plugins.push("caret_position");
|
||||||
|
}
|
||||||
|
|
||||||
|
//If multiple items can be selected, enable the remove_button plugin
|
||||||
|
if (this.element.multiple) {
|
||||||
|
settings.plugins.push('remove_button');
|
||||||
|
}
|
||||||
|
|
||||||
this._tomSelect = new TomSelect(this.element, settings);
|
this._tomSelect = new TomSelect(this.element, settings);
|
||||||
|
|
||||||
|
//If the select is ordered, we need to update the value field (with the decoded value from the orderedValue field)
|
||||||
|
if (this.element.dataset.orderedValue) {
|
||||||
|
const data = JSON.parse(this.element.dataset.orderedValue);
|
||||||
|
this._tomSelect.setValue(data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getTomSelect() {
|
getTomSelect() {
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
import {Controller} from "@hotwired/stimulus";
|
import {Controller} from "@hotwired/stimulus";
|
||||||
import TomSelect from "tom-select";
|
import TomSelect from "tom-select";
|
||||||
|
|
||||||
|
// TODO: Merge with select_controller.js
|
||||||
|
|
||||||
export default class extends Controller {
|
export default class extends Controller {
|
||||||
_tomSelect;
|
_tomSelect;
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
"hshn/base64-encoded-file": "^5.0",
|
"hshn/base64-encoded-file": "^5.0",
|
||||||
"jbtronics/2fa-webauthn": "^v2.2.0",
|
"jbtronics/2fa-webauthn": "^v2.2.0",
|
||||||
"jbtronics/dompdf-font-loader-bundle": "^1.0.0",
|
"jbtronics/dompdf-font-loader-bundle": "^1.0.0",
|
||||||
|
"jbtronics/settings-bundle": "dev-master",
|
||||||
"jfcherng/php-diff": "^6.14",
|
"jfcherng/php-diff": "^6.14",
|
||||||
"knpuniversity/oauth2-client-bundle": "^2.15",
|
"knpuniversity/oauth2-client-bundle": "^2.15",
|
||||||
"league/csv": "^9.8.0",
|
"league/csv": "^9.8.0",
|
||||||
|
@ -71,7 +72,7 @@
|
||||||
"symfony/runtime": "6.4.*",
|
"symfony/runtime": "6.4.*",
|
||||||
"symfony/security-bundle": "6.4.*",
|
"symfony/security-bundle": "6.4.*",
|
||||||
"symfony/serializer": "6.4.*",
|
"symfony/serializer": "6.4.*",
|
||||||
"symfony/string": "6.4.*",
|
"symfony/string": "6.4.8",
|
||||||
"symfony/translation": "6.4.*",
|
"symfony/translation": "6.4.*",
|
||||||
"symfony/twig-bundle": "6.4.*",
|
"symfony/twig-bundle": "6.4.*",
|
||||||
"symfony/ux-translator": "^2.10",
|
"symfony/ux-translator": "^2.10",
|
||||||
|
|
404
composer.lock
generated
404
composer.lock
generated
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "ca8701d95e24bae5d28ccdcfe242e8e4",
|
"content-hash": "7a8b16e978685556f1bc6edd3bf1fe5a",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "amphp/amp",
|
"name": "amphp/amp",
|
||||||
|
@ -456,16 +456,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "amphp/http-client",
|
"name": "amphp/http-client",
|
||||||
"version": "v5.2.1",
|
"version": "v5.2.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/amphp/http-client.git",
|
"url": "https://github.com/amphp/http-client.git",
|
||||||
"reference": "2117f7e7cd1ecf35d4d0daea1ba5dc6fd318b114"
|
"reference": "a3e8711cb71fe909c1ae17450bfa5db652559c20"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/amphp/http-client/zipball/2117f7e7cd1ecf35d4d0daea1ba5dc6fd318b114",
|
"url": "https://api.github.com/repos/amphp/http-client/zipball/a3e8711cb71fe909c1ae17450bfa5db652559c20",
|
||||||
"reference": "2117f7e7cd1ecf35d4d0daea1ba5dc6fd318b114",
|
"reference": "a3e8711cb71fe909c1ae17450bfa5db652559c20",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -483,8 +483,11 @@
|
||||||
"psr/http-message": "^1 | ^2",
|
"psr/http-message": "^1 | ^2",
|
||||||
"revolt/event-loop": "^1"
|
"revolt/event-loop": "^1"
|
||||||
},
|
},
|
||||||
|
"conflict": {
|
||||||
|
"amphp/file": "<3 | >=5"
|
||||||
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"amphp/file": "^3",
|
"amphp/file": "^3 | ^4",
|
||||||
"amphp/http-server": "^3",
|
"amphp/http-server": "^3",
|
||||||
"amphp/php-cs-fixer-config": "^2",
|
"amphp/php-cs-fixer-config": "^2",
|
||||||
"amphp/phpunit-util": "^3",
|
"amphp/phpunit-util": "^3",
|
||||||
|
@ -539,7 +542,7 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/amphp/http-client/issues",
|
"issues": "https://github.com/amphp/http-client/issues",
|
||||||
"source": "https://github.com/amphp/http-client/tree/v5.2.1"
|
"source": "https://github.com/amphp/http-client/tree/v5.2.2"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -547,7 +550,7 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-12-13T16:16:08+00:00"
|
"time": "2025-01-12T20:02:49+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "amphp/parser",
|
"name": "amphp/parser",
|
||||||
|
@ -965,16 +968,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "api-platform/core",
|
"name": "api-platform/core",
|
||||||
"version": "v3.4.10",
|
"version": "v3.4.16",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/api-platform/core.git",
|
"url": "https://github.com/api-platform/core.git",
|
||||||
"reference": "f8dae8e1154480a49e86d2393118ffbd99acc51c"
|
"reference": "64c6e1092cf988ba619907b3e4cce8a229ce4fae"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/api-platform/core/zipball/f8dae8e1154480a49e86d2393118ffbd99acc51c",
|
"url": "https://api.github.com/repos/api-platform/core/zipball/64c6e1092cf988ba619907b3e4cce8a229ce4fae",
|
||||||
"reference": "f8dae8e1154480a49e86d2393118ffbd99acc51c",
|
"reference": "64c6e1092cf988ba619907b3e4cce8a229ce4fae",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -1180,9 +1183,9 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/api-platform/core/issues",
|
"issues": "https://github.com/api-platform/core/issues",
|
||||||
"source": "https://github.com/api-platform/core/tree/v3.4.10"
|
"source": "https://github.com/api-platform/core/tree/v3.4.16"
|
||||||
},
|
},
|
||||||
"time": "2024-12-20T10:18:28+00:00"
|
"time": "2025-01-17T14:17:26+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "beberlei/assert",
|
"name": "beberlei/assert",
|
||||||
|
@ -1375,16 +1378,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "composer/ca-bundle",
|
"name": "composer/ca-bundle",
|
||||||
"version": "1.5.4",
|
"version": "1.5.5",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/composer/ca-bundle.git",
|
"url": "https://github.com/composer/ca-bundle.git",
|
||||||
"reference": "bc0593537a463e55cadf45fd938d23b75095b7e1"
|
"reference": "08c50d5ec4c6ced7d0271d2862dec8c1033283e6"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/bc0593537a463e55cadf45fd938d23b75095b7e1",
|
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/08c50d5ec4c6ced7d0271d2862dec8c1033283e6",
|
||||||
"reference": "bc0593537a463e55cadf45fd938d23b75095b7e1",
|
"reference": "08c50d5ec4c6ced7d0271d2862dec8c1033283e6",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -1431,7 +1434,7 @@
|
||||||
"support": {
|
"support": {
|
||||||
"irc": "irc://irc.freenode.org/composer",
|
"irc": "irc://irc.freenode.org/composer",
|
||||||
"issues": "https://github.com/composer/ca-bundle/issues",
|
"issues": "https://github.com/composer/ca-bundle/issues",
|
||||||
"source": "https://github.com/composer/ca-bundle/tree/1.5.4"
|
"source": "https://github.com/composer/ca-bundle/tree/1.5.5"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -1447,7 +1450,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-11-27T15:35:25+00:00"
|
"time": "2025-01-08T16:17:16+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "composer/package-versions-deprecated",
|
"name": "composer/package-versions-deprecated",
|
||||||
|
@ -1830,16 +1833,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "doctrine/dbal",
|
"name": "doctrine/dbal",
|
||||||
"version": "4.2.1",
|
"version": "4.2.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/doctrine/dbal.git",
|
"url": "https://github.com/doctrine/dbal.git",
|
||||||
"reference": "dadd35300837a3a2184bd47d403333b15d0a9bd0"
|
"reference": "19a2b7deb5fe8c2df0ff817ecea305e50acb62ec"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/dadd35300837a3a2184bd47d403333b15d0a9bd0",
|
"url": "https://api.github.com/repos/doctrine/dbal/zipball/19a2b7deb5fe8c2df0ff817ecea305e50acb62ec",
|
||||||
"reference": "dadd35300837a3a2184bd47d403333b15d0a9bd0",
|
"reference": "19a2b7deb5fe8c2df0ff817ecea305e50acb62ec",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -1852,16 +1855,14 @@
|
||||||
"doctrine/coding-standard": "12.0.0",
|
"doctrine/coding-standard": "12.0.0",
|
||||||
"fig/log-test": "^1",
|
"fig/log-test": "^1",
|
||||||
"jetbrains/phpstorm-stubs": "2023.2",
|
"jetbrains/phpstorm-stubs": "2023.2",
|
||||||
"phpstan/phpstan": "1.12.6",
|
"phpstan/phpstan": "2.1.1",
|
||||||
"phpstan/phpstan-phpunit": "1.4.0",
|
"phpstan/phpstan-phpunit": "2.0.3",
|
||||||
"phpstan/phpstan-strict-rules": "^1.6",
|
"phpstan/phpstan-strict-rules": "^2",
|
||||||
"phpunit/phpunit": "10.5.30",
|
"phpunit/phpunit": "10.5.39",
|
||||||
"psalm/plugin-phpunit": "0.19.0",
|
|
||||||
"slevomat/coding-standard": "8.13.1",
|
"slevomat/coding-standard": "8.13.1",
|
||||||
"squizlabs/php_codesniffer": "3.10.2",
|
"squizlabs/php_codesniffer": "3.10.2",
|
||||||
"symfony/cache": "^6.3.8|^7.0",
|
"symfony/cache": "^6.3.8|^7.0",
|
||||||
"symfony/console": "^5.4|^6.3|^7.0",
|
"symfony/console": "^5.4|^6.3|^7.0"
|
||||||
"vimeo/psalm": "5.25.0"
|
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"symfony/console": "For helpful console commands such as SQL execution and import of files."
|
"symfony/console": "For helpful console commands such as SQL execution and import of files."
|
||||||
|
@ -1918,7 +1919,7 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/doctrine/dbal/issues",
|
"issues": "https://github.com/doctrine/dbal/issues",
|
||||||
"source": "https://github.com/doctrine/dbal/tree/4.2.1"
|
"source": "https://github.com/doctrine/dbal/tree/4.2.2"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -1934,7 +1935,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-10-10T18:01:27+00:00"
|
"time": "2025-01-16T08:40:56+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "doctrine/deprecations",
|
"name": "doctrine/deprecations",
|
||||||
|
@ -1983,16 +1984,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "doctrine/doctrine-bundle",
|
"name": "doctrine/doctrine-bundle",
|
||||||
"version": "2.13.1",
|
"version": "2.13.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/doctrine/DoctrineBundle.git",
|
"url": "https://github.com/doctrine/DoctrineBundle.git",
|
||||||
"reference": "2740ad8b8739b39ab37d409c972b092f632b025a"
|
"reference": "2363c43d9815a11657e452625cd64172d5587486"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/2740ad8b8739b39ab37d409c972b092f632b025a",
|
"url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/2363c43d9815a11657e452625cd64172d5587486",
|
||||||
"reference": "2740ad8b8739b39ab37d409c972b092f632b025a",
|
"reference": "2363c43d9815a11657e452625cd64172d5587486",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -2006,7 +2007,7 @@
|
||||||
"symfony/console": "^5.4 || ^6.0 || ^7.0",
|
"symfony/console": "^5.4 || ^6.0 || ^7.0",
|
||||||
"symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0",
|
"symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0",
|
||||||
"symfony/deprecation-contracts": "^2.1 || ^3",
|
"symfony/deprecation-contracts": "^2.1 || ^3",
|
||||||
"symfony/doctrine-bridge": "^5.4.46 || ^6.4.3 || ^7.0.3",
|
"symfony/doctrine-bridge": "^5.4.46 || ~6.3.12 || ^6.4.3 || ^7.0.3",
|
||||||
"symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0",
|
"symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0",
|
||||||
"symfony/polyfill-php80": "^1.15",
|
"symfony/polyfill-php80": "^1.15",
|
||||||
"symfony/service-contracts": "^1.1.1 || ^2.0 || ^3"
|
"symfony/service-contracts": "^1.1.1 || ^2.0 || ^3"
|
||||||
|
@ -2022,13 +2023,14 @@
|
||||||
"doctrine/deprecations": "^1.0",
|
"doctrine/deprecations": "^1.0",
|
||||||
"doctrine/orm": "^2.17 || ^3.0",
|
"doctrine/orm": "^2.17 || ^3.0",
|
||||||
"friendsofphp/proxy-manager-lts": "^1.0",
|
"friendsofphp/proxy-manager-lts": "^1.0",
|
||||||
|
"phpstan/phpstan": "2.1.1",
|
||||||
|
"phpstan/phpstan-phpunit": "2.0.3",
|
||||||
|
"phpstan/phpstan-strict-rules": "^2",
|
||||||
"phpunit/phpunit": "^9.5.26",
|
"phpunit/phpunit": "^9.5.26",
|
||||||
"psalm/plugin-phpunit": "^0.18.4",
|
|
||||||
"psalm/plugin-symfony": "^5",
|
|
||||||
"psr/log": "^1.1.4 || ^2.0 || ^3.0",
|
"psr/log": "^1.1.4 || ^2.0 || ^3.0",
|
||||||
"symfony/phpunit-bridge": "^6.1 || ^7.0",
|
"symfony/phpunit-bridge": "^6.1 || ^7.0",
|
||||||
"symfony/property-info": "^5.4 || ^6.0 || ^7.0",
|
"symfony/property-info": "^5.4 || ^6.0 || ^7.0",
|
||||||
"symfony/proxy-manager-bridge": "^5.4 || ^6.0 || ^7.0",
|
"symfony/proxy-manager-bridge": "^5.4 || ^6.0",
|
||||||
"symfony/security-bundle": "^5.4 || ^6.0 || ^7.0",
|
"symfony/security-bundle": "^5.4 || ^6.0 || ^7.0",
|
||||||
"symfony/stopwatch": "^5.4 || ^6.0 || ^7.0",
|
"symfony/stopwatch": "^5.4 || ^6.0 || ^7.0",
|
||||||
"symfony/string": "^5.4 || ^6.0 || ^7.0",
|
"symfony/string": "^5.4 || ^6.0 || ^7.0",
|
||||||
|
@ -2037,8 +2039,7 @@
|
||||||
"symfony/var-exporter": "^5.4 || ^6.2 || ^7.0",
|
"symfony/var-exporter": "^5.4 || ^6.2 || ^7.0",
|
||||||
"symfony/web-profiler-bundle": "^5.4 || ^6.0 || ^7.0",
|
"symfony/web-profiler-bundle": "^5.4 || ^6.0 || ^7.0",
|
||||||
"symfony/yaml": "^5.4 || ^6.0 || ^7.0",
|
"symfony/yaml": "^5.4 || ^6.0 || ^7.0",
|
||||||
"twig/twig": "^1.34 || ^2.12 || ^3.0",
|
"twig/twig": "^1.34 || ^2.12 || ^3.0"
|
||||||
"vimeo/psalm": "^5.15"
|
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"doctrine/orm": "The Doctrine ORM integration is optional in the bundle.",
|
"doctrine/orm": "The Doctrine ORM integration is optional in the bundle.",
|
||||||
|
@ -2083,7 +2084,7 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/doctrine/DoctrineBundle/issues",
|
"issues": "https://github.com/doctrine/DoctrineBundle/issues",
|
||||||
"source": "https://github.com/doctrine/DoctrineBundle/tree/2.13.1"
|
"source": "https://github.com/doctrine/DoctrineBundle/tree/2.13.2"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -2099,26 +2100,26 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-11-08T23:27:54+00:00"
|
"time": "2025-01-15T11:12:38+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "doctrine/doctrine-migrations-bundle",
|
"name": "doctrine/doctrine-migrations-bundle",
|
||||||
"version": "3.3.1",
|
"version": "3.4.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/doctrine/DoctrineMigrationsBundle.git",
|
"url": "https://github.com/doctrine/DoctrineMigrationsBundle.git",
|
||||||
"reference": "715b62c31a5894afcb2b2cdbbc6607d7dd0580c0"
|
"reference": "a5c5fe0d2c6b911c03555046febb05a05a347078"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/doctrine/DoctrineMigrationsBundle/zipball/715b62c31a5894afcb2b2cdbbc6607d7dd0580c0",
|
"url": "https://api.github.com/repos/doctrine/DoctrineMigrationsBundle/zipball/a5c5fe0d2c6b911c03555046febb05a05a347078",
|
||||||
"reference": "715b62c31a5894afcb2b2cdbbc6607d7dd0580c0",
|
"reference": "a5c5fe0d2c6b911c03555046febb05a05a347078",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"doctrine/doctrine-bundle": "^2.4",
|
"doctrine/doctrine-bundle": "^2.4",
|
||||||
"doctrine/migrations": "^3.2",
|
"doctrine/migrations": "^3.2",
|
||||||
"php": "^7.2|^8.0",
|
"php": "^7.2 || ^8.0",
|
||||||
"symfony/deprecation-contracts": "^2.1 || ^3",
|
"symfony/deprecation-contracts": "^2.1 || ^3",
|
||||||
"symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0"
|
"symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0"
|
||||||
},
|
},
|
||||||
|
@ -2126,27 +2127,21 @@
|
||||||
"composer/semver": "^3.0",
|
"composer/semver": "^3.0",
|
||||||
"doctrine/coding-standard": "^12",
|
"doctrine/coding-standard": "^12",
|
||||||
"doctrine/orm": "^2.6 || ^3",
|
"doctrine/orm": "^2.6 || ^3",
|
||||||
"doctrine/persistence": "^2.0 || ^3 ",
|
"doctrine/persistence": "^2.0 || ^3",
|
||||||
"phpstan/phpstan": "^1.4",
|
"phpstan/phpstan": "^1.4 || ^2",
|
||||||
"phpstan/phpstan-deprecation-rules": "^1",
|
"phpstan/phpstan-deprecation-rules": "^1 || ^2",
|
||||||
"phpstan/phpstan-phpunit": "^1",
|
"phpstan/phpstan-phpunit": "^1 || ^2",
|
||||||
"phpstan/phpstan-strict-rules": "^1.1",
|
"phpstan/phpstan-strict-rules": "^1.1 || ^2",
|
||||||
"phpstan/phpstan-symfony": "^1.3",
|
"phpstan/phpstan-symfony": "^1.3 || ^2",
|
||||||
"phpunit/phpunit": "^8.5|^9.5",
|
"phpunit/phpunit": "^8.5 || ^9.5",
|
||||||
"psalm/plugin-phpunit": "^0.18.4",
|
|
||||||
"psalm/plugin-symfony": "^3 || ^5",
|
|
||||||
"symfony/phpunit-bridge": "^6.3 || ^7",
|
"symfony/phpunit-bridge": "^6.3 || ^7",
|
||||||
"symfony/var-exporter": "^5.4 || ^6 || ^7",
|
"symfony/var-exporter": "^5.4 || ^6 || ^7"
|
||||||
"vimeo/psalm": "^4.30 || ^5.15"
|
|
||||||
},
|
},
|
||||||
"type": "symfony-bundle",
|
"type": "symfony-bundle",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Doctrine\\Bundle\\MigrationsBundle\\": ""
|
"Doctrine\\Bundle\\MigrationsBundle\\": "src"
|
||||||
},
|
}
|
||||||
"exclude-from-classmap": [
|
|
||||||
"/Tests/"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
"license": [
|
"license": [
|
||||||
|
@ -2175,7 +2170,7 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/doctrine/DoctrineMigrationsBundle/issues",
|
"issues": "https://github.com/doctrine/DoctrineMigrationsBundle/issues",
|
||||||
"source": "https://github.com/doctrine/DoctrineMigrationsBundle/tree/3.3.1"
|
"source": "https://github.com/doctrine/DoctrineMigrationsBundle/tree/3.4.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -2191,7 +2186,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-05-14T20:32:18+00:00"
|
"time": "2025-01-16T20:28:10+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "doctrine/event-manager",
|
"name": "doctrine/event-manager",
|
||||||
|
@ -2869,16 +2864,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "dompdf/dompdf",
|
"name": "dompdf/dompdf",
|
||||||
"version": "v3.0.2",
|
"version": "v3.1.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/dompdf/dompdf.git",
|
"url": "https://github.com/dompdf/dompdf.git",
|
||||||
"reference": "baf4084b27c7f4b5b7a221b19a94d11327664eb8"
|
"reference": "a51bd7a063a65499446919286fb18b518177155a"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/dompdf/dompdf/zipball/baf4084b27c7f4b5b7a221b19a94d11327664eb8",
|
"url": "https://api.github.com/repos/dompdf/dompdf/zipball/a51bd7a063a65499446919286fb18b518177155a",
|
||||||
"reference": "baf4084b27c7f4b5b7a221b19a94d11327664eb8",
|
"reference": "a51bd7a063a65499446919286fb18b518177155a",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -2927,9 +2922,9 @@
|
||||||
"homepage": "https://github.com/dompdf/dompdf",
|
"homepage": "https://github.com/dompdf/dompdf",
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/dompdf/dompdf/issues",
|
"issues": "https://github.com/dompdf/dompdf/issues",
|
||||||
"source": "https://github.com/dompdf/dompdf/tree/v3.0.2"
|
"source": "https://github.com/dompdf/dompdf/tree/v3.1.0"
|
||||||
},
|
},
|
||||||
"time": "2024-12-27T20:27:37+00:00"
|
"time": "2025-01-15T14:09:04+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "dompdf/php-font-lib",
|
"name": "dompdf/php-font-lib",
|
||||||
|
@ -3089,6 +3084,72 @@
|
||||||
],
|
],
|
||||||
"time": "2024-12-27T00:36:43+00:00"
|
"time": "2024-12-27T00:36:43+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "ergebnis/classy",
|
||||||
|
"version": "1.7.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/ergebnis/classy.git",
|
||||||
|
"reference": "32880f00b442d0fcdb50df94ea8d45e48f9cb430"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/ergebnis/classy/zipball/32880f00b442d0fcdb50df94ea8d45e48f9cb430",
|
||||||
|
"reference": "32880f00b442d0fcdb50df94ea8d45e48f9cb430",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-tokenizer": "*",
|
||||||
|
"php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"ergebnis/composer-normalize": "^2.45.0",
|
||||||
|
"ergebnis/license": "^2.6.0",
|
||||||
|
"ergebnis/php-cs-fixer-config": "^6.40.0",
|
||||||
|
"ergebnis/phpunit-slow-test-detector": "^2.17.0",
|
||||||
|
"fakerphp/faker": "^1.24.1",
|
||||||
|
"infection/infection": "~0.26.6",
|
||||||
|
"phpstan/extension-installer": "^1.4.3",
|
||||||
|
"phpstan/phpstan": "^2.1.1",
|
||||||
|
"phpstan/phpstan-deprecation-rules": "^2.0.1",
|
||||||
|
"phpstan/phpstan-phpunit": "^2.0.3",
|
||||||
|
"phpstan/phpstan-strict-rules": "^2.0.1",
|
||||||
|
"phpunit/phpunit": "^9.6.19",
|
||||||
|
"rector/rector": "^2.0.6"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Ergebnis\\Classy\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Andreas Möller",
|
||||||
|
"email": "am@localheinz.com",
|
||||||
|
"homepage": "https://localheinz.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Provides a finder for classy constructs (classes, enums, interfaces, and traits).",
|
||||||
|
"homepage": "https://github.com/ergebnis/classy",
|
||||||
|
"keywords": [
|
||||||
|
"classes",
|
||||||
|
"classy",
|
||||||
|
"constructs",
|
||||||
|
"finder",
|
||||||
|
"interfaces",
|
||||||
|
"traits"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/ergebnis/classy/issues",
|
||||||
|
"source": "https://github.com/ergebnis/classy"
|
||||||
|
},
|
||||||
|
"time": "2025-01-07T10:31:33+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "erusev/parsedown",
|
"name": "erusev/parsedown",
|
||||||
"version": "1.7.4",
|
"version": "1.7.4",
|
||||||
|
@ -4028,6 +4089,92 @@
|
||||||
},
|
},
|
||||||
"time": "2024-06-06T17:42:51+00:00"
|
"time": "2024-06-06T17:42:51+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "jbtronics/settings-bundle",
|
||||||
|
"version": "dev-master",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/jbtronics/settings-bundle.git",
|
||||||
|
"reference": "deb51a945cc6c7a2004584e2ac0c92e3841b22f6"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/jbtronics/settings-bundle/zipball/deb51a945cc6c7a2004584e2ac0c92e3841b22f6",
|
||||||
|
"reference": "deb51a945cc6c7a2004584e2ac0c92e3841b22f6",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ergebnis/classy": "^1.6",
|
||||||
|
"ext-json": "*",
|
||||||
|
"php": "^8.1",
|
||||||
|
"symfony/deprecation-contracts": "^3.4",
|
||||||
|
"symfony/form": "^6.4|^7.0",
|
||||||
|
"symfony/framework-bundle": "^6.4|^7.0",
|
||||||
|
"symfony/translation": "^7.0|^6.4",
|
||||||
|
"symfony/translation-contracts": "^2.5|^3.0",
|
||||||
|
"symfony/validator": "^6.4|^7.0",
|
||||||
|
"symfony/var-exporter": "^6.4|^7.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"doctrine/doctrine-bundle": "^2.11",
|
||||||
|
"doctrine/doctrine-fixtures-bundle": "^3.5",
|
||||||
|
"doctrine/orm": "^3.0",
|
||||||
|
"ekino/phpstan-banned-code": "^1.0",
|
||||||
|
"phpstan/extension-installer": "^1.3",
|
||||||
|
"phpstan/phpstan": "^1.10",
|
||||||
|
"phpstan/phpstan-strict-rules": "^1.5",
|
||||||
|
"phpstan/phpstan-symfony": "^1.3",
|
||||||
|
"phpunit/phpunit": "^9.5",
|
||||||
|
"roave/security-advisories": "dev-latest",
|
||||||
|
"symfony/phpunit-bridge": "^6.4|^7.0",
|
||||||
|
"symfony/security-csrf": "^7.0|^6.4",
|
||||||
|
"symfony/twig-bridge": "^6.4|^7.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"doctrine/doctrine-bundle": "To use the doctrine ORM storage",
|
||||||
|
"symfony/twig-bridge": "Allows to access settings in twig templates"
|
||||||
|
},
|
||||||
|
"default-branch": true,
|
||||||
|
"type": "symfony-bundle",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Jbtronics\\SettingsBundle\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jan Böhmer",
|
||||||
|
"email": "mail@jan-boehmer.de"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A symfony bundle to easily create typesafe, user-configurable settings for symfony applications",
|
||||||
|
"keywords": [
|
||||||
|
"Settings",
|
||||||
|
"config",
|
||||||
|
"symfony",
|
||||||
|
"symfony-bundle",
|
||||||
|
"user-configurable"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/jbtronics/settings-bundle/issues",
|
||||||
|
"source": "https://github.com/jbtronics/settings-bundle/tree/v2.4.1"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://www.paypal.me/do9jhb",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/jbtronics",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-08-06T22:36:40+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "jfcherng/php-color-output",
|
"name": "jfcherng/php-color-output",
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
|
@ -7545,20 +7692,20 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "scheb/2fa-backup-code",
|
"name": "scheb/2fa-backup-code",
|
||||||
"version": "v6.12.0",
|
"version": "v6.13.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/scheb/2fa-backup-code.git",
|
"url": "https://github.com/scheb/2fa-backup-code.git",
|
||||||
"reference": "1ad84e7eb26eb425c609e03097cac99387dde44c"
|
"reference": "6dceeb5be0f6339d76f8e380ee09631c8bbebc7e"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/scheb/2fa-backup-code/zipball/1ad84e7eb26eb425c609e03097cac99387dde44c",
|
"url": "https://api.github.com/repos/scheb/2fa-backup-code/zipball/6dceeb5be0f6339d76f8e380ee09631c8bbebc7e",
|
||||||
"reference": "1ad84e7eb26eb425c609e03097cac99387dde44c",
|
"reference": "6dceeb5be0f6339d76f8e380ee09631c8bbebc7e",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0",
|
"php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0",
|
||||||
"scheb/2fa-bundle": "self.version"
|
"scheb/2fa-bundle": "self.version"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
|
@ -7588,27 +7735,27 @@
|
||||||
"two-step"
|
"two-step"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/scheb/2fa-backup-code/tree/v6.12.0"
|
"source": "https://github.com/scheb/2fa-backup-code/tree/v6.13.1"
|
||||||
},
|
},
|
||||||
"time": "2023-12-03T15:44:26+00:00"
|
"time": "2024-11-29T19:22:48+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "scheb/2fa-bundle",
|
"name": "scheb/2fa-bundle",
|
||||||
"version": "v6.12.0",
|
"version": "v6.13.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/scheb/2fa-bundle.git",
|
"url": "https://github.com/scheb/2fa-bundle.git",
|
||||||
"reference": "6e51477c53070f27ac3e3d36be1a991870db415a"
|
"reference": "8eadd57ebc2078ef273dca72b1ac4bd283812346"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/scheb/2fa-bundle/zipball/6e51477c53070f27ac3e3d36be1a991870db415a",
|
"url": "https://api.github.com/repos/scheb/2fa-bundle/zipball/8eadd57ebc2078ef273dca72b1ac4bd283812346",
|
||||||
"reference": "6e51477c53070f27ac3e3d36be1a991870db415a",
|
"reference": "8eadd57ebc2078ef273dca72b1ac4bd283812346",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0",
|
"php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0",
|
||||||
"symfony/config": "^5.4 || ^6.0",
|
"symfony/config": "^5.4 || ^6.0",
|
||||||
"symfony/dependency-injection": "^5.4 || ^6.0",
|
"symfony/dependency-injection": "^5.4 || ^6.0",
|
||||||
"symfony/event-dispatcher": "^5.4 || ^6.0",
|
"symfony/event-dispatcher": "^5.4 || ^6.0",
|
||||||
|
@ -7656,27 +7803,27 @@
|
||||||
"two-step"
|
"two-step"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/scheb/2fa-bundle/tree/v6.12.0"
|
"source": "https://github.com/scheb/2fa-bundle/tree/v6.13.1"
|
||||||
},
|
},
|
||||||
"time": "2023-12-03T16:02:15+00:00"
|
"time": "2024-11-29T19:29:49+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "scheb/2fa-google-authenticator",
|
"name": "scheb/2fa-google-authenticator",
|
||||||
"version": "v6.12.0",
|
"version": "v6.13.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/scheb/2fa-google-authenticator.git",
|
"url": "https://github.com/scheb/2fa-google-authenticator.git",
|
||||||
"reference": "2c43bbe432fdc465d8f1d1b2d73ca9ea5276fe34"
|
"reference": "2c960a5cb32edb4c37f719f10180df378a44fd6f"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/scheb/2fa-google-authenticator/zipball/2c43bbe432fdc465d8f1d1b2d73ca9ea5276fe34",
|
"url": "https://api.github.com/repos/scheb/2fa-google-authenticator/zipball/2c960a5cb32edb4c37f719f10180df378a44fd6f",
|
||||||
"reference": "2c43bbe432fdc465d8f1d1b2d73ca9ea5276fe34",
|
"reference": "2c960a5cb32edb4c37f719f10180df378a44fd6f",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"paragonie/constant_time_encoding": "^2.4",
|
"paragonie/constant_time_encoding": "^2.4",
|
||||||
"php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0",
|
"php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0",
|
||||||
"scheb/2fa-bundle": "self.version",
|
"scheb/2fa-bundle": "self.version",
|
||||||
"spomky-labs/otphp": "^10.0 || ^11.0"
|
"spomky-labs/otphp": "^10.0 || ^11.0"
|
||||||
},
|
},
|
||||||
|
@ -7707,28 +7854,28 @@
|
||||||
"two-step"
|
"two-step"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/scheb/2fa-google-authenticator/tree/v6.12.0"
|
"source": "https://github.com/scheb/2fa-google-authenticator/tree/v6.13.1"
|
||||||
},
|
},
|
||||||
"time": "2023-12-03T15:44:26+00:00"
|
"time": "2024-11-29T19:22:48+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "scheb/2fa-trusted-device",
|
"name": "scheb/2fa-trusted-device",
|
||||||
"version": "v6.12.0",
|
"version": "v6.13.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/scheb/2fa-trusted-device.git",
|
"url": "https://github.com/scheb/2fa-trusted-device.git",
|
||||||
"reference": "1ca6158dc6518ca9dba8b111bd9807a8b9be2903"
|
"reference": "38e690325232a4037ff4aec8de926c938906942c"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/scheb/2fa-trusted-device/zipball/1ca6158dc6518ca9dba8b111bd9807a8b9be2903",
|
"url": "https://api.github.com/repos/scheb/2fa-trusted-device/zipball/38e690325232a4037ff4aec8de926c938906942c",
|
||||||
"reference": "1ca6158dc6518ca9dba8b111bd9807a8b9be2903",
|
"reference": "38e690325232a4037ff4aec8de926c938906942c",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"lcobucci/clock": "^2.0 || ^3.0",
|
"lcobucci/clock": "^2.0 || ^3.0",
|
||||||
"lcobucci/jwt": "^4.1 || ^5.0",
|
"lcobucci/jwt": "^4.1 || ^5.0",
|
||||||
"php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0",
|
"php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0",
|
||||||
"scheb/2fa-bundle": "self.version"
|
"scheb/2fa-bundle": "self.version"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
|
@ -7758,9 +7905,9 @@
|
||||||
"two-step"
|
"two-step"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/scheb/2fa-trusted-device/tree/v6.12.0"
|
"source": "https://github.com/scheb/2fa-trusted-device/tree/v6.13.1"
|
||||||
},
|
},
|
||||||
"time": "2023-12-03T15:44:26+00:00"
|
"time": "2024-11-29T19:22:48+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "shivas/versioning-bundle",
|
"name": "shivas/versioning-bundle",
|
||||||
|
@ -12790,16 +12937,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/string",
|
"name": "symfony/string",
|
||||||
"version": "v6.4.15",
|
"version": "v6.4.8",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/string.git",
|
"url": "https://github.com/symfony/string.git",
|
||||||
"reference": "73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f"
|
"reference": "a147c0f826c4a1f3afb763ab8e009e37c877a44d"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/string/zipball/73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f",
|
"url": "https://api.github.com/repos/symfony/string/zipball/a147c0f826c4a1f3afb763ab8e009e37c877a44d",
|
||||||
"reference": "73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f",
|
"reference": "a147c0f826c4a1f3afb763ab8e009e37c877a44d",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -12856,7 +13003,7 @@
|
||||||
"utf8"
|
"utf8"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/string/tree/v6.4.15"
|
"source": "https://github.com/symfony/string/tree/v6.4.8"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -12872,7 +13019,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-11-13T13:31:12+00:00"
|
"time": "2024-05-31T14:49:08+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/translation",
|
"name": "symfony/translation",
|
||||||
|
@ -16604,12 +16751,12 @@
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/Roave/SecurityAdvisories.git",
|
"url": "https://github.com/Roave/SecurityAdvisories.git",
|
||||||
"reference": "6ec01b072baedc0e230b90c70e521007851c8f7c"
|
"reference": "e7a38fcc13e4ddfe9a28d5c7bf50aa9a9da758ec"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/6ec01b072baedc0e230b90c70e521007851c8f7c",
|
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/e7a38fcc13e4ddfe9a28d5c7bf50aa9a9da758ec",
|
||||||
"reference": "6ec01b072baedc0e230b90c70e521007851c8f7c",
|
"reference": "e7a38fcc13e4ddfe9a28d5c7bf50aa9a9da758ec",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"conflict": {
|
"conflict": {
|
||||||
|
@ -16845,6 +16992,7 @@
|
||||||
"gilacms/gila": "<=1.15.4",
|
"gilacms/gila": "<=1.15.4",
|
||||||
"gleez/cms": "<=1.3|==2",
|
"gleez/cms": "<=1.3|==2",
|
||||||
"globalpayments/php-sdk": "<2",
|
"globalpayments/php-sdk": "<2",
|
||||||
|
"goalgorilla/open_social": "<12.3.8|>=12.4,<12.4.5|>=13.0.0.0-alpha1,<13.0.0.0-alpha11",
|
||||||
"gogentooss/samlbase": "<1.2.7",
|
"gogentooss/samlbase": "<1.2.7",
|
||||||
"google/protobuf": "<3.15",
|
"google/protobuf": "<3.15",
|
||||||
"gos/web-socket-bundle": "<1.10.4|>=2,<2.6.1|>=3,<3.3",
|
"gos/web-socket-bundle": "<1.10.4|>=2,<2.6.1|>=3,<3.3",
|
||||||
|
@ -16892,6 +17040,7 @@
|
||||||
"intelliants/subrion": "<4.2.2",
|
"intelliants/subrion": "<4.2.2",
|
||||||
"inter-mediator/inter-mediator": "==5.5",
|
"inter-mediator/inter-mediator": "==5.5",
|
||||||
"ipl/web": "<0.10.1",
|
"ipl/web": "<0.10.1",
|
||||||
|
"islandora/crayfish": "<4.1",
|
||||||
"islandora/islandora": ">=2,<2.4.1",
|
"islandora/islandora": ">=2,<2.4.1",
|
||||||
"ivankristianto/phpwhois": "<=4.3",
|
"ivankristianto/phpwhois": "<=4.3",
|
||||||
"jackalope/jackalope-doctrine-dbal": "<1.7.4",
|
"jackalope/jackalope-doctrine-dbal": "<1.7.4",
|
||||||
|
@ -16974,6 +17123,7 @@
|
||||||
"mediawiki/abuse-filter": "<1.39.9|>=1.40,<1.41.3|>=1.42,<1.42.2",
|
"mediawiki/abuse-filter": "<1.39.9|>=1.40,<1.41.3|>=1.42,<1.42.2",
|
||||||
"mediawiki/cargo": "<3.6.1",
|
"mediawiki/cargo": "<3.6.1",
|
||||||
"mediawiki/core": "<1.39.5|==1.40",
|
"mediawiki/core": "<1.39.5|==1.40",
|
||||||
|
"mediawiki/data-transfer": ">=1.39,<1.39.11|>=1.41,<1.41.3|>=1.42,<1.42.2",
|
||||||
"mediawiki/matomo": "<2.4.3",
|
"mediawiki/matomo": "<2.4.3",
|
||||||
"mediawiki/semantic-media-wiki": "<4.0.2",
|
"mediawiki/semantic-media-wiki": "<4.0.2",
|
||||||
"melisplatform/melis-asset-manager": "<5.0.1",
|
"melisplatform/melis-asset-manager": "<5.0.1",
|
||||||
|
@ -17014,6 +17164,8 @@
|
||||||
"neos/media-browser": "<7.3.19|>=8,<8.0.16|>=8.1,<8.1.11|>=8.2,<8.2.11|>=8.3,<8.3.9",
|
"neos/media-browser": "<7.3.19|>=8,<8.0.16|>=8.1,<8.1.11|>=8.2,<8.2.11|>=8.3,<8.3.9",
|
||||||
"neos/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<5.3.10|>=7,<7.0.9|>=7.1,<7.1.7|>=7.2,<7.2.6|>=7.3,<7.3.4|>=8,<8.0.2",
|
"neos/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<5.3.10|>=7,<7.0.9|>=7.1,<7.1.7|>=7.2,<7.2.6|>=7.3,<7.3.4|>=8,<8.0.2",
|
||||||
"neos/swiftmailer": "<5.4.5",
|
"neos/swiftmailer": "<5.4.5",
|
||||||
|
"nesbot/carbon": "<2.72.6|>=3,<3.8.4",
|
||||||
|
"netcarver/textile": "<=4.1.2",
|
||||||
"netgen/tagsbundle": ">=3.4,<3.4.11|>=4,<4.0.15",
|
"netgen/tagsbundle": ">=3.4,<3.4.11|>=4,<4.0.15",
|
||||||
"nette/application": ">=2,<2.0.19|>=2.1,<2.1.13|>=2.2,<2.2.10|>=2.3,<2.3.14|>=2.4,<2.4.16|>=3,<3.0.6",
|
"nette/application": ">=2,<2.0.19|>=2.1,<2.1.13|>=2.2,<2.2.10|>=2.3,<2.3.14|>=2.4,<2.4.16|>=3,<3.0.6",
|
||||||
"nette/nette": ">=2,<2.0.19|>=2.1,<2.1.13",
|
"nette/nette": ">=2,<2.0.19|>=2.1,<2.1.13",
|
||||||
|
@ -17167,7 +17319,7 @@
|
||||||
"silverstripe/cms": "<4.11.3",
|
"silverstripe/cms": "<4.11.3",
|
||||||
"silverstripe/comments": ">=1.3,<3.1.1",
|
"silverstripe/comments": ">=1.3,<3.1.1",
|
||||||
"silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3",
|
"silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3",
|
||||||
"silverstripe/framework": "<5.2.16",
|
"silverstripe/framework": "<5.3.8",
|
||||||
"silverstripe/graphql": ">=2,<2.0.5|>=3,<3.8.2|>=4,<4.3.7|>=5,<5.1.3",
|
"silverstripe/graphql": ">=2,<2.0.5|>=3,<3.8.2|>=4,<4.3.7|>=5,<5.1.3",
|
||||||
"silverstripe/hybridsessions": ">=1,<2.4.1|>=2.5,<2.5.1",
|
"silverstripe/hybridsessions": ">=1,<2.4.1|>=2.5,<2.5.1",
|
||||||
"silverstripe/recipe-cms": ">=4.5,<4.5.3",
|
"silverstripe/recipe-cms": ">=4.5,<4.5.3",
|
||||||
|
@ -17299,13 +17451,20 @@
|
||||||
"twig/twig": "<3.11.2|>=3.12,<3.14.1",
|
"twig/twig": "<3.11.2|>=3.12,<3.14.1",
|
||||||
"typo3/cms": "<9.5.29|>=10,<10.4.35|>=11,<11.5.23|>=12,<12.2",
|
"typo3/cms": "<9.5.29|>=10,<10.4.35|>=11,<11.5.23|>=12,<12.2",
|
||||||
"typo3/cms-backend": "<4.1.14|>=4.2,<4.2.15|>=4.3,<4.3.7|>=4.4,<4.4.4|>=7,<=7.6.50|>=8,<=8.7.39|>=9,<=9.5.24|>=10,<10.4.46|>=11,<11.5.40|>=12,<12.4.21|>=13,<13.3.1",
|
"typo3/cms-backend": "<4.1.14|>=4.2,<4.2.15|>=4.3,<4.3.7|>=4.4,<4.4.4|>=7,<=7.6.50|>=8,<=8.7.39|>=9,<=9.5.24|>=10,<10.4.46|>=11,<11.5.40|>=12,<12.4.21|>=13,<13.3.1",
|
||||||
"typo3/cms-core": "<=8.7.56|>=9,<=9.5.47|>=10,<=10.4.44|>=11,<=11.5.36|>=12,<=12.4.14|>=13,<=13.1",
|
"typo3/cms-belog": ">=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2",
|
||||||
|
"typo3/cms-beuser": ">=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2",
|
||||||
|
"typo3/cms-core": "<=8.7.56|>=9,<=9.5.48|>=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2",
|
||||||
|
"typo3/cms-dashboard": ">=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2",
|
||||||
"typo3/cms-extbase": "<6.2.24|>=7,<7.6.8|==8.1.1",
|
"typo3/cms-extbase": "<6.2.24|>=7,<7.6.8|==8.1.1",
|
||||||
|
"typo3/cms-extensionmanager": ">=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2",
|
||||||
"typo3/cms-fluid": "<4.3.4|>=4.4,<4.4.1",
|
"typo3/cms-fluid": "<4.3.4|>=4.4,<4.4.1",
|
||||||
"typo3/cms-form": ">=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1",
|
"typo3/cms-form": ">=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2",
|
||||||
"typo3/cms-frontend": "<4.3.9|>=4.4,<4.4.5",
|
"typo3/cms-frontend": "<4.3.9|>=4.4,<4.4.5",
|
||||||
"typo3/cms-install": "<4.1.14|>=4.2,<4.2.16|>=4.3,<4.3.9|>=4.4,<4.4.5|>=12.2,<12.4.8",
|
"typo3/cms-indexed-search": ">=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2",
|
||||||
|
"typo3/cms-install": "<4.1.14|>=4.2,<4.2.16|>=4.3,<4.3.9|>=4.4,<4.4.5|>=12.2,<12.4.8|==13.4.2",
|
||||||
|
"typo3/cms-lowlevel": ">=11,<=11.5.41",
|
||||||
"typo3/cms-rte-ckeditor": ">=9.5,<9.5.42|>=10,<10.4.39|>=11,<11.5.30",
|
"typo3/cms-rte-ckeditor": ">=9.5,<9.5.42|>=10,<10.4.39|>=11,<11.5.30",
|
||||||
|
"typo3/cms-scheduler": ">=11,<=11.5.41",
|
||||||
"typo3/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6",
|
"typo3/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6",
|
||||||
"typo3/html-sanitizer": ">=1,<=1.5.2|>=2,<=2.1.3",
|
"typo3/html-sanitizer": ">=1,<=1.5.2|>=2,<=2.1.3",
|
||||||
"typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.3.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<3.3.23|>=4,<4.0.17|>=4.1,<4.1.16|>=4.2,<4.2.12|>=4.3,<4.3.3",
|
"typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.3.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<3.3.23|>=4,<4.0.17|>=4.1,<4.1.16|>=4.2,<4.2.12|>=4.3,<4.3.3",
|
||||||
|
@ -17453,7 +17612,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2025-01-06T20:04:58+00:00"
|
"time": "2025-01-15T23:05:13+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sebastian/cli-parser",
|
"name": "sebastian/cli-parser",
|
||||||
|
@ -18629,16 +18788,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/maker-bundle",
|
"name": "symfony/maker-bundle",
|
||||||
"version": "v1.61.0",
|
"version": "v1.62.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/maker-bundle.git",
|
"url": "https://github.com/symfony/maker-bundle.git",
|
||||||
"reference": "a3b7f14d349f8f44ed752d4dde2263f77510cc18"
|
"reference": "468ff2708200c95ebc0d85d3174b6c6711b8a590"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/maker-bundle/zipball/a3b7f14d349f8f44ed752d4dde2263f77510cc18",
|
"url": "https://api.github.com/repos/symfony/maker-bundle/zipball/468ff2708200c95ebc0d85d3174b6c6711b8a590",
|
||||||
"reference": "a3b7f14d349f8f44ed752d4dde2263f77510cc18",
|
"reference": "468ff2708200c95ebc0d85d3174b6c6711b8a590",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -18701,7 +18860,7 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/symfony/maker-bundle/issues",
|
"issues": "https://github.com/symfony/maker-bundle/issues",
|
||||||
"source": "https://github.com/symfony/maker-bundle/tree/v1.61.0"
|
"source": "https://github.com/symfony/maker-bundle/tree/v1.62.1"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -18717,7 +18876,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2024-08-29T22:50:23+00:00"
|
"time": "2025-01-15T00:21:40+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/phpunit-bridge",
|
"name": "symfony/phpunit-bridge",
|
||||||
|
@ -19006,6 +19165,7 @@
|
||||||
"minimum-stability": "stable",
|
"minimum-stability": "stable",
|
||||||
"stability-flags": {
|
"stability-flags": {
|
||||||
"florianv/swap-bundle": 20,
|
"florianv/swap-bundle": 20,
|
||||||
|
"jbtronics/settings-bundle": 20,
|
||||||
"roave/security-advisories": 20
|
"roave/security-advisories": 20
|
||||||
},
|
},
|
||||||
"prefer-stable": false,
|
"prefer-stable": false,
|
||||||
|
|
|
@ -31,5 +31,6 @@ return [
|
||||||
KnpU\OAuth2ClientBundle\KnpUOAuth2ClientBundle::class => ['all' => true],
|
KnpU\OAuth2ClientBundle\KnpUOAuth2ClientBundle::class => ['all' => true],
|
||||||
Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true],
|
Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true],
|
||||||
ApiPlatform\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true],
|
ApiPlatform\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true],
|
||||||
|
Jbtronics\SettingsBundle\JbtronicsSettingsBundle::class => ['all' => true],
|
||||||
Jbtronics\TranslationEditorBundle\JbtronicsTranslationEditorBundle::class => ['dev' => true],
|
Jbtronics\TranslationEditorBundle\JbtronicsTranslationEditorBundle::class => ['dev' => true],
|
||||||
];
|
];
|
||||||
|
|
|
@ -9,7 +9,8 @@ datatables:
|
||||||
# Set options, as documented at https://datatables.net/reference/option/
|
# Set options, as documented at https://datatables.net/reference/option/
|
||||||
options:
|
options:
|
||||||
lengthMenu : [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]]
|
lengthMenu : [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]]
|
||||||
pageLength: '%partdb.table.default_page_size%' # Set to -1 to disable pagination (i.e. show all rows) by default
|
#pageLength: '%partdb.table.default_page_size%' # Set to -1 to disable pagination (i.e. show all rows) by default
|
||||||
|
pageLength: 50 #TODO
|
||||||
dom: " <'row' <'col mb-2 input-group flex-nowrap' B l > <'col-auto mb-2' < p >>>
|
dom: " <'row' <'col mb-2 input-group flex-nowrap' B l > <'col-auto mb-2' < p >>>
|
||||||
<'card'
|
<'card'
|
||||||
rt
|
rt
|
||||||
|
|
2
config/packages/settings.yaml
Normal file
2
config/packages/settings.yaml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
jbtronics_settings:
|
||||||
|
default_storage_adapter: Jbtronics\SettingsBundle\Storage\PHPFileStorageAdapter
|
|
@ -1,11 +1,10 @@
|
||||||
framework:
|
framework:
|
||||||
default_locale: '%partdb.locale%'
|
default_locale: 'en'
|
||||||
# Just enable the locales we need for performance reasons.
|
# Just enable the locales we need for performance reasons.
|
||||||
enabled_locale: '%partdb.locale_menu%'
|
enabled_locale: '%partdb.locale_menu%'
|
||||||
translator:
|
translator:
|
||||||
default_path: '%kernel.project_dir%/translations'
|
default_path: '%kernel.project_dir%/translations'
|
||||||
fallbacks:
|
fallbacks:
|
||||||
- '%partdb.locale%'
|
|
||||||
- 'en'
|
- 'en'
|
||||||
providers:
|
providers:
|
||||||
# crowdin:
|
# crowdin:
|
||||||
|
|
|
@ -6,16 +6,12 @@ twig:
|
||||||
'%kernel.project_dir%/assets/css': css
|
'%kernel.project_dir%/assets/css': css
|
||||||
|
|
||||||
globals:
|
globals:
|
||||||
partdb_title: '%partdb.title%'
|
|
||||||
default_currency: '%partdb.default_currency%'
|
|
||||||
global_theme: '%partdb.global_theme%'
|
|
||||||
allow_email_pw_reset: '%partdb.users.email_pw_reset%'
|
allow_email_pw_reset: '%partdb.users.email_pw_reset%'
|
||||||
locale_menu: '%partdb.locale_menu%'
|
locale_menu: '%partdb.locale_menu%'
|
||||||
attachment_manager: '@App\Services\Attachments\AttachmentManager'
|
attachment_manager: '@App\Services\Attachments\AttachmentManager'
|
||||||
label_profile_dropdown_helper: '@App\Services\LabelSystem\LabelProfileDropdownHelper'
|
label_profile_dropdown_helper: '@App\Services\LabelSystem\LabelProfileDropdownHelper'
|
||||||
error_page_admin_email: '%partdb.error_pages.admin_email%'
|
error_page_admin_email: '%partdb.error_pages.admin_email%'
|
||||||
error_page_show_help: '%partdb.error_pages.show_help%'
|
error_page_show_help: '%partdb.error_pages.show_help%'
|
||||||
sidebar_items: '%partdb.sidebar.items%'
|
|
||||||
sidebar_tree_updater: '@App\Services\Trees\SidebarTreeUpdater'
|
sidebar_tree_updater: '@App\Services\Trees\SidebarTreeUpdater'
|
||||||
avatar_helper: '@App\Services\UserSystem\UserAvatarHelper'
|
avatar_helper: '@App\Services\UserSystem\UserAvatarHelper'
|
||||||
available_themes: '%partdb.available_themes%'
|
available_themes: '%partdb.available_themes%'
|
||||||
|
|
|
@ -5,14 +5,10 @@ parameters:
|
||||||
######################################################################################################################
|
######################################################################################################################
|
||||||
# Common
|
# Common
|
||||||
######################################################################################################################
|
######################################################################################################################
|
||||||
partdb.locale: '%env(string:DEFAULT_LANG)%' # The default language to use serverwide
|
|
||||||
partdb.timezone: '%env(string:DEFAULT_TIMEZONE)%' # The default timezone
|
# This is used as workaround for places where we can not access the settings directly (like the 2FA application names)
|
||||||
partdb.title: '%env(trim:string:INSTANCE_NAME)%' # The title shown inside of Part-DB (e.g. in the navbar and on homepage)
|
partdb.title: '%env(string:settings:customization:instanceName)%' # The title shown inside of Part-DB (e.g. in the navbar and on homepage)
|
||||||
partdb.banner: '%env(trim:string:BANNER)%' # The info text shown in the homepage, if empty config/banner.md is used
|
|
||||||
partdb.default_currency: '%env(string:BASE_CURRENCY)%' # The currency that is used inside the DB (and is assumed when no currency is set). This can not be changed later, so be sure to set it the currency used in your country
|
|
||||||
partdb.global_theme: '' # The theme to use globally (see public/build/themes/ for choices, use name without .css). Set to '' for default bootstrap theme
|
|
||||||
partdb.locale_menu: ['en', 'de', 'it', 'fr', 'ru', 'ja', 'cs', 'da', 'zh', 'pl'] # The languages that are shown in user drop down menu
|
partdb.locale_menu: ['en', 'de', 'it', 'fr', 'ru', 'ja', 'cs', 'da', 'zh', 'pl'] # The languages that are shown in user drop down menu
|
||||||
partdb.enforce_change_comments_for: '%env(csv:ENFORCE_CHANGE_COMMENTS_FOR)%' # The actions for which a change comment is required (e.g. "part_edit", "part_create", etc.). If this is empty, change comments are not required at all.
|
|
||||||
|
|
||||||
partdb.default_uri: '%env(string:DEFAULT_URI)%' # The default URI to use for the Part-DB instance (e.g. https://part-db.example.com/). This is used for generating links in emails
|
partdb.default_uri: '%env(string:DEFAULT_URI)%' # The default URI to use for the Part-DB instance (e.g. https://part-db.example.com/). This is used for generating links in emails
|
||||||
|
|
||||||
|
@ -22,11 +18,8 @@ parameters:
|
||||||
# Users and Privacy
|
# Users and Privacy
|
||||||
######################################################################################################################
|
######################################################################################################################
|
||||||
partdb.gdpr_compliance: true # If this option is activated, IP addresses are anonymized to be GDPR compliant
|
partdb.gdpr_compliance: true # If this option is activated, IP addresses are anonymized to be GDPR compliant
|
||||||
partdb.users.use_gravatar: '%env(bool:USE_GRAVATAR)%' # Set to false, if no Gravatar images should be used for user profiles.
|
|
||||||
partdb.users.email_pw_reset: '%env(bool:ALLOW_EMAIL_PW_RESET)%' # Config if users are able, to reset their password by email. By default this enabled, when a mail server is configured.
|
partdb.users.email_pw_reset: '%env(bool:ALLOW_EMAIL_PW_RESET)%' # Config if users are able, to reset their password by email. By default this enabled, when a mail server is configured.
|
||||||
|
|
||||||
partdb.check_for_updates: '%env(bool:CHECK_FOR_UPDATES)' # Set to false, if Part-DB should not contact the GitHub API to check for updates
|
|
||||||
|
|
||||||
######################################################################################################################
|
######################################################################################################################
|
||||||
# Mail settings
|
# Mail settings
|
||||||
######################################################################################################################
|
######################################################################################################################
|
||||||
|
@ -36,11 +29,8 @@ parameters:
|
||||||
######################################################################################################################
|
######################################################################################################################
|
||||||
# Attachments and files
|
# Attachments and files
|
||||||
######################################################################################################################
|
######################################################################################################################
|
||||||
partdb.attachments.allow_downloads: '%env(bool:ALLOW_ATTACHMENT_DOWNLOADS)%' # Allow users to download attachments to server. Warning: This can be dangerous, because via that feature attackers maybe can access ressources on your intranet!
|
|
||||||
partdb.attachments.download_by_default: '%env(bool:ATTACHMENT_DOWNLOAD_BY_DEFAULT)%' # If this is set the 'download external files' checkbox is set by default for new attachments (only if allow_downloads is set to true)
|
|
||||||
partdb.attachments.dir.media: 'public/media/' # The folder where uploaded attachment files are saved (must be in public folder)
|
partdb.attachments.dir.media: 'public/media/' # The folder where uploaded attachment files are saved (must be in public folder)
|
||||||
partdb.attachments.dir.secure: 'uploads/' # The folder where secured attachment files are saved (must not be in public/)
|
partdb.attachments.dir.secure: 'uploads/' # The folder where secured attachment files are saved (must not be in public/)
|
||||||
partdb.attachments.max_file_size: '%env(string:MAX_ATTACHMENT_FILE_SIZE)%' # The maximum size of an attachment file (in bytes, you can use M for megabytes and G for gigabytes)
|
|
||||||
|
|
||||||
######################################################################################################################
|
######################################################################################################################
|
||||||
# Error pages
|
# Error pages
|
||||||
|
@ -53,22 +43,6 @@ parameters:
|
||||||
######################################################################################################################
|
######################################################################################################################
|
||||||
partdb.saml.enabled: '%env(bool:SAML_ENABLED)%' # If this is set to true, SAML authentication is enabled
|
partdb.saml.enabled: '%env(bool:SAML_ENABLED)%' # If this is set to true, SAML authentication is enabled
|
||||||
|
|
||||||
######################################################################################################################
|
|
||||||
# Table settings
|
|
||||||
######################################################################################################################
|
|
||||||
partdb.table.default_page_size: '%env(int:TABLE_DEFAULT_PAGE_SIZE)%' # The default number of entries shown per page in tables
|
|
||||||
partdb.table.parts.default_columns: '%env(trim:string:TABLE_PARTS_DEFAULT_COLUMNS)%' # The default columns in part tables and their order
|
|
||||||
|
|
||||||
######################################################################################################################
|
|
||||||
# Sidebar
|
|
||||||
######################################################################################################################
|
|
||||||
# You can configures the default shown tree items in the sidebar here. You can add or remove entries here, to change the number of trees in the sidebar. The possible entries are: categories, locations, footprints, manufacturers, suppliers, devices, tools
|
|
||||||
partdb.sidebar.items:
|
|
||||||
- categories
|
|
||||||
- devices
|
|
||||||
- tools
|
|
||||||
partdb.sidebar.root_expanded: true # If this is set to true, the root node of the sidebar is expanded by default
|
|
||||||
partdb.sidebar.root_node_enable: true # Put all entities below a root node in the sidebar
|
|
||||||
|
|
||||||
######################################################################################################################
|
######################################################################################################################
|
||||||
# Miscellaneous
|
# Miscellaneous
|
||||||
|
@ -110,17 +84,8 @@ parameters:
|
||||||
# Env default values
|
# Env default values
|
||||||
######################################################################################################################
|
######################################################################################################################
|
||||||
|
|
||||||
env(DEFAULT_LANG): 'en'
|
|
||||||
env(DEFAULT_TIMEZONE): 'Europe/Berlin'
|
|
||||||
env(INSTANCE_NAME): 'Part-DB'
|
|
||||||
env(BASE_CURRENCY): 'EUR'
|
|
||||||
env(USE_GRAVATAR): '0'
|
|
||||||
env(MAX_ATTACHMENT_FILE_SIZE): '100M'
|
|
||||||
|
|
||||||
env(REDIRECT_TO_HTTPS): 0
|
env(REDIRECT_TO_HTTPS): 0
|
||||||
|
|
||||||
env(ENFORCE_CHANGE_COMMENTS_FOR): ''
|
|
||||||
|
|
||||||
env(ERROR_PAGE_ADMIN_EMAIL): ''
|
env(ERROR_PAGE_ADMIN_EMAIL): ''
|
||||||
env(ERROR_PAGE_SHOW_HELP): 1
|
env(ERROR_PAGE_SHOW_HELP): 1
|
||||||
|
|
||||||
|
@ -132,8 +97,6 @@ parameters:
|
||||||
env(EMAIL_SENDER_NAME): 'Part-DB Mailer'
|
env(EMAIL_SENDER_NAME): 'Part-DB Mailer'
|
||||||
env(ALLOW_EMAIL_PW_RESET): 0
|
env(ALLOW_EMAIL_PW_RESET): 0
|
||||||
|
|
||||||
env(TABLE_DEFAULT_PAGE_SIZE): 50
|
|
||||||
|
|
||||||
env(TRUSTED_PROXIES): '127.0.0.1' #By default trust only our own server
|
env(TRUSTED_PROXIES): '127.0.0.1' #By default trust only our own server
|
||||||
env(TRUSTED_HOSTS): '' # Trust all host names by default
|
env(TRUSTED_HOSTS): '' # Trust all host names by default
|
||||||
|
|
||||||
|
@ -141,11 +104,4 @@ parameters:
|
||||||
|
|
||||||
env(SAML_ROLE_MAPPING): '{}'
|
env(SAML_ROLE_MAPPING): '{}'
|
||||||
|
|
||||||
env(HISTORY_SAVE_CHANGED_DATA): 1
|
|
||||||
env(HISTORY_SAVE_CHANGED_FIELDS): 1
|
|
||||||
env(HISTORY_SAVE_REMOVED_DATA): 1
|
|
||||||
env(HISTORY_SAVE_NEW_DATA): 1
|
|
||||||
|
|
||||||
env(EDA_KICAD_CATEGORY_DEPTH): 0
|
|
||||||
|
|
||||||
env(DATABASE_EMULATE_NATURAL_SORT): 0
|
env(DATABASE_EMULATE_NATURAL_SORT): 0
|
||||||
|
|
|
@ -17,8 +17,6 @@ services:
|
||||||
bool $gdpr_compliance: '%partdb.gdpr_compliance%'
|
bool $gdpr_compliance: '%partdb.gdpr_compliance%'
|
||||||
bool $kernel_debug_enabled: '%kernel.debug%'
|
bool $kernel_debug_enabled: '%kernel.debug%'
|
||||||
string $kernel_cache_dir: '%kernel.cache_dir%'
|
string $kernel_cache_dir: '%kernel.cache_dir%'
|
||||||
string $partdb_title: '%partdb.title%'
|
|
||||||
string $base_currency: '%partdb.default_currency%'
|
|
||||||
|
|
||||||
_instanceof:
|
_instanceof:
|
||||||
App\Services\LabelSystem\PlaceholderProviders\PlaceholderProviderInterface:
|
App\Services\LabelSystem\PlaceholderProviders\PlaceholderProviderInterface:
|
||||||
|
@ -76,28 +74,10 @@ services:
|
||||||
# Only the event classes specified here are saved to DB (set to []) to log all events
|
# Only the event classes specified here are saved to DB (set to []) to log all events
|
||||||
$whitelist: []
|
$whitelist: []
|
||||||
|
|
||||||
App\EventListener\LogSystem\EventLoggerListener:
|
|
||||||
arguments:
|
|
||||||
$save_changed_fields: '%env(bool:HISTORY_SAVE_CHANGED_FIELDS)%'
|
|
||||||
$save_changed_data: '%env(bool:HISTORY_SAVE_CHANGED_DATA)%'
|
|
||||||
$save_removed_data: '%env(bool:HISTORY_SAVE_REMOVED_DATA)%'
|
|
||||||
$save_new_data: '%env(bool:HISTORY_SAVE_NEW_DATA)%'
|
|
||||||
|
|
||||||
App\Form\AttachmentFormType:
|
|
||||||
arguments:
|
|
||||||
$allow_attachments_download: '%partdb.attachments.allow_downloads%'
|
|
||||||
$max_file_size: '%partdb.attachments.max_file_size%'
|
|
||||||
$download_by_default: '%partdb.attachments.download_by_default%'
|
|
||||||
|
|
||||||
App\Services\Attachments\AttachmentSubmitHandler:
|
App\Services\Attachments\AttachmentSubmitHandler:
|
||||||
arguments:
|
arguments:
|
||||||
$allow_attachments_downloads: '%partdb.attachments.allow_downloads%'
|
|
||||||
$mimeTypes: '@mime_types'
|
$mimeTypes: '@mime_types'
|
||||||
$max_upload_size: '%partdb.attachments.max_file_size%'
|
|
||||||
|
|
||||||
App\Services\LogSystem\EventCommentNeededHelper:
|
|
||||||
arguments:
|
|
||||||
$enforce_change_comments_for: '%partdb.enforce_change_comments_for%'
|
|
||||||
|
|
||||||
####################################################################################################################
|
####################################################################################################################
|
||||||
# Attachment system
|
# Attachment system
|
||||||
|
@ -156,29 +136,6 @@ services:
|
||||||
tags:
|
tags:
|
||||||
- { name: doctrine.orm.entity_listener }
|
- { name: doctrine.orm.entity_listener }
|
||||||
|
|
||||||
####################################################################################################################
|
|
||||||
# Price system
|
|
||||||
####################################################################################################################
|
|
||||||
App\Command\Currencies\UpdateExchangeRatesCommand:
|
|
||||||
arguments:
|
|
||||||
$base_current: '%partdb.default_currency%'
|
|
||||||
|
|
||||||
App\Form\Type\CurrencyEntityType:
|
|
||||||
arguments:
|
|
||||||
$base_currency: '%partdb.default_currency%'
|
|
||||||
|
|
||||||
App\Services\Parts\PricedetailHelper:
|
|
||||||
arguments:
|
|
||||||
$base_currency: '%partdb.default_currency%'
|
|
||||||
|
|
||||||
App\Services\Formatters\MoneyFormatter:
|
|
||||||
arguments:
|
|
||||||
$base_currency: '%partdb.default_currency%'
|
|
||||||
|
|
||||||
App\Services\Tools\ExchangeRateUpdater:
|
|
||||||
arguments:
|
|
||||||
$base_currency: '%partdb.default_currency%'
|
|
||||||
|
|
||||||
###################################################################################################################
|
###################################################################################################################
|
||||||
# User system
|
# User system
|
||||||
####################################################################################################################
|
####################################################################################################################
|
||||||
|
@ -186,10 +143,6 @@ services:
|
||||||
arguments:
|
arguments:
|
||||||
$demo_mode: '%partdb.demo_mode%'
|
$demo_mode: '%partdb.demo_mode%'
|
||||||
|
|
||||||
App\EventSubscriber\UserSystem\SetUserTimezoneSubscriber:
|
|
||||||
arguments:
|
|
||||||
$default_timezone: '%partdb.timezone%'
|
|
||||||
|
|
||||||
App\Controller\SecurityController:
|
App\Controller\SecurityController:
|
||||||
arguments:
|
arguments:
|
||||||
$allow_email_pw_reset: '%partdb.users.email_pw_reset%'
|
$allow_email_pw_reset: '%partdb.users.email_pw_reset%'
|
||||||
|
@ -203,10 +156,6 @@ services:
|
||||||
tags:
|
tags:
|
||||||
- { name: 'translation.extractor', alias: 'permissionExtractor'}
|
- { name: 'translation.extractor', alias: 'permissionExtractor'}
|
||||||
|
|
||||||
App\Services\UserSystem\UserAvatarHelper:
|
|
||||||
arguments:
|
|
||||||
$use_gravatar: '%partdb.users.use_gravatar%'
|
|
||||||
|
|
||||||
App\Form\Type\ThemeChoiceType:
|
App\Form\Type\ThemeChoiceType:
|
||||||
arguments:
|
arguments:
|
||||||
$available_themes: '%partdb.available_themes%'
|
$available_themes: '%partdb.available_themes%'
|
||||||
|
@ -222,9 +171,6 @@ services:
|
||||||
####################################################################################################################
|
####################################################################################################################
|
||||||
# Table settings
|
# Table settings
|
||||||
####################################################################################################################
|
####################################################################################################################
|
||||||
App\DataTables\PartsDataTable:
|
|
||||||
arguments:
|
|
||||||
$visible_columns: '%partdb.table.parts.default_columns%'
|
|
||||||
|
|
||||||
App\DataTables\Helpers\ColumnSortHelper:
|
App\DataTables\Helpers\ColumnSortHelper:
|
||||||
shared: false # Service has a state so not share it between different tables
|
shared: false # Service has a state so not share it between different tables
|
||||||
|
@ -246,14 +192,6 @@ services:
|
||||||
$fontDirectory: '%kernel.project_dir%/var/dompdf/fonts/'
|
$fontDirectory: '%kernel.project_dir%/var/dompdf/fonts/'
|
||||||
$tmpDirectory: '%kernel.project_dir%/var/dompdf/tmp/'
|
$tmpDirectory: '%kernel.project_dir%/var/dompdf/tmp/'
|
||||||
|
|
||||||
####################################################################################################################
|
|
||||||
# Trees
|
|
||||||
####################################################################################################################
|
|
||||||
App\Services\Trees\TreeViewGenerator:
|
|
||||||
arguments:
|
|
||||||
$rootNodeExpandedByDefault: '%partdb.sidebar.root_expanded%'
|
|
||||||
$rootNodeEnabled: '%partdb.sidebar.root_node_enable%'
|
|
||||||
|
|
||||||
####################################################################################################################
|
####################################################################################################################
|
||||||
# Part info provider system
|
# Part info provider system
|
||||||
####################################################################################################################
|
####################################################################################################################
|
||||||
|
@ -261,11 +199,6 @@ services:
|
||||||
arguments:
|
arguments:
|
||||||
$providers: !tagged_iterator 'app.info_provider'
|
$providers: !tagged_iterator 'app.info_provider'
|
||||||
|
|
||||||
App\Services\InfoProviderSystem\Providers\Element14Provider:
|
|
||||||
arguments:
|
|
||||||
$api_key: '%env(string:PROVIDER_ELEMENT14_KEY)%'
|
|
||||||
$store_id: '%env(string:PROVIDER_ELEMENT14_STORE_ID)%'
|
|
||||||
|
|
||||||
App\Services\InfoProviderSystem\Providers\DigikeyProvider:
|
App\Services\InfoProviderSystem\Providers\DigikeyProvider:
|
||||||
arguments:
|
arguments:
|
||||||
$clientId: '%env(string:PROVIDER_DIGIKEY_CLIENT_ID)%'
|
$clientId: '%env(string:PROVIDER_DIGIKEY_CLIENT_ID)%'
|
||||||
|
@ -273,18 +206,6 @@ services:
|
||||||
$language: '%env(string:PROVIDER_DIGIKEY_LANGUAGE)%'
|
$language: '%env(string:PROVIDER_DIGIKEY_LANGUAGE)%'
|
||||||
$country: '%env(string:PROVIDER_DIGIKEY_COUNTRY)%'
|
$country: '%env(string:PROVIDER_DIGIKEY_COUNTRY)%'
|
||||||
|
|
||||||
App\Services\InfoProviderSystem\Providers\TMEClient:
|
|
||||||
arguments:
|
|
||||||
$secret: '%env(string:PROVIDER_TME_SECRET)%'
|
|
||||||
$token: '%env(string:PROVIDER_TME_KEY)%'
|
|
||||||
|
|
||||||
App\Services\InfoProviderSystem\Providers\TMEProvider:
|
|
||||||
arguments:
|
|
||||||
$currency: '%env(string:PROVIDER_TME_CURRENCY)%'
|
|
||||||
$country: '%env(string:PROVIDER_TME_COUNTRY)%'
|
|
||||||
$language: '%env(string:PROVIDER_TME_LANGUAGE)%'
|
|
||||||
$get_gross_prices: '%env(bool:PROVIDER_TME_GET_GROSS_PRICES)%'
|
|
||||||
|
|
||||||
App\Services\InfoProviderSystem\Providers\OctopartProvider:
|
App\Services\InfoProviderSystem\Providers\OctopartProvider:
|
||||||
arguments:
|
arguments:
|
||||||
$clientId: '&env(string:PROVIDER_OCTOPART_CLIENT_ID)%'
|
$clientId: '&env(string:PROVIDER_OCTOPART_CLIENT_ID)%'
|
||||||
|
@ -294,27 +215,6 @@ services:
|
||||||
$search_limit: '%env(int:PROVIDER_OCTOPART_SEARCH_LIMIT)%'
|
$search_limit: '%env(int:PROVIDER_OCTOPART_SEARCH_LIMIT)%'
|
||||||
$onlyAuthorizedSellers: '%env(bool:PROVIDER_OCTOPART_ONLY_AUTHORIZED_SELLERS)%'
|
$onlyAuthorizedSellers: '%env(bool:PROVIDER_OCTOPART_ONLY_AUTHORIZED_SELLERS)%'
|
||||||
|
|
||||||
App\Services\InfoProviderSystem\Providers\MouserProvider:
|
|
||||||
arguments:
|
|
||||||
$api_key: '%env(string:PROVIDER_MOUSER_KEY)%'
|
|
||||||
$language: '%env(string:PROVIDER_MOUSER_SEARCH_WITH_SIGNUP_LANGUAGE)%'
|
|
||||||
$options: '%env(string:PROVIDER_MOUSER_SEARCH_OPTION)%'
|
|
||||||
$search_limit: '%env(int:PROVIDER_MOUSER_SEARCH_LIMIT)%'
|
|
||||||
|
|
||||||
App\Services\InfoProviderSystem\Providers\LCSCProvider:
|
|
||||||
arguments:
|
|
||||||
$enabled: '%env(bool:PROVIDER_LCSC_ENABLED)%'
|
|
||||||
$currency: '%env(string:PROVIDER_LCSC_CURRENCY)%'
|
|
||||||
|
|
||||||
App\Services\InfoProviderSystem\Providers\OEMSecretsProvider:
|
|
||||||
arguments:
|
|
||||||
$api_key: '%env(string:PROVIDER_OEMSECRETS_KEY)%'
|
|
||||||
$country_code: '%env(string:PROVIDER_OEMSECRETS_COUNTRY_CODE)%'
|
|
||||||
$currency: '%env(PROVIDER_OEMSECRETS_CURRENCY)%'
|
|
||||||
$zero_price: '%env(PROVIDER_OEMSECRETS_ZERO_PRICE)%'
|
|
||||||
$set_param: '%env(PROVIDER_OEMSECRETS_SET_PARAM)%'
|
|
||||||
$sort_criteria: '%env(PROVIDER_OEMSECRETS_SORT_CRITERIA)%'
|
|
||||||
|
|
||||||
|
|
||||||
####################################################################################################################
|
####################################################################################################################
|
||||||
# API system
|
# API system
|
||||||
|
@ -322,15 +222,6 @@ services:
|
||||||
App\State\PartDBInfoProvider:
|
App\State\PartDBInfoProvider:
|
||||||
arguments:
|
arguments:
|
||||||
$default_uri: '%partdb.default_uri%'
|
$default_uri: '%partdb.default_uri%'
|
||||||
$global_locale: '%partdb.locale%'
|
|
||||||
$global_timezone: '%partdb.timezone%'
|
|
||||||
|
|
||||||
####################################################################################################################
|
|
||||||
# EDA system
|
|
||||||
####################################################################################################################
|
|
||||||
App\Services\EDA\KiCadHelper:
|
|
||||||
arguments:
|
|
||||||
$category_depth: '%env(int:EDA_KICAD_CATEGORY_DEPTH)%'
|
|
||||||
|
|
||||||
####################################################################################################################
|
####################################################################################################################
|
||||||
# Symfony overrides
|
# Symfony overrides
|
||||||
|
@ -355,7 +246,6 @@ services:
|
||||||
####################################################################################################################
|
####################################################################################################################
|
||||||
App\Controller\RedirectController:
|
App\Controller\RedirectController:
|
||||||
arguments:
|
arguments:
|
||||||
$default_locale: '%partdb.locale%'
|
|
||||||
$enforce_index_php: '%env(bool:NO_URL_REWRITE_AVAILABLE)%'
|
$enforce_index_php: '%env(bool:NO_URL_REWRITE_AVAILABLE)%'
|
||||||
|
|
||||||
App\Doctrine\Purger\ResetAutoIncrementPurgerFactory:
|
App\Doctrine\Purger\ResetAutoIncrementPurgerFactory:
|
||||||
|
@ -370,14 +260,6 @@ services:
|
||||||
arguments:
|
arguments:
|
||||||
$project_dir: '%kernel.project_dir%'
|
$project_dir: '%kernel.project_dir%'
|
||||||
|
|
||||||
App\Services\System\UpdateAvailableManager:
|
|
||||||
arguments:
|
|
||||||
$check_for_updates: '%partdb.check_for_updates%'
|
|
||||||
|
|
||||||
App\Services\System\BannerHelper:
|
|
||||||
arguments:
|
|
||||||
$partdb_banner: '%partdb.banner%'
|
|
||||||
$project_dir: '%kernel.project_dir%'
|
|
||||||
|
|
||||||
App\Doctrine\Middleware\MySQLSSLConnectionMiddlewareWrapper:
|
App\Doctrine\Middleware\MySQLSSLConnectionMiddlewareWrapper:
|
||||||
arguments:
|
arguments:
|
||||||
|
|
|
@ -22,6 +22,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Command\Currencies;
|
namespace App\Command\Currencies;
|
||||||
|
|
||||||
|
use App\Settings\SystemSettings\LocalizationSettings;
|
||||||
use Symfony\Component\Console\Attribute\AsCommand;
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
use App\Entity\PriceInformations\Currency;
|
use App\Entity\PriceInformations\Currency;
|
||||||
use App\Services\Tools\ExchangeRateUpdater;
|
use App\Services\Tools\ExchangeRateUpdater;
|
||||||
|
@ -39,7 +40,7 @@ use function strlen;
|
||||||
#[AsCommand('partdb:currencies:update-exchange-rates|partdb:update-exchange-rates|app:update-exchange-rates', 'Updates the currency exchange rates.')]
|
#[AsCommand('partdb:currencies:update-exchange-rates|partdb:update-exchange-rates|app:update-exchange-rates', 'Updates the currency exchange rates.')]
|
||||||
class UpdateExchangeRatesCommand extends Command
|
class UpdateExchangeRatesCommand extends Command
|
||||||
{
|
{
|
||||||
public function __construct(protected string $base_current, protected EntityManagerInterface $em, protected ExchangeRateUpdater $exchangeRateUpdater)
|
public function __construct(protected EntityManagerInterface $em, protected ExchangeRateUpdater $exchangeRateUpdater, private readonly LocalizationSettings $localizationSettings)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
@ -54,13 +55,13 @@ class UpdateExchangeRatesCommand extends Command
|
||||||
$io = new SymfonyStyle($input, $output);
|
$io = new SymfonyStyle($input, $output);
|
||||||
|
|
||||||
//Check for valid base current
|
//Check for valid base current
|
||||||
if (3 !== strlen($this->base_current)) {
|
if (3 !== strlen($this->localizationSettings->baseCurrency)) {
|
||||||
$io->error('Chosen Base current is not valid. Check your settings!');
|
$io->error('Chosen Base current is not valid. Check your settings!');
|
||||||
|
|
||||||
return Command::FAILURE;
|
return Command::FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
$io->note('Update currency exchange rates with base currency: '.$this->base_current);
|
$io->note('Update currency exchange rates with base currency: '.$this->localizationSettings->baseCurrency);
|
||||||
|
|
||||||
//Check what currencies we need to update:
|
//Check what currencies we need to update:
|
||||||
$iso_code = $input->getArgument('iso_code');
|
$iso_code = $input->getArgument('iso_code');
|
||||||
|
|
|
@ -28,6 +28,7 @@ use App\Entity\Attachments\Attachment;
|
||||||
use App\Form\Filters\AttachmentFilterType;
|
use App\Form\Filters\AttachmentFilterType;
|
||||||
use App\Services\Attachments\AttachmentManager;
|
use App\Services\Attachments\AttachmentManager;
|
||||||
use App\Services\Trees\NodesListBuilder;
|
use App\Services\Trees\NodesListBuilder;
|
||||||
|
use App\Settings\BehaviorSettings\TableSettings;
|
||||||
use Omines\DataTablesBundle\DataTableFactory;
|
use Omines\DataTablesBundle\DataTableFactory;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
@ -98,7 +99,8 @@ class AttachmentFileController extends AbstractController
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route(path: '/attachment/list', name: 'attachment_list')]
|
#[Route(path: '/attachment/list', name: 'attachment_list')]
|
||||||
public function attachmentsTable(Request $request, DataTableFactory $dataTableFactory, NodesListBuilder $nodesListBuilder): Response
|
public function attachmentsTable(Request $request, DataTableFactory $dataTableFactory, NodesListBuilder $nodesListBuilder,
|
||||||
|
TableSettings $tableSettings): Response
|
||||||
{
|
{
|
||||||
$this->denyAccessUnlessGranted('@attachments.list_attachments');
|
$this->denyAccessUnlessGranted('@attachments.list_attachments');
|
||||||
|
|
||||||
|
@ -110,7 +112,7 @@ class AttachmentFileController extends AbstractController
|
||||||
|
|
||||||
$filterForm->handleRequest($formRequest);
|
$filterForm->handleRequest($formRequest);
|
||||||
|
|
||||||
$table = $dataTableFactory->createFromType(AttachmentDataTable::class, ['filter' => $filter])
|
$table = $dataTableFactory->createFromType(AttachmentDataTable::class, ['filter' => $filter], ['pageLength' => $tableSettings->fullDefaultPageSize])
|
||||||
->handleRequest($request);
|
->handleRequest($request);
|
||||||
|
|
||||||
if ($table->isCallback()) {
|
if ($table->isCallback()) {
|
||||||
|
|
|
@ -38,6 +38,7 @@ use App\Services\LogSystem\LogEntryExtraFormatter;
|
||||||
use App\Services\LogSystem\LogLevelHelper;
|
use App\Services\LogSystem\LogLevelHelper;
|
||||||
use App\Services\LogSystem\LogTargetHelper;
|
use App\Services\LogSystem\LogTargetHelper;
|
||||||
use App\Services\LogSystem\TimeTravel;
|
use App\Services\LogSystem\TimeTravel;
|
||||||
|
use App\Settings\BehaviorSettings\TableSettings;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use Omines\DataTablesBundle\DataTableFactory;
|
use Omines\DataTablesBundle\DataTableFactory;
|
||||||
|
@ -58,7 +59,7 @@ class LogController extends AbstractController
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route(path: '/', name: 'log_view')]
|
#[Route(path: '/', name: 'log_view')]
|
||||||
public function showLogs(Request $request, DataTableFactory $dataTable): Response
|
public function showLogs(Request $request, DataTableFactory $dataTable, TableSettings $tableSettings): Response
|
||||||
{
|
{
|
||||||
$this->denyAccessUnlessGranted('@system.show_logs');
|
$this->denyAccessUnlessGranted('@system.show_logs');
|
||||||
|
|
||||||
|
@ -72,7 +73,7 @@ class LogController extends AbstractController
|
||||||
|
|
||||||
$table = $dataTable->createFromType(LogDataTable::class, [
|
$table = $dataTable->createFromType(LogDataTable::class, [
|
||||||
'filter' => $filter,
|
'filter' => $filter,
|
||||||
])
|
], ['pageLength' => $tableSettings->fullDefaultPageSize])
|
||||||
->handleRequest($request);
|
->handleRequest($request);
|
||||||
|
|
||||||
if ($table->isCallback()) {
|
if ($table->isCallback()) {
|
||||||
|
|
|
@ -35,6 +35,7 @@ use App\Exceptions\InvalidRegexException;
|
||||||
use App\Form\Filters\PartFilterType;
|
use App\Form\Filters\PartFilterType;
|
||||||
use App\Services\Parts\PartsTableActionHandler;
|
use App\Services\Parts\PartsTableActionHandler;
|
||||||
use App\Services\Trees\NodesListBuilder;
|
use App\Services\Trees\NodesListBuilder;
|
||||||
|
use App\Settings\BehaviorSettings\TableSettings;
|
||||||
use Doctrine\DBAL\Exception\DriverException;
|
use Doctrine\DBAL\Exception\DriverException;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Omines\DataTablesBundle\DataTableFactory;
|
use Omines\DataTablesBundle\DataTableFactory;
|
||||||
|
@ -47,7 +48,12 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
class PartListsController extends AbstractController
|
class PartListsController extends AbstractController
|
||||||
{
|
{
|
||||||
public function __construct(private readonly EntityManagerInterface $entityManager, private readonly NodesListBuilder $nodesListBuilder, private readonly DataTableFactory $dataTableFactory, private readonly TranslatorInterface $translator)
|
public function __construct(private readonly EntityManagerInterface $entityManager,
|
||||||
|
private readonly NodesListBuilder $nodesListBuilder,
|
||||||
|
private readonly DataTableFactory $dataTableFactory,
|
||||||
|
private readonly TranslatorInterface $translator,
|
||||||
|
private readonly TableSettings $tableSettings
|
||||||
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +138,7 @@ class PartListsController extends AbstractController
|
||||||
|
|
||||||
$filterForm->handleRequest($formRequest);
|
$filterForm->handleRequest($formRequest);
|
||||||
|
|
||||||
$table = $this->dataTableFactory->createFromType(PartsDataTable::class, array_merge(['filter' => $filter], $additional_table_vars))
|
$table = $this->dataTableFactory->createFromType(PartsDataTable::class, array_merge(['filter' => $filter], $additional_table_vars), ['pageLength' => $this->tableSettings->fullDefaultPageSize])
|
||||||
->handleRequest($request);
|
->handleRequest($request);
|
||||||
|
|
||||||
if ($table->isCallback()) {
|
if ($table->isCallback()) {
|
||||||
|
|
|
@ -31,6 +31,7 @@ use App\Form\ProjectSystem\ProjectBuildType;
|
||||||
use App\Helpers\Projects\ProjectBuildRequest;
|
use App\Helpers\Projects\ProjectBuildRequest;
|
||||||
use App\Services\ImportExportSystem\BOMImporter;
|
use App\Services\ImportExportSystem\BOMImporter;
|
||||||
use App\Services\ProjectSystem\ProjectBuildHelper;
|
use App\Services\ProjectSystem\ProjectBuildHelper;
|
||||||
|
use App\Settings\BehaviorSettings\TableSettings;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use League\Csv\SyntaxError;
|
use League\Csv\SyntaxError;
|
||||||
|
@ -55,11 +56,12 @@ class ProjectController extends AbstractController
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route(path: '/{id}/info', name: 'project_info', requirements: ['id' => '\d+'])]
|
#[Route(path: '/{id}/info', name: 'project_info', requirements: ['id' => '\d+'])]
|
||||||
public function info(Project $project, Request $request, ProjectBuildHelper $buildHelper): Response
|
public function info(Project $project, Request $request, ProjectBuildHelper $buildHelper, TableSettings $tableSettings): Response
|
||||||
{
|
{
|
||||||
$this->denyAccessUnlessGranted('read', $project);
|
$this->denyAccessUnlessGranted('read', $project);
|
||||||
|
|
||||||
$table = $this->dataTableFactory->createFromType(ProjectBomEntriesDataTable::class, ['project' => $project])
|
$table = $this->dataTableFactory->createFromType(ProjectBomEntriesDataTable::class, ['project' => $project],
|
||||||
|
['pageLength' => $tableSettings->fullDefaultPageSize])
|
||||||
->handleRequest($request);
|
->handleRequest($request);
|
||||||
|
|
||||||
if ($table->isCallback()) {
|
if ($table->isCallback()) {
|
||||||
|
|
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||||
namespace App\Controller;
|
namespace App\Controller;
|
||||||
|
|
||||||
use App\Entity\UserSystem\User;
|
use App\Entity\UserSystem\User;
|
||||||
|
use App\Settings\SystemSettings\LocalizationSettings;
|
||||||
use function function_exists;
|
use function function_exists;
|
||||||
use function in_array;
|
use function in_array;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
@ -35,7 +36,7 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
*/
|
*/
|
||||||
class RedirectController extends AbstractController
|
class RedirectController extends AbstractController
|
||||||
{
|
{
|
||||||
public function __construct(protected string $default_locale, protected TranslatorInterface $translator, protected bool $enforce_index_php)
|
public function __construct(private readonly LocalizationSettings $localizationSettings, protected TranslatorInterface $translator, protected bool $enforce_index_php)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +47,7 @@ class RedirectController extends AbstractController
|
||||||
public function addLocalePart(Request $request): RedirectResponse
|
public function addLocalePart(Request $request): RedirectResponse
|
||||||
{
|
{
|
||||||
//By default, we use the global default locale
|
//By default, we use the global default locale
|
||||||
$locale = $this->default_locale;
|
$locale = $this->localizationSettings->locale;
|
||||||
|
|
||||||
//Check if a user has set a preferred language setting:
|
//Check if a user has set a preferred language setting:
|
||||||
$user = $this->getUser();
|
$user = $this->getUser();
|
||||||
|
|
73
src/Controller/SettingsController.php
Normal file
73
src/Controller/SettingsController.php
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use App\Settings\AppSettings;
|
||||||
|
use Jbtronics\SettingsBundle\Form\SettingsFormFactoryInterface;
|
||||||
|
use Jbtronics\SettingsBundle\Manager\SettingsManagerInterface;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
use Symfony\Contracts\Cache\TagAwareCacheInterface;
|
||||||
|
|
||||||
|
class SettingsController extends AbstractController
|
||||||
|
{
|
||||||
|
public function __construct(private readonly SettingsManagerInterface $settingsManager, private readonly SettingsFormFactoryInterface $settingsFormFactory)
|
||||||
|
{}
|
||||||
|
|
||||||
|
#[Route("/settings", name: "system_settings")]
|
||||||
|
public function systemSettings(Request $request, TagAwareCacheInterface $cache): Response
|
||||||
|
{
|
||||||
|
//Create a clone of the settings object
|
||||||
|
$settings = $this->settingsManager->createTemporaryCopy(AppSettings::class);
|
||||||
|
|
||||||
|
//Create a form builder for the settings object
|
||||||
|
$builder = $this->settingsFormFactory->createSettingsFormBuilder($settings);
|
||||||
|
|
||||||
|
//Add a submit button to the form
|
||||||
|
$builder->add('submit', \Symfony\Component\Form\Extension\Core\Type\SubmitType::class, ['label' => 'save']);
|
||||||
|
|
||||||
|
//Create the form
|
||||||
|
$form = $builder->getForm();
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
//If the form was submitted and is valid, save the settings
|
||||||
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
|
$this->settingsManager->mergeTemporaryCopy($settings);
|
||||||
|
$this->settingsManager->save($settings);
|
||||||
|
|
||||||
|
//It might be possible, that the tree settings have changed, so clear the cache
|
||||||
|
$cache->invalidateTags(['tree_treeview', 'sidebar_tree_update']);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Render the form
|
||||||
|
return $this->render('settings/settings.html.twig', [
|
||||||
|
'form' => $form
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,6 +29,7 @@ use App\Services\Doctrine\DBInfoHelper;
|
||||||
use App\Services\Doctrine\NatsortDebugHelper;
|
use App\Services\Doctrine\NatsortDebugHelper;
|
||||||
use App\Services\Misc\GitVersionInfo;
|
use App\Services\Misc\GitVersionInfo;
|
||||||
use App\Services\System\UpdateAvailableManager;
|
use App\Services\System\UpdateAvailableManager;
|
||||||
|
use App\Settings\AppSettings;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
@ -47,7 +48,8 @@ class ToolsController extends AbstractController
|
||||||
|
|
||||||
#[Route(path: '/server_infos', name: 'tools_server_infos')]
|
#[Route(path: '/server_infos', name: 'tools_server_infos')]
|
||||||
public function systemInfos(GitVersionInfo $versionInfo, DBInfoHelper $DBInfoHelper, NatsortDebugHelper $natsortDebugHelper,
|
public function systemInfos(GitVersionInfo $versionInfo, DBInfoHelper $DBInfoHelper, NatsortDebugHelper $natsortDebugHelper,
|
||||||
AttachmentSubmitHandler $attachmentSubmitHandler, UpdateAvailableManager $updateAvailableManager): Response
|
AttachmentSubmitHandler $attachmentSubmitHandler, UpdateAvailableManager $updateAvailableManager,
|
||||||
|
AppSettings $settings): Response
|
||||||
{
|
{
|
||||||
$this->denyAccessUnlessGranted('@system.server_infos');
|
$this->denyAccessUnlessGranted('@system.server_infos');
|
||||||
|
|
||||||
|
@ -55,23 +57,23 @@ class ToolsController extends AbstractController
|
||||||
//Part-DB section
|
//Part-DB section
|
||||||
'git_branch' => $versionInfo->getGitBranchName(),
|
'git_branch' => $versionInfo->getGitBranchName(),
|
||||||
'git_commit' => $versionInfo->getGitCommitHash(),
|
'git_commit' => $versionInfo->getGitCommitHash(),
|
||||||
'default_locale' => $this->getParameter('partdb.locale'),
|
'default_locale' => $settings->system->localization->locale,
|
||||||
'default_timezone' => $this->getParameter('partdb.timezone'),
|
'default_timezone' => $settings->system->localization->timezone,
|
||||||
'default_currency' => $this->getParameter('partdb.default_currency'),
|
'default_currency' => $settings->system->localization->baseCurrency,
|
||||||
'default_theme' => $this->getParameter('partdb.global_theme'),
|
'default_theme' => $settings->system->customization->theme,
|
||||||
'enabled_locales' => $this->getParameter('partdb.locale_menu'),
|
'enabled_locales' => $this->getParameter('partdb.locale_menu'),
|
||||||
'demo_mode' => $this->getParameter('partdb.demo_mode'),
|
'demo_mode' => $this->getParameter('partdb.demo_mode'),
|
||||||
|
'use_gravatar' => $settings->system->privacy->useGravatar,
|
||||||
'gdpr_compliance' => $this->getParameter('partdb.gdpr_compliance'),
|
'gdpr_compliance' => $this->getParameter('partdb.gdpr_compliance'),
|
||||||
'use_gravatar' => $this->getParameter('partdb.users.use_gravatar'),
|
|
||||||
'email_password_reset' => $this->getParameter('partdb.users.email_pw_reset'),
|
'email_password_reset' => $this->getParameter('partdb.users.email_pw_reset'),
|
||||||
'environment' => $this->getParameter('kernel.environment'),
|
'environment' => $this->getParameter('kernel.environment'),
|
||||||
'is_debug' => $this->getParameter('kernel.debug'),
|
'is_debug' => $this->getParameter('kernel.debug'),
|
||||||
'email_sender' => $this->getParameter('partdb.mail.sender_email'),
|
'email_sender' => $this->getParameter('partdb.mail.sender_email'),
|
||||||
'email_sender_name' => $this->getParameter('partdb.mail.sender_name'),
|
'email_sender_name' => $this->getParameter('partdb.mail.sender_name'),
|
||||||
'allow_attachments_downloads' => $this->getParameter('partdb.attachments.allow_downloads'),
|
'allow_attachments_downloads' => $settings->system->attachments->allowDownloads,
|
||||||
'detailed_error_pages' => $this->getParameter('partdb.error_pages.show_help'),
|
'detailed_error_pages' => $this->getParameter('partdb.error_pages.show_help'),
|
||||||
'error_page_admin_email' => $this->getParameter('partdb.error_pages.admin_email'),
|
'error_page_admin_email' => $this->getParameter('partdb.error_pages.admin_email'),
|
||||||
'configured_max_file_size' => $this->getParameter('partdb.attachments.max_file_size'),
|
'configured_max_file_size' => $settings->system->attachments->maxFileSize,
|
||||||
'effective_max_file_size' => $attachmentSubmitHandler->getMaximumAllowedUploadSize(),
|
'effective_max_file_size' => $attachmentSubmitHandler->getMaximumAllowedUploadSize(),
|
||||||
'saml_enabled' => $this->getParameter('partdb.saml.enabled'),
|
'saml_enabled' => $this->getParameter('partdb.saml.enabled'),
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,8 @@ class ColumnSortHelper
|
||||||
* Apply the visibility configuration to the given DataTable and configure the columns.
|
* Apply the visibility configuration to the given DataTable and configure the columns.
|
||||||
* @param DataTable $dataTable
|
* @param DataTable $dataTable
|
||||||
* @param string|array $visible_columns Either a list or a comma separated string of column names, which should
|
* @param string|array $visible_columns Either a list or a comma separated string of column names, which should
|
||||||
* be visible by default. If a column is not listed here, it will be hidden by default.
|
* be visible by default. If a column is not listed here, it will be hidden by default. If an array of enum values are passed,
|
||||||
|
* their value will be used as the column name.
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function applyVisibilityAndConfigureColumns(DataTable $dataTable, string|array $visible_columns,
|
public function applyVisibilityAndConfigureColumns(DataTable $dataTable, string|array $visible_columns,
|
||||||
|
@ -83,6 +84,14 @@ class ColumnSortHelper
|
||||||
$visible_columns = array_map(trim(...), explode(",", $visible_columns));
|
$visible_columns = array_map(trim(...), explode(",", $visible_columns));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//If $visible_columns is a list of enum values, convert them to the column names
|
||||||
|
foreach ($visible_columns as &$value) {
|
||||||
|
if ($value instanceof \BackedEnum) {
|
||||||
|
$value = $value->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset ($value);
|
||||||
|
|
||||||
$processed_columns = [];
|
$processed_columns = [];
|
||||||
|
|
||||||
//First add all columns which visibility is not configurable
|
//First add all columns which visibility is not configurable
|
||||||
|
|
|
@ -45,6 +45,7 @@ use App\Entity\Parts\PartLot;
|
||||||
use App\Entity\ProjectSystem\Project;
|
use App\Entity\ProjectSystem\Project;
|
||||||
use App\Services\EntityURLGenerator;
|
use App\Services\EntityURLGenerator;
|
||||||
use App\Services\Formatters\AmountFormatter;
|
use App\Services\Formatters\AmountFormatter;
|
||||||
|
use App\Settings\BehaviorSettings\TableSettings;
|
||||||
use Doctrine\ORM\AbstractQuery;
|
use Doctrine\ORM\AbstractQuery;
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Omines\DataTablesBundle\Adapter\Doctrine\ORM\SearchCriteriaProvider;
|
use Omines\DataTablesBundle\Adapter\Doctrine\ORM\SearchCriteriaProvider;
|
||||||
|
@ -63,8 +64,8 @@ final class PartsDataTable implements DataTableTypeInterface
|
||||||
private readonly AmountFormatter $amountFormatter,
|
private readonly AmountFormatter $amountFormatter,
|
||||||
private readonly PartDataTableHelper $partDataTableHelper,
|
private readonly PartDataTableHelper $partDataTableHelper,
|
||||||
private readonly Security $security,
|
private readonly Security $security,
|
||||||
private readonly string $visible_columns,
|
|
||||||
private readonly ColumnSortHelper $csh,
|
private readonly ColumnSortHelper $csh,
|
||||||
|
private readonly TableSettings $tableSettings,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,7 +245,7 @@ final class PartsDataTable implements DataTableTypeInterface
|
||||||
]);
|
]);
|
||||||
|
|
||||||
//Apply the user configured order and visibility and add the columns to the table
|
//Apply the user configured order and visibility and add the columns to the table
|
||||||
$this->csh->applyVisibilityAndConfigureColumns($dataTable, $this->visible_columns,
|
$this->csh->applyVisibilityAndConfigureColumns($dataTable, $this->tableSettings->partsDefaultColumns,
|
||||||
"TABLE_PARTS_DEFAULT_COLUMNS");
|
"TABLE_PARTS_DEFAULT_COLUMNS");
|
||||||
|
|
||||||
$dataTable->addOrderBy('name')
|
$dataTable->addOrderBy('name')
|
||||||
|
|
|
@ -197,7 +197,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
|
||||||
/**
|
/**
|
||||||
* @var string|null The language/locale the user prefers
|
* @var string|null The language/locale the user prefers
|
||||||
*/
|
*/
|
||||||
#[Assert\Language]
|
#[Assert\Locale]
|
||||||
#[Groups(['full', 'import', 'user:read'])]
|
#[Groups(['full', 'import', 'user:read'])]
|
||||||
#[ORM\Column(name: 'config_language', type: Types::STRING, nullable: true)]
|
#[ORM\Column(name: 'config_language', type: Types::STRING, nullable: true)]
|
||||||
protected ?string $language = '';
|
protected ?string $language = '';
|
||||||
|
|
|
@ -39,6 +39,8 @@ use App\Services\LogSystem\EventCommentHelper;
|
||||||
use App\Services\LogSystem\EventLogger;
|
use App\Services\LogSystem\EventLogger;
|
||||||
use App\Services\LogSystem\EventUndoHelper;
|
use App\Services\LogSystem\EventUndoHelper;
|
||||||
use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener;
|
use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener;
|
||||||
|
use App\Settings\SystemSettings\HistorySettings;
|
||||||
|
use Doctrine\Common\EventSubscriber;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\Event\OnFlushEventArgs;
|
use Doctrine\ORM\Event\OnFlushEventArgs;
|
||||||
use Doctrine\ORM\Event\PostFlushEventArgs;
|
use Doctrine\ORM\Event\PostFlushEventArgs;
|
||||||
|
@ -74,14 +76,15 @@ class EventLoggerListener
|
||||||
];
|
];
|
||||||
|
|
||||||
protected const MAX_STRING_LENGTH = 2000;
|
protected const MAX_STRING_LENGTH = 2000;
|
||||||
protected bool $save_new_data;
|
|
||||||
|
|
||||||
public function __construct(protected EventLogger $logger, protected SerializerInterface $serializer, protected EventCommentHelper $eventCommentHelper,
|
public function __construct(
|
||||||
protected bool $save_changed_fields, protected bool $save_changed_data, protected bool $save_removed_data, bool $save_new_data,
|
protected EventLogger $logger,
|
||||||
protected PropertyAccessorInterface $propertyAccessor, protected EventUndoHelper $eventUndoHelper)
|
protected SerializerInterface $serializer,
|
||||||
|
protected EventCommentHelper $eventCommentHelper,
|
||||||
|
private readonly HistorySettings $settings,
|
||||||
|
protected PropertyAccessorInterface $propertyAccessor,
|
||||||
|
protected EventUndoHelper $eventUndoHelper)
|
||||||
{
|
{
|
||||||
//This option only makes sense if save_changed_data is true
|
|
||||||
$this->save_new_data = $save_new_data && $save_changed_data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onFlush(OnFlushEventArgs $eventArgs): void
|
public function onFlush(OnFlushEventArgs $eventArgs): void
|
||||||
|
@ -200,14 +203,14 @@ class EventLoggerListener
|
||||||
if ($this->eventUndoHelper->isUndo()) {
|
if ($this->eventUndoHelper->isUndo()) {
|
||||||
$log->setUndoneEvent($this->eventUndoHelper->getUndoneEvent(), $this->eventUndoHelper->getMode());
|
$log->setUndoneEvent($this->eventUndoHelper->getUndoneEvent(), $this->eventUndoHelper->getMode());
|
||||||
}
|
}
|
||||||
if ($this->save_removed_data) {
|
if ($this->settings->saveRemovedData) {
|
||||||
//The 4th param is important here, as we delete the element...
|
//The 4th param is important here, as we delete the element...
|
||||||
$this->saveChangeSet($entity, $log, $em, true);
|
$this->saveChangeSet($entity, $log, $em, true);
|
||||||
}
|
}
|
||||||
$this->logger->logFromOnFlush($log);
|
$this->logger->logFromOnFlush($log);
|
||||||
|
|
||||||
//Check if we have to log CollectionElementDeleted entries
|
//Check if we have to log CollectionElementDeleted entries
|
||||||
if ($this->save_changed_data) {
|
if ($this->settings->saveOldData) {
|
||||||
$metadata = $em->getClassMetadata($entity::class);
|
$metadata = $em->getClassMetadata($entity::class);
|
||||||
$mappings = $metadata->getAssociationMappings();
|
$mappings = $metadata->getAssociationMappings();
|
||||||
//Check if class is whitelisted for CollectionElementDeleted entry
|
//Check if class is whitelisted for CollectionElementDeleted entry
|
||||||
|
@ -243,9 +246,9 @@ class EventLoggerListener
|
||||||
}
|
}
|
||||||
|
|
||||||
$log = new ElementEditedLogEntry($entity);
|
$log = new ElementEditedLogEntry($entity);
|
||||||
if ($this->save_changed_data) {
|
if ($this->settings->saveOldData) {
|
||||||
$this->saveChangeSet($entity, $log, $em);
|
$this->saveChangeSet($entity, $log, $em);
|
||||||
} elseif ($this->save_changed_fields) {
|
} elseif ($this->settings->saveChangedFields) {
|
||||||
$changed_fields = array_keys($uow->getEntityChangeSet($entity));
|
$changed_fields = array_keys($uow->getEntityChangeSet($entity));
|
||||||
//Remove lastModified field, as this is always changed (gives us no additional info)
|
//Remove lastModified field, as this is always changed (gives us no additional info)
|
||||||
$changed_fields = array_diff($changed_fields, ['lastModified']);
|
$changed_fields = array_diff($changed_fields, ['lastModified']);
|
||||||
|
@ -313,7 +316,7 @@ class EventLoggerListener
|
||||||
$changeSet = $uow->getEntityChangeSet($entity);
|
$changeSet = $uow->getEntityChangeSet($entity);
|
||||||
$old_data = array_combine(array_keys($changeSet), array_column($changeSet, 0));
|
$old_data = array_combine(array_keys($changeSet), array_column($changeSet, 0));
|
||||||
//If save_new_data is enabled, we extract it from the change set
|
//If save_new_data is enabled, we extract it from the change set
|
||||||
if ($this->save_new_data) {
|
if ($this->settings->saveNewData && $this->settings->saveOldData) { //Only useful if we save old data too
|
||||||
$new_data = array_combine(array_keys($changeSet), array_column($changeSet, 1));
|
$new_data = array_combine(array_keys($changeSet), array_column($changeSet, 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||||
namespace App\EventSubscriber\UserSystem;
|
namespace App\EventSubscriber\UserSystem;
|
||||||
|
|
||||||
use App\Entity\UserSystem\User;
|
use App\Entity\UserSystem\User;
|
||||||
|
use App\Settings\SystemSettings\LocalizationSettings;
|
||||||
use Symfony\Bundle\SecurityBundle\Security;
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
use Symfony\Component\HttpKernel\Event\ControllerEvent;
|
use Symfony\Component\HttpKernel\Event\ControllerEvent;
|
||||||
|
@ -33,7 +34,7 @@ use Symfony\Component\HttpKernel\KernelEvents;
|
||||||
*/
|
*/
|
||||||
final class SetUserTimezoneSubscriber implements EventSubscriberInterface
|
final class SetUserTimezoneSubscriber implements EventSubscriberInterface
|
||||||
{
|
{
|
||||||
public function __construct(private readonly string $default_timezone, private readonly Security $security)
|
public function __construct(private readonly LocalizationSettings $localizationSettings, private readonly Security $security)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,8 +49,8 @@ final class SetUserTimezoneSubscriber implements EventSubscriberInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
//Fill with default value if needed
|
//Fill with default value if needed
|
||||||
if (null === $timezone && $this->default_timezone !== '') {
|
if (null === $timezone && $this->localizationSettings !== '') {
|
||||||
$timezone = $this->default_timezone;
|
$timezone = $this->localizationSettings->timezone;
|
||||||
}
|
}
|
||||||
|
|
||||||
//If timezone was configured anywhere set it, otherwise just use the one from php.ini
|
//If timezone was configured anywhere set it, otherwise just use the one from php.ini
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace App\Form\AdminPages;
|
||||||
use App\Entity\PriceInformations\Currency;
|
use App\Entity\PriceInformations\Currency;
|
||||||
use App\Entity\ProjectSystem\Project;
|
use App\Entity\ProjectSystem\Project;
|
||||||
use App\Entity\UserSystem\Group;
|
use App\Entity\UserSystem\Group;
|
||||||
|
use App\Services\LogSystem\EventCommentType;
|
||||||
use Symfony\Bundle\SecurityBundle\Security;
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
use App\Entity\Base\AbstractNamedDBElement;
|
use App\Entity\Base\AbstractNamedDBElement;
|
||||||
use App\Entity\Base\AbstractStructuralDBElement;
|
use App\Entity\Base\AbstractStructuralDBElement;
|
||||||
|
@ -152,7 +153,7 @@ class BaseEntityAdminForm extends AbstractType
|
||||||
$builder->add('log_comment', TextType::class, [
|
$builder->add('log_comment', TextType::class, [
|
||||||
'label' => 'edit.log_comment',
|
'label' => 'edit.log_comment',
|
||||||
'mapped' => false,
|
'mapped' => false,
|
||||||
'required' => $this->eventCommentNeededHelper->isCommentNeeded($is_new ? 'datastructure_create': 'datastructure_edit'),
|
'required' => $this->eventCommentNeededHelper->isCommentNeeded($is_new ? EventCommentType::DATASTRUCTURE_CREATE: EventCommentType::DATASTRUCTURE_EDIT),
|
||||||
'empty_data' => null,
|
'empty_data' => null,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Form\AdminPages;
|
namespace App\Form\AdminPages;
|
||||||
|
|
||||||
|
use App\Settings\SystemSettings\LocalizationSettings;
|
||||||
use Symfony\Bundle\SecurityBundle\Security;
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
use App\Entity\Base\AbstractNamedDBElement;
|
use App\Entity\Base\AbstractNamedDBElement;
|
||||||
use App\Form\Type\BigDecimalMoneyType;
|
use App\Form\Type\BigDecimalMoneyType;
|
||||||
|
@ -32,7 +33,7 @@ use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
|
||||||
class CurrencyAdminForm extends BaseEntityAdminForm
|
class CurrencyAdminForm extends BaseEntityAdminForm
|
||||||
{
|
{
|
||||||
public function __construct(Security $security, EventCommentNeededHelper $eventCommentNeededHelper, private readonly string $base_currency)
|
public function __construct(Security $security, EventCommentNeededHelper $eventCommentNeededHelper, private readonly LocalizationSettings $localizationSettings)
|
||||||
{
|
{
|
||||||
parent::__construct($security, $eventCommentNeededHelper);
|
parent::__construct($security, $eventCommentNeededHelper);
|
||||||
}
|
}
|
||||||
|
@ -51,7 +52,7 @@ class CurrencyAdminForm extends BaseEntityAdminForm
|
||||||
$builder->add('exchange_rate', BigDecimalMoneyType::class, [
|
$builder->add('exchange_rate', BigDecimalMoneyType::class, [
|
||||||
'required' => false,
|
'required' => false,
|
||||||
'label' => 'currency.edit.exchange_rate',
|
'label' => 'currency.edit.exchange_rate',
|
||||||
'currency' => $this->base_currency,
|
'currency' => $this->localizationSettings->baseCurrency,
|
||||||
'scale' => 6,
|
'scale' => 6,
|
||||||
'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -22,6 +22,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Form\AdminPages;
|
namespace App\Form\AdminPages;
|
||||||
|
|
||||||
|
use App\Settings\SystemSettings\LocalizationSettings;
|
||||||
use Symfony\Bundle\SecurityBundle\Security;
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
use App\Entity\Base\AbstractNamedDBElement;
|
use App\Entity\Base\AbstractNamedDBElement;
|
||||||
use App\Entity\PriceInformations\Currency;
|
use App\Entity\PriceInformations\Currency;
|
||||||
|
@ -32,7 +33,7 @@ use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
|
||||||
class SupplierForm extends CompanyForm
|
class SupplierForm extends CompanyForm
|
||||||
{
|
{
|
||||||
public function __construct(Security $security, EventCommentNeededHelper $eventCommentNeededHelper, protected string $base_currency)
|
public function __construct(Security $security, EventCommentNeededHelper $eventCommentNeededHelper, private readonly LocalizationSettings $localizationSettings)
|
||||||
{
|
{
|
||||||
parent::__construct($security, $eventCommentNeededHelper);
|
parent::__construct($security, $eventCommentNeededHelper);
|
||||||
}
|
}
|
||||||
|
@ -53,7 +54,7 @@ class SupplierForm extends CompanyForm
|
||||||
|
|
||||||
$builder->add('shipping_costs', BigDecimalMoneyType::class, [
|
$builder->add('shipping_costs', BigDecimalMoneyType::class, [
|
||||||
'required' => false,
|
'required' => false,
|
||||||
'currency' => $this->base_currency,
|
'currency' => $this->localizationSettings->baseCurrency,
|
||||||
'scale' => 3,
|
'scale' => 3,
|
||||||
'label' => 'supplier.shipping_costs.label',
|
'label' => 'supplier.shipping_costs.label',
|
||||||
'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity),
|
||||||
|
|
|
@ -22,6 +22,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Form;
|
namespace App\Form;
|
||||||
|
|
||||||
|
use App\Settings\SystemSettings\AttachmentsSettings;
|
||||||
use Symfony\Bundle\SecurityBundle\Security;
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
use App\Entity\Attachments\Attachment;
|
use App\Entity\Attachments\Attachment;
|
||||||
use App\Entity\Attachments\AttachmentType;
|
use App\Entity\Attachments\AttachmentType;
|
||||||
|
@ -54,9 +55,7 @@ class AttachmentFormType extends AbstractType
|
||||||
protected Security $security,
|
protected Security $security,
|
||||||
protected AttachmentSubmitHandler $submitHandler,
|
protected AttachmentSubmitHandler $submitHandler,
|
||||||
protected TranslatorInterface $translator,
|
protected TranslatorInterface $translator,
|
||||||
protected bool $allow_attachments_download,
|
protected AttachmentsSettings $settings,
|
||||||
protected bool $download_by_default,
|
|
||||||
protected string $max_file_size
|
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +107,7 @@ class AttachmentFormType extends AbstractType
|
||||||
'required' => false,
|
'required' => false,
|
||||||
'label' => 'attachment.edit.download_url',
|
'label' => 'attachment.edit.download_url',
|
||||||
'mapped' => false,
|
'mapped' => false,
|
||||||
'disabled' => !$this->allow_attachments_download,
|
'disabled' => !$this->settings->allowDownloads,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$builder->add('file', FileType::class, [
|
$builder->add('file', FileType::class, [
|
||||||
|
@ -177,7 +176,7 @@ class AttachmentFormType extends AbstractType
|
||||||
|
|
||||||
//If the attachment should be downloaded by default (and is download allowed at all), register a listener,
|
//If the attachment should be downloaded by default (and is download allowed at all), register a listener,
|
||||||
// which sets the downloadURL checkbox to true for new attachments
|
// which sets the downloadURL checkbox to true for new attachments
|
||||||
if ($this->download_by_default && $this->allow_attachments_download) {
|
if ($this->settings->downloadByDefault && $this->settings->allowDownloads) {
|
||||||
$builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event): void {
|
$builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event): void {
|
||||||
$form = $event->getForm();
|
$form = $event->getForm();
|
||||||
$attachment = $form->getData();
|
$attachment = $form->getData();
|
||||||
|
@ -204,7 +203,7 @@ class AttachmentFormType extends AbstractType
|
||||||
{
|
{
|
||||||
$resolver->setDefaults([
|
$resolver->setDefaults([
|
||||||
'data_class' => Attachment::class,
|
'data_class' => Attachment::class,
|
||||||
'max_file_size' => $this->max_file_size,
|
'max_file_size' => $this->settings->maxFileSize,
|
||||||
'allow_builtins' => true,
|
'allow_builtins' => true,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
49
src/Form/History/EnforceEventCommentTypesType.php
Normal file
49
src/Form/History/EnforceEventCommentTypesType.php
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Form\History;
|
||||||
|
|
||||||
|
use App\Services\LogSystem\EventCommentType;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\EnumType;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type for the "enforceComments" setting in the HistorySettings.
|
||||||
|
*/
|
||||||
|
class EnforceEventCommentTypesType extends AbstractType
|
||||||
|
{
|
||||||
|
public function getParent(): string
|
||||||
|
{
|
||||||
|
return EnumType::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver->setDefaults([
|
||||||
|
'multiple' => true,
|
||||||
|
'class' => EventCommentType::class,
|
||||||
|
'empty_data' => [],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,6 +40,7 @@ use App\Form\Type\SIUnitType;
|
||||||
use App\Form\Type\StructuralEntityType;
|
use App\Form\Type\StructuralEntityType;
|
||||||
use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
|
use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
|
||||||
use App\Services\LogSystem\EventCommentNeededHelper;
|
use App\Services\LogSystem\EventCommentNeededHelper;
|
||||||
|
use App\Services\LogSystem\EventCommentType;
|
||||||
use Symfony\Bundle\SecurityBundle\Security;
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||||
|
@ -265,7 +266,7 @@ class PartBaseType extends AbstractType
|
||||||
$builder->add('log_comment', TextType::class, [
|
$builder->add('log_comment', TextType::class, [
|
||||||
'label' => 'edit.log_comment',
|
'label' => 'edit.log_comment',
|
||||||
'mapped' => false,
|
'mapped' => false,
|
||||||
'required' => $this->event_comment_needed_helper->isCommentNeeded($new_part ? 'part_create' : 'part_edit'),
|
'required' => $this->event_comment_needed_helper->isCommentNeeded($new_part ? EventCommentType::PART_CREATE : EventCommentType::PART_EDIT),
|
||||||
'empty_data' => null,
|
'empty_data' => null,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
60
src/Form/SelectTypeOrderExtension.php
Normal file
60
src/Form/SelectTypeOrderExtension.php
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Form;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractTypeExtension;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\EnumType;
|
||||||
|
use Symfony\Component\Form\FormInterface;
|
||||||
|
use Symfony\Component\Form\FormView;
|
||||||
|
use Symfony\Component\OptionsResolver\Options;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
class SelectTypeOrderExtension extends AbstractTypeExtension
|
||||||
|
{
|
||||||
|
public static function getExtendedTypes(): iterable
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
ChoiceType::class,
|
||||||
|
EnumType::class
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver->setDefault('ordered', false);
|
||||||
|
$resolver->setDefault('by_reference', function (Options $options) {
|
||||||
|
//Disable by_reference if the field is ordered (otherwise the order will be lost)
|
||||||
|
return !$options['ordered'];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildView(FormView $view, FormInterface $form, array $options)
|
||||||
|
{
|
||||||
|
//Pass the data in ordered form to the frontend controller, so it can make the items appear in the correct order.
|
||||||
|
if ($options['ordered']) {
|
||||||
|
$view->vars['attr']['data-ordered-value'] = json_encode($form->getViewData(), JSON_THROW_ON_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ namespace App\Form\Type;
|
||||||
use App\Entity\PriceInformations\Currency;
|
use App\Entity\PriceInformations\Currency;
|
||||||
use App\Form\Type\Helper\StructuralEntityChoiceHelper;
|
use App\Form\Type\Helper\StructuralEntityChoiceHelper;
|
||||||
use App\Services\Trees\NodesListBuilder;
|
use App\Services\Trees\NodesListBuilder;
|
||||||
|
use App\Settings\SystemSettings\LocalizationSettings;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Component\Intl\Currencies;
|
use Symfony\Component\Intl\Currencies;
|
||||||
use Symfony\Component\OptionsResolver\Options;
|
use Symfony\Component\OptionsResolver\Options;
|
||||||
|
@ -36,7 +37,7 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
*/
|
*/
|
||||||
class CurrencyEntityType extends StructuralEntityType
|
class CurrencyEntityType extends StructuralEntityType
|
||||||
{
|
{
|
||||||
public function __construct(EntityManagerInterface $em, NodesListBuilder $builder, TranslatorInterface $translator, StructuralEntityChoiceHelper $choiceHelper, protected ?string $base_currency)
|
public function __construct(EntityManagerInterface $em, NodesListBuilder $builder, TranslatorInterface $translator, StructuralEntityChoiceHelper $choiceHelper, private readonly LocalizationSettings $localizationSettings)
|
||||||
{
|
{
|
||||||
parent::__construct($em, $builder, $translator, $choiceHelper);
|
parent::__construct($em, $builder, $translator, $choiceHelper);
|
||||||
}
|
}
|
||||||
|
@ -57,7 +58,7 @@ class CurrencyEntityType extends StructuralEntityType
|
||||||
|
|
||||||
$resolver->setDefault('empty_message', function (Options $options) {
|
$resolver->setDefault('empty_message', function (Options $options) {
|
||||||
//By default, we use the global base currency:
|
//By default, we use the global base currency:
|
||||||
$iso_code = $this->base_currency;
|
$iso_code = $this->localizationSettings->baseCurrency;
|
||||||
|
|
||||||
if ($options['base_currency']) { //Allow to override it
|
if ($options['base_currency']) { //Allow to override it
|
||||||
$iso_code = $options['base_currency'];
|
$iso_code = $options['base_currency'];
|
||||||
|
|
53
src/Form/Type/LocaleSelectType.php
Normal file
53
src/Form/Type/LocaleSelectType.php
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Form\Type;
|
||||||
|
|
||||||
|
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\LocaleType;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A locale select field that uses the preferred languages from the configuration.
|
||||||
|
|
||||||
|
*/
|
||||||
|
class LocaleSelectType extends AbstractType
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(#[Autowire(param: 'partdb.locale_menu')] private readonly array $preferred_languages)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public function getParent(): string
|
||||||
|
{
|
||||||
|
return LocaleType::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver->setDefaults([
|
||||||
|
'preferred_choices' => $this->preferred_languages,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Form;
|
namespace App\Form;
|
||||||
|
|
||||||
|
use App\Form\Type\LocaleSelectType;
|
||||||
use Symfony\Bundle\SecurityBundle\Security;
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
use App\Entity\Base\AbstractNamedDBElement;
|
use App\Entity\Base\AbstractNamedDBElement;
|
||||||
use App\Entity\UserSystem\Group;
|
use App\Entity\UserSystem\Group;
|
||||||
|
@ -35,7 +36,6 @@ use App\Form\Type\ThemeChoiceType;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
|
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\LanguageType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
|
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
|
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\ResetType;
|
use Symfony\Component\Form\Extension\Core\Type\ResetType;
|
||||||
|
@ -140,11 +140,10 @@ class UserAdminForm extends AbstractType
|
||||||
])
|
])
|
||||||
|
|
||||||
//Config section
|
//Config section
|
||||||
->add('language', LanguageType::class, [
|
->add('language', LocaleSelectType::class, [
|
||||||
'required' => false,
|
'required' => false,
|
||||||
'placeholder' => 'user_settings.language.placeholder',
|
'placeholder' => 'user_settings.language.placeholder',
|
||||||
'label' => 'user.language_select',
|
'label' => 'user.language_select',
|
||||||
'preferred_choices' => ['en', 'de'],
|
|
||||||
'disabled' => !$this->security->isGranted('change_user_settings', $entity),
|
'disabled' => !$this->security->isGranted('change_user_settings', $entity),
|
||||||
])
|
])
|
||||||
->add('timezone', TimezoneType::class, [
|
->add('timezone', TimezoneType::class, [
|
||||||
|
|
|
@ -22,6 +22,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Form;
|
namespace App\Form;
|
||||||
|
|
||||||
|
use App\Form\Type\LocaleSelectType;
|
||||||
use Symfony\Bundle\SecurityBundle\Security;
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
use App\Entity\UserSystem\User;
|
use App\Entity\UserSystem\User;
|
||||||
use App\Form\Type\CurrencyEntityType;
|
use App\Form\Type\CurrencyEntityType;
|
||||||
|
@ -33,7 +34,6 @@ use Symfony\Component\Form\Event\PreSetDataEvent;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\EmailType;
|
use Symfony\Component\Form\Extension\Core\Type\EmailType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\FileType;
|
use Symfony\Component\Form\Extension\Core\Type\FileType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\LanguageType;
|
|
||||||
use Symfony\Component\Form\Extension\Core\Type\ResetType;
|
use Symfony\Component\Form\Extension\Core\Type\ResetType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
|
@ -47,7 +47,7 @@ class UserSettingsType extends AbstractType
|
||||||
{
|
{
|
||||||
public function __construct(protected Security $security,
|
public function __construct(protected Security $security,
|
||||||
protected bool $demo_mode,
|
protected bool $demo_mode,
|
||||||
#[Autowire(param: 'partdb.locale_menu')] private readonly array $preferred_languages)
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,12 +107,11 @@ class UserSettingsType extends AbstractType
|
||||||
'mode' => 'markdown-full',
|
'mode' => 'markdown-full',
|
||||||
'disabled' => !$this->security->isGranted('edit_infos', $options['data']) || $this->demo_mode,
|
'disabled' => !$this->security->isGranted('edit_infos', $options['data']) || $this->demo_mode,
|
||||||
])
|
])
|
||||||
->add('language', LanguageType::class, [
|
->add('language', LocaleSelectType::class, [
|
||||||
'disabled' => $this->demo_mode,
|
'disabled' => $this->demo_mode,
|
||||||
'required' => false,
|
'required' => false,
|
||||||
'placeholder' => 'user_settings.language.placeholder',
|
'placeholder' => 'user_settings.language.placeholder',
|
||||||
'label' => 'user.language_select',
|
'label' => 'user.language_select',
|
||||||
'preferred_choices' => $this->preferred_languages,
|
|
||||||
])
|
])
|
||||||
->add('timezone', TimezoneType::class, [
|
->add('timezone', TimezoneType::class, [
|
||||||
'disabled' => $this->demo_mode,
|
'disabled' => $this->demo_mode,
|
||||||
|
|
|
@ -40,6 +40,7 @@ use App\Entity\Attachments\StorageLocationAttachment;
|
||||||
use App\Entity\Attachments\SupplierAttachment;
|
use App\Entity\Attachments\SupplierAttachment;
|
||||||
use App\Entity\Attachments\UserAttachment;
|
use App\Entity\Attachments\UserAttachment;
|
||||||
use App\Exceptions\AttachmentDownloadException;
|
use App\Exceptions\AttachmentDownloadException;
|
||||||
|
use App\Settings\SystemSettings\AttachmentsSettings;
|
||||||
use Hshn\Base64EncodedFile\HttpFoundation\File\Base64EncodedFile;
|
use Hshn\Base64EncodedFile\HttpFoundation\File\Base64EncodedFile;
|
||||||
use Hshn\Base64EncodedFile\HttpFoundation\File\UploadedBase64EncodedFile;
|
use Hshn\Base64EncodedFile\HttpFoundation\File\UploadedBase64EncodedFile;
|
||||||
use const DIRECTORY_SEPARATOR;
|
use const DIRECTORY_SEPARATOR;
|
||||||
|
@ -64,12 +65,13 @@ class AttachmentSubmitHandler
|
||||||
'asp', 'cgi', 'py', 'pl', 'exe', 'aspx', 'js', 'mjs', 'jsp', 'css', 'jar', 'html', 'htm', 'shtm', 'shtml', 'htaccess',
|
'asp', 'cgi', 'py', 'pl', 'exe', 'aspx', 'js', 'mjs', 'jsp', 'css', 'jar', 'html', 'htm', 'shtm', 'shtml', 'htaccess',
|
||||||
'htpasswd', ''];
|
'htpasswd', ''];
|
||||||
|
|
||||||
public function __construct(protected AttachmentPathResolver $pathResolver, protected bool $allow_attachments_downloads,
|
public function __construct(
|
||||||
protected HttpClientInterface $httpClient, protected MimeTypesInterface $mimeTypes,
|
protected AttachmentPathResolver $pathResolver,
|
||||||
protected FileTypeFilterTools $filterTools, /**
|
protected HttpClientInterface $httpClient,
|
||||||
* @var string The user configured maximum upload size. This is a string like "10M" or "1G" and will be converted to
|
protected MimeTypesInterface $mimeTypes,
|
||||||
*/
|
protected FileTypeFilterTools $filterTools,
|
||||||
protected string $max_upload_size)
|
protected AttachmentsSettings $settings,
|
||||||
|
)
|
||||||
{
|
{
|
||||||
//The mapping used to determine which folder will be used for an attachment type
|
//The mapping used to determine which folder will be used for an attachment type
|
||||||
$this->folder_mapping = [
|
$this->folder_mapping = [
|
||||||
|
@ -334,7 +336,7 @@ class AttachmentSubmitHandler
|
||||||
protected function downloadURL(Attachment $attachment, bool $secureAttachment): Attachment
|
protected function downloadURL(Attachment $attachment, bool $secureAttachment): Attachment
|
||||||
{
|
{
|
||||||
//Check if we are allowed to download files
|
//Check if we are allowed to download files
|
||||||
if (!$this->allow_attachments_downloads) {
|
if (!$this->settings->allowDownloads) {
|
||||||
throw new RuntimeException('Download of attachments is not allowed!');
|
throw new RuntimeException('Download of attachments is not allowed!');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,7 +474,7 @@ class AttachmentSubmitHandler
|
||||||
$this->max_upload_size_bytes = min(
|
$this->max_upload_size_bytes = min(
|
||||||
$this->parseFileSizeString(ini_get('post_max_size')),
|
$this->parseFileSizeString(ini_get('post_max_size')),
|
||||||
$this->parseFileSizeString(ini_get('upload_max_filesize')),
|
$this->parseFileSizeString(ini_get('upload_max_filesize')),
|
||||||
$this->parseFileSizeString($this->max_upload_size),
|
$this->parseFileSizeString($this->settings->maxFileSize)
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->max_upload_size_bytes;
|
return $this->max_upload_size_bytes;
|
||||||
|
|
|
@ -28,6 +28,7 @@ use App\Entity\Parts\Footprint;
|
||||||
use App\Entity\Parts\Part;
|
use App\Entity\Parts\Part;
|
||||||
use App\Services\Cache\ElementCacheTagGenerator;
|
use App\Services\Cache\ElementCacheTagGenerator;
|
||||||
use App\Services\Trees\NodesListBuilder;
|
use App\Services\Trees\NodesListBuilder;
|
||||||
|
use App\Settings\MiscSettings\KiCadEDASettings;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||||
|
@ -38,6 +39,9 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
class KiCadHelper
|
class KiCadHelper
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/** @var int The maximum level of the shown categories. 0 Means only the top level categories are shown. -1 means only a single one containing */
|
||||||
|
private readonly int $category_depth;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly NodesListBuilder $nodesListBuilder,
|
private readonly NodesListBuilder $nodesListBuilder,
|
||||||
private readonly TagAwareCacheInterface $kicadCache,
|
private readonly TagAwareCacheInterface $kicadCache,
|
||||||
|
@ -45,9 +49,9 @@ class KiCadHelper
|
||||||
private readonly ElementCacheTagGenerator $tagGenerator,
|
private readonly ElementCacheTagGenerator $tagGenerator,
|
||||||
private readonly UrlGeneratorInterface $urlGenerator,
|
private readonly UrlGeneratorInterface $urlGenerator,
|
||||||
private readonly TranslatorInterface $translator,
|
private readonly TranslatorInterface $translator,
|
||||||
/** The maximum level of the shown categories. 0 Means only the top level categories are shown. -1 means only a single one containing */
|
KiCadEDASettings $kiCadEDASettings,
|
||||||
private readonly int $category_depth,
|
|
||||||
) {
|
) {
|
||||||
|
$this->category_depth = $kiCadEDASettings->categoryDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||||
namespace App\Services\Formatters;
|
namespace App\Services\Formatters;
|
||||||
|
|
||||||
use App\Entity\PriceInformations\Currency;
|
use App\Entity\PriceInformations\Currency;
|
||||||
|
use App\Settings\SystemSettings\LocalizationSettings;
|
||||||
use Locale;
|
use Locale;
|
||||||
use NumberFormatter;
|
use NumberFormatter;
|
||||||
|
|
||||||
|
@ -30,7 +31,7 @@ class MoneyFormatter
|
||||||
{
|
{
|
||||||
protected string $locale;
|
protected string $locale;
|
||||||
|
|
||||||
public function __construct(protected string $base_currency)
|
public function __construct(private readonly LocalizationSettings $localizationSettings)
|
||||||
{
|
{
|
||||||
$this->locale = Locale::getDefault();
|
$this->locale = Locale::getDefault();
|
||||||
}
|
}
|
||||||
|
@ -45,7 +46,7 @@ class MoneyFormatter
|
||||||
*/
|
*/
|
||||||
public function format(string|float $value, ?Currency $currency = null, int $decimals = 5, bool $show_all_digits = false): string
|
public function format(string|float $value, ?Currency $currency = null, int $decimals = 5, bool $show_all_digits = false): string
|
||||||
{
|
{
|
||||||
$iso_code = $this->base_currency;
|
$iso_code = $this->localizationSettings->baseCurrency;
|
||||||
if ($currency instanceof Currency && ($currency->getIsoCode() !== '')) {
|
if ($currency instanceof Currency && ($currency->getIsoCode() !== '')) {
|
||||||
$iso_code = $currency->getIsoCode();
|
$iso_code = $currency->getIsoCode();
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ use App\Entity\Parts\Supplier;
|
||||||
use App\Entity\PriceInformations\Currency;
|
use App\Entity\PriceInformations\Currency;
|
||||||
use App\Entity\PriceInformations\Orderdetail;
|
use App\Entity\PriceInformations\Orderdetail;
|
||||||
use App\Entity\PriceInformations\Pricedetail;
|
use App\Entity\PriceInformations\Pricedetail;
|
||||||
|
use App\Settings\SystemSettings\LocalizationSettings;
|
||||||
use Brick\Math\BigDecimal;
|
use Brick\Math\BigDecimal;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Component\Intl\Currencies;
|
use Symfony\Component\Intl\Currencies;
|
||||||
|
@ -47,7 +48,7 @@ class PKPartImporter
|
||||||
{
|
{
|
||||||
use PKImportHelperTrait;
|
use PKImportHelperTrait;
|
||||||
|
|
||||||
public function __construct(EntityManagerInterface $em, PropertyAccessorInterface $propertyAccessor, private readonly string $base_currency)
|
public function __construct(EntityManagerInterface $em, PropertyAccessorInterface $propertyAccessor, private readonly LocalizationSettings $localizationSettings)
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->propertyAccessor = $propertyAccessor;
|
$this->propertyAccessor = $propertyAccessor;
|
||||||
|
@ -210,7 +211,7 @@ class PKPartImporter
|
||||||
$currency_iso_code = strtoupper($currency_iso_code);
|
$currency_iso_code = strtoupper($currency_iso_code);
|
||||||
|
|
||||||
//We do not have a currency for the base currency to be consistent with prices without currencies
|
//We do not have a currency for the base currency to be consistent with prices without currencies
|
||||||
if ($currency_iso_code === $this->base_currency) {
|
if ($currency_iso_code === $this->localizationSettings->baseCurrency) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ use App\Services\InfoProviderSystem\DTOs\ParameterDTO;
|
||||||
use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
|
use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
|
||||||
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
|
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
|
||||||
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
|
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
|
||||||
|
use App\Settings\SystemSettings\LocalizationSettings;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,8 +55,11 @@ final class DTOtoEntityConverter
|
||||||
private const TYPE_DATASHEETS_NAME = 'Datasheet';
|
private const TYPE_DATASHEETS_NAME = 'Datasheet';
|
||||||
private const TYPE_IMAGE_NAME = 'Image';
|
private const TYPE_IMAGE_NAME = 'Image';
|
||||||
|
|
||||||
public function __construct(private readonly EntityManagerInterface $em, private readonly string $base_currency)
|
private readonly string $base_currency;
|
||||||
|
|
||||||
|
public function __construct(private readonly EntityManagerInterface $em, LocalizationSettings $localizationSettings)
|
||||||
{
|
{
|
||||||
|
$this->base_currency = $localizationSettings->baseCurrency;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -29,6 +29,7 @@ use App\Services\InfoProviderSystem\DTOs\ParameterDTO;
|
||||||
use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
|
use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
|
||||||
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
|
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
|
||||||
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
|
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
|
||||||
|
use App\Settings\InfoProviderSystem\Element14Settings;
|
||||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||||
|
|
||||||
class Element14Provider implements InfoProviderInterface
|
class Element14Provider implements InfoProviderInterface
|
||||||
|
@ -43,7 +44,7 @@ class Element14Provider implements InfoProviderInterface
|
||||||
private const COMPLIANCE_ATTRIBUTES = ['euEccn', 'hazardous', 'MSL', 'productTraceability', 'rohsCompliant',
|
private const COMPLIANCE_ATTRIBUTES = ['euEccn', 'hazardous', 'MSL', 'productTraceability', 'rohsCompliant',
|
||||||
'rohsPhthalatesCompliant', 'SVHC', 'tariffCode', 'usEccn', 'hazardCode'];
|
'rohsPhthalatesCompliant', 'SVHC', 'tariffCode', 'usEccn', 'hazardCode'];
|
||||||
|
|
||||||
public function __construct(private readonly HttpClientInterface $element14Client, private readonly string $api_key, private readonly string $store_id)
|
public function __construct(private readonly HttpClientInterface $element14Client, private readonly Element14Settings $settings)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -65,7 +66,7 @@ class Element14Provider implements InfoProviderInterface
|
||||||
|
|
||||||
public function isActive(): bool
|
public function isActive(): bool
|
||||||
{
|
{
|
||||||
return $this->api_key !== '';
|
return $this->settings->storeId !== null && $this->settings->apiKey !== '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -77,11 +78,11 @@ class Element14Provider implements InfoProviderInterface
|
||||||
$response = $this->element14Client->request('GET', self::ENDPOINT_URL, [
|
$response = $this->element14Client->request('GET', self::ENDPOINT_URL, [
|
||||||
'query' => [
|
'query' => [
|
||||||
'term' => $term,
|
'term' => $term,
|
||||||
'storeInfo.id' => $this->store_id,
|
'storeInfo.id' => $this->settings->storeId,
|
||||||
'resultsSettings.offset' => 0,
|
'resultsSettings.offset' => 0,
|
||||||
'resultsSettings.numberOfResults' => self::NUMBER_OF_RESULTS,
|
'resultsSettings.numberOfResults' => self::NUMBER_OF_RESULTS,
|
||||||
'resultsSettings.responseGroup' => 'large',
|
'resultsSettings.responseGroup' => 'large',
|
||||||
'callInfo.apiKey' => $this->api_key,
|
'callInfo.apiKey' => $this->settings->apiKey,
|
||||||
'callInfo.responseDataFormat' => 'json',
|
'callInfo.responseDataFormat' => 'json',
|
||||||
'callInfo.version' => self::API_VERSION_NUMBER,
|
'callInfo.version' => self::API_VERSION_NUMBER,
|
||||||
],
|
],
|
||||||
|
@ -119,7 +120,7 @@ class Element14Provider implements InfoProviderInterface
|
||||||
|
|
||||||
private function generateProductURL($sku): string
|
private function generateProductURL($sku): string
|
||||||
{
|
{
|
||||||
return 'https://' . $this->store_id . '/' . $sku;
|
return 'https://' . $this->settings->storeId . '/' . $sku;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -152,7 +153,7 @@ class Element14Provider implements InfoProviderInterface
|
||||||
$locale = 'en_US';
|
$locale = 'en_US';
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'https://' . $this->store_id . '/productimages/standard/' . $locale . $image['baseName'];
|
return 'https://' . $this->settings->storeId . '/productimages/standard/' . $locale . $image['baseName'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -187,7 +188,7 @@ class Element14Provider implements InfoProviderInterface
|
||||||
public function getUsedCurrency(): string
|
public function getUsedCurrency(): string
|
||||||
{
|
{
|
||||||
//Decide based on the shop ID
|
//Decide based on the shop ID
|
||||||
return match ($this->store_id) {
|
return match ($this->settings->storeId) {
|
||||||
'bg.farnell.com', 'at.farnell.com', 'si.farnell.com', 'sk.farnell.com', 'ro.farnell.com', 'pt.farnell.com', 'nl.farnell.com', 'be.farnell.com', 'lv.farnell.com', 'lt.farnell.com', 'it.farnell.com', 'fr.farnell.com', 'fi.farnell.com', 'ee.farnell.com', 'es.farnell.com', 'ie.farnell.com', 'cpcireland.farnell.com', 'de.farnell.com' => 'EUR',
|
'bg.farnell.com', 'at.farnell.com', 'si.farnell.com', 'sk.farnell.com', 'ro.farnell.com', 'pt.farnell.com', 'nl.farnell.com', 'be.farnell.com', 'lv.farnell.com', 'lt.farnell.com', 'it.farnell.com', 'fr.farnell.com', 'fi.farnell.com', 'ee.farnell.com', 'es.farnell.com', 'ie.farnell.com', 'cpcireland.farnell.com', 'de.farnell.com' => 'EUR',
|
||||||
'cz.farnell.com' => 'CZK',
|
'cz.farnell.com' => 'CZK',
|
||||||
'dk.farnell.com' => 'DKK',
|
'dk.farnell.com' => 'DKK',
|
||||||
|
@ -214,7 +215,7 @@ class Element14Provider implements InfoProviderInterface
|
||||||
'tw.element14.com' => 'TWD',
|
'tw.element14.com' => 'TWD',
|
||||||
'kr.element14.com' => 'KRW',
|
'kr.element14.com' => 'KRW',
|
||||||
'vn.element14.com' => 'VND',
|
'vn.element14.com' => 'VND',
|
||||||
default => throw new \RuntimeException('Unknown store ID: ' . $this->store_id)
|
default => throw new \RuntimeException('Unknown store ID: ' . $this->settings->storeId)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ use App\Services\InfoProviderSystem\DTOs\ParameterDTO;
|
||||||
use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
|
use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
|
||||||
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
|
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
|
||||||
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
|
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
|
||||||
|
use App\Settings\InfoProviderSystem\LCSCSettings;
|
||||||
use Symfony\Component\HttpFoundation\Cookie;
|
use Symfony\Component\HttpFoundation\Cookie;
|
||||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ class LCSCProvider implements InfoProviderInterface
|
||||||
|
|
||||||
public const DISTRIBUTOR_NAME = 'LCSC';
|
public const DISTRIBUTOR_NAME = 'LCSC';
|
||||||
|
|
||||||
public function __construct(private readonly HttpClientInterface $lcscClient, private readonly string $currency, private readonly bool $enabled = true)
|
public function __construct(private readonly HttpClientInterface $lcscClient, private readonly LCSCSettings $settings)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -62,7 +63,7 @@ class LCSCProvider implements InfoProviderInterface
|
||||||
// This provider is always active
|
// This provider is always active
|
||||||
public function isActive(): bool
|
public function isActive(): bool
|
||||||
{
|
{
|
||||||
return $this->enabled;
|
return $this->settings->enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,7 +74,7 @@ class LCSCProvider implements InfoProviderInterface
|
||||||
{
|
{
|
||||||
$response = $this->lcscClient->request('GET', self::ENDPOINT_URL . "/product/detail", [
|
$response = $this->lcscClient->request('GET', self::ENDPOINT_URL . "/product/detail", [
|
||||||
'headers' => [
|
'headers' => [
|
||||||
'Cookie' => new Cookie('currencyCode', $this->currency)
|
'Cookie' => new Cookie('currencyCode', $this->settings->currency)
|
||||||
],
|
],
|
||||||
'query' => [
|
'query' => [
|
||||||
'productCode' => $id,
|
'productCode' => $id,
|
||||||
|
@ -123,7 +124,7 @@ class LCSCProvider implements InfoProviderInterface
|
||||||
{
|
{
|
||||||
$response = $this->lcscClient->request('GET', self::ENDPOINT_URL . "/search/global", [
|
$response = $this->lcscClient->request('GET', self::ENDPOINT_URL . "/search/global", [
|
||||||
'headers' => [
|
'headers' => [
|
||||||
'Cookie' => new Cookie('currencyCode', $this->currency)
|
'Cookie' => new Cookie('currencyCode', $this->settings->currency)
|
||||||
],
|
],
|
||||||
'query' => [
|
'query' => [
|
||||||
'keyword' => $term,
|
'keyword' => $term,
|
||||||
|
@ -273,7 +274,7 @@ class LCSCProvider implements InfoProviderInterface
|
||||||
'kr.' => 'DKK',
|
'kr.' => 'DKK',
|
||||||
'₹' => 'INR',
|
'₹' => 'INR',
|
||||||
//Fallback to the configured currency
|
//Fallback to the configured currency
|
||||||
default => $this->currency,
|
default => $this->settings->currency,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ use App\Services\InfoProviderSystem\DTOs\FileDTO;
|
||||||
use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
|
use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
|
||||||
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
|
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
|
||||||
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
|
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
|
||||||
|
use App\Settings\InfoProviderSystem\MouserSettings;
|
||||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||||
use Symfony\Contracts\HttpClient\ResponseInterface;
|
use Symfony\Contracts\HttpClient\ResponseInterface;
|
||||||
|
|
||||||
|
@ -50,10 +51,7 @@ class MouserProvider implements InfoProviderInterface
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly HttpClientInterface $mouserClient,
|
private readonly HttpClientInterface $mouserClient,
|
||||||
private readonly string $api_key,
|
private readonly MouserSettings $settings,
|
||||||
private readonly string $language,
|
|
||||||
private readonly string $options,
|
|
||||||
private readonly int $search_limit
|
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +72,7 @@ class MouserProvider implements InfoProviderInterface
|
||||||
|
|
||||||
public function isActive(): bool
|
public function isActive(): bool
|
||||||
{
|
{
|
||||||
return $this->api_key !== '';
|
return $this->settings->apiKey !== '' && $this->settings->apiKey !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function searchByKeyword(string $keyword): array
|
public function searchByKeyword(string $keyword): array
|
||||||
|
@ -119,15 +117,15 @@ class MouserProvider implements InfoProviderInterface
|
||||||
|
|
||||||
$response = $this->mouserClient->request('POST', self::ENDPOINT_URL."/keyword", [
|
$response = $this->mouserClient->request('POST', self::ENDPOINT_URL."/keyword", [
|
||||||
'query' => [
|
'query' => [
|
||||||
'apiKey' => $this->api_key,
|
'apiKey' => $this->settings->apiKey
|
||||||
],
|
],
|
||||||
'json' => [
|
'json' => [
|
||||||
'SearchByKeywordRequest' => [
|
'SearchByKeywordRequest' => [
|
||||||
'keyword' => $keyword,
|
'keyword' => $keyword,
|
||||||
'records' => $this->search_limit, //self::NUMBER_OF_RESULTS,
|
'records' => $this->settings->searchLimit, //self::NUMBER_OF_RESULTS,
|
||||||
'startingRecord' => 0,
|
'startingRecord' => 0,
|
||||||
'searchOptions' => $this->options,
|
'searchOptions' => $this->settings->searchOption->value,
|
||||||
'searchWithYourSignUpLanguage' => $this->language,
|
'searchWithYourSignUpLanguage' => $this->settings->searchWithSignUpLanguage ? 'true' : 'false',
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
@ -160,7 +158,7 @@ class MouserProvider implements InfoProviderInterface
|
||||||
|
|
||||||
$response = $this->mouserClient->request('POST', self::ENDPOINT_URL."/partnumber", [
|
$response = $this->mouserClient->request('POST', self::ENDPOINT_URL."/partnumber", [
|
||||||
'query' => [
|
'query' => [
|
||||||
'apiKey' => $this->api_key,
|
'apiKey' => $this->settings->apiKey,
|
||||||
],
|
],
|
||||||
'json' => [
|
'json' => [
|
||||||
'SearchByPartRequest' => [
|
'SearchByPartRequest' => [
|
||||||
|
|
|
@ -88,6 +88,8 @@ use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
|
||||||
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
|
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
|
||||||
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
|
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
|
||||||
use App\Services\InfoProviderSystem\DTOs\ParameterDTO;
|
use App\Services\InfoProviderSystem\DTOs\ParameterDTO;
|
||||||
|
use App\Settings\InfoProviderSystem\OEMSecretsSettings;
|
||||||
|
use App\Settings\InfoProviderSystem\OEMSecretsSortMode;
|
||||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||||
use Psr\Cache\CacheItemPoolInterface;
|
use Psr\Cache\CacheItemPoolInterface;
|
||||||
|
|
||||||
|
@ -99,12 +101,7 @@ class OEMSecretsProvider implements InfoProviderInterface
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly HttpClientInterface $oemsecretsClient,
|
private readonly HttpClientInterface $oemsecretsClient,
|
||||||
private readonly string $api_key,
|
private readonly OEMSecretsSettings $settings,
|
||||||
private readonly string $country_code,
|
|
||||||
private readonly string $currency,
|
|
||||||
private readonly string $zero_price,
|
|
||||||
private readonly string $set_param,
|
|
||||||
private readonly string $sort_criteria,
|
|
||||||
private readonly CacheItemPoolInterface $partInfoCache
|
private readonly CacheItemPoolInterface $partInfoCache
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -268,7 +265,7 @@ class OEMSecretsProvider implements InfoProviderInterface
|
||||||
*/
|
*/
|
||||||
public function isActive(): bool
|
public function isActive(): bool
|
||||||
{
|
{
|
||||||
return $this->api_key !== '';
|
return $this->settings->apiKey !== '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -324,9 +321,9 @@ class OEMSecretsProvider implements InfoProviderInterface
|
||||||
$response = $this->oemsecretsClient->request('GET', self::ENDPOINT_URL, [
|
$response = $this->oemsecretsClient->request('GET', self::ENDPOINT_URL, [
|
||||||
'query' => [
|
'query' => [
|
||||||
'searchTerm' => $keyword,
|
'searchTerm' => $keyword,
|
||||||
'apiKey' => $this->api_key,
|
'apiKey' => $this->settings->apiKey,
|
||||||
'currency' => $this->currency,
|
'currency' => $this->settings->currency,
|
||||||
'countryCode' => $this->country_code,
|
'countryCode' => $this->settings->country,
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -533,7 +530,7 @@ class OEMSecretsProvider implements InfoProviderInterface
|
||||||
|
|
||||||
// Extract prices
|
// Extract prices
|
||||||
$priceDTOs = $this->getPrices($product);
|
$priceDTOs = $this->getPrices($product);
|
||||||
if (empty($priceDTOs) && (int)$this->zero_price === 0) {
|
if (empty($priceDTOs) && !$this->settings->keepZeroPrices) {
|
||||||
return null; // Skip products without valid prices
|
return null; // Skip products without valid prices
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,7 +554,7 @@ class OEMSecretsProvider implements InfoProviderInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
$imagesResults[$provider_id] = $this->getImages($product, $imagesResults[$provider_id] ?? []);
|
$imagesResults[$provider_id] = $this->getImages($product, $imagesResults[$provider_id] ?? []);
|
||||||
if ($this->set_param == 1) {
|
if ($this->settings->parseParams) {
|
||||||
$parametersResults[$provider_id] = $this->getParameters($product, $parametersResults[$provider_id] ?? []);
|
$parametersResults[$provider_id] = $this->getParameters($product, $parametersResults[$provider_id] ?? []);
|
||||||
} else {
|
} else {
|
||||||
$parametersResults[$provider_id] = [];
|
$parametersResults[$provider_id] = [];
|
||||||
|
@ -582,7 +579,7 @@ class OEMSecretsProvider implements InfoProviderInterface
|
||||||
$regionB = $this->countryCodeToRegionMap[$countryCodeB] ?? '';
|
$regionB = $this->countryCodeToRegionMap[$countryCodeB] ?? '';
|
||||||
|
|
||||||
// If the map is empty or doesn't contain the key for $this->country_code, assign a placeholder region.
|
// If the map is empty or doesn't contain the key for $this->country_code, assign a placeholder region.
|
||||||
$regionForEnvCountry = $this->countryCodeToRegionMap[$this->country_code] ?? '';
|
$regionForEnvCountry = $this->countryCodeToRegionMap[$this->settings->country] ?? '';
|
||||||
|
|
||||||
// Convert to string before comparison to avoid mixed types
|
// Convert to string before comparison to avoid mixed types
|
||||||
$countryCodeA = (string) $countryCodeA;
|
$countryCodeA = (string) $countryCodeA;
|
||||||
|
@ -599,9 +596,9 @@ class OEMSecretsProvider implements InfoProviderInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 1: country_code from the environment
|
// Step 1: country_code from the environment
|
||||||
if ($countryCodeA === $this->country_code && $countryCodeB !== $this->country_code) {
|
if ($countryCodeA === $this->settings->country && $countryCodeB !== $this->settings->country) {
|
||||||
return -1;
|
return -1;
|
||||||
} elseif ($countryCodeA !== $this->country_code && $countryCodeB === $this->country_code) {
|
} elseif ($countryCodeA !== $this->settings->country && $countryCodeB === $this->settings->country) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -681,8 +678,8 @@ class OEMSecretsProvider implements InfoProviderInterface
|
||||||
|
|
||||||
if (is_array($prices)) {
|
if (is_array($prices)) {
|
||||||
// Step 1: Check if prices exist in the preferred currency
|
// Step 1: Check if prices exist in the preferred currency
|
||||||
if (isset($prices[$this->currency]) && is_array($prices[$this->currency])) {
|
if (isset($prices[$this->settings->currency]) && is_array($prices[$this->settings->currency])) {
|
||||||
$priceDetails = $prices[$this->currency];
|
$priceDetails = $prices[$this->$this->settings->currency];
|
||||||
foreach ($priceDetails as $priceDetail) {
|
foreach ($priceDetails as $priceDetail) {
|
||||||
if (
|
if (
|
||||||
is_array($priceDetail) &&
|
is_array($priceDetail) &&
|
||||||
|
@ -694,7 +691,7 @@ class OEMSecretsProvider implements InfoProviderInterface
|
||||||
$priceDTOs[] = new PriceDTO(
|
$priceDTOs[] = new PriceDTO(
|
||||||
minimum_discount_amount: (float)$priceDetail['unit_break'],
|
minimum_discount_amount: (float)$priceDetail['unit_break'],
|
||||||
price: (string)$priceDetail['unit_price'],
|
price: (string)$priceDetail['unit_price'],
|
||||||
currency_iso_code: $this->currency,
|
currency_iso_code: $this->settings->currency,
|
||||||
includes_tax: false,
|
includes_tax: false,
|
||||||
price_related_quantity: 1.0
|
price_related_quantity: 1.0
|
||||||
);
|
);
|
||||||
|
@ -1293,7 +1290,7 @@ class OEMSecretsProvider implements InfoProviderInterface
|
||||||
private function sortResultsData(array &$resultsData, string $searchKeyword): void
|
private function sortResultsData(array &$resultsData, string $searchKeyword): void
|
||||||
{
|
{
|
||||||
// If the SORT_CRITERIA is not 'C' or 'M', do not sort
|
// If the SORT_CRITERIA is not 'C' or 'M', do not sort
|
||||||
if ($this->sort_criteria !== 'C' && $this->sort_criteria !== 'M') {
|
if ($this->settings->sortMode !== OEMSecretsSortMode::COMPLETENESS && $this->settings->sortMode !== OEMSecretsSortMode::MANUFACTURER) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
usort($resultsData, function ($a, $b) use ($searchKeyword) {
|
usort($resultsData, function ($a, $b) use ($searchKeyword) {
|
||||||
|
@ -1332,9 +1329,9 @@ class OEMSecretsProvider implements InfoProviderInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
// Final sorting: by completeness or manufacturer, if necessary
|
// Final sorting: by completeness or manufacturer, if necessary
|
||||||
if ($this->sort_criteria === 'C') {
|
if ($this->settings->sortMode === OEMSecretsSortMode::COMPLETENESS) {
|
||||||
return $this->compareByCompleteness($a, $b);
|
return $this->compareByCompleteness($a, $b);
|
||||||
} elseif ($this->sort_criteria === 'M') {
|
} elseif ($this->settings->sortMode === OEMSecretsSortMode::MANUFACTURER) {
|
||||||
return strcasecmp($a->manufacturer, $b->manufacturer);
|
return strcasecmp($a->manufacturer, $b->manufacturer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Services\InfoProviderSystem\Providers;
|
namespace App\Services\InfoProviderSystem\Providers;
|
||||||
|
|
||||||
|
use App\Settings\InfoProviderSystem\TMESettings;
|
||||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||||
use Symfony\Contracts\HttpClient\ResponseInterface;
|
use Symfony\Contracts\HttpClient\ResponseInterface;
|
||||||
|
|
||||||
|
@ -30,15 +31,15 @@ class TMEClient
|
||||||
{
|
{
|
||||||
public const BASE_URI = 'https://api.tme.eu';
|
public const BASE_URI = 'https://api.tme.eu';
|
||||||
|
|
||||||
public function __construct(private readonly HttpClientInterface $tmeClient, private readonly string $token, private readonly string $secret)
|
public function __construct(private readonly HttpClientInterface $tmeClient, private readonly TMESettings $settings)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function makeRequest(string $action, array $parameters): ResponseInterface
|
public function makeRequest(string $action, array $parameters): ResponseInterface
|
||||||
{
|
{
|
||||||
$parameters['Token'] = $this->token;
|
$parameters['Token'] = $this->settings->apiToken;
|
||||||
$parameters['ApiSignature'] = $this->getSignature($action, $parameters, $this->secret);
|
$parameters['ApiSignature'] = $this->getSignature($action, $parameters, $this->settings->apiSecret);
|
||||||
|
|
||||||
return $this->tmeClient->request('POST', $this->getUrlForAction($action), [
|
return $this->tmeClient->request('POST', $this->getUrlForAction($action), [
|
||||||
'body' => $parameters,
|
'body' => $parameters,
|
||||||
|
@ -47,7 +48,7 @@ class TMEClient
|
||||||
|
|
||||||
public function isUsable(): bool
|
public function isUsable(): bool
|
||||||
{
|
{
|
||||||
return $this->token !== '' && $this->secret !== '';
|
return !($this->settings->apiToken === '' || $this->settings->apiSecret === '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,16 +30,14 @@ use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
|
||||||
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
|
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
|
||||||
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
|
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
|
||||||
use App\Services\InfoProviderSystem\DTOs\SearchResultDTO;
|
use App\Services\InfoProviderSystem\DTOs\SearchResultDTO;
|
||||||
|
use App\Settings\InfoProviderSystem\TMESettings;
|
||||||
|
|
||||||
class TMEProvider implements InfoProviderInterface
|
class TMEProvider implements InfoProviderInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
private const VENDOR_NAME = 'TME';
|
private const VENDOR_NAME = 'TME';
|
||||||
|
|
||||||
public function __construct(private readonly TMEClient $tmeClient, private readonly string $country,
|
public function __construct(private readonly TMEClient $tmeClient, private readonly TMESettings $settings)
|
||||||
private readonly string $language, private readonly string $currency,
|
|
||||||
/** @var bool If true, the prices are gross prices. If false, the prices are net prices. */
|
|
||||||
private readonly bool $get_gross_prices)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -67,8 +65,8 @@ class TMEProvider implements InfoProviderInterface
|
||||||
public function searchByKeyword(string $keyword): array
|
public function searchByKeyword(string $keyword): array
|
||||||
{
|
{
|
||||||
$response = $this->tmeClient->makeRequest('Products/Search', [
|
$response = $this->tmeClient->makeRequest('Products/Search', [
|
||||||
'Country' => $this->country,
|
'Country' => $this->settings->country,
|
||||||
'Language' => $this->language,
|
'Language' => $this->settings->language,
|
||||||
'SearchPlain' => $keyword,
|
'SearchPlain' => $keyword,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -97,8 +95,8 @@ class TMEProvider implements InfoProviderInterface
|
||||||
public function getDetails(string $id): PartDetailDTO
|
public function getDetails(string $id): PartDetailDTO
|
||||||
{
|
{
|
||||||
$response = $this->tmeClient->makeRequest('Products/GetProducts', [
|
$response = $this->tmeClient->makeRequest('Products/GetProducts', [
|
||||||
'Country' => $this->country,
|
'Country' => $this->settings->country,
|
||||||
'Language' => $this->language,
|
'Language' => $this->settings->language,
|
||||||
'SymbolList' => [$id],
|
'SymbolList' => [$id],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -142,8 +140,8 @@ class TMEProvider implements InfoProviderInterface
|
||||||
public function getFiles(string $id): array
|
public function getFiles(string $id): array
|
||||||
{
|
{
|
||||||
$response = $this->tmeClient->makeRequest('Products/GetProductsFiles', [
|
$response = $this->tmeClient->makeRequest('Products/GetProductsFiles', [
|
||||||
'Country' => $this->country,
|
'Country' => $this->settings->country,
|
||||||
'Language' => $this->language,
|
'Language' => $this->settings->language,
|
||||||
'SymbolList' => [$id],
|
'SymbolList' => [$id],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -184,10 +182,10 @@ class TMEProvider implements InfoProviderInterface
|
||||||
public function getVendorInfo(string $id, ?string $productURL = null): PurchaseInfoDTO
|
public function getVendorInfo(string $id, ?string $productURL = null): PurchaseInfoDTO
|
||||||
{
|
{
|
||||||
$response = $this->tmeClient->makeRequest('Products/GetPricesAndStocks', [
|
$response = $this->tmeClient->makeRequest('Products/GetPricesAndStocks', [
|
||||||
'Country' => $this->country,
|
'Country' => $this->settings->country,
|
||||||
'Language' => $this->language,
|
'Language' => $this->settings->language,
|
||||||
'Currency' => $this->currency,
|
'Currency' => $this->settings->currency,
|
||||||
'GrossPrices' => $this->get_gross_prices,
|
'GrossPrices' => $this->settings->grossPrices,
|
||||||
'SymbolList' => [$id],
|
'SymbolList' => [$id],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -227,8 +225,8 @@ class TMEProvider implements InfoProviderInterface
|
||||||
public function getParameters(string $id, string|null &$footprint_name = null): array
|
public function getParameters(string $id, string|null &$footprint_name = null): array
|
||||||
{
|
{
|
||||||
$response = $this->tmeClient->makeRequest('Products/GetParameters', [
|
$response = $this->tmeClient->makeRequest('Products/GetParameters', [
|
||||||
'Country' => $this->country,
|
'Country' => $this->settings->country,
|
||||||
'Language' => $this->language,
|
'Language' => $this->settings->language,
|
||||||
'SymbolList' => [$id],
|
'SymbolList' => [$id],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ declare(strict_types=1);
|
||||||
namespace App\Services\LabelSystem;
|
namespace App\Services\LabelSystem;
|
||||||
|
|
||||||
use App\Entity\LabelSystem\LabelProcessMode;
|
use App\Entity\LabelSystem\LabelProcessMode;
|
||||||
|
use App\Settings\SystemSettings\CustomizationSettings;
|
||||||
use Symfony\Bundle\SecurityBundle\Security;
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
use App\Entity\Contracts\NamedElementInterface;
|
use App\Entity\Contracts\NamedElementInterface;
|
||||||
use App\Entity\LabelSystem\LabelOptions;
|
use App\Entity\LabelSystem\LabelOptions;
|
||||||
|
@ -60,7 +61,7 @@ final class LabelHTMLGenerator
|
||||||
private readonly LabelBarcodeGenerator $barcodeGenerator,
|
private readonly LabelBarcodeGenerator $barcodeGenerator,
|
||||||
private readonly SandboxedTwigFactory $sandboxedTwigProvider,
|
private readonly SandboxedTwigFactory $sandboxedTwigProvider,
|
||||||
private readonly Security $security,
|
private readonly Security $security,
|
||||||
private readonly string $partdb_title)
|
private readonly CustomizationSettings $customizationSettings,)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +89,8 @@ final class LabelHTMLGenerator
|
||||||
'page' => $page,
|
'page' => $page,
|
||||||
'last_page' => count($elements),
|
'last_page' => count($elements),
|
||||||
'user' => $current_user,
|
'user' => $current_user,
|
||||||
'install_title' => $this->partdb_title,
|
'install_title' => $this->customizationSettings->instanceName,
|
||||||
|
'partdb_title' => $this->customizationSettings->instanceName,
|
||||||
'paper_width' => $options->getWidth(),
|
'paper_width' => $options->getWidth(),
|
||||||
'paper_height' => $options->getHeight(),
|
'paper_height' => $options->getHeight(),
|
||||||
]
|
]
|
||||||
|
|
|
@ -41,6 +41,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Services\LabelSystem\PlaceholderProviders;
|
namespace App\Services\LabelSystem\PlaceholderProviders;
|
||||||
|
|
||||||
|
use App\Settings\SystemSettings\CustomizationSettings;
|
||||||
use Symfony\Bundle\SecurityBundle\Security;
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
use App\Entity\UserSystem\User;
|
use App\Entity\UserSystem\User;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
|
@ -54,14 +55,18 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||||
*/
|
*/
|
||||||
final class GlobalProviders implements PlaceholderProviderInterface
|
final class GlobalProviders implements PlaceholderProviderInterface
|
||||||
{
|
{
|
||||||
public function __construct(private readonly string $partdb_title, private readonly Security $security, private readonly UrlGeneratorInterface $url_generator)
|
public function __construct(
|
||||||
|
private readonly Security $security,
|
||||||
|
private readonly UrlGeneratorInterface $url_generator,
|
||||||
|
private CustomizationSettings $customizationSettings,
|
||||||
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public function replace(string $placeholder, object $label_target, array $options = []): ?string
|
public function replace(string $placeholder, object $label_target, array $options = []): ?string
|
||||||
{
|
{
|
||||||
if ('[[INSTALL_NAME]]' === $placeholder) {
|
if ('[[INSTALL_NAME]]' === $placeholder) {
|
||||||
return $this->partdb_title;
|
return $this->customizationSettings->instanceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = $this->security->getUser();
|
$user = $this->security->getUser();
|
||||||
|
|
|
@ -22,37 +22,25 @@ declare(strict_types=1);
|
||||||
*/
|
*/
|
||||||
namespace App\Services\LogSystem;
|
namespace App\Services\LogSystem;
|
||||||
|
|
||||||
|
use App\Settings\SystemSettings\HistorySettings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This service is used to check if a log change comment is needed for a given operation type.
|
* This service is used to check if a log change comment is needed for a given operation type.
|
||||||
* It is configured using the "enforce_change_comments_for" config parameter.
|
* It is configured using the "enforce_change_comments_for" config parameter.
|
||||||
* @see \App\Tests\Services\LogSystem\EventCommentNeededHelperTest
|
* @see \App\Tests\Services\LogSystem\EventCommentNeededHelperTest
|
||||||
*/
|
*/
|
||||||
class EventCommentNeededHelper
|
final class EventCommentNeededHelper
|
||||||
{
|
{
|
||||||
final public const VALID_OPERATION_TYPES = [
|
public function __construct(private readonly HistorySettings $settings)
|
||||||
'part_edit',
|
|
||||||
'part_create',
|
|
||||||
'part_delete',
|
|
||||||
'part_stock_operation',
|
|
||||||
'datastructure_edit',
|
|
||||||
'datastructure_create',
|
|
||||||
'datastructure_delete',
|
|
||||||
];
|
|
||||||
|
|
||||||
public function __construct(protected array $enforce_change_comments_for)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a log change comment is needed for the given operation type
|
* Checks if a log change comment is needed for the given operation type
|
||||||
*/
|
*/
|
||||||
public function isCommentNeeded(string $comment_type): bool
|
public function isCommentNeeded(EventCommentType $comment_type): bool
|
||||||
{
|
{
|
||||||
//Check if the comment type is valid
|
return in_array($comment_type, $this->settings->enforceComments, true);
|
||||||
if (! in_array($comment_type, self::VALID_OPERATION_TYPES, true)) {
|
|
||||||
throw new \InvalidArgumentException('The comment type "'.$comment_type.'" is not valid!');
|
|
||||||
}
|
|
||||||
|
|
||||||
return in_array($comment_type, $this->enforce_change_comments_for, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
47
src/Services/LogSystem/EventCommentType.php
Normal file
47
src/Services/LogSystem/EventCommentType.php
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Services\LogSystem;
|
||||||
|
|
||||||
|
use Symfony\Contracts\Translation\TranslatableInterface;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This enum represents the different types of event comments that could be required, by the system.
|
||||||
|
* They are almost only useful when working with the EventCommentNeededHelper service.
|
||||||
|
*/
|
||||||
|
enum EventCommentType: string implements TranslatableInterface
|
||||||
|
{
|
||||||
|
case PART_EDIT = 'part_edit';
|
||||||
|
case PART_CREATE = 'part_create';
|
||||||
|
case PART_DELETE = 'part_delete';
|
||||||
|
case PART_STOCK_OPERATION = 'part_stock_operation';
|
||||||
|
case DATASTRUCTURE_EDIT = 'datastructure_edit';
|
||||||
|
case DATASTRUCTURE_CREATE = 'datastructure_create';
|
||||||
|
case DATASTRUCTURE_DELETE = 'datastructure_delete';
|
||||||
|
|
||||||
|
public function trans(TranslatorInterface $translator, ?string $locale = null): string
|
||||||
|
{
|
||||||
|
return $translator->trans('settings.system.history.enforceComments.type.' . $this->value, locale: $locale);
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ namespace App\Services\Parts;
|
||||||
use App\Entity\Parts\Part;
|
use App\Entity\Parts\Part;
|
||||||
use App\Entity\PriceInformations\Currency;
|
use App\Entity\PriceInformations\Currency;
|
||||||
use App\Entity\PriceInformations\Pricedetail;
|
use App\Entity\PriceInformations\Pricedetail;
|
||||||
|
use App\Settings\SystemSettings\LocalizationSettings;
|
||||||
use Brick\Math\BigDecimal;
|
use Brick\Math\BigDecimal;
|
||||||
use Brick\Math\RoundingMode;
|
use Brick\Math\RoundingMode;
|
||||||
use Doctrine\ORM\PersistentCollection;
|
use Doctrine\ORM\PersistentCollection;
|
||||||
|
@ -39,7 +40,7 @@ class PricedetailHelper
|
||||||
{
|
{
|
||||||
protected string $locale;
|
protected string $locale;
|
||||||
|
|
||||||
public function __construct(protected string $base_currency)
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->locale = Locale::getDefault();
|
$this->locale = Locale::getDefault();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,14 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Services\System;
|
namespace App\Services\System;
|
||||||
|
|
||||||
|
use App\Settings\SystemSettings\CustomizationSettings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper service to retrieve the banner of this Part-DB installation
|
* Helper service to retrieve the banner of this Part-DB installation
|
||||||
*/
|
*/
|
||||||
class BannerHelper
|
class BannerHelper
|
||||||
{
|
{
|
||||||
public function __construct(private readonly string $project_dir, private readonly string $partdb_banner)
|
public function __construct(private CustomizationSettings $customizationSettings)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,18 +41,6 @@ class BannerHelper
|
||||||
*/
|
*/
|
||||||
public function getBanner(): string
|
public function getBanner(): string
|
||||||
{
|
{
|
||||||
$banner = $this->partdb_banner;
|
return $this->customizationSettings->banner ?? "";
|
||||||
if ($banner === '') {
|
|
||||||
$banner_path = $this->project_dir
|
|
||||||
.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'banner.md';
|
|
||||||
|
|
||||||
$tmp = file_get_contents($banner_path);
|
|
||||||
if (false === $tmp) {
|
|
||||||
throw new \RuntimeException('The banner file could not be read.');
|
|
||||||
}
|
|
||||||
$banner = $tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $banner;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Services\System;
|
namespace App\Services\System;
|
||||||
|
|
||||||
|
use App\Settings\SystemSettings\PrivacySettings;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Shivas\VersioningBundle\Service\VersionManagerInterface;
|
use Shivas\VersioningBundle\Service\VersionManagerInterface;
|
||||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||||
|
@ -43,7 +44,7 @@ class UpdateAvailableManager
|
||||||
|
|
||||||
public function __construct(private readonly HttpClientInterface $httpClient,
|
public function __construct(private readonly HttpClientInterface $httpClient,
|
||||||
private readonly CacheInterface $updateCache, private readonly VersionManagerInterface $versionManager,
|
private readonly CacheInterface $updateCache, private readonly VersionManagerInterface $versionManager,
|
||||||
private readonly bool $check_for_updates, private readonly LoggerInterface $logger,
|
private readonly PrivacySettings $privacySettings, private readonly LoggerInterface $logger,
|
||||||
#[Autowire(param: 'kernel.debug')] private readonly bool $is_dev_mode)
|
#[Autowire(param: 'kernel.debug')] private readonly bool $is_dev_mode)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -83,7 +84,7 @@ class UpdateAvailableManager
|
||||||
public function isUpdateAvailable(): bool
|
public function isUpdateAvailable(): bool
|
||||||
{
|
{
|
||||||
//If we don't want to check for updates, we can return false
|
//If we don't want to check for updates, we can return false
|
||||||
if (!$this->check_for_updates) {
|
if (!$this->privacySettings->checkForUpdates) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +102,7 @@ class UpdateAvailableManager
|
||||||
private function getLatestVersionInfo(): array
|
private function getLatestVersionInfo(): array
|
||||||
{
|
{
|
||||||
//If we don't want to check for updates, we can return dummy data
|
//If we don't want to check for updates, we can return dummy data
|
||||||
if (!$this->check_for_updates) {
|
if (!$this->privacySettings->checkForUpdates) {
|
||||||
return [
|
return [
|
||||||
'version' => '0.0.1',
|
'version' => '0.0.1',
|
||||||
'url' => 'update-checking-disabled'
|
'url' => 'update-checking-disabled'
|
||||||
|
|
|
@ -23,13 +23,14 @@ declare(strict_types=1);
|
||||||
namespace App\Services\Tools;
|
namespace App\Services\Tools;
|
||||||
|
|
||||||
use App\Entity\PriceInformations\Currency;
|
use App\Entity\PriceInformations\Currency;
|
||||||
|
use App\Settings\SystemSettings\LocalizationSettings;
|
||||||
use Brick\Math\BigDecimal;
|
use Brick\Math\BigDecimal;
|
||||||
use Brick\Math\RoundingMode;
|
use Brick\Math\RoundingMode;
|
||||||
use Swap\Swap;
|
use Swap\Swap;
|
||||||
|
|
||||||
class ExchangeRateUpdater
|
class ExchangeRateUpdater
|
||||||
{
|
{
|
||||||
public function __construct(private readonly string $base_currency, private readonly Swap $swap)
|
public function __construct(private LocalizationSettings $localizationSettings, private readonly Swap $swap)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ class ExchangeRateUpdater
|
||||||
public function update(Currency $currency): Currency
|
public function update(Currency $currency): Currency
|
||||||
{
|
{
|
||||||
//Currency pairs are always in the format "BASE/QUOTE"
|
//Currency pairs are always in the format "BASE/QUOTE"
|
||||||
$rate = $this->swap->latest($this->base_currency.'/'.$currency->getIsoCode());
|
$rate = $this->swap->latest($this->localizationSettings->baseCurrency.'/'.$currency->getIsoCode());
|
||||||
//The rate says how many quote units are worth one base unit
|
//The rate says how many quote units are worth one base unit
|
||||||
//So we need to invert it to get the exchange rate
|
//So we need to invert it to get the exchange rate
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ use App\Repository\StructuralDBElementRepository;
|
||||||
use App\Services\Cache\ElementCacheTagGenerator;
|
use App\Services\Cache\ElementCacheTagGenerator;
|
||||||
use App\Services\Cache\UserCacheKeyGenerator;
|
use App\Services\Cache\UserCacheKeyGenerator;
|
||||||
use App\Services\EntityURLGenerator;
|
use App\Services\EntityURLGenerator;
|
||||||
|
use App\Settings\BehaviorSettings\SidebarSettings;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use RecursiveIteratorIterator;
|
use RecursiveIteratorIterator;
|
||||||
|
@ -53,6 +54,10 @@ use function count;
|
||||||
*/
|
*/
|
||||||
class TreeViewGenerator
|
class TreeViewGenerator
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private readonly bool $rootNodeExpandedByDefault;
|
||||||
|
private readonly bool $rootNodeEnabled;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
protected EntityURLGenerator $urlGenerator,
|
protected EntityURLGenerator $urlGenerator,
|
||||||
protected EntityManagerInterface $em,
|
protected EntityManagerInterface $em,
|
||||||
|
@ -61,10 +66,10 @@ class TreeViewGenerator
|
||||||
protected UserCacheKeyGenerator $keyGenerator,
|
protected UserCacheKeyGenerator $keyGenerator,
|
||||||
protected TranslatorInterface $translator,
|
protected TranslatorInterface $translator,
|
||||||
private readonly UrlGeneratorInterface $router,
|
private readonly UrlGeneratorInterface $router,
|
||||||
protected bool $rootNodeExpandedByDefault,
|
private readonly SidebarSettings $sidebarSettings,
|
||||||
protected bool $rootNodeEnabled,
|
|
||||||
|
|
||||||
) {
|
) {
|
||||||
|
$this->rootNodeEnabled = $this->sidebarSettings->rootNodeEnabled;
|
||||||
|
$this->rootNodeExpandedByDefault = $this->sidebarSettings->rootNodeExpanded;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -30,6 +30,7 @@ use App\Entity\Attachments\UserAttachment;
|
||||||
use App\Entity\UserSystem\User;
|
use App\Entity\UserSystem\User;
|
||||||
use App\Services\Attachments\AttachmentSubmitHandler;
|
use App\Services\Attachments\AttachmentSubmitHandler;
|
||||||
use App\Services\Attachments\AttachmentURLGenerator;
|
use App\Services\Attachments\AttachmentURLGenerator;
|
||||||
|
use App\Settings\SystemSettings\PrivacySettings;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Component\Asset\Packages;
|
use Symfony\Component\Asset\Packages;
|
||||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||||
|
@ -42,7 +43,7 @@ class UserAvatarHelper
|
||||||
public const IMG_DEFAULT_AVATAR_PATH = 'img/default_avatar.svg';
|
public const IMG_DEFAULT_AVATAR_PATH = 'img/default_avatar.svg';
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly bool $use_gravatar,
|
private readonly PrivacySettings $privacySettings,
|
||||||
private readonly Packages $packages,
|
private readonly Packages $packages,
|
||||||
private readonly AttachmentURLGenerator $attachmentURLGenerator,
|
private readonly AttachmentURLGenerator $attachmentURLGenerator,
|
||||||
private readonly EntityManagerInterface $entityManager,
|
private readonly EntityManagerInterface $entityManager,
|
||||||
|
@ -65,7 +66,7 @@ class UserAvatarHelper
|
||||||
}
|
}
|
||||||
|
|
||||||
//If not check if gravatar is enabled (then use gravatar URL)
|
//If not check if gravatar is enabled (then use gravatar URL)
|
||||||
if ($this->use_gravatar) {
|
if ($this->privacySettings->useGravatar) {
|
||||||
return $this->getGravatar($user, 200); //200px wide picture
|
return $this->getGravatar($user, 200); //200px wide picture
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +83,7 @@ class UserAvatarHelper
|
||||||
}
|
}
|
||||||
|
|
||||||
//If not check if gravatar is enabled (then use gravatar URL)
|
//If not check if gravatar is enabled (then use gravatar URL)
|
||||||
if ($this->use_gravatar) {
|
if ($this->privacySettings->useGravatar) {
|
||||||
return $this->getGravatar($user, 50); //50px wide picture
|
return $this->getGravatar($user, 50); //50px wide picture
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +100,7 @@ class UserAvatarHelper
|
||||||
}
|
}
|
||||||
|
|
||||||
//If not check if gravatar is enabled (then use gravatar URL)
|
//If not check if gravatar is enabled (then use gravatar URL)
|
||||||
if ($this->use_gravatar) {
|
if ($this->privacySettings->useGravatar) {
|
||||||
return $this->getGravatar($user, 150);
|
return $this->getGravatar($user, 150);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
52
src/Settings/AppSettings.php
Normal file
52
src/Settings/AppSettings.php
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings;
|
||||||
|
|
||||||
|
use App\Settings\BehaviorSettings\BehaviorSettings;
|
||||||
|
use App\Settings\InfoProviderSystem\InfoProviderSettings;
|
||||||
|
use App\Settings\MiscSettings\MiscSettings;
|
||||||
|
use App\Settings\SystemSettings\AttachmentsSettings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\EmbeddedSettings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||||
|
|
||||||
|
#[Settings]
|
||||||
|
#[SettingsIcon('folder-tree')]
|
||||||
|
class AppSettings
|
||||||
|
{
|
||||||
|
use SettingsTrait;
|
||||||
|
|
||||||
|
|
||||||
|
#[EmbeddedSettings()]
|
||||||
|
public ?SystemSettings $system = null;
|
||||||
|
|
||||||
|
#[EmbeddedSettings()]
|
||||||
|
public ?BehaviorSettings $behavior = null;
|
||||||
|
|
||||||
|
#[EmbeddedSettings()]
|
||||||
|
public ?InfoProviderSettings $infoProviders = null;
|
||||||
|
|
||||||
|
#[EmbeddedSettings()]
|
||||||
|
public ?MiscSettings $miscSettings = null;
|
||||||
|
}
|
40
src/Settings/BehaviorSettings/BehaviorSettings.php
Normal file
40
src/Settings/BehaviorSettings/BehaviorSettings.php
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings\BehaviorSettings;
|
||||||
|
|
||||||
|
use Jbtronics\SettingsBundle\Settings\EmbeddedSettings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||||
|
|
||||||
|
#[Settings]
|
||||||
|
class BehaviorSettings
|
||||||
|
{
|
||||||
|
use SettingsTrait;
|
||||||
|
|
||||||
|
#[EmbeddedSettings]
|
||||||
|
public ?SidebarSettings $sidebar = null;
|
||||||
|
|
||||||
|
#[EmbeddedSettings]
|
||||||
|
public ?TableSettings $table = null;
|
||||||
|
}
|
66
src/Settings/BehaviorSettings/PartTableColumns.php
Normal file
66
src/Settings/BehaviorSettings/PartTableColumns.php
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings\BehaviorSettings;
|
||||||
|
|
||||||
|
use Symfony\Contracts\Translation\TranslatableInterface;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
|
enum PartTableColumns : string implements TranslatableInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
case NAME = "name";
|
||||||
|
case ID = "id";
|
||||||
|
case IPN = "ipn";
|
||||||
|
case DESCRIPTION = "description";
|
||||||
|
case CATEGORY = "category";
|
||||||
|
case FOOTPRINT = "footprint";
|
||||||
|
case MANUFACTURER = "manufacturer";
|
||||||
|
case LOCATION = "storage_location";
|
||||||
|
case AMOUNT = "amount";
|
||||||
|
case MIN_AMOUNT = "minamount";
|
||||||
|
case PART_UNIT = "partUnit";
|
||||||
|
case ADDED_DATE = "addedDate";
|
||||||
|
case LAST_MODIFIED = "lastModified";
|
||||||
|
case NEEDS_REVIEW = "needs_review";
|
||||||
|
case FAVORITE = "favorite";
|
||||||
|
case MANUFACTURING_STATUS = "manufacturing_status";
|
||||||
|
case MPN = "manufacturer_product_number";
|
||||||
|
case MASS = "mass";
|
||||||
|
case TAGS = "tags";
|
||||||
|
case ATTACHMENTS = "attachments";
|
||||||
|
case EDIT = "edit";
|
||||||
|
|
||||||
|
public function trans(TranslatorInterface $translator, ?string $locale = null): string
|
||||||
|
{
|
||||||
|
$key = match($this) {
|
||||||
|
self::LOCATION => 'part.table.storeLocations',
|
||||||
|
self::NEEDS_REVIEW => 'part.table.needsReview',
|
||||||
|
self::MANUFACTURING_STATUS => 'part.table.manufacturingStatus',
|
||||||
|
self::MPN => 'part.table.mpn',
|
||||||
|
default => 'part.table.' . $this->value,
|
||||||
|
};
|
||||||
|
|
||||||
|
return $translator->trans($key, locale: $locale);
|
||||||
|
}
|
||||||
|
}
|
53
src/Settings/BehaviorSettings/SidebarItems.php
Normal file
53
src/Settings/BehaviorSettings/SidebarItems.php
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings\BehaviorSettings;
|
||||||
|
|
||||||
|
use Symfony\Contracts\Translation\TranslatableInterface;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
|
enum SidebarItems: string implements TranslatableInterface
|
||||||
|
{
|
||||||
|
case TOOLS = "tools";
|
||||||
|
case CATEGORIES = "categories";
|
||||||
|
case LOCATIONS = "locations";
|
||||||
|
case FOOTPRINTS = "footprints";
|
||||||
|
case MANUFACTURERS = "manufacturers";
|
||||||
|
case SUPPLIERS = "suppliers";
|
||||||
|
case PROJECTS = "projects";
|
||||||
|
|
||||||
|
public function trans(TranslatorInterface $translator, ?string $locale = null): string
|
||||||
|
{
|
||||||
|
$key = match($this) {
|
||||||
|
self::TOOLS => 'tools.label',
|
||||||
|
self::CATEGORIES => 'category.labelp',
|
||||||
|
self::LOCATIONS => 'storelocation.labelp',
|
||||||
|
self::FOOTPRINTS => 'footprint.labelp',
|
||||||
|
self::MANUFACTURERS => 'manufacturer.labelp',
|
||||||
|
self::SUPPLIERS => 'supplier.labelp',
|
||||||
|
self::PROJECTS => 'project.labelp',
|
||||||
|
};
|
||||||
|
|
||||||
|
return $translator->trans($key, locale: $locale);
|
||||||
|
}
|
||||||
|
}
|
70
src/Settings/BehaviorSettings/SidebarSettings.php
Normal file
70
src/Settings/BehaviorSettings/SidebarSettings.php
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings\BehaviorSettings;
|
||||||
|
|
||||||
|
use App\Settings\SettingsIcon;
|
||||||
|
use Jbtronics\SettingsBundle\ParameterTypes\ArrayType;
|
||||||
|
use Jbtronics\SettingsBundle\ParameterTypes\EnumType;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||||
|
use Symfony\Component\Translation\TranslatableMessage as TM;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
|
#[Settings(label: new TM("settings.behavior.sidebar"))]
|
||||||
|
#[SettingsIcon('fa-border-top-left')]
|
||||||
|
class SidebarSettings
|
||||||
|
{
|
||||||
|
use SettingsTrait;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var SidebarItems[] The items to show in the sidebar.
|
||||||
|
*/
|
||||||
|
#[SettingsParameter(ArrayType::class,
|
||||||
|
label: new TM("settings.behavior.sidebar.items"),
|
||||||
|
description: new TM("settings.behavior.sidebar.items.help"),
|
||||||
|
options: ['type' => EnumType::class, 'options' => ['class' => SidebarItems::class]],
|
||||||
|
formType: \Symfony\Component\Form\Extension\Core\Type\EnumType::class,
|
||||||
|
formOptions: ['class' => SidebarItems::class, 'multiple' => true, 'ordered' => true]
|
||||||
|
)]
|
||||||
|
#[Assert\NotBlank()]
|
||||||
|
#[Assert\Unique()]
|
||||||
|
public array $items = [SidebarItems::CATEGORIES, SidebarItems::PROJECTS, SidebarItems::TOOLS];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool Whether categories, etc. should be grouped under a root node or put directly into the sidebar trees.
|
||||||
|
*/
|
||||||
|
#[SettingsParameter(
|
||||||
|
label: new TM("settings.behavior.sidebar.rootNodeEnabled"),
|
||||||
|
description: new TM("settings.behavior.sidebar.rootNodeEnabled.help")
|
||||||
|
)]
|
||||||
|
public bool $rootNodeEnabled = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool Whether the root node should be expanded by default, or not.
|
||||||
|
*/
|
||||||
|
#[SettingsParameter(label: new TM("settings.behavior.sidebar.rootNodeExpanded"))]
|
||||||
|
public bool $rootNodeExpanded = true;
|
||||||
|
}
|
90
src/Settings/BehaviorSettings/TableSettings.php
Normal file
90
src/Settings/BehaviorSettings/TableSettings.php
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings\BehaviorSettings;
|
||||||
|
|
||||||
|
use App\Settings\SettingsIcon;
|
||||||
|
use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
|
||||||
|
use Jbtronics\SettingsBundle\ParameterTypes\ArrayType;
|
||||||
|
use Jbtronics\SettingsBundle\ParameterTypes\EnumType;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||||
|
use Symfony\Component\Translation\TranslatableMessage as TM;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
|
#[Settings(label: new TM("settings.behavior.table"))]
|
||||||
|
#[SettingsIcon('fa-table')]
|
||||||
|
class TableSettings
|
||||||
|
{
|
||||||
|
use SettingsTrait;
|
||||||
|
|
||||||
|
#[SettingsParameter(
|
||||||
|
label: new TM("settings.behavior.table.default_page_size"),
|
||||||
|
description: new TM("settings.behavior.table.default_page_size.help"),
|
||||||
|
envVar: "int:TABLE_DEFAULT_PAGE_SIZE",
|
||||||
|
envVarMode: EnvVarMode::OVERWRITE,
|
||||||
|
)]
|
||||||
|
#[Assert\AtLeastOneOf(constraints:
|
||||||
|
[
|
||||||
|
new Assert\Positive(),
|
||||||
|
new Assert\EqualTo(value: -1)
|
||||||
|
]
|
||||||
|
)]
|
||||||
|
public int $fullDefaultPageSize = 50;
|
||||||
|
|
||||||
|
|
||||||
|
/** @var PartTableColumns[] */
|
||||||
|
#[SettingsParameter(ArrayType::class,
|
||||||
|
label: new TM("settings.behavior.table.parts_default_columns"),
|
||||||
|
description: new TM("settings.behavior.table.parts_default_columns.help"),
|
||||||
|
options: ['type' => EnumType::class, 'options' => ['class' => PartTableColumns::class]],
|
||||||
|
formType: \Symfony\Component\Form\Extension\Core\Type\EnumType::class,
|
||||||
|
formOptions: ['class' => PartTableColumns::class, 'multiple' => true, 'ordered' => true],
|
||||||
|
envVar: "TABLE_PARTS_DEFAULT_COLUMNS", envVarMode: EnvVarMode::OVERWRITE, envVarMapper: [self::class, 'mapPartsDefaultColumnsEnv']
|
||||||
|
)]
|
||||||
|
#[Assert\NotBlank()]
|
||||||
|
#[Assert\Unique()]
|
||||||
|
#[Assert\All([new Assert\Type(PartTableColumns::class)])]
|
||||||
|
public array $partsDefaultColumns = [PartTableColumns::NAME, PartTableColumns::DESCRIPTION,
|
||||||
|
PartTableColumns::CATEGORY, PartTableColumns::FOOTPRINT, PartTableColumns::MANUFACTURER,
|
||||||
|
PartTableColumns::LOCATION, PartTableColumns::AMOUNT];
|
||||||
|
|
||||||
|
|
||||||
|
public static function mapPartsDefaultColumnsEnv(string $columns): array
|
||||||
|
{
|
||||||
|
$exploded = explode(',', $columns);
|
||||||
|
$ret = [];
|
||||||
|
foreach ($exploded as $column) {
|
||||||
|
$enum = PartTableColumns::tryFrom($column);
|
||||||
|
if (!$enum) {
|
||||||
|
throw new \InvalidArgumentException("Invalid column '$column' in TABLE_PARTS_DEFAULT_COLUMNS");
|
||||||
|
}
|
||||||
|
|
||||||
|
$ret[] = $enum;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
43
src/Settings/InfoProviderSystem/Element14Settings.php
Normal file
43
src/Settings/InfoProviderSystem/Element14Settings.php
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings\InfoProviderSystem;
|
||||||
|
|
||||||
|
use App\Settings\SettingsIcon;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||||
|
use Symfony\Component\Translation\TranslatableMessage as TM;
|
||||||
|
|
||||||
|
#[Settings(label: new TM("settings.ips.element14"))]
|
||||||
|
#[SettingsIcon("fa-plug")]
|
||||||
|
class Element14Settings
|
||||||
|
{
|
||||||
|
use SettingsTrait;
|
||||||
|
|
||||||
|
#[SettingsParameter(label: new TM("settings.ips.element14.apiKey"), description: new TM("settings.ips.element14.apiKey.help"), formOptions: ["help_html" => true], envVar: "PROVIDER_ELEMENT14_KEY")]
|
||||||
|
public ?string $apiKey = null;
|
||||||
|
|
||||||
|
#[SettingsParameter(label: new TM("settings.ips.element14.storeId"), description: new TM("settings.ips.element14.storeId.help"), formOptions: ["help_html" => true], envVar: "PROVIDER_ELEMENT14_STORE_ID")]
|
||||||
|
public string $storeId = "de.farnell.com";
|
||||||
|
}
|
49
src/Settings/InfoProviderSystem/InfoProviderSettings.php
Normal file
49
src/Settings/InfoProviderSystem/InfoProviderSettings.php
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings\InfoProviderSystem;
|
||||||
|
|
||||||
|
use Jbtronics\SettingsBundle\Settings\EmbeddedSettings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||||
|
|
||||||
|
#[Settings()]
|
||||||
|
class InfoProviderSettings
|
||||||
|
{
|
||||||
|
use SettingsTrait;
|
||||||
|
|
||||||
|
#[EmbeddedSettings]
|
||||||
|
public ?MouserSettings $mouser = null;
|
||||||
|
|
||||||
|
#[EmbeddedSettings]
|
||||||
|
public ?TMESettings $tme = null;
|
||||||
|
|
||||||
|
#[EmbeddedSettings]
|
||||||
|
public ?Element14Settings $element14 = null;
|
||||||
|
|
||||||
|
#[EmbeddedSettings]
|
||||||
|
public ?LCSCSettings $lcsc = null;
|
||||||
|
|
||||||
|
#[EmbeddedSettings]
|
||||||
|
public ?OEMSecretsSettings $oemsecrets = null;
|
||||||
|
}
|
46
src/Settings/InfoProviderSystem/LCSCSettings.php
Normal file
46
src/Settings/InfoProviderSystem/LCSCSettings.php
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings\InfoProviderSystem;
|
||||||
|
|
||||||
|
use App\Settings\SettingsIcon;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\CurrencyType;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
use Symfony\Component\Translation\TranslatableMessage as TM;
|
||||||
|
|
||||||
|
#[Settings(label: new TM("settings.ips.lcsc"), description: new TM("settings.ips.lcsc.help"))]
|
||||||
|
#[SettingsIcon("fa-plug")]
|
||||||
|
class LCSCSettings
|
||||||
|
{
|
||||||
|
use SettingsTrait;
|
||||||
|
|
||||||
|
#[SettingsParameter(label: new TM("settings.ips.lcsc.enabled"), envVar: "bool:PROVIDER_LCSC_ENABLED")]
|
||||||
|
public bool $enabled = false;
|
||||||
|
|
||||||
|
#[SettingsParameter(label: new TM("settings.ips.lcsc.currency"), formType: CurrencyType::class, envVar: "string:PROVIDER_LCSC_CURRENCY")]
|
||||||
|
#[Assert\Currency()]
|
||||||
|
public string $currency = 'EUR';
|
||||||
|
}
|
47
src/Settings/InfoProviderSystem/MouserSearchOptions.php
Normal file
47
src/Settings/InfoProviderSystem/MouserSearchOptions.php
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings\InfoProviderSystem;
|
||||||
|
|
||||||
|
use Symfony\Contracts\Translation\TranslatableInterface;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
|
enum MouserSearchOptions: string implements TranslatableInterface
|
||||||
|
{
|
||||||
|
case NONE = "None";
|
||||||
|
case ROHS = "Rohs";
|
||||||
|
case IN_STOCK = "InStock";
|
||||||
|
case ROHS_AND_INSTOCK = "RohsAndInStock";
|
||||||
|
|
||||||
|
public function trans(TranslatorInterface $translator, ?string $locale = null): string
|
||||||
|
{
|
||||||
|
$key = match($this) {
|
||||||
|
self::NONE => "settings.ips.mouser.searchOptions.none",
|
||||||
|
self::ROHS => "settings.ips.mouser.searchOptions.rohs",
|
||||||
|
self::IN_STOCK => "settings.ips.mouser.searchOptions.inStock",
|
||||||
|
self::ROHS_AND_INSTOCK => "settings.ips.mouser.searchOptions.rohsAndInStock",
|
||||||
|
};
|
||||||
|
|
||||||
|
return $translator->trans($key, locale: $locale);
|
||||||
|
}
|
||||||
|
}
|
63
src/Settings/InfoProviderSystem/MouserSettings.php
Normal file
63
src/Settings/InfoProviderSystem/MouserSettings.php
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings\InfoProviderSystem;
|
||||||
|
|
||||||
|
use App\Settings\SettingsIcon;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
use Symfony\Component\Translation\TranslatableMessage as TM;
|
||||||
|
|
||||||
|
#[Settings(label: new TM("settings.ips.mouser"))]
|
||||||
|
#[SettingsIcon("fa-plug")]
|
||||||
|
class MouserSettings
|
||||||
|
{
|
||||||
|
#[SettingsParameter(label: new TM("settings.ips.mouser.apiKey"), description: new TM("settings.ips.mouser.apiKey.help"), formOptions: ["help_html" => true], envVar: "PROVIDER_MOUSER_KEY")]
|
||||||
|
public ?string $apiKey = null;
|
||||||
|
|
||||||
|
/** @var int The number of results to get from Mouser while searching (please note that this value is max 50) */
|
||||||
|
#[SettingsParameter(label: new TM("settings.ips.mouser.searchLimit"), description: new TM("settings.ips.mouser.searchLimit.help"), envVar: "int:PROVIDER_MOUSER_SEARCH_LIMIT")]
|
||||||
|
#[Assert\Range(min: 1, max: 50)]
|
||||||
|
public int $searchLimit = 50;
|
||||||
|
|
||||||
|
/** @var MouserSearchOptions Filter search results by RoHS compliance and stock availability */
|
||||||
|
#[SettingsParameter(label: new TM("settings.ips.mouser.searchOptions"), description: new TM("settings.ips.mouser.searchOptions.help"), envVar: "PROVIDER_MOUSER_SEARCH_OPTION", envVarMapper: [self::class, "mapSearchOptionEnvVar"])]
|
||||||
|
public MouserSearchOptions $searchOption = MouserSearchOptions::NONE;
|
||||||
|
|
||||||
|
/** @var bool It is recommended to leave this set to 'true'. The option is not really documented by Mouser:
|
||||||
|
* Used when searching for keywords in the language specified when you signed up for Search API. */
|
||||||
|
//TODO: Put this into some expert mode only
|
||||||
|
#[SettingsParameter(envVar: "bool:PROVIDER_MOUSER_SEARCH_WITH_SIGNUP_LANGUAGE")]
|
||||||
|
public bool $searchWithSignUpLanguage = true;
|
||||||
|
|
||||||
|
public static function mapSearchOptionEnvVar(?string $value): MouserSearchOptions
|
||||||
|
{
|
||||||
|
if (!$value) {
|
||||||
|
return MouserSearchOptions::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MouserSearchOptions::tryFrom($value) ?? MouserSearchOptions::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
82
src/Settings/InfoProviderSystem/OEMSecretsSettings.php
Normal file
82
src/Settings/InfoProviderSystem/OEMSecretsSettings.php
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2025 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings\InfoProviderSystem;
|
||||||
|
|
||||||
|
use App\Settings\SettingsIcon;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\CountryType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\CurrencyType;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
use Symfony\Component\Translation\TranslatableMessage as TM;
|
||||||
|
|
||||||
|
#[Settings(label: new TM("settings.ips.oemsecrets"))]
|
||||||
|
#[SettingsIcon("fa-plug")]
|
||||||
|
class OEMSecretsSettings
|
||||||
|
{
|
||||||
|
use SettingsTrait;
|
||||||
|
|
||||||
|
public const SUPPORTED_CURRENCIES = ["AUD", "CAD", "CHF", "CNY", "DKK", "EUR", "GBP", "HKD", "ILS", "INR", "JPY", "KRW", "NOK",
|
||||||
|
"NZD", "RUB", "SEK", "SGD", "TWD", "USD"];
|
||||||
|
|
||||||
|
#[SettingsParameter(label: new TM("settings.ips.element14.apiKey"), envVar: "PROVIDER_OEMSECRETS_KEY")]
|
||||||
|
public ?string $apiKey = null;
|
||||||
|
|
||||||
|
#[Assert\Country]
|
||||||
|
#[SettingsParameter(label: new TM("settings.ips.tme.country"), formType: CountryType::class, formOptions: ["preferred_choices" => ["DE", "PL", "GB", "FR", "US"]], envVar: "PROVIDER_OEMSECRETS_COUNTRY_CODE")]
|
||||||
|
public ?string $country = "DE";
|
||||||
|
|
||||||
|
#[SettingsParameter(label: new TM("settings.ips.tme.currency"), formType: CurrencyType::class, formOptions: ["preferred_choices" => self::SUPPORTED_CURRENCIES], envVar: "PROVIDER_OEMSECRETS_CURRENCY")]
|
||||||
|
#[Assert\Choice(choices: self::SUPPORTED_CURRENCIES)]
|
||||||
|
public string $currency = "EUR";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool If this is enabled, distributors with zero prices
|
||||||
|
* will be discarded from the creation of a new part
|
||||||
|
*/
|
||||||
|
#[SettingsParameter(label: new TM("settings.ips.oemsecrets.keepZeroPrices"), description: new TM("settings.ips.oemsecrets.keepZeroPrices.help"), envVar: "bool:PROVIDER_OEMSECRETS_ZERO_PRICE")]
|
||||||
|
public bool $keepZeroPrices = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool If set to 1 the parameters for the part are generated
|
||||||
|
* # from the description transforming unstructured descriptions into structured parameters;
|
||||||
|
* # each parameter in description should have the form: "...;name1:value1;name2:value2"
|
||||||
|
*/
|
||||||
|
#[SettingsParameter(label: new TM("settings.ips.oemsecrets.parseParams"), description: new TM("settings.ips.oemsecrets.parseParams.help"), envVar: "bool:PROVIDER_OEMSECRETS_SET_PARAM")]
|
||||||
|
public bool $parseParams = true;
|
||||||
|
|
||||||
|
#[SettingsParameter(label: new TM("settings.ips.oemsecrets.sortMode"), envVar: "PROVIDER_OEMSECRETS_SORT_CRITERIA", envVarMapper: [self::class, "mapSortModeEnvVar"])]
|
||||||
|
public OEMSecretsSortMode $sortMode = OEMSecretsSortMode::COMPLETENESS;
|
||||||
|
|
||||||
|
|
||||||
|
public static function mapSortModeEnvVar(?string $value): OEMSecretsSortMode
|
||||||
|
{
|
||||||
|
if (!$value) {
|
||||||
|
return OEMSecretsSortMode::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OEMSecretsSortMode::tryFrom($value) ?? OEMSecretsSortMode::NONE;
|
||||||
|
}
|
||||||
|
}
|
46
src/Settings/InfoProviderSystem/OEMSecretsSortMode.php
Normal file
46
src/Settings/InfoProviderSystem/OEMSecretsSortMode.php
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2025 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings\InfoProviderSystem;
|
||||||
|
|
||||||
|
use Symfony\Contracts\Translation\TranslatableInterface;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This environment variable determines the sorting criteria for product results.
|
||||||
|
* The sorting process first arranges items based on the provided keyword.
|
||||||
|
* Then, if set to 'C', it further sorts by completeness (prioritizing items with the most
|
||||||
|
* detailed information). If set to 'M', it further sorts by manufacturer name.
|
||||||
|
* If unset or set to any other value, no sorting is performed.
|
||||||
|
*/
|
||||||
|
enum OEMSecretsSortMode : string implements TranslatableInterface
|
||||||
|
{
|
||||||
|
case NONE = "N";
|
||||||
|
case COMPLETENESS = "C";
|
||||||
|
case MANUFACTURER = "M";
|
||||||
|
|
||||||
|
public function trans(TranslatorInterface $translator, ?string $locale = null): string
|
||||||
|
{
|
||||||
|
return $translator->trans('settings.ips.oemsecrets.sortMode.' . $this->value, locale: $locale);
|
||||||
|
}
|
||||||
|
}
|
65
src/Settings/InfoProviderSystem/TMESettings.php
Normal file
65
src/Settings/InfoProviderSystem/TMESettings.php
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings\InfoProviderSystem;
|
||||||
|
|
||||||
|
use App\Settings\SettingsIcon;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\CountryType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\CurrencyType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\LanguageType;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
use Symfony\Component\Translation\TranslatableMessage as TM;
|
||||||
|
|
||||||
|
#[Settings(label: new TM("settings.ips.tme"))]
|
||||||
|
#[SettingsIcon("fa-plug")]
|
||||||
|
class TMESettings
|
||||||
|
{
|
||||||
|
use SettingsTrait;
|
||||||
|
|
||||||
|
private const SUPPORTED_CURRENCIES = ["EUR", "USD", "PLN", "GBP"];
|
||||||
|
|
||||||
|
#[SettingsParameter(label: new TM("settings.ips.tme.token"),
|
||||||
|
description: new TM("settings.ips.tme.token.help"), formOptions: ["help_html" => true], envVar: "PROVIDER_TME_KEY")]
|
||||||
|
public ?string $apiToken = null;
|
||||||
|
|
||||||
|
#[SettingsParameter(label: new TM("settings.ips.tme.secret"), envVar: "PROVIDER_TME_SECRET")]
|
||||||
|
public ?string $apiSecret = null;
|
||||||
|
|
||||||
|
#[SettingsParameter(label: new TM("settings.ips.tme.currency"), formType: CurrencyType::class, formOptions: ["preferred_choices" => self::SUPPORTED_CURRENCIES], envVar: "PROVIDER_TME_CURRENCY")]
|
||||||
|
#[Assert\Choice(choices: self::SUPPORTED_CURRENCIES)]
|
||||||
|
public string $currency = "EUR";
|
||||||
|
|
||||||
|
#[SettingsParameter(label: new TM("settings.ips.tme.language"), formType: LanguageType::class, formOptions: ["preferred_choices" => ["en", "de", "fr", "pl"]], envVar: "PROVIDER_TME_LANGUAGE")]
|
||||||
|
#[Assert\Language]
|
||||||
|
public string $language = "en";
|
||||||
|
|
||||||
|
#[SettingsParameter(label: new TM("settings.ips.tme.country"), envVar: "PROVIDER_TME_COUNTRY", formType: CountryType::class, formOptions: ["preferred_choices" => ["DE", "PL", "GB", "FR"]])]
|
||||||
|
#[Assert\Country]
|
||||||
|
public string $country = "DE";
|
||||||
|
|
||||||
|
#[SettingsParameter(label: new TM("settings.ips.tme.grossPrices"), envVar: "bool:PROVIDER_TME_GET_GROSS_PRICES")]
|
||||||
|
public bool $grossPrices = true;
|
||||||
|
}
|
46
src/Settings/MiscSettings/KiCadEDASettings.php
Normal file
46
src/Settings/MiscSettings/KiCadEDASettings.php
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings\MiscSettings;
|
||||||
|
|
||||||
|
use App\Settings\SettingsIcon;
|
||||||
|
use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||||
|
use Symfony\Component\Translation\TranslatableMessage as TM;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
|
#[Settings(label: new TM("settings.misc.kicad_eda"))]
|
||||||
|
#[SettingsIcon("fa-bolt-lightning")]
|
||||||
|
class KiCadEDASettings
|
||||||
|
{
|
||||||
|
use SettingsTrait;
|
||||||
|
|
||||||
|
|
||||||
|
#[SettingsParameter(label: new TM("settings.misc.kicad_eda.category_depth"),
|
||||||
|
description: new TM("settings.misc.kicad_eda.category_depth.help"),
|
||||||
|
envVar: "int:EDA_KICAD_CATEGORY_DEPTH", envVarMode: EnvVarMode::OVERWRITE)]
|
||||||
|
#[Assert\Range(min: -1)]
|
||||||
|
public int $categoryDepth = 0;
|
||||||
|
}
|
34
src/Settings/MiscSettings/MiscSettings.php
Normal file
34
src/Settings/MiscSettings/MiscSettings.php
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings\MiscSettings;
|
||||||
|
|
||||||
|
use Jbtronics\SettingsBundle\Settings\EmbeddedSettings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||||
|
|
||||||
|
#[Settings]
|
||||||
|
class MiscSettings
|
||||||
|
{
|
||||||
|
#[EmbeddedSettings]
|
||||||
|
public ?KiCadEDASettings $kicadEDA = null;
|
||||||
|
}
|
32
src/Settings/SettingsIcon.php
Normal file
32
src/Settings/SettingsIcon.php
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_CLASS)]
|
||||||
|
class SettingsIcon
|
||||||
|
{
|
||||||
|
public function __construct(public string $icon)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
51
src/Settings/SystemSettings.php
Normal file
51
src/Settings/SystemSettings.php
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings;
|
||||||
|
|
||||||
|
use App\Settings\SystemSettings\AttachmentsSettings;
|
||||||
|
use App\Settings\SystemSettings\CustomizationSettings;
|
||||||
|
use App\Settings\SystemSettings\HistorySettings;
|
||||||
|
use App\Settings\SystemSettings\LocalizationSettings;
|
||||||
|
use App\Settings\SystemSettings\PrivacySettings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\EmbeddedSettings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||||
|
|
||||||
|
#[Settings]
|
||||||
|
class SystemSettings
|
||||||
|
{
|
||||||
|
#[EmbeddedSettings()]
|
||||||
|
public ?LocalizationSettings $localization = null;
|
||||||
|
|
||||||
|
#[EmbeddedSettings()]
|
||||||
|
public ?CustomizationSettings $customization = null;
|
||||||
|
|
||||||
|
#[EmbeddedSettings()]
|
||||||
|
public ?PrivacySettings $privacy = null;
|
||||||
|
|
||||||
|
#[EmbeddedSettings()]
|
||||||
|
public ?AttachmentsSettings $attachments = null;
|
||||||
|
|
||||||
|
#[EmbeddedSettings()]
|
||||||
|
public ?HistorySettings $history = null;
|
||||||
|
}
|
61
src/Settings/SystemSettings/AttachmentsSettings.php
Normal file
61
src/Settings/SystemSettings/AttachmentsSettings.php
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings\SystemSettings;
|
||||||
|
|
||||||
|
use App\Settings\SettingsIcon;
|
||||||
|
use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||||
|
use Symfony\Component\Translation\TranslatableMessage as TM;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
|
#[Settings(label: new TM("settings.system.attachments"))]
|
||||||
|
#[SettingsIcon("fa-paperclip")]
|
||||||
|
class AttachmentsSettings
|
||||||
|
{
|
||||||
|
use SettingsTrait;
|
||||||
|
|
||||||
|
#[SettingsParameter(
|
||||||
|
label: new TM("settings.system.attachments.maxFileSize"),
|
||||||
|
description: new TM("settings.system.attachments.maxFileSize.help"),
|
||||||
|
envVar: "MAX_ATTACHMENT_FILE_SIZE", envVarMode: EnvVarMode::OVERWRITE
|
||||||
|
)]
|
||||||
|
#[Assert\Regex("/^([1-9][0-9]*)([KMG])?$/", message: "validator.fileSize.invalidFormat")]
|
||||||
|
public string $maxFileSize = '100M';
|
||||||
|
|
||||||
|
#[SettingsParameter(
|
||||||
|
label: new TM("settings.system.attachments.allowDownloads"),
|
||||||
|
description: new TM("settings.system.attachments.allowDownloads.help"),
|
||||||
|
formOptions: ['help_html' => true],
|
||||||
|
envVar: "bool:ALLOW_ATTACHMENT_DOWNLOADS", envVarMode: EnvVarMode::OVERWRITE
|
||||||
|
)]
|
||||||
|
public bool $allowDownloads = false;
|
||||||
|
|
||||||
|
#[SettingsParameter(
|
||||||
|
label: new TM("settings.system.attachments.downloadByDefault"),
|
||||||
|
envVar: "bool:ATTACHMENT_DOWNLOAD_BY_DEFAULT", envVarMode: EnvVarMode::OVERWRITE
|
||||||
|
)]
|
||||||
|
public bool $downloadByDefault = false;
|
||||||
|
}
|
61
src/Settings/SystemSettings/CustomizationSettings.php
Normal file
61
src/Settings/SystemSettings/CustomizationSettings.php
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings\SystemSettings;
|
||||||
|
|
||||||
|
use App\Form\Type\RichTextEditorType;
|
||||||
|
use App\Form\Type\ThemeChoiceType;
|
||||||
|
use App\Settings\SettingsIcon;
|
||||||
|
use App\Validator\Constraints\ValidTheme;
|
||||||
|
use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||||
|
use Symfony\Component\Translation\TranslatableMessage as TM;
|
||||||
|
|
||||||
|
#[Settings(name: "customization", label: new TM("settings.system.customization"))]
|
||||||
|
#[SettingsIcon("fa-paint-roller")]
|
||||||
|
class CustomizationSettings
|
||||||
|
{
|
||||||
|
use SettingsTrait;
|
||||||
|
|
||||||
|
#[SettingsParameter(
|
||||||
|
label: new TM("settings.system.customization.instanceName"),
|
||||||
|
description: new TM("settings.system.customization.instanceName.help"),
|
||||||
|
envVar: "INSTANCE_NAME", envVarMode: EnvVarMode::OVERWRITE,
|
||||||
|
)]
|
||||||
|
public string $instanceName = "Part-DB";
|
||||||
|
|
||||||
|
#[SettingsParameter(
|
||||||
|
label: new TM("settings.system.customization.banner"),
|
||||||
|
formType: RichTextEditorType::class, formOptions: ['mode' => 'markdown-full'],
|
||||||
|
)]
|
||||||
|
public ?string $banner = null;
|
||||||
|
|
||||||
|
#[SettingsParameter(
|
||||||
|
label: new TM("settings.system.customization.theme"),
|
||||||
|
formType: ThemeChoiceType::class, formOptions: ['placeholder' => false]
|
||||||
|
)]
|
||||||
|
#[ValidTheme]
|
||||||
|
public string $theme = 'bootstrap';
|
||||||
|
}
|
86
src/Settings/SystemSettings/HistorySettings.php
Normal file
86
src/Settings/SystemSettings/HistorySettings.php
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings\SystemSettings;
|
||||||
|
|
||||||
|
use App\Form\History\EnforceEventCommentTypesType;
|
||||||
|
use App\Services\LogSystem\EventCommentType;
|
||||||
|
use App\Settings\SettingsIcon;
|
||||||
|
use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
|
||||||
|
use Jbtronics\SettingsBundle\ParameterTypes\ArrayType;
|
||||||
|
use Jbtronics\SettingsBundle\ParameterTypes\EnumType;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||||
|
use Symfony\Component\Translation\TranslatableMessage as TM;
|
||||||
|
|
||||||
|
#[Settings(label: new TM("settings.system.history"))]
|
||||||
|
#[SettingsIcon("fa-binoculars")]
|
||||||
|
class HistorySettings
|
||||||
|
{
|
||||||
|
use SettingsTrait;
|
||||||
|
|
||||||
|
#[SettingsParameter(
|
||||||
|
label: new TM("settings.system.history.saveChangedFields"),
|
||||||
|
envVar: "bool:HISTORY_SAVE_CHANGED_FIELDS", envVarMode: EnvVarMode::OVERWRITE)]
|
||||||
|
public bool $saveChangedFields = true;
|
||||||
|
|
||||||
|
#[SettingsParameter(
|
||||||
|
label: new TM("settings.system.history.saveOldData"),
|
||||||
|
envVar: "bool:HISTORY_SAVE_CHANGED_DATA", envVarMode: EnvVarMode::OVERWRITE
|
||||||
|
)]
|
||||||
|
public bool $saveOldData = true;
|
||||||
|
|
||||||
|
#[SettingsParameter(
|
||||||
|
label: new TM("settings.system.history.saveNewData"),
|
||||||
|
envVar: "bool:HISTORY_SAVE_NEW_DATA", envVarMode: EnvVarMode::OVERWRITE
|
||||||
|
)]
|
||||||
|
public bool $saveNewData = true;
|
||||||
|
|
||||||
|
#[SettingsParameter(
|
||||||
|
label: new TM("settings.system.history.saveRemovedData"),
|
||||||
|
envVar: "bool:HISTORY_SAVE_REMOVED_DATA", envVarMode: EnvVarMode::OVERWRITE
|
||||||
|
)]
|
||||||
|
public bool $saveRemovedData = true;
|
||||||
|
|
||||||
|
/** @var EventCommentType[] */
|
||||||
|
#[SettingsParameter(
|
||||||
|
type: ArrayType::class,
|
||||||
|
label: new TM("settings.system.history.enforceComments"),
|
||||||
|
description: new TM("settings.system.history.enforceComments.description"),
|
||||||
|
options: ['type' => EnumType::class, 'nullable' => false, 'options' => ['class' => EventCommentType::class]],
|
||||||
|
formType: EnforceEventCommentTypesType::class,
|
||||||
|
envVar: "ENFORCE_CHANGE_COMMENTS_FOR", envVarMode: EnvVarMode::OVERWRITE, envVarMapper: [self::class, 'mapEnforceComments']
|
||||||
|
)]
|
||||||
|
public array $enforceComments = [];
|
||||||
|
|
||||||
|
public static function mapEnforceComments(string $value): array
|
||||||
|
{
|
||||||
|
if (trim($value) === '') {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$explode = explode(',', $value);
|
||||||
|
return array_map(fn(string $type) => EventCommentType::from($type), $explode);
|
||||||
|
}
|
||||||
|
}
|
63
src/Settings/SystemSettings/LocalizationSettings.php
Normal file
63
src/Settings/SystemSettings/LocalizationSettings.php
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings\SystemSettings;
|
||||||
|
|
||||||
|
use App\Form\Type\LocaleSelectType;
|
||||||
|
use App\Settings\SettingsIcon;
|
||||||
|
use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\CurrencyType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\TimezoneType;
|
||||||
|
use Symfony\Component\Translation\TranslatableMessage as TM;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
|
#[Settings(label: new TM("settings.system.localization"))]
|
||||||
|
#[SettingsIcon("fa-globe")]
|
||||||
|
class LocalizationSettings
|
||||||
|
{
|
||||||
|
use SettingsTrait;
|
||||||
|
|
||||||
|
#[Assert\Locale()]
|
||||||
|
#[Assert\NotBlank()]
|
||||||
|
#[SettingsParameter(label: new TM("settings.system.localization.locale"), formType: LocaleSelectType::class,
|
||||||
|
envVar: "string:DEFAULT_LANG", envVarMode: EnvVarMode::OVERWRITE)]
|
||||||
|
public string $locale = 'en';
|
||||||
|
|
||||||
|
#[Assert\Timezone()]
|
||||||
|
#[Assert\NotBlank()]
|
||||||
|
#[SettingsParameter(label: new TM("settings.system.localization.timezone"), formType: TimezoneType::class,
|
||||||
|
envVar: "string:DEFAULT_TIMEZONE", envVarMode: EnvVarMode::OVERWRITE)]
|
||||||
|
public string $timezone = 'Europe/Berlin';
|
||||||
|
|
||||||
|
#[Assert\Currency()]
|
||||||
|
#[Assert\NotBlank()]
|
||||||
|
#[SettingsParameter(label: new TM("settings.system.localization.base_currency"),
|
||||||
|
description: new TM("settings.system.localization.base_currency_description"),
|
||||||
|
formType: CurrencyType::class, formOptions: ['preferred_choices' => ['EUR', 'USD', 'GBP', "JPY", "CNY"], 'help_html' => true],
|
||||||
|
envVar: "string:BASE_CURRENCY", envVarMode: EnvVarMode::OVERWRITE
|
||||||
|
)]
|
||||||
|
public string $baseCurrency = 'EUR';
|
||||||
|
}
|
53
src/Settings/SystemSettings/PrivacySettings.php
Normal file
53
src/Settings/SystemSettings/PrivacySettings.php
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace App\Settings\SystemSettings;
|
||||||
|
|
||||||
|
use App\Settings\SettingsIcon;
|
||||||
|
use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\Settings;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsParameter;
|
||||||
|
use Jbtronics\SettingsBundle\Settings\SettingsTrait;
|
||||||
|
use Symfony\Component\Translation\TranslatableMessage as TM;
|
||||||
|
|
||||||
|
#[Settings(label: new TM("settings.system.privacy"))]
|
||||||
|
#[SettingsIcon("fa-location-pin-lock")]
|
||||||
|
class PrivacySettings
|
||||||
|
{
|
||||||
|
use SettingsTrait;
|
||||||
|
|
||||||
|
#[SettingsParameter(
|
||||||
|
label: new TM("settings.system.privacy.checkForUpdates"),
|
||||||
|
description: new TM("settings.system.privacy.checkForUpdates.description"),
|
||||||
|
envVar: 'bool:CHECK_FOR_UPDATES', envVarMode: EnvVarMode::OVERWRITE)]
|
||||||
|
public bool $checkForUpdates = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool Use gravatars for user avatars, when user has no own avatar defined
|
||||||
|
*/
|
||||||
|
#[SettingsParameter(
|
||||||
|
label: new TM("settings.system.privacy.useGravatar"),
|
||||||
|
description: new TM("settings.system.privacy.useGravatar.description"),
|
||||||
|
envVar: 'bool:USE_GRAVATAR', envVarMode: EnvVarMode::OVERWRITE)]
|
||||||
|
public bool $useGravatar = false;
|
||||||
|
}
|
|
@ -9,6 +9,8 @@ use ApiPlatform\State\ProviderInterface;
|
||||||
use App\ApiResource\PartDBInfo;
|
use App\ApiResource\PartDBInfo;
|
||||||
use App\Services\Misc\GitVersionInfo;
|
use App\Services\Misc\GitVersionInfo;
|
||||||
use App\Services\System\BannerHelper;
|
use App\Services\System\BannerHelper;
|
||||||
|
use App\Settings\SystemSettings\CustomizationSettings;
|
||||||
|
use App\Settings\SystemSettings\LocalizationSettings;
|
||||||
use Shivas\VersioningBundle\Service\VersionManagerInterface;
|
use Shivas\VersioningBundle\Service\VersionManagerInterface;
|
||||||
|
|
||||||
class PartDBInfoProvider implements ProviderInterface
|
class PartDBInfoProvider implements ProviderInterface
|
||||||
|
@ -16,12 +18,10 @@ class PartDBInfoProvider implements ProviderInterface
|
||||||
|
|
||||||
public function __construct(private readonly VersionManagerInterface $versionManager,
|
public function __construct(private readonly VersionManagerInterface $versionManager,
|
||||||
private readonly GitVersionInfo $gitVersionInfo,
|
private readonly GitVersionInfo $gitVersionInfo,
|
||||||
private readonly string $partdb_title,
|
|
||||||
private readonly string $base_currency,
|
|
||||||
private readonly BannerHelper $bannerHelper,
|
private readonly BannerHelper $bannerHelper,
|
||||||
private readonly string $default_uri,
|
private readonly string $default_uri,
|
||||||
private readonly string $global_timezone,
|
private readonly LocalizationSettings $localizationSettings,
|
||||||
private readonly string $global_locale
|
private readonly CustomizationSettings $customizationSettings,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -33,12 +33,12 @@ class PartDBInfoProvider implements ProviderInterface
|
||||||
version: $this->versionManager->getVersion()->toString(),
|
version: $this->versionManager->getVersion()->toString(),
|
||||||
git_branch: $this->gitVersionInfo->getGitBranchName(),
|
git_branch: $this->gitVersionInfo->getGitBranchName(),
|
||||||
git_commit: $this->gitVersionInfo->getGitCommitHash(),
|
git_commit: $this->gitVersionInfo->getGitCommitHash(),
|
||||||
title: $this->partdb_title,
|
title: $this->customizationSettings->instanceName,
|
||||||
banner: $this->bannerHelper->getBanner(),
|
banner: $this->bannerHelper->getBanner(),
|
||||||
default_uri: $this->default_uri,
|
default_uri: $this->default_uri,
|
||||||
global_timezone: $this->global_timezone,
|
global_timezone: $this->localizationSettings->timezone,
|
||||||
base_currency: $this->base_currency,
|
base_currency: $this->localizationSettings->baseCurrency,
|
||||||
global_locale: $this->global_locale,
|
global_locale: $this->localizationSettings->locale,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,9 @@ declare(strict_types=1);
|
||||||
namespace App\Twig;
|
namespace App\Twig;
|
||||||
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use App\Services\LogSystem\EventCommentType;
|
||||||
|
use Jbtronics\SettingsBundle\Proxy\SettingsProxyInterface;
|
||||||
|
use ReflectionClass;
|
||||||
use Twig\TwigFunction;
|
use Twig\TwigFunction;
|
||||||
use App\Services\LogSystem\EventCommentNeededHelper;
|
use App\Services\LogSystem\EventCommentNeededHelper;
|
||||||
use Twig\Extension\AbstractExtension;
|
use Twig\Extension\AbstractExtension;
|
||||||
|
@ -36,14 +39,43 @@ final class MiscExtension extends AbstractExtension
|
||||||
public function getFunctions(): array
|
public function getFunctions(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
new TwigFunction('event_comment_needed',
|
new TwigFunction('event_comment_needed', $this->evenCommentNeeded(...)),
|
||||||
fn(string $operation_type) => $this->eventCommentNeededHelper->isCommentNeeded($operation_type)
|
|
||||||
),
|
|
||||||
|
|
||||||
|
new TwigFunction('settings_icon', $this->settingsIcon(...)),
|
||||||
new TwigFunction('uri_without_host', $this->uri_without_host(...))
|
new TwigFunction('uri_without_host', $this->uri_without_host(...))
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function evenCommentNeeded(string|EventCommentType $operation_type): bool
|
||||||
|
{
|
||||||
|
if (is_string($operation_type)) {
|
||||||
|
$operation_type = EventCommentType::from($operation_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->eventCommentNeededHelper->isCommentNeeded($operation_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of the icon attribute of the SettingsIcon attribute of the given class.
|
||||||
|
* If the class does not have a SettingsIcon attribute, then null is returned.
|
||||||
|
* @param string|object $objectOrClass
|
||||||
|
* @return string|null
|
||||||
|
* @throws \ReflectionException
|
||||||
|
*/
|
||||||
|
private function settingsIcon(string|object $objectOrClass): ?string
|
||||||
|
{
|
||||||
|
//If the given object is a proxy, then get the real object
|
||||||
|
if (is_a($objectOrClass, SettingsProxyInterface::class)) {
|
||||||
|
$objectOrClass = get_parent_class($objectOrClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
$reflection = new ReflectionClass($objectOrClass);
|
||||||
|
|
||||||
|
$attribute = $reflection->getAttributes(\App\Settings\SettingsIcon::class)[0] ?? null;
|
||||||
|
|
||||||
|
return $attribute?->newInstance()->icon;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Similar to the getUri function of the request, but does not contain protocol and host.
|
* Similar to the getUri function of the request, but does not contain protocol and host.
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
|
|
|
@ -154,6 +154,9 @@
|
||||||
"jbtronics/dompdf-font-loader-bundle": {
|
"jbtronics/dompdf-font-loader-bundle": {
|
||||||
"version": "v1.1.1"
|
"version": "v1.1.1"
|
||||||
},
|
},
|
||||||
|
"jbtronics/settings-bundle": {
|
||||||
|
"version": "2.0.1"
|
||||||
|
},
|
||||||
"jbtronics/translation-editor-bundle": {
|
"jbtronics/translation-editor-bundle": {
|
||||||
"version": "v1.0"
|
"version": "v1.0"
|
||||||
},
|
},
|
||||||
|
@ -248,12 +251,6 @@
|
||||||
"./config/packages/datatables.yaml"
|
"./config/packages/datatables.yaml"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"phenx/php-font-lib": {
|
|
||||||
"version": "0.5.1"
|
|
||||||
},
|
|
||||||
"phenx/php-svg-lib": {
|
|
||||||
"version": "v0.3.3"
|
|
||||||
},
|
|
||||||
"php-http/discovery": {
|
"php-http/discovery": {
|
||||||
"version": "1.18",
|
"version": "1.18",
|
||||||
"recipe": {
|
"recipe": {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
{% import "helper.twig" as helper %}
|
{% import "helper.twig" as helper %}
|
||||||
|
{% import "vars.macro.twig" as vars %}
|
||||||
{% import "components/search.macro.html.twig" as search %}
|
{% import "components/search.macro.html.twig" as search %}
|
||||||
|
|
||||||
<nav class="navbar navbar-expand-md bg-body-tertiary border-bottom shadow-sm fixed-top py-0" id="navbar">
|
<nav class="navbar navbar-expand-md bg-body-tertiary border-bottom shadow-sm fixed-top py-0" id="navbar">
|
||||||
|
@ -17,7 +18,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a class="navbar-brand" href="{{ path('homepage') }}"><i class="fa fa-microchip"
|
<a class="navbar-brand" href="{{ path('homepage') }}"><i class="fa fa-microchip"
|
||||||
aria-hidden="true"></i> {{ partdb_title }}</a>
|
aria-hidden="true"></i> {{ vars.partdb_title() }}</a>
|
||||||
|
|
||||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarContent"
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarContent"
|
||||||
aria-controls="navbarContent" aria-expanded="false" aria-label="Toggle navigation">
|
aria-controls="navbarContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
|
|
||||||
<div class="nav flex-column">
|
<div class="nav flex-column">
|
||||||
{% for item in sidebar_items %}
|
{% for item in settings_instance('sidebar').items %}
|
||||||
{{ tree.treeview_sidebar('sidebar-panel-' ~ loop.index, item) }}
|
{{ tree.treeview_sidebar('sidebar-panel-' ~ loop.index, item.value) }}
|
||||||
<div class="mb-2"></div>
|
<div class="mb-2"></div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
|
@ -1,5 +1,7 @@
|
||||||
{% extends "admin/base_admin.html.twig" %}
|
{% extends "admin/base_admin.html.twig" %}
|
||||||
|
|
||||||
|
{% import "vars.macro.twig" as vars %}
|
||||||
|
|
||||||
{% block card_title %}
|
{% block card_title %}
|
||||||
<i class="fa-solid fa-coins"></i> {% trans %}currency.caption{% endtrans %}
|
<i class="fa-solid fa-coins"></i> {% trans %}currency.caption{% endtrans %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -20,8 +22,8 @@
|
||||||
{{ form_row(form.exchange_rate) }}
|
{{ form_row(form.exchange_rate) }}
|
||||||
{% if entity.inverseExchangeRate %}
|
{% if entity.inverseExchangeRate %}
|
||||||
<p class="form-text text-muted offset-3 col-9">
|
<p class="form-text text-muted offset-3 col-9">
|
||||||
{{ '1'|format_currency(default_currency) }} = {{ entity.inverseExchangeRate.tofloat | format_currency(entity.isoCode, {fraction_digit: 5}) }}<br>
|
{{ '1'|format_currency(vars.base_currency()) }} = {{ entity.inverseExchangeRate.tofloat | format_currency(entity.isoCode, {fraction_digit: 5}) }}<br>
|
||||||
{{ '1'|format_currency(entity.isoCode) }} = {{ entity.exchangeRate.tofloat | format_currency(default_currency, {fraction_digit: 5}) }}
|
{{ '1'|format_currency(entity.isoCode) }} = {{ entity.exchangeRate.tofloat | format_currency(vars.base_currency(), {fraction_digit: 5}) }}
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
{% import "vars.macro.twig" as vars %}
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="{{ app.request.locale | replace({"_": "-"}) }}"
|
<html lang="{{ app.request.locale | replace({"_": "-"}) }}"
|
||||||
{# For the UX translator, just use the language part (before the _. should be 2 chars), otherwise it finds no translations #}
|
{# For the UX translator, just use the language part (before the _. should be 2 chars), otherwise it finds no translations #}
|
||||||
|
@ -31,21 +33,19 @@
|
||||||
<link rel="mask-icon" href="{{ asset('icon/safari-pinned-tab.svg') }}" color="#5bbad5">
|
<link rel="mask-icon" href="{{ asset('icon/safari-pinned-tab.svg') }}" color="#5bbad5">
|
||||||
|
|
||||||
{# The content block is already escaped. so we must not escape it again. #}
|
{# The content block is already escaped. so we must not escape it again. #}
|
||||||
<title>{% apply trim|raw %}{% block title %}{{ partdb_title }}{% endblock %}{% endapply %}</title>
|
<title>{% apply trim|raw %}{% block title %}{{ vars.partdb_title() }}{% endblock %}{% endapply %}</title>
|
||||||
{% set current_page_title = block("title")|raw %}
|
{% set current_page_title = block("title")|raw %}
|
||||||
{% block stylesheets %}
|
{% block stylesheets %}
|
||||||
{# Include the main bootstrap theme based on user/global setting #}
|
{# Include the main bootstrap theme based on user/global setting #}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{% if not app.user.theme is defined %}
|
{% if app.user.theme is not defined or app.user.theme is null %}
|
||||||
{% set theme = global_theme %}
|
{% set theme = settings_instance('customization').theme %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% set theme = app.user.theme %}
|
{% set theme = app.user.theme %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{% if theme and theme in available_themes and encore_entry_exists('theme_' ~ theme) %}
|
{% if theme and theme in available_themes and encore_entry_exists('theme_' ~ theme) %}
|
||||||
{{ encore_entry_link_tags('theme_' ~ theme) }}
|
{{ encore_entry_link_tags('theme_' ~ theme) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
['footprints', path('tree_footprint_root'), 'footprint.labelp', is_granted('@footprints.read') and is_granted('@parts.read')],
|
['footprints', path('tree_footprint_root'), 'footprint.labelp', is_granted('@footprints.read') and is_granted('@parts.read')],
|
||||||
['manufacturers', path('tree_manufacturer_root'), 'manufacturer.labelp', is_granted('@manufacturers.read') and is_granted('@parts.read')],
|
['manufacturers', path('tree_manufacturer_root'), 'manufacturer.labelp', is_granted('@manufacturers.read') and is_granted('@parts.read')],
|
||||||
['suppliers', path('tree_supplier_root'), 'supplier.labelp', is_granted('@suppliers.read') and is_granted('@parts.read')],
|
['suppliers', path('tree_supplier_root'), 'supplier.labelp', is_granted('@suppliers.read') and is_granted('@parts.read')],
|
||||||
['devices', path('tree_device_root'), 'project.labelp', is_granted('@projects.read')],
|
['projects', path('tree_device_root'), 'project.labelp', is_granted('@projects.read')],
|
||||||
['tools', path('tree_tools'), 'tools.label', true],
|
['tools', path('tree_tools'), 'tools.label', true],
|
||||||
] %}
|
] %}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
{% import "components/new_version.macro.html.twig" as nv %}
|
{% import "components/new_version.macro.html.twig" as nv %}
|
||||||
{% import "components/search.macro.html.twig" as search %}
|
{% import "components/search.macro.html.twig" as search %}
|
||||||
|
{% import "vars.macro.twig" as vars %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
@ -16,7 +17,7 @@
|
||||||
|
|
||||||
|
|
||||||
<div class="rounded p-4 bg-body-secondary">
|
<div class="rounded p-4 bg-body-secondary">
|
||||||
<h1 class="display-3">{{ partdb_title }}</h1>
|
<h1 class="display-3">{{ vars.partdb_title() }}</h1>
|
||||||
<h4>
|
<h4>
|
||||||
{% trans %}version.caption{% endtrans %}: {{ shivas_app_version }}
|
{% trans %}version.caption{% endtrans %}: {{ shivas_app_version }}
|
||||||
{% if git_branch is not empty or git_commit is not empty %}
|
{% if git_branch is not empty or git_commit is not empty %}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
{% import "vars.macro.twig" as vars %}
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>{{ meta_title }}</title>
|
<title>{{ meta_title }}</title>
|
||||||
<meta name="author" content="{{ partdb_title }}">
|
<meta name="author" content="{{ vars.partdb_title() }}">
|
||||||
<meta name="description" content="Label for {{ meta_title }}">
|
<meta name="description" content="Label for {{ meta_title }}">
|
||||||
<meta name="keywords" content="Part-DB, Label, Barcode">
|
<meta name="keywords" content="Part-DB, Label, Barcode">
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
{% import "vars.macro.twig" as vars %}
|
||||||
|
|
||||||
{% apply inky_to_html|inline_css(source('@css/email/foundation-emails.css'), source('@css/email/email.css')) %}
|
{% apply inky_to_html|inline_css(source('@css/email/foundation-emails.css'), source('@css/email/email.css')) %}
|
||||||
|
|
||||||
<container>
|
<container>
|
||||||
|
@ -5,7 +7,7 @@
|
||||||
<row class="header">
|
<row class="header">
|
||||||
<columns>
|
<columns>
|
||||||
<spacer size="16"></spacer>
|
<spacer size="16"></spacer>
|
||||||
<h4 class="text-center"><a href="{{ url('homepage') }}">{{ partdb_title }}</a></h4>
|
<h4 class="text-center"><a href="{{ url('homepage') }}">{{ vars.partdb_title() }}</a></h4>
|
||||||
</columns>
|
</columns>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
|
60
templates/settings/settings.html.twig
Normal file
60
templates/settings/settings.html.twig
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
{% extends "main_card.html.twig" %}
|
||||||
|
{% macro genId(widget) %}{{ widget.vars.full_name }}{% endmacro %}
|
||||||
|
|
||||||
|
{% block title %}{% trans %}settings.title{% endtrans %}{% endblock %}
|
||||||
|
|
||||||
|
{% block card_title %}<i class="fa-solid fa-gears fa-fw"></i> {% trans %}settings.title{% endtrans %}{% endblock %}
|
||||||
|
|
||||||
|
{% block card_content %}
|
||||||
|
{{ form_start(form) }}
|
||||||
|
|
||||||
|
{# Tabs #}
|
||||||
|
<ul class="nav nav-tabs">
|
||||||
|
{% for tab_widget in form %}
|
||||||
|
{# Create a tab for each compound form #}
|
||||||
|
{% if tab_widget.vars.compound ?? false %}
|
||||||
|
<li class="nav-item">
|
||||||
|
<button type="button" class="nav-link {% if loop.first %}active{% endif %}" aria-current="page" data-bs-toggle="tab"
|
||||||
|
id="settings-{{ _self.genId(tab_widget) }}-tab" data-bs-target="#settings-{{ _self.genId(tab_widget) }}-pane"
|
||||||
|
>{{ (tab_widget.vars.label ?? tab_widget.vars.name|humanize)|trans }}</button>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{# Panes #}
|
||||||
|
<div class="tab-content">
|
||||||
|
{% for tab_widget in form %}
|
||||||
|
{# Create a tab for each compound form #}
|
||||||
|
{% if tab_widget.vars.compound ?? false %}
|
||||||
|
<div class="tab-pane fade pt-2 {% if loop.first %}show active{% endif %}" id="settings-{{ _self.genId(tab_widget) }}-pane">
|
||||||
|
{{ form_help(tab_widget) }}
|
||||||
|
{{ form_errors(tab_widget) }}
|
||||||
|
|
||||||
|
{% for section_widget in tab_widget %}
|
||||||
|
{% set settings_object = section_widget.vars.value %}
|
||||||
|
|
||||||
|
{% if section_widget.vars.compound ?? false %}
|
||||||
|
<fieldset>
|
||||||
|
<legend class="offset-3">
|
||||||
|
<i class="fa-solid {{ settings_icon(settings_object)|default('fa-sliders') }} fa-fw"></i>
|
||||||
|
{{ (section_widget.vars.label ?? section_widget.vars.name|humanize)|trans }}
|
||||||
|
</legend>
|
||||||
|
{{ form_help(section_widget) }}
|
||||||
|
{{ form_errors(section_widget) }}
|
||||||
|
{{ form_widget(section_widget) }}
|
||||||
|
</fieldset>
|
||||||
|
{% if not loop.last %}
|
||||||
|
<hr class="mx-0 mb-2 mt-2">
|
||||||
|
{% endif %}
|
||||||
|
{% else %} {# If not a compound render as normal row #}
|
||||||
|
{{ form_row(section_widget) }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ form_end(form) }}
|
||||||
|
{% endblock %}
|
|
@ -1,4 +1,5 @@
|
||||||
{% import "helper.twig" as helper %}
|
{% import "helper.twig" as helper %}
|
||||||
|
{% import "vars.macro.twig" as vars %}
|
||||||
|
|
||||||
<table class="table table-sm table-striped table-hover table-bordered">
|
<table class="table table-sm table-striped table-hover table-bordered">
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -15,7 +16,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Part-DB Instance name</td>
|
<td>Part-DB Instance name</td>
|
||||||
<td>{{ partdb_title }}</td>
|
<td>{{ vars.partdb_title() }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Default locale</td>
|
<td>Default locale</td>
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
{% extends "base.html.twig" %}
|
{% extends "base.html.twig" %}
|
||||||
|
{% import "vars.macro.twig" as vars %}
|
||||||
|
|
||||||
{% block title %}{{ partdb_title }} {% trans %}tfa_backup.codes.title{% endtrans %}{% endblock %}
|
{% block title %}{{ vars.partdb_title() }} {% trans %}tfa_backup.codes.title{% endtrans %}{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
{{ partdb_title }} {% trans %}tfa_backup.codes.title{% endtrans %}
|
{{ vars.partdb_title() }} {% trans %}tfa_backup.codes.title{% endtrans %}
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title">{% trans %}tfa_backup.codes.explanation{% endtrans %}</h5>
|
<h5 class="card-title">{% trans %}tfa_backup.codes.explanation{% endtrans %}</h5>
|
||||||
|
|
3
templates/vars.macro.twig
Normal file
3
templates/vars.macro.twig
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{% macro partdb_title() %}{{ settings_instance("customization").instanceName }}{% endmacro %}
|
||||||
|
|
||||||
|
{% macro base_currency() %}{{ settings_instance("localization").baseCurrency }}{% endmacro %}
|
|
@ -23,23 +23,22 @@ declare(strict_types=1);
|
||||||
namespace App\Tests\Services\LogSystem;
|
namespace App\Tests\Services\LogSystem;
|
||||||
|
|
||||||
use App\Services\LogSystem\EventCommentNeededHelper;
|
use App\Services\LogSystem\EventCommentNeededHelper;
|
||||||
|
use App\Services\LogSystem\EventCommentType;
|
||||||
|
use App\Settings\SystemSettings\HistorySettings;
|
||||||
|
use App\Tests\SettingsTestHelper;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class EventCommentNeededHelperTest extends TestCase
|
class EventCommentNeededHelperTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testIsCommentNeeded(): void
|
public function testIsCommentNeeded(): void
|
||||||
{
|
{
|
||||||
$service = new EventCommentNeededHelper(['part_edit', 'part_create']);
|
$settings = SettingsTestHelper::createSettingsDummy(HistorySettings::class);
|
||||||
$this->assertTrue($service->isCommentNeeded('part_edit'));
|
$settings->enforceComments = [EventCommentType::PART_CREATE, EventCommentType::PART_EDIT];
|
||||||
$this->assertTrue($service->isCommentNeeded('part_create'));
|
|
||||||
$this->assertFalse($service->isCommentNeeded('part_delete'));
|
|
||||||
$this->assertFalse($service->isCommentNeeded('part_stock_operation'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testIsCommentNeededInvalidTypeException(): void
|
$service = new EventCommentNeededHelper($settings);
|
||||||
{
|
$this->assertTrue($service->isCommentNeeded(EventCommentType::PART_CREATE));
|
||||||
$service = new EventCommentNeededHelper(['part_edit', 'part_create']);
|
$this->assertTrue($service->isCommentNeeded(EventCommentType::PART_EDIT));
|
||||||
$this->expectException(\InvalidArgumentException::class);
|
$this->assertFalse($service->isCommentNeeded(EventCommentType::DATASTRUCTURE_EDIT));
|
||||||
$service->isCommentNeeded('this_is_not_valid');
|
$this->assertFalse($service->isCommentNeeded(EventCommentType::PART_STOCK_OPERATION));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
57
tests/SettingsTestHelper.php
Normal file
57
tests/SettingsTestHelper.php
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 - 2024 Jan Böhmer (https://github.com/jbtronics)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Tests;
|
||||||
|
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use ReflectionClass;
|
||||||
|
|
||||||
|
class SettingsTestHelper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Creates a new dummy settings object for testing purposes.
|
||||||
|
* It does not contain any embedded objects!
|
||||||
|
* @template T of object
|
||||||
|
* @param string $class
|
||||||
|
* @phpstan-param class-string<T> $class
|
||||||
|
* @return object
|
||||||
|
* @phpstan-return T
|
||||||
|
*/
|
||||||
|
public static function createSettingsDummy(string $class): object
|
||||||
|
{
|
||||||
|
$reflection = new ReflectionClass($class);
|
||||||
|
|
||||||
|
//Check if it is a settings class (has a Settings attribute)
|
||||||
|
if ($reflection->getAttributes(\Jbtronics\SettingsBundle\Settings\Settings::class) === []) {
|
||||||
|
throw new InvalidArgumentException("The class $class is not a settings class!");
|
||||||
|
}
|
||||||
|
|
||||||
|
$object = $reflection->newInstanceWithoutConstructor();
|
||||||
|
|
||||||
|
//If the object has some initialization logic, then call it
|
||||||
|
if ($object instanceof \Jbtronics\SettingsBundle\Settings\ResettableSettingsInterface) {
|
||||||
|
$object->resetToDefaultValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $object;
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue