Welcome Guest, Not a member yet? Register   Sign In
ZIP a specific directory.
#11

[eluser]TheFuzzy0ne[/eluser]
No, like this:
Code:
$path = getcwd() . '/files/mydirectory/';

Using base_url(), you are trying to pass a URL to read_dir(), and as it doesn't understand URLs, it tries to load a file by that name, and of course, can't find one.
#12

[eluser]leighmarble[/eluser]
[quote author="TheFuzzy0ne" date="1236148352"]No, like this:
Code:
$path = getcwd() . '/files/mydirectory/';

Using base_url(), you are trying to pass a URL to read_dir(), and as it doesn't understand URLs, it tries to load a file by that name, and of course, can't find one.[/quote]

Makes sense - I made this change. Unfortunately, while the download works now using that path, the Zip now contains that many more extra parent directories.

So, whereas before I was getting one extra parent directory in my Zip:

/files/mydirectory

Now I'm getting three:

/home/username/webroot/files/mydirectory
#13

[eluser]leighmarble[/eluser]
Here's the full read_dir function, from system/libraries/Zip.php

Code:
function read_dir($path)
    {    
        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) != ".")
                {
                    if (FALSE !== ($data = file_get_contents($path.$file)))
                    {                        
                        $this->add_data(str_replace("\\", "/", $path).$file, $data);
                    }
                }
            }
            return TRUE;
        }
    }

This code seems to be lacking anything to prevent it from moving into parent directories, no? Shouldn't it have something like
Code:
&& substr($file, 0, 2) != '..'
added to the second "if" condition (and maybe to the "elseif" as well)?
#14

[eluser]TheFuzzy0ne[/eluser]
You right! That's really strange! If you add that, I think you might be on to a winner. That's got to be a bug!
#15

[eluser]leighmarble[/eluser]
Well, I tried that out, but it is still grabbing the parent directories. Bummer!

I think I had tried that idea last week too, which is why I then tried my hand at the (PHP 5-only) RecursiveIteratorIterator approach I posted above. Using that approach, you can track the directory depth with the getDepth method. Unfortunately, this resulted in Zip files that expanded to ".zip.cpgz" files. Why, I don't know, but that's clearly no good either.

FYI, this is what I changed read_dir to:

Code:
function read_dir($path)
    {    
        if ($fp = @opendir($path))
        {
            while (FALSE !== ($file = readdir($fp)))
            {
                if (@is_dir($path.$file) && substr($file, 0, 1) != '.' && substr($file, 0, 2) != '..')
                {                    
                    $this->read_dir($path.$file."/");
                }
                elseif (substr($file, 0, 1) != "." && substr($file, 0, 2) != '..')
                {
                    if (FALSE !== ($data = file_get_contents($path.$file)))
                    {                        
                        $this->add_data(str_replace("\\", "/", $path).$file, $data);
                    }
                }
            }
            return TRUE;
        }
    }
I'm not much of a code ninja... would love it if a real pro here would work over this code for a few minutes!

thanks,
Leigh
#16

[eluser]TheFuzzy0ne[/eluser]
I have one final suggestion for now. That is to CD into the directory you want to zip.
Code:
chdir('files/mydirectory/');
$this->zip->read_dir('.');
$this->zip->download('mydirectory.zip');
#17

[eluser]leighmarble[/eluser]
[quote author="TheFuzzy0ne" date="1236153265"]I have one final suggestion for now. That is to CD into the directory you want to zip.
Code:
chdir('files/mydirectory/');
$this->zip->read_dir('.');
$this->zip->download('mydirectory.zip');
[/quote]

OK, now we're on to something!

The above code produced a PHP error for every file and subdirectory in "mydirectory", saying:
Message: file_get_contents(.index.html) [function.file-get-contents]: failed to open stream: No such file or directory
and
Message: file_get_contents(.images) [function.file-get-contents]: failed to open stream: No such file or directory

Note the prefixing of the "." before each file and directory name. Somewhere along the line, the period is being treated as a literal character, rather than as the web server's special designation for "this directory". (Perhaps that's the root of the problem with the Zip class as well?)

In any case, here's the code that finally worked:

Code:
chdir(getcwd() .'/files/');
$this->zip->read_dir('mydirectory/');

In other words, switch the current working directory to the parent directory of the dir you want to zip. Then, feed read_dir just the name of your target dir (with the trailing slash). Boom, it works.

Cheers, and thanks for helping with the brainstorm,
Leigh
#18

[eluser]TheFuzzy0ne[/eluser]
Nicely done!



Also, I'd imagine this would have worked better than my original code:
Code:
chdir('files/mydirectory/');
$this->zip->read_dir('./');
$this->zip->download('mydirectory.zip');
Note: the trailing slash in the call to $this->zip->read_dir(). Not sure why I didn't add it in the first place...

But yes, both our scripts are essentially doing the same thing.

Would you mind posting your patch for any other poor souls who experience this same problem in the future? I'd hate for anyone else to have to go through this. Hehe.

Thanks. Smile
#19

[eluser]leighmarble[/eluser]
[quote author="TheFuzzy0ne" date="1236214833"]Would you mind posting your patch for any other poor souls who experience this same problem in the future? I'd hate for anyone else to have to go through this. Hehe.[/quote]

I'm always happy to share, in a community such as this.

In this case, the code I posted above is the whole of the solution:

Code:
chdir(getcwd() .'/files/');
$this->zip->read_dir('mydirectory/');

I returned the Zip encoding class ( /system/libraries/Zip.php ) to its stock form, and the above code still works.

cheers,
Leigh
#20

[eluser]TheFuzzy0ne[/eluser]
Oh I see. So we don't need the extra bit that checks that the directory isn't ".."? Sweet. I'll post that as a patch shortly.

Thanks, Leigh!




Theme © iAndrew 2016 - Forum software by © MyBB