/lib/Cake/Network/Http/FormData.php

https://github.com/shama/cakephp · PHP · 175 lines · 74 code · 13 blank · 88 comment · 7 complexity · 3429eebe1583c6503347b305a8e9c6d7 MD5 · raw file

  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * Redistributions of files must retain the above copyright notice.
  8. *
  9. * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  10. * @link http://cakephp.org CakePHP(tm) Project
  11. * @since CakePHP(tm) v 3.0.0
  12. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  13. */
  14. namespace Cake\Network\Http;
  15. use Cake\Network\Http\FormData\Part;
  16. /**
  17. * Provides an interface for building
  18. * multipart/form-encoded message bodies.
  19. *
  20. * Used by Http\Client to upload POST/PUT data
  21. * and files.
  22. *
  23. */
  24. class FormData implements \Countable {
  25. /**
  26. * Boundary marker.
  27. *
  28. * @var string
  29. */
  30. protected $_boundary;
  31. /**
  32. * The parts in the form data.
  33. *
  34. * @var array
  35. */
  36. protected $_parts = [];
  37. /**
  38. * Get the boundary marker
  39. *
  40. * @return string
  41. */
  42. public function boundary() {
  43. if ($this->_boundary) {
  44. return $this->_boundary;
  45. }
  46. $this->_boundary = md5(uniqid(time()));
  47. return $this->_boundary;
  48. }
  49. /**
  50. * Method for creating new instances of Part
  51. *
  52. * @param string $name The name of the part.
  53. * @param string $value The value to add.
  54. * @return Cake\Network\Http\FormData\Part
  55. */
  56. public function newPart($name, $value) {
  57. return new Part($name, $value);
  58. }
  59. /**
  60. * Add a new part to the data.
  61. *
  62. * The value for a part can be a string, array, int,
  63. * float, filehandle, or object implementing __toString()
  64. *
  65. * If the $value is an array, multiple parts will be added.
  66. * Files will be read from their current position and saved in memory.
  67. *
  68. * @param string $name The name of the part.
  69. * @param mixed $value The value for the part.
  70. * @return FormData $this
  71. */
  72. public function add($name, $value) {
  73. if (is_array($value)) {
  74. $this->addRecursive($name, $value);
  75. } elseif (is_resource($value)) {
  76. $this->_parts[] = $this->addFile($name, $value);
  77. } elseif (is_string($value) && $value[0] === '@') {
  78. $this->_parts[] = $this->addFile($name, $value);
  79. } else {
  80. $this->_parts[] = $this->newPart($name, $value);
  81. }
  82. return $this;
  83. }
  84. /**
  85. * Add multiple parts at once.
  86. *
  87. * Iterates the parameter and adds all the key/values.
  88. * @param array $data Array of data to add.
  89. * @return FormData $this
  90. */
  91. public function addMany(array $data) {
  92. foreach ($data as $name => $value) {
  93. $this->add($name, $value);
  94. }
  95. return $this;
  96. }
  97. /**
  98. * Add either a file reference (string starting with @)
  99. * or a file handle.
  100. *
  101. * @param string $name The name to use.
  102. * @param mixed $value Either a string filename, or a filehandle.
  103. * @return void
  104. */
  105. public function addFile($name, $value) {
  106. $filename = false;
  107. $contentType = 'application/octet-stream';
  108. if (is_resource($value)) {
  109. $content = stream_get_contents($value);
  110. } else {
  111. $finfo = new \finfo(FILEINFO_MIME);
  112. $value = substr($value, 1);
  113. $filename = basename($value);
  114. $content = file_get_contents($value);
  115. $contentType = $finfo->file($value);
  116. }
  117. $part = $this->newPart($name, $content);
  118. $part->type($contentType);
  119. if ($filename) {
  120. $part->filename($filename);
  121. }
  122. return $part;
  123. }
  124. /**
  125. * Recursively add data.
  126. *
  127. * @param string $name The name to use.
  128. * @param mixed $value The value to add.
  129. * @return void
  130. */
  131. public function addRecursive($name, $value) {
  132. foreach ($value as $key => $value) {
  133. $key = $name . '[' . $key . ']';
  134. $this->add($key, $value);
  135. }
  136. }
  137. /**
  138. * Returns the count of parts inside this object.
  139. *
  140. * @return int
  141. */
  142. public function count() {
  143. return count($this->_parts);
  144. }
  145. /**
  146. * Converts the FormData and its parts into a string suitable
  147. * for use in an HTTP request.
  148. *
  149. * @return string
  150. */
  151. public function __toString() {
  152. $boundary = $this->boundary();
  153. $out = '';
  154. foreach ($this->_parts as $part) {
  155. $out .= "--$boundary\r\n";
  156. $out .= (string)$part;
  157. $out .= "\r\n";
  158. }
  159. $out .= "--$boundary--\r\n\r\n";
  160. return $out;
  161. }
  162. }