Command::execute()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 16
rs 9.4285
ccs 10
cts 10
cp 1
cc 2
eloc 9
nc 2
nop 2
crap 2
1
<?php namespace Simondubois\UnsplashDownloader;
2
3
use Symfony\Component\Console\Command\Command as SymfonyCommand;
4
use Symfony\Component\Console\Input\InputInterface;
5
use Symfony\Component\Console\Input\InputOption;
6
use Symfony\Component\Console\Output\OutputInterface;
7
8
/**
9
 * A command to check parameters validity and call a download task. Steps are :
10
 *  - check option validity (destination, count, history, featured, categories, category).
11
 *  - create a task (to deal with Unsplash API).
12
 *  - execute the task.
13
 */
14
class Command extends SymfonyCommand
15
{
16
17
    //
18
    // Constants & Attributes
19
    //
20
    const DESCRIPTION_DESTINATION = 'Directory where to download photos.';
21
    const DESCRIPTION_QUANTITY = 'Number of photos to download.';
22
    const DESCRIPTION_HISTORY = 'Filename to use as download history.
23
                When photos are downloaded, their IDs will be stored into the file.
24
                Then any further download is going to ignore photos that have their ID in the history.
25
                Usefull to delete unwanted pictures and prevent the CLI to download them again.';
26
    const DESCRIPTION_FEATURED = 'Download only featured photos (incompatible with --category).';
27
    const DESCRIPTION_CATEGORIES = 'Print out categories and quit (no download).';
28
    const DESCRIPTION_CATEGORY = 'Only download photos for the given category ID (incompatible with the --featured).';
29
    /**
30
     * Output instance.
31
     * Stored to simplify method calls and to be used in callbacks.
32
     * @var OutputInterface
33
     */
34
    public $output;
35
36
37
38
    //
39
    // Helpers
40
    //
41
42
    /**
43
     * Output text only if run with verbose attribute
44
     * @param  string  $message Text to output
45
     * @param  string|null $context Context of the message
46
     * @param  int $type Symfony output type
47
     */
48 2
    public function verboseOutput($message, $context = null, $type = OutputInterface::OUTPUT_NORMAL) {
49 2
        if ($this->output->getVerbosity() < OutputInterface::VERBOSITY_VERBOSE) {
50 1
            return;
51
        }
52
53 2
        if (is_string($context)) {
54 1
            $append = '';
55
56 1
            if (substr($message, -1) === PHP_EOL) {
57 1
                $message = substr($message, 0, -1);
58 1
                $append = PHP_EOL;
59 1
            }
60
61 1
            $message = sprintf('<%s>%s</%s>%s', $context, $message, $context, $append);
62 1
        }
63
64 2
        $this->output->write($message, false, $type);
65 2
    }
66
67
68
69
    /**
70
     * Output text only if run with verbose attribute
71
     * @param  string  $message Text to output
72
     * @param  string|null $context Context of the message
73
     * @param  int $type Symfony output type
74
     */
75 1
    public function output($message, $context = null, $type = OutputInterface::OUTPUT_NORMAL) {
76 1
        if ($this->output->getVerbosity() < OutputInterface::VERBOSITY_NORMAL) {
77 1
            return;
78
        }
79
80 1
        if (is_string($context)) {
81 1
            $append = '';
82
83 1
            if (substr($message, -1) === PHP_EOL) {
84 1
                $message = substr($message, 0, -1);
85 1
                $append = PHP_EOL;
86 1
            }
87
88 1
            $message = sprintf('<%s>%s</%s>%s', $context, $message, $context, $append);
89 1
        }
90
91 1
        $this->output->write($message, false, $type);
92 1
    }
93
94
95
96
    //
97
    // Handle command setup
98
    //
99
100
    /**
101
     * Configure the Symfony command
102
     */
103 6
    protected function configure()
104
    {
105 6
        $this->setName('unsplash-downloader');
106 6
        $this->setDescription('Download unsplash photos');
107 6
        $this->configureOptions();
108 6
    }
109
110
    /**
111
     * Set command options
112
     */
113 6
    private function configureOptions()
114
    {
115 6
        $this->addOption('destination', null, InputOption::VALUE_REQUIRED, self::DESCRIPTION_DESTINATION, getcwd());
116 6
        $this->addOption('quantity', null, InputOption::VALUE_REQUIRED, self::DESCRIPTION_QUANTITY, '10');
117 6
        $this->addOption('history', null, InputOption::VALUE_REQUIRED, self::DESCRIPTION_HISTORY);
118 6
        $this->addOption('featured', null, InputOption::VALUE_NONE, self::DESCRIPTION_FEATURED);
119 6
        $this->addOption('categories', null, InputOption::VALUE_NONE, self::DESCRIPTION_CATEGORIES);
120 6
        $this->addOption('category', null, InputOption::VALUE_REQUIRED, self::DESCRIPTION_CATEGORY);
121 6
    }
122
123
124
125
    //
126
    // Handle command operations
127
    //
128
129
    /**
130
     * Process the download based on provided options
131
     * @param  InputInterface  $input  Command input
132
     * @param  OutputInterface $output Command output
133
     */
134 2
    public function execute(InputInterface $input, OutputInterface $output)
135
    {
136 2
        $this->output = $output;
137
138 2
        $validate = new Validate();
139
140 2
        $task = $this->task();
141
142 2
        if ($input->getOption('categories')) {
143 1
            $task->categories();
144 1
            return;
145
        }
146
147 1
        $this->parameters($validate, $task, $input->getOptions());
148 1
        $task->download();
149 1
    }
150
151
    /**
152
     * Instantiate a new task
153
     * @return Task Task instance
154
     */
155 1
    public function task() {
156 1
        $task = new Task();
157 1
        $task->setNotificationCallback([$this, 'output']);
158
159 1
        return $task;
160
    }
161
162
    /**
163
     * Check & validate the parameters
164
     * @param  Validate $validate Validate instance
165
     * @param  Task $task Download task
166
     * @param  array $options Command options
167
     */
168 1
    public function parameters(Validate $validate, Task $task, $options)
169
    {
170 1
        $this->destinationParameter($validate, $task, $options['destination']);
171 1
        $this->quantityParameter($validate, $task, $options['quantity']);
172 1
        $this->historyParameter($validate, $task, $options['history']);
173 1
        $this->featuredParameter($task, $options['featured']);
174 1
        $this->categoryParameter($validate, $task, $options['category']);
175 1
    }
176
177
    /**
178
     * Check & validate the destination parameter
179
     * @param  Validate $validate Validate instance
180
     * @param  Task $task Download task
181
     * @param  string $option Option value
182
     */
183 1
    public function destinationParameter(Validate $validate, Task $task, $option)
184
    {
185 1
        $destination = $validate->destination($option);
186
187 1
        $task->setDestination($destination);
188
189 1
        $this->verboseOutput('Download photos to '.$destination.'.'.PHP_EOL);
190 1
    }
191
192
    /**
193
     * Check & validate the quantity parameter
194
     * @param  Validate $validate Validate instance
195
     * @param  Task $task Download task
196
     * @param  string $option Option value
197
     */
198 1
    public function quantityParameter(Validate $validate, Task $task, $option)
199
    {
200 1
        $quantity = $validate->quantity($option);
201
202 1
        $task->setQuantity($quantity);
203
204 1
        $this->verboseOutput('Download the last '.$quantity.' photos.'.PHP_EOL);
205 1
    }
206
207
    /**
208
     * Check & validate the history parameter
209
     * @param  Validate $validate Validate instance
210
     * @param  Task $task Download task
211
     * @param  string $option Option value
212
     */
213 1
    public function historyParameter(Validate $validate, Task $task, $option)
214
    {
215 1
        $history = $validate->history($option);
216
217 1
        $task->setHistory($history);
218
219 1
        if (is_null($history)) {
220 1
            $this->verboseOutput('Do not use history.'.PHP_EOL);
221 1
            return;
222
        }
223
224 1
        $this->verboseOutput('Use '.$history.' as history.'.PHP_EOL);
225 1
    }
226
227
    /**
228
     * Check & validate the featured parameter
229
     * @param  Task $task Download task
230
     * @param  bool $option Option value
231
     */
232 1
    public function featuredParameter(Task $task, $option)
233
    {
234 1
        $task->setFeatured($option);
235
236 1
        if ($option === true) {
237 1
            $this->verboseOutput('Download only featured photos.');
238 1
        }
239
240 1
        $this->verboseOutput('Download featured and not featured photos.');
241 1
    }
242
243
    /**
244
     * Check & validate the category parameter
245
     * @param  Validate $validate Validate instance
246
     * @param  Task $task Download task
247
     * @param  string $option Option value
248
     */
249 1
    public function categoryParameter(Validate $validate, Task $task, $option)
250
    {
251 1
        $category = $validate->category($option);
252
253 1
        $task->setCategory($category);
254
255 1
        if (is_int($category) && $task->getFeatured() !== true) {
256 1
            $this->verboseOutput('Download only photos for category ID '.$option.'.'.PHP_EOL);
257 1
        }
258 1
    }
259
260
}
261