2009年3月31日火曜日

CakePHP でドメインの異なるサイトでセッションを共有する

2009年3月31日火曜日 0

これは簡単なティップですが、ドキュメントとしてここに記しておきます。ドメインの異なる CakePHP サイトでセッションを共有する方法を紹介します。

2つのドメインの異なるサイト siteA.com と siteB.com があるとします。siteA.com にいるログイン認証済みのユーザがあるリンクをクリックして siteB.com へ移動するとき、セッション情報を保持したままリダイレクトするようにします。

まず、設定する項目がいくつかあります。

  • siteB.com のコアファイル (/app/config/core.php) の 'Security.level' を 'low' に設定します。 'high' and 'medium' に設定すると、埋め込まれたセッションID は無効だと判断されます。
  • セッション・ハンドリング・メソッド(app/config/core.php 内の 'Session.save') を 'php' か 'database' にします。siteA.com と siteB.com のセッション・ハンドリング・メソッド (Session.save) を同じにする必要があります。2つのサイトが同じセッションストーレッジを使用してセッションを共有するようにします。
  • 両サイトとも同じ Security.salt (/app/config/core.php) を使用します。
siteA.com のビューで、次のようにセッションIDをリンクに埋め込みます。
echo $html->link('Go to siteB.com',
 "http://siteB.com/tests/index?sid=" . $session->id()
);
受け手側の siteB.com の任意のコントローラ、beforeFilter メソッド内で, $this->Session->id($this->params['url']['sid']) を使います。
function beforeFilter() {
  if (!empty($this->params['url']['sid'])) {
    $this->Session->id($this->params['url']['sid']);
  }
}
ユーザが siteA.com のリンクをクリックすると、siteB.com へリダイレクトして、パラメータとして渡されたセッションIDから新しいセッションIDを生成します。

2009年3月16日月曜日

AppController::beforeRender を活用して CakePHP のコントローラ属性をアサインする

2009年3月16日月曜日 0
これは好みの問題かもしれませんが、Kyo は、 ビューに渡すためのコントローラ属性を、CakePHP のコントローラー内でその都度セットするのが苦痛に感じます。なので、こんな方法をいつもとっています。 Add a $this->set into the AppController::beforeRender to always read $this->data.
class AppController extends Controller {
  function beforeRender() {
    if (!isset($this->viewVars['data'])) {
      $this->set('data', $this->data);
    }
  }
}
コントローラ(app controller を継承したコントローラ)で、 もう $this->data をセットする必要はありません。
class PostsController extends AppController {
  function index() {
    $this->data = $this->paginate();
  }
}
同様に次のようにもできます。
function beforeRender() {
  if (!isset($this->viewVars['data'])) {
    $this->set('data', $this->data);
  }
  if (!isset($this->viewVars['modelClass'])) {
    $this->set('modelClass', $this->modelClass);
  }
}
これで、どのビューからでも $data と $modelClass という変数でアクセスできるようになりました。
<? if($data): ?>
<? pr($data)?>
<? endif; ?>

<? if($modelClass): ?>
<? pr($modelClass)?>
<? endif; ?>

2009年3月10日火曜日

CakePHP 1.2 で自己参照HABTMアソシエーション (Self-Referential HABTM Relationships) をページングする

2009年3月10日火曜日 0
Cakebaker (Daniel Hofstetter) が以前書いた記事の中に、"Pagination of data from a HABTM relationship" という素晴らしい記事があります。この記事は 、HABTMアソシエーションのデータを CakePHP 1.2 を使ってどのようにページングするのかについて書かれたものです。 Daniel に触発されて、Kyo は自己参照HABTMアソシエーション (Self-Referential HABTM Relationships) をページングする方法を紹介します。 この方法は CakePHP 1.2.1.8004 でテストしましたが、それより古いバージョンでは動作しないかもしれません。 まず、 User model を用意しましょう。ある User に対して Friends をページングします。テーブル定義は次のようになります。
create table users (
  id int(11) not null auto_increment,
  username varchar(32) not null,
  primary key (id)
);

create table users_friends (
  id int(11) not null auto_increment,
  user_id int(11) not null,
  friend_id int(11) not null,
  primary key (id)
);
作成したテーブルにテストデータをインサートしましょう。
insert into users (id, username) values (1, 'kevin');
insert into users (id, username) values (2, 'stephanie');
insert into users (id, username) values (3, 'michael');
insert into users (id, username) values (4, 'jennifer');

insert into users_friends (user_id, friend_id) values (1, 2);
insert into users_friends (user_id, friend_id) values (1, 3);

insert into users_friends (user_id, friend_id) values (2, 1);
insert into users_friends (user_id, friend_id) values (2, 4);

insert into users_friends (user_id, friend_id) values (3, 1);
insert into users_friends (user_id, friend_id) values (3, 4);

insert into users_friends (user_id, friend_id) values (4, 2);
insert into users_friends (user_id, friend_id) values (4, 3);
自己参照HABTMアソシエーションを User model で設定します。
class User extends AppModel {
  var $name = 'User';
  var $hasAndBelongsToMany = array(
    'Friend' => array(
      'className' => 'User',
      'joinTable' => 'users_friends',
      'foreignKey' => 'user_id',
      'associationForeignKey' => 'friend_id',
      'unique' => true,
    )
  );
}
ユーザ “kevin” の ID から、その友達をページングします。Nate のチュートリアル "Quick Tip - Doing Ad-hoc Joins in Model::find()" を参考に、コントローラを作成します。
// app/controllers/friends_controller.php
class FriendsController extends AppController {
  function index() {
    $this->paginate = array(
      'Friend' => array(
        'limit' => 2,
        'joins' => array(
          array(
            'table' => 'users_friends',
            'alias' => 'UsersFriend',
            'type' => 'inner',
            'conditions'=> array(
              'UsersFriend.friend_id = Friend.id',
            ),
          ),
          array(
            'table' => 'users',
            'alias' => 'User',
            'type' => 'inner',
            'conditions'=> array(
              'User.id = UsersFriend.user_id',
              'User.id' => 1
            )
          )
        )
      )
    );
    $data = $this->paginate('Friend');
    debug($data);
    exit;
  }
}
デバッグアウトプットは以下の通りです。
Array
(
[0] => Array
   (
       [Friend] => Array
           (
               [id] => 2
               [username] => stephanie
               [0] => Array
                   (
                       [id] => 1
                       [username] => kevin
                       [UsersFriend] => Array
                           (
                               [id] => 3
                               [user_id] => 2
                               [friend_id] => 1
                           )
                   )
               [1] => Array
                   (
                       [id] => 4
                       [username] => jennifer
                       [UsersFriend] => Array
                           (
                               [id] => 4
                               [user_id] => 2
                               [friend_id] => 4
                           )
                   )
           )
   )
[1] => Array
   (
       [Friend] => Array
           (
               [id] => 3
               [username] => michael
               [0] => Array
                   (
                       [id] => 1
                       [username] => kevin
                       [UsersFriend] => Array
                           (
                               [id] => 5
                               [user_id] => 3
                               [friend_id] => 1
                           )
                   )
               [1] => Array
                   (
                       [id] => 4
                       [username] => jennifer
                       [UsersFriend] => Array
                           (
                               [id] => 6
                               [user_id] => 3
                               [friend_id] => 4
                           )
                   )
           )
   )
)

2009年3月7日土曜日

このブログについて

2009年3月7日土曜日 0
ウェブディベロッパー Kyo のブログ "JamNite" の日本語版ブログです。CakePHP の話題を中心に掲載していきます。基本的に、本家ブログと平行して更新いていく予定ですが、たまに内容が変わるかもしれません。最新記事は "JamNite" をご覧ください。
 
JamNite Japan ◄Design by Pocket, BlogBulk Blogger Templates