Skip to content

Commit

Permalink
bug #12972 Make the container considered non-fresh if the environment…
Browse files Browse the repository at this point in the history
… parameters are changed (thewilkybarkid)

This PR was merged into the 2.3 branch.

Discussion
----------

Make the container considered non-fresh if the environment parameters are changed

| Q             | A
| ------------- | ---
| Bug fix?      | not really
| New feature?  | kind of
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #11365
| License       | MIT
| Doc PR        | symfony/symfony-docs#4645

Fixes #11365 by making the container non-fresh if any of the prefixed environment parameters are added/removed/changed. Not a bug as it was documented as behaving as such, but I think it's worth applying to 2.3 rather than considering it a new feature.

Commits
-------

b49fa12 Make the container considered non-fresh if the environment parameters are changed
  • Loading branch information
fabpot committed Jan 25, 2015
2 parents 5dd44b6 + b49fa12 commit aa0bf6c
Show file tree
Hide file tree
Showing 4 changed files with 233 additions and 0 deletions.
95 changes: 95 additions & 0 deletions src/Symfony/Component/HttpKernel/Config/EnvParametersResource.php
@@ -0,0 +1,95 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\HttpKernel\Config;

use Symfony\Component\Config\Resource\ResourceInterface;

/**
* EnvParametersResource represents resources stored in prefixed environment variables.
*
* @author Chris Wilkinson <chriswilkinson84@gmail.com>
*/
class EnvParametersResource implements ResourceInterface, \Serializable
{
/**
* @var string
*/
private $prefix;

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

/**
* Constructor.
*
* @param string $prefix
*/
public function __construct($prefix)
{
$this->prefix = $prefix;
$this->variables = $this->findVariables();
}

/**
* {@inheritdoc}
*/
public function __toString()
{
return serialize($this->getResource());
}

/**
* {@inheritdoc}
*/
public function getResource()
{
return array('prefix' => $this->prefix, 'variables' => $this->variables);
}

/**
* {@inheritdoc}
*/
public function isFresh($timestamp)
{
return $this->findVariables() === $this->variables;
}

public function serialize()
{
return serialize(array('prefix' => $this->prefix, 'variables' => $this->variables));
}

public function unserialize($serialized)
{
$unserialized = unserialize($serialized);

$this->prefix = $unserialized['prefix'];
$this->variables = $unserialized['variables'];
}

private function findVariables()
{
$variables = array();

foreach ($_SERVER as $key => $value) {
if (0 === strpos($key, $this->prefix)) {
$variables[$key] = $value;
}
}

ksort($variables);

return $variables;
}
}
2 changes: 2 additions & 0 deletions src/Symfony/Component/HttpKernel/Kernel.php
Expand Up @@ -25,6 +25,7 @@
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
use Symfony\Component\HttpKernel\Config\EnvParametersResource;
use Symfony\Component\HttpKernel\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass;
use Symfony\Component\HttpKernel\DependencyInjection\AddClassesToCachePass;
Expand Down Expand Up @@ -621,6 +622,7 @@ protected function buildContainer()
}

$container->addCompilerPass(new AddClassesToCachePass($this));
$container->addResource(new EnvParametersResource('SYMFONY__'));

return $container;
}
Expand Down
@@ -0,0 +1,106 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\HttpKernel\Tests\Config;

use Symfony\Component\HttpKernel\Config\EnvParametersResource;

class EnvParametersResourceTest extends \PHPUnit_Framework_TestCase
{
protected $prefix = '__DUMMY_';
protected $initialEnv;
protected $resource;

protected function setUp()
{
$this->initialEnv = array(
$this->prefix.'1' => 'foo',
$this->prefix.'2' => 'bar',
);

foreach ($this->initialEnv as $key => $value) {
$_SERVER[$key] = $value;
}

$this->resource = new EnvParametersResource($this->prefix);
}

protected function tearDown()
{
foreach ($_SERVER as $key => $value) {
if (0 === strpos($key, $this->prefix)) {
unset($_SERVER[$key]);
}
}
}

public function testGetResource()
{
$this->assertSame(
array('prefix' => $this->prefix, 'variables' => $this->initialEnv),
$this->resource->getResource(),
'->getResource() returns the resource'
);
}

public function testToString()
{
$this->assertSame(
serialize(array('prefix' => $this->prefix, 'variables' => $this->initialEnv)),
(string) $this->resource
);
}

public function testIsFreshNotChanged()
{
$this->assertTrue(
$this->resource->isFresh(time()),
'->isFresh() returns true if the variables have not changed'
);
}

public function testIsFreshValueChanged()
{
reset($this->initialEnv);
$_SERVER[key($this->initialEnv)] = 'baz';

$this->assertFalse(
$this->resource->isFresh(time()),
'->isFresh() returns false if a variable has been changed'
);
}

public function testIsFreshValueRemoved()
{
reset($this->initialEnv);
unset($_SERVER[key($this->initialEnv)]);

$this->assertFalse(
$this->resource->isFresh(time()),
'->isFresh() returns false if a variable has been removed'
);
}

public function testIsFreshValueAdded()
{
$_SERVER[$this->prefix.'3'] = 'foo';

$this->assertFalse(
$this->resource->isFresh(time()),
'->isFresh() returns false if a variable has been added'
);
}

public function testSerializeUnserialize()
{
$this->assertEquals($this->resource, unserialize(serialize($this->resource)));
}
}
30 changes: 30 additions & 0 deletions src/Symfony/Component/HttpKernel/Tests/KernelTest.php
Expand Up @@ -11,6 +11,7 @@

namespace Symfony\Component\HttpKernel\Tests;

use Symfony\Component\HttpKernel\Config\EnvParametersResource;
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpFoundation\Request;
Expand Down Expand Up @@ -146,6 +147,35 @@ public function testClassCacheIsNotLoadedWhenKernelIsNotBooted()
->method('doLoadClassCache');
}

public function testEnvParametersResourceIsAdded()
{
$container = $this->getMock('Symfony\Component\DependencyInjection\ContainerBuilder');
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\Tests\Fixtures\KernelForTest')
->disableOriginalConstructor()
->setMethods(array('getContainerBuilder', 'prepareContainer', 'getCacheDir', 'getLogDir'))
->getMock();
$kernel->expects($this->any())
->method('getContainerBuilder')
->will($this->returnValue($container));
$kernel->expects($this->any())
->method('prepareContainer')
->will($this->returnValue(null));
$kernel->expects($this->any())
->method('getCacheDir')
->will($this->returnValue(sys_get_temp_dir()));
$kernel->expects($this->any())
->method('getLogDir')
->will($this->returnValue(sys_get_temp_dir()));
$container->expects($this->once())
->method('addResource')
->with(new EnvParametersResource('SYMFONY__'));

$reflection = new \ReflectionClass(get_class($kernel));
$method = $reflection->getMethod('buildContainer');
$method->setAccessible(true);
$method->invoke($kernel);
}

public function testBootKernelSeveralTimesOnlyInitializesBundlesOnce()
{
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\Tests\Fixtures\KernelForTest')
Expand Down

0 comments on commit aa0bf6c

Please sign in to comment.