nazolabo

フリーランスのWebエンジニアが近況や思ったことを発信しています。

CakePHP2.0のブログチュートリアル

CakePHP2.0がリリースされました

とりあえず英語でブログチュートリアルがあるのでやってみます。

インストール


まずgithubから、2.0のtarballをダウンロードします。zipでもいいです。

適当に展開して、展開したところにWebからアクセスします。(webrootではなく、展開したところ。index.phpがあって、appとかcakeとかってフォルダが見えるところ)
ここでは、/Users/nazo/public_html/cakeblogに展開して、http://localhost/cakeblog/にアクセスする、とします。

いろいろエラーが出ます。

「Warning: _cake_core_ cache was unable to write 'cake_dev_ja' to Apc cache in 〜」と出た場合


APCが無効になっています。APCを有効にするか、apc.soを読み込まないようにしてください。どちらもphp.iniで設定できます。

「Warning: _cake_core_ cache was unable to write 'cake_dev_ja' to File cache in 〜」と出た場合


APCは無効ですが、ファイルキャッシュへの書き込みができません。「chmod -R 777 app/tmp」で、いろいろエラーが消えます。(Apacheに権限が入れば何でもいいです。以下同様。)

「Warning: /Users/nazo/public_html/cakeblog/app/tmp/cache/ is not writable in 〜」と出た場合


「chmod -R 777 app/tmp」で解決します。

「Your tmp directory is NOT writable.」と出た場合


「chmod -R 777 app/tmp」で解決します。

「URL rewriting is not properly configured on your server. 」と出た場合


Apachemod_rewriteを有効にしてください。できない場合はどうにかなります。(未調査)

「Please change the value of 'Security.salt' in app/Config/core.php to a salt value specific to your application」と出た場合


「app/Config/core.php」の、

Configure::write('Security.salt', 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi');

の行の、よくわからない文字列の部分を、適当なよくわからない文字列に変更してください。

「Please change the value of 'Security.cipherSeed' in app/Config/core.php to a numeric (digits only) seed value 〜」と出た場合


「app/Config/core.php」の、

Configure::write('Security.cipherSeed', '76859309657453542496749683645');

の行の、よくわからない数字の部分を、適当なよくわからない数字に変更してください。

「Your database configuration file is NOT present.」と出た場合


「app/Config/database.php.default」を、「app/Config/database.php」にリネーム(あるいはコピー)し、

        public $default = array(
                'datasource' => 'Database/Mysql',
                'persistent' => false,
                'host' => 'localhost',
                'login' => 'user',
                'password' => 'password',
                'database' => 'database_name',
                'prefix' => '',
                //'encoding' => 'utf8',
        );

の部分を適当に変更してください。とりあえず今回は、

        public $default = array(
                'datasource' => 'Database/Mysql',
                'persistent' => false,
                'host' => 'localhost',
                'login' => 'root',
                'password' => '',
                'database' => 'cakeblog',
                'prefix' => '',
                'encoding' => 'utf8',
        );

とします。MySQLで、この設定のデータベースも作ってください。

DBの作成


チュートリアル通りに、以下のデータを入れます。

/* First, create our posts table: */
CREATE TABLE posts (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(50),
    body TEXT,
    created DATETIME DEFAULT NULL,
    modified DATETIME DEFAULT NULL
);

/* Then insert some posts for testing: */
INSERT INTO posts (title,body,created)
    VALUES ('The title', 'This is the post body.', NOW());
INSERT INTO posts (title,body,created)
    VALUES ('A title once again', 'And the post body follows.', NOW());
INSERT INTO posts (title,body,created)
    VALUES ('Title strikes back', 'This is really exciting! Not.', NOW());

モデルの作成


app/Model/Post.phpを作成します。

<?php

class Post extends AppModel {
    public $name = 'Post';
}

?>

コントローラーの作成


app/Controller/PostsController.phpを作成します。

<?php
class PostsController extends AppController {
    public $helpers = array ('Html','Form');
    public $name = 'Posts';

    public function index() {
        $this->set('posts', $this->Post->find('all'));
    }
}
?>

ビューの作成


app/View/Posts/index.ctpを作成します。

<!-- File: /app/View/Posts/index.ctp -->

<h1>Blog posts</h1>
<table>
    <tr>
        <th>Id</th>
        <th>Title</th>
        <th>Created</th>
    </tr>

    <!-- Here is where we loop through our $posts array, printing out post info -->

    <?php foreach ($posts as $post): ?>
    <tr>
        <td><?php echo $post['Post']['id']; ?></td>
        <td>
            <?php echo $this->Html->link($post['Post']['title'],
array('controller' => 'posts', 'action' => 'view', $post['Post']['id'])); ?>
        </td>
        <td><?php echo $post['Post']['created']; ?></td>
    </tr>
    <?php endforeach; ?>

</table>

これで、 http://localhost/cakeblog/posts にアクセスすると、

一覧画面が表示されます。

詳細画面の作成


app/Controller/PostsController.phpを修正します。

<?php
class PostsController extends AppController {
    public $helpers = array('Html', 'Form');
    public $name = 'Posts';

    public function index() {
         $this->set('posts', $this->Post->find('all'));
    }

    public function view($id = null) {
        $this->Post->id = $id;
        $this->set('post', $this->Post->read());
    }
}
?>

app/View/Posts/view.ctpを作成します。

<!-- File: /app/View/Posts/view.ctp -->

<h1><?php echo $post['Post']['title']?></h1>

<p><small>Created: <?php echo $post['Post']['created']?></small></p>

<p><?php echo $post['Post']['body']?></p>

新規作成画面の作成


app/Controller/AppController.phpを修正します。

<?php
class PostsController extends AppController {
    public $name = 'Posts';
    public $components = array('Session');

    public function index() {
        $this->set('posts', $this->Post->find('all'));
    }

    public function view($id) {
        $this->Post->id = $id;
        $this->set('post', $this->Post->read());

    }

    public function add() {
        if ($this->request->is('post')) {
            if ($this->Post->save($this->request->data)) {
                $this->Session->setFlash('Your post has been saved.');
                $this->redirect(array('action' => 'index'));
            }
        }
    }
}
?>

app/View/Posts/add.ctpを作成します。

<!-- File: /app/View/Posts/add.ctp -->

<h1>Add Post</h1>
<?php
echo $this->Form->create('Post');
echo $this->Form->input('title');
echo $this->Form->input('body', array('rows' => '3'));
echo $this->Form->end('Save Post');
?>

app/View/Post/index.ctpの末尾に、addへのリンクを追加します。

<?php echo $this->Html->link('Add Post', array('controller' => 'posts', 'action' => 'add')); ?>

バリデーション


空データの入力を拒否します。
app/Model/Post.phpを修正します。

<?php
class Post extends AppModel {
    public $name = 'Post';

    public $validate = array(
        'title' => array(
            'rule' => 'notEmpty'
        ),
        'body' => array(
            'rule' => 'notEmpty'
        )
    );
}
?>

編集画面の作成


app/Controller/PostsController.phpに、以下の処理を追加します。

<?php
class PostsController extends AppController {
...
public function edit($id = null) {
    $this->Post->id = $id;
    if ($this->request->is('get')) {
        $this->request->data = $this->Post->read();
    } else {
        if ($this->Post->save($this->request->data)) {
            $this->Session->setFlash('Your post has been updated.');
            $this->redirect(array('action' => 'index'));
        }
    }
}
…
}
?>

app/View/Posts/edit.ctpを作成します。

<!-- File: /app/View/Posts/edit.ctp -->

<h1>Edit Post</h1>
<?php
    echo $this->Form->create('Post', array('action' => 'edit'));
    echo $this->Form->input('title');
    echo $this->Form->input('body', array('rows' => '3'));
    echo $this->Form->input('id', array('type' => 'hidden'));
    echo $this->Form->end('Save Post');
?>

app/View/Posts/index.ctpに、編集リンクを追加します。

<!-- File: /app/View/Posts/index.ctp  (edit links added) -->

<h1>Blog posts</h1>
<p><?php echo $this->Html->link("Add Post", array('action' => 'add')); ?></p>
<table>
    <tr>
        <th>Id</th>
        <th>Title</th>
                <th>Action</th>
        <th>Created</th>
    </tr>

<!-- Here's where we loop through our $posts array, printing out post info -->

<?php foreach ($posts as $post): ?>
    <tr>
        <td><?php echo $post['Post']['id']; ?></td>
        <td>
            <?php echo $this->Html->link($post['Post']['title'], array('action' => 'view', $post['Post']['id']));?>
                </td>
                <td>
            <?php echo $this->Form->postLink(
                'Delete',
                array('action' => 'delete', $post['Post']['id']),
                array('confirm' => 'Are you sure?')
            )?>
            <?php echo $this->Html->link('Edit', array('action' => 'edit', $post['Post']['id']));?>
        </td>
        <td><?php echo $post['Post']['created']; ?></td>
    </tr>
<?php endforeach; ?>

</table>

削除リンクもあります。(使うのはこの後)

削除機能の作成

app/Controller/PostsController.phpに、以下の処理を追加します。

<?php
class PostsController extends AppController {
...

public function delete($id) {
    if (!$this->request->is('post')) {
        throw new MethodNotAllowedException();
    }
    if ($this->Post->delete($id)) {
        $this->Session->setFlash('The post with id: ' . $id . ' has been deleted.');
        $this->redirect(array('action' => 'index'));
    }
}
…
}
?>

ルーティング


ルーティングを変更する場合は、app/Config/routes.phpを編集します。

現在は http://localhost/cakeblog/posts からアクセスしていますが、これを http://localhost/cakeblog/ でアクセスできるようにするには、

        Router::connect('/', array('controller' => 'posts', 'action' => 'index'));
        //Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));

のようにします。