MJHD

エモさ駆動開発

FuelPHPのemailで日本語メールを送る際に気を付けること

マルチバイト環境でFuelPHPのemailを使う際、いくつか気を付けなければいけない問題がある。

今回想定している環境は、以下。

  • FuelPHP 1.8
  • UTF8でメールを送りたい
  • HTMLメールを送りたい

 

自動改行処理を止める(あるいは、改善する)

FuelPHPのemailパッケージには、自動改行処理を行う部分がある。

デフォルトでは76文字で改行を行ってくれるのだが、この際に使用している関数がPHP標準のwordwrap関数。この関数はマルチバイト文字に対応していないため、改行付近で文字化けするという痛い問題が発生する。

自動改行処理を止めるには、/fuel/core/config/email.phpを/fuel/app/config/email.phpとしてコピーをし、


 'wordwrap' = 76,

となっている部分を、


 'wordwrap' = false,

と書き換える。

もし、自動改行処理は有効にしたいけど、文字化けを解消したいという方は、emailクラスを編集して、マルチバイトに対応させる必要がある。

具体的には、/fuel/packages/email/classes/email/driver.phpのwordwrapを呼び出している箇所(おそらく二か所)を、[PHP]マルチバイト対応のwordwrapが無いから作った - Qiitaこういったものに置き換える必要がある。

 

 代替テキストの生成を止める

HTMLメールを送る際、emailパッケージは親切にプレーンテキスト版を自動生成し、一緒に送信してくれる。

受信したクライアントは、HTML版、プレーンテキスト版の二つから好きな方を表示することができる便利な機能である。

しかし、メールの見た目を統一したいなどの理由で、代替テキストが表示されてほしくない場面もある。

この場合、/fuel/app/config/email.phpを編集し、'generate_alt'の欄をfalseに設定すればよいのだが、

日本語を送る関係で'encoding'に"quoted-printable"や"base64"を指定している場合、正常に表示ができなくなる。

これは、何故かemailパッケージが"Content-Transfer-Encoding"のヘッダーを出力しないためであり、

/fuel/packages/email/classes/email/driver.phpの以下の箇所を編集することで対応が可能。


protected function build_message($no_bbc = false)
{<
    ...中略...
    $parts = array('Date', 'Return-Path', ...中略..., 'Content-Type');

となっている部分を、以下のように変更する。


    protected function build_message($no_bbc = false)
    {
    ...中略...
    $parts = array('Date', 'Return-Path', ...中略..., 'Content-Type', 'Content-Transfer-Encoding'); // 追加した

これで、正常に表示ができるようになる。

最高のXiaomi Notebook Air 13.3を購入した

もともとはMacBookAir13を4年間使っていたのだが、macOS sierraにアップデートしてから様々な問題にぶち当たり、Macが少しだけ嫌いになったのと、もともとメモリ4GBしかなかったため流石にしんどくなってきたので、新しいPCを買うことに。

中国メーカーXiaomiが出しているMacBookAirもろリスペクトのノートPC、「Xiomi Notebook Air」を購入した。

安い

gearbestで購入したのだが、記事執筆時の値段は$809.99=「9.17万円」

スペックは後述するが、この性能でこの値段はなかなかない。

www.gearbest.com

スペック

CPU: Intel Core i5 2.3GHz(最大2.8GHz) 物理2コア

GPUGeForce GT 940MX 1GB

SSD: サムスン製 256GB

RAM: 8GB(アップグレード不可、はんだ付け)

バッテリー: 5400mAh (USB Type-Cポートを使用して充電、30分ほどで充電完了、5時間ほど持つ)

外部ポート: HDMI、イヤホン/マイク共用ジャック、USB Type-C、USB3 x 2

WiFiIntel(R) Dual Band Wireless-AC 8260、802.11n

Bluetooth: 4.1

ディスプレイ: 1920x1080 IPS 13.3inch

スピーカー: AKG speaker with Dolby Audio Premium Surround Sound(かなり良い)

OS:

Windows10 Homeの中国語版がプリインストールされている。日本語版をクリーンインストールすることでアクティベーション可能。

開封の儀

f:id:wait0000:20161111113154j:plain

f:id:wait0000:20161111113344j:plain

f:id:wait0000:20161111113426j:plain

これまたMacBookAirっぽい箱の中に、フィルムにくるまった状態で入っていた。

付属品は簡単な説明書と充電用アダプタだけだった。

充電用アダプタは前述したとおり、USB Type-Cの形状をしており、幅広い機器に使えるもののようだ。

手に持った感じ、MacBookAirと重さは変わらなかった。大きさは若干Xiaomi NotebookAirの方が小さかった。

 

ちゃんと最後まで開封してみた。

f:id:wait0000:20161111121341j:plain

ファンはCPU用とGPU用の二つ。

SSDスロットは拡張用含めて二つ。

スピーカーも二つ確認できた。

 

以下、使ってみての感想。

スピーカーが良い

一番感動しているのがココ。AKG製のスピーカーが背面に2つ入っているのだが、Dolbyのサラウンド対応ということで音がヤバイ。語彙力がないのでヤバイしか言えないのだが、映画などを観るとその凄さがよくわかる。

目の前のパソコンから音が出ているとは思えない…。

このPCを購入してから、イヤホンをほとんど使わなくなってしまった。

 

キーボード

MacBookAirのキーボードがグッグッなら、Xiaomi Notebook Airはパタパタという感じ。

打鍵音は大きめ、またキーの打鍵感も大きいので少し指がつかれるかも。

それでも打鍵感がかなり良く、打っていて楽しい。

 

デザインはほぼほぼMacBookAir

背面にリンゴがいない以外、ほぼほぼMacBookAir。

アルミ感満載なところ、キーにLEDがついてるところ、トラックパッドに関してはまったく同じ見た目。

 

f:id:wait0000:20161111113657j:plain

 

f:id:wait0000:20161111113724j:plain

f:id:wait0000:20161111114144j:plain

 

軽いしバッテリーのもちもいいし性能もいいし安いし、大満足。

最高のBoW(Bash on Ubuntu on Windows)環境のために

最近、Macを捨ててWindowsに乗り換えた。その際に、Macで使用していたCUIにより開発環境をできるだけWindowsに移植できないかと考えた。

BoW(Bash on Ubuntu on Windows)

BoWは、Windows10よりベータ版として提供された、Windows上でLinuxバイナリを実行することができる仕組み。

仮想環境よりもっとミニマルで、内部的にはWindows上で動作するUbuntu互換のAPIを実装している模様。

つまり、Linuxマシン語をネイティブに実行することができるということ。(しっかりとWindowsのプロセスとして立ち上がる)

このBoW環境が思ったよりもしっかりとしていたため、開発環境を整えてみた。

どんな見た目?

デスクトップにおいたリンクから端末を起動することができる。

 

X11に対応しているので、GUIも使える。

 

インストールすべきもの

まず、BoWのインストールが済んでいることが前提。

 

qiita.com

こちらを参考に。

 

次に、VcXsrvをインストールする。これは、X11互換のサーバであり、GUIを表示するために必要。(Xmingをおススメしているサイトが多いが、こちらのほうが安定している)

sourceforge.net

 インストールが終わったら、スタートアップとして登録しておこう。

BoWにて

まず、Win+Rボタンを押し「cmd」と入力しエンターを押す。

コマンドプロンプトが立ち上がるので、ここに「bash」と入力する。これでBoW環境に入ることができる。

ここで、以下のコマンドを実行しよう。

 

sudo apt-get install aptitude
sudo aptitude install gnome-terminal

 これで、gnome-terminalというターミナルエミュレータが入った。

bash上で、「gnome-terminal」と入力することで、新しい端末が立ち上がる。

 

また、日本語入力ができるよう、以下のコマンドも実行しよう。

sudo aptitude install uim-fep uim-anthy

そして~/.uimを作成し、以下の内容を記述しよう。キーバインドなどは自由でおk。

(define default-im-name 'anthy)
(define-key generic-on-key? '(" "))
(define-key generic-off-key? '(" "))

 

次に、zshを入れよう。

sudo aptitude install zsh

 

あとは好みに応じて、各自のdotfilesを入れるといいと思う。

使いやすく

この時点で、~/.bashrcを編集し、以下のように書き足そう。


export DISPLAY=localhost:0.0
export XMODIFIERS=@im=uim

if [ -t 1 ]; then
	 exec gnome-terminal -x uim-fep -e zsh
fi

 

 

これにより、bashコマンドを叩くとすぐにgnome-terminal上でuim-fepzshを起動することができるようになる。

また、以下のようなファイルを作成することで、cmdを非表示にしたまま、gnome-terminalだけを起動することができる。

terminal.vbs

Set ws = CreateObject("Wscript.Shell")
ws.run "bash", vbhide

 

あとは煮るなり焼くなり、好きなように環境設定をしよう。

 

mysqlapacheなどの個人的に必要なソフトウェアも、serviceコマンドから実行できるようなので、逆に他に何がほしいの?というレベル。

MacからWindowsに乗り換えるタイミングとしては最適だったように思える。

 

AirPrintをXamarin Androidに載っけてみた

 

mjhd.hatenablog.com

 

の記事にて、BMPからUNIRASTへの変換が完了した。

あとは、BonjourとIPPを実装すれば理論上はXamarin AndroidからAirPrintができるはず。

ということで実装してみた。

 

Bonjour

Bonjourは、ネットワーク上のデバイスを探すためのプロトコルのよう。

NuGetにPCLでも使えるBonjourライブラリがあったため、今回はこれを使用する。

www.nuget.org

例えば、ネットワーク上にあるプリンタを列挙したい場合、以下のようなコードを書くことで可能になる。

 

 


    var printer_search = ZeroconfResolver.ResolveAsync("_printer._tcp.local.");
    printer_search.Wait();
    var printers = printer_search.Result;
    foreach(var printer in printers)
      Console.WriteLine(printer);

IPP

AirPrintは実際はIPPを使用して印刷している。

IPPはHTTP上に実装された印刷を制御するためのプロトコル。HTTP上でやりとりが行われているため、プロクシやらSSLやら何やら、HTTPで使用できる技術の恩恵が受けられる点が強みらしい。

遠隔地からの印刷なども、HTTPさえ繋がれば可能になる。

 

今回は、以下のプロジェクトを参考に、IPPをある程度実装した。

github.com

IPPは以下のような書式になっている。(全てビッグエンディアン)

 

Major Version                                 1byte

Minor Version                                 1byte

Operation ID または Status Code  2byte (送信はOperationID、受信はStatusCode)

Request ID                                     4byte (1以上、リクエスト毎の連番)

-- Group

Group ID                                        1byte

-- Attribute

Tag ID                                             1byte

Name Length                                  2byte

Name                                              (Name Length)byte

Value Length                                   2byte

Value                                              (Value Length)byte

Tag ID

-- Attributeの繰り返し

-- Groupの繰り返し

0x03(EndOfAttribute Group ID)      1byte

Groupは、Attributeの集合。操作に関するIDや、ジョブに関するIDなど、Attributeの種類に応じてグループが存在する。

 

Attributeは、実際の値の集合となっている。この辺からかなり複雑になってくるので、割愛。

 

実際のやりとりは、プリンタに対して行いたい操作をOperation IDとしてセットし、詳しい設定をAttributeとしてセット、そして送信する。

その後、帰ってきたIPPデータを読み取り、Status CodeがSuccessなどだったら、Attributeを読み込み、結果を取得する。

という流れになる。

 

今回は、プリンタの情報を取得するGet-Printer-Attributes操作と、ジョブの有効性を判定するValidate-Job操作、実際に印刷をするPrint-Job操作、印刷の状況を取得するGet-Job-Attribute操作を実装した。

 

## ソースコード

https://github.com/mj-hd/AirPrint.NET

 

結果

以上、すべてのソースコードがPCL上で完結しているため、Xamarin上で使用することができる。

そして、無事、Xamarin AndroidからAirPrint対応プリンタを通して印刷が行えた。

 

これにより何が嬉しいかというと、Android標準の印刷ダイアログを表示せずに印刷を行うことができる。

Android標準の印刷機能を使うと、どうしてもユーザに印刷ボタンを押す操作をしてもらう必要が出てしまうため、回避するためにはこう言った工夫が必要なのだと思う。

 

今後の課題

今現在は多くの印刷に関する設定を、プリンタのデフォルト値にしているため、プリンタによって印刷結果が変わってしまうことがある。

この辺どうにかしたい。けど、テストできるプリンタがない…。

 

追記:

実は、AirPrintはBonjourを使うとも限らないようで、自分が探した中にも、Bonjour以外の方法でしか探すことのできないプリンタがあった。どういった方法で探索しているかは、ベンダしか知らないようなので、今回の方法ではすべてのプリンタを探索できるわけではないということが分かった。

探索できない場合は、手動でIPアドレスを指定するようにした。

UNIRASTをC#で実装してみる

UNIRASTという画像形式がある。

AirPrintなどで使われている形式のようで、Appleが独自開発をしたもののようだ。公式なドキュメントは見当たらないが、リバースエンジニアリングしたものがGitHub上にたくさん転がっていたので、それをC#で書き直してみた。

 

目標は、BMP形式から、URF(UNIRAST)形式へ相互変換できること。

UNIRAST

UNIRASTは、以下のようなフォーマットになっている。

 

github.com

 

TIFFに結構近い模様。

ファイルは、

"UNIRAST\0" 12byte (\0は0x00)

Page Count    4byte   (ページ数)

から始まる。

この後、各ページが格納される。

各ページは以下のヘッダから始まる。

Bit Per Pixel   1byte   (深度)

Color Space   1byte   (なんだろ?)

Duplex Mode  1byte   (両面印刷)

Quality            1byte   (印刷クオリティ)

-                      4byte

-                      4byte 

Width              4byte  (横幅)

Height             4byte  (縦幅)

DPI                  4byte

-                      4byte

-                      4byte 

それぞれのページ毎に形式の違うデータを格納できるよう。

 

そしてその後各ページのピクセルデータが続く。

ピクセルデータは、以下のような書式になっている。

Line Repeat Count   1byte (一行のピクセルデータを、何回繰り返すか)

PackBit                     1byte (後述)

Pixel Data                 Bit Per Pixel分 (RGBが入る)

...

PackBit                     1byte

...(PackBitとPixelDataが、右端まで続く)

Line Repeat Count    1byte

...(Line Repeat Countが、下端まで続く)

Line Repeat Countは、一行のピクセルデータを何回繰り返すかを表しており、たとえば3だった場合は、次から始まる一行のデータを4行繰り返す。

 

PickBitは、TIFFで使われているアルゴリズムのようで、この値により後に現れるピクセルデータの扱いが変わる。

0x00-0x7Fの場合、後に現れるピクセルデータを、PackBit+1回だけ繰り返す。

0x80の場合、その時点から右端までデータは空白になる。真っ白。

0x81-0xFFの場合、後に現れるピクセルデータを、PackBit - 0x80個そのまま取り出す。

 

以上でUNIRAST形式のファイルを生成することができる。

## ソースコード

https://github.com/mj-hd/AirPrint.NET

法人を立ち上げる手順

実際に法人を立ち上げてみて、その手順のメモ。

ちなみに、私は大学生なので、近い境遇で起業を考えてる人などの参考になれば。

 

前提

  • 学生
  • 合同会社
  • 共同設立者あり
  • 報酬あり
  • 紙定款

 

準備

法人登記にあたって必要なものは以下。

  • 代表社員個人の印鑑登録証明書
  • 各役員の年金手帳
  • 法人の印鑑
  • 出資金
  • 出資金を入れる口座の通帳
  • CD-R
  • ある程度のお金(収入印紙代など)

まずやること

もし住民票の住所が現在のものと違うなら、変更しておこう。

また、印鑑登録なども済んでいなければ、市役所へ行き登録してこよう。

決めておくこと

  • 事業年度
  • 役員報酬額

事業年度は、会社設立日よりも前の日付を設定しよう。そうでないと、会社設立直後に年度末が来てしまう。

役員報酬額は、きちんと社会保険料なども考慮して、資本金と相談して決めよう。特に、最初の数ヶ月間はキャッシュが不足する。

法人の印鑑

法人の印鑑を購入すること。法人の印鑑は三点セットになっており、銀行印、社印、代表者印の役割がある。(4点セットの場合もある)

ネットで数千円ほどで購入できる。

おそらく、注文してから届くまでに1週間ほど必要なため、この間に定款の作成を始めよう。

定款

合同会社においては、定款認証なども要らず、あまり精査されない。よって、ある程度書いておけばまず問題はない。

ネット上で見つかる、合同会社用の定款のテンプレートをもとに、作成しよう。

inqup.com

代表社員を定める文言について、当初は「当会社の代表社員は,社員の互選によって定める。」と記載していたが、法務局の人によると「きちんと、ここで記載してしておいた方がいいよ」とのことだったため、「当会社の代表社員は,○○○○とする。」と明記しておいた。

 また、社員の氏名などは、苗字と名前の間にスペースを空けないなど、細かなルールがあるようだ。

作成が終わったら、印刷し、製本テープを使い製本した後に、以下の箇所に印鑑を押す。

  • 最後のページ、自分の名前の隣に各個人の印
  • 最後のページ、右下余白部分に各個人の印(捨印)
  • 定款表紙、製本テープと定款の境目に各個人の印(割印)
  • 定款裏表紙、製本テープと定款の境目に各個人の印

これで、定款は完成。

データは後々何度も使うことになるので、取っておこう。

また、定款提出後は定款の内容の変更がない限り、上書き保存はしないように気をつけよう。

法人登記申請書

本店所在地及び資本金決定書

払込証明書

この辺はみんなこれを参考に書けばOK。

inqup.com

ただし、一つの書類が複数枚に分かれる場合は、きちんと割印を押そう。

例えば、振り込みを証明するものは、複数枚に分かれることになると思うので、

簡単なものであれば、左側を二か所ホチキスで止め、各ページの境目(一枚めくった真ん中)に代表社員の印鑑を、

製本テープを用いるのであれば表紙と裏表紙のテープの境目に代表社員の印鑑を押そう。

また、参考URLのテンプレートはいろいろと適当なので、適宜修正をしよう。(そこまで細かく見ないということの表れなのかも)

就任承諾書

この辺も参考URLの通り。

CD-R

これも、参考URLの通りに作成するが、事業内容、公告の方法などは定款のものを一字一句違わずに記載しよう。

コピペがおすすめ。

代表社員の印鑑登録証明書

市役所などで取得したものを添付しよう。

法人の印鑑届出書

これも、参考URLを見て、記入しよう。

収入印紙

収入印紙を貼る用紙。法務局で購入できるので、登記申請当日でも大丈夫。

申請

ここまでで不安のある人は、予め法務局に登記相談の予約を入れ、書類の不備などを確認してもらうととてもスムーズに行く。

実際相談してみたところ、とても気さくなおじさんが対応してくれた。(「若いのに偉いねぇ〜、頑張って」と声をかけていただいた)

そして、上で準備した書類を持参し、住民票のある自治体の法務局へ行く。

申請自体は5分程で終わり、受付番号と1週間後ぐらいに登記が完了する旨を伝えられる。

登記完了後

登記が完了したら、社会保険の申し込みや、市区町村への届け出、都道府県への届け出などやることがたくさんある。

登記完了までは一週間ほどあるため、その間に準備しておこう。

また、基礎年金番号などが分からない人は、早めに調べよう。

定款の写し

各申し込みについて、定款の写しが必要になる。基本的に、登記時に提出したものと同じWordファイルを印刷したものでよいが、奥書というものが必要になる。

奥書は、定款の最後のページ余白に、

「本書は原本と相違ないことを証明する。

   平成28年○○月○○日

                合同会社○○ 代表社員 ○○○○ 印」

と記入し、法人印の代表印を押す。また、定款の作成時と同じように、製本し、法人印の代表印を割り印として、表表紙と裏表紙に押す。

なお、各役員の印などは無しで問題なかった。

全部で4部ほど刷った。

税務署

  • 法人設立届出書
  • 定款の写し
  • 登記事項証明書
  • 株主等の名簿
  • 貸借対照表
  • 青色申告の承認申請書
  • 給与所得税の特例の承認に関する申請書

これも、ネットを参考に書けば問題なかった。

受付の人が3分ほどで申請を受け付けてくれた。

要追記。

県税事務所

  • 法人設立届出書
  • 定款の写し
  • 登記事項証明書

これもネットを参考に書けば問題ない。

一瞬で申請がおわった。

要追記。

市役所

  • 法人設立届出書
  • 定款の写し
  • 登記事項証明書

これも一瞬。

要追記。

年金事務所

  • 新規適用届
  • 登記簿謄本
  • 保険料校様振替依頼書
  • 被保険者資格取得届

一番時間がかかったかもしれない。

特に問題もなく申請できた。

要追記。

法人口座

今後追記する。

地方銀行の方が審査が緩い印象。

というかもはや審査なしで解説できた。

MacのJIS配列キーボードをUS配列で使いたい人用カスタムキーボードレイアウト

追記

現在はもっといい方法を使っています。 mjhd.hatenablog.com

MacのJIS配列キーボードをUS配列で使いたい人用、カスタムキーボードレイアウトを作成した。
El Capitan以前の人は、Karabinerというソフトを使った方が色々捗る。
macOS Sierra以降の人は、Karabinerがサポートされなくなった為、このキーボードレイアウトを入れる必要がある。

一応、通常のUS配列を選択するだけでも、US配列にはなるのだが、入力できない文字が出て来てしまう。そのため、こう言った工夫が必要
なお、作成にはUkeleleというソフトを使用した

ダウンロード

US_Custom.dmg - Google ドライブ

使い方

まず、ダウンロードしたdmgファイルを開きます。
f:id:wait0000:20161027184250p:plain

keyboardlayoutファイルを左のKeyboard Layoutsフォルダのリンクへドロップします。

あとは設定画面から、入力ソースの追加を選択し、US_Customを探して追加すればOKf:id:wait0000:20161027184336p:plain