Completed
Push — master ( 3c34e6...717c8b )
by Pascal
11:46
created

SetInfos::output()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 16
ccs 0
cts 11
cp 0
rs 9.4286
cc 3
eloc 9
nc 4
nop 3
crap 12
1
<?php namespace MtGTutor\Console\Commands;
2
3
use Goutte\Client;
4
use Symfony\Component\Console\Command\Command;
5
use Symfony\Component\Console\Helper\Table;
6
use Symfony\Component\Console\Input\InputArgument;
7
use Symfony\Component\Console\Input\InputInterface;
8
use Symfony\Component\Console\Input\InputOption;
9
use Symfony\Component\Console\Output\OutputInterface;
10
use Symfony\Component\DomCrawler\Crawler;
11
12
/**
13
 * Class SetInfos
14
 * @package MtGTutor\Console\Commands
15
 */
16
class SetInfos extends Command
17
{
18
    /**
19
     * @var string
20
     */
21
    protected $url = 'http://magic.wizards.com/en/game-info/products/card-set-archive';
22
23
    /**
24
     * @var string
25
     */
26
    protected $imagePath = 'http://magic.wizards.com/sites/mtg/files/';
27
28
    /**
29
     * Configure command
30
     */
31 12
    protected function configure()
32
    {
33 12
        $this->setName('set:info')
34 12
            ->addArgument('set', InputArgument::REQUIRED, 'Which set do you want to select. Use the official three-letter code.')
35 12
            ->addOption('full-path', null, InputOption::VALUE_NONE, 'Add the full path to the images')
36 12
            ->addOption('date-format', null, InputOption::VALUE_OPTIONAL, 'Date Format', 'Y-m-d')
37 12
            ->addOption('json', null, InputOption::VALUE_NONE, 'Output result as json')
38 12
            ->setDescription('Get some basic information about a specific set')
39 12
            ->setHelp(
40
                <<<EOT
41
Gets the following information about a set:
42
 * Official Three-Letter Code
43
 * Set Name
44
 * Block
45
 * Number of Cards
46
 * Release Date
47
 * Logo
48
 * Icon
49
50
Usage:
51
Default usage to get a set (here Alara Reborn)
52
<info>mtgtutor-console set:info ARB</info>
53
54
You can specify a date format via the --date-format option
55
<info>mtgtutor-console set:info ARB --date-format=d.m.Y</info>
56
57
You can change the output format to json with the --json option
58
<info>mtgtutor-console set:info ARB --json</info>
59
60
You can add the full path to the files with --full-path
61
<info>mtgtutor-console set:info ARB --full-path</info>
62
63
You can combine all these options
64
<info>mtgtutor-console set:info ARB --date-format=d.m.Y --json --full-path</info>
65
EOT
66 12
            );
67 12
    }
68
69
    /**
70
     * Get set infos
71
     * @throws \InvalidArgumentException if no set is found
72
     * @param \Symfony\Component\Console\Input\InputInterface   $input
73
     * @param \Symfony\Component\Console\Output\OutputInterface $output
74
     * @return void
75
     */
76
    protected function execute(InputInterface $input, OutputInterface $output)
77
    {
78
        // init vars
79
        $exists = false;
80
        $data = [
81
            'code' => $input->getArgument('set'),
82
            'name' => null,
83
            'block' => null,
84
            'number' => null,
85
            'date' => null,
86
            'logo' => null,
87
            'icon' => null,
88
        ];
89
90
        // Fetch WotC website
91
        $client = new Client();
92
        $crawler = $client->request('GET', $this->url);
93
94
        $crawler->filter('.card-set-archive-table > ul > li > a > span.logo > img')->each(function (Crawler $node) use (&$client, &$data, &$exists) {
95
            $logo = $node->attr('src');
96
97
            if(strpos(strtolower($logo), strtolower($data['code'])) !== false) {
98
                // Set exists
99
                $exists = true;
100
101
                // Get Logo + Icon + Name
102
                $siblings = $node->parents()->first()->siblings();
103
104
                $data['logo'] = str_replace($this->imagePath, '', $logo);
105
                $data['icon'] = str_replace($this->imagePath, '', $siblings->eq(0)->children()->attr('src'));
106
                $data['name'] = trim($siblings->eq(1)->text());
107
108
                // Go to details page
109
                $link = $node->parents()->parents()->link();
110
                $crawler = $client->click($link);
111
112
                // Go to to info page (if exists)
113
                $anchor = $crawler->selectLink('Info');
114
                if ($anchor->count()) {
115
                    $link = $anchor->link();
116
                    $crawler = $client->click($link);
117
                }
118
119
                // Fetch block, number of cards and release date
120
                $crawler->filter('.tab-content.current > p')->each(function (Crawler $node, $i) use (&$data) {
121
                    if ($i % 2) {
122
                        // Get block and number of cards
123
                        if ($i == 1) {
124
                            preg_match('~<strong>Block:<\\/strong>.*<em>(.+?)</~m', $node->html(), $block);
125
                            preg_match('~<strong>Number of Cards:\s*<\/strong>[^\d]*(\d+)<?~m', $node->html(), $number);
126
127
                            $data['block'] = $block[1];
128
                            $data['number'] = (int)$number[1];
129
                        }
130
131
                        // get release date
132
                        if ($i == 5) {
133
                            preg_match('~<strong>Release Date:<\/strong>.+?([\w|,|\s]+)<~im', $node->html(), $release);
134
                            $data['date'] = $release[1];
135
                        }
136
                    }
137
                });
138
            }
139
        });
140
141
        // Could not find set
142
        if (!$exists) {
143
            throw new \InvalidArgumentException('Could not find set with the following code: ' . $data['code']);
144
        }
145
146
        // Format result
147
        $data = $this->formatResult($data, $input);
148
149
        // Ouput result
150
        $this->output($data, $input, $output);
151
    }
152
153
    /**
154
     * Format result
155
     * @param array                                           $data
156
     * @param \Symfony\Component\Console\Input\InputInterface $input
157
     * @return array
158
     */
159
    protected function formatResult(array $data, InputInterface $input)
160
    {
161
        // change date format
162
        $date = new \DateTime(date('Y-m-d H:i:s', strtotime($data['date'])));
163
        $data['date'] = $date->format($input->getOption('date-format'));
164
165
        // add full path to url
166
        if ($input->getOption('full-path')) {
167
            $data['logo'] = $this->imagePath . $data['logo'];
168
            $data['icon'] = $this->imagePath . $data['icon'];
169
        }
170
171
        return $data;
172
    }
173
174
    /**
175
     * Write result to console
176
     * @param array                                             $data
177
     * @param \Symfony\Component\Console\Input\InputInterface   $input
178
     * @param \Symfony\Component\Console\Output\OutputInterface $output
179
     */
180
    protected function output(array $data, InputInterface $input, OutputInterface $output)
181
    {
182
        // json output
183
        if ($input->getOption('json')) {
184
            $output->writeln(json_encode($data, JSON_PRETTY_PRINT));
185
        }
186
187
        // table output
188
        if (!$input->getOption('json')) {
189
            $table = new Table($output);
190
            $table
191
                ->setHeaders(['Code', 'Name', 'Block', 'Number', 'Release Date', 'Logo', 'Icon'])
192
                ->setRows([$data]);
193
            $table->render();
194
        }
195
    }
196
}
197