読者です 読者をやめる 読者になる 読者になる

Ethnaで絵文字ライブラリText_Pictogram_Mobileを使って絵文字表示

Asial blogにて、絵文字ライブラリをPEARパッケージ化されたものが公開されました。
symfony用プラグインとして出てはいたのですが、PEARパッケージ化されたことにより、Ethnaからも容易に使えるようになりました。


絵文字ライブラリをPEARパッケージ化&sfPictogramMobilePluginをバージョンアップしました。 : アシアルブログ

PEARライブラリの方も機能的には同じです。
ただし、symfonyプラグインを移植した関係上、PHP5以上でないと使えません。
PHP4に対応も考えたのですが、まずはとにかく出すことが優先かなと思って、PHP5用パッケージにしました。

とのことですので、php5以上が必要です。


以下、Ethnaに組み込んでみました。
組み込み方はいろいろあると思いますので、あくまでも、その中のひとつの方法という位置づけでお願いします。
組み込むにあたって前提条件

  • internal_encoding を UTF-8 で作成する
    • せっかくなので、EthnaのUTF8ブランチを使ってみます
  • 出力文字列もUTF-8
    • output_handler に mb_output_handlerを使わない
  • テンプレート上での使用方法は、modifierプラグイン形式にしてみます
    • {1|emoji} という書き方

Ethnaを落としてくる

Ethnaを落としてきます。
今回は、mobileというアプリケーションIDで作成しますので、違う名前の場合には、ディレクトリ名を適宜読み替えてください。

$ mkdir mobile
$ cd mobile
$ svn co http://svn.sourceforge.jp/svnroot/ethna/ethna/branches/ETHNA_UTF8_BRANCH/ lib/Ethna

※注意:こちらはブランチの開発バージョンを試しに使っています。実際の運用には、最新版のEthnaを使ってください。
http://ethna.jp/

lib/Ethnaを使うためのシェルスクリプトを作る

上記で落としたEthnaが使われるようにシェルスクリプトを作成します。
ethna.sh (追記:#/bin/shになってたので修正)

#!/bin/sh
export ETHNA_HOME=$(dirname $0)/lib/Ethna
$ETHNA_HOME/bin/ethna.sh "$@"


作成後

$ ls
ethna.sh  lib

プロジェクトを作成する

$ sh ethna.sh add-project -b ../ mobile
project sub directory created [/path/to/mobile/app]
()

project skelton for [mobile] is successfully generated at [/path/to]

pear-local を使う前に修正

現在、pear-local を使うと、インストール時に使うデータをtmpディレクトリ内に作成してしまいますので、そちらを修正します。

lib/Ethna/class/Plugin/Handle/Ethna_Plugin_Handle_PearLocal.php line:41付近
修正前

<?php // 色づけのため
        $base = $this->target_ctl->getBaseDir();
        $bin  = $this->target_ctl->getDirectory('bin');
        $tmp  = $this->target_ctl->getDirectory('tmp');

修正後

<?php // 色づけのため
        $base = $this->target_ctl->getBaseDir();
        $bin  = $this->target_ctl->getDirectory('bin');
        $tmp  = $base . '/lib';


mumumuさんがUTF8ブランチにも修正をマージしてくださいました。ですので、今後、ブランチから落とした場合には、こちらの修正は必要ありません。

Text_Pictogram_Mobile-0.0.2.tgz をインストール

ethna pear-localというすばらしいコマンドがあるので、こちらを使ってインストールします。
このコマンドを使うと、プロジェクト内のlibにPEARライブラリをインストールしてくれます。

$ sh ethna.sh pear-local install http://blog.asial.co.jp/data/Text_Pictogram_Mobile-0.0.2.tgz
downloading Text_Pictogram_Mobile-0.0.2.tgz ...
Starting to download Text_Pictogram_Mobile-0.0.2.tgz (64,393 bytes)
................done: 64,393 bytes
Did not download optional dependencies: pecl/json, use --alldeps to download automatically
__uri/Text_Pictogram_Mobile can optionally use package "pecl/json"
install ok: channel://__uri/Text_Pictogram_Mobile-0.0.2

無事、インストール完了です!

Net_UserAgent_Mobile-beta をインストール

キャリア判別に Net_UserAgent_Mobile を使おうと思いますので、同じくインストールします。
私の環境では、依存関係のせいか、いろいろインストールされました。

$ sh ethna.sh pear-local install Net_UserAgent_Mobile-beta
WARNING: channel "pear.php.net" has updated its protocols, use "channel-update pear.php.net" to update
Did not download optional dependencies: pear/XML_RPC, use --alldeps to download automatically
pear/PEAR can optionally use package "pear/XML_RPC" (version >= 1.4.0)
downloading Net_UserAgent_Mobile-0.31.0.tgz ...
Starting to download Net_UserAgent_Mobile-0.31.0.tgz (44,720 bytes)
............done: 44,720 bytes
downloading PEAR-1.7.1.tgz ...
Starting to download PEAR-1.7.1.tgz (302,377 bytes)
...done: 302,377 bytes
downloading Archive_Tar-1.3.2.tgz ...
Starting to download Archive_Tar-1.3.2.tgz (17,150 bytes)
...done: 17,150 bytes
downloading Structures_Graph-1.0.2.tgz ...
Starting to download Structures_Graph-1.0.2.tgz (30,947 bytes)
...done: 30,947 bytes
downloading Console_Getopt-1.2.3.tgz ...
Starting to download Console_Getopt-1.2.3.tgz (4,011 bytes)
...done: 4,011 bytes
install ok: channel://pear.php.net/Archive_Tar-1.3.2
install ok: channel://pear.php.net/Structures_Graph-1.0.2
install ok: channel://pear.php.net/Console_Getopt-1.2.3
install ok: channel://pear.php.net/PEAR-1.7.1
install ok: channel://pear.php.net/Net_UserAgent_Mobile-0.31.0
PEAR: Optional feature webinstaller available (PEAR's web-based installer)
PEAR: Optional feature gtkinstaller available (PEAR's PHP-GTK-based installer)
PEAR: Optional feature gtk2installer available (PEAR's PHP-GTK2-based installer)
PEAR: To install optional features use "pear install pear/PEAR#featurename"


インストール後の libディレクトリ内

$ ls -a lib/
.   .channels  .depdblock  .lock  .registry  Console  Net  PEAR      Structures  Text       pearcmd.php
..  .depdb     .filemap    .pear  Archive    Ethna    OS   PEAR.php  System.php  pear.conf  peclcmd.php

Smartyプラグイン環境を

Smarty用のプラグインディレクトリを作成します

$ mkdir app/plugin/Smarty


app/plugin/Smarty内にプラグインを作成します
app/plugin/Smarty/modifier.emoji.php

<?php
/**
 * Smarty修正子ラグイン
 */

/**
 * IDを絵文字に変換
 *
 * <pre>
 * ex.)
 * {1|emoji}
 * </pre>
 */
function smarty_modifier_emoji($string)
{
    $ctl =& Ethna_Controller::getInstance();
    $renderer =& $ctl->getRenderer();
    $emojilist =& $renderer->getProp('emojilist');
    if (isset($emojilist[$string])) {
        return $emojilist[$string];
    } else {
        return $string;
    }
}

?>

最後に Controller周りに設定を追加

出力文字列が、内部エンコードと同じ UTF-8 になるように先頭に追記します。
app/Mobile_Controller.php line:10付近
追記(php.iniの設定によっては必要ないかも)

<?php // 色づけのため
while(@ob_end_clean());
ini_set('mbstring.internal_encoding', 'UTF-8');
header('Content-type: text/html; charset=utf-8');


クラスのインクルードを追加します。
app/Mobile_Controller.php line:29付近
修正前

<?php // 色づけのため
/** アプリケーションライブラリのインクルード */
require_once 'Ethna/Ethna.php';
require_once 'Mobile_Error.php';
require_once 'Mobile_ActionClass.php';
require_once 'Mobile_ActionForm.php';
require_once 'Mobile_ViewClass.php';

修正後

<?php // 色づけのため
/** アプリケーションライブラリのインクルード */
require_once 'Ethna/Ethna.php';
require_once 'Mobile_Error.php';
require_once 'Mobile_ActionClass.php';
require_once 'Mobile_ActionForm.php';
require_once 'Mobile_ViewClass.php';
//PEAR
include_once 'Net/UserAgent/Mobile.php';
include_once 'Text/Pictogram/Mobile.php';


Smartyプラグインディレクトリが有効になるように設定を追加します。
app/Mobile_Controller.php line:106付近
修正前

<?php // 色づけのため
        'log'           => 'log',
        'plugins'       => array(),
        'template'      => 'template',

修正後

<?php // 色づけのため
        'log'           => 'log',
        'plugins'       => array('app/plugin/Smarty'),
        'template'      => 'template',


Smartyプラグイン内で値を使えるようにします。
app/Mobile_Controller.php line:268付近
メソッド追加

<?php // 色づけのため
    /**
     *  テンプレートエンジンのデフォルト状態を設定する
     *
     *  @access protected
     *  @param  object  Ethna_Renderer  レンダラオブジェクト
     *  @obsolete
     */
    function _setDefaultTemplateEngine(&$renderer)
    {
        $smarty =& $renderer->getEngine();

        $agent =& Net_UserAgent_Mobile::factory($_SERVER['HTTP_USER_AGENT']);
        if (method_exists($agent, 'isNonMobile') && !$agent->isNonMobile()) {
            $picObject = Text_Pictogram_Mobile::factory($agent->getName(), 'utf-8');
            $emojilist = $picObject->getFormattedPictogramsArray();
            $renderer->setPropByRef('emojilist', $emojilist);
        }
    }

エントリポイントが環境依存なので修正

www/index.php
修正前

<?php
require_once '/path/to/mobile/app/Mobile_Controller.php';

Mobile_Controller::main('Mobile_Controller', 'index');
?>

修正後

<?php
require_once dirname(__FILE__) . '/../app/Mobile_Controller.php';

Mobile_Controller::main('Mobile_Controller', 'index');
?>


これで、テンプレートに絵文字が使えるようになりました!

EZweb用に一箇所だけ修正

mobile/lib/Text/Pictogram/Mobile.php
修正前

<?php // 色づけのため
                case 'ezweb':
                case 'au':
                case 'kddi':
                    $agent = 'ezweb';
                    break;

修正後

<?php // 色づけのため
                case 'ezweb':
                case 'au':
                case 'kddi':
                case 'up.browser':
                    $agent = 'ezweb';
                    break;

サンプル

今回作成したプロジェクトをごっそり固めて以下に置いておきます。
サンプルでは、環境依存のwww以下のファイルを一部修正してあります。


http://maru.cc/files/20080501_ethna_with_text_pictogram_mobile.tar.gz (約1.8M)
サンプルとしてわかりやすいように、同梱しちゃってます。
問題がありましたら、ご指摘ください。


なお、Smartysimpletestは、すでにインストール済であることを前提としています。
ダウンロードしたサンプルがそのまま動かない場合があります。

最後に

すばらしいライブラリを公開してくださった、Asialのかめもとさんに感謝!


うちの会社では、文字コードの出力をSJISでやっている関係から、&#xXXXX;形式を使用していて、バイナリ形式は使用していません。なので、中をみるととても勉強になりました。

追記

UTF-8で表示している関係上、auのWinより前、DoCoMoのmova端末は見えないと思います。
A5401ca、P506iCではダメだった。