cakephp3 バリデーション

->add(‘zip’, [
    ‘num’ => [‘rule’ => [‘numeric’], ‘message’ => ‘郵便番号をご確認下さい’],
    ‘range’ => [‘rule’ => [‘lengthBetween’, 7, 7], ‘message’ => ‘郵便番号をご確認下さい’],
])

$validator
    ->add(‘username’, [‘len’ => [‘rule’ => [‘maxLength’, 50], ‘message’ => ‘文字数オーバー(50文字以内)’]])
    ->add(‘username’, ‘custom’, [‘rule’ => [$this, ‘checkUsername’], ‘message’ => ‘そのIDは既に登録されています’])
    ->requirePresence(‘username’, ‘create’)
    ->notEmpty(‘username’);

public function checkUsername($value, $context)
{
    if($this->find()->where([‘username’ => $value])->count() > 0){
        return false;
    }
    return true;
}

cakephp3 FormHelper

■control
$this->Form->control(‘item_category_id’, [‘label’ => [‘text’ => ‘カテゴリー選択’], ‘options’ => $itemCategories])

■input
$this->Form->input($key . ‘.no’, array_merge($input_set, [‘oninput’ => ‘input_set(‘ . $key . ‘)’]))

■hidden
$this->Form->hidden(‘chk_flg_’ . $key, [‘value’ => 0])

■checkbox
$this->Form->checkbox(‘all’, [‘style’=> ‘margin:0 0 0 0;’, ‘hiddenField’ => false, ‘checked’ => false, ‘onClick’ => ‘allchk(“item_chk[]”);’])

■image
$this->Html->image(“upload_img/” . $item->image, [‘style’ => ‘width:100px;height:auto;’])

■link
$this->Html->link(‘【カートを確認】’, [‘controller’ => ‘Carts’, ‘action’ => ‘index’])

■postLink
$this->Form->postLink(‘削除’, [‘action’ => ‘delete’, $item->id], [‘confirm’ => __(‘削除します # {0}?’, $item->name)])

■button
$this->Form->button(‘戻る’, [‘name’ => ‘back’, ‘style’ => ‘margin-right:1rem;’])

■element
$this->element(‘menu/menu’)

■親テーブルの値
h($item->item_category->name)

■create
<?= $this->Form->create(null, [‘url’ => [‘action’ => $act], ‘name’ => ‘index’]) ?><?= $this->Form->end() ?>

■foreach
<?php foreach ($items as $key => $item): ?><?php endforeach; ?>

■if
<?php if ($item->flg == 0): ?>あり<?php else: ?>なし<?php endif; ?>

cakephp3 クエリビルダ

■find

$this->paginate = [
    ‘limit’ => 10,
    ‘order’ => [‘Items.no’ => ‘desc’]
];

$items = $this->Items->find();
$items->select($this->Items);
$items->select($this->Items->ItemCategories);
$items->select([‘cart’ => ‘ IF(Carts.id IS NULL, 0, 1) ‘]);
$items->leftJoin([‘Carts’ => ‘carts’], [‘Carts.user_id = ‘ . $this->Auth->user(‘id’), ‘Carts.item_id = Items.id’, ‘Carts.flg = 0’]);
$items->contain([‘ItemCategories’]);
$items->where([‘Items.name like’ => ‘%’. $this->request->data[‘search_txt’] . ‘%’]);

$items = $this->paginate($items);

■countとfirst

$this->Users->find()->where([‘role’ => ‘user’])->count()
$this->Users->find()->where([‘role’ => ‘user’])->order([‘Users.modified’ => ‘ASC’])->first()

■updateAll

$this->Carts->updateAll([‘flg’ => 1], [‘user_id’ => $this->Auth->user(‘id’)]);

cakephp3 ログイン処理

■AppControllerのinitialize()に

$this->loadComponent(‘Auth’,[
    ‘authorize’ => [‘Controller’],
    ‘authenticate’ => [
        ‘Form’ => [
            ‘fields’ => [
                ‘username’ => ‘username’,
                ‘password’ => ‘password’
            ]
        ]
    ],
    ‘loginRedirect’ => [
        ‘controller’ => ‘Users’,
        ‘action’ => ‘index’
    ],
    ‘logoutRedirect’ => [
        ‘controller’ => ‘Users’,
        ‘action’ => ‘login’,
    ],
    ‘loginAction’ => [
        ‘controller’ => ‘Users’,
        ‘action’ => ‘login’
    ],
    ‘authError’ => false,
]);

■UsersControllerに

public function isAuthorized($user = null){
    if(in_array($this->request->params[‘action’], [‘index’, ‘delete’])){
        if(in_array($user[‘role’], [‘admin’, ‘super’])) {
            return true;
        }
    }
    if(in_array($this->request->params[‘action’], [‘edit’])){
        if(in_array($user[‘role’], [‘admin’, ‘super’, ‘user’, ‘sp’])) {
            return true;
        }
    }

    return false;
}

public function beforeFilter(\Cake\Event\Event $event) {
    parent::beforeFilter($event);
    $this->Auth->allow([‘add’, ‘confirm’, ‘logout’]);
}

public function login()
{
    $this->viewBuilder()->setLayout(‘nohead’);

    if($this->request->is(‘post’)){
        $user = $this->Auth->identify();
        if($user){
            $this->Auth->setUser($user);
            return $this->redirect($this->Auth->redirectUrl());
        }
        $this->Flash->error(‘ユーザー名かパスワードが間違えています。’);
    }
}

public function logout()
{
    $this->Flash->success(‘ログアウトしました’);
    return $this->redirect($this->Auth->logout());
}

■login.ctp

<div class=”users form columns content”>
    <p style=”text-align:center;border-bottom:1px solid #555;”>Login</p>
    <?= $this->Form->create() ?>

    <?= $this->Form->input(‘username’) ?>
    <?= $this->Form->input(‘password’) ?>
    <?= $this->Form->button(‘Login’) ?>

    <p style=”clear:right;float:right;”><?= $this->Html->link(“ユーザー登録はこちらから”, [‘action’ => ‘add’]) ?></p>

    <?= $this->Form->end() ?>
</div>

■Model User

use Cake\Auth\DefaultPasswordHasher;

protected $_hidden = [
    ‘password’
];

protected function _setPassword($password)
{
    if (strlen($password) > 0) {
        return (new DefaultPasswordHasher)->hash($password);
    }
}

■SQL

CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(255) NOT NULL,
`role` varchar(20) DEFAULT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
)

timezone

・bootstrap.phpのdate_default_timezone_set(‘Asia/Tokyo’);
PHPでの「date(‘Y-m-d H:i:s’, time())」などが日本時間になる。
・app.phpの’timezone’ => ‘+09:00’,
MySQLでの「now()」などが日本時間になる。
※DATE_FORMAT(EventLists.enddate,”%Y/%m/%d %k:%i:%s”)などは、普通に登録されている時刻が表示される。
※UNIX_TIMESTAMP(EventLists.enddate)なんかは、timezoneの設定で、値が変化する。
(date()やtime()とか、()に何か入れないとエラーになる連中は影響を受けないみたい・・・)

cakephp3 ディレクトリ階層変更

(composer.pharの場所 www.test.co.jp直下)
sudo php composer.phar create-project –prefer-dist -s dev cakephp/app /var/www/www.test.co.jp/cake/app/mb

mb以下のファイルはすべて削除(bin~webrootのディレクトリのみの状態)

webroot内の以下のディレクトリ、ファイルを「html/m」へ移動
css
img
js
favicon.ico

以下のファイルを「html/m」へコピー
.htaccess
index.php

.htaccess修正
<IfModule mod_rewrite.c>
    RewriteEngine on
    # RewriteRule ^$ webroot/ [L]
    # RewriteRule (.*) webroot/$1 [L]
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php?url=$1 [L]
</IfModule>

index.php修正
//require ‘webroot’ . DIRECTORY_SEPARATOR . ‘index.php’;
require dirname(dirname(__DIR__)) . ‘/cake/app/mb/webroot/index.php’;

config/bootstrap.php修正
//require ROOT . DS . ‘vendor’ . DS . ‘autoload.php’;
require dirname(dirname(dirname(__DIR__))) . DS . ‘vendor’ . DS . ‘autoload.php’;

config/paths.php修正
//define(‘CAKE_CORE_INCLUDE_PATH’, ROOT . DS . ‘vendor’ . DS . ‘cakephp’ . DS . ‘cakephp’);
define(‘CAKE_CORE_INCLUDE_PATH’, dirname(dirname(dirname(__DIR__))) . DS . ‘vendor’ . DS . ‘cakephp’ . DS . ‘cakephp’);

define(‘CAKE_APP’, ‘mb’);//追加

vendor/composer修正
appディレクトリのsrcの場所を指定している箇所がある。
ここの指定を修正しないと、「[Cake\Routing\Exception\MissingControllerException] Controller class」とか言われる。
composer.phar実行時の引数によって、ファイルや記載方法が違うので、composer内で「src」で検索してヒットした箇所を修正。
例1)
※こちらは、そのままにしておくと、XAMPPで接続した時、Error: [Cake\Routing\Exception\MissingControllerException] Controller class Tests could not be found. となった。
vendor/composer/autoload_psr4.php
‘App\\Test\\’ => array($baseDir . ‘/tests’),
‘App\\’ => array($baseDir . ‘/src’),

‘App\\Test\\’ => array($baseDir . ‘/app/’.CAKE_APP.’/tests’),
‘App\\’ => array($baseDir . ‘/app/’.CAKE_APP.’/src’),

例2)
vendor/composer/autoload_static.php
‘App\\Test\\’ =>
    array (
        0 => __DIR__ . ‘/../..’ . ‘/tests’,
    ),
‘App\\’ =>
    array (
        0 => __DIR__ . ‘/../..’ . ‘/src’,
    ),

‘App\\Test\\’ =>
    array (
        0 => __DIR__ . ‘/../..’ . ‘/app/’.CAKE_APP.’/tests’,
    ),
‘App\\’ =>
    array (
        0 => __DIR__ . ‘/../..’ . ‘/app/’.CAKE_APP.’/src’,
    ),

cakephp3インストール

cd /var/www/
(dev.test.co.jpディレクトリがある状態でいいらしい)
(dev.test.co.jpディレクトリの中は空じゃないとエラーになる)
sudo curl -sS https://getcomposer.org/installer | php
sudo php composer.phar create-project –prefer-dist -s dev cakephp/app dev.test.co.jp
↑↑↑
3.2.10では、config/bootstrap.phpの110行目「setDefaultOutputTimezone」でエラーになった。
110行目、111行目をコメントアウトすると問題なく動く。
(3.2.8では、この2行は無い)
なので、3.2.8を手動でとってきて、手動で置いておいた。