Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.45% covered (success)
95.45%
21 / 22
66.67% covered (warning)
66.67%
2 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
SearchSettings
95.24% covered (success)
95.24%
20 / 21
66.67% covered (warning)
66.67%
2 / 3
10
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 fromArray
92.86% covered (success)
92.86%
13 / 14
0.00% covered (danger)
0.00%
0 / 1
8.02
 jsonSerialize
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5/** @license For full copyright and license information, please see the LICENSE.md file. */
6
7namespace App\Core\Search\Domain\Model;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11use JsonSerializable;
12
13/**
14 * User Search Settings Value Object.
15 *
16 * Stores user preferences regarding active modules, searchable fields, and default search mode.
17 *
18 * @package App\Core\Search\Domain\Model
19 */
20final readonly class SearchSettings implements JsonSerializable
21{
22    /**
23     * SearchSettings constructor.
24     *
25     * @param list<string>                 $enabledModules   List of module names included in search.
26     * @param array<string, list<string>>  $searchableFields Map of moduleName => list of fieldKeys.
27     * @param SearchMode                   $defaultMode      Default execution mode.
28     * @param int                          $limitPerModule   Default result count limit per module.
29     */
30    public function __construct(
31        public array $enabledModules = [],
32        public array $searchableFields = [],
33        public SearchMode $defaultMode = SearchMode::SMART,
34        public int $limitPerModule = SearchQuery::DEFAULT_LIMIT_PER_MODULE
35    ) {
36    }
37
38    /**
39     * Creates instance from raw associative array.
40     *
41     * @param array<string, mixed> $data Configuration data.
42     * @return self Resolved settings instance.
43     */
44    public static function fromArray(array $data): self
45    {
46        $enabled = [];
47        if (isset($data['enabled_modules']) && is_array($data['enabled_modules'])) {
48            $enabled = array_values(array_map('strval', $data['enabled_modules']));
49        }
50
51        $fields = [];
52        if (isset($data['searchable_fields']) && is_array($data['searchable_fields'])) {
53            foreach ($data['searchable_fields'] as $mod => $fList) {
54                if (is_array($fList)) {
55                    $fields[(string) $mod] = array_values(array_map('strval', $fList));
56                }
57            }
58        }
59
60        $modeVal = (string) ($data['default_mode'] ?? SearchMode::SMART->value);
61        $mode = SearchMode::tryFrom($modeVal) ?? SearchMode::SMART;
62
63        $limit = isset($data['limit_per_module'])
64            ? max(1, min(SearchQuery::MAX_LIMIT_PER_MODULE, (int) $data['limit_per_module']))
65            : SearchQuery::DEFAULT_LIMIT_PER_MODULE;
66
67        return new self($enabled, $fields, $mode, $limit);
68    }
69
70    /**
71     * Serializes settings to array.
72     *
73     * @return array<string, mixed> Serialized configuration.
74     */
75    public function jsonSerialize(): array
76    {
77        return [
78            'enabled_modules'   => $this->enabledModules,
79            'searchable_fields' => $this->searchableFields,
80            'default_mode'      => $this->defaultMode->value,
81            'limit_per_module'  => $this->limitPerModule,
82        ];
83    }
84}