~tcuthbert/wordpress/openstack-objectstorage

« back to all changes in this revision

Viewing changes to vendor/guzzlehttp/guzzle/src/Post/MultipartBody.php

  • Committer: Jacek Nykis
  • Date: 2015-02-11 15:35:31 UTC
  • Revision ID: jacek.nykis@canonical.com-20150211153531-hmy6zi0ov2qfkl0b
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
 
 
3
namespace GuzzleHttp\Post;
 
4
 
 
5
use GuzzleHttp\Stream\AppendStream;
 
6
use GuzzleHttp\Stream\Stream;
 
7
use GuzzleHttp\Stream\StreamDecoratorTrait;
 
8
use GuzzleHttp\Stream\StreamInterface;
 
9
 
 
10
/**
 
11
 * Stream that when read returns bytes for a streaming multipart/form-data body
 
12
 */
 
13
class MultipartBody implements StreamInterface
 
14
{
 
15
    use StreamDecoratorTrait;
 
16
 
 
17
    private $boundary;
 
18
 
 
19
    /**
 
20
     * @param array  $fields   Associative array of field names to values where
 
21
     *                         each value is a string or array of strings.
 
22
     * @param array  $files    Associative array of PostFileInterface objects
 
23
     * @param string $boundary You can optionally provide a specific boundary
 
24
     * @throws \InvalidArgumentException
 
25
     */
 
26
    public function __construct(
 
27
        array $fields = [],
 
28
        array $files = [],
 
29
        $boundary = null
 
30
    ) {
 
31
        $this->boundary = $boundary ?: uniqid();
 
32
        $this->stream = $this->createStream($fields, $files);
 
33
    }
 
34
 
 
35
    /**
 
36
     * Get the boundary
 
37
     *
 
38
     * @return string
 
39
     */
 
40
    public function getBoundary()
 
41
    {
 
42
        return $this->boundary;
 
43
    }
 
44
 
 
45
    public function isWritable()
 
46
    {
 
47
        return false;
 
48
    }
 
49
 
 
50
    /**
 
51
     * Get the string needed to transfer a POST field
 
52
     */
 
53
    private function getFieldString($name, $value)
 
54
    {
 
55
        return sprintf(
 
56
            "--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n",
 
57
            $this->boundary,
 
58
            $name,
 
59
            $value
 
60
        );
 
61
    }
 
62
 
 
63
    /**
 
64
     * Get the headers needed before transferring the content of a POST file
 
65
     */
 
66
    private function getFileHeaders(PostFileInterface $file)
 
67
    {
 
68
        $headers = '';
 
69
        foreach ($file->getHeaders() as $key => $value) {
 
70
            $headers .= "{$key}: {$value}\r\n";
 
71
        }
 
72
 
 
73
        return "--{$this->boundary}\r\n" . trim($headers) . "\r\n\r\n";
 
74
    }
 
75
 
 
76
    /**
 
77
     * Create the aggregate stream that will be used to upload the POST data
 
78
     */
 
79
    private function createStream(array $fields, array $files)
 
80
    {
 
81
        $stream = new AppendStream();
 
82
 
 
83
        foreach ($fields as $name => $fieldValues) {
 
84
            foreach ((array) $fieldValues as $value) {
 
85
                $stream->addStream(
 
86
                    Stream::factory($this->getFieldString($name, $value))
 
87
                );
 
88
            }
 
89
        }
 
90
 
 
91
        foreach ($files as $file) {
 
92
 
 
93
            if (!$file instanceof PostFileInterface) {
 
94
                throw new \InvalidArgumentException('All POST fields must '
 
95
                    . 'implement PostFieldInterface');
 
96
            }
 
97
 
 
98
            $stream->addStream(
 
99
                Stream::factory($this->getFileHeaders($file))
 
100
            );
 
101
            $stream->addStream($file->getContent());
 
102
            $stream->addStream(Stream::factory("\r\n"));
 
103
        }
 
104
 
 
105
        // Add the trailing boundary
 
106
        $stream->addStream(Stream::factory("--{$this->boundary}--"));
 
107
 
 
108
        return $stream;
 
109
    }
 
110
}