Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
CRAP
100.00% covered (success)
100.00%
1 / 1
PlaceholderResolver
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
1 / 1
 resolve
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5/**
6 * This file is part of fast-forward/dev-tools.
7 *
8 * This source file is subject to the license bundled
9 * with this source code in the file LICENSE.
10 *
11 * @copyright Copyright (c) 2026 Felipe SayĆ£o Lobato Abreu <github@mentordosnerds.com>
12 * @license   https://opensource.org/licenses/MIT MIT License
13 *
14 * @see       https://github.com/php-fast-forward/dev-tools
15 * @see       https://github.com/php-fast-forward
16 * @see       https://datatracker.ietf.org/doc/html/rfc2119
17 */
18
19namespace FastForward\DevTools\License;
20
21use function Safe\preg_replace;
22
23/**
24 * Resolves placeholders in license templates with metadata values.
25 *
26 * This class replaces placeholders like {{ year }}, {{ author }}, {{ project }},
27 * {{ organization }}, and {{ copyright_holder }} with values from metadata.
28 * Unresolved placeholders are removed and excess newlines are normalized.
29 */
30 class PlaceholderResolver implements PlaceholderResolverInterface
31{
32    /**
33     * Resolves placeholders in a license template with the provided metadata.
34     *
35     * Supported placeholders:
36     * - {{ year }} - The copyright year (defaults to current year)
37     * - {{ organization }} - The organization or vendor name
38     * - {{ author }} - The primary author name or email
39     * - {{ project }} - The project/package name
40     * - {{ copyright_holder }} - Organization or author (organization takes precedence)
41     *
42     * Unmatched placeholders are removed, and consecutive blank lines are normalized.
43     *
44     * @param string $template The license template content with placeholders
45     * @param array{year?: int, organization?: string, author?: string, project?: string} $metadata The metadata values to use for replacement
46     *
47     * @return string The template with all resolved placeholders
48     */
49    public function resolve(string $template, array $metadata): string
50    {
51        $replacements = [
52            '{{ year }}' => (string) ($metadata['year'] ?? date('Y')),
53            '{{ organization }}' => $metadata['organization'] ?? '',
54            '{{ author }}' => $metadata['author'] ?? '',
55            '{{ project }}' => $metadata['project'] ?? '',
56            '{{ copyright_holder }}' => $metadata['organization'] ?? $metadata['author'] ?? '',
57        ];
58
59        $result = $template;
60
61        foreach ($replacements as $placeholder => $value) {
62            $result = str_replace($placeholder, $value, $result);
63        }
64
65        $result = preg_replace('/\{\{\s*\w+\s*\}\}/', '', $result);
66
67        $result = preg_replace('/\n{3,}/', "\n\n", $result);
68
69        return trim((string) $result);
70    }
71}