diff --git a/composer.lock b/composer.lock index 2a59f016..b394fccb 100644 --- a/composer.lock +++ b/composer.lock @@ -5090,16 +5090,16 @@ }, { "name": "jbtronics/settings-bundle", - "version": "v3.0.0", + "version": "v3.0.1", "source": { "type": "git", "url": "https://github.com/jbtronics/settings-bundle.git", - "reference": "34b9629af73c7ad8989d8284470e79f3f8d79712" + "reference": "9103bd7f78f0b223d1c7167feb824004fc2a9f07" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jbtronics/settings-bundle/zipball/34b9629af73c7ad8989d8284470e79f3f8d79712", - "reference": "34b9629af73c7ad8989d8284470e79f3f8d79712", + "url": "https://api.github.com/repos/jbtronics/settings-bundle/zipball/9103bd7f78f0b223d1c7167feb824004fc2a9f07", + "reference": "9103bd7f78f0b223d1c7167feb824004fc2a9f07", "shasum": "" }, "require": { @@ -5160,7 +5160,7 @@ ], "support": { "issues": "https://github.com/jbtronics/settings-bundle/issues", - "source": "https://github.com/jbtronics/settings-bundle/tree/v3.0.0" + "source": "https://github.com/jbtronics/settings-bundle/tree/v3.0.1" }, "funding": [ { @@ -5172,7 +5172,7 @@ "type": "github" } ], - "time": "2025-08-24T17:17:43+00:00" + "time": "2025-08-24T21:20:15+00:00" }, { "name": "jfcherng/php-color-output", diff --git a/src/Controller/InfoProviderController.php b/src/Controller/InfoProviderController.php index a6ce3f1b..a6e886e6 100644 --- a/src/Controller/InfoProviderController.php +++ b/src/Controller/InfoProviderController.php @@ -29,10 +29,14 @@ 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; @@ -46,7 +50,9 @@ class InfoProviderController extends AbstractController public function __construct(private readonly ProviderRegistry $providerRegistry, private readonly PartInfoRetriever $infoRetriever, - private readonly ExistingPartFinder $existingPartFinder + private readonly ExistingPartFinder $existingPartFinder, + private readonly SettingsManagerInterface $settingsManager, + private readonly SettingsFormFactoryInterface $settingsFormFactory ) { @@ -63,6 +69,48 @@ 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 @@ -128,4 +176,4 @@ class InfoProviderController extends AbstractController 'update_target' => $update_target ]); } -} \ No newline at end of file +} diff --git a/src/Services/InfoProviderSystem/Providers/DigikeyProvider.php b/src/Services/InfoProviderSystem/Providers/DigikeyProvider.php index 5596ea2b..51f460e4 100644 --- a/src/Services/InfoProviderSystem/Providers/DigikeyProvider.php +++ b/src/Services/InfoProviderSystem/Providers/DigikeyProvider.php @@ -78,7 +78,8 @@ 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.' + 'disabled_help' => 'Set the Client ID and Secret in provider settings and connect OAuth to enable.', + 'settings_class' => DigikeySettings::class, ]; } diff --git a/src/Services/InfoProviderSystem/Providers/Element14Provider.php b/src/Services/InfoProviderSystem/Providers/Element14Provider.php index 9ba5330d..27dfb908 100644 --- a/src/Services/InfoProviderSystem/Providers/Element14Provider.php +++ b/src/Services/InfoProviderSystem/Providers/Element14Provider.php @@ -66,7 +66,8 @@ 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.' + 'disabled_help' => 'Configure the API key in the provider settings to enable.', + 'settings_class' => Element14Settings::class, ]; } diff --git a/src/Services/InfoProviderSystem/Providers/InfoProviderInterface.php b/src/Services/InfoProviderSystem/Providers/InfoProviderInterface.php index 30821bad..1f787559 100644 --- a/src/Services/InfoProviderSystem/Providers/InfoProviderInterface.php +++ b/src/Services/InfoProviderSystem/Providers/InfoProviderInterface.php @@ -39,8 +39,9 @@ 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 } + * @phpstan-return array{ name: string, description?: string, logo?: string, url?: string, disabled_help?: string, oauth_app_name?: string, settings_class?: class-string } */ public function getProviderInfo(): array; @@ -78,4 +79,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 bfb6ad97..58df3b82 100755 --- a/src/Services/InfoProviderSystem/Providers/LCSCProvider.php +++ b/src/Services/InfoProviderSystem/Providers/LCSCProvider.php @@ -51,7 +51,8 @@ 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.' + 'disabled_help' => 'Enable this provider in the provider settings.', + 'settings_class' => LCSCSettings::class, ]; } diff --git a/src/Services/InfoProviderSystem/Providers/MouserProvider.php b/src/Services/InfoProviderSystem/Providers/MouserProvider.php index 8bbdcd9c..6639e5c1 100644 --- a/src/Services/InfoProviderSystem/Providers/MouserProvider.php +++ b/src/Services/InfoProviderSystem/Providers/MouserProvider.php @@ -61,7 +61,8 @@ 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.' + 'disabled_help' => 'Configure the API key in the provider settings to enable.', + 'settings_class' => MouserSettings::class ]; } diff --git a/src/Services/InfoProviderSystem/Providers/OEMSecretsProvider.php b/src/Services/InfoProviderSystem/Providers/OEMSecretsProvider.php index ec035015..b705e04a 100644 --- a/src/Services/InfoProviderSystem/Providers/OEMSecretsProvider.php +++ b/src/Services/InfoProviderSystem/Providers/OEMSecretsProvider.php @@ -246,7 +246,8 @@ 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.' + 'disabled_help' => 'Configure the API key in the provider settings to enable.', + 'settings_class' => OEMSecretsSettings::class ]; } /** diff --git a/src/Services/InfoProviderSystem/Providers/OctopartProvider.php b/src/Services/InfoProviderSystem/Providers/OctopartProvider.php index c05931d3..1142f4ef 100644 --- a/src/Services/InfoProviderSystem/Providers/OctopartProvider.php +++ b/src/Services/InfoProviderSystem/Providers/OctopartProvider.php @@ -170,7 +170,8 @@ 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.' + 'disabled_help' => 'Set the Client ID and Secret in provider settings.', + 'settings_class' => OctopartSettings::class ]; } diff --git a/src/Services/InfoProviderSystem/Providers/PollinProvider.php b/src/Services/InfoProviderSystem/Providers/PollinProvider.php index 5f2268e0..55fa335a 100644 --- a/src/Services/InfoProviderSystem/Providers/PollinProvider.php +++ b/src/Services/InfoProviderSystem/Providers/PollinProvider.php @@ -51,7 +51,8 @@ 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' + 'disabled_help' => 'Enable the provider in provider settings', + 'settings_class' => PollinSettings::class, ]; } diff --git a/src/Services/InfoProviderSystem/Providers/ReicheltProvider.php b/src/Services/InfoProviderSystem/Providers/ReicheltProvider.php index e836937b..5c8efbf1 100644 --- a/src/Services/InfoProviderSystem/Providers/ReicheltProvider.php +++ b/src/Services/InfoProviderSystem/Providers/ReicheltProvider.php @@ -51,7 +51,8 @@ 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.' + 'disabled_help' => 'Enable provider in provider settings.', + 'settings_class' => ReicheltSettings::class, ]; } diff --git a/src/Services/InfoProviderSystem/Providers/TMEProvider.php b/src/Services/InfoProviderSystem/Providers/TMEProvider.php index 7c846a65..9bc73f09 100644 --- a/src/Services/InfoProviderSystem/Providers/TMEProvider.php +++ b/src/Services/InfoProviderSystem/Providers/TMEProvider.php @@ -54,7 +54,8 @@ 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.' + 'disabled_help' => 'Configure the API Token and secret in provider settings to use this provider.', + 'settings_class' => TMESettings::class ]; } diff --git a/templates/info_providers/providers.macro.html.twig b/templates/info_providers/providers.macro.html.twig index 7304806a..827a95fd 100644 --- a/templates/info_providers/providers.macro.html.twig +++ b/templates/info_providers/providers.macro.html.twig @@ -13,7 +13,6 @@ {% else %} {{ provider.providerInfo.name | trans }} {% endif %} -
{{ info_provider_info.description }}
+ {% endif %} +