symfonyで携帯サイトを作る件
わけあってsymfonyを使ってたら、動的に携帯サイトも対応しなくちゃいけなくなった。
symfonyで携帯サイトをやる情報が少なかったり、プラグインとか重そうだったので、勝手に対応してみた。
これでいいんじゃないかと思う。
symfonyを使って3日くらいしかたってなかったので書き方おかしい???
方針
- PCサイトも携帯サイトも出来れば一緒
- テンプレートをPC用と携帯用と2つ作るのはいたしかたなし
- 絵文字はもともとキャリアごとにiniファイル的なのを作ってたのでそれを使う。
- 携帯は全てSJISで
- view.ymlくらいはキャリア毎に分けたい(レイアウトは分けたいし・・・)
- いざというときtemplateを分けたいかも・・・
というわけで、FilterとViewとHelperを作って対応した。
templates以下にmというモバイル用ディレクトリができて、
m以下にi,y,eという各キャリアごとのディれくトリを作れるようにします。
その他のキャリアはmで吸収?
view.ymlのディレクトリの分け方も同じ。
以下で、動いた。
MobileFilter.php
isFirstCall())
{
// デバッグモードのエラー回避
$er = error_reporting();
if ($er > E_STRICT) {
error_reporting($er - E_STRICT);
}
require_once 'Net/UserAgent/Mobile.php';
$userAgent = Net_UserAgent_Mobile::singleton();
// 出力文字コードを変更する
if ($userAgent->isDoCoMo()
|| $userAgent->isEZweb()
|| $userAgent->isSoftBank())
{
sfConfig::set("sf_charset", "shift_jis");
$this->encordingParams("SJIS", "UTF-8");
mb_internal_encoding('UTF-8');
mb_http_output('SJIS');
ob_start('mb_output_handler');
}
$this->getContext()->getRequest()->setAttribute("userAgent", $userAgent);
}if ($filterChain)
$filterChain->execute();
}
protected function encordingParams($from, $to) {
if ( $to != "" && $from != "" && $from != $to ) {
$params = $this->getContext()->getRequest()->getParameterHolder()->getNames();
foreach ( $params as $param ) {
$in = $this->getContext()->getRequest()->getParameter($param);
$this->getContext()->getRequest()->setParameter($param, mb_convert_encoding($in, $to, $from));
}
}
}
}
?>
MobileView.class.php
userAgent) {
$this->userAgent = $this->getContext()->getRequest()->getAttribute("userAgent");
}// store our current view
$actionStackEntry = $this->getContext()->getActionStack()->getLastEntry();
if (!$actionStackEntry->getViewInstance())
{
$actionStackEntry->setViewInstance($this);
}
$default_sf_app_module_config_dir_name = sfConfig::get('sf_app_module_config_dir_name');
$mobile_base_dir = "";
$carrier_dir = "";if ( !$this->userAgent->isNonMobile() ) {
$mobile_base_dir = "m";if ($this->userAgent->isDoCoMo()) {
$carrier_dir = "i";
} elseif ($this->userAgent->isEZweb()) {
$carrier_dir = "e";
} elseif ($this->userAgent->isSoftBank()) {
$carrier_dir = "y";
}$module_config = $default_sf_app_module_config_dir_name . "/" . $mobile_base_dir;
if ($carrier_dir != "") {
$module_config .= '/'.$carrier_dir;
}sfConfig::set('sf_app_module_config_dir_name',$module_config);
}$viewConfigFile = sfConfig::get('sf_app_module_config_dir_name').'/view.yml';
// オリジナルの候補はアプリケーションまで
$configFile = sfConfigCache::getInstance()->checkConfig(sfConfig::get('sf_app_module_dir_name').'/'.$this->moduleName.'/'.$viewConfigFile,true);if ($configFile == null) {
$configFile = sfConfigCache::getInstance()->checkConfig($this->moduleName.'/'.$viewConfigFile,true);
}if ($configFile == null) {
$configFile = sfConfigCache::getInstance()->checkConfig(sfConfig::get('sf_app').'/'.$viewConfigFile,true);
}if ($configFile == null) {
$configFile = sfConfigCache::getInstance()->checkConfig($viewConfigFile, true);
}if ($configFile == null) {
$error = sprintf('Configuration "%s" does not exist or is unreadable', sfConfig::get('sf_app_module_dir_name').'/'.$viewConfigFile);
throw new sfConfigurationException($error);
}require($configFile);
// template
if (!$this->directory)
{
$temprates = array();if ($carrier_dir != "") {
$temprates['carrier'] = $mobile_base_dir . "/" . $carrier_dir."/".$this->template;
}if ($mobile_base_dir != "") {
$temprates['mobile'] = $mobile_base_dir . "/" . $this->template;
}$temprates["pc"] = $this->template;
foreach ($temprates as $type => $myTemplate) {
$directry = sfLoader::getTemplateDir($this->moduleName, $myTemplate);
if ($directry) {
$this->setTemplate($myTemplate);
$this->setDirectory($directry);
break;
}
}
}sfConfig::set('sf_app_module_config_dir_name',$default_sf_app_module_config_dir_name);
$standard_helpers = sfConfig::get('sf_standard_helpers');
$standard_helpers[] = "emoji";
sfConfig::set('sf_standard_helpers', $standard_helpers);
}
}
?>
emojiHelper.php
getEmoji($v);
}function get_emoji($v)
{
return EmojiHelper::getInstatnce()->getEmoji($v);
}class EmojiHelper
{private static $instanse;
private $emoji;
private function __construct($data_dir = "")
{
$userAgent = Net_UserAgent_Mobile::singleton();
if ($userAgent->isDoCoMo()) {
$carrier = "i";
} elseif ($userAgent->isEZweb()) {
$carrier = "e";
} elseif ($userAgent->isSoftBank()) {
$carrier = "y";
} else {
$carrier = "p";
}if ($data_dir == "") {
$data_dir = dirname(__FILE__)."/data";
}$data = $data_dir."/".$carrier.".emoji.ini";
$this->emoji = array();
if (file_exists($data)) {
$this->emoji = parse_ini_file($data);
}}
public static function getInstatnce($data_dir = "")
{
if (!isset(self::$instanse)) {
self::$instanse = new EmojiHelper($data_dir);
}
return self::$instanse;
}
public function getEmoji($key) {
if (!isset($this->emoji[$key])) {
return "";
}
return $this->emoji[$key];
}}
?>
あとはfilters.ymlとmodule.ymlを書き換えれば使える。
iniファイルの書き方はご自由にすればよい
絵文字を使うときはテンプレートで以下のようにすればよい
p_emoji('hoge')
これでめんどいのは、PC専用モジュールにするときに、いちいち下記のようにしなきゃいけないから、
おなじみのYAMLでなんとかしたいなーーー
public function preExecute()
{
$this->userAgent = $this->getRequest()->getAttribute("userAgent");
$this->forword404if(!$this->userAgent->isNonMobile());
}