I'm trying to create a backup class, with the main goal of customizing the class-call to make the final backup be filtered only on specific extensions, specific filesizes, or specific directories within a main directory, based on user choices.
Currently, the class lacks the compression algorithms, because I've been stuck on finding solutions about the .zip compression.
Here's an example of the file and folder structure that the class will use to be able to create a compressed archive ( zip, rar, gz, whatever ):
Array
(
[0] => pclzip.lib.php
[1] => index.php
[style] => Array
(
[js] => Array
(
[0] => jNice.js
[1] => jquery.js
)
[img] => Array
(
[0] => input-shaddow-hover.gif
[1] => btn_right.gif
[2] => top-menu-bg.gif
[3] => top-menu-item-bg.gif
[4] => left-menu-bg.gif
[5] => button-submit.gif
[6] => btn_left.gif
[7] => select_right.gif
[8] => select_left.gif
[9] => transdmin-light.png
[10] => content.gif
[11] => input-shaddow.gif
)
[css] => Array
(
[0] => transdmin.css
[1] => layout.css
[2] => ie7.css
[3] => hack.css
[4] => jNice.css
[5] => ie6.css
[6] => reset.css
)
)
[2] => config.php
[3] => delete.php
[4] => restore.php
[5] => cron.php
[6] => manage.php
)
As you can see, the file and folder structure needs to be mantained in the backup file, so the list of file and folders to be backupped has been structured so that if an array leaf contains a sub-array, the leaf is a DIRECTORY, if a leaf contains no sub-arrays, the leaf is a FILE.
Here's what I came for in creating a procedure for recursively zip files and folders that ( should ) work for the structured array I presented before:
private function zipFileAndFolderStructureArray ( $backupContentsArray, $zipDestination, $backupRootDirectory ) {
if ( $this -> zipObject == null ) {
if ( extension_loaded ( 'zip' ) === true ) {
$this -> zipObject = new ZipArchive();
if ( ( $zipErrorCode = $this -> zipObject -> open ( $zipDestination, ZipArchive::CREATE ) ) !== true ) $this -> zipObject = null;
else $this -> zipFileAndFolderStructureArray ( $backupContentsArray, $zipDestination, $backupRootDirectory );
}
}
else if ( $this -> zipObject != null ) {
foreach ( $backupContentsArray as $folder => $file_or_folder_list ) {
$cwd = rtrim ( $backupRootDirectory, '/' ) . '/' . $folder . '/';
if ( is_array ( $file_or_folder_list ) && is_dir ( $cwd . $folder ) ) {
echo 'adding folder ' . $folder . ' in cwd ' . $cwd . '<br>';
$this -> zipObject -> addEmptyDir ( $folder );
$this -> zipFileAndFolderStructureArray ( $file_or_folder_list, $zipDestination, $cwd );
}
else if ( is_file ( $cwd . $file_or_folder_list ) ) {
echo 'adding file ' . $file_or_folder_list . '<br>';
$this -> zipObject -> addFromString ( $cwd . $file_or_folder_list );
}
}
$this -> zipObject -> close ();
return true;
}
}
The problem is, I'm stuck at this point. This recursive function exists after the first folder leaf has been entered, creating an archive with only 1 empty folder inside of it.
Can you help me in figure out what's wrong?
Hints on possible classes I can use to extend the compression functionality to RAR and GZ, reusing as much as possible the same compression algorithm used for the ZIP one?
Thank you in advance
P.S Added the current function that creates the folder and directory structure
public function directory_list ( $directory_base_path, $filter_dir = false, $filter_files = false, $exclude_empty_dirs = true, $include_extensions = null, $exclude_extensions = null, $exclude_files = null, $recursive = true ) {
$directory_base_path = rtrim ($directory_base_path, "/" ) . "/";
if ( ! is_dir ( $directory_base_path ) ) return false;
$result_list = array();
if ( ! is_array ( $exclude_files ) ) $exclude_array = Array ( '.', '..' );
else $exclude_array = array_merge ( Array ( '.', '..' ), $exclude_files );
if ( ! $folder_handle = opendir ( $directory_base_path ) ) return false;
else{
while ( false !== ( $filename = readdir ( $folder_handle ) ) ) {
if ( ! in_array ( $filename, $exclude_array ) ) {
if ( is_dir ( $directory_base_path . $filename . "/" ) ) {
if ( $recursive && strcmp ( $filename, "." ) != 0 && strcmp ( $filename, ".." ) != 0 ) { // prevent infinite recursion
$result = self::directory_list("$directory_base_path$filename/", $filter_dir, $filter_files, $exclude_empty_dirs, $include_extensions, $exclude_extensions, $exclude_files, $recursive);
if ( $exclude_empty_dirs ) {
if ( count ( array_keys ( $result ) ) > 0 ) $result_list[$filename] = $result;
}
else $result_list[$filename] = $result;
}
else if ( ! $filter_dir ) $result_list[] = $filename;
}
else if ( ! $filter_files ) {
$extension = end ( explode ( '.', $filename ) );
if ( ! is_array ( $include_extensions ) && count ( $include_extensions ) == 0 && ! is_array ( $exclude_extensions ) && count ( $exclude_extensions ) == 0 ) if ( $filename != '.' && $filename != '..' ) $result_list[] = $filename;
if ( is_array ( $exclude_extensions ) && count ( $exclude_extensions ) > 0 && ! in_array ( $extension, $exclude_extensions ) ) $result_list[] = $filename;
else if ( is_array ( $include_extensions ) && count ( $include_extensions ) > 0 && strlen ( $extension ) > 0 && in_array ( $extension, $include_extensions ) ) $result_list[] = $filename;
}
}
}
closedir($folder_handle);
return $result_list;
}
}