CakePHP3勉強会@福岡 vol.2 ハンズオン資料

## 目次

1. ゴール
2. CakePHP 3 インストール
3. CakePHP3 初期設定
4. マイグレーション
5. Bake
6. 登録、編集、削除をやってみよう。
7. ログイン画面の作成

## 1. ゴール

CakePHP3のBakeで簡単にProjectを作成し
触ってみる。

## 2. CakePHP 3 インストール

まずCakePHP3 インストールしてみましょう！

### システム要件

インストールする前にCakePHP3のシステム要件を知りましょう！

 - HTTPサーバー(例: Apache。mod_rewrite が推奨されますが、必須ではありません)
 - PHP 5.6 以上 (PHP 7 も含む)
 - PHP mbstring 拡張
 - PHP intl 拡張
 - DB(必ず必要ではありません)
   - MySQL (5.1.10 以上)
   - PostgreSQL
   - Microsoft SQL Server (2008 以上)
   - SQLite 3
   
今回はMySQL or PostgreSQL想定
* 組み込みのドライバは全て PDO を必要とします。 正しい PDO 拡張モジュールがインストールされているか必ず確かめてください。

### CakePHP のインストール

始める前に、PHP バージョンがPHP 5.6 以上であることを確認してください。

参考：http://book.cakephp.org/3.0/ja/installation.html

```
*叩く場所はどこでもよい
command
    php -v
```

### CakePHP3のインストール

- CakePHP の公式のインストール方法として、依存性管理ツール Composer を使用します。

```
command
    cd /var/www/html/
    curl -s https://getcomposer.org/installer | php
```

```
output

All settings correct for using Composer
Downloading 1.0.0...

Composer successfully installed to: /var/www/html/htdocs/hands-on/composer.phar
Use it: php composer.phar
```

- composer.phar ダウンロード確認

```
command
    cd /var/www/html/
    ls -la
```

```
output
    composer.phar
```

### CakePHP3 プロジェクトを作成

```
command
    cd /var/www/html/
    php composer.phar create-project --prefer-dist cakephp/app {{project name}}
```

```
Writing lock file
Generating autoload files
> Cake\Composer\Installer\PluginInstaller::postAutoloadDump
> App\Console\Installer::postInstall
Created `config/app.php` file
Set Folder Permissions ? (Default to Y) [Y,n]? Y
```

```
URL
    http://{{自分のIP}}/{{project name}}/
```

![image](https://qiita-image-store.s3.amazonaws.com/0/74128/cd80dfa4-93c9-1b4d-0751-c24ce9ab58c9.png)
![image](https://qiita-image-store.s3.amazonaws.com/0/74128/9752e1c4-e92c-09fd-cff6-826ad627b4da.png)


- インストール確認

基本的には下記の構成のProjectができます。

```
/{{project name}}
    /bin // 実行可能なCakeコンソールが入ります。
    /config // CakePHP が使用する（数個の）設定ファイルが入る場所です。 データベース接続の詳細、ブートストラップ、コアの設定ファイルなどがここに入ります。
    /logs
    /plugins // あなたのアプリケーションが使うプラグインが入ります。
    /src // 作成するプログラムが入る場所です。 あなたのアプリケーションのファイルはここに入れます。
    /tests // あなたのアプリケーションのテストケースが入る場所です。
    /tmp // CakePHP の一時的なデータが入る場所です。
    /vendor // CakePHP と他のアプリケーションの依存ライブラリが入る場所です。 このフォルダの中のファイルを勝手に編集 しない と誓ってください。 これはコア (心臓部分) で、ここをいじってしまうと、私たちはもう助けを差し伸べることができません。
    /webroot // ディレクトリはあなたのアプリケーションのパブリックドキュメントルートです。
    .editorconfig
    .gitignore
    .htaccess
    .travis.yml
    composer.json
    index.php
    phpunit.xml.dist
    README.md
```

作ったProjectにアクセスできるのが確認できます。
ここまでがCakePHP3のインストール方法です。
次にはCakePHP3 初期設定を行ってみます。

## 2. CakePHP3 初期設定

### データベースの作成

DBを作成してみましょう。

```
* postgresの場合
command
    cd /var/www/html/
    psql -U postgres
    postgres=# create database {{DB name}};
    CREATE DATABASE
```

```
* mysqlの場合
command
    cd /var/www/html/
    mysql -u root -p
    create database {{DB name}};
```

### データベースの設定

今作ったDBをCakePHP3に設定しましょう。

```
command
    vim /var/www/html/{{project name}}/app/config/app.php
```

```
* /var/www/html/{{project name}}/app/config/app.php
220行目

vim
    // Postgresの方は、testのdriverも書き換えてください。
    'Datasources' => [
            'default' => [
                'className' => 'Cake\Database\Connection',
                // 'driver' => 'Cake\Database\Driver\Mysql',
                'driver' => 'Cake\Database\Driver\Postgres',
                'persistent' => false,
                'host' => 'localhost',
                /**
                 * CakePHP will use the default DB port based on the driver selected
                 * MySQL on MAMP uses port 8889, MAMP users will want to uncomment
                 * the following line and set the port accordingly
                 */
                //'port' => 'non_standard_port_number',
                'username' => '{username}', // 231行
                'password' => '{password}', // 232行
                'database' => '{{DB name}}', // 233行
                'encoding' => 'utf8',
                'timezone' => 'UTC',
                'flags' => [],
                'cacheMetadata' => true,
                'log' => false,
            ]
    ]
```

### キャッシュファイルのパーミッション設定

```
* /var/www/html/{{project name}}/app/config/app.php
85行目

    'Cache' => [
        'default' => [
            'className' => 'File',
            'path' => CACHE,
            'url' => env('CACHE_DEFAULT_URL', null),
        ],

        /**
         * Configure the cache used for general framework caching.
         * Translation cache files are stored with this configuration.
         * Duration will be set to '+1 year' in bootstrap.php when debug = false
         */
        '_cake_core_' => [ 
            'className' => 'File',
            'prefix' => 'myapp_cake_core_',
            'path' => CACHE . 'persistent/',
            'serialize' => true,
            'duration' => '+2 minutes',
            'url' => env('CACHE_CAKECORE_URL', null),
            'mask' => 0666, // 104行
        ],

        /**
         * Configure the cache for model and datasource caches. This cache
         * configuration is used to store schema descriptions, and table listings
         * in connections.
         * Duration will be set to '+1 year' in bootstrap.php when debug = false
         */
        '_cake_model_' => [
            'className' => 'File',
            'prefix' => 'myapp_cake_model_',
            'path' => CACHE . 'models/',
            'serialize' => true,
            'duration' => '+2 minutes',
            'url' => env('CACHE_CAKEMODEL_URL', null),
            'mask' => 0666, // 120行
        ],
    ],
```

## 3. マイグレーション

情報を保存するためのTableのmigrationファイルを作成してみましょう。

参考：http://book.cakephp.org/3.0/ja/migrations.html

### マイグレーションファイル作成

```
* /var/www/html/{{project name}}

command
    // accounts テーブル作成
    bin/cake bake migration CreateUsers name:text description:text username:text password:text created modified
```

### シードファイル作成

Loginユーザーの初期値を設定するシードファイルを作成してみましょう。

```
* /var/www/html/{{project name}}

command
    bin/cake bake seed Users
```

シードファイル修正

```
* /var/www/html/{{project name}}

command
    vim config/Seeds/UsersSeed.php
```

```
* /var/www/html/{{project name}}/config/Seeds/UsersSeed.php
3行目

vim
    use Cake\Auth\DefaultPasswordHasher;  
```

```
* /var/www/html/{{project name}}/config/Seeds/UsersSeed.php
19行目

vim
    public function run()
    {
        $data = [
          [
              'name'            => 'AccountA',
              'description'     => '',
              'username'        => 'admin',
              'password'        => (new DefaultPasswordHasher)->hash('admin'),
              'created'         => date('Y-m-d H:i:s'),
              'modified'        => date('Y-m-d H:i:s'),
          ]
        ];
    }
```

### マイグレーション実行

設定したmigrationファイルを実行してみましょう。

```
* /var/www/html/{{project name}}

command
    bin/cake migrations migrate
```

### シード実行

```
* /var/www/html/{{project name}}

command
    bin/cake migrations seed --seed UsersSeed
```

## 5. Bake

基本的なアプリケーションを 素早く生成するために bake コンソール アプリケーションが使用できます。

```
* /var/www/html/{{project name}}

bin/cake bake all users
```

- 確認

```
一覧 ： http://{{自分のIP}}/{{project name}}/users
登録 ： http://{{自分のIP}}/{{project name}}/users/add
編集 ： http://{{自分のIP}}/{{project name}}/users/edit/{{id}}
```

## 6. 登録、編集、削除をやってみよう

### 一覧

```
URL
http://{{自分のIP}}/{{project name}}/users
```

<img width="642" alt="スクリーンショット 2016-09-13 20.04.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/74128/9c1db416-5697-1669-cfe2-34764d6ec1db.png">

### 登録

```
URL
http://{{自分のIP}}/{{project name}}/users/add
```

<img width="1246" alt="スクリーンショット 2016-09-13 20.11.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/74128/6b4202d1-4723-3c58-d3a2-699b1f384fae.png">



### 詳細

```
URL
http://{{自分のIP}}/{{project name}}/users/view/{{id}}
```

<img width="656" alt="スクリーンショット 2016-09-13 20.05.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/74128/f612e1c8-c2ab-d25f-8e66-3be945233b07.png">


### 編集

```
URL
http://{{自分のIP}}/{{project name}}/users/edit/{{id}}
```

<img width="1207" alt="スクリーンショット 2016-09-13 20.05.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/74128/c1236b6a-2700-6f75-7565-29b44ec8f5d5.png">


### 削除

一覧画面にあるdeleteを押してみましょう！

<img width="1264" alt="スクリーンショット 2016-09-13 20.14.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/74128/61414074-322a-a28c-90a2-d7a33080c4f8.png">


## 7. ログイン及びログアウト機能

### Auth

CakePHPには認証機能などを実装しやすくするAuthコンポーネットが標準で使えるようになっています。
まずAuthの設定を行いましょう。

- src/Controller/AppController.php の修正

```
command
    vim src/Controller/AppController.php
```

```
vim
    public function initialize()
    {
        parent::initialize();

        $this->loadComponent('RequestHandler');　// RequestHandlerコンポーネント。入力されたデータの取得などに使用
        $this->loadComponent('Flash');　// Flashコンポーネント。エラーメッセージの表示などに使用
        $this->loadComponent('Auth', [　// Authコンポーネントの読み込み
            'authenticate' => [
                'Form' => [　// 認証の種類を指定。Form,Basic,Digestが使える。デフォルトはForm
                    // 'userModel' => 'Users', // デフォルトでUsersになっている
                    'fields' => [　// ユーザー名とパスワードに使うカラムの指定。省略した場合はusernameとpasswordになる
                        'username' => 'username', // ユーザー名のカラムを指定
                        'password' => 'password' //パスワードに使うカラムを指定
                    ]
                ]
            ],
            'loginRedirect' => [ // ログイン後に遷移するアクションを指定
                'controller' => 'Users',
                'action' => 'index'
            ],
            'loginAction' => [ // ログアウト後に遷移するアクションを指定
                'controller' => 'Users',
                'action' => 'login',
            ],
        ]);
    }
```
### ログイン画面とログアウト機能の作成

まずUsersControllerにloginとlogout actionを追加します。

```
command
    vim src/Controller/AccountsController.php
```

```
vim
    public function login()
    {
        if ($this->request->is('post')) {
            $user = $this->Auth->identify();
            if ($user) {
                $this->Auth->setUser($user);
                return $this->redirect($this->Auth->redirectUrl());
            }
            $this->Flash->error(__('Invalid username or password, try again'));
        }
    }

    public function logout()
    {
        return $this->redirect($this->Auth->logout());
    }
```

src/Template/Accounts/login.ctp の作成

```
command
    vim src/Template/Accounts/login.ctp
```

```
vim
    <!-- File: src/Template/Users/login.ctp -->
    <div class="users form">
        <?= $this->Flash->render('auth') ?>
        <?= $this->Form->create() ?>
            <fieldset>
                <legend><?= __('Please enter your username and password') ?></legend>
                <?= $this->Form->input('username') ?>
                <?= $this->Form->input('password') ?>
            </fieldset>
        <?= $this->Form->button(__('Login')); ?>
        <?= $this->Form->end() ?>
    </div>
```

### Password暗号化

CakePHP3からはGetter、Setterという概念ができました。
Password暗号化はSetterを使って、設定してみましょう。

```
command
    vim src/Model/Entity/Account.php 
```

```
vim
    use Cake\Auth\DefaultPasswordHasher;
```

```
vim
    protected function _setPassword($password)
    {
        return (new DefaultPasswordHasher)->hash($password);
    }
```