Skip to main content

Black Friday 2025! Only until December 1st: coupon FRIDAY25 for 40% off Yearly/Lifetime membership!

Read more here

HiEventsDev/Hi.Events

3299 stars
4 code files
View HiEventsDev/Hi.Events on GitHub

backend/composer.json

Open in GitHub
{
// ...
 
"require": {
// ...
"maatwebsite/excel": "^3.1",
// ...
},
 
// ...
}

backend/routes/api.php

Open in GitHub
use HiEvents\Http\Actions\Attendees\ExportAttendeesAction;
 
$router = app()->get('router');
 
// ...
 
$router->middleware(['auth:api'])->group(
function (Router $router): void {
// ...
 
$router->post('/events/{event_id}/attendees/export', ExportAttendeesAction::class);
 
// ...
}
);
 
// ...

backend/app/Exports/AttendeesExport.php

Open in GitHub
use Carbon\Carbon;
use HiEvents\DomainObjects\Enums\QuestionTypeEnum;
use HiEvents\DomainObjects\QuestionDomainObject;
use HiEvents\Resources\Attendee\AttendeeResource;
use HiEvents\Services\Domain\Question\QuestionAnswerFormatter;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithStyles;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
 
class AttendeesExport implements FromCollection, WithHeadings, WithMapping, WithStyles
{
private LengthAwarePaginator|Collection $data;
private Collection $questions;
 
public function __construct(private QuestionAnswerFormatter $questionAnswerFormatter)
{
}
 
public function withData(LengthAwarePaginator|Collection $data, Collection $questions): AttendeesExport
{
$this->data = $data;
$this->questions = $questions;
return $this;
}
 
public function collection(): AnonymousResourceCollection
{
return AttendeeResource::collection($this->data);
}
 
public function headings(): array
{
$questionTitles = $this->questions->map(fn($question) => $question->getTitle())->toArray();
 
return array_merge([
'ID',
'First Name',
'Last Name',
'Email',
'Status',
'Is Checked In',
'Checked In At',
'Ticket ID',
'Event ID',
'Public ID',
'Short ID',
'Created Date',
'Last Updated Date'
], $questionTitles);
}
 
public function map($attendee): array
{
$answers = $this->questions->map(function (QuestionDomainObject $question) use ($attendee) {
$answer = $attendee->getQuestionAndAnswerViews()
->first(fn($qav) => $qav->getQuestionId() === $question->getId())?->getAnswer() ?? '';
 
return $this->questionAnswerFormatter->getAnswerAsText(
$answer,
QuestionTypeEnum::fromName($question->getType()),
);
});
 
return array_merge([
$attendee->getId(),
$attendee->getFirstName(),
$attendee->getLastName(),
$attendee->getEmail(),
$attendee->getStatus(),
$attendee->getCheckedInAt() ? 'Yes' : 'No',
$attendee->getCheckedInAt()
? Carbon::parse($attendee->getCheckedInAt())->format('Y-m-d H:i:s')
: '',
$attendee->getTicketId(),
$attendee->getEventId(),
$attendee->getPublicId(),
$attendee->getShortId(),
Carbon::parse($attendee->getCreatedAt())->format('Y-m-d H:i:s'),
Carbon::parse($attendee->getUpdatedAt())->format('Y-m-d H:i:s'),
], $answers->toArray());
}
 
public function styles(Worksheet $sheet): array
{
return [
1 => ['font' => ['bold' => true]],
];
}
}

backend/app/Http/Actions/Attendees/ExportAttendeesAction.php

Open in GitHub
use HiEvents\DomainObjects\Enums\QuestionBelongsTo;
use HiEvents\DomainObjects\EventDomainObject;
use HiEvents\DomainObjects\QuestionAndAnswerViewDomainObject;
use HiEvents\Exports\AttendeesExport;
use HiEvents\Http\Actions\BaseAction;
use HiEvents\Repository\Interfaces\AttendeeRepositoryInterface;
use HiEvents\Repository\Interfaces\QuestionRepositoryInterface;
use Maatwebsite\Excel\Facades\Excel;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
 
class ExportAttendeesAction extends BaseAction
{
public function __construct(
private readonly AttendeesExport $export,
private readonly AttendeeRepositoryInterface $attendeeRepository,
private readonly QuestionRepositoryInterface $questionRepository
)
{
}
 
public function __invoke(int $eventId): BinaryFileResponse
{
$this->isActionAuthorized($eventId, EventDomainObject::class);
 
$attendees = $this->attendeeRepository
->loadRelation(QuestionAndAnswerViewDomainObject::class)
->findByEventIdForExport($eventId);
 
$questions = $this->questionRepository->findWhere([
'event_id' => $eventId,
'belongs_to' => QuestionBelongsTo::TICKET->name,
]);
 
return Excel::download(
$this->export->withData($attendees, $questions),
'attendees.xlsx'
);
}
}

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.