Skip to content

Commit 2b1818e

Browse files
Release version 1.1.0 (#13)
* feat:implement_toString_for_result_class * feat:implement_stop()_to_replace_deprecated_end() * refactor:replace_ramsey_uuid_with_native_php_functions * refactor:rename_static_method_from_run()_to_watch() * refactor:move_timer_status_to_dedicated_Enum_class (#5) * fix:update_timer_status_constant_with_enum_in_test_cases (#6) * feat:add_new_methods_in_timetracker (#7) New methods, 1. isStarted() 2. isStopped() 3. getActiveTimers() * fix:add_isStopped_check_in_finally_block_to_prevent_duplicate_stop_calls (#8) * docs:update_README_to_include_new_methods * feat: add new methods in timetracker (#9) new methods: - lap - getLaps - pause - resume - inspect * chore: add phpunit cache and coverage folders to .gitignore * chore: add test workflow for master and dev branches (#10) * chore: add test workflow for master and dev branches * remove version field from composer.json * refactor: restore run() as deprecated alias for backward compatibility (#11) - Reintroduce run() which was previously removed when adding watch() - Mark run() as deprecated but keep it fully functional * docs: add changelog for recent changes (#12)
1 parent 096c625 commit 2b1818e

13 files changed

+815
-71
lines changed

.github/workflows/tests.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: [ "master", "dev" ]
6+
pull_request:
7+
branches: [ "master", "dev" ]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
build:
14+
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Set up PHP
21+
uses: shivammathur/setup-php@v2
22+
with:
23+
php-version: 8.3
24+
25+
- name: Validate composer.json and composer.lock
26+
run: composer validate --strict
27+
28+
- name: Cache Composer packages
29+
id: composer-cache
30+
uses: actions/cache@v3
31+
with:
32+
path: vendor
33+
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
34+
restore-keys: |
35+
${{ runner.os }}-php-
36+
37+
- name: Install dependencies
38+
run: composer install --prefer-dist --no-progress --no-suggest
39+
40+
- name: Run test suite
41+
run: composer test

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ vendor/
1010
# Ignore PHPUnit configuration file (if you're using phpunit.xml for local customizations)
1111
phpunit.xml
1212

13+
# Ignore PHPUnit test result output files
14+
.phpunit.cache
15+
coverage-report
16+
1317
# Ignore Composer lock file if you don't want to share it (usually, you want to commit composer.lock)
1418
# composer.lock
1519

CHANGELOG.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# ChangeLog
2+
3+
## v1.1.0 - 2025-12-09
4+
### Added
5+
- Implemented `__toString()` method for the `Result` class, allowing instances to be converted to strings (e.g. `"$result"` now returns the calculated value). (PR #1)
6+
- Added new `stop()` method to the timer, supporting stopping: (PR #2)
7+
- a specific timer by ID
8+
- **or** the **most recently started timer** when no ID is provided.
9+
- Added new `watch()` static method to replace `run()` for executing and timing callbacks. (PR #4)
10+
- Added new timer utility methods `isStarted()`, `isStopped()`, and `getActiveTimers()` in `TimeTracker` to inspect active and completed timers. (PR #7)
11+
- Added new timer utility methods `lap()`, `getLaps()`, `pause()`, `resume()`, and `inspect()` in `TimeTracker`. (PR #9)
12+
13+
### Changed
14+
- Replaced `ramsey/uuid` with native PHP functions (`bin2hex(random_bytes(16))`) for generating random IDs. (PR #3)
15+
- Removed the `ramsey/uuid` dependency as it is no longer required. (PR #3)
16+
- Replaced `STATUS_*` string constants with a dedicated `TimerStatus` enum. (PR #5)
17+
18+
### Fixed
19+
- Prevent duplicate `stop()` calls in `watch()` by adding an `isStopped()` check in the `finally` block. (RP #8)
20+
21+
### Deprecated
22+
- Marked `end()` as deprecated. It still works for backward compatibility but will be removed in a future major release. (PR #2)
23+
- Marked `run()` as deprecated. It still works for backward compatibility but will be removed in a future major release. (PR #4)

README.md

Lines changed: 77 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,25 @@
1717
- composer
1818

1919
## Installation via Composer
20-
To install, navigate to your project root directory (where `composer.json` is located) and run the following command:
21-
```shell
22-
composer require naingaunglwin-dev/timetracker
20+
> If Composer is not installed, follow the [official guide](https://getcomposer.org/download/).
21+
22+
1. Create a `composer.json` file at your project root directory (if you don't have one):
23+
```json
24+
{
25+
"require": {
26+
"naingaunglwin-dev/timetracker": "^1.0"
27+
}
28+
}
29+
```
30+
31+
- Run the following command in your terminal from the project's root directory:
32+
```bash
33+
composer install
2334
```
24-
- If `composer.json` doesn't exits, run this command first,
25-
```shell
26-
composer init
35+
36+
If you already have `composer.json` file in your project, just run this command in your terminal,
37+
```bash
38+
composer require naingaunglwin-dev/timetracker
2739
```
2840

2941
## Usage
@@ -40,7 +52,7 @@ $tracker->start('test');
4052
echo 'hello world<br>';
4153
sleep(3);
4254

43-
$tracker->end('test');
55+
$tracker->stop('test');
4456

4557
echo $tracker->calculate('test')
4658
->get();
@@ -53,18 +65,12 @@ echo $tracker->calculate('test')
5365
### Convert to different unit
5466
- By default, the unit is in seconds (s). You can convert to other predefined units like milliseconds (ms), microseconds (us), and more:
5567
```php
56-
<?php
57-
58-
require 'vendor/autoload.php';
59-
60-
$tracker = new NAL\TimeTracker\TimeTracker();
61-
6268
$tracker->start('test');
6369

6470
echo 'hello world<br>';
6571
sleep(3);
6672

67-
$tracker->end('test');
73+
$tracker->stop('test');
6874

6975
echo $tracker->calculate('test')
7076
->convert('ms')
@@ -78,18 +84,12 @@ echo $tracker->calculate('test')
7884
### Add custom unit
7985
- You can define custom units based on seconds (for example, converting seconds to custom units):
8086
```php
81-
<?php
82-
83-
require 'vendor/autoload.php';
84-
85-
$tracker = new NAL\TimeTracker\TimeTracker();
86-
8787
$tracker->start('test');
8888

8989
echo 'hello world<br>';
9090
sleep(3);
9191

92-
$tracker->end('test');
92+
$tracker->stop('test');
9393

9494
// Add a custom unit definition (1 second = 10 custom units)
9595
$tracker->addUnitDefinition('testunit', '*', 10);
@@ -106,18 +106,12 @@ echo $tracker->calculate('test')
106106
### Format output
107107
- You can format the output of the calculated time using placeholders:
108108
```php
109-
<?php
110-
111-
require 'vendor/autoload.php';
112-
113-
$tracker = new NAL\TimeTracker\TimeTracker();
114-
115109
$tracker->start('test');
116110

117111
echo 'hello world<br>';
118112
sleep(3);
119113

120-
$tracker->end('test');
114+
$tracker->stop('test');
121115

122116
echo $tracker->calculate('test')
123117
->convert('ms')
@@ -132,23 +126,21 @@ echo $tracker->calculate('test')
132126
### Time tracking with callback function
133127
- You can track time for a callback function and get both the execution time and the result:
134128
```php
135-
$result = \NAL\TimeTracker\TimeTracker::run(
136-
function (Conversation $conv, $time) {
137-
sleep(3);
138-
return $conv->greet($time) . '<br>do something at ' . $time;
139-
},
140-
['time' => 'evening'], //parameters variableName => value
141-
'ms' // time unit, default is `s`
142-
);
143-
144129
class Conversation
145130
{
146131
public function greet($time){
147132
return 'good ' . $time;
148133
}
149134
}
150135

151-
var_dump($result);
136+
$watch = \NAL\TimeTracker\TimeTracker::watch(
137+
function (Conversation $conv, $time) {
138+
sleep(3);
139+
return $conv->greet($time) . '<br>do something at ' . $time;
140+
},
141+
['time' => 'evening'], //parameters variableName => value
142+
'ms' // time unit, default is `s`
143+
);
152144
```
153145
- Example output:
154146
```php
@@ -160,3 +152,50 @@ array (size=4)
160152
'unit' => string 'ms' (length=2)
161153
'output' => string 'good evening, do something at evening' (length=37)
162154
```
155+
156+
### Checking timer states
157+
158+
The following methods help you check timer states and get currently active timers.
159+
160+
#### Check if a timer has started
161+
```php
162+
$tracker->start('download');
163+
164+
if ($tracker->isStarted('download')) {
165+
echo "Download timer is started.";
166+
}
167+
168+
// Output:
169+
// Download timer is started.
170+
```
171+
172+
#### Check if a timer has stopped
173+
```php
174+
$tracker->start('process');
175+
176+
sleep(1);
177+
178+
$tracker->stop('process');
179+
180+
if ($tracker->isStopped('process')) {
181+
echo "Process timer is stopped.";
182+
}
183+
184+
// Output:
185+
// Process timer is stopped.
186+
```
187+
188+
#### Get currently active timers
189+
```php
190+
$tracker->start('task1');
191+
$tracker->start('task2');
192+
$tracker->stop('task1');
193+
194+
print_r($tracker->getActiveTimers());
195+
196+
// Output:
197+
// Array
198+
// (
199+
// [0] => task2
200+
// )
201+
```

composer.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"name": "naingaunglwin-dev/timetracker",
33
"description": "A lightweight time tracker for php",
44
"minimum-stability": "stable",
5-
"version": "1.0.0",
65
"type": "library",
76
"prefer-stable": true,
87
"license": "MIT",
@@ -19,10 +18,12 @@
1918
},
2019
"require": {
2120
"php": ">=8.3",
22-
"ramsey/uuid": "^4.7",
2321
"illuminate/container": "^11.36"
2422
},
2523
"require-dev": {
2624
"phpunit/phpunit": "^11.5"
25+
},
26+
"scripts": {
27+
"test": "vendor/bin/phpunit tests"
2728
}
2829
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace NAL\TimeTracker\Exception;
4+
5+
class NoActivePausedTimerToResume extends \BadMethodCallException
6+
{
7+
public function __construct($id)
8+
{
9+
parent::__construct("The timer with ID '{$id}' has no active pause to resume");
10+
}
11+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace NAL\TimeTracker\Exception;
4+
5+
use BadMethodCallException;
6+
7+
class NoActiveTimerToStopException extends BadMethodCallException
8+
{
9+
public function __construct()
10+
{
11+
parent::__construct("No active timer to stop.");
12+
}
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace NAL\TimeTracker\Exception;
4+
5+
use BadMethodCallException;
6+
7+
class TimerAlreadyPaused extends BadMethodCallException
8+
{
9+
public function __construct($id)
10+
{
11+
parent::__construct("The timer with ID '{$id}' is already paused and not yet resumed");
12+
}
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace NAL\TimeTracker\Exception;
4+
5+
use RuntimeException;
6+
7+
class UnmatchedPauseWithoutResume extends RuntimeException
8+
{
9+
public function __construct($id)
10+
{
11+
parent::__construct("Unmatched pause without resume for timer with ID '{$id}'");
12+
}
13+
}

src/Result.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,12 @@ private function _convert(float|int $from, float|int $to, string $operator, bool
118118
default => throw new UnsupportedLogic("Unsupported operator '{$operator}' in unit definition."),
119119
};
120120
}
121+
122+
/**
123+
* @return string
124+
*/
125+
public function __toString(): string
126+
{
127+
return $this->calculated;
128+
}
121129
}

0 commit comments

Comments
 (0)