TimedCounter::enablePrecisionMode()   A
last analyzed

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