ホーム > タグ > CakePHP

CakePHP

CakePHPのお勉強(#022)

新年一発目。

去年の振り返りも、今年の目標も書かず、、、
気づけばもう3月も終わりに近づいています。

これはいかん!これはいかんぞ!!!

ということで、CakePHPに関して書いていきます!!

MySQLのクエリを表示する。

ビューにMySQLのクエリを表示させることができます。
設定は以下。

1.”core.php”の編集

デバッグレベルを2以上にします。

$ vim app/config/core.php

    Configure::write('debug', 2);

2.レイアウトにsql_dumpを追加する

レイアウトに以下を追加する。

$ vim app/views/layout/default.ctp

  <div class="debug">
    <?php echo $this->element('sql_dump'); ?>
  </div>

以上。

CakePHPのお勉強(#020)

お久しぶりです。
最近はテンションだだ下がり諦めかけましたが、
『CakePHPに罪はない』と悔い改めやってまいります。

その前にちょっとグチ。
人生って難しいな〜。。

さて、今回はプロフィールページを作っていきます。
プロフィールページの要件を以下に記載。

  1. ユーザネームが変更できる
  2. メールアドレスが変更できる
  3. 自己紹介が変更できること

今日のところはこれで許してやろう。。
他にもパスワード、画像変更などがありますが、それはまたやります。

あとそろそろバリデーションをきちんと書こうと思い、
そちらにも力を入れていきます。

で、そのバリデーションに関してですが、意外とくせ者。
エラーがでなかったりエラーがでなかったりエラーがでなかったり。。

結論としてはものすごく簡単なことだったんですが、

『バリデーション後にリダイレクトをするとバリデーションエラーがでなくなる!?』

ということでした。(ソースコードは見てないので自分で実験した結果です。。)
そろそろソースも読み始めたいなー。

でも、、、
何かを編集したらリダイレクトしたくなるもんじゃないのかなー
と思いつつ進めていきます。

テーブルカラム追加

今回、これまたデータベースにカラムを追加しました。
本家twitterでは名前とユーザネームが分かれていたので
こちらもそれにあわせて分けるようにしました。
ユーザネームはURIに使うため、not null, uniqueにするように設定しました。

また、ちらっと引っかかったところはカラムを追加してからユニークキーを追加しようとすると既存で入っているレコードが既にユニークではないためエラーがでる。
めんどくさくても全レコードに対してユニークにしてからキー追加を行う必要がある。
こういうのは実際に手を動かしてみないとわからないところだな。

mysql> desc users;
+------------+------------------+------+-----+---------+----------------+
| Field      | Type             | Null | Key | Default | Extra          |
+------------+------------------+------+-----+---------+----------------+
| id         | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name       | varchar(50)      | YES  |     | NULL    |                |
| email      | varchar(255)     | NO   | UNI | NULL    |                |
| passwd     | varchar(255)     | YES  |     | NULL    |                |
| profile    | text             | YES  |     | NULL    |                |
| regist_key | char(40)         | YES  | UNI | NULL    |                |
| registed   | int(1)           | NO   |     | 0       |                |
| created    | datetime         | YES  |     | NULL    |                |
| modified   | datetime         | YES  |     | NULL    |                |
+------------+------------------+------+-----+---------+----------------+
10 rows in set (0.00 sec)

mysql> alter table users add username varchar(50) after name;
mysql> alter table users modify username varchar(50) not null;
//ここで各レコードのusernameを変更
mysql> alter table users add unique('username');
mysql> desc users;
+------------+------------------+------+-----+---------+----------------+
| Field      | Type             | Null | Key | Default | Extra          |
+------------+------------------+------+-----+---------+----------------+
| id         | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name       | varchar(50)      | YES  |     | NULL    |                |
| username   | varchar(50)      | NO   | UNI | NULL    |                |
| email      | varchar(255)     | NO   | UNI | NULL    |                |
| passwd     | varchar(255)     | YES  |     | NULL    |                |
| profile    | text             | YES  |     | NULL    |                |
| regist_key | char(40)         | YES  | UNI | NULL    |                |
| registed   | int(1)           | NO   |     | 0       |                |
| created    | datetime         | YES  |     | NULL    |                |
| modified   | datetime         | YES  |     | NULL    |                |
+------------+------------------+------+-----+---------+----------------+
10 rows in set (0.01 sec)

ビュー


% vim views/users/profile.ctp
<div id="page-header">
  <h2>
    <a href="/twit/users/profile"><img class="sumbnail" src="*" alt="prof photo" align="left"/></a>
    kichonの設定
  </h2>
</div>
<div id="wrapper">
  <?php echo $form->create('User', array('type' => 'post', 'action' => 'profile' . DS . $id)); ?>
  <table id="profile">
    <tr>
      <th>アイコン</th>
      <td><?php echo $html->image('*', array('alt' => 'photo')); ?></td>
    </tr>
    <tr <th>username
      <td><?php echo $form->input('username', array('size' => 20, 'label' => false)); ?></td>
    </tr>
    <tr>
      <th>email</th>
      <td><?php echo $form->input('email', array('size' => 20, 'label' => false)); ?></td>
    </tr>
    <tr>
      <th>profile</th>
      <td><?php echo $form->input('profile', array('type' => 'textarea', 'cols' => 55, 'rows' => 2, 'label' => false)); ?></td>
    </tr>
    <tr>
      <th></th>
      <td><?php echo $form->end('登録'); ?></td>
    </tr>
  </table>
</div>

コントローラ


% vim controllers/users_controller.php
function profile($id = null) {

  $this->set("page_title", "fake twit");
  $this->set("content_header", "fake twit");
  $this->set("content_footer", "Copyright 2010 kichon fake twit, All Rights Reserved.");

  $this->_checkSession('myname');
  if (!empty($this->data)) {
    $this->User->id = $id;
    if (empty($this->data['User']['username'])) {
      unset($this->data['User']['username']);
    }
    if (empty($this->data['User']['email'])) {
      unset($this->data['User']['email']);
    }
    if (empty($this->data['User']['profile'])) {
      unset($this->data['User']['profile']);
    }

    if ($this->User->validates()) {
      $this->User->save($this->data);
    }
  }

}

モデル


% vim models/user.php
<?php

class User extends AppModel {

  public $name = 'User';
  public $validate = array(
                    'name' => array(
                        'rule' => 'notEmpty',
                        'message' => '名前を入力してください',
                        'last' => true,
                    ),
                    'username' => array(
                        'notempty' => array(
                            'rule' => 'notEmpty',
                            'message' => 'ユーザ名を入力してください',
                            'last' => true,
                        ),
                        'unique' => array(
                            'rule' => 'isUnique',
                            'message' => '他のユーザが使用しています',
                            'last' => true,
                        ),
                    ),
                    'email' => array(
                        'notempty' => array(
                            'rule' => 'notEmpty',
                            'message' => 'メールアドレスを入力してください',
                            'last' => true,
                        ),
                        'unique' => array(
                            'rule' => 'isUnique',
                            'message' => 'このメールアドレスは既に使用されています',
                            'last' => true,
                        ),
                        'mail' => array(
                            'rule' => 'email',
                            'message' => 'メールアドレスの形式と異なっています',
                            'last' => true,
                        ),
                    ),
                    'passwd' => array(
                        'notempty' => array(
                            'rule' => 'notEmpty',
                            'message' => 'メールアドレスを入力してください',
                            'last' => true,
                        ),
                        'alphaNumeric' => array(
                            'rule' => 'alphaNumeric',
                            'message' => 'アルファベットか数字のみを入力してください',
                            'last' => true,
                        ),
                        'length' => array(
                            'rule' => array('between', 5, 10),
                            'message' => 'パスワードは5文字以上、10文字以下で入力してください',
                            'last' => true,
                        ),
                    ),
                    'profile' => array(
                        'rule' => array('maxLength', 150),
                    ),
                );
  public $hasMany = 'Tweet';

}

バリデーションに関して

今回のバリデーション設定

上記で設定したバリデーションの要件を書いておきます。

usersテーブル
  • 名前:name
    • 必須
  • ユーザ名:username
    • 必須
    • ユニーク
  • メール:email
    • 必須
    • メールアドレスの形式かどうかの確認
    • ユニーク
  • パスワード
    • 必須
    • アルファベットか数字のみ許可
    • 長さが5文字以上10文字以下
  • プロフィール:profile
    • 150字以内

こんな感じかな。いつも通り足りなければ随時追加していきます。


CakePHPのバリデーションに関して

CakePHPのお勉強(#013)
バリデーションに関して少し書きましたが、少し追記します。

saveメソッド以外のチェック方法

CakePHP1.3の4.1.6 コントローラ(Controller)からデータのバリデーションを実行するを読みました。
バリデーションはコントローラでsaveメソッドを実行すると自動的にチェックが走り、エラーがある場合はデータベースへの保存は行われずに、エラーの出力を行います。
saveメソッドを行わないでバリデーションを行いたい場合はvalidatesメソッドを使用する。

–補足1–
このブログの一番始めにリダイレクトできないと書いたけど、validatesメソッドを使用したらいけました。。。
マニュアルはちゃんと読まなきゃだめだよね。
以下のような書き方をする。

    $this->User->set($this->data);
    if ($this->User->validates()) {
        $this->User->save($this->data, false);
        $this->redirect('mypage' . DS . $id);
    }

validatesメソッドを使用する場合は必ず事前にモデルへデータをセットしてやる。
saveメソッドはデフォルトでバリデートチェックを行うようになっているため、このままだと2回チェックを行うことになる。
そんなときはsaveメソッドの第2引数にfalseを指定してあげる。
エラーを取得するにはinvalidFiledsメソッドを使用する。

–補足2–
以下を書いていたのですが、再度実験したらlastがなくてもうまくいっていました。。。。
たぶんバリデーションの設定方法が悪かったのかな。。

エラーメッセージを出力する

いくつかバリデーションを設定したときにそれぞれに対するエラーメッセージを出力したいというのは当たり前だと思います。
例えば、メールアドレスには”必須”, “メールアドレスの形式に準拠している”、”ユニーク”というのを設定しましたが、このチェックのそれぞれにメッセージを設定し、チェックに引っかかったらそれに関してのエラーを出力したいということです。
それがうまくいかず色々調べてたんですが、Validateのエラーメッセージを複数書いた時に最初のメッセージを出す方法を参考に設定したらうまくいきました。

バリデーションの参考
http://cakephp.chorochoro.com/archives/197
http://blog.syuhari.jp/archives/187
http ://cakephp.hamazo.tv/e1577376.html
http://blog.ecworks.jp/archives/792
http://www.1×1.jp/blog/2007/04/cakephp_save_validates.html


さて、次はもうちょっとプロフィールページを充実させていったり
ツイートの部分を変更しようかと思います。

CakePHPのお勉強(#019)

今回は新規登録機能部分をもっと掘り下げて進めていきました。

前回はメール送信部分までやりましたが、
今回は6〜8を・・・と考えたのですが、ちょっと処理を変えました。

> 5.チェックがOKであればメールを送信
> 6.メールにプロフィール変更ページへのリンクを張る
> 7.プロフィール情報記入
> 8.自分のホームページにリダイレクトして完了



5.チェックがOKであればメールを送信を行い、プロフィール変更画面へリダイレクト(この時点では仮登録)
6.メールに本登録URLを張り、本登録を促す
7.本登録URLからアクセスがあった場合に本登録完了
8.自分のホームページにリダイレクト

という風に変更しました。
仮登録と本登録が分かれているのは本人の確認と本登録までにワンステップ挟むことによって大量にアカウントを取られることがないようにするため?かな。

考えなければならないのは以下の2点。

  1. 仮登録、本登録の区別を付ける必要がある
  2. 本登録用のURLを作成する必要がある。

1.仮登録、本登録の区別に関して

usersテーブルにその人が本登録完了しているか完了していないかのカラムを追加することにしました。

カラム名はregistedでデフォルト値は0でこれを仮登録として、本登録作業を行ったら1にアップデートします。


テーブル定義変更


% mysql -u root // アカウントをきちんと作らねば><。
mysql> use twit;
mysql> desc users;
+------------+------------------+------+-----+---------+----------------+
| Field      | Type             | Null | Key | Default | Extra          |
+------------+------------------+------+-----+---------+----------------+
| id         | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name       | varchar(50)      | YES  |     | NULL    |                |
| email      | varchar(255)     | NO   | UNI | NULL    |                |
| passwd     | varchar(255)     | YES  |     | NULL    |                |
| profile    | text             | YES  |     | NULL    |                |
| created    | datetime         | YES  |     | NULL    |                |
| modified   | datetime         | YES  |     | NULL    |                |
+------------+------------------+------+-----+---------+----------------+
7 rows in set (0.01 sec)

mysql> alter table users add registed int(1) after regist_keys;
mysql> alter table users modify registed int(1) not null default 0;
mysql> desc users;
+------------+------------------+------+-----+---------+----------------+
| Field      | Type             | Null | Key | Default | Extra          |
+------------+------------------+------+-----+---------+----------------+
| id         | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name       | varchar(50)      | YES  |     | NULL    |                |
| email      | varchar(255)     | NO   | UNI | NULL    |                |
| passwd     | varchar(255)     | YES  |     | NULL    |                |
| profile    | text             | YES  |     | NULL    |                |
| registed   | int(1)           | NO   |     | 0       |                |
| created    | datetime         | YES  |     | NULL    |                |
| modified   | datetime         | YES  |     | NULL    |                |
+------------+------------------+------+-----+---------+----------------+
8 rows in set (0.02 sec)

mysql> update users set registed=1;
mysql> select id, name, registed from users;
+----+-----------+----------+
| id | name      | registed |
+----+-----------+----------+
|  1 | kichon    |        1 |
+----+-----------+----------+
1 rows in set (0.00 sec)

新規登録機能実装

とりあえず解説は後にして、コードを晒します。


% vim controllers/users_controller.php
function signup() {

  $this->set("page_title", "fake twit");
  $this->set("content_header", "fake twit");
  $this->set("content_footer", "Copyright 2010 kichon fake twit, All Rights Reserved.");

  $err = Array();

  if (!empty($this->data)) {
    if (empty($this->data['User']['name'])) {
      $err['name'] = 'ユーザ名は必須です.';
    }
    if (empty($this->data['User']['email'])) {
      $err['email'] = 'メールアドレスは必須です.';
    }
    if (empty($this->data['User']['passwd'])) {
      $err['passwd'] = 'パスワードを記入してください.';
    }

    if (!$err) {
      if ($this->data['User']['passwd'] === $this->data['User']['passwdVerify']) {
        // ユーザ登録作業
        unset($this->data['User']['passwdVerify']);
        $this->data['User']['regist_key'] = sha1(uniqid(rand(), 1));  // 後ほど解説
        $this->data['User']['passwd'] = sha1($this->data['User']['passwd']);
        $this->User->save($this->data);
        $this->Session->write('myname', $this->data['User']['name']);
        $this->_sendNewUserMail($this->User->getLastInsertID());
      } else {
        $err['missmach'] = 'パスワードが異なっています.';
      }
    }
    $this->set('errors', $err);
  }

}

ポイントとしては一度データベースに登録してから、セッションを発行して、メール処理を行っている部分

先ほど作成したregistedカラムはデフォルトでは0になっているため、ここでは特に設定せず本登録用のURLをクリックしたときに1にアップデート処理を行う。

2.本登録用のURLを作成に関して

これまた処理を分解していくと

  1. ユーザ登録した時点で一意のIDを発行
  2. IDをURLの一部として作成し、メールに添付
  3. 本登録時に発行したIDとURLに存在しているIDが一致しているか確認
  4. 問題なければ本登録完了

という風にしたいため、本登録用のURLに関しては以下の要件でなければならない。
  • 一意のIDが付与されている
  • どのユーザがそのIDを発行されているかがわからなければならない

そのため次のようなURI体系にしました。

http://localhost/twit/users/confirm_email/[ユーザID]/[一意のID]

一意のIDに関して

こちらを参考に一意のIDを作成しました。
ハッシュ値はsha1でphpのuniqid関数を用いました。
またuniqie関数はマイクロ秒単位での一意性なので、引数にrand関数を用いることにより同じマイクロ秒単位でも異なるIDを発行させる。

コード

users_controller.phpは上記のものを参考にしてもらって、他のコードを晒します。

% vim controllers/app_controller.php
function _sendNewUserMail($id = null) {

  $user = $this->User->read('name', $id);
  $regist_key = $this->User->read('regist_key', $id);
  $this->Email->to = 'kichon@kichon.net';
  $this->Email->subject = 'Welcome to fake twit';
  $this->Email->replyTo = 'support@kichon.net';
  $this->Email->from = 'Fake Twit App <support @kichon.net>';
  $this->Email->template = 'simple_message';
  $this->Email->sendAs = 'both';
  $this->set('name', $user['User']);
  $this->set('id', $id);
  $this->set('regist_key', $regist_key['User']);
  $this->Email->send();

}



% vim views/elements/email/html/simple_message.ctp
<p>Dear <?php echo $name['name']; ?></p><br />
Thank you for interest.<br />

以下のアドレスをクリックすることにより、あなたのアカウントの登録確認が完了します。<br />
<a href="http://localhost/twit/users/confirm_email/<?php echo $id . DIRECTORY_SEPARATOR . $regist_key['regist_key']; ?>">http;//localhost/twit/users/confirm_email/<?php echo $id . DIRECTORY_SEPARATOR . $regist_key['regist_key']; ?></a>



% vim views/elements/email/text/simple_message.ctp
Dear <?php echo $name['name'] . "\n"; ?>
Thank you for interest.

以下のアドレスをクリックすることにより、あなたのアカウントの登録確認が完了します。
http://localhost/twit/users/confirm_email/<?php echo $id . DIRECTORY_SEPARATOR . $regist_key['regist_key']; ?>



% vim controllers/users_controller.php
function confirm_email($id = null, $key = null) {

  $this->set("page_title", "fake twit");
  $this->set("content_header", "fake twit");
  $this->set("content_footer", "Copyright 2010 kichon fake twit, All Rights Reserved.");

  if (!empty($id) && !empty($key)) {
    $this->set('id', $id);
    $this->set('key', $key);

    if ($user['User']['regist_key'] === $key) {
      $this->User->id = $id;
      $this->User->saveField('registed', 1);
      $this->redirect('mypage' . DS . $id);
    }
  }

  $this->set("err", "申し訳ありません。そのページは存在しません。");

}



% vim views/users/confirm_email.ctp
<?php if (!empty($err)): ?>
  <h1><?php echo $err; ?></h1>
<?php endif; ?>

データの更新に関して

confirm_emailアクションで、

$this->User->id = $id;
$this->User->saveField('registed', 1);

という処理の部分で、本登録完了ステータス変更へのデータ更新をしてます。

cakephpでのデータ挿入と更新に関しての詳細はここをみてもらえるとわかると思います。

単一のフィールドの値を更新する場合はsaveFieldメソッドを使用すればよく、

saveField(string $fieldName, string $fieldValue, $validate = false)

1つ目の引数は更新対象のフィールド名、2つ目の引数は更新する値、3つ目の引数でバリデーションの設定を変更できます。

また

saveField() を呼び出す前に、モデルの ID ($this->ModelName->id = $id)をセットする。

というのが大事みたい。

今回はこんな感じで。
次回はプロフィールページを作っていこうと思ってます!

CakePHPのお勉強(#018)

ユーザのホーム画面の変更を行いました。
具体的には以下。

ユーザホーム画面変更

  • ログイン後のURIにユーザIDを付与
  • 処理をTweetsコントローラからUsersコントローラに変更

ホーム画面をUserコントローラに変更するとそのままではユーザのツイートが表示されなくなる(使用するテーブルが変わる)ため、アソシエーションを使用してユーザIDからそのユーザのツイートを取ってくるように処理を変更させました。

ログイン後のURIにユーザIDを付与

cakephpではURIに変数をつけてあげるとコントローラ側からその変数を取得できるので(説明が全然わからないw)、処理自体はそんなに難しい物ではありませんでした。

URI処理に関して


通常は

http://localhost/プロジェクト名/コントローラ名/アクション名

でアクセスしますが、これを

http://localhost/プロジェクト名/コントローラ名/アクション名/変数

としても処理自体は変わらず、さらにアクション側からこの変数を取得することができる。

これができると、例えはログイン時にユーザIDを付与してユーザのホーム画面に飛ばすことができ、そのIDを使ってユーザの情報を取ってこれるため処理が楽になる。

$this->redirect('home')

としていたのを

$this->redirect('home/1')

とすることができるという意味。
アクション側では

function home($id = null) {
  // ホーム画面の処理
}

とすることでユーザ変数が取ってこれる。

処理をTweetsコントローラからUsersコントローラに変更

変更点としては以下になる

  • mypageアクションをTweetsコントローラからUsersコントローラに移動
  • ビューを/views/tweets以下から/views/users以下に移動
  • 各アクションのリダイレクト先を変更
  • ツイートの表示処理方法を変更

ツイートの表示処理方法を変更に関して

mypageアクションをTweetsからUsersに変更すると、DBへのアクセス方法が変わる

今までのままではUsersからtweetsテーブルへのアクセスはできないため、アソシエーションを使用する。


以下、コード

コントローラ

PHPでDIRECTORY_SEPARATORという定数がありますが、CakePHPではDSとして使えるのでそれを使いました。


% vim controllers/users_controller.php
function login() {

  $this->set("page_title", "fake twit");
  $this->set("content_header", "fake twit");
  $this->set("content_footer", "Copyright 2010 kichon fake twit, All Rights Reserved.");

  if (!empty($this->data)) {
    $someone = $this->User->findByEmail($this->data['User']['email']);
    if (!empty($someone) && $someone['User']['passwd'] == $this->data['User']['passwd']) {
      // ユーザIDの取得
      $id = $someone['User']['id'];
      $this->Session->write('myname', $someone['User']['name']);
      // リダイレクト時にユーザIDを付与
      $this->redirect('mypage' . DS . $id);
    } else {
      $this->set('err', 'ユーザ名かパスワードが間違っています。');
    }
  }

}

loginアクションから渡されたユーザIDを使用して$dataにそのユーザの情報を格納する。

% vim controllers/users_controller.php
function mypage($id = null) {

  $this->set("page_title", "fake twit");
  $this->set("content_header", "fake twit");
  $this->set("content_footer", "Copyright 2010 kichon fake twit, All Rights Reserved.");

  $this->_checkSession('myname');
  $data = $this->User->findById($id);
  $this->set('id', $id);
  $this->set('datas', $data);

}

モデル

Userモデルにアソシエーションの設定を行う


% vim models/user.php
<?php

class User extends AppModel {

  public $name = 'User';
  public $hasMany = 'Tweet';

}

ビュー

mypageのテンプレートをviews/tweets以下からviews/usersに移動し、ツイートの表示設定を変更する


% vim views/users/mypage.ctp
<div id="main-content">
  <div id="home-header">
    <div id="tweet-box-title">
      <h2>いまなにしてる?</h2>
    </div>
    <div id="tweet-box">
      <?php echo $form->create('Tweet', array('type' => 'post', 'action' => 'add')); ?>
      <?php echo $form->textarea('Tweet.tweet', array('cols' => 55, 'rows' => 2)); ?>
    </div>
    <div id="tweet-box-button">
      <?php echo $form->end('ツイート'); ?>
    </div>
    <div id="tweets-area">
      <?php if (!empty($datas)): ?>
        <?php foreach ($datas['Tweet'] as $data): ?>
          <p><?php echo $data['tweet']; ?>
        <?php endforeach; ?>
      <?php endif; ?>
    </p></div>
  </div>
</div>
<div id="dashboard">
  <div id="my-prof">
    <div id="my-photo">
      <?php echo $html->image('_sized/sml_kichon.png', array('alt' => 'my-photo')); ?>
    </div>
    <div id="my-name">
      <b>kichon</b>
    </div>
    <div id="my-comment">
      <p>はじめまして。kichonといいます。</p>
    </div>
    <div id="my-id">
      <?php if (!empty($id)): ?>
        <?php echo $id; ?>
      <?php endif; ?>
    </div>
    <div id="signout">
      <?php echo $form->create('User', array('type' => 'post', 'action' => 'logout')); ?>
      <?php echo $form->end('ログアウト'); ?>
    </div>
  </div>
</div>

アソシエーションの表示に関して

Userモデルにアソシエーションの設定をして表示を行うと以下のようになる。

Array
(
    [User] => Array
        (
            [id] => 1
            [name] => kichon
            [email] => kikuchi@gmail.com
            [passwd] => kichon
            [profile] =>
            [created] =>
            [modified] =>
        )

    [Tweet] => Array
        (
            [0] => Array
                (
                    [id] => 1
                    [user_id] => 1
                    [tweet] =>
                    [created] => 2010-11-15 23:15:22
                    [modified] => 2010-11-15 23:15:22
                )

            [1] => Array
                (
                    [id] => 2
                    [user_id] => 1
                    [tweet] => hogehoge
                    [created] => 2010-11-24 18:37:14
                    [modified] => 2010-11-24 18:37:14
                )

            [2] => Array
                (
                    [id] => 3
                    [user_id] => 1
                    [tweet] => hogehoge
                    [created] => 2010-11-26 16:17:25
                    [modified] => 2010-11-26 16:17:25
                )
        )
)

その為、mypageアクションとmypageビューを以下のように設定している。

mypageアクション


$data = $this->User->findById($id);
$this->set('id', $id);
$this->set('datas', $data);

mypageビュー


<?php if (!empty($datas)): ?>
  <?php foreach ($datas['Tweet'] as $data): ?>
    <p><?php echo $data['tweet']; ?>
  <?php endforeach; ?>
<?php endif; ?>

次回は新規登録の部分をもっと進めていこうかなと思います。

CakePHPのお勉強(#017)

では新規登録機能を実装していきます。
まず新規登録に関する流れを書きます。

新規登録に関する手順

1.新規登録ページにアクセス
2.名前、メールアドレス、パスワード、パスワード確認を記入し、新規登録ボタンを押す
3.必要項目が記入されていなければエラーを表示
4.パスワードとパスワード確認に入力した値が違っていればエラーを表示
5.チェックがOKであればメールを送信
6.メールにプロフィール変更ページへのリンクを張る
7.プロフィール情報記入
8.自分のホームページにリダイレクトして完了

メールにプロフィール変更ページのリンクを張って飛ばすところの認証?周りが
よくわかりませんが、気にせず行きます。

新規登録リンク作成

ログインページに新規登録に関するリンクを作成しました。

デザインはあとで調整するとしてとりあえずリンク作成ー。
20101127163640-1

次に新規登録ページを作成しました。

signup

メール処理作成

マニュアルを参考にサンプルをそのまま書いたらいけました。

注意する点としてはコンポーネントの設定を追加してあげなければならないということです。

メール送信処理

・app_controller.phpにメール送信メソッド(_sendNewUserMail)を作成
・users_controller.phpからメール送信メソッドを呼ぶ($this->_sendNewUserMail())
・メールの文面はビューのレイアウトとエレメントから作成する

以下、コードです。

コントローラ

データがなければ新規登録ページを表示

データがあればそれをチェックして、メール送信処理を行う


% vim controllers/users_controller.php
function signup() {

  $this->set("page_title", "fake twit");
  $this->set("content_header", "fake twit");
  $this->set("content_footer", "Copyright 2010 kichon fake twit, All Rights Reserved.");

  $err = Array();

  if (!empty($this->data)) {
    if (empty($this->data['User']['name'])) {
      $err['name'] = 'ユーザ名は必須です.';
    }
    if (empty($this->data['User']['email'])) {
      $err['email'] = 'メールアドレスは必須です.';
    }
    if (empty($this->data['User']['passwd'])) {
      $err['passwd'] = 'パスワードを記入してください.';
    }

    if (!$err) {
      if ($this->data['User']['passwd'] == $this->data['User']['passwdVerify']) {
        // ユーザ登録作業
        $this->_sendNewUserMail();
      } else {
        $err['missmach'] = 'パスワードが異なっています.';
      }
    }
    $this->set('errors', $err);
  }

}

メール送信処理


コンポーネントのところを書きたかったので全部のコードを書きました。

今回はユーザを固定にしていますが、後々ユーザIDを取ってきてユーザごとの処理に変更します。


% vim controllers/app_controller.php
<?php

class AppController extends Controller {

  public $components = array('Email', 'Session');

  function _checkSession() {

    if (!$this->Session->check('myname')) {
      $this->redirect('/users/login');
    }

  }

  function _sendNewUserMail($id = null) {

    //$User = $this->User->read(null, $id);
    $this->Email->to = 'kichon@kichon.net';
    $this->Email->subject = 'Welcome to fake twit';
    $this->Email->replyTo = 'support@kichon.net';
    $this->Email->from = 'Fake Twit App <support @kichon.net>';
    $this->Email->template = 'simple_message';
    $this->Email->sendAs = 'both';
    $this->set('User', 'kichon');
    $this->Email->send();

  }

}

ビュー


% vim views/users/signup.ctp
<div id='signup_form'>
  <?php echo $form->create('User', array('type' => 'post', 'action' => 'signup')); ?>
  <table class='signup_table'>
    <tr>
      <th>username</th>
      <td><?php echo $form->text('User.name', array('size' => 20)); ?></td>
    </tr>
    <tr>
      <th>email</th>
      <td><?php echo $form->text('User.email', array('size' => 20)); ?></td>
    </tr>
    <tr>
      <th>password</th>
      <td><?php echo $form->password('User.passwd', array('size' => 20, 'value' => '')); ?></td>
    </tr>
    <tr>
      <th>password again</th>
      <td><?php echo $form->password('User.passwdVerify', array('size' => 20, 'value' => '')); ?></td>
    </tr>
    <tr>
      <th></th>
      <td><?php echo $form->end('Create my account'); ?></td>
    </tr>
  </table>
</div>
<div id="print_data">
  <?php if (!empty($errors)): ?>
    <?php foreach($errors as $error): ?>
      <?php echo $error; ?><br />
    <?php endforeach; ?>
  <?php endif; ?>
  <?php if (!empty($data)): ?>
    <?php print_r($data); ?>
  <?php endif; ?>
</div>

メール本文

メールの本文はビュー内にtextメールとhtmlメールの両方を作成してあげる。


レイアウト



% vim views/layouts/email/text/default.ctp
<?php echo $content_for_layout; ?>



% vim views/layouts/email/html/default.ctp
< !DOCTYPE HTML PUVLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
  <body>
    <?php echo $content_for_layout; ?>
  </body>
</html>

エレメント



% vim views/elements/email/text/simple_message.ctp
Dear <?php echo $User; ?>
Thank you for interest.



% vim views/elements/email/html/simple_message.ctp
<p>Dear <?php echo $User; ?></p><br />
Thank you for interest.

メールの送信完了画面は今度あげます。
(イーモバイルからだとOP25Bの影響でメールが送れないので。。)

またプロフィール変更などはまた今度書いていきます。

Home > Tags > CakePHP

Search
Feeds
Meta

Return to page top