FeedInspectCommand   A
last analyzed

Complexity

Total Complexity 22

Size/Duplication

Total Lines 176
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 10

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 22
lcom 2
cbo 10
dl 0
loc 176
ccs 0
cts 79
cp 0
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A execute() 0 13 1
A getFeed() 0 8 1
A configure() 0 10 1
A interact() 0 10 2
B inspect() 0 22 6
B report() 0 55 8
A arrayToString() 0 12 3
1
<?php
2
3
namespace TreeHouse\IoBundle\Command;
4
5
use Symfony\Component\Console\Command\Command;
6
use Symfony\Component\Console\Helper\QuestionHelper;
7
use Symfony\Component\Console\Input\InputArgument;
8
use Symfony\Component\Console\Input\InputInterface;
9
use Symfony\Component\Console\Input\InputOption;
10
use Symfony\Component\Console\Output\OutputInterface;
11
use Symfony\Component\Console\Question\Question;
12
use TreeHouse\Feeder\Feed;
13
use TreeHouse\Feeder\Reader\XmlReader;
14
use TreeHouse\Feeder\Resource\FileResource;
15
use TreeHouse\IoBundle\Import\Feed\TransportFactory;
16
17
class FeedInspectCommand extends Command
18
{
19
    /**
20
     * @var array
21
     */
22
    protected $data = [];
23
24
    /**
25
     * @var array
26
     */
27
    protected $values = [];
28
29
    /**
30
     * @inheritdoc
31
     */
32
    protected function configure()
33
    {
34
        $this
35
            ->setName('io:feed:inspect')
36
            ->addArgument('url', InputArgument::REQUIRED, 'The url of the feed to inspect.')
37
            ->addOption('node', null, InputOption::VALUE_REQUIRED, 'The item node name.')
38
            ->addOption('limit', null, InputOption::VALUE_OPTIONAL, 'Number of distinct values per key to display', 20)
39
            ->setDescription('Inspects a feed and displays information about it')
40
        ;
41
    }
42
43
    /**
44
     * @inheritdoc
45
     */
46
    protected function interact(InputInterface $input, OutputInterface $output)
47
    {
48
        if (!$input->getOption('node')) {
49
            $helper = new QuestionHelper();
50
            $question = new Question('Enter the name of the node that contains a property in this feed: ');
51
52
            $node = $helper->ask($input, $output, $question);
53
            $input->setOption('node', $node);
54
        }
55
    }
56
57
    /**
58
     * @inheritdoc
59
     */
60
    protected function execute(InputInterface $input, OutputInterface $output)
61
    {
62
        $url = $input->getArgument('url');
63
        $node = $input->getOption('node');
64
        $limit = $input->getOption('limit');
65
66
        $feed = $this->getFeed($url, $node);
0 ignored issues
show
Bug introduced by
It seems like $url defined by $input->getArgument('url') on line 62 can also be of type array<integer,string> or null; however, TreeHouse\IoBundle\Comma...spectCommand::getFeed() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
67
68
        $this->inspect($feed);
69
        $this->report($output, $limit);
70
71
        return 0;
72
    }
73
74
    /**
75
     * @param string $url
76
     * @param string $node
77
     *
78
     * @return Feed
79
     */
80
    protected function getFeed($url, $node)
81
    {
82
        $transport = TransportFactory::createTransportFromUrl($url);
83
        $reader = new XmlReader(new FileResource($transport));
84
        $reader->setNodeCallback($node);
85
86
        return new Feed($reader);
87
    }
88
89
    /**
90
     * @param Feed $feed
91
     */
92
    protected function inspect(Feed $feed)
93
    {
94
        while ($item = $feed->getNextItem()) {
95
            foreach ($item->all() as $key => $value) {
96
                if (!array_key_exists($key, $this->data)) {
97
                    $this->data[$key] = [];
98
                }
99
100
                $hash = md5(serialize($value));
101
102
                if (!array_key_exists($hash, $this->data[$key])) {
103
                    $this->data[$key][$hash] = 0;
104
                }
105
106
                ++$this->data[$key][$hash];
107
108
                if (!array_key_exists($hash, $this->values)) {
109
                    $this->values[$hash] = $value;
110
                }
111
            }
112
        }
113
    }
114
115
    /**
116
     * @param OutputInterface $output
117
     * @param int             $limit
118
     */
119
    protected function report(OutputInterface $output, $limit)
120
    {
121
        $output->writeln('Report for feed:');
122
        $output->writeln('');
123
124
        $valueLength = 50;
125
126
        foreach ($this->data as $key => $hashes) {
127
            $output->writeln(sprintf('Statistics for node <info>%s</info>:', $key));
128
            $output->writeln('');
129
130
            arsort($hashes, SORT_NUMERIC);
131
132
            $output->writeln(sprintf('%s | %s', str_pad('Value', $valueLength, ' ', STR_PAD_RIGHT), 'Count'));
133
            $output->writeln(sprintf('%s+%s', str_pad('', $valueLength + 1, '-'), str_pad('', 15, '-')));
134
135
            $counter = 0;
136
            $notShown = 0;
137
138
            foreach ($hashes as $hash => $count) {
139
                if ($counter > $limit) {
140
                    ++$notShown;
141
                    continue;
142
                }
143
144
                $value = $this->arrayToString($this->values[$hash]);
145
                $lines = explode("\n", wordwrap($value, $valueLength, "\n", true));
146
147
                $firstLine = array_shift($lines);
148
                $output->writeln(sprintf('%s | %s', str_pad($firstLine, $valueLength, ' ', STR_PAD_RIGHT), $count));
149
150
                $numLines = count($lines);
151
                $lineLimit = 2;
152
153
                foreach (array_slice($lines, 0, 2) as $n => $line) {
154
                    $ellipses = '';
155
                    if ($lineLimit - 1 === $n) {
156
                        $ellipses = $numLines > 2 ? ' (...)' : '';
157
                        $line = substr($line, 0, -5);
158
                    }
159
160
                    $output->writeln($line . $ellipses);
161
                }
162
163
                ++$counter;
164
            }
165
166
            if ($notShown > 0) {
167
                $output->writeln(sprintf('And <info>%d</info> more...', $notShown));
168
            }
169
170
            $output->writeln('');
171
            $output->writeln('');
172
        }
173
    }
174
175
    /**
176
     * @param mixed $value
177
     *
178
     * @return string
179
     */
180
    protected function arrayToString($value)
181
    {
182
        if (!is_array($value)) {
183
            return $value;
184
        }
185
186
        foreach ($value as &$subvalue) {
187
            $subvalue = $this->arrayToString($subvalue);
188
        }
189
190
        return implode(', ', $value);
191
    }
192
}
193