メールによる画像のアップロード

スマホからは

<input type="file">

でファイルをアップロードできないっぽいので、メールによるアップロードで実現する方向になりそうなので、やってみた。
メールによる方法のほかにも、FacebookとかがやってるJavaScriptによる方法もあるっぽいけど。

QdmailReceiverを使う

結論からいうと、iPhone5で画像を添付して送ると、ヘッダの形が期待している形式じゃないからかできなかった。QdmailReceiverに関しては、ヘッダを解析する部分の正規表現をいじると良いという情報がたくさん公開されているようで、それを試してみたけどダメだった。
開発止まってるみたいだなぁ。QdmailReceiverとは - QdmailReceiver Multibyte mail decoder & POP Client

PEARを使う

PEAR::Net_POP3PEAR::Mail_mimeDecodeを使うとよさげ。ってことで、次の記事を参考にやってみた。cronでバッチ処理を想定しているので、vendorに配置してみた。

後者はラッパークラスを作ってくださってて、ありがたやありがたや〜。

<?php

// 配置したパスに応じて変更すること
// http://d.hatena.ne.jp/ya--mada/20080415/1208318475より拝借
App::import('vendor', 'ReceiptMailDecoder', array('file' => 'mail' . DS . 'ReceiptMailDecoder.class.php'));

class CheckmailShell extends Shell {

  function main() {

    $server = 'mail.hogehoge.com'; // サーバ
    $port = 110; // ポート番号(POP3 on SSLなら995)
    $user = 'foobar@hogehoge.com'; // メールアドレス
    $pass = 'foobarbazqux'; // パスワード

    // 保存先のディレクトリ
    $img_dir = 'foo/bar/baz';

    require_once 'Net/POP3.php';
    $pop = new Net_POP3();
    $ret = $pop->connect($server, $port);
    if ( !$ret ) {
      echo 'wrong settings for mail server.';
      exit;
    }

    // ユーザ名 と パスワード でログイン
    $ret = $pop->login($user, $pass);
    if ( !$ret ) {
      echo 'failed to login.';
      exit;
    }

    // メールの件数を取得
    $num = $pop->numMsg();
    for ($mail_id = $num; 1 <= $mail_id; $mail_id--) {

      // メールを取得(IDは1〜件数なので注意。0開始じゃないっぽい)
      $data = $pop->getMsg($mail_id);

      // 解析用のオブジェクト作成
      $decoder = new ReceiptMailDecoder($data);

      /////////////////////////////////////////
      // 必要に応じて利用する
      /////////////////////////////////////////
      //// To:アドレスのみを取得する
      //$toAddr = $decoder->getToAddr();
      //// To:ヘッダの値を取得する
      //$toString = $decoder->getDecodedHeader( 'to' );
      // Subject:ヘッダの値を取得する
      //$subject = $decoder->getDecodedHeader( 'subject' );
      //
      //// text/planなメール本文を取得する
      //$body = mb_convert_encoding($decoder->body['text'],"eucjp-win","jis");
      //// text/htmlなメール本文を取得する
      //$body = mb_convert_encoding($decoder->body['html'],"eucjp-win","jis");

      if ($decoder->isMultipart()) {

        $tempFiles = array();
        $num_of_attaches = $decoder->getNumOfAttach();

        for ($i = 0; $i < $num_of_attaches; $i++) {

          $file = $decoder->attachments[$i];

          // 保存先のディレクトリ
          $fpath = $img_dir . DS . $file['file_name']);

          // とりあえず保存してみる
          $decoder->saveAttachFile($i, $fpath);

          // 確認
          echo $fpath, PHP_EOL;
        }
      }
      // メールを削除
      $pop->deleteMsg($mail_id);
    }
    $pop->disconnect();
  }
}