pico の survey プラグインで遊ぼう!の picoSurveyAssistant を書いていて気づいたんですが、pico の formmail プラグインで、checkbox や radio が複数あるフォームの場合、最初の要素の legend が、以降すべての checkbox と radio のタイトルとして、メールで送られているようでした。
で、/trust_path/modules/pico/class/FormProcessByHtml.class.php の 132 行目あたりをチェックしてみました。
// search the nearest <regend> for radio/checkbox
if( preg_match( '#<fieldset.*'.preg_quote($tag).'.*</fieldset>#isU' , $form_html , $regs ) ) {
if( preg_match( '#<legend[^>]*>([^<]+)</legend>#' , $regs[0] , $sub_regs ) ) {
$label = strip_tags( @$sub_regs[1] ) ;
}
}
これを下記のようにしてみたところ、目的の legend の値が、タイトルになって送られたように思われます。
#あっ、コメントにも typo が…… ^^;
// search the nearest <legend> for radio/checkbox
if( preg_match( '#<fieldset.*'.preg_quote($tag).'.*</fieldset>#isU' , $form_html , $regs ) ) {
if( preg_match_all( '#<legend[^>]*>([^<]+)</legend>#' , $regs[0] , $sub_regs ) ) {
$sub_regs_tmp = isset( $sub_regs[1] ) ? array_pop( $sub_regs[1] ) : '' ;
$label = strip_tags( $sub_regs_tmp ) ;
}
}
これが最良の措置かどうかわからないのですが、ご報告まで〜。
Quote:
jidaikobo wrotes:
pico の survey プラグインで遊ぼう!の picoSurveyAssistant を書いていて気づいたんですが、pico の formmail プラグインで、checkbox や radio が複数あるフォームの場合、最初の要素の legend が、以降すべての checkbox と radio のタイトルとして、メールで送られているようでした。
本当ですね
<fieldset>と<legend>の間に</fieldset>が見つかったら終了、って正規表現がパッと書けなかったので、preg_split()でいったん分割しました。
1.75aを試してみてください。
# いただいたコードが悪いってことはないのですが、<fieldset>のブロックという概念から外れてしまうので。
## コメントのtypoも修正しました
jidaikobo です。
Quote:
GIJOE wrotes:
<fieldset>と<legend>の間に</fieldset>が見つかったら終了、って正規表現がパッと書けなかったので、preg_split()でいったん分割しました。
1.75aを試してみてください。
試してみました。バッチリです
Quote:
# いただいたコードが悪いってことはないのですが、<fieldset>のブロックという概念から外れてしまうので。
いや、おっしゃる通りだと思います。
そういう論理一貫性があると気持ちいいですね。
この form 解析の仕組みも、ソースコードを拝見して、とても考え方の参考になりました。
ご対応ありがとうございました〜。
こんにちは、こちらに投稿させて頂くのは初めてです。いつもpico使わせて頂いております。
すでに解決済みのところ恐縮なのですが、
Quote:
<fieldset>と<legend>の間に</fieldset>が見つかったら終了、って正規表現がパッと書けなかったので、preg_split()でいったん分割しました。
ここ、私は否定先読みを使って
if( preg_match( '#<fieldset(?:(?!fieldset).)*'.preg_quote($tag).'.*</fieldset>#isU' , $form_html , $regs ) ) {
とやってました。一応これで上手くいくかと思います。
実は1.60くらいでバグかな?と思っていたのですが、なんやかんやで先送りになってました。その時点でご報告していればよかったですね・・・
ditamineさん、こんにちは。
Quote:
ここ、私は否定先読みを使ってif( preg_match( '#<fieldset(?:(?!fieldset).)*'.preg_quote($tag).'.*</fieldset>#isU' , $form_html , $regs ) ) {
とやってました。一応これで上手くいくかと思います。
ありがとうございます。
否定先読み苦手なんですよね
今回はこのまま行きますが、今後何かの折には役立たせていただきます。
Quote:
実は1.60くらいでバグかな?と思っていたのですが、なんやかんやで先送りになってました。その時点でご報告していればよかったですね・・・
ぜひお気軽にバグ報告ください
jidaikobo です。
しつこく FormProcessByHtml.class.php の件ですが、ひとつ気づいたことがあります。
134行目、
if( strstr( $fieldsetblock , $tag ) && preg_match( '#<legend[^>]*>([^<]+)</legend>#' , $fieldsetblock , $sub_regs ) ) {
ですが、legend の中で、html のタグが出てきたときに、legend の値を取得しないようになっているとおもいます。
でも、legend 自体は、DTD としては、中になにか要素がきてもいい要素(*)なので、たとえば span、strong とかがくると、値を取得できなくなります。
フォームの html 側でいくらでも回避方法はあるのですが、せっかく自由に html がかける仕組みですし、
if( strstr( $fieldsetblock , $tag ) && preg_match( '#<legend[^>]*>(.+)</legend>#' , $fieldsetblock , $sub_regs ) ) {
としちゃうとマズいでしょうか?
あいかわらず、なにか勘違いしてたらすみません……
* %inline だからインライン要素限定ですが。