Passed
Pull Request — master (#11)
by Simon
01:34
created

SlackStatusController::getClient()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Firesphere\StripeSlack\Controller;
4
5
use Firesphere\StripeSlack\Model\SlackUserCount;
6
use GuzzleHttp\Client;
7
use SilverStripe\Control\Controller;
8
use SilverStripe\Control\HTTPResponse;
9
use SilverStripe\Core\Convert;
10
use SilverStripe\ORM\FieldType\DBDatetime;
11
use SilverStripe\ORM\ValidationException;
12
use SilverStripe\SiteConfig\SiteConfig;
13
14
/**
15
 * Class SlackStatusController
16
 *
17
 */
18
class SlackStatusController extends Controller
19
{
20
    private static $allowed_actions = [
0 ignored issues
show
introduced by
The private property $allowed_actions is not used, and could be removed.
Loading history...
21
        'usercount',
22
        'badge'
23
    ];
24
25
    /**
26
     * @return int
27
     * @throws ValidationException
28
     */
29
    public function usercount()
30
    {
31
        /** @var SiteConfig $config */
32
        $config = SiteConfig::current_site_config();
33
        // Break if there is a configuration error
34
        if (!$config->SlackURL || !$config->SlackToken || !$config->SlackChannel) {
35
            return '';
0 ignored issues
show
Bug Best Practice introduced by
The expression return '' returns the type string which is incompatible with the documented return type integer.
Loading history...
36
        }
37
38
        return $this->getStatus($config);
39
    }
40
41
    protected function getRequestParams($config)
42
    {
43
        return [
44
            'form_params' => [
45
                'token'   => $config->SlackToken,
46
                'type'    => 'post',
47
                'channel' => $config->SlackChannel,
48
                'scope'   => 'identify,read,post,client',
49
            ]
50
        ];
51
    }
52
53
    /**
54
     * @param SiteConfig $config
55
     * @return int
56
     * @throws ValidationException
57
     */
58
    public function getStatus($config)
59
    {
60
        /** @var SlackUserCount $count */
61
        $count = SlackUserCount::get()->first();
62
        // To limit the amount of API requests, only update the count
63
        // once every 3 hours
64
        if ($count) {
65
            $dateTime = DBDatetime::create();
66
            $dateTime->setValue($count->LastEdited);
67
            $diff = explode(' ', $dateTime->TimeDiffIn('hours'));
68
            if ($diff[0] < 3) {
69
                return $count->UserCount;
70
            }
71
        } else {
72
            $count = SlackUserCount::create();
73
        }
74
75
        return $this->getSlackCount($config, $count);
76
    }
77
78
    /**
79
     * @param SiteConfig $config
80
     * @param SlackUserCount $count
81
     * @return int
82
     * @throws ValidationException
83
     */
84
    protected function getSlackCount($config, $count)
85
    {
86
        $service = $this->getClient($config);
87
        $params = $this->getRequestParams($config);
88
        $url = 'api/channels.info?t=' . time();
89
90
        $response = $service->request('POST', $url, $params);
91
        $result = Convert::json2array($response->getBody());
92
93
        return $this->validateResponse($count, $result);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of Firesphere\StripeSlack\C...ler::validateResponse() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

93
        return $this->validateResponse($count, /** @scrutinizer ignore-type */ $result);
Loading history...
94
    }
95
96
    /**
97
     * @param $config
98
     * @return Client
99
     */
100
    public function getClient($config)
101
    {
102
        $baseURL = $config->SlackURL;
103
        $baseURL = (substr($baseURL, -1) === '/') ? $baseURL : $baseURL . '/';
104
105
        return new Client(['base_uri' => $baseURL]);
106
    }
107
108
    /**
109
     * @param SlackUserCount $count
110
     * @param array $result
111
     * @return int
112
     */
113
    public function validateResponse($count, $result)
114
    {
115
        if (isset($result['ok']) && $result['ok']) {
116
            $userCount = count($result['channel']['members']);
117
            $count->UserCount = $userCount;
118
            $count->write();
119
120
            return $userCount;
121
        }
122
123
        return 0;
124
    }
125
126
    /**
127
     * @return HTTPResponse
128
     * @throws ValidationException
129
     */
130
    public function badge()
131
    {
132
        $config = SiteConfig::current_site_config();
133
        $count = $this->getStatus($config);
134
        list($width, $pos) = $this->getSVGSettings($count);
135
136
        $body = $this->renderWith('SVGTemplate', ['Count' => $count, 'Width' => $width, 'Pos' => $pos]);
137
        $response = new HTTPResponse($body);
138
        $response->addHeader('Content-Type', 'image/svg+xml');
139
140
        return $response;
141
    }
142
143
    /**
144
     * @param $count
145
     * @return array
146
     */
147
    public function getSVGSettings($count)
148
    {
149
        if ($count < 100) {
150
            $width = 25;
151
            $pos = 60;
152
        } elseif ($count < 1000) {
153
            $width = 35;
154
            $pos = 65;
155
        } else {
156
            $width = 45;
157
            $pos = 70;
158
        }
159
160
        return [$width, $pos];
161
    }
162
}
163