Welcome Guest, Not a member yet? Register   Sign In
bug / feature? $this->ftp->delete_dir() won't delete non-empty directory
#1

[eluser]HdotNET[/eluser]
Hi there,

Just encountered this:

Code:
$config['hostname'] = 'democrat.ftp.server';
    $config['username'] = 'hillary';
    $config['password'] = 'obama';
    $config['debug'] = TRUE;
    $this->ftp->connect($config);
    $this->ftp->delete_dir('/path/to/non/empty/remote/dir/');
    $this->ftp->close();

This fails for me, yet in the guide it states:

Quote:
Code:
$this->ftp->delete_dir()
Lets you delete a directory and everything it contains. Supply the source path to the directory with a trailing slash.

FTP class in user guide

If someone could test this out I'd be very grateful. Am using CI 1.6.1
#2

[eluser]HdotNET[/eluser]
k... I think I've fixed it.
Code:
function delete_dir($filepath)
    {
        if ( ! $this->_is_conn())
        {
            return FALSE;
        }

        // Add a trailing slash to the file path if needed
        $filepath = preg_replace("/(.+?)\/*$/", "\\1/",  $filepath);
        
        $list = $this->list_files($filepath);
        
        if ($list !== FALSE AND count($list) > 0)
        {
            foreach ($list as $item)
            {            
                // If we can't delete the item it's probaly a folder so
                // we'll recursively call delete_dir()
                if ( ! @ftp_delete($this->conn_id, $item))
                {
                    $this->delete_dir($item);
                }
            }
        }
    
        
        $result = @ftp_rmdir($this->conn_id, $filepath);
        
        if ($result === FALSE)
        {
            if ($this->debug == TRUE)
            {                
                $this->_error('ftp_unable_to_delete');
            }        
            return FALSE;        
        }
        
        return TRUE;
    }
#3

[eluser]HdotNET[/eluser]
doh... forgot to say what I fixed! This bit:

Code:
// If we can't delete the item it's probaly a folder so
                // we'll recursively call delete_dir()
                if ( ! @ftp_delete($this->conn_id, $item))
                {
                    $this->delete_dir($item);
                }

The code was like this:

Code:
// If we can't delete the item it's probaly a folder so
                // we'll recursively call delete_dir()
                if ( ! @ftp_delete($this->conn_id, $filepath.$item))
                {
                    $this->delete_dir($filepath.$item);
                }

which meant if you passed the function /path/to/dir/ it would try and delete /path/to/dir/path/to/dir/file
#4

[eluser]Seppo[/eluser]
Hey, I've filled a bug report for this one. Please check if it's OK. http://codeigniter.com/bug_tracker/bug/4215/
#5

[eluser]mdriscol[/eluser]
thanks for this! I was having the same problem. This is an easy fix so hopefully it will be in the next update.
#6

[eluser]Elliot Haughin[/eluser]
Good catch HdotNet. Looks like a valid bug to me! I'll give it a try tonight.
#7

[eluser]Unknown[/eluser]
[quote author="HdotNET" date="1204732573"]doh... forgot to say what I fixed! This bit:

Code:
// If we can't delete the item it's probaly a folder so
                // we'll recursively call delete_dir()
                if ( ! @ftp_delete($this->conn_id, $item))
                {
                    $this->delete_dir($item);
                }

The code was like this:

Code:
// If we can't delete the item it's probaly a folder so
                // we'll recursively call delete_dir()
                if ( ! @ftp_delete($this->conn_id, $filepath.$item))
                {
                    $this->delete_dir($filepath.$item);
                }

which meant if you passed the function /path/to/dir/ it would try and delete /path/to/dir/path/to/dir/file[/quote]

If you do it like so your will get paths like:

public_html/dir_name/./
public_html/dir_name/././
public_html/dir_name/./././

So this is endless recursion and you need do some checks

Code:
if ($list !== FALSE AND count($list) > 0) {
foreach ($list as $item) {
  // If it's not . and ..
  if ($item != '.' && $item != '..' && $item != '../' && $item != '../') {
   // If we can't delete the item it's probaly a folder so
   // we'll recursively call delete_dir()
   if (!ftp_delete($this->conn_id, $filepath . $item)) {
    $this->delete_dir($filepath . $item);
   }
  }
}
}




Theme © iAndrew 2016 - Forum software by © MyBB