Skip to content

Instantly share code, notes, and snippets.

@bubba-h57
Created March 14, 2013 20:23
Show Gist options
  • Select an option

  • Save bubba-h57/5164888 to your computer and use it in GitHub Desktop.

Select an option

Save bubba-h57/5164888 to your computer and use it in GitHub Desktop.
<?php
/**
* A Recursive directory copy that allows exclusions.
*
* @param string $sourceDir The fully qualified source directory to copy
* @param string $targetDir The fully qualified destination directory to copy to
* @param array $exclusions An array of preg_match patterns to ignore in the copy process
* @throws InvalidArgumentException
* @throws ErrorException
* @return boolean Returns TRUE on success, throws an error otherwise.
*/
function rcopy($src, $dest, $exclusions = array()){
// If source is not a directory stop processing
if(!is_dir($src)) throw new InvalidArgumentException('The source passed in does not appear to be a valid directory: ['.$src.']', 1);
// If the destination directory does not exist create it
if(!is_dir($dest)) {
if(!mkdir($dest, 0, true)){
throw new InvalidArgumentException('The destination does not exist, and I can not create it: ['.$dest.']', 2);
}
}
// Ensure enclusions parameter is an array.
if (! is_array($exclusions)) throw new InvalidArgumentException('The exclustion parameter is not an array, it MUST be an array.', 3);
// Open the source directory to read in files
foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($src, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST) as $f) {
// Check to see if we should ignore this file or directory
foreach ($exclusions as $pattern){
if (preg_match($pattern, $f->getRealPath())){
// Because we have to jump up two foreach levels
continue 2;
}
}
// We need to get a path relative to where we are copying from
$relativePath = str_replace($src, '', $f->getRealPath());
// And we can create a destination now.
$destination = $dest . $relativePath;
// if it is a file, lets just copy that sucker over
if($f->isFile()) {
if (! copy($f->getRealPath(), $destination)) throw new ErrorException("Failed to copy file [{$f->getRealPath()}] to [$destination]", 4);
// if it is a directory, lets create the new one
}elseif($f->isDir()){
// Check to see if the destination directory already exists for some reason
if (! is_dir($destination)){
if (! mkdir($destination, 0, true)) throw new ErrorException("Failed to create the distination directory: [$destination]", 5);
}
// if it is something else, throw a fit. Symlinks can potentially end up here. I haven't tested them yet, but I think isFile() will typically
// just pick them up and work
}else{
throw new ErrorException("I found [{$f->getRealPath()}] yet it appears to be neither a directory nor a file. [{$f->isDot()}] I don't know what to do with that!", 6);
}
}
return true;
}
<?php
/**
* Wraps up our recursive copy so that we get the error reporting we desire.
*
* @param string $sourceDir The fully qualified source directory to copy
* @param string $targetDir The fully qualified destination directory to copy to
* @param array $exclusions An array of preg_match patterns to ignore in the copy process
*/
function copyWrapper($sourceDir, $targetDir, $exclusions = array()){
try{
rcopy($sourceDir, $targetDir, $exclusions);
}catch(Exception $e){
switch ($e->getCode()) {
case 1:
print "ERROR: Source Directory [$sourceDir] doesn't exist or isn't a directory, we can't copy it to [$targetDir] if it isn't there.\n";
break;
case 2:
print "ERROR: Destination Directory [$targetDir] doesn't exist and we can't create it.\n";
break;
case 3:
case 4:
case 5:
echo "ERROR: " . $e->getMessage() . "\n";
break;
default:
print "ERROR: Something went sideways with copying the [$sourceDir] directory to [$targetDir].\n";
print $e->getMessage() . "\n";
print $e->getTraceAsString() . "\n";
}
print $e->getMessage() . "\n";
print $e->getTraceAsString() . "\n";
}
}
<?php
$exclusions = array('/\.gitignore/',
'/.*\.svn.*/',
'/.*\.bak.*/',
'/backups/',
'/readme.txt/',
'/generic/',
'/orig.css/'
);
rcopyWrapper('D:\Users\Bubba\tmp\test\src', 'D:\Users\Bubba\tmp\copy\dest', $exclusions);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment