fix 3
This commit is contained in:
@@ -7,451 +7,461 @@ namespace App\Config;
|
||||
final class ShopServiceConfig
|
||||
{
|
||||
public const DEVICE_QUERY_KEYWORDS = [
|
||||
'analysegerät',
|
||||
'analysegeraet',
|
||||
'analysegeräte',
|
||||
'analysegeraete',
|
||||
'messgerät',
|
||||
'messgeraet',
|
||||
'messgeräte',
|
||||
'messgeraete',
|
||||
'analysator',
|
||||
'analysatoren',
|
||||
'analyzer',
|
||||
'gerät',
|
||||
'geraet',
|
||||
'geräte',
|
||||
'geraete',
|
||||
'monitor',
|
||||
'monitore',
|
||||
'controller',
|
||||
'gerät für',
|
||||
'geraet fuer',
|
||||
'geräte für',
|
||||
'geraete fuer',
|
||||
'system',
|
||||
'systeme',
|
||||
'anlage',
|
||||
'anlagen',
|
||||
'analysegerät', 'analysegeraet', 'analysegeräte', 'analysegeraete',
|
||||
'messgerät', 'messgeraet', 'messgeräte', 'messgeraete',
|
||||
'analysator', 'analysatoren', 'analyzer', 'gerät', 'geraet', 'geräte',
|
||||
'geraete', 'monitor', 'monitore', 'controller', 'gerät für',
|
||||
'geraet fuer', 'geräte für', 'geraete fuer', 'system', 'systeme',
|
||||
'anlage', 'anlagen',
|
||||
];
|
||||
|
||||
public const ACCESSORY_QUERY_KEYWORDS = [
|
||||
'zubehör',
|
||||
'zubehor',
|
||||
'reagenz',
|
||||
'reagenzien',
|
||||
'reagent',
|
||||
'indikator',
|
||||
'indikatoren',
|
||||
'indicator',
|
||||
'kit',
|
||||
'set',
|
||||
'ersatz',
|
||||
'ersatzteil',
|
||||
'ersatzteile',
|
||||
'verbrauchsmaterial',
|
||||
'consumable',
|
||||
'dazu',
|
||||
'passend',
|
||||
'passende',
|
||||
'passendes',
|
||||
'nachfüll',
|
||||
'nachfuell',
|
||||
'refill',
|
||||
'filter',
|
||||
'pumpenkopf',
|
||||
'motorblock',
|
||||
'service set',
|
||||
'serviceset',
|
||||
'service-set',
|
||||
'zubehör', 'zubehor', 'reagenz', 'reagenzien', 'reagent', 'indikator',
|
||||
'indikatoren', 'indicator', 'kit', 'set', 'ersatz', 'ersatzteil',
|
||||
'ersatzteile', 'verbrauchsmaterial', 'consumable', 'dazu', 'passend',
|
||||
'passende', 'passendes', 'nachfüll', 'nachfuell', 'refill', 'filter',
|
||||
'pumpenkopf', 'motorblock', 'service set', 'serviceset', 'service-set',
|
||||
];
|
||||
|
||||
public const ACCESSORY_PRODUCT_KEYWORDS = [
|
||||
'reagenz',
|
||||
'reagenzien',
|
||||
'reagent',
|
||||
'indikator',
|
||||
'indikatoren',
|
||||
'indicator',
|
||||
'kit',
|
||||
'set',
|
||||
'verbrauchsmaterial',
|
||||
'consumable',
|
||||
'zubehör',
|
||||
'zubehor',
|
||||
'ersatz',
|
||||
'ersatzteil',
|
||||
'ersatzteile',
|
||||
'nachfüll',
|
||||
'nachfuell',
|
||||
'refill',
|
||||
'lösung',
|
||||
'loesung',
|
||||
'solution',
|
||||
'teststreifen',
|
||||
'test strip',
|
||||
'filter',
|
||||
'pumpenkopf',
|
||||
'motorblock',
|
||||
'service set',
|
||||
'serviceset',
|
||||
'service-set',
|
||||
'reagenz', 'reagenzien', 'reagent', 'indikator', 'indikatoren',
|
||||
'indicator', 'kit', 'set', 'verbrauchsmaterial', 'consumable',
|
||||
'zubehör', 'zubehor', 'ersatz', 'ersatzteil', 'ersatzteile',
|
||||
'nachfüll', 'nachfuell', 'refill', 'lösung', 'loesung', 'solution',
|
||||
'teststreifen', 'test strip', 'filter', 'pumpenkopf', 'motorblock',
|
||||
'service set', 'serviceset', 'service-set',
|
||||
];
|
||||
|
||||
public const DEVICE_PRODUCT_KEYWORDS = [
|
||||
'analysegerät',
|
||||
'analysegeraet',
|
||||
'analysegeräte',
|
||||
'analysegeraete',
|
||||
'messgerät',
|
||||
'messgeraet',
|
||||
'messgeräte',
|
||||
'messgeraete',
|
||||
'analysator',
|
||||
'analysatoren',
|
||||
'analyzer',
|
||||
'monitor',
|
||||
'monitore',
|
||||
'controller',
|
||||
'online-analysator',
|
||||
'online analysator',
|
||||
'online-analysegerät',
|
||||
'online analysegeraet',
|
||||
'online-analysegeräte',
|
||||
'online analysegeraete',
|
||||
'online analyzer',
|
||||
'online monitor',
|
||||
'system',
|
||||
'systeme',
|
||||
'anlage',
|
||||
'anlagen',
|
||||
'gerät',
|
||||
'geraet',
|
||||
'geräte',
|
||||
'geraete',
|
||||
'analysegerät', 'analysegeraet', 'analysegeräte', 'analysegeraete',
|
||||
'messgerät', 'messgeraet', 'messgeräte', 'messgeraete',
|
||||
'analysator', 'analysatoren', 'analyzer', 'monitor', 'monitore',
|
||||
'controller', 'online-analysator', 'online analysator',
|
||||
'online-analysegerät', 'online analysegeraet', 'online-analysegeräte',
|
||||
'online analysegeraete', 'online analyzer', 'online monitor', 'system',
|
||||
'systeme', 'anlage', 'anlagen', 'gerät', 'geraet', 'geräte', 'geraete',
|
||||
];
|
||||
|
||||
private const DEVICE_FOCUS_KEYWORDS = [
|
||||
'geräte', 'geraete', 'gerät', 'geraet', 'analysegerät', 'analysegeraet',
|
||||
'messgerät', 'messgeraet', 'analysator', 'controller', 'monitor',
|
||||
];
|
||||
|
||||
private const ACCESSORY_FOCUS_KEYWORDS = [
|
||||
'indikator', 'indikatoren', 'reagenz', 'reagenzien', 'zubehör',
|
||||
'zubehor', 'ersatzteil', 'ersatzteile', 'verbrauchsmaterial',
|
||||
'service set', 'serviceset', 'filter', 'pumpenkopf', 'motorblock',
|
||||
];
|
||||
|
||||
private const ACCESSORY_FOCUS_VARIANT_MAP = [
|
||||
'indikator' => ['indikator', 'indikatoren'],
|
||||
'indikatoren' => ['indikator', 'indikatoren'],
|
||||
'reagenz' => ['reagenz', 'reagenzien'],
|
||||
'reagenzien' => ['reagenz', 'reagenzien'],
|
||||
'ersatzteil' => ['ersatzteil', 'ersatzteile'],
|
||||
'ersatzteile' => ['ersatzteil', 'ersatzteile'],
|
||||
'service set' => ['service set', 'serviceset', 'service-set'],
|
||||
'serviceset' => ['service set', 'serviceset', 'service-set'],
|
||||
'service-set' => ['service set', 'serviceset', 'service-set'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $config
|
||||
*/
|
||||
public function __construct(private array $config = [])
|
||||
{
|
||||
}
|
||||
|
||||
public function getTopProductLogLimit(): int
|
||||
{
|
||||
return 3;
|
||||
return $this->int('top_product_log_limit', 3, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
/** @return string[] */
|
||||
public function getDeviceFocusKeywords(): array
|
||||
{
|
||||
return [
|
||||
'geräte',
|
||||
'geraete',
|
||||
'gerät',
|
||||
'geraet',
|
||||
'analysegerät',
|
||||
'analysegeraet',
|
||||
'messgerät',
|
||||
'messgeraet',
|
||||
'analysator',
|
||||
'controller',
|
||||
'monitor',
|
||||
];
|
||||
return $this->stringList('device_focus_keywords', self::DEVICE_FOCUS_KEYWORDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
/** @return string[] */
|
||||
public function getAccessoryFocusKeywords(): array
|
||||
{
|
||||
return [
|
||||
'indikator',
|
||||
'indikatoren',
|
||||
'reagenz',
|
||||
'reagenzien',
|
||||
'zubehör',
|
||||
'zubehor',
|
||||
'ersatzteil',
|
||||
'ersatzteile',
|
||||
'verbrauchsmaterial',
|
||||
'service set',
|
||||
'serviceset',
|
||||
'filter',
|
||||
'pumpenkopf',
|
||||
'motorblock',
|
||||
];
|
||||
return $this->stringList('accessory_focus_keywords', self::ACCESSORY_FOCUS_KEYWORDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string[]>
|
||||
*/
|
||||
/** @return array<string, string[]> */
|
||||
public function getAccessoryFocusVariantMap(): array
|
||||
{
|
||||
return [
|
||||
'indikator' => ['indikator', 'indikatoren'],
|
||||
'indikatoren' => ['indikator', 'indikatoren'],
|
||||
'reagenz' => ['reagenz', 'reagenzien'],
|
||||
'reagenzien' => ['reagenz', 'reagenzien'],
|
||||
'ersatzteil' => ['ersatzteil', 'ersatzteile'],
|
||||
'ersatzteile' => ['ersatzteil', 'ersatzteile'],
|
||||
'service set' => ['service set', 'serviceset', 'service-set'],
|
||||
'serviceset' => ['service set', 'serviceset', 'service-set'],
|
||||
'service-set' => ['service set', 'serviceset', 'service-set'],
|
||||
];
|
||||
return $this->stringListMap('accessory_focus_variant_map', self::ACCESSORY_FOCUS_VARIANT_MAP);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
/** @return string[] */
|
||||
public function getDeviceQueryKeywords(): array
|
||||
{
|
||||
return self::DEVICE_QUERY_KEYWORDS;
|
||||
return $this->stringList('device_query_keywords', self::DEVICE_QUERY_KEYWORDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
/** @return string[] */
|
||||
public function getAccessoryQueryKeywords(): array
|
||||
{
|
||||
return self::ACCESSORY_QUERY_KEYWORDS;
|
||||
return $this->stringList('accessory_query_keywords', self::ACCESSORY_QUERY_KEYWORDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
/** @return string[] */
|
||||
public function getAccessoryProductKeywords(): array
|
||||
{
|
||||
return self::ACCESSORY_PRODUCT_KEYWORDS;
|
||||
return $this->stringList('accessory_product_keywords', self::ACCESSORY_PRODUCT_KEYWORDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
/** @return string[] */
|
||||
public function getDeviceProductKeywords(): array
|
||||
{
|
||||
return self::DEVICE_PRODUCT_KEYWORDS;
|
||||
return $this->stringList('device_product_keywords', self::DEVICE_PRODUCT_KEYWORDS);
|
||||
}
|
||||
|
||||
public function getExactProductNumberPhraseScore(): int
|
||||
{
|
||||
return 160;
|
||||
return $this->int('scores.exact_product_number_phrase', 160);
|
||||
}
|
||||
|
||||
public function getExactProductNamePhraseScore(): int
|
||||
{
|
||||
return 90;
|
||||
return $this->int('scores.exact_product_name_phrase', 90);
|
||||
}
|
||||
|
||||
public function getExactManufacturerMatchScore(): int
|
||||
{
|
||||
return 40;
|
||||
return $this->int('scores.exact_manufacturer_match', 40);
|
||||
}
|
||||
|
||||
public function getBrandContainedInNameScore(): int
|
||||
{
|
||||
return 20;
|
||||
return $this->int('scores.brand_contained_in_name', 20);
|
||||
}
|
||||
|
||||
public function getNameTokenOverlapWeight(): int
|
||||
{
|
||||
return 6;
|
||||
return $this->int('scores.name_token_overlap_weight', 6);
|
||||
}
|
||||
|
||||
public function getProductNumberTokenOverlapWeight(): int
|
||||
{
|
||||
return 10;
|
||||
return $this->int('scores.product_number_token_overlap_weight', 10);
|
||||
}
|
||||
|
||||
public function getCorpusTokenOverlapWeight(): int
|
||||
{
|
||||
return 2;
|
||||
return $this->int('scores.corpus_token_overlap_weight', 2);
|
||||
}
|
||||
|
||||
public function getNameNumberOverlapWeight(): int
|
||||
{
|
||||
return 18;
|
||||
return $this->int('scores.name_number_overlap_weight', 18);
|
||||
}
|
||||
|
||||
public function getProductNumberNumberOverlapWeight(): int
|
||||
{
|
||||
return 28;
|
||||
return $this->int('scores.product_number_number_overlap_weight', 28);
|
||||
}
|
||||
|
||||
public function getCorpusNumberOverlapWeight(): int
|
||||
{
|
||||
return 8;
|
||||
return $this->int('scores.corpus_number_overlap_weight', 8);
|
||||
}
|
||||
|
||||
public function getSizeMatchScore(): int
|
||||
{
|
||||
return 12;
|
||||
return $this->int('scores.size_match', 12);
|
||||
}
|
||||
|
||||
public function getAvailabilityBonusScore(): int
|
||||
{
|
||||
return 1;
|
||||
return $this->int('scores.availability_bonus', 1);
|
||||
}
|
||||
|
||||
public function getDeviceQueryDeviceProductBonus(): int
|
||||
{
|
||||
return 60;
|
||||
return $this->int('scores.device_query_device_product_bonus', 60);
|
||||
}
|
||||
|
||||
public function getDeviceQueryAccessoryPenalty(): int
|
||||
{
|
||||
return 120;
|
||||
return $this->int('scores.device_query_accessory_penalty', 120);
|
||||
}
|
||||
|
||||
public function getAccessoryQueryAccessoryProductBonus(): int
|
||||
{
|
||||
return 30;
|
||||
return $this->int('scores.accessory_query_accessory_product_bonus', 30);
|
||||
}
|
||||
|
||||
public function getAccessoryQueryDeviceProductBonus(): int
|
||||
{
|
||||
return 10;
|
||||
return $this->int('scores.accessory_query_device_product_bonus', 10);
|
||||
}
|
||||
|
||||
public function getContainsDigitPattern(): string
|
||||
{
|
||||
return '/\d/u';
|
||||
return $this->string('patterns.contains_digit', '/\d/u');
|
||||
}
|
||||
|
||||
public function getMatchingCleanupPattern(): string
|
||||
{
|
||||
return '/[^\p{L}\p{N}]+/u';
|
||||
return $this->string('patterns.matching_cleanup', '/[^\p{L}\p{N}]+/u');
|
||||
}
|
||||
|
||||
public function getWhitespaceCollapsePattern(): string
|
||||
{
|
||||
return '/\s+/u';
|
||||
return $this->string('patterns.whitespace_collapse', '/\s+/u');
|
||||
}
|
||||
|
||||
public function getTokenSplitPattern(): string
|
||||
{
|
||||
return '/[^\p{L}\p{N}]+/u';
|
||||
return $this->string('patterns.token_split', '/[^\p{L}\p{N}]+/u');
|
||||
}
|
||||
|
||||
public function wrapWithPaddingSpaces(string $value): string
|
||||
{
|
||||
return ' ' . trim($value) . ' ';
|
||||
return $this->string('padding.prefix', ' ') . trim($value) . $this->string('padding.suffix', ' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
/** @return string[] */
|
||||
public function getPriceNormalizationSearch(): array
|
||||
{
|
||||
return ['€', ' ', '.'];
|
||||
return $this->stringList('price.normalization_search', ['€', ' ', '.']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
/** @return string[] */
|
||||
public function getPriceNormalizationReplace(): array
|
||||
{
|
||||
return ['', '', ''];
|
||||
return $this->stringList('price.normalization_replace', ['', '', ''], true, ['', '', '']);
|
||||
}
|
||||
|
||||
public function getPrimaryCustomFieldKey(): string
|
||||
{
|
||||
return 'migration_Backup_product_attr1';
|
||||
return $this->string('custom_fields.primary', 'migration_Backup_product_attr1');
|
||||
}
|
||||
|
||||
public function getSecondaryCustomFieldKey(): string
|
||||
{
|
||||
return 'migration_Backup_product_attr2';
|
||||
return $this->string('custom_fields.secondary', 'migration_Backup_product_attr2');
|
||||
}
|
||||
|
||||
public function getUseCasesCustomFieldKey(): string
|
||||
{
|
||||
return 'migration_Backup_product_attr4';
|
||||
return $this->string('custom_fields.use_cases', 'migration_Backup_product_attr4');
|
||||
}
|
||||
|
||||
public function getLanguagesCustomFieldKey(): string
|
||||
{
|
||||
return 'migration_Backup_product_attr5';
|
||||
return $this->string('custom_fields.languages', 'migration_Backup_product_attr5');
|
||||
}
|
||||
|
||||
public function getPrimarySecondarySeparator(): string
|
||||
{
|
||||
return ': ';
|
||||
return $this->string('text.primary_secondary_separator', ': ');
|
||||
}
|
||||
|
||||
public function getUseCasesLabel(): string
|
||||
{
|
||||
return 'Einsatzgebiete: ';
|
||||
return $this->string('text.use_cases_label', 'Einsatzgebiete: ');
|
||||
}
|
||||
|
||||
public function getLanguagesLabel(): string
|
||||
{
|
||||
return 'Sprachen: ';
|
||||
return $this->string('text.languages_label', 'Sprachen: ');
|
||||
}
|
||||
|
||||
public function getCustomFieldJoinSeparator(): string
|
||||
{
|
||||
return ' | ';
|
||||
return $this->string('text.custom_field_join_separator', ' | ');
|
||||
}
|
||||
|
||||
public function getDescriptionEmptyLinePattern(): string
|
||||
{
|
||||
return '/^[ \t]*\R/m';
|
||||
return $this->string('description.empty_line_pattern', '/^[ \t]*\R/m');
|
||||
}
|
||||
|
||||
public function getDescriptionWhitespaceCleanupPattern(): string
|
||||
{
|
||||
return '/[ \t]{2,}/';
|
||||
return $this->string('description.whitespace_cleanup_pattern', '/[ \t]{2,}/');
|
||||
}
|
||||
|
||||
public function getDescriptionMaxLength(): int
|
||||
{
|
||||
return 1500;
|
||||
return $this->int('description.max_length', 1500, 0);
|
||||
}
|
||||
|
||||
public function getPriceDecimals(): int
|
||||
{
|
||||
return 2;
|
||||
return $this->int('price.decimals', 2, 0);
|
||||
}
|
||||
|
||||
public function getPriceDecimalSeparator(): string
|
||||
{
|
||||
return ',';
|
||||
return $this->string('price.decimal_separator', ',');
|
||||
}
|
||||
|
||||
public function getPriceThousandsSeparator(): string
|
||||
{
|
||||
return '.';
|
||||
return $this->string('price.thousands_separator', '.');
|
||||
}
|
||||
|
||||
public function getPriceSuffix(): string
|
||||
{
|
||||
return ' €';
|
||||
return $this->string('price.suffix', ' €');
|
||||
}
|
||||
|
||||
public function buildRelativeSeoUrl(string $path): string
|
||||
{
|
||||
return '/' . ltrim($path, '/');
|
||||
return $this->string('seo.relative_prefix', '/') . ltrim($path, '/');
|
||||
}
|
||||
|
||||
public function getAvailableHighlightLabel(): string
|
||||
{
|
||||
return 'Verfügbar';
|
||||
return $this->string('highlight.available_label', 'Verfügbar');
|
||||
}
|
||||
|
||||
public function getUnavailableHighlightLabel(): string
|
||||
{
|
||||
return 'Nicht verfügbar';
|
||||
return $this->string('highlight.unavailable_label', 'Nicht verfügbar');
|
||||
}
|
||||
|
||||
public function getProductNumberHighlightPrefix(): string
|
||||
{
|
||||
return 'Produktnummer: ';
|
||||
return $this->string('highlight.product_number_prefix', 'Produktnummer: ');
|
||||
}
|
||||
|
||||
public function getMissingProductImagePlaceholder(): string
|
||||
{
|
||||
return 'no-image';
|
||||
return $this->string('image.missing_placeholder', 'no-image');
|
||||
}
|
||||
|
||||
public function getDeduplicationSeparator(): string
|
||||
{
|
||||
return '|';
|
||||
return $this->string('deduplication.separator', '|');
|
||||
}
|
||||
}
|
||||
|
||||
private function int(string $path, int $default, int $min = PHP_INT_MIN): int
|
||||
{
|
||||
$value = $this->value($path, $default);
|
||||
|
||||
if (!is_numeric($value)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return max($min, (int) $value);
|
||||
}
|
||||
|
||||
private function string(string $path, string $default): string
|
||||
{
|
||||
$value = $this->value($path, $default);
|
||||
|
||||
if (!is_scalar($value)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return (string) $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $default
|
||||
* @param string[]|null $emptySafeDefault
|
||||
* @return string[]
|
||||
*/
|
||||
private function stringList(string $path, array $default, bool $allowEmptyStrings = false, ?array $emptySafeDefault = null): array
|
||||
{
|
||||
$value = $this->value($path, $default);
|
||||
|
||||
if (!is_array($value)) {
|
||||
return $emptySafeDefault ?? $default;
|
||||
}
|
||||
|
||||
$out = [];
|
||||
foreach ($value as $item) {
|
||||
if (!is_scalar($item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$item = (string) $item;
|
||||
if (!$allowEmptyStrings) {
|
||||
$item = trim($item);
|
||||
}
|
||||
|
||||
if (!$allowEmptyStrings && $item === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($allowEmptyStrings || !in_array($item, $out, true)) {
|
||||
$out[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
if ($out === [] && !$allowEmptyStrings) {
|
||||
return $emptySafeDefault ?? $default;
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, string[]> $default
|
||||
* @return array<string, string[]>
|
||||
*/
|
||||
private function stringListMap(string $path, array $default): array
|
||||
{
|
||||
$value = $this->value($path, $default);
|
||||
|
||||
if (!is_array($value)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$out = [];
|
||||
foreach ($value as $key => $items) {
|
||||
if (!is_string($key) || !is_array($items)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$cleanKey = trim($key);
|
||||
if ($cleanKey === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$cleanItems = [];
|
||||
foreach ($items as $item) {
|
||||
if (!is_scalar($item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$item = trim((string) $item);
|
||||
if ($item === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!in_array($item, $cleanItems, true)) {
|
||||
$cleanItems[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
if ($cleanItems !== []) {
|
||||
$out[$cleanKey] = $cleanItems;
|
||||
}
|
||||
}
|
||||
|
||||
return $out !== [] ? $out : $default;
|
||||
}
|
||||
|
||||
private function value(string $path, mixed $default): mixed
|
||||
{
|
||||
$current = $this->config;
|
||||
|
||||
foreach (explode('.', $path) as $segment) {
|
||||
if (!is_array($current) || !array_key_exists($segment, $current)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$current = $current[$segment];
|
||||
}
|
||||
|
||||
return $current;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user