MODX EvolutionのDittoCalの文字化け対策
MODX Evolution 1.0.7Jを構築して、カレンダー表示させたかったので、DittoCalをダウンロードしてinstallationの通りにスニペットを作成したが、UTF-8で構築しているのにも関わらず年、月の文字列が文字化けを起こしてしまう。http://forum.modx.jp/viewtopic.php?f=7&t=283の解決策のようにするこで解決することも可能だが、いまいち納得できずにいたのでソースをみたところ、以下の点がわかった。
- PHPマニュアルによるとhtmlentitiesは文字コードの指定がないとPHP5.3以下ではISO-8859-1として解釈する(動作環境ではPHP5.2)。そのためUTF-8文字列が変換されてしまうようだ(PHP5.4以降はUTF-8になるとのこと)。
- 曜日の文字列をdayNameLengthで切りつめるがその際substr()を使用している。マルチバイトの場合はmb_substr()を使用するべきで、かつ文字コードの指定は内部文字エンコーディングに依存する。
よって、htmlentitiesにUTF-8を指定すること、substr()をmb_substr()に変更して文字コードもハードコーディングしてみたところうまくいった。
--- snippet.DittoCal.php.org 2007-11-02 18:51:46.000000000 +0900 +++ snippet.DittoCal.php 2012-12-06 15:09:58.000000000 +0900 @@ -319,7 +319,7 @@ list($month, $year, $month_name, $weekday) = explode(',',gmstrftime('%m,%Y,%B,%w',$first_of_month)); $weekday = ($weekday + 7 - $first_day) % 7; #adjust for $first_day - $title = htmlentities(ucfirst($month_name)).' '.$year; #note that some locales don't capitalize month and day names + $title = htmlentities(ucfirst($month_name), ENT_COMPAT | ENT_HTML401, 'UTF-8').' / '.$year; #note that some locales don't capitalize month and day names #Begin calendar. Uses a real <caption>. See http://diveintomark.org/archives/2002/07/03 @list($p, $pl) = each($pn); @list($n, $nl) = each($pn); #previous and next links, if applicable @@ -331,7 +331,7 @@ if($day_name_length){ #if the day names should be shown ($day_name_length > 0) #if day_name_length is >3, the full name of the day will be printed foreach($day_names as $d) - $calendar .= '<th abbr="'.htmlentities($d).'">'.htmlentities($day_name_length < 4 ? substr($d,0,$day_name_length) : $d).'</th>'; + $calendar .= '<th abbr="'.htmlentities($d, ENT_COMPAT | ENT_HTML401, 'UTF-8').'">'.htmlentities($day_name_length < 4 ? mb_substr($d,0,$day_name_length, 'UTF-8') : $d, ENT_COMPAT | ENT_HTML401, 'UTF-8').'</th>'; $calendar .= "</tr>\n<tr>"; }
以下のようにコンテンツに指定しても大丈夫だ。
[!DittoCal?&calSource=`16`&setLocal=`ja_JP.UTF-8`&futureDate=`1`&dayNameLength=`1`!]