Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
Extractor
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
3 / 3
8
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 extract
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
5
 fold
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace Celemas\Verba\Tool;
6
7/**
8 * Runs a domain's scanners, keeps the messages that belong to it, and merges
9 * duplicates by id (unioning locations, preferring a plural form when any call
10 * site supplied one).
11 *
12 * @api
13 */
14final class Extractor
15{
16    public function __construct(
17        private readonly Domain $domain,
18    ) {}
19
20    /**
21     * @return array{messages: array<string, Message>, warnings: list<string>}
22     */
23    public function extract(): array
24    {
25        $merged = [];
26        $warnings = [];
27
28        foreach ($this->domain->scanners as $scanner) {
29            foreach ($scanner->scan() as $message) {
30                if (!$this->domain->owns($message->domain)) {
31                    continue;
32                }
33
34                $merged[$message->id] = $this->fold($merged[$message->id] ?? null, $message);
35            }
36
37            foreach ($scanner->warnings() as $warning) {
38                $warnings[] = $warning;
39            }
40        }
41
42        ksort($merged, SORT_STRING);
43
44        return ['messages' => $merged, 'warnings' => $warnings];
45    }
46
47    private function fold(?Message $existing, Message $next): Message
48    {
49        if ($existing === null) {
50            return new Message(null, $next->id, $next->plural, $next->locations);
51        }
52
53        return new Message(
54            null,
55            $next->id,
56            $existing->plural ?? $next->plural,
57            [...$existing->locations, ...$next->locations],
58        );
59    }
60}