<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>sys238:blog</title>
	<atom:link href="http://www.sys238.jp/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.sys238.jp/blog</link>
	<description>誰かが必要とするかもしれないから、なんでもメモしよう...</description>
	<lastBuildDate>Mon, 12 Mar 2012 16:06:45 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Codaで公開ができなくなった話</title>
		<link>http://www.sys238.jp/blog/2011/12/coda_up_error/</link>
		<comments>http://www.sys238.jp/blog/2011/12/coda_up_error/#comments</comments>
		<pubDate>Tue, 13 Dec 2011 13:28:24 +0000</pubDate>
		<dc:creator>fkit</dc:creator>
				<category><![CDATA[Coda]]></category>
		<category><![CDATA[作業メモ]]></category>
		<category><![CDATA[未分類]]></category>

		<guid isPermaLink="false">http://www.sys238.jp/blog/?p=400</guid>
		<description><![CDATA[Codaを使ってます。 ブラウザとメールの次に使用頻度が高いです。 Codaはローカルでの変更を監視してるので「すべて公開」ボタンを押すだけでアップロードが完了します。複数ファイル、複数フォルダにまたがった修正でも「すべ &#8230; <a href="http://www.sys238.jp/blog/2011/12/coda_up_error/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.panic.com/jp/coda/" target="_blank">Coda</a>を使ってます。<br />
ブラウザとメールの次に使用頻度が高いです。</p>
<p>Codaはローカルでの変更を監視してるので「すべて公開」ボタンを押すだけでアップロードが完了します。複数ファイル、複数フォルダにまたがった修正でも「すべて公開」一発でアップロード完了です。</p>
<p>この、ものすごく気に入っていた「すべて公開」が使えなくなりました。</p>
<p>Coda使いならわかると思うんですが、ファイルを修正するとファイルブラウザの該当ファイルに「青マル」が付きますよね、で次に保存すると「青マル」が「↑マル」に変わるじゃないですか、これが変わらない。消えちゃう。</p>
<p>「↑マル」のファイルがないから公開もできない。<br />
困った。</p>
<p>初夏くらいから兆候はあったんです。</p>
<p>でも、再起動すれば直っていたんで騙し騙し使ってました。Lionにアップデートするまではこのままなんとか&#8230;って。</p>
<p>しかし今朝は違った、何回再起動しても直らない。「もうちょっとで今の仕事が一段落する、そしたらHDDをSDDに交換してLionにアップデートするんだ♪」とか言ってたらこれですよ。</p>
<p>まったく。なんなんだ。ガッ!!</p>
<p>&#8212;&#8212;<br />
直りました。</p>
<p>キャッシュと設定ファイル<br />
　~/Library/Caches/com.panic.Coda<br />
　~/Library/Preferences/com.panic.Coda*</p>
<p>を消して、ディスクユーティリティでディスクのアクセス権を修復して、<a href="http://www.titanium.free.fr/" target="_blank">OnyX</a>でメンテナンスとクリーニングを実行したら直りました。</p>
<p>上記を順番に実行しては確認してたんですが、OnyXでクリーニングした時点で直りました。</p>
<p>Onyxでクリーニングするだけで直るのか、それとも他の操作との組み合わせが効いたのかは判りません。</p>
<p>とにかく直ってよかった。<br />
ホントによかった。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sys238.jp/blog/2011/12/coda_up_error/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>さくらのレンタルサーバのデータベースが大幅機能強化されていました</title>
		<link>http://www.sys238.jp/blog/2011/11/sakura_db_veru/</link>
		<comments>http://www.sys238.jp/blog/2011/11/sakura_db_veru/#comments</comments>
		<pubDate>Wed, 16 Nov 2011 06:11:49 +0000</pubDate>
		<dc:creator>fkit</dc:creator>
				<category><![CDATA[さくら]]></category>
		<category><![CDATA[作業メモ]]></category>

		<guid isPermaLink="false">http://www.sys238.jp/blog/?p=394</guid>
		<description><![CDATA[新規に作成したデータベースからになるけど、MySQLのバージョンが5.1から5.5にバージョンアップされました。 それにともない、ストレージエンジンに従来のMyISAMに加えInnoDBも選択できるようになりました。 そ &#8230; <a href="http://www.sys238.jp/blog/2011/11/sakura_db_veru/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>新規に作成したデータベースからになるけど、MySQLのバージョンが5.1から5.5にバージョンアップされました。</p>
<p>それにともない、ストレージエンジンに従来のMyISAMに加えInnoDBも選択できるようになりました。</p>
<p>それから作成できるデータベースの数が増えてます。<br />
うちの場合は1個だったのが50個になりました。<br />
50倍って&#8230;</p>
<p>9/21日から実施されてたみたいです。<br />
今、知ったけど。</p>
<p>「あ〜あぁ、なんでInnoDBが使えないんだろ、参照整合性でdelete cascadeできたらラクチンなのに」とか文句を言いながら作ってたシステムが完成したのが先週末ですよ。</p>
<p>今日、さくらのレンタルサーバの仕様を別件で調べてて、MySQLで選択可能なストレージエンジンにInnoDBがあるのを見た時にはビックリしました。</p>
<p>「なんで？」って。</p>
<p>メンテナンスで停止するってメールは来てたけど、データベースの機能強化のお知らせメールはなかったよな。</p>
<p>メールくれればいいのに。</p>
<p>参考：<br />
　<a href="http://www.sakura.ad.jp/news/sakurainfo/newsentry.php?id=567" target="_blank">「さくらのレンタルサーバ」データベース機能の強化について</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sys238.jp/blog/2011/11/sakura_db_veru/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Smartyの簡易日付整形修飾子（プラグイン）</title>
		<link>http://www.sys238.jp/blog/2011/10/smarty_s238_ts_edit/</link>
		<comments>http://www.sys238.jp/blog/2011/10/smarty_s238_ts_edit/#comments</comments>
		<pubDate>Wed, 12 Oct 2011 08:12:18 +0000</pubDate>
		<dc:creator>fkit</dc:creator>
				<category><![CDATA[Smarty]]></category>
		<category><![CDATA[作業メモ]]></category>

		<guid isPermaLink="false">http://www.sys238.jp/blog/?p=375</guid>
		<description><![CDATA[Smartyには日付整形のために「date_format修飾子」が用意されています。内部的にはPHPの strftime()関数のラッパのようです。 この「date_format修飾子」はテンプレート（デザイン）側で日付 &#8230; <a href="http://www.sys238.jp/blog/2011/10/smarty_s238_ts_edit/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Smartyには日付整形のために「date_format修飾子」が用意されています。内部的にはPHPの strftime()関数のラッパのようです。</p>
<p>この「date_format修飾子」はテンプレート（デザイン）側で日付を色々と整形できて便利なんですが、修飾対象の値はUnixタイムスタンプでなければいけません。</p>
<p>DBで定義されている項目が日時型（PostgreSQLのTIMESTAMP型やMySQLのDATETIME型なんか）で定義されている場合、PHPで普通に値を取り出すと &#8220;2011-10-12 17:17:12.1234&#8243;のように「日付を示す文字列」が返ってきます。</p>
<p>この値を「date_format修飾子」で使用するためにはUnixタイムスタンプに変換してからSmartyに渡す必要があります&#8230;意外と面倒ですよね。</p>
<p>そこで、&#8221;2011-10-12 17:17:12.1234&#8243;のような「日付を示す文字列」を直接整形するプラグインをつくりました。</p>
<pre><code style="font-size: 12px;">[modifier.s238_ts_edit.php]
&lt;php
/**
 * タイムスタンプ編集
 * @access public
 * @param  string  $value DBから得られたタイムスタンプ値
 * @param  string  $opt   フォーマット種別　設定値はソースの「出力」以降を参照
 */
function smarty_modifier_s238_ts_edit($value, $opt){
  if ($value == '') return '';

  list($ymd, $time) = explode(' ', $value);

  //出力
  /* 日付をそのまま */   if     ($opt == 'D'){ return $ymd;}
  /* 時刻をそのまま */   elseif ($opt == 'T'){ return $time;}
  /* 日付を'/'区切り */  elseif ($opt == '/'){ return strtr($ymd, array('-'=>'/'));}
  /* 時刻を':'区切り */  elseif ($opt == ':'){ return substr(strtr($time, array('.'=>':')), 0, 8);}
  /* 日時を'/:'区切り */ elseif ($opt == '/:'){return strtr($ymd, array('-'=>'/')). ' '. substr(strtr($time, array('.'=>':')), 0, 8);}
}
</code></pre>
<p>以下は実行例です。</p>
<pre><code style="font-size: 12px;">[smartyの定義]
{$str='2011-10-12 17:17:12.1234'}
{$str} //オリジナル&lt;br&gt;
{$str|s238_ts_edit:'D'} //日付をそのまま&lt;br&gt;
{$str|s238_ts_edit:'T'} //時刻をそのまま&lt;br&gt;
{$str|s238_ts_edit:'/'} //日付を'/'区切り&lt;br&gt;
{$str|s238_ts_edit:':'} //時刻を':'区切り&lt;br&gt;
{$str|s238_ts_edit:'/:'} //日時を'/:'区切り&lt;br&gt;

[実行結果]
2011-10-12 17:17:12.1234 //オリジナル
2011-10-12 //日付をそのまま&lt;br&gt;
17:17:12.1234 //時刻をそのまま&lt;br&gt;
2011/10/12 //日付を'/'区切り&lt;br&gt;
17:17:12 //時刻を':'区切り&lt;br&gt;
2011/10/12 17:17:12 //日時を'/:'区切り&lt;br&gt;
</code></pre>
<p>なんか、ベタであんまりカッッコ良いやり方じゃないとは思うんですが結構使えてます。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sys238.jp/blog/2011/10/smarty_s238_ts_edit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Smarty3のtruncate修飾子はマルチバイト対応&#8230;だけど</title>
		<link>http://www.sys238.jp/blog/2011/09/smarty_truncat/</link>
		<comments>http://www.sys238.jp/blog/2011/09/smarty_truncat/#comments</comments>
		<pubDate>Sat, 10 Sep 2011 04:57:26 +0000</pubDate>
		<dc:creator>fkit</dc:creator>
				<category><![CDATA[Smarty]]></category>
		<category><![CDATA[作業メモ]]></category>

		<guid isPermaLink="false">http://www.sys238.jp/blog/?p=351</guid>
		<description><![CDATA[Smarty3のtruncate修飾子がマルチバイト対応になりました。 Googleで「smarty　truncate　マルチバイト」で検索すると結構な数の「自前でマルチバイト対応のtruncate修飾子を作りました」っ &#8230; <a href="http://www.sys238.jp/blog/2011/09/smarty_truncat/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Smarty3のtruncate修飾子がマルチバイト対応になりました。</p>
<p>Googleで「smarty　truncate　マルチバイト」で検索すると結構な数の「自前でマルチバイト対応のtruncate修飾子を作りました」ってサイトがヒットするので、みんなが待ち望んだ改善ですね。</p>
<p>でもね、ただちょっと、そのままだと微妙に使いづらいんですよ。</p>
<p>結論から言うと、3番目のパラメタ「切り捨てを単語の境界で行うか(FALSE)、厳密なキャラクタ数で行うか(TRUE)」に必ず「TRUE」をセットしないと結果がおかしくなる場合があります。</p>
<p>以下、実行例です。20文字で切り捨ててみます</p>
<pre><code style="font-size: 12px;">[smartyの定義]
{$str='OS X Lionは Eメールにまったく新しい方法を採用しました。'}
{$str} //オリジナル&lt;br&gt;
{$str|truncate:20} //境界指定を省略&lt;br&gt;
{$str|truncate:20:'...':true} //境界をTRUE&lt;br&gt;

[実行結果]
Lionは Eメールにまったく新しい方法を採用しました。 //オリジナル
OS X Lionは... //境界指定を省略
OS X Lionは Eメールにま... //境界をTRUE
</code></pre>
<p>オリジナル文章の&#8221;Eメール&#8221;の前に半角のスペースが入ってます。<br />
境界指定がfalseだとココで切り捨ててしまいます。<br />
英語だと単語境界で切り捨てるのが便利なんでしょうが、日本語だと残念な事になります。</p>
<p>対応方法としては<br />
　a){$str|truncate:20:&#8217;&#8230;&#8217;:true}と面倒でも書く<br />
　b)Smarty/plugins/modifier.truncate.phpを修正してデフォルトをTRUEにする<br />
　c)自前のマルチバイト対応truncate修飾子を作る<br />
ぐらいでしょうか？</p>
<p>a)は面倒くさいし、b)は後々問題になりそうだし。<br />
そういう事で、私はC)の自前マルチバイトtruncate修飾子を作る事にしました。<br />
結局、Smarty2と同じになっちゃいました。(笑)</p>
<p>こういう場合のために、Smartyのインスタンス生成時に
<pre><code style="font-size: 12px;">Smarty->Lang = 'Japan';</code></pre>
<p>とかできればいいんですけどね。</p>
<p>
一応、SYS238版のマルチバイトtruncate修飾子を載せておきます。</p>
<pre><code style="font-size: 12px;">[modifier.s238_mb_truncate.php]
&lt;php
/**
 * 文字の切り捨て
 * Type:  modifier
 * Name:  s238_mb_truncate
 * @param string    $string   文字列
 * @param integer   $length   切り捨て長
 * @param string    $etc      付加文字
 * @param string    $encoding エンコーディング
 * @return string
 */
function smarty_modifier_s238_mb_truncate($string, $length=80, $etc='...', $encoding='UTF-8'){
  if($length == 0)	return '';

  if(mb_strlen($string, $encoding) > $length){
    $length -= mb_strlen($etc, $encoding);
    return mb_substr($string, 0, $length, $encoding).$etc;
  }else{
    return $string;
  }
}
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.sys238.jp/blog/2011/09/smarty_truncat/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>さくらのレンタルサーバにWebSVNをいれる</title>
		<link>http://www.sys238.jp/blog/2011/09/sakura_websv/</link>
		<comments>http://www.sys238.jp/blog/2011/09/sakura_websv/#comments</comments>
		<pubDate>Fri, 02 Sep 2011 02:12:24 +0000</pubDate>
		<dc:creator>fkit</dc:creator>
				<category><![CDATA[Subversion]]></category>
		<category><![CDATA[作業メモ]]></category>

		<guid isPermaLink="false">http://www.sys238.jp/blog/?p=335</guid>
		<description><![CDATA[WebSVNはSubversionをwebブラウザから操作するアプリケーションです。これを、さくらのレンタルサーバに導入してみます。 以前のバージョンでは日本語の文字化けを回避するために色々と設定が必要だったようですが、 &#8230; <a href="http://www.sys238.jp/blog/2011/09/sakura_websv/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>WebSVNはSubversionをwebブラウザから操作するアプリケーションです。これを、さくらのレンタルサーバに導入してみます。</p>
<p>以前のバージョンでは日本語の文字化けを回避するために色々と設定が必要だったようですが、最新バージョンでは管理対象のソースをutf-8で作成していれば面倒な設定なしに利用できます。</p>
<p>今回はソースのブラウズのみです。リポジトリ内容をtarballでダウンロードしたりとかの設定はやってません。</p>
<p>それから、このWebSVNのインストール手順は、<a href="http://www.sys238.jp/blog/2011/08/sakura_subversion/" title="さくらのレンタルサーバにSubversionを入れる" target="_blank">前回のSubversionインストール</a>を前提としています。</p>
<p><span id="more-335"></span><br />
まずWebSVNを<a href="http://www.websvn.info/" target="_blank">公式サイト</a>から入手します。投稿時点の最新バージョンは2.3.3でした。</p>
<p>次に入手したWebSVNを解凍し、webサーバのドキュメントルート下に配置します。</p>
<pre><code style="font-size: 12px;">%tar zxvf websvn-2.3.3.tar.gz
%mv websvn-2.3.3 ~/www/[WebSVN公開ディレクトリ]
</code></pre>
<p>設定ファイルを編集します。</p>
<pre><code style="font-size: 12px;">%cd ~/www/[WebSVN公開ディレクトリ]/include/
%cp distconfig.php config.php

[config.php]に以下の2行を追加します。
・追加場所はコメントを参考（該当コメントの下）にしてください。
・ディレクトリ名は自分の環境に合わせて適宜変更してください。

//リポジトリを追加
$config->addRepository('[リポジトリ名]', 'file:///home/[ユーザ名]/svn/[リポジトリ名]/');
//svnコマンドのパス
$config->setSVNCommandPath('/home/[ユーザ名]/local/bin/');
</code></pre>
<p>これで、[WebSVN公開ディレクトリ]にアクセスすればリポジトリ内容の参照ができます。<br />
必要に応じてBasic認証などを実施してください。</p>
<p>参考：<br />
　<a href="http://m120.scriptkiddie.net/wordpress/2010/02/09_456" target="_blank">LinuxTIPS – websvn インストールメモ</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sys238.jp/blog/2011/09/sakura_websv/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Frameworkでファイルにログを出力する</title>
		<link>http://www.sys238.jp/blog/2011/08/zf_logwrit/</link>
		<comments>http://www.sys238.jp/blog/2011/08/zf_logwrit/#comments</comments>
		<pubDate>Sat, 27 Aug 2011 07:19:20 +0000</pubDate>
		<dc:creator>fkit</dc:creator>
				<category><![CDATA[ZendFramework]]></category>
		<category><![CDATA[作業メモ]]></category>

		<guid isPermaLink="false">http://www.sys238.jp/blog/?p=327</guid>
		<description><![CDATA[//include_pathは適切に設定されている前提で... require_once('Zend/Log.php'); require_once('Zend/Log/Writer/Stream.php'); defi &#8230; <a href="http://www.sys238.jp/blog/2011/08/zf_logwrit/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<pre><code style="font-size: 12px;">//include_pathは適切に設定されている前提で...
require_once('Zend/Log.php');
require_once('Zend/Log/Writer/Stream.php');

define('LOG_PATH',      '/ver/tmp/webapps/log');  //ログ出力先
define('LOG_FILE_NAME', 'weblog_#DT#.log');       //ログファイル名

/**
 * log writer
 * @param  String    $message  エラーメッセージ
 * @param  String    $level    ログレベル
 * @see    Zend/Log.php
 */
function logWrite($message, $level){
  //'#DT#'を日付に差替える。日毎にログを分割（1ヶ月でローテート）する。
  $logFile = LOG_PATH. '/'. strtr(LOG_FILE_NAME, array('#DT#'=>strftime('%d')));
  $logger = new Zend_Log(new Zend_Log_Writer_Stream($logFile));
  $logger->log($message, $level);
}

//エラーでログ出力
logWrite("エラーです。", Zend_Log::ERR);

//デバッグでログ出力
logWrite("デバッグ情報です。", Zend_Log::DEBUG);
</code></pre>
<pre><code style="font-size: 12px;">//ログレベル
EMERG   = 0;  // 緊急事態 (Emergency): システムが使用不可能です
ALERT   = 1;  // 警報 (Alert): 至急対応が必要です
CRIT    = 2;  // 危機 (Critical): 危機的な状況です
ERR     = 3;  // エラー (Error): エラーが発生しました
WARN    = 4;  // 警告 (Warning): 警告が発生しました
NOTICE  = 5;  // 注意 (Notice): 通常動作ですが、注意すべき状況です
INFO    = 6;  // 情報 (Informational): 情報メッセージ
DEBUG   = 7;  // デバッグ (Debug): デバッグメッセージ
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.sys238.jp/blog/2011/08/zf_logwrit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Frameworkで日本語のメールを送信する</title>
		<link>http://www.sys238.jp/blog/2011/08/zf_mailsend/</link>
		<comments>http://www.sys238.jp/blog/2011/08/zf_mailsend/#comments</comments>
		<pubDate>Tue, 23 Aug 2011 05:33:36 +0000</pubDate>
		<dc:creator>fkit</dc:creator>
				<category><![CDATA[ZendFramework]]></category>
		<category><![CDATA[作業メモ]]></category>

		<guid isPermaLink="false">http://www.sys238.jp/blog/?p=312</guid>
		<description><![CDATA[//include_pathは適切に設定されている前提で... require_once('Zend/Mail.php'); define('APP_CHARSET', 'UTF-8'); define('MAIL_CH &#8230; <a href="http://www.sys238.jp/blog/2011/08/zf_mailsend/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<pre><code style="font-size: 12px;">//include_pathは適切に設定されている前提で...
require_once('Zend/Mail.php');

define('APP_CHARSET',  'UTF-8');
define('MAIL_CHARSET', 'ISO-2022-JP');

$title = "メール送信サンプル";

$body  = "Zend Framework はオープンソースのフレームワークで、\n";
$body .= "ウェブアプリケーションやウェブサービスを PHP5で開発\n";
$body .= "するためのものです。\n";

$mail  = new Zend_Mail(MAIL_CHARSET);

$mail->setFrom([送信者メールアドレス]);
$mail->addTo([受信者メールアドレス1]);
$mail->addTo([受信者メールアドレス2]);
$mail->setSubject(mailTextCnv($title));
$mail->setBodyText(mailTextCnv($body));

$mail->send();

// メールの文字コード変換
function mailTextCnv($str){
  return mb_convert_encoding($str, MAIL_CHARSET, APP_CHARSET);
}
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.sys238.jp/blog/2011/08/zf_mailsend/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend FrameworkでSmartyを使う</title>
		<link>http://www.sys238.jp/blog/2011/08/zf_smarty/</link>
		<comments>http://www.sys238.jp/blog/2011/08/zf_smarty/#comments</comments>
		<pubDate>Mon, 22 Aug 2011 05:46:37 +0000</pubDate>
		<dc:creator>fkit</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Smarty]]></category>
		<category><![CDATA[ZendFramework]]></category>
		<category><![CDATA[作業メモ]]></category>

		<guid isPermaLink="false">http://sys238.sakura.ne.jp/blog/?p=41</guid>
		<description><![CDATA[Zend Framework（以下、ZFと略）からSmartyを使うためのメモ ここやここなんかではZend_View_Interfaceを継承して実現していますが、このメモでは違うアプローチで実現します。 まずやる事は &#8230; <a href="http://www.sys238.jp/blog/2011/08/zf_smarty/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Zend Framework（以下、ZFと略）からSmartyを使うためのメモ</p>
<p><a href="http://www.phppro.jp/school/smarty/vol12/1" target="_blank">ここ</a>や<a href="http://www.trekdevel.net/archives/118" target="_blank">ここ</a>なんかではZend_View_Interfaceを継承して実現していますが、このメモでは違うアプローチで実現します。</p>
<p>まずやる事はフロントコントローラ（index.php）を以下のように修正してZFのZend_Viewによるレンダリングを無効にします。</p>
<pre><code style="font-size: 12px;">　　　　:
　　  省略
　　　　:
require_once 'Zend/Controller/Front.php';
$front = Zend_Controller_Front::getInstance();
$front->setControllerDirectory(APP_BASE_PATH. '/application/controllers');
$front->setParam('noViewRenderer', true);  //Smartyを使うので標準view機構を無効にする
$front->dispatch();
</code></pre>
<p>「setParam(&#8216;noViewRenderer&#8217;, true)」する事で標準View機構が無効になるので、あとは普通にSmartyが使えます。</p>
<p>簡単ですね。</p>
<p>これだけだとなんなんで続きではZFの標準ディレクトリ構成っぽいファイル配置ができるように、Zend_Controller_ActionとSmartyを拡張してみます。</p>
<p><span id="more-41"></span></p>
<h3>ディレクトリ構成</h3>
<pre><code style="font-size: 12px;">/[APP_BASE_PATH]/
  ├application/
  │  ├ controllers/
  │  │ └ SmartyTest1Controller.php
  │  └ view/
  │      ├ common/
  │      └ scripts/
  │         └ smarty-test1/
  │            └ index.tpl
  ├ index.php
  ├ library/
  │  └ MySmarty.php
  │  ├ MyZendControllerAction.php
  │  ├ Smarty/
  │  └ Zend/
  └ temp/
     ├ cache/
     └ templates_c/
</code></pre>
<p></p>
<h3>フロントコントローラ [index.php]</h3>
<pre><code style="font-size: 12px;">&lt;?php
define('APP_BASE_PATH',       dirname(__FILE__));
define('SMARTY_TEMPLATE_DIR', APP_BASE_PATH. '/application/views/scripts');
define('SMARTY_CONFIG_DIR',   APP_BASE_PATH. '/application/views/common');
define('SMARTY_COMPILE_DIR',  APP_BASE_PATH. '/temp/templates_c');
define('SMARTY_CACHE_DIR',    APP_BASE_PATH. '/temp/cache');
define('SMARTY_EXTENSION',    'tpl');

set_include_path(get_include_path(). PATH_SEPARATOR. realpath(APP_BASE_PATH. '/library'));

require_once 'Zend/Controller/Front.php';

$front	= Zend_Controller_Front::getInstance();
$front->setControllerDirectory(APP_BASE_PATH. '/application/controllers');
$front->setParam('noViewRenderer', true);  //Smartyを使うので標準view機構を使用しない
$front->dispatch();
</code></pre>
<p></p>
<h3>Zend_Controller_Action [MyZendControllerAction.php]</h3>
<pre><code style="font-size: 12px;">&lt;?php
require_once 'MySmarty.php';
require_once 'Zend/Controller/Action.php';

class MyZendControllerAction extends Zend_Controller_Action{
  protected $TPL;    //smarty

  /**
   * init
   */
  public function init(){
    $param = $this->getRequest()->getParams();

    //smarty
    $this->TPL = new mySmarty(
      SMARTY_TEMPLATE_DIR,
      $param['controller'],
      SMARTY_CONFIG_DIR,
      SMARTY_COMPILE_DIR,
      SMARTY_CACHE_DIR
    );
  }
}
</code></pre>
<p></p>
<h3>Smarty [MySmarty.php]</h3>
<pre><code style="font-size: 12px;">&lt;?php
require_once('Smarty/Smarty.class.php');

final class MySmarty extends Smarty{
  /**
   * コンストラクタ
   * @param String $templateDir   テンプレートディレクトリ
   * @param String $controllerDir コントローラディレクトリ
   * @param String $configDir     設定＆共通
   * @param String $compileDir    コンパイルディレクトリ
   * @param String $cacheDir      キャッシュ
   */
  function __construct($templateDir, $controllerDir, $configDir, $compileDir, $cacheDir){
    parent::__construct();

    $this->template_dir = $templateDir. '/'. $controllerDir;
    $this->compile_id   = $controllerDir; //コンパイル済みファイル名が衝突しないためにセット
    $this->config_dir   = $configDir;
    $this->compile_dir  = $compileDir;
    $this->cache_dir    = $cacheDir;
  }

  /**
   * dispaly
   * @param String $method メソッド名(クラス名::メソッド名)
   * @param String $suffix テンプレート名の末尾付加文字
   */
  public function display($classMethod, $suffix=null){
    //メッソッド名からテンプレート名を生成
    list($class, $method) = explode('::', $classMethod);
    $tplName = strtolower(ltrim(preg_replace("/([A-Z])/", "-$1", str_replace('Action', '', $method)), "-"));
    $tplName .= ($suffix)? "_{$suffix}": '';

    //errorだけテンプレートの呼出し元を変える
    if ($class == 'ErrorController') $this->template_dir = SMARTY_TEMPLATE_DIR. '/error';

    parent::display($tplName. '.'. SMARTY_EXTENSION);
  }
}
</code></pre>
<p></p>
<h3>コントローラ [SmartyTest1Controller.php]</h3>
<pre><code style="font-size: 12px;">&lt;?php
require_once 'MyZendControllerAction.php';

class SmartyTest1Controller extends MyZendControllerAction{

  public function indexAction(){
    $this->TPL->assign('title', 'ZF &#038; Smarty');
    $this->TPL->assign('testStr', 'こんにちは');
    $this->TPL->display(__METHOD__);
  }
}
</code></pre>
<p></p>
<h3>テンプレート [index.tpl]</h3>
<pre><code style="font-size: 12px;">&lt;html&gt;

&lt;head&gt;
&lt;title&gt;{$title}&lt;/title&gt;
&lt;/head&gt;

&lt;body&gt;
{$testStr}
&lt;/body&gt;

&lt;/html&gt;
</code></pre>
<p>いかがでしょうか？</p>
<p>Zend_View_Interfaceを拡張するのが本筋なんでしょうが、この書き方もアリかな？と個人的には思ってます。Smartyをずっと使ってきた人がZFに移行するときはこっちの方が取っ付きやすいんじゃないかと思います。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sys238.jp/blog/2011/08/zf_smarty/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>さくらのレンタルサーバのwebアプリのログインでアカウントを入力済みにする</title>
		<link>http://www.sys238.jp/blog/2011/08/sakura_webapps_login/</link>
		<comments>http://www.sys238.jp/blog/2011/08/sakura_webapps_login/#comments</comments>
		<pubDate>Sat, 20 Aug 2011 06:25:37 +0000</pubDate>
		<dc:creator>fkit</dc:creator>
				<category><![CDATA[さくら]]></category>
		<category><![CDATA[作業メモ]]></category>

		<guid isPermaLink="false">http://www.sys238.jp/blog/?p=248</guid>
		<description><![CDATA[Webメールやコントロールパネルなどのログイン画面でアカウントを入力済みにする方法。 ログインがちょっとだけ楽になる。 ブックマークのURLを以下のようにするとアカウントが入力済みでページが開く。 Webメール http &#8230; <a href="http://www.sys238.jp/blog/2011/08/sakura_webapps_login/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Webメールやコントロールパネルなどのログイン画面でアカウントを入力済みにする方法。<br />
ログインがちょっとだけ楽になる。</p>
<p>ブックマークのURLを以下のようにするとアカウントが入力済みでページが開く。</p>
<h3>Webメール</h3>
<pre><code style="font-size: 12px;">https://secure.sakura.ad.jp/rscontrol/?webmail=1&#038;domain=[ユーザID]@[ドメイン]</code></pre>
<h3>サーバコントロールパネル</h3>
<pre><code style="font-size: 12px;">https://secure.sakura.ad.jp/rscontrol/?domain=[ドメイン]</code></pre>
<p>自動的にログインしたい場合は<a href="http://www.sys238.jp/blog/2011/08/webapps_autologin/">昨日の投稿</a>を見てください。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sys238.jp/blog/2011/08/sakura_webapps_login/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Webアプリで自動ログインする方法</title>
		<link>http://www.sys238.jp/blog/2011/08/webapps_autologin/</link>
		<comments>http://www.sys238.jp/blog/2011/08/webapps_autologin/#comments</comments>
		<pubDate>Fri, 19 Aug 2011 08:49:51 +0000</pubDate>
		<dc:creator>fkit</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[さくら]]></category>
		<category><![CDATA[作業メモ]]></category>

		<guid isPermaLink="false">http://www.sys238.jp/blog/?p=255</guid>
		<description><![CDATA[MacFan(2011/09)を読んでいたら「iのコンシェルジェ」というコーナーにブックマークレットでWebアプリに自動ログインする方法が載っていた。 以前、同じ事をやろうとしてブックマークレットで実現するのを挫折した事 &#8230; <a href="http://www.sys238.jp/blog/2011/08/webapps_autologin/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://macfan.jp/" target="_blank">MacFan(2011/09)</a>を読んでいたら「iのコンシェルジェ」というコーナーにブックマークレットでWebアプリに自動ログインする方法が載っていた。</p>
<p>以前、同じ事をやろうとして<strong>ブックマークレットで実現するのを挫折</strong>した事があるのでムムッと読んでみたら&#8230;</p>
<pre><code style="font-size: 12px;">[記事のブックマークレット]

javascript:
location.href=='http://mixi.jp/'
document.getElementsByName('email')[0].value='[ユーザID]';
document.getElementsByName('password')[0].value='[パスワード]';
document.getElementsByName('email')[0].form.submit();
</code></pre>
<p>この方法じゃダメ。<br />
うまく行かないパターンがある。</p>
<p>ログインページを開いた状態で、このブックマークレットを実行すればうまくログインできるけど、他のページやブランクページで実行した場合はログインできない。</p>
<p>原因は実際の実行順が「ユーザID＆パスワードをセット → ログイン実行 → ログインページを開く」になってしまうからだ。「ユーザID＆パスワードをセット」の段階では対象ページがまだ無いから値をセットできなくてエラーになってしまう。</p>
<p>JavaScriptは各ステップの実行結果（終了）を待ってから次のステップに進むんじゃなく、時間のかかる処理は待たずに次のステップに進むのを考慮してないのがこのブックマークレットの敗因。</p>
<p>ちなみに、ページが開くまでsetTimeout()なんかを使って「ユーザID＆パスワードをセット → ログイン実行」の処理を待たせてもダメ。今度はページ遷移した段階でsetTimeout()で待たせている後続処理がクリアされてしまう。なのでMacFanの例は二重にダメって事になります。</p>
<p>で、結局どうやって自動ログインを実現したかというと。</p>
<p>一連の自動ログイン処理をhtmlファイルに記述し、そのファイルに対してブックマークを設定して実現しました。</p>
<p><span id="more-255"></span></p>
<p>ただ、このhtmlファイルで実現する方法ですが、２つの大きな制限があります。</p>
<p>まず一つ目が、ポップアップウィンドウをブロックしている場合は動作しません。</p>
<p>二つ目はhtmlファイルはローカルに置く必要があります。webサーバ上に置いても動作しません。（正確にはドメイン名が異なる場合は動作しない）</p>
<p>両方ともJavaScriptのセキュリティ上の制限です。</p>
<p>この制限が問題になる方は以下の方法は使用できません。<br />
あしからず。</p>
<p>以下、さくらのレンタルサーバでの記述例です。他のサーバの場合は適宜、書換えてください。</p>
<p>各htmlファイルは、そのままダブルクリックしてもブックマークに登録しても使用できます。</p>
<h3>Webメール</h3>
<pre><code style="font-size: 12px;">[saku_WebMail_login.html]

&lt;script language="JavaScript"&gt;
u='https://secure.sakura.ad.jp/rscontrol/?webmail=1';
w = window.open(u,'_blank');
setInterval("login()", 500);

function login(){
  if (w.document.location.href==u){
    w.document.getElementsByName('domain')[0].value = '[メールアドレス]';
    w.document.getElementsByName('password')[0].value = '[パスワード]';
    w.document.forms[0].elements[4].click();
    w.focus();
    close();
  }
}
&lt;/script&gt;
</code></pre>
<h3>サーバコントロールパネル</h3>
<pre><code style="font-size: 12px;">[saku_ControlPanel_login.html]

&lt;script language="JavaScript"&gt;
u='https://secure.sakura.ad.jp/rscontrol/';
w = window.open(u,'_blank');
setInterval("login()", 500);

function login(){
  if (w.document.location.href==u){
    w.document.getElementsByName('domain')[0].value = '[ドメイン]';
    w.document.getElementsByName('password')[0].value = '[パスワード]';
    w.document.getElementsByName('domain')[0].form.submit();
    w.focus();
    close();
  }
}
&lt;/script&gt;
</code></pre>
<h3>phpMyAdmin</h3>
<pre><code style="font-size: 12px;">[saku_phpMyAdmin_login.html]

&lt;script language="JavaScript"&gt;
u='https://secure.sakura.ad.jp/phpmyadmin2/?server=[DBサーバのURL]';
w = window.open(u,'_blank');
setInterval("login()", 500);

function login(){
  if (w.document.location.href==u){
    w.document.getElementsByName('pma_username')[0].value = '[DBユーザ名]';
    w.document.getElementsByName('pma_password')[0].value = '[パスワード]';
    w.document.getElementsByName('pma_username')[0].form.submit();
    w.focus();
    close();
  }
}
&lt;/script&gt;
</code></pre>
<p>上記、いずれのhtmlファイルでも読まれてしまうとIDやパスワードがダダ漏れなので注意してください。</p>
<p>パスワードまで書いてしまうのに抵抗のある方は以下のように修正するとパスワード入力[return]　でログインできて便利です。</p>
<pre><code style="font-size: 12px;">[この行を]
    w.document.getElementsByName('**password**')[0].value = '[パスワード]';
    w.document.getElementsByName('** userid **')[0].form.submit();
[こうする]
    w.document.getElementsByName('**password**')[0].focus();
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.sys238.jp/blog/2011/08/webapps_autologin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

