アシアルブログ

アシアルの中の人が技術と想いのたけをつづるブログです

symfonyの携帯開発プラグイン作成

みなさん、こんばんは。
笹亀です。

最近、寒い日が続くことが多く布団から出るのが嫌になる季節になりました。
夏の暑いのと冬の寒いのは苦手です。はやくも春が恋しくなってきました^^;

symfonyでは、携帯のWebを開発するにはまだまだ足らないことや不便なことがたくさんあります。そんな風に思う中、無いのであらば試しに作ってみよう精神で作成してみました。今回は、第一弾でお試しということでsymfonyを使ったViewのプラグインを作成してみました。
プラグインの名前は「sfMobileViewPlugin」という名前にしました。(それっぽい名前で)
通常のViewでは、1枚のテンプレートですべて表現しないといけませんが、今回はViewプラグインとして、1枚のテンプレートで携帯ごとに分けて表示したい場合などを想定しました。
携帯キャリアごとに実行するタグ(i,e,s/i,e,s)を作成し、キャリアごとに実行するViewファイルを作成するようにしました。

ベースはsymfonySmartyプラグインを参考にして作成しております。
作る方法などに慣れていないので、お恥ずかしいですが、
以下がスクリプトになります。


<?php

class sfMobileView extends sfPHPView {
  private $mobileTypeMode = false;
  private $mobileView = false;
  private $php_tmpfile = false;
  protected static $log;

    public function initialize($context, $moduleName, $actionName, $viewName)
    {
      self::$log = sfConfig::get('sf_logging_enabled')? $context->getLogger() : false;
      $this->mobileTypeMode = sfConfig::get('app_sfMobileView_typemode',false);
      $this->mobileView = sfConfig::get('app_sfMobileView_view',false);
      if (self::$log) self::$log->info('{sfMobileView} mobile setting');
      if ($this->mobileView) {
        $this->mobileSetting();
      }
      parent::initialize($context, $moduleName, $actionName, $viewName);
      return true;

 
    }
    
    private function mobileSetting()
    {
      if (self::$log) self::$log->info('{sfMobileView} mobile view setting');
      $output_type = sfConfig::get('app_sfMobileView_view_encoding',false);
      if ($output_type) {
	ini_set('mbstring.http_output',$output_type);
        ob_start("mb_output_handler");
      }
    }
 
    public function renderFile($file)
    {
    $this->php_tmpfile = false;
    if (self::$log) self::$log->info('{sfMobileView} render "'.$file.'"');

    $this->loadCoreAndStandardHelpers();

    $_escaping = $this->getEscaping();
    if ($_escaping === false || $_escaping === 'bc')
    {
      extract($this->attributeHolder->getAll());
    }

    if ($_escaping !== false)
    {
      $sf_data = sfOutputEscaper::escape($this->getEscapingMethod(), $this->attributeHolder->getAll());

      if ($_escaping === 'both')
      {
        foreach ($sf_data as $_key => $_value)
        {
          ${$_key} = $_value;
        }
      }
    }
    // render
    ob_start();
    ob_implicit_flush(0);
    if ($this->mobileTypeMode) {
     $file = $this->getCarrerFileView($file);
    }
    require($file);
    if ($this->php_tmpfile  & & is_file($file)) {
      unlink($file);
    }
    return ob_get_clean();
    }

    private function getCarrerFileView($file)
    {
     $start_tag = "";
     $end_tag   = "";
     
     //E_STRICT NOTERROR VIEW
     $er = error_reporting();
     if ($er > E_STRICT) {
       error_reporting($er - E_STRICT);
     }
     $page_html = file_get_contents($file);
     require_once('Net/UserAgent/Mobile.php');
     $agent =  &Net_UserAgent_Mobile::singleton(); 
     if( method_exists( $agent , "isDoCoMo" ) ){ 
       switch( true ) {
         case ($agent->isDoCoMo()):
	   $start_tag = "\[\[i\]\]";
	   $end_tag   = "\[\[\/i\]\]";
           $page_html = preg_replace("/(\[\[e\]\](.*?)\[\[\/e\]\])?/s","",$page_html);
           $page_html = preg_replace("/(\[\[s\]\](.*?)\[\[\/s\]\])?/s","",$page_html);
           $page_html = preg_replace("/" . $start_tag . "/","",$page_html);
           $page_html = preg_replace("/" . $end_tag . "/","",$page_html);
           break;
	 case ($agent->isVodafone()):
	   $start_tag = "\[\[s\]\]";
	   $end_tag   = "\[\[\/s\]\]";
           $page_html = preg_replace("/(\[\[e\]\](.*?)\[\[\/e\]\])?/s","",$page_html);
           $page_html = preg_replace("/(\[\[i\]\](.*?)\[\[\/i\]\])?/s","",$page_html);
           $page_html = preg_replace("/" . $start_tag . "/","",$page_html);
           $page_html = preg_replace("/" . $end_tag . "/","",$page_html);
           break;
         case ($agent->isEZweb()):
	   $start_tag = "\[\[e\]\]";
	   $end_tag   = "\[\[\/e\]\]";
           $page_html = preg_replace("/(\[\[i\]](.*?)\[\[\/i\]\])?/s","",$page_html);
           $page_html = preg_replace("/(\[\[s\]\](.*?)\[\[\/s\]\])?/s","",$page_html);
           $page_html = preg_replace("/" . $start_tag . "/","",$page_html);
           $page_html = preg_replace("/" . $end_tag . "/","",$page_html);
           break;
	 default:
           $page_html = preg_replace("/(\[\[i\]\](.*?)\[\[\/i\]\])?/s","",$page_html);
           $page_html = preg_replace("/(\[\[e\]\](.*?)\[\[\/e\]\])?/s","",$page_html);
           $page_html = preg_replace("/(\[\[s\]\](.*?)\[\[\/s\]\])?/s","",$page_html);
           break;
       }
     }
     $tmpfilename = md5(microtime()) . ".php";
     $file_path = sfConfig::get('app_sfMobileView_file_save_path','/tmp/');
     $fname = $file_path . $tmpfilename;
     $handle = fopen($fname, "w");
     fwrite($handle,$page_html);
     fclose($handle);
     $this->php_tmpfile = true;
     return $fname;
    }

}
?>

このような、プラグインを作成してみました。
プラグインを作成することにより、symfonyのプログラムの流れや使用するymlの書き方などを知ることができました。
問題点としては、
1.毎回キャリアのView用のファイルを作成するためにきっと重いです^^;
2.キャリアタグを入れ子にすることができません。
3.sfPHPViewクラスを継承しているだけなので、partialなどのViewでは使用できません。
上記については、社内の技術ミーティングでも発表しましたが、改良案やこうしたらいいのではとか、作成方法についても、いろいろと助言いただきました。
また、その助言などをもとにプロジェクトでも使用できるレベルのものを作れたら良いなぁと思います^^


このままでは、動作しませんので、ご興味があるかたは、
動作方法について記述しますので、お試しください。
 ※βどころかαくらいなので、動作しない場合についてはご了承ください。

まずは、上記スクリプトの設置場所は「plugins/sfMobileViewPlugin/lib/sfMobileView.class.php」に作成をします。

次に、PEARのケータイを判別してくれるパッケージの「PEAR::Net_UserAgent_Mobile」をインストールする必要があります。
 ※インストール方法は省略します。

使用モジュールを設定します。
「apps/appname/config/module.yml」ファイルに追記(ファイルがない場合は新規で作成)します。
モバイルのview_classを追加するので、下記のような記述をします。


all:
 view_class: sfMobile


app.yml(アプリケーションの設定)にモバイルプラグイン(sfMobileViewPlugin)を使用するための設定を記述をします。


all:
 sfMobileView:
   typemode:        true
   view:            true
   view_encoding:   SJIS
   file_save_path: /tmp/

typemodeは、テンプレートをキャリアごとに分ける設定を有効・無効にするときはtrue・falseを設定する
viewは、モバイル表示(http_output)の設定を有効・無効にするときにはtrue・falseを設定する
view_encodingは、http_outputの文字コードを設定する
file_save_pathは、キャリアごとに作成したViewファイルの作成場所の設定を指定します。

「apps/appname/modules/modulename/templates/listSuccess.php
を編集例に下記に乗せます。
>>PHP

[[i]]
掲示板内容一覧(i-mode
[[/i]]
[[e]]掲示板内容一覧(ezweb[[/e]]
[[s]]
掲示板内容一覧(softbank[[/s]]


[[e]][[/e]]タイトルを表示する場所

投稿日時を表示する場所

詳細リンクを表示しよう。
TOP


[[e]][[/e]]タイトルを表示する場所

投稿日時を表示する場所

詳細リンクを表示しよう。
TOP