Last active
March 7, 2019 05:38
-
-
Save bubba-h57/5117694 to your computer and use it in GitHub Desktop.
Recursively move a directory with Native PHP Function calls and allow exclusions.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| $exclusions = array('/\.gitignore/', | |
| '/.*\.svn.*/', | |
| '/.*\.bak.*/', | |
| '/backups/', | |
| '/readme.txt/', | |
| '/generic/', | |
| '/orig.css/' | |
| ); | |
| rmoveWrapper('D:\Users\Bubba\tmp\test\src', 'D:\Users\Bubba\tmp\move\dest', $exclusions); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * A Recursive directory move that allows exclusions. The excluded items in the src will be deleted | |
| * rather than moved. | |
| * | |
| * @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 rmove($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); | |
| $emptiedDirs = array(); | |
| // Open the source directory to read in files | |
| foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($src, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $f) { | |
| // Check to see if we should ignore this file or directory | |
| foreach ($exclusions as $pattern){ | |
| if (preg_match($pattern, $f->getRealPath())){ | |
| if ($f->isFile()){ | |
| if (! unlink($f->getRealPath())) throw new ErrorException("Failed to delete file [{$f->getRealPath()}] ", 4); | |
| }elseif($f->isDir()){ | |
| // we will attempt deleting these after we have moved all the files. | |
| array_push($emptiedDirs, $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 move that sucker over | |
| if($f->isFile()) { | |
| $path_parts = pathinfo($destination); | |
| // If we don't have a directory for this yet | |
| if (! is_dir($path_parts['dirname'])){ | |
| // Lets create one! | |
| if (! mkdir($path_parts['dirname'], 0, true)) throw new ErrorException("Failed to create the destination directory: [{$path_parts['dirname']}]", 5); | |
| } | |
| if (! rename($f->getRealPath(), $destination)) throw new ErrorException("Failed to rename file [{$f->getRealPath()}] to [$destination]", 6); | |
| // if it is a directory, lets handle it | |
| }elseif($f->isDir()){ | |
| // Check to see if the destination directory already exists | |
| if (! is_dir($destination)){ | |
| if (! mkdir($destination, 0, true)) throw new ErrorException("Failed to create the destination directory: [$destination]", 7); | |
| } | |
| // we will attempt deleting these after we have moved all the files. | |
| array_push($emptiedDirs, $f->getRealPath()); | |
| // 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!", 8); | |
| } | |
| } | |
| foreach ($emptiedDirs as $emptyDir){ | |
| print "Deleting $emptyDir\n"; | |
| if (realpath($emptyDir) == realpath($src)){ | |
| continue; | |
| } | |
| if (!is_readable($emptyDir)) throw new ErrorException("The source directory: [$emptyDir] is not Readable", 9); | |
| // Delete the old directory | |
| if (! rmdir($emptyDir)){ | |
| // The directory is empty, we should have successfully deleted it. | |
| if ((count(scandir($emptyDir)) == 2)){ | |
| throw new ErrorException("Failed to delete the source directory: [$emptyDir]", 10); | |
| } | |
| } | |
| } | |
| // Finally, delete the base of the source directory we just recursed through | |
| if (! rmdir($src)) throw new ErrorException("Failed to delete the base source directory: [$src]", 11); | |
| return true; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Wraps up our recursive move 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 rmoveWrapper($sourceDir, $targetDir, $exclusions = array()){ | |
| try{ | |
| rmove($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: | |
| case 6: | |
| case 7: | |
| case 8: | |
| case 9: | |
| case 10: | |
| case 11: | |
| 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"; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How can i use this function in my PHP program ?