/** * Make a copy of a source Filestore\File into this Filestore\File. * * (Generally only useful internally) * * @param Filestore\File $src Source file backend * @param bool $overwrite true to overwrite existing file * * @throws \Exception * @return bool True or False if succeeded. */ public function copyFrom(Filestore\File $src, $overwrite = false) { // Don't overwrite existing files unless told otherwise... if (!$overwrite) { $c = 0; $ext = $this->getExtension(); $base = $this->getBaseFilename(true); $dir = dirname($this->_filename); $prefix = $dir . '/' . $base; $suffix = (($ext == '') ? '' : '.' . $ext); $thathash = $src->getHash(); $f = $prefix . $suffix; while(file_exists($f) && md5_file($f) != $thathash){ $f = $prefix . ' (' . ++$c . ')' . $suffix; } $this->_filename = $f; } // And do the actual copy! // To save memory, try to use as low-level functions as possible. $localfilename = $src->getLocalFilename(); $localhash = $src->getHash(); $localmodified = $src->getMTime(); $localsize = $src->getFilesize(); // Resolve it from its default. // This is provided from a config define, (probably). $mode = (defined('DEFAULT_FILE_PERMS') ? DEFAULT_FILE_PERMS : 0644); // Make sure the directory exists first! $this->_mkdir(dirname($this->_filename), null, true); // FTP requires a filename, not data... // WELL how bout that! I happen to have a local filename ;) if (!ftp_put($this->_ftp->getConn(), $this->_filename, $localfilename, FTP_BINARY)) { throw new \Exception(error_get_last()['message']); } if (!ftp_chmod($this->_ftp->getConn(), $mode, $this->_filename)){ throw new \Exception(error_get_last()['message']); } // Don't forget to save the metadata for this file! $filename = $this->getFilename(); $this->_ftp->setFileHash($filename, $localhash); $this->_ftp->setFileModified($filename, $localmodified); $this->_ftp->setFileSize($filename, $localsize); // woot... return true; }
/** * Make a copy of a source Filestore\File into this File. * * (Generally only useful internally) * * @param Filestore\File $src Source file backend * @param bool $overwrite true to overwrite existing file * * @throws \Exception * @return bool True or False if succeeded. */ public function copyFrom(Filestore\File $src, $overwrite = false) { // Don't overwrite existing files unless told otherwise... if (!$overwrite) { $c = 0; $ext = $this->getExtension(); $base = $this->getBaseFilename(true); $dir = dirname($this->_filename); $prefix = $dir . '/' . $base; $suffix = (($ext == '') ? '' : '.' . $ext); $thathash = $src->getHash(); $f = $prefix . $suffix; while(file_exists($f) && md5_file($f) != $thathash){ $f = $prefix . '-' . ++$c . '' . $suffix; } $this->_filename = $f; } // And do the actual copy! // To save memory, try to use as low-level functions as possible. $localfilename = $src->getLocalFilename(); // I also want to know when this file was modified so I can set the new version to have the same datestamp. $modifiedtime = $src->getMTime(); $ftp = \Core\ftp(); $tmpdir = TMP_DIR; if ($tmpdir{0} != '/') $tmpdir = ROOT_PDIR . $tmpdir; // Needs to be fully resolved // Resolve it from its default. // This is provided from a config define, (probably). $mode = (defined('DEFAULT_FILE_PERMS') ? DEFAULT_FILE_PERMS : 0644); // Make sure the directory exists first! // This has to be done regardless of FTP mode or not. self::_Mkdir(dirname($this->_filename), null, true); if ( !$ftp || // FTP not enabled or (strpos($this->_filename, $tmpdir) === 0) // Destination is a temporary file. ) { // Read in only so much data at a time. This is to prevent // PHP from trying to read a full 2GB file into memory at once :S $maxbuffer = (1024 * 1024 * 10); $handlein = fopen($localfilename, 'r'); $handleout = fopen($this->_filename, 'w'); // Couldn't get a lock on both input and output files. if(!$handlein){ throw new \Exception('Unable to open file ' . $localfilename . ' for reading.'); } if(!$handleout){ throw new \Exception('Unable to open file ' . $this->_filename . ' for writing.'); } while(!feof($handlein)){ fwrite($handleout, fread($handlein, $maxbuffer)); } // yayz fclose($handlein); fclose($handleout); chmod($this->_filename, $mode); // Don't forget the mtime ;) touch($this->_filename, $modifiedtime); return true; } else { // Trim off the ROOT_PDIR since it'll be relative to the ftp root set in the config. if (strpos($this->_filename, ROOT_PDIR) === 0){ $filename = substr($this->_filename, strlen(ROOT_PDIR)); } else{ $filename = $this->_filename; } // Re-acquire the FTP connection. Core will reset the cwd back to root upon doing this. // This is required because mkdir may change directories. $ftp = \Core\ftp(); // FTP requires a filename, not data... // WELL how bout that! I happen to have a local filename ;) if (!ftp_put($ftp, $filename, $localfilename, FTP_BINARY)) { throw new \Exception(error_get_last()['message']); } if (!ftp_chmod($ftp, $mode, $filename)){ throw new \Exception(error_get_last()['message']); } // woot... return true; } }