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

nette / application / 27919019709

21 Jun 2026 10:08PM UTC coverage: 84.111% (+0.05%) from 84.059%
27919019709

push

github

dg
phpstan fix

2038 of 2423 relevant lines covered (84.11%)

0.84 hits per line

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

74.67
/src/Bridges/ApplicationDI/LatteExtension.php
1
<?php declare(strict_types=1);
2

3
/**
4
 * This file is part of the Nette Framework (https://nette.org)
5
 * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6
 */
7

8
namespace Nette\Bridges\ApplicationDI;
9

10
use Latte;
11
use Nette;
12
use Nette\Bridges\ApplicationLatte;
13
use Nette\DI\Definitions\Statement;
14
use Nette\Schema\Expect;
15
use Tracy;
16
use function class_exists, explode, is_string, str_contains, version_compare;
17

18

19
/**
20
 * Latte extension for Nette DI.
21
 *
22
 * @property object{
23
 *     debugger: bool|'all'|null,
24
 *     macros: array<string>,
25
 *     extensions: array<string|Nette\DI\Definitions\Statement>,
26
 *     templateClass: string|null,
27
 *     strictTypes: bool,
28
 *     strictParsing: bool,
29
 *     phpLinter: string|null,
30
 *     locale: string|null,
31
 * } $config
32
 */
33
final class LatteExtension extends Nette\DI\CompilerExtension
34
{
35
        public function __construct(
1✔
36
                private readonly string $tempDir,
37
                private readonly bool $debugMode = false,
38
        ) {
39
        }
1✔
40

41

42
        public function getConfigSchema(): Nette\Schema\Schema
43
        {
44
                return Expect::structure([
1✔
45
                        'debugger' => Expect::anyOf(true, false, 'all'),
1✔
46
                        'macros' => Expect::arrayOf('string'),
1✔
47
                        'extensions' => Expect::arrayOf('string|Nette\DI\Definitions\Statement'),
1✔
48
                        'templateClass' => Expect::string(),
1✔
49
                        'strictTypes' => Expect::bool(false),
1✔
50
                        'strictParsing' => Expect::bool(false),
1✔
51
                        'phpLinter' => Expect::string(),
1✔
52
                        'locale' => Expect::string(),
1✔
53
                ]);
54
        }
55

56

57
        public function loadConfiguration(): void
58
        {
59
                if (!class_exists(Latte\Engine::class)) {
1✔
60
                        return;
×
61
                }
62

63
                $config = $this->config;
1✔
64
                $builder = $this->getContainerBuilder();
1✔
65

66
                $latteFactory = $builder->addFactoryDefinition($this->prefix('latteFactory'))
1✔
67
                        ->setImplement(ApplicationLatte\LatteFactory::class)
1✔
68
                        ->getResultDefinition()
1✔
69
                                ->setFactory(Latte\Engine::class)
1✔
70
                                ->addSetup('setTempDirectory', [$this->tempDir])
1✔
71
                                ->addSetup('setAutoRefresh', [$this->debugMode])
1✔
72
                                ->addSetup('setStrictTypes', [$config->strictTypes]);
1✔
73

74
                if (version_compare(Latte\Engine::VERSION, '3', '<')) {
1✔
75
                        foreach ($config->macros as $macro) {
×
76
                                $this->addMacro($macro);
×
77
                        }
78
                } else {
79
                        $latteFactory->addSetup('setStrictParsing', [$config->strictParsing])
1✔
80
                                ->addSetup('enablePhpLinter', [$config->phpLinter])
1✔
81
                                ->addSetup('setLocale', [$config->locale]);
1✔
82

83
                        $builder->getDefinition($this->prefix('latteFactory'))
1✔
84
                                ->getResultDefinition()
1✔
85
                                ->addSetup('?', [$builder::literal('func_num_args() && $service->addExtension(new Nette\Bridges\ApplicationLatte\UIExtension(func_get_arg(0)))')]);
1✔
86

87
                        if ($builder->getByType(Nette\Caching\Storage::class)) {
1✔
88
                                $this->addExtension(new Statement(Nette\Bridges\CacheLatte\CacheExtension::class));
×
89
                        }
90
                        if (class_exists(Nette\Bridges\FormsLatte\FormsExtension::class)) {
1✔
91
                                $this->addExtension(new Statement(Nette\Bridges\FormsLatte\FormsExtension::class));
1✔
92
                        }
93

94
                        foreach ($config->extensions as $extension) {
1✔
95
                                if ($extension === Latte\Essential\TranslatorExtension::class) {
1✔
96
                                        $extension = new Statement($extension, [new Nette\DI\Definitions\Reference(Nette\Localization\Translator::class)]);
1✔
97
                                }
98
                                $this->addExtension($extension);
1✔
99
                        }
100
                }
101

102
                $builder->addDefinition($this->prefix('templateFactory'))
1✔
103
                        ->setFactory(ApplicationLatte\TemplateFactory::class)
1✔
104
                        ->setArguments(['templateClass' => $config->templateClass]);
1✔
105

106
                if ($this->name === 'latte') {
1✔
107
                        $builder->addAlias('nette.latteFactory', $this->prefix('latteFactory'));
1✔
108
                        $builder->addAlias('nette.templateFactory', $this->prefix('templateFactory'));
1✔
109
                }
110
        }
1✔
111

112

113
        public function beforeCompile(): void
114
        {
115
                $builder = $this->getContainerBuilder();
1✔
116

117
                if (
118
                        $this->debugMode
1✔
119
                        && ($this->config->debugger ?? $builder->getByType(Tracy\Bar::class))
1✔
120
                        && class_exists(Latte\Bridges\Tracy\LattePanel::class)
1✔
121
                ) {
122
                        $factory = $builder->getDefinition($this->prefix('templateFactory'));
×
123
                        $factory->addSetup([self::class, 'initLattePanel'], [$factory, 'all' => $this->config->debugger === 'all']);
×
124
                }
125
        }
1✔
126

127

128
        public static function initLattePanel(
129
                Nette\Application\UI\TemplateFactory $factory,
130
                Tracy\Bar $bar,
131
                bool $all = false,
132
        ): void
133
        {
134
                if (!$factory instanceof ApplicationLatte\TemplateFactory) {
×
135
                        return;
×
136
                }
137

138
                $factory->onCreate[] = function (ApplicationLatte\Template $template) use ($bar, $all) {
×
139
                        $control = $template->getLatte()->getProviders()['uiControl'] ?? null;
140
                        if ($all || $control instanceof Nette\Application\UI\Presenter) {
141
                                $name = $all && $control ? (new \ReflectionObject($control))->getShortName() : '';
142
                                if (version_compare(Latte\Engine::VERSION, '3', '<')) {
143
                                        $bar->addPanel(new Latte\Bridges\Tracy\LattePanel($template->getLatte(), $name));
144
                                } else {
145
                                        $template->getLatte()->addExtension(new Latte\Bridges\Tracy\TracyExtension($name));
146
                                }
147
                        }
148
                };
149
        }
150

151

152
        public function addMacro(string $macro): void
153
        {
154
                $builder = $this->getContainerBuilder();
×
155
                $definition = $builder->getDefinition($this->prefix('latteFactory'))->getResultDefinition();
×
156

157
                if (($macro[0] ?? null) === '@') {
×
158
                        if (str_contains($macro, '::')) {
×
159
                                [$macro, $method] = explode('::', $macro);
×
160
                        } else {
161
                                $method = 'install';
×
162
                        }
163

164
                        $definition->addSetup('?->onCompile[] = function ($engine) { ?->' . $method . '($engine->getCompiler()); }', ['@self', $macro]);
×
165

166
                } else {
167
                        if (!str_contains($macro, '::') && class_exists($macro)) {
×
168
                                $macro .= '::install';
×
169
                        }
170

171
                        $definition->addSetup('?->onCompile[] = function ($engine) { ' . $macro . '($engine->getCompiler()); }', ['@self']);
×
172
                }
173
        }
174

175

176
        public function addExtension(Statement|string $extension): void
1✔
177
        {
178
                $extension = is_string($extension)
1✔
179
                        ? new Statement($extension)
1✔
180
                        : $extension;
1✔
181

182
                $builder = $this->getContainerBuilder();
1✔
183
                $builder->getDefinition($this->prefix('latteFactory'))
1✔
184
                        ->getResultDefinition()
1✔
185
                        ->addSetup('addExtension', [$extension]);
1✔
186
        }
1✔
187
}
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