Task::getCategory()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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