LoginSignup
1
0

More than 5 years have passed since last update.

CakePHP3でプロジェクト作成

Last updated at Posted at 2017-08-08
1 / 2

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のテーブルがあります。
10000001.jpg

マスターデータ設定は、CSVファイルをインポートする。

3、BAKEしてみよう

htdocs/gramanagerにて、下記のコマンドを実行した。

php bin/cake.php bake all gramanager

NetBeansエディターで開けてみたら、この感じです。
※NetBeansでctpファイルが認識できなかった問題は、下記サイトを参照して解決しました。
http://gomocool.net/gomokulog/?p=117

image.png

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

<?php
if ($GLOBALS['current_rank_id'] < 5 or $GLOBALS['current_rank_id'] ==7) {
echo "

一次
" ;
}
?>
    <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のコード:

<?php
namespace App\Controller;

use App\Form\UploadForm;
use Cake\Datasource\ConnectionManager;
use Cake\I18n\Time;

require_once(realpath(TMP).DS."classes".DS."PHPExcel.php");
require_once(realpath(TMP).DS."classes".DS."PHPExcel".DS."IOFactory.php");
use PHPExcel_IOFactory;

class UploadsController extends AppController
{
public function index()
{
$upload = new UploadForm();

    if ($this->request->is('post')) {

        if ($upload->readFromExcel($this->request->data['file']['tmp_name'])) {
            $this->Flash->success('アップロードが成功しました');

            echo "<br/>";
            echo $this->request->data('file.name')." を正常インポートしました。";
            echo "<br/>";

        } else {
            $this->Flash->error('バリデーションに引っかかりました。');
            echo $this->request->data('file.name')."をインポートできませんでした。";
        }
    }

    $this->set('upload', $upload);
}  

}

UploadFormのコード:

<?php

namespace App\Form;

use app\Controller\AppController;
use Cake\Form\Form;
use Cake\Form\Schema;
use Cake\Validation\Validator;

use Cake\Datasource\ConnectionManager;
use Cake\I18n\Time;

require_once(realpath(TMP).DS."classes".DS."PHPExcel.php");
require_once(realpath(TMP).DS."classes".DS."PHPExcel".DS."IOFactory.php");

use PHPExcel_IOFactory;

class UploadForm extends Form{

// ファイル名渡したら配列返すラッパー関数
public function readFromExcel($inputFile)

{

 $readFile = $inputFile;

// ファイルの存在チェック
if (!file_exists($readFile)) {
    exit($readFile. "が見つかりません。" );
}

// xlsxをPHPExcelに 
$objPExcel = PHPExcel_IOFactory::load($readFile);
$sheet = $objPExcel->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']) ?>


  • = $this->Form->create($upload, ['type' => 'file']) ?>

    = $this->Form->file('file') ?>

    = $this->Form->button('アップロード', ['type' => 'submit','id' => 'register']) ?>
    = $this->Form->end() ?>

9、エクセルファイル書きだす
 参照:
 http://qiita.com/suin/items/7a8d0979b7675d6fd05b

 書き出すはアップロードよりシンプルです。
 固定のフォーマットで書き出したいので、EXCELテンプレートを事前に用意しました。

・参照設定:
<?php
namespace App\Controller;
use Cake\ORM\TableRegistry;
use Cake\Datasource\ConnectionManager;
use Cake\I18n\Time;

require_once(realpath(TMP).DS."classes".DS."PHPExcel.php");
require_once(realpath(TMP).DS."classes".DS."PHPExcel".DS."IOFactory.php");

use PHPExcel_IOFactory;

・エクセルテンプレート置く場所:
tmp/excel/template.xlsx

・ソース

public function download ($id=null){

$target = $this->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'])?>
<?= $this->Html->link(('アップロード'), ['controller' => 'Uploads', 'action' => 'index']) ?>
 
・PHPコード入れ
<?php
if ($GLOBALS['current_rank_id'] < 4 or $GLOBALS['current_rank_id'] == 7 ) {
echo "",$this->Html->link(__('AAAA'), ['controller' => 'BumonTargets', 'action' => 'index']),"" ;
}
?>

・php endforeach/php endifの書き方

<?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 class="actions">
                    <?= $this->Html->link(__('編集'), ['action' => 'edit', $home_self->id]) ?>
                </td>

             </tr>
             <?php endforeach; ?>
        </table>   

<?php endif; ?>
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0