BeerCommand   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 174
Duplicated Lines 6.9 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 98.61%

Importance

Changes 0
Metric Value
wmc 15
lcom 1
cbo 4
dl 12
loc 174
ccs 71
cts 72
cp 0.9861
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 12 12 1
A processAll() 0 4 1
A processTop10() 0 10 2
A processStats() 0 12 3
A processFor() 0 19 3
A checkSpendingOfLastBeer() 0 15 2
A getBeerCountByUsername() 0 11 1
A getBeerCountAll() 0 9 1
A getBeerTop10() 0 12 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * T3Bot.
4
 *
5
 * @author Frank Nägler <[email protected]>
6
 *
7
 * @link http://www.t3bot.de
8
 * @link http://wiki.typo3.org/T3Bot
9
 */
10
namespace T3Bot\Commands;
11
12
use Slack\Payload;
13
use Slack\RealTimeClient;
14
15
/**
16
 * Class BeerCommand.
17
 *
18
 * @property string commandName
19
 * @property array helpCommands
20
 */
21
class BeerCommand extends AbstractCommand
22
{
23
    /**
24
     * AbstractCommand constructor.
25
     *
26
     * @param Payload $payload
27
     * @param RealTimeClient $client
28
     * @param array|null $configuration
29
     */
30 8 View Code Duplication
    public function __construct(Payload $payload, RealTimeClient $client, array $configuration = null)
31
    {
32 8
        $this->commandName = 'beer';
33 8
        $this->helpCommands = [
34
            'help' => 'shows this help',
35
            'stats [username]' => 'show beer counter for [username]',
36
            'for [username]' => 'give [username] a T3Beer',
37
            'all' => 'show all beer counter',
38
            'top10' => 'show TOP 10',
39
        ];
40 8
        parent::__construct($payload, $client, $configuration);
41 8
    }
42
43
    /**
44
     * stats for all beer counter.
45
     *
46
     * @return string
47
     *
48
     * @throws \Doctrine\DBAL\DBALException
49
     */
50 1
    protected function processAll() : string
51
    {
52 1
        return 'Yeah, ' . $this->getBeerCountAll() . ' :t3beer: spend to all people';
53
    }
54
55
    /**
56
     * stats for TOP 10.
57
     *
58
     * @return string
59
     *
60
     * @throws \Doctrine\DBAL\DBALException
61
     */
62 1
    protected function processTop10() : string
63
    {
64 1
        $rows = $this->getBeerTop10();
65 1
        $text = ['*Yeah, here are the TOP 10*'];
66 1
        foreach ($rows as $row) {
67
            $text[] = '<@' . $row['username'] . '> has received ' . $row['cnt'] . ' :t3beer:';
68
        }
69
70 1
        return implode(chr(10), $text);
71
    }
72
73
    /**
74
     * stats for beer counter.
75
     *
76
     * @return string
77
     *
78
     * @throws \Doctrine\DBAL\DBALException
79
     */
80 2
    protected function processStats() : string
81
    {
82 2
        $params = $this->params;
83 2
        array_shift($params);
84 2
        $username = trim($params[0]);
85 2
        if (strpos($username, '<') === 0 && $username[1] === '@') {
86 1
            $username = str_replace(['<', '>', '@'], '', $username);
87
88 1
            return '<@' . $username . '> has received ' . $this->getBeerCountByUsername($username) . ' :t3beer: so far';
89
        }
90 1
        return '*Sorry, a username must start with a @-sign:*';
91
    }
92
93
    /**
94
     * give someone a beer.
95
     *
96
     * @return string
97
     *
98
     * @throws \Doctrine\DBAL\DBALException
99
     */
100 3
    protected function processFor() : string
101
    {
102 3
        $from_user = $this->payload->getData()['user'];
103 3
        $username = trim($this->params[1]);
104 3
        if (strpos($username, '<@') === 0) {
105 2
            $username = str_replace(['<', '>', '@'], '', $username);
106 2
            if ($this->checkSpendingOfLastBeer($username, $from_user)) {
107 2
                $this->getDatabaseConnection()->insert('beers', [
108 2
                    'to_user' => $username,
109 2
                    'from_user' => $from_user,
110 2
                    'tstamp' => time()
111
                ]);
112 2
                return 'Yeah, one more :t3beer: for <@' . $username . '>' . chr(10) . '<@' . $username . '> has received '
113 2
                    . $this->getBeerCountByUsername($username) . ' :t3beer: so far';
114
            }
115 1
            return 'You spend one :t3beer: to <@' . $username . '> within in last 24 hours. Too much beer is unhealthy ;)';
116
        }
117 1
        return '*Sorry, a username must start with a @-sign:*';
118
    }
119
120
    /**
121
     * @param string $username
122
     * @param string $from_user
123
     *
124
     * @return bool
125
     * @throws \Doctrine\DBAL\DBALException
126
     */
127 2
    protected function checkSpendingOfLastBeer(string $username, string $from_user) : bool
128
    {
129 2
        $queryBuilder = $this->getDatabaseConnection()
130 2
            ->createQueryBuilder();
131
        $record = $queryBuilder
132 2
            ->select('tstamp')
133 2
            ->from('beers')
134 2
            ->where($queryBuilder->expr()->eq('to_user', $queryBuilder->createNamedParameter($username)))
135 2
            ->andWhere($queryBuilder->expr()->eq('from_user', $queryBuilder->createNamedParameter($from_user)))
136 2
            ->orderBy('tstamp', 'DESC')
137 2
            ->setMaxResults(1)
138 2
            ->execute()
139 2
            ->fetch();
140 2
        return empty($record) || $record['tstamp'] + 86400 < time();
141
    }
142
143
    /**
144
     * @param $username
145
     *
146
     * @return int
147
     *
148
     * @throws \Doctrine\DBAL\DBALException
149
     */
150 3
    protected function getBeerCountByUsername($username) : int
151
    {
152 3
        $queryBuilder = $this->getDatabaseConnection()
153 3
            ->createQueryBuilder();
154
        return $queryBuilder
155 3
            ->select('*')
156 3
            ->from('beers')
157 3
            ->where($queryBuilder->expr()->eq('to_user', $queryBuilder->createNamedParameter($username)))
158 3
            ->execute()
159 3
            ->rowCount();
160
    }
161
162
    /**
163
     * @return int
164
     *
165
     * @throws \Doctrine\DBAL\DBALException
166
     */
167 1
    protected function getBeerCountAll() : int
168
    {
169 1
        return $this->getDatabaseConnection()
170 1
            ->createQueryBuilder()
171 1
            ->select('*')
172 1
            ->from('beers')
173 1
            ->execute()
174 1
            ->rowCount();
175
    }
176
177
    /**
178
     * @return array
179
     *
180
     * @throws \Doctrine\DBAL\DBALException
181
     */
182 1
    protected function getBeerTop10() : array
183
    {
184 1
        return $this->getDatabaseConnection()
185 1
            ->createQueryBuilder()
186 1
            ->select('count(*) AS cnt', 'to_user AS username')
187 1
            ->from('beers')
188 1
            ->groupBy('to_user')
189 1
            ->orderBy('cnt', 'DESC')
190 1
            ->setMaxResults(10)
191 1
            ->execute()
192 1
            ->fetchAll();
193
    }
194
}
195