Status   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 156
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 37
c 2
b 0
f 0
dl 0
loc 156
ccs 43
cts 43
cp 1
rs 10
wmc 19

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A getCurrent() 0 3 1
A getSecondsElapsed() 0 3 1
A make() 0 10 3
A getTotal() 0 3 1
A getIntervalElapsed() 0 4 1
A getSpeed() 0 7 2
A getEstimatedTimeOfEnd() 0 12 3
A getMessage() 0 3 1
A getValue() 0 3 1
A getRatio() 0 6 2
A getStart() 0 3 1
A getRemain() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace EngineWorks\ProgressStatus;
6
7
use DateInterval;
8
use DateTimeImmutable;
9
10
class Status
11
{
12
    /** This is the minimum speed before declare undefined ETA (1 day) */
13
    private const MINIMUM_SPEED = 1 / 86400;
14
15
    /** @var int */
16
    private $value;
17
18
    /** @var int */
19
    private $total;
20
21
    /** @var int */
22
    private $current;
23
24
    /** @var int */
25
    private $start;
26
27
    /** @var string $message */
28
    private $message;
29
30
    /**
31
     * Progress Status. This is an immutable object.
32
     *
33
     * @param int $current
34
     * @param int $start
35
     * @param int $value
36
     * @param int $total
37
     * @param string $message
38
     */
39 30
    public function __construct(int $current, int $start, int $value, int $total, string $message)
40
    {
41 30
        $this->current = $current;
42 30
        $this->start = $start;
43 30
        $this->value = $value;
44 30
        $this->total = $total;
45 30
        $this->message = $message;
46
    }
47
48
    /**
49
     * Helper function to create a new object
50
     *
51
     * @param int $total
52
     * @param string $message
53
     * @param int $value
54
     * @param int|null $startTime if null then uses the value of time()
55
     * @param int|null $current if null then uses the value of time()
56
     *
57
     * @return self
58
     */
59 29
    public static function make(
60
        int $total = 0,
61
        string $message = '',
62
        int $value = 0,
63
        ?int $startTime = null,
64
        ?int $current = null
65
    ): self {
66 29
        $now = time();
67
        /** @psalm-suppress RiskyTruthyFalsyComparison */
68 29
        return new self($current ?: $now, $startTime ?: $now, $value, $total, $message);
69
    }
70
71 11
    public function getStart(): int
72
    {
73 11
        return $this->start;
74
    }
75
76 16
    public function getValue(): int
77
    {
78 16
        return $this->value;
79
    }
80
81 13
    public function getTotal(): int
82
    {
83 13
        return $this->total;
84
    }
85
86 6
    public function getCurrent(): int
87
    {
88 6
        return $this->current;
89
    }
90
91 13
    public function getMessage(): string
92
    {
93 13
        return $this->message;
94
    }
95
96
    /**
97
     * Get the current value in seconds elapsed
98
     *
99
     * @return float
100
     */
101 5
    public function getSpeed(): float
102
    {
103 5
        $elapsed = $this->getSecondsElapsed();
104 5
        if (0 === $elapsed) {
105 1
            return 0.0;
106
        }
107 4
        return $this->value / $elapsed;
108
    }
109
110
    /**
111
     * Get the ratio between current value and total, if total is zero it returns zero
112
     *
113
     * @return float
114
     */
115 3
    public function getRatio(): float
116
    {
117 3
        if (0 == $this->total) {
118 1
            return 0.0;
119
        }
120 2
        return floatval($this->value / $this->total);
121
    }
122
123
    /**
124
     * Get the difference between the total and current value
125
     *
126
     * @return int
127
     */
128 5
    public function getRemain(): int
129
    {
130 5
        return $this->total - $this->value;
131
    }
132
133
    /**
134
     * Return the estimated time of end, NULL if too high
135
     * @return int|null
136
     */
137 5
    public function getEstimatedTimeOfEnd(): ?int
138
    {
139 5
        $speed = $this->getSpeed();
140 5
        $remain = $this->getRemain();
141 5
        if (0 === $remain) {
142 1
            return time();
143
        }
144 4
        $minimumSpeed = self::MINIMUM_SPEED;
145 4
        if (abs($speed) < $minimumSpeed) {
146 1
            return null;
147
        }
148 3
        return $this->current + intval($remain / $speed);
149
    }
150
151 5
    public function getSecondsElapsed(): int
152
    {
153 5
        return $this->current - $this->start;
154
    }
155
156
    /**
157
     * Get elapsed time between start time and current time
158
     *
159
     * @return DateInterval
160
     * @noinspection PhpDocMissingThrowsInspection
161
     */
162 1
    public function getIntervalElapsed(): DateInterval
163
    {
164
        /** @noinspection PhpUnhandledExceptionInspection */
165 1
        return (new DateTimeImmutable('@' . $this->start))->diff(new DateTimeImmutable('@' . $this->current));
166
    }
167
}
168