1. */ public function __construct($xmlString = null, $filePath = null, $fileContentType = null) { if (!file_exists($filePath) || !is_readable($filePath)) { require_once 'Zend/Gdata/App/IOException.php'; throw new Zend_Gdata_App_IOException('File to be uploaded at ' . $filePath . ' does not exist or is not readable.'); } $this->_fileHandle = fopen($filePath, 'rb', TRUE); $this->_boundaryString = '=_' . md5(microtime(1) . rand(1,20)); $entry = $this->wrapEntry($xmlString, $fileContentType); $closingBoundary = new Zend_Gdata_MimeBodyString("\r\n--{$this->_boundaryString}--\r\n"); $file = new Zend_Gdata_MimeFile($this->_fileHandle); $this->_parts = array($entry, $file, $closingBoundary); $fileSize = filesize($filePath); $this->_totalSize = $entry->getSize() + $fileSize + $closingBoundary->getSize(); } /** * Sandwiches the entry body into a MIME message * * @return void */ private function wrapEntry($entry, $fileMimeType) { $wrappedEntry = "--{$this->_boundaryString}\r\n"; $wrappedEntry .= "Content-Type: application/atom+xml\r\n\r\n"; $wrappedEntry .= $entry; $wrappedEntry .= "\r\n--{$this->_boundaryString}\r\n"; $wrappedEntry .= "Content-Type: $fileMimeType\r\n\r\n"; return new Zend_Gdata_MimeBodyString($wrappedEntry); } /** * Read a specific chunk of the the MIME multipart message. * * @param integer $bufferSize The size of the chunk that is to be read, * must be lower than MAX_BUFFER_SIZE. * @return string A corresponding piece of the message. This could be * binary or regular text. */ public function read($bytesRequested) { if($this->_currentPart >= count($this->_parts)) { return FALSE; } $activePart = $this->_parts[$this->_currentPart]; $buffer = $activePart->read($bytesRequested); while(strlen($buffer) < $bytesRequested) { $this->_currentPart += 1; $nextBuffer = $this->read($bytesRequested - strlen($buffer)); if($nextBuffer === FALSE) { break; } $buffer .= $nextBuffer; } return $buffer; } /** * Return the total size of the mime message. * * @return integer Total size of the message to be sent. */ public function getTotalSize() { return $this->_totalSize; } /** * Close the internal file that we are streaming to the socket. * * @return void */ public function closeFileHandle() { if ($this->_fileHandle !== null) { fclose($this->_fileHandle); } } /** * Return a Content-type header that includes the current boundary string. * * @return string A valid HTTP Content-Type header. */ public function getContentType() { return 'multipart/related;boundary="' . $this->_boundaryString . '"' . "\r\n"; } }