Merge branch '3.0' into 3.1
* 3.0: [TwigBundle] Removed redundant return statement. [DependencyInjection] Fixed deprecated default message template with XML [TwigBridge] Removed extra arguments in 2 places. [Process] Fix write access check for pipes on Windows [HttpKernel] Use flock() for HttpCache's lock files
This commit is contained in:
commit
75ebbf826c
@ -11,7 +11,6 @@
|
||||
|
||||
namespace Symfony\Bridge\Twig\Extension;
|
||||
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Component\Security\Http\Logout\LogoutUrlGenerator;
|
||||
|
||||
/**
|
||||
@ -48,7 +47,7 @@ class LogoutUrlExtension extends \Twig_Extension
|
||||
*/
|
||||
public function getLogoutPath($key = null)
|
||||
{
|
||||
return $this->generator->getLogoutPath($key, UrlGeneratorInterface::ABSOLUTE_PATH);
|
||||
return $this->generator->getLogoutPath($key);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -60,7 +59,7 @@ class LogoutUrlExtension extends \Twig_Extension
|
||||
*/
|
||||
public function getLogoutUrl($key = null)
|
||||
{
|
||||
return $this->generator->getLogoutUrl($key, UrlGeneratorInterface::ABSOLUTE_URL);
|
||||
return $this->generator->getLogoutUrl($key);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,7 +48,7 @@ class FilesystemLoaderTest extends TestCase
|
||||
;
|
||||
$loader = new FilesystemLoader($locator, $parser);
|
||||
|
||||
return $this->assertTrue($loader->exists($template));
|
||||
$this->assertTrue($loader->exists($template));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -166,7 +166,7 @@ class XmlFileLoader extends FileLoader
|
||||
}
|
||||
|
||||
if ($deprecated = $this->getChildren($service, 'deprecated')) {
|
||||
$definition->setDeprecated(true, $deprecated[0]->nodeValue);
|
||||
$definition->setDeprecated(true, $deprecated[0]->nodeValue ?: null);
|
||||
}
|
||||
|
||||
$definition->setArguments($this->getArgumentsAsPhp($service, 'argument'));
|
||||
|
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||
<services>
|
||||
<service id="foo" class="Foo">
|
||||
<deprecated />
|
||||
</service>
|
||||
<service id="bar" class="Bar">
|
||||
<deprecated>The "%service_id%" service is deprecated.</deprecated>
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
@ -302,6 +302,21 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
$loader->load('tag_with_empty_name.xml');
|
||||
}
|
||||
|
||||
public function testDeprecated()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
|
||||
$loader->load('services_deprecated.xml');
|
||||
|
||||
$this->assertTrue($container->getDefinition('foo')->isDeprecated());
|
||||
$message = 'The "foo" service is deprecated. You should stop using it, as it will soon be removed.';
|
||||
$this->assertSame($message, $container->getDefinition('foo')->getDeprecationMessage('foo'));
|
||||
|
||||
$this->assertTrue($container->getDefinition('bar')->isDeprecated());
|
||||
$message = 'The "bar" service is deprecated.';
|
||||
$this->assertSame($message, $container->getDefinition('bar')->getDeprecationMessage('bar'));
|
||||
}
|
||||
|
||||
public function testConvertDomElementToArray()
|
||||
{
|
||||
$doc = new \DOMDocument('1.0');
|
||||
|
@ -38,7 +38,7 @@ class Store implements StoreInterface
|
||||
public function __construct($root)
|
||||
{
|
||||
$this->root = $root;
|
||||
if (!is_dir($this->root) && !@mkdir($this->root, 0777, true) && !is_dir($this->root)) {
|
||||
if (!file_exists($this->root) && !@mkdir($this->root, 0777, true) && !is_dir($this->root)) {
|
||||
throw new \RuntimeException(sprintf('Unable to create the store directory (%s).', $this->root));
|
||||
}
|
||||
$this->keyCache = new \SplObjectStorage();
|
||||
@ -52,22 +52,15 @@ class Store implements StoreInterface
|
||||
{
|
||||
// unlock everything
|
||||
foreach ($this->locks as $lock) {
|
||||
if (file_exists($lock)) {
|
||||
@unlink($lock);
|
||||
}
|
||||
flock($lock, LOCK_UN);
|
||||
fclose($lock);
|
||||
}
|
||||
|
||||
$error = error_get_last();
|
||||
if (1 === $error['type'] && false === headers_sent()) {
|
||||
// send a 503
|
||||
header('HTTP/1.0 503 Service Unavailable');
|
||||
header('Retry-After: 10');
|
||||
echo '503 Service Unavailable';
|
||||
}
|
||||
$this->locks = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks the cache for a given Request.
|
||||
* Tries to lock the cache for a given Request, without blocking.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
*
|
||||
@ -75,21 +68,24 @@ class Store implements StoreInterface
|
||||
*/
|
||||
public function lock(Request $request)
|
||||
{
|
||||
$path = $this->getPath($this->getCacheKey($request).'.lck');
|
||||
if (!is_dir(dirname($path)) && false === @mkdir(dirname($path), 0777, true) && !is_dir(dirname($path))) {
|
||||
return false;
|
||||
$key = $this->getCacheKey($request);
|
||||
|
||||
if (!isset($this->locks[$key])) {
|
||||
$path = $this->getPath($key);
|
||||
if (!file_exists(dirname($path)) && false === @mkdir(dirname($path), 0777, true) && !is_dir(dirname($path))) {
|
||||
return $path;
|
||||
}
|
||||
$h = fopen($path, 'cb');
|
||||
if (!flock($h, LOCK_EX | LOCK_NB)) {
|
||||
fclose($h);
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
$this->locks[$key] = $h;
|
||||
}
|
||||
|
||||
$lock = @fopen($path, 'x');
|
||||
if (false !== $lock) {
|
||||
fclose($lock);
|
||||
|
||||
$this->locks[] = $path;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return !file_exists($path) ?: $path;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -101,17 +97,37 @@ class Store implements StoreInterface
|
||||
*/
|
||||
public function unlock(Request $request)
|
||||
{
|
||||
$file = $this->getPath($this->getCacheKey($request).'.lck');
|
||||
$key = $this->getCacheKey($request);
|
||||
|
||||
return is_file($file) ? @unlink($file) : false;
|
||||
if (isset($this->locks[$key])) {
|
||||
flock($this->locks[$key], LOCK_UN);
|
||||
fclose($this->locks[$key]);
|
||||
unset($this->locks[$key]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isLocked(Request $request)
|
||||
{
|
||||
$path = $this->getPath($this->getCacheKey($request).'.lck');
|
||||
clearstatcache(true, $path);
|
||||
$key = $this->getCacheKey($request);
|
||||
|
||||
return is_file($path);
|
||||
if (isset($this->locks[$key])) {
|
||||
return true; // shortcut if lock held by this process
|
||||
}
|
||||
|
||||
if (!file_exists($path = $this->getPath($key))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$h = fopen($path, 'rb');
|
||||
flock($h, LOCK_EX | LOCK_NB, $wouldBlock);
|
||||
flock($h, LOCK_UN); // release the lock we just acquired
|
||||
fclose($h);
|
||||
|
||||
return (bool) $wouldBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -144,7 +160,7 @@ class Store implements StoreInterface
|
||||
}
|
||||
|
||||
list($req, $headers) = $match;
|
||||
if (is_file($body = $this->getPath($headers['x-content-digest'][0]))) {
|
||||
if (file_exists($body = $this->getPath($headers['x-content-digest'][0]))) {
|
||||
return $this->restoreResponse($headers, $body);
|
||||
}
|
||||
|
||||
@ -291,7 +307,7 @@ class Store implements StoreInterface
|
||||
*/
|
||||
private function getMetadata($key)
|
||||
{
|
||||
if (false === $entries = $this->load($key)) {
|
||||
if (!$entries = $this->load($key)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
@ -307,7 +323,15 @@ class Store implements StoreInterface
|
||||
*/
|
||||
public function purge($url)
|
||||
{
|
||||
if (is_file($path = $this->getPath($this->getCacheKey(Request::create($url))))) {
|
||||
$key = $this->getCacheKey(Request::create($url));
|
||||
|
||||
if (isset($this->locks[$key])) {
|
||||
flock($this->locks[$key], LOCK_UN);
|
||||
fclose($this->locks[$key]);
|
||||
unset($this->locks[$key]);
|
||||
}
|
||||
|
||||
if (file_exists($path = $this->getPath($key))) {
|
||||
unlink($path);
|
||||
|
||||
return true;
|
||||
@ -327,7 +351,7 @@ class Store implements StoreInterface
|
||||
{
|
||||
$path = $this->getPath($key);
|
||||
|
||||
return is_file($path) ? file_get_contents($path) : false;
|
||||
return file_exists($path) ? file_get_contents($path) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -341,23 +365,36 @@ class Store implements StoreInterface
|
||||
private function save($key, $data)
|
||||
{
|
||||
$path = $this->getPath($key);
|
||||
if (!is_dir(dirname($path)) && false === @mkdir(dirname($path), 0777, true) && !is_dir(dirname($path))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$tmpFile = tempnam(dirname($path), basename($path));
|
||||
if (false === $fp = @fopen($tmpFile, 'wb')) {
|
||||
return false;
|
||||
}
|
||||
@fwrite($fp, $data);
|
||||
@fclose($fp);
|
||||
if (isset($this->locks[$key])) {
|
||||
$fp = $this->locks[$key];
|
||||
@ftruncate($fp, 0);
|
||||
@fseek($fp, 0);
|
||||
$len = @fwrite($fp, $data);
|
||||
if (strlen($data) !== $len) {
|
||||
@ftruncate($fp, 0);
|
||||
|
||||
if ($data != file_get_contents($tmpFile)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!file_exists(dirname($path)) && false === @mkdir(dirname($path), 0777, true) && !is_dir(dirname($path))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (false === @rename($tmpFile, $path)) {
|
||||
return false;
|
||||
$tmpFile = tempnam(dirname($path), basename($path));
|
||||
if (false === $fp = @fopen($tmpFile, 'wb')) {
|
||||
return false;
|
||||
}
|
||||
@fwrite($fp, $data);
|
||||
@fclose($fp);
|
||||
|
||||
if ($data != file_get_contents($tmpFile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (false === @rename($tmpFile, $path)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@chmod($path, 0666 & ~umask());
|
||||
|
@ -50,6 +50,9 @@ class HttpCacheTestCase extends \PHPUnit_Framework_TestCase
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
if ($this->cache) {
|
||||
$this->cache->getStore()->cleanup();
|
||||
}
|
||||
$this->kernel = null;
|
||||
$this->cache = null;
|
||||
$this->caches = null;
|
||||
|
@ -19,6 +19,10 @@ class StoreTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $request;
|
||||
protected $response;
|
||||
|
||||
/**
|
||||
* @var Store
|
||||
*/
|
||||
protected $store;
|
||||
|
||||
protected function setUp()
|
||||
|
@ -52,27 +52,30 @@ class WindowsPipes extends AbstractPipes
|
||||
Process::STDERR => Process::ERR,
|
||||
);
|
||||
$tmpDir = sys_get_temp_dir();
|
||||
if (!@fopen($file = $tmpDir.'\\sf_proc_00.check', 'wb')) {
|
||||
throw new RuntimeException('A temporary file could not be opened to write the process output to, verify that your TEMP environment variable is writable');
|
||||
}
|
||||
@unlink($file);
|
||||
$error = 'unknown reason';
|
||||
set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; });
|
||||
for ($i = 0;; ++$i) {
|
||||
foreach ($pipes as $pipe => $name) {
|
||||
$file = sprintf('%s\\sf_proc_%02X.%s', $tmpDir, $i, $name);
|
||||
if (file_exists($file) && !@unlink($file)) {
|
||||
if (file_exists($file) && !unlink($file)) {
|
||||
continue 2;
|
||||
}
|
||||
$h = @fopen($file, 'xb');
|
||||
$h = fopen($file, 'xb');
|
||||
if (!$h && false === strpos($error, 'File exists')) {
|
||||
restore_error_handler();
|
||||
throw new RuntimeException(sprintf('A temporary file could not be opened to write the process output: %s', $error));
|
||||
}
|
||||
if (!$h || !$this->fileHandles[$pipe] = fopen($file, 'rb')) {
|
||||
continue 2;
|
||||
}
|
||||
if (isset($this->files[$pipe])) {
|
||||
@unlink($this->files[$pipe]);
|
||||
unlink($this->files[$pipe]);
|
||||
}
|
||||
$this->files[$pipe] = $file;
|
||||
}
|
||||
break;
|
||||
}
|
||||
restore_error_handler();
|
||||
}
|
||||
|
||||
parent::__construct($input);
|
||||
|
Reference in New Issue
Block a user