Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
84.21% covered (warning)
84.21%
16 / 19
66.67% covered (warning)
66.67%
2 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
RecordTitleResolver
88.89% covered (warning)
88.89%
16 / 18
66.67% covered (warning)
66.67%
2 / 3
12.20
0.00% covered (danger)
0.00%
0 / 1
 resolveTitle
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
5
 resolveExplicitTitle
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
4
 resolveFallbackTitle
60.00% covered (warning)
60.00%
3 / 5
0.00% covered (danger)
0.00%
0 / 1
3.58
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\Engine\Presentation\Web\Support;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11use App\Core\Engine\Domain\Model\FieldMetadata;
12
13/**
14 * Record Title Resolver.
15 *
16 * Resolves user-friendly display labels and titles for records based on field metadata heuristics.
17 *
18 * @package App\Core\Engine\Presentation\Web\Support
19 */
20final readonly class RecordTitleResolver
21{
22    /**
23     * Resolves display title for the record based on FieldMetadata title detection.
24     *
25     * @param array<FieldMetadata> $fields Field definitions.
26     * @param array<string, mixed> $record Record data map.
27     * @param int                  $id     Record primary key.
28     * @return string Display title.
29     */
30    public function resolveTitle(array $fields, array $record, int $id): string
31    {
32        $title = $this->resolveExplicitTitle($record);
33        if ($title !== null) {
34            return $title;
35        }
36
37        foreach ($fields as $field) {
38            if ($field->isTitleField() && !empty($record[$field->fieldKey])) {
39                return (string) $record[$field->fieldKey];
40            }
41        }
42
43        return $this->resolveFallbackTitle($record, $id);
44    }
45
46    /**
47     * Resolves high-priority explicit record title fields.
48     *
49     * @param array<string, mixed> $record Record data map.
50     * @return string|null Resolved explicit title or null.
51     */
52    public function resolveExplicitTitle(array $record): ?string
53    {
54        if (!empty($record['subject'])) {
55            return (string) $record['subject'];
56        }
57
58        if (!empty($record['contract_name'])) {
59            return (string) $record['contract_name'];
60        }
61
62        $fullName = trim(($record['first_name'] ?? '') . ' ' . ($record['last_name'] ?? ''));
63        return $fullName !== '' ? $fullName : null;
64    }
65
66    /**
67     * Resolves fallback generic title fields or primary key ID fallback.
68     *
69     * @param array<string, mixed> $record Record data map.
70     * @param int                  $id     Record primary key.
71     * @return string Fallback title.
72     */
73    public function resolveFallbackTitle(array $record, int $id): string
74    {
75        if (!empty($record['name'])) {
76            return (string) $record['name'];
77        }
78
79        if (!empty($record['title'])) {
80            return (string) $record['title'];
81        }
82
83        return '#' . $id;
84    }
85}