hetemlにgitの俺専用リポジトリを作る

hetemlで、sshとgitが使えるのでやってみました。
作ってpushするとこまでです。
※案外すんなりいったし、これからよく使うと思うのでメモ。

●その0:《はじめに》
リモートリポジトリのパスを $HOME/git/example と仮定します。

●その1:heteml側でやること

$ mkdir git
$ mkdir git/example
$ cd git/example
$ git init --bare

●その2:ローカルでやること

$ cd example
$ git init
$ git add .
$ git commit -a
$ git remote add origin ssh://《自分のユーザー名》@《自分のサーバ名》:《sshポート番号》/(home directory)/git/example/
$ git push orign master

home directory んとこは home/sites/heteml/users???/(中略)/ユーザー名 が入ります。
要はポート番号打ったあとから、リモートリポジトリでpwdした結果をコピペすればいいです。

うまくいったら、git push origin masterでこう出ます

$ git push origin master
-----------------------------------------------------
--***-------------------------------------------***--
--***---------------***-------------------------***--
--***---------------******----------------------***--
--********-********-******-********-***********-***--
--********-***--***-***----***--***-***********-***--
--***--***-********-***----********-***-***-***-***--
--***--***-***------******-***------***-***-***-***--
--***--***-********-******-********-***-***-***-***--
-----------------------------------------------------


username@ssh***.heteml.jp's password:
Counting objects: 90, done.
Compressing objects: 100% (75/75), done.
Writing objects: 100% (90/90), 35.99 KiB, done.
Total 90 (delta 14), reused 0 (delta 0)
To ssh://username@ssh***.heteml.jp:****/(home directory)/git/example
 * [new branch]      master -> master
$

こんなの出て失敗したら、多分git pushの書き方を間違えている。

No refs in common and none specified; doing nothing.
Perhaps you should specify a branch such as 'master'.
fatal: The remote end hung up unexpectedly

あとはgit pushしたりpullしたり、です。

なお、git remote addでリモート等の指定を間違えたときは、いったん git remote rm して再度 git remote add すればOK。

 
参考にした:
「ハッカー」って言葉の響きが好きです。:Git: pull/pushの設定

iPadのUser-Agent

メモ。

Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; ja-jp) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10

CakePHPでレコード直読み

CakePHPのmodelでは、データベースから読み込んだものをいったん配列に「全部」入れています。
これだと、諸事情でものすごい量のデータを読み込むけど配列には入れたくないケース(集計等)では、確実にメモリ不足でこけます。

だから、直接レコードを読み取れないかなー、ということで。
わかりやすく言うと、フレームワーク使わずにMySQL等を直接さわる関数(mysql_query,mysql_fetch_array)を使う気分で使いたいときです。
そんなわけで、調べてました。

・・・ちょっと大変なことをする必要があります。割とハイレベル。
データソースの rawQuery , fetchRow を呼ぶ必要があります。
こんなかんじです。

class Hoge extends AppModel {
    var $name  = "Hoge" ;
    var $useTable = "table_hoge" ; 

    private $dbob ;
    private $sqlrsrc ;  
  
    function __construct() {
        parent::__construct() ;
        $this->dbob = &ConnectionManager::getDataSource($this->useDbConfig);
    }

    function executeQuery( $arg_query ) {
        $this->sqlrsrc = $this->dbob->rawQuery( $arg_query ) ;
        return $this->sqlrsrc ;
    }

    function fetchRow2( $arg_arg = null ) {
        $this->dbob->results = $this->mysqlrsrc ;
        $__result = $this->dbob->fetchRow() ; 
        return $__result ;
    }

}

※注:private の宣言は意味ないです(笑) ぶっちゃけ var でいいですが、自分の好みでこうやってます。

executeQuery でクエリ実行、fetchRow2 でレコード1つ取得、です。
fetchRow2 で戻ってくるのは、CakePHPのモデルで戻ってくるのと同じ様式の配列です。
ですから、以前

$__rows = $this->Hoge->query( $__query ) ; // とりあえず全部読み
foreach( $__rows as $__r ) {
//以下略

と書いていたのを、

$__rows = $this->Hoge->executeQuery( $__query ) ; // とりあえず全部読み
while( $__r = $this->Hoge->fetchRow2() ) {
//以下略

と2行書き換えるだけでそのまま動きます。

ちなみにこのへんについて知りたければ、
CORE/cake/libs/model/model.php
CORE/cake/libs/model/datasources/datasource.php
CORE/cake/libs/model/datasources/dbo_source.php
CORE/cake/libs/model/datasources/dbo/dbp_mysql.php
あたりを読めばいいんじゃないかなと。

symfonyの初歩の初歩(参考サイトまとめ)

もはや、個人的メモ。
OpenPNE3に繋げるためにも避けられないしー。

気づいたら&気が向いたら、少しづつ増やすかも。

○ポータル系
symfonyの日本語情報サイト

○今日のtwitterから。symfonyのガイドとか。

●2010-05-08 18:18:32 by YoruFukurou
メモ > The Definitive Guide to symfonyの翻訳: http://symfony.xrea.jp/ ←ちょっと離れてたら忘れてたw さっきからこれ探してた。
RT @hidenorigoto: http://symfony.sarabande.jp/ こちらもどうぞ RT @sayama_yuki: メモ > The Definitive Guide to symfonyの翻訳: http://symfony.xrea.jp/

○Doctorine
「Propel使って良いのは小g(ry …」とかいう雰囲気ぽいのと(←ぇ?)、いま一つ理解しきれてないので。

hetemlでPHP OpenID Libraryを使うときの注意事項(mixi.jpの場合)

というか、hetemlでOpenIDでmixiを使うときにdiscoverに失敗するって例なんだけどね。
CakePHPのexamplesにある「discover.php」を使っても「discoverに失敗したお」エラーが出るので確認はできると思います。
2010050202

なお、今回はこの場合が該当します。

※Symfonyに関しては同等のライブラリ提供は無さげなので今回は割愛です。
なお、symfonyでOpenIDを実装してみた | ueblogで実装されているようです。

まあ、ぶっちゃけ解決策は「証明書インストールしる!」ってことです。
○mixiでログインできない件
きさら’s – 利用報告(heteml)
○証明書インストールの方法(root権限がない場合)
mixi OpenIDのサンプルコードをPHP OpenID Libraryを使って動かしてみた(訂正) – 大阪 本町で働くソーシャルアプリ開発者 ダイアリー

Auth_Yadis_ParanoidHTTPFetcher#get関数と、Auth_Yadis_ParanoidHTTPFetcher#post関数でcurl_exec関数を実行する直前の、132行目と196行目に下記のコードを追記

このへんを参照しました。
(1)まず、https://mixi.jp/ にアクセスして、証明書を保存する。
(2)保存した証明書をサーバへUPする。
(3)Yadisのソースで、cURLでアクセスしてる部分でcURLオプション(CURLOPT_CAINFO) を変更する。
ソース変更点は、こういうかんじになります。

--- old/Auth/Yadis/ParanoidHTTPFetcher.php	2009-04-21 11:31:20.000000000 +0900
+++ new/Auth/Yadis/ParanoidHTTPFetcher.php	2010-05-02 16:14:15.000000000 +0900
@@ -128,6 +128,12 @@
             curl_setopt($c, CURLOPT_TIMEOUT, $off);
             curl_setopt($c, CURLOPT_URL, $url);
 
+            if ( $this->isHTTPS( $url )  && mb_ereg( "mixi\.jp" , $url ) ) {
+                curl_setopt( 
+                        $c , 
+                        CURLOPT_CAINFO ,
+                        '/home/sites/heteml/users***/*/*/*/*/ssl/mixi.jp.crt' ) ;
+            }
             curl_exec($c);
 
             $code = curl_getinfo($c, CURLINFO_HTTP_CODE);
@@ -191,6 +197,12 @@
         curl_setopt($c, CURLOPT_URL, $url);
         curl_setopt($c, CURLOPT_WRITEFUNCTION,
                     array(&$this, "_writeData"));
+            if ( $this->isHTTPS( $url )  && mb_ereg( "mixi\.jp" , $url ) ) {
+                curl_setopt( 
+                        $c , 
+                        CURLOPT_CAINFO ,
+                        '/home/sites/heteml/users***/*/*/*/*/*/ssl/mixi.jp.crt' ) ;
+            }
 
         curl_exec($c);

これで、さっくり動きました。
あ、/home/sites〜に関しては各自のホームディレクトリと証明書のある場所を指定してください。

なお、証明書に関する件はFAQにも述べられています

※追記
mixi.jp 以外の場合に挙動がおかしくなるのでなおしました。
証明書が「ない」OP毎にこの処理を追加してあげる必要があります。

hetemlでCakePHPを使うときの.htaccess設定注意事項

さきほどはまってしまったので、忘れないためにもメモ。

インストールは普通にやってOK。特にはまった記憶は無いです。
私の場合、webディレクトリと(CakePHPの)appディレクトリをわけています。
このへんに関しては省略。

それはさておき。
.htaccessが通常の設定のやりかたと違うので、忘れないためにメモ。
ちなみに、RewriteBaseの設定です。

(1)http://*.heteml.jp/hoge/ でアクセスするときは、RewriteBaseの設定は不要
(2)http://example.com/ (独自ドメイン)でアクセスするときは、RewriteBaseの設定が必要

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteBase    /
    RewriteRule    ^$    webroot/    [L]
    RewriteRule    (.*) webroot/$1    [L]
</IfModule>

※省略しましたが webroot/.htaccess にも同様に RewriteBase を追加してあげてください。

つまり、Apacheのデフォルト設定でやった時と完全に逆です。

ちなみに。
RewriteBaseを設定するということは、アクセス方法は(1)か(2)のどちらかしか選べません、ということです。
(2)の設定で(1)にアクセスされる心配は(たぶん)ありません。

・・・というか。
確実なのは、どっちにせよ「RewriteBaseでちゃんと明示しとけ」ってことですねw

Yahoo!JAPANのOpenIDが急に動かなくなった人へ

PerlでNet::OpenID::Consumer を使ってOpenIDの認証をしてるケースです。

つい先日あたりから(判明したのは今日)、

naive_verify_failed_return

を返してエラーになってしまいます。

なんでか、って延々と調べてたら・・・わかりました。
Need help deciphering this LiveJournal OpenID error

It comes from this line:

        return $self->_fail("naive_verify_failed_return") unless $args{'lifetime'};

So it did a dumb-mode (stateless) check_authentication request to your
server, but wasn’t able to find a “lifetime:\n” row where was
non-zero.

lifetimeがかえってないよー(または返すモードになってないよー)、ってかんじです。
Consumer.pmを再度確認。該当の記述はこちら。

        return $self->_fail("naive_verify_failed_return") unless
            $args{'is_valid'} eq "true" ||  # protocol 1.1
            $args{'lifetime'} > 0;          # DEPRECATED protocol 1.0

はい・・・そういうことです。

早い話が、ローカルに認証用のキャッシュ持たせないとだめっす。
というわけで、オブジェクト作ってるところでキャッシュを作るようにすればOK。

use CGI;
use LWP::UserAgent;
use Net::OpenID::Consumer;
use Cache::File ;

my $csr = Net::OpenID::Consumer->new(
  ua => LWP::UserAgent->new,
  cache => Cache::File->new( cache_root=>'/tmp/opicache',
                             default_expires=>'6000sec'      ) ,
  args => $query,
  consumer_secret => "hogehogehoge" ,
  required_root => "https://example.com/" ,
  minimum_version => 2.0
  );

参考:ソースから読むOpenID (1) – Yet Another Hackadelicなど

sysinfo関数でシステム情報取得。

Linuxのはなし。
とりあえずサンプル見てだだだーって書いてみました的。

#include <stdio.h>
#include <sys/sysinfo.h>

/* getla : Load Average を取得。値はuptimeで出る値の100倍。 */
unsigned long getla( long int * la01 , long int * la05 ) {
        struct  sysinfo         s_info          ;
        int                     rerror          ;
        unsigned long           la15            ;
        unsigned long           lashift         ;

        /* SI_LOAD_SHIFT のビット分が小数点以下の部分。 */
        lashift = ( 1 << SI_LOAD_SHIFT ) / 100 ;

        rerror = sysinfo( &s_info ) ;

        /* [0]=1min,[1]=5min,[2]=15min  */
        if ( la01 != NULL ) {
                *la01 = s_info.loads[0] / lashift ;
                *la05 = s_info.loads[1] / lashift ;
        }
        la15 = s_info.loads[2]  /lashift ;
        return la15 ;
}

main() {
        unsigned long la01 , la05 , la15 ;
        la15 = getla( &la01 , &la05 ) ;
        printf( "LoadAverage %lu / %lu / %lu\n" , la01 , la05 , la15 ) ;
}

sysinfo構造体のloadsで戻ってきた値を読んでもわからん数字だった。
どうやら、2のSI_LOAD_SHIFT乗の数字で割らないと正しい数字は得られないようだ。
ちなみに私んとこではこうなってた。
linux/kernel.h:

#define SI_LOAD_SHIFT    16

上記例の関数の引数があからさまにおかしいのは、テスト用にあとからla01とla05を追加した結果です(爆)本当にやりたいところでは、la15とれれば十分だったので・・・(^^;

参考:
man 2 sysinfo
sysinfo – システムコールの説明 – Linux コマンド集 一覧表
Linux の sysinfo での load average – spiritlooseのはてなダイアリー

Apache2 on Debian – あなたの予想に反してIt Works!

最近、いろいろあってDebianさわってます。
自宅のサーバ(2台目)もDebianです。
個人的には、FreeBSD触ってたらあまりストレスなく使えるかんじ。

さて。
DebianでApache2の設定をしようとしたら、いっぱいconfigファイルがあるので、混乱したわけですよ。
・・・ええ、いままで、httpd.conf (またはapache2.conf) に全部書いてたんで(笑)
このへんの解説を読んで再度勉強。

設定ファイルは、/etc/apache2/ 以下にあります。
そして、その中でよく弄るのが、 sites-available , mods-available のフォルダ内のファイル。
前者はVirtualHostの設定、後者はApacheモジュールの設定に関わります。

sites-available に (site-name) のファイル名で VirtualHostの設定を書いておけば、

# a2ensite (site-name)

これで sites-enabled フォルダにシンボリックリンクが生成され、有効になります。
モジュール設定も同様です。(a2enmod)

向こうにしたい場合は enをdisにすればOK。

※VirtualHost、moduleに関しての説明はばっさり割愛。
各自ぐぐってみてくだされ。

おまけ・・・というか、本当に余談。
モジュールというと、個人的にはここはチェックしておきたい。(個人的メモだけどw)
Apache 2.2でWebサイトをパフォーマンスアップ!(1/3) - @IT

rsyncで同期 on さくら

いい加減面倒になってきたのでrsync使うことにした。
プロジェクトごとにup/down用のshell scriptを書いて。

rsyncの基本は、

rsync オプション 転送元パス 転送先パス

です。
ssh使って転送したい場合は、オプションに-e "ssh -l *user* "を指定すればOK。
また、それぞれのオプションは、man rsyncしてもられえばわかると思う。
ちなみに、tがタイムスタンプ保持、rが再帰的(recursive)、zが圧縮、vがverbose mode。

さくらのサーバから自分のローカルマシンへ。

#!/bin/sh
rsync -t -r -z -v \
	-e "ssh -l *user* " \
	*user*@[user].sakura.ne.jp:*path/to/remote* \
	*path/to/local*

逆に自分のマシンからの場合。

#!/bin/sh
rsync -t -r -z -v \
	-e "ssh -l *user* " \
	--exclude '*~' \
	*path/to/local* \
	*user*@[user].sakura.ne.jp:*path/to/remote*

exclude に指定してあるのは、Emacsのバックアップファイルを除外するためですw

*path/to/remote* と *path/to/local* を書くときの注意。

  • *path/to/remote* に /home/user/www/hoge と書いて
  • *path/to/local* に /home/user/wwwwork/hoge/ と書いた
  • この場合、/home/user/wwwwork/hoge/hoge/ 以下に展開される
  • とりあえず、

    • ディレクトリ名ごと全部なら / をつけない
    • ディレクトリの下から全部なら / をつける

    ・・・ということです。

『docomo ID認証が怪しげすぎる件』が怪しすぎる件

なんというか、あきれる記事がまことしやかに信じられてて、げんなりなんだけど。
docomo ID認証が怪しげすぎる件 | [ bROOM.LOG ! ]
はてなブックマーク – docomo ID認証が怪しげすぎる件 | [ bROOM.LOG ! ]
本気でケータイサイト作ったことのある人間が読めば「ばっかじゃねーの」的レベルの記事です。
ところがブコメを見るとあまりに鵜呑みにしてるところが多いので、ちょいと軽くツッコミを入れておきます。

そのまえに、まずそれぞれの用語・機能について説明しないといけませんね。

●iモードID
端末(というよりは1契約単位)に与えられた固有のコード。
英数7文字、大文字/小文字の区別はあり。
ユーザ設定によって非通知にも設定可能(これはdocomo IDでの通知にも反映されます(後述))
なお、SSL通信では利用できません。
iモードIDについて(NTTドコモ)に説明があります。
英数7文字、大文字小文字区別ありということは、(10+26+26)^7通り、つまり3.52×10^12、unsignedで42bitで表せる情報(4.40×10^12)です。

●docomo ID
NTTドコモによるOpenID。OpenIDではOPに相当する。携帯電話との連携のために独自仕様が存在する。
なお、OP-local identifierはRP(OpenIDを利用する側)ごとに異なり、他のRPとの共用は出来ない。(仕様書3.7.2の(2)など)
docomo IDについて | NTTドコモ

●docomo ID の独自仕様
携帯電話との連携のために追加された独自仕様。
「ユーザ属性情報通知」(仕様書の3.8)、「ケータイ送信」(仕様書の4)の2つがある。
前者は、認証されたユーザのユーザーエージェント(User-Agentヘッダで送出される内容)とiモードIDを取得できる機能、後者は認証されたユーザに対して誘導先URLを(ユーザのメールアドレスを取得することなく)送信する機能。
正直、前者に関しては「これならSREGとか使えよ!」と思った程度にひどい(訂正)SREGだと「だだ漏れ」になっちゃうからマズいですよね。一応、OP-local identifierとresponse_nonceの両方が必要でなおかつ有効期限が設定されている(短い)ため、第三者から乗っ取りアクセスはほぼ不可能。
ケータイ送信は、OpenIDの機能を使ってない。docomo IDのサイトでログインセッションが有効なときのみ使用可能で、docomo IDのサイトでユーザーに対して「送信確認」を行わないと使用できない。

それでは、説明が終わったので、本題。

まずは私自身の持論。
iモードIDですが、そもそもこれをID+パスワードの代替として使うものではない、ってことです。だからこれを「かんたんログイン」として使うには危険ってこと。
「guid=ON」さえつければ取得できる情報なので、IPアドレスと同程度の情報、と考えてます。
ちなみに、iモードID送出をオフにした(iメニューから辿って設定できます)場合、docomo IDで取得しようとした場合、このようになります。
1つ前の記事で書いたサンプルを利用しました。)
2010031021
GUIDに「9999999」など、本来と違う値がかえってきます。

まず、そもそもの「iモードID抜き放題」の話。
42bitくらいの情報だったら、ブルートフォースアタックしちゃえばいいじゃん!
IPアドレス制限してないとこだったら、(げふんげふん(自主規制))
まぁ、docomo ID使って取得じゃ!とかそんなセコいことしなくても得られるしー。

そして。
「危ない」という事例で示してる例は、よく読むといづれも「docomo ID」とは直接関係しない事例。
つまり、アクセス元のIPアドレスをチェックしてない(つまり、本当にケータイかどうかをチェックしてない)サイトに対して、突破攻撃できちゃうよん、ってこと。
それ、全然iモードIDともdocomo IDとも関係ないじゃん。
iモードIDの取得?docomo IDなんか使わないで、ケータイ向け勝手サイト作ってケータイで直接アクセスさせたほうがよっぽど効率的に取得できますよー。うふふ。

さらに大きな間違いが1つ。

docomoからすれば、これだけ世に広まっているケータイ認証や決済をPCの世界にも広めたい意図なのだというのは容易に想像できる。

「オフィシャルの」決済系はケータイからじゃないと行えないです。
単刀直入に言うと、決済処理に入るには、iモードIDだけではなにもできません。
いったん、決済の確認ページに飛ばされて、暗証番号を要求されます。

なんというか。
docomo IDのシステム「だけ」を責めるのは根本的に間違ってるよ、ってことが言いたかったんです。

docomo ID の独自APIにアクセスする(1)

前回の続きです。
例によって?PHP OpenID Libraryのexampleを改造。

今回は、独自APIの1つ「ユーザ属性情報通知」(3.8)、これはiモードID(guid=ONにしたときにDCMGUIDヘッダで取得できる個体識別文字列)をとってくるAPIです。
なお、iモードIDに関しては以前書いたのでそちらを参照してください。

割と手抜きのコードですが、差分はだいたいこんなかんじ。

--- ../../../w/php-openid-2.1.3/examples/consumer/finish_auth.php       2009-04-22 03:31:20.000000000 +0900
+++ ./finish_auth.php   2010-03-10 18:29:39.000000000 +0900
@@ -38,6 +38,26 @@
             $success .= '  (XRI CanonicalID: '.$escaped_canonicalID.') ';
         }

+       // var_dump ($response->message->getArg('http://specs.openid.net/auth/2.0','response_nonce') ) ;
+       // var_dump ( $response->message ) ;
+       $response_nonce = $response->message->getArg('http://specs.openid.net/auth/2.0','response_nonce') ;
+
+       // call docomo original API
+       $success .= "<br />response_nonce:" . $response_nonce . "<br /><br />\n" ;
+       $apicall_url  = "https://i.mydocomo.com/api/imode/g-info?" ;
+       $apicall_url .= "ver=1.0&openid=" . urlencode( $openid ) ;
+       $apicall_url .= "&nonce=" . urlencode( $response_nonce ) ;
+       $apicall_url .= "&GUID=&UA=" ;
+       $cu = curl_init() ;
+       curl_setopt( $cu , CURLOPT_URL            , $apicall_url ) ;
+       curl_setopt( $cu , CURLOPT_RETURNTRANSFER , TRUE ) ;
+       $httpresult = curl_exec( $cu ) ;
+       $aline = explode( "\n" , $httpresult ) ;
+       $success .= "API RESULT:<br />\n" ;
+       foreach( $aline as $a ) {
+               $success .= $a . "<br />\n" ;
+       }
+
         $sreg_resp = Auth_OpenID_SRegResponse::fromSuccessResponse($response);

         $sreg = $sreg_resp->contents();

実行するとこんなかんじになります。
2010031011

追記:docomo IDの実装をはじめ、なぜiモードID等の取得のみこのようなことをしてるかについて興味深い考察をしてるサイトがありましたので紹介。
docomoのOpenIDの実装周りについて – 金利0無利息キャッシング – キャッシングできます – subtech

PHP OpenID Library で RP Discovery要求対応の例

具体的に言うとdocomo IDのことなんですが(笑)
とりあえずわかったことなんでメモ。

OpenIDそのに関しては前書いたメモがあるんでそっち参照。
で、今回の件。docomo IDの場合、RP Discoveryするんで、TrustRoot のaddressに、Accept: application/xrds+xmlで要求かけてるんですよね。
だから、index.php で、Acceptを判定して、XRDSドキュメントを返してあげればOKです。

PHP OpenID Libraryのexampleだと、追加するコードはこうなります。

--- ../../../w/php-openid-2.1.3/examples/consumer/index.php	2009-04-22 03:31:20.000000000 +0900
+++ ./index.php	2010-03-10 10:10:52.000000000 +0900
@@ -2,6 +2,17 @@
 require_once "common.php";
 
 global $pape_policy_uris;
+
+if ( $_SERVER['HTTP_ACCEPT'] == "application/xrds+xml" ) {
+	// returns XRDS
+	header ( "Content-type: application/xrds+xml" ) ;
+	$fh = fopen( "yadis.xrdf" , "r" ) ;
+	while( !feof( $fh ) ) {
+	 	print fgets( $fh ) ;
+	}
+	fclose( $fh ) ;
+	exit() ;
+}
 ?>
 <html>
   <head><title>PHP OpenID Authentication Example</title></head>

そして、読み込んでるyadis.xrdfはこう。

<?xml version="1.0" encoding="UTF-8"?>
<xrds:XRDS xmlns:xrds="xri://$xrds" xmlns:openid="http://openid.net/xmlns/1.0" xmlns="xri://$xrd*($v*2.0)">
<XRD>
<Service priority="0">
<Type>http://specs.openid.net/auth/2.0/return_to</Type>
<URI>http://example.ne.jp:80/php-openid-2.1.3/examples/consumer/finish_auth.php</URI>
</Service>
</XRD>
</xrds:XRDS>

URIには、戻り先のURIを書いてねー。

もうちょっと、まともな書き方(XRDSを返す関数での書き方)があると思いますが、それはあとで調べて書くつもり。

なお、この件は、「docomo ID 認証 インターフェース仕様書」の「3.7.2 OP実装仕様」の表3.2にありるように、

RP Discoveryに失敗した場合、RPにはエラーは返却せず、エラー画面を返却し終了します。

と、なってます。だからいきなりこんな画面が出ます。
2010031001
無事成功するとこうなります。
2010031002
docomo ID 固有の実装・機能に関しては、のちほど書きたいと思います。

参考:RP Discovery対策 – Web Life!!! – Yahoo!ブログ

OpenPNE3プラグイン開発勉強会、の復習

手嶋屋さん主催のOpenPNE3プラグイン開発勉強会に行ってきました。
勉強会というよりは自習会+サポートというかんじでの進め方でした。
OpenPNE3.4プラグイン開発チュートリアルを教材に、ひたすらコードを書く!(笑)というかんじでした。

ちなみに私ですが、今日はパート8まで進めました。

進めていく上で、Symfonyをちゃんと理解してない部分も多々あったので、進めながら参照したところを(復習がてら)貼っておきます。

実は今回、本気でSymfonyを触ったわけだったりします。
仕事でCakePHPを使ってましたが、流儀の違いさえ飲み込めれば(それが一番難しいんでしょうがw)理解ははやいかなと思います。

※追記
OpenPNEプラグインの作り方は下記も参照
OpenPNE3プラグインの作り方#6|OpenPNE(バックナンバーもここから)

※追記2
今日の参加者それぞれの進捗状況が公開されました。
OpenPNE3プラグイン開発勉強会終了|SNS構築の手嶋屋

WordPressのテーマを弄ってみる

1から作ってみるのもいいですが、ちょっと難しいかなということで、「WordPress Classic」のテーマを少しづつ弄りながら覚えてみることにしました。
「WordPress Default」は結構複雑なので、とっかかるには敷居高いなぁ、ということで。

ファイルの構成はこんなかんじです。

  • テンプレート
    • ヘッダー (header.php)
    • メインインデックスのテンプレート (index.php)
    • ポップアップコメント (comments-popup.php)
    • コメント (comments.php)
    • サイドバー (sidebar.php)
    • フッター (footer.php)
    • テーマのための関数 (functions.php)
  • スタイル
    • スタイルシート (style.css)
    • RTL スタイルシート (rtl.css)

HTML上での要素構成とそれぞれを主に定義しているファイルとの対応は下記の図の通りです。
2010022501
ポップアップコメントとコメントは、メインインデックスの中で使用しています。
また、テーマのための関数は、右のサイドバーを作成するときに呼ばれます。

CSSだけを変えたい場合は、スタイルの「スタイルシート(style.css)」だけ触ればOKです。この図をもとに、どの要素を弄るかを決定すれば(多分)問題ありません。

HTMLそのものを弄りたい場合は、この図の対応してるファイルを触れば大丈夫でしょう。
コメント表示部分は「コメントあり/なし/不許可」で動作が分岐してるので、若干ややこしいです。(トラックバックも同様)
なお、ポップアップコメントはデフォルトで未使用になってます(ヘッダ部分のcomments_popup_script()がコメント扱いになってる)。このへんは割愛します。

あとはHTMLやCSSの知識があれば、WordPress Classicテーマをベースとした改造は難しくないと思います。