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

ericfortmeyer / activity-log / 20420404465

22 Dec 2025 03:01AM UTC coverage: 51.874% (-1.6%) from 53.429%
20420404465

push

github

web-flow
fix: add tenant id to all post requests (#60)

Signed-off-by: Eric Fortmeyer <e.fortmeyer01@gmail.com>

17 of 49 new or added lines in 10 files covered. (34.69%)

2 existing lines in 2 files now uncovered.

346 of 667 relevant lines covered (51.87%)

1.62 hits per line

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

0.0
/src/Http/RequestProcessors/EmailReportForMonth.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace EricFortmeyer\ActivityLog\Http\RequestProcessors;
6

7
use EricFortmeyer\ActivityLog\{
8
    CreditHours,
9
    TimeEntry,
10
    EmailConfig,
11
    MonthFilters,
12
    RemarksForMonth,
13
    EmailReport
14
};
15
use EricFortmeyer\ActivityLog\UserInterface\Contexts\TimeEntriesContext;
16
use EricFortmeyer\ActivityLog\Services\{
17
    TimeEntryService,
18
    RemarksForMonthService,
19
    CreditHoursService,
20
};
21
use EricFortmeyer\ActivityLog\Utils\Hasher;
22
use Phpolar\Model\Model;
23
use Phpolar\PurePhp\HtmlSafeContext;
24
use Phpolar\PurePhp\TemplateEngine;
25
use Phpolar\Storage\NotFound;
26

27
final class EmailReportForMonth extends AbstractTenantBasedRequestProcessor
28
{
29
    public function __construct(
30
        private readonly EmailConfig $mailConfig,
31
        private readonly TimeEntryService $timeEntryService,
32
        private readonly RemarksForMonthService $remarksService,
33
        private readonly CreditHoursService $creditHoursService,
34
        private readonly TemplateEngine $templateEngine,
35
        readonly Hasher $hasher,
36
    ) {
37
        parent::__construct($hasher);
×
38
    }
39

40
    public function process(
41
        #[Model] EmailReport $emailReportContext = new EmailReport(),
42
        #[Model] MonthFilters $monthFilters = new MonthFilters(),
43
    ): string {
44
        $month = $monthFilters->getMonth();
×
45
        $year = $monthFilters->getYear();
×
46
        $timeEntries = $this->timeEntryService->getAllByMonth(
×
47
            month: $month,
×
48
            year: $year,
×
49
            tenantId: $this->getTenantId(),
×
50
        );
×
51
        $remarks = $this->remarksService->get(RemarksForMonth::getIdFromMonth(
×
52
            month: $month,
×
53
            year: $year,
×
54
            tenantId: $this->getTenantId(),
×
55
        ));
×
56
        $creditHours = $this->creditHoursService->get(CreditHours::getIdFromMonth(
×
57
            month: $month,
×
58
            year: $year,
×
59
            tenantId: $this->getTenantId(),
×
60
        ));
×
61
        $context = $this->getContext(
×
62
            timeEntries: $timeEntries,
×
63
            monthFilters: $monthFilters,
×
64
            remarks: $remarks,
×
65
            creditHours: $creditHours,
×
66
        );
×
67
        $this->emailReport($emailReportContext, $context);
×
68
        return (string) $this->templateEngine->apply("index", new HtmlSafeContext($context));
×
69
    }
70

71
    private function emailReport(
72
        EmailReport $emailReportContext,
73
        TimeEntriesContext $timeEntriesContext,
74
    ): void {
75
        $success = mail(
×
76
            to: $emailReportContext->mailTo,
×
77
            subject: sprintf("Report for %s", $timeEntriesContext->getMonthTitle()),
×
78
            message: $this->getMessage(
×
79
                totalHours: $timeEntriesContext->getTotalHours(),
×
80
                creditHours: $timeEntriesContext->getCreditHours(),
×
81
                remarks: $timeEntriesContext->getRemarksForCurrentMonth(),
×
82
                shouldShowRemarks: $timeEntriesContext->hasRemarks(),
×
83
                shouldShowCreditHours: $timeEntriesContext->shouldShowCreditHours(),
×
84
            ),
×
85
            additional_headers: $this->mailConfig->headers,
×
86
        );
×
87

88
        if (!$success) {
×
89
            $error = error_get_last();
×
90
            if ($error !== null) {
×
91
                echo $error["message"];
×
92
            }
93
        }
94
    }
95

96
    private function getMessage(
97
        int $totalHours,
98
        int $creditHours,
99
        string $remarks,
100
        bool $shouldShowCreditHours,
101
        bool $shouldShowRemarks,
102
    ): string {
103
        return match (true) {
×
104
            $shouldShowCreditHours && $shouldShowRemarks =>
×
105
            <<<HTML
×
106
            <p>
×
107
                <strong>Total:</strong> {$totalHours} Hours
×
108
            </p>
109
            <p>
110
                <strong>Credit:</strong> {$creditHours} Hours
×
111
            </p>
112
            <p>
113
                <strong>Remarks:</strong> {$remarks}
×
114
            </p>
115
            HTML,
×
116
            $shouldShowCreditHours =>
×
117
            <<<HTML
×
118
            <p>
×
119
                <strong>Total:</strong> {$totalHours} Hours
×
120
            </p>
121
            <p>
122
                <strong>Credit:</strong> {$creditHours} Hours
×
123
            </p>
124
            HTML,
×
125
            $shouldShowRemarks =>
×
126
            <<<HTML
×
127
            <p>
×
128
                <strong>Total:</strong> {$totalHours} Hours
×
129
            </p>
130
            <p>
131
                <strong>Remarks:</strong> {$remarks}
×
132
            </p>
133
            HTML,
×
134
            default =>
×
135
            <<<HTML
×
136
            <p>
×
137
                <strong>Total:</strong> {$totalHours} Hours
×
138
            </p>
139
            HTML
×
140
        };
×
141
    }
142

143
    /**
144
     * @param TimeEntry[] $timeEntries
145
     */
146
    private function getContext(
147
        array $timeEntries,
148
        MonthFilters $monthFilters,
149
        RemarksForMonth| NotFound $remarks,
150
        CreditHours|NotFound $creditHours,
151
    ): TimeEntriesContext {
152
        return match (true) {
×
153
            $remarks instanceof NotFound && $creditHours instanceof NotFound =>
×
154
            new TimeEntriesContext(
×
155
                timeEntries: $timeEntries,
×
NEW
156
                tenantId: $this->getTenantId(),
×
157
                filters: $monthFilters,
×
158
                user: $this->user
×
159
            ),
×
160
            $creditHours instanceof CreditHours && $remarks instanceof NotFound =>
×
161
            new TimeEntriesContext(
×
162
                timeEntries: $timeEntries,
×
NEW
163
                tenantId: $this->getTenantId(),
×
164
                filters: $monthFilters,
×
165
                creditHours: $creditHours,
×
166
                user: $this->user
×
167
            ),
×
168
            $creditHours instanceof CreditHours && $remarks instanceof RemarksForMonth =>
×
169
            new TimeEntriesContext(
×
170
                timeEntries: $timeEntries,
×
NEW
171
                tenantId: $this->getTenantId(),
×
172
                filters: $monthFilters,
×
173
                remarks: $remarks,
×
174
                creditHours: $creditHours,
×
175
                user: $this->user,
×
176
            ),
×
177
            $remarks instanceof RemarksForMonth && $creditHours instanceof NotFound =>
×
178
            new TimeEntriesContext(
×
179
                timeEntries: $timeEntries,
×
NEW
180
                tenantId: $this->getTenantId(),
×
181
                filters: $monthFilters,
×
182
                remarks: $remarks,
×
183
                user: $this->user
×
184
            ),
×
185
            default =>
×
NEW
186
            new TimeEntriesContext(
×
NEW
187
                user: $this->user,
×
NEW
188
                tenantId: $this->getTenantId(),
×
NEW
189
            )
×
UNCOV
190
        };
×
191
    }
192
}
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