ENTEREAL

CakePHP3を始めた方に

データ検索

get

テーブルのプライマリーキーを指定して1件のデータを検索する時に使用

// MODELから同モデルを読み込む場合
$result = $this->MODELs->get($id);

// 他のモデルを読み込む場合
use Cake\ORM\TableRegistry;

$class = TableRegistry::get('Xxxx');
$result = $class->get($id);

find

テーブルのデータを全件又は、絞り込んで検索する時に使用
※ CakePHP2から若干変わって、QueryBuilderを使う

// MODELsController.phpから同モデルを読み込む場合
$results = $this->MODELs->find();

// 他のモデルを読み込む場合
use Cake\ORM\TableRegistry;

$class = TableRegistry::get('Xxxx');
$results = $class->find();

出力するカラムを指定する場合

// 全カラム
$results = $this->MODELs->find();

// 列記方式
$results = $this->MODELs->find()
->select(['id', 'name', 'email', ...]);

// 除外方式
$results = $this->MODELs->find()
->extract(['name']);

// 列別名
$results = $this->MODELs->find()
->select(['id' => 'id_number', 'name' => 'user_name', 'email', ...]);

// Distinct
// SELECT DISTINCT id FROM Xxxx ...
$results = $this->MODELs->find()
->distinct(['id']);

データを絞り込む

// 出力する条件を指定する場合 (イコール)
$results = $this->MODELs->find()
->where(['id' => 1, 'name' => 'test_user']);

// 出力する条件を指定する場合 (不等号)
$results = $this->MODELs->find()
->where(['id !=' => 1]);

// 出力する条件を指定する場合 (大小)
$results = $this->MODELs->find()
->where(['id >' => 1]);

// 出力する条件を指定する場合 (IN)
$results = $this->MODELs->find()
->where(['id IN' => [1, 2, 3, ...]]);

// 出力する条件を指定する場合 (LIKE)
$results = $this->MODELs->find()
->where(['name LIKE' => %test%]);


// whereを複数回使う
$results = $this->MODELs->find()
->where(['id' => 1])
->where(['name' => 'test_user']);

// OR を使う
// SELECT * FROM MODELs WHERE id = 1 AND (username = 'A' OR username = 'B');
$results = $this->MODELs->find()
->where([
'id' => 1,
'OR' => [['username' => 'A'], ['username' => 'B']]
]);

// orWhere を使う
// SELECT * FROM MODELs WHERE id = 1 OR username = 'A';
$results = $this->MODELs->find()
->where(['id' => 1])
->orWhere(['name' => 'A']);

データを絞り込む (外部キー)

// Yyyy belongsTo Xxxx
$results = $this->MODELs->Yyyies->find()
->where(['id >' => 1]);

データをソートする

$results = $this->MODELs->find()
->order(['created' => 'DESC', 'modified' => 'ASC']);

結果セットの数をカウント

$results = $this->MODELs->find()
->where(['id' => 1, 'name' => 'test_user'])
->count();

結果セットの数を変えたい

// 先頭1行だけ
$result = $this->MODELs->find()
->first();

// 50行目から100行目だけを取得
$result = $this->MODELs->find()
->limit(50)
->page(2);

結果セットの形を変えたい

// Array形式
// $resultsArray[0]->id
$resultArray = $this->MODELs->find()
->toArray();

// リスト形式 (1)
$resultsList = $this->MODELs->find('list')
->select(['id', 'title']);

// リスト形式 (2)
$resultsList = $this->MODELs->find()
->combine('id', 'title');

// foreach ($resultsList as $id => $title) {
// 	echo "$id : $title"
// }

集計した値を取得

// SELECT COUNT(*) count FROM ...
$results = $this->MODELs->find();
$results->select(['count' => $results->func()->count('*')]);

// SELECT SUM(score) total FROM ...
$results = $this->MODELs->find();
$results->select(['total' => $results->func()->sum('score')]);

// SELECT AVG(score) average FROM ...
$results = $this->MODELs->find();
$results->select(['avarage' => $results->func()->avg('score')]);

// SELECT MIN(score) minimum FROM ...
$results = $this->MODELs->find();
$results->select(['minimum' => $results->func()->min('score')]);

// SELECT MAX(score) maximum FROM ...
$results = $this->MODELs->find();
$results->select(['maximum' => $results->func()->max('score')]);

// SELECT COUNT(prefecture) count FROM ...
// The arguments will be treated as literal values.
$results = $this->MODELs->find();
$results->select(['count' => $results->func()->count('prefecture')]);

// SELECT CONCAT(prefecture, city) address FROM ...
$results = $this->MODELs->find();
$results->select(['address' => $results->func()->concat('prefecture', 'city')]);

// SELECT COALESCE(gender, 'unknown') gender FROM ...
// if gender data is null, then it returns 'unknown' value instead.
$results = $this->MODELs->find();
$results->select(['gender' => $results->func()->coalesce('gender', 'unknown')]);

作成されたSQLを見たい

debug($this->MODELs->find()->where(['id' => '...']));

// Outputs
// ...
// 'sql' => 'SELECT * FROM MODELs where id = ?'
// ...

アソシエーションテーブルも取得する場合

// アソシエイトしたテーブル丸ごと取得
$query = $articles->find('all');
$query->contain(['Authors', 'Comments']);

// 特定のカラムだけ取得
$query = $articles->find()
->contain([
'Authors' => ['Addresses'],
'Comments' => ['Authors']
]);

// 特定のカラムだけ取得
$query = $articles->find()
->contain([
'Authors.Addresses',
'Comments.Authors'
]);

// 更に先のアソシエイトテーブルのデータを取得
$query = $products->find()
->contain([
'Shops.Cities.Countries',
'Shops.Managers'
]);

// アソシエイトテーブルのデータを絞り込んで取得
// Articles belongsToMany Tags
// it returns Articles that have the CakePHP tag.
$query = $articles->find();
$query->matching('Tags', function($q) {
return $q->where(['Tags.name' => 'CakePHP']);
});

// アソシエイトテーブルのデータを絞り込んで取得
// Authors HasMany Articles
// it returns Authers who created(wrote) new articles in last 10 dyas
$query = $authors->find();
$query->matching('Articles', function($q) {
return $q->where(['Articles.created >=' => new DateTime('-10 days')]);
});


// In a controller or table method.
$query = $products->find()
->matching(
'Shops.Cities.Countries', function($q) {
return $q->where(['Countries.name' => 'Japan']);
}
);

// Bring unique articles that were commented by 'markstory' using passed variable
$username = 'markstory';
$query = $articles->find()
->matching('Comments.Users', function($q) use ($username) {
return $q->where(['username' => $username]);
});

データ更新

INSERT

データを追加する
※ 通常はORM\Table::save()メソッドを使う

$query = $articles->query();
$query->insert(['title', 'body'])
->values([
'title' => 'First post',
'body' => 'Some body text'
])
->execute();

// SELECT AND INSERT
$select = $articles->find()
->select(['title', 'body', 'published'])
->where(['id' => 3]);

$query = $articles->query()
->insert(['title', 'body', 'published'])
->values($select)
->execute();

UPDATE

データを更新する
※ 通常はORM\Table::patchEntity()メソッドを使う

$query = $articles->query();
$query->update()
->set(['published' => true])
->where(['id' => $id])
->execute();

DELETE

データを削除する
※ 通常はORM\Table::delete()メソッドを使う

$query = $articles->query();
$query->delete()
->where(['id' => $id])
->execute();

View関連

Form Helper

フォーム要素

// FULL Option
Form->create($xxxx,
[
'type' => 'file',										// get, post, file, put, ...
'url' => ['controller' => 'controller_name', 'action' => 'action_name', value],
//			'url' => 'http://www.google.com/search'					// can user this as well
]
);

// you put elements here

echo $this->Form->button(__(' Submit'),
[
'type' => 'submit',						// button, reset, ...
'escape' => true
]
);
echo $this->Form->end(['data-type' => 'hidden']);
?>

INPUT要素

Form->input('name',
[
'type' => 'text',				// text, file, date, email, tel, ...
'id' => 'id_name',
'class' => 'class_name',
'required' => false,
'label' => 'label_text',
'default' => 'Taro',
'placeholder' => 'Taro',
'maxlength' => 5,
'disabled' => false,
'readonly' => true
]
);


// Actually it depends on how the table is defined
// Users table
CREATE TABLE users (
id INT(11) AUTO_INCREMENT PRIMARY KEY comment 'アカウントID',
name VARCHAR(50) NOT NULL comment 'アカウント名',
email VARCHAR(50) NOT NULL comment 'メールアドレス',
password VARCHAR(255) NOT NULL comment 'パスワード',
birthday DATE NOT NULL comment '誕生日',
memo TEXT NOT NULL comment 'メモ',
created DATETIME,
modified DATETIME
);

echo $this->Form->input('name');
// this will be 

echo $this->Form->input('password');
// this will be 

echo $this->Form->input('birthday');
// this will be SELECT inputs for Year, Month, Day

echo $this->Form->input('memo');


// VALIDATION MESSAGE
$this->Form->input('name', [
'error' => ['Not long enough' => __('This is not long enough')]
]);
?>

DATE要素

Form->input('birthday', [
'type' => 'date',
'label' => 'Date of birth',
'empty' => true,									// If true, the empty select option is shown
'round' => 'up',									// or down
'minYear' => date('Y') - 70,
'maxYear' => date('Y') - 18,
'orderYear' => 'asc',
'monthNames' => false,		// 01, 02, 03 ....
//	'monthNames' => ['01' => '1月', '02' => '2月', ...],		// ...
'year' => [
'class' => 'year-classname',
],
'month' => [
'class' => 'month-class',
'data-type' => 'month',
],
'day' => [
'class' => 'day-class',
'data-type' => 'day',
]
]);

// TIME
echo $this->Form->input('time', [
'type' => 'time',
'interval' => 15,
'timeFormat' => 24,									// or 12
'second' => false,
'hour' => [
'class' => 'hour-class',
'data-type' => 'hour',
],
'minute' => [
'class' => 'minute-class',
'data-type' => 'minute',
]
]);
?>


// To change order of the inputs
$this->Form->templates([
'dateWidget' => '{{year}}年{{month}}月{{day}}日 {{hour}}時{{minute}}分{{second}}秒 {{meridian}}'
]);

SELECT要素

 'Small', 'm' => 'Medium', 'l' => 'Large'];			// ['value' => 'option text', ...]
echo $this->Form->select('size',
$sizes_list,
[
'multiple' => true,
//		'multiple' => 'checkbox',							// this will outputs a list of related checkboxes
'default' => ['s', 'l'],
'empty' => '(choose one)',
'id' => 'id_name',
'class' => 'class_name',
'required' => false,
'label' => 'label_text',
'disabled' => false,
//		'disabled' => ['s', 'm'],							// this can be enabled when it outputs with checkboxes
'readonly' => true
]
);



// OPTIONs from DB
$this->set('groups', $this->Users->Groups->find('list'));
echo $this->Form->input('group_id', ['options' => $groups]);

// OPTGROUP
$options = [
'Group 1' => [
'Value 1' => 'Label 1',
'Value 2' => 'Label 2'
],
'Group 2' => [
'Value 3' => 'Label 3'
]
];
?>

RADIO要素

Form->radio(
'favorite_color',
[
[
'value' => 'r',
'text' => 'Red',
'style' => 'color:red;',
'id' => 'id_name',						// id 'favorite_color_r' is given by default if id is not defined
'class' => 'class_name',
'checked' => true,
'disabled' => false
],
['value' => 'u', 'text' => 'Blue', 'style' => 'color:blue;'],
['value' => 'g', 'text' => 'Green', 'style' => 'color:green;']
]
);
?>

CHECKBOX要素

Form->input('Baseball',
[
'hiddenField' => 'No Interests',
'type' => 'checkbox',
'value' => 'baseball',
'name' => 'interests[]',
'id' => 'id_name',
'class' => 'class_name',
'checked' => true,
'disabled' => false
]
);
// 
// so that the key in $this->request->data will exist even without a value specified


// Multiple checkboxes
$options = [
['text' => 'Baseball', 'value' => 'baseball', 'id' => 'id_name'],
['text' => 'Football', 'value' => 'football'],
['text' => 'Basketball', 'value' => 'basketball'],
];
echo $this->Form->select('interests', $options, ['multiple' => 'checkbox']);
?>

TEXT要素

Form->textarea('notes',
[
'escape' => false,
'rows' => '5',
'cols' => '5',
'default' => 'defalut_text',
'id' => 'id_name',
'class' => 'class_name',
'required' => false,
'placeholder' => 'placeholder_text',
'disabled' => false,
'readonly' => true
]
);

// another way
echo $this->Form->input('notes',
[
'type' => 'textarea'
]
);
?>

FILE要素

Form->create('resume',
[
'type' => 'file'
]
);

// another way
echo $this->Form->file('resume');


// In the Controller
$this->request->data['resume'] = [
'name' => 'my_resume_file.pdf',
'type' => 'application/pdf',
'tmp_name' => 'C:/WINDOWS/TEMP/php1EE.tmp',
'error' => 0, // On Windows this can be a string.
'size' => 41737,
];
?>

アソシエイトテーブル

Form->input('title');

// Author inputs (belongsTo)
echo $this->Form->input('author.id');
echo $this->Form->input('author.first_name');
echo $this->Form->input('author.last_name');

// Author profile (belongsTo + hasOne)
echo $this->Form->input('author.profile.id');
echo $this->Form->input('author.profile.username');

// Tags inputs (belongsToMany)
echo $this->Form->input('tags.0.id');
echo $this->Form->input('tags.0.name');
echo $this->Form->input('tags.1.id');
echo $this->Form->input('tags.1.name');

// Multiple select element for belongsToMany
echo $this->Form->input('tags._ids', [
'type' => 'select',
'multiple' => true,
'options' => $tagList,
]);

// Inputs for the joint table (articles_tags)
echo $this->Form->input('tags.0._joinData.starred');
echo $this->Form->input('tags.1._joinData.starred');

// Comments inputs (hasMany)
echo $this->Form->input('comments.0.id');
echo $this->Form->input('comments.0.comment');
echo $this->Form->input('comments.1.id');
echo $this->Form->input('comments.1.comment');


// In the Controller
$article = $this->Articles->patchEntity($article, $this->request->data, [
'associated' => [
'Authors',
'Authors.Profiles',
'Tags',
'Comments'
]
]);
?>

default.ctp以外のテンプレート(src/Template/Layout/xxx.ctp)を使用する

$this->viewBuilder()->layout('template_name');

認証情報を使う

$LoginUser = $this->Auth->user();

echo $LoginUser['id'];				# id
echo $LoginUser['username'];		# username
echo $LoginUser['password'];		# password
echo $LoginUser['role'];			# role

元のページに転送

$this->redirect($this->referer(array('controller' => 'Planners', 'action' => 'index')));
# referer()内は、リファラーが取れない場合のリダイレクト先

Flashメッセージを変更する

これを任意に書き換える

例) Bootstrapのalert要素で代替


データを「0」埋めする

$this->Number->format(($planner->user_id), ['pattern' => '000000']);

コントローラ名/アクション名を取得

// コントローラ名 => Users
$this->name

// アクション名 => index
$this->request->action

Tags