Completed
Push — master ( 2a5b9e...5fec60 )
by rugk
02:33
created

ThreemaGateway_Model_ActionThrottle   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 131
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 0

Importance

Changes 0
Metric Value
wmc 13
lcom 0
cbo 0
dl 0
loc 131
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A logAction() 0 8 1
A clearActionLogForUser() 0 7 1
A getActionsInTime() 0 10 1
A isLimited() 0 15 3
A pruneActionLog() 0 10 2
B getActionLimit() 0 23 5
1
<?php
2
/**
3
 * Model for temporare action log.
4
 *
5
 * @package ThreemaGateway
6
 * @author rugk
7
 * @copyright Copyright (c) 2015-2016 rugk
8
 * @license MIT
9
 */
10
11
class ThreemaGateway_Model_ActionThrottle extends XenForo_Model
12
{
13
    /**
14
     * @var string database table name
15
     */
16
    const DB_TABLE = 'xf_threemagw_action_throttle';
17
18
    /**
19
     * Logs the fact that the user executed a particular action.
20
     *
21
     * @param int    $userId
22
     * @param string $actionType
23
     */
24
    public function logAction($userId, $actionType)
25
    {
26
        $dataWriter = XenForo_DataWriter::create('ThreemaGateway_DataWriter_ActionThrottle');
27
        $dataWriter->set('user_id', $userId);
28
        $dataWriter->set('action_date', XenForo_Application::$time);
29
        $dataWriter->set('action_type', $actionType);
30
        return $dataWriter->save();
31
    }
32
33
    /**
34
     * Clears the whole action log for a particular action for a user.
35
     *
36
     * @param int    $userId
37
     * @param string $actionType
38
     */
39
    public function clearActionLogForUser($userId, $actionType)
40
    {
41
        $this->_getDb()->delete(self::DB_TABLE, [
42
            'user_id = ?' => $userId,
43
            'action_type = ?' => $actionType,
44
        ]);
45
    }
46
47
    /**
48
     * Returns the count of a specific action, which was executed by a particular
49
     * user since a specific time.
50
     *
51
     * @param int    $userId     the affected user
52
     * @param string $actionType describe the action to be count
53
     * @param int    $timeLimit  the oldest date, where actions should be "cut off"
54
     *
55
     * @return int
56
     */
57
    public function getActionsInTime($userId, $actionType, $timeLimit)
58
    {
59
        return $this->_getDb()->fetchOne('
60
            SELECT COUNT(*)
61
            FROM `' . self::DB_TABLE . '`
62
            WHERE action_date > ? AND
63
                action_type = ? AND
64
                user_id = ?
65
        ', [$timeLimit, $actionType, $userId]);
66
    }
67
68
    /**
69
     * Checks whether a user is rate-limited concerning a specific action.
70
     *
71
     * @param int    $userId     the affected user
72
     * @param string $actionType describe the action to be checked
73
     *
74
     * @return bool
75
     */
76
    public function isLimited($userId, $actionType)
77
    {
78
        $limits = $this->getActionLimit($actionType);
79
        foreach ($limits AS $limit) {
80
            $timeLimit = $limit[0];
81
            $actionLimit = $limit[1];
82
83
            $actionExecuted = $this->getActionsInTime($userId, $actionType, XenForo_Application::$time - $timeLimit);
84
            if ($actionExecuted >= $actionLimit) {
85
                return true;
86
            }
87
        }
88
89
        return false;
90
    }
91
92
    /**
93
     * Removes old action log entries.
94
     *
95
     * @param int    $timeLimit  the oldest date, where actions are saved
96
     */
97
    public function pruneActionLog($timeLimit = null)
98
    {
99
        if ($timeLimit === null) {
100
            $timeLimit = XenForo_Application::$time - 3600; // 1h before
101
        }
102
103
        $this->_getDb()->delete(self::DB_TABLE, [
104
            'action_date < ?' => $timeLimit
105
        ]);
106
    }
107
108
    /**
109
     * Returns the number of actions a user is allowed to do in an specific time.
110
     *
111
     * THe returned array has the format:
112
     * [time, max number of actions to be executed]
113
     *
114
     * @param string $actionType
115
     *
116
     * @return array
117
     */
118
    protected function getActionLimit($actionType)
119
    {
120
        /** @var array $limitArray */
121
        $limitArray = [];
122
        /** @var XenForo_Options $xenOptions */
123
        $xenOptions = XenForo_Application::getOptions();
124
125
        switch ($actionType) {
126
            case 'send':
127
                if ($xenOptions->threema_gateway_throttle_1min > 0) {
128
                    $limitArray[] = [60, $xenOptions->threema_gateway_throttle_1min];
129
                }
130
                if ($xenOptions->threema_gateway_throttle_5min > 0) {
131
                    $limitArray[] = [60 * 5, $xenOptions->threema_gateway_throttle_5min];
132
                }
133
                if ($xenOptions->threema_gateway_throttle_5h > 0) {
134
                    $limitArray[] = [60 * 60, $xenOptions->threema_gateway_throttle_5h];
135
                }
136
                break;
137
        }
138
139
        return $limitArray;
140
    }
141
}
142