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

nette / assets / 15135537291

20 May 2025 10:47AM UTC coverage: 95.067% (-0.06%) from 95.122%
15135537291

push

github

dg
DIExtension: parameters are passed by constructor (BC break)

6 of 6 new or added lines in 1 file covered. (100.0%)

4 existing lines in 1 file now uncovered.

424 of 446 relevant lines covered (95.07%)

0.95 hits per line

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

94.59
/src/Bridges/AssetsDI/DIExtension.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Nette\Bridges\Assets;
6

7
use Nette;
8
use Nette\Assets\FilesystemMapper;
9
use Nette\Assets\Registry;
10
use Nette\Assets\ViteMapper;
11
use Nette\Bridges\AssetsLatte\LatteExtension;
12
use Nette\DI\Definitions\Statement;
13
use Nette\Schema\Expect;
14

15

16
/**
17
 * Dependency injection extension that integrates asset management into Nette application.
18
 * Provides configuration of asset mappers and their mapping to URL paths.
19
 */
20
final class DIExtension extends Nette\DI\CompilerExtension
21
{
22
        private const VitePort = 5173;
23

24
        private int $needVariable;
25

26

27
        public function __construct(
1✔
28
                private string|Nette\Schema\DynamicParameter|null $baseUrl = null,
29
                private ?string $basePath = null,
30
                private bool $debugMode = false,
31
        ) {
32
        }
1✔
33

34

35
        public function getConfigSchema(): Nette\Schema\Schema
36
        {
37
                return Expect::structure([
1✔
38
                        'basePath' => Expect::string()->dynamic(),
1✔
39
                        'baseUrl' => Expect::string()->dynamic(),
1✔
40
                        'versioning' => Expect::bool(),
1✔
41
                        'mapping' => Expect::arrayOf(
1✔
42
                                Expect::anyOf(
1✔
43
                                        Expect::string(),
1✔
44
                                        Expect::structure([
1✔
45
                                                'type' => Expect::string(),
1✔
46
                                                'path' => Expect::string()->dynamic(),
1✔
47
                                                'url' => Expect::string()->dynamic(),
1✔
48
                                                'extension' => Expect::anyOf(Expect::string(), Expect::arrayOf('string')),
1✔
49
                                                'versioning' => Expect::bool(),
1✔
50
                                                'manifest' => Expect::string()->dynamic(),
1✔
51
                                                'devServer' => Expect::anyOf(Expect::string(), Expect::bool())->default(false)->dynamic(),
1✔
52
                                        ]),
53
                                        Expect::type(Statement::class),
1✔
54
                                ),
55
                        )->default(['default' => 'assets']),
1✔
56
                ]);
57
        }
58

59

60
        public function loadConfiguration()
61
        {
62
                $builder = $this->getContainerBuilder();
1✔
63
                $registry = $builder->addDefinition($this->prefix('registry'))
1✔
64
                        ->setFactory(Registry::class);
1✔
65

66
                $this->needVariable = 0;
1✔
67
                $this->basePath = $this->config->basePath ?? $this->basePath ?? null;
1✔
68

69
                foreach ($this->config->mapping as $scope => $item) {
1✔
70
                        if (is_string($item)) {
1✔
71
                                $mapper = str_contains($item, '\\')
1✔
72
                                        ? new Statement($item)
1✔
73
                                        : $this->createFileMapper((object) ['path' => $item]);
1✔
74

75
                        } elseif (!$item instanceof \stdClass) {
1✔
UNCOV
76
                                $mapper = $item;
×
77

78
                        } elseif (($item->type ?? null) === 'vite') {
1✔
79
                                $mapper = $this->createViteMapper($item);
1✔
80

81
                        } else {
82
                                $mapper = $this->createFileMapper($item);
1✔
83
                        }
84

85
                        if ($this->needVariable === 1) {
1✔
86
                                $baseUrl = $this->config->baseUrl ?? $this->baseUrl ?? throw new \LogicException("Assets: 'baseUrl' is not defined");
1✔
87
                                $registry->addSetup('$baseUrl = new Nette\Http\UrlImmutable(?)', [new Statement("rtrim(?, '/') . '/'", [$baseUrl])]);
1✔
88
                        }
89

90
                        $registry->addSetup('addMapper', [$scope, $mapper]);
1✔
91
                }
92
        }
1✔
93

94

95
        private function createFileMapper(\stdClass $config): Statement
1✔
96
        {
97
                $this->needVariable++;
1✔
98
                return new Statement(FilesystemMapper::class, [
1✔
99
                        'baseUrl' => $this->resolveUrl($config),
1✔
100
                        'basePath' => $this->resolvePath($config),
1✔
101
                        'extensions' => (array) ($config->extension ?? null),
1✔
102
                        'versioning' => $config->versioning ?? $this->config->versioning ?? true,
1✔
103
                ]);
104
        }
105

106

107
        private function createViteMapper(\stdClass $config): Statement
1✔
108
        {
109
                return new Statement(ViteMapper::class, [
1✔
110
                        'baseUrl' => $this->resolveUrl($config),
1✔
111
                        'basePath' => new Statement('$path = ?', [$this->resolvePath($config)]),
1✔
112
                        'manifestPath' => $config->manifest ? new Statement('Nette\Utils\FileSystem::resolvePath($path, ?)', [$config->manifest]) : null,
1✔
113
                        'devServer' => $this->resolveDevServer($config),
1✔
114
                        'publicMapper' => $this->createFileMapper($config),
1✔
115
                ]);
116
        }
117

118

119
        public function beforeCompile()
120
        {
121
                $builder = $this->getContainerBuilder();
1✔
122
                if ($name = $builder->getByType(Nette\Bridges\ApplicationLatte\LatteFactory::class)) {
1✔
UNCOV
123
                        $builder->getDefinition($name)
×
UNCOV
124
                                ->getResultDefinition()
×
UNCOV
125
                                ->addSetup('addExtension', [new Statement(LatteExtension::class)]);
×
126
                }
127
        }
1✔
128

129

130
        private function resolvePath(\stdClass $config): string|Statement
1✔
131
        {
132
                $path = $this->basePath && $config->path
1✔
133
                        ? new Statement('Nette\Utils\FileSystem::resolvePath(?, ?)', [$this->basePath, $config->path])
1✔
134
                        : $config->path ?? $this->basePath ?? throw new \LogicException("Assets: 'basePath' is not defined");
1✔
135
                return new Statement("rtrim(?, '\\/')", [$path]);
1✔
136
        }
137

138

139
        private function resolveUrl(\stdClass $config): Statement
1✔
140
        {
141
                $url = new Statement('$baseUrl->resolve(?)->getAbsoluteUrl()', [$config->url ?? $config->path ?? '']);
1✔
142
                return new Statement("rtrim(?, '/')", [$url]);
1✔
143
        }
144

145

146
        private function resolveDevServer(\stdClass $config): Statement|string|null
1✔
147
        {
148
                if (!$this->debugMode || !$config->devServer) {
1✔
149
                        return null;
1✔
150
                }
151
                $devServer = is_string($config->devServer)
1✔
152
                        ? $config->devServer
1✔
153
                        : new Statement('(new Nette\Http\UrlImmutable(?))->withPort(?)->getAbsoluteUrl()', [$this->config->baseUrl ?? $this->baseUrl, self::VitePort]);
1✔
154
                return new Statement("rtrim(?, '/')", [$devServer]);
1✔
155
        }
156
}
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