• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ICanBoogie / Render / 4175973983

pending completion
4175973983

push

github

Olivier Laviale
Add TemplateResolver\Namespaced

25 of 25 new or added lines in 4 files covered. (100.0%)

174 of 188 relevant lines covered (92.55%)

9.2 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.88
/lib/TemplateName.php
1
<?php
2

3
/*
4
 * This file is part of the ICanBoogie package.
5
 *
6
 * (c) Olivier Laviale <olivier.laviale@gmail.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

12
namespace ICanBoogie\Render;
13

14
use ICanBoogie\Accessor\AccessorTrait;
15
use ICanBoogie\ActiveRecord\Query;
16

17
use function basename;
18
use function dirname;
19
use function in_array;
20
use function is_string;
21
use function substr;
22

23
/**
24
 * Representation of a template name.
25
 *
26
 * @property-read string $as_template Name as template name.
27
 * @property-read string $as_partial Name as partial name.
28
 * @property-read string $as_layout Name as layout name.
29
 */
30
final class TemplateName
31
{
32
    /**
33
     * @uses get_as_template
34
     * @uses get_as_partial
35
     * @uses get_as_layout
36
     */
37
    use AccessorTrait;
38

39
    public const TEMPLATE_PREFIX_VIEW = '';
40
    public const TEMPLATE_PREFIX_LAYOUT = '@';
41
    public const TEMPLATE_PREFIX_PARTIAL = '_';
42
    public const TEMPLATE_NAMESPACE_SEPARATOR = '/';
43

44
    /**
45
     * @var array<string, self>
46
     */
47
    private static array $instances = [];
48

49
    public static function from(mixed $source): self
50
    {
51
        if ($source instanceof self) {
53✔
52
            return $source;
1✔
53
        }
54

55
        if ($source instanceof Query) { // @phpstan-ignore-line
53✔
56
            $source = $source->model->id . self::TEMPLATE_NAMESPACE_SEPARATOR . 'list'; // @phpstan-ignore-line
×
57
        }
58

59
        assert(is_string($source));
60

61
        $source = self::normalize($source);
53✔
62

63
        if (isset(self::$instances[$source])) {
53✔
64
            return self::$instances[$source];
45✔
65
        }
66

67
        return self::$instances[$source] = new self($source);
9✔
68
    }
69

70
    /**
71
     * Normalizes a template name by removing any known prefix.
72
     */
73
    public static function normalize(string $name): string
74
    {
75
        $basename = basename($name);
65✔
76
        $dirname = $basename != $name ? dirname($name) : null;
65✔
77

78
        if (
79
            in_array(
65✔
80
                $basename[0],
65✔
81
                [ self::TEMPLATE_PREFIX_VIEW, self::TEMPLATE_PREFIX_LAYOUT, self::TEMPLATE_PREFIX_PARTIAL ]
65✔
82
            )
65✔
83
        ) {
84
            $basename = substr($basename, 1);
32✔
85
        }
86

87
        if ($dirname) {
65✔
88
            $basename = $dirname . self::TEMPLATE_NAMESPACE_SEPARATOR . $basename;
48✔
89
        }
90

91
        return $basename;
65✔
92
    }
93

94
    private function get_as_template(): string
95
    {
96
        return $this->name;
12✔
97
    }
98

99
    /**
100
     * Returns the name as partial name.
101
     */
102
    private function get_as_partial(): string
103
    {
104
        return $this->with_prefix(self::TEMPLATE_PREFIX_PARTIAL);
15✔
105
    }
106

107
    /**
108
     * Returns the name as layout name.
109
     */
110
    protected function get_as_layout(): string
111
    {
112
        return $this->with_prefix(self::TEMPLATE_PREFIX_LAYOUT);
14✔
113
    }
114

115
    /**
116
     * Returns the template name with the specified prefix.
117
     */
118
    public function with_prefix(string $prefix): string
119
    {
120
        $name = $this->name;
39✔
121

122
        if (!$prefix) {
39✔
123
            return $name;
4✔
124
        }
125

126
        $basename = basename($name);
35✔
127
        $dirname = $basename != $name ? dirname($name) : null;
35✔
128

129
        $name = $prefix . $basename;
35✔
130

131
        if ($dirname) {
35✔
132
            $name = $dirname . self::TEMPLATE_NAMESPACE_SEPARATOR . $name;
26✔
133
        }
134

135
        return $name;
35✔
136
    }
137

138
    private function __construct(
139
        private readonly string $name
140
    ) {
141
    }
9✔
142

143
    public function __toString()
144
    {
145
        return $this->name;
1✔
146
    }
147
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc