+And God said
+$\nabla \cdot \vec{D} = \rho$,
+$\nabla \cdot \vec{B} = 0$,
+$\nabla \times \vec{E} = -\frac{\partial \vec{B}}{\partial t}$,
+$\nabla \times \vec{H} = \vec{j} + \frac{\partial \vec{D}}{\partial t}$,
+and then there was light.
+
+
\ No newline at end of file
diff --git a/config/bundles.php b/config/bundles.php
index 084e6870..ea066084 100644
--- a/config/bundles.php
+++ b/config/bundles.php
@@ -30,8 +30,6 @@ return [
Jbtronics\DompdfFontLoaderBundle\DompdfFontLoaderBundle::class => ['all' => true],
KnpU\OAuth2ClientBundle\KnpUOAuth2ClientBundle::class => ['all' => true],
Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true],
- Jbtronics\SettingsBundle\JbtronicsSettingsBundle::class => ['all' => true],
- Jbtronics\TranslationEditorBundle\JbtronicsTranslationEditorBundle::class => ['dev' => true],
ApiPlatform\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true],
- Symfony\UX\TogglePassword\TogglePasswordBundle::class => ['all' => true],
+ Jbtronics\TranslationEditorBundle\JbtronicsTranslationEditorBundle::class => ['dev' => true],
];
diff --git a/config/packages/api_platform.yaml b/config/packages/api_platform.yaml
index 1b679cd1..d55f91ea 100644
--- a/config/packages/api_platform.yaml
+++ b/config/packages/api_platform.yaml
@@ -32,9 +32,10 @@ api_platform:
pagination_client_items_per_page: true # Allow clients to override the default items per page
+ keep_legacy_inflector: false
# Need to be true, or some tests will fail
use_symfony_listeners: true
serializer:
# Change this to false later, to remove the hydra prefix on the API
- hydra_prefix: true
+ hydra_prefix: true
\ No newline at end of file
diff --git a/config/packages/csrf.yaml b/config/packages/csrf.yaml
deleted file mode 100644
index 01db6267..00000000
--- a/config/packages/csrf.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-# Enable stateless CSRF protection for forms and logins/logouts
-framework:
- form:
- csrf_protection:
- token_id: submit
-
- csrf_protection:
- check_header: true
- stateless_token_ids:
- - submit
- - authenticate
- - logout
diff --git a/config/packages/datatables.yaml b/config/packages/datatables.yaml
index 1297fc9d..6076a6c7 100644
--- a/config/packages/datatables.yaml
+++ b/config/packages/datatables.yaml
@@ -9,8 +9,7 @@ datatables:
# Set options, as documented at https://datatables.net/reference/option/
options:
lengthMenu : [[10, 25, 50, 100], [10, 25, 50, 100]] # We add the "All" option, when part tables are generated
- #pageLength: '%partdb.table.default_page_size%' # Set to -1 to disable pagination (i.e. show all rows) by default
- pageLength: 50 #TODO
+ pageLength: '%partdb.table.default_page_size%' # Set to -1 to disable pagination (i.e. show all rows) by default
dom: " <'row' <'col mb-2 input-group flex-nowrap' B l > <'col-auto mb-2' < p >>>
<'card'
rt
diff --git a/config/packages/doctrine.yaml b/config/packages/doctrine.yaml
index 5261c295..3211fbbe 100644
--- a/config/packages/doctrine.yaml
+++ b/config/packages/doctrine.yaml
@@ -25,6 +25,10 @@ doctrine:
tinyint:
class: App\Doctrine\Types\TinyIntType
+ # This was removed in doctrine/orm 4.0 but we need it for the WebauthnKey entity
+ array:
+ class: App\Doctrine\Types\ArrayType
+
schema_filter: ~^(?!internal)~
# Only enable this when needed
profiling_collect_backtrace: false
@@ -35,8 +39,6 @@ doctrine:
report_fields_where_declared: true
validate_xml_mapping: true
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
- identity_generation_preferences:
- Doctrine\DBAL\Platforms\PostgreSQLPlatform: identity
auto_mapping: true
controller_resolver:
auto_mapping: true
diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml
index 6843a177..279c51f5 100644
--- a/config/packages/framework.yaml
+++ b/config/packages/framework.yaml
@@ -1,6 +1,9 @@
# see https://symfony.com/doc/current/reference/configuration/framework.html
framework:
secret: '%env(APP_SECRET)%'
+ csrf_protection: true
+ annotations: false
+ handle_all_throwables: true
# We set this header by ourselves, so we can disable it here
disallow_search_engine_index: false
@@ -27,11 +30,8 @@ framework:
#esi: true
#fragments: true
-
-
- form: { csrf_protection: { token_id: 'submit' } }
- csrf_protection:
- stateless_token_ids: ['submit', 'authenticate', 'logout']
+ php_errors:
+ log: true
when@test:
framework:
diff --git a/config/packages/knpu_oauth2_client.yaml b/config/packages/knpu_oauth2_client.yaml
index 5e56d5c5..7d296a8b 100644
--- a/config/packages/knpu_oauth2_client.yaml
+++ b/config/packages/knpu_oauth2_client.yaml
@@ -6,8 +6,8 @@ knpu_oauth2_client:
type: generic
provider_class: '\League\OAuth2\Client\Provider\GenericProvider'
- client_id: '%env(settings:digikey:clientId)%'
- client_secret: '%env(settings:digikey:secret)%'
+ client_id: '%env(PROVIDER_DIGIKEY_CLIENT_ID)%'
+ client_secret: '%env(PROVIDER_DIGIKEY_SECRET)%'
redirect_route: 'oauth_client_check'
redirect_params: {name: 'ip_digikey_oauth'}
@@ -26,8 +26,8 @@ knpu_oauth2_client:
type: generic
provider_class: '\League\OAuth2\Client\Provider\GenericProvider'
- client_id: '%env(settings:octopart:clientId)%'
- client_secret: '%env(settings:octopart:secret)%'
+ client_id: '%env(PROVIDER_OCTOPART_CLIENT_ID)%'
+ client_secret: '%env(PROVIDER_OCTOPART_SECRET)%'
redirect_route: 'oauth_client_check'
redirect_params: { name: 'ip_octopart_oauth' }
diff --git a/config/packages/property_info.yaml b/config/packages/property_info.yaml
deleted file mode 100644
index dd31b9da..00000000
--- a/config/packages/property_info.yaml
+++ /dev/null
@@ -1,3 +0,0 @@
-framework:
- property_info:
- with_constructor_extractor: true
diff --git a/config/packages/routing.yaml b/config/packages/routing.yaml
index 0f34f872..df5d98d2 100644
--- a/config/packages/routing.yaml
+++ b/config/packages/routing.yaml
@@ -1,5 +1,7 @@
framework:
router:
+ utf8: true
+
# Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
default_uri: '%env(DEFAULT_URI)%'
diff --git a/config/packages/security.yaml b/config/packages/security.yaml
index e7a44e0c..95f5c6b1 100644
--- a/config/packages/security.yaml
+++ b/config/packages/security.yaml
@@ -13,7 +13,7 @@ security:
firewalls:
dev:
- pattern: ^/(_(profiler|wdt)|css|images|js|\.well-known)/
+ pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
provider: app_user_provider
diff --git a/config/packages/settings.yaml b/config/packages/settings.yaml
deleted file mode 100644
index 05e21636..00000000
--- a/config/packages/settings.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-jbtronics_settings:
- default_storage_adapter: Jbtronics\SettingsBundle\Storage\ORMStorageAdapter
-
- cache:
- default_cacheable: true
-
- orm_storage:
- default_entity_class: App\Entity\SettingsEntry
\ No newline at end of file
diff --git a/config/packages/swap.yaml b/config/packages/swap.yaml
index beb41d26..2767f740 100644
--- a/config/packages/swap.yaml
+++ b/config/packages/swap.yaml
@@ -6,5 +6,5 @@ florianv_swap:
providers:
european_central_bank: ~ # European Central Bank (only works for EUR base currency)
fixer: # Fixer.io (needs an API key)
- access_key: "%env(string:default:settings:exchange_rate:fixerApiKey:INVALID)%"
+ access_key: "%env(FIXER_API_KEY)%"
#exchange_rates_api: ~
\ No newline at end of file
diff --git a/config/packages/translation.yaml b/config/packages/translation.yaml
index cbc1cd7e..7266a176 100644
--- a/config/packages/translation.yaml
+++ b/config/packages/translation.yaml
@@ -1,10 +1,11 @@
framework:
- default_locale: 'en'
+ default_locale: '%partdb.locale%'
# Just enable the locales we need for performance reasons.
enabled_locale: '%partdb.locale_menu%'
translator:
default_path: '%kernel.project_dir%/translations'
fallbacks:
+ - '%partdb.locale%'
- 'en'
providers:
# crowdin:
diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml
index 674aa317..044f7d21 100644
--- a/config/packages/twig.yaml
+++ b/config/packages/twig.yaml
@@ -6,17 +6,22 @@ twig:
'%kernel.project_dir%/assets/css': css
globals:
+ partdb_title: '%partdb.title%'
+ default_currency: '%partdb.default_currency%'
+ global_theme: '%partdb.global_theme%'
allow_email_pw_reset: '%partdb.users.email_pw_reset%'
locale_menu: '%partdb.locale_menu%'
attachment_manager: '@App\Services\Attachments\AttachmentManager'
label_profile_dropdown_helper: '@App\Services\LabelSystem\LabelProfileDropdownHelper'
error_page_admin_email: '%partdb.error_pages.admin_email%'
error_page_show_help: '%partdb.error_pages.show_help%'
+ sidebar_items: '%partdb.sidebar.items%'
sidebar_tree_updater: '@App\Services\Trees\SidebarTreeUpdater'
avatar_helper: '@App\Services\UserSystem\UserAvatarHelper'
available_themes: '%partdb.available_themes%'
saml_enabled: '%partdb.saml.enabled%'
part_preview_generator: '@App\Services\Attachments\PartPreviewGenerator'
+ img_overlay: '%partdb.show_part_image_overlay%'
when@test:
twig:
diff --git a/config/packages/uid.yaml b/config/packages/uid.yaml
new file mode 100644
index 00000000..01520944
--- /dev/null
+++ b/config/packages/uid.yaml
@@ -0,0 +1,4 @@
+framework:
+ uid:
+ default_uuid_version: 7
+ time_based_uuid_version: 7
diff --git a/config/packages/ux_turbo.yaml b/config/packages/ux_turbo.yaml
deleted file mode 100644
index c2a6a44e..00000000
--- a/config/packages/ux_turbo.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-# Enable stateless CSRF protection for forms and logins/logouts
-framework:
- csrf_protection:
- check_header: true
diff --git a/config/packages/validator.yaml b/config/packages/validator.yaml
index dd47a6ad..0201281d 100644
--- a/config/packages/validator.yaml
+++ b/config/packages/validator.yaml
@@ -1,5 +1,7 @@
framework:
validation:
+ email_validation_mode: html5
+
# Enables validator auto-mapping support.
# For instance, basic validation constraints will be inferred from Doctrine's metadata.
#auto_mapping:
diff --git a/config/packages/web_profiler.yaml b/config/packages/web_profiler.yaml
index 15112444..b9461110 100644
--- a/config/packages/web_profiler.yaml
+++ b/config/packages/web_profiler.yaml
@@ -1,14 +1,17 @@
when@dev:
web_profiler:
- toolbar:
- ajax_replace: true
+ toolbar: true
+ intercept_redirects: false
framework:
profiler:
+ only_exceptions: false
collect_serializer_data: true
when@test:
+ web_profiler:
+ toolbar: false
+ intercept_redirects: false
+
framework:
- profiler:
- collect: false
- collect_serializer_data: true
+ profiler: { collect: false }
diff --git a/config/parameters.yaml b/config/parameters.yaml
index 154fbd8a..5e647766 100644
--- a/config/parameters.yaml
+++ b/config/parameters.yaml
@@ -5,10 +5,14 @@ parameters:
######################################################################################################################
# Common
######################################################################################################################
-
- # This is used as workaround for places where we can not access the settings directly (like the 2FA application names)
- partdb.title: '%env(string:settings:customization:instanceName)%' # The title shown inside of Part-DB (e.g. in the navbar and on homepage)
+ partdb.locale: '%env(string:DEFAULT_LANG)%' # The default language to use serverwide
+ partdb.timezone: '%env(string:DEFAULT_TIMEZONE)%' # The default timezone
+ partdb.title: '%env(trim:string:INSTANCE_NAME)%' # 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.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
@@ -18,8 +22,11 @@ parameters:
# Users and Privacy
######################################################################################################################
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.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
######################################################################################################################
@@ -29,8 +36,11 @@ parameters:
######################################################################################################################
# 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.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
@@ -43,11 +53,28 @@ parameters:
######################################################################################################################
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
######################################################################################################################
partdb.demo_mode: '%env(bool:DEMO_MODE)%' # If set to true, all potentially dangerous things are disabled (like changing passwords of the own user)
+ partdb.show_part_image_overlay: '%env(bool:SHOW_PART_IMAGE_OVERLAY)%' # If set to false, the filename overlay of the part image will be disabled
# Set the themes from which the user can choose from in the settings.
# Themes commented here by default, are not really usable, because of display problems. Enable them at your own risk!
@@ -84,18 +111,30 @@ parameters:
# 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(ENFORCE_CHANGE_COMMENTS_FOR): ''
+
env(ERROR_PAGE_ADMIN_EMAIL): ''
env(ERROR_PAGE_SHOW_HELP): 1
env(DEMO_MODE): 0
+ env(BANNER): ''
env(EMAIL_SENDER_EMAIL): 'noreply@partdb.changeme'
env(EMAIL_SENDER_NAME): 'Part-DB Mailer'
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_HOSTS): '' # Trust all host names by default
@@ -103,4 +142,11 @@ parameters:
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
diff --git a/config/permissions.yaml b/config/permissions.yaml
index e5a1d65b..b8970556 100644
--- a/config/permissions.yaml
+++ b/config/permissions.yaml
@@ -265,13 +265,17 @@ perms: # Here comes a list with all Permission names (they have a perm_[name] co
# label: "perm.database.write_db_settings"
# alsoSet: ['read_db_settings', 'see_status']
- config:
- label: "perm.config"
- group: "system"
- operations:
- change_system_settings:
- label: "perm.config.change_system_settings"
- apiTokenRole: ROLE_API_ADMIN
+ #config:
+ # label: "perm.config"
+ # group: "system"
+ # operations:
+ # read_config:
+ # label: "perm.config.read_config"
+ # edit_config:
+ # label: "perm.config.edit_config"
+ # alsoSet: 'read_config'
+ # server_info:
+ # label: "perm.config.server_info"
system:
label: "perm.system"
diff --git a/config/routes/framework.yaml b/config/routes/framework.yaml
index bc1feace..0fc74bba 100644
--- a/config/routes/framework.yaml
+++ b/config/routes/framework.yaml
@@ -1,4 +1,4 @@
when@dev:
_errors:
- resource: '@FrameworkBundle/Resources/config/routing/errors.php'
+ resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
prefix: /_error
diff --git a/config/routes/web_profiler.yaml b/config/routes/web_profiler.yaml
index b3b7b4b0..8d85319f 100644
--- a/config/routes/web_profiler.yaml
+++ b/config/routes/web_profiler.yaml
@@ -1,8 +1,8 @@
when@dev:
web_profiler_wdt:
- resource: '@WebProfilerBundle/Resources/config/routing/wdt.php'
+ resource: '@WebProfilerBundle/Resources/config/routing/wdt.xml'
prefix: /_wdt
web_profiler_profiler:
- resource: '@WebProfilerBundle/Resources/config/routing/profiler.php'
+ resource: '@WebProfilerBundle/Resources/config/routing/profiler.xml'
prefix: /_profiler
diff --git a/config/services.yaml b/config/services.yaml
index 17611cea..b2342edd 100644
--- a/config/services.yaml
+++ b/config/services.yaml
@@ -17,6 +17,8 @@ services:
bool $gdpr_compliance: '%partdb.gdpr_compliance%'
bool $kernel_debug_enabled: '%kernel.debug%'
string $kernel_cache_dir: '%kernel.cache_dir%'
+ string $partdb_title: '%partdb.title%'
+ string $base_currency: '%partdb.default_currency%'
_instanceof:
App\Services\LabelSystem\PlaceholderProviders\PlaceholderProviderInterface:
@@ -29,6 +31,10 @@ services:
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/'
+ exclude:
+ - '../src/DependencyInjection/'
+ - '../src/Entity/'
+ - '../src/Kernel.php'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
@@ -70,10 +76,28 @@ services:
# Only the event classes specified here are saved to DB (set to []) to log all events
$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:
arguments:
+ $allow_attachments_downloads: '%partdb.attachments.allow_downloads%'
$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
@@ -132,6 +156,29 @@ services:
tags:
- { 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
####################################################################################################################
@@ -139,6 +186,10 @@ services:
arguments:
$demo_mode: '%partdb.demo_mode%'
+ App\EventSubscriber\UserSystem\SetUserTimezoneSubscriber:
+ arguments:
+ $default_timezone: '%partdb.timezone%'
+
App\Controller\SecurityController:
arguments:
$allow_email_pw_reset: '%partdb.users.email_pw_reset%'
@@ -152,6 +203,10 @@ services:
tags:
- { name: 'translation.extractor', alias: 'permissionExtractor'}
+ App\Services\UserSystem\UserAvatarHelper:
+ arguments:
+ $use_gravatar: '%partdb.users.use_gravatar%'
+
App\Form\Type\ThemeChoiceType:
arguments:
$available_themes: '%partdb.available_themes%'
@@ -167,6 +222,9 @@ services:
####################################################################################################################
# Table settings
####################################################################################################################
+ App\DataTables\PartsDataTable:
+ arguments:
+ $visible_columns: '%partdb.table.parts.default_columns%'
App\DataTables\Helpers\ColumnSortHelper:
shared: false # Service has a state so not share it between different tables
@@ -188,6 +246,14 @@ services:
$fontDirectory: '%kernel.project_dir%/var/dompdf/fonts/'
$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
####################################################################################################################
@@ -195,12 +261,76 @@ services:
arguments:
$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:
+ arguments:
+ $clientId: '%env(string:PROVIDER_DIGIKEY_CLIENT_ID)%'
+ $currency: '%env(string:PROVIDER_DIGIKEY_CURRENCY)%'
+ $language: '%env(string:PROVIDER_DIGIKEY_LANGUAGE)%'
+ $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:
+ arguments:
+ $clientId: '&env(string:PROVIDER_OCTOPART_CLIENT_ID)%'
+ $secret: '%env(string:PROVIDER_OCTOPART_SECRET)%'
+ $country: '%env(string:PROVIDER_OCTOPART_COUNTRY)%'
+ $currency: '%env(string:PROVIDER_OCTOPART_CURRENCY)%'
+ $search_limit: '%env(int:PROVIDER_OCTOPART_SEARCH_LIMIT)%'
+ $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
####################################################################################################################
App\State\PartDBInfoProvider:
arguments:
$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
@@ -225,6 +355,7 @@ services:
####################################################################################################################
App\Controller\RedirectController:
arguments:
+ $default_locale: '%partdb.locale%'
$enforce_index_php: '%env(bool:NO_URL_REWRITE_AVAILABLE)%'
App\Doctrine\Purger\ResetAutoIncrementPurgerFactory:
@@ -239,6 +370,14 @@ services:
arguments:
$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:
arguments:
diff --git a/docs/assets/getting_started/system_settings.png b/docs/assets/getting_started/system_settings.png
deleted file mode 100644
index 5a7d7380..00000000
Binary files a/docs/assets/getting_started/system_settings.png and /dev/null differ
diff --git a/docs/configuration.md b/docs/configuration.md
index d4b21781..b4e5efc4 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -10,7 +10,7 @@ Part-DBs behavior can be configured to your needs. There are different kinds of
user-changeable (changeable dynamically via frontend), options that can be configured by environment variables, and
options that are only configurable via Symfony config files.
-## User configruation
+## User changeable
The following things can be changed for every user and a user can change it for himself (if he has the correct permission
for it). Configuration is either possible via the user's own settings page (where you can also change the password) or via
@@ -24,34 +24,15 @@ the user admin page:
* **Preferred currency**: One of the defined currencies, in which all prices should be shown, if possible. Prices with
other currencies will be converted to the price selected here
-## System configuration (via web interface)
-
-Many common configuration options can be changed via the web interface. You can find the settings page in the sidebar under
-"System" -> "Settings". You need to have the "Change system settings" permission to access this page.
-
-If a setting is greyed out and cannot be changed, it means that this setting is currently overwritten by an environment
-variable. You can either change the environment variable to change the setting, or you can migrate the setting to the
-database, so that it can be changed via the web interface. To do this, you can use the `php bin/console settings:migrate-env-to-settings` command
-and remove the environment variable afterward.
-
## Environment variables (.env.local)
The following configuration options can only be changed by the server administrator, by either changing the server
variables, changing the `.env.local` file or setting env for your docker container. Here are just the most important
options listed, see `.env` file for the full list of possible env variables.
-Environment variables allow to overwrite settings in the web interface. This is useful, if you want to enforce certain
-settings to be unchangable by users, or if you want to configure settings in a central place in a deployed environment.
-On the settings page, you can hover over a setting to see, which environment variable can be used to overwrite it, it
-is shown as tooltip. API keys or similar sensitve data which is overwritten by env variables, are redacted on the web
-interface, so that even administrators cannot see them (only the last 2 characters and the length).
-
-For technical and security reasons some settings can only be configured via environment variables and not via the web
-interface. These settings are marked with "(env only)" in the description below.
-
### General options
-* `DATABASE_URL` (env only): Configures the database which Part-DB uses:
+* `DATABASE_URL`: Configures the database which Part-DB uses:
* For MySQL (or MariaDB) use a string in the form of `mysql://:@:/` here
(e.g. `DATABASE_URL=mysql://user:password@127.0.0.1:3306/part-db`).
* For SQLite use the following format to specify the
@@ -61,10 +42,10 @@ interface. These settings are marked with "(env only)" in the description below.
Please note that **`serverVersion=x.y`** variable is required due to dependency of Symfony framework.
-* `DATABASE_MYSQL_USE_SSL_CA` (env only): If this value is set to `1` or `true` and a MySQL connection is used, then the connection
+* `DATABASE_MYSQL_USE_SSL_CA`: If this value is set to `1` or `true` and a MySQL connection is used, then the connection
is encrypted by SSL/TLS and the server certificate is verified against the system CA certificates or the CA certificate
bundled with Part-DB. Set `DATABASE_MYSQL_SSL_VERIFY_CERT` if you want to accept all certificates.
-* `DATABASE_EMULATE_NATURAL_SORT` (default 0) (env only): If set to 1, Part-DB will emulate natural sorting, even if the database
+* `DATABASE_EMULATE_NATURAL_SORT` (default 0): If set to 1, Part-DB will emulate natural sorting, even if the database
does not support it natively. However this is much slower than the native sorting, and contain bugs or quirks, so use
it only, if you have to.
* `DEFAULT_LANG`: The default language to use server-wide (when no language is explicitly specified by a user or via
@@ -93,7 +74,7 @@ bundled with Part-DB. Set `DATABASE_MYSQL_SSL_VERIFY_CERT` if you want to accept
to specify the size in kilobytes, megabytes or gigabytes. By default `100M` (100 megabytes). Please note that this is
only the limit of Part-DB. You still need to configure the php.ini `upload_max_filesize` and `post_max_size` to allow
bigger files to be uploaded.
-* `DEFAULT_URI` (env only): The default URI base to use for the Part-DB, when no URL can be determined from the browser request.
+* `DEFAULT_URI`: The default URI base to use for the Part-DB, when no URL can be determined from the browser request.
This should be the primary URL/Domain, which is used to access Part-DB. This value is used to create correct links in
emails and other places, where the URL is needed. It is also used, when SAML is enabled.s If you are using a reverse
proxy, you should set this to the URL of the reverse proxy (e.g. `https://part-db.example.com`). **This value must end
@@ -110,14 +91,14 @@ bundled with Part-DB. Set `DATABASE_MYSQL_SSL_VERIFY_CERT` if you want to accept
* `datastructure_create`: Creation of a new datastructure (e.g. category, manufacturer, ...)
* `CHECK_FOR_UPDATES` (default `1`): Set this to 0, if you do not want Part-DB to connect to GitHub to check for new
versions, or if your server can not connect to the internet.
-* `APP_SECRET` (env only): This variable is a configuration parameter used for various security-related purposes,
+* `APP_SECRET`: This variable is a configuration parameter used for various security-related purposes,
particularly for securing and protecting various aspects of your application. It's a secret key that is used for
cryptographic operations and security measures (session management, CSRF protection, etc..). Therefore this
value should be handled as confidential data and not shared publicly.
* `SHOW_PART_IMAGE_OVERLAY`: Set to 0 to disable the part image overlay, which appears if you hover over an image in the
part image gallery
-### E-Mail settings (all env only)
+### E-Mail settings
* `MAILER_DSN`: You can configure the mail provider which should be used for email delivery (
see https://symfony.com/doc/current/components/mailer.html for full documentation). If you just want to use an SMTP
@@ -157,7 +138,7 @@ The following options are used to configure, which (and how much) data is writte
If you want to use want to revert changes or view older revisions of entities,
then `HISTORY_SAVE_CHANGED_FIELDS`, `HISTORY_SAVE_CHANGED_DATA` and `HISTORY_SAVE_REMOVED_DATA` all have to be true.
-### Error pages settings (all env only)
+### Error pages settings
* `ERROR_PAGE_ADMIN_EMAIL`: You can set an email address here, which is shown on the error page, who should be contacted
about the issue (e.g. an IT support email of your company)
@@ -172,7 +153,7 @@ then `HISTORY_SAVE_CHANGED_FIELDS`, `HISTORY_SAVE_CHANGED_DATA` and `HISTORY_SAV
All parts in the selected category and all subcategories are shown in KiCad. Set this to a higher value, if you want to show more categories in KiCad.
When you set this value to -1, all parts are shown inside a single category in KiCad.
-### SAML SSO settings (all env only)
+### SAML SSO settings
The following settings can be used to enable and configure Single-Sign on via SAML. This allows users to log in to
Part-DB without entering a username and password, but instead they are redirected to a SAML Identity Provider (IdP) and
@@ -220,26 +201,26 @@ See the [information providers]({% link usage/information_provider_system.md %})
### Other / less-used options
-* `TRUSTED_PROXIES` (env only): Set the IP addresses (or IP blocks) of trusted reverse proxies here. This is needed to get correct
+* `TRUSTED_PROXIES`: Set the IP addresses (or IP blocks) of trusted reverse proxies here. This is needed to get correct
IP information (see [here](https://symfony.com/doc/current/deployment/proxies.html) for more info).
-* `TRUSTED_HOSTS` (env only): To prevent `HTTP Host header attacks` you can set a regex containing all host names via which Part-DB
+* `TRUSTED_HOSTS`: To prevent `HTTP Host header attacks` you can set a regex containing all host names via which Part-DB
should be accessible. If accessed via the wrong hostname, an error will be shown.
-* `DEMO_MODE` (env only): Set Part-DB into demo mode, which forbids users to change their passwords and settings. Used for the demo
+* `DEMO_MODE`: Set Part-DB into demo mode, which forbids users to change their passwords and settings. Used for the demo
instance. This should not be needed for normal installations.
-* `NO_URL_REWRITE_AVAILABLE` (allowed values `true` or `false`) (env only): Set this value to true, if your webserver does not
+* `NO_URL_REWRITE_AVAILABLE` (allowed values `true` or `false`): Set this value to true, if your webserver does not
support rewrite. In this case, all URL paths will contain index.php/, which is needed then. Normally this setting does
not need to be changed.
-* `REDIRECT_TO_HTTPS` (env only): If this is set to true, all requests to http will be redirected to https. This is useful if your
+* `REDIRECT_TO_HTTPS`: If this is set to true, all requests to http will be redirected to https. This is useful if your
web server does not already do this (like the one used in the demo instance). If your web server already redirects to
https, you don't need to set this. Ensure that Part-DB is accessible via HTTPS before you enable this setting.
* `FIXER_API_KEY`: If you want to automatically retrieve exchange rates for base currencies other than euros, you have to
configure an exchange rate provider API. [Fixer.io](https://fixer.io/) is preconfigured, and you just have to register
there and set the retrieved API key in this environment variable.
-* `APP_ENV` (env only): This value should always be set to `prod` in normal use. Set it to `dev` to enable debug/development
+* `APP_ENV`: This value should always be set to `prod` in normal use. Set it to `dev` to enable debug/development
mode. (**You should not do this on a publicly accessible server, as it will leak sensitive information!**)
* `BANNER`: You can configure the text that should be shown as the banner on the homepage. Useful especially for docker
containers. In all other applications you can just change the `config/banner.md` file.
-* `DISABLE_YEAR2038_BUG_CHECK` (env only): If set to `1`, the year 2038 bug check is disabled on 32-bit systems, and dates after
+* `DISABLE_YEAR2038_BUG_CHECK`: If set to `1`, the year 2038 bug check is disabled on 32-bit systems, and dates after
2038 are no longer forbidden. However this will lead to 500 error messages when rendering dates after 2038 as all current
32-bit PHP versions can not format these dates correctly. This setting is for the case that future PHP versions will
handle this correctly on 32-bit systems. 64-bit systems are not affected by this bug, and the check is always disabled.
@@ -247,7 +228,7 @@ handle this correctly on 32-bit systems. 64-bit systems are not affected by this
## Banner
To change the banner you can find on the homepage, you can either set the `BANNER` environment variable to the text you
-want to show, or change it in the system settings webinterface. The banner is written in markdown, so you can use all
+want to show, or you can edit the `config/banner.md` file. The banner is written in markdown, so you can use all
markdown (and even some subset of HTML) syntax to format the text.
## parameters.yaml
@@ -262,6 +243,8 @@ command `bin/console cache:clear`.
The following options are available:
+* `partdb.global_theme`: The default theme to use, when no user specific theme is set. Should be one of the themes from
+ the `partdb.available_themes` config option.
* `partdb.locale_menu`: The codes of the languages, which should be shown in the language chooser menu (the one with the
user icon in the navbar). The first language in the list will be the default language.
* `partdb.gdpr_compliance`: When set to true (default value), IP addresses which are saved in the database will be
diff --git a/docs/installation/installation_guide-debian.md b/docs/installation/installation_guide-debian.md
index 312fe21e..885eea90 100644
--- a/docs/installation/installation_guide-debian.md
+++ b/docs/installation/installation_guide-debian.md
@@ -1,13 +1,13 @@
---
-title: Direct Installation on Debian 12
+title: Direct Installation on Debian 11
layout: default
parent: Installation
nav_order: 4
---
-# Part-DB installation guide for Debian 12 (Bookworm)
+# Part-DB installation guide for Debian 11 (Bullseye)
-This guide shows you how to install Part-DB directly on Debian 12 using apache2 and SQLite. This guide should work with
+This guide shows you how to install Part-DB directly on Debian 11 using apache2 and SQLite. This guide should work with
recent Ubuntu and other Debian-based distributions with little to no changes.
Depending on what you want to do, using the prebuilt docker images may be a better choice, as you don't need to install
this many dependencies. See [here]({% link installation/installation_docker.md %}) for more information on the docker
@@ -33,22 +33,35 @@ sudo apt install git curl zip ca-certificates software-properties-common apt-tra
### Install PHP and apache2
-Part-DB is written in [PHP](https://php.net) and therefore needs a PHP interpreter to run. Part-DB needs PHP 8.2 or
+Part-DB is written in [PHP](https://php.net) and therefore needs a PHP interpreter to run. Part-DB needs PHP 8.1 or
higher. However, it is recommended to use the most recent version of PHP for performance reasons and future
compatibility.
-Install PHP with required extensions and apache2:
+As Debian 11 does not ship PHP 8.1 in its default repositories, we have to add a repository for it. You can skip this
+step if your distribution is shipping a recent version of PHP or you want to use the built-in PHP version. If you are
+using Debian 12, you can skip this step, as PHP 8.1 is already included in the default repositories.
```bash
-sudo apt install apache2 php8.2 libapache2-mod-php8.2 \
- php8.2-opcache php8.2-curl php8.2-gd php8.2-mbstring \
- php8.2-xml php8.2-bcmath php8.2-intl php8.2-zip php8.2-xsl \
- php8.2-sqlite3 php8.2-mysql
+# Add sury repository for PHP 8.1
+sudo curl -sSL https://packages.sury.org/php/README.txt | sudo bash -x
+
+# Update package list
+sudo apt update && sudo apt upgrade
```
+Now you can install PHP 8.1 and the required packages (change the 8.1 in the package version according to the version you
+want to use):
+
+```bash
+sudo apt install php8.1 libapache2-mod-php8.1 php8.1-opcache php8.1-curl php8.1-gd php8.1-mbstring php8.1-xml php8.1-bcmath php8.1-intl php8.1-zip php8.1-xsl php8.1-sqlite3 php8.1-mysql
+```
+
+The apache2 webserver should be already installed with this command and configured basically.
+
### Install composer
-Part-DB uses [composer](https://getcomposer.org/) to install required PHP libraries. Install the latest version manually:
+Part-DB uses [composer](https://getcomposer.org/) to install required PHP libraries. As the version shipped in the
+repositories is pretty old, we will install it manually:
```bash
# Download composer installer script
@@ -65,9 +78,10 @@ To build the front end (the user interface) Part-DB uses [yarn](https://yarnpkg.
shipped versions are pretty old, we install new versions from the official Node.js repository:
```bash
-curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
-sudo apt install -y nodejs
-
+# Add recent node repository (nodejs 18 is supported until 2025)
+curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -
+# Install nodejs
+sudo apt install nodejs
```
We can install yarn with the following commands:
@@ -103,8 +117,8 @@ Alternatively, you can check out a specific version by running (
see [GitHub Releases page](https://github.com/Part-DB/Part-DB-server/releases) for a list of available versions):
```bash
-# This checks out the version 2.0.0
-git checkout v2.0.0
+# This checks out the version 1.5.2
+git checkout v1.5.2
```
Change ownership of the files to the apache user:
@@ -128,10 +142,11 @@ configuration:
cp .env .env.local
```
-In your `.env.local` you can configure Part-DB according to your wishes and overwrite web interface settings.
-A full list of configuration options can be found [here](../configuration.md).
+In your `.env.local` you can configure Part-DB according to your wishes. A full list of configuration options can be
+found [here](../configuration.md).
+Other configuration options like the default language or default currency can be found in `config/parameters.yaml`.
-Please check that the configured base currency matches your mainly used currency, as
+Please check that the `partdb.default_currency` value in `config/parameters.yaml` matches your mainly used currency, as
this can not be changed after creating price information.
### Install dependencies for Part-DB and build frontend
@@ -241,7 +256,6 @@ network to point to the server).
Navigate to the Part-DB web interface and login via the user icon in the top right corner. You can log in using the
username `admin` and the password you have written down earlier.
-As first steps, you should check out the system settings and check if everything is correct.
## Update Part-DB
@@ -277,7 +291,7 @@ sudo -u www-data php bin/console cache:clear
## MySQL/MariaDB database
To use a MySQL database, follow the steps from above (except the creation of the database, we will do this later).
-Debian 12 does not ship MySQL in its repositories anymore, so we use the compatible MariaDB instead:
+Debian 11 does not ship MySQL in its repositories anymore, so we use the compatible MariaDB instead:
1. Install maria-db with:
diff --git a/docs/upgrade/1_to_2.md b/docs/upgrade/1_to_2.md
deleted file mode 100644
index e063c49d..00000000
--- a/docs/upgrade/1_to_2.md
+++ /dev/null
@@ -1,88 +0,0 @@
----
-layout: default
-title: Upgrade from Part-DB 1.x to 2.x
-nav_order: 1
-has_children: false
----
-
-# Upgrade from Part-DB 1.x to 2.x
-
-Part-DB 2.0 is a major release that changes a lot of things internally, but it is still compatible with Part-DB 1.x.
-Depending on your preferences, you will have to do some changes to your Part-DB installation, this document will guide
-you through the upgrade process.
-
-## New requirements
-*If you are running Part-DB inside a docker container, you can skip this section, as the new requirements are already
-fulfilled by the official Part-DB docker image.*
-
-Part-DB 2.0 requires at least PHP 8.2 (newer versions are recommended). So if your existing Part-DB installation is still
-running PHP 8.1, you will have to upgrade your PHP version first.
-The minimum required version of node.js is now 20.0 or newer, so if you are using 18.0, you will have to upgrade it too.
-
-Most distributions should have the possibility to get backports for PHP 8.4 and modern nodejs, so you should be able to
-easily upgrade your system to the new requirements. Otherwise, you can use the official Part-DB docker image, which
-ships all required dependencies and is always up to date with the latest requirements, so that you do not have to worry
-about the requirements at all.
-
-## Changes
-* Configuration is now preferably done via a web settings interface. You can still use environment variables, these overwrite
-the settings in the web interface. Existing configuration will still work, but you should consider migriting them to the
-web interface as described below.
-* The `config/banner.md` file that could been used to customize the banner text, was removed. You can now set the banner text
- directly in the admin interface, or by setting the `BANNER` environment variable. If you want to keep your existing
- banner text, you will have to copy it from the `config/banner.md` file to the admin interface or set the `BANNER`
- environment variable.
-* The parameters `partdb.sidebar.items`, `partdb.sidebar.root_node_enable` and `partdb.sidebar.root_expanded` in `config/parameters.yaml`,
-were removed. You can configure them now directly in the admin interface.
-* Updated icon set. As fontawesome 7 is now used, some icons have changed slightly.
-
-## Upgrade installation
-
-The upgrade process works very similar to a normal (minor release) upgrade.
-
-### Direct installation
-
-**Be sure to execute the following steps as the user that owns the Part-DB files (e.g. `www-data`, or your webserver user). So prepend a `sudo -u wwww-data` where necessary.**
-
-1. Make a backup of your existing Part-DB installation, including the database, data directories and the configuration files and `.env.local` file.
-The `php bin/console partdb:backup` command can help you with this.
-2. Pull the v2 version. For git installation you can do this with `git checkout v2.0.0` (or newer version)
-3. Run `composer install --no-dev -o` to update the dependencies.
-4. Run `yarn install` and `yarn build` to update the frontend assets.
-5. Rund `php bin/console doctrine:migrations:migrate` to update the database schema.
-6. Clear the cache with `php bin/console cache:clear`.
-7. Open your Part-DB instance in the browser and log in as an admin user.
-8. Go to the user or group permissions page, and give yourself (and other administrators) the right to change system settings (under "System" and "Configuration").
-9. You can now go to the settings page (under "System" and "Settings") and check if all settings are correct.
-10. Parameters which were previously set via environment variables are greyed out and cannot be changed in the web interface.
-If you want to change them, you must migrate them to the settings interface as described below.
-
-### Docker installation
-1. Make a backup of your existing Part-DB installation, including the database, data directories and the configuration files and the file where you configure the docker environment variables.
-2. Stop the existing Part-DB container with `docker compose down`
-3. Ensure that your docker compose file uses the new latest images (either `latest` or `2` tag).
-4. Pull the new images with `docker compose pull` and start the container with `docker compose up -d`
-5. If you have database automigration disabled, run `docker exec --user=www-data partdb php bin/console doctrine:migrations:migrate` to update the database schema.
-6. Open your Part-DB instance in the browser and log in as an admin user.
-7. Go to the user or group permissions page, and give yourself (and other administrators)
-the right to change system settings (under "System" and "Configuration").
-8. You can now go to the settings page (under "System" and "Settings")
-9. Parameters which were previously set via environment variables are greyed out and cannot be changed in the web interface.
-If you want to change them, you must migrate them to the settings interface as described below.
-
-## Migrate environment variable configuration to settings interface
-As described above, configuration can now be done via the web interface, and can be overwritten by environment variables, so
-that existing configuration should still work. However, if a parameter is set via an environment variable, it cannot be changed in the web interface.
-To change it, you must migrate your environment variable configuration to the new system.
-
-For this there is the new console command `settings:migrate-env-to-settings`, which reads in all environment variables used to overwrite
-settings and write them to the database, so that you can safely delete them from your environment variable configuration afterwards, without
-loosing your configuration.
-
-To run the command, execute `php bin/console settings:migrate-env-to-settings --all` as webserver user (or run `docker exec --user=www-data -it partdb php bin/console settings:migrate-env-to-settings --all` for docker containers).
-It will list you all environment variables, it found and ask you for confirmation to migrate them. Answer with `yes` to migrate them and hit enter.
-
-After the migration run successfully, the contents of your environment variables are now stored in the database and you can safely remove them from your environment variable configuration.
-Go through the environment variables listed by the command and remove them from your environment variable configuration (e.g. `.env.local` file or docker compose file), or just comment them out for now.
-
-If you want to keep some environment variables, just leave them as they are, they will still work as before, the migration command only affects the settings stored in the database.
diff --git a/docs/upgrade/index.md b/docs/upgrade/index.md
deleted file mode 100644
index 95a9cc33..00000000
--- a/docs/upgrade/index.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-layout: default
-title: Upgrade
-nav_order: 7
-has_children: true
----
-
-This section provides information on how to upgrade Part-DB to the latest version.
-This is intended for major release upgrades, where requirements or things changes significantly.
diff --git a/docs/upgrade/upgrade_legacy.md b/docs/upgrade_legacy.md
similarity index 97%
rename from docs/upgrade/upgrade_legacy.md
rename to docs/upgrade_legacy.md
index 39257a11..e1e43831 100644
--- a/docs/upgrade/upgrade_legacy.md
+++ b/docs/upgrade_legacy.md
@@ -2,7 +2,6 @@
layout: default
title: Upgrade from legacy Part-DB version (<1.0)
nav_order: 100
-redirect_from: /upgrade_legacy
---
# Upgrade from legacy Part-DB version
@@ -17,8 +16,8 @@ sections carefully before proceeding to upgrade.
## Changes
-* PHP 8.2 or higher is required now (Part-DB 0.5 required PHP 5.4+, Part-DB 0.6 PHP 7.0).
- Releases are available for Windows too, so almost everybody should be able to use PHP 8.2
+* PHP 8.1 or higher is required now (Part-DB 0.5 required PHP 5.4+, Part-DB 0.6 PHP 7.0).
+ Releases are available for Windows too, so almost everybody should be able to use PHP 8.1
* **Console access is highly recommended.** The installation of composer and frontend dependencies require console access,
also more sensitive stuff like database migration works via CLI now, so you should have console access on your server.
* Markdown/HTML is now used instead of BBCode for rich text in description and command fields.
diff --git a/docs/usage/console_commands.md b/docs/usage/console_commands.md
index 173f7b78..e5197251 100644
--- a/docs/usage/console_commands.md
+++ b/docs/usage/console_commands.md
@@ -66,8 +66,6 @@ docker exec --user=www-data partdb php bin/console cache:clear
* `partdb:migrations:import-partkeepr`: Imports a mysqldump XML dump of a PartKeepr database into Part-DB. This is only
needed for users, which want to migrate from PartKeepr to Part-DB. *All existing data in the Part-DB database is
deleted!*
-* `settings:migrate-env-to-settings`: Migrate configuration from environment variables to the settings interface.
-The value of the environment variable is copied to the settings database, so the environment variable can be removed afterwards without losing the configuration.
## Database commands
@@ -78,4 +76,4 @@ The value of the environment variable is copied to the settings database, so the
* `php bin/console partdb:attachments:download`: Download all attachments, which are not already downloaded, to the
local filesystem. This is useful to create local backups of the attachments, no matter what happens on the remote and
- also makes pictures thumbnails available for the frontend for them
+ also makes pictures thumbnails available for the frontend for them
\ No newline at end of file
diff --git a/docs/usage/getting_started.md b/docs/usage/getting_started.md
index 4b9a809a..4bb8afb9 100644
--- a/docs/usage/getting_started.md
+++ b/docs/usage/getting_started.md
@@ -12,19 +12,11 @@ Before starting, it's useful to read a bit about the [concepts of Part-DB]({% li
1. TOC
{:toc}
-## Customize system settings
+## Customize config files
-Before starting creating datastructures, you should check the system settings to ensure that they fit your needs.
-After login as an administrator, you can find the settings in the sidebar under `Tools -> System -> Settings`.
-
-
-Here you can change various settings, like the name of your Part-DB instance (which is shown in the title bar of the
-browser), the default language (which is used if no user preference is set), the default timezone (which is used to
-display times correctly), the default currency (which is used to display prices correctly), and many more.
-
-Some more fundamental settings like database connection, mail server settings, SSO, etc. are configured via environment variables.
-Environment variables also allow to overwrite various settings from the web interface.
-Environment variables can be changed by editing the `.env.local` file in a direct installation or by changing the env variables in
+Before you start creating data structures, you should configure Part-DB to your needs by changing possible configuration
+options.
+This is done either via changing the `.env.local` file in a direct installation or by changing the env variables in
your `docker-compose.yaml` file.
A list of possible configuration options can be found [here]({% link configuration.md %}).
@@ -52,8 +44,8 @@ used.
## (Optional) Customize homepage banner
-The banner which is shown on the homepage, can be customized/changed via the homepage banner setting in system settings.
-You can use markdown and (safe) HTML here, to style and customize the banner.
+The banner which is shown on the homepage, can be customized/changed by changing the `config/banner.md` file with a text
+editor. You can use markdown and (safe) HTML here, to style and customize the banner.
You can even use LaTeX-style equations by wrapping the expressions into `$` (like `$E=mc^2$`, which is rendered inline:
$E=mc^2$) or `$$` (like `$$E=mc^2$$`) which will be rendered as a block, like so: $$E=mc^2$$
@@ -210,4 +202,4 @@ later.
You can choose from your created datastructures to add manufacturer information, supplier information, etc. to the part.
You can also create new datastructures on the fly, if you want to add additional information to the part, by typing the
name of the new datastructure in the field and select the "New ..." option in the dropdown menu. See [tips]({% link
-usage/tips_tricks.md %}) for more information.
+usage/tips_tricks.md %}) for more information.
\ No newline at end of file
diff --git a/docs/usage/import_export.md b/docs/usage/import_export.md
index 0534221f..e43936cc 100644
--- a/docs/usage/import_export.md
+++ b/docs/usage/import_export.md
@@ -20,7 +20,7 @@ Part-DB. Data can also be exported from Part-DB into various formats.
> individually in the permissions settings.
If you want to import data from PartKeepr you might want to look into the [PartKeepr migration guide]({% link
-upgrade/upgrade_legacy.md %}).
+upgrade_legacy.md %}).
### Import parts
@@ -158,4 +158,4 @@ information, this can lead to very large export files.
You can export parts in all part tables. Select the parts you want via the checkbox in the table line and select the
export format and level in the appearing menu.
-See the section about exporting data structures for more information about the export formats and levels.
+See the section about exporting data structures for more information about the export formats and levels.
\ No newline at end of file
diff --git a/docs/usage/information_provider_system.md b/docs/usage/information_provider_system.md
index 953db409..8de83a8e 100644
--- a/docs/usage/information_provider_system.md
+++ b/docs/usage/information_provider_system.md
@@ -80,11 +80,6 @@ Normally the providers utilize an API of a service, and you need to create an ac
Also, there are limits on how many requests you can do per day or month, depending on the provider and your contract
with them.
-Data providers can be either configured in the system settings (in the info provider tab) or on the settings page which is
-reachable via the cogwheel symbol next to the provider in the provider list. It is also possible to configure them via
-environment variables. See below for the available configuration options. API keys configured via environment variables
-are redacted in the settings interface.
-
The following providers are currently available and shipped with Part-DB:
(All trademarks are property of their respective owners. Part-DB is not affiliated with any of the companies.)
diff --git a/docs/usage/tips_tricks.md b/docs/usage/tips_tricks.md
index 6eda718d..d033cbe8 100644
--- a/docs/usage/tips_tricks.md
+++ b/docs/usage/tips_tricks.md
@@ -95,9 +95,4 @@ It is only be shown to users which has the `Show available Part-DB updates` perm
For the notification to work, Part-DB queries the GitHub API every 2 days to check for new releases. No data is sent to
GitHub besides the metadata required for the connection (so the public IP address of your computer running Part-DB).
If you don't want Part-DB to query the GitHub API, or if your server can not reach the internet, you can disable the
-update notifications by setting the `CHECK_FOR_UPDATES` option to `false`.
-
-## Internet access via proxy
-If you server running Part-DB does not have direct access to the internet, but has to use a proxy server, you can configure
-the proxy settings in the `.env.local` file (or docker env config). You can set the `HTTP_PROXY` and `HTTPS_PROXY` environment
-variables to the URL of your proxy server. If your proxy server requires authentication, you can include the username and password in the URL.
+update notifications by setting the `CHECK_FOR_UPDATES` option to `false`.
\ No newline at end of file
diff --git a/migrations/Version20221114193325.php b/migrations/Version20221114193325.php
index bc2a97fa..9766ccf3 100644
--- a/migrations/Version20221114193325.php
+++ b/migrations/Version20221114193325.php
@@ -4,15 +4,18 @@ declare(strict_types=1);
namespace DoctrineMigrations;
-use App\Doctrine\Migration\ContainerAwareMigrationInterface;
use App\Migration\AbstractMultiPlatformMigration;
use App\Migration\WithPermPresetsTrait;
use App\Services\UserSystem\PermissionPresetsHelper;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Schema\Schema;
use Psr\Log\LoggerInterface;
+use Symfony\Component\DependencyInjection\ContainerAwareInterface;
-final class Version20221114193325 extends AbstractMultiPlatformMigration implements ContainerAwareMigrationInterface
+/**
+ * Auto-generated Migration: Please modify to your needs!
+ */
+final class Version20221114193325 extends AbstractMultiPlatformMigration implements ContainerAwareInterface
{
use WithPermPresetsTrait;
diff --git a/migrations/Version20240606203053.php b/migrations/Version20240606203053.php
index 1c7d2bf9..83370ad6 100644
--- a/migrations/Version20240606203053.php
+++ b/migrations/Version20240606203053.php
@@ -4,16 +4,16 @@ declare(strict_types=1);
namespace DoctrineMigrations;
-use App\Doctrine\Migration\ContainerAwareMigrationInterface;
use App\Migration\AbstractMultiPlatformMigration;
use App\Migration\WithPermPresetsTrait;
use App\Services\UserSystem\PermissionPresetsHelper;
use Doctrine\DBAL\Schema\Schema;
+use Symfony\Component\DependencyInjection\ContainerAwareInterface;
/**
* Auto-generated Migration: Please modify to your needs!
*/
-final class Version20240606203053 extends AbstractMultiPlatformMigration implements ContainerAwareMigrationInterface
+final class Version20240606203053 extends AbstractMultiPlatformMigration implements ContainerAwareInterface
{
use WithPermPresetsTrait;
diff --git a/migrations/Version20250706201121.php b/migrations/Version20250706201121.php
deleted file mode 100644
index b7563978..00000000
--- a/migrations/Version20250706201121.php
+++ /dev/null
@@ -1,49 +0,0 @@
-addSql('CREATE TABLE settings_entry (`key` VARCHAR(255) NOT NULL, `data` JSON DEFAULT NULL, id INT AUTO_INCREMENT NOT NULL, UNIQUE INDEX UNIQ_93F8DB394E645A7E (`key`), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci`');
-
- }
-
- public function mySQLDown(Schema $schema): void
- {
- $this->addSql('DROP TABLE settings_entry');
- }
-
- public function sqLiteUp(Schema $schema): void
- {
- $this->addSql('CREATE TABLE settings_entry ("key" VARCHAR(255) NOT NULL, "data" CLOB DEFAULT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)');
- $this->addSql('CREATE UNIQUE INDEX UNIQ_93F8DB39F48571EB ON settings_entry ("key")');
- }
-
- public function sqLiteDown(Schema $schema): void
- {
- $this->addSql('DROP TABLE settings_entry');
- }
-
- public function postgreSQLUp(Schema $schema): void
- {
- $this->addSql('CREATE TABLE settings_entry ("key" VARCHAR(255) NOT NULL, "data" JSON DEFAULT NULL, id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, PRIMARY KEY(id))');
- $this->addSql('CREATE UNIQUE INDEX UNIQ_93F8DB39F48571EB ON settings_entry ("key")');
- }
-
- public function postgreSQLDown(Schema $schema): void
- {
- $this->addSql('DROP TABLE settings_entry');
- }
-}
diff --git a/migrations/Version20250813214628.php b/migrations/Version20250813214628.php
deleted file mode 100644
index 5b9350b2..00000000
--- a/migrations/Version20250813214628.php
+++ /dev/null
@@ -1,75 +0,0 @@
-connection;
- $rows = $connection->fetchAllAssociative('SELECT id, transports, other_ui FROM webauthn_keys');
-
- foreach ($rows as $row) {
- $id = $row['id'];
- $new_transports = json_encode(unserialize($row['transports'], ['allowed_classes' => false]),
- JSON_THROW_ON_ERROR);
- $new_other_ui = json_encode(unserialize($row['other_ui'], ['allowed_classes' => false]),
- JSON_THROW_ON_ERROR);
-
- $connection->executeStatement(
- 'UPDATE webauthn_keys SET transports = :transports, other_ui = :other_ui WHERE id = :id',
- [
- 'transports' => $new_transports,
- 'other_ui' => $new_other_ui,
- 'id' => $id,
- ]
- );
- }
- }
-
- public function mySQLUp(Schema $schema): void
- {
- $this->convertArrayToJson();
- $this->addSql('ALTER TABLE webauthn_keys CHANGE transports transports JSON NOT NULL, CHANGE other_ui other_ui JSON DEFAULT NULL');
- }
-
- public function mySQLDown(Schema $schema): void
- {
- $this->addSql('ALTER TABLE webauthn_keys CHANGE transports transports LONGTEXT NOT NULL, CHANGE other_ui other_ui LONGTEXT DEFAULT NULL');
- }
-
- public function sqLiteUp(Schema $schema): void
- {
- //As there is no JSON type in SQLite, we only need to convert the data.
- $this->convertArrayToJson();
- }
-
- public function sqLiteDown(Schema $schema): void
- {
- //Nothing to do here, as SQLite does not support JSON type and we are not changing the column type.
- }
-
- public function postgreSQLUp(Schema $schema): void
- {
- $this->convertArrayToJson();
- $this->addSql('ALTER TABLE webauthn_keys ALTER transports TYPE JSON USING transports::JSON');
- $this->addSql('ALTER TABLE webauthn_keys ALTER other_ui TYPE JSON USING other_ui::JSON');
- }
-
- public function postgreSQLDown(Schema $schema): void
- {
- $this->addSql('ALTER TABLE webauthn_keys ALTER transports TYPE TEXT');
- $this->addSql('ALTER TABLE webauthn_keys ALTER other_ui TYPE TEXT');
- }
-}
diff --git a/package.json b/package.json
index 1080a74c..1b00611a 100644
--- a/package.json
+++ b/package.json
@@ -2,12 +2,11 @@
"devDependencies": {
"@babel/core": "^7.19.6",
"@babel/preset-env": "^7.19.4",
- "@fortawesome/fontawesome-free": "^7.0.0",
+ "@fortawesome/fontawesome-free": "^6.1.1",
"@hotwired/stimulus": "^3.0.0",
"@hotwired/turbo": "^8.0.1",
"@popperjs/core": "^2.10.2",
- "@symfony/stimulus-bridge": "^4.0.0",
- "@symfony/ux-toggle-password": "file:vendor/symfony/ux-toggle-password/assets",
+ "@symfony/stimulus-bridge": "^3.2.0",
"@symfony/ux-translator": "file:vendor/symfony/ux-translator/assets",
"@symfony/ux-turbo": "file:vendor/symfony/ux-turbo/assets",
"@symfony/webpack-encore": "^5.0.0",
@@ -30,28 +29,54 @@
"watch": "encore dev --watch",
"build": "encore production --progress"
},
- "engines": {
- "node": ">=20.0.0"
- },
"dependencies": {
"@algolia/autocomplete-js": "^1.17.0",
"@algolia/autocomplete-plugin-recent-searches": "^1.17.0",
"@algolia/autocomplete-theme-classic": "^1.17.0",
+ "@ckeditor/ckeditor5-alignment": "^44.0.0",
+ "@ckeditor/ckeditor5-autoformat": "^44.0.0",
+ "@ckeditor/ckeditor5-basic-styles": "^44.0.0",
+ "@ckeditor/ckeditor5-block-quote": "^44.0.0",
+ "@ckeditor/ckeditor5-code-block": "^44.0.0",
"@ckeditor/ckeditor5-dev-translations": "^43.0.1",
- "@ckeditor/ckeditor5-dev-utils": "^43.0.1",
+ "@ckeditor/ckeditor5-dev-utils": "43.0.*",
+ "@ckeditor/ckeditor5-editor-classic": "^44.0.0",
+ "@ckeditor/ckeditor5-essentials": "^44.0.0",
+ "@ckeditor/ckeditor5-find-and-replace": "^44.0.0",
+ "@ckeditor/ckeditor5-font": "^44.0.0",
+ "@ckeditor/ckeditor5-heading": "^44.0.0",
+ "@ckeditor/ckeditor5-highlight": "^44.0.0",
+ "@ckeditor/ckeditor5-horizontal-line": "^44.0.0",
+ "@ckeditor/ckeditor5-html-embed": "^44.0.0",
+ "@ckeditor/ckeditor5-html-support": "^44.0.0",
+ "@ckeditor/ckeditor5-image": "^44.0.0",
+ "@ckeditor/ckeditor5-indent": "^44.0.0",
+ "@ckeditor/ckeditor5-link": "^44.0.0",
+ "@ckeditor/ckeditor5-list": "^44.0.0",
+ "@ckeditor/ckeditor5-markdown-gfm": "^44.0.0",
+ "@ckeditor/ckeditor5-media-embed": "^44.0.0",
+ "@ckeditor/ckeditor5-paragraph": "^44.0.0",
+ "@ckeditor/ckeditor5-paste-from-office": "^44.0.0",
+ "@ckeditor/ckeditor5-remove-format": "^44.0.0",
+ "@ckeditor/ckeditor5-source-editing": "^44.0.0",
+ "@ckeditor/ckeditor5-special-characters": "^44.0.0",
+ "@ckeditor/ckeditor5-table": "^44.0.0",
+ "@ckeditor/ckeditor5-theme-lark": "^44.0.0",
+ "@ckeditor/ckeditor5-upload": "^44.0.0",
+ "@ckeditor/ckeditor5-watchdog": "^44.0.0",
+ "@ckeditor/ckeditor5-word-count": "^44.0.0",
"@jbtronics/bs-treeview": "^1.0.1",
- "@part-db/html5-qrcode": "^4.0.0",
+ "@part-db/html5-qrcode": "^3.1.0",
"@zxcvbn-ts/core": "^3.0.2",
"@zxcvbn-ts/language-common": "^3.0.3",
"@zxcvbn-ts/language-de": "^3.0.1",
"@zxcvbn-ts/language-en": "^3.0.1",
"@zxcvbn-ts/language-fr": "^3.0.1",
"@zxcvbn-ts/language-ja": "^3.0.1",
- "barcode-detector": "^3.0.5",
+ "barcode-detector": "^2.3.1",
"bootbox": "^6.0.0",
"bootswatch": "^5.1.3",
"bs-custom-file-input": "^1.3.4",
- "ckeditor5": "^46.0.0",
"clipboard": "^2.0.4",
"compression-webpack-plugin": "^11.1.0",
"datatables.net": "^2.0.0",
@@ -60,13 +85,14 @@
"datatables.net-colreorder-bs5": "^2.0.0",
"datatables.net-fixedheader-bs5": "^4.0.0",
"datatables.net-responsive-bs5": "^3.0.0",
- "datatables.net-select-bs5": "^3.0.1",
+ "datatables.net-select-bs5": "^2.0.0",
"dompurify": "^3.0.3",
+ "emoji.json": "^15.0.0",
"exports-loader": "^5.0.0",
"json-formatter-js": "^2.3.4",
"jszip": "^3.2.0",
"katex": "^0.16.0",
- "marked": "^16.1.1",
+ "marked": "^15.0.4",
"marked-gfm-heading-id": "^4.1.1",
"marked-mangle": "^1.0.1",
"pdfmake": "^0.2.2",
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 4a37b420..7ee7596f 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,42 +1,36 @@
-
-
-
-
-
-
-
-
-
-
-
-
- src
-
-
+
+
+
+
+
+
+
+
+
+
+
+ src
+
+
-
-
- tests
-
-
-
-
-
-
-
-
-
+
+
+ tests
+
+
+
+
+
+
+
+
diff --git a/public/.htaccess b/public/.htaccess
index a13baeee..bfaab5de 100644
--- a/public/.htaccess
+++ b/public/.htaccess
@@ -86,7 +86,7 @@ DirectoryIndex index.php
# - use Apache >= 2.3.9 and replace all L flags by END flags and remove the
# following RewriteCond (best solution)
RewriteCond %{ENV:REDIRECT_STATUS} =""
- RewriteRule ^index\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=308,L]
+ RewriteRule ^index\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L]
# If the requested filename exists, simply serve it.
# We only want to let Apache serve files and not directories.
diff --git a/rector.php b/rector.php
index 936b447e..40eee9f7 100644
--- a/rector.php
+++ b/rector.php
@@ -7,7 +7,6 @@ use Rector\CodingStyle\Rector\FuncCall\CountArrayToEmptyArrayComparisonRector;
use Rector\Config\RectorConfig;
use Rector\Doctrine\Set\DoctrineSetList;
use Rector\PHPUnit\CodeQuality\Rector\Class_\PreferPHPUnitThisCallRector;
-use Rector\PHPUnit\CodeQuality\Rector\MethodCall\AssertEmptyNullableObjectToAssertInstanceofRector;
use Rector\PHPUnit\Set\PHPUnitSetList;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;
@@ -17,61 +16,6 @@ use Rector\Symfony\CodeQuality\Rector\MethodCall\LiteralGetToRequestClassConstan
use Rector\Symfony\Set\SymfonySetList;
use Rector\TypeDeclaration\Rector\StmtsAwareInterface\DeclareStrictTypesRector;
-return RectorConfig::configure()
- ->withComposerBased(phpunit: true)
-
- ->withSymfonyContainerPhp(__DIR__ . '/tests/symfony-container.php')
- ->withSymfonyContainerXml(__DIR__ . '/var/cache/dev/App_KernelDevDebugContainer.xml')
-
- ->withImportNames(importShortClasses: false)
- ->withPaths([
- __DIR__ . '/config',
- __DIR__ . '/public',
- __DIR__ . '/src',
- __DIR__ . '/tests',
- ])
-
- ->withSets([
- PHPUnitSetList::ANNOTATIONS_TO_ATTRIBUTES,
- PHPUnitSetList::PHPUNIT_90,
- PHPUnitSetList::PHPUNIT_110,
- PHPUnitSetList::PHPUNIT_CODE_QUALITY,
-
-
- ])
-
- ->withRules([
- DeclareStrictTypesRector::class
- ])
-
- ->withSkip([
- //Leave our AssertNull tests alone
- AssertEmptyNullableObjectToAssertInstanceofRector::class,
-
-
- CountArrayToEmptyArrayComparisonRector::class,
- //Leave our !== null checks alone
- FlipTypeControlToUseExclusiveTypeRector::class,
- //Leave our PartList TableAction alone
- ActionSuffixRemoverRector::class,
- //We declare event listeners via attributes, therefore no need to migrate them to subscribers
- EventListenerToEventSubscriberRector::class,
- PreferPHPUnitThisCallRector::class,
- //Do not replace 'GET' with class constant,
- LiteralGetToRequestClassConstantRector::class,
- ])
-
- //Do not apply rules to Symfony own files
- ->withSkip([
- __DIR__ . '/public/index.php',
- __DIR__ . '/src/Kernel.php',
- __DIR__ . '/config/preload.php',
- __DIR__ . '/config/bundles.php',
- ])
-
- ;
-
-/*
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->symfonyContainerXml(__DIR__ . '/var/cache/dev/App_KernelDevDebugContainer.xml');
$rectorConfig->symfonyContainerPhp(__DIR__ . '/tests/symfony-container.php');
@@ -135,4 +79,3 @@ return static function (RectorConfig $rectorConfig): void {
__DIR__ . '/config/bundles.php',
]);
};
-*/
diff --git a/src/ApiPlatform/DocumentedAPIProperties/PropertyMetadataFactory.php b/src/ApiPlatform/DocumentedAPIProperties/PropertyMetadataFactory.php
index 2ffb9179..49e9a031 100644
--- a/src/ApiPlatform/DocumentedAPIProperties/PropertyMetadataFactory.php
+++ b/src/ApiPlatform/DocumentedAPIProperties/PropertyMetadataFactory.php
@@ -70,4 +70,4 @@ class PropertyMetadataFactory implements PropertyMetadataFactoryInterface
return $metadata;
}
-}
+}
\ No newline at end of file
diff --git a/src/Command/CheckRequirementsCommand.php b/src/Command/CheckRequirementsCommand.php
index f9080c42..5e15e8e2 100644
--- a/src/Command/CheckRequirementsCommand.php
+++ b/src/Command/CheckRequirementsCommand.php
@@ -69,8 +69,8 @@ class CheckRequirementsCommand extends Command
if ($io->isVerbose()) {
$io->comment('Checking PHP version...');
}
- //We recommend PHP 8.2, but 8.2 is the minimum
- if (PHP_VERSION_ID < 80400) {
+ //We recommend PHP 8.2, but 8.1 is the minimum
+ if (PHP_VERSION_ID < 80200) {
$io->warning('You are using PHP '. PHP_VERSION .'. This will work, but a newer version is recommended.');
} elseif (!$only_issues) {
$io->success('PHP version is sufficient.');
@@ -84,7 +84,7 @@ class CheckRequirementsCommand extends Command
$io->success('You are using a 64-bit system.');
}
} else {
- $io->warning(' areYou using a system with an unknown bit size. That is interesting xD');
+ $io->warning('You are using a system with an unknown bit size. That is interesting xD');
}
//Check if opcache is enabled
diff --git a/src/Command/Currencies/UpdateExchangeRatesCommand.php b/src/Command/Currencies/UpdateExchangeRatesCommand.php
index 2c1f5f92..0f3eb11f 100644
--- a/src/Command/Currencies/UpdateExchangeRatesCommand.php
+++ b/src/Command/Currencies/UpdateExchangeRatesCommand.php
@@ -22,7 +22,6 @@ declare(strict_types=1);
namespace App\Command\Currencies;
-use App\Settings\SystemSettings\LocalizationSettings;
use Symfony\Component\Console\Attribute\AsCommand;
use App\Entity\PriceInformations\Currency;
use App\Services\Tools\ExchangeRateUpdater;
@@ -40,7 +39,7 @@ use function strlen;
#[AsCommand('partdb:currencies:update-exchange-rates|partdb:update-exchange-rates|app:update-exchange-rates', 'Updates the currency exchange rates.')]
class UpdateExchangeRatesCommand extends Command
{
- public function __construct(protected EntityManagerInterface $em, protected ExchangeRateUpdater $exchangeRateUpdater, private readonly LocalizationSettings $localizationSettings)
+ public function __construct(protected string $base_current, protected EntityManagerInterface $em, protected ExchangeRateUpdater $exchangeRateUpdater)
{
parent::__construct();
}
@@ -55,13 +54,13 @@ class UpdateExchangeRatesCommand extends Command
$io = new SymfonyStyle($input, $output);
//Check for valid base current
- if (3 !== strlen($this->localizationSettings->baseCurrency)) {
+ if (3 !== strlen($this->base_current)) {
$io->error('Chosen Base current is not valid. Check your settings!');
return Command::FAILURE;
}
- $io->note('Update currency exchange rates with base currency: '.$this->localizationSettings->baseCurrency);
+ $io->note('Update currency exchange rates with base currency: '.$this->base_current);
//Check what currencies we need to update:
$iso_code = $input->getArgument('iso_code');
diff --git a/src/Command/Migrations/ImportPartKeeprCommand.php b/src/Command/Migrations/ImportPartKeeprCommand.php
index aee71afe..98272440 100644
--- a/src/Command/Migrations/ImportPartKeeprCommand.php
+++ b/src/Command/Migrations/ImportPartKeeprCommand.php
@@ -44,7 +44,7 @@ class ImportPartKeeprCommand extends Command
protected PKDatastructureImporter $datastructureImporter, protected PKPartImporter $partImporter, protected PKImportHelper $importHelper,
protected PKOptionalImporter $optionalImporter)
{
- parent::__construct();
+ parent::__construct(self::$defaultName);
}
protected function configure(): void
diff --git a/src/Command/User/UpgradePermissionsSchemaCommand.php b/src/Command/User/UpgradePermissionsSchemaCommand.php
index a53e21a0..4947fd5c 100644
--- a/src/Command/User/UpgradePermissionsSchemaCommand.php
+++ b/src/Command/User/UpgradePermissionsSchemaCommand.php
@@ -39,7 +39,14 @@ final class UpgradePermissionsSchemaCommand extends Command
{
public function __construct(private readonly PermissionSchemaUpdater $permissionSchemaUpdater, private readonly EntityManagerInterface $em, private readonly EventCommentHelper $eventCommentHelper)
{
- parent::__construct();
+ parent::__construct(self::$defaultName);
+ }
+
+ protected function configure(): void
+ {
+ $this
+ ->setDescription(self::$defaultDescription)
+ ;
}
protected function execute(InputInterface $input, OutputInterface $output): int
diff --git a/src/Command/User/UsersPermissionsCommand.php b/src/Command/User/UsersPermissionsCommand.php
index 27382371..6408e9c9 100644
--- a/src/Command/User/UsersPermissionsCommand.php
+++ b/src/Command/User/UsersPermissionsCommand.php
@@ -46,7 +46,7 @@ class UsersPermissionsCommand extends Command
{
$this->userRepository = $entityManager->getRepository(User::class);
- parent::__construct();
+ parent::__construct(self::$defaultName);
}
protected function configure(): void
diff --git a/src/Controller/AttachmentFileController.php b/src/Controller/AttachmentFileController.php
index 7917e97f..d8bd8d87 100644
--- a/src/Controller/AttachmentFileController.php
+++ b/src/Controller/AttachmentFileController.php
@@ -28,7 +28,6 @@ use App\Entity\Attachments\Attachment;
use App\Form\Filters\AttachmentFilterType;
use App\Services\Attachments\AttachmentManager;
use App\Services\Trees\NodesListBuilder;
-use App\Settings\BehaviorSettings\TableSettings;
use Omines\DataTablesBundle\DataTableFactory;
use RuntimeException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@@ -99,8 +98,7 @@ class AttachmentFileController extends AbstractController
}
#[Route(path: '/attachment/list', name: 'attachment_list')]
- public function attachmentsTable(Request $request, DataTableFactory $dataTableFactory, NodesListBuilder $nodesListBuilder,
- TableSettings $tableSettings): Response
+ public function attachmentsTable(Request $request, DataTableFactory $dataTableFactory, NodesListBuilder $nodesListBuilder): Response
{
$this->denyAccessUnlessGranted('@attachments.list_attachments');
@@ -112,7 +110,7 @@ class AttachmentFileController extends AbstractController
$filterForm->handleRequest($formRequest);
- $table = $dataTableFactory->createFromType(AttachmentDataTable::class, ['filter' => $filter], ['pageLength' => $tableSettings->fullDefaultPageSize])
+ $table = $dataTableFactory->createFromType(AttachmentDataTable::class, ['filter' => $filter])
->handleRequest($request);
if ($table->isCallback()) {
diff --git a/src/Controller/InfoProviderController.php b/src/Controller/InfoProviderController.php
index a6e886e6..a6ce3f1b 100644
--- a/src/Controller/InfoProviderController.php
+++ b/src/Controller/InfoProviderController.php
@@ -29,14 +29,10 @@ use App\Form\InfoProviderSystem\PartSearchType;
use App\Services\InfoProviderSystem\ExistingPartFinder;
use App\Services\InfoProviderSystem\PartInfoRetriever;
use App\Services\InfoProviderSystem\ProviderRegistry;
-use App\Settings\AppSettings;
use Doctrine\ORM\EntityManagerInterface;
-use Jbtronics\SettingsBundle\Form\SettingsFormFactoryInterface;
-use Jbtronics\SettingsBundle\Manager\SettingsManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bridge\Doctrine\Attribute\MapEntity;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
-use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpClient\Exception\ClientException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -50,9 +46,7 @@ class InfoProviderController extends AbstractController
public function __construct(private readonly ProviderRegistry $providerRegistry,
private readonly PartInfoRetriever $infoRetriever,
- private readonly ExistingPartFinder $existingPartFinder,
- private readonly SettingsManagerInterface $settingsManager,
- private readonly SettingsFormFactoryInterface $settingsFormFactory
+ private readonly ExistingPartFinder $existingPartFinder
)
{
@@ -69,48 +63,6 @@ class InfoProviderController extends AbstractController
]);
}
- #[Route('/provider/{provider}/settings', name: 'info_providers_provider_settings')]
- public function providerSettings(string $provider, Request $request): Response
- {
- $this->denyAccessUnlessGranted('@config.change_system_settings');
- $this->denyAccessUnlessGranted('@info_providers.create_parts');
-
- $providerInstance = $this->providerRegistry->getProviderByKey($provider);
- $settingsClass = $providerInstance->getProviderInfo()['settings_class'] ?? throw new \LogicException('Provider ' . $provider . ' does not have a settings class defined');
-
- //Create a clone of the settings object
- $settings = $this->settingsManager->createTemporaryCopy($settingsClass);
-
- //Create a form builder for the settings object
- $builder = $this->settingsFormFactory->createSettingsFormBuilder($settings);
-
- //Add a submit button to the form
- $builder->add('submit', 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);
-
- $this->addFlash('success', t('settings.flash.saved'));
- }
-
- if ($form->isSubmitted() && !$form->isValid()) {
- $this->addFlash('error', t('settings.flash.invalid'));
- }
-
- //Render the form
- return $this->render('info_providers/settings/provider_settings.html.twig', [
- 'form' => $form,
- 'info_provider_key' => $provider,
- 'info_provider_info' => $providerInstance->getProviderInfo(),
- ]);
- }
-
#[Route('/search', name: 'info_providers_search')]
#[Route('/update/{target}', name: 'info_providers_update_part_search')]
public function search(Request $request, #[MapEntity(id: 'target')] ?Part $update_target, LoggerInterface $exceptionLogger): Response
@@ -176,4 +128,4 @@ class InfoProviderController extends AbstractController
'update_target' => $update_target
]);
}
-}
+}
\ No newline at end of file
diff --git a/src/Controller/LogController.php b/src/Controller/LogController.php
index 8aed44e8..a849539d 100644
--- a/src/Controller/LogController.php
+++ b/src/Controller/LogController.php
@@ -38,7 +38,6 @@ use App\Services\LogSystem\LogEntryExtraFormatter;
use App\Services\LogSystem\LogLevelHelper;
use App\Services\LogSystem\LogTargetHelper;
use App\Services\LogSystem\TimeTravel;
-use App\Settings\BehaviorSettings\TableSettings;
use Doctrine\ORM\EntityManagerInterface;
use InvalidArgumentException;
use Omines\DataTablesBundle\DataTableFactory;
@@ -59,7 +58,7 @@ class LogController extends AbstractController
}
#[Route(path: '/', name: 'log_view')]
- public function showLogs(Request $request, DataTableFactory $dataTable, TableSettings $tableSettings): Response
+ public function showLogs(Request $request, DataTableFactory $dataTable): Response
{
$this->denyAccessUnlessGranted('@system.show_logs');
@@ -73,7 +72,7 @@ class LogController extends AbstractController
$table = $dataTable->createFromType(LogDataTable::class, [
'filter' => $filter,
- ], ['pageLength' => $tableSettings->fullDefaultPageSize])
+ ])
->handleRequest($request);
if ($table->isCallback()) {
diff --git a/src/Controller/PartListsController.php b/src/Controller/PartListsController.php
index f6836ddc..48995228 100644
--- a/src/Controller/PartListsController.php
+++ b/src/Controller/PartListsController.php
@@ -36,7 +36,6 @@ use App\Exceptions\InvalidRegexException;
use App\Form\Filters\PartFilterType;
use App\Services\Parts\PartsTableActionHandler;
use App\Services\Trees\NodesListBuilder;
-use App\Settings\BehaviorSettings\TableSettings;
use Doctrine\DBAL\Exception\DriverException;
use Doctrine\ORM\EntityManagerInterface;
use Omines\DataTablesBundle\DataTableFactory;
@@ -52,12 +51,7 @@ use function Symfony\Component\Translation\t;
class PartListsController extends AbstractController
{
- public function __construct(private readonly EntityManagerInterface $entityManager,
- private readonly NodesListBuilder $nodesListBuilder,
- private readonly DataTableFactory $dataTableFactory,
- private readonly TranslatorInterface $translator,
- private readonly TableSettings $tableSettings
- )
+ public function __construct(private readonly EntityManagerInterface $entityManager, private readonly NodesListBuilder $nodesListBuilder, private readonly DataTableFactory $dataTableFactory, private readonly TranslatorInterface $translator)
{
}
@@ -161,7 +155,11 @@ class PartListsController extends AbstractController
$filterForm->handleRequest($formRequest);
- $table = $this->dataTableFactory->createFromType(PartsDataTable::class, array_merge(['filter' => $filter], $additional_table_vars), ['pageLength' => $this->tableSettings->fullDefaultPageSize])
+ $table = $this->dataTableFactory->createFromType(
+ PartsDataTable::class,
+ array_merge(['filter' => $filter], $additional_table_vars),
+ ['lengthMenu' => PartsDataTable::LENGTH_MENU]
+ )
->handleRequest($request);
if ($table->isCallback()) {
diff --git a/src/Controller/ProjectController.php b/src/Controller/ProjectController.php
index a64c1851..761e498c 100644
--- a/src/Controller/ProjectController.php
+++ b/src/Controller/ProjectController.php
@@ -31,7 +31,6 @@ use App\Form\ProjectSystem\ProjectBuildType;
use App\Helpers\Projects\ProjectBuildRequest;
use App\Services\ImportExportSystem\BOMImporter;
use App\Services\ProjectSystem\ProjectBuildHelper;
-use App\Settings\BehaviorSettings\TableSettings;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManagerInterface;
use League\Csv\SyntaxError;
@@ -56,12 +55,11 @@ class ProjectController extends AbstractController
}
#[Route(path: '/{id}/info', name: 'project_info', requirements: ['id' => '\d+'])]
- public function info(Project $project, Request $request, ProjectBuildHelper $buildHelper, TableSettings $tableSettings): Response
+ public function info(Project $project, Request $request, ProjectBuildHelper $buildHelper): Response
{
$this->denyAccessUnlessGranted('read', $project);
- $table = $this->dataTableFactory->createFromType(ProjectBomEntriesDataTable::class, ['project' => $project],
- ['pageLength' => $tableSettings->fullDefaultPageSize])
+ $table = $this->dataTableFactory->createFromType(ProjectBomEntriesDataTable::class, ['project' => $project])
->handleRequest($request);
if ($table->isCallback()) {
diff --git a/src/Controller/RedirectController.php b/src/Controller/RedirectController.php
index a4cac3aa..65bd78f5 100644
--- a/src/Controller/RedirectController.php
+++ b/src/Controller/RedirectController.php
@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace App\Controller;
use App\Entity\UserSystem\User;
-use App\Settings\SystemSettings\LocalizationSettings;
use function function_exists;
use function in_array;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@@ -36,7 +35,7 @@ use Symfony\Contracts\Translation\TranslatorInterface;
*/
class RedirectController extends AbstractController
{
- public function __construct(private readonly LocalizationSettings $localizationSettings, protected TranslatorInterface $translator, protected bool $enforce_index_php)
+ public function __construct(protected string $default_locale, protected TranslatorInterface $translator, protected bool $enforce_index_php)
{
}
@@ -47,7 +46,7 @@ class RedirectController extends AbstractController
public function addLocalePart(Request $request): RedirectResponse
{
//By default, we use the global default locale
- $locale = $this->localizationSettings->locale;
+ $locale = $this->default_locale;
//Check if a user has set a preferred language setting:
$user = $this->getUser();
diff --git a/src/Controller/SettingsController.php b/src/Controller/SettingsController.php
deleted file mode 100644
index 3479cf84..00000000
--- a/src/Controller/SettingsController.php
+++ /dev/null
@@ -1,81 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-
-namespace App\Controller;
-
-use Symfony\Component\Form\Extension\Core\Type\SubmitType;
-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;
-
-use function Symfony\Component\Translation\t;
-
-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
- {
- $this->denyAccessUnlessGranted('@config.change_system_settings');
-
- //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', 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']);
-
- $this->addFlash('success', t('settings.flash.saved'));
- }
-
- if ($form->isSubmitted() && !$form->isValid()) {
- $this->addFlash('error', t('settings.flash.invalid'));
- }
-
- //Render the form
- return $this->render('settings/settings.html.twig', [
- 'form' => $form
- ]);
- }
-}
diff --git a/src/Controller/ToolsController.php b/src/Controller/ToolsController.php
index d78aff62..dbcb91a1 100644
--- a/src/Controller/ToolsController.php
+++ b/src/Controller/ToolsController.php
@@ -29,7 +29,6 @@ use App\Services\Doctrine\DBInfoHelper;
use App\Services\Doctrine\NatsortDebugHelper;
use App\Services\Misc\GitVersionInfo;
use App\Services\System\UpdateAvailableManager;
-use App\Settings\AppSettings;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
@@ -48,8 +47,7 @@ class ToolsController extends AbstractController
#[Route(path: '/server_infos', name: 'tools_server_infos')]
public function systemInfos(GitVersionInfo $versionInfo, DBInfoHelper $DBInfoHelper, NatsortDebugHelper $natsortDebugHelper,
- AttachmentSubmitHandler $attachmentSubmitHandler, UpdateAvailableManager $updateAvailableManager,
- AppSettings $settings): Response
+ AttachmentSubmitHandler $attachmentSubmitHandler, UpdateAvailableManager $updateAvailableManager): Response
{
$this->denyAccessUnlessGranted('@system.server_infos');
@@ -57,23 +55,23 @@ class ToolsController extends AbstractController
//Part-DB section
'git_branch' => $versionInfo->getGitBranchName(),
'git_commit' => $versionInfo->getGitCommitHash(),
- 'default_locale' => $settings->system->localization->locale,
- 'default_timezone' => $settings->system->localization->timezone,
- 'default_currency' => $settings->system->localization->baseCurrency,
- 'default_theme' => $settings->system->customization->theme,
+ 'default_locale' => $this->getParameter('partdb.locale'),
+ 'default_timezone' => $this->getParameter('partdb.timezone'),
+ 'default_currency' => $this->getParameter('partdb.default_currency'),
+ 'default_theme' => $this->getParameter('partdb.global_theme'),
'enabled_locales' => $this->getParameter('partdb.locale_menu'),
'demo_mode' => $this->getParameter('partdb.demo_mode'),
- 'use_gravatar' => $settings->system->privacy->useGravatar,
'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'),
'environment' => $this->getParameter('kernel.environment'),
'is_debug' => $this->getParameter('kernel.debug'),
'email_sender' => $this->getParameter('partdb.mail.sender_email'),
'email_sender_name' => $this->getParameter('partdb.mail.sender_name'),
- 'allow_attachments_downloads' => $settings->system->attachments->allowDownloads,
+ 'allow_attachments_downloads' => $this->getParameter('partdb.attachments.allow_downloads'),
'detailed_error_pages' => $this->getParameter('partdb.error_pages.show_help'),
'error_page_admin_email' => $this->getParameter('partdb.error_pages.admin_email'),
- 'configured_max_file_size' => $settings->system->attachments->maxFileSize,
+ 'configured_max_file_size' => $this->getParameter('partdb.attachments.max_file_size'),
'effective_max_file_size' => $attachmentSubmitHandler->getMaximumAllowedUploadSize(),
'saml_enabled' => $this->getParameter('partdb.saml.enabled'),
diff --git a/src/DataTables/Helpers/ColumnSortHelper.php b/src/DataTables/Helpers/ColumnSortHelper.php
index b7b5b567..05bd8182 100644
--- a/src/DataTables/Helpers/ColumnSortHelper.php
+++ b/src/DataTables/Helpers/ColumnSortHelper.php
@@ -72,8 +72,7 @@ class ColumnSortHelper
* Apply the visibility configuration to the given DataTable and configure the columns.
* @param DataTable $dataTable
* @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. If an array of enum values are passed,
- * their value will be used as the column name.
+ * be visible by default. If a column is not listed here, it will be hidden by default.
* @return void
*/
public function applyVisibilityAndConfigureColumns(DataTable $dataTable, string|array $visible_columns,
@@ -84,14 +83,6 @@ class ColumnSortHelper
$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 = [];
//First add all columns which visibility is not configurable
diff --git a/src/DataTables/PartsDataTable.php b/src/DataTables/PartsDataTable.php
index f0decf27..3163a38b 100644
--- a/src/DataTables/PartsDataTable.php
+++ b/src/DataTables/PartsDataTable.php
@@ -45,7 +45,6 @@ use App\Entity\Parts\PartLot;
use App\Entity\ProjectSystem\Project;
use App\Services\EntityURLGenerator;
use App\Services\Formatters\AmountFormatter;
-use App\Settings\BehaviorSettings\TableSettings;
use Doctrine\ORM\AbstractQuery;
use Doctrine\ORM\QueryBuilder;
use Omines\DataTablesBundle\Adapter\Doctrine\ORM\SearchCriteriaProvider;
@@ -66,8 +65,8 @@ final class PartsDataTable implements DataTableTypeInterface
private readonly AmountFormatter $amountFormatter,
private readonly PartDataTableHelper $partDataTableHelper,
private readonly Security $security,
+ private readonly string $visible_columns,
private readonly ColumnSortHelper $csh,
- private readonly TableSettings $tableSettings,
) {
}
@@ -247,7 +246,7 @@ final class PartsDataTable implements DataTableTypeInterface
]);
//Apply the user configured order and visibility and add the columns to the table
- $this->csh->applyVisibilityAndConfigureColumns($dataTable, $this->tableSettings->partsDefaultColumns,
+ $this->csh->applyVisibilityAndConfigureColumns($dataTable, $this->visible_columns,
"TABLE_PARTS_DEFAULT_COLUMNS");
$dataTable->addOrderBy('name')
diff --git a/src/Doctrine/Migration/ContainerAwareMigrationFactory.php b/src/Doctrine/Migration/ContainerAwareMigrationFactory.php
deleted file mode 100644
index 81565c0e..00000000
--- a/src/Doctrine/Migration/ContainerAwareMigrationFactory.php
+++ /dev/null
@@ -1,55 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-
-namespace App\Doctrine\Migration;
-
-use App\Services\UserSystem\PermissionPresetsHelper;
-use Doctrine\Migrations\AbstractMigration;
-use Doctrine\Migrations\Version\MigrationFactory;
-use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
-use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
-use Psr\Container\ContainerInterface;
-
-#[AsDecorator("doctrine.migrations.migrations_factory")]
-class ContainerAwareMigrationFactory implements MigrationFactory
-{
- public function __construct(private readonly MigrationFactory $decorated,
- //List all services that should be available in migrations here
- #[AutowireLocator([
- PermissionPresetsHelper::class
- ])]
- private readonly ContainerInterface $container)
- {
- }
-
- public function createVersion(string $migrationClassName): AbstractMigration
- {
- $migration = $this->decorated->createVersion($migrationClassName);
-
- if ($migration instanceof ContainerAwareMigrationInterface) {
- $migration->setContainer($this->container);
- }
-
- return $migration;
- }
-}
\ No newline at end of file
diff --git a/src/Doctrine/Migration/ContainerAwareMigrationInterface.php b/src/Doctrine/Migration/ContainerAwareMigrationInterface.php
deleted file mode 100644
index bd92116a..00000000
--- a/src/Doctrine/Migration/ContainerAwareMigrationInterface.php
+++ /dev/null
@@ -1,31 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-
-namespace App\Doctrine\Migration;
-
-use Psr\Container\ContainerInterface;
-
-interface ContainerAwareMigrationInterface
-{
- public function setContainer(?ContainerInterface $container = null): void;
-}
\ No newline at end of file
diff --git a/src/Doctrine/Types/ArrayType.php b/src/Doctrine/Types/ArrayType.php
new file mode 100644
index 00000000..daab9b75
--- /dev/null
+++ b/src/Doctrine/Types/ArrayType.php
@@ -0,0 +1,116 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace App\Doctrine\Types;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform;
+use Doctrine\DBAL\Types\Exception\SerializationFailed;
+use Doctrine\DBAL\Types\Type;
+use Doctrine\Deprecations\Deprecation;
+
+use function is_resource;
+use function restore_error_handler;
+use function serialize;
+use function set_error_handler;
+use function stream_get_contents;
+use function unserialize;
+
+use const E_DEPRECATED;
+use const E_USER_DEPRECATED;
+
+/**
+ * This class is taken from doctrine ORM 3.8. https://github.com/doctrine/dbal/blob/3.8.x/src/Types/ArrayType.php
+ *
+ * It was removed in doctrine ORM 4.0. However, we require it for backward compatibility with WebauthnKey.
+ * Therefore, we manually added it here as a custom type as a forward compatibility layer.
+ */
+class ArrayType extends Type
+{
+ /**
+ * {@inheritDoc}
+ */
+ public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
+ {
+ return $platform->getClobTypeDeclarationSQL($column);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): string
+ {
+ return serialize($value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function convertToPHPValue(mixed $value, AbstractPlatform $platform): mixed
+ {
+ if ($value === null) {
+ return null;
+ }
+
+ $value = is_resource($value) ? stream_get_contents($value) : $value;
+
+ set_error_handler(function (int $code, string $message): bool {
+ if ($code === E_DEPRECATED || $code === E_USER_DEPRECATED) {
+ return false;
+ }
+
+ //Change to original code. Use SerializationFailed instead of ConversionException.
+ throw new SerializationFailed("Serialization failed (Code $code): " . $message);
+ });
+
+ try {
+ //Change to original code. Use false for allowed_classes, to avoid unsafe unserialization of objects.
+ return unserialize($value, ['allowed_classes' => false]);
+ } finally {
+ restore_error_handler();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getName(): string
+ {
+ return "array";
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @deprecated
+ */
+ public function requiresSQLCommentHint(AbstractPlatform $platform): bool
+ {
+ Deprecation::triggerIfCalledFromOutside(
+ 'doctrine/dbal',
+ 'https://github.com/doctrine/dbal/pull/5509',
+ '%s is deprecated.',
+ __METHOD__,
+ );
+
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/src/Entity/Base/AbstractDBElement.php b/src/Entity/Base/AbstractDBElement.php
index 9fb5d648..871a22d0 100644
--- a/src/Entity/Base/AbstractDBElement.php
+++ b/src/Entity/Base/AbstractDBElement.php
@@ -39,7 +39,6 @@ use App\Entity\Attachments\SupplierAttachment;
use App\Entity\Attachments\UserAttachment;
use App\Entity\Parameters\AbstractParameter;
use App\Entity\Parts\Category;
-use App\Entity\PriceInformations\Pricedetail;
use App\Entity\ProjectSystem\Project;
use App\Entity\ProjectSystem\ProjectBOMEntry;
use App\Entity\Parts\Footprint;
@@ -68,7 +67,7 @@ use Symfony\Component\Serializer\Annotation\Groups;
* Every database table which are managed with this class (or a subclass of it)
* must have the table row "id"!! The ID is the unique key to identify the elements.
*/
-#[DiscriminatorMap(typeProperty: 'type', mapping: ['attachment_type' => AttachmentType::class, 'attachment' => Attachment::class, 'attachment_type_attachment' => AttachmentTypeAttachment::class, 'category_attachment' => CategoryAttachment::class, 'currency_attachment' => CurrencyAttachment::class, 'footprint_attachment' => FootprintAttachment::class, 'group_attachment' => GroupAttachment::class, 'label_attachment' => LabelAttachment::class, 'manufacturer_attachment' => ManufacturerAttachment::class, 'measurement_unit_attachment' => MeasurementUnitAttachment::class, 'part_attachment' => PartAttachment::class, 'project_attachment' => ProjectAttachment::class, 'storelocation_attachment' => StorageLocationAttachment::class, 'supplier_attachment' => SupplierAttachment::class, 'user_attachment' => UserAttachment::class, 'category' => Category::class, 'project' => Project::class, 'project_bom_entry' => ProjectBOMEntry::class, 'footprint' => Footprint::class, 'group' => Group::class, 'manufacturer' => Manufacturer::class, 'orderdetail' => Orderdetail::class, 'part' => Part::class, 'pricedetail' => Pricedetail::class, 'storelocation' => StorageLocation::class, 'part_lot' => PartLot::class, 'currency' => Currency::class, 'measurement_unit' => MeasurementUnit::class, 'parameter' => AbstractParameter::class, 'supplier' => Supplier::class, 'user' => User::class])]
+#[DiscriminatorMap(typeProperty: 'type', mapping: ['attachment_type' => AttachmentType::class, 'attachment' => Attachment::class, 'attachment_type_attachment' => AttachmentTypeAttachment::class, 'category_attachment' => CategoryAttachment::class, 'currency_attachment' => CurrencyAttachment::class, 'footprint_attachment' => FootprintAttachment::class, 'group_attachment' => GroupAttachment::class, 'label_attachment' => LabelAttachment::class, 'manufacturer_attachment' => ManufacturerAttachment::class, 'measurement_unit_attachment' => MeasurementUnitAttachment::class, 'part_attachment' => PartAttachment::class, 'project_attachment' => ProjectAttachment::class, 'storelocation_attachment' => StorageLocationAttachment::class, 'supplier_attachment' => SupplierAttachment::class, 'user_attachment' => UserAttachment::class, 'category' => Category::class, 'project' => Project::class, 'project_bom_entry' => ProjectBOMEntry::class, 'footprint' => Footprint::class, 'group' => Group::class, 'manufacturer' => Manufacturer::class, 'orderdetail' => Orderdetail::class, 'part' => Part::class, 'pricedetail' => 'App\Entity\PriceInformation\Pricedetail', 'storelocation' => StorageLocation::class, 'part_lot' => PartLot::class, 'currency' => Currency::class, 'measurement_unit' => MeasurementUnit::class, 'parameter' => AbstractParameter::class, 'supplier' => Supplier::class, 'user' => User::class])]
#[ORM\MappedSuperclass(repositoryClass: DBElementRepository::class)]
abstract class AbstractDBElement implements JsonSerializable
{
diff --git a/src/Entity/SettingsEntry.php b/src/Entity/SettingsEntry.php
deleted file mode 100644
index 488de1d1..00000000
--- a/src/Entity/SettingsEntry.php
+++ /dev/null
@@ -1,35 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-
-namespace App\Entity;
-
-use Doctrine\DBAL\Types\Types;
-use Jbtronics\SettingsBundle\Entity\AbstractSettingsORMEntry;
-use Doctrine\ORM\Mapping as ORM;
-
-#[ORM\Entity]
-class SettingsEntry extends AbstractSettingsORMEntry
-{
- #[ORM\Id, ORM\GeneratedValue, ORM\Column(type: Types::INTEGER)]
- protected int $id;
-}
\ No newline at end of file
diff --git a/src/Entity/UserSystem/User.php b/src/Entity/UserSystem/User.php
index 78f89347..b39bea4f 100644
--- a/src/Entity/UserSystem/User.php
+++ b/src/Entity/UserSystem/User.php
@@ -197,7 +197,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
/**
* @var string|null The language/locale the user prefers
*/
- #[Assert\Locale]
+ #[Assert\Language]
#[Groups(['full', 'import', 'user:read'])]
#[ORM\Column(name: 'config_language', type: Types::STRING, nullable: true)]
protected ?string $language = '';
diff --git a/src/Entity/UserSystem/WebauthnKey.php b/src/Entity/UserSystem/WebauthnKey.php
index 7d3cb7b3..b2716e07 100644
--- a/src/Entity/UserSystem/WebauthnKey.php
+++ b/src/Entity/UserSystem/WebauthnKey.php
@@ -100,19 +100,16 @@ class WebauthnKey extends BasePublicKeyCredentialSource implements TimeStampable
public static function fromRegistration(BasePublicKeyCredentialSource $registration): self
{
return new self(
- publicKeyCredentialId: $registration->publicKeyCredentialId,
- type: $registration->type,
- transports: $registration->transports,
- attestationType: $registration->attestationType,
- trustPath: $registration->trustPath,
- aaguid: $registration->aaguid,
- credentialPublicKey: $registration->credentialPublicKey,
- userHandle: $registration->userHandle,
- counter: $registration->counter,
- otherUI: $registration->otherUI,
- backupEligible: $registration->backupEligible,
- backupStatus: $registration->backupStatus,
- uvInitialized: $registration->uvInitialized,
+ $registration->getPublicKeyCredentialId(),
+ $registration->getType(),
+ $registration->getTransports(),
+ $registration->getAttestationType(),
+ $registration->getTrustPath(),
+ $registration->getAaguid(),
+ $registration->getCredentialPublicKey(),
+ $registration->getUserHandle(),
+ $registration->getCounter(),
+ $registration->getOtherUI()
);
}
}
diff --git a/src/EventListener/LogSystem/EventLoggerListener.php b/src/EventListener/LogSystem/EventLoggerListener.php
index 96c6ef51..6fe3d8dc 100644
--- a/src/EventListener/LogSystem/EventLoggerListener.php
+++ b/src/EventListener/LogSystem/EventLoggerListener.php
@@ -39,8 +39,6 @@ use App\Services\LogSystem\EventCommentHelper;
use App\Services\LogSystem\EventLogger;
use App\Services\LogSystem\EventUndoHelper;
use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener;
-use App\Settings\SystemSettings\HistorySettings;
-use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Event\OnFlushEventArgs;
use Doctrine\ORM\Event\PostFlushEventArgs;
@@ -76,15 +74,14 @@ class EventLoggerListener
];
protected const MAX_STRING_LENGTH = 2000;
+ protected bool $save_new_data;
- public function __construct(
- protected EventLogger $logger,
- protected SerializerInterface $serializer,
- protected EventCommentHelper $eventCommentHelper,
- private readonly HistorySettings $settings,
- protected PropertyAccessorInterface $propertyAccessor,
- protected EventUndoHelper $eventUndoHelper)
+ public function __construct(protected EventLogger $logger, protected SerializerInterface $serializer, protected EventCommentHelper $eventCommentHelper,
+ protected bool $save_changed_fields, protected bool $save_changed_data, protected bool $save_removed_data, bool $save_new_data,
+ 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
@@ -203,14 +200,14 @@ class EventLoggerListener
if ($this->eventUndoHelper->isUndo()) {
$log->setUndoneEvent($this->eventUndoHelper->getUndoneEvent(), $this->eventUndoHelper->getMode());
}
- if ($this->settings->saveRemovedData) {
+ if ($this->save_removed_data) {
//The 4th param is important here, as we delete the element...
$this->saveChangeSet($entity, $log, $em, true);
}
$this->logger->logFromOnFlush($log);
//Check if we have to log CollectionElementDeleted entries
- if ($this->settings->saveOldData) {
+ if ($this->save_changed_data) {
$metadata = $em->getClassMetadata($entity::class);
$mappings = $metadata->getAssociationMappings();
//Check if class is whitelisted for CollectionElementDeleted entry
@@ -246,9 +243,9 @@ class EventLoggerListener
}
$log = new ElementEditedLogEntry($entity);
- if ($this->settings->saveOldData) {
+ if ($this->save_changed_data) {
$this->saveChangeSet($entity, $log, $em);
- } elseif ($this->settings->saveChangedFields) {
+ } elseif ($this->save_changed_fields) {
$changed_fields = array_keys($uow->getEntityChangeSet($entity));
//Remove lastModified field, as this is always changed (gives us no additional info)
$changed_fields = array_diff($changed_fields, ['lastModified']);
@@ -316,7 +313,7 @@ class EventLoggerListener
$changeSet = $uow->getEntityChangeSet($entity);
$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 ($this->settings->saveNewData && $this->settings->saveOldData) { //Only useful if we save old data too
+ if ($this->save_new_data) {
$new_data = array_combine(array_keys($changeSet), array_column($changeSet, 1));
}
}
diff --git a/src/EventSubscriber/SymfonyDebugToolbarSubscriber.php b/src/EventSubscriber/SymfonyDebugToolbarSubscriber.php
new file mode 100644
index 00000000..6f17e399
--- /dev/null
+++ b/src/EventSubscriber/SymfonyDebugToolbarSubscriber.php
@@ -0,0 +1,69 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace App\EventSubscriber;
+
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpKernel\Event\ResponseEvent;
+
+/**
+ * This subscriber sets a Header in Debug mode that signals the Symfony Profiler to also update on Ajax requests.
+ */
+final class SymfonyDebugToolbarSubscriber implements EventSubscriberInterface
+{
+ public function __construct(private readonly bool $kernel_debug_enabled)
+ {
+ }
+
+ /**
+ * Returns an array of event names this subscriber wants to listen to.
+ *
+ * The array keys are event names and the value can be:
+ *
+ * * The method name to call (priority defaults to 0)
+ * * An array composed of the method name to call and the priority
+ * * An array of arrays composed of the method names to call and respective
+ * priorities, or 0 if unset
+ *
+ * For instance:
+ *
+ * * ['eventName' => 'methodName']
+ * * ['eventName' => ['methodName', $priority]]
+ * * ['eventName' => [['methodName1', $priority], ['methodName2']]]
+ *
+ * @return array The event names to listen to
+ */
+ public static function getSubscribedEvents(): array
+ {
+ return ['kernel.response' => 'onKernelResponse'];
+ }
+
+ public function onKernelResponse(ResponseEvent $event): void
+ {
+ if (!$this->kernel_debug_enabled) {
+ return;
+ }
+
+ $response = $event->getResponse();
+ $response->headers->set('Symfony-Debug-Toolbar-Replace', '1');
+ }
+}
diff --git a/src/EventSubscriber/UserSystem/SetUserTimezoneSubscriber.php b/src/EventSubscriber/UserSystem/SetUserTimezoneSubscriber.php
index 9964c618..10ecaddf 100644
--- a/src/EventSubscriber/UserSystem/SetUserTimezoneSubscriber.php
+++ b/src/EventSubscriber/UserSystem/SetUserTimezoneSubscriber.php
@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace App\EventSubscriber\UserSystem;
use App\Entity\UserSystem\User;
-use App\Settings\SystemSettings\LocalizationSettings;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
@@ -34,7 +33,7 @@ use Symfony\Component\HttpKernel\KernelEvents;
*/
final class SetUserTimezoneSubscriber implements EventSubscriberInterface
{
- public function __construct(private readonly LocalizationSettings $localizationSettings, private readonly Security $security)
+ public function __construct(private readonly string $default_timezone, private readonly Security $security)
{
}
@@ -49,8 +48,8 @@ final class SetUserTimezoneSubscriber implements EventSubscriberInterface
}
//Fill with default value if needed
- if (null === $timezone && $this->localizationSettings->timezone !== '') {
- $timezone = $this->localizationSettings->timezone;
+ if (null === $timezone && $this->default_timezone !== '') {
+ $timezone = $this->default_timezone;
}
//If timezone was configured anywhere set it, otherwise just use the one from php.ini
diff --git a/src/Form/AdminPages/BaseEntityAdminForm.php b/src/Form/AdminPages/BaseEntityAdminForm.php
index 5a4ef5bc..d1a0ffd0 100644
--- a/src/Form/AdminPages/BaseEntityAdminForm.php
+++ b/src/Form/AdminPages/BaseEntityAdminForm.php
@@ -25,7 +25,6 @@ namespace App\Form\AdminPages;
use App\Entity\PriceInformations\Currency;
use App\Entity\ProjectSystem\Project;
use App\Entity\UserSystem\Group;
-use App\Services\LogSystem\EventCommentType;
use Symfony\Bundle\SecurityBundle\Security;
use App\Entity\Base\AbstractNamedDBElement;
use App\Entity\Base\AbstractStructuralDBElement;
@@ -153,7 +152,7 @@ class BaseEntityAdminForm extends AbstractType
$builder->add('log_comment', TextType::class, [
'label' => 'edit.log_comment',
'mapped' => false,
- 'required' => $this->eventCommentNeededHelper->isCommentNeeded($is_new ? EventCommentType::DATASTRUCTURE_CREATE: EventCommentType::DATASTRUCTURE_EDIT),
+ 'required' => $this->eventCommentNeededHelper->isCommentNeeded($is_new ? 'datastructure_create': 'datastructure_edit'),
'empty_data' => null,
]);
diff --git a/src/Form/AdminPages/CurrencyAdminForm.php b/src/Form/AdminPages/CurrencyAdminForm.php
index afcf3c1f..0fab055d 100644
--- a/src/Form/AdminPages/CurrencyAdminForm.php
+++ b/src/Form/AdminPages/CurrencyAdminForm.php
@@ -22,7 +22,6 @@ declare(strict_types=1);
namespace App\Form\AdminPages;
-use App\Settings\SystemSettings\LocalizationSettings;
use Symfony\Bundle\SecurityBundle\Security;
use App\Entity\Base\AbstractNamedDBElement;
use App\Form\Type\BigDecimalMoneyType;
@@ -33,7 +32,7 @@ use Symfony\Component\Form\FormBuilderInterface;
class CurrencyAdminForm extends BaseEntityAdminForm
{
- public function __construct(Security $security, EventCommentNeededHelper $eventCommentNeededHelper, private readonly LocalizationSettings $localizationSettings)
+ public function __construct(Security $security, EventCommentNeededHelper $eventCommentNeededHelper, private readonly string $base_currency)
{
parent::__construct($security, $eventCommentNeededHelper);
}
@@ -52,7 +51,7 @@ class CurrencyAdminForm extends BaseEntityAdminForm
$builder->add('exchange_rate', BigDecimalMoneyType::class, [
'required' => false,
'label' => 'currency.edit.exchange_rate',
- 'currency' => $this->localizationSettings->baseCurrency,
+ 'currency' => $this->base_currency,
'scale' => 6,
'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity),
]);
diff --git a/src/Form/AdminPages/SupplierForm.php b/src/Form/AdminPages/SupplierForm.php
index 43ac0616..34b3b27a 100644
--- a/src/Form/AdminPages/SupplierForm.php
+++ b/src/Form/AdminPages/SupplierForm.php
@@ -22,7 +22,6 @@ declare(strict_types=1);
namespace App\Form\AdminPages;
-use App\Settings\SystemSettings\LocalizationSettings;
use Symfony\Bundle\SecurityBundle\Security;
use App\Entity\Base\AbstractNamedDBElement;
use App\Entity\PriceInformations\Currency;
@@ -33,7 +32,7 @@ use Symfony\Component\Form\FormBuilderInterface;
class SupplierForm extends CompanyForm
{
- public function __construct(Security $security, EventCommentNeededHelper $eventCommentNeededHelper, private readonly LocalizationSettings $localizationSettings)
+ public function __construct(Security $security, EventCommentNeededHelper $eventCommentNeededHelper, protected string $base_currency)
{
parent::__construct($security, $eventCommentNeededHelper);
}
@@ -54,7 +53,7 @@ class SupplierForm extends CompanyForm
$builder->add('shipping_costs', BigDecimalMoneyType::class, [
'required' => false,
- 'currency' => $this->localizationSettings->baseCurrency,
+ 'currency' => $this->base_currency,
'scale' => 3,
'label' => 'supplier.shipping_costs.label',
'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity),
diff --git a/src/Form/AttachmentFormType.php b/src/Form/AttachmentFormType.php
index eb484a58..957d692b 100644
--- a/src/Form/AttachmentFormType.php
+++ b/src/Form/AttachmentFormType.php
@@ -22,7 +22,6 @@ declare(strict_types=1);
namespace App\Form;
-use App\Settings\SystemSettings\AttachmentsSettings;
use Symfony\Bundle\SecurityBundle\Security;
use App\Entity\Attachments\Attachment;
use App\Entity\Attachments\AttachmentType;
@@ -55,7 +54,9 @@ class AttachmentFormType extends AbstractType
protected Security $security,
protected AttachmentSubmitHandler $submitHandler,
protected TranslatorInterface $translator,
- protected AttachmentsSettings $settings,
+ protected bool $allow_attachments_download,
+ protected bool $download_by_default,
+ protected string $max_file_size
) {
}
@@ -107,7 +108,7 @@ class AttachmentFormType extends AbstractType
'required' => false,
'label' => 'attachment.edit.download_url',
'mapped' => false,
- 'disabled' => !$this->settings->allowDownloads,
+ 'disabled' => !$this->allow_attachments_download,
]);
$builder->add('file', FileType::class, [
@@ -176,7 +177,7 @@ class AttachmentFormType extends AbstractType
//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
- if ($this->settings->downloadByDefault && $this->settings->allowDownloads) {
+ if ($this->download_by_default && $this->allow_attachments_download) {
$builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event): void {
$form = $event->getForm();
$attachment = $form->getData();
@@ -203,7 +204,7 @@ class AttachmentFormType extends AbstractType
{
$resolver->setDefaults([
'data_class' => Attachment::class,
- 'max_file_size' => $this->settings->maxFileSize,
+ 'max_file_size' => $this->max_file_size,
'allow_builtins' => true,
]);
}
diff --git a/src/Form/History/EnforceEventCommentTypesType.php b/src/Form/History/EnforceEventCommentTypesType.php
deleted file mode 100644
index 8bb095b9..00000000
--- a/src/Form/History/EnforceEventCommentTypesType.php
+++ /dev/null
@@ -1,49 +0,0 @@
-.
- */
-
-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' => [],
- ]);
- }
-}
\ No newline at end of file
diff --git a/src/Form/Part/PartBaseType.php b/src/Form/Part/PartBaseType.php
index 0bd3d0e3..b1d2ebea 100644
--- a/src/Form/Part/PartBaseType.php
+++ b/src/Form/Part/PartBaseType.php
@@ -40,7 +40,6 @@ use App\Form\Type\SIUnitType;
use App\Form\Type\StructuralEntityType;
use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
use App\Services\LogSystem\EventCommentNeededHelper;
-use App\Services\LogSystem\EventCommentType;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
@@ -266,7 +265,7 @@ class PartBaseType extends AbstractType
$builder->add('log_comment', TextType::class, [
'label' => 'edit.log_comment',
'mapped' => false,
- 'required' => $this->event_comment_needed_helper->isCommentNeeded($new_part ? EventCommentType::PART_CREATE : EventCommentType::PART_EDIT),
+ 'required' => $this->event_comment_needed_helper->isCommentNeeded($new_part ? 'part_create' : 'part_edit'),
'empty_data' => null,
]);
diff --git a/src/Form/SelectTypeOrderExtension.php b/src/Form/SelectTypeOrderExtension.php
deleted file mode 100644
index 7115d763..00000000
--- a/src/Form/SelectTypeOrderExtension.php
+++ /dev/null
@@ -1,60 +0,0 @@
-.
- */
-
-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): void
- {
- $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): void
- {
- //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);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Form/Type/APIKeyType.php b/src/Form/Type/APIKeyType.php
deleted file mode 100644
index 57eaea96..00000000
--- a/src/Form/Type/APIKeyType.php
+++ /dev/null
@@ -1,81 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-
-namespace App\Form\Type;
-
-use Symfony\Component\Form\AbstractType;
-use Symfony\Component\Form\Extension\Core\Type\PasswordType;
-use Symfony\Component\Form\FormInterface;
-use Symfony\Component\Form\FormView;
-use Symfony\Component\OptionsResolver\OptionsResolver;
-use Symfony\Contracts\Translation\TranslatorInterface;
-
-class APIKeyType extends AbstractType
-{
- public function __construct(private readonly TranslatorInterface $translator)
- {
- }
-
- public function getParent(): string
- {
- return PasswordType::class;
- }
-
- public function buildView(FormView $view, FormInterface $form, array $options): void
- {
- $viewData = $form->getViewData();
-
- //If the field is disabled, show the redacted API key
- if ($options['disabled'] ?? false) {
- if ($viewData === null || $viewData === '') {
- $view->vars['value'] = $viewData;
- } else {
-
- $view->vars['value'] = self::redact((string)$viewData) . ' (' . $this ->translator->trans("form.apikey.redacted") . ')';
- }
- } else { //Otherwise, show the actual value
- $view->vars['value'] = $viewData;
- }
- }
-
- public static function redact(string $apiKey): string
- {
- //Show only the last 2 characters of the API key if it is long enough (more than 16 characters)
- //Replace all other characters with dots
- if (strlen($apiKey) > 16) {
- return str_repeat('*', strlen($apiKey) - 2) . substr($apiKey, -2);
- }
-
- return str_repeat('*', strlen($apiKey));
- }
-
- public function configureOptions(OptionsResolver $resolver): void
- {
- $resolver->setDefaults([
- 'always_empty' => false,
- 'toggle' => true,
- 'empty_data' => null,
- 'attr' => ['autocomplete' => 'off'],
- ]);
- }
-}
diff --git a/src/Form/Type/CurrencyEntityType.php b/src/Form/Type/CurrencyEntityType.php
index 875ca35f..07f0a9f8 100644
--- a/src/Form/Type/CurrencyEntityType.php
+++ b/src/Form/Type/CurrencyEntityType.php
@@ -25,7 +25,6 @@ namespace App\Form\Type;
use App\Entity\PriceInformations\Currency;
use App\Form\Type\Helper\StructuralEntityChoiceHelper;
use App\Services\Trees\NodesListBuilder;
-use App\Settings\SystemSettings\LocalizationSettings;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Intl\Currencies;
use Symfony\Component\OptionsResolver\Options;
@@ -37,7 +36,7 @@ use Symfony\Contracts\Translation\TranslatorInterface;
*/
class CurrencyEntityType extends StructuralEntityType
{
- public function __construct(EntityManagerInterface $em, NodesListBuilder $builder, TranslatorInterface $translator, StructuralEntityChoiceHelper $choiceHelper, private readonly LocalizationSettings $localizationSettings)
+ public function __construct(EntityManagerInterface $em, NodesListBuilder $builder, TranslatorInterface $translator, StructuralEntityChoiceHelper $choiceHelper, protected ?string $base_currency)
{
parent::__construct($em, $builder, $translator, $choiceHelper);
}
@@ -58,7 +57,7 @@ class CurrencyEntityType extends StructuralEntityType
$resolver->setDefault('empty_message', function (Options $options) {
//By default, we use the global base currency:
- $iso_code = $this->localizationSettings->baseCurrency;
+ $iso_code = $this->base_currency;
if ($options['base_currency']) { //Allow to override it
$iso_code = $options['base_currency'];
diff --git a/src/Form/Type/LocaleSelectType.php b/src/Form/Type/LocaleSelectType.php
deleted file mode 100644
index aa7af5c2..00000000
--- a/src/Form/Type/LocaleSelectType.php
+++ /dev/null
@@ -1,53 +0,0 @@
-.
- */
-
-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,
- ]);
- }
-}
\ No newline at end of file
diff --git a/src/Form/Type/TriStateCheckboxType.php b/src/Form/Type/TriStateCheckboxType.php
index b2a85ad3..4523a839 100644
--- a/src/Form/Type/TriStateCheckboxType.php
+++ b/src/Form/Type/TriStateCheckboxType.php
@@ -100,7 +100,7 @@ final class TriStateCheckboxType extends AbstractType implements DataTransformer
* @return mixed The value in the transformed representation
*
*/
- public function transform(mixed $value): mixed
+ public function transform(mixed $value)
{
if (true === $value) {
return 'true';
@@ -142,7 +142,7 @@ final class TriStateCheckboxType extends AbstractType implements DataTransformer
*
* @return mixed The value in the original representation
*/
- public function reverseTransform(mixed $value): mixed
+ public function reverseTransform(mixed $value)
{
return match ($value) {
'true' => true,
diff --git a/src/Form/UserAdminForm.php b/src/Form/UserAdminForm.php
index 69be181f..864bcf6b 100644
--- a/src/Form/UserAdminForm.php
+++ b/src/Form/UserAdminForm.php
@@ -22,7 +22,6 @@ declare(strict_types=1);
namespace App\Form;
-use App\Form\Type\LocaleSelectType;
use Symfony\Bundle\SecurityBundle\Security;
use App\Entity\Base\AbstractNamedDBElement;
use App\Entity\UserSystem\Group;
@@ -36,6 +35,7 @@ use App\Form\Type\ThemeChoiceType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
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\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\ResetType;
@@ -140,10 +140,11 @@ class UserAdminForm extends AbstractType
])
//Config section
- ->add('language', LocaleSelectType::class, [
+ ->add('language', LanguageType::class, [
'required' => false,
'placeholder' => 'user_settings.language.placeholder',
'label' => 'user.language_select',
+ 'preferred_choices' => ['en', 'de'],
'disabled' => !$this->security->isGranted('change_user_settings', $entity),
])
->add('timezone', TimezoneType::class, [
diff --git a/src/Form/UserSettingsType.php b/src/Form/UserSettingsType.php
index 0c7cb169..05f63df4 100644
--- a/src/Form/UserSettingsType.php
+++ b/src/Form/UserSettingsType.php
@@ -22,7 +22,6 @@ declare(strict_types=1);
namespace App\Form;
-use App\Form\Type\LocaleSelectType;
use Symfony\Bundle\SecurityBundle\Security;
use App\Entity\UserSystem\User;
use App\Form\Type\CurrencyEntityType;
@@ -34,6 +33,7 @@ use Symfony\Component\Form\Event\PreSetDataEvent;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
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\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
@@ -47,7 +47,7 @@ class UserSettingsType extends AbstractType
{
public function __construct(protected Security $security,
protected bool $demo_mode,
- )
+ #[Autowire(param: 'partdb.locale_menu')] private readonly array $preferred_languages)
{
}
@@ -107,11 +107,12 @@ class UserSettingsType extends AbstractType
'mode' => 'markdown-full',
'disabled' => !$this->security->isGranted('edit_infos', $options['data']) || $this->demo_mode,
])
- ->add('language', LocaleSelectType::class, [
+ ->add('language', LanguageType::class, [
'disabled' => $this->demo_mode,
'required' => false,
'placeholder' => 'user_settings.language.placeholder',
'label' => 'user.language_select',
+ 'preferred_choices' => $this->preferred_languages,
])
->add('timezone', TimezoneType::class, [
'disabled' => $this->demo_mode,
diff --git a/src/Migration/WithPermPresetsTrait.php b/src/Migration/WithPermPresetsTrait.php
index 203ef68a..44bc4510 100644
--- a/src/Migration/WithPermPresetsTrait.php
+++ b/src/Migration/WithPermPresetsTrait.php
@@ -26,7 +26,7 @@ namespace App\Migration;
use App\Entity\UserSystem\PermissionData;
use App\Security\Interfaces\HasPermissionsInterface;
use App\Services\UserSystem\PermissionPresetsHelper;
-use Psr\Container\ContainerInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
trait WithPermPresetsTrait
{
diff --git a/src/Security/TwoFactor/WebauthnKeyLastUseTwoFactorProvider.php b/src/Security/TwoFactor/WebauthnKeyLastUseTwoFactorProvider.php
index 4d1269d6..9bfa691d 100644
--- a/src/Security/TwoFactor/WebauthnKeyLastUseTwoFactorProvider.php
+++ b/src/Security/TwoFactor/WebauthnKeyLastUseTwoFactorProvider.php
@@ -33,7 +33,6 @@ use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\TwoFactorProviderInterface
use Symfony\Component\DependencyInjection\Attribute\AsDecorator;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\DependencyInjection\Attribute\AutowireDecorated;
-use Webauthn\PublicKeyCredential;
/**
* This class decorates the Webauthn TwoFactorProvider and adds additional logic which allows us to set a last used date
@@ -89,12 +88,10 @@ class WebauthnKeyLastUseTwoFactorProvider implements TwoFactorProviderInterface
private function getWebauthnKeyFromCode(string $authenticationCode): ?WebauthnKey
{
- $serializer = $this->webauthnProvider->getWebauthnSerializer();
+ $publicKeyCredentialLoader = $this->webauthnProvider->getPublicKeyCredentialLoader();
//Try to load the public key credential from the code
- $publicKeyCredential = $serializer->deserialize($authenticationCode, PublicKeyCredential::class, 'json', [
- 'json_decode_options' => JSON_THROW_ON_ERROR
- ]);
+ $publicKeyCredential = $publicKeyCredentialLoader->load($authenticationCode);
//Find the credential source for the given credential id
$publicKeyCredentialSource = $this->publicKeyCredentialSourceRepository->findOneByCredentialId($publicKeyCredential->rawId);
@@ -106,4 +103,4 @@ class WebauthnKeyLastUseTwoFactorProvider implements TwoFactorProviderInterface
return $publicKeyCredentialSource;
}
-}
+}
\ No newline at end of file
diff --git a/src/Serializer/APIPlatform/DetermineTypeFromElementIRIDenormalizer.php b/src/Serializer/APIPlatform/DetermineTypeFromElementIRIDenormalizer.php
index 78679214..8283dbbe 100644
--- a/src/Serializer/APIPlatform/DetermineTypeFromElementIRIDenormalizer.php
+++ b/src/Serializer/APIPlatform/DetermineTypeFromElementIRIDenormalizer.php
@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace App\Serializer\APIPlatform;
use ApiPlatform\Metadata\Exception\ResourceClassNotFoundException;
-use ApiPlatform\Metadata\IriConverterInterface;
+use ApiPlatform\Api\IriConverterInterface;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
@@ -121,4 +121,4 @@ class DetermineTypeFromElementIRIDenormalizer implements DenormalizerInterface,
return $tmp;
}
-}
+}
\ No newline at end of file
diff --git a/src/Serializer/PartNormalizer.php b/src/Serializer/PartNormalizer.php
index 775df77f..9050abfc 100644
--- a/src/Serializer/PartNormalizer.php
+++ b/src/Serializer/PartNormalizer.php
@@ -92,7 +92,7 @@ class PartNormalizer implements NormalizerInterface, DenormalizerInterface, Norm
return $data;
}
- public function supportsDenormalization($data, string $type, ?string $format = null, array $context = []): bool
+ public function supportsDenormalization($data, string $type, string $format = null, array $context = []): bool
{
//Only denormalize if we are doing a file import operation
if (!($context['partdb_import'] ?? false)) {
diff --git a/src/Serializer/StructuralElementDenormalizer.php b/src/Serializer/StructuralElementDenormalizer.php
index 9f4256f9..d9b03ae7 100644
--- a/src/Serializer/StructuralElementDenormalizer.php
+++ b/src/Serializer/StructuralElementDenormalizer.php
@@ -122,7 +122,7 @@ class StructuralElementDenormalizer implements DenormalizerInterface, Denormaliz
return $deserialized_entity;
}
- public function getSupportedTypes(?string $format): array
+ public function getSupportedTypes(): array
{
//Must be false, because we use in_array in supportsDenormalization
return [
diff --git a/src/Serializer/StructuralElementNormalizer.php b/src/Serializer/StructuralElementNormalizer.php
index bf3e1097..e73f69be 100644
--- a/src/Serializer/StructuralElementNormalizer.php
+++ b/src/Serializer/StructuralElementNormalizer.php
@@ -23,21 +23,20 @@ declare(strict_types=1);
namespace App\Serializer;
use App\Entity\Base\AbstractStructuralDBElement;
-use App\Serializer\APIPlatform\SkippableItemNormalizer;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
-use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
-use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
/**
* @see \App\Tests\Serializer\StructuralElementNormalizerTest
*/
-class StructuralElementNormalizer implements NormalizerInterface, NormalizerAwareInterface
+class StructuralElementNormalizer implements NormalizerInterface
{
- use NormalizerAwareTrait;
-
- public const ALREADY_CALLED = 'STRUCTURAL_ELEMENT_NORMALIZER_ALREADY_CALLED';
+ public function __construct(
+ #[Autowire(service: ObjectNormalizer::class)]private readonly NormalizerInterface $normalizer
+ )
+ {
+ }
public function supportsNormalization($data, ?string $format = null, array $context = []): bool
{
@@ -46,25 +45,15 @@ class StructuralElementNormalizer implements NormalizerInterface, NormalizerAwar
return false;
}
- if (isset($context[self::ALREADY_CALLED]) && in_array($data, $context[self::ALREADY_CALLED], true)) {
- //If we already handled this object, skip it
- return false;
- }
-
return $data instanceof AbstractStructuralDBElement;
}
- public function normalize($object, ?string $format = null, array $context = []): \ArrayObject|bool|float|int|string|array
+ public function normalize($object, ?string $format = null, array $context = []): mixed
{
if (!$object instanceof AbstractStructuralDBElement) {
throw new \InvalidArgumentException('This normalizer only supports AbstractStructural objects!');
}
- //Avoid infinite recursion by checking if we already handled this object
- $context[self::ALREADY_CALLED] = $context[self::ALREADY_CALLED] ?? [];
- $context[SkippableItemNormalizer::DISABLE_ITEM_NORMALIZER] = true;
- $context[self::ALREADY_CALLED][] = $object;
-
$data = $this->normalizer->normalize($object, $format, $context);
//If the data is not an array, we can't do anything with it
@@ -88,8 +77,7 @@ class StructuralElementNormalizer implements NormalizerInterface, NormalizerAwar
public function getSupportedTypes(?string $format): array
{
return [
- //We cannot cache the result, as it depends on the context
- AbstractStructuralDBElement::class => false,
+ AbstractStructuralDBElement::class => true,
];
}
}
diff --git a/src/Services/Attachments/AttachmentSubmitHandler.php b/src/Services/Attachments/AttachmentSubmitHandler.php
index a30163ae..89457cea 100644
--- a/src/Services/Attachments/AttachmentSubmitHandler.php
+++ b/src/Services/Attachments/AttachmentSubmitHandler.php
@@ -40,7 +40,6 @@ use App\Entity\Attachments\StorageLocationAttachment;
use App\Entity\Attachments\SupplierAttachment;
use App\Entity\Attachments\UserAttachment;
use App\Exceptions\AttachmentDownloadException;
-use App\Settings\SystemSettings\AttachmentsSettings;
use Hshn\Base64EncodedFile\HttpFoundation\File\Base64EncodedFile;
use Hshn\Base64EncodedFile\HttpFoundation\File\UploadedBase64EncodedFile;
use const DIRECTORY_SEPARATOR;
@@ -65,14 +64,12 @@ class AttachmentSubmitHandler
'asp', 'cgi', 'py', 'pl', 'exe', 'aspx', 'js', 'mjs', 'jsp', 'css', 'jar', 'html', 'htm', 'shtm', 'shtml', 'htaccess',
'htpasswd', ''];
- public function __construct(
- protected AttachmentPathResolver $pathResolver,
- protected HttpClientInterface $httpClient,
- protected MimeTypesInterface $mimeTypes,
- protected FileTypeFilterTools $filterTools,
- protected AttachmentsSettings $settings,
- protected readonly SVGSanitizer $SVGSanitizer,
- )
+ public function __construct(protected AttachmentPathResolver $pathResolver, protected bool $allow_attachments_downloads,
+ protected HttpClientInterface $httpClient, protected MimeTypesInterface $mimeTypes, protected readonly SVGSanitizer $SVGSanitizer,
+ protected FileTypeFilterTools $filterTools, /**
+ * @var string The user configured maximum upload size. This is a string like "10M" or "1G" and will be converted to
+ */
+ protected string $max_upload_size)
{
//The mapping used to determine which folder will be used for an attachment type
$this->folder_mapping = [
@@ -340,7 +337,7 @@ class AttachmentSubmitHandler
protected function downloadURL(Attachment $attachment, bool $secureAttachment): Attachment
{
//Check if we are allowed to download files
- if (!$this->settings->allowDownloads) {
+ if (!$this->allow_attachments_downloads) {
throw new RuntimeException('Download of attachments is not allowed!');
}
@@ -499,7 +496,7 @@ class AttachmentSubmitHandler
$this->max_upload_size_bytes = min(
$this->parseFileSizeString(ini_get('post_max_size')),
$this->parseFileSizeString(ini_get('upload_max_filesize')),
- $this->parseFileSizeString($this->settings->maxFileSize)
+ $this->parseFileSizeString($this->max_upload_size),
);
return $this->max_upload_size_bytes;
diff --git a/src/Services/EDA/KiCadHelper.php b/src/Services/EDA/KiCadHelper.php
index 75c2cc34..7777ec61 100644
--- a/src/Services/EDA/KiCadHelper.php
+++ b/src/Services/EDA/KiCadHelper.php
@@ -29,7 +29,6 @@ use App\Entity\Parts\Part;
use App\Services\Cache\ElementCacheTagGenerator;
use App\Services\EntityURLGenerator;
use App\Services\Trees\NodesListBuilder;
-use App\Settings\MiscSettings\KiCadEDASettings;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
@@ -40,9 +39,6 @@ use Symfony\Contracts\Translation\TranslatorInterface;
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(
private readonly NodesListBuilder $nodesListBuilder,
private readonly TagAwareCacheInterface $kicadCache,
@@ -51,9 +47,9 @@ class KiCadHelper
private readonly UrlGeneratorInterface $urlGenerator,
private readonly EntityURLGenerator $entityURLGenerator,
private readonly TranslatorInterface $translator,
- KiCadEDASettings $kiCadEDASettings,
+ /** 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,
) {
- $this->category_depth = $kiCadEDASettings->categoryDepth;
}
/**
diff --git a/src/Services/Formatters/MoneyFormatter.php b/src/Services/Formatters/MoneyFormatter.php
index 505752c3..44a49cb5 100644
--- a/src/Services/Formatters/MoneyFormatter.php
+++ b/src/Services/Formatters/MoneyFormatter.php
@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace App\Services\Formatters;
use App\Entity\PriceInformations\Currency;
-use App\Settings\SystemSettings\LocalizationSettings;
use Locale;
use NumberFormatter;
@@ -31,7 +30,7 @@ class MoneyFormatter
{
protected string $locale;
- public function __construct(private readonly LocalizationSettings $localizationSettings)
+ public function __construct(protected string $base_currency)
{
$this->locale = Locale::getDefault();
}
@@ -46,7 +45,7 @@ class MoneyFormatter
*/
public function format(string|float $value, ?Currency $currency = null, int $decimals = 5, bool $show_all_digits = false): string
{
- $iso_code = $this->localizationSettings->baseCurrency;
+ $iso_code = $this->base_currency;
if ($currency instanceof Currency && ($currency->getIsoCode() !== '')) {
$iso_code = $currency->getIsoCode();
}
diff --git a/src/Services/ImportExportSystem/EntityExporter.php b/src/Services/ImportExportSystem/EntityExporter.php
index 271642da..c37db50c 100644
--- a/src/Services/ImportExportSystem/EntityExporter.php
+++ b/src/Services/ImportExportSystem/EntityExporter.php
@@ -137,7 +137,7 @@ class EntityExporter
$options = [
'format' => $request->get('format') ?? 'json',
'level' => $request->get('level') ?? 'extended',
- 'include_children' => $request->request->getBoolean('include_children'),
+ 'include_children' => $request->request->getBoolean('include_children') ?? false,
];
if (!is_array($entities)) {
diff --git a/src/Services/ImportExportSystem/PartKeeprImporter/PKPartImporter.php b/src/Services/ImportExportSystem/PartKeeprImporter/PKPartImporter.php
index 80c2dbf7..9dd67233 100644
--- a/src/Services/ImportExportSystem/PartKeeprImporter/PKPartImporter.php
+++ b/src/Services/ImportExportSystem/PartKeeprImporter/PKPartImporter.php
@@ -35,7 +35,6 @@ use App\Entity\Parts\Supplier;
use App\Entity\PriceInformations\Currency;
use App\Entity\PriceInformations\Orderdetail;
use App\Entity\PriceInformations\Pricedetail;
-use App\Settings\SystemSettings\LocalizationSettings;
use Brick\Math\BigDecimal;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Intl\Currencies;
@@ -48,7 +47,7 @@ class PKPartImporter
{
use PKImportHelperTrait;
- public function __construct(EntityManagerInterface $em, PropertyAccessorInterface $propertyAccessor, private readonly LocalizationSettings $localizationSettings)
+ public function __construct(EntityManagerInterface $em, PropertyAccessorInterface $propertyAccessor, private readonly string $base_currency)
{
$this->em = $em;
$this->propertyAccessor = $propertyAccessor;
@@ -211,7 +210,7 @@ class PKPartImporter
$currency_iso_code = strtoupper($currency_iso_code);
//We do not have a currency for the base currency to be consistent with prices without currencies
- if ($currency_iso_code === $this->localizationSettings->baseCurrency) {
+ if ($currency_iso_code === $this->base_currency) {
return null;
}
diff --git a/src/Services/InfoProviderSystem/DTOtoEntityConverter.php b/src/Services/InfoProviderSystem/DTOtoEntityConverter.php
index d09f1d05..40f69498 100644
--- a/src/Services/InfoProviderSystem/DTOtoEntityConverter.php
+++ b/src/Services/InfoProviderSystem/DTOtoEntityConverter.php
@@ -43,7 +43,6 @@ use App\Services\InfoProviderSystem\DTOs\ParameterDTO;
use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
-use App\Settings\SystemSettings\LocalizationSettings;
use Doctrine\ORM\EntityManagerInterface;
/**
@@ -55,11 +54,8 @@ final class DTOtoEntityConverter
private const TYPE_DATASHEETS_NAME = 'Datasheet';
private const TYPE_IMAGE_NAME = 'Image';
- private readonly string $base_currency;
-
- public function __construct(private readonly EntityManagerInterface $em, LocalizationSettings $localizationSettings)
+ public function __construct(private readonly EntityManagerInterface $em, private readonly string $base_currency)
{
- $this->base_currency = $localizationSettings->baseCurrency;
}
/**
diff --git a/src/Services/InfoProviderSystem/ExistingPartFinder.php b/src/Services/InfoProviderSystem/ExistingPartFinder.php
index 614ca105..762c1517 100644
--- a/src/Services/InfoProviderSystem/ExistingPartFinder.php
+++ b/src/Services/InfoProviderSystem/ExistingPartFinder.php
@@ -1,7 +1,5 @@
getQuery()->getResult();
}
-}
+}
\ No newline at end of file
diff --git a/src/Services/InfoProviderSystem/Providers/DigikeyProvider.php b/src/Services/InfoProviderSystem/Providers/DigikeyProvider.php
index 51f460e4..b20368ce 100644
--- a/src/Services/InfoProviderSystem/Providers/DigikeyProvider.php
+++ b/src/Services/InfoProviderSystem/Providers/DigikeyProvider.php
@@ -31,7 +31,6 @@ use App\Services\InfoProviderSystem\DTOs\PriceDTO;
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
use App\Services\InfoProviderSystem\DTOs\SearchResultDTO;
use App\Services\OAuth\OAuthTokenManager;
-use App\Settings\InfoProviderSystem\DigikeySettings;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class DigikeyProvider implements InfoProviderInterface
@@ -56,16 +55,17 @@ class DigikeyProvider implements InfoProviderInterface
];
public function __construct(HttpClientInterface $httpClient, private readonly OAuthTokenManager $authTokenManager,
- private readonly DigikeySettings $settings,)
+ private readonly string $currency, private readonly string $clientId,
+ private readonly string $language, private readonly string $country)
{
//Create the HTTP client with some default options
$this->digikeyClient = $httpClient->withOptions([
"base_uri" => self::BASE_URI,
"headers" => [
- "X-DIGIKEY-Client-Id" => $this->settings->clientId,
- "X-DIGIKEY-Locale-Site" => $this->settings->country,
- "X-DIGIKEY-Locale-Language" => $this->settings->language,
- "X-DIGIKEY-Locale-Currency" => $this->settings->currency,
+ "X-DIGIKEY-Client-Id" => $clientId,
+ "X-DIGIKEY-Locale-Site" => $this->country,
+ "X-DIGIKEY-Locale-Language" => $this->language,
+ "X-DIGIKEY-Locale-Currency" => $this->currency,
"X-DIGIKEY-Customer-Id" => 0,
]
]);
@@ -78,8 +78,7 @@ class DigikeyProvider implements InfoProviderInterface
'description' => 'This provider uses the DigiKey API to search for parts.',
'url' => 'https://www.digikey.com/',
'oauth_app_name' => self::OAUTH_APP_NAME,
- 'disabled_help' => 'Set the Client ID and Secret in provider settings and connect OAuth to enable.',
- 'settings_class' => DigikeySettings::class,
+ 'disabled_help' => 'Set the PROVIDER_DIGIKEY_CLIENT_ID and PROVIDER_DIGIKEY_SECRET env option and connect OAuth to enable.'
];
}
@@ -102,7 +101,7 @@ class DigikeyProvider implements InfoProviderInterface
public function isActive(): bool
{
//The client ID has to be set and a token has to be available (user clicked connect)
- return $this->settings->clientId !== null && $this->settings->clientId !== '' && $this->authTokenManager->hasToken(self::OAUTH_APP_NAME);
+ return $this->clientId !== '' && $this->authTokenManager->hasToken(self::OAUTH_APP_NAME);
}
public function searchByKeyword(string $keyword): array
@@ -269,7 +268,7 @@ class DigikeyProvider implements InfoProviderInterface
$prices = [];
foreach ($price_breaks as $price_break) {
- $prices[] = new PriceDTO(minimum_discount_amount: $price_break['BreakQuantity'], price: (string) $price_break['UnitPrice'], currency_iso_code: $this->settings->currency);
+ $prices[] = new PriceDTO(minimum_discount_amount: $price_break['BreakQuantity'], price: (string) $price_break['UnitPrice'], currency_iso_code: $this->currency);
}
return [
diff --git a/src/Services/InfoProviderSystem/Providers/Element14Provider.php b/src/Services/InfoProviderSystem/Providers/Element14Provider.php
index 27dfb908..b942b929 100644
--- a/src/Services/InfoProviderSystem/Providers/Element14Provider.php
+++ b/src/Services/InfoProviderSystem/Providers/Element14Provider.php
@@ -29,7 +29,6 @@ use App\Services\InfoProviderSystem\DTOs\ParameterDTO;
use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
-use App\Settings\InfoProviderSystem\Element14Settings;
use Composer\CaBundle\CaBundle;
use Symfony\Contracts\HttpClient\HttpClientInterface;
@@ -47,7 +46,7 @@ class Element14Provider implements InfoProviderInterface
private readonly HttpClientInterface $element14Client;
- public function __construct(HttpClientInterface $element14Client, private readonly Element14Settings $settings)
+ public function __construct(HttpClientInterface $element14Client, private readonly string $api_key, private readonly string $store_id)
{
/* We use the mozilla CA from the composer ca bundle directly, as some debian systems seems to have problems
* with the SSL.COM CA, element14 uses. See https://github.com/Part-DB/Part-DB-server/issues/866
@@ -66,8 +65,7 @@ class Element14Provider implements InfoProviderInterface
'name' => 'Farnell element14',
'description' => 'This provider uses the Farnell element14 API to search for parts.',
'url' => 'https://www.element14.com/',
- 'disabled_help' => 'Configure the API key in the provider settings to enable.',
- 'settings_class' => Element14Settings::class,
+ 'disabled_help' => 'Configure the API key in the PROVIDER_ELEMENT14_KEY environment variable to enable.'
];
}
@@ -78,7 +76,7 @@ class Element14Provider implements InfoProviderInterface
public function isActive(): bool
{
- return $this->settings->apiKey !== null && trim($this->settings->apiKey) !== '';
+ return $this->api_key !== '';
}
/**
@@ -90,11 +88,11 @@ class Element14Provider implements InfoProviderInterface
$response = $this->element14Client->request('GET', self::ENDPOINT_URL, [
'query' => [
'term' => $term,
- 'storeInfo.id' => $this->settings->storeId,
+ 'storeInfo.id' => $this->store_id,
'resultsSettings.offset' => 0,
'resultsSettings.numberOfResults' => self::NUMBER_OF_RESULTS,
'resultsSettings.responseGroup' => 'large',
- 'callInfo.apiKey' => $this->settings->apiKey,
+ 'callInfo.apiKey' => $this->api_key,
'callInfo.responseDataFormat' => 'json',
'versionNumber' => self::API_VERSION_NUMBER,
],
@@ -162,7 +160,7 @@ class Element14Provider implements InfoProviderInterface
$locale = 'en_US';
}
- return 'https://' . $this->settings->storeId . '/productimages/standard/' . $locale . $image['baseName'];
+ return 'https://' . $this->store_id . '/productimages/standard/' . $locale . $image['baseName'];
}
/**
@@ -197,7 +195,7 @@ class Element14Provider implements InfoProviderInterface
public function getUsedCurrency(): string
{
//Decide based on the shop ID
- return match ($this->settings->storeId) {
+ return match ($this->store_id) {
'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',
'dk.farnell.com' => 'DKK',
@@ -224,7 +222,7 @@ class Element14Provider implements InfoProviderInterface
'tw.element14.com' => 'TWD',
'kr.element14.com' => 'KRW',
'vn.element14.com' => 'VND',
- default => throw new \RuntimeException('Unknown store ID: ' . $this->settings->storeId)
+ default => throw new \RuntimeException('Unknown store ID: ' . $this->store_id)
};
}
@@ -309,4 +307,4 @@ class Element14Provider implements InfoProviderInterface
ProviderCapabilities::DATASHEET,
];
}
-}
+}
\ No newline at end of file
diff --git a/src/Services/InfoProviderSystem/Providers/InfoProviderInterface.php b/src/Services/InfoProviderSystem/Providers/InfoProviderInterface.php
index 1f787559..30821bad 100644
--- a/src/Services/InfoProviderSystem/Providers/InfoProviderInterface.php
+++ b/src/Services/InfoProviderSystem/Providers/InfoProviderInterface.php
@@ -39,9 +39,8 @@ interface InfoProviderInterface
* - url?: The url of the provider (e.g. "https://www.digikey.com")
* - disabled_help?: A help text which is shown when the provider is disabled, explaining how to enable it
* - oauth_app_name?: The name of the OAuth app which is used for authentication (e.g. "ip_digikey_oauth"). If this is set a connect button will be shown
- * - settings_class?: The class name of the settings class which contains the settings for this provider (e.g. "App\Settings\InfoProviderSettings\DigikeySettings"). If this is set a link to the settings will be shown
*
- * @phpstan-return array{ name: string, description?: string, logo?: string, url?: string, disabled_help?: string, oauth_app_name?: string, settings_class?: class-string }
+ * @phpstan-return array{ name: string, description?: string, logo?: string, url?: string, disabled_help?: string, oauth_app_name?: string }
*/
public function getProviderInfo(): array;
@@ -79,4 +78,4 @@ interface InfoProviderInterface
* @return ProviderCapabilities[]
*/
public function getCapabilities(): array;
-}
+}
\ No newline at end of file
diff --git a/src/Services/InfoProviderSystem/Providers/LCSCProvider.php b/src/Services/InfoProviderSystem/Providers/LCSCProvider.php
index 58df3b82..d903a8dd 100755
--- a/src/Services/InfoProviderSystem/Providers/LCSCProvider.php
+++ b/src/Services/InfoProviderSystem/Providers/LCSCProvider.php
@@ -29,7 +29,6 @@ use App\Services\InfoProviderSystem\DTOs\ParameterDTO;
use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
-use App\Settings\InfoProviderSystem\LCSCSettings;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Contracts\HttpClient\HttpClientInterface;
@@ -40,7 +39,7 @@ class LCSCProvider implements InfoProviderInterface
public const DISTRIBUTOR_NAME = 'LCSC';
- public function __construct(private readonly HttpClientInterface $lcscClient, private readonly LCSCSettings $settings)
+ public function __construct(private readonly HttpClientInterface $lcscClient, private readonly string $currency, private readonly bool $enabled = true)
{
}
@@ -51,8 +50,7 @@ class LCSCProvider implements InfoProviderInterface
'name' => 'LCSC',
'description' => 'This provider uses the (unofficial) LCSC API to search for parts.',
'url' => 'https://www.lcsc.com/',
- 'disabled_help' => 'Enable this provider in the provider settings.',
- 'settings_class' => LCSCSettings::class,
+ 'disabled_help' => 'Set PROVIDER_LCSC_ENABLED to 1 (or true) in your environment variable config.'
];
}
@@ -64,7 +62,7 @@ class LCSCProvider implements InfoProviderInterface
// This provider is always active
public function isActive(): bool
{
- return $this->settings->enabled;
+ return $this->enabled;
}
/**
@@ -75,7 +73,7 @@ class LCSCProvider implements InfoProviderInterface
{
$response = $this->lcscClient->request('GET', self::ENDPOINT_URL . "/product/detail", [
'headers' => [
- 'Cookie' => new Cookie('currencyCode', $this->settings->currency)
+ 'Cookie' => new Cookie('currencyCode', $this->currency)
],
'query' => [
'productCode' => $id,
@@ -125,7 +123,7 @@ class LCSCProvider implements InfoProviderInterface
{
$response = $this->lcscClient->request('GET', self::ENDPOINT_URL . "/search/global", [
'headers' => [
- 'Cookie' => new Cookie('currencyCode', $this->settings->currency)
+ 'Cookie' => new Cookie('currencyCode', $this->currency)
],
'query' => [
'keyword' => $term,
@@ -275,7 +273,7 @@ class LCSCProvider implements InfoProviderInterface
'kr.' => 'DKK',
'โน' => 'INR',
//Fallback to the configured currency
- default => $this->settings->currency,
+ default => $this->currency,
};
}
diff --git a/src/Services/InfoProviderSystem/Providers/MouserProvider.php b/src/Services/InfoProviderSystem/Providers/MouserProvider.php
index 6639e5c1..90bad263 100644
--- a/src/Services/InfoProviderSystem/Providers/MouserProvider.php
+++ b/src/Services/InfoProviderSystem/Providers/MouserProvider.php
@@ -37,7 +37,6 @@ use App\Services\InfoProviderSystem\DTOs\FileDTO;
use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
-use App\Settings\InfoProviderSystem\MouserSettings;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;
@@ -51,7 +50,10 @@ class MouserProvider implements InfoProviderInterface
public function __construct(
private readonly HttpClientInterface $mouserClient,
- private readonly MouserSettings $settings,
+ private readonly string $api_key,
+ private readonly string $language,
+ private readonly string $options,
+ private readonly int $search_limit
) {
}
@@ -61,8 +63,7 @@ class MouserProvider implements InfoProviderInterface
'name' => 'Mouser',
'description' => 'This provider uses the Mouser API to search for parts.',
'url' => 'https://www.mouser.com/',
- 'disabled_help' => 'Configure the API key in the provider settings to enable.',
- 'settings_class' => MouserSettings::class
+ 'disabled_help' => 'Configure the API key in the PROVIDER_MOUSER_KEY environment variable to enable.'
];
}
@@ -73,7 +74,7 @@ class MouserProvider implements InfoProviderInterface
public function isActive(): bool
{
- return $this->settings->apiKey !== '' && $this->settings->apiKey !== null;
+ return $this->api_key !== '';
}
public function searchByKeyword(string $keyword): array
@@ -119,15 +120,15 @@ class MouserProvider implements InfoProviderInterface
$response = $this->mouserClient->request('POST', self::ENDPOINT_URL."/keyword", [
'query' => [
- 'apiKey' => $this->settings->apiKey
+ 'apiKey' => $this->api_key,
],
'json' => [
'SearchByKeywordRequest' => [
'keyword' => $keyword,
- 'records' => $this->settings->searchLimit, //self::NUMBER_OF_RESULTS,
+ 'records' => $this->search_limit, //self::NUMBER_OF_RESULTS,
'startingRecord' => 0,
- 'searchOptions' => $this->settings->searchOption->value,
- 'searchWithYourSignUpLanguage' => $this->settings->searchWithSignUpLanguage ? 'true' : 'false',
+ 'searchOptions' => $this->options,
+ 'searchWithYourSignUpLanguage' => $this->language,
]
],
]);
@@ -160,7 +161,7 @@ class MouserProvider implements InfoProviderInterface
$response = $this->mouserClient->request('POST', self::ENDPOINT_URL."/partnumber", [
'query' => [
- 'apiKey' => $this->settings->apiKey,
+ 'apiKey' => $this->api_key,
],
'json' => [
'SearchByPartRequest' => [
@@ -346,4 +347,4 @@ class MouserProvider implements InfoProviderInterface
return $tmp;
}
-}
+}
\ No newline at end of file
diff --git a/src/Services/InfoProviderSystem/Providers/OEMSecretsProvider.php b/src/Services/InfoProviderSystem/Providers/OEMSecretsProvider.php
index b705e04a..ccf800f8 100644
--- a/src/Services/InfoProviderSystem/Providers/OEMSecretsProvider.php
+++ b/src/Services/InfoProviderSystem/Providers/OEMSecretsProvider.php
@@ -88,8 +88,6 @@ use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
use App\Services\InfoProviderSystem\DTOs\ParameterDTO;
-use App\Settings\InfoProviderSystem\OEMSecretsSettings;
-use App\Settings\InfoProviderSystem\OEMSecretsSortMode;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Psr\Cache\CacheItemPoolInterface;
@@ -101,7 +99,12 @@ class OEMSecretsProvider implements InfoProviderInterface
public function __construct(
private readonly HttpClientInterface $oemsecretsClient,
- private readonly OEMSecretsSettings $settings,
+ private readonly string $api_key,
+ 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
)
{
@@ -246,8 +249,7 @@ class OEMSecretsProvider implements InfoProviderInterface
'name' => 'OEMSecrets',
'description' => 'This provider uses the OEMSecrets API to search for parts.',
'url' => 'https://www.oemsecrets.com/',
- 'disabled_help' => 'Configure the API key in the provider settings to enable.',
- 'settings_class' => OEMSecretsSettings::class
+ 'disabled_help' => 'Configure the API key in the PROVIDER_OEMSECRETS_KEY environment variable to enable.'
];
}
/**
@@ -266,7 +268,7 @@ class OEMSecretsProvider implements InfoProviderInterface
*/
public function isActive(): bool
{
- return $this->settings->apiKey !== null && $this->settings->apiKey !== '';
+ return $this->api_key !== '';
}
@@ -286,18 +288,18 @@ class OEMSecretsProvider implements InfoProviderInterface
public function searchByKeyword(string $keyword): array
{
/*
- oemsecrets Part Search API 3.0.1
+ oemsecrets Part Search API 3.0.1
"https://oemsecretsapi.com/partsearch?
searchTerm=BC547
&apiKey=icawpb0bspoo2c6s64uv4vpdfp2vgr7e27bxw0yct2bzh87mpl027x353uelpq2x
¤cy=EUR
- &countryCode=IT"
-
+ &countryCode=IT"
+
partsearch description:
- Use the Part Search API to find distributor data for a full or partial manufacturer
+ Use the Part Search API to find distributor data for a full or partial manufacturer
part number including part details, pricing, compliance and inventory.
-
+
Required Parameter Format Description
searchTerm string Part number you are searching for
apiKey string Your unique API key provided to you by OEMsecrets
@@ -305,14 +307,14 @@ class OEMSecretsProvider implements InfoProviderInterface
Additional Parameter Format Description
countryCode string The country you want to output for
currency string / array The currency you want the prices to be displayed as
-
+
To display the output for GB and to view prices in USD, add [ countryCode=GB ] and [ currency=USD ]
as seen below:
oemsecretsapi.com/partsearch?apiKey=abcexampleapikey123&searchTerm=bd04&countryCode=GB¤cy=USD
-
+
To view prices in both USD and GBP add [ currency[]=USD¤cy[]=GBP ]
oemsecretsapi.com/partsearch?searchTerm=bd04&apiKey=abcexampleapikey123¤cy[]=USD¤cy[]=GBP
-
+
*/
@@ -322,9 +324,9 @@ class OEMSecretsProvider implements InfoProviderInterface
$response = $this->oemsecretsClient->request('GET', self::ENDPOINT_URL, [
'query' => [
'searchTerm' => $keyword,
- 'apiKey' => $this->settings->apiKey,
- 'currency' => $this->settings->currency,
- 'countryCode' => $this->settings->country,
+ 'apiKey' => $this->api_key,
+ 'currency' => $this->currency,
+ 'countryCode' => $this->country_code,
],
]);
@@ -531,7 +533,7 @@ class OEMSecretsProvider implements InfoProviderInterface
// Extract prices
$priceDTOs = $this->getPrices($product);
- if (empty($priceDTOs) && !$this->settings->keepZeroPrices) {
+ if (empty($priceDTOs) && (int)$this->zero_price === 0) {
return null; // Skip products without valid prices
}
@@ -555,7 +557,7 @@ class OEMSecretsProvider implements InfoProviderInterface
}
$imagesResults[$provider_id] = $this->getImages($product, $imagesResults[$provider_id] ?? []);
- if ($this->settings->parseParams) {
+ if ($this->set_param == 1) {
$parametersResults[$provider_id] = $this->getParameters($product, $parametersResults[$provider_id] ?? []);
} else {
$parametersResults[$provider_id] = [];
@@ -580,7 +582,7 @@ class OEMSecretsProvider implements InfoProviderInterface
$regionB = $this->countryCodeToRegionMap[$countryCodeB] ?? '';
// If the map is empty or doesn't contain the key for $this->country_code, assign a placeholder region.
- $regionForEnvCountry = $this->countryCodeToRegionMap[$this->settings->country] ?? '';
+ $regionForEnvCountry = $this->countryCodeToRegionMap[$this->country_code] ?? '';
// Convert to string before comparison to avoid mixed types
$countryCodeA = (string) $countryCodeA;
@@ -597,9 +599,9 @@ class OEMSecretsProvider implements InfoProviderInterface
}
// Step 1: country_code from the environment
- if ($countryCodeA === $this->settings->country && $countryCodeB !== $this->settings->country) {
+ if ($countryCodeA === $this->country_code && $countryCodeB !== $this->country_code) {
return -1;
- } elseif ($countryCodeA !== $this->settings->country && $countryCodeB === $this->settings->country) {
+ } elseif ($countryCodeA !== $this->country_code && $countryCodeB === $this->country_code) {
return 1;
}
@@ -679,8 +681,8 @@ class OEMSecretsProvider implements InfoProviderInterface
if (is_array($prices)) {
// Step 1: Check if prices exist in the preferred currency
- if (isset($prices[$this->settings->currency]) && is_array($prices[$this->settings->currency])) {
- $priceDetails = $prices[$this->$this->settings->currency];
+ if (isset($prices[$this->currency]) && is_array($prices[$this->currency])) {
+ $priceDetails = $prices[$this->currency];
foreach ($priceDetails as $priceDetail) {
if (
is_array($priceDetail) &&
@@ -692,7 +694,7 @@ class OEMSecretsProvider implements InfoProviderInterface
$priceDTOs[] = new PriceDTO(
minimum_discount_amount: (float)$priceDetail['unit_break'],
price: (string)$priceDetail['unit_price'],
- currency_iso_code: $this->settings->currency,
+ currency_iso_code: $this->currency,
includes_tax: false,
price_related_quantity: 1.0
);
@@ -1291,7 +1293,7 @@ class OEMSecretsProvider implements InfoProviderInterface
private function sortResultsData(array &$resultsData, string $searchKeyword): void
{
// If the SORT_CRITERIA is not 'C' or 'M', do not sort
- if ($this->settings->sortMode !== OEMSecretsSortMode::COMPLETENESS && $this->settings->sortMode !== OEMSecretsSortMode::MANUFACTURER) {
+ if ($this->sort_criteria !== 'C' && $this->sort_criteria !== 'M') {
return;
}
usort($resultsData, function ($a, $b) use ($searchKeyword) {
@@ -1330,9 +1332,9 @@ class OEMSecretsProvider implements InfoProviderInterface
}
// Final sorting: by completeness or manufacturer, if necessary
- if ($this->settings->sortMode === OEMSecretsSortMode::COMPLETENESS) {
+ if ($this->sort_criteria === 'C') {
return $this->compareByCompleteness($a, $b);
- } elseif ($this->settings->sortMode === OEMSecretsSortMode::MANUFACTURER) {
+ } elseif ($this->sort_criteria === 'M') {
return strcasecmp($a->manufacturer, $b->manufacturer);
}
@@ -1466,4 +1468,4 @@ class OEMSecretsProvider implements InfoProviderInterface
return $url;
}
-}
+}
\ No newline at end of file
diff --git a/src/Services/InfoProviderSystem/Providers/OctopartProvider.php b/src/Services/InfoProviderSystem/Providers/OctopartProvider.php
index 1142f4ef..e28162ba 100644
--- a/src/Services/InfoProviderSystem/Providers/OctopartProvider.php
+++ b/src/Services/InfoProviderSystem/Providers/OctopartProvider.php
@@ -30,7 +30,6 @@ use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
use App\Services\OAuth\OAuthTokenManager;
-use App\Settings\InfoProviderSystem\OctopartSettings;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\HttpClient\HttpOptions;
use Symfony\Contracts\HttpClient\HttpClientInterface;
@@ -115,8 +114,9 @@ class OctopartProvider implements InfoProviderInterface
public function __construct(private readonly HttpClientInterface $httpClient,
private readonly OAuthTokenManager $authTokenManager, private readonly CacheItemPoolInterface $partInfoCache,
- private readonly OctopartSettings $settings,
- )
+ private readonly string $clientId, private readonly string $secret,
+ private readonly string $currency, private readonly string $country,
+ private readonly int $search_limit, private readonly bool $onlyAuthorizedSellers)
{
}
@@ -170,8 +170,7 @@ class OctopartProvider implements InfoProviderInterface
'name' => 'Octopart',
'description' => 'This provider uses the Nexar/Octopart API to search for parts on Octopart.',
'url' => 'https://www.octopart.com/',
- 'disabled_help' => 'Set the Client ID and Secret in provider settings.',
- 'settings_class' => OctopartSettings::class
+ 'disabled_help' => 'Set the PROVIDER_OCTOPART_CLIENT_ID and PROVIDER_OCTOPART_SECRET env option.'
];
}
@@ -184,8 +183,7 @@ class OctopartProvider implements InfoProviderInterface
{
//The client ID has to be set and a token has to be available (user clicked connect)
//return /*!empty($this->clientId) && */ $this->authTokenManager->hasToken(self::OAUTH_APP_NAME);
- return $this->settings->clientId !== null && $this->settings->clientId !== ''
- && $this->settings->secret !== null && $this->settings->secret !== '';
+ return $this->clientId !== '' && $this->secret !== '';
}
private function mapLifeCycleStatus(?string $value): ?ManufacturingStatus
@@ -339,7 +337,7 @@ class OctopartProvider implements InfoProviderInterface
) {
hits
results {
- part
+ part
%s
}
}
@@ -349,10 +347,10 @@ class OctopartProvider implements InfoProviderInterface
$result = $this->makeGraphQLCall($graphQL, [
'keyword' => $keyword,
- 'limit' => $this->settings->searchLimit,
- 'currency' => $this->settings->currency,
- 'country' => $this->settings->country,
- 'authorizedOnly' => $this->settings->onlyAuthorizedSellers,
+ 'limit' => $this->search_limit,
+ 'currency' => $this->currency,
+ 'country' => $this->country,
+ 'authorizedOnly' => $this->onlyAuthorizedSellers,
]);
$tmp = [];
@@ -385,9 +383,9 @@ class OctopartProvider implements InfoProviderInterface
$result = $this->makeGraphQLCall($graphql, [
'ids' => [$id],
- 'currency' => $this->settings->currency,
- 'country' => $this->settings->country,
- 'authorizedOnly' => $this->settings->onlyAuthorizedSellers,
+ 'currency' => $this->currency,
+ 'country' => $this->country,
+ 'authorizedOnly' => $this->onlyAuthorizedSellers,
]);
$tmp = $this->partResultToDTO($result['data']['supParts'][0]);
@@ -405,4 +403,4 @@ class OctopartProvider implements InfoProviderInterface
ProviderCapabilities::PRICE,
];
}
-}
+}
\ No newline at end of file
diff --git a/src/Services/InfoProviderSystem/Providers/PollinProvider.php b/src/Services/InfoProviderSystem/Providers/PollinProvider.php
index 55fa335a..09ab8fd4 100644
--- a/src/Services/InfoProviderSystem/Providers/PollinProvider.php
+++ b/src/Services/InfoProviderSystem/Providers/PollinProvider.php
@@ -31,7 +31,6 @@ use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
use App\Services\InfoProviderSystem\DTOs\SearchResultDTO;
-use App\Settings\InfoProviderSystem\PollinSettings;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Contracts\HttpClient\HttpClientInterface;
@@ -40,7 +39,8 @@ class PollinProvider implements InfoProviderInterface
{
public function __construct(private readonly HttpClientInterface $client,
- private readonly PollinSettings $settings,
+ #[Autowire(env: 'bool:PROVIDER_POLLIN_ENABLED')]
+ private readonly bool $enabled = true,
)
{
}
@@ -51,8 +51,7 @@ class PollinProvider implements InfoProviderInterface
'name' => 'Pollin',
'description' => 'Webscraping from pollin.de to get part information',
'url' => 'https://www.pollin.de/',
- 'disabled_help' => 'Enable the provider in provider settings',
- 'settings_class' => PollinSettings::class,
+ 'disabled_help' => 'Set PROVIDER_POLLIN_ENABLED env to 1'
];
}
@@ -63,7 +62,7 @@ class PollinProvider implements InfoProviderInterface
public function isActive(): bool
{
- return $this->settings->enabled;
+ return $this->enabled;
}
public function searchByKeyword(string $keyword): array
@@ -247,4 +246,4 @@ class PollinProvider implements InfoProviderInterface
ProviderCapabilities::DATASHEET
];
}
-}
+}
\ No newline at end of file
diff --git a/src/Services/InfoProviderSystem/Providers/ReicheltProvider.php b/src/Services/InfoProviderSystem/Providers/ReicheltProvider.php
index 5c8efbf1..0c31c411 100644
--- a/src/Services/InfoProviderSystem/Providers/ReicheltProvider.php
+++ b/src/Services/InfoProviderSystem/Providers/ReicheltProvider.php
@@ -29,7 +29,6 @@ use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
use App\Services\InfoProviderSystem\DTOs\SearchResultDTO;
-use App\Settings\InfoProviderSystem\ReicheltSettings;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Contracts\HttpClient\HttpClientInterface;
@@ -40,7 +39,16 @@ class ReicheltProvider implements InfoProviderInterface
public const DISTRIBUTOR_NAME = "Reichelt";
public function __construct(private readonly HttpClientInterface $client,
- private readonly ReicheltSettings $settings,
+ #[Autowire(env: "bool:PROVIDER_REICHELT_ENABLED")]
+ private readonly bool $enabled = true,
+ #[Autowire(env: "PROVIDER_REICHELT_LANGUAGE")]
+ private readonly string $language = "en",
+ #[Autowire(env: "PROVIDER_REICHELT_COUNTRY")]
+ private readonly string $country = "DE",
+ #[Autowire(env: "PROVIDER_REICHELT_INCLUDE_VAT")]
+ private readonly bool $includeVAT = false,
+ #[Autowire(env: "PROVIDER_REICHELT_CURRENCY")]
+ private readonly string $currency = "EUR",
)
{
}
@@ -51,8 +59,7 @@ class ReicheltProvider implements InfoProviderInterface
'name' => 'Reichelt',
'description' => 'Webscraping from reichelt.com to get part information',
'url' => 'https://www.reichelt.com/',
- 'disabled_help' => 'Enable provider in provider settings.',
- 'settings_class' => ReicheltSettings::class,
+ 'disabled_help' => 'Set PROVIDER_REICHELT_ENABLED env to 1'
];
}
@@ -63,7 +70,7 @@ class ReicheltProvider implements InfoProviderInterface
public function isActive(): bool
{
- return $this->settings->enabled;
+ return $this->enabled;
}
public function searchByKeyword(string $keyword): array
@@ -114,8 +121,8 @@ class ReicheltProvider implements InfoProviderInterface
sprintf(
'https://www.reichelt.com/?ACTION=514&id=74&article=%s&LANGUAGE=%s&CCOUNTRY=%s',
$id,
- strtoupper($this->settings->language),
- strtoupper($this->settings->country)
+ strtoupper($this->language),
+ strtoupper($this->country)
)
);
$json = $response->toArray();
@@ -126,8 +133,8 @@ class ReicheltProvider implements InfoProviderInterface
$response = $this->client->request('GET', $productPage, [
'query' => [
- 'CCTYPE' => $this->settings->includeVAT ? 'private' : 'business',
- 'currency' => $this->settings->currency,
+ 'CCTYPE' => $this->includeVAT ? 'private' : 'business',
+ 'currency' => $this->currency,
],
]);
$html = $response->getContent();
@@ -151,7 +158,7 @@ class ReicheltProvider implements InfoProviderInterface
distributor_name: self::DISTRIBUTOR_NAME,
order_number: $json[0]['article_artnr'],
prices: array_merge(
- [new PriceDTO(1.0, $priceString, $currency, $this->settings->includeVAT)]
+ [new PriceDTO(1.0, $priceString, $currency, $this->includeVAT)]
, $this->parseBatchPrices($dom, $currency)),
product_url: $productPage
);
@@ -211,7 +218,7 @@ class ReicheltProvider implements InfoProviderInterface
//Strip any non-numeric characters
$priceString = preg_replace('/[^0-9.]/', '', $priceString);
- $prices[] = new PriceDTO($minAmount, $priceString, $currency, $this->settings->includeVAT);
+ $prices[] = new PriceDTO($minAmount, $priceString, $currency, $this->includeVAT);
});
return $prices;
@@ -263,7 +270,7 @@ class ReicheltProvider implements InfoProviderInterface
private function getBaseURL(): string
{
//Without the trailing slash
- return 'https://www.reichelt.com/' . strtolower($this->settings->country) . '/' . strtolower($this->settings->language);
+ return 'https://www.reichelt.com/' . strtolower($this->country) . '/' . strtolower($this->language);
}
public function getCapabilities(): array
@@ -275,4 +282,4 @@ class ReicheltProvider implements InfoProviderInterface
ProviderCapabilities::PRICE,
];
}
-}
+}
\ No newline at end of file
diff --git a/src/Services/InfoProviderSystem/Providers/TMEClient.php b/src/Services/InfoProviderSystem/Providers/TMEClient.php
index ae2ab0d1..d4df133e 100644
--- a/src/Services/InfoProviderSystem/Providers/TMEClient.php
+++ b/src/Services/InfoProviderSystem/Providers/TMEClient.php
@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace App\Services\InfoProviderSystem\Providers;
-use App\Settings\InfoProviderSystem\TMESettings;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;
@@ -31,15 +30,15 @@ class TMEClient
{
public const BASE_URI = 'https://api.tme.eu';
- public function __construct(private readonly HttpClientInterface $tmeClient, private readonly TMESettings $settings)
+ public function __construct(private readonly HttpClientInterface $tmeClient, private readonly string $token, private readonly string $secret)
{
}
public function makeRequest(string $action, array $parameters): ResponseInterface
{
- $parameters['Token'] = $this->settings->apiToken;
- $parameters['ApiSignature'] = $this->getSignature($action, $parameters, $this->settings->apiSecret);
+ $parameters['Token'] = $this->token;
+ $parameters['ApiSignature'] = $this->getSignature($action, $parameters, $this->secret);
return $this->tmeClient->request('POST', $this->getUrlForAction($action), [
'body' => $parameters,
@@ -48,7 +47,7 @@ class TMEClient
public function isUsable(): bool
{
- return !($this->settings->apiToken === null || $this->settings->apiSecret === null);
+ return $this->token !== '' && $this->secret !== '';
}
/**
@@ -59,7 +58,7 @@ class TMEClient
public function isUsingPrivateToken(): bool
{
//Private tokens are longer than anonymous ones (50 instead of 45 characters)
- return strlen($this->settings->apiToken ?? '') > 45;
+ return strlen($this->token) > 45;
}
/**
@@ -94,4 +93,4 @@ class TMEClient
return $params;
}
-}
+}
\ No newline at end of file
diff --git a/src/Services/InfoProviderSystem/Providers/TMEProvider.php b/src/Services/InfoProviderSystem/Providers/TMEProvider.php
index 9bc73f09..32fc0c72 100644
--- a/src/Services/InfoProviderSystem/Providers/TMEProvider.php
+++ b/src/Services/InfoProviderSystem/Providers/TMEProvider.php
@@ -30,21 +30,24 @@ use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
use App\Services\InfoProviderSystem\DTOs\PriceDTO;
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
use App\Services\InfoProviderSystem\DTOs\SearchResultDTO;
-use App\Settings\InfoProviderSystem\TMESettings;
class TMEProvider implements InfoProviderInterface
{
private const VENDOR_NAME = 'TME';
+ /** @var bool If true, the prices are gross prices. If false, the prices are net prices. */
private readonly bool $get_gross_prices;
- public function __construct(private readonly TMEClient $tmeClient, private readonly TMESettings $settings)
+
+ public function __construct(private readonly TMEClient $tmeClient, private readonly string $country,
+ private readonly string $language, private readonly string $currency,
+ bool $get_gross_prices)
{
//If we have a private token, set get_gross_prices to false, as it is automatically determined by the account type then
if ($this->tmeClient->isUsingPrivateToken()) {
$this->get_gross_prices = false;
} else {
- $this->get_gross_prices = $this->settings->grossPrices;
+ $this->get_gross_prices = $get_gross_prices;
}
}
@@ -54,8 +57,7 @@ class TMEProvider implements InfoProviderInterface
'name' => 'TME',
'description' => 'This provider uses the API of TME (Transfer Multipart).',
'url' => 'https://tme.eu/',
- 'disabled_help' => 'Configure the API Token and secret in provider settings to use this provider.',
- 'settings_class' => TMESettings::class
+ 'disabled_help' => 'Configure the PROVIDER_TME_KEY and PROVIDER_TME_SECRET environment variables to use this provider.'
];
}
@@ -72,8 +74,8 @@ class TMEProvider implements InfoProviderInterface
public function searchByKeyword(string $keyword): array
{
$response = $this->tmeClient->makeRequest('Products/Search', [
- 'Country' => $this->settings->country,
- 'Language' => $this->settings->language,
+ 'Country' => $this->country,
+ 'Language' => $this->language,
'SearchPlain' => $keyword,
]);
@@ -102,8 +104,8 @@ class TMEProvider implements InfoProviderInterface
public function getDetails(string $id): PartDetailDTO
{
$response = $this->tmeClient->makeRequest('Products/GetProducts', [
- 'Country' => $this->settings->country,
- 'Language' => $this->settings->language,
+ 'Country' => $this->country,
+ 'Language' => $this->language,
'SymbolList' => [$id],
]);
@@ -147,8 +149,8 @@ class TMEProvider implements InfoProviderInterface
public function getFiles(string $id): array
{
$response = $this->tmeClient->makeRequest('Products/GetProductsFiles', [
- 'Country' => $this->settings->country,
- 'Language' => $this->settings->language,
+ 'Country' => $this->country,
+ 'Language' => $this->language,
'SymbolList' => [$id],
]);
@@ -189,9 +191,9 @@ class TMEProvider implements InfoProviderInterface
public function getVendorInfo(string $id, ?string $productURL = null): PurchaseInfoDTO
{
$response = $this->tmeClient->makeRequest('Products/GetPricesAndStocks', [
- 'Country' => $this->settings->country,
- 'Language' => $this->settings->language,
- 'Currency' => $this->settings->currency,
+ 'Country' => $this->country,
+ 'Language' => $this->language,
+ 'Currency' => $this->currency,
'GrossPrices' => $this->get_gross_prices,
'SymbolList' => [$id],
]);
@@ -232,8 +234,8 @@ class TMEProvider implements InfoProviderInterface
public function getParameters(string $id, string|null &$footprint_name = null): array
{
$response = $this->tmeClient->makeRequest('Products/GetParameters', [
- 'Country' => $this->settings->country,
- 'Language' => $this->settings->language,
+ 'Country' => $this->country,
+ 'Language' => $this->language,
'SymbolList' => [$id],
]);
@@ -296,4 +298,4 @@ class TMEProvider implements InfoProviderInterface
ProviderCapabilities::PRICE,
];
}
-}
+}
\ No newline at end of file
diff --git a/src/Services/LabelSystem/LabelHTMLGenerator.php b/src/Services/LabelSystem/LabelHTMLGenerator.php
index 8a5201ff..42aa1e72 100644
--- a/src/Services/LabelSystem/LabelHTMLGenerator.php
+++ b/src/Services/LabelSystem/LabelHTMLGenerator.php
@@ -42,7 +42,6 @@ declare(strict_types=1);
namespace App\Services\LabelSystem;
use App\Entity\LabelSystem\LabelProcessMode;
-use App\Settings\SystemSettings\CustomizationSettings;
use Symfony\Bundle\SecurityBundle\Security;
use App\Entity\Contracts\NamedElementInterface;
use App\Entity\LabelSystem\LabelOptions;
@@ -61,7 +60,7 @@ final class LabelHTMLGenerator
private readonly LabelBarcodeGenerator $barcodeGenerator,
private readonly SandboxedTwigFactory $sandboxedTwigProvider,
private readonly Security $security,
- private readonly CustomizationSettings $customizationSettings,)
+ private readonly string $partdb_title)
{
}
@@ -89,8 +88,7 @@ final class LabelHTMLGenerator
'page' => $page,
'last_page' => count($elements),
'user' => $current_user,
- 'install_title' => $this->customizationSettings->instanceName,
- 'partdb_title' => $this->customizationSettings->instanceName,
+ 'install_title' => $this->partdb_title,
'paper_width' => $options->getWidth(),
'paper_height' => $options->getHeight(),
]
diff --git a/src/Services/LabelSystem/PlaceholderProviders/GlobalProviders.php b/src/Services/LabelSystem/PlaceholderProviders/GlobalProviders.php
index f14a5863..ddd4dbf1 100644
--- a/src/Services/LabelSystem/PlaceholderProviders/GlobalProviders.php
+++ b/src/Services/LabelSystem/PlaceholderProviders/GlobalProviders.php
@@ -41,7 +41,6 @@ declare(strict_types=1);
namespace App\Services\LabelSystem\PlaceholderProviders;
-use App\Settings\SystemSettings\CustomizationSettings;
use Symfony\Bundle\SecurityBundle\Security;
use App\Entity\UserSystem\User;
use DateTime;
@@ -55,18 +54,14 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
*/
final class GlobalProviders implements PlaceholderProviderInterface
{
- public function __construct(
- private readonly Security $security,
- private readonly UrlGeneratorInterface $url_generator,
- private CustomizationSettings $customizationSettings,
- )
+ public function __construct(private readonly string $partdb_title, private readonly Security $security, private readonly UrlGeneratorInterface $url_generator)
{
}
public function replace(string $placeholder, object $label_target, array $options = []): ?string
{
if ('[[INSTALL_NAME]]' === $placeholder) {
- return $this->customizationSettings->instanceName;
+ return $this->partdb_title;
}
$user = $this->security->getUser();
diff --git a/src/Services/LabelSystem/PlaceholderProviders/PartProvider.php b/src/Services/LabelSystem/PlaceholderProviders/PartProvider.php
index 7d9e4db5..0df4d3d7 100644
--- a/src/Services/LabelSystem/PlaceholderProviders/PartProvider.php
+++ b/src/Services/LabelSystem/PlaceholderProviders/PartProvider.php
@@ -46,9 +46,7 @@ use App\Entity\Parts\Manufacturer;
use App\Entity\Parts\Footprint;
use App\Entity\Parts\Part;
use App\Services\Formatters\SIFormatter;
-use League\CommonMark\Environment\Environment;
-use League\CommonMark\Extension\InlinesOnly\InlinesOnlyExtension;
-use League\CommonMark\MarkdownConverter;
+use Parsedown;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
@@ -56,13 +54,8 @@ use Symfony\Contracts\Translation\TranslatorInterface;
*/
final class PartProvider implements PlaceholderProviderInterface
{
- private readonly MarkdownConverter $inlineConverter;
-
public function __construct(private readonly SIFormatter $siFormatter, private readonly TranslatorInterface $translator)
{
- $environment = new Environment();
- $environment->addExtension(new InlinesOnlyExtension());
- $this->inlineConverter = new MarkdownConverter($environment);
}
public function replace(string $placeholder, object $part, array $options = []): ?string
@@ -119,20 +112,22 @@ final class PartProvider implements PlaceholderProviderInterface
return $this->translator->trans($part->getManufacturingStatus()->toTranslationKey());
}
+ $parsedown = new Parsedown();
+
if ('[[DESCRIPTION]]' === $placeholder) {
- return trim($this->inlineConverter->convert($part->getDescription())->getContent());
+ return $parsedown->line($part->getDescription());
}
if ('[[DESCRIPTION_T]]' === $placeholder) {
- return trim(strip_tags($this->inlineConverter->convert($part->getDescription())->getContent()));
+ return strip_tags((string) $parsedown->line($part->getDescription()));
}
if ('[[COMMENT]]' === $placeholder) {
- return trim($this->inlineConverter->convert($part->getComment())->getContent());
+ return $parsedown->line($part->getComment());
}
if ('[[COMMENT_T]]' === $placeholder) {
- return trim(strip_tags($this->inlineConverter->convert($part->getComment())->getContent()));
+ return strip_tags((string) $parsedown->line($part->getComment()));
}
return null;
diff --git a/src/Services/LogSystem/EventCommentNeededHelper.php b/src/Services/LogSystem/EventCommentNeededHelper.php
index cacf525f..8440f199 100644
--- a/src/Services/LogSystem/EventCommentNeededHelper.php
+++ b/src/Services/LogSystem/EventCommentNeededHelper.php
@@ -22,25 +22,37 @@ declare(strict_types=1);
*/
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.
* It is configured using the "enforce_change_comments_for" config parameter.
* @see \App\Tests\Services\LogSystem\EventCommentNeededHelperTest
*/
-final class EventCommentNeededHelper
+class EventCommentNeededHelper
{
- public function __construct(private readonly HistorySettings $settings)
- {
+ final public const VALID_OPERATION_TYPES = [
+ '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
*/
- public function isCommentNeeded(EventCommentType $comment_type): bool
+ public function isCommentNeeded(string $comment_type): bool
{
- return in_array($comment_type, $this->settings->enforceComments, true);
+ //Check if the comment type is valid
+ 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);
}
}
diff --git a/src/Services/LogSystem/EventCommentType.php b/src/Services/LogSystem/EventCommentType.php
deleted file mode 100644
index d68c03b2..00000000
--- a/src/Services/LogSystem/EventCommentType.php
+++ /dev/null
@@ -1,47 +0,0 @@
-.
- */
-
-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);
- }
-}
diff --git a/src/Services/Parts/PricedetailHelper.php b/src/Services/Parts/PricedetailHelper.php
index b2e1340f..092cc278 100644
--- a/src/Services/Parts/PricedetailHelper.php
+++ b/src/Services/Parts/PricedetailHelper.php
@@ -25,7 +25,6 @@ namespace App\Services\Parts;
use App\Entity\Parts\Part;
use App\Entity\PriceInformations\Currency;
use App\Entity\PriceInformations\Pricedetail;
-use App\Settings\SystemSettings\LocalizationSettings;
use Brick\Math\BigDecimal;
use Brick\Math\RoundingMode;
use Doctrine\ORM\PersistentCollection;
@@ -40,7 +39,7 @@ class PricedetailHelper
{
protected string $locale;
- public function __construct()
+ public function __construct(protected string $base_currency)
{
$this->locale = Locale::getDefault();
}
diff --git a/src/Services/System/BannerHelper.php b/src/Services/System/BannerHelper.php
index bb27158f..3d5daef9 100644
--- a/src/Services/System/BannerHelper.php
+++ b/src/Services/System/BannerHelper.php
@@ -23,14 +23,12 @@ declare(strict_types=1);
namespace App\Services\System;
-use App\Settings\SystemSettings\CustomizationSettings;
-
/**
* Helper service to retrieve the banner of this Part-DB installation
*/
class BannerHelper
{
- public function __construct(private readonly CustomizationSettings $customizationSettings)
+ public function __construct(private readonly string $project_dir, private readonly string $partdb_banner)
{
}
@@ -41,6 +39,18 @@ class BannerHelper
*/
public function getBanner(): string
{
- return $this->customizationSettings->banner ?? "";
+ $banner = $this->partdb_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;
}
-}
+}
\ No newline at end of file
diff --git a/src/Services/System/UpdateAvailableManager.php b/src/Services/System/UpdateAvailableManager.php
index 82cfb84e..31cb3266 100644
--- a/src/Services/System/UpdateAvailableManager.php
+++ b/src/Services/System/UpdateAvailableManager.php
@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace App\Services\System;
-use App\Settings\SystemSettings\PrivacySettings;
use Psr\Log\LoggerInterface;
use Shivas\VersioningBundle\Service\VersionManagerInterface;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
@@ -44,7 +43,7 @@ class UpdateAvailableManager
public function __construct(private readonly HttpClientInterface $httpClient,
private readonly CacheInterface $updateCache, private readonly VersionManagerInterface $versionManager,
- private readonly PrivacySettings $privacySettings, private readonly LoggerInterface $logger,
+ private readonly bool $check_for_updates, private readonly LoggerInterface $logger,
#[Autowire(param: 'kernel.debug')] private readonly bool $is_dev_mode)
{
@@ -84,7 +83,7 @@ class UpdateAvailableManager
public function isUpdateAvailable(): bool
{
//If we don't want to check for updates, we can return false
- if (!$this->privacySettings->checkForUpdates) {
+ if (!$this->check_for_updates) {
return false;
}
@@ -102,7 +101,7 @@ class UpdateAvailableManager
private function getLatestVersionInfo(): array
{
//If we don't want to check for updates, we can return dummy data
- if (!$this->privacySettings->checkForUpdates) {
+ if (!$this->check_for_updates) {
return [
'version' => '0.0.1',
'url' => 'update-checking-disabled'
diff --git a/src/Services/Tools/ExchangeRateUpdater.php b/src/Services/Tools/ExchangeRateUpdater.php
index 7c14b16f..eac6de16 100644
--- a/src/Services/Tools/ExchangeRateUpdater.php
+++ b/src/Services/Tools/ExchangeRateUpdater.php
@@ -23,14 +23,13 @@ declare(strict_types=1);
namespace App\Services\Tools;
use App\Entity\PriceInformations\Currency;
-use App\Settings\SystemSettings\LocalizationSettings;
use Brick\Math\BigDecimal;
use Brick\Math\RoundingMode;
use Swap\Swap;
class ExchangeRateUpdater
{
- public function __construct(private LocalizationSettings $localizationSettings, private readonly Swap $swap)
+ public function __construct(private readonly string $base_currency, private readonly Swap $swap)
{
}
@@ -40,7 +39,7 @@ class ExchangeRateUpdater
public function update(Currency $currency): Currency
{
//Currency pairs are always in the format "BASE/QUOTE"
- $rate = $this->swap->latest($this->localizationSettings->baseCurrency.'/'.$currency->getIsoCode());
+ $rate = $this->swap->latest($this->base_currency.'/'.$currency->getIsoCode());
//The rate says how many quote units are worth one base unit
//So we need to invert it to get the exchange rate
diff --git a/src/Services/Trees/ToolsTreeBuilder.php b/src/Services/Trees/ToolsTreeBuilder.php
index f7a9d1c4..18571306 100644
--- a/src/Services/Trees/ToolsTreeBuilder.php
+++ b/src/Services/Trees/ToolsTreeBuilder.php
@@ -289,13 +289,6 @@ class ToolsTreeBuilder
))->setIcon('fa-fw fa-treeview fa-solid fa-database');
}
- if ($this->security->isGranted('@config.change_system_settings')) {
- $nodes[] = (new TreeViewNode(
- $this->translator->trans('tree.tools.system.settings'),
- $this->urlGenerator->generate('system_settings')
- ))->setIcon('fa fa-fw fa-gears fa-solid');
- }
-
return $nodes;
}
}
diff --git a/src/Services/Trees/TreeViewGenerator.php b/src/Services/Trees/TreeViewGenerator.php
index 73ffa5ba..c66f2ee2 100644
--- a/src/Services/Trees/TreeViewGenerator.php
+++ b/src/Services/Trees/TreeViewGenerator.php
@@ -38,7 +38,6 @@ use App\Repository\StructuralDBElementRepository;
use App\Services\Cache\ElementCacheTagGenerator;
use App\Services\Cache\UserCacheKeyGenerator;
use App\Services\EntityURLGenerator;
-use App\Settings\BehaviorSettings\SidebarSettings;
use Doctrine\ORM\EntityManagerInterface;
use InvalidArgumentException;
use RecursiveIteratorIterator;
@@ -54,10 +53,6 @@ use function count;
*/
class TreeViewGenerator
{
-
- private readonly bool $rootNodeExpandedByDefault;
- private readonly bool $rootNodeEnabled;
-
public function __construct(
protected EntityURLGenerator $urlGenerator,
protected EntityManagerInterface $em,
@@ -66,10 +61,11 @@ class TreeViewGenerator
protected UserCacheKeyGenerator $keyGenerator,
protected TranslatorInterface $translator,
private readonly UrlGeneratorInterface $router,
- private readonly SidebarSettings $sidebarSettings,
+ protected bool $rootNodeExpandedByDefault,
+ protected bool $rootNodeEnabled,
+ //TODO: Make this configurable in the future
+ protected bool $rootNodeRedirectsToNewEntity = false,
) {
- $this->rootNodeEnabled = $this->sidebarSettings->rootNodeEnabled;
- $this->rootNodeExpandedByDefault = $this->sidebarSettings->rootNodeExpanded;
}
/**
@@ -192,7 +188,7 @@ class TreeViewGenerator
protected function entityClassToRootNodeHref(string $class): ?string
{
//If the root node should redirect to the new entity page, we return the URL for the new entity.
- if ($this->sidebarSettings->rootNodeRedirectsToNewEntity) {
+ if ($this->rootNodeRedirectsToNewEntity) {
return match ($class) {
Category::class => $this->router->generate('category_new'),
StorageLocation::class => $this->router->generate('store_location_new'),
diff --git a/src/Services/UserSystem/PermissionPresetsHelper.php b/src/Services/UserSystem/PermissionPresetsHelper.php
index 554da8b3..eeb80f61 100644
--- a/src/Services/UserSystem/PermissionPresetsHelper.php
+++ b/src/Services/UserSystem/PermissionPresetsHelper.php
@@ -105,9 +105,6 @@ class PermissionPresetsHelper
$this->permissionResolver->setAllOperationsOfPermission($perm_holder, 'suppliers', PermissionData::ALLOW);
$this->permissionResolver->setAllOperationsOfPermission($perm_holder, 'projects', PermissionData::ALLOW);
- //Allow to change system settings
- $this->permissionResolver->setPermission($perm_holder, 'config', 'change_system_settings', PermissionData::ALLOW);
-
//Allow to manage Oauth tokens
$this->permissionResolver->setPermission($perm_holder, 'system', 'manage_oauth_tokens', PermissionData::ALLOW);
//Allow to show updates
diff --git a/src/Services/UserSystem/UserAvatarHelper.php b/src/Services/UserSystem/UserAvatarHelper.php
index 9dbe9c12..a694fa77 100644
--- a/src/Services/UserSystem/UserAvatarHelper.php
+++ b/src/Services/UserSystem/UserAvatarHelper.php
@@ -30,7 +30,6 @@ use App\Entity\Attachments\UserAttachment;
use App\Entity\UserSystem\User;
use App\Services\Attachments\AttachmentSubmitHandler;
use App\Services\Attachments\AttachmentURLGenerator;
-use App\Settings\SystemSettings\PrivacySettings;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Asset\Packages;
use Symfony\Component\HttpFoundation\File\UploadedFile;
@@ -43,7 +42,7 @@ class UserAvatarHelper
public const IMG_DEFAULT_AVATAR_PATH = 'img/default_avatar.svg';
public function __construct(
- private readonly PrivacySettings $privacySettings,
+ private readonly bool $use_gravatar,
private readonly Packages $packages,
private readonly AttachmentURLGenerator $attachmentURLGenerator,
private readonly EntityManagerInterface $entityManager,
@@ -66,7 +65,7 @@ class UserAvatarHelper
}
//If not check if gravatar is enabled (then use gravatar URL)
- if ($this->privacySettings->useGravatar) {
+ if ($this->use_gravatar) {
return $this->getGravatar($user, 200); //200px wide picture
}
@@ -83,7 +82,7 @@ class UserAvatarHelper
}
//If not check if gravatar is enabled (then use gravatar URL)
- if ($this->privacySettings->useGravatar) {
+ if ($this->use_gravatar) {
return $this->getGravatar($user, 50); //50px wide picture
}
@@ -100,7 +99,7 @@ class UserAvatarHelper
}
//If not check if gravatar is enabled (then use gravatar URL)
- if ($this->privacySettings->useGravatar) {
+ if ($this->use_gravatar) {
return $this->getGravatar($user, 150);
}
diff --git a/src/Settings/AppSettings.php b/src/Settings/AppSettings.php
deleted file mode 100644
index 1695638a..00000000
--- a/src/Settings/AppSettings.php
+++ /dev/null
@@ -1,52 +0,0 @@
-.
- */
-
-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;
-}
\ No newline at end of file
diff --git a/src/Settings/BehaviorSettings/BehaviorSettings.php b/src/Settings/BehaviorSettings/BehaviorSettings.php
deleted file mode 100644
index 1251a097..00000000
--- a/src/Settings/BehaviorSettings/BehaviorSettings.php
+++ /dev/null
@@ -1,43 +0,0 @@
-.
- */
-
-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;
-
- #[EmbeddedSettings]
- public ?PartInfoSettings $partInfo = null;
-}
\ No newline at end of file
diff --git a/src/Settings/BehaviorSettings/PartInfoSettings.php b/src/Settings/BehaviorSettings/PartInfoSettings.php
deleted file mode 100644
index 4c44b9bb..00000000
--- a/src/Settings/BehaviorSettings/PartInfoSettings.php
+++ /dev/null
@@ -1,43 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-
-namespace App\Settings\BehaviorSettings;
-
-use App\Settings\SettingsIcon;
-use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
-use Jbtronics\SettingsBundle\Settings\Settings;
-use Jbtronics\SettingsBundle\Settings\SettingsParameter;
-use Symfony\Component\Translation\TranslatableMessage as TM;
-
-#[Settings(name: "part_info", label: new TM("settings.behavior.part_info"))]
-#[SettingsIcon('fa-circle-info')]
-class PartInfoSettings
-{
- /**
- * Whether to show the part image overlays in the part info view
- * @var bool
- */
- #[SettingsParameter(label: new TM("settings.behavior.part_info.show_part_image_overlay"), description: new TM("settings.behavior.part_info.show_part_image_overlay.help"),
- envVar: "bool:SHOW_PART_IMAGE_OVERLAY", envVarMode: EnvVarMode::OVERWRITE)]
- public bool $showPartImageOverlay = true;
-}
\ No newline at end of file
diff --git a/src/Settings/BehaviorSettings/PartTableColumns.php b/src/Settings/BehaviorSettings/PartTableColumns.php
deleted file mode 100644
index eea6ad86..00000000
--- a/src/Settings/BehaviorSettings/PartTableColumns.php
+++ /dev/null
@@ -1,66 +0,0 @@
-.
- */
-
-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);
- }
-}
\ No newline at end of file
diff --git a/src/Settings/BehaviorSettings/SidebarItems.php b/src/Settings/BehaviorSettings/SidebarItems.php
deleted file mode 100644
index cb0e60be..00000000
--- a/src/Settings/BehaviorSettings/SidebarItems.php
+++ /dev/null
@@ -1,53 +0,0 @@
-.
- */
-
-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);
- }
-}
\ No newline at end of file
diff --git a/src/Settings/BehaviorSettings/SidebarSettings.php b/src/Settings/BehaviorSettings/SidebarSettings.php
deleted file mode 100644
index 1266fa47..00000000
--- a/src/Settings/BehaviorSettings/SidebarSettings.php
+++ /dev/null
@@ -1,76 +0,0 @@
-.
- */
-
-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;
-
- /**
- * @var bool Whether the root node should redirect to a new entity creation page when clicked.
- */
- #[SettingsParameter(label: new TM("settings.behavior.sidebar.rootNodeRedirectsToNewEntity"))]
- public bool $rootNodeRedirectsToNewEntity = false;
-}
\ No newline at end of file
diff --git a/src/Settings/BehaviorSettings/TableSettings.php b/src/Settings/BehaviorSettings/TableSettings.php
deleted file mode 100644
index 7b4e7912..00000000
--- a/src/Settings/BehaviorSettings/TableSettings.php
+++ /dev/null
@@ -1,90 +0,0 @@
-.
- */
-
-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;
- }
-
-}
\ No newline at end of file
diff --git a/src/Settings/InfoProviderSystem/DigikeySettings.php b/src/Settings/InfoProviderSystem/DigikeySettings.php
deleted file mode 100644
index f42c1c1c..00000000
--- a/src/Settings/InfoProviderSystem/DigikeySettings.php
+++ /dev/null
@@ -1,73 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-
-namespace App\Settings\InfoProviderSystem;
-
-use App\Form\Type\APIKeyType;
-use App\Settings\SettingsIcon;
-use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
-use Jbtronics\SettingsBundle\Settings\Settings;
-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\Translation\TranslatableMessage as TM;
-use Jbtronics\SettingsBundle\Settings\SettingsParameter;
-use Symfony\Component\Validator\Constraints as Assert;
-
-#[Settings(label: new TM("settings.ips.digikey"))]
-#[SettingsIcon("fa-plug")]
-class DigikeySettings
-{
- use SettingsTrait;
-
- #[SettingsParameter(
- label: new TM("settings.ips.digikey.client_id"),
- formType: APIKeyType::class,
- envVar: "PROVIDER_DIGIKEY_CLIENT_ID", envVarMode: EnvVarMode::OVERWRITE
- )]
- public ?string $clientId = null;
-
- #[SettingsParameter(
- label: new TM("settings.ips.digikey.secret"),
- formType: APIKeyType::class,
- envVar: "PROVIDER_DIGIKEY_SECRET", envVarMode: EnvVarMode::OVERWRITE
- )]
- public ?string $secret = null;
-
- #[SettingsParameter(label: new TM("settings.ips.tme.currency"), formType: CurrencyType::class,
- formOptions: ["preferred_choices" => ["EUR", "USD", "CHF", "GBP"]],
- envVar: "PROVIDER_DIGIKEY_CURRENCY", envVarMode: EnvVarMode::OVERWRITE)]
- #[Assert\Currency()]
- public string $currency = "EUR";
-
- #[SettingsParameter(label: new TM("settings.ips.tme.country"), formType: CountryType::class,
- envVar: "PROVIDER_DIGIKEY_COUNTRY", envVarMode: EnvVarMode::OVERWRITE)]
- #[Assert\Country]
- public string $country = "DE";
-
- #[SettingsParameter(label: new TM("settings.ips.tme.language"), formType: LanguageType::class,
- envVar: "PROVIDER_DIGIKEY_LANGUAGE", envVarMode: EnvVarMode::OVERWRITE)]
- #[Assert\Language]
- public string $language = "en";
-}
diff --git a/src/Settings/InfoProviderSystem/Element14Settings.php b/src/Settings/InfoProviderSystem/Element14Settings.php
deleted file mode 100644
index a4cdbf0d..00000000
--- a/src/Settings/InfoProviderSystem/Element14Settings.php
+++ /dev/null
@@ -1,48 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-
-namespace App\Settings\InfoProviderSystem;
-
-use App\Form\Type\APIKeyType;
-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.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"),#
- formType: APIKeyType::class,
- formOptions: ["help_html" => true], envVar: "PROVIDER_ELEMENT14_KEY", envVarMode: EnvVarMode::OVERWRITE)]
- 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", envVarMode: EnvVarMode::OVERWRITE)]
- public string $storeId = "de.farnell.com";
-}
diff --git a/src/Settings/InfoProviderSystem/InfoProviderSettings.php b/src/Settings/InfoProviderSystem/InfoProviderSettings.php
deleted file mode 100644
index 3c7159cb..00000000
--- a/src/Settings/InfoProviderSystem/InfoProviderSettings.php
+++ /dev/null
@@ -1,61 +0,0 @@
-.
- */
-
-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 ?DigikeySettings $digikey = null;
-
- #[EmbeddedSettings]
- public ?MouserSettings $mouser = null;
-
- #[EmbeddedSettings]
- public ?TMESettings $tme = null;
-
- #[EmbeddedSettings]
- public ?Element14Settings $element14 = null;
-
- #[EmbeddedSettings]
- public ?OctopartSettings $octopartSettings = null;
-
- #[EmbeddedSettings]
- public ?LCSCSettings $lcsc = null;
-
- #[EmbeddedSettings]
- public ?OEMSecretsSettings $oemsecrets = null;
-
- #[EmbeddedSettings]
- public ?ReicheltSettings $reichelt = null;
-
- #[EmbeddedSettings]
- public ?PollinSettings $pollin = null;
-}
\ No newline at end of file
diff --git a/src/Settings/InfoProviderSystem/LCSCSettings.php b/src/Settings/InfoProviderSystem/LCSCSettings.php
deleted file mode 100644
index 906838e2..00000000
--- a/src/Settings/InfoProviderSystem/LCSCSettings.php
+++ /dev/null
@@ -1,49 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-
-namespace App\Settings\InfoProviderSystem;
-
-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\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", envVarMode: EnvVarMode::OVERWRITE)]
- public bool $enabled = false;
-
- #[SettingsParameter(label: new TM("settings.ips.lcsc.currency"), formType: CurrencyType::class,
- envVar: "string:PROVIDER_LCSC_CURRENCY", envVarMode: EnvVarMode::OVERWRITE)]
- #[Assert\Currency()]
- public string $currency = 'EUR';
-}
\ No newline at end of file
diff --git a/src/Settings/InfoProviderSystem/MouserSearchOptions.php b/src/Settings/InfoProviderSystem/MouserSearchOptions.php
deleted file mode 100644
index 429fab56..00000000
--- a/src/Settings/InfoProviderSystem/MouserSearchOptions.php
+++ /dev/null
@@ -1,47 +0,0 @@
-.
- */
-
-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);
- }
-}
\ No newline at end of file
diff --git a/src/Settings/InfoProviderSystem/MouserSettings.php b/src/Settings/InfoProviderSystem/MouserSettings.php
deleted file mode 100644
index 0abaa7f2..00000000
--- a/src/Settings/InfoProviderSystem/MouserSettings.php
+++ /dev/null
@@ -1,69 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-
-namespace App\Settings\InfoProviderSystem;
-
-use App\Form\Type\APIKeyType;
-use App\Settings\SettingsIcon;
-use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
-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"),
- formType: APIKeyType::class,
- formOptions: ["help_html" => true], envVar: "PROVIDER_MOUSER_KEY", envVarMode: EnvVarMode::OVERWRITE)]
- 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", envVarMode: EnvVarMode::OVERWRITE)]
- #[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", envVarMode: EnvVarMode::OVERWRITE, 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;
- }
-
-}
diff --git a/src/Settings/InfoProviderSystem/OEMSecretsSettings.php b/src/Settings/InfoProviderSystem/OEMSecretsSettings.php
deleted file mode 100644
index 77cf9080..00000000
--- a/src/Settings/InfoProviderSystem/OEMSecretsSettings.php
+++ /dev/null
@@ -1,90 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-
-namespace App\Settings\InfoProviderSystem;
-
-use App\Form\Type\APIKeyType;
-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\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"),
- formType: APIKeyType::class,
- envVar: "PROVIDER_OEMSECRETS_KEY", envVarMode: EnvVarMode::OVERWRITE)]
- 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", envVarMode: EnvVarMode::OVERWRITE)]
- 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", envVarMode: EnvVarMode::OVERWRITE)]
- #[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", envVarMode: EnvVarMode::OVERWRITE)]
- 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", envVarMode: EnvVarMode::OVERWRITE)]
- 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;
- }
-}
diff --git a/src/Settings/InfoProviderSystem/OEMSecretsSortMode.php b/src/Settings/InfoProviderSystem/OEMSecretsSortMode.php
deleted file mode 100644
index e479e07e..00000000
--- a/src/Settings/InfoProviderSystem/OEMSecretsSortMode.php
+++ /dev/null
@@ -1,46 +0,0 @@
-.
- */
-
-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);
- }
-}
\ No newline at end of file
diff --git a/src/Settings/InfoProviderSystem/OctopartSettings.php b/src/Settings/InfoProviderSystem/OctopartSettings.php
deleted file mode 100644
index c28da459..00000000
--- a/src/Settings/InfoProviderSystem/OctopartSettings.php
+++ /dev/null
@@ -1,81 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-
-namespace App\Settings\InfoProviderSystem;
-
-use App\Form\Type\APIKeyType;
-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\CountryType;
-use Symfony\Component\Form\Extension\Core\Type\CurrencyType;
-use Symfony\Component\Form\Extension\Core\Type\NumberType;
-use Symfony\Component\Translation\TranslatableMessage as TM;
-use Symfony\Component\Validator\Constraints as Assert;
-
-#[Settings(label: new TM("settings.ips.octopart"))]
-#[SettingsIcon("fa-plug")]
-class OctopartSettings
-{
- use SettingsTrait;
-
- #[SettingsParameter(
- label: new TM("settings.ips.digikey.client_id"),
- formType: APIKeyType::class,
- envVar: "PROVIDER_OCTOPART_CLIENT_ID", envVarMode: EnvVarMode::OVERWRITE,
- )]
- public ?string $clientId = null;
-
- #[SettingsParameter(
- label: new TM("settings.ips.digikey.secret"),
- formType: APIKeyType::class,
- envVar: "PROVIDER_OCTOPART_SECRET", envVarMode: EnvVarMode::OVERWRITE
- )]
- public ?string $secret = null;
-
- #[SettingsParameter(label: new TM("settings.ips.tme.currency"), formType: CurrencyType::class,
- formOptions: ["preferred_choices" => ["EUR", "USD", "CHF", "GBP"]],
- envVar: "PROVIDER_OCTOPART_CURRENCY", envVarMode: EnvVarMode::OVERWRITE)]
- #[Assert\Currency()]
- public string $currency = "EUR";
-
- #[SettingsParameter(label: new TM("settings.ips.tme.country"), formType: CountryType::class,
- envVar: "PROVIDER_OCTOPART_COUNTRY", envVarMode: EnvVarMode::OVERWRITE)]
- #[Assert\Country]
- public string $country = "DE";
-
- #[SettingsParameter(label: new TM("settings.ips.octopart.searchLimit"), description: new TM("settings.ips.octopart.searchLimit.help"),
- formType: NumberType::class, formOptions: ["attr" => ["min" => 1, "max" => 100]],
- envVar: "int:PROVIDER_OCTOPART_SEARCH_LIMIT", envVarMode: EnvVarMode::OVERWRITE)]
- #[Assert\Range(min: 1, max: 100)]
- public int $searchLimit = 10;
-
- #[SettingsParameter(label: new TM("settings.ips.octopart.onlyAuthorizedSellers"),
- description: new TM("settings.ips.octopart.onlyAuthorizedSellers.help"),
- envVar: "bool:PROVIDER_OCTOPART_ONLY_AUTHORIZED_SELLERS", envVarMode: EnvVarMode::OVERWRITE
- )]
- public bool $onlyAuthorizedSellers = true;
-
-}
diff --git a/src/Settings/InfoProviderSystem/PollinSettings.php b/src/Settings/InfoProviderSystem/PollinSettings.php
deleted file mode 100644
index 033d8b7e..00000000
--- a/src/Settings/InfoProviderSystem/PollinSettings.php
+++ /dev/null
@@ -1,39 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-
-namespace App\Settings\InfoProviderSystem;
-
-use App\Settings\SettingsIcon;
-use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
-use Jbtronics\SettingsBundle\Settings\Settings;
-use Jbtronics\SettingsBundle\Settings\SettingsParameter;
-use Symfony\Component\Translation\TranslatableMessage as TM;
-
-#[Settings(label: new TM("settings.ips.pollin"), description: new TM("settings.ips.pollin.help"))]
-#[SettingsIcon("fa-plug")]
-class PollinSettings
-{
- #[SettingsParameter(label: new TM("settings.ips.lcsc.enabled"),
- envVar: "bool:PROVIDER_POLLIN_ENABLED", envVarMode: EnvVarMode::OVERWRITE)]
- public bool $enabled = false;
-}
\ No newline at end of file
diff --git a/src/Settings/InfoProviderSystem/ReicheltSettings.php b/src/Settings/InfoProviderSystem/ReicheltSettings.php
deleted file mode 100644
index 588447de..00000000
--- a/src/Settings/InfoProviderSystem/ReicheltSettings.php
+++ /dev/null
@@ -1,68 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-
-namespace App\Settings\InfoProviderSystem;
-
-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\CountryType;
-use Symfony\Component\Form\Extension\Core\Type\CurrencyType;
-use Symfony\Component\Form\Extension\Core\Type\LanguageType;
-use Symfony\Component\Translation\TranslatableMessage as TM;
-use Symfony\Component\Validator\Constraints as Assert;
-
-#[Settings(label: new TM("settings.ips.reichelt"), description: new TM("settings.ips.reichelt.help"))]
-#[SettingsIcon("fa-plug")]
-class ReicheltSettings
-{
- use SettingsTrait;
-
- public const SUPPORTED_LANGUAGE = ["en", "de", "fr", "nl", "pl", "it", "es"];
-
- #[SettingsParameter(label: new TM("settings.ips.lcsc.enabled"),
- envVar: "bool:PROVIDER_REICHELT_ENABLED", envVarMode: EnvVarMode::OVERWRITE)]
- public bool $enabled = false;
-
- #[SettingsParameter(label: new TM("settings.ips.tme.currency"), formType: CurrencyType::class, formOptions: ["preferred_choices" => ["EUR"]],
- envVar: "PROVIDER_REICHELT_CURRENCY", envVarMode: EnvVarMode::OVERWRITE)]
- public string $currency = "EUR";
-
- #[SettingsParameter(label: new TM("settings.ips.tme.language"), formType: LanguageType::class, formOptions: ["preferred_choices" => self::SUPPORTED_LANGUAGE],
- envVar: "PROVIDER_REICHELT_LANGUAGE", envVarMode: EnvVarMode::OVERWRITE)]
- #[Assert\Language()]
- #[Assert\Choice(choices: self::SUPPORTED_LANGUAGE)]
- public string $language = "en";
-
- #[SettingsParameter(label: new TM("settings.ips.tme.country"), formType: CountryType::class, formOptions: ["preferred_choices" => ["DE", "PL", "GB", "FR"]],
- envVar: "PROVIDER_REICHELT_COUNTRY", envVarMode: EnvVarMode::OVERWRITE)]
- #[Assert\Country]
- public string $country = "DE";
-
- #[SettingsParameter(label: new TM("settings.ips.reichelt.include_vat"),
- envVar: "bool:PROVIDER_REICHELT_INCLUDE_VAT", envVarMode: EnvVarMode::OVERWRITE)]
- public bool $includeVAT = true;
-
-}
\ No newline at end of file
diff --git a/src/Settings/InfoProviderSystem/TMESettings.php b/src/Settings/InfoProviderSystem/TMESettings.php
deleted file mode 100644
index d6f03d34..00000000
--- a/src/Settings/InfoProviderSystem/TMESettings.php
+++ /dev/null
@@ -1,75 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-
-namespace App\Settings\InfoProviderSystem;
-
-use App\Form\Type\APIKeyType;
-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\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"),
- formType: APIKeyType::class, formOptions: ["help_html" => true],
- envVar: "PROVIDER_TME_KEY", envVarMode: EnvVarMode::OVERWRITE)]
- public ?string $apiToken = null;
-
- #[SettingsParameter(label: new TM("settings.ips.tme.secret"),
- formType: APIKeyType::class,
- envVar: "PROVIDER_TME_SECRET", envVarMode: EnvVarMode::OVERWRITE)]
- 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", envVarMode: EnvVarMode::OVERWRITE)]
- #[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", envVarMode: EnvVarMode::OVERWRITE)]
- #[Assert\Language]
- public string $language = "en";
-
- #[SettingsParameter(label: new TM("settings.ips.tme.country"), formType: CountryType::class, formOptions: ["preferred_choices" => ["DE", "PL", "GB", "FR"]],
- envVar: "PROVIDER_TME_COUNTRY", envVarMode: EnvVarMode::OVERWRITE)]
- #[Assert\Country]
- public string $country = "DE";
-
- #[SettingsParameter(label: new TM("settings.ips.tme.grossPrices"),
- envVar: "bool:PROVIDER_TME_GET_GROSS_PRICES", envVarMode: EnvVarMode::OVERWRITE)]
- public bool $grossPrices = true;
-}
diff --git a/src/Settings/MiscSettings/ExchangeRateSettings.php b/src/Settings/MiscSettings/ExchangeRateSettings.php
deleted file mode 100644
index 744523c6..00000000
--- a/src/Settings/MiscSettings/ExchangeRateSettings.php
+++ /dev/null
@@ -1,43 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-
-namespace App\Settings\MiscSettings;
-
-use App\Form\Type\APIKeyType;
-use App\Settings\SettingsIcon;
-use Jbtronics\SettingsBundle\Metadata\EnvVarMode;
-use Jbtronics\SettingsBundle\Settings\Settings;
-use Jbtronics\SettingsBundle\Settings\SettingsParameter;
-use Symfony\Component\Translation\TranslatableMessage as TM;
-
-#[Settings(name: "exchange_rate", label: new TM("settings.misc.exchange_rate"))]
-#[SettingsIcon("fa-money-bill-transfer")]
-class ExchangeRateSettings
-{
- #[SettingsParameter(label: new TM("settings.misc.exchange_rate.fixer_api_key"),
- description: new TM("settings.misc.exchange_rate.fixer_api_key.help"),
- formType: APIKeyType::class,
- envVar: "FIXER_API_KEY", envVarMode: EnvVarMode::OVERWRITE,
- )]
- public ?string $fixerApiKey = null;
-}
diff --git a/src/Settings/MiscSettings/KiCadEDASettings.php b/src/Settings/MiscSettings/KiCadEDASettings.php
deleted file mode 100644
index d8f1026d..00000000
--- a/src/Settings/MiscSettings/KiCadEDASettings.php
+++ /dev/null
@@ -1,46 +0,0 @@
-.
- */
-
-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;
-}
\ No newline at end of file
diff --git a/src/Settings/MiscSettings/MiscSettings.php b/src/Settings/MiscSettings/MiscSettings.php
deleted file mode 100644
index b8a3a73f..00000000
--- a/src/Settings/MiscSettings/MiscSettings.php
+++ /dev/null
@@ -1,37 +0,0 @@
-.
- */
-
-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;
-
- #[EmbeddedSettings]
- public ?ExchangeRateSettings $exchangeRate = null;
-}
\ No newline at end of file
diff --git a/src/Settings/SettingsIcon.php b/src/Settings/SettingsIcon.php
deleted file mode 100644
index 45bfc544..00000000
--- a/src/Settings/SettingsIcon.php
+++ /dev/null
@@ -1,32 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-
-namespace App\Settings;
-
-#[\Attribute(\Attribute::TARGET_CLASS)]
-class SettingsIcon
-{
- public function __construct(public string $icon)
- {
- }
-}
\ No newline at end of file
diff --git a/src/Settings/SystemSettings.php b/src/Settings/SystemSettings.php
deleted file mode 100644
index 83d00afc..00000000
--- a/src/Settings/SystemSettings.php
+++ /dev/null
@@ -1,51 +0,0 @@
-.
- */
-
-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;
-}
\ No newline at end of file
diff --git a/src/Settings/SystemSettings/AttachmentsSettings.php b/src/Settings/SystemSettings/AttachmentsSettings.php
deleted file mode 100644
index 6d15c639..00000000
--- a/src/Settings/SystemSettings/AttachmentsSettings.php
+++ /dev/null
@@ -1,61 +0,0 @@
-.
- */
-
-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;
-}
\ No newline at end of file
diff --git a/src/Settings/SystemSettings/CustomizationSettings.php b/src/Settings/SystemSettings/CustomizationSettings.php
deleted file mode 100644
index d7e92a51..00000000
--- a/src/Settings/SystemSettings/CustomizationSettings.php
+++ /dev/null
@@ -1,62 +0,0 @@
-.
- */
-
-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'],
- envVar: "BANNER", envVarMode: EnvVarMode::OVERWRITE,
- )]
- public ?string $banner = null;
-
- #[SettingsParameter(
- label: new TM("settings.system.customization.theme"),
- formType: ThemeChoiceType::class, formOptions: ['placeholder' => false]
- )]
- #[ValidTheme]
- public string $theme = 'bootstrap';
-}
diff --git a/src/Settings/SystemSettings/HistorySettings.php b/src/Settings/SystemSettings/HistorySettings.php
deleted file mode 100644
index 46003c6d..00000000
--- a/src/Settings/SystemSettings/HistorySettings.php
+++ /dev/null
@@ -1,87 +0,0 @@
-.
- */
-
-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,
- formOptions: ['required' => false, "empty_data" => []],
- 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);
- }
-}
\ No newline at end of file
diff --git a/src/Settings/SystemSettings/LocalizationSettings.php b/src/Settings/SystemSettings/LocalizationSettings.php
deleted file mode 100644
index 434a4e69..00000000
--- a/src/Settings/SystemSettings/LocalizationSettings.php
+++ /dev/null
@@ -1,63 +0,0 @@
-.
- */
-
-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';
-}
\ No newline at end of file
diff --git a/src/Settings/SystemSettings/PrivacySettings.php b/src/Settings/SystemSettings/PrivacySettings.php
deleted file mode 100644
index 1ef3c635..00000000
--- a/src/Settings/SystemSettings/PrivacySettings.php
+++ /dev/null
@@ -1,53 +0,0 @@
-.
- */
-
-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;
-}
\ No newline at end of file
diff --git a/src/State/PartDBInfoProvider.php b/src/State/PartDBInfoProvider.php
index b3496cad..c6760ede 100644
--- a/src/State/PartDBInfoProvider.php
+++ b/src/State/PartDBInfoProvider.php
@@ -9,8 +9,6 @@ use ApiPlatform\State\ProviderInterface;
use App\ApiResource\PartDBInfo;
use App\Services\Misc\GitVersionInfo;
use App\Services\System\BannerHelper;
-use App\Settings\SystemSettings\CustomizationSettings;
-use App\Settings\SystemSettings\LocalizationSettings;
use Shivas\VersioningBundle\Service\VersionManagerInterface;
class PartDBInfoProvider implements ProviderInterface
@@ -18,10 +16,12 @@ class PartDBInfoProvider implements ProviderInterface
public function __construct(private readonly VersionManagerInterface $versionManager,
private readonly GitVersionInfo $gitVersionInfo,
+ private readonly string $partdb_title,
+ private readonly string $base_currency,
private readonly BannerHelper $bannerHelper,
private readonly string $default_uri,
- private readonly LocalizationSettings $localizationSettings,
- private readonly CustomizationSettings $customizationSettings,
+ private readonly string $global_timezone,
+ private readonly string $global_locale
)
{
@@ -33,12 +33,12 @@ class PartDBInfoProvider implements ProviderInterface
version: $this->versionManager->getVersion()->toString(),
git_branch: $this->gitVersionInfo->getGitBranchName(),
git_commit: $this->gitVersionInfo->getGitCommitHash(),
- title: $this->customizationSettings->instanceName,
+ title: $this->partdb_title,
banner: $this->bannerHelper->getBanner(),
default_uri: $this->default_uri,
- global_timezone: $this->localizationSettings->timezone,
- base_currency: $this->localizationSettings->baseCurrency,
- global_locale: $this->localizationSettings->locale,
+ global_timezone: $this->global_timezone,
+ base_currency: $this->base_currency,
+ global_locale: $this->global_locale,
);
}
}
diff --git a/src/Twig/MiscExtension.php b/src/Twig/MiscExtension.php
index 8b6ebc68..93762d35 100644
--- a/src/Twig/MiscExtension.php
+++ b/src/Twig/MiscExtension.php
@@ -22,11 +22,7 @@ declare(strict_types=1);
*/
namespace App\Twig;
-use App\Settings\SettingsIcon;
use Symfony\Component\HttpFoundation\Request;
-use App\Services\LogSystem\EventCommentType;
-use Jbtronics\SettingsBundle\Proxy\SettingsProxyInterface;
-use ReflectionClass;
use Twig\TwigFunction;
use App\Services\LogSystem\EventCommentNeededHelper;
use Twig\Extension\AbstractExtension;
@@ -40,43 +36,14 @@ final class MiscExtension extends AbstractExtension
public function getFunctions(): array
{
return [
- new TwigFunction('event_comment_needed', $this->evenCommentNeeded(...)),
+ new TwigFunction('event_comment_needed',
+ fn(string $operation_type) => $this->eventCommentNeededHelper->isCommentNeeded($operation_type)
+ ),
- new TwigFunction('settings_icon', $this->settingsIcon(...)),
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(SettingsIcon::class)[0] ?? null;
-
- return $attribute?->newInstance()->icon;
- }
-
/**
* Similar to the getUri function of the request, but does not contain protocol and host.
* @param Request $request
diff --git a/src/Twig/TwigCoreExtension.php b/src/Twig/TwigCoreExtension.php
index 7b2b58f8..352e09d3 100644
--- a/src/Twig/TwigCoreExtension.php
+++ b/src/Twig/TwigCoreExtension.php
@@ -34,11 +34,8 @@ use Twig\TwigTest;
*/
final class TwigCoreExtension extends AbstractExtension
{
- private readonly ObjectNormalizer $objectNormalizer;
-
- public function __construct()
+ public function __construct(protected ObjectNormalizer $objectNormalizer)
{
- $this->objectNormalizer = new ObjectNormalizer();
}
public function getFunctions(): array
diff --git a/symfony.lock b/symfony.lock
index f484d13c..c7471b73 100644
--- a/symfony.lock
+++ b/symfony.lock
@@ -1,16 +1,16 @@
{
- "api-platform/symfony": {
- "version": "4.1",
+ "api-platform/core": {
+ "version": "3.2",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
- "version": "4.0",
- "ref": "e9952e9f393c2d048f10a78f272cd35e807d972b"
+ "version": "3.2",
+ "ref": "696d44adc3c0d4f5d25a2f1c4f3700dd8a5c6db9"
},
"files": [
- "./config/packages/api_platform.yaml",
- "./config/routes/api_platform.yaml",
- "./src/ApiResource/.gitignore"
+ "config/packages/api_platform.yaml",
+ "config/routes/api_platform.yaml",
+ "src/ApiResource/.gitignore"
]
},
"beberlei/assert": {
@@ -29,15 +29,15 @@
"version": "1.11.99.4"
},
"dama/doctrine-test-bundle": {
- "version": "8.3",
+ "version": "8.0",
"recipe": {
"repo": "github.com/symfony/recipes-contrib",
"branch": "main",
- "version": "8.3",
- "ref": "dfc51177476fb39d014ed89944cde53dc3326d23"
+ "version": "7.2",
+ "ref": "896306d79d4ee143af9eadf9b09fd34a8c391b70"
},
"files": [
- "config/packages/dama_doctrine_test_bundle.yaml"
+ "./config/packages/dama_doctrine_test_bundle.yaml"
]
},
"doctrine/cache": {
@@ -53,26 +53,20 @@
"version": "v2.9.2"
},
"doctrine/deprecations": {
- "version": "1.1",
- "recipe": {
- "repo": "github.com/symfony/recipes",
- "branch": "main",
- "version": "1.0",
- "ref": "87424683adc81d7dc305eefec1fced883084aab9"
- }
+ "version": "v0.5.3"
},
"doctrine/doctrine-bundle": {
- "version": "2.15",
+ "version": "2.11",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
- "version": "2.13",
- "ref": "620b57f496f2e599a6015a9fa222c2ee0a32adcb"
+ "version": "2.10",
+ "ref": "c170ded8fc587d6bd670550c43dafcf093762245"
},
"files": [
- "config/packages/doctrine.yaml",
- "src/Entity/.gitignore",
- "src/Repository/.gitignore"
+ "./config/packages/doctrine.yaml",
+ "./src/Entity/.gitignore",
+ "./src/Repository/.gitignore"
]
},
"doctrine/doctrine-fixtures-bundle": {
@@ -133,6 +127,9 @@
"ekino/phpstan-banned-code": {
"version": "v0.3.1"
},
+ "erusev/parsedown": {
+ "version": "1.7.4"
+ },
"florianv/exchanger": {
"version": "1.4.1"
},
@@ -157,9 +154,6 @@
"jbtronics/dompdf-font-loader-bundle": {
"version": "v1.1.1"
},
- "jbtronics/settings-bundle": {
- "version": "2.0.1"
- },
"jbtronics/translation-editor-bundle": {
"version": "v1.0"
},
@@ -213,15 +207,15 @@
]
},
"nelmio/security-bundle": {
- "version": "3.5",
+ "version": "2.4",
"recipe": {
"repo": "github.com/symfony/recipes",
- "branch": "main",
+ "branch": "master",
"version": "2.4",
- "ref": "71045833e4f882ad9de8c95fe47efb99a1eec2f7"
+ "ref": "65726efb67ff51d89de38195bc0d230fa811f64d"
},
"files": [
- "config/packages/nelmio_security.yaml"
+ "./config/packages/nelmio_security.yaml"
]
},
"nikic/php-parser": {
@@ -254,6 +248,12 @@
"./config/packages/datatables.yaml"
]
},
+ "phenx/php-font-lib": {
+ "version": "0.5.1"
+ },
+ "phenx/php-svg-lib": {
+ "version": "v0.3.3"
+ },
"php-http/discovery": {
"version": "1.18",
"recipe": {
@@ -306,18 +306,17 @@
"version": "0.12.4"
},
"phpunit/phpunit": {
- "version": "11.5",
+ "version": "9.6",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
- "version": "11.1",
- "ref": "c6658a60fc9d594805370eacdf542c3d6b5c0869"
+ "version": "9.6",
+ "ref": "7364a21d87e658eb363c5020c072ecfdc12e2326"
},
"files": [
- ".env.test",
- "bin/phpunit",
- "phpunit.xml.dist",
- "tests/bootstrap.php"
+ "./.env.test",
+ "./phpunit.xml.dist",
+ "./tests/bootstrap.php"
]
},
"psr/cache": {
@@ -387,10 +386,10 @@
"repo": "github.com/symfony/recipes-contrib",
"branch": "main",
"version": "1.0",
- "ref": "5d454ec6cc4c700ed3d963f3803e1d427d9669fb"
+ "ref": "0f18b4decdf5695d692c1d0dfd65516a07a6adf1"
},
"files": [
- "public/.htaccess"
+ "./public/.htaccess"
]
},
"symfony/asset": {
@@ -482,27 +481,17 @@
]
},
"symfony/form": {
- "version": "7.3",
- "recipe": {
- "repo": "github.com/symfony/recipes",
- "branch": "main",
- "version": "7.2",
- "ref": "7d86a6723f4a623f59e2bf966b6aad2fc461d36b"
- },
- "files": [
- "./config/packages/csrf.yaml"
- ]
+ "version": "v4.2.3"
},
"symfony/framework-bundle": {
- "version": "7.3",
+ "version": "6.4",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
- "version": "7.3",
- "ref": "5a1497d539f691b96afd45ae397ce5fe30beb4b9"
+ "version": "6.4",
+ "ref": "a91c965766ad3ff2ae15981801643330eb42b6a5"
},
"files": [
- ".editorconfig",
"config/packages/cache.yaml",
"config/packages/framework.yaml",
"config/preload.php",
@@ -529,15 +518,15 @@
"version": "v4.2.3"
},
"symfony/mailer": {
- "version": "7.3",
+ "version": "6.4",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "4.3",
- "ref": "09051cfde49476e3c12cd3a0e44289ace1c75a4f"
+ "ref": "df66ee1f226c46f01e85c29c2f7acce0596ba35a"
},
"files": [
- "config/packages/mailer.yaml"
+ "./config/packages/mailer.yaml"
]
},
"symfony/maker-bundle": {
@@ -574,14 +563,19 @@
"version": "v5.3.8"
},
"symfony/phpunit-bridge": {
- "version": "7.3",
+ "version": "6.4",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
- "version": "7.3",
- "ref": "dc13fec96bd527bd399c3c01f0aab915c67fd544"
+ "version": "6.3",
+ "ref": "a411a0480041243d97382cac7984f7dce7813c08"
},
- "files": []
+ "files": [
+ "./.env.test",
+ "./bin/phpunit",
+ "./phpunit.xml.dist",
+ "./tests/bootstrap.php"
+ ]
},
"symfony/polyfill-ctype": {
"version": "v1.14.0"
@@ -611,24 +605,15 @@
"version": "v4.2.3"
},
"symfony/property-info": {
- "version": "7.3",
- "recipe": {
- "repo": "github.com/symfony/recipes",
- "branch": "main",
- "version": "7.3",
- "ref": "dae70df71978ae9226ae915ffd5fad817f5ca1f7"
- },
- "files": [
- "./config/packages/property_info.yaml"
- ]
+ "version": "v4.2.3"
},
"symfony/routing": {
- "version": "7.3",
+ "version": "6.2",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
- "version": "7.0",
- "ref": "21b72649d5622d8f7da329ffb5afb232a023619d"
+ "version": "6.2",
+ "ref": "e0a11b4ccb8c9e70b574ff5ad3dfdcd41dec5aa6"
},
"files": [
"config/packages/routing.yaml",
@@ -667,18 +652,17 @@
"version": "v1.1.5"
},
"symfony/stimulus-bundle": {
- "version": "2.27",
+ "version": "2.16",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
- "version": "2.20",
- "ref": "e058471c5502e549c1404ebdd510099107bb5549"
+ "version": "2.13",
+ "ref": "6acd9ff4f7fd5626d2962109bd4ebab351d43c43"
},
"files": [
- "assets/bootstrap.js",
- "assets/controllers.json",
- "assets/controllers/csrf_protection_controller.js",
- "assets/controllers/hello_controller.js"
+ "./assets/bootstrap.js",
+ "./assets/controllers.json",
+ "./assets/controllers/hello_controller.js"
]
},
"symfony/stopwatch": {
@@ -688,16 +672,16 @@
"version": "v5.1.0"
},
"symfony/translation": {
- "version": "7.3",
+ "version": "6.4",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "6.3",
- "ref": "620a1b84865ceb2ba304c8f8bf2a185fbf32a843"
+ "ref": "e28e27f53663cc34f0be2837aba18e3a1bef8e7b"
},
"files": [
- "config/packages/translation.yaml",
- "translations/.gitignore"
+ "./config/packages/translation.yaml",
+ "./translations/.gitignore"
]
},
"symfony/translation-contracts": {
@@ -720,17 +704,16 @@
]
},
"symfony/uid": {
- "version": "7.3",
+ "version": "6.2",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
- "version": "7.0",
- "ref": "0df5844274d871b37fc3816c57a768ffc60a43a5"
+ "version": "6.2",
+ "ref": "d294ad4add3e15d7eb1bae0221588ca89b38e558"
},
- "files": []
- },
- "symfony/ux-toggle-password": {
- "version": "v2.29.2"
+ "files": [
+ "./config/packages/uid.yaml"
+ ]
},
"symfony/ux-translator": {
"version": "2.9",
@@ -748,24 +731,15 @@
]
},
"symfony/ux-turbo": {
- "version": "2.28",
- "recipe": {
- "repo": "github.com/symfony/recipes",
- "branch": "main",
- "version": "2.20",
- "ref": "287f7c6eb6e9b65e422d34c00795b360a787380b"
- },
- "files": [
- "config/packages/ux_turbo.yaml"
- ]
+ "version": "v2.16.0"
},
"symfony/validator": {
- "version": "7.3",
+ "version": "5.4",
"recipe": {
"repo": "github.com/symfony/recipes",
- "branch": "main",
- "version": "7.0",
- "ref": "8c1c4e28d26a124b0bb273f537ca8ce443472bfd"
+ "branch": "master",
+ "version": "5.3",
+ "ref": "c32cfd98f714894c4f128bb99aa2530c1227603c"
},
"files": [
"config/packages/validator.yaml"
@@ -781,12 +755,12 @@
"version": "v4.2.3"
},
"symfony/web-profiler-bundle": {
- "version": "7.3",
+ "version": "6.3",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
- "version": "7.3",
- "ref": "a363460c1b0b4a4d0242f2ce1a843ca0f6ac9026"
+ "version": "6.1",
+ "ref": "e42b3f0177df239add25373083a564e5ead4e13a"
},
"files": [
"config/packages/web_profiler.yaml",
@@ -794,12 +768,12 @@
]
},
"symfony/webpack-encore-bundle": {
- "version": "2.2",
+ "version": "2.1",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "2.0",
- "ref": "9ef5412a4a2a8415aca3a3f2b4edd3866aab9a19"
+ "ref": "082d754b3bd54b3fc669f278f1eea955cfd23cf5"
},
"files": [
"assets/app.js",
@@ -812,6 +786,9 @@
"symfony/yaml": {
"version": "v4.2.3"
},
+ "symplify/easy-coding-standard": {
+ "version": "v7.1.3"
+ },
"tecnickcom/tc-lib-barcode": {
"version": "1.15.20"
},
diff --git a/templates/_navbar.html.twig b/templates/_navbar.html.twig
index 446ccdab..cd1f641f 100644
--- a/templates/_navbar.html.twig
+++ b/templates/_navbar.html.twig
@@ -1,5 +1,4 @@
{% import "helper.twig" as helper %}
-{% import "vars.macro.twig" as vars %}
{% import "components/search.macro.html.twig" as search %}