add CommerceReferenceResolverConfig
This commit is contained in:
124
src/Config/CommerceReferenceResolverConfig.php
Normal file
124
src/Config/CommerceReferenceResolverConfig.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Config;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
final class CommerceReferenceResolverConfig
|
||||
{
|
||||
/**
|
||||
* @param array<string, mixed> $config
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly array $config = [],
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getConversationProductPatterns(): array
|
||||
{
|
||||
return $this->stringList('conversation_product_patterns');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function getFocusTermPatterns(): array
|
||||
{
|
||||
return $this->stringMap('focus_term_patterns');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
private function stringList(string $path): array
|
||||
{
|
||||
$value = $this->value($path);
|
||||
|
||||
if (!is_array($value)) {
|
||||
throw $this->invalid($path, 'must be a list of non-empty strings');
|
||||
}
|
||||
|
||||
$out = [];
|
||||
|
||||
foreach ($value as $item) {
|
||||
if (!is_scalar($item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$item = trim((string) $item);
|
||||
|
||||
if ($item !== '' && !in_array($item, $out, true)) {
|
||||
$out[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
if ($out === []) {
|
||||
throw $this->invalid($path, 'must contain at least one non-empty string');
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
private function stringMap(string $path): array
|
||||
{
|
||||
$value = $this->value($path);
|
||||
|
||||
if (!is_array($value)) {
|
||||
throw $this->invalid($path, 'must be a map of non-empty strings');
|
||||
}
|
||||
|
||||
$out = [];
|
||||
|
||||
foreach ($value as $key => $item) {
|
||||
if (!is_scalar($key) || !is_scalar($item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$cleanKey = trim((string) $key);
|
||||
$cleanValue = trim((string) $item);
|
||||
|
||||
if ($cleanKey !== '' && $cleanValue !== '') {
|
||||
$out[$cleanKey] = $cleanValue;
|
||||
}
|
||||
}
|
||||
|
||||
if ($out === []) {
|
||||
throw $this->invalid($path, 'must contain at least one non-empty mapping');
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
private function value(string $path): mixed
|
||||
{
|
||||
$current = $this->config;
|
||||
|
||||
foreach (explode('.', $path) as $segment) {
|
||||
if (!is_array($current) || !array_key_exists($segment, $current)) {
|
||||
throw $this->missing($path);
|
||||
}
|
||||
|
||||
$current = $current[$segment];
|
||||
}
|
||||
|
||||
return $current;
|
||||
}
|
||||
|
||||
private function missing(string $path): InvalidArgumentException
|
||||
{
|
||||
return new InvalidArgumentException(sprintf('RetrieX commerce reference resolver config "%s" is missing.', $path));
|
||||
}
|
||||
|
||||
private function invalid(string $path, string $reason): InvalidArgumentException
|
||||
{
|
||||
return new InvalidArgumentException(sprintf('RetrieX commerce reference resolver config "%s" %s.', $path, $reason));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user