モデルなしフォーム作成
src/Form/HogeCsvForm.php
<?php
namespace App\Form;
use Cake\Form\Form;
use Cake\Form\Schema;
use Cake\Validation\Validator;
class HogeCsvForm extends Form
{
protected function _buildSchema(Schema $schema)
{
return $schema->addField('csv', ['type' => 'file']);
}
protected function _buildValidator(Validator $validator)
{
$validator->provider('upload', \Josegonzalez\Upload\Validation\DefaultValidation::class);
$validator->add('csv', 'fileFileUpload', [
'rule' => ['isFileUpload'],
'message' => 'アップロードに失敗しました。',
'provider' => 'upload'
])->add('csv', 'fileBelowMaxSize', [
'rule' => ['isBelowMaxSize', 10240000],
'message' => 'ファイルサイズが大きすぎます。',
'provider' => 'upload'
])->add('csv', 'fileType', [
'rule' => ['mimeType', ['text/plain']],
'message' => 'ファイル形式が違います。'
]);
}
protected function _execute(array $data)
{
return true;
}
}
Controller作成
src/Controller/HogesController.php
<?php
namespace App\Controller\Manage;
use App\Controller\AppController;
use App\Form\HogeCsvForm; // モデルなしフォームロード
use Cake\Filesystem\Folder; // Folderユーティリティロード
class HogesController extends AppController
{
public function initialize()
{
parent::initialize();
$this->loadComponent('Csv'); // CSVコンポートロード
}
public function csv()
{
$hogesCsv = new HogesCsvForm();
if ($this->request->is(['patch', 'post', 'put'])) {
if ($hogesCsv ->execute($this->request->getData())) {
// ファイルコピー
$path = ROOT . DS . 'uploadfiles' . DS . 'tmp';
$folder = new Folder();
$folder->create($path);
$file = $path . DS . sha1(uniqid(mt_rand(), true)) . '.csv';
if (move_uploaded_file($this->request->getData('csv.tmp_name'), $file)) {
chmod($file, 0644);
// CSVデータ取込
$csvData = $this->Csv->getCsv($file);
// データ整形
$data = [];
foreach ($csvData as $vol) {
$data[] = [
'real_estate_id' => 0,
'aggregated_at' => date('Y-m-d'),
'incomes' => $vol['2'],
'expenses' => $vol['3'],
];
}
// データ登録
$this->loadModel('Hoges');
$entities = $this->MonthlyBalances->newEntities($data);
$result = $this->MonthlyBalances->saveMany($entities);
unlink($file);
$this->Flash->success('登録しました。');
}else{
$this->Flash->error('登録に失敗しました。');
}
} else {
$this->Flash->error('登録に失敗しました。');
}
}
$this->set('hogesCsv', $hogesCsv);
}
}
view作成
src/Template/Hoges/csv.ctp
<div>
<?= $this->Form->create($hogesCsv, ['type' => 'file']) ?>
<fieldset>
<legend><?= __('CSV登録') ?></legend>
<?php
echo $this->Form->control('csv', ['type' => 'file']);
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
CSVデータ読込コンポーネント作成
Controller\Component\CsvComponent.php
<?php
namespace App\Controller\Component;
use Cake\Controller\Component;
use Cake\Controller\ComponentRegistry;
use \SplFileObject;
/**
* Csv component
*/
class CsvComponent extends Component
{
/**
* Default configuration.
*
* @var array
*/
protected $_defaultConfig = [];
public function getCsv($csvfile, $mode='sjis')
{
// ファイル存在確認
if (!file_exists($csvfile)) {
return false;
}
// 文字コードを変換しながら読み込めるようにPHPフィルタを定義
if ($mode === 'sjis') {
$filter = 'php://filter/read=convert.iconv.cp932%2Futf-8/resource='.$csvfile;
} elseif ($mode === 'utf16') {
$filter = 'php://filter/read=convert.iconv.utf-16%2Futf-8/resource='.$csvfile;
} elseif ($mode === 'utf8') {
$filter = $csvfile;
}
// SplFileObject()を使用してCSVロード
$file = new SplFileObject($filter);
if ($mode === 'utf16') {
$file->setCsvControl("\t");
}
$file->setFlags(
SplFileObject::READ_CSV |
SplFileObject::SKIP_EMPTY |
SplFileObject::READ_AHEAD
);
// 各行を処理
$records = [];
foreach ($file as $i => $row)
{
// 1行目はスキップ
if ($i===0) {
continue;
}
// 2行目以降はデータ行として取り込み
$records[] = $row;
}
return $records;
}
}