今回は外部からCSVファイルをインポートして、CSVファイル内のデータを一旦確認してからデータベースに保存するという処理を書いていきたいと思います。
Controllerの設定
ArticlesController.php
class ArticlesCpntroller extends AppController{ public function csvImport(){ $article = $this->Articles->newEntity(); if ($this->request->is('post')) { $connection = ConnectionManager::get('default'); // トランザクション開始 $connection->begin(); try { $postData = $this->request->getData(); $action = $postData['action']; switch($action){ case 'preview': $tmp_file_name = $_FILES["csv"]["tmp_name"]; $data = array(); if (is_uploaded_file($tmp_file_name)){ $csv_contents = fopen($tmp_file_name, "r"); while(($csv_content = fgetcsv($csv_contents, 0, ",")) !==FALSE){ $datas = mb_convert_encoding($csv_content, 'UTF-8', "auto"); // エンコード $temp['title'] = $datas[0]; $temp['contents'] = $datas[0]; $data[] = $temp; } } $article = $this->Articles->patchEntity($article, $data); break; case 'save': $article = $this->Articles->patchEntity($article, $postData); if($this->Articles->save($article)){ $connection->commit(); $this->Flash->success(__('CSVファイルを追加しました')); return $this->redirect(['action' => 'index']); } $this->log(print_r($deposits->getErrors(), true), LOG_DEBUG); $this->Flash->error(__('CSVファイルを追加できませんでした')); break; } } catch (Exception $e) { $this->log($e); //ロールバック $connection->rollback(); } } if($action == 'preview' || $action == 'save'){ $this->set(compact('article')); $this->render('csv_preview', 'single'); } else { $this->set(compact('article')); $this->render('csv_import', 'single'); } } }
前回のCSVを読み込む内容を含んでいます。 postDataのなかの’action’という連想配列の値がによって表示させる画面を変えます。 previewのときはタイトルとコンテンツをアップロードされたCSVファイルから読みだしてプレビュー画面(csv_preview.ctp)に遷移します。 saveのときはpostDataをデータベースに保存して保存が失敗したら再びアップロード画面(csv_import.ctp)に戻ります。
アップロード画面(csv_import.ctp)
<?= $this->Form->create($article, array('type' => 'file')) ?> <?= $this->Form->file('csv',[ 'accept'=>'.csv', 'id'=>'elmFile']) ?> <?= $this->Form->button('プレビューへ', [ 'name' => 'action', 'value' => 'preview', 'id' => 'btnUpload', 'disabled']); ?> <?= $this->Form->end() ?> <script> document.getElementById("elmFile").addEventListener('change', selectFile, {passive: true}); window.onload = function() { selectFile(); }; function selectFile() { if (document.getElementById("elmFile").value === "") { document.getElementById("btnUpload").disabled = true; } else { document.getElementById("btnUpload").disabled = false; } } </script>
csvがきちんとセットされれば「プレビューへ」と書かれたボタンが有効になります。 このボタンに「’name’ => ‘action’, ‘value’ => ‘preview’」としてやることで、コントローラ側で画面の遷移ができます
プレビュー画面(csv_preview.ctp)
<?= $this->Form->create($deposit) ?> <?= $this->Form->control('title') ?> <?= $this->Form->control('contents') ?> <?= $this->Form->button('インポート', [ 'name' => 'action', 'value' => 'save']); ?> <?= $this->Form->end() ?>
同様にボタンに「’name’ => ‘action’, ‘value’ => ‘save’」としてやることで、コントローラ側でデータベースへの値の保存が実行されます。