/** * Get the global FTP connection. * * This is used for local assets and public files by some sites. * * Returns the FTP resource or false on failure. * * @return FTPConnection | false */ function ftp(){ static $ftp = null; if($ftp === null){ if(!defined('FTP_USERNAME')){ // Prevent the installer from freaking out. $ftp = false; return false; } if(!defined('FTP_PASSWORD')){ // Prevent the installer from freaking out. $ftp = false; return false; } if(!defined('FTP_PATH')){ // Prevent the installer from freaking out. $ftp = false; return false; } if(!FTP_USERNAME){ // If there is no username for the FTP server, don't try to connect either. $ftp = false; return false; } $ftp = new FTPConnection(); $ftp->host = '127.0.0.1'; $ftp->username = FTP_USERNAME; $ftp->password = FTP_PASSWORD; $ftp->root = FTP_PATH; $ftp->url = ROOT_WDIR; try{ $ftp->connect(); } catch(\Exception $e){ \Core\ErrorManagement\exception_handler($e); $ftp = false; return false; } } if($ftp && $ftp instanceof FTPConnection){ try{ $ftp->reset(); } catch(\Exception $e){ \Core\ErrorManagement\exception_handler($e); $ftp = false; return false; } } return $ftp; }
/** * Save this meta file back up to the FTP server. * * @throws \Exception */ public function saveMetas(){ if($this->_contents === null){ // Contents never loaded, nothing to save. return; } if(!$this->_changed){ // File wasn't changed, nothing to save. return; } $remotefile = $this->_dir . '.ftpmetas'; // Make sure the local directory exists and is writable first! // This will effectively touch the file to ensure it's writable and everything. $this->_local->putContents(''); $fh = fopen($this->_local->getFilename(), 'w'); if(!$fh){ throw new \Exception('Unable to open ' . $this->_local->getFilename() . ' for writing.'); } // Write the current header. fputcsv($fh, ['filename', 'hash', 'modified', 'size']); // And each line. foreach($this->_contents as $c){ fputcsv($fh, array_values($c)); } fclose($fh); // And publish to the FTP server. ftp_put($this->_ftp->getConn(), $remotefile, $this->_local->getFilename(), FTP_BINARY); $this->_changed = false; }
/** * Get the temporary local version of the file. * This is useful for doing operations such as hash and identicalto. * * @return FileLocal */ private function _getTmpLocal() { if ($this->_tmplocal === null) { // If this FTP object is simply a proxy for the local file store, I can cheat and not actually request the files over FTP. // This makes it quicker. if($this->_ftp->isLocal){ $this->_tmplocal = new FileLocal(ROOT_PDIR . $this->_filename); } else{ $filename = $this->getFilename(); $fhash = md5($filename); $this->_tmplocal = Filestore\Factory::File('tmp/remotefile-cache/' . $fhash); if(!$this->_tmplocal->exists()){ ftp_get($this->_ftp->getConn(), $this->_tmplocal->getFilename(), $filename, FTP_BINARY); } // Since I have a local copy, I might as well make sure that the cache is as updated as possible. if(!$this->_ftp->getFileHash($filename)){ $this->_ftp->setFileHash($filename, $this->_tmplocal->getHash()); } if(!$this->_ftp->getFileModified($filename)){ $this->_ftp->setFileModified($filename, ftp_mdtm($this->_ftp->getConn(), $filename)); } if(!$this->_ftp->getFileSize($filename)){ $this->_ftp->setFileSize($filename, ftp_size($this->_ftp->getConn(), $filename)); } } } return $this->_tmplocal; }