Completed
Push — master ( 3d7154...87dec9 )
by Hector
05:10 queued 02:26
created

TONUpload::perform()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 24
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 1
Metric Value
c 5
b 0
f 1
dl 0
loc 24
rs 8.9713
cc 3
eloc 18
nc 3
nop 0
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: hborras
5
 * Date: 1/07/16
6
 * Time: 21:35
7
 */
8
9
namespace Hborras\TwitterAdsSDK;
10
11
12
class TONUpload
13
{
14
    const DEFAULT_DOMAIN = 'https://ton.twitter.com';
15
    const DEFAULT_RESOURCE = '/1.1/ton/bucket/';
16
    const DEFAULT_BUCKET = 'ta_partner';
17
    const MIN_FILE_SIZE = 1048576;
18
19
    private $filePath;
20
    private $fileSize;
21
    /** @var TwitterAds */
22
    private $twitterAds;
23
    private $params;
24
25
    public function __construct(TwitterAds $twitterAds, $filePath, $params = [])
26
    {
27
        if (!file_exists($filePath)) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
28
            // TODO: Throw Exception
29
        }
30
        $this->filePath = $filePath;
31
        $this->fileSize = filesize($filePath);
32
        $this->twitterAds = $twitterAds;
33
        $this->params = $params;
34
    }
35
36
    public function getContentType()
37
    {
38
        if (isset($this->contentType)) {
39
            return $this->contentType;
0 ignored issues
show
Bug introduced by
The property contentType does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
40
        }
41
42
        $extension = pathinfo($this->filePath, PATHINFO_EXTENSION);
43
44
        if ($extension == 'csv') {
45
            $this->contentType = 'text/csv';
46
        } else if ($extension == 'tsv') {
47
            $this->contentType = 'text/tab-separated-values';
48
        } else {
49
            $this->contentType = 'text/plain';
50
        }
51
52
        return $this->contentType;
53
    }
54
55
    public function perform()
56
    {
57
        if ($this->fileSize < self::MIN_FILE_SIZE) {
58
            $response = $this->upload();
59
            return $response->getsHeaders()['location'];
60
        } else {
61
            $response = $this->initChunkedUpload();
62
            $responseHeaders = $response->getsHeaders();
63
            $chunkSize = intval($responseHeaders['x_ton_min_chunk_size']);
64
            $location = $responseHeaders['location'];
65
66
            $file = fopen($this->filePath, 'rb');
67
            $bytesRead = 0;
68
            while (!feof($file)) {
69
                $bytes = fread($file, $chunkSize);
70
                $bytesStart = $bytesRead;
71
                $bytesRead += strlen($bytes);
72
                $this->uploadChunk($location, $chunkSize, $bytes, $bytesStart, $bytesRead);
73
            }
74
            fclose($file);
75
76
            return $location;
77
        }
78
    }
79
80
    public function upload()
81
    {
82
        /** Here you can add any header you want to the request*/
83
        $headers = [
84
            'x-ton-expires: ' . gmdate('D, d M Y H:i:s T', strtotime("+10 day")),
85
            'content-type: ' . $this->getContentType(),
86
            'Content-Length: ' . $this->fileSize
87
        ];
88
89
        $response = $this->getTwitterAds()->post(self::DEFAULT_DOMAIN.self::DEFAULT_RESOURCE.self::DEFAULT_BUCKET, ['raw' => file_get_contents($this->filePath)], $headers);
90
        return $response;
91
    }
92
93
    public function uploadChunk($resource, $chunkSize, $bytes, $bytesStart, $bytesRead)
0 ignored issues
show
Unused Code introduced by
The parameter $chunkSize is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
94
    {
95
        $headers = [
96
            'Content-Type: ' . $this->getContentType(),
97
            'Content-Range: bytes ' . $bytesStart . '-' . ($bytesRead - 1) . '/' . $this->fileSize
98
        ];
99
        $response = $this->getTwitterAds()->put(self::DEFAULT_DOMAIN.$resource, ['raw' => $bytes], $headers);
100
101
        return $response;
102
    }
103
104
    public function initChunkedUpload()
105
    {
106
        $headers = [
107
            'X-Ton-Content-Type: ' . $this->getContentType(),
108
            'X-Ton-Content-Length: ' . $this->fileSize,
109
            'X-Ton-Expires: ' . gmdate('D, d M Y H:i:s T', strtotime("+6 day")),
110
            'Content-Type: ' . $this->getContentType(),
111
            'Content-Length: ' . strval(0)
112
        ];
113
114
        $resource = self::DEFAULT_DOMAIN.self::DEFAULT_RESOURCE.self::DEFAULT_BUCKET. '?resumable=true';
115
        $response = $this->getTwitterAds()->post($resource, [], $headers);
116
        return $response;
117
    }
118
119
    /**
120
     * @return mixed
121
     */
122
    public function getFilePath()
123
    {
124
        return $this->filePath;
125
    }
126
127
    /**
128
     * @param mixed $filePath
129
     */
130
    public function setFilePath($filePath)
131
    {
132
        $this->filePath = $filePath;
133
    }
134
135
    /**
136
     * @return mixed
137
     */
138
    public function getFileSize()
139
    {
140
        return $this->fileSize;
141
    }
142
143
    /**
144
     * @param mixed $fileSize
145
     */
146
    public function setFileSize($fileSize)
147
    {
148
        $this->fileSize = $fileSize;
149
    }
150
151
    /**
152
     * @return TwitterAds
153
     */
154
    public function getTwitterAds()
155
    {
156
        return $this->twitterAds;
157
    }
158
159
    /**
160
     * @param mixed $twitterAds
161
     */
162
    public function setTwitterAds($twitterAds)
163
    {
164
        $this->twitterAds = $twitterAds;
165
    }
166
167
    /**
168
     * @return mixed
169
     */
170
    public function getParams()
171
    {
172
        return $this->params;
173
    }
174
175
    /**
176
     * @param mixed $params
177
     */
178
    public function setParams($params)
179
    {
180
        $this->params = $params;
181
    }
182
}