Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
100.00% |
1 / 1 |
|
100.00% |
9 / 9 |
CRAP | |
100.00% |
71 / 71 |
StatusesHomeTimelineCommand | |
100.00% |
1 / 1 |
|
100.00% |
9 / 9 |
15 | |
100.00% |
71 / 71 |
configure | |
100.00% |
1 / 1 |
1 | |
100.00% |
9 / 9 |
|||
execute | |
100.00% |
1 / 1 |
3 | |
100.00% |
11 / 11 |
|||
setAndDisplayLastTweet | |
100.00% |
1 / 1 |
2 | |
100.00% |
9 / 9 |
|||
getContent | |
100.00% |
1 / 1 |
1 | |
100.00% |
8 / 8 |
|||
displayContentNotArrayError | |
100.00% |
1 / 1 |
1 | |
100.00% |
6 / 6 |
|||
addAndDisplayTweets | |
100.00% |
1 / 1 |
2 | |
100.00% |
10 / 10 |
|||
setProgressBar | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
setTable | |
100.00% |
1 / 1 |
2 | |
100.00% |
6 / 6 |
|||
iterateTweets | |
100.00% |
1 / 1 |
2 | |
100.00% |
8 / 8 |
1 | <?php |
2 | |
3 | namespace AlexisLefebvre\Bundle\AsyncTweetsBundle\Command; |
4 | |
5 | use Abraham\TwitterOAuth\TwitterOAuth; |
6 | use AlexisLefebvre\Bundle\AsyncTweetsBundle\Entity\Tweet; |
7 | use AlexisLefebvre\Bundle\AsyncTweetsBundle\Entity\TweetRepository; |
8 | use AlexisLefebvre\Bundle\AsyncTweetsBundle\Utils\PersistTweet; |
9 | use Symfony\Component\Console\Helper\ProgressBar; |
10 | use Symfony\Component\Console\Helper\Table; |
11 | use Symfony\Component\Console\Input\InputInterface; |
12 | use Symfony\Component\Console\Input\InputOption; |
13 | use Symfony\Component\Console\Output\OutputInterface; |
14 | |
15 | class StatusesHomeTimelineCommand extends BaseCommand |
16 | { |
17 | /** @var bool */ |
18 | private $displayTable; |
19 | /** @var Table */ |
20 | private $table; |
21 | /** @var ProgressBar */ |
22 | private $progress; |
23 | |
24 | /** |
25 | * @var array<bool|int> |
26 | * |
27 | * @see https://dev.twitter.com/rest/reference/get/statuses/home_timeline |
28 | */ |
29 | private $parameters = [ |
30 | 'count' => 200, |
31 | 'exclude_replies' => true, |
32 | ]; |
33 | |
34 | protected function configure(): void |
35 | { |
36 | parent::configure(); |
37 | |
38 | $this |
39 | ->setName('statuses:hometimeline') |
40 | ->setDescription('Fetch home timeline') |
41 | // http://symfony.com/doc/2.3/cookbook/console/console_command.html#automatically-registering-commands |
42 | ->addOption( |
43 | 'table', |
44 | null, |
45 | InputOption::VALUE_NONE, |
46 | 'Display a table with tweets' |
47 | ); |
48 | } |
49 | |
50 | protected function execute(InputInterface $input, OutputInterface $output): int |
51 | { |
52 | $this->setAndDisplayLastTweet($output); |
53 | |
54 | $content = $this->getContent($input); |
55 | |
56 | if (!is_array($content)) { |
57 | $this->displayContentNotArrayError($output, $content); |
58 | |
59 | return 1; |
60 | } |
61 | |
62 | $numberOfTweets = count($content); |
63 | |
64 | if ($numberOfTweets == 0) { |
65 | $output->writeln('<comment>No new tweet.</comment>'); |
66 | |
67 | return 0; |
68 | } |
69 | |
70 | $this->addAndDisplayTweets($input, $output, $content, $numberOfTweets); |
71 | |
72 | return 0; |
73 | } |
74 | |
75 | protected function setAndDisplayLastTweet(OutputInterface $output): void |
76 | { |
77 | /** @var TweetRepository $tweetRepository */ |
78 | $tweetRepository = $this->em |
79 | ->getRepository(Tweet::class); |
80 | |
81 | // Get the last tweet |
82 | $lastTweet = $tweetRepository->getLastTweet(); |
83 | |
84 | // And use it in the request if it exists |
85 | if ($lastTweet) { |
86 | $this->parameters['since_id'] = $lastTweet->getId(); |
87 | |
88 | $comment = 'last tweet = '.$this->parameters['since_id']; |
89 | } else { |
90 | $comment = 'no last tweet'; |
91 | } |
92 | |
93 | $output->writeln('<comment>'.$comment.'</comment>'); |
94 | } |
95 | |
96 | /** |
97 | * @return array<\stdClass>|object |
98 | */ |
99 | protected function getContent(InputInterface $input) |
100 | { |
101 | $connection = new TwitterOAuth( |
102 | (string) $this->container->getParameter('twitter_consumer_key'), |
103 | (string) $this->container->getParameter('twitter_consumer_secret'), |
104 | (string) $this->container->getParameter('twitter_token'), |
105 | (string) $this->container->getParameter('twitter_token_secret') |
106 | ); |
107 | |
108 | return $connection->get( |
109 | 'statuses/home_timeline', |
110 | $this->parameters |
111 | ); |
112 | } |
113 | |
114 | /** |
115 | * @param array<string>|object $content |
116 | */ |
117 | protected function displayContentNotArrayError( |
118 | OutputInterface $output, |
119 | $content |
120 | ): void { |
121 | $formatter = $this->getHelper('formatter'); |
122 | |
123 | $errorMessages = ['Error!', 'Something went wrong, $content is not an array.']; |
124 | $formattedBlock = $formatter->formatBlock($errorMessages, 'error'); |
125 | $output->writeln($formattedBlock); |
126 | $output->writeln(print_r($content, true)); |
127 | } |
128 | |
129 | /** |
130 | * @param array<\stdClass> $content |
131 | */ |
132 | protected function addAndDisplayTweets( |
133 | InputInterface $input, |
134 | OutputInterface $output, |
135 | array $content, |
136 | int $numberOfTweets |
137 | ): void { |
138 | $output->writeln('<comment>Number of tweets: '.$numberOfTweets.'</comment>'); |
139 | |
140 | // Iterate through $content in order to add the oldest tweet first, |
141 | // if there is an error the oldest tweet will still be saved |
142 | // and newer tweets can be saved next time the command is launched |
143 | $tweets = array_reverse($content); |
144 | |
145 | $this->setProgressBar($output, $numberOfTweets); |
146 | $this->setTable($input, $output); |
147 | $this->iterateTweets($tweets); |
148 | |
149 | $this->progress->finish(); |
150 | $output->writeln(''); |
151 | |
152 | if ($this->displayTable) { |
153 | $this->table->render(); |
154 | } |
155 | } |
156 | |
157 | protected function setProgressBar( |
158 | OutputInterface $output, |
159 | int $numberOfTweets |
160 | ): void { |
161 | $this->progress = new ProgressBar($output, $numberOfTweets); |
162 | $this->progress->setBarCharacter('<comment>=</comment>'); |
163 | $this->progress->start(); |
164 | } |
165 | |
166 | protected function setTable( |
167 | InputInterface $input, |
168 | OutputInterface $output |
169 | ): void { |
170 | $this->displayTable = (bool) $input->getOption('table'); |
171 | |
172 | // Display |
173 | if ($this->displayTable) { |
174 | $this->table = new Table($output); |
175 | $this->table |
176 | ->setHeaders(['Datetime', 'Text excerpt', 'Name']); |
177 | } |
178 | } |
179 | |
180 | /** |
181 | * @param array<\stdClass> $tweets |
182 | */ |
183 | protected function iterateTweets(array $tweets): void |
184 | { |
185 | $persistTweet = new PersistTweet( |
186 | $this->em, |
187 | $this->displayTable, |
188 | $this->table |
189 | ); |
190 | |
191 | foreach ($tweets as $tweetTmp) { |
192 | $persistTweet->addTweet($tweetTmp, true); |
193 | |
194 | $this->progress->advance(); |
195 | } |
196 | } |
197 | } |