From 68a486aa3e95c5da1b27e04c478962a8e6f17552 Mon Sep 17 00:00:00 2001 From: Jose Andres Tejerina Date: Mon, 29 Dec 2025 15:15:14 -0300 Subject: [PATCH 1/3] feat: add news formatter for Event site and Event --- .../RSVPAnswerAuditLogFormatter.php | 69 +++++++++++++++ ...entationCategoryGroupAuditLogFormatter.php | 78 +++++++++++++++++ .../RSVPAuditLogFormatter.php | 85 +++++++++++++++++++ .../RSVPInvitationAuditLogFormatter.php | 77 +++++++++++++++++ .../RSVPQuestionTemplateAuditLogFormatter.php | 84 ++++++++++++++++++ .../RSVPTemplateAuditLogFormatter.php | 85 +++++++++++++++++++ ...nueRoomAttributeValueAuditLogFormatter.php | 71 ++++++++++++++++ .../SummitEventTypeAuditLogFormatter.php | 81 ++++++++++++++++++ .../SummitMetricAuditLogFormatter.php | 73 ++++++++++++++++ ...itPresentationCommentAuditLogFormatter.php | 72 ++++++++++++++++ ...heduleAllowedLocationAuditLogFormatter.php | 74 ++++++++++++++++ ...tSelectedPresentationAuditLogFormatter.php | 74 ++++++++++++++++ ...ectedPresentationListAuditLogFormatter.php | 76 +++++++++++++++++ .../SummitSponsorshipAuditLogFormatter.php | 74 ++++++++++++++++ config/audit_log.php | 28 ++++++ 15 files changed, 1101 insertions(+) create mode 100644 app/Audit/ConcreteFormatters/ChildEntityFormatters/RSVPAnswerAuditLogFormatter.php create mode 100644 app/Audit/ConcreteFormatters/PresentationCategoryGroupAuditLogFormatter.php create mode 100644 app/Audit/ConcreteFormatters/RSVPAuditLogFormatter.php create mode 100644 app/Audit/ConcreteFormatters/RSVPInvitationAuditLogFormatter.php create mode 100644 app/Audit/ConcreteFormatters/RSVPQuestionTemplateAuditLogFormatter.php create mode 100644 app/Audit/ConcreteFormatters/RSVPTemplateAuditLogFormatter.php create mode 100644 app/Audit/ConcreteFormatters/SummitBookableVenueRoomAttributeValueAuditLogFormatter.php create mode 100644 app/Audit/ConcreteFormatters/SummitEventTypeAuditLogFormatter.php create mode 100644 app/Audit/ConcreteFormatters/SummitMetricAuditLogFormatter.php create mode 100644 app/Audit/ConcreteFormatters/SummitPresentationCommentAuditLogFormatter.php create mode 100644 app/Audit/ConcreteFormatters/SummitProposedScheduleAllowedLocationAuditLogFormatter.php create mode 100644 app/Audit/ConcreteFormatters/SummitSelectedPresentationAuditLogFormatter.php create mode 100644 app/Audit/ConcreteFormatters/SummitSelectedPresentationListAuditLogFormatter.php create mode 100644 app/Audit/ConcreteFormatters/SummitSponsorshipAuditLogFormatter.php diff --git a/app/Audit/ConcreteFormatters/ChildEntityFormatters/RSVPAnswerAuditLogFormatter.php b/app/Audit/ConcreteFormatters/ChildEntityFormatters/RSVPAnswerAuditLogFormatter.php new file mode 100644 index 000000000..d841c895f --- /dev/null +++ b/app/Audit/ConcreteFormatters/ChildEntityFormatters/RSVPAnswerAuditLogFormatter.php @@ -0,0 +1,69 @@ +getQuestionId(); + $value = $subject->getValue(); + $question = $subject->getQuestion(); + $questionLabel = $question?->getLabel() ?? sprintf("Question #%d", $questionId); + + switch ($child_entity_action_type) { + case IChildEntityAuditLogFormatter::CHILD_ENTITY_CREATION: + return sprintf( + "RSVP Answer added for question '%s' with value '%s'", + $questionLabel, + $value + ); + + case IChildEntityAuditLogFormatter::CHILD_ENTITY_UPDATE: + if (!empty($additional_info)) { + return sprintf( + "RSVP Answer for question '%s' updated: %s", + $questionLabel, + $additional_info + ); + } + return sprintf( + "RSVP Answer for question '%s' updated to '%s'", + $questionLabel, + $value + ); + + case IChildEntityAuditLogFormatter::CHILD_ENTITY_DELETION: + return sprintf( + "RSVP Answer removed for question '%s' (had value '%s')", + $questionLabel, + $value + ); + } + } catch (\Exception $ex) { + return null; + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/PresentationCategoryGroupAuditLogFormatter.php b/app/Audit/ConcreteFormatters/PresentationCategoryGroupAuditLogFormatter.php new file mode 100644 index 000000000..c96bab0d8 --- /dev/null +++ b/app/Audit/ConcreteFormatters/PresentationCategoryGroupAuditLogFormatter.php @@ -0,0 +1,78 @@ +getName() ?? 'Unknown Track Group'; + $id = $subject->getId() ?? 'unknown'; + $summit = $subject->getSummit(); + $summit_name = $summit ? ($summit->getName() ?? 'Unknown Summit') : 'Unknown Summit'; + $color = $subject->getColor() ?? 'N/A'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + + return sprintf( + "Track Group (PresentationCategoryGroup) '%s' (%d) created for Summit '%s' with color '%s', max votes: %d by user %s", + $name, + $id, + $summit_name, + $color, + $subject->getMaxAttendeeVotes(), + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Track Group (PresentationCategoryGroup) '%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( + "Track Group (PresentationCategoryGroup) '%s' (%d) for Summit '%s' with color '%s' was deleted by user %s", + $name, + $id, + $summit_name, + $color, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("PresentationCategoryGroupAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/RSVPAuditLogFormatter.php b/app/Audit/ConcreteFormatters/RSVPAuditLogFormatter.php new file mode 100644 index 000000000..883a0930e --- /dev/null +++ b/app/Audit/ConcreteFormatters/RSVPAuditLogFormatter.php @@ -0,0 +1,85 @@ +getEvent()?->getTitle() ?? 'Unknown Event'; + $ownerEmail = $subject->getOwner()?->getEmail() ?? 'Unknown Member'; + $ownerId = $subject->getOwner()?->getId() ?? 'unknown'; + $id = $subject->getId() ?? 'unknown'; + $status = $subject->getStatus() ?? 'Unknown'; + $seatType = $subject->getSeatType() ?? 'Unknown'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "RSVP created for event '%s' (ID: %s) by member %s (ID: %s) - Status: %s, Seat Type: %s, by user %s", + $eventTitle, + $subject->getEvent()?->getId() ?? 'unknown', + $ownerEmail, + $ownerId, + $status, + $seatType, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "RSVP (ID: %s) for event '%s' updated: %s by user %s", + $id, + $eventTitle, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "RSVP (ID: %s) deleted for event '%s' by member %s (ID: %s) - Final Status: %s, Seat Type: %s by user %s", + $id, + $eventTitle, + $ownerEmail, + $ownerId, + $status, + $seatType, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("RSVPAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/RSVPInvitationAuditLogFormatter.php b/app/Audit/ConcreteFormatters/RSVPInvitationAuditLogFormatter.php new file mode 100644 index 000000000..345080bba --- /dev/null +++ b/app/Audit/ConcreteFormatters/RSVPInvitationAuditLogFormatter.php @@ -0,0 +1,77 @@ +getAttendee()?->getEmail() ?? 'Unknown'; + $attendeeId = $subject->getAttendee()?->getId() ?? 'unknown'; + $eventTitle = $subject->getEvent()?->getTitle() ?? 'Unknown Event'; + $eventId = $subject->getEvent()?->getId() ?? 'unknown'; + $id = $subject->getId() ?? 'unknown'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "RSVP invitation created for attendee '%s' (ID: %s) to event '%s' (ID: %s) by user %s", + $attendeeEmail, + $attendeeId, + $eventTitle, + $eventId, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "RSVP invitation (ID: %s) for attendee '%s' to event '%s' updated: %s by user %s", + $id, + $attendeeEmail, + $eventTitle, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "RSVP invitation (ID: %s) deleted for attendee '%s' (ID: %s) to event '%s' (ID: %s) by user %s", + $id, + $attendeeEmail, + $attendeeId, + $eventTitle, + $eventId, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("RSVPInvitationAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/RSVPQuestionTemplateAuditLogFormatter.php b/app/Audit/ConcreteFormatters/RSVPQuestionTemplateAuditLogFormatter.php new file mode 100644 index 000000000..8b1709491 --- /dev/null +++ b/app/Audit/ConcreteFormatters/RSVPQuestionTemplateAuditLogFormatter.php @@ -0,0 +1,84 @@ +getName() ?? 'Unknown'; + $label = $subject->getLabel() ?? 'Unknown'; + $templateId = $subject->getTemplate()?->getId() ?? 'unknown'; + $id = $subject->getId() ?? 'unknown'; + $className = class_basename($subject); + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + $isMandatory = $subject->isMandatory() ? 'required' : 'optional'; + $order = $subject->getOrder() ?? 0; + return sprintf( + "%s question '%s' (label: '%s') created in RSVP template (ID: %s) - Position: %d, Type: %s by user %s", + $className, + $name, + $label, + $templateId, + $order, + $isMandatory, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "%s question '%s' (ID: %s) in RSVP template (ID: %s) updated: %s by user %s", + $className, + $label, + $id, + $templateId, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + $order = $subject->getOrder() ?? 0; + return sprintf( + "%s question '%s' (ID: %s, label: '%s') deleted from RSVP template (ID: %s) - Was at position %d by user %s", + $className, + $name, + $id, + $label, + $templateId, + $order, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("RSVPQuestionTemplateAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/RSVPTemplateAuditLogFormatter.php b/app/Audit/ConcreteFormatters/RSVPTemplateAuditLogFormatter.php new file mode 100644 index 000000000..086b77638 --- /dev/null +++ b/app/Audit/ConcreteFormatters/RSVPTemplateAuditLogFormatter.php @@ -0,0 +1,85 @@ +getTitle() ?? 'Unknown Template'; + $id = $subject->getId() ?? 'unknown'; + $summit = $subject->getSummit(); + $summit_name = $summit ? ($summit->getName() ?? 'Unknown Summit') : 'Unknown Summit'; + $is_enabled = $subject->isEnabled() ? 'enabled' : 'disabled'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + $created_by = $subject->getCreatedBy(); + $created_by_name = $created_by + ? sprintf("%s %s", $created_by->getFirstName() ?? '', $created_by->getLastName() ?? '') + : 'Unknown'; + $created_by_name = trim($created_by_name) ?: 'Unknown'; + + return sprintf( + "RSVP Template '%s' (%d) created for Summit '%s', status: %s, template creator: %s by user %s", + $title, + $id, + $summit_name, + $is_enabled, + $created_by_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "RSVP Template '%s' (%d) for Summit '%s' updated: %s by user %s", + $title, + $id, + $summit_name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + $question_count = $subject->getQuestions()->count(); + return sprintf( + "RSVP Template '%s' (%d) for Summit '%s' with status %s and %d questions was deleted by user %s", + $title, + $id, + $summit_name, + $is_enabled, + $question_count, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("RSVPTemplateAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitBookableVenueRoomAttributeValueAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitBookableVenueRoomAttributeValueAuditLogFormatter.php new file mode 100644 index 000000000..81561ad31 --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitBookableVenueRoomAttributeValueAuditLogFormatter.php @@ -0,0 +1,71 @@ +getValue() ?? 'Unknown Value'; + $type = $subject->getType(); + $type_name = $type ? ($type->getType() ?? 'Unknown Type') : 'Unknown Type'; + $id = $subject->getId() ?? 'unknown'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Summit Bookable Venue Room Attribute Value (%d) '%s' Type '%s' created by user %s", + $id, + $value, + $type_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Summit Bookable Venue Room Attribute Value (%d) '%s' updated: %s by user %s", + $id, + $value, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Summit Bookable Venue Room Attribute Value (%d) '%s' was deleted by user %s", + $id, + $value, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitBookableVenueRoomAttributeValueAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitEventTypeAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitEventTypeAuditLogFormatter.php new file mode 100644 index 000000000..087d9b614 --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitEventTypeAuditLogFormatter.php @@ -0,0 +1,81 @@ +getType() ?? 'Unknown Type'; + $id = $subject->getId() ?? 'unknown'; + $summit = $subject->getSummit(); + $summit_name = $summit ? ($summit->getName() ?? 'Unknown Summit') : 'Unknown Summit'; + $color = $subject->getColor() ?? 'N/A'; + $is_default = $subject->isDefault() ? 'yes' : 'no'; + $is_private = $subject->isPrivate() ? 'yes' : 'no'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + + return sprintf( + "Event Type '%s' (%d) created for Summit '%s' with color '%s', default: %s, private: %s by user %s", + $type, + $id, + $summit_name, + $color, + $is_default, + $is_private, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Event Type '%s' (%d) for Summit '%s' updated: %s by user %s", + $type, + $id, + $summit_name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Event Type '%s' (%d) for Summit '%s' with color '%s' was deleted by user %s", + $type, + $id, + $summit_name, + $color, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitEventTypeAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitMetricAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitMetricAuditLogFormatter.php new file mode 100644 index 000000000..413847097 --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitMetricAuditLogFormatter.php @@ -0,0 +1,73 @@ +getType() ?? 'Unknown 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( + "Summit Metric Type '%s' (%d) created for Summit '%s' by user %s", + $type, + $id, + $summit_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Summit Metric Type '%s' (%d) for Summit '%s' updated: %s by user %s", + $type, + $id, + $summit_name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Summit Metric Type '%s' (%d) for Summit '%s' was deleted by user %s", + $type, + $id, + $summit_name, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitMetricAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitPresentationCommentAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitPresentationCommentAuditLogFormatter.php new file mode 100644 index 000000000..db473e23f --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitPresentationCommentAuditLogFormatter.php @@ -0,0 +1,72 @@ +getPresentation(); + $presentation_name = $presentation ? ($presentation->getTitle() ?? 'Unknown Presentation') : 'Unknown Presentation'; + $creator = $subject->getCreator(); + $creator_name = $creator ? ($creator->getFullName() ?? 'Unknown Creator') : 'Unknown Creator'; + $id = $subject->getId() ?? 'unknown'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Presentation Comment (%d) on '%s' by '%s' created by user %s", + $id, + $presentation_name, + $creator_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Presentation Comment (%d) on '%s' updated: %s by user %s", + $id, + $presentation_name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Presentation Comment (%d) on '%s' was deleted by user %s", + $id, + $presentation_name, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitPresentationCommentAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitProposedScheduleAllowedLocationAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitProposedScheduleAllowedLocationAuditLogFormatter.php new file mode 100644 index 000000000..2870e3ec2 --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitProposedScheduleAllowedLocationAuditLogFormatter.php @@ -0,0 +1,74 @@ +getTrack(); + $track_name = $track ? ($track->getTitle() ?? 'Unknown Track') : 'Unknown Track'; + $location = $subject->getLocation(); + $location_name = $location ? ($location->getName() ?? 'Unknown Location') : 'Unknown Location'; + $id = $subject->getId() ?? 'unknown'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Proposed Schedule Allowed Location (%d) Track '%s' Location '%s' created by user %s", + $id, + $track_name, + $location_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Proposed Schedule Allowed Location (%d) Track '%s' Location '%s' updated: %s by user %s", + $id, + $track_name, + $location_name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Proposed Schedule Allowed Location (%d) Track '%s' Location '%s' was deleted by user %s", + $id, + $track_name, + $location_name, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitProposedScheduleAllowedLocationAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitSelectedPresentationAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitSelectedPresentationAuditLogFormatter.php new file mode 100644 index 000000000..cbadfbb4a --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitSelectedPresentationAuditLogFormatter.php @@ -0,0 +1,74 @@ +getPresentation(); + $presentation_name = $presentation ? ($presentation->getTitle() ?? 'Unknown Presentation') : 'Unknown Presentation'; + $collection = $subject->getCollection(); + $member = $subject->getMember(); + $member_name = $member ? ($member->getFullName() ?? 'Unknown Member') : 'Unknown Member'; + $id = $subject->getId() ?? 'unknown'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Selected Presentation (%d) '%s' Collection '%s' by '%s' created by user %s", + $id, + $presentation_name, + $collection, + $member_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Selected Presentation (%d) '%s' updated: %s by user %s", + $id, + $presentation_name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Selected Presentation (%d) '%s' was deleted by user %s", + $id, + $presentation_name, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitSelectedPresentationAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitSelectedPresentationListAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitSelectedPresentationListAuditLogFormatter.php new file mode 100644 index 000000000..34c889bb6 --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitSelectedPresentationListAuditLogFormatter.php @@ -0,0 +1,76 @@ +getName() ?? 'Unknown List'; + $list_type = $subject->getListType() ?? 'Unknown Type'; + $category = $subject->getCategory(); + $category_name = $category ? ($category->getTitle() ?? 'Unknown Category') : 'Unknown Category'; + $owner = $subject->getOwner(); + $owner_name = $owner ? ($owner->getFullName() ?? 'Unknown Owner') : 'Unknown Owner'; + $id = $subject->getId() ?? 'unknown'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Selected Presentation List (%d) '%s' Type '%s' Category '%s' Owner '%s' created by user %s", + $id, + $name, + $list_type, + $category_name, + $owner_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Selected Presentation List (%d) '%s' updated: %s by user %s", + $id, + $name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Selected Presentation List (%d) '%s' was deleted by user %s", + $id, + $name, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitSelectedPresentationListAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/app/Audit/ConcreteFormatters/SummitSponsorshipAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitSponsorshipAuditLogFormatter.php new file mode 100644 index 000000000..280f0e224 --- /dev/null +++ b/app/Audit/ConcreteFormatters/SummitSponsorshipAuditLogFormatter.php @@ -0,0 +1,74 @@ +getSponsor(); + $sponsor_name = $sponsor ? ($sponsor->getName() ?? 'Unknown Sponsor') : 'Unknown Sponsor'; + $sponsorship_type = $subject->getType(); + $type_name = $sponsorship_type ? ($sponsorship_type->getName() ?? 'Unknown Type') : 'Unknown Type'; + $id = $subject->getId() ?? 'unknown'; + + switch ($this->event_type) { + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Summit Sponsorship (%d) for Sponsor '%s' Type '%s' created by user %s", + $id, + $sponsor_name, + $type_name, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Summit Sponsorship (%d) for Sponsor '%s' Type '%s' updated: %s by user %s", + $id, + $sponsor_name, + $type_name, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Summit Sponsorship (%d) for Sponsor '%s' Type '%s' was deleted by user %s", + $id, + $sponsor_name, + $type_name, + $this->getUserInfo() + ); + } + } catch (\Exception $ex) { + Log::warning("SummitSponsorshipAuditLogFormatter error: " . $ex->getMessage()); + } + + return null; + } +} diff --git a/config/audit_log.php b/config/audit_log.php index 51462a6b5..8923ec688 100644 --- a/config/audit_log.php +++ b/config/audit_log.php @@ -124,5 +124,33 @@ 'enabled' => true, 'strategy' => \App\Audit\ConcreteFormatters\SummitVenueRoomAuditLogFormatter::class, ], + \models\summit\SummitMetric::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitMetricAuditLogFormatter::class, + ], + \models\summit\SummitSponsorship::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitSponsorshipAuditLogFormatter::class, + ], + \models\summit\SummitPresentationComment::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitPresentationCommentAuditLogFormatter::class, + ], + \App\Models\Foundation\Summit\ProposedSchedule\SummitProposedScheduleAllowedLocation::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitProposedScheduleAllowedLocationAuditLogFormatter::class, + ], + \models\summit\SummitSelectedPresentation::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitSelectedPresentationAuditLogFormatter::class, + ], + \models\summit\SummitBookableVenueRoomAttributeValue::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitBookableVenueRoomAttributeValueAuditLogFormatter::class, + ], + \models\summit\SummitSelectedPresentationList::class => [ + 'enabled' => true, + 'strategy' => \App\Audit\ConcreteFormatters\SummitSelectedPresentationListAuditLogFormatter::class, + ], ] ]; From 4c408d134762b4ee514f776fd85bc791ee19268a Mon Sep 17 00:00:00 2001 From: Jose Andres Tejerina Date: Mon, 29 Dec 2025 15:25:50 -0300 Subject: [PATCH 2/3] feat: add user context and id for generic entities --- .../EntityCreationAuditLogFormatter.php | 11 ++++++++++- .../EntityDeletionAuditLogFormatter.php | 7 +++++-- .../EntityUpdateAuditLogFormatter.php | 9 +++++++-- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/app/Audit/ConcreteFormatters/EntityCreationAuditLogFormatter.php b/app/Audit/ConcreteFormatters/EntityCreationAuditLogFormatter.php index 8ca836e18..608a381c4 100644 --- a/app/Audit/ConcreteFormatters/EntityCreationAuditLogFormatter.php +++ b/app/Audit/ConcreteFormatters/EntityCreationAuditLogFormatter.php @@ -25,6 +25,11 @@ */ class EntityCreationAuditLogFormatter extends AbstractAuditLogFormatter { + public function __construct() + { + parent::__construct('entity_creation'); + } + protected function getCreationIgnoredEntities(): array { return [ 'PresentationAction', @@ -39,6 +44,10 @@ public function format($subject, $change_set): ?string { $class_name = (new ReflectionClass($subject))->getShortName(); $ignored_entities = $this->getCreationIgnoredEntities(); if (in_array($class_name, $ignored_entities)) return null; - return "{$class_name} created"; + + $entity_id = method_exists($subject, 'getId') ? $subject->getId() : 'N/A'; + $user_info = $this->getUserInfo(); + + return "{$class_name} (ID: {$entity_id}) created by {$user_info}"; } } diff --git a/app/Audit/ConcreteFormatters/EntityDeletionAuditLogFormatter.php b/app/Audit/ConcreteFormatters/EntityDeletionAuditLogFormatter.php index 9e2ac8ed7..ea48bf22f 100644 --- a/app/Audit/ConcreteFormatters/EntityDeletionAuditLogFormatter.php +++ b/app/Audit/ConcreteFormatters/EntityDeletionAuditLogFormatter.php @@ -31,8 +31,9 @@ class EntityDeletionAuditLogFormatter extends AbstractAuditLogFormatter */ private $child_entity_formatter; - public function __construct(?IChildEntityAuditLogFormatter $child_entity_formatter) + public function __construct(?IChildEntityAuditLogFormatter $child_entity_formatter = null) { + parent::__construct('entity_deletion'); $this->child_entity_formatter = $child_entity_formatter; } @@ -56,6 +57,8 @@ public function format($subject, $change_set): ?string { ->format($subject, IChildEntityAuditLogFormatter::CHILD_ENTITY_DELETION); } - return "{$class_name} deleted"; + $entity_id = method_exists($subject, 'getId') ? $subject->getId() : 'unknown'; + $user_info = $this->getUserInfo(); + return "{$class_name} (ID: {$entity_id}) deleted by {$user_info}"; } } diff --git a/app/Audit/ConcreteFormatters/EntityUpdateAuditLogFormatter.php b/app/Audit/ConcreteFormatters/EntityUpdateAuditLogFormatter.php index 63bafe327..514959ff3 100644 --- a/app/Audit/ConcreteFormatters/EntityUpdateAuditLogFormatter.php +++ b/app/Audit/ConcreteFormatters/EntityUpdateAuditLogFormatter.php @@ -37,8 +37,9 @@ class EntityUpdateAuditLogFormatter extends AbstractAuditLogFormatter */ private $child_entity_formatter; - public function __construct(?IChildEntityAuditLogFormatter $child_entity_formatter) + public function __construct(?IChildEntityAuditLogFormatter $child_entity_formatter = null) { + parent::__construct('entity_update'); $this->child_entity_formatter = $child_entity_formatter; } @@ -157,6 +158,10 @@ public function format($subject, $change_set): ?string if (count($res) == 0) return null; - return join("|", $res); + $entity_id = method_exists($subject, 'getId') ? $subject->getId() : 'N/A'; + $user_info = $this->getUserInfo(); + $message = join("|", $res); + + return "{$class_name} (ID: {$entity_id}) updated by {$user_info}: {$message}"; } } From 292800e097d6d55fc55b87e5a1d6b327781191de Mon Sep 17 00:00:00 2001 From: Jose Andres Tejerina Date: Mon, 29 Dec 2025 15:33:16 -0300 Subject: [PATCH 3/3] fix: refactor for old formatters --- .../BasePresentationAuditLogFormatter.php | 1 + .../PresentationSpeakerAuditLogFormatter.php | 33 ++-------------- ...resentationSubmissionAuditLogFormatter.php | 17 ++------ .../SpeakerAssistanceAuditLogFormatter.php | 32 ++------------- .../SummitMemberScheduleAuditLogFormatter.php | 39 ++++++++++++++++--- 5 files changed, 44 insertions(+), 78 deletions(-) diff --git a/app/Audit/ConcreteFormatters/PresentationFormatters/BasePresentationAuditLogFormatter.php b/app/Audit/ConcreteFormatters/PresentationFormatters/BasePresentationAuditLogFormatter.php index 6d548b07e..339b6bdf2 100644 --- a/app/Audit/ConcreteFormatters/PresentationFormatters/BasePresentationAuditLogFormatter.php +++ b/app/Audit/ConcreteFormatters/PresentationFormatters/BasePresentationAuditLogFormatter.php @@ -106,6 +106,7 @@ public function format($subject, array $change_set): ?string case IAuditStrategy::EVENT_ENTITY_UPDATE: $extracted = $this->extractChangedFields($change_set); + $extracted['change_set'] = $change_set; return $this->formatUpdate($data, $extracted); case IAuditStrategy::EVENT_ENTITY_DELETION: diff --git a/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationSpeakerAuditLogFormatter.php b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationSpeakerAuditLogFormatter.php index d9bdf1d2b..f772d130e 100644 --- a/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationSpeakerAuditLogFormatter.php +++ b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationSpeakerAuditLogFormatter.php @@ -46,39 +46,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'])) { - $changed_fields[] = "email"; - } - if (isset($change_set['Title'])) { - $changed_fields[] = "title"; - } - - if (isset($change_set['Country'])) { - $changed_fields[] = "country"; - } - if (isset($change_set['AvailableForBureau'])) { - $changed_fields[] = "available_for_bureau"; - } - if (isset($change_set['FundedTravel'])) { - $changed_fields[] = "funded_travel"; - } - if (isset($change_set['WillingToTravel'])) { - $changed_fields[] = "willing_to_travel"; - } - if (isset($change_set['WillingToPresentVideo'])) { - $changed_fields[] = "willing_to_present_video"; - } - - $fields_str = !empty($changed_fields) ? implode(', ', $changed_fields) : 'properties'; + $change_details = $this->buildChangeDetails($change_set); return sprintf( - "Speaker '%s' (%s) updated (%s changed) by user %s", + "Speaker '%s' (%s) updated: %s by user %s", $full_name, $speaker_id, - $fields_str, + $change_details, $this->getUserInfo() ); diff --git a/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationSubmissionAuditLogFormatter.php b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationSubmissionAuditLogFormatter.php index 1343f4c0f..3e4795d20 100644 --- a/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationSubmissionAuditLogFormatter.php +++ b/app/Audit/ConcreteFormatters/PresentationFormatters/PresentationSubmissionAuditLogFormatter.php @@ -32,23 +32,12 @@ protected function formatCreation(array $data): string protected function formatUpdate(array $data, array $extracted): string { - if ($extracted['old_status'] && $extracted['new_status']) { - return sprintf( - "Presentation '%s' (%s) status changed: %s → %s (%s changed) by user %s", - $data['title'], - $data['id'], - strtoupper($extracted['old_status']), - strtoupper($extracted['new_status']), - $extracted['fields'], - $this->getUserInfo() - ); - } - + $change_details = $this->buildChangeDetails($extracted['change_set']); return sprintf( - "Presentation '%s' (%s) updated (%s changed) by user %s", + "Presentation '%s' (%s) updated: %s by user %s", $data['title'], $data['id'], - $extracted['fields'], + $change_details, $this->getUserInfo() ); } diff --git a/app/Audit/ConcreteFormatters/SpeakerAssistanceAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SpeakerAssistanceAuditLogFormatter.php index 1a8e04a75..c46827e55 100644 --- a/app/Audit/ConcreteFormatters/SpeakerAssistanceAuditLogFormatter.php +++ b/app/Audit/ConcreteFormatters/SpeakerAssistanceAuditLogFormatter.php @@ -17,7 +17,7 @@ use App\Audit\AbstractAuditLogFormatter; use App\Audit\Interfaces\IAuditStrategy; -use models\summit\SpeakerAssistanceRequest; +use models\summit\PresentationSpeakerSummitAssistanceConfirmationRequest; use Illuminate\Support\Facades\Log; class SpeakerAssistanceAuditLogFormatter extends AbstractAuditLogFormatter @@ -56,37 +56,13 @@ public function format($subject, array $change_set): ?string ); case IAuditStrategy::EVENT_ENTITY_UPDATE: - $changed_fields = []; - - if (isset($change_set['IsConfirmed'])) { - $old_status = $change_set['IsConfirmed'][0] ? 'confirmed' : 'pending'; - $new_status = $change_set['IsConfirmed'][1] ? 'confirmed' : 'pending'; - $changed_fields[] = sprintf("confirmation %s → %s", $old_status, $new_status); - } - if (isset($change_set['CheckedIn'])) { - $old_status = $change_set['CheckedIn'][0] ? 'checked_in' : 'not_checked_in'; - $new_status = $change_set['CheckedIn'][1] ? 'checked_in' : 'not_checked_in'; - $changed_fields[] = sprintf("check_in %s → %s", $old_status, $new_status); - } - if (isset($change_set['RegisteredForSummit'])) { - $old_status = $change_set['RegisteredForSummit'][0] ? 'registered' : 'unregistered'; - $new_status = $change_set['RegisteredForSummit'][1] ? 'registered' : 'unregistered'; - $changed_fields[] = sprintf("registration %s → %s", $old_status, $new_status); - } - if (isset($change_set['OnSitePhoneNumber'])) { - $changed_fields[] = "on_site_phone"; - } - if (isset($change_set['ConfirmationDate'])) { - $changed_fields[] = "confirmation_date"; - } - - $fields_str = !empty($changed_fields) ? implode(', ', $changed_fields) : 'properties'; + $change_details = $this->buildChangeDetails($change_set); return sprintf( - "Speaker assistance for '%s' (%s) on Summit '%s' updated (%s changed) by user %s", + "Speaker assistance for '%s' (%s) on Summit '%s' updated: %s by user %s", $speaker_name, $speaker_id, $summit_name, - $fields_str, + $change_details, $this->getUserInfo() ); diff --git a/app/Audit/ConcreteFormatters/SummitMemberScheduleAuditLogFormatter.php b/app/Audit/ConcreteFormatters/SummitMemberScheduleAuditLogFormatter.php index ce00d0cf6..d9c45a969 100644 --- a/app/Audit/ConcreteFormatters/SummitMemberScheduleAuditLogFormatter.php +++ b/app/Audit/ConcreteFormatters/SummitMemberScheduleAuditLogFormatter.php @@ -18,6 +18,11 @@ class SummitMemberScheduleAuditLogFormatter extends AbstractAuditLogFormatter { + public function __construct() + { + parent::__construct('summit_member_schedule'); + } + /** * @param $subject * @param array $change_set @@ -27,13 +32,35 @@ public function format($subject, array $change_set): ?string { if(!$subject instanceof SummitMemberSchedule) return null; $summit_event = $subject->getEvent(); + $event_title = $summit_event ? ($summit_event->getTitle() ?? 'Unknown Event') : 'Unknown Event'; + $event_id = $summit_event ? ($summit_event->getId() ?? 'unknown') : 'unknown'; + switch($this->event_type) { - case IAuditStrategy::EVENT_ENTITY_DELETION:{ - return sprintf("Activity %s (%s) was removed from user custom schedule.", $summit_event->getTitle(), $summit_event->getId()); - } - case IAuditStrategy::EVENT_ENTITY_CREATION:{ - return sprintf("Activity %s (%s) was inserted onto user custom schedule.", $summit_event->getTitle(), $summit_event->getId()); - } + case IAuditStrategy::EVENT_ENTITY_CREATION: + return sprintf( + "Activity '%s' (%s) was inserted onto user custom schedule by user %s", + $event_title, + $event_id, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_UPDATE: + $change_details = $this->buildChangeDetails($change_set); + return sprintf( + "Activity '%s' (%s) in user custom schedule updated: %s by user %s", + $event_title, + $event_id, + $change_details, + $this->getUserInfo() + ); + + case IAuditStrategy::EVENT_ENTITY_DELETION: + return sprintf( + "Activity '%s' (%s) was removed from user custom schedule by user %s", + $event_title, + $event_id, + $this->getUserInfo() + ); } return null; }