GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( f500e6...8bb85a )
by Andreas
02:52
created

DbHandler::processRecord()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 16
ccs 12
cts 12
cp 1
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 9
nc 4
nop 1
crap 5
1
<?php
2
/**
3
 * Starlit Db.
4
 *
5
 * @copyright Copyright (c) 2016 Starweb AB
6
 * @license   BSD 3-Clause
7
 */
8
9
namespace Starlit\Db\Monolog;
10
11
use Monolog\Handler\AbstractProcessingHandler;
12
use Monolog\Logger;
13
use Starlit\Db\Db;
14
15
/**
16
 * Monolog handler to log to a database table.
17
 *
18
 * Use a table structure like this for compatibility:
19
 *
20
 * CREATE TABLE `log` (
21
 *   `log_entry_id` BIGINT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
22
 *   `time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
23
 *   `channel` VARCHAR(64) NOT NULL,
24
 *   `level` VARCHAR(10) NOT NULL,
25
 *   `message` TEXT NOT NULL,
26
 *   PRIMARY KEY (`log_entry_id`),
27
 *   KEY `time` (`time`),
28
 *   KEY `channel` (`channel`),
29
 *   KEY `level` (`level`)
30
 * );
31
 *
32
 * @author Andreas Nilsson <http://github.com/jandreasn>
33
 */
34
class DbHandler extends AbstractProcessingHandler
35
{
36
    /**
37
     * @var Db
38
     */
39
    protected $db;
40
41
    /**
42
     * @var string
43
     */
44
    protected $table;
45
46
    /**
47
     * @var array
48
     */
49
    protected $additionalFields;
50
51
    /**
52
     * @var int
53
     */
54
    protected $maxEntries;
55
56
    /**
57
     * @var int
58
     */
59
    protected $cleanDivisor = 100;
60
61
    /**
62
     * Default probability of table being cleaned (1/100 = 1%).
63
     *
64
     * @var int
65
     */
66
    protected $cleanProbability = 1;
67
68
    /**
69
     * @param Db        $db
70
     * @param int       $maxEntries
71
     * @param array     $additionalFields
72
     * @param int       $level
73
     * @param bool      $bubble
74
     * @param string    $table
75
     */
76 5
    public function __construct(
77
        Db $db,
78
        $maxEntries = null,
79
        array $additionalFields = [],
80
        $level = Logger::DEBUG,
81
        $bubble = true,
82
        $table = 'log'
83
    ) {
84 5
        parent::__construct($level, $bubble);
85
86 5
        $this->db = $db;
87 5
        $this->maxEntries = $maxEntries;
88 5
        $this->additionalFields = $additionalFields;
89 5
        $this->table = $table;
90 5
    }
91
92
    /**
93
     * {@inheritdoc}
94
     */
95 5
    protected function processRecord(array $record)
96
    {
97 5
        $record = parent::processRecord($record);
98
99 5
        $record['additionalFieldsData'] = [];
100 5
        foreach ($this->additionalFields as $field) {
101 5
            foreach (['context', 'extra'] as $sourceKey) {
102 5
                if (isset($record[$sourceKey]) && array_key_exists($field, $record[$sourceKey])) {
103 1
                    $record['additionalFieldsData'][$field] = $record[$sourceKey][$field];
104 1
                    unset($record[$sourceKey][$field]);
105 1
                }
106 5
            }
107 5
        }
108
109 5
        return $record;
110
    }
111
112
    /**
113
     * {@inheritdoc}
114
     */
115 5
    protected function write(array $record)
116
    {
117
        $dbData = [
118 5
            'channel' => $record['channel'],
119 5
            'level'   => $record['level_name'],
120 5
            'message' => $record['formatted'],
121 5
        ] + $record['additionalFieldsData'];
122
123 5
        $this->db->insert($this->table, $dbData);
124
125 5
        $this->clean($record['channel']);
126 5
    }
127
128
    /**
129
     * @param string $channel
130
     */
131 5
    protected function clean($channel)
132
    {
133 5
        if ($this->maxEntries && mt_rand(1, $this->cleanDivisor) <= $this->cleanProbability) {
134 2
            $currentCount = $this->getChannelEntriesCount($channel);
135 2
            if ($currentCount > $this->maxEntries) {
136 1
                $entriesToDelete = $currentCount - $this->maxEntries;
137 1
                $this->deleteXOldestChannelEntries($channel, $entriesToDelete);
138 1
            }
139 2
        }
140 5
    }
141
142
    /**
143
     * @param string $channel
144
     * @return int
145
     */
146 2
    protected function getChannelEntriesCount($channel)
147
    {
148 2
        return $this->db->fetchValue(
149 2
            'SELECT COUNT(*) FROM `' . $this->table . '` WHERE `channel` = ?',
150 2
            [$channel]
151 2
        );
152
    }
153
154
    /**
155
     * @param $channel
156
     * @param $entriesToDelete
157
     */
158 1
    protected function deleteXOldestChannelEntries($channel, $entriesToDelete)
159
    {
160 1
        $this->db->exec(
161 1
            sprintf(
162 1
                'DELETE FROM `%s` WHERE `channel` = ?  ORDER BY `time` ASC LIMIT %d',
163 1
                $this->table,
164
                (int) $entriesToDelete
165 1
            ),
166 1
            [$channel]
167 1
        );
168 1
    }
169
170
    /**
171
     * @param Logger $logger
172
     */
173
    public function clear(Logger $logger)
174
    {
175
        $this->db->exec(sprintf('DELETE FROM `%s` WHERE `channel` = ?', $this->table), [$logger->getName()]);
176
    }
177
178
    /**
179
     * {@inheritdoc}
180
     */
181 5
    protected function getDefaultFormatter()
182
    {
183 5
        return new DbFormatter();
184
    }
185
186
    /**
187
     * @see setCleanProbability()
188
     * @param int $cleanDivisor
189
     */
190 1
    public function setCleanDivisor($cleanDivisor)
191
    {
192 1
        $this->cleanDivisor = $cleanDivisor;
193 1
    }
194
195
    /**
196
     * Sets the probability that log table is cleaned on log write.
197
     *
198
     * The clean probability together with clean divisor is used to calculate the probability.
199
     * With a clean probability of 1 and a divisor of 100, there's a 1% chance (1/100) the table
200
     * will be cleaned.
201
     *
202
     * @param int $cleanProbability
203
     */
204 3
    public function setCleanProbability($cleanProbability)
205
    {
206 3
        $this->cleanProbability = $cleanProbability;
207 3
    }
208
}
209