Compare commits

..

No commits in common. "4137bde1948c6a5287f049a1d7491acf12a8a7b5" and "4f67f21b33a6c35f5950da76cc115457d6ee6639" have entirely different histories.

13 changed files with 1832 additions and 1908 deletions

View file

@ -33,7 +33,7 @@
"jbtronics/dompdf-font-loader-bundle": "^1.0.0", "jbtronics/dompdf-font-loader-bundle": "^1.0.0",
"jbtronics/settings-bundle": "^3.0.0", "jbtronics/settings-bundle": "^3.0.0",
"jfcherng/php-diff": "^6.14", "jfcherng/php-diff": "^6.14",
"jkphl/micrometa": "^v3.4.0", "jkphl/micrometa": "dev-master",
"knpuniversity/oauth2-client-bundle": "^2.15", "knpuniversity/oauth2-client-bundle": "^2.15",
"league/commonmark": "^2.7", "league/commonmark": "^2.7",
"league/csv": "^9.8.0", "league/csv": "^9.8.0",
@ -160,6 +160,12 @@
"App\\Tests\\": "tests/" "App\\Tests\\": "tests/"
} }
}, },
"repositories": [
{
"type": "vcs",
"url": "https://github.com/jbtronics/micrometa"
}
],
"scripts": { "scripts": {
"auto-scripts": { "auto-scripts": {
"cache:clear": "symfony-cmd", "cache:clear": "symfony-cmd",

685
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -128,7 +128,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* @psalm-type FrameworkConfig = array{ * @psalm-type FrameworkConfig = array{
* secret?: scalar|Param|null, * secret?: scalar|Param|null,
* http_method_override?: bool|Param, // Set true to enable support for the '_method' request parameter to determine the intended HTTP method on POST requests. // Default: false * http_method_override?: bool|Param, // Set true to enable support for the '_method' request parameter to determine the intended HTTP method on POST requests. // Default: false
* allowed_http_method_override?: null|list<string|Param>, * allowed_http_method_override?: list<string|Param>|null,
* trust_x_sendfile_type_header?: scalar|Param|null, // Set true to enable support for xsendfile in binary file responses. // Default: "%env(bool:default::SYMFONY_TRUST_X_SENDFILE_TYPE_HEADER)%" * trust_x_sendfile_type_header?: scalar|Param|null, // Set true to enable support for xsendfile in binary file responses. // Default: "%env(bool:default::SYMFONY_TRUST_X_SENDFILE_TYPE_HEADER)%"
* ide?: scalar|Param|null, // Default: "%env(default::SYMFONY_IDE)%" * ide?: scalar|Param|null, // Default: "%env(default::SYMFONY_IDE)%"
* test?: bool|Param, * test?: bool|Param,
@ -136,9 +136,9 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* set_locale_from_accept_language?: bool|Param, // Whether to use the Accept-Language HTTP header to set the Request locale (only when the "_locale" request attribute is not passed). // Default: false * set_locale_from_accept_language?: bool|Param, // Whether to use the Accept-Language HTTP header to set the Request locale (only when the "_locale" request attribute is not passed). // Default: false
* set_content_language_from_locale?: bool|Param, // Whether to set the Content-Language HTTP header on the Response using the Request locale. // Default: false * set_content_language_from_locale?: bool|Param, // Whether to set the Content-Language HTTP header on the Response using the Request locale. // Default: false
* enabled_locales?: list<scalar|Param|null>, * enabled_locales?: list<scalar|Param|null>,
* trusted_hosts?: string|list<scalar|Param|null>, * trusted_hosts?: list<scalar|Param|null>,
* trusted_proxies?: mixed, // Default: ["%env(default::SYMFONY_TRUSTED_PROXIES)%"] * trusted_proxies?: mixed, // Default: ["%env(default::SYMFONY_TRUSTED_PROXIES)%"]
* trusted_headers?: string|list<scalar|Param|null>, * trusted_headers?: list<scalar|Param|null>,
* error_controller?: scalar|Param|null, // Default: "error_controller" * error_controller?: scalar|Param|null, // Default: "error_controller"
* handle_all_throwables?: bool|Param, // HttpKernel will handle all kinds of \Throwable. // Default: true * handle_all_throwables?: bool|Param, // HttpKernel will handle all kinds of \Throwable. // Default: true
* csrf_protection?: bool|array{ * csrf_protection?: bool|array{
@ -202,23 +202,23 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* property?: scalar|Param|null, * property?: scalar|Param|null,
* service?: scalar|Param|null, * service?: scalar|Param|null,
* }, * },
* supports?: string|list<scalar|Param|null>, * supports?: list<scalar|Param|null>,
* definition_validators?: list<scalar|Param|null>, * definition_validators?: list<scalar|Param|null>,
* support_strategy?: scalar|Param|null, * support_strategy?: scalar|Param|null,
* initial_marking?: backed-enum|string|list<scalar|Param|null>, * initial_marking?: list<scalar|Param|null>,
* events_to_dispatch?: null|list<string|Param>, * events_to_dispatch?: list<string|Param>|null,
* places?: string|list<array{ // Default: [] * places?: list<array{ // Default: []
* name?: scalar|Param|null, * name?: scalar|Param|null,
* metadata?: array<string, mixed>, * metadata?: array<string, mixed>,
* }>, * }>,
* transitions?: list<array{ // Default: [] * transitions?: list<array{ // Default: []
* name?: string|Param, * name?: string|Param,
* guard?: string|Param, // An expression to block the transition. * guard?: string|Param, // An expression to block the transition.
* from?: backed-enum|string|list<array{ // Default: [] * from?: list<array{ // Default: []
* place?: string|Param, * place?: string|Param,
* weight?: int|Param, // Default: 1 * weight?: int|Param, // Default: 1
* }>, * }>,
* to?: backed-enum|string|list<array{ // Default: [] * to?: list<array{ // Default: []
* place?: string|Param, * place?: string|Param,
* weight?: int|Param, // Default: 1 * weight?: int|Param, // Default: 1
* }>, * }>,
@ -271,7 +271,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* version_format?: scalar|Param|null, // Default: "%%s?%%s" * version_format?: scalar|Param|null, // Default: "%%s?%%s"
* json_manifest_path?: scalar|Param|null, // Default: null * json_manifest_path?: scalar|Param|null, // Default: null
* base_path?: scalar|Param|null, // Default: "" * base_path?: scalar|Param|null, // Default: ""
* base_urls?: string|list<scalar|Param|null>, * base_urls?: list<scalar|Param|null>,
* packages?: array<string, array{ // Default: [] * packages?: array<string, array{ // Default: []
* strict_mode?: bool|Param, // Throw an exception if an entry is missing from the manifest.json. // Default: false * strict_mode?: bool|Param, // Throw an exception if an entry is missing from the manifest.json. // Default: false
* version_strategy?: scalar|Param|null, // Default: null * version_strategy?: scalar|Param|null, // Default: null
@ -279,12 +279,12 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* version_format?: scalar|Param|null, // Default: null * version_format?: scalar|Param|null, // Default: null
* json_manifest_path?: scalar|Param|null, // Default: null * json_manifest_path?: scalar|Param|null, // Default: null
* base_path?: scalar|Param|null, // Default: "" * base_path?: scalar|Param|null, // Default: ""
* base_urls?: string|list<scalar|Param|null>, * base_urls?: list<scalar|Param|null>,
* }>, * }>,
* }, * },
* asset_mapper?: bool|array{ // Asset Mapper configuration * asset_mapper?: bool|array{ // Asset Mapper configuration
* enabled?: bool|Param, // Default: false * enabled?: bool|Param, // Default: false
* paths?: string|array<string, scalar|Param|null>, * paths?: array<string, scalar|Param|null>,
* excluded_patterns?: list<scalar|Param|null>, * excluded_patterns?: list<scalar|Param|null>,
* exclude_dotfiles?: bool|Param, // If true, any files starting with "." will be excluded from the asset mapper. // Default: true * exclude_dotfiles?: bool|Param, // If true, any files starting with "." will be excluded from the asset mapper. // Default: true
* server?: bool|Param, // If true, a "dev server" will return the assets from the public directory (true in "debug" mode only by default). // Default: true * server?: bool|Param, // If true, a "dev server" will return the assets from the public directory (true in "debug" mode only by default). // Default: true
@ -303,7 +303,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* }, * },
* translator?: bool|array{ // Translator configuration * translator?: bool|array{ // Translator configuration
* enabled?: bool|Param, // Default: true * enabled?: bool|Param, // Default: true
* fallbacks?: string|list<scalar|Param|null>, * fallbacks?: list<scalar|Param|null>,
* logging?: bool|Param, // Default: false * logging?: bool|Param, // Default: false
* formatter?: scalar|Param|null, // Default: "translator.formatter.default" * formatter?: scalar|Param|null, // Default: "translator.formatter.default"
* cache_dir?: scalar|Param|null, // Default: "%kernel.cache_dir%/translations" * cache_dir?: scalar|Param|null, // Default: "%kernel.cache_dir%/translations"
@ -333,7 +333,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* enabled?: bool|Param, // Default: true * enabled?: bool|Param, // Default: true
* cache?: scalar|Param|null, // Deprecated: Setting the "framework.validation.cache.cache" configuration option is deprecated. It will be removed in version 8.0. * cache?: scalar|Param|null, // Deprecated: Setting the "framework.validation.cache.cache" configuration option is deprecated. It will be removed in version 8.0.
* enable_attributes?: bool|Param, // Default: true * enable_attributes?: bool|Param, // Default: true
* static_method?: string|list<scalar|Param|null>, * static_method?: list<scalar|Param|null>,
* translation_domain?: scalar|Param|null, // Default: "validators" * translation_domain?: scalar|Param|null, // Default: "validators"
* email_validation_mode?: "html5"|"html5-allow-no-tld"|"strict"|"loose"|Param, // Default: "html5" * email_validation_mode?: "html5"|"html5-allow-no-tld"|"strict"|"loose"|Param, // Default: "html5"
* mapping?: array{ * mapping?: array{
@ -396,7 +396,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* default_doctrine_dbal_provider?: scalar|Param|null, // Default: "database_connection" * default_doctrine_dbal_provider?: scalar|Param|null, // Default: "database_connection"
* default_pdo_provider?: scalar|Param|null, // Default: null * default_pdo_provider?: scalar|Param|null, // Default: null
* pools?: array<string, array{ // Default: [] * pools?: array<string, array{ // Default: []
* adapters?: string|list<scalar|Param|null>, * adapters?: list<scalar|Param|null>,
* tags?: scalar|Param|null, // Default: null * tags?: scalar|Param|null, // Default: null
* public?: bool|Param, // Default: false * public?: bool|Param, // Default: false
* default_lifetime?: scalar|Param|null, // Default lifetime of the pool. * default_lifetime?: scalar|Param|null, // Default lifetime of the pool.
@ -419,11 +419,11 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* }, * },
* lock?: bool|string|array{ // Lock configuration * lock?: bool|string|array{ // Lock configuration
* enabled?: bool|Param, // Default: false * enabled?: bool|Param, // Default: false
* resources?: string|array<string, string|list<scalar|Param|null>>, * resources?: array<string, string|list<scalar|Param|null>>,
* }, * },
* semaphore?: bool|string|array{ // Semaphore configuration * semaphore?: bool|string|array{ // Semaphore configuration
* enabled?: bool|Param, // Default: false * enabled?: bool|Param, // Default: false
* resources?: string|array<string, scalar|Param|null>, * resources?: array<string, scalar|Param|null>,
* }, * },
* messenger?: bool|array{ // Messenger configuration * messenger?: bool|array{ // Messenger configuration
* enabled?: bool|Param, // Default: false * enabled?: bool|Param, // Default: false
@ -453,7 +453,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* rate_limiter?: scalar|Param|null, // Rate limiter name to use when processing messages. // Default: null * rate_limiter?: scalar|Param|null, // Rate limiter name to use when processing messages. // Default: null
* }>, * }>,
* failure_transport?: scalar|Param|null, // Transport name to send failed messages to (after all retries have failed). // Default: null * failure_transport?: scalar|Param|null, // Transport name to send failed messages to (after all retries have failed). // Default: null
* stop_worker_on_signals?: int|string|list<scalar|Param|null>, * stop_worker_on_signals?: list<scalar|Param|null>,
* default_bus?: scalar|Param|null, // Default: null * default_bus?: scalar|Param|null, // Default: null
* buses?: array<string, array{ // Default: {"messenger.bus.default":{"default_middleware":{"enabled":true,"allow_no_handlers":false,"allow_no_senders":true},"middleware":[]}} * buses?: array<string, array{ // Default: {"messenger.bus.default":{"default_middleware":{"enabled":true,"allow_no_handlers":false,"allow_no_senders":true},"middleware":[]}}
* default_middleware?: bool|string|array{ * default_middleware?: bool|string|array{
@ -461,7 +461,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* allow_no_handlers?: bool|Param, // Default: false * allow_no_handlers?: bool|Param, // Default: false
* allow_no_senders?: bool|Param, // Default: true * allow_no_senders?: bool|Param, // Default: true
* }, * },
* middleware?: string|list<string|array{ // Default: [] * middleware?: list<string|array{ // Default: []
* id?: scalar|Param|null, * id?: scalar|Param|null,
* arguments?: list<mixed>, * arguments?: list<mixed>,
* }>, * }>,
@ -510,9 +510,9 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* retry_failed?: bool|array{ * retry_failed?: bool|array{
* enabled?: bool|Param, // Default: false * enabled?: bool|Param, // Default: false
* retry_strategy?: scalar|Param|null, // service id to override the retry strategy. // Default: null * retry_strategy?: scalar|Param|null, // service id to override the retry strategy. // Default: null
* http_codes?: int|string|array<string, array{ // Default: [] * http_codes?: array<string, array{ // Default: []
* code?: int|Param, * code?: int|Param,
* methods?: string|list<string|Param>, * methods?: list<string|Param>,
* }>, * }>,
* max_retries?: int|Param, // Default: 3 * max_retries?: int|Param, // Default: 3
* delay?: int|Param, // Time in ms to delay (or the initial value when multiplier is used). // Default: 1000 * delay?: int|Param, // Time in ms to delay (or the initial value when multiplier is used). // Default: 1000
@ -563,9 +563,9 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* retry_failed?: bool|array{ * retry_failed?: bool|array{
* enabled?: bool|Param, // Default: false * enabled?: bool|Param, // Default: false
* retry_strategy?: scalar|Param|null, // service id to override the retry strategy. // Default: null * retry_strategy?: scalar|Param|null, // service id to override the retry strategy. // Default: null
* http_codes?: int|string|array<string, array{ // Default: [] * http_codes?: array<string, array{ // Default: []
* code?: int|Param, * code?: int|Param,
* methods?: string|list<string|Param>, * methods?: list<string|Param>,
* }>, * }>,
* max_retries?: int|Param, // Default: 3 * max_retries?: int|Param, // Default: 3
* delay?: int|Param, // Time in ms to delay (or the initial value when multiplier is used). // Default: 1000 * delay?: int|Param, // Time in ms to delay (or the initial value when multiplier is used). // Default: 1000
@ -582,8 +582,8 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* transports?: array<string, scalar|Param|null>, * transports?: array<string, scalar|Param|null>,
* envelope?: array{ // Mailer Envelope configuration * envelope?: array{ // Mailer Envelope configuration
* sender?: scalar|Param|null, * sender?: scalar|Param|null,
* recipients?: string|list<scalar|Param|null>, * recipients?: list<scalar|Param|null>,
* allowed_recipients?: string|list<scalar|Param|null>, * allowed_recipients?: list<scalar|Param|null>,
* }, * },
* headers?: array<string, string|array{ // Default: [] * headers?: array<string, string|array{ // Default: []
* value?: mixed, * value?: mixed,
@ -635,7 +635,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* cache_pool?: scalar|Param|null, // The cache pool to use for storing the current limiter state. // Default: "cache.rate_limiter" * cache_pool?: scalar|Param|null, // The cache pool to use for storing the current limiter state. // Default: "cache.rate_limiter"
* storage_service?: scalar|Param|null, // The service ID of a custom storage implementation, this precedes any configured "cache_pool". // Default: null * storage_service?: scalar|Param|null, // The service ID of a custom storage implementation, this precedes any configured "cache_pool". // Default: null
* policy?: "fixed_window"|"token_bucket"|"sliding_window"|"compound"|"no_limit"|Param, // The algorithm to be used by this limiter. * policy?: "fixed_window"|"token_bucket"|"sliding_window"|"compound"|"no_limit"|Param, // The algorithm to be used by this limiter.
* limiters?: string|list<scalar|Param|null>, * limiters?: list<scalar|Param|null>,
* limit?: int|Param, // The maximum allowed hits in a fixed interval or burst. * limit?: int|Param, // The maximum allowed hits in a fixed interval or burst.
* interval?: scalar|Param|null, // Configures the fixed interval if "policy" is set to "fixed_window" or "sliding_window". The value must be a number followed by "second", "minute", "hour", "day", "week" or "month" (or their plural equivalent). * interval?: scalar|Param|null, // Configures the fixed interval if "policy" is set to "fixed_window" or "sliding_window". The value must be a number followed by "second", "minute", "hour", "day", "week" or "month" (or their plural equivalent).
* rate?: array{ // Configures the fill rate if "policy" is set to "token_bucket". * rate?: array{ // Configures the fill rate if "policy" is set to "token_bucket".
@ -658,20 +658,20 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* allow_safe_elements?: bool|Param, // Allows "safe" elements and attributes. // Default: false * allow_safe_elements?: bool|Param, // Allows "safe" elements and attributes. // Default: false
* allow_static_elements?: bool|Param, // Allows all static elements and attributes from the W3C Sanitizer API standard. // Default: false * allow_static_elements?: bool|Param, // Allows all static elements and attributes from the W3C Sanitizer API standard. // Default: false
* allow_elements?: array<string, mixed>, * allow_elements?: array<string, mixed>,
* block_elements?: string|list<string|Param>, * block_elements?: list<string|Param>,
* drop_elements?: string|list<string|Param>, * drop_elements?: list<string|Param>,
* allow_attributes?: array<string, mixed>, * allow_attributes?: array<string, mixed>,
* drop_attributes?: array<string, mixed>, * drop_attributes?: array<string, mixed>,
* force_attributes?: array<string, array<string, string|Param>>, * force_attributes?: array<string, array<string, string|Param>>,
* force_https_urls?: bool|Param, // Transforms URLs using the HTTP scheme to use the HTTPS scheme instead. // Default: false * force_https_urls?: bool|Param, // Transforms URLs using the HTTP scheme to use the HTTPS scheme instead. // Default: false
* allowed_link_schemes?: string|list<string|Param>, * allowed_link_schemes?: list<string|Param>,
* allowed_link_hosts?: null|string|list<string|Param>, * allowed_link_hosts?: list<string|Param>|null,
* allow_relative_links?: bool|Param, // Allows relative URLs to be used in links href attributes. // Default: false * allow_relative_links?: bool|Param, // Allows relative URLs to be used in links href attributes. // Default: false
* allowed_media_schemes?: string|list<string|Param>, * allowed_media_schemes?: list<string|Param>,
* allowed_media_hosts?: null|string|list<string|Param>, * allowed_media_hosts?: list<string|Param>|null,
* allow_relative_medias?: bool|Param, // Allows relative URLs to be used in media source attributes (img, audio, video, ...). // Default: false * allow_relative_medias?: bool|Param, // Allows relative URLs to be used in media source attributes (img, audio, video, ...). // Default: false
* with_attribute_sanitizers?: string|list<string|Param>, * with_attribute_sanitizers?: list<string|Param>,
* without_attribute_sanitizers?: string|list<string|Param>, * without_attribute_sanitizers?: list<string|Param>,
* max_input_length?: int|Param, // The maximum length allowed for the sanitized input. // Default: 0 * max_input_length?: int|Param, // The maximum length allowed for the sanitized input. // Default: 0
* }>, * }>,
* }, * },
@ -958,7 +958,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* }, * },
* password_hashers?: array<string, string|array{ // Default: [] * password_hashers?: array<string, string|array{ // Default: []
* algorithm?: scalar|Param|null, * algorithm?: scalar|Param|null,
* migrate_from?: string|list<scalar|Param|null>, * migrate_from?: list<scalar|Param|null>,
* hash_algorithm?: scalar|Param|null, // Name of hashing algorithm for PBKDF2 (i.e. sha256, sha512, etc..) See hash_algos() for a list of supported algorithms. // Default: "sha512" * hash_algorithm?: scalar|Param|null, // Name of hashing algorithm for PBKDF2 (i.e. sha256, sha512, etc..) See hash_algos() for a list of supported algorithms. // Default: "sha512"
* key_length?: scalar|Param|null, // Default: 40 * key_length?: scalar|Param|null, // Default: 40
* ignore_case?: bool|Param, // Default: false * ignore_case?: bool|Param, // Default: false
@ -972,7 +972,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* providers?: array<string, array{ // Default: [] * providers?: array<string, array{ // Default: []
* id?: scalar|Param|null, * id?: scalar|Param|null,
* chain?: array{ * chain?: array{
* providers?: string|list<scalar|Param|null>, * providers?: list<scalar|Param|null>,
* }, * },
* entity?: array{ * entity?: array{
* class?: scalar|Param|null, // The full entity class name of your user class. * class?: scalar|Param|null, // The full entity class name of your user class.
@ -982,7 +982,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* memory?: array{ * memory?: array{
* users?: array<string, array{ // Default: [] * users?: array<string, array{ // Default: []
* password?: scalar|Param|null, // Default: null * password?: scalar|Param|null, // Default: null
* roles?: string|list<scalar|Param|null>, * roles?: list<scalar|Param|null>,
* }>, * }>,
* }, * },
* ldap?: array{ * ldap?: array{
@ -991,7 +991,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* search_dn?: scalar|Param|null, // Default: null * search_dn?: scalar|Param|null, // Default: null
* search_password?: scalar|Param|null, // Default: null * search_password?: scalar|Param|null, // Default: null
* extra_fields?: list<scalar|Param|null>, * extra_fields?: list<scalar|Param|null>,
* default_roles?: string|list<scalar|Param|null>, * default_roles?: list<scalar|Param|null>,
* role_fetcher?: scalar|Param|null, // Default: null * role_fetcher?: scalar|Param|null, // Default: null
* uid_key?: scalar|Param|null, // Default: "sAMAccountName" * uid_key?: scalar|Param|null, // Default: "sAMAccountName"
* filter?: scalar|Param|null, // Default: "({uid_key}={user_identifier})" * filter?: scalar|Param|null, // Default: "({uid_key}={user_identifier})"
@ -1005,7 +1005,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* firewalls?: array<string, array{ // Default: [] * firewalls?: array<string, array{ // Default: []
* pattern?: scalar|Param|null, * pattern?: scalar|Param|null,
* host?: scalar|Param|null, * host?: scalar|Param|null,
* methods?: string|list<scalar|Param|null>, * methods?: list<scalar|Param|null>,
* security?: bool|Param, // Default: true * security?: bool|Param, // Default: true
* user_checker?: scalar|Param|null, // The UserChecker to use when authenticating users in this firewall. // Default: "security.user_checker" * user_checker?: scalar|Param|null, // The UserChecker to use when authenticating users in this firewall. // Default: "security.user_checker"
* request_matcher?: scalar|Param|null, * request_matcher?: scalar|Param|null,
@ -1024,8 +1024,8 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* path?: scalar|Param|null, // Default: "/logout" * path?: scalar|Param|null, // Default: "/logout"
* target?: scalar|Param|null, // Default: "/" * target?: scalar|Param|null, // Default: "/"
* invalidate_session?: bool|Param, // Default: true * invalidate_session?: bool|Param, // Default: true
* clear_site_data?: string|list<"*"|"cache"|"cookies"|"storage"|"executionContexts"|Param>, * clear_site_data?: list<"*"|"cache"|"cookies"|"storage"|"executionContexts"|Param>,
* delete_cookies?: string|array<string, array{ // Default: [] * delete_cookies?: array<string, array{ // Default: []
* path?: scalar|Param|null, // Default: null * path?: scalar|Param|null, // Default: null
* domain?: scalar|Param|null, // Default: null * domain?: scalar|Param|null, // Default: null
* secure?: scalar|Param|null, // Default: false * secure?: scalar|Param|null, // Default: false
@ -1092,7 +1092,6 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* }, * },
* registration?: bool|array{ * registration?: bool|array{
* enabled?: bool|Param, // Default: false * enabled?: bool|Param, // Default: false
* hide_existing_credentials?: bool|Param, // Default: true
* profile?: scalar|Param|null, // Default: "default" * profile?: scalar|Param|null, // Default: "default"
* options_builder?: scalar|Param|null, // Default: null * options_builder?: scalar|Param|null, // Default: null
* routes?: array{ * routes?: array{
@ -1240,7 +1239,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* success_handler?: scalar|Param|null, * success_handler?: scalar|Param|null,
* failure_handler?: scalar|Param|null, * failure_handler?: scalar|Param|null,
* realm?: scalar|Param|null, // Default: null * realm?: scalar|Param|null, // Default: null
* token_extractors?: string|list<scalar|Param|null>, * token_extractors?: list<scalar|Param|null>,
* token_handler?: string|array{ * token_handler?: string|array{
* id?: scalar|Param|null, * id?: scalar|Param|null,
* oidc_user_info?: string|array{ * oidc_user_info?: string|array{
@ -1255,7 +1254,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* }, * },
* oidc?: array{ * oidc?: array{
* discovery?: array{ // Enable the OIDC discovery. * discovery?: array{ // Enable the OIDC discovery.
* base_uri?: string|list<scalar|Param|null>, * base_uri?: list<scalar|Param|null>,
* cache?: array{ * cache?: array{
* id?: scalar|Param|null, // Cache service id to use to cache the OIDC discovery configuration. * id?: scalar|Param|null, // Cache service id to use to cache the OIDC discovery configuration.
* }, * },
@ -1298,7 +1297,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* remember_me?: array{ * remember_me?: array{
* secret?: scalar|Param|null, // Default: "%kernel.secret%" * secret?: scalar|Param|null, // Default: "%kernel.secret%"
* service?: scalar|Param|null, * service?: scalar|Param|null,
* user_providers?: string|list<scalar|Param|null>, * user_providers?: list<scalar|Param|null>,
* catch_exceptions?: bool|Param, // Default: true * catch_exceptions?: bool|Param, // Default: true
* signature_properties?: list<scalar|Param|null>, * signature_properties?: list<scalar|Param|null>,
* token_provider?: string|array{ * token_provider?: string|array{
@ -1326,12 +1325,12 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* path?: scalar|Param|null, // Use the urldecoded format. // Default: null * path?: scalar|Param|null, // Use the urldecoded format. // Default: null
* host?: scalar|Param|null, // Default: null * host?: scalar|Param|null, // Default: null
* port?: int|Param, // Default: null * port?: int|Param, // Default: null
* ips?: string|list<scalar|Param|null>, * ips?: list<scalar|Param|null>,
* attributes?: array<string, scalar|Param|null>, * attributes?: array<string, scalar|Param|null>,
* route?: scalar|Param|null, // Default: null * route?: scalar|Param|null, // Default: null
* methods?: string|list<scalar|Param|null>, * methods?: list<scalar|Param|null>,
* allow_if?: scalar|Param|null, // Default: null * allow_if?: scalar|Param|null, // Default: null
* roles?: string|list<scalar|Param|null>, * roles?: list<scalar|Param|null>,
* }>, * }>,
* role_hierarchy?: array<string, string|list<scalar|Param|null>>, * role_hierarchy?: array<string, string|list<scalar|Param|null>>,
* } * }
@ -1352,7 +1351,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* auto_reload?: scalar|Param|null, * auto_reload?: scalar|Param|null,
* optimizations?: int|Param, * optimizations?: int|Param,
* default_path?: scalar|Param|null, // The default path used to load templates. // Default: "%kernel.project_dir%/templates" * default_path?: scalar|Param|null, // The default path used to load templates. // Default: "%kernel.project_dir%/templates"
* file_name_pattern?: string|list<scalar|Param|null>, * file_name_pattern?: list<scalar|Param|null>,
* paths?: array<string, mixed>, * paths?: array<string, mixed>,
* date?: array{ // The default format options used by the date filter. * date?: array{ // The default format options used by the date filter.
* format?: scalar|Param|null, // Default: "F j, Y H:i" * format?: scalar|Param|null, // Default: "F j, Y H:i"
@ -1453,7 +1452,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* delay_between_messages?: bool|Param, // Default: false * delay_between_messages?: bool|Param, // Default: false
* topic?: int|Param, // Default: null * topic?: int|Param, // Default: null
* factor?: int|Param, // Default: 1 * factor?: int|Param, // Default: 1
* tags?: string|list<scalar|Param|null>, * tags?: list<scalar|Param|null>,
* console_formatter_options?: mixed, // Default: [] * console_formatter_options?: mixed, // Default: []
* formatter?: scalar|Param|null, * formatter?: scalar|Param|null,
* nested?: bool|Param, // Default: false * nested?: bool|Param, // Default: false
@ -1497,7 +1496,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* host?: scalar|Param|null, * host?: scalar|Param|null,
* }, * },
* from_email?: scalar|Param|null, * from_email?: scalar|Param|null,
* to_email?: string|list<scalar|Param|null>, * to_email?: list<scalar|Param|null>,
* subject?: scalar|Param|null, * subject?: scalar|Param|null,
* content_type?: scalar|Param|null, // Default: null * content_type?: scalar|Param|null, // Default: null
* headers?: list<scalar|Param|null>, * headers?: list<scalar|Param|null>,
@ -1587,7 +1586,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* }, * },
* filesystem?: array{ * filesystem?: array{
* locator?: "filesystem"|"filesystem_insecure"|Param, // Using the "filesystem_insecure" locator is not recommended due to a less secure resolver mechanism, but is provided for those using heavily symlinked projects. // Default: "filesystem" * locator?: "filesystem"|"filesystem_insecure"|Param, // Using the "filesystem_insecure" locator is not recommended due to a less secure resolver mechanism, but is provided for those using heavily symlinked projects. // Default: "filesystem"
* data_root?: string|list<scalar|Param|null>, * data_root?: list<scalar|Param|null>,
* allow_unresolvable_data_roots?: bool|Param, // Default: false * allow_unresolvable_data_roots?: bool|Param, // Default: false
* bundle_resources?: array{ * bundle_resources?: array{
* enabled?: bool|Param, // Default: false * enabled?: bool|Param, // Default: false
@ -1931,7 +1930,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* script-src?: list<scalar|Param|null>, * script-src?: list<scalar|Param|null>,
* style-src?: list<scalar|Param|null>, * style-src?: list<scalar|Param|null>,
* upgrade-insecure-requests?: bool|Param, // Default: false * upgrade-insecure-requests?: bool|Param, // Default: false
* report-uri?: string|list<scalar|Param|null>, * report-uri?: list<scalar|Param|null>,
* worker-src?: list<scalar|Param|null>, * worker-src?: list<scalar|Param|null>,
* prefetch-src?: list<scalar|Param|null>, * prefetch-src?: list<scalar|Param|null>,
* report-to?: scalar|Param|null, * report-to?: scalar|Param|null,
@ -1959,7 +1958,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* script-src?: list<scalar|Param|null>, * script-src?: list<scalar|Param|null>,
* style-src?: list<scalar|Param|null>, * style-src?: list<scalar|Param|null>,
* upgrade-insecure-requests?: bool|Param, // Default: false * upgrade-insecure-requests?: bool|Param, // Default: false
* report-uri?: string|list<scalar|Param|null>, * report-uri?: list<scalar|Param|null>,
* worker-src?: list<scalar|Param|null>, * worker-src?: list<scalar|Param|null>,
* prefetch-src?: list<scalar|Param|null>, * prefetch-src?: list<scalar|Param|null>,
* report-to?: scalar|Param|null, * report-to?: scalar|Param|null,
@ -1967,7 +1966,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* }, * },
* referrer_policy?: bool|array{ * referrer_policy?: bool|array{
* enabled?: bool|Param, // Default: false * enabled?: bool|Param, // Default: false
* policies?: string|list<scalar|Param|null>, * policies?: list<scalar|Param|null>,
* }, * },
* permissions_policy?: bool|array{ * permissions_policy?: bool|array{
* enabled?: bool|Param, // Default: false * enabled?: bool|Param, // Default: false
@ -2098,10 +2097,10 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* secured_rp_ids?: array<string, scalar|Param|null>, * secured_rp_ids?: array<string, scalar|Param|null>,
* counter_checker?: scalar|Param|null, // This service will check if the counter is valid. By default it throws an exception (recommended). // Default: "Webauthn\\Counter\\ThrowExceptionIfInvalid" * counter_checker?: scalar|Param|null, // This service will check if the counter is valid. By default it throws an exception (recommended). // Default: "Webauthn\\Counter\\ThrowExceptionIfInvalid"
* top_origin_validator?: scalar|Param|null, // For cross origin (e.g. iframe), this service will be in charge of verifying the top origin. // Default: null * top_origin_validator?: scalar|Param|null, // For cross origin (e.g. iframe), this service will be in charge of verifying the top origin. // Default: null
* creation_profiles?: bool|array<string, array{ // Default: [] * creation_profiles?: array<string, array{ // Default: []
* rp?: array{ * rp?: array{
* id?: scalar|Param|null, // Default: null * id?: scalar|Param|null, // Default: null
* name?: scalar|Param|null, // Deprecated: The child node "name" at path "webauthn.creation_profiles..rp.name" is deprecated and will be removed in the next major release. // Default: "" * name?: scalar|Param|null,
* icon?: scalar|Param|null, // Deprecated: The child node "icon" at path "webauthn.creation_profiles..rp.icon" is deprecated and has no effect. // Default: null * icon?: scalar|Param|null, // Deprecated: The child node "icon" at path "webauthn.creation_profiles..rp.icon" is deprecated and has no effect. // Default: null
* }, * },
* challenge_length?: int|Param, // Default: 32 * challenge_length?: int|Param, // Default: 32
@ -2115,40 +2114,14 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* extensions?: array<string, scalar|Param|null>, * extensions?: array<string, scalar|Param|null>,
* public_key_credential_parameters?: list<int|Param>, * public_key_credential_parameters?: list<int|Param>,
* attestation_conveyance?: scalar|Param|null, // Default: "none" * attestation_conveyance?: scalar|Param|null, // Default: "none"
* conditional_create?: bool|Param, // Enable Conditional Create (auto-register) for this profile. When true, user presence can be false after password authentication. See https://github.com/w3c/webauthn/wiki/Explainer:-Conditional-Create // Default: false
* }>, * }>,
* request_profiles?: bool|array<string, array{ // Default: [] * request_profiles?: array<string, array{ // Default: []
* rp_id?: scalar|Param|null, // Default: null * rp_id?: scalar|Param|null, // Default: null
* challenge_length?: int|Param, // Default: 32 * challenge_length?: int|Param, // Default: 32
* timeout?: int|Param, // Default: null * timeout?: int|Param, // Default: null
* user_verification?: scalar|Param|null, // Default: "preferred" * user_verification?: scalar|Param|null, // Default: "preferred"
* extensions?: array<string, scalar|Param|null>, * extensions?: array<string, scalar|Param|null>,
* }>, * }>,
* client_override_policy?: array{ // Configuration for allowing client request values to override profile configuration
* user_verification?: array{
* enabled?: bool|Param, // Whether to allow client requests to override the user verification requirement // Default: false
* allowed_values?: list<scalar|Param|null>,
* },
* authenticator_attachment?: array{
* enabled?: bool|Param, // Whether to allow client requests to override the authenticator attachment // Default: true
* allowed_values?: list<scalar|Param|null>,
* },
* resident_key?: array{
* enabled?: bool|Param, // Whether to allow client requests to override the resident key requirement // Default: true
* allowed_values?: list<scalar|Param|null>,
* },
* attestation_conveyance?: array{
* enabled?: bool|Param, // Whether to allow client requests to override the attestation conveyance preference // Default: true
* allowed_values?: list<scalar|Param|null>,
* },
* extensions?: array{
* enabled?: bool|Param, // Whether to allow client requests to override extensions // Default: true
* },
* mediation?: array{
* enabled?: bool|Param, // Whether to allow client requests to request the conditional mediation flow (auto-register). // Default: false
* allowed_values?: list<scalar|Param|null>,
* },
* },
* metadata?: bool|array{ // Enable the support of the Metadata Statements. Please read the documentation for this feature. * metadata?: bool|array{ // Enable the support of the Metadata Statements. Please read the documentation for this feature.
* enabled?: bool|Param, // Default: false * enabled?: bool|Param, // Default: false
* mds_repository?: scalar|Param|null, // The Metadata Statement repository. * mds_repository?: scalar|Param|null, // The Metadata Statement repository.
@ -2192,21 +2165,6 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* secured_rp_ids?: array<string, scalar|Param|null>, * secured_rp_ids?: array<string, scalar|Param|null>,
* }>, * }>,
* }, * },
* passkey_endpoints?: bool|array{ // Enable the .well-known/passkey-endpoints discovery endpoint as defined in the W3C Passkey Endpoints specification.
* enabled?: bool|Param, // Default: false
* enroll?: string|array{ // URL to the passkey enrollment/creation interface.
* path?: scalar|Param|null, // The absolute HTTPS URL or Symfony route name.
* params?: list<mixed>,
* },
* manage?: string|array{ // URL to the passkey management interface.
* path?: scalar|Param|null, // The absolute HTTPS URL or Symfony route name.
* params?: list<mixed>,
* },
* prf_usage_details?: string|array{ // URL to informational page about PRF (Pseudo-Random Function) extension usage.
* path?: scalar|Param|null, // The absolute HTTPS URL or Symfony route name.
* params?: list<mixed>,
* },
* },
* } * }
* @psalm-type NbgrpOneloginSamlConfig = array{ // nb:group OneLogin PHP Symfony Bundle configuration * @psalm-type NbgrpOneloginSamlConfig = array{ // nb:group OneLogin PHP Symfony Bundle configuration
* onelogin_settings?: array<string, array{ // Default: [] * onelogin_settings?: array<string, array{ // Default: []
@ -2335,7 +2293,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* type?: scalar|Param|null, * type?: scalar|Param|null,
* elements?: list<scalar|Param|null>, * elements?: list<scalar|Param|null>,
* }, * },
* keys_patterns?: string|list<scalar|Param|null>, * keys_patterns?: list<scalar|Param|null>,
* } * }
* @psalm-type DompdfFontLoaderConfig = array{ * @psalm-type DompdfFontLoaderConfig = array{
* autodiscovery?: bool|array{ * autodiscovery?: bool|array{

View file

@ -40,7 +40,6 @@ use App\Services\Attachments\AttachmentSubmitHandler;
use App\Services\Attachments\PartPreviewGenerator; use App\Services\Attachments\PartPreviewGenerator;
use App\Services\EntityMergers\Mergers\PartMerger; use App\Services\EntityMergers\Mergers\PartMerger;
use App\Services\InfoProviderSystem\PartInfoRetriever; use App\Services\InfoProviderSystem\PartInfoRetriever;
use App\Services\InfoProviderSystem\Providers\InfoProviderInterface;
use App\Services\LogSystem\EventCommentHelper; use App\Services\LogSystem\EventCommentHelper;
use App\Services\LogSystem\HistoryHelper; use App\Services\LogSystem\HistoryHelper;
use App\Services\LogSystem\TimeTravel; use App\Services\LogSystem\TimeTravel;
@ -284,10 +283,7 @@ final class PartController extends AbstractController
{ {
$this->denyAccessUnlessGranted('@info_providers.create_parts'); $this->denyAccessUnlessGranted('@info_providers.create_parts');
//Force info providers to not use cache, when retrieving part details for creating a new part, because otherwise we might end up with outdated information $dto = $infoRetriever->getDetails($providerKey, $providerId);
$no_cache = $request->query->getBoolean('no_cache', false);
$dto = $infoRetriever->getDetails($providerKey, $providerId, [InfoProviderInterface::OPTION_NO_CACHE => $no_cache]);
$new_part = $infoRetriever->dtoToPart($dto); $new_part = $infoRetriever->dtoToPart($dto);
if ($new_part->getCategory() === null || $new_part->getCategory()->getID() === null) { if ($new_part->getCategory() === null || $new_part->getCategory()->getID() === null) {

View file

@ -53,7 +53,6 @@ final class PartInfoRetriever
* Search for a keyword in the given providers. The results can be cached * Search for a keyword in the given providers. The results can be cached
* @param string[]|InfoProviderInterface[] $providers A list of providers to search in, either as provider keys or as provider instances * @param string[]|InfoProviderInterface[] $providers A list of providers to search in, either as provider keys or as provider instances
* @param string $keyword The keyword to search for * @param string $keyword The keyword to search for
* @param array<string, mixed> $options An associative array of options which can be used to modify the search behavior. The supported options depend on the provider and should be documented in the provider's documentation.
* @return SearchResultDTO[] The search results * @return SearchResultDTO[] The search results
* @throws InfoProviderNotActiveException if any of the given providers is not active * @throws InfoProviderNotActiveException if any of the given providers is not active
* @throws ClientException if any of the providers throws an exception during the search * @throws ClientException if any of the providers throws an exception during the search
@ -61,7 +60,7 @@ final class PartInfoRetriever
* @throws TransportException if any of the providers throws an exception during the search * @throws TransportException if any of the providers throws an exception during the search
* @throws OAuthReconnectRequiredException if any of the providers throws an exception during the search that indicates that the OAuth token needs to be refreshed * @throws OAuthReconnectRequiredException if any of the providers throws an exception during the search that indicates that the OAuth token needs to be refreshed
*/ */
public function searchByKeyword(string $keyword, array $providers, array $options = []): array public function searchByKeyword(string $keyword, array $providers): array
{ {
$results = []; $results = [];
@ -90,31 +89,15 @@ final class PartInfoRetriever
* Search for a keyword in the given provider. The result is cached for 7 days. * Search for a keyword in the given provider. The result is cached for 7 days.
* @return SearchResultDTO[] * @return SearchResultDTO[]
*/ */
protected function searchInProvider(InfoProviderInterface $provider, string $keyword, array $options = []): array protected function searchInProvider(InfoProviderInterface $provider, string $keyword): array
{ {
//Generate key and escape reserved characters from the provider id //Generate key and escape reserved characters from the provider id
$escaped_keyword = hash('xxh3', $keyword); $escaped_keyword = hash('xxh3', $keyword);
return $this->partInfoCache->get("search_{$provider->getProviderKey()}_{$escaped_keyword}", function (ItemInterface $item) use ($provider, $keyword) {
$no_cache = $options[InfoProviderInterface::OPTION_NO_CACHE] ?? false;
//Exclude the no_cache option from the options hash, since it should not affect the cache key, as it only determines whether to bypass the cache or not, but does not change the actual search results
$options_without_cache = $options;
unset($options_without_cache[InfoProviderInterface::OPTION_NO_CACHE]);
//Generate a hash for the options, to ensure that different options result in different cache entries
$options_hash = hash('xxh3', json_encode($options_without_cache, JSON_THROW_ON_ERROR));
$cache_key = "search_{$provider->getProviderKey()}_{$escaped_keyword}_{$options_hash}";
//If no_cache is set, bypass the cache and get fresh results from the provider
if ($no_cache) {
$this->partInfoCache->delete($cache_key);
}
return $this->partInfoCache->get($cache_key, function (ItemInterface $item) use ($provider, $keyword, $options) {
//Set the expiration time //Set the expiration time
$item->expiresAfter(!$this->debugMode ? self::CACHE_RESULT_EXPIRATION : 10); $item->expiresAfter(!$this->debugMode ? self::CACHE_RESULT_EXPIRATION : 10);
return $provider->searchByKeyword($keyword, $options); return $provider->searchByKeyword($keyword);
}); });
} }
@ -123,11 +106,10 @@ final class PartInfoRetriever
* The result is cached for 4 days. * The result is cached for 4 days.
* @param string $provider_key * @param string $provider_key
* @param string $part_id * @param string $part_id
* @param array<string, mixed> $options An associative array of options which can be used to modify the search behavior. The supported options depend on the provider and should be documented in the provider's documentation.
* @return PartDetailDTO * @return PartDetailDTO
* @throws InfoProviderNotActiveException if the the given providers is not active * @throws InfoProviderNotActiveException if the the given providers is not active
*/ */
public function getDetails(string $provider_key, string $part_id, array $options = []): PartDetailDTO public function getDetails(string $provider_key, string $part_id): PartDetailDTO
{ {
$provider = $this->provider_registry->getProviderByKey($provider_key); $provider = $this->provider_registry->getProviderByKey($provider_key);
@ -136,26 +118,13 @@ final class PartInfoRetriever
throw InfoProviderNotActiveException::fromProvider($provider); throw InfoProviderNotActiveException::fromProvider($provider);
} }
//Exclude the no_cache option from the options hash, since it should not affect the cache key, as it only determines whether to bypass the cache or not, but does not change the actual search results
$options_without_cache = $options;
unset($options_without_cache[InfoProviderInterface::OPTION_NO_CACHE]);
//Generate a hash for the options, to ensure that different options result in different cache entries
$options_hash = hash('xxh3', json_encode($options_without_cache, JSON_THROW_ON_ERROR));
//Generate key and escape reserved characters from the provider id //Generate key and escape reserved characters from the provider id
$escaped_part_id = hash('xxh3', $part_id); $escaped_part_id = hash('xxh3', $part_id);
$cache_key = "details_{$provider_key}_{$escaped_part_id}_{$options_hash}"; return $this->partInfoCache->get("details_{$provider_key}_{$escaped_part_id}", function (ItemInterface $item) use ($provider, $part_id) {
//Delete the cache entry if no_cache is set, to ensure that the next get call will fetch fresh data from the provider, instead of returning stale data from the cache.
if ($options[InfoProviderInterface::OPTION_NO_CACHE] ?? false) {
$this->partInfoCache->delete($cache_key);
}
return $this->partInfoCache->get($cache_key, function (ItemInterface $item) use ($provider, $part_id, $options) {
//Set the expiration time //Set the expiration time
$item->expiresAfter(!$this->debugMode ? self::CACHE_DETAIL_EXPIRATION : 10); $item->expiresAfter(!$this->debugMode ? self::CACHE_DETAIL_EXPIRATION : 10);
return $provider->getDetails($part_id, $options); return $provider->getDetails($part_id);
}); });
} }

View file

@ -120,7 +120,7 @@ class BuerklinProvider implements BatchInfoProviderInterface, URLHandlerInfoProv
]; ];
} }
private function getProduct(string $code, bool $use_cache = true): array private function getProduct(string $code): array
{ {
$code = strtoupper(trim($code)); $code = strtoupper(trim($code));
if ($code === '') { if ($code === '') {
@ -132,11 +132,6 @@ class BuerklinProvider implements BatchInfoProviderInterface, URLHandlerInfoProv
md5($code . '|' . $this->settings->language . '|' . $this->settings->currency) md5($code . '|' . $this->settings->language . '|' . $this->settings->currency)
); );
if (!$use_cache) {
$this->partInfoCache->deleteItem($cacheKey);
unset($this->productCache[$cacheKey]);
}
if (isset($this->productCache[$cacheKey])) { if (isset($this->productCache[$cacheKey])) {
return $this->productCache[$cacheKey]; return $this->productCache[$cacheKey];
} }
@ -493,7 +488,7 @@ class BuerklinProvider implements BatchInfoProviderInterface, URLHandlerInfoProv
// Fallback: try direct lookup by code // Fallback: try direct lookup by code
try { try {
$product = $this->getProduct($keyword, use_cache: !($options[self::OPTION_NO_CACHE] ?? false)); $product = $this->getProduct($keyword);
return [$this->getPartDetail($product)]; return [$this->getPartDetail($product)];
} catch (\Throwable $e) { } catch (\Throwable $e) {
return []; return [];
@ -503,8 +498,7 @@ class BuerklinProvider implements BatchInfoProviderInterface, URLHandlerInfoProv
public function getDetails(string $id, array $options = []): PartDetailDTO public function getDetails(string $id, array $options = []): PartDetailDTO
{ {
// Detail endpoint is /products/{code}/ // Detail endpoint is /products/{code}/
//By default use cache for details, but allow bypassing cache with option (e.g. for refresh) $response = $this->getProduct($id);
$response = $this->getProduct($id, use_cache: !($options[self::OPTION_NO_CACHE] ?? false));
return $this->getPartDetail($response); return $this->getPartDetail($response);
} }

View file

@ -184,10 +184,8 @@ class CanopyProvider implements InfoProviderInterface
throw new \InvalidArgumentException("The id must be a valid ASIN (10 characters, letters and numbers)"); throw new \InvalidArgumentException("The id must be a valid ASIN (10 characters, letters and numbers)");
} }
$do_not_cache = ($options[self::OPTION_NO_CACHE] ?? false) || $this->settings->alwaysGetDetails;
//Use cached details if available and the settings allow it, to avoid unnecessary API requests, since the search results already contain most of the details //Use cached details if available and the settings allow it, to avoid unnecessary API requests, since the search results already contain most of the details
if(!$do_not_cache && ($cached = $this->getFromCache($id)) !== null) { if(!$this->settings->alwaysGetDetails && ($cached = $this->getFromCache($id)) !== null) {
return $cached; return $cached;
} }

View file

@ -50,8 +50,6 @@ class GenericWebProvider implements InfoProviderInterface
use FixAndValidateUrlTrait; use FixAndValidateUrlTrait;
public const OPTION_CHECK_FOR_DELEGATION = 'check_for_delegation';
public const DISTRIBUTOR_NAME = 'Website'; public const DISTRIBUTOR_NAME = 'Website';
private readonly HttpClientInterface $httpClient; private readonly HttpClientInterface $httpClient;
@ -101,7 +99,7 @@ class GenericWebProvider implements InfoProviderInterface
try { try {
return [ return [
$this->getDetails($keyword, [self::OPTION_CHECK_FOR_DELEGATION => false]) //We already tried delegation $this->getDetails($keyword, false) //We already tried delegation
]; } catch (ProviderIDNotSupportedException $e) { ]; } catch (ProviderIDNotSupportedException $e) {
return []; return [];
} }
@ -314,10 +312,8 @@ class GenericWebProvider implements InfoProviderInterface
public function getDetails(string $id, array $options = []): PartDetailDTO public function getDetails(string $id, bool $check_for_delegation = true): PartDetailDTO
{ {
//We check for delegation by default
$check_for_delegation = $options[self::OPTION_CHECK_FOR_DELEGATION] ?? true;
$url = $this->fixAndValidateURL($id); $url = $this->fixAndValidateURL($id);
if ($check_for_delegation) { if ($check_for_delegation) {

View file

@ -28,7 +28,6 @@ use App\Services\InfoProviderSystem\DTOs\SearchResultDTO;
interface InfoProviderInterface interface InfoProviderInterface
{ {
public const OPTION_NO_CACHE = 'no_cache'; // if set to true, the provider should not use any cache and retrieve fresh data from the source
/** /**
* Get information about this provider * Get information about this provider

View file

@ -76,7 +76,7 @@ class MouserProvider implements InfoProviderInterface
return $this->settings->apiKey !== '' && $this->settings->apiKey !== null; return $this->settings->apiKey !== '' && $this->settings->apiKey !== null;
} }
public function searchByKeyword(string $keyword, array $options = []): array public function searchByKeyword(string $keyword): array
{ {
/* /*
SearchByKeywordRequest description: SearchByKeywordRequest description:
@ -144,7 +144,7 @@ class MouserProvider implements InfoProviderInterface
return $this->responseToDTOArray($response); return $this->responseToDTOArray($response);
} }
public function getDetails(string $id, array $options = []): PartDetailDTO public function getDetails(string $id): PartDetailDTO
{ {
/* /*
SearchByPartRequest description: SearchByPartRequest description:

View file

@ -424,11 +424,6 @@ class OEMSecretsProvider implements InfoProviderInterface
public function getDetails(string $id, array $options = []): PartDetailDTO public function getDetails(string $id, array $options = []): PartDetailDTO
{ {
$cacheKey = $this->getCacheKey($id); $cacheKey = $this->getCacheKey($id);
if ($options[self::OPTION_NO_CACHE] ?? false) {
$this->partInfoCache->deleteItem($cacheKey);
}
$cacheItem = $this->partInfoCache->getItem($cacheKey); $cacheItem = $this->partInfoCache->getItem($cacheKey);
if ($cacheItem->isHit()) { if ($cacheItem->isHit()) {

View file

@ -369,11 +369,9 @@ class OctopartProvider implements InfoProviderInterface
public function getDetails(string $id, array $options = []): PartDetailDTO public function getDetails(string $id, array $options = []): PartDetailDTO
{ {
$no_cache = $options[self::OPTION_NO_CACHE] ?? false;
//Check if we have the part cached //Check if we have the part cached
$cached = $this->getFromCache($id); $cached = $this->getFromCache($id);
if (!$no_cache && $cached !== null) { if ($cached !== null) {
return $cached; return $cached;
} }

View file

@ -105,6 +105,6 @@ class UpdateAvailableFacade
return $this->updateCache->get(self::CACHE_KEY, function (ItemInterface $item) { return $this->updateCache->get(self::CACHE_KEY, function (ItemInterface $item) {
$item->expiresAfter(self::CACHE_TTL); $item->expiresAfter(self::CACHE_TTL);
return $this->updateChecker->getLatestVersion(); return $this->updateChecker->getLatestVersion();
}) ?? ['version' => '0.0.1', 'url' => 'update-checking-failed']; });
} }
} }