前回の記事で多重にTraitをuseする方法について紹介しました. 今回はこの機能を使ってcsvエクスポート機能を実装していきたいと思います.
基本的なTempパスの設定,ファイルの編集&データの追加などは基本的にcsvで共通な処理となりますので,この機能を持つtraitを親とし,データの部分を編集するTraitでそれをUseして,コントローラに取り込むという流れとなります.
以下がまず基本となるCSVの編集を担うTraitです.
trait CsvTrait { abstract protected function getDatas(); abstract protected function getFileName(); private function createCsv() { $temp_dir = sys_get_temp_dir(); $csv_file_path = tempnam($temp_dir, 'temp_csv'); $fp = fopen($csv_file_path, 'w'); if ($fp === false) { fclose($fp); throw new \Exception("Failed to open {$temp_csv_file_path}."); } $this->file_path = $csv_file_path; fclose($fp); } private function writeCsv(){ $file_path = $this->file_path; $fp = fopen($file_path, 'a'); $datas = $this->getDatas(); foreach($datas as $row) { if(fputcsv($fp, $row) === false) { fclose($fp); throw new \Exception("Failed to write data into {$file_path}."); } } fclose($fp); } public function downloadCsv(){ $this->createCsv(); $this->writeCsv(); $file_name = $this->getFileName(); return $this->getResponse() ->withCharset('UTF-8') ->withType('csv') ->withFile( $this->file_path, [ 'download' => true, 'name' => $file_name ] ); } }
これを継承してCsvにユーザー名を追加していくTraitを作ります.
trait UserCsvTrait { use CsvTrait; protected function getDatas() { return $this->Users->find()->extract('name'); } protected function getFileName() { return "users.csv"; } }
これをコントローラーに追加すると,
class UsersController extends AppController{ use UserCsvTarit; // use // 以下省略 }
パブリックとしていたdownloadCsvが追加されるので,アクション等でそのメソッドを呼べばCSVエクスポート機能が実装できるはずです.