Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughAdds a new Changes
Sequence DiagramsequenceDiagram
participant User as User
participant Afform as Afform Submit Event
participant Service as UrbanExternalMeetingService
participant API as CiviCRM API4
participant DB as Database
User->>Afform: Submit form (afformUrbanExternalMeetingSession)
Afform->>Service: civi.afform.submit
Service->>Service: Check form name & entity type
Service->>Service: Extract contact IDs from records
loop for each contact ID
Service->>API: Create Activity (API4::create with fields)
API->>DB: Persist activity
API-->>Service: Success / throws \CiviCRM_API4_Exception
Service->>Service: Log error on exception
end
Service-->>Afform: Processing complete
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@wp-content/civi-extensions/goonjcustom/Civi/UrbanExternalMeetingService.php`:
- Around line 80-93: The createActivityForContact function currently only
catches \CiviCRM_API4_Exception so unexpected runtime errors can abort the
submission loop; update the exception handling around Activity::create(...) in
createActivityForContact to also catch generic failures (preferably \Throwable
or at least \Exception) and log the full error (message and optionally trace)
using \Civi::log()->error, while preserving the existing CiviCRM_API4_Exception
handling semantics so the method swallows errors and allows processing to
continue for remaining records.
- Around line 38-64: Remove the raw PHP error_log calls in
UrbanExternalMeetingService.php that print full $fields, $individualOrPocId, and
$institutionId within the event handling loop; instead use the application's
logger (or a debug-only logger) to emit non-PII, sanitized messages (e.g., log
only a boolean/presence flag, record ID, or masked identifiers) and guard those
logs behind a configurable debug flag. Locate the logging in the block that
checks self::FORM_NAME and entityType (Eck_Meetings_Sessions) and inside the
foreach over $event->records where $fields, $individualOrPocId, and
$institutionId are read, remove or replace the error_log calls with
sanitized/conditional logging so PII is not written to PHP error logs.
- Around line 57-73: The record parsing assumes $record['fields'] exists and may
call createActivityForContact twice for the same ID; update the loop over
$event->records in UrbanExternalMeetingService to first verify that
$record['fields'] is set and is an array (skip or log and continue otherwise),
safely extract and normalize the two candidate IDs
(Urban_Meetings.Select_Individual and Urban_Meetings.Institution) into scalars
(cast/trim), build a deduplicated list or set of non-empty IDs, and then iterate
that deduplicated list calling self::createActivityForContact only once per
unique ID; reference the variables $record['fields'], $individualOrPocId,
$institutionId and the method createActivityForContact when making the changes.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 986d3f42-71fc-45fc-8218-28ae1a0047dc
📒 Files selected for processing (1)
wp-content/civi-extensions/goonjcustom/Civi/UrbanExternalMeetingService.php
| foreach ($event->records as $record) { | ||
| $fields = $record['fields']; | ||
| error_log('Record fields: ' . print_r($fields, TRUE)); | ||
|
|
||
| $individualOrPocId = $fields['Urban_Meetings.Select_Individual'] ?? NULL; | ||
| error_log('individualOrPocId: ' . print_r($individualOrPocId, TRUE)); | ||
| $institutionId = $fields['Urban_Meetings.Institution'] ?? NULL; | ||
| error_log('institutionId: ' . print_r($institutionId, TRUE)); | ||
|
|
||
|
|
||
| if ($individualOrPocId) { | ||
| self::createActivityForContact($individualOrPocId); | ||
| } | ||
|
|
||
| if ($institutionId) { | ||
| self::createActivityForContact($institutionId); | ||
| } |
There was a problem hiding this comment.
Harden record parsing and deduplicate contact IDs before activity creation.
Line 58 assumes fields always exists, and Lines 67-73 can create duplicate activities if both fields resolve to the same contact ID.
Proposed fix
foreach ($event->records as $record) {
- $fields = $record['fields'];
-
- $individualOrPocId = $fields['Urban_Meetings.Select_Individual'] ?? NULL;
- $institutionId = $fields['Urban_Meetings.Institution'] ?? NULL;
-
-
- if ($individualOrPocId) {
- self::createActivityForContact($individualOrPocId);
- }
-
- if ($institutionId) {
- self::createActivityForContact($institutionId);
- }
+ $fields = $record['fields'] ?? [];
+ if (!$fields) {
+ continue;
+ }
+
+ $contactIds = array_filter([
+ $fields['Urban_Meetings.Select_Individual'] ?? NULL,
+ $fields['Urban_Meetings.Institution'] ?? NULL,
+ ], static fn($id) => is_scalar($id) && (int) $id > 0);
+
+ foreach (array_unique(array_map('intval', $contactIds)) as $contactId) {
+ self::createActivityForContact($contactId);
+ }
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@wp-content/civi-extensions/goonjcustom/Civi/UrbanExternalMeetingService.php`
around lines 57 - 73, The record parsing assumes $record['fields'] exists and
may call createActivityForContact twice for the same ID; update the loop over
$event->records in UrbanExternalMeetingService to first verify that
$record['fields'] is set and is an array (skip or log and continue otherwise),
safely extract and normalize the two candidate IDs
(Urban_Meetings.Select_Individual and Urban_Meetings.Institution) into scalars
(cast/trim), build a deduplicated list or set of non-empty IDs, and then iterate
that deduplicated list calling self::createActivityForContact only once per
unique ID; reference the variables $record['fields'], $individualOrPocId,
$institutionId and the method createActivityForContact when making the changes.
| private static function createActivityForContact(int $contactId) { | ||
| try { | ||
| Activity::create(FALSE) | ||
| ->addValue('subject', self::ACTIVITY_SUBJECT) | ||
| ->addValue('activity_type_id:name', self::ACTIVITY_TYPE_NAME) | ||
| ->addValue('status_id:name', self::ACTIVITY_STATUS) | ||
| ->addValue('activity_date_time', date('Y-m-d H:i:s')) | ||
| ->addValue('source_contact_id', $contactId) | ||
| ->addValue('target_contact_id', $contactId) | ||
| ->execute(); | ||
| } | ||
| catch (\CiviCRM_API4_Exception $ex) { | ||
| \Civi::log()->error('Exception while creating Urban External Meeting Session activity for contact ' . $contactId . ': ' . $ex->getMessage()); | ||
| } |
There was a problem hiding this comment.
Broaden exception handling to avoid aborting the submission loop on unexpected failures.
Only \CiviCRM_API4_Exception is caught. Runtime issues (type/conversion/data shape) will currently bubble up and stop processing remaining records.
Proposed fix
- catch (\CiviCRM_API4_Exception $ex) {
+ catch (\Throwable $ex) {
\Civi::log()->error('Exception while creating Urban External Meeting Session activity for contact ' . $contactId . ': ' . $ex->getMessage());
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| private static function createActivityForContact(int $contactId) { | |
| try { | |
| Activity::create(FALSE) | |
| ->addValue('subject', self::ACTIVITY_SUBJECT) | |
| ->addValue('activity_type_id:name', self::ACTIVITY_TYPE_NAME) | |
| ->addValue('status_id:name', self::ACTIVITY_STATUS) | |
| ->addValue('activity_date_time', date('Y-m-d H:i:s')) | |
| ->addValue('source_contact_id', $contactId) | |
| ->addValue('target_contact_id', $contactId) | |
| ->execute(); | |
| } | |
| catch (\CiviCRM_API4_Exception $ex) { | |
| \Civi::log()->error('Exception while creating Urban External Meeting Session activity for contact ' . $contactId . ': ' . $ex->getMessage()); | |
| } | |
| private static function createActivityForContact(int $contactId) { | |
| try { | |
| Activity::create(FALSE) | |
| ->addValue('subject', self::ACTIVITY_SUBJECT) | |
| ->addValue('activity_type_id:name', self::ACTIVITY_TYPE_NAME) | |
| ->addValue('status_id:name', self::ACTIVITY_STATUS) | |
| ->addValue('activity_date_time', date('Y-m-d H:i:s')) | |
| ->addValue('source_contact_id', $contactId) | |
| ->addValue('target_contact_id', $contactId) | |
| ->execute(); | |
| } | |
| catch (\Throwable $ex) { | |
| \Civi::log()->error('Exception while creating Urban External Meeting Session activity for contact ' . $contactId . ': ' . $ex->getMessage()); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@wp-content/civi-extensions/goonjcustom/Civi/UrbanExternalMeetingService.php`
around lines 80 - 93, The createActivityForContact function currently only
catches \CiviCRM_API4_Exception so unexpected runtime errors can abort the
submission loop; update the exception handling around Activity::create(...) in
createActivityForContact to also catch generic failures (preferably \Throwable
or at least \Exception) and log the full error (message and optionally trace)
using \Civi::log()->error, while preserving the existing CiviCRM_API4_Exception
handling semantics so the method swallows errors and allows processing to
continue for remaining records.
Meeting workflow
Summary by CodeRabbit