openrat-cms

OpenRat Content Management System
git clone http://git.code.weiherhei.de/openrat-cms.git
Log | Files | Refs

Ftp.class.php (5428B)


      1 <?php
      2 // OpenRat Content Management System
      3 // Copyright (C) 2002-2012 Jan Dankert, cms@jandankert.de
      4 //
      5 // This program is free software; you can redistribute it and/or
      6 // modify it under the terms of the GNU General Public License
      7 // as published by the Free Software Foundation; either version 2
      8 // of the License, or (at your option) any later version.
      9 //
     10 // This program is distributed in the hope that it will be useful,
     11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 // GNU General Public License for more details.
     14 //
     15 // You should have received a copy of the GNU General Public License
     16 // along with this program; if not, write to the Free Software
     17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     18 namespace cms\publish;
     19 
     20 use logger\Logger;
     21 use util\exception\PublisherException;
     22 use util\exception\UIException;
     23 
     24 
     25 /**
     26  * Darstellen einer FTP-Verbindung, das beinhaltet
     27  * das Login, das Kopieren von Dateien sowie praktische
     28  * FTP-Funktionen
     29  *
     30  * @author $Author$
     31  * @version $Revision$
     32  * @package openrat.services
     33  */
     34 class Ftp
     35 {
     36 	var $verb;
     37 	var $url;
     38 	var $log = array();
     39 
     40 	var $passive = false;
     41 
     42 	var $ok = true;
     43 
     44 	private $path;
     45 
     46 
     47 	// Konstruktor
     48 	public function __construct($url)
     49 	{
     50 		$this->connect($url);
     51 	}
     52 
     53 
     54 	// Aufbauen der Verbindung
     55 	private function connect($url)
     56 	{
     57 		$this->url = $url;
     58 
     59 		global $conf;
     60 
     61 		$conf_ftp = $conf['publish']['ftp'];
     62 		$ftp = parse_url($this->url);
     63 
     64 		// Die projektspezifischen Werte gewinnen bei �berschneidungen mit den Default-Werten
     65 		$ftp = array_merge($conf_ftp, $ftp);
     66 
     67 		// Nur FTP und FTPS (seit PHP 4.3) erlaubt
     68 		if (!in_array(@$ftp['scheme'], array('ftp', 'ftps'))) {
     69 			throw new PublisherException('Unknown scheme in FTP Url: ' . @$ftp['scheme'] .
     70 				'. Only FTP (and FTPS, if compiled in) are supported');
     71 		}
     72 
     73 		if (function_exists('ftp_ssl_connect') && $ftp['scheme'] == 'ftps')
     74 			$this->verb = @ftp_ssl_connect($ftp['host'], $ftp['port']);
     75 		else
     76 			$this->verb = @ftp_connect($ftp['host'], $ftp['port']);
     77 
     78 		if (!$this->verb) {
     79 			Logger::error('Cannot connect to ' . $ftp['host'] . ':' . $ftp['port']);
     80 			throw new PublisherException('Cannot connect to ' . $ftp['scheme'] . '-server: ' . $ftp['host'] . ':' . $ftp['port']);
     81 		}
     82 
     83 		$this->log[] = 'Connected to FTP server ' . $ftp['host'] . ':' . $ftp['port'];
     84 
     85 		if (empty($ftp['user'])) {
     86 			$ftp['user'] = 'anonymous';
     87 			$ftp['pass'] = 'openrat@openrat.de';
     88 		}
     89 
     90 		if (!ftp_login($this->verb, $ftp['user'], $ftp['pass']))
     91 			throw new PublisherException('Unable to login as user ' . $ftp['user']);
     92 
     93 		$this->log[] = 'Logged in as user ' . $ftp['user'];
     94 
     95 		$pasv = (!empty($ftp['fragment']) && $ftp['fragment'] == 'passive');
     96 
     97 		$this->log[] = 'entering passive mode ' . ($pasv ? 'on' : 'off');
     98 		if (!ftp_pasv($this->verb, true))
     99 			throw new PublisherException('Cannot switch to FTP PASV mode');
    100 
    101 		if (!empty($ftp['query'])) {
    102 			parse_str($ftp['query'], $ftp_var);
    103 
    104 			if (isset($ftp_var['site'])) {
    105 				$site_commands = explode(',', $ftp_var['site']);
    106 				foreach ($site_commands as $cmd) {
    107 					if (!@ftp_site($this->verb, $cmd))
    108 						throw new PublisherException('unable to do SITE command: ' . $cmd);
    109 				}
    110 			}
    111 		}
    112 
    113 		$this->path = rtrim($ftp['path'], '/');
    114 
    115 		$this->log[] = 'Changing directory to ' . $this->path;
    116 
    117 		if (!@ftp_chdir($this->verb, $this->path))
    118 			throw new PublisherException('unable CHDIR to directory: ' . $this->path);
    119 	}
    120 
    121 
    122 	/**
    123 	 * Kopieren einer Datei vom lokalen System auf den FTP-Server.
    124 	 *
    125 	 * @param String Quelle
    126 	 * @param String Ziel
    127 	 * @param int FTP-Mode (BINARY oder ASCII)
    128 	 */
    129 	public function put($source, $dest)
    130 	{
    131 		$dest = $this->path . '/' . $dest;
    132 
    133 		$this->log .= "Copying file: $source -&gt; $dest ...\n";
    134 
    135 		$mode = FTP_BINARY;
    136 		$p = strrpos(basename($dest), '.'); // Letzten Punkt suchen
    137 
    138 		if ($p !== false) // Wennn letzten Punkt gefunden, dann dort aufteilen
    139 		{
    140 			$extension = substr(basename($dest), $p + 1);
    141 			$type = config('mime-types', $extension);
    142 			if (substr($type, 0, 5) == 'text/')
    143 				$mode = FTP_ASCII;
    144 		}
    145 
    146 		Logger::debug("FTP PUT target:$dest mode:" . (($mode == FTP_ASCII) ? 'ascii' : 'binary'));
    147 
    148 		if (!@ftp_put($this->verb, $dest, $source, $mode)) {
    149 			if (!$this->mkdirs(dirname($dest)))
    150 				return; // Fehler.
    151 
    152 			ftp_chdir($this->verb, $this->path);
    153 
    154 			if (!@ftp_put($this->verb, $dest, $source, $mode))
    155 				throw new PublisherException("FTP PUT failed.\n" .
    156 					"source     : $source\n" .
    157 					"destination: $dest");
    158 
    159 		}
    160 	}
    161 
    162 
    163 	/**
    164 	 * Private Methode zum rekursiven Anlegen von Verzeichnissen.
    165 	 *
    166 	 * @param String Pfad
    167 	 * @return boolean true, wenn ok
    168 	 */
    169 	private function mkdirs($strPath)
    170 	{
    171 		if (@ftp_chdir($this->verb, $strPath))
    172 			return true; // Verzeichnis existiert schon :)
    173 
    174 		$pStrPath = dirname($strPath);
    175 
    176 		if (!$this->mkdirs($pStrPath))
    177 			return false;
    178 
    179 		if (!@ftp_mkdir($this->verb, $strPath))
    180 			throw new PublisherException("failed to create remote directory: $strPath");
    181 
    182 		return true;
    183 	}
    184 
    185 
    186 	/**
    187 	 * Schliessen der FTP-Verbindung.<br>
    188 	 * Sollte unbedingt aufgerufen werden, damit keine unn�tigen Sockets aufbleiben.
    189 	 */
    190 	public function close()
    191 	{
    192 		if (!@ftp_quit($this->verb)) {
    193 			// Closing not possible.
    194 			// Only logging. Maybe we could throw an Exception here?
    195 			Logger::warn('Failed to close FTP connection. Continueing...');
    196 			return;
    197 		}
    198 	}
    199 }
    200 
    201 
    202 ?>