WikiCommand::execute()   B
last analyzed

Complexity

Conditions 5
Paths 5

Size

Total Lines 32
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 32
ccs 0
cts 18
cp 0
rs 8.439
c 0
b 0
f 0
cc 5
eloc 18
nc 5
nop 2
crap 30
1
<?php declare(strict_types=1);
2
3
namespace Bigwhoop\Trumpet\Commands;
4
5
use Bigwhoop\SentenceBreaker\SentenceBreaker;
6
7
final class WikiCommand implements Command
8
{
9
    const ENDPOINT = 'https://en.wikipedia.org/w/api.php';
10
11
    /** @var CommandExecutionContext */
12
    private $executionContext;
13
    
14
    /** @var SentenceBreaker */
15
    private $sentenceBreaker;
16
17 1
    public function __construct(CommandExecutionContext $context, SentenceBreaker $sentenceBreaker)
18
    {
19 1
        $this->executionContext = $context;
20 1
        $this->sentenceBreaker  = $sentenceBreaker;
21 1
    }
22
23 1
    public function getToken(): string
24
    {
25 1
        return 'wiki';
26
    }
27
    
28
    public function execute(CommandParams $params, CommandExecutionContext $executionContext): string
29
    {
30
        $article = $params->getFirstArgument();
31
        $numSentences = (int) $params->getSecondArgument(0);
32
33
        $cacheFile = $this->getCacheFilePath($article);
34
        if (is_readable($cacheFile)) {
35
            $summary = file_get_contents($cacheFile);
36
37
            return $this->quote($summary, $numSentences);
38
        }
39
40
        $url = $this->buildURL($article);
41
        $response = file_get_contents($url);
42
43
        $data = json_decode($response);
44
        if (!$data) {
45
            throw new ExecutionFailedException('Wikipedia API response could not be decoded. Request URL: '.$url.'. Response: '.var_export($response, true));
46
        }
47
48
        foreach ($data->query->pages as $page) {
49
            if (isset($page->missing)) {
50
                continue;
51
            }
52
53
            file_put_contents($cacheFile, $page->extract);
54
55
            return $this->quote($page->extract, $numSentences);
56
        }
57
58
        throw new ExecutionFailedException("Failed to query for Wikipedia article '$article'. Request URL: $url");
59
    }
60
    
61
    private function getCacheFilePath(string $article): string
62
    {
63
        $tmpDir = $this->executionContext->ensureTempDirectory();
64
        
65
        return $tmpDir.'/summary-'.md5($article).'.txt';
66
    }
67
    
68
    private function quote(string $text, int $numSentences): string
69
    {
70
        if ($numSentences > 0) {
71
            $sentences = $this->sentenceBreaker->split($text);
72
            $text = join(' ', array_slice($sentences, 0, $numSentences));
73
        }
74
75
        return "> $text";
76
    }
77
    
78
    private function buildURL(string $article): string
79
    {
80
        $params = [
81
            'format'      => 'json',
82
            'action'      => 'query',
83
            'prop'        => 'extracts',
84
            'exintro'     => '',
85
            'explaintext' => '',
86
            'titles'      => $article,
87
        ];
88
89
        return self::ENDPOINT.'?'.http_build_query($params, null, '&', PHP_QUERY_RFC3986);
90
    }
91
}
92