PluginProbe
Packeta / 2.1
Packeta v2.1
2.3.2 2.3.1 trunk 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.3.0 1.3.1 1.3.2 1.4 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 All 56 releases
packeta / deps / nette / bootstrap / src / Bootstrap / Configurator.php

Configurator.php in Packeta 2.1, at deps/nette/bootstrap/src/Bootstrap/Configurator.php

266 lines 11.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
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 declare (strict_types=1);
8 namespace Packetery\Nette\Bootstrap;
9
10 use Packetery\Composer\Autoload\ClassLoader;
11 use Packetery\Latte;
12 use Packetery\Nette;
13 use Packetery\Nette\DI;
14 use Packetery\Tracy;
15 /**
16 * Initial system DI container generator.
17 */
18 class Configurator
19 {
20 use \Packetery\Nette\SmartObject;
21 public const CookieSecret = 'nette-debug';
22 /** @deprecated use Configurator::CookieSecret */
23 public const COOKIE_SECRET = self::CookieSecret;
24 /** @var callable[] function (Configurator $sender, DI\Compiler $compiler); Occurs after the compiler is created */
25 public $onCompile = [];
26 /** @var array */
27 public $defaultExtensions = ['application' => [\Packetery\Nette\Bridges\ApplicationDI\ApplicationExtension::class, ['%debugMode%', ['%appDir%'], '%tempDir%/cache/nette.application']], 'cache' => [\Packetery\Nette\Bridges\CacheDI\CacheExtension::class, ['%tempDir%']], 'constants' => Extensions\ConstantsExtension::class, 'database' => [\Packetery\Nette\Bridges\DatabaseDI\DatabaseExtension::class, ['%debugMode%']], 'decorator' => \Packetery\Nette\DI\Extensions\DecoratorExtension::class, 'di' => [\Packetery\Nette\DI\Extensions\DIExtension::class, ['%debugMode%']], 'extensions' => \Packetery\Nette\DI\Extensions\ExtensionsExtension::class, 'forms' => \Packetery\Nette\Bridges\FormsDI\FormsExtension::class, 'http' => [\Packetery\Nette\Bridges\HttpDI\HttpExtension::class, ['%consoleMode%']], 'inject' => \Packetery\Nette\DI\Extensions\InjectExtension::class, 'latte' => [\Packetery\Nette\Bridges\ApplicationDI\LatteExtension::class, ['%tempDir%/cache/latte', '%debugMode%']], 'mail' => \Packetery\Nette\Bridges\MailDI\MailExtension::class, 'php' => Extensions\PhpExtension::class, 'routing' => [\Packetery\Nette\Bridges\ApplicationDI\RoutingExtension::class, ['%debugMode%']], 'search' => [\Packetery\Nette\DI\Extensions\SearchExtension::class, ['%tempDir%/cache/nette.search']], 'security' => [\Packetery\Nette\Bridges\SecurityDI\SecurityExtension::class, ['%debugMode%']], 'session' => [\Packetery\Nette\Bridges\HttpDI\SessionExtension::class, ['%debugMode%', '%consoleMode%']], 'tracy' => [Tracy\Bridges\Nette\TracyExtension::class, ['%debugMode%', '%consoleMode%']]];
28 /** @var string[] of classes which shouldn't be autowired */
29 public $autowireExcludedClasses = [\ArrayAccess::class, \Countable::class, \IteratorAggregate::class, \stdClass::class, \Traversable::class];
30 /** @var array */
31 protected $staticParameters;
32 /** @var array */
33 protected $dynamicParameters = [];
34 /** @var array */
35 protected $services = [];
36 /** @var array of string|array */
37 protected $configs = [];
38 public function __construct()
39 {
40 $this->staticParameters = $this->getDefaultParameters();
41 }
42 /**
43 * Set parameter %debugMode%.
44 * @param bool|string|array $value
45 * @return static
46 */
47 public function setDebugMode($value)
48 {
49 if (\is_string($value) || \is_array($value)) {
50 $value = static::detectDebugMode($value);
51 } elseif (!\is_bool($value)) {
52 throw new \Packetery\Nette\InvalidArgumentException(\sprintf('Value must be either a string, array, or boolean, %s given.', \gettype($value)));
53 }
54 $this->staticParameters['debugMode'] = $value;
55 $this->staticParameters['productionMode'] = !$this->staticParameters['debugMode'];
56 // compatibility
57 return $this;
58 }
59 public function isDebugMode() : bool
60 {
61 return $this->staticParameters['debugMode'];
62 }
63 /**
64 * Sets path to temporary directory.
65 * @return static
66 */
67 public function setTempDirectory(string $path)
68 {
69 $this->staticParameters['tempDir'] = $path;
70 return $this;
71 }
72 /**
73 * Sets the default timezone.
74 * @return static
75 */
76 public function setTimeZone(string $timezone)
77 {
78 \date_default_timezone_set($timezone);
79 @\ini_set('date.timezone', $timezone);
80 // @ - function may be disabled
81 return $this;
82 }
83 /**
84 * Alias for addStaticParameters()
85 * @return static
86 */
87 public function addParameters(array $params)
88 {
89 return $this->addStaticParameters($params);
90 }
91 /**
92 * Adds new static parameters.
93 * @return static
94 */
95 public function addStaticParameters(array $params)
96 {
97 $this->staticParameters = DI\Config\Helpers::merge($params, $this->staticParameters);
98 return $this;
99 }
100 /**
101 * Adds new dynamic parameters.
102 * @return static
103 */
104 public function addDynamicParameters(array $params)
105 {
106 $this->dynamicParameters = $params + $this->dynamicParameters;
107 return $this;
108 }
109 /**
110 * Add instances of services.
111 * @return static
112 */
113 public function addServices(array $services)
114 {
115 $this->services = $services + $this->services;
116 return $this;
117 }
118 protected function getDefaultParameters() : array
119 {
120 $trace = \debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS);
121 $last = \end($trace);
122 $debugMode = static::detectDebugMode();
123 $loaderRc = \class_exists(ClassLoader::class) ? new \ReflectionClass(ClassLoader::class) : null;
124 return ['appDir' => isset($trace[1]['file']) ? \dirname($trace[1]['file']) : null, 'wwwDir' => isset($last['file']) ? \dirname($last['file']) : null, 'vendorDir' => $loaderRc ? \dirname($loaderRc->getFileName(), 2) : null, 'debugMode' => $debugMode, 'productionMode' => !$debugMode, 'consoleMode' => \PHP_SAPI === 'cli'];
125 }
126 public function enableTracy(?string $logDirectory = null, ?string $email = null) : void
127 {
128 if (!\class_exists(Tracy\Debugger::class)) {
129 throw new \Packetery\Nette\NotSupportedException('Tracy not found, do you have `tracy/tracy` package installed?');
130 }
131 Tracy\Debugger::$strictMode = \true;
132 Tracy\Debugger::enable(!$this->staticParameters['debugMode'], $logDirectory, $email);
133 Tracy\Bridges\Nette\Bridge::initialize();
134 if (\class_exists(Latte\Bridges\Tracy\BlueScreenPanel::class)) {
135 Latte\Bridges\Tracy\BlueScreenPanel::initialize();
136 }
137 }
138 /**
139 * Alias for enableTracy()
140 */
141 public function enableDebugger(?string $logDirectory = null, ?string $email = null) : void
142 {
143 $this->enableTracy($logDirectory, $email);
144 }
145 /**
146 * @throws \Packetery\Nette\NotSupportedException if RobotLoader is not available
147 */
148 public function createRobotLoader() : \Packetery\Nette\Loaders\RobotLoader
149 {
150 if (!\class_exists(\Packetery\Nette\Loaders\RobotLoader::class)) {
151 throw new \Packetery\Nette\NotSupportedException('RobotLoader not found, do you have `nette/robot-loader` package installed?');
152 }
153 $loader = new \Packetery\Nette\Loaders\RobotLoader();
154 $loader->setTempDirectory($this->getCacheDirectory() . '/nette.robotLoader');
155 $loader->setAutoRefresh($this->staticParameters['debugMode']);
156 if (isset($this->defaultExtensions['application'])) {
157 $this->defaultExtensions['application'][1][1] = null;
158 $this->defaultExtensions['application'][1][3] = $loader;
159 }
160 return $loader;
161 }
162 /**
163 * Adds configuration file.
164 * @param string|array $config
165 * @return static
166 */
167 public function addConfig($config)
168 {
169 $this->configs[] = $config;
170 return $this;
171 }
172 /**
173 * Returns system DI container.
174 */
175 public function createContainer(bool $initialize = \true) : DI\Container
176 {
177 $class = $this->loadContainer();
178 $container = new $class($this->dynamicParameters);
179 foreach ($this->services as $name => $service) {
180 $container->addService($name, $service);
181 }
182 if ($initialize) {
183 $container->initialize();
184 }
185 return $container;
186 }
187 /**
188 * Loads system DI container class and returns its name.
189 */
190 public function loadContainer() : string
191 {
192 $loader = new DI\ContainerLoader($this->getCacheDirectory() . '/nette.configurator', $this->staticParameters['debugMode']);
193 return $loader->load([$this, 'generateContainer'], $this->generateContainerKey());
194 }
195 /**
196 * @internal
197 */
198 public function generateContainer(DI\Compiler $compiler) : void
199 {
200 $loader = $this->createLoader();
201 $loader->setParameters($this->staticParameters);
202 foreach ($this->configs as $config) {
203 if (\is_string($config)) {
204 $compiler->loadConfig($config, $loader);
205 } else {
206 $compiler->addConfig($config);
207 }
208 }
209 $compiler->addConfig(['parameters' => DI\Helpers::escape($this->staticParameters)]);
210 $compiler->setDynamicParameterNames(\array_keys($this->dynamicParameters));
211 $builder = $compiler->getContainerBuilder();
212 $builder->addExcludedClasses($this->autowireExcludedClasses);
213 foreach ($this->defaultExtensions as $name => $extension) {
214 [$class, $args] = \is_string($extension) ? [$extension, []] : $extension;
215 if (\class_exists($class)) {
216 $args = DI\Helpers::expand($args, $this->staticParameters);
217 $compiler->addExtension($name, (new \ReflectionClass($class))->newInstanceArgs($args));
218 }
219 }
220 \Packetery\Nette\Utils\Arrays::invoke($this->onCompile, $this, $compiler);
221 }
222 protected function createLoader() : DI\Config\Loader
223 {
224 return new DI\Config\Loader();
225 }
226 protected function generateContainerKey() : array
227 {
228 return [
229 $this->staticParameters,
230 \array_keys($this->dynamicParameters),
231 $this->configs,
232 \PHP_VERSION_ID - \PHP_RELEASE_VERSION,
233 // minor PHP version
234 \class_exists(ClassLoader::class) ? \filemtime((new \ReflectionClass(ClassLoader::class))->getFilename()) : null,
235 ];
236 }
237 protected function getCacheDirectory() : string
238 {
239 if (empty($this->staticParameters['tempDir'])) {
240 throw new \Packetery\Nette\InvalidStateException('Set path to temporary directory using setTempDirectory().');
241 }
242 $dir = $this->staticParameters['tempDir'] . '/cache';
243 \Packetery\Nette\Utils\FileSystem::createDir($dir);
244 return $dir;
245 }
246 /********************* tools ****************d*g**/
247 /**
248 * Detects debug mode by IP addresses or computer names whitelist detection.
249 * @param string|array $list
250 */
251 public static function detectDebugMode($list = null) : bool
252 {
253 $addr = $_SERVER['REMOTE_ADDR'] ?? \php_uname('n');
254 $secret = \is_string($_COOKIE[self::CookieSecret] ?? null) ? $_COOKIE[self::CookieSecret] : null;
255 $list = \is_string($list) ? \preg_split('#[,\\s]+#', $list) : (array) $list;
256 if (!isset($_SERVER['HTTP_X_FORWARDED_FOR']) && !isset($_SERVER['HTTP_FORWARDED'])) {
257 $list[] = '127.0.0.1';
258 $list[] = '::1';
259 $list[] = '[::1]';
260 // workaround for PHP < 7.3.4
261 }
262 return \in_array($addr, $list, \true) || \in_array("{$secret}@{$addr}", $list, \true);
263 }
264 }
265 \class_exists(\Packetery\Nette\Configurator::class);
266