Laravel.Osaka のメモ書き

2016/10/29

寝坊しました。午後から。

# Laravel で Herokuにdeploy

大村さん @omoon

1. Larave on Homestend
2. Github Push
3. Heroku deploy


in 60 min.


## 準備

`Homsted`でやります。 `VirtualBox` + `Vagrant`

Homested の clone は Githubから。

init.sh で設定ファイルができる。

live coding...

# DD Pattern

@shin1x1

スライド: https://speakerdeck.com/shin1x1/ddd-with-laravel

## About DDD

DDD is Domain Driven Design.

開発手法.

ドメインにフォーカスして開発していく。

- ドメインレイヤーが主、それ以外は従
- ドメインレイヤーがアプリケーション
- 変化の早いLaravel

## Domain？

- システムの対象領域
	- 解決する問題領域
- ソースコード管理システムなら、ソフトウェア開発がドメイン


## ユビキタス言語

- 業務用語辞典
- その言葉をコードでも使う



| :==: | :=: | :=: |
| 商品 | Item | 商品ID, 商品名, 価格, 在庫|
| ItemID | 商品ID |
| ItemName | 商品名称 |
| ItemPrice | 価格。0以上の整数 |
| ItemStock | 在庫数。0以上の整数 |

| カート  | Cart | .. |

`商品カート`と`カート`と語の揺れがないようにする。


## Layerd Archtecture

- システムをLayer化
- Layer間で処理をする
- Layer間の流れは一方通行

## DDD - Layer

| UI |
| Application |
| Domain |
| Infrastructure |

### UI Layer

1. Userとシステムの接点
2. HTTP/HTML/JSON/STDIN/STDOUT
3. View/Request/Response

### Application Layer


1. システムのコントロールを担う
	1．POSTリクエストを受け取ったら商品IDを追加する。
	1. エラーがでたら、追加する画面に戻す等
2. Validation
3. サービスはそれぞれのレイヤーを呼び出して実行させる
	4. アイテムを取ってきて、カートを取ってきて、無い時はカート作って、カートにアイテム追加して云々

### Domain Layer

1. Domain 以外の関心事を持ち込まない
	2. HTTP/DB/Cache 等をこちこまない
3. POPO（PlainOldPHPObject）で実装、フレームワークからは独立
	4. Facadeやヘルパー関数を使わない
	5. Collectionとかドメインを表現する範囲なら。
5. Model, Service, Event 等
6. ValueObjectを最小粒度にする
	7. 理想は VO内以外ではスカラーを使わない。

#### Entity

- 商品、カートの実装
- Eloquent を継承しない
- 同一性の識別子（id）で識別
- Mutable

#### Value Object

- 商品ID, 商品価格、在庫
- 同一性は属性で判別
- 値に対する制約や振る舞い（演算）を実装
- Immutable


```php
class Item
{
	/** @var int */
	private $id;
	
	/** @var string */
	private $name;

	/** @var int */
	private $price;
	
	/** @var int */
	private $stock;
}
```

これだと演算が自由にできちゃうので制約を作る。

```php
class Item
{
	/** @var ItemID */
	private $id;
	
	/** @var string */
	private $name;

	/** @var Price */
	private $price;
	
	/** @var Stock */
	private $stock;
}

class ItemID
{
	private $value;
	
	public function __construct($value) { $this->value = $value; }
	
	public function value() { return $this->value; }
}

class Price {
 	private $value;
	public function __construct($value){
  		if( $value < 0) { throw new PriceRowException(); }
  		$this-value = $value;
  	}
}
```

### Infrastructure Layer

1. データストアやメール送信、外部API連携など、技術機能を提供レイヤー
2. リポジトリ、キャッシュ、APIクライアント…
3. Laravel で言う Eloquent / QueryBuilder / Cache

#### Repository


Model/DataStore の間に介在する。

- DmainModel: Itemクラス
- Database: items テーブル


- Eloquent を Persistence Model に使う
- インフラストラクチャレイヤのリポジトリ実装に閉じ込める
- 他レイヤでEloquentは基本使わない


# ACL Controllの話

msng さん

- Auth
	- Authorization(認可)
		- ツイッターなどに、この人の記事をください（認可）
	- Authentication(認証)
		- 貴様はこの人ですね（ログイン）

## Gate

AuthServiceProvider::bootに書くのが良いんじゃね

```
function boot()
{
	$this->registerPolicies();

	// POST を削除していいか確認
	\Gate::define('delete-post', function(User $user, Post $post){
		return $post->user_id == $user->id;
	});
}
```

```PostController.php

function destroy(int $id){
	$post = $this->posts->find($id);
	if(\Gate::allows('delete-post', $post)){
		$this->posts->destroy($post);
	}
}
```

### Policy

Gate にカキつなれるのは長いので、Policy を使う。

```
class PostPolicy {
	use HandlesAuthorizations;

	public function delete(User $user, Post $post){
		return $post->user_id == $user->id;
	}
}
```

```AuthServiceProvider に登録すうｒ

protected $policies = [
	Post::class => PostPolicy::class
];
```


```PostController.php

function destroy(int $id){
	$post = $this->posts->find($id);
	if(\Auth::user()->can('delete', $post)){
		$this->posts->destroy($post);
	}
}
```

今は


```PostController.php

function destroy(int $id){
	$post = $this->posts->find($id);
	
	// 自動的にしてくれる
	$this->authorize('delete', $post);
}
```

## View は？

```
@can('delete', $comment)
<form></form>
@endcan
```

でいける。


# Lumen + vue.js


高橋さん

# Laravel とテスト

後藤さん

https://php-jp.github.io/laravel-osaka-2016/