Passed
Push — develop ( 043862...ee5a55 )
by nguereza
03:18
created

Timer::stop()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 6
c 1
b 0
f 0
nc 4
nop 0
dl 0
loc 13
rs 10
1
<?php
2
3
/**
4
 * Platine Framework
5
 *
6
 * Platine Framework is a lightweight, high-performance, simple and elegant
7
 * PHP Web framework
8
 *
9
 * This content is released under the MIT License (MIT)
10
 *
11
 * Copyright (c) 2020 Platine Framework
12
 * Copyright (c) 2015 PHP Reboot
13
 *
14
 * Permission is hereby granted, free of charge, to any person obtaining a copy
15
 * of this software and associated documentation files (the "Software"), to deal
16
 * in the Software without restriction, including without limitation the rights
17
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
 * copies of the Software, and to permit persons to whom the Software is
19
 * furnished to do so, subject to the following conditions:
20
 *
21
 * The above copyright notice and this permission notice shall be included in all
22
 * copies or substantial portions of the Software.
23
 *
24
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
 * SOFTWARE.
31
 */
32
33
/**
34
 *  @file Timer.php
35
 *
36
 *  The Timer class
37
 *
38
 *  @package    Platine\Framework\Helper\Timer
39
 *  @author Platine Developers team
40
 *  @copyright  Copyright (c) 2020
41
 *  @license    http://opensource.org/licenses/MIT  MIT License
42
 *  @link   https://www.platine-php.com
43
 *  @version 1.0.0
44
 *  @filesource
45
 */
46
47
declare(strict_types=1);
48
49
namespace Platine\Framework\Helper\Timer;
50
51
use InvalidArgumentException;
52
53
/**
54
 * @class Timer
55
 * @package Platine\Framework\Helper\Timer
56
 */
57
class Timer
58
{
59
    public const NOT_STARTED = 0;
60
    public const STARTED = 1;
61
    public const PAUSED = 2;
62
    public const STOPPED = 3;
63
64
    /**
65
     * The name of timer
66
     * @var string
67
     */
68
    protected string $name;
69
70
    /**
71
     * The current timer state
72
     * @var int
73
     */
74
    protected int $state = self::NOT_STARTED;
75
76
    /**
77
     * The timer start time
78
     * @var float
79
     */
80
    protected float $startTime = 0;
81
82
    /**
83
     * The timer runtime
84
     * @var float
85
     */
86
    protected float $runtime = 0;
87
88
    /**
89
     * Create new timer instance
90
     * @param string $name
91
     */
92
    public function __construct(string $name)
93
    {
94
        $this->name = $name;
95
    }
96
97
    /**
98
     * Return the timer time
99
     * @return float
100
     */
101
    public function getTime(): float
102
    {
103
        $currentRuntime = 0;
104
        if ($this->state === self::STARTED) {
105
            $time = microtime(true);
106
            $currentRuntime = $time - $this->startTime;
107
        }
108
109
        return $this->runtime + $currentRuntime;
110
    }
111
112
    /**
113
     * Stop the timer
114
     * @return bool
115
     */
116
    public function stop(): bool
117
    {
118
        if ($this->state === self::STARTED) {
119
            $this->pause();
120
        }
121
122
        if ($this->state === self::PAUSED) {
123
            $this->state = self::STOPPED;
124
125
            return true;
126
        }
127
128
        return false;
129
    }
130
131
    /**
132
     * Pause the timer
133
     * @return bool
134
     */
135
    public function pause(): bool
136
    {
137
        if ($this->state !== self::STARTED) {
138
            return false;
139
        }
140
        $time = microtime(true);
141
142
        $this->runtime += ($time - $this->startTime);
143
        $this->startTime = 0;
144
145
        $this->setState(self::PAUSED);
146
147
        return true;
148
    }
149
150
    /**
151
     * Start the timer
152
     * @return bool
153
     */
154
    public function start(): bool
155
    {
156
        if ($this->canStart() === false) {
157
            return false;
158
        }
159
160
        $this->startTime = microtime(true);
0 ignored issues
show
Documentation Bug introduced by
It seems like microtime(true) can also be of type string. However, the property $startTime is declared as type double. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
161
162
        $this->setState(self::STARTED);
163
164
        return true;
165
    }
166
167
    /**
168
     * Confirms if the timer can be started or not. A timer can be started
169
     * if it is in following states:
170
     *   - Not started and
171
     *   - paused
172
     * Timer can not be started if it is already running or stopped.
173
     * @return bool
174
     */
175
    public function canStart(): bool
176
    {
177
        if (in_array($this->state, [self::NOT_STARTED, self::PAUSED])) {
178
            return true;
179
        }
180
181
        return false;
182
    }
183
184
    /**
185
     * Return the timer name
186
     * @return string
187
     */
188
    public function getName(): string
189
    {
190
        return $this->name;
191
    }
192
193
    /**
194
     * Return the current state
195
     * @return int
196
     */
197
    public function getState(): int
198
    {
199
        return $this->state;
200
    }
201
202
203
    /**
204
     * Set the timer state
205
     * @param int $state
206
     * @return $this
207
     */
208
    protected function setState(int $state): self
209
    {
210
        if ($state < 0 || $state > 3) {
211
            throw new InvalidArgumentException(sprintf(
212
                'Invalid state [%d] must be between [0-3]',
213
                $state
214
            ));
215
        }
216
217
        $this->state = $state;
218
219
        return $this;
220
    }
221
}
222