MJ::Blog

日々のあれこれをテキトーに

木曜日
4月 10,2008

MacのMailを使っている。
使用上問題はないのだが普通のメールを表示するときにお世辞にも早いとは言えない。
メールボックスに大量にメールがあるせいなのか、読み込みに時間がかかるのだ。

「読み込み中…」

となるわけである。

それをうちの娘が、「よみこみちゅう」だね
と読み込んだ!!

漢字を読めるのか!!と驚いて聞いてみたら

「ニコニコ動画に書いてあったんだもん」(´・ω・`)

ニコニコ動画確かに動画を読み込み中・・・とでますね。
たぶんそれを今読み込み中だから待っててねと言ったんだろう。

また、相変わらずタイムボカンシリーズがブームで、毎日保育園送りがてら聞いている。
ここ2〜3日のお気に入りは逆転イッパツマンの「嗚呼!逆転王」のようである。
車のHDDに入れてあるのでもう自在に曲をチョイスして聞いてくれるのだが、「嗚呼!逆転王」という漢字だけを見てどの歌か分かっているようなのだ。

単なる記号として記憶しちゃってるの?

何となくではあるがうちの娘は漢字を読むのに苦労はしなさそうである。
自分も小学時代漢字の読み取りだけは困らなかったのに似ている気がするのだ。
文脈から何となく漢字を読んでしまう・・・
そんな微妙な能力が開花しているようなしていないような・・・

水曜日
2月 27,2008

ことの顛末

仕事でメインに使っているうちの Mac G4@OS X Leopardくんがこの月曜日お亡くなりになった。こんなテンパリ気味のときにお亡くなりにならなくてもいいだろうと思うのだが。とにかくお亡くなりになったわけだ。
今では何とか復旧したのだけど、その復旧方法など含め投稿するわ。

症状は、Path Finderでファイルを開こうとしたらずーっと読み込み中のままで応答なし。マシン自体もなんだか重い・・・
うーむ仕事にならん。というわけで強制的に電源を落とした(電源おしっぱで落としたわけです)そして再度起動をしようとしたら、「このマシンは再起動をする必要があります・・・・」とでるので再起動。また同じメッセージ表示。ループ。
という顛末である。本格的に仕事にならなくなった。

で、インストールディスクから起動してディスクユーティリティからディスクの検証。検証中エラー「Bツリーノードサイズが正しくありません」よくわからんけど、だめっぽい。

Leopardの Time Machineを使用していたので最近のデータは保持されているはずだし、もう一個の G5(Tiger)で仕事しながら、復旧できるだろうし・・・と思ったので、もうこれは入れ替えだなーと HDDを購入して再インストールすることにした。

Leopard 再インストール

まー、うちの Safariが Flashコンテンツをみるとよく落ちてたし、ちょうどいいやとポジティブに考えつつも、仕事のテンパリ具合と秤にかけるとやはり気落ちする。
インストールにあまり時間をかけたくはないので、プリンタドライバいらねー、DVDチェックスキップだー!とインストールしようとするも、なかなかインストールディスクを認識しない(まえからドライブ変だったんだよね;;)仕方なく FireWireの外付けドライブから起動。よかった〜もらっといてこのドライブ。

無事インストール完了。インストールの時間は約40分。

その間、Time Machineでバックアップしたディスクを G5にマウントして作業を開始。うんうん。データはきちんと残っているっぽいすばらしい。
しかし、バックアップディスクから G5にドラッグしてコピーしても、エイリアス(ハードリンク?)としてコピーされるだけで、実コピーができなかった。
Time Machineから起動して復旧するしか、実データのコピーはできない模様。
データはちょっといじらない方がよいかと思ったので、バックアップデータはひとまずそのままにしておくことにした。

データの復旧

次のような手順で進めて、何とか落ち着いた。
1. Leopardインストール

2. ソフトウェア・アップデート(1回目)
OSのアップグレードなど

3. ソフトウェア・アップデート(2回目)
なんかグラフィック関係がよくなるらしいやつ

4. ATOK 2007インストールしてアップグレード

5. Xcodeインストール
4〜5はとりあえずCDから入れるものをとりあえず入れたかっただけ後でもいいよねこんなの。

6. Mailtagsインストール
Mailにタグ機能をつける拡張アプリ。
Mailデータの復旧をするときにタグデータも一緒に復旧するはずなので、先に入れ説いた方がよいと思いインストール。データの復旧のときに Bundleソフトとして復旧させれば大丈夫だったかもしれない。

7. Mail環境復旧
これはいろいろやってうまくできなかったりしたのだが、おそらくいかが正解だろう。
自分は仕事・プライベートなど複数アカウントを持っているので、ちょっと面倒だったのかな?

●~/Library/Preferences/com.apple.mail.plist を復旧
これは、Mailで管理しているアカウントの一覧などの模様。
これを復旧しないと、新しい Mailで作ったアカウントしかみれない
●~/Library/Mail/* を復旧 Bundlesを除いて(MailTagsをすでに入れていたので)
●メールボックス再構築
上記でメールボックス・スマートメールボックスなどそっくり復旧するのだが、メールボックス・フォルダ開いても一覧には何も表示されなかったので、それぞれのメールボックスで再構築。ほんと、一つ一つやんなきゃだめだったので大変だったわ。
一括でできんのかね?
●~/Library/Preferences/ca.indev.MailTags.plistの復旧
MailTagsで管理していたキーワード・プロジェクトのデータが復旧できる

8. その他いろいろなデータ復旧
あとはまー、Time Machineからデータ持ってくるよりは一からやり直した方が良さそうだったので、必要なデータを選んで復旧。
と、Time Machineの最新のデータを別の HDDにフル復旧させておいた。

9. その後
Time Machineで使っていた同じディスクでまた Time Machineを使おうとしたら、旧バックアップで使用していたバックアップのフォルダを新しいマシン名でリネームして、バックアップを開始しやがった。分けろよな、マシン名。
そのくせ Time Machineでは以前のバックアップデータより上にはさかのぼれないし

も一回、ディスク消去して Time Machineやりなおすかな〜

  • 1 Comment
  • add to hatena hatena.comment 0 user add to del.icio.us 0 user add to livedoor.clip 0 user この記事へのリンク
  • 雲の握手@滋賀県甲賀市

    日曜日
    2月 10,2008

    昨日は奥田民生のライブに行ってきた。子供は妹に見てもらって
    相変わらず力の抜けたオッサンだった。
    途中アンプの調子がおかしくなるというハプニングもあったし、久しぶりのライブはいいね。

    さて、その帰りしな
    うちの奥さんに奥さんのお母さんからメールが来ていた。写メである。
    これが結構すごいので写真もらってポストしてみる。

    雲の握手

    これはなんだろうね。甲賀忍法?

  • 1 Comment
  • add to hatena hatena.comment 0 user add to del.icio.us 0 user add to livedoor.clip 0 user この記事へのリンク
  • 金曜日
    2月 8,2008

    もう2月に入って今年初めの話をするのはなんだが年明けの正月休み明けのはなしだ。
    実は一昨年、さらに一昨昨年と2年連続で年末に体調を崩していた。
    一昨昨年は28日くらいに急に胸のあたりがいたくなり病院に駆け込み、40度近い熱を出した(結局は肋間神経痛だったようだ)
    一昨年は11月〜12月にかけて肺炎に。

    そんなわけで昨年は結構心配していたのだが何とか乗り切っていた・・・
    と思いきや年明けでまたダウンしてしまった。

    今回は頭痛である。頭痛と同時に肩もすごい凝っていて痛かった。
    休み明け仕事をしようと思ってもとてもそんな状態ではなく、1日目は安静。2日目もまだ頭が痛いので、うちの奥さんも働いているレインボーズへ行くことにした。ここはリフレクソロジーとアロママッサージなどを行ってくれるのだが、長年の技術と経験によって色々とアドバイスもしてくれる。
    この日はリフレと全身のマッサージをしてもらい、少し楽になった。

    先生曰く、血流が悪くなっている。運動不足ね!

    と言うわけで、今年の課題が早くも露見してしまった。
    運動、体調管理だ。やっぱ体が資本ですね。

    というわけで色々と検討した結果近くの市営運動公園でやっているジムに行くことにした。
    自転車で5分もかからないところにジムとプールがあるのであるしかも市営。利用しない手はない。
    で、今日はそのフォローアップ教室というのを受けてきた。現在の体力・目的から丁度よいトレーニングメニューを提案してくれるそうだ。

    まず体力テストをやってみると言うことでエアロバイクに。エアロバイクの体力テストモードで測るのだそうな。それによると、自分の年齢では最高レベルの体力だそうな・・・ほんまかいな。その後いくつかマシンを使った筋トレを提案してもらった。

    で、次のようなメニューができあがった。

    ●ウォームアップ
    ストレッチ(10分)
    エアロバイク(10分)

    ●マシン
    ローマンテストプレス(10回 x 2)
    ラットプルダウン(10回 x 2)
    レッグプレス(10回 x 2)
    レッグカール(10回 x 2)
    スクワット(10回 x 2)

    ●ダンベル
    ベントオーバーロウ(10回 x 2)
    ショルダーシュラッグ(10回 x 2)

    アブドミナルボード(腹筋・2種類)(10回 x 3)
    バックエクステンション(背筋)(10回 x 3)

    ■クールダウン
    トレッドミル(20〜30分)
    ストレッチ(10分)

    さあ、どうなるでしょう。

    本日の記録
    体重・・・・61.7kg
    体脂肪率・・24.5%

    木曜日
    2月 7,2008
    タイムボカン名曲の夕べ

    このクールからヤッターマンがテレビで放映されてますね。1回目見逃したけどその後から見ています。我が家はテレビはほとんど見ませんし、子供向け番組もほとんど家では見せないわけですが、これは見とけ!!と見せています。日本の心です。ぽちっとなです。

    うちの娘も、戦いのシーンは怖がりつつそれなりに楽しんでいるもよう。

    さてそんなある日、ディズニーの曲を聴きたくなった娘が CDかけてーと要求をしてきた。
    そういやCDどこいったっけ〜と探していたところ発見したのが、もう何年も前に買った、『TWIN BEST タイムボカン 名曲辞典』(リンク先はもうその商品無かったので類似のベスト盤)。タイムボカン〜イタダキマン までの全シリーズ(その後テレビ東京できらめきマンとかやってましたね)の主題歌・挿入歌がはいっているものです。

    見せたところ、聞きたいーというのでかけてみたところ・・・
    ここ数日間は我が家ではタイムボカンシリーズが延々かかっています。とほほ。
    子供の心をつかんで話しません。さすが山本節。
    毎日帰ってくると歌かけて〜とせがみ、ふりがなの振っていない歌詞カードを見て「勉強なの」といって一所懸命にらんでいます。

    現シリーズではまだ出てこないし出てくるかも分からない、ヤッターキング、ヤッターブル、パンダ、コパンダを知っていて保育園で「何それ?」とつっこまれないか心配です。
    ゼンダマンやオタスケマンの話をしても保育園では分からないぞ・・・

    微妙 - 4歳7ヶ月22日

    水曜日
    2月 6,2008

    うちの食事は、お魚の場合は一人ずつお皿に用意されるけど大体は大皿におかずが盛りつけられ、そこから各自取り分けて食べると言うスタイルだ。
    うちの娘にはこれ食べてねーとこちらで取り分けるのだけど。

    炒め物とかがこのパターン。

    この大皿の料理なのだが
    勢い余って作りすぎたり、その日の個人のコンディションによって多かったり少なかったりする。とくに娘の毎日の食べる分量の差異についてはうちの奥さんは毎回頭を悩ませている。

    で、大皿料理があと1〜2口で食べ終わるくらいで残ってしまうことがある。
    そういうときは「微妙に残っちゃった・・・」と奥さんが言い、手分けして食べたりする。

    昨日はこの大皿料理に値するのが『レンコンの醤油炒め』である。
    料理の名称違っていれば後で訂正するけど、輪切りにしたレンコンを醤油で味付けした実にシンプルでうまい一品である。どなたかがレシピをコメントしてくれるかもしれないw

    このレンコンが昨日は2切れ残ってしまった。

    それにうちの娘は気づいたようで一言ぼそっと
    「微妙だね」

    はい、微妙です。
    思わず笑ってしまったら、「笑わないで!」と怒られた。
    ちょっとしたことでも笑われると傷つくのかもしれない。気をつけよう

    日曜日
    12月 23,2007

    デュアリス購入して半年。6ヶ月点検に行ってきました。
    ま、点検自体は特になんてこと無かったのだけど、その前に事件が(涙)

    それは、11月も末日。自分の誕生日あたりのこと。
    住宅ローンの契約銀行がちょっと遠くにあるため記帳するのに車で10分程度いつも移動する。月末ローン支払い前の残高か確認のためだ。
    11月の末日も例によっていったわけだが、その帰り道事件は起こった!!

    ちょいと近道しようと裏道を通っていたときのこと。
    ここを右折すれば望みの場所にショートカットできるぜ!!というところがあった
    が、そこには左折オンリー表示が;;
    「なにおえー」と言いつつ左折したときである。

    「ドンッ! ズズズズズッーーー」

    という音が。
    ドアミラーを見るとなんか引きずっている!!

    車の哀しき傷痕

    すぐに車を止めて確認すると
    左後輪部分をカバーしている樹脂カバーが外れている!!
    そしてよく見ると、左後輪の前の部分の塗装がぱっくり割れている!!(涙)
    あと、ちょっとへこんでるし・・・

    写真ではよく分かりませんが、塗装面がぱっくり割れていて下地が見えています;;
    潮風吹き荒れるうちの方ではさびが心配。

    ちょっとした不注意だったけど、やってしまいましたよ!!
    前回のプジョーを乗り始めて約10年。これほど激しくぶつかったのは初めてだわ(涙)

    さて、ここで6ヶ月点検に話は戻る。
    点検と丁度時期があったので今回の修理見積をしてもらった

    ところ・・・

    なんと・・・

    203,219円!!!

    ちょwまってw

    早速担当営業さんに相談。
    営業さん実は知り合いからの紹介で近くのディーラーではなく、横浜方面の人。
    ディーラーとはあまり仲良くなっていないのでここは営業さんに相談だー

    営業さんにも携帯で写真を送ってみたところ
    どうもディーラーの見積はリヤドアすべて交換という見積だったようだ。そらかかるわな。
    板金だけで済むのかと思ってたんだけど・・・

    営業さんも板金で済むんじゃないかと・・・と言っているので
    来週営業さんが見に来てくれることになった(営業さん元は整備士さん)

    さー、どうなるべいか

  • 1 Comment
  • add to hatena hatena.comment 0 user add to del.icio.us 0 user add to livedoor.clip 0 user この記事へのリンク
  • 火曜日
    12月 18,2007

    なんか CakePHPのことばっか書いてたので違うことを・・・w

    うちの家には1階の今の真ん中に 16.5cm角の大黒柱が1本2階まで通っている。
    邪魔かもしれないとは思ったけどこれが結構邪魔になってなかったりする。

    大黒柱には娘の身長を測った跡をつけている。基本ですな。
    引っ越してきてすぐに1歳になったので1歳から記録されている。
    しかし思い切りよく傷を付けられず、ちょろりとシャープペンで強めに書きつつ傷がちょっとはいっている状態。がりっと跡を付けられる程思い切れないのである。

    その娘は先日丁度4歳半。
    成長が早い今の時期は半年ごとに記録をしていて、早速測ってみた。
    丁度 1m。4歳では標準かちょっと小さいくらいなのかな?
    何となく大台に乗った感じでうれしいですね。

    さて、その翌日柱の前を通り過ぎる娘を見て違和感が・・・
    「どう見ても、昨日付けた跡よりも大きくないか!?」
    柱の前には絨毯がひいてあるのでそのせいかと思い、ちょっとどけてみても一度測ってみたら、やっぱり気のせいじゃない。

    1cm 大きいw

    そういや昔自分の背をこまめに測ってた時(1番前か2番目か?と言う感じで背が低かったので気にしてよく測ってたのよ)朝の方が大きかったかもと思いだしたけど、 1cmも違ってたっけ?
    とあたまに?を残しつつその日は終了。

    やっぱり気になるので、夜にまた測ってみたら今度は 1m!

    やっぱり朝は 1cm 伸びてたのか・・・

    結構朝と夜とで違うのね。
    とりあえず、公式的には娘の身長は現時点で 1m ということにしています。それまでも夜に測ってたからね。

    CakePHP 認証機能

    日曜日
    12月 9,2007

    ログイン認証出来る機能がほしかったのだが標準で実装されているACLって認証機能じゃなかったのね orz
    データベースなどのユーザーテーブル上のID/PWで認証できる機能を探していたところ、いろいろとモジュールが見つかり以下が参考になった。

    とはいえ、個人で実装するにはいろいろと足りないところもあったりしたので、いいところを真似しつつ自作してみた。
    それなりのレベルまで作れた感じな為公開してみることにした。不具合点などはご指摘下さい。
    またご利用に際しては自己責任でお願いします。

    使い方

    コンポーネントとして動作。controllers/components にauth.phpとして配置。

    まずはコンポーネントを利用するためにコントローラのはじめに以下のように設定

      var $components = array('Auth');
    

    また、認証が必要なアクションを設定。
    beforeFilter() メソッド中に認証が必要になるアクションを定義する方法を採用。

        function beforeFilter() {
            // 認証設定
            $this->Auth->requireAuth('userMenu', 'editUser');
    
            // 二重登録防止
            $this->Security->requireAuth('editUser');
        }
    

    Securityコンポーネントと同様の方法で、認証が必要なアクションについて、requireAuth()の中にカンマ区切りでアクション名を羅列する方法としました。
    検索して見つけたもろもろのモジュールでは、すべてに対して認証をしていたり、アクションの実行時に呼び出しを行ったりと面倒な方法をしているのが多かったのと、Securityコンポーネントと同じ方法で対応した方がわかりやすかったという理由で、こうしてみた。
    Security->requireAuth()で二重投稿防止などをしている場合はその宣言より前に行う必要があります。

    課題としては、無制限に認証をかける場合は allとか指定すると認証とか出来るといいのかもしれません。ま、今のところ必要ないから作ってないけどw

    認証されているかをチェックする場合は、

      $this->Auth->checkAuth();
    

    にてチェック。

    ログアウトをする場合は、

      $this->Auth->logout();
    

    とする感じで。

    また、認証は ‘member’テーブルの ‘userid’ / ‘password’ を利用して行い、該当するユーザーが見つかった場合は ‘member’テーブル上のそのデータを認証ユーザーデータとして保存します。
    実際は ‘Member’モデルで find()したユーザーデータが配列として保存されます。それらの値を取得する場合は、

      $value = $this->Auth->getAuthData('フィールド名');
    

    member_name というフィールドの値を取りたい時は getAuthData(’member_name’) で取得。

    コンポーネント側の設定

    $authFormName:
    ま、authFormNameという命名が正しいかどうかは微妙です。
    ログインフォームで $html->input(’Login/userid’) などのように指定する際のモデル名(左では’Login’)を指定。

    $authModelName:
    認証で指定するモデル(テーブル)名。

    $authLoginIdField:
    ユーザーIDが格納されているフィールド名。 $authModelNameテーブルの $authLoginIdFieldがIDということになります。

    $authPasswordField:
    パスワードが格納されているフィールド名。 $authModelNameテーブルの $$authPasswordFieldがパスワードということになります。

    $authLifeTime:
    $authLifeTimeUnit:
    上が認証有効期間、下がその単位。60分の場合は
    $authLifeTime = 60;
    $authLifeTimeUnit = ‘minutes’;
    となる。strtotime() で比較するのでそこで認識できる単位を指定する。

    $loginFormUrl:
    ログインフォームURL。ログインが必要な場合はこのURLにリダイレクトされる。

    $sessionName:
    認証情報を保存するためのセッション名。ま、適当に。

    ログインエラーとしては ID不正、パスワード不正、認証有効期間オーバーを用意しており、それらが
    $this->Auth->getError() で取得出来るので、取得した内容をログインエラーとして表示できるんだけど、この辺がもうちょっとうまいこと実現できないかなーと思っているところ。
    現状、たとえば loginForm() というアクションを用意して

        function loginForm() {
            $this->data[$this->Auth->authFormName] = $this->Auth->getLoginFormData();
            $this->set('errMsgs', $this->Auth->getError());
        }
    

    のように errMsgsにエラー情報を渡してログイン画面を表示する必要があり、一つアクションに命令を各必要がある。
    できればここは、書かずに処理したいんですよね。コンポーネント側だけで解決出来るといいかなーと。

    書くべきところはこんな感じかしら?

    ソース[auth.php]

    
    class AuthComponent extends Object
    {
        var $controller = true;
        var $components = array('RequestHandler', 'Session');
    
        /** 認証が必要なアクション名を格納する配列 */
        var $requireAuth = array();
    
        /** ログインフォームのフォーム名 */
        var $authFormName = 'Login';
    
        /** 認証で利用するモデル */
        var $authModelName = 'Member';
        var $authModel = null;
        var $authMember = null; 
    
        /** 認証モデルのログインID フィールド名 */
        var $authLoginIdField = 'login_id';
    
        /** 認証モデルのパスワード フィールド名 */
        var $authPasswordField = 'password';
    
        /** 認証有効期間 */
        var $authLifeTime = 60;
        /** 認証有効期間の単位 */
        var $authLifeTimeUnit = 'minutes';
        /** 認証有効時間(期間から算出) */
        var $authExpire;
    
        /** ログインフォームへのURL */
        var $loginFormUrl = '/members/loginForm';
    
        /** ログイン完了後にリダイレクトするURL */
        var $authLoginBackUrl;
    
        /** 認証で利用するセッション名 */
        var $sessionName = 'dragonquest';
        /**
         * セッションに引き渡し認証比較をするためのデータ
         *      array('Member' => array(),  ---> ログインしたユーザーの情報、authModelからfindして取得
         *            'Login'  => array(),  ---> ログインフォームでの ID/PWを作成するためのフォーム情報
         *            'errors'  => array(),  ---> ログインエラー情報
         *            'loginBackUrl' => String,   ---> 認証完了後に実行するアクション
         *            'expire' => String,   ---> ログインの有効時間 strtotime() の形式で
         *            '' => '',
         *           )
         */
        var $authData = array();
        var $authErrors = array();
        var $authDataErrorSessName = 'errors';
        var $authLoginBackUrlSessName = 'loginBackUrl';
        var $authExpireSessName    = 'expire';
    
        /* 認証エラー関係 */
        var $AUTH_NORMAL        = 0;
        var $AUTH_IS_NOT_LOGIN  = 1;
        var $AUTH_LOGIN_ID_ERR  = 2;
        var $AUTH_PASSWORD_ERR  = 3;
        var $AUTH_OVER_LIFETIME = 4;
        var $errMsgs = array(0  => '',
                             1  => 'ログインして下さい。',
                             2  => 'ユーザーIDが正しくありません。',
                             3  => 'パスワードが正しくありません。',
                             4  => 'ログイン有効時間をすぎたためログアウトしました。再度ログインして下さい。'
                            );
    
        /** StartUp */
        function startup(&$controller) {
            $this->controller =& $controller;
    
            // 初期処理
            $this->_init();
    
            // 認証処理を行うアクションの場合は処理の開始
            if (in_array($controller->action, $this->requireAuth)) {
                $this->start();
            } else {
                $this->setLoginBackUrl();
            }
    
            // authDataをセッションに書き出す
            $this->Session->write($this->sessionName, $this->authData);
        }
    
        /**
         * 初期処理
         */
        function _init() {
            //
            // 利用するモデルの定義
            // 認証データが格納されているモデルを定義
            //
            loadModel($this->authModelName);
            $className = $this->authModelName;
            $this->authModel =& new $className();
    
            // セッションに認証データがある場合は $authDataに値を設定
            if ($this->Session->check($this->sessionName)) {
                $this->authData = $this->Session->read($this->sessionName);
            }
    
            // 別名参照の作成
            // $this->authData[xxxxx] と書くのを省略したいだけw
            $this->authErrors =& $this->authData[$this->authDataErrorSessName];
            $this->authExpire =& $this->authData[$this->authExpireSessName];
            $this->authLoginBackUrl =& $this->authData[$this->authLoginBackUrlSessName];
        }
    
        /**
         * 認証制限するための action名を設定
         *
         * @params  array   引数で定義されたアクション名は認証制限をかける物とする
         */
        function requireAuth() {
            $this->requireAuth = func_get_args();
        }
    
        /**
         * 認証処理の開始
         */
        function start() {
            // 認証開始時にエラー情報破棄(ログインエラー時用にエラー情報をセッションで渡しているため)
            $this->authData[$this->authDataErrorSessName] = array();
    
            //
            // ログインフォームから入った場合は
            // ログイン処理を実行
            //
            if ($this->_isLoginExecute()) {
                if(!$this->login($this->controller->data[$this->authFormName][$this->authLoginIdField],
                                $this->controller->data[$this->authFormName][$this->authPasswordField])) {
                    // ログイン失敗時
                    $this->_redirectLoginForm();
                } else {
                    // 別名参照の作成
                    // ログイン成功時はログイン実行によって取得した会員情報を authDataに渡す
                    $this->authData[$this->authModelName] =& $this->authMember[$this->authModelName];
                    // ログイン有効時間を更新
                    $this->setExpire();
                }
            } else {
                // 別名参照の作成
                // ログイン画面を経由していない場合は authMember にセッションに持っていた会員情報データを渡す
                $this->authMember[$this->authModelName] =& $this->authData[$this->authModelName];
            }
    
            //
            // 未ログイン時はログイン画面を表示
            //
            if  (!$this->checkAuth()){
                // ログイン完了後戻るべき URLをセット
                $this->setLoginBackUrl();
    
                // ログインエラーをセット
                $this->setError($this->AUTH_IS_NOT_LOGIN);
                $this->authData[$this->authFormName] = array();
    
                // ログインフォームへリダイレクト
                $this->_redirectLoginForm();
            }
    
            //
            // ログインしていても有効時間を過ぎていれば
            // やっぱりログイン画面を表示
            //
            if (!$this->checkExpire()) {
                $this->setError($this->AUTH_OVER_LIFETIME);
                $this->authData[$this->authFormName] = array();
                $this->_redirectLoginForm();
            }
    
            //
            // 問題なければ、認証時刻を記録
            //
            $this->setExpire();
        }
    
        /**
         * ログイン処理
         *
         * @param   String  $login_id
         * @param   String  $password
         * @return  Boolean True: ログイン成功 / False: ログイン失敗
         */
        function login($login_id, $password) {
            if (empty($login_id)) {
                $this->setError($this->AUTH_LOGIN_ID_ERR);
                return false;
            }
    
            //
            // ユーザーID / パスワードのチェック
            //
            $this->authMember =& $this->authModel->find(array($this->authLoginIdField => $login_id));
            if (empty($this->authMember)) {
                $this->setError($this->AUTH_LOGIN_ID_ERR);
                return false;
            }
    
            if ($this->authMember[$this->authModelName][$this->authPasswordField] != $password) {
                unset($this->authMember[$this->authModelName]);
                $this->authData[$this->authFormName][$this->authLoginIdField] = $login_id;
                $this->authData[$this->authFormName][$this->authPasswordField] = $password;
    
                // ログインエラーメッセージを表示してログイン画面を表示
                $this->setError($this->AUTH_PASSWORD_ERR);
                return false;
            }
    
            return true;
        }
    
        /**
         * ログアウト処理
         */
        function logout() {
            // セッションデータを削除する
            $this->Session->delete($this->sessionName);
        }
    
        /**
         * ログインされているかどうかのチェックを行う
         */
        function checkAuth() {
            return ($this->Session->check($this->sessionName) and !empty($this->authData[$this->authModelName]));
        }
    
        /**
         * ログイン有効時間をセットする
         * セットされた時間を過ぎるとログイン無効となる
         */
        function setExpire() {
            // authLifeTime (単位: authLifeTimeUnit) から有効時間を算出
            $this->authExpire = strtotime('+'.$this->authLifeTime.' '.$this->authLifeTimeUnit);
        }
    
        /**
         * ログイン時間が有効かどうかをチェックする
         *
         * @return  boolean     True: 有効なログイン
         */
        function checkExpire() {
            // authExpireが現在時刻いないであれば有効とする
            return (strtotime('now') < $this->authExpire);
        }
    
        /**
         * ログインエラーをセットする
         *
         * @param   Integer $errno  ログインエラーNo.
         */
        function setError($errno) {
            // ログインエラーNo. のメッセージも含めて
            // authErrors に対して格納
            $this->authErrors[$errno] = $this->errMsgs[$errno];
        }
    
        /**
         * ログインエラー情報を取得する
         *
         * @return  array    array(errno => errmsg, errno => errmsg, …)
         */
        function getError() {
            return $this->authErrors;
        }
    
        /**
         * ログインフォームから遷移したかどうか?
         *
         * @return  boolean     true: ログイン画面からの遷移
         */
        function _isLoginExecute() {
            // authModelName を名称とした POSTデータがわたる時はログインフォームからの遷移とする
            return !empty($this->controller->data[$this->authFormName]);
        }
    
        /**
         * ログイン完了後に戻るべきURLへリダイレクト
         */
        function _redirectLoginBack() {
            $this->Session->write($this->sessionName, $this->authData);
            $this->controller->redirect($this->authLoginBackUrl);
        }
    
        /**
         * ログイン画面へリダイレクトする
         * ログイン画面で表示するエラーメッセージ、入力フォームデータをセッションに格納し
         * リダイレクト
         */
        function _redirectLoginForm() {
            $this->Session->write($this->sessionName, $this->authData);
            $this->controller->redirect($this->loginFormUrl);
        }
    
        /*
         * Setter/Getter
         */
        function getAuthData($field = null) {
            if ($this->checkAuth()) {
                if ($field == null) {
                    return $this->authData[$this->authModelName];
                } else {
                    return $this->authData[$this->authModelName][$field];
                }
            } else {
                return false;
            }
        }
        function setAuthData($field, $value) {
            if ($this->checkAuth()) {
                $this->authData[$this->authModelName][$field] = $value;
    
                // authDataをセッションに書き出す
                $this->Session->write($this->sessionName, $this->authData);
            }
        }
    
        /**
         * フォームを中得する
         */
        function getLoginFormData() {
            if ($this->checkAuth()) {
                return $this->authData[$this->authFormName];
            } else {
                return false;
            }
        }
    
        /**
         * 実行中のURLを取得する
         * 実行したアクションに戻れるように
         *
         * @return String  アクションURL
         */
        function getLoginBackUrl() {
            if ($this->checkAuth()) {
                return $this->authData[$this->authLoginBackUrlSessName];
            } else {
                return false;
            }
        }
    
        /**
         * 実行中のURLを取得する
         * 実行したアクションに戻れるように
         *
         * @return String  アクションURL
         */
        function setLoginBackUrl() {
            if (getenv(’REQUEST_URI’) != $this->loginFormUrl) {
                // ログイン完了後戻るべき URLを現在のURLとして
                $this->authLoginBackUrl = getenv(’REQUEST_URI’);
            }
        }
    }
    
    月曜日
    12月 3,2007

    確認画面画面前の入力チェック。
    CakePHPの入力チェックは Model部分にて クラス変数 $validate を定義することで save()メソッドによる更新時、validates() メソッドによる明示的な操作のいずれかで入力チェックを行うことができる。
    入力チェックの方式としてはあらかじめ定義されている、VALID_NOT_EMPTY, VALID_NUMBER, VALID_EMAIL, VALID_YEAR で行えるのと、正規表現を利用することが出来る。定数 VALID_* もようは正規表現を定数定義してるだけだしね。

    確認画面を表示する前の入力チェックでは validates() による明示的な入力チェックが基本となるか。
    例えば、User モデルの入力チェックを行う場合コントローラー内で

      if($this->User->validates($this->data['User']) {
      // 無問題
      } else {
        $this->validateErrors($this-User);	// Viewで tagErrorMsgでメッセージを表示するための操作
        $this->render('フォーム');
      }
    

    として、Viewでエラーメッセージを表示するように出来る View側では

    <table class="registForm">
      <tr>
        <td>氏名</td><td><?php echo $html->input('User/name') ?><?php echo $html->tagErrorMsg('User/name', '氏名を入力して下さい'); ?></td>
    </table>
    

    とかしておくことで、name のバリデーションに引っかかった場合にのみ、’氏名を入力して下さい’ のメッセージが表示される。
    この tagErrorMsg のエラーの吐き出しが、<div class=”error_message”></div> でエラーメッセージを表示してくれる。これによって CSSでerror_message を定義しておけば目立たせることなど出来る。個人的には <span> で囲ってほしかったわ。ここだけ <span> にしちゃいました。

    また、入力エラーを目立たせたい場合以下のようにスタイルで class=”warning” などを使って、背景変えたり入力エラーの場所を目立たせることが多いので、

    <table class="registForm">
      <tr class="worning">
        <td>氏名</td><td><?php echo $html->input('User/name') ?><?php echo $html->tagErrorMsg('User/name', '氏名を入力して下さい'); ?></td>
      </tr>
    </table>
    

    次のヘルパー追加して実現しました。

    function tagErrorClass($field, $text) {
        $error = 1;
        $this->setFormTag($field);
        if ($error == $this->tagIsInvalid($this->model, $this->field)) {
            return sprintf('%s', is_array($text) ? (empty($text[$error - 1]) ? 'Error in field' : $text[$error - 1]) : $text);
        } else {
            return null;
        }
    }
    

    ま、tagErrorMsg を一部変えただけですね。呼び出す際は、

    <table class="registForm">
      <tr class="<?php echo $hige->tagErrorClass('User/name', 'warning'); ?>">
        <td>氏名</td><td><?php echo $html->input('User/name') ?><?php echo $html->tagErrorMsg('User/name', '氏名を入力して下さい'); ?></td>
      </tr>
    </table>
    

    と言った感じで。

    入力エラーの表示方法はどうも上記の方法しか用意されていないように思われる。探してみたところ。あったらすいません。
    例えばフォームの上部にまとめて入力エラーの内容を表示するとか簡単にできそうもない。
    このあたり、Validationに関しては結構使い勝手がもう一歩届かないというのが、現在使っているところでの感触だ。

    最近のコメント

    • だるま: MJさん、いろんなことやるんですねw いい人生送っている...
    • mio: 月別アーカイブのカレンダーに、表示中の月のカレンダーを表示するところで、 悪戦苦闘していたところ、偶然このエントリーを...
    • ひろじ: ふたりともキマッてます! こどもって発表会とか楽しみにしますよね。 ウチもYAMAHAや保育園の発表会などは「あと何...
    • だるま: かわゆい! 奥方も 娘さんも! こちらのフラ教室も60歳で若手らしいw でも多くの人に愛されていいです...
    • MJ: そ、それは(;゜д゜) アンに「にんじん」というのと同様の効果が期待されます。...

    最近の投稿

    Meta