• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ericfortmeyer / activity-log / 20565536343

29 Dec 2025 05:20AM UTC coverage: 40.833% (-0.7%) from 41.548%
20565536343

push

github

web-flow
Merge pull request #90 from ericfortmeyer:deploy-on-publish

ci: deploy when release is published

343 of 840 relevant lines covered (40.83%)

1.22 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.33
/src/TimeEntry.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace EricFortmeyer\ActivityLog;
6

7
use Closure;
8
use DateTimeImmutable;
9
use Phpolar\Model\{
10
    EntityName,
11
    Hidden,
12
    Label,
13
    PrimaryKey
14
};
15
use Phpolar\Validators\{
16
    Max,
17
    MaxLength,
18
    Min,
19
    Required,
20
};
21

22
#[EntityName("time-entry")]
23
class TimeEntry extends TenantData
24
{
25
    #[MaxLength(20)]
26
    #[PrimaryKey]
27
    #[Hidden]
28
    public string $id;
29

30
    #[Min(1)]
31
    #[Max(31)]
32
    #[Required]
33
    #[Label("Day of Month")]
34
    public int $dayOfMonth;
35

36
    #[Min(1)]
37
    #[Max(12)]
38
    #[Required]
39
    public int $month;
40

41
    #[Min(2025)]
42
    #[Max(2026)]
43
    #[Required]
44
    public string $year;
45

46
    #[Max(24)]
47
    #[Min(0)]
48
    #[Required]
49
    public int $hours;
50

51
    #[Max(59)]
52
    #[Min(0)]
53
    public int $minutes;
54

55
    #[Hidden]
56
    // phpcs:disable
57
    public DateTimeImmutable $createdOn {
58
        set(string|DateTimeImmutable $value) {
59
            $this->createdOnVal  = match(true) {
60
                $value instanceof DateTimeImmutable => $value,
61
                default => new DateTimeImmutable($value),
62
            };
63
        }
64
        get => $this->createdOnVal ?? new DateTimeImmutable("now");
65
    }
66

67
    private DateTimeImmutable $createdOnVal;
68
    // phpcs:enable
69

70
    public function create(): void
71
    {
72
        $this->id = uniqid();
1✔
73
    }
74

75
    public static function setUninitializedValues(TimeEntry $timeEntry, int $month, string $year): void
76
    {
77
        $timeEntry->month ??= $month;
3✔
78
        $timeEntry->year ??= $year;
3✔
79
        $timeEntry->dayOfMonth ??= TimeEntry::getDefaultValue("dayOfMonth");
3✔
80
        $timeEntry->hours ??= 0;
3✔
81
        $timeEntry->minutes ??= 0;
3✔
82
    }
83

84
    public function getDate(): string
85
    {
86
        return sprintf(
4✔
87
            "%02d/%02d/%04d",
4✔
88
            $this->month,
4✔
89
            $this->dayOfMonth,
4✔
90
            $this->year,
4✔
91
        );
4✔
92
    }
93

94
    public function getDuration(): string
95
    {
96
        return sprintf(
3✔
97
            "%dh %dm",
3✔
98
            $this->hours,
3✔
99
            $this->minutes,
3✔
100
        );
3✔
101
    }
102

103
    public function isValid(): bool
104
    {
105
        return parent::isValid() && ($this->minutes === 0 && $this->hours === 0) === false;
15✔
106
    }
107

108
    public function hasHoursError(): bool
109
    {
110
        return $this->shouldValidate === true
×
111
            && ($this->minutes === 0 && $this->hours === 0)
×
112
            || $this->hasError("hours");
×
113
    }
114

115
    public function getHoursErrorMessage(): string
116
    {
117
        return ($this->minutes === 0 && $this->hours === 0)
×
118
            ? "Either minutes or hours should be entered. ⚠"
×
119
            : $this->getFieldErrorMessage("hours", " ⚠");
×
120
    }
121

122
    public static function getDefaultValue(string $field, DateTimeImmutable $date = new DateTimeImmutable("now")): mixed
123
    {
124
        return match ($field) {
17✔
125
            "dayOfMonth" => (int)$date->format("j"),
4✔
126
            "month" => (int)$date->format("m"),
12✔
127
            "year" => (int)$date->format("Y"),
12✔
128
            "hours" => 0,
1✔
129
            "minutes" => 0,
1✔
130
            default => null,
17✔
131
        };
17✔
132
    }
133

134
    /**
135
     * @suppress PhanUnreferencedClosure
136
     */
137
    public static function forTenant(string $tenantId): Closure
138
    {
139
        return static fn(TimeEntry $timeEntry): bool => $timeEntry->tenantId === $tenantId;
2✔
140
    }
141

142
    /**
143
     * @suppress PhanUnreferencedClosure
144
     */
145
    public static function byMonthAndYear(int $month, string $year): Closure
146
    {
147
        return static fn(TimeEntry $timeEntry): bool =>
3✔
148
        $timeEntry->month === $month
3✔
149
            && $timeEntry->year === $year;
3✔
150
    }
151
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc