diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CompilerDebugDumpPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CompilerDebugDumpPass.php index ad93d7b419..20591c89ca 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CompilerDebugDumpPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CompilerDebugDumpPass.php @@ -12,16 +12,20 @@ namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\Config\ConfigCache; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\Filesystem\Filesystem; class CompilerDebugDumpPass implements CompilerPassInterface { public function process(ContainerBuilder $container) { - $cache = new ConfigCache($this->getCompilerLogFilename($container), false); - $cache->write(implode("\n", $container->getCompiler()->getLog())); + $filesystem = new Filesystem(); + $filesystem->dumpFile( + $this->getCompilerLogFilename($container), + implode("\n", $container->getCompiler()->getLog()), + 0666 & ~umask() + ); } public static function getCompilerLogFilename(ContainerInterface $container) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ContainerBuilderDebugDumpPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ContainerBuilderDebugDumpPass.php index 1457d7cf23..a9916cdbdc 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ContainerBuilderDebugDumpPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ContainerBuilderDebugDumpPass.php @@ -14,7 +14,7 @@ namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Dumper\XmlDumper; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; -use Symfony\Component\Config\ConfigCache; +use Symfony\Component\Filesystem\Filesystem; /** * Dumps the ContainerBuilder to a cache file so that it can be used by @@ -28,7 +28,11 @@ class ContainerBuilderDebugDumpPass implements CompilerPassInterface public function process(ContainerBuilder $container) { $dumper = new XmlDumper($container); - $cache = new ConfigCache($container->getParameter('debug.container.dump'), false); - $cache->write($dumper->dump()); + $filesystem = new Filesystem(); + $filesystem->dumpFile( + $container->getParameter('debug.container.dump'), + $dumper->dump(), + 0666 & ~umask() + ); } } diff --git a/src/Symfony/Component/Config/ConfigCache.php b/src/Symfony/Component/Config/ConfigCache.php index e3ce58adf2..cbb1984272 100644 --- a/src/Symfony/Component/Config/ConfigCache.php +++ b/src/Symfony/Component/Config/ConfigCache.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Config; use Symfony\Component\Config\Resource\ResourceInterface; +use Symfony\Component\Filesystem\Filesystem; /** * ConfigCache manages PHP cache files. @@ -66,7 +67,7 @@ class ConfigCache return true; } - $metadata = $this->file.'.meta'; + $metadata = $this->getMetaFile(); if (!is_file($metadata)) { return false; } @@ -92,28 +93,23 @@ class ConfigCache */ public function write($content, array $metadata = null) { - $dir = dirname($this->file); - if (!is_dir($dir)) { - if (false === @mkdir($dir, 0777, true)) { - throw new \RuntimeException(sprintf('Unable to create the %s directory', $dir)); - } - } elseif (!is_writable($dir)) { - throw new \RuntimeException(sprintf('Unable to write in the %s directory', $dir)); - } - - $tmpFile = tempnam($dir, basename($this->file)); - if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $this->file)) { - @chmod($this->file, 0666 & ~umask()); - } else { - throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $this->file)); - } + $mode = 0666 & ~umask(); + $filesystem = new Filesystem(); + $filesystem->dumpFile($this->file, $content, $mode); if (null !== $metadata && true === $this->debug) { - $file = $this->file.'.meta'; - $tmpFile = tempnam($dir, basename($file)); - if (false !== @file_put_contents($tmpFile, serialize($metadata)) && @rename($tmpFile, $file)) { - @chmod($file, 0666 & ~umask()); - } + $filesystem->dumpFile($this->getMetaFile(), serialize($metadata), $mode); } } + + /** + * Gets the meta file path. + * + * @return string The meta file path + */ + private function getMetaFile() + { + return $this->file.'.meta'; + } + } diff --git a/src/Symfony/Component/Filesystem/CHANGELOG.md b/src/Symfony/Component/Filesystem/CHANGELOG.md index d20ba07cdc..e6aee66a57 100644 --- a/src/Symfony/Component/Filesystem/CHANGELOG.md +++ b/src/Symfony/Component/Filesystem/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +2.3.0 +----- + + * added the dumpFile() method to atomically write files + 2.2.0 ----- diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index af26ef4c6f..809b32cf5e 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -430,4 +430,32 @@ class Filesystem return $files; } + + /** + * Atomically dumps content into a file. + * + * @param string $filename The file to be written to. + * @param string $content The data to write into the file. + * @param integer $mode The file mode (octal). + * @throws IOException If the file cannot be written to. + */ + public function dumpFile($filename, $content, $mode = 0666) + { + $dir = dirname($filename); + + if (!is_dir($dir)) { + $this->mkdir($dir); + } elseif (!is_writable($dir)) { + throw new IOException(sprintf('Unable to write in the %s directory\n', $dir)); + } + + $tmpFile = tempnam($dir, basename($filename)); + + if (false === @file_put_contents($tmpFile, $content)) { + throw new IOException(sprintf('Failed to write file "%s".', $filename)); + } + + $this->rename($tmpFile, $filename); + $this->chmod($filename, $mode); + } }