備忘録

個人的な試行錯誤のメモですので間違った情報が載っていたらごめんなさい。

CakePHP3(3.0.0-beta1)でとりあえずHelperを作ってみる

CakePHP3(3.0.0-beta1)でとりあえずHelperを作ってみる

①ColorHelper.phpを作成

<?php
namespace App\View\Helper;
use Cake\View\Helper;

class ColorHelper extends Helper {
    public function red($string) {
        return '<span style="color:red">' . $string . '</span>';
    }
}

②ArticlesControllerを下記のように変更

public $helpers = ['Paginator' => ['templates' => 'paginator-templates.php'],'Color'];

③index.ctpを下記のように変更

<th><?= $this->Color->red('Id') ?></th>
<th><?= $this->Color->red('Title') ?></th>
<th><?= $this->Color->red('Created') ?></th>
<th><?= $this->Color->red('Action') ?></th>

CakePHP3(3.0.0-beta1)でコメントが書き込まれたらメール送信されるようにしてみる

ぼんやりしている間にCakePHP 3.0.0-beta1がリリースされていました。

ブログチュートリアルにコメント機能を追加したので、コメントが書き込まれたらメール送信されるようにしてみます。



①ArticlesControllerを下記のように変更。
・ライブラリの読み込み

use Cake\Network\Email\Email;

・comment()にメール送信処理追加

public function comment() {
    $this->loadModel('Comments');

    $comment = $this->Comments->newEntity($this->request->data);
    if ($this->request->is('post')) {
        if ($this->Comments->save($comment)) {
          $email = new Email('dev');
          $email->to('送信先のメールアドレス')
            ->subject($this->request->data['title'])
            ->send($this->request->data['body']);

            $this->Flash->success(__('Your comment has been saved.'));
            //return $this->redirect(['action' => 'index']);
        }else{
            $this->Flash->error(__('Unable to add your comment.'));
        }
    }
    return $this->redirect('/articles/view/'.$this->request->data['article_id']);
}

②config/app.phpを下記のように変更(devを追加)

'EmailTransport' => [
 'default' => [
  'className' => 'Mail',
  // The following keys are used in SMTP transports
  'host' => 'localhost',
  'port' => 25,
  'timeout' => 30,
  'username' => 'user',
  'password' => 'secret',
  'client' => null,
  'tls' => null,
 ],
 'dev' => [
  'className' => 'Smtp',
  // The following keys are used in SMTP transports
  'host' => 'localhost',
  'port' => 25,
  'timeout' => 30,
  'client' => null,
  'tls' => null,
 ],
],

'Email' => [
 'default' => [
  'transport' => 'default',
  'from' => 'you@localhost',
  //'charset' => 'utf-8',
  //'headerCharset' => 'utf-8',
 ],
 'dev' => [
  'transport' => 'dev',
  'from' => ['差出人のメールアドレス'=>'差出人名'],
  //'charset' => 'utf-8',
  //'headerCharset' => 'utf-8',
 ],
],


差出人情報は送信時に都度指定することも可能。

Email — CakePHP Cookbook 3.x documentation

CakePHP3(3.0.0-alpha1)のブログチュートリアルで記事一覧にページネーションを追加してみる2

PaginatorのHelperが出力するタグからリストタグを削ってみる。

①ArticlesControllerを下記のように変更。

public $helpers = ['Paginator' => ['templates' => 'paginator-templates.php']];


②paginator-templates.phpというファイルをsrc/Config/下に作る。中身は下記の通り。(変更したのは一部のみ)
※2014/08/12追記:src/Config/は3.0.0-alpha2でconfigに変更になった様子。

<?php

$config =[
            'nextActive' => '<a rel="next" href="{{url}}">{{text}}</a>',
            'nextDisabled' => '<span>{{text}}</span>',
            'prevActive' => '<a rel="prev" href="{{url}}">{{text}}</a>',
            'prevDisabled' => '<span>{{text}}</span>',
            'number' => '<a href="{{url}}">{{text}}</a>',
            'current' => '<span>{{text}}</span>'
        ];

paginator-templates.phpの中に何を書いていいのかわからなくてしばらく悩んでしまった。
PaginatorHelper — CakePHP Cookbook 3.x documentation

CakePHP3(3.0.0-alpha1)のブログチュートリアルで記事一覧にページネーションを追加してみる

CakePHP3(3.0.0-alpha1)のブログチュートリアルで記事一覧にページネーションを追加してみる

①ArticlesControllerに下記を追加

public $helpers = ['Paginator'];
public $components = ['Paginator'];
public $paginate = ['limit' => '5', 'order' => ['Article.id' => 'asc']];


②ArticlesControllerのindexアクションを変更

public function index() {
    $articles = $this->Articles->find('all');
    //$this->set(compact('articles'));
    $this->set('articles', $this->paginate());
}

③index.ctpに下記を追加

<?php echo $this->Paginator->prev('<<' . __('previous')); ?>
<?php echo $this->Paginator->numbers(['modulus' => 9]); ?>
<?php echo $this->Paginator->next(__('next') . '>>'); ?>

デフォルトだとリストタグが付いてくるっぽい。

CakePHP3(3.0.0-alpha1)のブログチュートリアルで記事にコメント機能を追加する3

①ArticlesControllerにactionを追加

addをベースにしながら、色々試したかったのでaddの流れから少しだけ変更してある。

public function comment() {
    $this->loadModel('Comments');

    $comment = $this->Comments->newEntity($this->request->data);
    if ($this->request->is('post')) {
        if ($this->Comments->save($comment)) {
            $this->Flash->success(__('Your comment has been saved.'));
            //return $this->redirect(['action' => 'index']);
        }else{
            $this->Flash->error(__('Unable to add your comment.'));
        }
    }
    return $this->redirect('/articles/view/'.$this->request->data['article_id']);
}

前の記事でも$this->loadModel('Comments');でモデルを読み込むと書いたけれど、pdf版のドキュメントを見ると

Note: CakePHP merges the following variables from the AppController into your application’s controllers:
・$components
・$helpers
・$uses

と書いてあり、$usesだけリンクがない状態。この後のバージョンで追加されるのかも?

CakePHP3(3.0.0-alpha1)のブログチュートリアルで記事にコメント機能を追加する2

view.ctpにコメント一覧を表示したのでコメント入力欄を足してみる

①ArticlesControllerのview()を編集

public function view($id = null) {
    if (!$id) {
        throw new NotFoundException(__('Invalid article'));
    }

    //$article = $this->Articles->get($id);
    $article = $this->Articles->find('all')->contain(['Comments'])->where(['id'=>$id])->first();

    $this->set(compact('article'));

    $this->loadModel('Comments');
    $comment_entity = $this->Comments->newEntity($this->request->data);
    $this->set('comment_entity', $comment_entity);
}

$this->loadModel('Comments');
を省いて
$this->Articles->Comments->newEntity($this->request->data)
でも。

2.Xは$usesで使うモデルを指定していたけれど3.Xでは違うっぽい?
http://book.cakephp.org/3.0/en/controllers.html#Controller::loadModel

※2014/07/16追記:pdf版のドキュメントには

Note: CakePHP merges the following variables from the AppController into your application’s controllers:
・$components
・$helpers
・$uses

と書かれていて、$usesだけリンクがない状態。様子見。


②view.ctpに入力欄を追加する

<h1>Comment</h1>
<?php
    echo $this->Form->create($comment_entity,['action'=>'comment']);
    echo $this->Form->input('title');
    echo $this->Form->input('body', ['rows' => '3']);
    echo $this->Form->button(__('Save Comment'));
    echo $this->Form->hidden('article_id',array('value'=>$article->id));
    echo $this->Form->end();
?>

add.ctpみたいに入力欄が空だとメッセージが出る。

CakePHP3(3.0.0-alpha1)のブログチュートリアルで記事にコメント機能を追加する

①comentsテーブルを作る

CREATE TABLE comments (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(50),
body TEXT,
article_id int(10),
created DATETIME DEFAULT NULL,
modified DATETIME DEFAULT NULL
);

INSERT INTO comments (title,body,article_idcreated)
VALUES ('test', 'comment', 1, NOW());


②CommentsTable.phpを作る

<?php
namespace App\Model\Table;

use Cake\ORM\Table;
use Cake\Validation\Validator;


class CommentsTable extends Table {

	public function initialize(array $config) {
		$this->addBehavior('Timestamp');
	}

	public function validationDefault(Validator $validator) {
        $validator
            ->notEmpty('title')
            ->notEmpty('body');

        return $validator;
    }
}


③ArticleTable.phpでhasManyの設定

public function initialize(array $config) {
    $this->addBehavior('Timestamp');

    $this->hasMany('Comments', [
            'className' => 'Comments'
    ]);
}


④ArticlesController.phpを書き換える

public function view($id = null) {
        if (!$id) {
            throw new NotFoundException(__('Invalid article'));
        }

        //$article = $this->Articles->get($id);
        $article = $this->Articles->find('all')->contain(['Comments'])->where(['id'=>$id])->first();

        $this->set(compact('article'));
}


⑤view.ctpを書き換える(下記を追加)

<h1>Comment</h1>
<table>
 <tr>
 <th>Id</th>
 <th>Title</th>
 <th>Created</th>
 </tr>
 <?php foreach ($article->comments as $comment): ?>
 <tr>
 <td><?= $comment->id ?></td>
 <td><?= $comment->title ?></td>
 <td><?= $comment->created->format(DATE_RFC850) ?></td>
 </tr>
 <?php endforeach; ?>
</table>


【備考】
viewで呼び出すときは$article->Commentsじゃなくて$article->commentsみたい