Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9908df7

Browse files
committed
[Filesystem] Add appendToFile()
1 parent 0ab6628 commit 9908df7

File tree

2 files changed

+100
-18
lines changed

2 files changed

+100
-18
lines changed

src/Symfony/Component/Filesystem/Filesystem.php

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -624,28 +624,24 @@ public function tempnam($dir, $prefix)
624624
* @param string $filename The file to be written to
625625
* @param string $content The data to write into the file
626626
*
627-
* @throws IOException If the file cannot be written to.
627+
* @throws IOException If the file cannot be written to
628628
*/
629629
public function dumpFile($filename, $content)
630630
{
631-
$dir = dirname($filename);
632-
633-
if (!is_dir($dir)) {
634-
$this->mkdir($dir);
635-
} elseif (!is_writable($dir)) {
636-
throw new IOException(sprintf('Unable to write to the "%s" directory.', $dir), 0, null, $dir);
637-
}
638-
639-
// Will create a temp file with 0600 access rights
640-
// when the filesystem supports chmod.
641-
$tmpFile = $this->tempnam($dir, basename($filename));
642-
643-
if (false === @file_put_contents($tmpFile, $content)) {
644-
throw new IOException(sprintf('Failed to write file "%s".', $filename), 0, null, $filename);
645-
}
631+
return $this->writeFile($filename, $content);
632+
}
646633

647-
@chmod($tmpFile, 0666 & ~umask());
648-
$this->rename($tmpFile, $filename, true);
634+
/**
635+
* Atomically appends content to an existing file.
636+
*
637+
* @param string $filename The file for which to append content
638+
* @param string|array|resource $content The content to append
639+
*
640+
* @throws IOException If the file is not writable
641+
*/
642+
public function appendToFile($filename, $content)
643+
{
644+
return $this->writeFile($filename, $content, true);
649645
}
650646

651647
/**
@@ -675,4 +671,28 @@ private function getSchemeAndHierarchy($filename)
675671

676672
return 2 === count($components) ? array($components[0], $components[1]) : array(null, $components[0]);
677673
}
674+
675+
/**
676+
* Writes to a file.
677+
*
678+
* @param string $filename The file to write into
679+
* @param string|array|resource $content The content to write
680+
* @param bool $append Whether to append content to the file if it already exists
681+
*
682+
* @throws IOException If the file is not writable
683+
*/
684+
private function writeFile($filename, $content, $append = false)
685+
{
686+
$dir = dirname($filename);
687+
688+
if (!is_dir($dir)) {
689+
$this->mkdir($dir);
690+
} elseif (!is_writable($dir)) {
691+
throw new IOException(sprintf('Unable to write to the "%s" directory.', $dir), 0, null, $dir);
692+
}
693+
694+
if (false === @file_put_contents($filename, $content, $append ? FILE_APPEND | LOCK_EX : LOCK_EX)) {
695+
throw new IOException(sprintf('Failed to write file "%s".', $filename), 0, null, $filename);
696+
}
697+
}
678698
}

src/Symfony/Component/Filesystem/Tests/FilesystemTest.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,6 +1406,68 @@ public function testDumpFileWithZlibScheme()
14061406
$this->assertSame('bar', file_get_contents($filename));
14071407
}
14081408

1409+
public function testAppendToFile()
1410+
{
1411+
$filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.txt';
1412+
$this->filesystem->dumpFile($filename, 'foo');
1413+
1414+
// skip mode check on Windows
1415+
if ('\\' !== DIRECTORY_SEPARATOR) {
1416+
$this->filesystem->chmod($filename, 0664);
1417+
}
1418+
1419+
$this->filesystem->appendToFile($filename, 'bar');
1420+
1421+
$this->assertFileExists($filename);
1422+
$this->assertSame('foobar', file_get_contents($filename));
1423+
1424+
// skip mode check on Windows
1425+
if ('\\' !== DIRECTORY_SEPARATOR) {
1426+
$this->assertFilePermissions(664, $filename);
1427+
}
1428+
}
1429+
1430+
public function testAppendToFileWithScheme()
1431+
{
1432+
if (defined('HHVM_VERSION')) {
1433+
$this->markTestSkipped('HHVM does not handle the file:// scheme correctly');
1434+
}
1435+
1436+
$scheme = 'file://';
1437+
$filename = $scheme.$this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt';
1438+
$this->filesystem->dumpFile($filename, 'foo');
1439+
1440+
$this->filesystem->appendToFile($filename, 'bar');
1441+
1442+
$this->assertFileExists($filename);
1443+
$this->assertSame('foobar', file_get_contents($filename));
1444+
}
1445+
1446+
public function testAppendToFileWithZlibScheme()
1447+
{
1448+
$scheme = 'compress.zlib://';
1449+
$filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'baz.txt';
1450+
$this->filesystem->dumpFile($filename, 'foo');
1451+
1452+
// Zlib stat uses file:// wrapper so remove it
1453+
$this->assertSame('foo', file_get_contents(str_replace($scheme, '', $filename)));
1454+
1455+
$this->filesystem->appendToFile($filename, 'bar');
1456+
1457+
$this->assertFileExists($filename);
1458+
$this->assertSame('foobar', file_get_contents($filename));
1459+
}
1460+
1461+
public function testAppendToFileCreateTheFileIfNotExists()
1462+
{
1463+
$filename = $this->workspace.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.txt';
1464+
1465+
$this->filesystem->appendToFile($filename, 'bar');
1466+
1467+
$this->assertFileExists($filename);
1468+
$this->assertSame('bar', file_get_contents($filename));
1469+
}
1470+
14091471
public function testCopyShouldKeepExecutionPermission()
14101472
{
14111473
$this->markAsSkippedIfChmodIsMissing();

0 commit comments

Comments
 (0)