PageRenderTime 26ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/library/Zend/GData/MediaMimeStream.php

http://github.com/zendframework/zf2
PHP | 185 lines | 68 code | 21 blank | 96 comment | 5 complexity | 5e3370642df32b1d799268b36c41131a MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Gdata
  17. * @subpackage Gdata
  18. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. */
  21. /**
  22. * @namespace
  23. */
  24. namespace Zend\GData;
  25. /**
  26. * A streaming Media MIME class that allows for buffered read operations.
  27. *
  28. * @uses \Zend\GData\App\IOException
  29. * @uses \Zend\GData\MimeBodyString
  30. * @uses \Zend\GData\MimeFile
  31. * @category Zend
  32. * @package Zend_Gdata
  33. * @subpackage Gdata
  34. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  35. * @license http://framework.zend.com/license/new-bsd New BSD License
  36. */
  37. class MediaMimeStream
  38. {
  39. /**
  40. * A valid MIME boundary.
  41. *
  42. * @var string
  43. */
  44. protected $_boundaryString = null;
  45. /**
  46. * A handle to the file that is part of the message.
  47. *
  48. * @var resource
  49. */
  50. protected $_fileHandle = null;
  51. /**
  52. * The current part being read from.
  53. * @var integer
  54. */
  55. protected $_currentPart = 0;
  56. /**
  57. * The size of the MIME message.
  58. * @var integer
  59. */
  60. protected $_totalSize = 0;
  61. /**
  62. * An array of all the parts to be sent. Array members are either a
  63. * MimeFile or a MimeBodyString object.
  64. * @var array
  65. */
  66. protected $_parts = null;
  67. /**
  68. * Create a new MimeMediaStream object.
  69. *
  70. * @param string $xmlString The string corresponding to the XML section
  71. * of the message, typically an atom entry or feed.
  72. * @param string $filePath The path to the file that constitutes the binary
  73. * part of the message.
  74. * @param string $fileContentType The valid internet media type of the file.
  75. * @throws \Zend\GData\App\IOException If the file cannot be read or does
  76. * not exist. Also if mbstring.func_overload has been set > 1.
  77. */
  78. public function __construct($xmlString = null, $filePath = null,
  79. $fileContentType = null)
  80. {
  81. if (!file_exists($filePath) || !is_readable($filePath)) {
  82. throw new App\IOException('File to be uploaded at ' .
  83. $filePath . ' does not exist or is not readable.');
  84. }
  85. $this->_fileHandle = fopen($filePath, 'rb', TRUE);
  86. $this->_boundaryString = '=_' . md5(microtime(1) . rand(1,20));
  87. $entry = $this->wrapEntry($xmlString, $fileContentType);
  88. $closingBoundary = new MimeBodyString("\r\n--{$this->_boundaryString}--\r\n");
  89. $file = new MimeFile($this->_fileHandle);
  90. $this->_parts = array($entry, $file, $closingBoundary);
  91. $fileSize = filesize($filePath);
  92. $this->_totalSize = $entry->getSize() + $fileSize
  93. + $closingBoundary->getSize();
  94. }
  95. /**
  96. * Sandwiches the entry body into a MIME message
  97. *
  98. * @return void
  99. */
  100. private function wrapEntry($entry, $fileMimeType)
  101. {
  102. $wrappedEntry = "--{$this->_boundaryString}\r\n";
  103. $wrappedEntry .= "Content-Type: application/atom+xml\r\n\r\n";
  104. $wrappedEntry .= $entry;
  105. $wrappedEntry .= "\r\n--{$this->_boundaryString}\r\n";
  106. $wrappedEntry .= "Content-Type: $fileMimeType\r\n\r\n";
  107. return new MimeBodyString($wrappedEntry);
  108. }
  109. /**
  110. * Read a specific chunk of the the MIME multipart message.
  111. *
  112. * @param integer $bufferSize The size of the chunk that is to be read,
  113. * must be lower than MAX_BUFFER_SIZE.
  114. * @return string A corresponding piece of the message. This could be
  115. * binary or regular text.
  116. */
  117. public function read($bytesRequested)
  118. {
  119. if($this->_currentPart >= count($this->_parts)) {
  120. return FALSE;
  121. }
  122. $activePart = $this->_parts[$this->_currentPart];
  123. $buffer = $activePart->read($bytesRequested);
  124. while(strlen($buffer) < $bytesRequested) {
  125. $this->_currentPart += 1;
  126. $nextBuffer = $this->read($bytesRequested - strlen($buffer));
  127. if($nextBuffer === FALSE) {
  128. break;
  129. }
  130. $buffer .= $nextBuffer;
  131. }
  132. return $buffer;
  133. }
  134. /**
  135. * Return the total size of the mime message.
  136. *
  137. * @return integer Total size of the message to be sent.
  138. */
  139. public function getTotalSize()
  140. {
  141. return $this->_totalSize;
  142. }
  143. /**
  144. * Close the internal file that we are streaming to the socket.
  145. *
  146. * @return void
  147. */
  148. public function closeFileHandle()
  149. {
  150. if ($this->_fileHandle !== null) {
  151. fclose($this->_fileHandle);
  152. }
  153. }
  154. /**
  155. * Return a Content-type header that includes the current boundary string.
  156. *
  157. * @return string A valid HTTP Content-Type header.
  158. */
  159. public function getContentType()
  160. {
  161. return 'multipart/related;boundary="' .
  162. $this->_boundaryString . '"' . "\r\n";
  163. }
  164. }