diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index f9e462a6bd..194771ea08 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -459,34 +459,30 @@ class Filesystem * @param string $prefix The prefix of the generated temporary filename. * Note: Windows uses only the first three characters of prefix. * - * @return string The new temporary filename (with path), or false on failure. + * @return string The new temporary filename (with path), or throw an exception on failure. */ public function tempnam($dir, $prefix) { - $limit = 10; list($scheme, $hierarchy) = $this->getSchemeAndHierarchy($dir); // If no scheme or scheme is "file" create temp file in local filesystem if (null === $scheme || 'file' === $scheme) { - $tmpFile = tempnam($hierarchy, $prefix); // If tempnam failed or no scheme return the filename otherwise prepend the scheme - - if (null !== $scheme) { - return $scheme.'://'.$tmpFile; - } - if (false !== $tmpFile) { + if (null !== $scheme) { + return $scheme.'://'.$tmpFile; + } + return $tmpFile; } - throw new IOException('A temporary file could not be created'); + throw new IOException('A temporary file could not be created.'); } - // Loop until we create a valid temp file or have reached $limit attempts - for ($i = 0; $i < $limit; ++$i) { - + // Loop until we create a valid temp file or have reached 10 attempts + for ($i = 0; $i < 10; ++$i) { // Create a unique filename $tmpFile = $dir.'/'.$prefix.uniqid(mt_rand(), true); @@ -503,10 +499,9 @@ class Filesystem @fclose($handle); return $tmpFile; - } - return false; + throw new IOException('A temporary file could not be created.'); } /** @@ -570,7 +565,6 @@ class Filesystem { $components = explode('://', $filename, 2); - return count($components) === 2 ? array($components[0], $components[1]) : array(null, $components[0]); + return 2 === count($components) ? array($components[0], $components[1]) : array(null, $components[0]); } - } diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php index 7eceacc273..b9ad6c26f5 100644 --- a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php +++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php @@ -11,7 +11,6 @@ namespace Symfony\Component\Filesystem\Tests; -use Phar; /** * Test class for Filesystem. */ @@ -953,7 +952,6 @@ class FilesystemTest extends FilesystemTestCase $filename = $this->filesystem->tempnam($dirname, 'foo'); - $this->assertNotFalse($filename); $this->assertFileExists($filename); } @@ -964,39 +962,34 @@ class FilesystemTest extends FilesystemTestCase $filename = $this->filesystem->tempnam($dirname, 'foo'); - $this->assertNotFalse($filename); $this->assertStringStartsWith($scheme, $filename); $this->assertFileExists($filename); } public function testTempnamWithMockScheme() { - // We avoid autoloading via ClassLoader as stream_wrapper_register creates the object - if (!@include __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'MockStream'.DIRECTORY_SEPARATOR.'MockStream.php') { - $this->markTestSkipped('Unable to load mock:// stream.'); - } - - stream_wrapper_register('mock', 'MockStream\MockStream'); + stream_wrapper_register('mock', 'Symfony\Component\Filesystem\Tests\Fixtures\MockStream\MockStream'); $scheme = 'mock://'; $dirname = $scheme.$this->workspace; $filename = $this->filesystem->tempnam($dirname, 'foo'); - $this->assertNotFalse($filename); $this->assertStringStartsWith($scheme, $filename); $this->assertFileExists($filename); } + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ public function testTempnamWithZlibSchemeFails() { $scheme = 'compress.zlib://'; $dirname = $scheme.$this->workspace; - $filename = $this->filesystem->tempnam($dirname, 'bar'); - // The compress.zlib:// stream does not support mode x: creates the file, errors "failed to open stream: operation failed" and returns false - $this->assertFalse($filename); + $this->filesystem->tempnam($dirname, 'bar'); + } public function testTempnamWithPHPTempSchemeFails() @@ -1006,17 +999,19 @@ class FilesystemTest extends FilesystemTestCase $filename = $this->filesystem->tempnam($dirname, 'bar'); - $this->assertNotFalse($filename); $this->assertStringStartsWith($scheme, $filename); // The php://temp stream deletes the file after close $this->assertFileNotExists($filename); } + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ public function testTempnamWithPharSchemeFails() { // Skip test if Phar disabled phar.readonly must be 0 in php.ini - if (!Phar::canWrite()) { + if (!\Phar::canWrite()) { $this->markTestSkipped('This test cannot run when phar.readonly is 1.'); } @@ -1024,22 +1019,21 @@ class FilesystemTest extends FilesystemTestCase $dirname = $scheme.$this->workspace; $pharname = 'foo.phar'; - $p = new Phar($this->workspace.'/'.$pharname, 0, $pharname); - $filename = $this->filesystem->tempnam($dirname, $pharname.'/bar'); - + new \Phar($this->workspace.'/'.$pharname, 0, $pharname); // The phar:// stream does not support mode x: fails to create file, errors "failed to open stream: phar error: "$filename" is not a file in phar "$pharname"" and returns false - $this->assertFalse($filename); + $this->filesystem->tempnam($dirname, $pharname.'/bar'); } + /** + * @expectedException \Symfony\Component\Filesystem\Exception\IOException + */ public function testTempnamWithHTTPSchemeFails() { $scheme = 'http://'; $dirname = $scheme.$this->workspace; - $filename = $this->filesystem->tempnam($dirname, 'bar'); - // The http:// scheme is read-only - $this->assertFalse($filename); + $this->filesystem->tempnam($dirname, 'bar'); } public function testTempnamOnUnwritableFallsBackToSysTmp() @@ -1049,7 +1043,6 @@ class FilesystemTest extends FilesystemTestCase $filename = $this->filesystem->tempnam($dirname, 'bar'); - $this->assertNotFalse($filename); $this->assertStringStartsWith(rtrim($scheme.sys_get_temp_dir(), DIRECTORY_SEPARATOR), $filename); $this->assertFileExists($filename); diff --git a/src/Symfony/Component/Filesystem/Tests/Fixtures/MockStream/MockStream.php b/src/Symfony/Component/Filesystem/Tests/Fixtures/MockStream/MockStream.php index 7dabbfd805..f14420fb60 100644 --- a/src/Symfony/Component/Filesystem/Tests/Fixtures/MockStream/MockStream.php +++ b/src/Symfony/Component/Filesystem/Tests/Fixtures/MockStream/MockStream.php @@ -9,22 +9,14 @@ * file that was distributed with this source code. */ -namespace MockStream; +namespace Symfony\Component\Filesystem\Tests\Fixtures\MockStream; /** * Mock stream class to be used with stream_wrapper_register. - * stream_wrapper_register('mock', 'MockStream\MockStream'). + * stream_wrapper_register('mock', 'Symfony\Component\Filesystem\Tests\Fixtures\MockStream\MockStream'). */ class MockStream { - private $strOverloaded; - private $content; - private $position; - private $atime; - private $mtime; - private $ctime; - private $path; - /** * Opens file or URL. * @@ -32,169 +24,16 @@ class MockStream * @param string $mode The mode used to open the file, as detailed for fopen() * @param int $options Holds additional flags set by the streams API * @param string $opened_path If the path is opened successfully, and STREAM_USE_PATH is set in options, - * opened_path should be set to the full path of the file/resource that was actually - * opened + * opened_path should be set to the full path of the file/resource that was actually opened * * @return bool */ public function stream_open($path, $mode, $options, &$opened_path) { - // Is mbstring.func_overload applied to string functions (bit 2 set) - $this->strOverloaded = (bool) (ini_get('mbstring.func_overload') & (1 << 2)); - $this->path = $path; - $this->content = ''; - $this->position = 0; - $this->atime = 0; - $this->mtime = 0; - return true; } /** - * Read from stream. - * - * @param int $count How many bytes of data from the current position should be returned - * - * @return string The data - */ - public function stream_read($count) - { - $ret = $this->substr($this->content, $this->position, $count); - $this->position += $this->strlen($ret); - $this->atime = time(); - - return $ret; - } - - /** - * Write to stream. - * - * @param string $data Data to write to the stream - * - * @return int Number of bytes that were successfully stored, or 0 if none could be stored - */ - public function stream_write($data) - { - $left = $this->substr($this->content, 0, $this->position); - $right = $this->substr($this->content, $this->position + $this->strlen($data)); - $this->content = $left.$data.$right; - $this->position += $this->strlen($data); - $this->mtime = time(); - $this->ctime = time(); - - return $this->strlen($data); - } - - /** - * Retrieve the current position of a stream. - * - * @return int The current position of the stream - */ - public function stream_tell() - { - return $this->position; - } - - /** - * Tests for end-of-file on a file pointer. - * - * @return bool Return true if the read/write position is at the end of the stream and if no more data is available - * to be read, or false otherwise - */ - public function stream_eof() - { - return $this->position >= $this->strlen($this->content); - } - - /** - * Seeks to specific location in a stream. - * - * @param int $offset The stream offset to seek to - * @param int $whence Set position based on value - * - * @return bool Return true if the position was updated, false otherwise - */ - public function stream_seek($offset, $whence) - { - switch ($whence) { - case SEEK_SET: - if ($offset < $this->strlen($this->content) && 0 <= $offset) { - $this->position = $offset; - - return true; - } - break; - - case SEEK_CUR: - if (0 <= $offset) { - $this->position += $offset; - - return true; - } - break; - - case SEEK_END: - if (0 <= $this->strlen($this->content) + $offset) { - $this->position = $this->strlen($this->content) + $offset; - - return true; - } - break; - } - - return false; - } - - /** - * Change stream options, only touch is supported. - * - * @param string $path The file path or URL to set metadata - * @param array $option - * @param array $value Additional arguments for the option - * - * @return bool Return true on success or fale on failure or if option is not implemented - */ - public function stream_metadata($path, $option, $value) - { - if (STREAM_META_TOUCH === $option) { - $now = array_key_exists(0, $value) ? $value[0] : time(); - $this->atime = array_key_exists(1, $value) ? $value[1] : $now; - $this->mtime = $now; - $this->ctime = $now; - - return true; - } - - return false; - } - - /** - * Retrieve information about a stream. - * - * @return array Stream stats - */ - public function stream_stat() - { - return array( - 'dev' => 0, - 'ino' => 0, - 'mode' => 33188, // 100644 - 'nlink' => 1, - 'uid' => 0, - 'gid' => 0, - 'rdev' => 0, - 'size' => $this->strlen($this->content), - 'atime' => $this->atime, - 'mtime' => $this->mtime, - 'ctime' => $this->ctime, - 'blksize' => 4096, - 'blocks' => 8, - ); - } - - /** - * Retrieve information about a url, added as called by PHP's builtin functions. - * * @param string $path The file path or URL to stat * @param array $flags Holds additional flags set by the streams API * @@ -202,32 +41,6 @@ class MockStream */ public function url_stat($path, $flags) { - return $this->stream_stat(); - } - - /** - * Returns the number of bytes of the given string even when strlen is overloaded to mb_strlen. - * - * @param string $string The string being measured for bytes - * - * @return int The number of bytes in the string on success, and 0 if the string is empty - */ - protected function strlen($string) - { - return function_exists('mb_strlen') && $this->strOverloaded ? mb_strlen($string, '8bit') : strlen($string); - } - - /** - * Returns the portion of string specified by the start and length parameters even when substr is overloaded to mb_substr. - * - * @param string $string The input string which must be one character or longer - * @param int $start Starting position in bytes - * @param int $length Length in bytes which if omitted or NULL is passed, extracts all bytes to the end of the string - * - * @return string - */ - protected function substr($string, $start, $length = null) - { - return function_exists('mb_substr') && $this->strOverloaded ? mb_substr($string, $start, $length, '8bit') : substr($string, $start, $length); + return array(); } }