ACC SHELL

Path : /srv/www/vhosts/svj-u-leskavy/vendor/nette/di/src/DI/
File Upload :
Current File : /srv/www/vhosts/svj-u-leskavy/vendor/nette/di/src/DI/ContainerFactory.php

<?php

/**
 * This file is part of the Nette Framework (http://nette.org)
 * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
 */

namespace Nette\DI;

use Nette;


/**
 * DI container generator.
 *
 * @author     David Grudl
 */
class ContainerFactory extends Nette\Object
{
	/** @var array of function(ContainerFactory $factory, Compiler $compiler, $config); Occurs after the compiler is created */
	public $onCompile;

	/** @var bool */
	public $autoRebuild = FALSE;

	/** @var string */
	public $class = 'SystemContainer';

	/** @var string */
	public $parentClass = 'Nette\DI\Container';

	/** @var array */
	public $config = array();

	/** @var array [file|array, section] */
	public $configFiles = array();

	/** @var string */
	public $tempDirectory;

	/** @var array */
	private $dependencies = array();


	public function __construct($tempDirectory)
	{
		$this->tempDirectory = $tempDirectory;
	}


	/**
	 * @return Container
	 */
	public function create()
	{
		if (!class_exists($this->class)) {
			$this->loadClass();
		}
		return new $this->class;
	}


	/**
	 * @return string
	 */
	protected function generateCode()
	{
		$compiler = $this->createCompiler();
		$config = $this->generateConfig();
		$this->onCompile($this, $compiler, $config);

		$code = "<?php\n";
		foreach ($this->configFiles as $info) {
			if (is_scalar($info[0])) {
				$code .= "// source: $info[0] $info[1]\n";
			}
		}
		$code .= "\n" . $compiler->compile($config, $this->class, $this->parentClass);

		if ($this->autoRebuild !== 'compat') { // back compatibility
			$this->dependencies = array_merge($this->dependencies, $compiler->getContainerBuilder()->getDependencies());
		}
		return $code;
	}


	/**
	 * @return array
	 */
	protected function generateConfig()
	{
		$config = array();
		$loader = $this->createLoader();
		foreach ($this->configFiles as $info) {
			$info = is_scalar($info[0]) ? $loader->load($info[0], $info[1]) : $info[0];
			$config = Config\Helpers::merge($info, $config);
		}
		$this->dependencies = array_merge($this->dependencies, $loader->getDependencies());

		return Config\Helpers::merge($config, $this->config);
	}


	/**
	 * @return void
	 */
	private function loadClass()
	{
		$key = md5(serialize(array($this->config, $this->configFiles, $this->class, $this->parentClass)));
		$file = "$this->tempDirectory/$key.php";

		if (!$this->autoRebuild && (@include $file) !== FALSE) { // @ - file may not exist
			return;
		}

		$handle = fopen("$file.tmp", 'c+');
		if (!$handle) {
			throw new Nette\IOException("Unable to open or create file '$file.tmp'.");
		}

		if ($this->autoRebuild) {
			flock($handle, LOCK_SH);
			foreach ((array) @unserialize(file_get_contents("$file.meta")) as $f => $time) { // @ - file may not exist
				if (@filemtime($f) !== $time) { // @ - stat may fail
					@unlink($file); // @ - file may not exist
					break;
				}
			}
		}

		if (!is_file($file)) {
			flock($handle, LOCK_EX);
			if (!is_file($file)) {
				$this->dependencies = array();
				$code = $this->generateCode();
				if (!file_put_contents($file, $code)) {
					throw new Nette\IOException("Unable to write file '$file'.");
				}
				$tmp = array();
				foreach ($this->dependencies as $f) {
					$tmp[$f] = @filemtime($f); // @ - stat may fail
				}
				file_put_contents("$file.meta", serialize($tmp));
			}
		}

		require $file;
	}


	/**
	 * @return Compiler
	 */
	protected function createCompiler()
	{
		return new Compiler;
	}


	/**
	 * @return Config\Loader
	 */
	protected function createLoader()
	{
		return new Config\Loader;
	}

}

ACC SHELL 2018