Completed
Push — master ( 899775...3f74cc )
by Kunal
02:18
created

DropboxFile::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 5
ccs 0
cts 5
cp 0
rs 9.4285
c 1
b 0
f 0
cc 1
eloc 3
nc 1
nop 2
crap 2
1
<?php
2
namespace Kunnu\Dropbox;
3
4
use Kunnu\Dropbox\Exceptions\DropboxClientException;
5
6
/**
7
 * DropboxFile
8
 */
9
class DropboxFile
10
{
11
    const MODE_READ = 'r';
12
13
    const MODE_WRITE = 'w';
14
15
    /**
16
     * Path of the file to upload
17
     *
18
     * @var string
19
     */
20
    protected $path;
21
22
    /**
23
     * The maximum bytes to read. Defaults to -1 (read all the remaining buffer).
24
     *
25
     * @var int
26
     */
27
    protected $maxLength = -1;
28
29
    /**
30
     * Seek to the specified offset before reading.
31
     * If this number is negative, no seeking will
32
     * occur and reading will start from the current.
33
     *
34
     * @var int
35
     */
36
    protected $offset = -1;
37
38
    /**
39
     * File Stream
40
     *
41
     * @var \GuzzleHttp\Psr7\Stream
42
     */
43
    protected $stream;
44
45
    /**
46
     * The type of access
47
     *
48
     * @var string
49
     */
50
    protected $mode;
51
52
    /**
53
     * Flag to see if we created an instance using a stream
54
     *
55
     * @var bool
56
     */
57
    private $isStream = false;
58
    
59
    /**
60
     * Create a new DropboxFile instance
61
     *
62
     * @param string $filePath Path of the file to upload
63
     * @param string $mode     The type of access
64
     */
65
    public function __construct($filePath, $mode = self::MODE_READ)
66
    {
67
        $this->path = $filePath;
68
        $this->mode = $mode;
69
    }
70
71
    /**
72
     * Closes the stream when destructed.
73
     */
74
    public function __destruct()
75
    {
76
        $this->close();
77
    }
78
    
79
    
80
    /**
81
     * Create a new DropboxFile instance using a file stream
82
     *
83
     * @param $fileName
84
     * @param $resource
85
     * @param string $mode
86
     * @return DropboxFile
87
     * @throws DropboxClientException
88
     */
89
    public static function createByStream($fileName, $resource, $mode = self::MODE_READ)
90
    {
91
        // initialize a new intance
92
        $dropboxFile = new self($fileName, $mode);
93
94
        // create a new stream and set it to the dropbox file
95
        $stream = \GuzzleHttp\Psr7\stream_for($resource);
96
        if (!$stream) {
97
            throw new DropboxClientException('Failed to create DropboxFile instance. Unable to open the given resource.');
98
        }
99
        $dropboxFile->setStream($stream);
100
101
        return $dropboxFile;
102
    }
103
104
    /**
105
     * Create a new DropboxFile instance using a file path
106
     *
107
     * This behaves the same as the constructor but was added in order to
108
     * match the syntax of the static createByStream function
109
     *
110
     * @see DropboxFile::createByStream()
111
     *
112
     * @param $filePath
113
     * @param $mode
114
     * @return DropboxFile
115
     */
116
    public static function createByPath($filePath, $mode)
117
    {
118
        return new self($filePath, $mode);
119
    }
120
121
    /**
122
     * Close the file stream
123
     */
124
    public function close()
125
    {
126
        if ($this->stream) {
127
            $this->stream->close();
128
        }
129
    }
130
131
    /**
132
     * Set the offset to start reading
133
     * the data from the stream
134
     *
135
     * @param int $offset
136
     */
137
    public function setOffset($offset)
138
    {
139
        $this->offset = $offset;
140
    }
141
142
    /**
143
     * Set the Max Length till where to read
144
     * the data from the stream.
145
     *
146
     * @param int $maxLength
147
     */
148
    public function setMaxLength($maxLength)
149
    {
150
        $this->maxLength = $maxLength;
151
    }
152
    
153
    /**
154
     * Manually set the stream for this DropboxFile instance
155
     *
156
     * @param $stream
157
     */
158
    public function setStream($stream)
159
    {
160
        $this->isStream = true;
161
        $this->stream = $stream;
162
    }
163
164
    /**
165
     * Return the contents of the file
166
     *
167
     * @return string
168
     */
169
    public function getContents()
170
    {
171
        $stream = $this->getStream();
172
        // If an offset is provided
173
        if ($this->offset !== -1) {
174
            // Seek to the offset
175
            $stream->seek($this->offset);
176
        }
177
178
        // If a max length is provided
179
        if ($this->maxLength !== -1) {
180
            // Read from the offset till the maxLength
181
            return $stream->read($this->maxLength);
182
        }
183
184
        return $stream->getContents();
185
    }
186
187
    /**
188
     * Get the Open File Stream
189
     *
190
     * @return \GuzzleHttp\Psr7\Stream
191
     */
192
    public function getStream()
193
    {
194
        if (!$this->stream) {
195
            $this->open();
196
        }
197
        return $this->stream;
198
    }
199
200
    /**
201
     * Opens the File Stream
202
     *
203
     * @throws DropboxClientException
204
     *
205
     * @return void
206
     */
207
    public function open()
208
    {
209
        // File was created from a stream so don't open it again
210
        if ($this->stream && $this->isStream === true) {
211
            return;
212
        }
213
        
214
        if (!$this->isRemoteFile($this->path)) {
215
            if (self::MODE_READ === $this->mode && !is_readable($this->path)) {
216
                throw new DropboxClientException('Failed to create DropboxFile instance. Unable to read resource: ' . $this->path . '.');
217
            }
218
            if (self::MODE_WRITE === $this->mode && file_exists($this->path) && !is_writable($this->path)) {
219
                throw new DropboxClientException('Failed to create DropboxFile instance. Unable to write resource: ' . $this->path . '.');
220
            }
221
        }
222
223
        $this->stream = \GuzzleHttp\Psr7\stream_for(fopen($this->path, $this->mode));
224
225
        if (!$this->stream) {
226
            throw new DropboxClientException('Failed to create DropboxFile instance. Unable to open resource: ' . $this->path . '.');
227
        }
228
    }
229
230
    /**
231
     * Returns true if the path to the file is remote
232
     *
233
     * @param string $pathToFile
234
     *
235
     * @return boolean
236
     */
237
    protected function isRemoteFile($pathToFile)
238
    {
239
        return preg_match('/^(https?|ftp):\/\/.*/', $pathToFile) === 1;
240
    }
241
242
    /**
243
     * Get the name of the file
244
     *
245
     * @return string
246
     */
247
    public function getFileName()
248
    {
249
        return basename($this->path);
250
    }
251
252
    /**
253
     * Get the path of the file
254
     *
255
     * @return string
256
     */
257
    public function getFilePath()
258
    {
259
        return $this->path;
260
    }
261
262
    /**
263
     * Get the mode of the file stream
264
     *
265
     * @return string
266
     */
267
    public function getMode()
268
    {
269
        return $this->mode;
270
    }
271
272
    /**
273
     * Get the size of the file
274
     *
275
     * @return int
276
     */
277
    public function getSize()
278
    {
279
        return $this->getStream()->getSize();
280
    }
281
282
    /**
283
     * Get mimetype of the file
284
     *
285
     * @return string
286
     */
287
    public function getMimetype()
288
    {
289
        return \GuzzleHttp\Psr7\mimetype_from_filename($this->path) ?: 'text/plain';
290
    }
291
}
292