1
0

More than 1 year has passed since last update.

Cakephp4へのバージョンアップ

Last updated at Posted at 2022-12-21

Cakephp2からCakephp4へバージョンアップメモ

 かなりカスタマイズされたCakephp2をとうとうCakephp4にバージョンアップする事になり。
 ちまちま調べながら、まとめて知りたいことを書き連ねてます。
 追記追記していく所存。

フォルダー構成メモ

cakephp2 →  Cakephp4
app/Config config
app/Contoroller src/Controller
app/Model src/Model
app/View/Helper src/View/Helper
app/View templates

まずはControllerで知りたかった事の一部抜粋。

 Findやデータのわたしかたなどなど

Cakephp2で書いてた方法

WorkController.php
  //社内便利コンポーネントの呼び込み
   $components=array('CommonOriginal', 
                array('model'=>'Work',
                'index'=>array('hogehoge'・・・);////省略

	public function edit($id=null){
        //ログイン者の情報も必要なので取得。
		$user = $this->Auth->user();
		
		$status = $this->UserStatus->getXXStatus($user['id']);
        //データの取り出しJoinしまくり
		if($status==1){
		// 省略
		}

		$WorkCheck = $this->Work->findById($id);
		$data = $this->Work->find('all',
						array(
						'fields'=>Hash::merge(
								$this->Work->getDataSource()->fields($this->Work),
								$this->Time->getDataSource()->fields($this->Time),
								array('TotalTime.target_sum_time','TotalTime.fix'	)
								),
						'conditions'=>array('Work.id'=>$id)
						,'joins'=>
									array('type'=>'LEFT OUTER',
										'alias'=>'Time',
										'table'=> $this->Time->useTable ,
										'conditions'=>array('Time.id = Work.time_id',
															'Time.user_id = Work.user_id')
									),
									array('type'=>'LEFT OUTER',
										'alias'=>'TotalTime',
										'table'=> $this->TotalTime->useTable ,
										'conditions'=>array('TotalTime.id = Work.total_time_id',
															'TotalTime.user_id = Work.user_id')
									),
							)
							)
						);
		//一覧
		if( !empty($data[0]['Work']['order_number']) ||  !empty($data[0]['Work']['dummy'])  ){
			$TotalTimes = $this->TotalTime->TotalTImelist($user['id'] ,$data[0]['Work']['order_number'],$data[0]['Work']['dummy']);
			$this->set('TotalTimes',$TotalTimes);
		}

		$Attendance = $this->Attendance->getXXX($user['id'],
							( empty($data[0]['WorkMeter']['start_day']) ? null : date("Y/m/d" , strtotime($data[0]['WorkMeter']['start_day']) ))
							);
		//休憩合計時間
		$sumBreak = $this->WorkBreak->SumWorkMeterBreak($id);
		$time_now = strtotime( date( "Y/m/d H:i:s", time() ));

       //省略

	}

Cakephp4にとりあえず直したソース。

モデルが複数形になったら、コントローラー名も複数形。

WorksController.php
//↓↓↓↓宣言しないといけない↓↓↓↓↓↓↓↓
+ use Cake\ORM\TableRegistry;
+ use Cake\Utility\Hash; //ハッシュを使うために必要
//↑↑↑↑宣言しないといけない↑↑↑↑↑↑↑↑

  public function initialize(): void
  {
    parent::initialize();
  //社内便利コンポーネントの呼び込み
+   $this->loadComponent('CommonOriginal', 
+                ['model'=>'Works',
+               'index'=>['hogehoge'・・・);////省略
   }

	public function edit($id=null)
    {
        //ログイン者の情報も必要なので取得。
+		$user = $this->request->getAttribute('identity');
		
+		$status = $this->fetchTable('UserStatus')->getXXStatus($user->id);
		if($status==1)
        {
		   //省略
		}

+		$WorkCheck = $this->Works->get($id);
+        $querydata = $this->Works->find()
+                                ->select(
                                    Hash::merge(
+                                           $this->Works->getSchema()->columns(),
+                                           $this->fetchTable('Times')->getColumns('Times') ,
                                           ['TotalTimes.target_sum_time','TotalTimes.fix']
                                ))
+                                ->where(['Works.id'=>$id])
+                                ->join([
+                                      'Times'=>['type'=>'LEFT OUTER',
+                                                'table'=> $this->fetchTable('Times')->getTable(),
                                                'conditions'=>['Times.id = Works.time_id',
                                                                'Times.user_id = Works.user_id']
                                                ],
                                       'TotalTimes'=>['type'=>'LEFT OUTER',
+                                                'table'=> $this->fetchTable('TotalTimes')->getTable()  ,
                                                 'conditions'=>['TotalTimes.id = Works.total_time_id',
                                                                'TotalTimes.user_id = Works.user_id']
                                                ],
                                       ]);
+        $data= $querydata->toList();
        
		//一覧
+        if(!empty($data[0]->order_number) || !empty($data[0]->dummy))
        {
+            $TotalTimes = $this->fetchTable('TotalTimes')->TotalTImelist($user->id ,$data[0]->order_number,$data[0]->dummy);
            $this->set('TotalTimes',$TotalTimes);
        }

+        $Attendance =$this->fetchTable('Attendances')->getXXX($user['id'],
+                                ( empty($data[0]->start_day) ? null :$data[0]->start_day->i18nFormat('yyyy/MM/dd') )
                                );
        //休憩合計時間
+        $sumBreak = $this->fetchTable('WorkBreaks')->SumWorkMeterBreak($id);
        $time_now = strtotime( date( "Y/m/d H:i:s", time() ));

		//省略

	}

大きく書き方が変わったなという場所は色付けしました。そして気を付けることは

  • テーブル名は複数形!
  • コントローラーと違うModelを使う際には、書き方を変える。
  • 宣言をしないと使えないものがある。
  • FindAllしたものはコントローラー内で見れなかったので、toList()しないといけないらしい。
  • 詳細ページのデフォルトfunctionが、showからviewに変わった。

ていうか書き方変わりすぎて辛い。

コントローラの差分メモ

cake2 cake4 備考
Component $components=array('コンポーネント名', 引数); $this->loadComponent('コンポーネント名', 引数); $components廃止だそうです
モデルの呼び出し $this->model $this->models Cakephp4ではモデル名は複数形にする
モデルの呼び出し2 $this->model $this->fetchTable('models') Cakephp2でやれた方法は出来ないのか不明。
カラム名一気に取得 \$this->model->getDataSource()->fields($this->model) $this->models->getSchema()->columns()
カラム名一気に取得2 \$this->model->getDataSource()->fields($this->model) $this->fetchTable('models')->getColumns('models') なかなかソースが見つからず大変だった
モデルのFind \$this->model->findById($id) \$this->models->get($id) Get好きよねCakephp4って
日付フォーマット date("Y/m/d" , strtotime($data['model']['start_day']) $data->start_day->i18nFormat('yyyy/MM/dd') 整形するための指示方法がちょっと違うので注意
データの持ち方 \$data['model']['name'] \$data->name メインで呼び出したModel名は省かれる。
Findのジョイン array(省略, 'joins'=>array(
'type'=>'LEFT OUTER' ,'alias'=>Table名 …省略 
(省略) ->join([Table名=>[ 'type'=>'LEFT OUTER' ,…省略] なんで単数形になったの? そしてエイリアス名の配列位置が変わった
Begin宣言 $this->{model}->begin; //ヘッダーの宣言 

use Cake\Datasource\ConnectionManager;
use Cake\Core\Exception\Exception;

//ソース内部
\$connection = ConnectionManager::get('default');
$connection->begin();

モデル名で宣言できなくなったので注意。/td>
ログ出力 \$this->log($変数名, 'debug'); \$this->log(print_r($変数名,true), 'debug'); print_rしないと連想配列が出力できない。Modelクラスでは出し方違うので注意

Component 改修迷走中

 退職された人が作った、便利共通コンポーネントを愛用していたんですが。やはりこれもバージョンアップ。これを改修していってます(途中)

Cakephp2での表記

よくわかんないけど、コントローラーからの引数とかコントローラ名を取得してセットしてる

CommonOriginalComponent.php
class CommonOriginalComponent extends Component {

	public $settings = array();

	public $model;

	public function __construct(ComponentCollection $collection, $settings = array()) {
		$settings = array_merge($this->settings, (array)$settings);
		$this->Controller = $collection->getController();
		parent::__construct($collection, $settings);
	}

    public function index($fastView = null)
    {
  		$query = Hash::filter($this->Controller->params->query);
		$fastView = empty($fastView ) ? isset($this->Controller->request->params['named']['page']) : !empty($fastView) ;
		
	    $this->Controller->request->data = $query;
        //省略
		if(empty($options['limit'] )){
			$options['limit'] = 10;
		}
		if($fastView){
	    	$this->paginateSet($options);
	    }
	}

  /*Paginatorのセット*/
    public function paginateSet($options,$datasetName ='data')
    {
    //検索条件を入れたやつをPaginatorのsettingsにセット
    	$this->Controller->Paginator->settings = array_merge($this->Controller->Paginator->settings, $options);
    	$whitelist = isset($this->settings['index']['whitelist']) ? $this->settings['index']['whitelist'] : array();
    	try{
			$data = $this->Controller->Paginator->paginate($this->settings['model'], array(), $whitelist);
		} catch(NotFoundException $e){
			//PagenaiteでNotFoundExceptionになった場合強制的に1ページ目に移動
			$this->Controller->request->params['named'] = array('page' => 1);
			$data = $this->Controller->Paginator->paginate($this->settings['model'], array(), $whitelist);
		}
		$this->Controller->set($datasetName, $data);
	}


}

Cakephp4での表記

__constructは使わないほうがいいらしく。Cakephp2で使われてる奴の流用だとわかったので調べたけど、よくわからず。うまく取れる場所はbeforeFilterでは?と直してみました。

CommonOriginalComponent.php

namespace App\Controller\Component;
use Cake\Controller\Component;
use Cake\Controller\ComponentRegistry;
//省略
use Cake\Http\ServerRequest;
use Cake\Utility\Hash;
class CommonOriginalComponent extends Component {

  public function beforeFilter()
    {
       $this->Controller = $this->getController();
+      $this->request = $this->Controller->getRequest();
+      $this->settings = $this->Controller->components['CommonOriginal'];

    }
  public function index($fastView = null)
  {
+		$query = Hash::filter($this->Controller->getRequest()->getQueryParams());//検索条件の取得
+		$fastView = empty($fastView ) ? !empty($this->Controller->getRequest->getQuery('page')) : !empty($fastView) ;
        //省略
        $this->paginate['limit'] = (!empty($options['limit']) ? $options['limit'] : $this->paginate['limit'] );

        if($fastView){
            $this->paginateSet($options,$datasetName);
        }
  }


  /*Paginatorのセット*/
  public function paginateSet($options,$datasetName ='data')
  {
      //whitelistは廃止された allowedParametersを使えって書いてあるけど、使い方が分からず保留
      //$whitelist = isset($this->settings['index']['whitelist']) ? $this->settings['index']['whitelist'] : array();
      try{
         //Paginatorのsettingsがなくなってしまい。
         //とりあえず、検索条件を入れたやつでQueryを再度つくってみたけどなんか違う気がするので保留中です         
          $query = $this->Controller->$datasetName->find('all') //~省略~
+         $data = $this->Controller->paginate($query,$this->paginate);
      } catch(NotFoundException $e){
        //PagenaiteでNotFoundExceptionになった場合強制的に1ページ目に移動
        $this->paginate=['page' => 1];
        $this->Controller->Paginator->paginate($this->settings['model'], $options);
        $data = $this->Controller->paginate($query,$this->paginate);
      }
      $this->Controller->set("{$datasetName}", $data);
 }


どれがどう変わったのか、というよりも元のソースの理解が半分もないので新しくするためにどれを使えばいいのか…。

コンポーネントの差分メモ

cake2 cake4 備考
渡された引数 $settings $this->Controller->components['CommonOriginal'] Cakephp2はよくわからん
Formからのパラメータ $this->Controller->params->query $this->Controller->getRequest()->getQueryParams() Cakephp4のリクエストをとりあえず全部ログに出した結果これだった

モデルの差分メモ

cake2 cake4 備考
ログ出力 \$this->log($変数名, 'debug'); \Cake\Log\Log::write('debug', print_r($変数名,true)); print_rしないと連想配列が出力できない
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