Ftp.class.php (5809B)
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 19 20 /** 21 * Darstellen einer FTP-Verbindung, das beinhaltet 22 * das Login, das Kopieren von Dateien sowie praktische 23 * FTP-Funktionen 24 * 25 * @author $Author$ 26 * @version $Revision$ 27 * @package openrat.services 28 */ 29 class Ftp 30 { 31 var $verb; 32 var $url; 33 var $log = array(); 34 35 var $passive = false; 36 37 var $ok = true; 38 39 private $path; 40 41 42 // Konstruktor 43 public function __construct( $url ) 44 { 45 $this->connect( $url ); 46 } 47 48 49 // Aufbauen der Verbindung 50 private function connect( $url ) 51 { 52 $this->url = $url; 53 54 global $conf; 55 56 $conf_ftp = $conf['publish']['ftp']; 57 $ftp = parse_url( $this->url ); 58 59 // Die projektspezifischen Werte gewinnen bei �berschneidungen mit den Default-Werten 60 $ftp = array_merge($conf_ftp,$ftp); 61 62 // Nur FTP und FTPS (seit PHP 4.3) erlaubt 63 if ( !in_array(@$ftp['scheme'],array('ftp','ftps')) ) 64 { 65 throw new OpenRatException( 'ERROR_PUBLISH','Unknown scheme in FTP Url: '.@$ftp['scheme']. 66 '. Only FTP (and FTPS, if compiled in) are supported'); 67 } 68 69 if ( function_exists('ftp_ssl_connect') && $ftp['scheme'] == 'ftps' ) 70 $this->verb = @ftp_ssl_connect( $ftp['host'],$ftp['port'] ); 71 else 72 $this->verb = @ftp_connect( $ftp['host'],$ftp['port'] ); 73 74 if ( !$this->verb ) 75 { 76 Logger::error('Cannot connect to '.$ftp['host'].':'.$ftp['port']); 77 throw new OpenRatException('ERROR_PUBLISH','Cannot connect to '.$ftp['scheme'].'-server: '.$ftp['host'].':'.$ftp['port']); 78 } 79 80 $this->log[] = 'Connected to FTP server '.$ftp['host'].':'.$ftp['port']; 81 82 if ( empty($ftp['user']) ) 83 { 84 $ftp['user'] = 'anonymous'; 85 $ftp['pass'] = 'openrat@openrat.de'; 86 } 87 88 if ( ! ftp_login( $this->verb,$ftp['user'],$ftp['pass'] ) ) 89 throw new OpenRatException('ERROR_PUBLISH','Unable to login as user '.$ftp['user']); 90 91 $this->log[] = 'Logged in as user '.$ftp['user']; 92 93 $pasv = (!empty($ftp['fragment']) && $ftp['fragment'] == 'passive' ); 94 95 $this->log[] = 'entering passive mode '.($pasv?'on':'off'); 96 if ( ! ftp_pasv($this->verb,true) ) 97 throw new OpenRatException('ERROR_PUBLISH','Cannot switch to FTP PASV mode'); 98 99 if ( !empty($ftp['query']) ) 100 { 101 parse_str( $ftp['query'],$ftp_var ); 102 103 if ( isset( $ftp_var['site'] ) ) 104 { 105 $site_commands = explode( ',',$ftp_var['site'] ); 106 foreach( $site_commands as $cmd ) 107 { 108 if ( ! @ftp_site( $this->verb,$cmd ) ) 109 throw new OpenRatException('ERROR_PUBLISH','unable to do SITE command: '.$cmd); 110 } 111 } 112 } 113 114 $this->path = rtrim( $ftp['path'],'/' ); 115 116 $this->log[] = 'Changing directory to '.$this->path; 117 118 if ( ! @ftp_chdir( $this->verb,$this->path ) ) 119 throw new OpenRatException('ERROR_PUBLISH','unable CHDIR to directory: '.$this->path); 120 } 121 122 123 /** 124 * Kopieren einer Datei vom lokalen System auf den FTP-Server. 125 * 126 * @param String Quelle 127 * @param String Ziel 128 * @param int FTP-Mode (BINARY oder ASCII) 129 */ 130 public function put( $source,$dest ) 131 { 132 $dest = $this->path.'/'.$dest; 133 134 $this->log .= "Copying file: $source -> $dest ...\n"; 135 136 $mode = FTP_BINARY; 137 $p = strrpos( basename($dest),'.' ); // Letzten Punkt suchen 138 139 if ($p!==false) // Wennn letzten Punkt gefunden, dann dort aufteilen 140 { 141 $extension = substr( basename($dest),$p+1 ); 142 $type = config('mime-types',$extension); 143 if ( substr($type,0,5) == 'text/') 144 $mode = FTP_ASCII; 145 } 146 147 Logger::debug("FTP PUT target:$dest mode:".(($mode==FTP_ASCII)?'ascii':'binary')); 148 149 if ( !@ftp_put( $this->verb,$dest,$source,$mode ) ) 150 { 151 if ( !$this->mkdirs( dirname($dest) ) ) 152 return; // Fehler. 153 154 ftp_chdir( $this->verb,$this->path ); 155 156 if ( ! @ftp_put( $this->verb,$dest,$source,$mode ) ) 157 throw new OpenRatException('ERROR_PUBLISH', 158 "FTP PUT failed.\n". 159 "source : $source\n". 160 "destination: $dest"); 161 162 } 163 } 164 165 166 167 /** 168 * Private Methode zum rekursiven Anlegen von Verzeichnissen. 169 * 170 * @param String Pfad 171 * @return boolean true, wenn ok 172 */ 173 private function mkdirs( $strPath ) 174 { 175 if ( @ftp_chdir($this->verb,$strPath) ) 176 return true; // Verzeichnis existiert schon :) 177 178 $pStrPath = dirname($strPath); 179 180 if ( !$this->mkdirs($pStrPath) ) 181 return false; 182 183 if ( ! @ftp_mkdir($this->verb,$strPath) ) 184 throw new OpenRatException('ERROR_PUBLISH',"failed to create remote directory: $strPath"); 185 186 return true; 187 } 188 189 190 191 /** 192 * Schliessen der FTP-Verbindung.<br> 193 * Sollte unbedingt aufgerufen werden, damit keine unn�tigen Sockets aufbleiben. 194 */ 195 public function close() 196 { 197 if ( ! @ftp_quit( $this->verb ) ) 198 { 199 // Closing not possible. 200 // Only logging. Maybe we could throw an Exception here? 201 Logger::warn('Failed to close FTP connection. Continueing...'); 202 return; 203 } 204 } 205 } 206 207 208 ?>