Exemple #1
0
	/**
	 * 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;
	}
Exemple #2
0
	/**
	 * 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;
		}
	}