月別アーカイブ: 2011年11月

EC-CUBE2.11 入力フォームの内容チェック項目メモ

ユーザー入力のフォーム関連のクラスによく

$objFormParam->addParam(“お電話番号1”, ‘tel01’, TEL_ITEM_LEN, ‘n’, array(“EXIST_CHECK”, “SPTAB_CHECK”, “NUM_CHECK”, “MAX_LENGTH_CHECK”));

などと書かれているが、この”EXIST_CHECK”とか”SPTAB_CHECK”とか、実際何をチェックしているのかあいまいだったので調べてみました。

実際のチェックは
/data/class/SC_CheckError.php
に書かれています。

“HTML_TAG_CHECK”: HTMLのタグをチェックする

“EXIST_CHECK”: 必須入力の判定

“EXIST_CHECK_REVERSE”: 必須入力の判定(逆順)

“SPTAB_CHECK”: スペース、タブの判定(スペース、タブ、改行のみの入力はできません。)

“NO_SPTAB”: スペース、タブの判定(スペース、タブ、改行は含めないで下さい。)

“ZERO_START”: ゼロで開始されている数値の判定(0で始まる数値が入力されています。)

“SELECT_CHECK”: 必須選択の判定(選択されていません。)

“EQUAL_CHECK”: 同一性の判定(~と~が一致しません。)

“DIFFERENT_CHECK”: 値が異なることの判定(~と~は、同じ値を使用できません。)

“GREATER_CHECK”: 値の大きさを比較する (~は~より大きい値を入力できません。)

“MAX_LENGTH_CHECK”: 最大文字数制限の判定(○字以下で入力してください。)

“MIN_LENGTH_CHECK”: 最小文字数制限の判定(○字以上で入力してください。)

“MAX_CHECK”: 最大数値制限の判定 (n以下で入力してください。)←コメントでは「最大文字数制限の判定」と書かれているがたぶん間違い。

“MIN_CHECK”: 最小数値制限の判定(n以上で入力してください。)

“NUM_CHECK”: 数字の判定(は数字で入力してください。)

“NUM_POINT_CHECK”: 小数点を含む数字の判定(は数字で入力してください。)

“ALPHA_CHECK”: 半角の判定(は半角英字で入力してください。)

“TEL_CHECK”: 電話番号の判定(数字チェックと文字数チェック)

“FULL_EXIST_CHECK”: 関連項目が完全に満たされているか判定( が入力されていません。)←全部入力されているかのチェック?使われていない?

“ALL_EXIST_CHECK”: 関連項目がすべて満たされているか判定(はすべての項目を入力して下さい。)←たとえば郵便番号など二つのテキストフィールドが入力されているかどうか

“ONE_EXIST_CHECK”: 関連項目がどれか一つ満たされているか判定(どちらか一方が入力されていればOK)

“TOP_EXIST_CHECK”: 上位の項目が満たされているか判定(は先頭の項目から順番に入力して下さい。)←規格の選択などで使用している。

“KANA_CHECK”: カタカナの判定

“KANABLANK_CHECK”: カタカナの判定2(タブ、スペースは許可する)

“ALNUM_CHECK”: 英数字の判定

“GRAPH_CHECK”: 英数記号の判定

“ZERO_CHECK”: 必須選択の判定(ひとつは選択してね)

“NUM_RANGE_CHECK”: 桁数の判定 (○○はn桁~n桁で入力して下さい。)

“NUM_COUNT_CHECK”: 桁数の判定(○○はn桁で入力して下さい。)

“EMAIL_CHECK”: メールアドレス形式の判定

“EMAIL_CHAR_CHECK”: メールアドレスに使用できる文字の判定

“URL_CHECK”: URL”: URL形式の判定

“IP_CHECK”:  IPアドレスの判定

“FILE_EXT_CHECK”: 拡張子の判定

“FIND_FILE”: ファイルが存在するかチェックする

“FILE_EXIST_CHECK”: ファイルが上げられたか確認

“FILE_SIZE_CHECK”: ファイルサイズの判定(制限)

“FILE_NAME_CHECK”: ファイル名の判定(ファイル名に日本語やスペースは使用しないで下さい)

“FILE_NAME_CHECK_BY_NOUPLOAD”: ファイル名の判定(アップロード以外の時)

“CHECK_DATE”: 日付チェック[項目名,YYYY,MM,DD]

“CHECK_DATE2”: 日付チェック[項目名,YYYY,MM,DD,mm]

“CHECK_DATE3”: 日付チェック[項目名,YYYY,MM]

“CHECK_BIRTHDAY”: 誕生日チェック[項目名,YYYY,MM,DD]年の最大・最小数値のチェックがついている

“CHECK_SET_TERM”: 年月日に別れた2つの期間(YYYYMMDD)の妥当性をチェックし、整合性と期間を返す←要するに期間が正しいかどうか

“CHECK_SET_TERM2”: “CHECK_SET_TERM”のもっと細かい期間(YYYYMMDDHHmmss)のバージョン

“CHECK_SET_TERM3”: “CHECK_SET_TERM”の期間が年と月(YYYYMM)だけのバージョン

“DIR_CHECK”: ディレクトリがあるかどうか

“DOMAIN_CHECK”: ドメインの形式チェック

“MOBILE_EMAIL_CHECK”:  携帯メールアドレスのチェック

“CHECK_REGIST_CUSTOMER_EMAIL”: メールアドレスが会員登録されているか調べる

“PROHIBITED_STR_CHECK”: 禁止文字列のチェック

“EVAL_CHECK”: PHPコードとして評価可能かチェックする

FILE_EXIST_CHECK

Javascript: あるオブジェクトのメソッドをほかのオブジェクトに呼んでもらうとthisはwindowになる

[javascript]
A = function(){
this.myName = “A”;
}
A.prototype = {
trace:function(){
alert(this.myName);
}
}
B = function(){
this.myName = “B”;
}
B.prototype = {
callme:function(callme){
callme();
}
}
$a = new A();
$b = new B();
$b.callme($a.trace);
[/javascript]

AとBにはそれぞれmyNameを設定

BのインスタンスにAのインスタンスのメソッドtraceを渡し、Bのインスタンスに呼んでもらう。

結果はAでもBでもなく、undefined.

traceメソッド内のthisはwindowになる。traceが匿名関数になる。

なんどもなんどもつまずくところ。

ECCUBE 2.11 支払い方法に説明文を追加

代引きの手数料など一つ一つの支払い方法に説明文を入れたかったのでカスタマイズのメモ

データベーステーブルdtb_paymentにはmemo01とか02とか使われていないらしいカラムがあったのでそれを使うことにする。

1:管理画面のテンプレートを編集
data/Smarty/templates/admin/basis/payment_input.tpl
テーブルの行をひとつ追加
[html]
<tr>
<th>説明</th>
<!–{assign var=key value=”memo01″}–>
<td><textarea name=”<!–{$key}–>” cols=”60″ rows=”5″><!–{$arrForm[$key].value}–></textarea></td>
</tr>
[/html]

2:対象クラスを拡張
data/class_extends/pages/admin/basis/LC_Page_Admin_Basis_PaymentInput_Ex.php
フォームの内容を追加するためlfInitParamをオーバーライド
[PHP]function lfInitParam($mode, &$objFormParam) {
parent::lfInitParam($mode,$objFormParam);
$objFormParam->addParam(“説明”, “memo01”, STEXT_LEN, ‘KVa’, array(“SPTAB_CHECK”, “MAX_LENGTH_CHECK”));
}[/PHP]

3:公開側のテンプレートを編集
data/Smarty/templates/default/shopping/payment.tmpl
[html]
<!–{section name=cnt loop=$arrPayment}–>
<!–{$arrPayment[cnt].payment_memo01|h}–>
<!–{/section}–>
[/html]
※section ってよくわからないな。。foreachにしたい。。

4:データベースから値を持ってくるようにHelper_Purchase_Exクラスを編集
data/class_extends/helper_extends/SC_Helper_Purchase_Ex.php
getPaymentsByPriceをオーバーライドし、クエリにmemo01も入れるようにする
[php]
function getPaymentsByPrice($total,$deliv_id){
//省略
$payments = $objQuery->select(“payment_id, payment_method, rule, upper_rule, note, payment_image, charge, memo01”, “dtb_payment”, $where, $arrPaymentIds);
//省略
}[/php]

JQuery Balloonプラグイン: balloonの消し方

追記:2012/02/17

jquery.balloon.jsはバージョンアップされているようですのでそちらをお使いください。

追記ココマデ

ツールチップを表示するこちらのJQueryプラグイン「jquery.balloon.js」について動的に消したいのになかなか消せなかったのでメモ。

経緯:

削除ボタンがあって、そのボタンにマウスをあわせると「削除する」とツールチップを表示するために上記のプラグインを用いていたのですが、クリック時にボタン自体を消したら、ツールチップだけ画面に残ってしまった。

解決:

Balloonにはballoonを設定したオブジェクトに対し、data(“balloon”)で取得できる模様。

[javascript]
deleteBtn.click(function(){
$(this).data(“balloon”).remove();
});
deleteBtn.balloon();
[/javascript]

 

追記2011/11/11

 

上記の方法では不十分。消した後、ブラウザの画面サイズを変更するjavascriptエラーがでる。
理由はツールチップを表示したときに$.balloon.instancesに配列を追加していて、window.resizeイベントでそれらの配列の要素にアクセスしているため。

本当は拡張したかったのだが、面倒だったので直接プラグインに変更を加えた。

1:$.balloonにメソッドを二つ追加。

2:配列に常に突っ込むのをやめて、重複していないかのチェックをするように変更。

 

追記2 2011/11/11

と思ったが、adjustBalloonで位置が設定できない現象が。理由はこのメソッドが呼ばれたときに要素が表示されていないこと。表示する瞬間に位置情報を計算したほうがよいのではないかと思い、再び改造。

showメソッドの中で計算した。それによって$.balloon.instances関連のものが必要なくなった。

誰の助けになるかわかりませんが一応ソースを張っておきます。

 

EC-CUBE2.11(session_set_save_handler)+Ajaxでセッションがうまくいかない件。

2日悩んでまだうまくいっていないことですが、とりあえずこれまでわかったことをメモします。
※この情報は間違っている可能性が高いです。

EC-CUBEでは2.11ではセッション情報をデータベースに保存している。
通常、商品をカートに入れる際にはカートのページにリダイレクトされ、セッション情報にカートの内容が保存される。

カートの追加をAjaxで実装したところ、連続して複数の商品をカートに追加すると、タイミングによってカートに追加されない商品があるという現象が起きた。EC-CUBE2.11ではSC_Helper_Sessionクラスにてsession_set_save_handlerが呼ばれ、セッションに対して起こるイベント用のようなものが定義されて、オリジナルの処理(データベースへセッション情報を書く処理)がかかれている。

こうすることによって単純に$_SESSIONにプロパティをセットするだけでデータベースにセッション情報を残すことができる。

原因を探っていくと、どうやら$_SESSIONを操作した際に、その都度登録した処理(データベースへ書き込む処理)が呼ばれるわけではないことで、たとえばその処理の中で一度$_SESSIONを読み込み、それに対して何かを付けたし、そして再度$_SESSIONに書き込むというような処理を入れることが原因のようだ。

EC-CUBEではカートにある商品をID(連番の)で処理しているようなのだが、次の商品がカートに追加されるたびに一番最後のID(数字)に1を足して処理している。そのためカートに追加する際に一度カートの内容を読み込み、追加し、書き込むという処理をする。

Ajaxを使うことで「読み込み」「読み込み」「書き込み」という処理がありえるので、商品が0のときは「次はID:1」「次もID:1」「IDが二つかぶるので2つめのみ追加」となる。

通常は「読み込み」から「書き込み」まで同じ行に対する処理をロックできるので問題は起こらないのだが、読み込みは読み込み、書き込みは書き込みとデータベースへのアクセスが別々になっていることでこのようなことになってしまっている模様。

その辺のトランザクションを何とかするか。セッションを連番で処理するのを何とかするか。

どうすれば最善か。まだ考察中です。

追記(2011/11/10)

Ajaxを使うことで「読み込み」「読み込み」「書き込み」という処理がありえるので、商品が0のときは「次はID:1」「次もID:1」「IDが二つかぶるので2つめのみ追加」となる。

さらに調査した結果、こういうことではないようだ。

IDがかぶるから上書きされるのではなく、セッションが書き込まれるときには
「すべてを読み込み」→「変更(追加)」→「すべてを書き込み」となるので、
たとえばAが入っているセッションにB,Cを書き込みたい場合
「A」を読み込んでそれに「B」を足して「A,B」となり、それを書き込む前に「A」を読み込み「C」を足して「A,C」となり、最終的に「A,C」となってしまうということらしい。

これはsession_set_save_handlerでデータベースを使う際にまれにある現象らしい。
http://xoops.ec-cube.net/modules/newbb/viewtopic.php?viewmode=thread&topic_id=8247&forum=2&post_id=39923#forumpost39923
http://svn.ec-cube.net/open_trac/ticket/571

追記2(2011/11/11)

結局、非同期通信を行う場合、session_set_save_handlerを使うと読み込みと書き込みが入れ子になり、上記のような現象になることは避けられなかった。

また、Ajax側で通信を順番に行うようにすることでこれを回避することができた。
具体的には商品をaddしたときにqueueに追加し、順番に処理していく。

また処理が終わったらカートをリフレッシュしていたのだが、コレもまずかった。

カートのリフレッシュ時には当然最新のカートの情報を取得するのだが、それもこの現象の原因になった。
つまり読み込むだけであっても通信が入れ子になることでセッションの同期が取れず、セッション関連がある通信は常に順番に確実に行う必要がある。

session_set_save_handlerを使用しないような実装も考えたが、EC-CUBEの保守がややこしいことになりそうなのでやめた。

通信をすべて順番に行うことで、問題を解決することにした。

  1. 商品を追加ボタンを押す
  2. queueに追加
  3. queueがひとつだけならqueueを開始
  4. ajaxでpost
  5. javascriptでカートに追加中の表示(追加ボタンをロード中にし、カートに商品を半透明で追加表示)
  6. 応答があったら本当にカートに入っているかを一度チェックする
  7. 成功ならカートに追加済みの表示:失敗ならすべてを元に戻す。
  8. queueがまだあるなら次のqueueを開始し、4へ戻る。

追記3(2011/11/11)

resize_image.phpを動かすと、セッションが上書きされるようだ。なんで、画像をリサイズするためにセッションを操作しているのか不明。。
なんだか動作ももたつくので使用するのをやめた。