Skip to content

Commit 7b3c6b8

Browse files
chore: refactor strategy for get Formatters
1 parent 9b97589 commit 7b3c6b8

6 files changed

Lines changed: 324 additions & 19 deletions

app/Audit/AuditLogFormatterFactory.php

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,29 @@ public function make(AuditContext $ctx, $subject, $eventType): ?IAuditLogFormatt
5252
$formatter = new EntityCollectionUpdateAuditLogFormatter($child_entity_formatter);
5353
break;
5454
case IAuditStrategy::EVENT_ENTITY_CREATION:
55-
$formatter = $this->getStrategyClass($subject, $eventType);
55+
$formatter = $this->getFormatterByContext($subject, $eventType, $ctx);
56+
if (is_null($formatter)) {
57+
$formatter = $this->getStrategyClass($subject, $eventType);
58+
}
5659
if(is_null($formatter)) {
5760
$formatter = new EntityCreationAuditLogFormatter();
5861
}
5962
break;
6063
case IAuditStrategy::EVENT_ENTITY_DELETION:
61-
$formatter = $this->getStrategyClass($subject, $eventType);
64+
$formatter = $this->getFormatterByContext($subject, $eventType, $ctx);
65+
if (is_null($formatter)) {
66+
$formatter = $this->getStrategyClass($subject, $eventType);
67+
}
6268
if(is_null($formatter)) {
6369
$child_entity_formatter = ChildEntityFormatterFactory::build($subject);
6470
$formatter = new EntityDeletionAuditLogFormatter($child_entity_formatter);
6571
}
6672
break;
6773
case IAuditStrategy::EVENT_ENTITY_UPDATE:
68-
$formatter = $this->getStrategyClass($subject, $eventType);
74+
$formatter = $this->getFormatterByContext($subject, $eventType, $ctx);
75+
if (is_null($formatter)) {
76+
$formatter = $this->getStrategyClass($subject, $eventType);
77+
}
6978
if(is_null($formatter)) {
7079
$child_entity_formatter = ChildEntityFormatterFactory::build($subject);
7180
$formatter = new EntityUpdateAuditLogFormatter($child_entity_formatter);
@@ -75,4 +84,43 @@ public function make(AuditContext $ctx, $subject, $eventType): ?IAuditLogFormatt
7584
$formatter->setContext($ctx);
7685
return $formatter;
7786
}
87+
88+
private function getFormatterByContext(object $subject, string $event_type, AuditContext $ctx): ?IAuditLogFormatter
89+
{
90+
$class = get_class($subject);
91+
$entity_config = $this->config['entities'][$class] ?? null;
92+
93+
if (!$entity_config || !isset($entity_config['strategies'])) {
94+
return null;
95+
}
96+
97+
foreach ($entity_config['strategies'] as $strategy) {
98+
if (!$this->matchesStrategy($strategy, $ctx)) {
99+
continue;
100+
}
101+
102+
$formatter_class = $strategy['formatter'] ?? null;
103+
return $formatter_class ? new $formatter_class($event_type) : null;
104+
}
105+
106+
return null;
107+
}
108+
109+
private function matchesStrategy(array $strategy, AuditContext $ctx): bool
110+
{
111+
if (isset($strategy['route']) && !$this->routeMatches($strategy['route'], $ctx->route)) {
112+
return false;
113+
}
114+
115+
return true;
116+
}
117+
118+
private function routeMatches(string $pattern, string $actual_route): bool
119+
{
120+
$normalized_pattern = preg_replace('/\{[a-zA-Z_]+\}/', '\d+', $pattern);
121+
$regex = '/^' . preg_quote($normalized_pattern, '/') . '$/';
122+
$regex = str_replace('\\\d+', '\d+', $regex);
123+
124+
return preg_match($regex, $actual_route) === 1;
125+
}
78126
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<?php
2+
3+
namespace App\Audit\ConcreteFormatters\PresentationFormatters;
4+
5+
/**
6+
* Copyright 2025 OpenStack Foundation
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
**/
17+
18+
use App\Audit\AbstractAuditLogFormatter;
19+
use App\Audit\Interfaces\IAuditStrategy;
20+
use models\summit\Presentation;
21+
use Illuminate\Support\Facades\Log;
22+
23+
abstract class BasePresentationAuditLogFormatter extends AbstractAuditLogFormatter
24+
{
25+
protected string $event_type;
26+
27+
public function __construct(string $event_type)
28+
{
29+
$this->event_type = $event_type;
30+
}
31+
32+
protected function extractChangedFields(array $change_set): array
33+
{
34+
$changed_fields = [];
35+
$old_status = null;
36+
$new_status = null;
37+
38+
if (isset($change_set['Title'])) {
39+
$changed_fields[] = "title";
40+
}
41+
if (isset($change_set['Abstract'])) {
42+
$changed_fields[] = "abstract";
43+
}
44+
if (isset($change_set['ProblemAddressed'])) {
45+
$changed_fields[] = "problem_addressed";
46+
}
47+
if (isset($change_set['AttendeesExpectedLearnt'])) {
48+
$changed_fields[] = "attendees_expected_learnt";
49+
}
50+
51+
if (isset($change_set['Status'])) {
52+
$changed_fields[] = "status";
53+
$old_status = $change_set['Status'][0] ?? null;
54+
$new_status = $change_set['Status'][1] ?? null;
55+
}
56+
if (isset($change_set['CategoryID']) || isset($change_set['category'])) {
57+
$changed_fields[] = "track";
58+
}
59+
if (isset($change_set['Published'])) {
60+
$changed_fields[] = "published";
61+
}
62+
if (isset($change_set['SelectionPlanID'])) {
63+
$changed_fields[] = "selection_plan";
64+
}
65+
66+
return [
67+
'fields' => !empty($changed_fields) ? implode(', ', $changed_fields) : 'properties',
68+
'old_status' => $old_status,
69+
'new_status' => $new_status,
70+
];
71+
}
72+
73+
protected function getPresentationData(Presentation $subject): array
74+
{
75+
$creator = $subject->getCreator();
76+
$creator_name = $creator ? sprintf("%s %s", $creator->getFirstName() ?? '', $creator->getLastName() ?? '') : 'Unknown';
77+
$creator_name = trim($creator_name) ?: 'Unknown';
78+
79+
$category = $subject->getCategory();
80+
$category_name = $category ? $category->getTitle() : 'Unassigned Track';
81+
82+
$selection_plan = $subject->getSelectionPlan();
83+
$plan_name = $selection_plan ? $selection_plan->getName() : 'Unknown Plan';
84+
85+
return [
86+
'title' => $subject->getTitle() ?? 'Unknown Presentation',
87+
'id' => $subject->getId() ?? 'unknown',
88+
'creator_name' => $creator_name,
89+
'category_name' => $category_name,
90+
'plan_name' => $plan_name,
91+
];
92+
}
93+
94+
public function format($subject, array $change_set): ?string
95+
{
96+
if (!$subject instanceof Presentation) {
97+
return null;
98+
}
99+
100+
try {
101+
$data = $this->getPresentationData($subject);
102+
103+
switch ($this->event_type) {
104+
case IAuditStrategy::EVENT_ENTITY_CREATION:
105+
return $this->formatCreation($data);
106+
107+
case IAuditStrategy::EVENT_ENTITY_UPDATE:
108+
$extracted = $this->extractChangedFields($change_set);
109+
return $this->formatUpdate($data, $extracted);
110+
111+
case IAuditStrategy::EVENT_ENTITY_DELETION:
112+
return $this->formatDeletion($data);
113+
}
114+
} catch (\Exception $ex) {
115+
Log::warning(static::class . " error: " . $ex->getMessage());
116+
}
117+
118+
return null;
119+
}
120+
121+
abstract protected function formatCreation(array $data): string;
122+
123+
abstract protected function formatUpdate(array $data, array $extracted): string;
124+
125+
abstract protected function formatDeletion(array $data): string;
126+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
namespace App\Audit\ConcreteFormatters\PresentationFormatters;
4+
5+
/**
6+
* Copyright 2025 OpenStack Foundation
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
**/
17+
18+
class PresentationEventApiAuditLogFormatter extends BasePresentationAuditLogFormatter
19+
{
20+
protected function formatCreation(array $data): string
21+
{
22+
return sprintf(
23+
"Presentation '%s' (%s) created by '%s' under track '%s' (Plan: %s) by user %s",
24+
$data['title'],
25+
$data['id'],
26+
$data['creator_name'],
27+
$data['category_name'],
28+
$data['plan_name'],
29+
$this->getUserInfo()
30+
);
31+
}
32+
33+
protected function formatUpdate(array $data, array $extracted): string
34+
{
35+
if ($extracted['old_status'] && $extracted['new_status']) {
36+
return sprintf(
37+
"Presentation '%s' (%s) status changed: %s → %s (%s changed) by user %s",
38+
$data['title'],
39+
$data['id'],
40+
strtoupper($extracted['old_status']),
41+
strtoupper($extracted['new_status']),
42+
$extracted['fields'],
43+
$this->getUserInfo()
44+
);
45+
}
46+
47+
return sprintf(
48+
"Presentation '%s' (%s) modified (%s changed) by user %s",
49+
$data['title'],
50+
$data['id'],
51+
$extracted['fields'],
52+
$this->getUserInfo()
53+
);
54+
}
55+
56+
protected function formatDeletion(array $data): string
57+
{
58+
return sprintf(
59+
"Presentation '%s' (%s) created by '%s' under track '%s' was removed by user %s",
60+
$data['title'],
61+
$data['id'],
62+
$data['creator_name'],
63+
$data['category_name'],
64+
$this->getUserInfo()
65+
);
66+
}
67+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
namespace App\Audit\ConcreteFormatters\PresentationFormatters;
4+
5+
/**
6+
* Copyright 2025 OpenStack Foundation
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
**/
17+
18+
class PresentationSubmissionAuditLogFormatter extends BasePresentationAuditLogFormatter
19+
{
20+
protected function formatCreation(array $data): string
21+
{
22+
return sprintf(
23+
"Presentation '%s' (%s) submitted by '%s' to track '%s' (Plan: %s) by user %s",
24+
$data['title'],
25+
$data['id'],
26+
$data['creator_name'],
27+
$data['category_name'],
28+
$data['plan_name'],
29+
$this->getUserInfo()
30+
);
31+
}
32+
33+
protected function formatUpdate(array $data, array $extracted): string
34+
{
35+
if ($extracted['old_status'] && $extracted['new_status']) {
36+
return sprintf(
37+
"Presentation '%s' (%s) status changed: %s → %s (%s changed) by user %s",
38+
$data['title'],
39+
$data['id'],
40+
strtoupper($extracted['old_status']),
41+
strtoupper($extracted['new_status']),
42+
$extracted['fields'],
43+
$this->getUserInfo()
44+
);
45+
}
46+
47+
return sprintf(
48+
"Presentation '%s' (%s) updated (%s changed) by user %s",
49+
$data['title'],
50+
$data['id'],
51+
$extracted['fields'],
52+
$this->getUserInfo()
53+
);
54+
}
55+
56+
protected function formatDeletion(array $data): string
57+
{
58+
return sprintf(
59+
"Presentation '%s' (%s) submitted by '%s' to track '%s' was deleted by user %s",
60+
$data['title'],
61+
$data['id'],
62+
$data['creator_name'],
63+
$data['category_name'],
64+
$this->getUserInfo()
65+
);
66+
}
67+
}

app/Audit/ConcreteFormatters/PresentationSubmissionAuditLogFormatter.php renamed to app/Audit/ConcreteFormatters/PresentationUserSubmissionAuditLogFormatter.php

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,12 @@
22

33
namespace App\Audit\ConcreteFormatters;
44

5-
/**
6-
* Copyright 2025 OpenStack Foundation
7-
* Licensed under the Apache License, Version 2.0 (the "License");
8-
* you may not use this file except in compliance with the License.
9-
* You may obtain a copy of the License at
10-
* http://www.apache.org/licenses/LICENSE-2.0
11-
* Unless required by applicable law or agreed to in writing, software
12-
* distributed under the License is distributed on an "AS IS" BASIS,
13-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14-
* See the License for the specific language governing permissions and
15-
* limitations under the License.
16-
**/
17-
185
use App\Audit\AbstractAuditLogFormatter;
196
use App\Audit\Interfaces\IAuditStrategy;
207
use models\summit\Presentation;
218
use Illuminate\Support\Facades\Log;
229

23-
class PresentationSubmissionAuditLogFormatter extends AbstractAuditLogFormatter
10+
class PresentationUserSubmissionAuditLogFormatter extends AbstractAuditLogFormatter
2411
{
2512
private string $event_type;
2613

@@ -124,7 +111,7 @@ public function format($subject, array $change_set): ?string
124111
);
125112
}
126113
} catch (\Exception $ex) {
127-
Log::warning("PresentationSubmissionAuditLogFormatter error: " . $ex->getMessage());
114+
Log::warning("PresentationUserSubmissionAuditLogFormatter error: " . $ex->getMessage());
128115
}
129116

130117
return null;

0 commit comments

Comments
 (0)