diff --git a/README.md b/README.md index 4ede947..c1b5c67 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Simple File Manager -Simple file management for PHP. When you're looking for simple syntax to do complex things. It does everything recursively by default and with a minimum amount of complaining. +Simple file management for PHP. When you're looking for simple syntax to do complex things. The methods do everything recursively by default and with a minimum amount of complaining. ## Methods diff --git a/composer.json b/composer.json index 6d99976..31f2c37 100644 --- a/composer.json +++ b/composer.json @@ -1,13 +1,14 @@ { "name": "html2wp/simple-file-manager", "description": "Simple file management for PHP", + "version": "1.1.0", "license": "GPL-2.0+", - "homepage": "http://htmltowordpress.io", + "homepage": "https://htmltowordpress.io", "authors": [ { "name": "Harri Heljala", "email": "harri@htmltowordpress.io", - "homepage": "http://helja.la", + "homepage": "https://helja.la", "role": "Developer" } ], diff --git a/simple-file-manager.php b/simple-file-manager.php index 18eb1b4..4fd9c4b 100644 --- a/simple-file-manager.php +++ b/simple-file-manager.php @@ -1,30 +1,39 @@ open( $destination, ZIPARCHIVE::CREATE ) ) { return false; } + // Clean up the path $source = str_replace( '\\', '/', realpath( $source ) ); + // If the source is a folder, add the files recursively if ( is_dir( $source ) ) { + // Loop through the source folder foreach ( new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $source, FilesystemIterator::SKIP_DOTS ), RecursiveIteratorIterator::SELF_FIRST ) as $path ) { @@ -33,111 +42,131 @@ public static function zip( $source, $destination ) { $path = realpath( $path ); if ( is_dir( $path ) ) { - $zip->addEmptyDir( str_replace( $source . '/', '', $path . '/' ) ); - } - - elseif ( is_file( $path ) ) { - $zip->addFile( $path, str_replace( $source . '/', '', $path ) ); + // If a folder, add a coresponding placeholder folder to the zip + $zip->addEmptyDir( str_replace( "$source/", '', "$path/" ) ); + } elseif ( is_file( $path ) ) { + // If a file, add it to the zip + $zip->addFile( $path, str_replace( "$source/", '', $path ) ); } } - } - - elseif ( is_file( $source ) ) { + } elseif ( is_file( $source ) ) { + // Otherwise if the source is a file add it to the zip alone $zip->addFile( $source, basename( $source ) ); } + // Finish up return $zip->close(); } - + /** - * Extracts a zip file to given folder. Overwrite deletes an existing destination folder and replaces it with the content of the zip file. - * @param string $source The path of the zip file you want to extract - * @param string $destination The path of the folder you want to extract to - * @param bool $overwrite (Optional) Whether to overwrite an existing destination folder - * @return bool Returns TRUE on success or FALSE on failure. + * Extracts a zip file to a given folder. If optional overwrite is true, then the method deletes + * an existing destination folder and replaces it with the contents of the zip file. + * @param string $source The path of the zip file you want to extract + * @param string $destination The path of the folder you want to extract to + * @param bool $overwrite (Optional) Whether to overwrite an existing destination folder + * @return bool Returns TRUE on success or FALSE on failure. **/ public static function unzip( $source, $destination, $overwrite = false ) { + // Check that zip extensions is loaded and the source file/folder exists if ( ! extension_loaded( 'zip' ) || ! file_exists( $source ) ) { return false; } + // Create the zip $zip = new ZipArchive(); + // Check if able to open zip if ( ! $zip->open( $source ) ) { return false; } + // If the destination folder doesn't exist try to create it if ( ! is_dir( $destination ) ) { + // Try to create the destination folder if ( ! self::mkdir( $destination ) ) { return false; } - } - elseif ( $overwrite ) { + } elseif ( $overwrite ) { - self::delete( $destination ); + // If the destination folder needs to be overwritten, delete it + self::rm( $destination ); + // Try to re-create the folder if ( ! self::mkdir( $destination ) ) { return false; } } + // Exctract the zip to the destination folder $zip->extractTo( $destination ); // If we have a resource fork, get rid of it $resource_fork = $destination . '/__MACOSX/'; if ( file_exists( $resource_fork ) ) { - self::delete( $resource_fork ); + self::rm( $resource_fork ); } + // Finish up return $zip->close(); } /** * Delete a file, or recursively delete a folder and it's contents - * Based on: http://stackoverflow.com/a/15111679/3073849 - * @param string $source The path of the file or folder - * @return bool Returns TRUE on success or if file already deleted or FALSE on failure. + * @see http://stackoverflow.com/a/15111679/3073849 + * @param string $path The path of the file or folder + * @return bool Returns TRUE on success or if file already deleted or FALSE on failure. **/ - public static function delete( $source ) { + public static function rm( $path ) { - if ( ! file_exists( $source ) ) { + // If file doesn't exist we've achieved what is needed + if ( ! file_exists( $path ) ) { return true; } - if ( is_dir( $source ) ) { + // If the given path is a folder, we'll delete the contents recursively + if ( is_dir( $path ) ) { + // Loop through the folder starting from the childs (rmdir only works on empty folders) foreach ( new RecursiveIteratorIterator( - new RecursiveDirectoryIterator( $source, FilesystemIterator::SKIP_DOTS ), - RecursiveIteratorIterator::CHILD_FIRST ) as $path ) { - - if ( $path->isDir() && ! $path->isLink() ) { - rmdir( $path->getPathname() ); - } - else { - unlink( $path->getPathname() ); + new RecursiveDirectoryIterator( $path, FilesystemIterator::SKIP_DOTS ), + RecursiveIteratorIterator::CHILD_FIRST ) as $child_path ) { + + if ( $child_path->isDir() && ! $child_path->isLink() ) { + // Remove a folder, which is now empty + rmdir( $child_path->getPathname() ); + } else { + // Remove a file + unlink( $child_path->getPathname() ); } } - return rmdir( $source ); - } + // Finally remove the given folder + return rmdir( $path ); - else { - return unlink( $source ); + } else { + // Otherwise if the given path is a file, delete the file + return unlink( $path ); } + } + /** + * Alias for self:rm + */ + public static function delete( $source ) { + return self:rm( $source ); } /** * Copy a file, or recursively copy a folder and its contents - * Based on: http://stackoverflow.com/a/12763962/3073849 - * @param string $source Source path - * @param string $destination Destination path - * @param array $excludes (Optional) Name of files and folders to exclude from copying - * @return bool Returns true on success, false on failure + * @see http://stackoverflow.com/a/12763962/3073849 + * @param string $source Source path + * @param string $destination Destination path + * @param array $excludes (Optional) An array containing the names of files and folders to exclude from copying as strings + * @return bool Returns TRUE on success, FALSE on failure **/ public static function copy( $source, $destination, $excludes = array() ) { @@ -162,7 +191,9 @@ public static function copy( $source, $destination, $excludes = array() ) { } // Loop through the folder + // TODO: use recursive iterators $dir = dir( $source ); + while ( false !== $entry = $dir->read() ) { // Skip pointers @@ -174,32 +205,39 @@ public static function copy( $source, $destination, $excludes = array() ) { self::copy( "$source/$entry", "$destination/$entry", $excludes ); } - // Clean up + // Finish up $dir->close(); return true; } + /** + * Alias for self:copy + */ + public static function cp( $source, $destination, $excludes = array() ) { + return self:copy( $source, $destination, $excludes = array() ); + } + /** * Creates a folder recursively. - * @param string $path The path of the folder to create - * @param int $permissions (Optional) The mode given for the folder. The default mode (0764) is less permissive than the php default of (0777). - * @return bool Returns true if the folder already existed or if it was created on successfully, false on failure. + * @param string $path The path of the folder to create + * @param int $permissions (Optional) The mode given for the folder. The default mode (0774) is less permissive than the php default of (0777). + * @return bool Returns TRUE if the folder already existed or if it was created on successfully, FALSE on failure. */ public static function mkdir( $path, $permissions = SFM_DEFAULT_PERMISSIONS ) { // Folder exists already, return true - if ( file_exists( $path ) ) { + if ( is_dir( $path ) ) { return true; } + // Create the folder return mkdir( $path, $permissions, true ); } - } // Set default file/folder permission mode if not already defined if ( ! defined( 'SFM_DEFAULT_PERMISSIONS' ) ) { - define( 'SFM_DEFAULT_PERMISSIONS', 0764 ); + define( 'SFM_DEFAULT_PERMISSIONS', 0774 ); } \ No newline at end of file