Status::getIntervalElapsed()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 4
ccs 1
cts 1
cp 1
crap 1
rs 10
c 1
b 0
f 0
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
        return new self($current ?: $now, $startTime ?: $now, $value, $total, $message);
68 29
    }
69
70
    public function getStart(): int
71 11
    {
72
        return $this->start;
73 11
    }
74
75
    public function getValue(): int
76 16
    {
77
        return $this->value;
78 16
    }
79
80
    public function getTotal(): int
81 13
    {
82
        return $this->total;
83 13
    }
84
85
    public function getCurrent(): int
86 6
    {
87
        return $this->current;
88 6
    }
89
90
    public function getMessage(): string
91 13
    {
92
        return $this->message;
93 13
    }
94
95
    /**
96
     * Get the current value in seconds elapsed
97
     *
98
     * @return float
99
     */
100
    public function getSpeed(): float
101 5
    {
102
        $elapsed = $this->getSecondsElapsed();
103 5
        if (0 === $elapsed) {
104 5
            return 0.0;
105 1
        }
106
        return $this->value / $elapsed;
107 4
    }
108
109
    /**
110
     * Get the ratio between current value and total, if total is zero it returns zero
111
     *
112
     * @return float
113
     */
114
    public function getRatio(): float
115 3
    {
116
        if (0 == $this->total) {
117 3
            return 0.0;
118 1
        }
119
        return floatval($this->value / $this->total);
120 2
    }
121
122
    /**
123
     * Get the difference between the total and current value
124
     *
125
     * @return int
126
     */
127
    public function getRemain(): int
128 5
    {
129
        return $this->total - $this->value;
130 5
    }
131
132
    /**
133
     * Return the estimated time of end, NULL if too high
134
     * @return int|null
135
     */
136
    public function getEstimatedTimeOfEnd(): ?int
137 5
    {
138
        $speed = $this->getSpeed();
139 5
        $remain = $this->getRemain();
140 5
        if (0 === $remain) {
141 5
            return time();
142 1
        }
143
        $minimumSpeed = self::MINIMUM_SPEED;
144 4
        if (abs($speed) < $minimumSpeed) {
145 4
            return null;
146 1
        }
147
        return $this->current + intval($remain / $speed);
148 3
    }
149
150
    public function getSecondsElapsed(): int
151 5
    {
152
        return $this->current - $this->start;
153 5
    }
154
155
    /**
156
     * Get elapsed time between start time and current time
157
     *
158
     * @return DateInterval
159
     * @noinspection PhpDocMissingThrowsInspection
160
     */
161
    public function getIntervalElapsed(): DateInterval
162 1
    {
163
        /** @noinspection PhpUnhandledExceptionInspection */
164
        return (new DateTimeImmutable('@' . $this->start))->diff(new DateTimeImmutable('@' . $this->current));
165 1
    }
166
}
167