Skip to content
Open
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?php namespace App\Http\Controllers;
<?php

namespace App\Http\Controllers;

/**
* Copyright 2019 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -12,9 +15,12 @@
* limitations under the License.
**/
use App\Models\Foundation\Summit\Repositories\ISummitAttendeeBadgeRepository;
use App\Security\SummitScopes;
use models\oauth2\IResourceServerContext;
use models\summit\ISummitRepository;
use ModelSerializers\SerializerRegistry;
use OpenApi\Attributes as OA;
use Symfony\Component\HttpFoundation\Response;
use utils\Filter;
use utils\FilterElement;

Expand Down Expand Up @@ -52,6 +58,78 @@ protected function getSummitRepository(): ISummitRepository
return $this->summit_repository;
}

// OpenAPI Documentation

#[OA\Get(
path: '/api/v1/summits/{id}/badges',
summary: 'Get all attendee badges for a summit',
description: 'Retrieves a paginated list of attendee badges for a specific summit. Badges are issued to attendees and contain ticket information, badge type, printing details, and feature assignments (ribbons, special access indicators, etc.).',
security: [['Bearer' => [SummitScopes::ReadAllSummitData]]],
tags: ['Summit Badges'],
parameters: [
new OA\Parameter(
name: 'id',
in: 'path',
required: true,
description: 'Summit ID',
schema: new OA\Schema(type: 'integer')
),
new OA\Parameter(
name: 'page',
in: 'query',
required: false,
description: 'Page number for pagination',
schema: new OA\Schema(type: 'integer', example: 1)
),
new OA\Parameter(
name: 'per_page',
in: 'query',
required: false,
description: 'Items per page',
schema: new OA\Schema(type: 'integer', example: 10, maximum: 100)
),
new OA\Parameter(
name: 'filter[]',
in: 'query',
required: false,
description: 'Filter expressions. Format: field<op>value. Available fields: owner_first_name, owner_last_name, owner_full_name, owner_email, ticket_number, order_number (all support =@, ==). Operators: == (equals), =@ (contains)',
style: 'form',
explode: true,
schema: new OA\Schema(
type: 'array',
items: new OA\Items(type: 'string', example: '[email protected]')
)
),
new OA\Parameter(
name: 'order',
in: 'query',
required: false,
description: 'Order by field(s). Available fields: id, ticket_number, order_number, created. Use "-" prefix for descending order.',
schema: new OA\Schema(type: 'string', example: 'created')
),
new OA\Parameter(
name: 'expand',
in: 'query',
required: false,
description: 'Expand relationships. Available: ticket, type, features',
schema: new OA\Schema(type: 'string', example: 'ticket,type,features')
),
],
responses: [
new OA\Response(
response: 200,
description: 'Attendee badges retrieved successfully',
content: new OA\JsonContent(ref: '#/components/schemas/PaginatedSummitAttendeeBadgesResponse')
),
new OA\Response(response: Response::HTTP_BAD_REQUEST, description: "Bad Request"),
new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"),
new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"),
new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not Found"),
new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"),
new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"),
]
)]

/**
* @param $summit_id
* @return mixed
Expand Down Expand Up @@ -103,6 +181,61 @@ function(){
);
}

#[OA\Get(
path: '/api/v1/summits/{id}/badges/csv',
summary: 'Export all attendee badges for a summit to CSV',
description: 'Exports a CSV file containing all attendee badges for a specific summit. Supports the same filtering and ordering capabilities as the standard list endpoint.',
security: [['oauth2_security_scope' => [SummitScopes::ReadAllSummitData]]],
tags: ['Summit Badges'],
parameters: [
new OA\Parameter(
name: 'id',
in: 'path',
required: true,
description: 'Summit ID',
schema: new OA\Schema(type: 'integer')
),
new OA\Parameter(
name: 'filter[]',
in: 'query',
required: false,
description: 'Filter expressions. Format: field<op>value. Available fields: owner_first_name, owner_last_name, owner_full_name, owner_email, ticket_number, order_number (all support =@, ==)',
style: 'form',
explode: true,
schema: new OA\Schema(
type: 'array',
items: new OA\Items(type: 'string', example: '[email protected]')
)
),
new OA\Parameter(
name: 'order',
in: 'query',
required: false,
description: 'Order by field(s). Available fields: id, ticket_number, order_number, created',
schema: new OA\Schema(type: 'string', example: '-created')
),
],
responses: [
new OA\Response(
response: 200,
description: 'CSV file generated successfully',
content: new OA\MediaType(
mediaType: 'text/csv',
schema: new OA\Schema(
type: 'string',
format: 'binary'
)
)
),
new OA\Response(response: Response::HTTP_BAD_REQUEST, description: "Bad Request"),
new OA\Response(response: Response::HTTP_UNAUTHORIZED, description: "Unauthorized"),
new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"),
new OA\Response(response: Response::HTTP_NOT_FOUND, description: "not found"),
new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"),
new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"),
]
)]

/**
* @param $summit_id
* @return mixed
Expand Down Expand Up @@ -163,4 +296,4 @@ function(){



}
}
48 changes: 47 additions & 1 deletion app/Swagger/SummitSchemas.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,50 @@

use OpenApi\Attributes as OA;

//
// Summit Attendee Badges

#[OA\Schema(
schema: 'SummitAttendeeBadge',
type: 'object',
properties: [
new OA\Property(property: 'id', type: 'integer', example: 1),
new OA\Property(property: 'print_date', type: 'integer', nullable: true, example: 1633024800, description: 'Unix timestamp of when the badge was printed'),
new OA\Property(property: 'qr_code', type: 'string', nullable: true, example: 'QR123456789'),
new OA\Property(property: 'is_void', type: 'boolean', example: false, description: 'Whether the badge has been voided'),
new OA\Property(property: 'printed_times', type: 'integer', example: 2, description: 'Number of times this badge has been printed'),
],
anyOf: [
new OA\Property(property: 'ticket_id', type: 'integer', example: 123, description: 'Associated ticket ID'),
new OA\Property(property: 'ticket', type: 'Ticket'),
new OA\Property(property: 'type_id', type: 'integer', example: 5, description: 'Badge type ID'),
new OA\Property(property: 'type', type: 'BadgeType'),
new OA\Property(property: 'print_excerpt', type: 'string', example: 'John Doe - Speaker', description: 'Short text excerpt for printing'),
new OA\Property(
property: 'features',
type: 'array',
description: 'Array of feature IDs assigned to this badge (use expand=features for full details)',
items: new OA\Items(type: 'integer'),
example: [1, 2, 3]
),
],
)]
class SummitAttendeeBadgeSchema {}

#[OA\Schema(
schema: 'PaginatedSummitAttendeeBadgesResponse',
allOf: [
new OA\Schema(ref: '#/components/schemas/PaginateDataSchemaResponse'),
new OA\Schema(
type: 'object',
properties: [
new OA\Property(
property: 'data',
type: 'array',
items: new OA\Items(ref: '#/components/schemas/SummitAttendeeBadge')
)
]
)
]
)]
class PaginatedSummitAttendeeBadgesResponseSchema {}