Windows系のプロジェクトをたくさん作りましたが、
WEB系はプロジェクトマネージャーとHTML作成の経験しかないでした。
今回はcakephp3で、一からプロジェクトを作って見ます。
1、ローカル環境構築
2、DBテーブル
3、Bakeしてみよう
4、汎用SQLの利用方法
5、Global変数
6、Global関数
7、ControllerからViewへ複数の変数を渡す
8、エクセルファイル読み込む
9、エクセルファイル書きだす
10、サーバー環境構築
11、Templateビューの編集
1、ローカル環境構築
参照サイト:
http://tech.pjin.jp/blog/2016/06/30/howto-baking-bulletinboard/
XAMPPのインストールサイト:
https://www.apachefriends.org/jp/index.html
CakePHPのダウンロードサイト
http://www.phpbook.jp/cakephp/install/index1.html
2、テーブル
今回のプロジェクトは13のテーブルがあります。
マスターデータ設定は、CSVファイルをインポートする。
3、BAKEしてみよう
htdocs/gramanagerにて、下記のコマンドを実行した。
#php bin/cake.php bake all gramanager
NetBeansエディターで開けてみたら、この感じです。
※NetBeansでctpファイルが認識できなかった問題は、下記サイトを参照して解決しました。
http://gomocool.net/gomokulog/?p=117
4、汎用SQLの利用方法
コントローラーに下記参照を追加したら、汎用SQLでデータを取れます。
登録・更新・削除もできます。
use Cake\ORM\TableRegistry;
use Cake\Datasource\ConnectionManager;
//ログイン者の漢字名を取得
public function cal_user_janame($manager_id) {
$janame='';
$connection = ConnectionManager::get('default');
$statement = "SELECT * FROM managers WHERE managers.id = '$manager_id'";
$stmt = $connection->execute( $statement)->fetchAll('assoc');
foreach ($stmt as $row) {
$janame = $row['name'] ;
$GLOBALS["current_directorA"]= $row['directora_id'];
$GLOBALS["current_directorB"]= $row['directorb_id'];
$GLOBALS["current_directorC"]= $row['directorc_id'];
}
return $janame;
}
5、Global変数
App\Controllerに、このように定義できます。
$GLOBALS['current_user_id']=$this->Auth->user('name');
参照:PHP $GLOBALS(グローバル変数)のすべて!
http://wepicks.net/phpref-globals/
6、Global関数
//ログイン者の漢字名を取得
public function cal_user_janame($manager_id) {
}
7、ControllerからViewへ複数の変数を渡す
自動作成されたコードは、1テーブルの全データをcontrollerから、ctpへ渡す。
複数のデータを渡すのは、Controllerに定義できます。
public function index()
{
$this->paginate = [
'limit' => 50,
'contain' => ['Managers']
];
$homes = $this->paginate($this->Homes);
$this->set(compact('homes'));
$this->set('_serialize', ['homes']);
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 条件なしなら、テーブルのデータを丸ごと渡す。
$manager_id=$GLOBALS["current_manager_id"];
$year_number=$GLOBALS["current_year"];
$sec=$GLOBALS["current_sec"];
$this->paginate = [
'limit' => 50,
'contain' => ['Managers']
,'conditions' =>array(
'and' => array(
'Homes.year_number' => $GLOBALS["current_year"],
'Homes.sec' => $GLOBALS["current_sec"],
'Homes.manager_id' => $GLOBALS["current_manager_id"]
))
,'group' => 'Homes.manager_id'
,'order' => array('Homes.manager_id')
];
$homes_self = $this->paginate($this->Homes);
$this->set(compact('homes_self'));
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 一部のデータ
$this->paginate = [
'limit' => 50,
'contain' => ['Managers']
,'conditions' =>array(
'and' => array(
'Homes.year_number' => $GLOBALS["current_year"],
'Homes.sec' => $GLOBALS["current_sec"],
'Homes.dira_shainid' => $GLOBALS["current_user_id"]
))
,'group' => 'Homes.manager_id'
,'order' => array('Homes.manager_id')
];
$homes_A = $this->paginate($this->Homes);
$this->set(compact('homes_A'));
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 一部のデータ
}
ビュー側:
タイトル
<thead valign="top">
<tr>
<th scope="col" class="actions"><?= __('AA') ?></th>
<th scope="col" class="actions"><?= __('AAAAA') ?></th>
<th scope="col" class="actions"><?= __('AAAA') ?></th>
<th scope="col" class="actions"><?= __('AAA') ?></th>
<th scope="col" class="actions"><?= __('A') ?></th>
<th scope="col" class="actions"><?= __('A') ?></th>
<th scope="col" class="actions"><?= __('A') ?></th>
<th scope="col" class="actions"><?= __('A') ?></th>
<th scope="col" class="actions"><?= __('Action') ?></th>
</tr>
</thead>
</table>
条件A:
<?php if ($GLOBALS['current_rank_id'] < 7 and $GLOBALS['current_rank_id'] >2) : ?>
<h5>本人</h5>
<table cellpadding="0" cellspacing="0">
<?php foreach ($homes_self as $home_self): ?>
<tr>
<td><?= $home_self->has('manager') ? $this->Html->link($home_self->manager->name, ['controller' => 'Targets', 'action' => 'index', $home_self->manager->id]) : '' ?></td>
<td><?= h($home_self->target_put) ?></td>
<td><?= h($home_self->dir_permission) ?></td>
<td><?= h($home_self->self_put) ?></td>
<td><?= h($home_self->director_aput) ?></td>
<td><?= h($home_self->director_bput) ?></td>
<td><?= h($home_self->director_cput) ?></td>
<td><?= h($home_self->director_over) ?></td>
<td class="actions">
<?= $this->Html->link(__('編集'), ['action' => 'edit', $home_self->id]) ?>
</td>
</tr>
<?php endforeach; ?>
</table>
<?php endif; ?>
条件B
一次" ;
}
?>
<table cellpadding="0" cellspacing="0">
<?php foreach ($homes_A as $home_A): ?>
<tr>
<td><?= $home_A->has('manager') ? $this->Html->link($home_A->manager->name, ['controller' => 'Targets', 'action' => 'index', $home_A->manager->id]) : '' ?></td>
<td><?= h($home_A->target_put) ?></td>
<td><?= h($home_A->dir_permission) ?></td>
<td><?= h($home_A->self_put) ?></td>
<td><?= h($home_A->director_aput) ?></td>
<td><?= h($home_A->director_bput) ?></td>
<td><?= h($home_A->director_cput) ?></td>
<td><?= h($home_A->director_over) ?></td>
<td class="actions">
<?= $this->Html->link(__('編集'), ['action' => 'edit', $home_A->id]) ?>
</td>
</tr>
<?php endforeach; ?>
</table>
8、エクセルファイル読み込む
エクセルファイルのデータををDBへ読み込む出来ます。
・PHPExcelのインストール
https://github.com/PHPOffice/PHPExcel
上記URLにアクセスし、Clone or downloadボタンをクリックします。
さらに「Download Zip」をクリックすると、zipファイルがダウンロードされます。
(2017/8/24時点 のファイル名は PHPExcel-1.8.zip)
ダウンロードしたzipファイルを解凍し、
解凍フォルダ内のClassesフォルダの中身を全て、使用したいphpファイルが読み込める場所にコピーします。
自分はすべてtmpに保存しました。
Documentationフォルダ、Examplesフォルダ等は不要です。
・モデルなしのUploadsControllerとupload formを利用します。
UploadsControllerのコード:
request->is('post')) {
if ($upload->readFromExcel($this->request->data['file']['tmp_name'])) {
$this->Flash->success('アップロードが成功しました');
echo "
";
echo $this->request->data('file.name')." を正常インポートしました。";
echo "
";
} else {
$this->Flash->error('バリデーションに引っかかりました。');
echo $this->request->data('file.name')."をインポートできませんでした。";
}
}
$this->set('upload', $upload);
}
}
UploadFormのコード:
getActiveSheet();
$shainid = $sheet->getCell( 'A3' )->getValue();
$upController = new AppController;
$manager_id= $upController->get_manager_id_from_shainid($shainid);
$directora_id= $upController->get_directorid($shainid,"a") ;
$directora_shainid=$upController->get_shainid_from_directorid($directora_id,"a");
$year_number=$GLOBALS["current_year"]; //計算
$sec=$GLOBALS["current_sec"]; //計算
//既存を削除
$connection = ConnectionManager::get('default');
$connection->delete('targets', ['year_number' => $year_number,'sec' => $sec, 'manager_id' => $manager_id]);
$i=0;
$firstLine=27;
$cellLine = $firstLine ;
for($i = 1; $i < 6; $i++){
$cellB="B" .strval($cellLine);
$cellO="O" .strval($cellLine);
$cellAB="AB" .strval($cellLine);
・・・
$mokuhyou = $sheet->getCell($cellB )->getValue();
$plan = $sheet->getCell($cellO )->getValue();
$weight = $sheet->getCell($cellAB )->getValue();
・・・
date_default_timezone_set('Japan');
$created = date('Y/m/d H:i:s');
// $connection = ConnectionManager::get('default');
if ( strlen($mokuhyou) > 0) {
$connection->insert('targets', [
'year_number' => $year_number,
'sec' => $sec,
'subid' => $i,
'manager_id' => $manager_id,
'target' => $mokuhyou,
'plan' => $plan,
'weight' => $weight,
'status' => '編集中',
'self_coment' => $self_coment,
'self_degree' =>$self_degree,
'director_txt' => $director_txt,
'directora_id' => $directora_shainid,
'directorb_id' => $directorb_shainid,
'directorc_id' => $directorc_shainid,
'degree_a' => $degree_a,
'degree_b' => $degree_b,
'degree_c' => $degree_c,
'created' => $created,
'created_user' => $GLOBALS["current_user_janame"]]);
}
$cellLine = $cellLine + 4;
}
return true;
}
}
・Upload.ctp: アップロードファイルを選択する。
- = $this->Html->link(__('Home'), ['controller' =>'Homes', 'action' => 'index']) ?>
<br/>
<br/>
<?= $this->Form->create($upload, ['type' => 'file']) ?>
<div><p><?= $this->Form->file('file') ?></p></div>
<div><?= $this->Form->button('アップロード', ['type' => 'submit','id' => 'register']) ?></div>
<?= $this->Form->end() ?>
</ul>
9、エクセルファイル書きだす
参照:
http://qiita.com/suin/items/7a8d0979b7675d6fd05b
書き出すはアップロードよりシンプルです。
固定のフォーマットで書き出したいので、EXCELテンプレートを事前に用意しました。
・参照設定:
Targets->get($id,
[ 'contain' => []
]);
// データを配置
$manager_id=$target->manager_id;
$year_number=$GLOBALS["current_year"];
$sec=$GLOBALS["current_sec"];
$shainjname=AppController::cal_user_janame($manager_id);
// 入出力の情報設定
$driPath = realpath(TMP) . "/excel/";
$inputPath = $driPath . "template.xlsx";
$sheetName = "data_sheet";
$outputFile = "output_".$shainjname.date('YmdHis'). ".xlsx";
$outputPath = $driPath . $outputFile;
// Excalファイル作成
$reader = PHPExcel_IOFactory::createReader('Excel2007');
$book = $reader->load($inputPath);
$sheet = $book->getSheetByName($sheetName);
if ($sec == 1) {
$jasec="上期";
} else {
$jasec="下期";
}
$sheet->setCellValue( "BY1", strval($year_number)."年度".$jasec);
$connection = ConnectionManager::get('default');
//タイトル情報
//managers テーブルのデータ ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
$statementm = "SELECT * FROM managers WHERE managers.id = '$manager_id'";
$stmtm = $connection->execute( $statementm)->fetchAll('assoc');
foreach ($stmtm as $row) {
$sheet->setCellValue( "A3", $shainid);
・・・
}
//honbu_targets テーブルのデータ ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
$hstatement = "SELECT * FROM honbu_targets WHERE honbu_targets.year_number = '$year_number' and honbu_targets.section = '$sec' and honbu_targets.honbu_id = '$honbu_id' order by subid";
$hstmt = $connection->execute( $hstatement)->fetchAll('assoc');
$h=0;
$hfirstLine=7;
foreach ($hstmt as $hrow) {
$hcellLine = $hfirstLine +$h;
$hcellB="B" .strval($hcellLine);
$honbu_target=$hrow['target'] ;
$sheet->setCellValue( $hcellB, $honbu_target);
$h=$h+3;
}
//bumon_targets テーブルのデータ ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
$jstatement = "SELECT * FROM bumon_targets WHERE bumon_targets.year_number = '$year_number' and bumon_targets.section = '$sec' and bumon_targets.bumon_id = '$bumon_id' order by subid";
$jstmt = $connection->execute( $jstatement)->fetchAll('assoc');
$j=0;
$jfirstLine=7;
foreach ($jstmt as $jrow) {
$jcellLine = $jfirstLine +$j;
$jcellAB="AB" .strval($jcellLine);
$bumon_target=$jrow['target'] ;
$sheet->setCellValue( $jcellAB, $bumon_target);
$j=$j+3;
}
//targets テーブルのデータ ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
$statement = "SELECT * FROM targets WHERE targets.year_number = '$year_number' and targets.sec = '$sec' and targets.manager_id = '$manager_id' order by subid";
$stmt = $connection->execute( $statement)->fetchAll('assoc');
$i=0;
$firstLine=27;
foreach ($stmt as $row) {
$cellLine = $firstLine +$i;
$cellB="B" .strval($cellLine);
$cellO="O" .strval($cellLine);
・・・
$mokuhyou=$row['target'] ;
$plan=$row['plan'] ;
・・・
$sheet->setCellValue( $cellB, $mokuhyou);
$sheet->setCellValue( $cellO, $plan);
$sheet->setCellValue( $cellAB, $weight);
・・・・
$i=$i+4;
}
//targets テーブルのデータ ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
// 保存
$book->setActiveSheetIndex(0);
$writer = PHPExcel_IOFactory::createWriter($book, 'Excel2007');
$writer->save($outputPath);
// ダウンロード
header('Content-Type: application/octet-stream');
ob_end_clean();//バッファのゴミ捨て
header('Content-Disposition: attachment;filename="' . $outputFile . '"');
header('Cache-Control: max-age=0');
$book->setActiveSheetIndex(0);
$writer = PHPExcel_IOFactory::createWriter($book, 'Excel2007');
$writer->save('php://output');
exit;
return $this->redirect(['action' => 'index']);
}
10、サーバー環境構築
CPIのサーバーを利用する。下記サイトを参照しました、
CPIサーバでCakePHP:
http://g37.jp/2015/03/use-cakephp-in-cpi-server-vol1/
/html/に、プロジェクトフォルダを丸ごとアップします。
※サーバーパス、ファイル名などは、大文字小文字を区別するので、気をつけてください。
11、Templateビューの編集
・自動作成のコード
= $this->Html->link(__('テンプレート・ダウンロード'),['controller' => 'Targets', 'action' => 'get_template'])?>
<li><?= $this->Html->link(__('アップロード'), ['controller' => 'Uploads', 'action' => 'index']) ?></li>
・PHPコード入れ
",$this->Html->link(__('AAAA'), ['controller' => 'BumonTargets', 'action' => 'index']),"" ;
}
?>
・php endforeach/php endifの書き方
2) : ?>
<h5>本人</h5>
<table cellpadding="0" cellspacing="0">
<?php foreach ($homes_self as $home_self): ?>
<tr>
<td><?= $home_self->has('manager') ? $this->Html->link($home_self->manager->name, ['controller' => 'Targets', 'action' => 'index', $home_self->manager->id]) : '' ?></td>
<td><?= h($home_self->target_put) ?></td>
<td><?= h($home_self->dir_permission) ?></td>
<td><?= h($home_self->self_put) ?></td>
...
<td class="actions">
<?= $this->Html->link(__('編集'), ['action' => 'edit', $home_self->id]) ?>
</td>
</tr>
<?php endforeach; ?>
</table>
<?php endif; ?>