canAccessTenant($tenant)) { throw new NotFoundHttpException; } Gate::forUser($actor)->authorize(Capabilities::ENVIRONMENT_REVIEW_ACKNOWLEDGE, $tenant); if ((int) $review->managed_environment_id !== (int) $tenant->getKey()) { throw new NotFoundHttpException; } if ((int) $review->workspace_id !== (int) $tenant->workspace_id) { throw new NotFoundHttpException; } if (! $review->isPublished()) { throw new InvalidArgumentException('Only published reviews can be acknowledged.'); } $comment = is_string($comment) ? trim($comment) : null; $comment = $comment !== null && $comment !== '' ? $comment : null; if (is_string($comment) && mb_strlen($comment) > 2000) { throw new InvalidArgumentException('comment must be at most 2000 characters.'); } $acknowledgedAt = CarbonImmutable::now(); $ack = EnvironmentReviewAcknowledgement::query()->updateOrCreate( ['environment_review_id' => (int) $review->getKey()], [ 'managed_environment_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'acknowledged_at' => $acknowledgedAt, 'acknowledged_by_user_id' => (int) $actor->getKey(), 'comment' => $comment, 'evidence_snapshot_id' => is_numeric($review->evidence_snapshot_id) ? (int) $review->evidence_snapshot_id : null, 'review_pack_id' => is_numeric($review->current_export_review_pack_id) ? (int) $review->current_export_review_pack_id : null, ], ); $workspace = $tenant->workspace; if ($workspace !== null) { $this->audit->log( workspace: $workspace, action: AuditActionId::EnvironmentReviewAcknowledged, context: [ 'metadata' => [ 'review_id' => (int) $review->getKey(), 'acknowledgement_id' => (int) $ack->getKey(), 'review_pack_id' => is_numeric($review->current_export_review_pack_id) ? (int) $review->current_export_review_pack_id : null, 'evidence_snapshot_id' => is_numeric($review->evidence_snapshot_id) ? (int) $review->evidence_snapshot_id : null, ], ], actor: $actor, resourceType: 'environment_review', resourceId: (string) $review->getKey(), targetLabel: sprintf('ManagedEnvironment review #%d', (int) $review->getKey()), tenant: $tenant, ); } return $ack; } }