Skip to content

Commit

Permalink
added ContainerLoader: humble replacement for ContainerFactory
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Nov 16, 2014
1 parent ab02d38 commit 7da1abe
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/DI/ContainerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* DI container generator.
*
* @author David Grudl
* @deprecated
*/
class ContainerFactory extends Nette\Object
{
Expand Down
104 changes: 104 additions & 0 deletions src/DI/ContainerLoader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?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 loader.
*
* @author David Grudl
*/
class ContainerLoader extends Nette\Object
{
/** @var bool */
private $autoRebuild = FALSE;

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


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


/**
* @param mixed
* @param callable function(string $class): [code, files]
* @return string
*/
public function load($key, $generator)
{
$class = $this->getClassName($key);
if (!class_exists($class)) {

This comment has been minimized.

Copy link
@JanTvrdik

JanTvrdik Feb 20, 2015

Contributor

Why not class_exists($class, FALSE)?

This comment has been minimized.

Copy link
@dg

dg Feb 21, 2015

Author Member

Yep.

$this->loadFile($class, $generator);
}
return $class;
}


/**
* @return string
*/
public function getClassName($key)
{
return 'Container_' . substr(md5(serialize($key)), 0, 10);
}


/**
* @return void
*/
private function loadFile($class, $generator)
{
$file = "$this->tempDirectory/$class.php";
if (!$this->autoRebuild && (@include $file) !== FALSE) { // @ - file may not exist
return;
}

if (!is_dir($this->tempDirectory)) {
@mkdir($this->tempDirectory); // @ - directory may already exist
}
$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)) {
list($code, $dependencies) = call_user_func($generator, $class);
if (!file_put_contents($file, "<?php\n" . $code)) {
throw new Nette\IOException("Unable to write file '$file'.");
}
$tmp = array();
foreach ((array) $dependencies as $f) {
$tmp[$f] = @filemtime($f); // @ - stat may fail
}
file_put_contents("$file.meta", serialize($tmp));
}
}

require $file;
}

}
23 changes: 23 additions & 0 deletions tests/DI/ContainerLoader.basic.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

/**
* Test: Nette\DI\ContainerLoader basic usage.
*/

use Nette\DI,
Tester\Assert;


require __DIR__ . '/../bootstrap.php';


$cache = new DI\ContainerLoader(TEMP_DIR . '/subdir');

$key = array(1, 2);
$className = $cache->getClassName($key);
Assert::match('Container%[\w]+%', $className);

$container = $cache->load($key, function($class) {
return array("class $class {}", array());
});
Assert::type($className, new $container);

0 comments on commit 7da1abe

Please sign in to comment.