ポケモン預かりシステムの実装
システムの仕様とクラスも整ってきたので、いざ実装をしていきましょう。
前回までに作成した項目で、いくつか変更になったものがあるので、まずはじめに挙げておきます。
シャットダウン機能
ボックスの選択を解除するというものでしたが、こちらを不採用にしました。ボックスは常にどれかが選択された状態にしておき、シャットダウンそのものはグローバルで行っている1つだけにしました。
選択ボックスの初期値
初期値を0としました。nullと0が混在すると判定がややこしくなるため、シャットダウン機能と合わせて常にどれかのボックスが選択されている状態にしています。
それでは、順を追ってPHPポケモンに実装していきましょう。
コントローラーの作成
まずは主軸となるコントローラーの作成です。作成する分岐は以下の5つです。
- ボックス切り替え
- ボックス追加
- ポケモンを預ける
- ポケモンを引き取る
- ボックス操作の終了
ポケモン預かりシステムコントローラー(/App/Controllers/Pokeox/PokeboxController.php)
<?php
$root_path = __DIR__.'/../../..';
require_once($root_path.'/App/Controllers/Controller.php');
// サービス
require_once($root_path.'/App/Services/Pokebox/SwitchService.php');
require_once($root_path.'/App/Services/Pokebox/DepositService.php');
require_once($root_path.'/App/Services/Pokebox/ReceiveService.php');
require_once($root_path.'/App/Services/Pokebox/AddBoxService.php');
// ポケモンボックス用コントローラー
class PokeboxController extends Controller
{
/**
* @return void
*/
public function __construct()
{
// 親コンストラクタの呼び出し
parent::__construct();
// ボックスの起動
startPokebox();
// 分岐処理
$this->branch();
// 親デストラクタの呼び出し
parent::__destruct();
}
/**
* @return void
*/
public function __destruct()
{
// ボックスの保存
savePokebox();
// 親デストラクタの呼び出し
parent::__destruct();
}
/**
* アクションに合わせた分岐
* @return void
*/
private function branch()
{
switch (request('action')) {
/******************************************
* ボックスの切り替え
*/
case 'switch':
$service = new SwitchService;
$service->execute();
break;
/******************************************
* ポケモンを預ける
*/
case 'deposit':
$service = new DepositService;
$service->execute();
break;
/******************************************
* ポケモンを引き取る
*/
case 'receive':
$service = new ReceiveService;
$service->execute();
break;
/******************************************
* ボックスの追加
*/
case 'add_box':
$service = new AddBoxService;
$service->execute();
break;
/******************************************
* ボックス終了
*/
case 'shutdown':
shutdownPokebox();
$_SESSION['__route'] = 'home';
// 画面移管
$this->redirect();
break;
/******************************************
* アクション未選択・ボックス起動
*/
default:
response()->setMessage('ようこそ、ポケモン預かりシステムへ');
break;
}
}
}
ボックス操作の終了は、ホーム画面へ移管させるだけのものなのでサービスは不要です。ポケモン預かりシステムの操作画面では毎回ボックスの起動が必要になるので、こちらはコンストラクタ内で、保存処理はデストラクタ内で行なっています。
ボックス切り替え
まずはボックス切り替えから見ていきましょう。原則としてボックス操作はアクセス中のものしかできないようにしているため、管理画面で見られるのはパーティーと1つのボックスのみになります。なので、別ボックスのポケモンを確認、引き取るなどの処理を行う場合は、アクセス中のボックスを切り替える必要があります。
ボックス切り替えサービス(/App/Services/Pokebox/SwitchService.php)
<?php
$root_path = __DIR__.'/../../..';
// 親クラス
require_once($root_path.'/App/Services/Service.php');
/**
* ボックスの切り替え
*/
class SwitchService extends Service
{
/**
* @return void
*/
public function __construct()
{
//
}
/**
* @return void
*/
public function execute()
{
// ボックスの切り替え
if(pokebox()->selectBox(request('box'))){
response()->setMessage(
'ボックス'.pokebox()->getSelectedBoxNumber().'を起動しました'
);
}else{
response()->setMessage('ボックスの起動に失敗しました');
}
}
}
POSTでボックスの値を受け取り、そのボックスの存在確認をしてから結果を返却しています。selectBoxではボックスが見つかればselectedプロパティに値をセット、返り値としてbooleanを返しています。
ボックス追加
次にボックスの追加処理についてです。ポケモンをボックス分けしたい時などに、満杯で無くても他のボックスを使用したい場合がありますね。そんなときに新規でボックスが追加できるようにサービスを用意しておきます。
ボックス追加サービス(/App/Services/Pokebox/AddBoxService.php)
<?php
$root_path = __DIR__.'/../../..';
// 親クラス
require_once($root_path.'/App/Services/Service.php');
/**
* ボックスの追加
*/
class AddBoxService extends Service
{
/**
* @return void
*/
public function __construct()
{
//
}
/**
* @return void
*/
public function execute()
{
// ボックスの追加
if(count(pokebox()->getPokebox()) < 10){
$box = pokebox()->addBox();
response()->setMessage('ボックス'.($box + 1).'を追加しました');
}else{
response()->setMessage('これ以上は追加できません');
}
}
}
こちらはPOSTによる値は不要です。リクエストがあればaddBoxメソッドを使って空の配列を最後尾に追加しています。ただし、ボックスが無限に増やすわけにもいかないので、現段階では最大数を10ボックスとしています。
ポケモンを預ける
こからがポケモン預かりシステムの本格的な実装となります。まずは、手持ちのポケモンを預けるための処理を作成します。
ポケモンを預ける(/App/Services/Pokebox/DepositService.php)
<?php
$root_path = __DIR__.'/../../..';
// 親クラス
require_once($root_path.'/App/Services/Service.php');
/**
* ポケモンを預ける
*/
class DepositService extends Service
{
/**
* 預けるポケモン
* @var object::Pokemon
*/
private $pokemon;
/**
* @return void
*/
public function __construct()
{
//
}
/**
* @return void
*/
public function execute()
{
if($this->validation()){
// 預け入れ処理
$this->migratePartyToBox();
// 接続成功
response()->setMessage(
$this->pokemon->getNickname().'をボックス'.pokebox()->getSelectedBoxNumber().'へ預けた'
);
}
}
/**
* 検証
* @return boolean
*/
private function validation(): bool
{
/**
* ボックスの検証
*/
// 空きチェック
if(!pokebox()->isSelectedBoxSpace()){
response()->setMessage('ボックス'.pokebox()->getSelectedBoxNumber().'には空きがありません');
return false;
}
/**
* ポケモンの検証
*/
// 手持ちが1匹以下
if(count(player()->getParty()) <= 1){
response()->setMessage('手持ちのポケモンが、いなくなってしまいます');
return false;
}
// 手持ちポケモンの存在チェック
$this->pokemon = player()->getPartner(request('pokemon_id'), 'id');
if(empty($this->pokemon)){
response()->setMessage('選択されたポケモンは預けることができません');
return false;
}
// 検証成功
return true;
}
/**
* ポケモンをボックスへ預ける
* @return void
*/
private function migratePartyToBox(): void
{
// パーティー内のポケモン情報を削除
player()->releasePartner(request('pokemon_id'));
// ボックスへ追加
pokebox()->addPokemon($this->pokemon);
}
}
ポケモンを預ける際には、パーティー内のポケモンを判別するためのポケモンIDを受け取っています。
※こちらがorder値でない理由は後ほど画面実装の際に説明します
まずバリデーションで、ボックスの空きチェック、手持ちポケモンの数をチェックして預けられる状態かどうかを確認します。その後、requestで受け取ったポケモンIDが手持ちに存在しているかを確認し、問題がなければポケモンを移動します。
ポケモンの移動では、パーティー内からの削除とボックスへのポケモン追加を同時に行なっています。ここに不具合があるとポケモンが消失したり、第2世代のように複製される原因となりかねませんので注意です。
ポケモンを引き取る
最後に、ボックスに預けたポケモンを手持ちに加えるための引き取り処理です。こちらは、預けるとは逆の工程を踏むことで実装していきます。
ポケモンを引き取る(/App/Services/Pokebox/ReceiveService.php)
<?php
$root_path = __DIR__.'/../../..';
// 親クラス
require_once($root_path.'/App/Services/Service.php');
/**
* ポケモンを引き取る
*/
class ReceiveService extends Service
{
/**
* 引き取るポケモン
* @var array
*/
private $pokemon;
/**
* @return void
*/
public function __construct()
{
//
}
/**
* @return void
*/
public function execute()
{
if($this->validation()){
// 引き取り処理
$this->migrateBoxToParty();
// 接続成功
response()->setMessage(
$this->pokemon
->getNickname().'を連れて行くことにした'
);
}
}
/**
* 検証
* @return boolean
*/
private function validation(): bool
{
/**
* パーティーの検証
*/
if(count(player()->getParty()) >= 6){
response()->setMessage('これ以上は連れていけません');
return false;
}
/**
* ボックス内のポケモンの検証
*/
$pokemon = array_filter(pokebox()->accessSelectedBox(false), function($pokemon){
return $pokemon['id'] === request('pokemon_id');
});
if(empty($pokemon)){
response()->setMessage('指定されたポケモンは存在しません');
return false;
}
// 検証成功
$this->pokemon = unserializeObject(array_shift($pokemon)['object']);
return true;
}
/**
* ボックスからパーティーへの移動
* @return void
*/
private function migrateBoxToParty(): void
{
// ボックスからポケモンを削除する
pokebox()->releasePokemon(request('pokemon_id'));
// 取り出したポケモンをパーティーへセットする
player()->setParty($this->pokemon);
}
}
こちらでも預けると同様に、引き取るポケモンのIDをリクエストすることで、対象のポケモンを判別しています。
まず初めにパーティーが上限に達していないかを確認、その後ボックス内にポケモンが存在しているかどうかを確認しています。
では、ボックス内のポケモンにアクセスするためのaccessSelectedBoxメソッドの中身を見てみましょう。
ポケモン預かりシステム ボックス操作用トレイト(/App/Traits/Class/Pokebox/ClassPokeboxTrait.php)
/**
* 選択中のボックスへアクセス(復号化して返却)
* @param serialize:boolean
* @return array
*/
public function accessSelectedBox($serialize=true): array
{
if($serialize){
// 復号化して返却
return array_map(function($pokemon){
return unserializeObject($pokemon['object']);
}, $this->pokebox[$this->selected] ?? []);
}else{
// 復号化せずに返却
return $this->pokebox[$this->selected];
}
}
もし引数でtrue(初期値)が指定された場合は、ポケモン情報を復号化して選択中のボックスのポケモン一覧を返却します。falseが指定された際にはそのままの状態で返却するため、対象ポケモン1匹だけが欲しい場合などは、復号化せずに検証、通れば取り出したポケモンだけを復号化することで、余計な処理をする必要がなくなります。
画面の作成
最後に画面の作成です。画面上がボックスの管理画面となるように作成し、パーティーと現在選択中のボックスのポケモン一覧が表示されるようにします。
ポケモン預かりシステム画面(/Resources/Pages/Pokebox.php)
<?php
$root_path = __DIR__.'/../..';
?>
<!DOCTYPE html>
<html lang="jp" dir="ltr">
<head>
<?php
# metaの読み込み
include($root_path.'/Resources/Partials/Layouts/Head/meta.php');
# cssの読み込み
include($root_path.'/Resources/Partials/Layouts/Head/css.php');
?>
</head>
<body>
<?php
# headerの読み込み
include($root_path.'/Resources/Partials/Layouts/Head/header.php');
?>
<main>
<div class="container">
<section>
<div class="card">
<div class="card-header d-flex align-items-center justify-content-between">
<h5 class="mb-0">
<img src="/Assets/img/icon/pokebox.png" class="mr-2" alt="ポケモン預かりシステム" />ポケモン預かりシステム
</h5>
<button type="button" class="btn btn-danger rounded-circle p-0" style="width:40px;height:40px;" data-submit_remote="shutdown" title="終了する">
<i class="fas fa-power-off"></i>
</button>
</div>
<div class="card-body py-0 px-3">
<div class="row">
<?php include($root_path.'/Resources/Partials/Pokebox/body.php'); ?>
</div>
</div>
<div class="card-footer d-flex justify-content-center" data-pokebox="controls">
<?php include($root_path.'/Resources/Partials/Pokebox/foot.php'); ?>
</div>
<div class="card-footer p-3 overflow-auto bg-white" style="height: 90px;">
<?php foreach(response()->messages() as list($message)): ?>
<p class="mb-0"><?=$message?></p>
<?php endforeach; ?>
</div>
</div>
</section>
</div>
</main>
<?php
# footerの読み込み
include($root_path.'/Resources/Partials/Layouts/Foot/footer.php');
# モーダルの読み込み
include($root_path.'/Resources/Partials/Pokebox/Modals/deposit.php');
include($root_path.'/Resources/Partials/Pokebox/Modals/receive.php');
include($root_path.'/Resources/Partials/Pokebox/Modals/switch.php');
# JSの読み込み
include($root_path.'/Resources/Partials/Layouts/Foot/js.php');
?>
<script src="/Assets/js/Pokebox/pokebox.js" type="text/javascript" defer></script>
</body>
</html>
ポケモン預かりシステムcard-body部分(/Resources/Partials/Pokebox/body.php)
<div class="col-12 bg-purple">
<p class="text-white text-center mb-0 small">ボックス<?=pokebox()->getSelectedBoxNumber()?> 接続中...</p>
</div>
<div class="col-12 col-md-4 py-3 bg-light">
<div class="overflow-auto" style="height:300px;">
<div class="nav flex-column nav-pills" id="pokebox-tab" role="tablist" aria-orientation="vertical" data-list="pokebox">
<?php # 手持ち ?>
<a class="nav-link d-flex justify-content-between btn-sm btn-secondary text-left m-1" id="pokebox-party-tab" href="#pokebox-party" role="tab" aria-controls="pokebox-party" aria-selected="true" data-toggle="pill" data-category="party">
<span>手持ち</span>
<span class="badge badge-light d-flex align-items-center"><?=count(player()->getParty())?></span>
</a>
<?php # ボックス ?>
<?php foreach(pokebox()->getPokebox() as $num => $box): ?>
<?php if(pokebox()->getSelectedBox() === $num): ?>
<?php # 起動中のボックス ?>
<a class="nav-link d-flex justify-content-between btn-sm btn-orange text-left m-1 active" id="pokebox-<?=$num?>-tab" href="#pokebox-<?=$num?>" role="tab" aria-controls="pokebox-<?=$num?>" aria-selected="true" data-toggle="pill" data-category="pokebox">
<span class="pokebox-name">ボックス<?=$num+1?><i class="fas fa-check-circle ml-2"></i></span>
<span class="badge badge-light d-flex align-items-center"><?=count($box)?></span>
</a>
<?php else: ?>
<?php # 未接続のボックス ?>
<a class="nav-link d-flex justify-content-between btn-sm btn-secondary text-left m-1 cursor-pointer" data-toggle="modal" data-target="#pokebox-switch-modal" data-box="<?=$num?>">
<span class="pokebox-name">ボックス<?=$num+1?></span>
<span class="badge badge-light d-flex align-items-center"><?=count($box)?></span>
</a>
<?php endif; ?>
<?php endforeach; ?>
</div>
</div>
</div>
<div class="col-12 col-md-8 py-3 bg-light-success">
<div class="tab-content overflow-auto" id="pokebox-tabContent" style="height:300px;">
<?php # 手持ち ?>
<div class="tab-pane fade show" id="pokebox-party" role="tabpanel" aria-labelledby="pokebox-party-tab">
<div class="row table-selected" data-list="pokemon">
<?php foreach(player()->getParty() as $party): ?>
<figure class="col-6 col-sm-4 col-md-3 col-lg-2 d-flex">
<div class="d-flex w-100 flex-column justify-content-between table-selected-row border rounded" data-place="party" data-pokemon_id="<?=$party->getId()?>">
<div class="p-1">
<p class="mb-0" id="pokebox-pokemon-name-<?=$party->getId()?>"><?=$party->getNickname()?></p>
<p>Lv.<?=$party->getLevel()?></p>
</div>
<div class="text-center mb-2">
<img id="pokebox-pokemon-img-<?=$party->getId()?>" src="/Assets/img/pokemon/dots/front/<?=get_class($party)?>.gif" alt="<?=$party->getName()?>">
</div>
</div>
</figure>
<?php endforeach; ?>
</div>
</div>
<?php # ボックス ?>
<div class="tab-pane fade show active" id="pokebox-<?=pokebox()->getSelectedBox()?>" role="tabpanel" aria-labelledby="pokebox-<?=pokebox()->getSelectedBox()?>-tab">
<div class="row table-selected" data-list="pokemon">
<?php foreach(pokebox()->accessSelectedBox() as $pokemon): ?>
<figure class="col-6 col-sm-4 col-md-3 col-lg-2 d-flex">
<div class="d-flex w-100 flex-column justify-content-between table-selected-row border rounded" data-place="pokebox" data-pokemon_id="<?=$pokemon->getId()?>">
<div class="p-1">
<p class="mb-0" id="pokebox-pokemon-name-<?=$pokemon->getId()?>"><?=$pokemon->getNickname()?></p>
<p>Lv.<?=$pokemon->getLevel()?></p>
</div>
<div class="text-center mb-2">
<img id="pokebox-pokemon-img-<?=$pokemon->getId()?>" src="/Assets/img/pokemon/dots/front/<?=get_class($pokemon)?>.gif" alt="<?=$pokemon->getName()?>">
</div>
</div>
</figure>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
ポケモン預かりシステムcard-footer部分(/Resources/Partials/Pokebox/foot.php)
<?php if(count(pokebox()->getPokebox()) < 10): ?>
<button type="button" class="btn btn-sm btn-purple mx-1" data-submit_remote="add_box">ボックス追加</button>
<?php endif; ?>
<?php # 共通 ?>
<button type="button" class="btn btn-sm btn-secondary mx-1" data-category="common" data-btn="default" disabled>様子を見る</button>
<?php foreach(array_merge(player()->getParty(), pokebox()->accessSelectedBox()) as $pokemon): ?>
<button type="button" class="btn btn-sm btn-purple d-soft-none mx-1" data-category="common" data-btn="details" data-pokemon_id="<?=$pokemon->getId()?>" data-toggle="modal" data-target="#pokemon<?=$pokemon->getId()?>-details-modal">様子を見る</button>
<?php
# 詳細モーダルの読み込み
include($root_path.'/Resources/Partials/Common/Modals/pokemon-details.php');
?>
<?php endforeach; ?>
<?php # パーティー用のボタン ?>
<button type="button" class="btn btn-sm btn-secondary mx-1 d-soft-none" data-category="party" data-btn="default" disabled>預ける</button>
<button type="button" class="btn btn-sm btn-purple mx-1 d-soft-none" data-category="party" data-btn="deposit" data-target="#pokebox-deposit-modal" data-toggle="modal">預ける</button>
<?php # ボックス移動ボタン ?>
<button type="button" class="btn btn-sm btn-secondary mx-1" data-category="pokebox" data-btn="default" disabled>連れて行く</button>
<button type="button" class="btn btn-sm btn-purple mx-1 d-soft-none" data-category="pokebox" data-btn="receive" data-target="#pokebox-receive-modal" data-toggle="modal">連れて行く</button>
前述したポケモンの並び順(order)で管理しない理由が、ボックス内のポケモンとパーティーのポケモンでの番号重複です。詳細画面を開く際などにこれが原因で共通詳細が使用できなくなるため、共通詳細にもポケモンIDを使用、判別にもIDを使用することで対応しました。
専用JSではボックスやポケモンの選択に合わせて、操作ボタンやモーダルの画像やボタンを切り替えるようにします。
ポケモン預かりシステムJS(/Public/Assets/js/Pokebox/pokebox.js)
/*----------------------------------------------------------
// 初期化する関数
----------------------------------------------------------*/
/**
* ボックス選択
* @function on click
*/
var selectPokeboxInit = function() {
$('[data-list="pokebox"] > [role="tab"]').on('click', function(){
var category = $(this).data('category');
var name = $(this).find('.pokebox-name')
.text();
// ボックスリストボタンの色変更
$('[data-list="pokebox"] > .nav-link').removeClass('btn-orange')
.addClass('btn-secondary');
$(this).removeClass('btn-secondary')
.addClass('btn-orange');
// ボックス操作ボタンの表示・非表示
$('[data-pokebox="controls"] [data-category="common"]').hide();
$('[data-pokebox="controls"] [data-category][data-category!="' + category + '"]').hide();
$('[data-pokebox="controls"] [data-category="' + category + '"][data-btn="default"]').show();
$('[data-pokebox="controls"] [data-category="common"][data-btn="default"]').show();
// 選択中のポケモンを解除
var row = $('.table-selected[data-list="pokemon"]')
.find('.table-selected-row')
.removeClass('active');
});
}
/**
* ポケモンの選択
* @function on click
*/
var selectPokemonInit = function() {
$('[data-list="pokemon"] .table-selected-row').on('click', function(){
var place = $(this).data('place');
var pokemon_id = $(this).data('pokemon_id');
// ボックス操作関係のフォーム・ボタンを非表示
$('[data-category="' + place + '"]').hide();
$('[data-btn="default"]').hide();
// 「様子を見る」の有効化
$('[data-btn="details"]').hide();
$('[data-btn="details"][data-pokemon_id="' + pokemon_id + '"]').show();
// 選択されたポケモン情報を取得
var name = $(this).find('#pokebox-pokemon-name-' + pokemon_id)
.text();
var img = $(this).find('#pokebox-pokemon-img-' + pokemon_id)
.attr('src');
// パーティー、ボックス内ポケモンの分岐
if(place === 'party'){
var action = 'deposit';
}else if(place === 'pokebox'){
var action = 'receive';
}
// 「預ける」または「引き取る」を有効化
$('[data-btn="' + action + '"]').show();
// モーダルに選択されたポケモン情報をセット
$('form#pokebox-' + action + '-form [name="pokemon_id"]').val(pokemon_id);
$('#' + action + '-pokemon-name').text(name);
$('#' + action + '-pokemon-img').attr('src', img);
});
}
/**
* ボックス切り替え
* @function on click
*/
var switchPokeboxModalInit = function() {
$('[data-target="#pokebox-switch-modal"]').on('click', function(){
var box = $(this).data('box');
var name = $(this).find('.pokebox-name').text();
// ボックス名と番号をセット
$('#switch-pokebox-name').text(name);
$('#pokebox-switch-form [name="box"]').val(box);
});
}
/*----------------------------------------------------------
// 初期化
----------------------------------------------------------*/
jQuery(function($){
selectPokemonInit();
selectPokeboxInit();
switchPokeboxModalInit();
});
ボックス切り替え、預ける、引き取るではモーダルによる確認を挟むため、それぞれモーダルを用意しておきましょう。
ボックス切り替え確認モーダル(/Resources/Partials/Pokebo/Modals/switch.php)
<div class="modal fade" id="pokebox-switch-modal" tabindex="-1" role="dialog" aria-labelledby="pokebox-switch-modal-title" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-body">
<figure class="text-center p-3 mb-0">
<p class="mb-0"><span id="switch-pokebox-name"></span>に切り替えても良いですか?</p>
</figure>
</div>
<div class="modal-footer justify-content-center">
<form id="pokebox-switch-form" method="post">
<?php input_token(); ?>
<input type="hidden" name="action" value="switch">
<input type="hidden" name="box">
<button type="submit" class="btn btn-sm btn-primary">切り替える</button>
</form>
<button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">やめる</button>
</div>
</div>
</div>
</div>
預ける確認モーダル(/Resources/Partials/Pokebo/Modals/deposit.php)
<div class="modal fade" id="pokebox-deposit-modal" tabindex="-1" role="dialog" aria-labelledby="pokebox-deposit-modal-title" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-body">
<figure class="text-center p-3 mb-0">
<img class="mb-3" id="deposit-pokemon-img" src="" alt="預けるポケモン" />
<p class="mb-0"><span id="deposit-pokemon-name"></span>をボックスに預けますか?</p>
</figure>
</div>
<div class="modal-footer justify-content-center">
<form id="pokebox-deposit-form" method="post">
<?php input_token(); ?>
<input type="hidden" name="action" value="deposit">
<input type="hidden" name="pokemon_id">
<button type="submit" class="btn btn-sm btn-primary">預ける</button>
</form>
<button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">やめる</button>
</div>
</div>
</div>
</div>
引き取る確認モーダル(/Resources/Partials/Pokebo/Modals/receive.php)
<div class="modal fade" id="pokebox-receive-modal" tabindex="-1" role="dialog" aria-labelledby="pokebox-receive-modal-title" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-body">
<figure class="text-center p-3 mb-0">
<img class="mb-3" id="receive-pokemon-img" src="" alt="引き取るポケモン" />
<p class="mb-0"><span id="receive-pokemon-name"></span>を引き取りますか?</p>
</figure>
</div>
<div class="modal-footer justify-content-center">
<form id="pokebox-receive-form" method="post">
<?php input_token(); ?>
<input type="hidden" name="action" value="receive">
<input type="hidden" name="pokemon_id">
<button type="submit" class="btn btn-sm btn-primary">引き取る</button>
</form>
<button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">やめる</button>
</div>
</div>
</div>
</div>
では実際にボックスの挙動を見てみましょう。
ポケモンの預け入れから引き取りまで正常に動作しましたね。アクセスは原作寄せでポケモンセンターからできるようにしました。
ジョーイさんの中(大)サイズのgifが見当たらなかったので、PHPポケモンではラッキーさんが受付対応してくれます。
以上で、ポケモン預かりシステムの実装は完了です。
まとめ
いかがだったでしょうか。
今回のPHPポケモンでは「ポケモン預かりシステム」の実装方法をご紹介しました。
これで、ポケモンを捕まえていくための最低限の準備が整いました。
近日中に本番環境へ反映予定ですので、乞うご期待ください。