仕事で勉強する必要に駆られたので、「CakePHPで高速Webアプリ開発」を基に勉強。
でも、例が1.1なんだけど使ってるのは1.2だったりして結構直しが必要だったのでメモ。
ちなみにMultiple flashes with different classesを使用してみた。エラーメッセージが綺麗に出力されて便利。
models/tasks.php
<?php class Task extends AppModel { var $name = "Task"; /* * 入力規則のチェック * http://www.syuhari.jp/blog/archives/394 */ var $validate = array("content" => array( "required" => array( "rule"=>VALID_NOT_EMPTY , "message" => "必須項目です" ), ), ); } ?>
controllers/tasks_controller.php
<?php // app/controllers/tasks_controller.php class TasksController extends AppController { var $name = "Tasks"; var $uses = array("Task"); var $helpers = array("flash"); var $app_title = "CakePHPでToDoアプリ!"; /* * Multiple flashes with different classes * http://bakery.cakephp.org/articles/view/multiple-flashes-with-different-classes * flashヘルパを使用しています。 */ function flash( $message, $class = "status" ) { $this->Session->activate(); $old = $this->Session->read("messages"); $old[$class][] = $message; $this->Session->write( "messages", $old ); } /* デフォルトで実行されるアクション */ function index() { /* 未完了タスクのデータを取得する */ $this->set("yet_tasks", $this->Task->findAllByStatus("yet", null, "Task.created ASC")); /* 完了タスクのデータを取得する */ $this->set("done_tasks", $this->Task->findAllByStatus("done", null, "Task.modified DESC")); $this->pageTitle = $this->app_title . " - タスク一覧"; } /* データ追加アクション */ function add () { //データが渡っていれば if (!empty($this->data) && $this->data["Task"]["content"] != "") { //保存処理を実行する if ($this->Task->save($this->data, true, array("content", "created", "modified"))) { //画面にメッセージを表示 $this->flash("追加したよ!", "success"); /* サンプルでは $this->flash("タスクが追加されました", "/tasks"); してるけど、イマイチなのでしない! */ } } else { $this->flash("入力してよ!", "error"); } $this->redirect("/tasks"); } /* タスクを「完了」にした時のアクション */ function done($id) { if ($this->Task->findById($id)) { $this->Task->id = $id; $this->Task->save(array("status" => "done")); $this->flash("完了にしたよ!", "success"); } $this->redirect("/tasks"); } /* タスク編集時のアクション */ function edit($id) { /* idでデータを取得してみる */ $task = $this->Task->findById($id); if (!$task) { /* 取得できなければリストページに戻す */ $this->redirect("/tasks"); return; } if (!empty($this->data)) { if ($this->data["Task"]["content"] != "") { /* オブジェクトへ値を格納してテーブルを更新する */ $task["Task"]["content"] = $this->data["Task"]["content"]; $this->Task->save($task); $this->flash("更新したよ!", "success"); } else { $this->flash("入力してよ!", "error"); } } $this->set("task", $task); $this->pageTitle = $this->app_title . " - タスクの編集 ID: " . $id; } /* タスク削除時のアクション */ function del($id) { $this->Task->del($id); $this->flash("削除したよ!", "success"); $this->redirect("/tasks"); } } ?>
views/tasks/index.ctp
<?php /* http://gihyo.jp/dev/serial/01/cakephp/0006 の記述方法で書くと、1.2ではうまく保存できなかった。以下の書き方なら大丈夫。 ちなみにこの書き方は、CakePHPポケットリファレンスを参照。 */ /* フォームオブジェクト開始 */ echo $form->create("Task", array("action" => "add", "type"=>"post")); /* contentに対応するテキストエリアを追加 */ echo $form->text("content", array("type"=>"text")); /* フォームオブジェクト終了(submitボタンもついでに追加) */ echo $form->end(array("label" => "タスクを追加", "name" => "submitButton", "div" => array("class"=>"submitDiv"))); ?> <?php echo $flash->show(); ?> <h2>未完了タスク</h2> <table> <tr> <th>Id</th> <th>タスク内容</th> <th>状態</th> <th>操作</th> <th>作成日</th> </tr> <?php /* オブジェクトの値をループ。イメージとしてはDAO? */ foreach ($yet_tasks as $task) { ?> <tr> <td><?php echo h($task["Task"]["id"]) ?></td> <td><?php echo h($task["Task"]["content"]) ?></td> <td><?php echo h($task["Task"]["status"]) ?></td> <td> <?php echo $html->link("完了", "/tasks/done/" . $task["Task"]["id"], null, "完了してもよろしいですか?") ?> <?php echo $html->link("編集", "/tasks/edit/" . $task["Task"]["id"]) ?> <?php echo $html->link("削除", "/tasks/del/" . $task["Task"]["id"], null, "削除してもよろしいですか?") ?> </td> <td><?php echo h($task["Task"]["created"]) ?></td> </tr> <?php } ?> </table> <h2>完了タスク</h2> <table> <tr> <th>Id</th> <th>タスク内容</th> <th>状態</th> <th>操作</th> <th>作成日</th> </tr> <?php foreach ($done_tasks as $task) { ?> <tr> <td><?php echo h($task["Task"]["id"]) ?></td> <td><?php echo h($task["Task"]["content"]) ?></td> <td><?php echo h($task["Task"]["status"]) ?></td> <td><?php echo $html->link("削除", "/tasks/del/" . $task["Task"]["id"], null, "削除してもよろしいですか?") ?></td> <td><?php echo h($task["Task"]["created"]) ?></td> </tr> <?php } ?> </table>
views/tasks/edit.ctp
<h1>タスクの編集</h1> <p><a href="<?php echo h($html->url("/tasks")) ?>">タスク一覧へ戻る</a></p> <?php echo $flash->show(); ?> <?php /* フォームオブジェクト開始 */ echo $form->create("Task", array("action" => "edit/".$task["Task"]["id"], "type" => "post")); /* idを隠しフィールドとして格納 */ echo $form->hidden("Task.id", array("value" => $task["Task"]["id"])); /* contentに対応するテキストエリアを追加 */ echo $form->text("content", array("type" => "text", "value" => $task["Task"]["content"])); /* フォームオブジェクト終了(submitボタンもついでに追加) */ echo $form->end(array("label" => "タスクを更新", "name" => "submitButton", "div" => array("class"=>"submitDiv"))); ?>
views/layouts/default.ctp
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title><?php echo h($title_for_layout); ?></title> <?php echo $html->css("cake.generic");?> </head> <body> <div id="container"> <div id="header"> <h1>Todo App</h1> </div> <div id="content"> <?php echo $content_for_layout; ?> </div> </div> </body> </html>