Skip to content

Instantly share code, notes, and snippets.

@ak-ymst
Last active December 6, 2016 04:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ak-ymst/e4dde180ecb7bd021ec4fc19d319dada to your computer and use it in GitHub Desktop.
Save ak-ymst/e4dde180ecb7bd021ec4fc19d319dada to your computer and use it in GitHub Desktop.
<?php
abstract class CardMapper {
protected $pdo;
public function __construct($pdo) {
$this->pdo = $pdo;
}
/**
* IDをキーにCardsクラスのインスタンスを一件取得する
*
* 取得されるインスタンスの実際のクラスはこのマッパーを継承する
* クラスによって異なる
*
*/
public function find($id) {
$sql = "SELECT * FROM singletable_cards WHERE id = :id AND type = :type";
$params = ['id' => $id, 'type' => $this->getType()];
$row = $this->fetchRow($sql, $params);
if ($row == null) {
return null;
}
$model = $this->createNewInstance();
$this->fill($row, $model);
return $model;
}
/**
* SQLを実行し, 結果を一件モデルして返す
*/
private function fetchRow($sql, $params) {
$stmt = $this->pdo->prepare($sql);
$stmt->execute($params);
$assoc = $stmt->fetch(PDO::FETCH_ASSOC);
if ($assoc === false) {
return null;
}
return $assoc;
}
/**
* DBのカラムの値を対応したフィールドにセットする
*
*/
protected function fill($row, $model) {
$model->id = $row['id'];
$model->name = $row['name'];
}
/**
* レコードの更新を行う
*
* マッパー毎に異なる更新可能なフィールド一覧を取得し, それをもとにSQLを生成する
*
*/
public function update($model) {
$columns = [];
foreach ($this->aggregateEditableAttributes($model) as $column => $value) {
$columns[] = $column.' = :'.$column;
}
$sql = 'UPDATE singletable_cards SET '.implode(', ', $columns).' WHERE id = :id';
return $this->execute($sql, array_merge($this->aggregateEditableAttributes($model), ['id' => $model->id]));
}
/**
* 編集可能な属性一覧を集める
*
*/
protected function aggregateEditableAttributes($model, $acc = []) {
return array_merge($acc, ['name' => $model->name]);
}
private function execute($sql, $params) {
$stmt = $this->pdo->prepare($sql);
return $stmt->execute($params);
}
/**
* マッパーに対応するクラスの種別を返す
*/
protected abstract function getType();
/**
* マッパーに対応するクラスのインスタンスを生成する
*/
protected abstract function createNewInstance();
}
/**
* アイドル用データマッパー
*/
class IdolMapper extends CardMapper {
protected function getType() {
return 'idol';
}
protected function createNewInstance() {
return new Idol();
}
/**
* DBのカラムの値を対応したフィールドにセットする
*
* @Override
*/
protected function fill($row, $model) {
$model->cost = $row['cost'];
parent::fill($row, $model);
}
/**
* 編集可能な属性一覧を集める
*
* @Override
*/
protected function aggregateEditableAttributes($model, $acc = []) {
$acc = array_merge($acc, ['cost' => $model->cost]);
return parent::aggregateEditableAttributes($model, $acc);
}
}
/**
* トレイナー用データマッパー
*/
class TrainerMapper extends IdolMapper {
protected function getType() {
return 'trainer';
}
protected function createNewInstance() {
return new Trainer();
}
/**
* DBのカラムの値を対応したフィールドにセットする
*
* @Override
*/
protected function fill($row, $model) {
$model->exp = $row['exp'];
parent::fill($row, $model);
}
/**
* 編集可能な属性一覧を集める
*
* @Override
*/
protected function aggregateEditableAttributes($model, $acc = []) {
$acc = array_merge($acc, ['exp' => $model->exp]);
return parent::aggregateEditableAttributes($model, $acc);
}
}
/**
* アイテム用データマッパー
*/
class ItemMapper extends CardMapper {
protected function getType() {
return 'item';
}
protected function createNewInstance() {
return new Item();
}
/**
* DBのカラムの値を対応したフィールドにセットする
*
* @Override
*/
protected function fill($row, $model) {
$model->repairCost = $row['repair_cost'];
parent::fill($row, $model);
}
/**
* 編集可能な属性一覧を集める
*
* @Override
*/
protected function aggregateEditableAttributes($model, $acc = []) {
$acc = array_merge($acc, ['repair_point' => $model->repairPoint]);
return parent::aggregateEditableAttributes($model, $acc);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment