commit 4a3ae679a2e70a459eef8e5974d69e6ab211b97a
parent f2f11fd26d6902f7ab78b50fcb8a038df47d19e7
Author: dankert <devnull@localhost>
Date: Sat, 6 Oct 2007 01:31:32 +0200
Bei Fehlersituationen kein Abbruch, sondern nur Status OK auf false setzen.
Diffstat:
2 files changed, 266 insertions(+), 118 deletions(-)
diff --git a/serviceClasses/Ftp.class.php b/serviceClasses/Ftp.class.php
@@ -31,9 +31,11 @@ class Ftp
{
var $verb;
var $url;
- var $log = '';
+ var $log = array();
var $mode=FTP_ASCII;
- var $passive = false;
+ var $passive = false;
+
+ var $ok = true;
// Konstruktor
@@ -48,62 +50,59 @@ class Ftp
{
$this->url = $url;
- global $db,
- $SESS,
- $t_project;
-
+ global $conf;
+
+ $conf_ftp = $conf['publish']['ftp'];
$ftp = parse_url( $this->url );
- // Wenn kein Port vorgegeben, dann Port 21 verwenden
- if ( empty($ftp['port']) )
- $ftp['port'] = '21';
+ // Die projektspezifischen Werte gewinnen bei Überschneidungen mit den Default-Werten
+ $ftp = array_merge($conf_ftp,$ftp);
// Nur FTP und FTPS (seit PHP 4.3) erlaubt
- if ( !ereg('^ftps?$',$ftp['scheme']) )
- die( 'unknown scheme in FTP Url: '.$ftp['scheme'] );
+ if ( !ereg('^ftps?$',$ftp['scheme']) )
+ {
+ $this->log[] = 'Unknown scheme in FTP Url: '.$ftp['scheme'];
+ $this->log[] = 'Only FTP (and FTPS, if compiled in) are supported';
+ $this->ok = false;
+ return;
+ }
- $this->verb = ftp_connect( $ftp['host'],$ftp['port'] );
+ if ( function_exists('ftp_ssl_connect') && $ftp['scheme'] == 'ftps' )
+ $this->verb = ftp_ssl_connect( $ftp['host'],$ftp['port'] );
+ else
+ $this->verb = ftp_connect( $ftp['host'],$ftp['port'] );
if ( !$this->verb )
{
- error('ERROR_FTP','ERROR_FTP_CANNOT_CONNECT_TO_SERVER','Cannot connect to '.$ftp['host'].':'.$ftp['port']);
+ $this->log[] = 'Cannot connect to '.$ftp['scheme'].'-server '.$ftp['host'].':'.$ftp['port'];
+ $this->ok = false;
+
+ Logger::error('Cannot connect to '.$ftp['host'].':'.$ftp['port']);
+ return;
}
- $this->log .= 'connecting ...'."\n";
- $this->log .= 'host: '.$ftp['host']."\n";
- $this->log .= 'port: '.$ftp['port']."\n";
-
- $erg = ftp_login( $this->verb,$ftp['user'],$ftp['pass'] );
-
- if ( !$erg )
+ $this->log[] = 'Connected to FTP server '.$ftp['host'].':'.$ftp['port'];
+
+ if ( empty($ftp['user']) )
+ $ftp['user'] = 'anonymous';
+
+ if ( ! ftp_login( $this->verb,$ftp['user'],$ftp['pass'] ) )
{
- error('ERROR_FTP','ERROR_FTP_CANNOT_LOGIN','cannot login user: '.$ftp['user']);
+ $this->log[] = 'Unable to login as user '.$ftp['user'];
+ $this->ok = false;
+ return;
}
-
- $this->log .= 'ok'."\n";
- $this->log .= 'login ...'."\n";
- $this->log .= 'user: '.$ftp['user']."\n";
- $this->log .= 'ok'."\n";
-
- if ( !empty($ftp['fragment']) && $ftp['fragment'] == 'passive' )
- {
- $this->log .= 'entering passive mode'."\n";
- $erg = ftp_pasv( $this->verb,true );
+
+ $this->log[] = 'Logged in as user '.$ftp['user'];
- if ( !$erg )
- {
- error('ERROR_FTP','ERROR_FTP_CANNOT_PASV_ON');
- }
- }
- else
+ $pasv = (!empty($ftp['fragment']) && $ftp['fragment'] == 'passive' );
+
+ $this->log[] = 'entering passive mode '.($pasv?'on':'off');
+ if ( ! ftp_pasv($this->verb,true) )
{
- $this->log .= 'no passive mode'."\n";
- $erg = ftp_pasv( $this->verb,false );
-
- if ( !$erg )
- {
- error('ERROR_FTP','ERROR_FTP_CANNOT_PASV_OFF');
- }
+ $this->log[] = 'cannot switch PASV mode';
+ $this->ok = false;
+ return;
}
if ( !empty($ftp['query']) )
@@ -115,81 +114,114 @@ class Ftp
$site_commands = explode( ',',$ftp_var['site'] );
foreach( $site_commands as $cmd )
{
- $this->log .= 'exec SITE command: '.$cmd."\n";
- ftp_site( $this->verb,$cmd );
+ $this->log .= 'executing SITE command: '.$cmd;
+
+ if ( ! @ftp_site( $this->verb,$cmd ) )
+ {
+ $this->log[] = 'unable to do SITE command: '.$cmd;
+ $this->ok = false;
+ return;
+ }
}
}
}
$this->path = ereg_replace( '\/$','',$ftp['path']);
- $this->log .= 'Change directory to '.$this->path.'...'."\n";
- $erg = ftp_chdir( $this->verb,$this->path );
-
-
- if ( !$erg )
+ $this->log[] = 'Changing directory to '.$this->path;
+
+ if ( ! @ftp_chdir( $this->verb,$this->path ) )
{
- error('ERROR_FTP','ERROR_FTP_UNABLE_TO_CHDIR','could not CHDIR to '.$this->path );
- }
- $this->log .= 'ok'."\n";
-
-
- //echo "pwd ist".ftp_pwd( $this->verb );
+ $this->log[] = 'unable CHDIR to directory: '.$this->path;
+ $this->ok = false;
+ return;
+ }
}
-
+
+ /**
+ * Kopieren einer Datei vom lokalen System auf den FTP-Server.
+ *
+ * @param String Quelle
+ * @param String Ziel
+ * @param int FTP-Mode (BINARY oder ASCII)
+ */
function put( $source,$dest,$mode=FTP_BINARY )
- {
+ {
+ if ( ! $this->ok )
+ return;
+
$ftp = parse_url( $this->url );
$dest = $this->path.'/'.$dest;
$this->log .= "Copying file: $source -> $dest ...\n";
+
if ( !@ftp_put( $this->verb,$dest,$source,$this->mode ) )
{
- $this->log .= "Copying FAILED, checking path: ".dirname($dest)."\n";
-
- $erg = $this->mkdirs( dirname($dest) );
-
- if ( !$erg )
- {
- error('ERROR_FTP','ERROR_FTP_UNABLE_TO_MKDIR','cannot create directoriy '.$ftp['path'].'/'.dirname($dest) );
- }
+ if ( !$this->mkdirs( dirname($dest) ) )
+ return; // Fehler.
ftp_chdir( $this->verb,$this->path );
- $erg = ftp_put( $this->verb,$dest,$source,$mode );
-
- if ( !$erg )
+ if ( ! @ftp_put( $this->verb,$dest,$source,$mode ) )
{
- error('ERROR_FTP','ERROR_FTP_UNABLE_TO_COPY','put failed from '.$source.' to '.$dest );
+ $this->ok = false;
+ $this->log[] = 'FTP PUT failed...';
+ $this->log[] = 'source : '.$source;
+ $this->log[] = 'destination: '.$dest;
+ return;
}
}
}
-
-
- // Rekursives Anlagen von Verzeichnisse
+
+
+ /**
+ * Private Methode zum rekursiven Anlegen von Verzeichnissen.
+ *
+ * @param String Pfad
+ * @return boolean true, wenn ok
+ */
function mkdirs( $strPath )
{
- echo $strPath.'<br>';
if ( @ftp_chdir($this->verb,$strPath) )
- return true;
-
+ return true; // Verzeichnis existiert schon :)
+
$pStrPath = dirname($strPath);
+
if ( !$this->mkdirs($pStrPath) )
return false;
- $this->log .= "Creating directory: $strPath ...\n";
- //echo "lege an $strPath ...<br>";
- return ftp_mkdir($this->verb,$strPath);
+ if ( ! @ftp_mkdir($this->verb,$strPath) )
+ {
+ $this->ok = false;
+ $this->log[] = "failed to create remote directory: $strPath";
+ }
+
+ return $this->ok;
}
-
+
+
+ /**
+ * Schließen der FTP-Verbindung.<br>
+ * Sollte unbedingt aufgerufen werden, damit keine unnötigen Sockets aufbleiben.
+ */
function close()
{
- ftp_quit( $this->verb );
+ if ( !$this->ok ) // Noch alles ok?
+ return;
+
+ if ( ! @ftp_quit( $this->verb ) )
+ {
+ // Das Schließen der Verbindung hat nicht funktioniert.
+ // Eigentlich könnten wir das ignorieren, aber wir sind anständig und melden eine Fehler.
+ $this->log[] = 'failed to close connection';
+ $this->ok = false;
+ return;
+ }
}
}
diff --git a/serviceClasses/Publish.class.php b/serviceClasses/Publish.class.php
@@ -34,29 +34,52 @@ class Publish
var $content_negotiation = false;
var $cut_index = false;
var $cmd_after_publish = '';
- var $publishedObjects = array();
+ var $publishedObjects = array();
+ var $log = array();
+ var $ok = true;
// Konstruktor
function Publish()
- {
+ {
+ global $conf;
+ $conf_project = $conf['publish']['project'];
+
$project = Session::getProject();
- if ( !empty($project->ftp_url) )
+ if ( !empty($project->ftp_url) || isset($conf['publish']['ftp']['host']) )
{
+ $this->with_ftp = true;
$this->ftp = new Ftp( $project->ftp_url );
- $this->with_ftp = true;
-
+
+ if ( ! $this->ftp->ok )
+ {
+ $this->ok = false;
+ $this->log = $this->ftp->log;
+ return;
+ }
+
$this->ftp->passive = ( $project->ftp_passive == '1' );
}
- $this->local_destdir = ereg_replace( '\/$','',$project->target_dir);
+ $localDir = ereg_replace( '\/$','',$project->target_dir);
+ if ( empty( $localDir))
+ $localDir = $project->name;
+
+ if ( $conf_project['override_publish_dir'] && $localDir != basename($localDir) )
+ $this->local_destdir = $localDir;
+ else
+ $this->local_destdir = $conf_project['publish_dir'].$localDir;
+
// Sofort pruefen, ob das Zielverzeichnis ueberhaupt beschreibbar ist.
if ( $this->local_destdir != '' )
{
if ( !is_writeable( $this->local_destdir ) )
- {
- die( 'directory not writable: '.$this->local_destdir );
+ {
+ $this->ok = false;
+ $this->log[] = 'directory not writable: '.$this->local_destdir;
+ $this->log[] = 'please correct the file permissions.';
+ return;
}
$this->with_local = true;
@@ -65,47 +88,89 @@ class Publish
$this->content_negotiation = ( $project->content_negotiation == '1' );
$this->cut_index = ( $project->cut_index == '1' );
- $this->cmd_after_publish = $project->cmd_after_publish;
+ $this->cmd_after_publish = $project->cmd_after_publish;
+ // Variablen ersetzen
+ str_replace('{name}' ,$project->name ,$this->cmd_after_publish);
+ str_replace('{dir}' ,$this->local_destdir ,$this->cmd_after_publish);
+ str_replace('{dirbase}',basename($this->local_destdir),$this->cmd_after_publish);
}
-
+
+
+
+ /**
+ * Kopieren einer Datei aus dem temporären Verzeichnis in das Zielverzeichnis.<br>
+ * Falls notwenig, wird ein Hochladen per FTP ausgeführt.
+ *
+ * @param String $tmp_filename
+ * @param String $dest_filename
+ */
function copy( $tmp_filename,$dest_filename )
- {
+ {
+ if ( !$this->ok)
+ return;
+
global $conf;
$source = $tmp_filename;
if ( $this->with_local )
{
- $dest = $this->local_destdir.'/'.$dest_filename;
- //echo "$source > $dest<br>";
+ $dest = $this->local_destdir.'/'.$dest_filename;
+
if (!@copy( $source,$dest ));
{
- $this->mkdirs( dirname($dest) );
+ if ( ! $this->mkdirs( dirname($dest) ) )
+ return;
- if (!copy( $source,$dest ))
- {
- die('failed writing file: '.$dest);
+ if (!@copy( $source,$dest ))
+ {
+ $this->ok = false;
+ $this->log[] = 'failed copying local file:';
+ $this->log[] = 'source : '.$source;
+ $this->log[] = 'destination: '.$dest;
+ return;
}
}
-
+ // CHMOD auf der Datei ausgeführen.
if (!empty($conf['security']['chmod']))
- chmod($dest,octdec($conf['security']['chmod']));
+ {
+ if ( ! @chmod($dest,octdec($conf['security']['chmod'])) )
+ {
+ $this->ok = false;
+ $this->log[] = 'Unable to CHMOD file '.$dest;
+ return;
+ }
+ }
}
- if ( $this->with_ftp )
+ if ( $this->with_ftp ) // Falls FTP aktiviert
{
$dest = $dest_filename;
- $this->ftp->put( $source,$dest,FTP_ASCII );
+ $this->ftp->put( $source,$dest,FTP_ASCII );
+
+ if ( ! $this->ftp->ok )
+ {
+ $this->ok = false;
+ $this->log[] = $this->ftp->log;
+ }
}
}
+
-
- // Rekursives Anlagen von Verzeichnisse
- // Nett gemacht.
- // Quelle: http://de3.php.net/manual/de/function.mkdir.php
- // Thx to acroyear at io dot com
+
+ /**
+ * Rekursives Anlagen von Verzeichnisse
+ * Nett gemacht.
+ * Quelle: http://de3.php.net/manual/de/function.mkdir.php
+ * Thx to acroyear at io dot com
+ *
+ * @param String Verzeichnis
+ * @return boolean
+ */
function mkdirs( $strPath )
- {
+ {
+ global $conf;
+
if ( is_dir($strPath) )
return true;
@@ -113,31 +178,82 @@ class Publish
if ( !$this->mkdirs($pStrPath) )
return false;
- //echo "lege an: $strPath<br>";
- return @mkdir($strPath,0755);
+ if ( ! @mkdir($strPath,0777) )
+ {
+ $this->ok = false;
+ $this->log[] = 'Cannot create directory: '.$strPath;
+ return false;
+ }
+
+ // CHMOD auf dem Verzeichnis ausgeführen.
+ if (!empty($conf['security']['chmod_dir']))
+ {
+ if ( ! @chmod($strPath,octdec($conf['security']['chmod_dir'])) )
+ {
+ $this->ok = false;
+ $this->log[] = 'Unable to CHMOD directory: '.$strPath;
+ return false;
+ }
+ }
+
+
+ return $this->ok;
}
-
+
+ /**
+ * Beenden des Veröffentlichungs-Vorganges.<br>
+ * Eine vorhandene FTP-Verbindung wird geschlossen.<br>
+ * Falls entsprechend konfiguriert, wird ein Systemkommando ausgeführt.
+ */
function close()
{
if ( $this->with_ftp )
{
$this->ftp->close();
}
-
- if ( !empty($this->cmd_after_publish) )
- exec( $this->cmd_after_publish );
+
+ // Ausführen des Systemkommandos.
+ if ( !empty($this->cmd_after_publish) && $this->ok )
+ {
+ $ausgabe = array();
+ $rc = false;
+ exec( $this->cmd_after_publish,$ausgabe,$rc );
+
+ if ( $rc != 0 )
+ {
+ $this->log = $ausgabe;
+ $this->ok = false;
+ }
+ }
}
+
+ /**
+ * Aufräumen des Zielverzeichnisses.<br><br>
+ * Es wird der komplette Zielordner samt Unterverzeichnissen durchsucht. Jede
+ * Datei, die länger existiert als der aktuelle Request alt ist, wird gelöscht.<br>
+ * Natürlich darf diese Funktion nur nach einem Gesamt-Veröffentlichen ausgeführt werden.
+ */
function clean()
- {
+ {
+ if ( $this->ok )
+ return;
+
if ( !empty($this->local_destdir) )
$this->cleanFolder($this->local_destdir);
}
-
-
+
+
+
+ /**
+ * Aufräumen eines Verzeichnisses.<br><br>
+ * Dateien, die länger existieren als der aktuelle Request alt ist, werden gelöscht.<br>
+ *
+ * @param String Verzeichnis
+ */
function cleanFolder( $folderName )
{
$dh = opendir( $folderName );