[horde] FTP VFS functions

Jeff Graves jeff at image-src.com
Sun Feb 23 20:08:10 PST 2003


> Things don't seem quite right yet, but it might be the side-by-side patches
> that broke move/copy. Your code looks like a good start in any case, I've
> committed it. Thanks!

Chuck, I worked a little more on this code. I wasn't sure about the 
listFolders function though (whether it was supposed to return an entire 
directory structure or just folders in the current directory) so I went with 
what most (ftp) clients usually have - just the current directory contents. I 
tested these with the latest CVS head and the worked for me. Take a look at 
the changes, and let me know what you think. I had to make some changes to 
Gollem for the listFolders function.

Jeff Graves
Customer Support Engineer
Image Source, Inc.
10 Mill Street
Bellingham, MA 02019

508.966.5200 x31 - Phone
508.966.5170 - Fax
jeff at image-src.com - Email
-------------- next part --------------
CHANGES:

./lib/Gollem.php : 

**  function flistSelect($backend_key, $heading = '', $abbrev = true, $filter = array(), $dir = '')
    {
        require_once HORDE_BASE . '/lib/Text.php';

        $options = '';
        if (strlen($heading) > 0) {
            $options .= '<option value="none">' . $heading . "</option>\n";
        }
        $options .= '<option value="none">----</option>';
        $options .= '<option value="">' . _("[ Home ]") . "</option>\n";
        $options .= '<option value="none">----</option>';

**        $folders = $GLOBALS['vfs'][$backend_key]->listFolders($dir, $filter, $GLOBALS['prefs']->getValue('show_dotfiles'));

        if (is_a($folders, 'PEAR_Error')) {
            return $options;
        }
        foreach ($folders as $folder) {
            $val = htmlspecialchars($folder['val']);

            if ($abbrev) {
               $label = $folder['abbrev'];
            } else {
               $label = $folder['label'];
            }

            $options .= sprintf("<option value=\"%s\">%s</option>%s", $val, Text::htmlSpaces($label), "\n");
        }

        return $options;
    }

./manager.php :

@171:

$folder_options = Gollem::flistSelect($backend_key, _("Files to"), true, array(), Gollem::getDir($backend_key));

../horde/lib/VFS/ftp.php :

    /**
     * Returns a sorted folder list of the specified directory.
     *
     * @param string  $path     The path of the directory to get the directory list for.
     * @param mixed   $filter   (optional) hash of items to filter based on folderlist.
     * @param boolean $dotfiles (optional) Show dotfiles?     
     *
     * @return mixed  Folder list on success or a PEAR_Error object on failure.
     */
    function listFolders($path = '', $filter = null, $dotfiles = true)
    {
        $conn = $this->_connect();
        if (is_a($conn, 'PEAR_Error')) {
            return $conn;
        }

        $folders = array();
        $folder = array();	

        $folderList = $this->listFolder('/' . $path, null, $dotfiles, true);
	
	$folder['val'] = $this->_parentDir($path);
	$folder['abbrev'] = '..';
	$folder['label'] = '..';

	$folders[$folder['val']] = $folder;

        foreach ($folderList as $files) {
           $folder['val'] = $path . '/' . $files['name'];	
            $folder['abbrev'] = $files['name'];
            $folder['label'] = $folder['val'];

            $folders[$folder['val']] = $folder;
        }

        ksort($folders);
        return $folders;
    }

    /**
     * Returns the parent directory of specified path.
     *
     * @param string $path  The path whose parent to return.
     *
     * @return mixed Parent on success or PEAR_Error object on failure.
     */
    function _parentDir($path)
    {
	$conn = $this->_connect();
	if (is_a($conn, 'PEAR_Error')) {
	    return $conn;
	}

	@ftp_cdup($this->_stream);

	$parent = @ftp_pwd($this->_stream);
	
	if (!($parent)) {
	    return PEAR::raiseError(sprintf(_("Unable to determine current directory.")));
	}

	return $parent;
    }

    /**
     * Copies a file through the backend.
     *
     * @param string $path  The path to store the file in.
     * @param string $name  The filename to use.
     * @param string $dest  The destination of the file.
     *
     * @return mixed  True on success or a PEAR_Error object on failure.
     */
    function copy($path, $name, $dest)
    {
        $conn = $this->_connect();
        if (is_a($conn, 'PEAR_Error')) {
            return $conn;
        }
	
	$pos = strpos($path, '/');
	
	if (!($pos) || $pos > 0) {
	    $path = '/' . $path;
	}

	$pos = strpos($dest, '/');

	if (!($pos) || $pos > 0) {
	    $dest = '/' . $dest;
	}

        $fileCheck = $this->listFolder($dest, null, true);
        foreach ($fileCheck as $file) {
            if ($file['name'] == $name) {
		@ftp_chdir($this->_stream, $path);
                return PEAR::raiseError(_("%s already exists."), $this->_getPath($dest, $name));
            }
        }

	$dirCheck = $this->listFolder($path, null, false);
	$isDir = false;

	foreach ($dirCheck as $file) {
	    if ($file['name'] == $name && $file['type'] == '**dir') {
		$isDir = true;
		break;
	    }
	}

        @ftp_chdir($this->_stream, $path);

	if ($isDir) {

            $result = $this->createFolder($dest, $name);

            if (is_a($result, 'PEAR_Error')) {
                return $result;
            }

            $file_list = $this->listFolder($this->_getPath($path, $name));

            foreach ($file_list as $file) {
                $result = $this->copy($this->_getPath($path, $name), $file['name'], $this->_getPath($dest, $name));

                if (is_a($result, 'PEAR_Error')) {
                    return $result;
                }
            }

        } else {

            $tmpFile = Horde::getTempFile('vfs', false);
            $fetch = @ftp_get($this->_stream, $tmpFile, $this->_getPath($path, $name), FTP_BINARY);
            if (!($fetch)) {
                return PEAR::raiseError(sprintf(_("Failed to retrieve: %s"), $this->_getPath($path, $name)));
            }

            if (!@ftp_put($this->_stream, $this->_getPath($dest, $name), $tmpFile, FTP_BINARY)) {
                return PEAR::raiseError(sprintf(_("Copy failed: %s"), $this->_getPath($dest, $name)));
            }

            unlink($tmpFile);
	}

	@ftp_cdup($this->_stream);

        return true;
    }

    /**
     * Moves a file through the backend.
     *
     * @param string $path  The path to store the file in.
     * @param string $name  The filename to use.
     * @param string $dest  The destination of the file.
     *
     * @return mixed  True on success or a PEAR_Error object on failure.
     */
    function move($path, $name, $dest)
    {
        $conn = $this->_connect();
        if (is_a($conn, 'PEAR_Error')) {
            return $conn;
        }

        $fileCheck = $this->listFolder('/' . $dest, null, true);
        foreach ($fileCheck as $file) {
            if ($file['name'] == $name) {
                return PEAR::raiseError(_("%s already exists."), $this->_getPath('/' . $dest, $name));
            }
        }

        if (!@ftp_rename($this->_stream, $this->_getPath($path, $name), $this->_getPath($dest, $name))) {
            return PEAR::raiseError(_("Move file failed: %s"));
        }

        return true;
    }


More information about the horde mailing list