Author: kn
Date: Thu Sep 20 13:37:01 2007
New Revision: 6220
Log:
- Added the ezcBaseFile::copyRecursive() method, to recursively copy files or
directories
Added:
trunk/Base/tests/file_copy_recursive_test.php (with props)
Modified:
trunk/Base/ChangeLog
trunk/Base/src/file.php
trunk/Base/tests/suite.php
Modified: trunk/Base/ChangeLog
==============================================================================
--- trunk/Base/ChangeLog [iso-8859-1] (original)
+++ trunk/Base/ChangeLog [iso-8859-1] Thu Sep 20 13:37:01 2007
@@ -1,3 +1,9 @@
+1.4alpha2 - [RELEASEDATE]
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Added the ezcBaseFile::copyRecursive() method, to recursively copy files or
+ directories
+
1.4alpha1 - Tuesday 18 September 2007
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Modified: trunk/Base/src/file.php
==============================================================================
--- trunk/Base/src/file.php [iso-8859-1] (original)
+++ trunk/Base/src/file.php [iso-8859-1] Thu Sep 20 13:37:01 2007
@@ -169,6 +169,89 @@
}
/**
+ * Recursively copy a file or directory.
+ *
+ * Recursively copy a file or directory in $source to the given
+ * destination. If a depth is given, the operation will stop, if the given
+ * recursion depth is reached. A depth of -1 means no limit, while a depth
+ * of 0 means, that only the current file or directory will be copied,
+ * without any recursion.
+ *
+ * You may optionally define modes used to create files and directories.
+ *
+ * @throws ezcBaseFileNotFoundException
+ * If the $sourceDir directory is not a directory or does not exist.
+ * @throws ezcBaseFilePermissionException
+ * If the $sourceDir directory could not be opened for reading, or the
+ * destination is not writeable.
+ *
+ * @param string $source
+ * @param string $destination
+ * @param int $depth
+ * @param int $dirMode
+ * @param int $fileMode
+ * @return void
+ */
+ static public function copyRecursive( $source, $destination, $depth = -1,
$dirMode = 0775, $fileMode = 0664 )
+ {
+ // Check if source file exists at all.
+ if ( !is_file( $source ) && !is_dir( $source ) )
+ {
+ throw new ezcBaseFileNotFoundException( $source );
+ }
+
+ // Destination file should NOT exist
+ if ( is_file( $destination ) || is_dir( $destination ) )
+ {
+ throw new ezcBaseFilePermissionException( $destination,
ezcBaseFileException::WRITE );
+ }
+
+ // Skip non readable files in source directory
+ if ( !is_readable( $source ) )
+ {
+ return;
+ }
+
+ // Copy
+ if ( is_dir( $source ) )
+ {
+ mkdir( $destination );
+ // To ignore umask, umask() should not be changed with
+ // multithreaded servers...
+ chmod( $destination, $dirMode );
+ }
+ elseif ( is_file( $source ) )
+ {
+ copy( $source, $destination );
+ chmod( $destination, $fileMode );
+ }
+
+ if ( ( $depth === 0 ) ||
+ ( !is_dir( $source ) ) )
+ {
+ // Do not recurse (any more)
+ return;
+ }
+
+ // Recurse
+ $dh = opendir( $source );
+ while( $file = readdir( $dh ) )
+ {
+ if ( ( $file === '.' ) ||
+ ( $file === '..' ) )
+ {
+ continue;
+ }
+
+ self::copyRecursive(
+ $source . '/' . $file,
+ $destination . '/' . $file,
+ $depth - 1, $dirMode, $fileMode
+ );
+ }
+ }
+
+ /**
* Calculates the relative path of the file/directory '$path' to a given
* $base path.
* This method does not touch the filesystem.
Added: trunk/Base/tests/file_copy_recursive_test.php
==============================================================================
--- trunk/Base/tests/file_copy_recursive_test.php (added)
+++ trunk/Base/tests/file_copy_recursive_test.php [iso-8859-1] Thu Sep 20
13:37:01 2007
@@ -1,0 +1,234 @@
+<?php
+/**
+ * @copyright Copyright (C) 2005-2007 eZ systems as. All rights reserved.
+ * @license http://ez.no/licenses/new_bsd New BSD License
+ * @version //autogentag//
+ * @filesource
+ * @package Base
+ * @subpackage Tests
+ */
+
+/**
+ * @package Base
+ * @subpackage Tests
+ */
+class ezcBaseFileCopyRecursiveTest extends ezcTestCase
+{
+ protected function setUp()
+ {
+ $this->tempDir = $this->createTempDir( __CLASS__ );
+ mkdir( $this->tempDir . '/dir1' );
+ mkdir( $this->tempDir . '/dir2' );
+ mkdir( $this->tempDir . '/dir2/dir1' );
+ mkdir( $this->tempDir . '/dir2/dir1/dir1' );
+ mkdir( $this->tempDir . '/dir2/dir2' );
+ mkdir( $this->tempDir . '/dir4' );
+ mkdir( $this->tempDir . '/dir5' );
+ mkdir( $this->tempDir . '/dir6' );
+ file_put_contents( $this->tempDir . '/dir1/file1.txt', 'test' );
+ file_put_contents( $this->tempDir . '/dir1/file2.txt', 'test' );
+ file_put_contents( $this->tempDir . '/dir1/.file3.txt', 'test' );
+ file_put_contents( $this->tempDir . '/dir2/file1.txt', 'test' );
+ file_put_contents( $this->tempDir . '/dir2/dir1/file1.txt', 'test' );
+ file_put_contents( $this->tempDir . '/dir2/dir1/dir1/file1.txt',
'test' );
+ file_put_contents( $this->tempDir . '/dir2/dir1/dir1/file2.txt',
'test' );
+ file_put_contents( $this->tempDir . '/dir2/dir2/file1.txt', 'test' );
+ file_put_contents( $this->tempDir . '/dir4/file1.txt', 'test' );
+ file_put_contents( $this->tempDir . '/dir4/file2.txt', 'test' );
+ file_put_contents( $this->tempDir . '/dir5/file1.txt', 'test' );
+ file_put_contents( $this->tempDir . '/dir5/file2.txt', 'test' );
+ file_put_contents( $this->tempDir . '/dir6/file1.txt', 'test' );
+ file_put_contents( $this->tempDir . '/dir6/file2.txt', 'test' );
+ chmod( $this->tempDir . '/dir4/file1.txt', 0 );
+ chmod( $this->tempDir . '/dir5', 0 );
+ chmod( $this->tempDir . '/dir6', 0400 );
+ }
+
+ protected function tearDown()
+ {
+ chmod( $this->tempDir . '/dir5', 0700 );
+ chmod( $this->tempDir . '/dir6', 0700 );
+ $this->removeTempDir();
+ }
+
+ public function testRecursiveCopyEmptyDir()
+ {
+ ezcBaseFile::copyRecursive(
+ $this->tempDir . '/dir1',
+ $this->tempDir . '/dest'
+ );
+
+ $this->assertEquals(
+ count( ezcBaseFile::findRecursive( $this->tempDir . '/dir1' ) ),
+ count( ezcBaseFile::findRecursive( $this->tempDir . '/dest' ) )
+ );
+
+ $this->assertSame(
+ 0775,
+ fileperms( $this->tempDir . '/dest' ) & 0777,
+ 'Directory mode should equal 0775.'
+ );
+ }
+
+ public function testRecursiveCopyFile()
+ {
+ ezcBaseFile::copyRecursive(
+ $this->tempDir . '/dir1/file1.txt',
+ $this->tempDir . '/dest'
+ );
+
+ $this->assertTrue(
+ is_file( $this->tempDir . '/dest' )
+ );
+
+ $this->assertSame(
+ 0664,
+ fileperms( $this->tempDir . '/dest' ) & 0777,
+ 'File mode should equal 0664.'
+ );
+ }
+
+ public function testRecursiveCopyEmptyDirMode()
+ {
+ ezcBaseFile::copyRecursive(
+ $this->tempDir . '/dir1',
+ $this->tempDir . '/dest',
+ -1,
+ 0777,
+ 0777
+ );
+
+ $this->assertEquals(
+ count( ezcBaseFile::findRecursive( $this->tempDir . '/dir1' ) ),
+ count( ezcBaseFile::findRecursive( $this->tempDir . '/dest' ) )
+ );
+
+ $this->assertSame(
+ 0777,
+ fileperms( $this->tempDir . '/dest' ) & 0777,
+ 'Directory mode should equal 0777.'
+ );
+ }
+
+ public function testRecursiveCopyFileMode()
+ {
+ ezcBaseFile::copyRecursive(
+ $this->tempDir . '/dir1/file1.txt',
+ $this->tempDir . '/dest',
+ -1,
+ 0777,
+ 0777
+ );
+
+ $this->assertTrue(
+ is_file( $this->tempDir . '/dest' )
+ );
+
+ $this->assertSame(
+ 0777,
+ fileperms( $this->tempDir . '/dest' ) & 0777,
+ 'File mode should equal 0777.'
+ );
+ }
+
+ public function testRecursiveCopyFullDir()
+ {
+ ezcBaseFile::copyRecursive(
+ $this->tempDir . '/dir2',
+ $this->tempDir . '/dest'
+ );
+
+ $this->assertEquals(
+ count( ezcBaseFile::findRecursive( $this->tempDir . '/dir2' ) ),
+ count( ezcBaseFile::findRecursive( $this->tempDir . '/dest' ) )
+ );
+ }
+
+ public function testRecursiveCopyFullDirDepthZero()
+ {
+ ezcBaseFile::copyRecursive(
+ $this->tempDir . '/dir2',
+ $this->tempDir . '/dest',
+ 0
+ );
+
+ $this->assertEquals(
+ 0,
+ count( ezcBaseFile::findRecursive( $this->tempDir . '/dest' ) )
+ );
+
+ $this->assertTrue(
+ is_dir( $this->tempDir . '/dest' )
+ );
+ }
+
+ public function testRecursiveCopyFullDirLimitedDepth()
+ {
+ ezcBaseFile::copyRecursive(
+ $this->tempDir . '/dir2',
+ $this->tempDir . '/dest',
+ 2
+ );
+
+ $this->assertEquals(
+ 3,
+ count( ezcBaseFile::findRecursive( $this->tempDir . '/dest' ) )
+ );
+ }
+
+ public function testRecursiveCopyFailureNotExisting()
+ {
+ try
+ {
+ ezcBaseFile::copyRecursive(
+ $this->tempDir . '/not_existing',
+ $this->tempDir . '/dest'
+ );
+ }
+ catch ( ezcBaseFileNotFoundException $e )
+ {
+ return;
+ }
+
+ $this->fail( 'Expected ezcBaseFileNotFoundException.' );
+ }
+
+ public function testRecursiveCopyFailureNotReadable()
+ {
+ ezcBaseFile::copyRecursive(
+ $this->tempDir . '/dir5',
+ $this->tempDir . '/dest'
+ );
+
+ $this->assertFalse(
+ is_dir( $this->tempDir . '/dest' )
+ );
+
+ $this->assertFalse(
+ is_file( $this->tempDir . '/dest' )
+ );
+ }
+
+ public function testRecursiveCopyFailureNotWriteable()
+ {
+ try
+ {
+ ezcBaseFile::copyRecursive(
+ $this->tempDir . '/dir2',
+ $this->tempDir . '/dir4'
+ );
+ }
+ catch ( ezcBaseFilePermissionException $e )
+ {
+ return;
+ }
+
+ $this->fail( 'Expected ezcBaseFilePermissionException.' );
+ }
+
+ public static function suite()
+ {
+ return new PHPUnit_Framework_TestSuite( __CLASS__ );
+ }
+}
+?>
Propchange: trunk/Base/tests/file_copy_recursive_test.php
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/Base/tests/suite.php
==============================================================================
--- trunk/Base/tests/suite.php [iso-8859-1] (original)
+++ trunk/Base/tests/suite.php [iso-8859-1] Thu Sep 20 13:37:01 2007
@@ -14,6 +14,7 @@
require_once( "struct_test.php");
require_once 'file_find_recursive_test.php';
require_once 'file_is_absolute_path.php';
+require_once 'file_copy_recursive_test.php';
require_once 'file_remove_recursive_test.php';
require_once 'file_calculate_relative_path_test.php';
@@ -36,6 +37,7 @@
$this->addTest( ezcBaseFileCalculateRelativePathTest::suite() );
$this->addTest( ezcBaseFileFindRecursiveTest::suite() );
$this->addTest( ezcBaseFileIsAbsoluteTest::suite() );
+ $this->addTest( ezcBaseFileCopyRecursiveTest::suite() );
$this->addTest( ezcBaseFileRemoveRecursiveTest::suite() );
}
--
svn-components mailing list
[email protected]
http://lists.ez.no/mailman/listinfo/svn-components