diff --git a/app/Audit/AbstractAuditLogFormatter.php b/app/Audit/AbstractAuditLogFormatter.php index 6fc8e7364..1643b32e6 100644 --- a/app/Audit/AbstractAuditLogFormatter.php +++ b/app/Audit/AbstractAuditLogFormatter.php @@ -2,6 +2,8 @@ namespace App\Audit; +use App\Audit\Utils\DateFormatter; + /** * Copyright 2025 OpenStack Foundation * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,6 +20,12 @@ abstract class AbstractAuditLogFormatter implements IAuditLogFormatter { protected AuditContext $ctx; + protected string $event_type; + + public function __construct(string $event_type) + { + $this->event_type = $event_type; + } final public function setContext(AuditContext $ctx): void { @@ -41,5 +49,82 @@ protected function getUserInfo(): string return sprintf("%s (%s)", $user_name, $user_id); } + protected function formatAuditDate($date, string $format = 'Y-m-d H:i:s'): string + { + return DateFormatter::format($date, $format); + } + + protected function getIgnoredFields(): array + { + return [ + 'last_created', + 'last_updated', + 'last_edited', + 'created_by', + 'updated_by' + ]; + } + + protected function formatChangeValue($value): string + { + if (is_bool($value)) { + return $value ? 'true' : 'false'; + } + if (is_null($value)) { + return 'null'; + } + if ($value instanceof \DateTimeInterface) { + return $value->format('Y-m-d H:i:s'); + } + if ($value instanceof \Doctrine\Common\Collections\Collection) { + $count = $value->count(); + return sprintf('Collection[%d items]', $count); + } + if (is_object($value)) { + $className = get_class($value); + return sprintf('%s', $className); + } + if (is_array($value)) { + return sprintf('Array[%d items]', count($value)); + } + return (string) $value; + } + + + protected function buildChangeDetails(array $change_set): string + { + $changed_fields = []; + $ignored_fields = $this->getIgnoredFields(); + + foreach ($change_set as $prop_name => $change_values) { + if (in_array($prop_name, $ignored_fields)) { + continue; + } + + $old_value = $change_values[0] ?? null; + $new_value = $change_values[1] ?? null; + + $formatted_change = $this->formatFieldChange($prop_name, $old_value, $new_value); + if ($formatted_change !== null) { + $changed_fields[] = $formatted_change; + } + } + + if (empty($changed_fields)) { + return 'properties without changes registered'; + } + + $fields_summary = count($changed_fields) . ' field(s) modified: '; + return $fields_summary . implode(' | ', $changed_fields); + } + + protected function formatFieldChange(string $prop_name, $old_value, $new_value): ?string + { + $old_display = $this->formatChangeValue($old_value); + $new_display = $this->formatChangeValue($new_value); + + return sprintf("Property \"%s\" has changed from \"%s\" to \"%s\"", $prop_name, $old_display, $new_display); + } + abstract public function format($subject, array $change_set): ?string; } diff --git a/app/Audit/ConcreteFormatters/ChildEntityFormatters/SummitAttendeeBadgePrintAuditLogFormatter.php b/app/Audit/ConcreteFormatters/ChildEntityFormatters/SummitAttendeeBadgePrintAuditLogFormatter.php index cfe171db8..b50d18acc 100644 --- a/app/Audit/ConcreteFormatters/ChildEntityFormatters/SummitAttendeeBadgePrintAuditLogFormatter.php +++ b/app/Audit/ConcreteFormatters/ChildEntityFormatters/SummitAttendeeBadgePrintAuditLogFormatter.php @@ -3,6 +3,7 @@ namespace App\Audit\ConcreteFormatters\ChildEntityFormatters; use models\summit\SummitAttendeeBadgePrint; +use App\Audit\Utils\DateFormatter; /** * Copyright 2023 OpenStack Foundation @@ -29,7 +30,7 @@ class SummitAttendeeBadgePrintAuditLogFormatter implements IChildEntityAuditLogF public function format($subject, string $child_entity_action_type, ?string $additional_info = ""): ?string { if ($child_entity_action_type == IChildEntityAuditLogFormatter::CHILD_ENTITY_DELETION && $subject instanceof SummitAttendeeBadgePrint) { - $print_date = $subject->getPrintDate()->format('Y-m-d H:i:s'); + $print_date = DateFormatter::format($subject->getPrintDate()); $view_type_name = 'N/A'; $view_type = $subject->getViewType(); if (!is_null($view_type)) { diff --git a/app/Audit/ConcreteFormatters/EntityUpdateAuditLogFormatter.php b/app/Audit/ConcreteFormatters/EntityUpdateAuditLogFormatter.php index 28306711c..63bafe327 100644 --- a/app/Audit/ConcreteFormatters/EntityUpdateAuditLogFormatter.php +++ b/app/Audit/ConcreteFormatters/EntityUpdateAuditLogFormatter.php @@ -42,7 +42,7 @@ public function __construct(?IChildEntityAuditLogFormatter $child_entity_formatt $this->child_entity_formatter = $child_entity_formatter; } - protected function getIgnoredFields() + protected function getIgnoredFields(): array { return [ 'last_created', @@ -140,8 +140,8 @@ public function format($subject, $change_set): ?string } if ($old_value instanceof DateTime || $new_value instanceof DateTime) { - $old_value = $old_value != null ? $old_value->format('Y-m-d H:i:s') : ""; - $new_value = $new_value != null ? $new_value->format('Y-m-d H:i:s') : ""; + $old_value = $old_value != null ? $this->formatAuditDate($old_value) : ""; + $new_value = $new_value != null ? $this->formatAuditDate($new_value) : ""; } else if (is_bool($old_value) || is_bool($new_value)) { $old_value = $old_value ? 'true' : 'false'; $new_value = $new_value ? 'true' : 'false'; diff --git a/app/Audit/ConcreteFormatters/FeaturedSpeakerAuditLogFormatter.php b/app/Audit/ConcreteFormatters/FeaturedSpeakerAuditLogFormatter.php index b793766e9..e4c2fabbe 100644 --- a/app/Audit/ConcreteFormatters/FeaturedSpeakerAuditLogFormatter.php +++ b/app/Audit/ConcreteFormatters/FeaturedSpeakerAuditLogFormatter.php @@ -22,13 +22,6 @@ class FeaturedSpeakerAuditLogFormatter extends AbstractAuditLogFormatter { - private string $event_type; - - public function __construct(string $event_type) - { - $this->event_type = $event_type; - } - public function format($subject, array $change_set): ?string { if (!$subject instanceof FeaturedSpeaker) { @@ -59,23 +52,12 @@ public function format($subject, array $change_set): ?string ); case IAuditStrategy::EVENT_ENTITY_UPDATE: - $changed_fields = []; - - if (isset($change_set['Order'])) { - $old_order = $change_set['Order'][0] ?? 'unknown'; - $new_order = $change_set['Order'][1] ?? 'unknown'; - $changed_fields[] = sprintf("display_order %s → %s", $old_order, $new_order); - } - if (isset($change_set['PresentationSpeakerID'])) { - $changed_fields[] = "speaker"; - } - - $fields_str = !empty($changed_fields) ? implode(', ', $changed_fields) : 'properties'; + $change_details = $this->buildChangeDetails($change_set); return sprintf( - "Featured speaker '%s' (%s) updated (%s changed) by user %s", + "Featured speaker '%s' (%s) updated: %s by user %s", $speaker_name, $speaker_id, - $fields_str, + $change_details, $this->getUserInfo() ); diff --git a/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationActionTypeAuditLogFormatter.php b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationActionTypeAuditLogFormatter.php new file mode 100644 index 000000000..53d5933ae --- /dev/null +++ b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationActionTypeAuditLogFormatter.php @@ -0,0 +1,74 @@ +getLabel() ?? 'Unknown Action Type'; + $id = $subject->getId() ?? 'unknown'; + + $summit = $subject->getSummit(); + $summit_name = $summit ? ($summit->getName() ?? 'Unknown Summit') : 'Unknown Summit'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Presentation Action Type '%s' (%d) created for Summit '%s' by user %s", + $label, + $id, + $summit_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Presentation Action Type '%s' (%d) for Summit '%s' updated: %s by user %s", + $label, + $id, + $summit_name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Presentation Action Type '%s' (%d) for Summit '%s' was deleted by user %s", + $label, + $id, + $summit_name, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("PresentationActionTypeAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationLinkAuditLogFormatter.php b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationLinkAuditLogFormatter.php new file mode 100644 index 000000000..a3a87cfbb --- /dev/null +++ b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationLinkAuditLogFormatter.php @@ -0,0 +1,77 @@ +getName() ?? 'Unknown Link'; + $id = $subject->getId() ?? 'unknown'; + $class_name = $subject->getClassName(); + + $presentation = $subject->getPresentation(); + $presentation_title = $presentation ? ($presentation->getTitle() ?? 'Unknown Presentation') : 'Unknown Presentation'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Presentation Link '%s' (%d) of type %s created for presentation '%s' by user %s", + $title, + $id, + $class_name, + $presentation_title, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Presentation Link '%s' (%d) for presentation '%s' updated: %s by user %s", + $title, + $id, + $presentation_title, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Presentation Link '%s' (%d) of type %s for presentation '%s' was deleted by user %s", + $title, + $id, + $class_name, + $presentation_title, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("PresentationLinkAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationMediaUploadAuditLogFormatter.php b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationMediaUploadAuditLogFormatter.php new file mode 100644 index 000000000..0ed1b8099 --- /dev/null +++ b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationMediaUploadAuditLogFormatter.php @@ -0,0 +1,78 @@ +getName() ?? 'Unknown Media'; + $id = $subject->getId() ?? 'unknown'; + $class_name = $subject->getClassName(); + + $presentation = $subject->getPresentation(); + $presentation_title = $presentation ? ($presentation->getTitle() ?? 'Unknown Presentation') : 'Unknown Presentation'; + + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Presentation Media Upload '%s' (%d) of type %s created for presentation '%s' by user %s", + $title, + $id, + $class_name, + $presentation_title, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Presentation Media Upload '%s' (%d) for presentation '%s' updated: %s by user %s", + $title, + $id, + $presentation_title, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Presentation Media Upload '%s' (%d) of type %s for presentation '%s' was deleted by user %s", + $title, + $id, + $class_name, + $presentation_title, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("PresentationMediaUploadAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationSlideAuditLogFormatter.php b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationSlideAuditLogFormatter.php new file mode 100644 index 000000000..8f298f87c --- /dev/null +++ b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationSlideAuditLogFormatter.php @@ -0,0 +1,74 @@ +getName() ?? 'Unknown Slide'; + $id = $subject->getId() ?? 'unknown'; + + $presentation = $subject->getPresentation(); + $presentation_title = $presentation ? ($presentation->getTitle() ?? 'Unknown Presentation') : 'Unknown Presentation'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Presentation Slide '%s' (%d) created for presentation '%s' by user %s", + $title, + $id, + $presentation_title, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Presentation Slide '%s' (%d) for presentation '%s' updated: %s by user %s", + $title, + $id, + $presentation_title, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Presentation Slide '%s' (%d) for presentation '%s' was deleted by user %s", + $title, + $id, + $presentation_title, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("PresentationSlideAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/PresentationSpeakerAuditLogFormatter.php b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationSpeakerAuditLogFormatter.php similarity index 95% rename from app/Audit/ConcreteFormatters/PresentationSpeakerAuditLogFormatter.php rename to app/Audit/ConcreteFormatters/PresentationFormatters/PresentationSpeakerAuditLogFormatter.php index 3d81a3f3c..d9bdf1d2b 100644 --- a/app/Audit/ConcreteFormatters/PresentationSpeakerAuditLogFormatter.php +++ b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationSpeakerAuditLogFormatter.php @@ -1,6 +1,6 @@ event_type = $event_type; - } - public function format($subject, array $change_set): ?string { if (!$subject instanceof PresentationSpeaker) { diff --git a/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationSpeakerSummitAssistanceConfirmationAuditLogFormatter.php b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationSpeakerSummitAssistanceConfirmationAuditLogFormatter.php new file mode 100644 index 000000000..48a58fdba --- /dev/null +++ b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationSpeakerSummitAssistanceConfirmationAuditLogFormatter.php @@ -0,0 +1,78 @@ +getId() ?? 'unknown'; + + $speaker = $subject->getSpeaker(); + $speaker_name = $speaker ? sprintf("%s %s", $speaker->getFirstName() ?? '', $speaker->getLastName() ?? '') : 'Unknown Speaker'; + $speaker_email = $speaker ? ($speaker->getEmail() ?? 'unknown') : 'unknown'; + $speaker_name = trim($speaker_name) ?: $speaker_email; + + $summit = $subject->getSummit(); + $summit_name = $summit ? ($summit->getName() ?? 'Unknown Summit') : 'Unknown Summit'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Speaker Assistance Confirmation (%d) for '%s' on Summit '%s' created by user %s", + $id, + $speaker_name, + $summit_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Speaker Assistance Confirmation (%d) for '%s' on Summit '%s' updated: %s by user %s", + $id, + $speaker_name, + $summit_name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Speaker Assistance Confirmation (%d) for '%s' on Summit '%s' was deleted by user %s", + $id, + $speaker_name, + $summit_name, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("PresentationSpeakerSummitAssistanceConfirmationAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/PresentationTrackChairRatingTypeAuditLogFormatter.php b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationTrackChairRatingTypeAuditLogFormatter.php similarity index 79% rename from app/Audit/ConcreteFormatters/PresentationTrackChairRatingTypeAuditLogFormatter.php rename to app/Audit/ConcreteFormatters/PresentationFormatters/PresentationTrackChairRatingTypeAuditLogFormatter.php index 4fb260e97..b87576d68 100644 --- a/app/Audit/ConcreteFormatters/PresentationTrackChairRatingTypeAuditLogFormatter.php +++ b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationTrackChairRatingTypeAuditLogFormatter.php @@ -1,6 +1,6 @@ event_type = $event_type; - } - public function format($subject, array $change_set): ?string { if (!$subject instanceof PresentationTrackChairRatingType) { @@ -50,16 +43,11 @@ public function format($subject, array $change_set): ?string ); case IAuditStrategy::EVENT_ENTITY_UPDATE: - $changed_fields = []; - if (isset($change_set['name'])) { - $changed_fields[] = "name"; - } - - $fields_str = !empty($changed_fields) ? implode(', ', $changed_fields) : 'properties'; + $change_details = $this->buildChangeDetails($change_set); return sprintf( - "Track Chair Rating Type '%s' updated (%s changed) by user %s", + "Track Chair Rating Type '%s' updated: %s by user %s", $name, - $fields_str, + $change_details, $this->getUserInfo() ); diff --git a/app/Audit/ConcreteFormatters/PresentationTrackChairScoreTypeAuditLogFormatter.php b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationTrackChairScoreTypeAuditLogFormatter.php similarity index 77% rename from app/Audit/ConcreteFormatters/PresentationTrackChairScoreTypeAuditLogFormatter.php rename to app/Audit/ConcreteFormatters/PresentationFormatters/PresentationTrackChairScoreTypeAuditLogFormatter.php index abc722245..7dae84e8e 100644 --- a/app/Audit/ConcreteFormatters/PresentationTrackChairScoreTypeAuditLogFormatter.php +++ b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationTrackChairScoreTypeAuditLogFormatter.php @@ -1,6 +1,6 @@ event_type = $event_type; - } - public function format($subject, array $change_set): ?string { if (!$subject instanceof PresentationTrackChairScoreType) { @@ -52,19 +45,11 @@ public function format($subject, array $change_set): ?string ); case IAuditStrategy::EVENT_ENTITY_UPDATE: - $changed_fields = []; - if (isset($change_set['label'])) { - $changed_fields[] = "label"; - } - if (isset($change_set['score'])) { - $changed_fields[] = "score"; - } - - $fields_str = !empty($changed_fields) ? implode(', ', $changed_fields) : 'properties'; + $change_details = $this->buildChangeDetails($change_set); return sprintf( - "Score Type '%s' updated (%s changed) by user %s", + "Score Type '%s' updated: %s by user %s", $label, - $fields_str, + $change_details, $this->getUserInfo() ); diff --git a/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationUserSubmissionAuditLogFormatter.php b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationUserSubmissionAuditLogFormatter.php new file mode 100644 index 000000000..1c17a3e32 --- /dev/null +++ b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationUserSubmissionAuditLogFormatter.php @@ -0,0 +1,67 @@ +getTitle() ?? 'Unknown Presentation'; + $id = $subject->getId() ?? 'unknown'; + $creator = $subject->getCreator(); + $creator_name = $creator ? sprintf("%s %s", $creator->getFirstName() ?? '', $creator->getLastName() ?? '') : 'Unknown'; + $creator_name = trim($creator_name) ?: 'Unknown'; + $category = $subject->getCategory(); + $category_name = $category ? $category->getTitle() : 'Unassigned Track'; + $selection_plan = $subject->getSelectionPlan(); + $plan_name = $selection_plan ? $selection_plan->getName() : 'Unknown Plan'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Presentation '%s' (%d) submitted by '%s' to track '%s' (Plan: %s) by user %s", + $title, + $id, + $creator_name, + $category_name, + $plan_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Presentation '%s' (%d) updated: %s by user %s", + $title, + $id, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Presentation '%s' (%d) submitted by '%s' to track '%s' was deleted by user %s", + $title, + $id, + $creator_name, + $category_name, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("PresentationUserSubmissionAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationVideoAuditLogFormatter.php b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationVideoAuditLogFormatter.php new file mode 100644 index 000000000..0b911c767 --- /dev/null +++ b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationVideoAuditLogFormatter.php @@ -0,0 +1,77 @@ +getName() ?? 'Unknown Video'; + $id = $subject->getId() ?? 'unknown'; + $class_name = $subject->getClassName(); + + $presentation = $subject->getPresentation(); + $presentation_title = $presentation ? ($presentation->getTitle() ?? 'Unknown Presentation') : 'Unknown Presentation'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Presentation Video '%s' (%d) of type %s created for presentation '%s' by user %s", + $title, + $id, + $class_name, + $presentation_title, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Presentation Video '%s' (%d) for presentation '%s' updated: %s by user %s", + $title, + $id, + $presentation_title, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Presentation Video '%s' (%d) of type %s for presentation '%s' was deleted by user %s", + $title, + $id, + $class_name, + $presentation_title, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("PresentationVideoAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/PresentationUserSubmissionAuditLogFormatter.php b/app/Audit/ConcreteFormatters/PresentationUserSubmissionAuditLogFormatter.php deleted file mode 100644 index 011a7395e..000000000 --- a/app/Audit/ConcreteFormatters/PresentationUserSubmissionAuditLogFormatter.php +++ /dev/null @@ -1,119 +0,0 @@ -event_type = $event_type; - } - - public function format($subject, array $change_set): ?string - { - if (!$subject instanceof Presentation) { - return null; - } - - try { - $title = $subject->getTitle() ?? 'Unknown Presentation'; - $id = $subject->getId() ?? 'unknown'; - $creator = $subject->getCreator(); - $creator_name = $creator ? sprintf("%s %s", $creator->getFirstName() ?? '', $creator->getLastName() ?? '') : 'Unknown'; - $creator_name = trim($creator_name) ?: 'Unknown'; - $category = $subject->getCategory(); - $category_name = $category ? $category->getTitle() : 'Unassigned Track'; - $selection_plan = $subject->getSelectionPlan(); - $plan_name = $selection_plan ? $selection_plan->getName() : 'Unknown Plan'; - - switch ($this->event_type) { - case IAuditStrategy::EVENT_ENTITY_CREATION: - return sprintf( - "Presentation '%s' (%d) submitted by '%s' to track '%s' (Plan: %s) by user %s", - $title, - $id, - $creator_name, - $category_name, - $plan_name, - $this->getUserInfo() - ); - - case IAuditStrategy::EVENT_ENTITY_UPDATE: - $changed_fields = []; - $old_status = null; - $new_status = null; - - if (isset($change_set['Title'])) { - $changed_fields[] = "title"; - } - if (isset($change_set['Abstract'])) { - $changed_fields[] = "abstract"; - } - if (isset($change_set['ProblemAddressed'])) { - $changed_fields[] = "problem_addressed"; - } - if (isset($change_set['AttendeesExpectedLearnt'])) { - $changed_fields[] = "attendees_expected_learnt"; - } - - if (isset($change_set['Status'])) { - $changed_fields[] = "status"; - $old_status = $change_set['Status'][0] ?? null; - $new_status = $change_set['Status'][1] ?? null; - } - if (isset($change_set['CategoryID']) || isset($change_set['category'])) { - $changed_fields[] = "track"; - } - if (isset($change_set['Published'])) { - $changed_fields[] = "published"; - } - if (isset($change_set['SelectionPlanID'])) { - $changed_fields[] = "selection_plan"; - } - - $fields_str = !empty($changed_fields) ? implode(', ', $changed_fields) : 'properties'; - - if ($old_status && $new_status) { - return sprintf( - "Presentation '%s' (%d) status changed: %s → %s (%s changed) by user %s", - $title, - $id, - strtoupper($old_status), - strtoupper($new_status), - $fields_str, - $this->getUserInfo() - ); - } - - return sprintf( - "Presentation '%s' (%d) updated (%s changed) by user %s", - $title, - $id, - $fields_str, - $this->getUserInfo() - ); - - case IAuditStrategy::EVENT_ENTITY_DELETION: - return sprintf( - "Presentation '%s' (%d) submitted by '%s' to track '%s' was deleted by user %s", - $title, - $id, - $creator_name, - $category_name, - $this->getUserInfo() - ); - } - } catch (\Exception $ex) { - Log::warning("PresentationUserSubmissionAuditLogFormatter error: " . $ex->getMessage()); - } - - return null; - } -} diff --git a/app/Audit/ConcreteFormatters/SelectionPlanAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SelectionPlanAuditLogFormatter.php index 1366ec613..07be883a7 100644 --- a/app/Audit/ConcreteFormatters/SelectionPlanAuditLogFormatter.php +++ b/app/Audit/ConcreteFormatters/SelectionPlanAuditLogFormatter.php @@ -22,21 +22,6 @@ class SelectionPlanAuditLogFormatter extends AbstractAuditLogFormatter { - private string $event_type; - - public function __construct(string $event_type) - { - $this->event_type = $event_type; - } - - private function formatDate($date): string - { - if ($date instanceof \DateTime) { - return $date->format('Y-m-d H:i:s'); - } - return $date ?? 'N/A'; - } - public function format($subject, array $change_set): ?string { if (!$subject instanceof SelectionPlan) { @@ -54,16 +39,16 @@ public function format($subject, array $change_set): ?string $submission_dates = $subject->hasSubmissionPeriodDefined() ? sprintf( "[%s - %s]", - $this->formatDate($subject->getSubmissionBeginDate()), - $this->formatDate($subject->getSubmissionEndDate()) + $this->formatAuditDate($subject->getSubmissionBeginDate()), + $this->formatAuditDate($subject->getSubmissionEndDate()) ) : 'No dates set'; $selection_dates = $subject->hasSelectionPeriodDefined() ? sprintf( "[%s - %s]", - $this->formatDate($subject->getSelectionBeginDate()), - $this->formatDate($subject->getSelectionEndDate()) + $this->formatAuditDate($subject->getSelectionBeginDate()), + $this->formatAuditDate($subject->getSelectionEndDate()) ) : 'No dates set'; @@ -78,56 +63,13 @@ public function format($subject, array $change_set): ?string ); case IAuditStrategy::EVENT_ENTITY_UPDATE: - $changed_fields = []; - - if (isset($change_set['Name'])) { - $changed_fields[] = "name"; - } - if (isset($change_set['Enabled'])) { - $status = $change_set['Enabled'][1] ? 'enabled' : 'disabled'; - $changed_fields[] = "status ($status)"; - } - if (isset($change_set['IsHidden'])) { - $changed_fields[] = "visibility"; - } - if (isset($change_set['AllowNewPresentations'])) { - $changed_fields[] = "allow_new_presentations"; - } - if (isset($change_set['AllowProposedSchedules'])) { - $changed_fields[] = "allow_proposed_schedules"; - } - if (isset($change_set['AllowTrackChangeRequests'])) { - $changed_fields[] = "allow_track_change_requests"; - } - if (isset($change_set['SubmissionBeginDate']) || isset($change_set['SubmissionEndDate'])) { - $old_begin = isset($change_set['SubmissionBeginDate']) ? $this->formatDate($change_set['SubmissionBeginDate'][0]) : 'N/A'; - $new_begin = isset($change_set['SubmissionBeginDate']) ? $this->formatDate($change_set['SubmissionBeginDate'][1]) : 'N/A'; - $old_end = isset($change_set['SubmissionEndDate']) ? $this->formatDate($change_set['SubmissionEndDate'][0]) : 'N/A'; - $new_end = isset($change_set['SubmissionEndDate']) ? $this->formatDate($change_set['SubmissionEndDate'][1]) : 'N/A'; - $changed_fields[] = sprintf("CFP period [%s - %s] → [%s - %s]", $old_begin, $old_end, $new_begin, $new_end); - } - if (isset($change_set['VotingBeginDate']) || isset($change_set['VotingEndDate'])) { - $changed_fields[] = "voting period"; - } - if (isset($change_set['SelectionBeginDate']) || isset($change_set['SelectionEndDate'])) { - $changed_fields[] = "selection period"; - } - if (isset($change_set['MaxSubmissionAllowedPerUser'])) { - $old_val = $change_set['MaxSubmissionAllowedPerUser'][0] ?? 0; - $new_val = $change_set['MaxSubmissionAllowedPerUser'][1] ?? 0; - $changed_fields[] = sprintf("max_submissions (%d → %d)", $old_val, $new_val); - } - if (isset($change_set['SubmissionPeriodDisclaimer'])) { - $changed_fields[] = "disclaimer"; - } - - $fields_str = !empty($changed_fields) ? implode(', ', $changed_fields) : 'properties'; + $change_details = $this->buildChangeDetails($change_set); return sprintf( - "Selection Plan '%s' (%d) for Summit '%s' updated (%s changed) by user %s", + "Selection Plan '%s' (%d) for Summit '%s' updated: %s by user %s", $name, $id, $summit_name, - $fields_str, + $change_details, $this->getUserInfo() ); diff --git a/app/Audit/ConcreteFormatters/SpeakerAssistanceAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SpeakerAssistanceAuditLogFormatter.php index 857b9728a..1a8e04a75 100644 --- a/app/Audit/ConcreteFormatters/SpeakerAssistanceAuditLogFormatter.php +++ b/app/Audit/ConcreteFormatters/SpeakerAssistanceAuditLogFormatter.php @@ -17,18 +17,11 @@ use App\Audit\AbstractAuditLogFormatter; use App\Audit\Interfaces\IAuditStrategy; -use models\summit\PresentationSpeakerSummitAssistanceConfirmationRequest; +use models\summit\SpeakerAssistanceRequest; use Illuminate\Support\Facades\Log; class SpeakerAssistanceAuditLogFormatter extends AbstractAuditLogFormatter { - private string $event_type; - - public function __construct(string $event_type) - { - $this->event_type = $event_type; - } - public function format($subject, array $change_set): ?string { if (!$subject instanceof PresentationSpeakerSummitAssistanceConfirmationRequest) { diff --git a/app/Audit/ConcreteFormatters/SpeakerRegistrationRequestAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SpeakerRegistrationRequestAuditLogFormatter.php index 21b8eac5a..4a3f263cb 100644 --- a/app/Audit/ConcreteFormatters/SpeakerRegistrationRequestAuditLogFormatter.php +++ b/app/Audit/ConcreteFormatters/SpeakerRegistrationRequestAuditLogFormatter.php @@ -22,13 +22,6 @@ class SpeakerRegistrationRequestAuditLogFormatter extends AbstractAuditLogFormatter { - private string $event_type; - - public function __construct(string $event_type) - { - $this->event_type = $event_type; - } - public function format($subject, array $change_set): ?string { if (!$subject instanceof SpeakerRegistrationRequest) { @@ -51,33 +44,11 @@ public function format($subject, array $change_set): ?string ); case IAuditStrategy::EVENT_ENTITY_UPDATE: - $changed_fields = []; - - if (isset($change_set['Email'])) { - $old_email = $change_set['Email'][0] ?? 'N/A'; - $new_email = $change_set['Email'][1] ?? 'N/A'; - $changed_fields[] = sprintf("email %s → %s", $old_email, $new_email); - } - if (isset($change_set['IsConfirmed'])) { - $old_status = $change_set['IsConfirmed'][0] ? 'confirmed' : 'pending'; - $new_status = $change_set['IsConfirmed'][1] ? 'confirmed' : 'pending'; - $changed_fields[] = sprintf("status %s → %s", $old_status, $new_status); - } - if (isset($change_set['ConfirmationDate'])) { - $changed_fields[] = "confirmation_date"; - } - if (isset($change_set['ProposerID'])) { - $changed_fields[] = "proposer"; - } - if (isset($change_set['SpeakerID'])) { - $changed_fields[] = "speaker"; - } - - $fields_str = !empty($changed_fields) ? implode(', ', $changed_fields) : 'properties'; + $change_details = $this->buildChangeDetails($change_set); return sprintf( - "Speaker registration request for '%s' (%s changed) by user %s", + "Speaker registration request for '%s' updated: %s by user %s", $email, - $fields_str, + $change_details, $this->getUserInfo() ); diff --git a/app/Audit/ConcreteFormatters/SubmissionInvitationAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SubmissionInvitationAuditLogFormatter.php index 260795fbd..ef8d4e316 100644 --- a/app/Audit/ConcreteFormatters/SubmissionInvitationAuditLogFormatter.php +++ b/app/Audit/ConcreteFormatters/SubmissionInvitationAuditLogFormatter.php @@ -22,13 +22,6 @@ class SubmissionInvitationAuditLogFormatter extends AbstractAuditLogFormatter { - private string $event_type; - - public function __construct(string $event_type) - { - $this->event_type = $event_type; - } - public function format($subject, array $change_set): ?string { if (!$subject instanceof SummitSubmissionInvitation) { @@ -59,31 +52,12 @@ public function format($subject, array $change_set): ?string ); case IAuditStrategy::EVENT_ENTITY_UPDATE: - $changed_fields = []; - - if (isset($change_set['FirstName']) || isset($change_set['LastName'])) { - $changed_fields[] = "name"; - } - if (isset($change_set['Email'])) { - $old_email = $change_set['Email'][0] ?? 'N/A'; - $new_email = $change_set['Email'][1] ?? 'N/A'; - $changed_fields[] = sprintf("email %s to %s", $old_email, $new_email); - } - if (isset($change_set['SentDate'])) { - $old_status = isset($change_set['SentDate'][0]) && $change_set['SentDate'][0] ? 'sent' : 'not sent'; - $new_status = isset($change_set['SentDate'][1]) && $change_set['SentDate'][1] ? 'sent' : 'not sent'; - $changed_fields[] = sprintf("status %s to %s", $old_status, $new_status); - } - if (isset($change_set['SpeakerID'])) { - $changed_fields[] = "speaker"; - } - - $fields_str = !empty($changed_fields) ? implode(', ', $changed_fields) : 'properties'; + $change_details = $this->buildChangeDetails($change_set); return sprintf( - "Submission invitation for '%s' (%s) updated (%s changed) by user %s", + "Submission invitation for '%s' (%s) updated: %s by user %s", $email, $id, - $fields_str, + $change_details, $this->getUserInfo() ); diff --git a/app/Audit/ConcreteFormatters/SummitAirportAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitAirportAuditLogFormatter.php new file mode 100644 index 000000000..d42c0f950 --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitAirportAuditLogFormatter.php @@ -0,0 +1,73 @@ +getName() ?? 'Unknown Airport'; + $id = $subject->getId() ?? 'unknown'; + $summit = $subject->getSummit(); + $summit_name = $summit ? ($summit->getName() ?? 'Unknown Summit') : 'Unknown Summit'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Summit Airport '%s' (%d) created for Summit '%s' by user %s", + $name, + $id, + $summit_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Summit Airport '%s' (%d) for Summit '%s' updated: %s by user %s", + $name, + $id, + $summit_name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Summit Airport '%s' (%d) for Summit '%s' was deleted by user %s", + $name, + $id, + $summit_name, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitAirportAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitAuditLogFormatter.php new file mode 100644 index 000000000..7d4b0b10f --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitAuditLogFormatter.php @@ -0,0 +1,68 @@ +getName() ?? 'Unknown Summit'; + $id = $subject->getId() ?? 'unknown'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Summit '%s' (%d) created by user %s", + $name, + $id, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Summit '%s' (%d) updated: %s by user %s", + $name, + $id, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Summit '%s' (%d) was deleted by user %s", + $name, + $id, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitEventAttendanceMetricAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitEventAttendanceMetricAuditLogFormatter.php new file mode 100644 index 000000000..93a597d40 --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitEventAttendanceMetricAuditLogFormatter.php @@ -0,0 +1,76 @@ +getId() ?? 'unknown'; + + $event = $subject->getEvent(); + $event_title = $event ? ($event->getTitle() ?? 'Unknown Event') : 'Unknown Event'; + + $member = $subject->getMember(); + $member_name = $member ? sprintf("%s %s", $member->getFirstName(), $member->getLastName()) : 'Unknown Member'; + + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Attendance Metric (%d) for member '%s' at event '%s' created by user %s", + $id, + $member_name, + $event_title, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Attendance Metric (%d) for event '%s' updated: %s by user %s", + $id, + $event_title, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Attendance Metric (%d) for member '%s' at event '%s' was deleted by user %s", + $id, + $member_name, + $event_title, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitEventAttendanceMetricAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitEventAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitEventAuditLogFormatter.php new file mode 100644 index 000000000..63f197c9d --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitEventAuditLogFormatter.php @@ -0,0 +1,74 @@ +getTitle() ?? 'Unknown Event'; + $id = $subject->getId() ?? 'unknown'; + $summit = $subject->getSummit(); + $summit_name = $summit ? ($summit->getName() ?? 'Unknown Summit') : 'Unknown Summit'; + + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Summit Event '%s' (%d) created for Summit '%s' by user %s", + $title, + $id, + $summit_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Summit Event '%s' (%d) for Summit '%s' updated: %s by user %s", + $title, + $id, + $summit_name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Summit Event '%s' (%d) for Summit '%s' was deleted by user %s", + $title, + $id, + $summit_name, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitEventAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitExternalLocationAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitExternalLocationAuditLogFormatter.php new file mode 100644 index 000000000..7c8ce6103 --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitExternalLocationAuditLogFormatter.php @@ -0,0 +1,73 @@ +getName() ?? 'Unknown Location'; + $id = $subject->getId() ?? 'unknown'; + $summit = $subject->getSummit(); + $summit_name = $summit ? ($summit->getName() ?? 'Unknown Summit') : 'Unknown Summit'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "External Location '%s' (%d) created for Summit '%s' by user %s", + $name, + $id, + $summit_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "External Location '%s' (%d) for Summit '%s' updated: %s by user %s", + $name, + $id, + $summit_name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "External Location '%s' (%d) for Summit '%s' was deleted by user %s", + $name, + $id, + $summit_name, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitExternalLocationAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitGeoLocatedLocationAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitGeoLocatedLocationAuditLogFormatter.php new file mode 100644 index 000000000..2f52254b1 --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitGeoLocatedLocationAuditLogFormatter.php @@ -0,0 +1,73 @@ +getName() ?? 'Unknown Location'; + $id = $subject->getId() ?? 'unknown'; + $summit = $subject->getSummit(); + $summit_name = $summit ? ($summit->getName() ?? 'Unknown Summit') : 'Unknown Summit'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Geo-Located Location '%s' (%d) created for Summit '%s' by user %s", + $name, + $id, + $summit_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Geo-Located Location '%s' (%d) for Summit '%s' updated: %s by user %s", + $name, + $id, + $summit_name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Geo-Located Location '%s' (%d) for Summit '%s' was deleted by user %s", + $name, + $id, + $summit_name, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitGeoLocatedLocationAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitHotelAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitHotelAuditLogFormatter.php new file mode 100644 index 000000000..203d05df8 --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitHotelAuditLogFormatter.php @@ -0,0 +1,73 @@ +getName() ?? 'Unknown Hotel'; + $id = $subject->getId() ?? 'unknown'; + $summit = $subject->getSummit(); + $summit_name = $summit ? ($summit->getName() ?? 'Unknown Summit') : 'Unknown Summit'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Summit Hotel '%s' (%d) created for Summit '%s' by user %s", + $name, + $id, + $summit_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Summit Hotel '%s' (%d) for Summit '%s' updated: %s by user %s", + $name, + $id, + $summit_name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Summit Hotel '%s' (%d) for Summit '%s' was deleted by user %s", + $name, + $id, + $summit_name, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitHotelAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitMediaUploadTypeAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitMediaUploadTypeAuditLogFormatter.php new file mode 100644 index 000000000..76c4da7fa --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitMediaUploadTypeAuditLogFormatter.php @@ -0,0 +1,73 @@ +getName() ?? 'Unknown Media Type'; + $id = $subject->getId() ?? 'unknown'; + $summit = $subject->getSummit(); + $summit_name = $summit ? ($summit->getName() ?? 'Unknown Summit') : 'Unknown Summit'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Media Upload Type '%s' (%d) created for Summit '%s' by user %s", + $name, + $id, + $summit_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Media Upload Type '%s' (%d) for Summit '%s' updated: %s by user %s", + $name, + $id, + $summit_name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Media Upload Type '%s' (%d) for Summit '%s' was deleted by user %s", + $name, + $id, + $summit_name, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitMediaUploadTypeAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitMemberScheduleAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitMemberScheduleAuditLogFormatter.php index a7c45a967..ce00d0cf6 100644 --- a/app/Audit/ConcreteFormatters/SummitMemberScheduleAuditLogFormatter.php +++ b/app/Audit/ConcreteFormatters/SummitMemberScheduleAuditLogFormatter.php @@ -18,13 +18,6 @@ class SummitMemberScheduleAuditLogFormatter extends AbstractAuditLogFormatter { - - private string $event_type; - public function __construct(string $event_type) - { - $this->event_type = $event_type; - } - /** * @param $subject * @param array $change_set diff --git a/app/Audit/ConcreteFormatters/SummitTrackChairAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitTrackChairAuditLogFormatter.php index 2fbe1ad4f..07780e471 100644 --- a/app/Audit/ConcreteFormatters/SummitTrackChairAuditLogFormatter.php +++ b/app/Audit/ConcreteFormatters/SummitTrackChairAuditLogFormatter.php @@ -22,13 +22,6 @@ class SummitTrackChairAuditLogFormatter extends AbstractAuditLogFormatter { - private string $event_type; - - public function __construct(string $event_type) - { - $this->event_type = $event_type; - } - public function format($subject, array $change_set): ?string { if (!$subject instanceof SummitTrackChair) { @@ -56,29 +49,13 @@ public function format($subject, array $change_set): ?string ); case IAuditStrategy::EVENT_ENTITY_UPDATE: - if (isset($change_set['categories'])) { - $old_cats = $change_set['categories'][0] ?? []; - $new_cats = $change_set['categories'][1] ?? []; - - $old_names = is_array($old_cats) - ? array_map(fn($c) => $c->getTitle() ?? 'Unknown', $old_cats) - : []; - $new_names = is_array($new_cats) - ? array_map(fn($c) => $c->getTitle() ?? 'Unknown', $new_cats) - : []; - - $old_str = !empty($old_names) ? implode(', ', $old_names) : 'None'; - $new_str = !empty($new_names) ? implode(', ', $new_names) : 'None'; - - return sprintf( - "Track Chair '%s' tracks changed: [%s] → [%s] by user %s", - $member_name, - $old_str, - $new_str, - $this->getUserInfo() - ); - } - return sprintf("Track Chair '%s' updated by user %s", $member_name, $this->getUserInfo()); + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Track Chair '%s' updated: %s by user %s", + $member_name, + $change_details, + $this->getUserInfo() + ); case IAuditStrategy::EVENT_ENTITY_DELETION: return sprintf( diff --git a/app/Audit/ConcreteFormatters/SummitVenueAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitVenueAuditLogFormatter.php new file mode 100644 index 000000000..4ac585993 --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitVenueAuditLogFormatter.php @@ -0,0 +1,73 @@ +getName() ?? 'Unknown Venue'; + $id = $subject->getId() ?? 'unknown'; + $summit = $subject->getSummit(); + $summit_name = $summit ? ($summit->getName() ?? 'Unknown Summit') : 'Unknown Summit'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Summit Venue '%s' (%d) created for Summit '%s' by user %s", + $name, + $id, + $summit_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Summit Venue '%s' (%d) for Summit '%s' updated: %s by user %s", + $name, + $id, + $summit_name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Summit Venue '%s' (%d) for Summit '%s' was deleted by user %s", + $name, + $id, + $summit_name, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitVenueAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitVenueRoomAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitVenueRoomAuditLogFormatter.php new file mode 100644 index 000000000..061e53a0c --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitVenueRoomAuditLogFormatter.php @@ -0,0 +1,80 @@ +getName() ?? 'Unknown Room'; + $id = $subject->getId() ?? 'unknown'; + + $venue = $subject->getVenue(); + $venue_name = $venue ? ($venue->getName() ?? 'Unknown Venue') : 'Unknown Venue'; + + $summit = $subject->getSummit(); + $summit_name = $summit ? ($summit->getName() ?? 'Unknown Summit') : 'Unknown Summit'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Venue Room '%s' (%d) created in Venue '%s' for Summit '%s' by user %s", + $name, + $id, + $venue_name, + $summit_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Venue Room '%s' (%d) in Venue '%s' for Summit '%s' updated: %s by user %s", + $name, + $id, + $venue_name, + $summit_name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Venue Room '%s' (%d) in Venue '%s' for Summit '%s' was deleted by user %s", + $name, + $id, + $venue_name, + $summit_name, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitVenueRoomAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/Utils/DateFormatter.php b/app/Audit/Utils/DateFormatter.php new file mode 100644 index 000000000..11d37d11d --- /dev/null +++ b/app/Audit/Utils/DateFormatter.php @@ -0,0 +1,31 @@ +format($format); + } + if ($date instanceof \DateTime) { + return $date->format($format); + } + return 'N/A'; + } +} diff --git a/config/audit_log.php b/config/audit_log.php index 23e9de21b..51462a6b5 100644 --- a/config/audit_log.php +++ b/config/audit_log.php @@ -8,10 +8,11 @@ ], \models\summit\PresentationSpeaker::class => [ 'enabled' => true, - 'strategy' => \App\Audit\ConcreteFormatters\PresentationSpeakerAuditLogFormatter::class, + 'strategy' => \App\Audit\ConcreteFormatters\PresentationFormatters\PresentationSpeakerAuditLogFormatter::class, ], \models\summit\Presentation::class => [ 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\PresentationFormatters\PresentationUserSubmissionAuditLogFormatter::class, 'strategies' => [ [ 'route' => 'POST|api/v1/summits/{id}/events', @@ -49,7 +50,7 @@ ], \models\summit\PresentationSpeakerSummitAssistanceConfirmationRequest::class => [ 'enabled' => true, - 'strategy' => \App\Audit\ConcreteFormatters\SpeakerAssistanceAuditLogFormatter::class, + 'strategy' => \App\Audit\ConcreteFormatters\PresentationFormatters\PresentationSpeakerSummitAssistanceConfirmationAuditLogFormatter::class, ], \models\summit\SummitTrackChair::class => [ 'enabled' => true, @@ -57,11 +58,71 @@ ], \App\Models\Foundation\Summit\Events\Presentations\TrackChairs\PresentationTrackChairRatingType::class => [ 'enabled' => true, - 'strategy' => \App\Audit\ConcreteFormatters\PresentationTrackChairRatingTypeAuditLogFormatter::class, + 'strategy' => \App\Audit\ConcreteFormatters\PresentationFormatters\PresentationTrackChairRatingTypeAuditLogFormatter::class, ], \App\Models\Foundation\Summit\Events\Presentations\TrackChairs\PresentationTrackChairScoreType::class => [ 'enabled' => true, - 'strategy' => \App\Audit\ConcreteFormatters\PresentationTrackChairScoreTypeAuditLogFormatter::class, + 'strategy' => \App\Audit\ConcreteFormatters\PresentationFormatters\PresentationTrackChairScoreTypeAuditLogFormatter::class, + ], + \models\summit\Summit::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitAuditLogFormatter::class, + ], + \models\summit\SummitEvent::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitEventAuditLogFormatter::class, + ], + \models\summit\SummitGeoLocatedLocation::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitGeoLocatedLocationAuditLogFormatter::class, + ], + \models\summit\PresentationVideo::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\PresentationFormatters\PresentationVideoAuditLogFormatter::class, + ], + \models\summit\PresentationSlide::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\PresentationFormatters\PresentationSlideAuditLogFormatter::class, + ], + \models\summit\PresentationLink::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\PresentationFormatters\PresentationLinkAuditLogFormatter::class, + ], + \models\summit\PresentationMediaUpload::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\PresentationFormatters\PresentationMediaUploadAuditLogFormatter::class, + ], + \models\summit\PresentationActionType::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\PresentationFormatters\PresentationActionTypeAuditLogFormatter::class, + ], + \models\summit\SummitEventAttendanceMetric::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitEventAttendanceMetricAuditLogFormatter::class, + ], + \models\summit\SummitMediaUploadType::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitMediaUploadTypeAuditLogFormatter::class, + ], + \models\summit\SummitVenue::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitVenueAuditLogFormatter::class, + ], + \models\summit\SummitExternalLocation::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitExternalLocationAuditLogFormatter::class, + ], + \models\summit\SummitHotel::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitHotelAuditLogFormatter::class, + ], + \models\summit\SummitAirport::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitAirportAuditLogFormatter::class, + ], + \models\summit\SummitVenueRoom::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitVenueRoomAuditLogFormatter::class, ], ] ];