can_delete = true; $this->can_download_to_browser = true; $this->can_download_to_file = true; } public function processPart($absolute_filename, $upload_as = null) { // Retrieve engine configuration data $config = Factory::getConfiguration(); $host = $config->get('engine.postproc.ftp.host', ''); $port = $config->get('engine.postproc.ftp.port', 21); $user = $config->get('engine.postproc.ftp.user', ''); $pass = $config->get('engine.postproc.ftp.pass', 0); $directory = $config->get('volatile.postproc.directory', null); if (empty($directory)) { $directory = $config->get('engine.postproc.ftp.initial_directory', ''); } $subdir = trim($config->get('engine.postproc.ftp.subdirectory', ''), '/'); $ssl = $config->get('engine.postproc.ftp.ftps', 0) == 0 ? false : true; $passive = $config->get('engine.postproc.ftp.passive_mode', 0) == 0 ? false : true; // You can't fix stupid, but at least you get to shout at them if (strtolower(substr($host, 0, 6)) == 'ftp://') { Factory::getLog()->log(LogLevel::WARNING, 'YOU ARE *** N O T *** SUPPOSED TO ENTER THE ftp:// PROTOCOL PREFIX IN THE FTP HOSTNAME FIELD OF THE Upload to Remote FTP POST-PROCESSING ENGINE.'); Factory::getLog()->log(LogLevel::WARNING, 'I am trying to fix your bad configuration setting, but the backup might fail anyway. You MUST fix this in your configuration.'); $host = substr($host, 6); } // Process the initial directory $directory = '/' . ltrim(trim($directory), '/'); // Parse tags $directory = Factory::getFilesystemTools()->replace_archive_name_variables($directory); $config->set('volatile.postproc.directory', $directory); // Connect to the FTP server Factory::getLog()->log(LogLevel::DEBUG, __CLASS__ . ':: Connecting to remote FTP'); if ($ssl) { if (function_exists('ftp_ssl_connect')) { $ftphandle = @ftp_ssl_connect($host, $port); } else { $ftphandle = false; } } else { $ftphandle = @ftp_connect($host, $port); } if ($ftphandle === false) { $this->setWarning("Wrong FTP hostname or port (host:port = $host:$port)"); return false; } // Login Factory::getLog()->log(LogLevel::DEBUG, __CLASS__ . ":: Logging in"); if (!@ftp_login($ftphandle, $user, $pass)) { $this->setWarning('Invalid username/password for the remote FTP server'); ftp_close($ftphandle); return false; } // Change to initial directory Factory::getLog()->log(LogLevel::DEBUG, __CLASS__ . ":: Changing to initial directory"); if (!@ftp_chdir($ftphandle, $directory)) { $this->setWarning("Invalid initial directory $directory for the remote FTP server"); return false; } // If supplied, change to the subdirectory if($subdir) { $subdir = Factory::getFilesystemTools()->replace_archive_name_variables($subdir); if(!@ftp_chdir($ftphandle, $directory.$subdir)) { // Got an error? This means that the directory doesn't exist, let's try to create it if(!@ftp_mkdir($ftphandle, $directory.$subdir)) { // Ok, I really can't do anything, let's stop here $this->setWarning("Could not create the subdirectory $subdir in the remote FTP server"); return false; } else { // Let's move into the new directory if(!@ftp_chdir($ftphandle, $directory.$subdir)) { // This should never happen, anyway better be safe than sorry $this->setWarning("Could not move into the subdirectory $subdir in the remote FTP server"); return false; } } } } $isPassiveTag = $passive ? 'Passive' : 'Active'; Factory::getLog()->log(LogLevel::DEBUG, __CLASS__ . ":: Enabling $isPassiveTag mode"); @ftp_pasv($ftphandle, $passive); Factory::getLog()->log(LogLevel::DEBUG, __CLASS__ . ":: Starting FTP upload of $absolute_filename"); $realdir = substr($directory, -1) == '/' ? substr($directory, 0, strlen($directory) - 1) : $directory; if($subdir) { $realdir .= '/'.$subdir; } $basename = empty($upload_as) ? basename($absolute_filename) : $upload_as; $realname = $realdir . '/' . $basename; try { $res = @ftp_put($ftphandle, $realname, $absolute_filename, FTP_BINARY); } catch (\Exception $e) { // Funny how PHP dies without returning false if you don't use a try/catch statement, eh? $res = false; $this->setWarning($e->getMessage()); } // Store the absolute remote path in the class property $this->remote_path = $realname; @ftp_close($ftphandle); if (!$res) { // If the file was unreadable, just skip it... if (is_readable($absolute_filename)) { $this->setWarning('Uploading ' . $absolute_filename . ' has failed.'); return false; } else { $this->setWarning('Uploading ' . $absolute_filename . ' has failed because the file is unreadable.'); return true; } } else { return true; } } public function delete($path) { // Retrieve engine configuration data $config = Factory::getConfiguration(); $host = $config->get('engine.postproc.ftp.host', ''); $port = $config->get('engine.postproc.ftp.port', 21); $user = $config->get('engine.postproc.ftp.user', ''); $pass = $config->get('engine.postproc.ftp.pass', 0); $ssl = $config->get('engine.postproc.ftp.ftps', 0) == 0 ? false : true; $passive = $config->get('engine.postproc.ftp.passive_mode', 0) == 0 ? false : true; $directory = dirname($path); // Connect to the FTP server Factory::getLog()->log(LogLevel::DEBUG, __CLASS__ . '::delete() -- Connecting to remote FTP'); if ($ssl) { if (function_exists('ftp_ssl_connect')) { $ftphandle = @ftp_ssl_connect($host, $port); } else { $ftphandle = false; } } else { $ftphandle = @ftp_connect($host, $port); } if ($ftphandle === false) { $this->setWarning("Wrong FTP hostname or port (host:port = $host:$port)"); return false; } // Login if (!@ftp_login($ftphandle, $user, $pass)) { $this->setWarning('Invalid username/password for the remote FTP server'); ftp_close($ftphandle); return false; } @ftp_pasv($ftphandle, $passive); try { $res = @ftp_delete($ftphandle, $path); } catch (\Exception $e) { // Funny how PHP dies without returning false if you don't use a try/catch statement, eh? $res = false; $this->setWarning($e->getMessage()); } @ftp_close($ftphandle); if (!$res) { $this->setWarning('Deleting ' . $path . ' has failed.'); return false; } else { return true; } } public function downloadToFile($remotePath, $localFile, $fromOffset = null, $length = null) { // Retrieve engine configuration data $config = Factory::getConfiguration(); $host = $config->get('engine.postproc.ftp.host', ''); $port = $config->get('engine.postproc.ftp.port', 21); $user = $config->get('engine.postproc.ftp.user', ''); $pass = $config->get('engine.postproc.ftp.pass', 0); $ssl = $config->get('engine.postproc.ftp.ftps', 0) == 0 ? false : true; $passive = $config->get('engine.postproc.ftp.passive_mode', 0) == 0 ? false : true; $directory = dirname($remotePath); // Connect to the FTP server Factory::getLog()->log(LogLevel::DEBUG, __CLASS__ . '::delete() -- Connecting to remote FTP'); if ($ssl) { if (function_exists('ftp_ssl_connect')) { $ftphandle = @ftp_ssl_connect($host, $port); } else { $ftphandle = false; } } else { $ftphandle = @ftp_connect($host, $port); } if ($ftphandle === false) { $this->setWarning("Wrong FTP hostname or port (host:port = $host:$port)"); return false; } // Login if (!@ftp_login($ftphandle, $user, $pass)) { $this->setWarning('Invalid username/password for the remote FTP server'); ftp_close($ftphandle); return false; } @ftp_pasv($ftphandle, $passive); try { $result = ftp_get($ftphandle, $localFile, $remotePath, FTP_BINARY); } catch (\Exception $e) { $this->setWarning($e->getMessage()); return false; } ftp_close($ftphandle); return $result; } /** * Returns an FTP/FTPS URL for directly downloading the requested file (lame and functional) */ public function downloadToBrowser($remotePath) { // Retrieve engine configuration data $config = Factory::getConfiguration(); $host = $config->get('engine.postproc.ftp.host', ''); $port = $config->get('engine.postproc.ftp.port', 21); $user = $config->get('engine.postproc.ftp.user', ''); $pass = $config->get('engine.postproc.ftp.pass', 0); $ssl = $config->get('engine.postproc.ftp.ftps', 0) == 0 ? false : true; $uri = $ssl ? 'ftps://' : 'ftp://'; if ($user && $pass) { $uri .= urlencode($user) . ':' . urlencode($pass) . '@'; } $uri .= $host; if ($port && ($port != 21)) { $uri .= ':' . $port; } if (substr($remotePath, 0, 1) != '/') { $uri .= '/'; } $uri .= $remotePath; return $uri; } }