2011年4月21日木曜日

Ext4.0ドキュメントの印刷

Ext4.0のドキュメントページを印刷するブックマークレットを作ってみた。

今回は隠したインラインフレームに作成して、そのまま印刷するのではなく、
印刷可能なWindowを表示するようにした。ExtWikiでも試行錯誤したが、プレビュー代わりになりこれが一番便利だった。
また、ガイドがマニュアルに統合されたので、こちらも印刷しやすいようにしてみる。

例によってブックマークレット表示サイトで表示してみる。
ExtJS4.0 ドキュメント印刷(クラス)

ExtJS4.0 ドキュメント印刷(ガイド)

もともとβ3の時に作成したが、ファイナルで少し変わっていたので上記に修正した。β3の時のものはこんな感じ
ExtJS4.0β3 ドキュメント印刷(クラス)

2011年4月3日日曜日

画像をphpスクリプトのみで表示する

画像のパスが問題で、プラグインやライブラリの設計や導入方法が若干複雑になる事がある。
こんなとき、画像をプログラムに取り込んでしまうと設定自体不要になるケースがある。

そのやり方をメモしておく
1.画像をbase64文字列に変換する
2.変換したbase64文字列をプログラムに組み込む

1.画像をbase64文字列に変換する
 次のようなプログラムでbase64文字列を作成できる
img_encode.php

<?php
  //クォート内はターゲットのファイル名
  die(base64_encode(file_get_contents(''));
?>

出力は下記のようになる

R0lGODlhFQATAPcAAP//////zP//mf//Zv//M///AP/M///MzP/Mmf/MZv/MM//MAP+Z//+ZzP+Zmf+ZZv+ZM/+ZAP9m//9mzP9mmf9mZv9mM/9mAP8z//8zzP8zmf8zZv8zM/8zAP8A//8AzP8Amf8AZv8AM/8AAMz//8z/zMz/mcz/Zsz/M8z/AMzM/8zMzMzMmczMZszMM8zMAMyZ/8yZzMyZmcyZZsyZM8yZAMxm/8xmzMxmmcxmZsxmM8xmAMwz/8wzzMwzmcwzZswzM8wzAMwA/8wAzMwAmcwAZswAM8wAAJn//5n/zJn/mZn/Zpn/M5n/AJnM/5nMzJnMmZnMZpnMM5nMAJmZ/5mZzJmZmZmZZpmZM5mZAJlm/5lmzJlmmZlmZplmM5lmAJkz/5kzzJkzmZkzZpkzM5kzAJkA/5kAzJkAmZkAZpkAM5kAAGb//2b/zGb/mWb/Zmb/M2b/AGbM/2bMzGbMmWbMZmbMM2bMAGaZ/2aZzGaZmWaZZmaZM2aZAGZm/2ZmzGZmmWZmZmZmM2ZmAGYz/2YzzGYzmWYzZmYzM2YzAGYA/2YAzGYAmWYAZmYAM2YAADP//zP/zDP/mTP/ZjP/MzP/ADPM/zPMzDPMmTPMZjPMMzPMADOZ/zOZzDOZmTOZZjOZMzOZADNm/zNmzDNmmTNmZjNmMzNmADMz/zMzzDMzmTMzZjMzMzMzADMA/zMAzDMAmTMAZjMAMzMAAAD//wD/zAD/mQD/ZgD/MwD/AADM/wDMzADMmQDMZgDMMwDMAACZ/wCZzACZmQCZZgCZMwCZAABm/wBmzABmmQBmZgBmMwBmAAAz/wAzzAAzmQAzZgAzMwAzAAAA/wAAzAAAmQAAZgAAMwAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAFQATAAAI/AABCBzoaRQpUVSopFJFaqDDgXny/JH4B8+fUchUOVP1UOCTKhEjjho5KlUqUqpGPXxSoKVLPwmp+CnZ0s/AJypaOqmCJ48fPFScUBGVqmVKgSRaqkhosSWVmi4LOAPgpkTUlkBdPjXqzBmpEjkLqFAhNKFSoUZNkkoqduxSJy7H1iw5ShXbq1iVbi0gCtVXt0up4PnpByYVskz9kKIz1okKnnkGQy0Aw2wBZCUcF6iy2elMP1H9iPLzCcAczqEnF8ha4I/AEnudthTlEtVWTwOtuqS9enZUPQ9LzASacKloVKj8dOoIoESehGXLCgbOXCAmT53++JmYB/fDgAA7

2.変換した文字列をプログラムに組み込む
 上記で変換して得られたbase64文字列をbase64_decodeしヘッダーとともに出力する。
 1行が長い場合、適当な長さに切り、使うときに文字列として連結する。
img_decode.php

<?php
  $img = 'R0lGODlhFQATAPcAAP//////zP//mf//Zv//M///AP/M///MzP/Mmf/MZv/M'
 .'M//MAP+Z//+ZzP+Zmf+ZZv+ZM/+ZAP9m//9mzP9mmf9mZv9mM/9mAP8z//8z'
 .'zP8zmf8zZv8zM/8zAP8A//8AzP8Amf8AZv8AM/8AAMz//8z/zMz/mcz/Zsz/'
 .'M8z/AMzM/8zMzMzMmczMZszMM8zMAMyZ/8yZzMyZmcyZZsyZM8yZAMxm/8xm'
 .'zMxmmcxmZsxmM8xmAMwz/8wzzMwzmcwzZswzM8wzAMwA/8wAzMwAmcwAZswA'
 .'M8wAAJn//5n/zJn/mZn/Zpn/M5n/AJnM/5nMzJnMmZnMZpnMM5nMAJmZ/5mZ'
 .'zJmZmZmZZpmZM5mZAJlm/5lmzJlmmZlmZplmM5lmAJkz/5kzzJkzmZkzZpkz'
 .'M5kzAJkA/5kAzJkAmZkAZpkAM5kAAGb//2b/zGb/mWb/Zmb/M2b/AGbM/2bM'
 .'zGbMmWbMZmbMM2bMAGaZ/2aZzGaZmWaZZmaZM2aZAGZm/2ZmzGZmmWZmZmZm'
 .'M2ZmAGYz/2YzzGYzmWYzZmYzM2YzAGYA/2YAzGYAmWYAZmYAM2YAADP//zP/'
 .'zDP/mTP/ZjP/MzP/ADPM/zPMzDPMmTPMZjPMMzPMADOZ/zOZzDOZmTOZZjOZ'
 .'MzOZADNm/zNmzDNmmTNmZjNmMzNmADMz/zMzzDMzmTMzZjMzMzMzADMA/zMA'
 .'zDMAmTMAZjMAMzMAAAD//wD/zAD/mQD/ZgD/MwD/AADM/wDMzADMmQDMZgDM'
 .'MwDMAACZ/wCZzACZmQCZZgCZMwCZAABm/wBmzABmmQBmZgBmMwBmAAAz/wAz'
 .'zAAzmQAzZgAzMwAzAAAA/wAAzAAAmQAAZgAAMwAAAP///wAAAAAAAAAAAAAA'
 .'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
 .'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
 .'AAAAAAAAAAAAAAAAAAAAACwAAAAAFQATAAAI/AABCBzoaRQpUVSopFJFaqDD'
 .'gXny/JH4B8+fUchUOVP1UOCTKhEjjho5KlUqUqpGPXxSoKVLPwmp+CnZ0s/A'
 .'JypaOqmCJ48fPFScUBGVqmVKgSRaqkhosSWVmi4LOAPgpkTUlkBdPjXqzBmp'
 .'EjkLqFAhNKFSoUZNkkoqduxSJy7H1iw5ShXbq1iVbi0gCtVXt0up4PnpByYV'
 .'skz9kKIz1okKnnkGQy0Aw2wBZCUcF6iy2elMP1H9iPLzCcAczqEnF8ha4I/A'
 .'EnudthTlEtVWTwOtuqS9enZUPQ9LzASacKloVKj8dOoIoESehGXLCgbOXCAm'
 .'T53++JmYB/fDgAA7';
  header('Content-Type: image/gif');
  die(base64_decode($img));
?>

apacheのmod_rewriteで%2fを変換

apacheは通常エンコードされたパス分離文字(%2F)が存在するURLを404(Not found)エラーで拒否する。

通常は問題にならないのだろうが、パラメータをURLに埋め込み、mod_rewiteでphpに処理させるとき、urlやpathのようなパラメータを扱おうとすると顕在化する。

apacheにこれを許可させるには、apacheのhttpd.confに「AllowEncodedSlashes On」を記述すればよい。

VartualHostディレクティブ内でもOKだが、.htaccessに記述するとエラーとなる。

参考
apacheマニュアル
PHPプロ!mod_rewriteでの%2F問題

2011年3月24日木曜日

ExtJSのStoreにデータダウンロードの機能を追加する PART2

前回、時間の無い中作った「ExtJSのGridやChartにデータダウンロードの機能を追加する」を利用したアプリケーションで、追加要望が出たので拡張について少し考えてみた。

前回、拡張の方法としてはGridに特化して、Gridで表示されているカラムやrendererを利用して、見えているものが、タブ区切りでダウンロードできる事を検討した。が、見えているものとは別に列やフォーマットを指定できる方が汎用性が高いことが分かり、その方向で拡張を実施することとした。

拡張したdownloadメソッド
 /**
  * Download store data
  * @param {Object} opt (optional) Specifies download filename and columns.
  */
 Ext.data.Store.prototype.download = function(opt){
  opt = opt||{};
  var output=[],o=[],
   columns = opt.columns||(function(st){
    var cs=[], i=0;
    st.fields.eachKey(function(k) {cs.push(k);});
    return cs;
   })(this),
   fn = opt.filename||opt.fn||'download.txt';
  for (var i=0,col; col=columns[i]; ++i) {
   if (typeof col === 'string') {
    columns[i] = col = {field: col}
   }
   if (!col.header) col.header = col.field;
   if (!col.format) col.format = function(v,r){return v;};
   o.push(col.header);
  }
  output.push(o.join('\t'));
  this.each(function(rec) {
   var o=[];
   for (var i=0,col; col=columns[i]; ++i) {
    o.push(col.format(rec.get(col.field), rec));
   }
   output.push(o.join('\t'));
  });
  var form = Ext.DomHelper.append(document.body, {
   tag: 'form',
   style: 'display:none',
   action: 'download.php',
   method: 'post',
   cn:[{
    tag:'textarea',
    name:'body',
    html:output.join('\n')
   },{
    tag:'input',
    name:'Content-Disposition',
    value:'attachment;filename='+'"'+fn+'"'
   },{
    tag:'input',
    name:'Content-Type',
    value:'text/tab-separated-values'
   }]
  });
  form.submit();
  document.body.removeChild(form);
 }

呼出しサンプル1
こちらではパラメータなしでdownloadメソッドを呼び出した例、storeの内容がそのままダウンロードされる

呼出しサンプル2
こちらはパラメータとして、ダウンロードファイル名や、列やフォーマットの指定を行ってダウンロードする例

使用に当たっては「ExtJSのGridやChartにデータダウンロードの機能を追加する」で使用したdownload.phpが必要となります。

phpの出力をブラウザやプロキシーにキャッシュさせない

phpのヘッダーのマニュアル内にそのものが載っているが、下記を設定するとかなりキャッシュされにくくなるとのこと。

    header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
    header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // 過去の日付

ちなみに少し以前のマニュアルの例では、もう少しコテコテやっていた。

    // 日付が過去
    header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
    // 常に修正されている
    header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
    // HTTP/1.1
    header("Cache-Control: no-store, no-cache, must-revalidate");
    header("Cache-Control: post-check=0, pre-check=0", false);
    // HTTP/1.0
    header("Pragma: no-cache");

2011年3月11日金曜日

phpで仮名を全角に、英数字と空白を半角に統一する(mb_convert_kana)

何と1行でできる

mb_convert_kanaを使用する

/*「半角カタカナ」を「全角カタカナ」に変換し、
 「全角」英数字を「半角」に変換します。
  オプションの意味
   K: かな半→全
   V: 濁点をマージ
   a: 英数字を半角にする
   s: スペースを半角にする(U+3000 -> U+0020)
 */

$str = mb_convert_kana($str, 'KVas', 'utf-8');

エンコードをEUCもしくはUTF-8とすれば、ついでに英数字の後に続く長音記号をハイフンに変換するのも簡単。

$str = mb_convert_kana($str, 'KVas', 'utf-8');
$str = preg_replace('/([a-z0-9])ー/i', '${1}-', $str);

2011年3月9日水曜日

Illuminations for Devellopers 1.1.5導入

ExtJSでの開発やデバッグの効率を桁違いに高めてくれるかも知れないツールがFireFoxのアドオンとして提供されている。

名前は「Illuminations for Devellopers」で今日現在のバージョンは1.1.5となっている。Senchaのブログに載っていたのでインストールしてみた。

インストールは通常のFirefoxのアドオンと同じ。但し、アドオンFirebugが導入されていることは前提となります。
「ツール」→「アドオン」メニューから、「アドオンを入手」をクリックし、検索のテキストボックスに「Illuminations」と入力し検索すると
Illuminations for Developers for Firebug

作成者: Steven Roussey
が、見つかるのでこれを「Firefoxに追加」する。インストール完了後にFirefoxを再起動し、Firebugを開くと、一番右「接続」の隣に「Illuminations[Trial]」のタブが増えていることがわかる。赤い大きな「Buy or Login」のボタンが少々いやらしいが、まずは無視。

早速、ExtJSを使用しているページを見に行くと、ViewPort以下どのようにBorderLayoutがあり、その中にある入れ子のBorderLayoutがTabPanelでありどんなメニューとプロパティを持っているかなど、階層的に確認していくことができる。


今まで、FireFoxでこれを確認していくことはスクリプトのウォッチの機能でできないことはなかったが、いろいろな情報が頭に入っており、見たいデータを明確にして探さないと見つけることはできなかったし、探したオブジェクトがどんなクラスのオブジェクトかということですら、持っているプロパティやメソッドから推測することしかできなかった。

このアドオンの利用によりかなりデバッグの敷居が下がるかと思う。
まだ、全然見切れていないが、導入後気になったのはこのアドオンがトライアルで、製品版があるらしいということ。どんな機能の違いがあるのだろう。