SendPDF for contact form 7 は、WordPressのメールフォームプラグイン「Contact form 7」の機能拡張プラグインで、メールフォームに入力されたデータを使ってPDFファイルを出力、メールに添付して送付することができる。
mPDFというPHPプラグインを使っていて、HTMLからPDFを生成できるため、設定などのハードルが低くて使いやすい。
ただ、mPDFの問題として、CJKフォントが使われているため、出力される漢字が中華フォントになってしまう問題がある。
また、いくつかの漢字、記号、全角の英数字のフォントがなく、PDFプレビューや出力時に豆腐*1もしくは空白となってしまう。
過去に「追加して」とお願いしたことはあるものの、なしのつぶてなので自力でどうにかすることにした。
なお、過去2回ほど挑戦して失敗、3度目の正直で何とかなったのでここに記録しておくことにした。おそらくmPDFそのものを使っている人にもある程度役に立つのではないかと思います。
作業内容
0 記録時点の環境について
- PHP 7.4
- WordPress 6.1.1
- SendPDF for contact form 7 0.9.9.1
- mPDF 8.0
1 追加するフォントの用意
ttf形式のフォントしか使えなさそうなので、IPAフォントを使います。
IPA Font ダウンロード | 一般社団法人 文字情報技術促進協議会
今回使ったのはIPA P 明朝とPゴシックの2つ。
ダウンロードしたzipファイルを展開。
プラグインの /mpdf/vendor/mpdf/mpdf/ttfonts/
にコピー。
2 FontVariables.php の修正
/mpdf/vendor/mpdf/mpdf/src/Config/FontVariables.php
において、以下のコードを修正する。
'fontdata' => [
で始まるリストに登録したフォントを追加する。
/* CJK fonts */
の後ろあたりに以下を追加。
'ipamp' => [/* Japanese */
'R' => "ipamp.ttf",
],
'ipagp' => [
'R' => "ipagp.ttf",
],
あと、こちらは不要かもしれないけど 、
'backupSubsFont' => ['dejavusanscondensed', 'freesans', 'sun-exta'],
を
'backupSubsFont' => ['dejavusanscondensed', 'freesans', 'ipamp', 'sun-exta'],
に。
'backupSIPFont' => 'sun-extb',
を
'backupSIPFont' => ['ipagp', 'sun-extb'],
に変更。
コードのコメントを見ると、「useSubstitutionsを使用する際に欠落している文字に使用するフォントを設定する」「useSubstitutionsを使用する際、CJK文字に使うフォントを設定する」とある。
ただこの、"useSubstitutions" というのは、ConfigVariables.phpにて、
// Substitute missing characters in UTF-8(multibyte) documents - from other fonts
'useSubstitutions' => false,
とあったので、この設定は多分機能しないと思う。
3 LanguageToFont.phpの修正
/mpdf/vendor/mpdf/mpdf/src/Language/LanguageToFont.php
の、以下のコードを修正。
これは日本語を出力するときに使う可能性があるフォントの一覧らしい。優先適用したいフォントを追加した。
case 'ja':
case 'jpn': // Japanese HIRAGANA KATAKANA
$unifont = 'sun-exta';
if ($adobeCJK) {
$unifont = 'sjis';
}
break;
を
case 'ja':
case 'jpn': // Japanese HIRAGANA KATAKANA
$unifont = 'ipamp';
if ($adobeCJK) {
$unifont = 'ipamp,ipagp,sjis';
}
break;
に。
4 lang2fonts.cssの修正
/mpdf/vendor/mpdf/mpdf/data/lang2fonts.css
の以下のコードを修正。
:lang("ja"), :lang("jpn") { /* Japanese HIRAGANA KATAKANA */
font-family: sun-exta, sjis;
}
を
:lang("ja"), :lang("jpn") { /* Japanese HIRAGANA KATAKANA */
font-family: ipamp, ipagp, sjis;
}
に。
5 send-pdf.phpの修正
/classes/send-pdf.php
のfunction wpcf7pdf_getFontsTab()
にあるリストに以下を追加。
'IPA-gp' => 'ipagp',
'IPA-mp' => 'ipamp',
こちらは管理画面のフォントの選択リストに入る。
残る問題
中華フォントはそのまま
上記の作業を行い、テストサイトでとりあえず豆腐が出なくなることを確認。制作者さんはgithubで開発していたため、プルリクエストを送信した。
ただ、上記の作業を行っても、IPAフォントが適用されるのは不足している字体に対してだけである。豆腐はなくなるが大半の漢字は依然として中華フォントのまま。
この問題を解決するには以下のコードを修正する。
上記手順2番目に修正した、/mpdf/vendor/mpdf/mpdf/src/Config/FontVariables.php
において、
"sun-exta" => [
'R' => "Sun-ExtA.ttf",
'sip-ext' => 'sun-extb', /* SIP=Plane2 Unicode (extension B) */
],
"sun-extb" => [
'R' => "Sun-ExtB.ttf",
],
を
"sun-exta" => [
'R' => "ipamp.ttf",
'sip-ext' => 'sun-extb', /* SIP=Plane2 Unicode (extension B) */
],
"sun-extb" => [
'R' => "ipamp.ttf",
],
に。
これでデフォルトがIPA P明朝となる。
これをプルリクに入れなかったのは、このsun-exta, sun-extbというのが中国、韓国のユーザーに対しても影響すると思われるから。
いっそのこと、この変更を加えたものを、日本語専用のプラグインとして独立させようかと思っている。
ver. 0.9.6 以降は別の問題もある
上記の日本語の問題とは無関係だが、ver. 0.9.6 以降、チェックボックスとラジオボタンの値に2バイト文字があるとPDFに出力されないという問題が発生している。(ver. 0.9.9.1 の時点でも未解決)
一度はデバッグされて、値が1バイト文字列、または2バイト文字列のみの場合は出力され、1バイト文字と2バイト文字が混ざっていると出力されないという不思議な状態になっていたが、0.9.9.1では2バイト文字列があると出力されない状態になっている。
参考にした記事
最大限の感謝を。
mpdfで利用するfontをライブラリ外から指定する方法 - Qiita
mPDF、フォント(.ttf)を追加する|マコトのおもちゃ箱 ~ぼへぼへ自営業者の技術メモ~
mpdfで日本語のフォントを追加したり、文字化けを回避したり - tohokuaikiのチラシの裏
PHPからHTML形式の記述でPDFファイルを作るmpdfの使い方と日本語フォントの指定方法 | ゆうそうとITブログ