Passed
Push — master ( 85bfe7...8b81ae )
by Alec
03:15
created

TimedCounter::enablePrecisionMode()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * User: alec
4
 * Date: 19.11.18
5
 * Time: 17:30
6
 */
7
declare(strict_types=1);
8
9
namespace AlecRabbit\Counters;
10
11
use AlecRabbit\Traits\Nameable;
12
13
class TimedCounter
14
{
15
    use Nameable;
16
17
    /** @var int */
18
    protected $lastTimestamp;
19
20
    /** @var array */
21
    protected $data = [];
22
23
    /** @var bool */
24
    protected $relativeMode = false;
25
26
    /** @var bool */
27
    protected $precisionMode = false;
28
29
    /** @var array */
30
    protected $periods;
31
32
    /**
33
     * BasicCounter constructor.
34
     * @param array|null $periods
35
     */
36 20
    public function __construct(?array $periods = null)
37
    {
38 20
        $this->setName(DEFAULT_NAME);
39 20
        $this->lastTimestamp = 0;
40 20
        $this->periods = $periods ?? PERIODS;
41 20
    }
42
43
    /**
44
     * Enables relative time mode
45
     * @return self
46
     */
47 17
    public function enableRelativeMode(): self
48
    {
49 17
        $this->relativeMode = true;
50 17
        return $this;
51
    }
52
53
    /**
54
     * @return self
55
     */
56 1
    public function enablePrecisionMode(): self
57
    {
58 1
        $this->precisionMode = true;
59 1
        return $this;
60
    }
61
62
    /**
63
     * @param int|null $time
64
     */
65 16
    public function add(?int $time = null): void
66
    {
67 16
        $baseTimes = $this->getBaseTimes($time);
68 16
        foreach ($baseTimes as $period => $timestamp) {
69 16
            $this->data[$period][$timestamp] =
70 16
                $this->data[$period][$timestamp] ?? 0;
71 16
            $this->data[$period][$timestamp]++;
72 16
            $this->trim($period);
73
        }
74 16
    }
75
76
    /**
77
     * @param int|null $timestamp
78
     * @return array
79
     */
80 19
    protected function getBaseTimes(?int $timestamp = null): array
81
    {
82 19
        $this->lastTimestamp = $time = $timestamp ?? time();
83 19
        $baseTimes = [];
84 19
        foreach ($this->periods as $period => $groupBy) {
85 19
            $baseTimes[$period] = base_timestamp($time, $groupBy);
86
        }
87 19
        return $baseTimes;
88
    }
89
90
    /**
91
     * @param int $period
92
     */
93 16
    protected function trim(int $period): void
94
    {
95 16
        if (null !== ($key = array_key_first($this->data[$period]))
96 16
            && ($key <= $this->getThreshold($period))) {
97 12
            unset($this->data[$period][$key]);
98
        }
99 16
    }
100
101
    /**
102
     * @param int $period
103
     * @return int
104
     */
105 19
    protected function getThreshold(int $period): int
106
    {
107
        return
108 19
            $this->getTime() - $period;
109
    }
110
111
    /**
112
     * @return int
113
     */
114 19
    protected function getTime(): int
115
    {
116
        return
117 19
            $this->relativeMode ? $this->lastTimestamp : time();
118
    }
119
120
    /**
121
     * @param bool|null $reset
122
     * @return array
123
     */
124 16
    public function getDataArray(?bool $reset = null): array
125
    {
126 16
        $r = [];
127 16
        foreach ($this->periods as $period => $groupBy) {
128 16
            if (0 < ($sum = array_sum($this->data[$period] ?? []))) {
129 16
                $r[$period] = $sum;
130
            }
131
        }
132 16
        if ($reset) {
133 1
            $this->reset();
134
        }
135 16
        return $r;
136
    }
137
138
    /**
139
     * Resets all data
140
     */
141 4
    protected function reset(): void
142
    {
143 4
        $this->data = [];
144 4
    }
145
146
    /**
147
     * @param bool|null $reset
148
     * @return object
149
     */
150 4
    public function getDataObject(?bool $reset = null): object
151
    {
152 4
        $r = new \stdClass();
153 4
        foreach ($this->periods as $period => $groupBy) {
154 4
            if (0 < ($sum = array_sum($this->data[$period] ?? []))) {
155 4
                $r->{$period} = $sum;
156
            }
157
        }
158 4
        if ($reset) {
159 1
            $this->reset();
160
        }
161 4
        return $r;
162
    }
163
164
    /**
165
     * @return array
166
     */
167 19
    public function getRawData(): array
168
    {
169 19
        return $this->data;
170
    }
171
}
172