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 -> $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 ?>