PluginProbe
Packeta / trunk
Packeta vtrunk
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 / di / src / DI / ContainerLoader.php

ContainerLoader.php in Packeta trunk, at deps/nette/di/src/DI/ContainerLoader.php

103 lines 3.9 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\DI;
9
10 use Packetery\Nette;
11 /**
12 * DI container loader.
13 */
14 class ContainerLoader
15 {
16 use \Packetery\Nette\SmartObject;
17 /** @var bool */
18 private $autoRebuild;
19 /** @var string */
20 private $tempDirectory;
21 public function __construct(string $tempDirectory, bool $autoRebuild = \false)
22 {
23 $this->tempDirectory = $tempDirectory;
24 $this->autoRebuild = $autoRebuild;
25 }
26 /**
27 * @param callable $generator function (\Packetery\Nette\DI\Compiler $compiler): string|null
28 * @param mixed $key
29 */
30 public function load(callable $generator, $key = null) : string
31 {
32 $class = $this->getClassName($key);
33 if (!\class_exists($class, \false)) {
34 $this->loadFile($class, $generator);
35 }
36 return $class;
37 }
38 /**
39 * @param mixed $key
40 */
41 public function getClassName($key) : string
42 {
43 return 'Container_' . \substr(\md5(\serialize($key)), 0, 10);
44 }
45 private function loadFile(string $class, callable $generator) : void
46 {
47 $file = "{$this->tempDirectory}/{$class}.php";
48 if (!$this->isExpired($file) && @(include $file) !== \false) {
49 // @ file may not exist
50 return;
51 }
52 \Packetery\Nette\Utils\FileSystem::createDir($this->tempDirectory);
53 $handle = @\fopen("{$file}.lock", 'c+');
54 // @ is escalated to exception
55 if (!$handle) {
56 throw new \Packetery\Nette\IOException(\sprintf("Unable to create file '%s.lock'. %s", $file, \Packetery\Nette\Utils\Helpers::getLastError()));
57 } elseif (!@\flock($handle, \LOCK_EX)) {
58 // @ is escalated to exception
59 throw new \Packetery\Nette\IOException(\sprintf("Unable to acquire exclusive lock on '%s.lock'. %s", $file, \Packetery\Nette\Utils\Helpers::getLastError()));
60 }
61 if (!\is_file($file) || $this->isExpired($file, $updatedMeta)) {
62 if (isset($updatedMeta)) {
63 $toWrite["{$file}.meta"] = $updatedMeta;
64 } else {
65 [$toWrite[$file], $toWrite["{$file}.meta"]] = $this->generate($class, $generator);
66 }
67 foreach ($toWrite as $name => $content) {
68 if (\file_put_contents("{$name}.tmp", $content) !== \strlen($content) || !\rename("{$name}.tmp", $name)) {
69 @\unlink("{$name}.tmp");
70 // @ - file may not exist
71 throw new \Packetery\Nette\IOException(\sprintf("Unable to create file '%s'.", $name));
72 } elseif (\function_exists('opcache_invalidate')) {
73 @\opcache_invalidate($name, \true);
74 // @ can be restricted
75 }
76 }
77 }
78 if (@(include $file) === \false) {
79 // @ - error escalated to exception
80 throw new \Packetery\Nette\IOException(\sprintf("Unable to include '%s'.", $file));
81 }
82 \flock($handle, \LOCK_UN);
83 }
84 private function isExpired(string $file, ?string &$updatedMeta = null) : bool
85 {
86 if ($this->autoRebuild) {
87 $meta = @\unserialize((string) \file_get_contents("{$file}.meta"));
88 // @ - file may not exist
89 $orig = $meta[2] ?? null;
90 return empty($meta[0]) || DependencyChecker::isExpired(...$meta) || $orig !== $meta[2] && ($updatedMeta = \serialize($meta));
91 }
92 return \false;
93 }
94 /** @return array of (code, file[]) */
95 protected function generate(string $class, callable $generator) : array
96 {
97 $compiler = new Compiler();
98 $compiler->setClassName($class);
99 $code = $generator(...[&$compiler]) ?: $compiler->compile();
100 return ["<?php\n{$code}", \serialize($compiler->exportDependencies())];
101 }
102 }
103