requireAdministrator();$club=MaintenanceService::id($_POST['club_serial']??null);$name=$service->club($club)['club_name']; $history=(new LedgerService())->history($club);header('Content-Type: text/csv; charset=UTF-8');header('Content-Disposition: attachment; filename="club-financial-history.csv"');$file=fopen('php://output','w'); $write=static function(array $row)use($file){fputcsv($file,array_map(static fn($v)=>self::csvText((string)$v),$row),',','"','');}; $write(['Record type','Club','Record ID','Dues ID','Member','Amount cents (USD)','Date','Method','Reference','Recorded by','Status / reason']); foreach($service->dues($club) as $due)$write(['dues_total',$name,$due['due_serial'],$due['due_serial'],$due['user_first_name'].' '.$due['user_last_name'],$due['amount_cents'],'','','',$due['recorded_by']??'Historical','Paid cents '.$due['paid_cents'].'; balance cents '.($due['amount_cents']-$due['paid_cents'])]); foreach($history['payments'] as $p)$write(['payment',$name,$p['payment_serial'],$p['due_serial'],$p['member_name'],$p['amount_cents'],$p['paid_on'],$p['payment_method'],$p['payment_reference'],$p['actor']??'Historical',$p['reversal_serial']?'Reversed: '.$p['reversal_reason'].' by '.$p['reversal_actor'].' on '.$p['reversed_at']:'Received']); foreach($history['adjustments'] as $a)$write(['dues_adjustment',$name,$a['adjustment_serial'],$a['due_serial'],$a['member_name'],$a['amount_cents'],$a['created_at'],'','',$a['actor'],$a['reason']]); fclose($file);exit; } private function rows(): array { $service=new RosterService();$service->requireAdministrator();$id=MaintenanceService::id($_POST['club_serial']??null);$club=$service->club($id); $rows=[['Club','Username','First name','Last name','Email','Membership','Joined on']]; foreach($service->members($id) as $member)$rows[]=[$club['club_name'],$member['user_name'],$member['user_first_name'],$member['user_last_name'],$member['user_email'],$member['membership_status'],$member['joined_on']]; return $rows; } public static function csvText(string $value): string {return preg_match('/\A[\s]*[=+@\-]/u',$value)||preg_match('/\A[\t\r\n]/',$value)?"'".$value:$value;} public function csv(): void { $rows=$this->rows();header('Content-Type: text/csv; charset=UTF-8');header('Content-Disposition: attachment; filename="club-roster.csv"');$file=fopen('php://output','w'); foreach($rows as $row)fputcsv($file,array_map(static fn($cell)=>self::csvText((string)$cell),$row),',','"','');fclose($file);exit; } public function excel(): void { $rows=$this->rows();$book=new Spreadsheet();$sheet=$book->getActiveSheet();$sheet->setTitle('Club roster'); foreach($rows as $r=>$row)foreach($row as $c=>$cell)$sheet->setCellValueExplicit([$c+1,$r+1],(string)$cell,DataType::TYPE_STRING); $sheet->getStyle('A1:G1')->getFont()->setBold(true);$sheet->freezePane('A2');foreach(range('A','G') as $column)$sheet->getColumnDimension($column)->setAutoSize(true); header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');header('Content-Disposition: attachment; filename="club-roster.xlsx"');(new Xlsx($book))->save('php://output');exit; } public function pdf(): void { $rows=$this->rows();$pdf=new TCPDF('L');$pdf->SetCreator(self::APPLICATION_NAME);$pdf->SetTitle('Club roster');$pdf->setPrintHeader(false);$pdf->setPrintFooter(false);$pdf->AddPage();$pdf->SetFont('helvetica','',9); $html='
| ':' | ').htmlspecialchars((string)$cell,ENT_QUOTES,'UTF-8').($r===0?'':' | ');$html.='
|---|
Install the roster migration before exporting reports.