File indexing completed on 2024-05-12 06:02:40

0001 <?php
0002 
0003 /**
0004  * Zend Framework
0005  *
0006  * LICENSE
0007  *
0008  * This source file is subject to the new BSD license that is bundled
0009  * with this package in the file LICENSE.txt.
0010  * It is also available through the world-wide-web at this URL:
0011  * http://framework.zend.com/license/new-bsd
0012  * If you did not receive a copy of the license and are unable to
0013  * obtain it through the world-wide-web, please send an email
0014  * to license@zend.com so we can send you a copy immediately.
0015  *
0016  * @category   Zend
0017  * @package    Zend_Gdata
0018  * @subpackage Gdata
0019  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0020  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0021  * @version    $Id$
0022  */
0023 
0024 /**
0025 *  @see Zend_Gdata_MimeFile
0026 */
0027 // require_once 'Zend/Gdata/MimeFile.php';
0028 
0029 /**
0030 * @see Zend_Gdata_MimeBodyString
0031 */
0032 // require_once 'Zend/Gdata/MimeBodyString.php';
0033 
0034 
0035 /**
0036  * A streaming Media MIME class that allows for buffered read operations.
0037  *
0038  * @category   Zend
0039  * @package    Zend_Gdata
0040  * @subpackage Gdata
0041  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0042  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0043  */
0044 class Zend_Gdata_MediaMimeStream
0045 {
0046 
0047     /**
0048      * A valid MIME boundary.
0049      *
0050      * @var string
0051      */
0052     protected $_boundaryString = null;
0053 
0054     /**
0055      * A handle to the file that is part of the message.
0056      *
0057      * @var resource
0058      */
0059     protected $_fileHandle = null;
0060 
0061     /**
0062      * The current part being read from.
0063      * @var integer
0064      */
0065     protected $_currentPart = 0;
0066 
0067     /**
0068      * The size of the MIME message.
0069      * @var integer
0070      */
0071     protected $_totalSize = 0;
0072 
0073     /**
0074      * An array of all the parts to be sent. Array members are either a
0075      * MimeFile or a MimeBodyString object.
0076      * @var array
0077      */
0078     protected $_parts = null;
0079 
0080     /**
0081      * Create a new MimeMediaStream object.
0082      *
0083      * @param string $xmlString The string corresponding to the XML section
0084      *               of the message, typically an atom entry or feed.
0085      * @param string $filePath The path to the file that constitutes the binary
0086      *               part of the message.
0087      * @param string $fileContentType The valid internet media type of the file.
0088      * @throws Zend_Gdata_App_IOException If the file cannot be read or does
0089      *         not exist. Also if mbstring.func_overload has been set > 1.
0090      */
0091     public function __construct($xmlString = null, $filePath = null,
0092         $fileContentType = null)
0093     {
0094         if (!file_exists($filePath) || !is_readable($filePath)) {
0095             // require_once 'Zend/Gdata/App/IOException.php';
0096             throw new Zend_Gdata_App_IOException('File to be uploaded at ' .
0097                 $filePath . ' does not exist or is not readable.');
0098         }
0099 
0100         $this->_fileHandle = fopen($filePath, 'rb', TRUE);
0101         $this->_boundaryString = '=_' . md5(microtime(1) . rand(1,20));
0102         $entry = $this->wrapEntry($xmlString, $fileContentType);
0103         $closingBoundary = new Zend_Gdata_MimeBodyString("\r\n--{$this->_boundaryString}--\r\n");
0104         $file = new Zend_Gdata_MimeFile($this->_fileHandle);
0105         $this->_parts = array($entry, $file, $closingBoundary);
0106 
0107         $fileSize = filesize($filePath);
0108         $this->_totalSize = $entry->getSize() + $fileSize
0109           + $closingBoundary->getSize();
0110 
0111     }
0112 
0113     /**
0114      * Sandwiches the entry body into a MIME message
0115      *
0116      * @return void
0117      */
0118     private function wrapEntry($entry, $fileMimeType)
0119     {
0120         $wrappedEntry = "--{$this->_boundaryString}\r\n";
0121         $wrappedEntry .= "Content-Type: application/atom+xml\r\n\r\n";
0122         $wrappedEntry .= $entry;
0123         $wrappedEntry .= "\r\n--{$this->_boundaryString}\r\n";
0124         $wrappedEntry .= "Content-Type: $fileMimeType\r\n\r\n";
0125         return new Zend_Gdata_MimeBodyString($wrappedEntry);
0126     }
0127 
0128     /**
0129      * Read a specific chunk of the the MIME multipart message.
0130      *
0131      * @param integer $bufferSize The size of the chunk that is to be read,
0132      *                            must be lower than MAX_BUFFER_SIZE.
0133      * @return string A corresponding piece of the message. This could be
0134      *                binary or regular text.
0135      */
0136     public function read($bytesRequested)
0137     {
0138         if($this->_currentPart >= count($this->_parts)) {
0139           return FALSE;
0140         }
0141 
0142         $activePart = $this->_parts[$this->_currentPart];
0143         $buffer = $activePart->read($bytesRequested);
0144 
0145         while(strlen($buffer) < $bytesRequested) {
0146           $this->_currentPart += 1;
0147           $nextBuffer = $this->read($bytesRequested - strlen($buffer));
0148           if($nextBuffer === FALSE) {
0149             break;
0150           }
0151           $buffer .= $nextBuffer;
0152         }
0153 
0154         return $buffer;
0155     }
0156 
0157     /**
0158      * Return the total size of the mime message.
0159      *
0160      * @return integer Total size of the message to be sent.
0161      */
0162     public function getTotalSize()
0163     {
0164         return $this->_totalSize;
0165     }
0166 
0167     /**
0168      * Close the internal file that we are streaming to the socket.
0169      *
0170      * @return void
0171      */
0172     public function closeFileHandle()
0173     {
0174         if ($this->_fileHandle !== null) {
0175             fclose($this->_fileHandle);
0176         }
0177     }
0178 
0179     /**
0180      * Return a Content-type header that includes the current boundary string.
0181      *
0182      * @return string A valid HTTP Content-Type header.
0183      */
0184     public function getContentType()
0185     {
0186         return 'multipart/related;boundary="' .
0187             $this->_boundaryString . '"' . "\r\n";
0188     }
0189 
0190 }