はじめに
Slim3 Framework×slim-skeleton不使用×twigでプロジェクトを作成する
(5. チケット管理システムを再現➀)の続きです。
前提
下記記事で構築した環境を前提とします。
-
私家版 Slim Framework チュートリアル (1、2、3、4、5、6)
@nunulkさんのチュートリアルを一通り。
ここで作成したDBを使いまわします。 -
Slim3 Framework×slim-skeleton不使用×twigでプロジェクトを作成する(1、2、3、4、5)
手順
1. 専用のユーザーを作成
2. プロジェクトディレクトリを作成・slim3インストール
3. 各種設定
4. DocumentRootを変更&表示確認
5. Twigを使ってみよう
6. Loggingしてみよう
7. Controllerを作成しよう
8. PDOを使用してデータベースに接続しよう
9. @nunulkさんのチュートリアルで作成したチケット管理システムをtwigを使って再現しよう
やってみよう
今回の記事では、手順9の続きを行います。
9. @nunulkさんのチュートリアルで作成したチケット管理システムをtwigを使って再現しよう
Controllerクラスの残りを実装
Controllerクラスの残りを実装します。
<?php
namespace App\Action;
use App\Domain\Ticket\TicketRepository;
use App\Domain\Ticket\TicketService;
use Psr\Http\Message\ResponseInterface;
use Slim\Http\Request;
use Slim\Http\Response;
final class TicketAction extends Action
{
public function index(Request $request, Response $response)
{
$repository = new TicketRepository($this->db);
$service = new TicketService($repository);
$tickets = $service->getTickets();
$data = ['tickets' => $tickets];
return $this->twig->render($response, 'tickets/index.twig', $data);
}
public function create(Request $request, Response $response)
{
return $this->twig->render($response, 'tickets/create.twig');
}
public function store(Request $request, Response $response)
{
$repository = new TicketRepository($this->db);
$service = new TicketService($repository);
$subject = $request->getParsedBodyParam('subject');
$result = $service->insertTicket($subject);
return $response->withRedirect('/tickets');
}
public function show(Request $request, Response $response, array $args)
{
$repository = new TicketRepository($this->db);
$service = new TicketService($repository);
try {
$ticket = $service->getTicketById($args['id']);
} catch (\Exception $e) {
return $response->withStatus(404)->write($e->getMessage());
}
$data = ['ticket' => $ticket];
return $this->twig->render($response, 'tickets/show.twig', $data);
}
public function edit(Request $request, Response $response, array $args)
{
$repository = new TicketRepository($this->db);
$service = new TicketService($repository);
try {
$ticket = $service->getTicketById($args['id']);
} catch (\Exception $e) {
return $response->withStatus(404)->write($e->getMessage());
}
$data = ['ticket' => $ticket];
return $this->twig->render($response, 'tickets/edit.twig', $data);
}
public function update(Request $request, Response $response, array $args)
{
$repository = new TicketRepository($this->db);
$service = new TicketService($repository);
try {
$ticket = $service->getTicketById($args['id']);
} catch (\Exception $e) {
return $response->withStatus(404)->write($e->getMessage());
}
$ticket['subject'] = $request->getParsedBodyParam('subject');
$result = $service->updateTicket($ticket);
return $response->withRedirect("/tickets");
}
public function delete(Request $request, Response $response, array $args)
{
$repository = new TicketRepository($this->db);
$service = new TicketService($repository);
try {
$ticket = $service->getTicketById($args['id']);
} catch (\Exception $e) {
return $response->withStatus(404)->write($e->getMessage());
}
$result = $service->deleteTicket($ticket['id']);
return $response->withRedirect("/tickets");
}
}
routes.phpに追記
config/routes.php
に以下を追記します。
$app->get('/tickets/create', \App\Action\TicketAction::class . ':create');
$app->post('/tickets', \App\Action\TicketAction::class . ':store');
$app->get('/tickets/{id}', \App\Action\TicketAction::class . ':show');
$app->get('/tickets/{id}/edit', \App\Action\TicketAction::class . ':edit');
$app->patch('/tickets/{id}', \App\Action\TicketAction::class . ':update');
$app->delete('/tickets/{id}', \App\Action\TicketAction::class . ':delete');
twigで残りの画面を実装しよう
header.twig作成
タイトルを可変にするため、templates/header.twig
を作成します。
<div class="card">
<div class="card-body">
<h2 class="card-title">{{ title }}</h2>
<div class="card-text">
index.twig作成
header.twigを適用します。header.twigの変数title
にチケット一覧を代入しています。
{% extends 'base.twig' %}
{% block content %}
{% include 'header.twig' with {'title': 'チケット一覧'} %}
<a href="/tickets/create">新規作成</a>
<ul class="list-group">
{% for ticket in tickets %}
<li class="list-group-item">
<a href="/tickets/{{ticket.id}}">
{{ticket.subject|escape('html')}}
</a>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
{% endblock %}
show.twig作成
header.twigを適用します。header.twigの変数title
にチケット詳細を代入しています。
{% extends 'base.twig' %}
{% block content %}
{% include 'header.twig' with {'title': 'チケット詳細'} %}
<table class="table table-bordered">
<thread>
<tr>
<th>ID</th>
<th>件名</th>
</tr>
</thread>
<tbody>
<tr>
<td>{{ticket.id|escape('html')}}</td>
<td>{{ticket.subject|escape('html')}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2">
<a href="/tickets/{{ticket.id|escape('html')}}/edit" class="btn btn-primary" >編集</a>
<button class="btn btn-danger" data-toggle="modal" data-target="#deleteModal">削除</button>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
<div class="modal fade" id="deleteModal" tableindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">チケットの削除</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>本当に削除してよろしいですか?</p>
</div>
<form method="post" action="/tickets/{{ticket.id|escape('html')}}">
<input type="hidden" name="_METHOD" value="delete">
<div class="modal-footer">
<button type="submit" class="btn btn-danger">削除</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">キャンセル</button>
</div>
</form>
</div>
</div>
{% endblock %}
subject.twig作成
チケット作成画面とチケット編集画面は似てるので、テンプレートを作ります。
引数に件名とボタンの名前を渡します。
<div class="form-group">
<label for="subject">件名</label>
<input type="text" name="subject" id="subject" class="form-control" value="{{ subject }}">
</div>
</div>
</div>
<div class="card-body">
<button class="btn btn-primary">{{ button }}</button>
</div>
</div>
</form>
本当はembedを使ってみたかったのですが、使い方がよくわかりませんでした...
create.twig作成
header.twigとsubject.twigを適用します。
header.twigの変数title
にチケット作成を代入しています。
create.twigの変数button
に作成を代入しています。subject
に引き継ぐ値はないので、何も渡しません。
{% extends 'base.twig' %}
{% block content %}
<form method="POST" action="/tickets">
{% include 'header.twig' with {'title': 'チケット作成'} %}
{% include 'subject.twig' with {'button': '作成'} %}
{% endblock %}
edit.twig作成
header.twigとsubject.twigを適用します。
header.twigの変数title
にチケット編集を代入しています。
create.twigの変数subject
に引き継いだ件名、button
に編集を代入しています。
{% extends 'base.twig' %}
{% block content %}
<form method="POST" action="/tickets/{{ticket.id|escape('html')}}">
<input type="hidden" name="_METHOD" value="patch">
{% include 'header.twig' with {'title': 'チケット編集'} %}
{% include 'subject.twig' with {'subject': ticket.subject|escape('html'), 'button': '編集'} %}
{% endblock %}
動作確認
ブラウザで以下のURLを開いて、一通りの機能が動くか確認してみてください。
http://192.168.33.90/tickets
参考サイト
Creating your first Slim 3 Framework Application
Creating your first Slim 3 Framework Application Part 2
私家版 Slim Framework チュートリアル (1、2、3、4、5、6)
[PHP]Twigテンプレートの実践的な構成と作り方
Twig の使い方 - シンプルなチートシート的メモ 2 - テンプレートの分割
関連ページ
Windows10にVagrantをを入れてCentOS7をインストールしよう
1. VagrantインストールからVagrantfileを設置まで
2. 仮想マシンの操作
3. WinSCP、Tera Termに秘密鍵でログイン
4. WinSCP、Tera Termにrootユーザーでパスワードログイン
5. zip/unzipをインストール
6. Vagrantにて仮想環境を配布
ローカルでLAMP環境を構築しよう
0. 事前準備
1. Apacheをインストール
2. MySQLをインストール
3. PHPをインストール
4. ファイアウォールとか停止する
Composerをインストール
PHP Slim3フレームワークのサンプルアプリを作ろう
2-1. First Application Walkthrough Getting Set Upまで
Apache
Slim3 Framework×slim-skeleton不使用×twigでプロジェクトを作成する
1. プロジェクト作成~各種設定
2. DocumentRoot変更~Twigを使用
3. LoggingとController
4.PDO使用
5. チケット管理システムを再現➀
6. チケット管理システムを再現➁