Completed
Push — master ( fe0371...1946fd )
by Simon
04:01
created

Task::connect()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 2

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 2
eloc 9
c 4
b 0
f 0
nc 2
nop 1
dl 0
loc 15
rs 9.4285
ccs 9
cts 9
cp 1
crap 2
1
<?php namespace Simondubois\UnsplashDownloader;
2
3
use Exception;
4
5
/**
6
 * A task to download photos from Unsplash. Steps are
7
 * - list photos
8
 * - download photos
9
 */
10
class Task
11
{
12
13
    //
14
    // Constants
15
    //
16
17
    /**
18
     * Notification types
19
     */
20
    const NOTIFY_INFO = 'info';
21
    const NOTIFY_COMMENT = 'comment';
22
    const NOTIFY_ERROR = 'error';
23
24
    /**
25
     * Download status
26
     */
27
    const DOWNLOAD_SUCCESS = 0;
28
    const DOWNLOAD_SKIPPED = 1;
29
    const DOWNLOAD_FAILED  = 2;
30
31
32
33
    //
34
    // Attributes
35
    //
36
37
    /**
38
     * History proxy
39
     * @var History
40
     */
41
    private $history;
42
43
    /**
44
     * Callback to call when notification arised : function ($message, $level = null) {};
45
     * @var callable
46
     */
47
    private $notificationCallback;
48
49
    /**
50
     * Path where to download photos
51
     * @var string
52
     */
53
    private $destination;
54
55
    /**
56
     * Number of photos to download
57
     * @var int
58
     */
59
    private $quantity;
60
61
    /**
62
     * Category ID
63
     * @var int
64
     */
65
    private $category;
66
67
    /**
68
     * True if the task should only download featured photos
69
     * @var bool
70
     */
71
    private $featured;
72
73
74
75
    //
76
    // Getters
77
    //
78
79
    /**
80
     * Get history proxy attribute. Instantiate it if null
81
     * @return History Instance
82
     */
83 18
    public function getHistoryInstance()
84
    {
85 18
        if (is_null($this->history)) {
86 18
            $this->history = new History();
87 18
        }
88
89 18
        return $this->history;
90
    }
91
92
    /**
93
     * Get notification callback attribute
94
     * @return callable function ($message, $level = null) {}
95
     */
96 1
    public function getNotificationCallback()
97
    {
98 1
        return $this->notificationCallback;
99
    }
100
101
    /**
102
     * Get destination attribute
103
     * @return string Path to folder
104
     */
105 1
    public function getDestination()
106
    {
107 1
        return $this->destination;
108
    }
109
110
    /**
111
     * Get quantity attribute
112
     * @return int Number of photos to download
113
     */
114 1
    public function getQuantity()
115
    {
116 1
        return $this->quantity;
117
    }
118
119
    /**
120
     * Get category attribute
121
     * @return int Category ID
122
     */
123 1
    public function getCategory()
124
    {
125 1
        return $this->category;
126
    }
127
128
    /**
129
     * Get featured attribute
130
     * @return bool True if the task should only download featured photos
131
     */
132 2
    public function getFeatured()
133
    {
134 2
        return $this->featured;
135
    }
136
137
    /**
138
     * Get history path attribute
139
     * @return string Path to file
140
     */
141 1
    public function getHistory()
142
    {
143 1
        return $this->history->getPath();
144
    }
145
146
147
148
    //
149
    // Setters
150
    //
151
152
    /**
153
     * Task constructor (set non scalar attributes)
154
     */
155 22
    public function __construct()
156
    {
157 22
        $this->history = $this->getHistoryInstance();
158
        $this->notificationCallback = function($message, $level = null) {};
2 ignored issues
show
Unused Code introduced by
The parameter $message 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...
Unused Code introduced by
The parameter $level 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...
159 22
    }
160
161
    /**
162
     * Set notification callback attribute
163
     * @param callable $notificationCallback function ($message, $level = null) {}
164
     */
165 3
    public function setNotificationCallback($notificationCallback)
166
    {
167 3
        $this->notificationCallback = $notificationCallback;
168 3
    }
169
170
    /**
171
     * Set destination attribute
172
     * @param string $destination Path to folder
173
     */
174 3
    public function setDestination($destination)
175
    {
176 3
        $this->destination = $destination;
177 3
    }
178
179
    /**
180
     * Set quantity attribute
181
     * @param int $quantity Number of photos to download
182
     */
183 6
    public function setQuantity($quantity)
184
    {
185 6
        $this->quantity = $quantity;
186 6
    }
187
188
    /**
189
     * Set category attribute
190
     * @param int $category Number of photos to download
191
     */
192 2
    public function setCategory($category)
193
    {
194 2
        $this->category = $category;
195 2
    }
196
197
    /**
198
     * Set featured attribute
199
     * @param bool $featured True if the task should only download featured photos
200
     */
201 2
    public function setFeatured($featured)
202
    {
203 2
        $this->featured = $featured;
204 2
    }
205
206
    /**
207
     * Set path attribute in history instance
208
     * @param string $history Path to file
209
     */
210 1
    public function setHistory($history)
211
    {
212 1
        $this->history->load($history);
213 1
    }
214
215
216
217
    //
218
    // Notification
219
    //
220
221
    /**
222
     * Call the notification callback when a notification arised
223
     * @param  string $message Message text
224
     * @param  string|null $level Message context
225
     */
226 1
    public function notify($message, $level = null)
227
    {
228 1
        $callback = $this->notificationCallback;
229 1
        call_user_func($callback, $message, $level);
230 1
    }
231
232
233
234
    //
235
    //  Execution
236
    //
237
238
    /**
239
     * Find photos and download them
240
     * @return bool True if the execution is successful
241
     */
242 1
    public function download()
243
    {
244 1
        $unsplash = new Unsplash();
245
246 1
        $photos = $this->getPhotos($unsplash);
247 1
        $success = $this->downloadAllPhotos($photos);
248 1
        $this->history->save();
249
250 1
        return $success;
251
    }
252
253
    /**
254
     * List categories
255
     * @return bool True if the execution is successful
256
     */
257 1
    public function categories()
258
    {
259 1
        $unsplash = new Unsplash();
260
261 1
        return $this->listCategories($unsplash);
262
    }
263
264
    /**
265
     * Request APi to get photos to downloads
266
     * @param Unsplash $unsplash Proxy to Unsplash API
267
     * @return string[] Photo download links indexed by ID
268
     */
269 3
    public function getPhotos(Unsplash $unsplash) {
270 3
        $this->notify('Get photo list from unsplash... ');
271
272 3
        if ($this->featured) {
273 1
            $photos = $unsplash->featuredPhotos($this->quantity);
274 3
        } elseif (is_int($this->category)) {
275 1
            $photos = $unsplash->photosInCategory($this->quantity, $this->category);
276 1
        } else {
277 1
            $photos = $unsplash->allPhotos($this->quantity);
278
        }
279 3
        $this->notify('success.'.PHP_EOL, 'info');
280
281 3
        return $photos;
282
    }
283
284
    /**
285
     * Download all photos
286
     * @param string[] $photos Photo download links indexed by ID
287
     * @return boolean True if all downloads are successful
288
     */
289 2
    public function downloadAllPhotos($photos)
290
    {
291 2
        $success = true;
292
293 2
        foreach ($photos as $id => $source) {
294 2
            if ($this->downloadOnePhoto($id, $source) === false) {
295 1
                $success = false;
296 1
            }
297 2
        }
298
299 2
        return $success;
300
    }
301
302
    /**
303
     * Download one photo
304
     * @param  string $id Photo id
305
     * @param  string $source Photo downlaod url
306
     */
307 3
    public function downloadOnePhoto($id, $source)
308
    {
309 3
        $destination = $this->destination.'/'.$id.'.jpg';
310 3
        $this->notify('Download photo from '.$source.' to '.$destination.'... ');
311
312 3
        if ($this->history->has($id)) {
313 1
            $this->notify('ignored (in history).'.PHP_EOL, self::NOTIFY_COMMENT);
314 1
            return true;
315
        }
316
317 2
        $status = $this->copyFile($source, $destination);
318
319 2
        if ($status === false) {
320 1
            $this->notify('failed.'.PHP_EOL, self::NOTIFY_ERROR);
321 1
            return false;
322
        }
323
324 1
        $this->history->put($id);
325
326 1
        $this->notify('success.'.PHP_EOL, self::NOTIFY_INFO);
327 1
        return true;
328
    }
329
330
    /**
331
     * List all categories returned by API
332
     * @param Unsplash $unsplash Proxy to Unsplash API
333
     * @return boolean True on success
334
     */
335 1
    public function listCategories(Unsplash $unsplash)
336
    {
337 1
        $this->notify('Unsplash categories :'.PHP_EOL);
338
339 1
        $categories = $unsplash->allCategories();
340 1
        foreach ($categories as $id => $name) {
341 1
            $this->notify(sprintf("\t%s => %s%s", $id, $name, PHP_EOL));
342 1
        }
343
344 1
        return true;
345
    }
346
347
    /**
348
     * Download file from source to destination
349
     * @param  string $source      URL to download the file from
350
     * @param  string $destination Path to download the file to
351
     * @return bool                True if the copy is successful
352
     * @codeCoverageIgnore
353
     */
354
    public function copyFile($source, $destination) {
355
        return @copy($source, $destination);
356
    }
357
358
}
359