■ モデルに関数を書く
モデル
src/Model/Table/HogeMasterTable.php
use Cake\ORM\TableRegistry; // 他のモデルを参照する時
use Cake\Datasource\ConnectionManager; // 生 SQL を実行する時
~ ~ ~ ~
public function hoge($input)
{
$outoput = array();
// 【自分】の場合
$outoput['hoge'] = $this->find()->where(['hoge_id' => $input['hoge_id']])->first();
// 【他のモデル】の場合
$FugaMaster = TableRegistry::getTableLocator()->get('FugaMaster');
$outoput['fuga'] = $FugaMaster->find()->where(['hoge_id' => $input['hoge_id']])->first();
// 【生 SQL】の場合
$connection = ConnectionManager::get('default');
$sql = "SELECT * FROM `piyo_master` WHERE `id` = '{$input['hoge_id']}'";
$outoput['piyo'] = $connection->execute($sql)->fetchall('assoc');
// 1 つのときは fetch('assoc');
return $outoput;
}
コントローラー
public function index()
{
$input = array('hoge_id'=>10);
$res = $this->HogeMaster->hoge($input);
■ 生 SQL コントローラー
(参照)
use Cake\Datasource\ConnectionManager;
~ ~ ~ ~
$sql = "SELECT * FROM `users` WHERE `id` = '{$id}'";
$connection = ConnectionManager::get('default');
$users = $connection->execute($sql)->fetch('assoc'); // 1 つ
$users = $connection->execute($sql)->fetchall('assoc'); // 複数
(更新)
use Cake\Datasource\ConnectionManager;
~ ~ ~ ~
$connection = ConnectionManager::get('default');
$sql = "UPDATE `users` SET `name`='ケンジ' WHERE `id` = '{$id}'";
$connection->execute($sql);
■ ページネートにジョイン (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