diff --git a/.env b/.env
index 34c1b49e..19870ae9 100644
--- a/.env
+++ b/.env
@@ -67,16 +67,6 @@ ERROR_PAGE_ADMIN_EMAIL=''
# If this is set to true, solutions to common problems are shown on error pages. Disable this, if you do not want your users to see them...
ERROR_PAGE_SHOW_HELP=1
-##################################################################################
-# Part table settings
-##################################################################################
-
-# The default page size for the part table (set to -1 to show all parts on one page)
-#TABLE_DEFAULT_PAGE_SIZE=50
-# Configure which columns will be visible by default in the parts table (and in which order).
-# This is a comma separated list of column names. See documentation for available values.
-#TABLE_PARTS_DEFAULT_COLUMNS=name,description,category,footprint,manufacturer,storage_location,amount
-
##################################################################################
# Info provider settings
##################################################################################
@@ -106,27 +96,6 @@ PROVIDER_OCTOPART_SEARCH_LIMIT=10
# Set to false to include non authorized offers in the results
PROVIDER_OCTOPART_ONLY_AUTHORIZED_SELLERS=1
-
-# Reichelt provider:
-# Reichelt.com offers no official API, so this info provider webscrapes the website to extract info
-# It could break at any time, use it at your own risk
-# We dont require an API key for Reichelt, just set this to 1 to enable Reichelt support
-PROVIDER_REICHELT_ENABLED=0
-# The country to get prices for
-PROVIDER_REICHELT_COUNTRY=DE
-# The language to get results in (en, de, fr, nl, pl, it, es)
-PROVIDER_REICHELT_LANGUAGE=en
-# Include VAT in prices (set to 1 to include VAT, 0 to exclude VAT)
-PROVIDER_REICHELT_INCLUDE_VAT=1
-# The currency to get prices in (only for countries with countries other than EUR)
-PROVIDER_REICHELT_CURRENCY=EUR
-
-# Pollin provider:
-# Pollin.de offers no official API, so this info provider webscrapes the website to extract info
-# It could break at any time, use it at your own risk
-# We dont require an API key for Pollin, just set this to 1 to enable Pollin support
-PROVIDER_POLLIN_ENABLED=0
-
##################################################################################
# EDA integration related settings
##################################################################################
diff --git a/src/Services/InfoProviderSystem/Providers/PollinProvider.php b/src/Services/InfoProviderSystem/Providers/PollinProvider.php
index 09ab8fd4..864effd9 100644
--- a/src/Services/InfoProviderSystem/Providers/PollinProvider.php
+++ b/src/Services/InfoProviderSystem/Providers/PollinProvider.php
@@ -31,6 +31,7 @@ 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;
@@ -39,8 +40,7 @@ class PollinProvider implements InfoProviderInterface
{
public function __construct(private readonly HttpClientInterface $client,
- #[Autowire(env: 'bool:PROVIDER_POLLIN_ENABLED')]
- private readonly bool $enabled = true,
+ private readonly PollinSettings $settings,
)
{
}
@@ -62,7 +62,7 @@ class PollinProvider implements InfoProviderInterface
public function isActive(): bool
{
- return $this->enabled;
+ return $this->settings->enabled;
}
public function searchByKeyword(string $keyword): array
diff --git a/src/Services/InfoProviderSystem/Providers/ReicheltProvider.php b/src/Services/InfoProviderSystem/Providers/ReicheltProvider.php
index 0c31c411..ebc62dd5 100644
--- a/src/Services/InfoProviderSystem/Providers/ReicheltProvider.php
+++ b/src/Services/InfoProviderSystem/Providers/ReicheltProvider.php
@@ -29,6 +29,7 @@ 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;
@@ -39,16 +40,7 @@ class ReicheltProvider implements InfoProviderInterface
public const DISTRIBUTOR_NAME = "Reichelt";
public function __construct(private readonly HttpClientInterface $client,
- #[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",
+ private readonly ReicheltSettings $settings,
)
{
}
@@ -70,7 +62,7 @@ class ReicheltProvider implements InfoProviderInterface
public function isActive(): bool
{
- return $this->enabled;
+ return $this->settings->enabled;
}
public function searchByKeyword(string $keyword): array
@@ -121,8 +113,8 @@ class ReicheltProvider implements InfoProviderInterface
sprintf(
'https://www.reichelt.com/?ACTION=514&id=74&article=%s&LANGUAGE=%s&CCOUNTRY=%s',
$id,
- strtoupper($this->language),
- strtoupper($this->country)
+ strtoupper($this->settings->language),
+ strtoupper($this->settings->country)
)
);
$json = $response->toArray();
@@ -133,8 +125,8 @@ class ReicheltProvider implements InfoProviderInterface
$response = $this->client->request('GET', $productPage, [
'query' => [
- 'CCTYPE' => $this->includeVAT ? 'private' : 'business',
- 'currency' => $this->currency,
+ 'CCTYPE' => $this->settings->includeVAT ? 'private' : 'business',
+ 'currency' => $this->settings->currency,
],
]);
$html = $response->getContent();
@@ -158,7 +150,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->includeVAT)]
+ [new PriceDTO(1.0, $priceString, $currency, $this->settings->includeVAT)]
, $this->parseBatchPrices($dom, $currency)),
product_url: $productPage
);
@@ -218,7 +210,7 @@ class ReicheltProvider implements InfoProviderInterface
//Strip any non-numeric characters
$priceString = preg_replace('/[^0-9.]/', '', $priceString);
- $prices[] = new PriceDTO($minAmount, $priceString, $currency, $this->includeVAT);
+ $prices[] = new PriceDTO($minAmount, $priceString, $currency, $this->settings->includeVAT);
});
return $prices;
@@ -270,7 +262,7 @@ class ReicheltProvider implements InfoProviderInterface
private function getBaseURL(): string
{
//Without the trailing slash
- return 'https://www.reichelt.com/' . strtolower($this->country) . '/' . strtolower($this->language);
+ return 'https://www.reichelt.com/' . strtolower($this->settings->country) . '/' . strtolower($this->settings->language);
}
public function getCapabilities(): array
diff --git a/src/Settings/InfoProviderSystem/InfoProviderSettings.php b/src/Settings/InfoProviderSystem/InfoProviderSettings.php
index d087facc..109fbc02 100644
--- a/src/Settings/InfoProviderSystem/InfoProviderSettings.php
+++ b/src/Settings/InfoProviderSystem/InfoProviderSettings.php
@@ -46,4 +46,10 @@ class InfoProviderSettings
#[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/PollinSettings.php b/src/Settings/InfoProviderSystem/PollinSettings.php
new file mode 100644
index 00000000..8a7713c6
--- /dev/null
+++ b/src/Settings/InfoProviderSystem/PollinSettings.php
@@ -0,0 +1,37 @@
+.
+ */
+
+declare(strict_types=1);
+
+
+namespace App\Settings\InfoProviderSystem;
+
+use App\Settings\SettingsIcon;
+use Jbtronics\SettingsBundle\Settings\Settings;
+use Jbtronics\SettingsBundle\Settings\SettingsParameter;
+use Symfony\Component\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")]
+ public bool $enabled = false;
+}
\ No newline at end of file
diff --git a/src/Settings/InfoProviderSystem/ReicheltSettings.php b/src/Settings/InfoProviderSystem/ReicheltSettings.php
new file mode 100644
index 00000000..8672ae69
--- /dev/null
+++ b/src/Settings/InfoProviderSystem/ReicheltSettings.php
@@ -0,0 +1,62 @@
+.
+ */
+
+declare(strict_types=1);
+
+
+namespace App\Settings\InfoProviderSystem;
+
+use App\Settings\SettingsIcon;
+use Jbtronics\SettingsBundle\Settings\Settings;
+use Jbtronics\SettingsBundle\Settings\SettingsParameter;
+use Jbtronics\SettingsBundle\Settings\SettingsTrait;
+use Symfony\Component\Form\Extension\Core\Type\CountryType;
+use Symfony\Component\Form\Extension\Core\Type\CurrencyType;
+use Symfony\Component\Form\Extension\Core\Type\LanguageType;
+use Symfony\Component\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")]
+ public bool $enabled = false;
+
+ #[SettingsParameter(label: new TM("settings.ips.tme.currency"), formType: CurrencyType::class, formOptions: ["preferred_choices" => ["EUR"]], envVar: "PROVIDER_REICHELT_CURRENCY")]
+ 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")]
+ #[Assert\Language()]
+ #[Assert\Choice(choices: self::SUPPORTED_LANGUAGE)]
+ public string $language = "en";
+
+ #[SettingsParameter(label: new TM("settings.ips.tme.country"), envVar: "PROVIDER_REICHELT_COUNTRY", formType: CountryType::class, formOptions: ["preferred_choices" => ["DE", "PL", "GB", "FR"]])]
+ #[Assert\Country]
+ public string $country = "DE";
+
+ #[SettingsParameter(label: new TM("settings.ips.reichelt.include_vat"), envVar: "bool:PROVIDER_REICHELT_INCLUDE_VAT")]
+ public bool $includeVAT = true;
+
+}
\ No newline at end of file
diff --git a/src/Settings/InfoProviderSystem/TMESettings.php b/src/Settings/InfoProviderSystem/TMESettings.php
index d44e3325..f414e984 100644
--- a/src/Settings/InfoProviderSystem/TMESettings.php
+++ b/src/Settings/InfoProviderSystem/TMESettings.php
@@ -56,7 +56,7 @@ class TMESettings
#[Assert\Language]
public string $language = "en";
- #[SettingsParameter(label: new TM("settings.ips.tme.country"), envVar: "PROVIDER_TME_COUNTRY", formType: CountryType::class, formOptions: ["preferred_choices" => ["DE", "PL", "GB", "FR"]])]
+ #[SettingsParameter(label: new TM("settings.ips.tme.country"), formType: CountryType::class, formOptions: ["preferred_choices" => ["DE", "PL", "GB", "FR"]], envVar: "PROVIDER_TME_COUNTRY")]
#[Assert\Country]
public string $country = "DE";
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index 0a6c97b0..3ca784cd 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -242,7 +242,7 @@
part.info.timetravel_hint
- This is how the part appeared before %timestamp%. <i>Please note that this feature is experimental, so the info may not be correct.</i>
+ Please note that this feature is experimental, so the info may not be correct.]]>
@@ -731,10 +731,10 @@
user.edit.tfa.disable_tfa_message
- This will disable <b>all active two-factor authentication methods of the user</b> and delete the <b>backup codes</b>!
-<br>
-The user will have to set up all two-factor authentication methods again and print new backup codes! <br><br>
-<b>Only do this if you are absolutely sure about the identity of the user (seeking help), otherwise the account could be compromised by an attacker!</b>
+ all active two-factor authentication methods of the user and delete the backup codes!
+
+The user will have to set up all two-factor authentication methods again and print new backup codes!
+Only do this if you are absolutely sure about the identity of the user (seeking help), otherwise the account could be compromised by an attacker!]]>
@@ -885,9 +885,9 @@ The user will have to set up all two-factor authentication methods again and pri
entity.delete.message
- This can not be undone!
-<br>
-Sub elements will be moved upwards.
+
+Sub elements will be moved upwards.]]>
@@ -1441,7 +1441,7 @@ Sub elements will be moved upwards.
homepage.github.text
- Source, downloads, bug reports, to-do-list etc. can be found on <a href="%href%" class="link-external" target="_blank">GitHub project page</a>
+ GitHub project page]]>
@@ -1463,7 +1463,7 @@ Sub elements will be moved upwards.
homepage.help.text
- Help and tips can be found in Wiki the <a href="%href%" class="link-external" target="_blank">GitHub page</a>
+ GitHub page]]>
@@ -1705,7 +1705,7 @@ Sub elements will be moved upwards.
email.pw_reset.fallback
- If this does not work for you, go to <a href="%url%">%url%</a> and enter the following info
+ %url% and enter the following info]]>
@@ -1735,7 +1735,7 @@ Sub elements will be moved upwards.
email.pw_reset.valid_unit %date%
- The reset token will be valid until <i>%date%</i>.
+ %date%.]]>
@@ -3578,8 +3578,8 @@ Sub elements will be moved upwards.
tfa_google.disable.confirm_message
- If you disable the Authenticator App, all backup codes will be deleted, so you may need to reprint them.<br>
-Also note that without two-factor authentication, your account is no longer as well protected against attackers!
+
+Also note that without two-factor authentication, your account is no longer as well protected against attackers!]]>
@@ -3599,7 +3599,7 @@ Also note that without two-factor authentication, your account is no longer as w
tfa_google.step.download
- Download an authenticator app (e.g. <a class="link-external" target="_blank" href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2">Google Authenticator</a> oder <a class="link-external" target="_blank" href="https://play.google.com/store/apps/details?id=org.fedorahosted.freeotp">FreeOTP Authenticator</a>)
+ Google Authenticator oder FreeOTP Authenticator)]]>
@@ -3841,8 +3841,8 @@ Also note that without two-factor authentication, your account is no longer as w
tfa_trustedDevices.explanation
- When checking the second factor, the current computer can be marked as trustworthy, so no more two-factor checks on this computer are needed.
-If you have done this incorrectly or if a computer is no longer trusted, you can reset the status of <i>all </i>computers here.
+ all computers here.]]>
@@ -5313,7 +5313,7 @@ If you have done this incorrectly or if a computer is no longer trusted, you can
label_options.lines_mode.help
- If you select Twig here, the content field is interpreted as Twig template. See <a href="https://twig.symfony.com/doc/3.x/templates.html">Twig documentation</a> and <a href="https://docs.part-db.de/usage/labels.html#twig-mode">Wiki</a> for more information.
+ Twig documentation and Wiki for more information.]]>
@@ -9388,25 +9388,25 @@ Element 3
filter.parameter_value_constraint.operator.<
- Typ. Value <
+ filter.parameter_value_constraint.operator.>
- Typ. Value >
+ ]]>filter.parameter_value_constraint.operator.<=
- Typ. Value <=
+ filter.parameter_value_constraint.operator.>=
- Typ. Value >=
+ =]]>
@@ -9514,7 +9514,7 @@ Element 3
parts_list.search.searching_for
- Searching parts with keyword <b>%keyword%</b>
+ %keyword%]]>
@@ -10174,13 +10174,13 @@ Element 3
project.builds.number_of_builds_possible
- You have enough stocked to build <b>%max_builds%</b> builds of this project.
+ %max_builds% builds of this project.]]>project.builds.check_project_status
- The current project status is <b>"%project_status%"</b>. You should check if you really want to build the project with this status!
+ "%project_status%". You should check if you really want to build the project with this status!]]>
@@ -10282,7 +10282,7 @@ Element 3
entity.select.add_hint
- Use -> to create nested structures, e.g. "Node 1->Node 1.1"
+ to create nested structures, e.g. "Node 1->Node 1.1"]]>
@@ -10306,13 +10306,13 @@ Element 3
homepage.first_steps.introduction
- Your database is still empty. You might want to read the <a href="%url%">documentation</a> or start to creating the following data structures:
+ documentation or start to creating the following data structures:]]>homepage.first_steps.create_part
- Or you can directly <a href="%url%">create a new part</a>.
+ create a new part.]]>
@@ -10324,7 +10324,7 @@ Element 3
homepage.forum.text
- For questions about Part-DB use the <a href="%href%" class="link-external" target="_blank">discussion forum</a>
+ discussion forum]]>
@@ -10978,7 +10978,7 @@ Element 3
parts.import.help_documentation
- See the <a href="%link%">documentation</a> for more information on the file format.
+ documentation for more information on the file format.]]>
@@ -11158,7 +11158,7 @@ Element 3
part.filter.lessThanDesired
- In stock less than desired (total amount < min. amount)
+
@@ -11970,13 +11970,13 @@ Please note, that you can not impersonate a disabled user. If you try you will g
part.merge.confirm.title
- Do you really want to merge <b>%other%</b> into <b>%target%</b>?
+ %other% into %target%?]]>part.merge.confirm.message
- <b>%other%</b> will be deleted, and the part will be saved with the shown information.
+ %other% will be deleted, and the part will be saved with the shown information.]]>
@@ -12892,5 +12892,35 @@ Please note, that you can not impersonate a disabled user. If you try you will g
This part contains more than one stock. Change the location by hand to select, which stock to choose.
+
+
+ settings.ips.reichelt
+ Reichelt
+
+
+
+
+ settings.ips.reichelt.help
+ Reichelt.com offers no official API, so this info provider webscrapes the website to extract info. It could break at any time, use it at your own risk.
+
+
+
+
+ settings.ips.reichelt.include_vat
+ Include VAT in prices
+
+
+
+
+ settings.ips.pollin
+ Pollin
+
+
+
+
+ settings.ips.pollin.help
+ Pollin.de offers no official API, so this info provider webscrapes the website to extract info. It could break at any time, use it at your own risk.
+
+