|
13 | 13 | **/ |
14 | 14 |
|
15 | 15 | use App\Http\Controllers\Utils\Assertions; |
16 | | -use App\Http\Utils\BooleanCellFormatter; |
17 | 16 | use App\Http\Utils\EpochCellFormatter; |
18 | 17 | use App\Models\Foundation\Main\IGroup; |
19 | 18 | use App\ModelSerializers\SerializerUtils; |
20 | 19 | use App\Security\SummitScopes; |
21 | 20 | use App\Services\Model\ISummitRSVPService; |
22 | 21 | use Illuminate\Http\Response; |
| 22 | +use Illuminate\Support\Facades\Request; |
| 23 | +use Illuminate\Support\Facades\Validator; |
23 | 24 | use models\oauth2\IResourceServerContext; |
24 | 25 | use models\summit\IRSVPRepository; |
25 | 26 | use models\summit\ISummitEventRepository; |
|
29 | 30 | use OpenApi\Attributes as OA; |
30 | 31 | use utils\Filter; |
31 | 32 | use utils\FilterElement; |
| 33 | +use utils\FilterParser; |
32 | 34 |
|
33 | 35 |
|
34 | 36 | class OAuth2RSVPApiController extends OAuth2ProtectedController |
@@ -427,6 +429,166 @@ function () { |
427 | 429 | }); |
428 | 430 | } |
429 | 431 |
|
| 432 | + #[OA\Put( |
| 433 | + path: "/api/v1/summits/{id}/events/{event_id}/rsvps/resend", |
| 434 | + description: "required-groups " . IGroup::SummitAdministrators . ", " . IGroup::SuperAdmins . ", " . IGroup::Administrators, |
| 435 | + summary: 'Resend RSVP Confirmation Emails for event', |
| 436 | + operationId: 'resendRSVP', |
| 437 | + tags: ['RSVP'], |
| 438 | + x: [ |
| 439 | + 'required-groups' => [ |
| 440 | + IGroup::SummitAdministrators, |
| 441 | + IGroup::SuperAdmins, |
| 442 | + IGroup::Administrators |
| 443 | + ] |
| 444 | + ], |
| 445 | + security: [['summit_rsvp_oauth2' => [ |
| 446 | + SummitScopes::WriteSummitData, |
| 447 | + ]]], |
| 448 | + parameters: [ |
| 449 | + new OA\Parameter( |
| 450 | + name: 'access_token', |
| 451 | + in: 'query', |
| 452 | + required: false, |
| 453 | + description: 'OAuth2 access token (alternative to Authorization: Bearer)', |
| 454 | + schema: new OA\Schema(type: 'string', example: 'eyJhbGciOi...'), |
| 455 | + ), |
| 456 | + new OA\Parameter( |
| 457 | + name: 'summit_id', |
| 458 | + in: 'path', |
| 459 | + required: true, |
| 460 | + schema: new OA\Schema(type: 'integer'), |
| 461 | + description: 'The summit id' |
| 462 | + ), |
| 463 | + new OA\Parameter( |
| 464 | + name: 'event_id', |
| 465 | + in: 'path', |
| 466 | + required: true, |
| 467 | + schema: new OA\Schema(type: 'string'), |
| 468 | + description: 'The event id' |
| 469 | + ), |
| 470 | + // query string params |
| 471 | + new OA\Parameter( |
| 472 | + name: 'filter[]', |
| 473 | + in: 'query', |
| 474 | + required: false, |
| 475 | + description: 'Filter expressions in the format field<op>value. Operators: @@, ==, =@.', |
| 476 | + style: 'form', |
| 477 | + explode: true, |
| 478 | + schema: new OA\Schema( |
| 479 | + type: 'array', |
| 480 | + items: new OA\ Items(type: 'string', example: 'owner_email@@[email protected]') |
| 481 | + ) |
| 482 | + ), |
| 483 | + new OA\Parameter( |
| 484 | + name: 'order', |
| 485 | + in: 'query', |
| 486 | + required: false, |
| 487 | + description: 'Order by field(s)', |
| 488 | + schema: new OA\Schema(type: 'string', example: 'id,-seat_type') |
| 489 | + ), |
| 490 | + new OA\Parameter( |
| 491 | + name: 'expand', |
| 492 | + in: 'query', |
| 493 | + required: false, |
| 494 | + description: 'Comma-separated list of related resources to include', |
| 495 | + schema: new OA\Schema(type: 'string', example: 'event,owner') |
| 496 | + ), |
| 497 | + new OA\Parameter( |
| 498 | + name: 'relations', |
| 499 | + in: 'query', |
| 500 | + required: false, |
| 501 | + description: 'Relations to load eagerly', |
| 502 | + schema: new OA\Schema(type: 'string', example: 'event,owner') |
| 503 | + ), |
| 504 | + new OA\Parameter( |
| 505 | + name: 'fields', |
| 506 | + in: 'query', |
| 507 | + required: false, |
| 508 | + description: 'Comma-separated list of fields to return', |
| 509 | + schema: new OA\Schema(type: 'string', example: 'id,seat_type,owner.first_name,owner.last_name') |
| 510 | + ), |
| 511 | + ], |
| 512 | + requestBody: new OA\RequestBody( |
| 513 | + required: true, |
| 514 | + content: new OA\JsonContent(ref: "#/components/schemas/ReSendRSVPConfirmationRequest") |
| 515 | + ), |
| 516 | + responses: [ |
| 517 | + new OA\Response( |
| 518 | + response: 200, |
| 519 | + description: 'RSVP Confirmation send success', |
| 520 | + ), |
| 521 | + new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"), |
| 522 | + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "not found"), |
| 523 | + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), |
| 524 | + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error") |
| 525 | + ] |
| 526 | + )] |
| 527 | + |
| 528 | + public function resend($summit_id, $event_id) |
| 529 | + { |
| 530 | + return $this->processRequest(function () use ($summit_id, $event_id) { |
| 531 | + |
| 532 | + if (!Request::isJson()) return $this->error400(); |
| 533 | + $data = Request::json(); |
| 534 | + |
| 535 | + $summit = $this->getSummitOr404($summit_id); |
| 536 | + $summit_event = $this->getEventOr404($summit, $event_id); |
| 537 | + $this->getCurrentMemberOr403(); |
| 538 | + |
| 539 | + $payload = $data->all(); |
| 540 | + |
| 541 | + // Creates a Validator instance and validates the data. |
| 542 | + $validation = Validator::make($payload, [ |
| 543 | + 'rsvps_ids' => 'sometimes|int_array', |
| 544 | + 'excluded_rsvps_ids' => 'sometimes|int_array', |
| 545 | + 'test_email_recipient' => 'sometimes|email', |
| 546 | + 'outcome_email_recipient' => 'sometimes|email', |
| 547 | + ]); |
| 548 | + |
| 549 | + if ($validation->fails()) { |
| 550 | + $messages = $validation->messages()->toArray(); |
| 551 | + |
| 552 | + return $this->error412 |
| 553 | + ( |
| 554 | + $messages |
| 555 | + ); |
| 556 | + } |
| 557 | + |
| 558 | + $filter = null; |
| 559 | + |
| 560 | + if (Request::has('filter')) { |
| 561 | + $filter = FilterParser::parse(Request::input('filter'), [ |
| 562 | + 'id' => ['=='], |
| 563 | + 'not_id' => ['=='], |
| 564 | + 'owner_email' => ['@@', '=@', '=='], |
| 565 | + 'owner_first_name' => ['@@', '=@', '=='], |
| 566 | + 'owner_last_name' => ['@@', '=@', '=='], |
| 567 | + 'owner_full_name' => ['@@', '=@', '=='], |
| 568 | + 'seat_type' => ['=='], |
| 569 | + ]); |
| 570 | + } |
| 571 | + |
| 572 | + if (is_null($filter)) |
| 573 | + $filter = new Filter(); |
| 574 | + |
| 575 | + $filter->validate([ |
| 576 | + 'id' => 'sometimes|integer', |
| 577 | + 'not_id' => 'sometimes|integer', |
| 578 | + 'owner_email' => 'sometimes|required|string', |
| 579 | + 'owner_first_name' => 'sometimes|required|string', |
| 580 | + 'owner_last_name' => 'sometimes|required|string', |
| 581 | + 'owner_full_name' => 'sometimes|required|string', |
| 582 | + 'seat_type' => 'sometimes|required|string|in:' . join(",", RSVP::ValidSeatTypes), |
| 583 | + ]); |
| 584 | + |
| 585 | + $this->service->triggerReSend($summit_event, $payload, Request::input('filter')); |
| 586 | + |
| 587 | + return $this->ok(); |
| 588 | + |
| 589 | + }); |
| 590 | + } |
| 591 | + |
430 | 592 | #[OA\Get( |
431 | 593 | path: "/api/v1/summits/{id}/events/{event_id}/rsvps/csv", |
432 | 594 | description: "required-groups " . IGroup::SummitAdministrators . ", " . IGroup::SuperAdmins . ", " . IGroup::Administrators, |
|
0 commit comments