Welcome Guest, Not a member yet? Register   Sign In
Missing files when using Zip Encoding Library
#1

[eluser]captainredmuff[/eluser]
Hi guys,

I've had a good read/search through the CI forums and have found a few mentions of errors when using the Zip Encoding Library (CI 1.7.0) but no direct fixes to resolve the problem.

The issue i'm having is that the resulting zip file created by the library is empty when using the following code snippet:

Code:
//set the path to the backup folder (example file path)
$backup_path = "path/to/files/";

//load the zip library
$this->load->library('zip');

//read contents of backup folder and archive into a zip file
$this->zip->read_dir($backup_path);

//send contents of zip to be downloaded
$this->zip->download("backup.zip");

I have checked the file path is valid and can quite easily work with the directory and the contents externally from the Zip library but after compiling, downloading and opening the zip file, i get an error saying that the contents of the file have been blocked (Windows XP) and no errors at all on Mac OS X.

The closest i have come to a fix for this is a post i found which also outlines the same problem:

Possible Bug in Zip Class

The author supplies a temporary fix which indeed does work, but neglects to maintain the directory structure of the zip meaning that all the files are simply placed into the root directory which, whilst it does work, is not what i require.

I have spent a few hours this morning attempting to create a workaround as suggested by the author of the aforementioned post but have been unable to make any progress. Has anyone else encountered this problem and applied a successful fix? It looks like i may have to spend the afternoon extending and overloading the CI_Zip Library in hope that i can resolve this issue.

Additionally, for further clarification, this problem also exists when using:

Code:
//archive contents of the backup folder and save as a .zip on the server
$this->zip->archive($backup_path . "backup.zip");

The resulting .zip file is always empty, unless employing the aforementioned "fix" ofc.

Thanks for reading, any help would be greatly appreciated Smile

Edit: fixed a type in the code snippet
#2

[eluser]captainredmuff[/eluser]
This bug has now been reported via the Bug Tracker.

Meanwhile, if anyone can provide a fix or point out any obvious errors that could be rectified i would be most appreciative Smile
#3

[eluser]captainredmuff[/eluser]
The following code snippet taken from Possible Bug in Zip Library (posted almost a year ago) seems to be a temporary fix to this issue.

Code:
//overload the read_dir function to fix issues with blank zip files
    function read_dir($path, $preserve_filepath = FALSE)
    {
        if ($fp = @opendir($path))
        {
            while (FALSE !== ($file = readdir($fp)))
            {
                if (@is_dir($path.$file) && substr($file, 0, 1) != '.')
                {
                    $this->read_dir($path.$file."/");
                }
                elseif (substr($file, 0, 1) != ".")
                {
                    $this->read_file(str_replace("\\", "/", $path).$file, $preserve_filepath);
                }
            }
            return TRUE;
        }
        return FALSE;
    }

As mentioned previously, this snippet does indeed zip the requested files but neglects to maintain the appropriate directory structure.

To circumvent this, the $preserve_filepath flag should be set to true, however, this simply reverts back to missing files in the resulting zip file rendering this fix useless.

Following the flow of the function brings us to the following method in the Zip Library.

Code:
function read_file($path, $preserve_filepath = FALSE)
    {
        if ( ! file_exists($path))
        {
            return FALSE;
        }

        if (FALSE !== ($data = file_get_contents($path)))
        {
            $name = str_replace("\\", "/", $path);
            
            if ($preserve_filepath === FALSE)
            {
                $name = preg_replace("|.*/(.+)|", "\\1", $name);
            }

            $this->add_data($name, $data);
            return TRUE;
        }
        return FALSE;
    }

As can be seen from the $preserve_filepath flag, the $name (path to the current file) variable is being cleansed via some regex trickery (which i'm assuming trims the file name from the file path). As the $preserve_filepath flag seems to be the only stumbling block i have managed to narrow this bug down to so far, i'm not entirely sure where to begin looking next?

One thing i have noticed from browsing the source of the Zip Library is that no implicit calls are made to $this->add_dir();. I don't know if this is an issue, but it seems to me that subdirectories would fail to be created when recursing using read_dir() which may be the cause of the problem. Once again, i'm unsure if this is an issue or not.
#4

[eluser]captainredmuff[/eluser]
Ok, so i spent a few hours yesterday sifting through the Zip Encoding Library to see if i can find a fix for this issue. I haven't been able to fix this issue so any help would be greatly appreciated as this is holding up development of one of our current projects.

Whilst i admit i don't entirely understand the two methods, _add_dir() and _add_data(), i have noticed that the method _add_data() uses gzcompress() to "compress" the data being passed to it a la;

Code:
//line #160
$gzdata = gzcompress($data);

Upon reading the documentation for this function, php.net - gzcompress(), it appears that no compression is being applied due to the missing (optional) second parameter which should be specified as an integer between 0 - 9 to define the level of compression desired. Seeing that this parameter is missing and along with the documentation for the function, i can only assume that no compression is being applied.




Theme © iAndrew 2016 - Forum software by © MyBB