■ ページネートにジョイン (3.10)
例)FROM hoge A LEFT JOIN fuga B ON A.fugaid = B.id
◆ モデル
src/Model/Table/HogeTable.php
public function initialize(array $config): void { parent::initialize($config); //////// 以下を追加 $this->hasOne('Fuga', [ 'joinType' => 'LEFT OUTER', 'foreignKey' => 'id', // 相手 'bindingKey' => 'fugaid', // 自分 ]); }相手のモデルには特に何も書かなくてよい。
$options = [ 'conditions' => [ // 条件が必要なら書く。 'Hoge.honyarara' => 1, ], 'contain' => [ // 相手のテーブル。 'Fuga' ], 'limit' => 20 ]; $dataHpgeFuga = $this->paginate($this->Hoge, $options);
■ ページネートにジョインした項目でソート (3.10)
◆ コントローラー
src/Controller/HogeController.php
$options = [ 'conditions' => [ // 条件が必要なら書く。 'Hoge.honyarara' => 1, ], 'contain' => [ // 相手のテーブル。 'Fuga' ], 'order' => [ 'Fuga.sortkey desc' // asc は省略可 ], 'limit' => 20 ]; $dataHpgeFuga = $this->paginate($this->Hoge, $options);ただし、一覧見出しのソートと混ざるとエラーになります。
$options['order'] = array( 'hogekey'=>'asc', // URL の引数 'Fuga.sortkey desc' // ジョインの書式(本来はバリデーションでエラー) );マージ前に URL からの引数を渡している場所は以下。 vendor/cakephp/cakephp/src/Controller/Controller.php
L991 try { $results = $paginator->paginate( $table, $this->request->getQueryParams(), // ← これ $settings );どっちもコア部分で、いじるのは良くないし、
■ ページネートに条件
public function index() { $query = $this->Hogetables->find(); $query->where(['user_id' => $this->Auth->user('id'), 'status' => 0]); $hogetables = $this->paginate($query); $this->set(compact('hogetables')); }
■ コントローラーでバリデーションエラーを見る
save の後に getErrors() で採れます。
$this->Users ではなく、$user の方です。
if ($this->Users->save($user)) { $this->Flash->success(__('The user has been saved.')); return $this->redirect(['action' => 'index']); } $this->Flash->error(__('The user could not be saved. Please, try again.')); error_log("\n----- error -----\n", 3, '/home/logs/log'); error_log(print_r($user->getErrors(), true), 3, '/home/logs/log');↓ tail -f /home/logs/log ----- error ----- Array ( [username] => Array ( [_isUnique] => This value is already in use ) )
■ コントローラーからモデルに定義した独自関数を利用する
$vvv = $this->Users->vvv("vvvv");コントローラーでこんなふうにしたいときは、以下に書きます。
src/Model/Table/UsersTable.php public function vvv($data) { error_log("\n----- $data -----\n", 3, '/home/logs/log'); return $data; }
■ メール送信
例)
コントローラー
use Cake\Mailer\Email; ~ $email->setFrom(['from@example.com' => '管理人']) ->setTo('to@example.com') ->setSubject('題名') ->send('本文'); ~ // 分けて書く $email->setFrom(['from@example.com' => '管理人']) ->setTo('to@example.com') ->setSubject('題名'); if ($email->send('本文')) { $this->Flash->success('メール送信完了しました。'); }else{ $this->Flash->error('メール送信完了できませんでした。'); }
■ URL を作成
例)
$url = Router::url(['controller'=>'SentInquiries', 'action'=>'view', $id], true); // https://webinko.com/sys/sent-inquiries/view/5 $link = '<a href="'.$url.'">'.$url.'</a>';
■ ビューでオリジナル関数を使う
以下に任意のファイルを置いて書いて呼び出します。
/src/View/Helper/
例)
src/View/Helper/StandardHelper.php
<?php namespace App\View\Helper; use Cake\View\Helper; class StandardHelper extends Helper { // 男女のラジオボタン public function radioSex($data=null) { $res = array('type' => 'radio', 'options' => array('1'=>'男','2'=>'女','0'=>'その他'), 'legend'=>false); if(empty($data['sex'])){ $res['default'] = 0; }else{ $res['default'] = $data['sex']; } return $res; } // 男女の表示 public function dispSex($num=null) { $data = array('その他', '男', '女'); return $data[$num] ? $data[$num] : 'その他'; } }src/View/AppView.php
<?php namespace App\View; use Cake\View\View; class AppView extends View { public function initialize() { parent::initialize(); $this->loadHelper('Standard'); // ← StandardHelper 取り込み } }src/Template/Users/edit.ctp
<?php echo $this->Form->control('sex', $this->Standard->radioSex($user)); ?>src/Template/Users/view.ctp
<?= $this->Standard->dispSex($user->sex) ?>'type' => 'radio' って指定しないとセレクトボックスになります。
<?php echo $this->Form->control('remind_q', ['options' => $remind_q]); ?>
■ コントローラーで他のDBを参照
例)
コントローラーへ以下のように追加。
~ use Cake\ORM\TableRegistry; ~ class UsersController extends AppController { public function initialize() { parent::initialize(); $this->Notices = TableRegistry::get('notices'); } ~
$public_notices = $this->Notices->find('all', ['conditions' => ['status' => 0, 'public' => 1]]);
■ DBから1レコードだけでよいとき
[0] とか要らんときは最後に ->first() 付けます。でいいのかな。
例)
$duty = $this->Infos->find('all', ['conditions' => ['filename' => 'duty']])->first();
■ セレクトボックスのオプション
id をキーにした連想配列。
例)
モデル(src/Model/Table/ResTemplatesTable.php)
public function initialize(array $config) { ~ $this->setDisplayField('subject'); // list で表示したいカラムコントローラー
use Cake\ORM\TableRegistry; ~ public function initialize() { parent::initialize(); $this->ResTemplates = TableRegistry::get('res_templates'); ~ $resTemplate = $this->ResTemplates->find('list')->toArray();ビュー
<?= $this->Form->control('res_template_id', ['options'=>$resTemplate]) ?> <?php echo $this->Form->control('res_template_id', ['options'=>$resTemplate]); ?>
■ 本体はウェブりたくないとき
シンボリックリンクだと簡単です。
例)
https://ドメイン/sys/ とする場合。
/home/hoge/ ├ cakephp/webroot/ └ public_html/ └ sys -> /home/hoge/cakephp/webrootコマンド
ln -s /home/hoge/cakephp/webroot /home/hoge/public_html/sys