framework

July 14, 2008

Sabel AjaxUploader Sample

Sabel AjaxUploaderのサンプルを用意しました。

こちらで動作の様子を確認できます(100Mまで)。

コードは以下のような感じです。ジェネレータで生成することもできますが、コード量が少ないのでコピペでも楽かと思います。

コントローラ例
<?php

class Index_Controllers_Upload extends Sabel_Controller_Page
{
  public function upload()
  {
    $this->uploadId = md5hash();
  }
  
  public function fetchStatus()
  {
    $status = apc_fetch("upload_" . $this->request->fetchGetValue("uploadId"));
    
    echo json_encode($status);
    exit;
  }
  
  public function uploaded()
  {
    echo "uploaded";
    exit;
  }
}
uploadアクションのテンプレート例(Sabelレンダラ使用)
<script type="text/javascript" src="<?= linkto("js/Sabel.js") ?>"></script>
<script type="text/javascript" src="<?= linkto("js/helpers/AjaxUploader.js") ?>"></script>
<style type="text/css">
@import url("<?= linkto("js/helpers/css/Sabel.css") ?>");
</style>

<div id="progressBar"></div>

<form id="upload_form" enctype="multipart/form-data" action="<?= uri("a: uploaded") ?>" method="post">
  <p>
    <input type="hidden" name="APC_UPLOAD_PROGRESS" value="<?= $uploadId ?>" />
    <input type="file"   name="upfile" /><br />
    <input type="submit" value="upload" />
  </p>
</form>

<script type="text/javascript">
new Sabel.PHP.AjaxUploader("upload_form", "<?= uri("a: fetchStatus") ?>?uploadId=<?= $uploadId ?>", "progressBar");
</script>

  Powered by Sabel

July 05, 2008

Sabel JS - DatePicker(Sabel.Widget.Calendar)

Sabel 1.1で追加されるSabel.Widget.Calendarのサンプル。

カレンダーで日付を選択し、その選択された日付をインプットに適用するDatePicker.jsを書いてみた。
DatePicker.js

function datepicker(inputs) {
  Sabel.Array.each(inputs, function(input) {
    var div = document.createElement("div");
    div.style.position = "absolute";
    div.style.zIndex = 100;
    document.body.appendChild(div);
    
    var self = {
      element: Sabel.get(input),
      calendar: new Sabel.Widget.Calendar(div, {
        callback: function(date) {
          self.element.value = date.join("-");
        }
      }),
      render: function() {
        self.calendar.render();
      }
    };
    
    div.style.top  = Sabel.Element.getCumulativeTop(self.element)  + "px";
    div.style.left = Sabel.Element.getCumulativeLeft(self.element) + "px";
    
    self.calendar.WeekDays = ["日", "月", "火", "水", "木", "金", "土"];
    self.element.observe("mousedown", self.render);
  });
}
インプットのidをdatepicker()関数に渡すだけで使用できる(簡単に使えるようにしているため、任意のタイミングでカレンダーを消すなどの処理はできない)。インプットをクリックすると、そのインプットの位置にカレンダーが表示され、日付をクリックするとインプットに年-月-日が入る。
<script type="text/javascript" src="Sabel.js"></script>
<script type="text/javascript" src="DatePicker.js"></script>

<script type="text/javascript">
  new Sabel.Event(window, "load", function() {
    datepicker(["inputid1", "inputid2", ...]);
  });
</script>
動作の様子はこちら
* 実際にサンプルのように表示するにはSabelに含まれるcssや画像が必要


July 02, 2008

Sabel 1.1 Release Announcement

Sabel-1.1のリリースが7/7(月)に決定しました。
概要は以下の通りです。
  • (Core)Sabel::using()でクラスファイルを読み込めたかどうかに応じてbool値を返すように変更
  • (Function)get_temp_dir()関数追加
  • (Function)md5hash()関数追加
  • (Function)remove_nullbyte()関数追加
  • (DI)DIコンテナ追加
  • (Aspect)Aspect追加(AOPアライアンス準準拠)
  • (Mail)メール(送信/Mimeデコード)追加
  • (Http)HTTPクライアント追加
  • (Annotation)バックスラッシュによるクオートのエスケープに対応
  • (Response)設計の改善・ステータスオブジェクト追加
  • (Request-Validator)一つの入力に対し複数のバリデーションメソッドを登録できるように改善
  • (Controller-Redirector)外部サイトにリダイレクトする際などに使用するurl()メソッドが正常に動作しない問題の修正
  • (View-Pager)実装の改善(3割程度の高速化)
  • (View-PageViewer)実装のスリム化(setPriorityPrevious(), setPriorityNext(), setIgnoreEmpty()メソッド削除)
  • (Session-Memcache)createメソッドでポート番号を指定できるように改善, addServer()メソッド追加
  • (Storage-Memcache)addServer()メソッド追加
  • (Cache-Memcache)addServer()メソッド追加
  • (Util-FileSystem)Sabel_Util_FileSystemによりディレクトリやファイルを作成する際のデフォルトのパーミッションを744から755に変更
  • (DB)バイナリデータ(画像・ファイル)の保存・取得に対応
  • (DB)行のバージョニング(楽観的ロック)に対応
  • (DB)sabel.db.mssql(Microsoft SQL Server)パッケージの追加
  • (DB)Sabel_DB_Modelの各メソッドに対するコールバックの対応が変更
  • (DB)Joinオブジェクト使用時のカラムの指定を可能に改善
  • (DB-Model)selectWithChildrenメソッドを削除
  • (DB-Model)save()メソッドによりモデルの状態をデータベースに反映する際、プライマリキーの値が変更されている場合に例外を投げるように変更
  • (Test)Sabel_Test_Fixtureクラス追加
  • (Processor-Action)リクエストバリデーションがURIクエリに対応
  • (Processor-Session)session.use_trans_sidがOnかつクライアントがCOOKIEを無効にしている時にセッションIDが2重に付加される問題の修正, セッションが開始されていない際にリンクやリダイレクト先URIにセッション名が付加される問題の修正
  • (JS)Sabel.Environment追加
  • (JS)Sabel.Class追加
  • (JS)Sabel.KeyEvent追加
  • (JS)Sabel.Number追加
  • (JS)Ajaxアップローダ追加(apc必須)
  • (JS)Dateピッカー(カレンダー)追加
  • (JS)ElementにgetRegion(), replaceClass()メソッド追加
  • (JS)Sabel.Util.UriをSabel.Uriに変更
  • (JS)Element.getDimentionsメソッドのバグ修正
  • (JS)Effectのバグ修正
  • (JS)要素の絶対位置取得メソッドのバグ修正
  • (JS)現在のスクロール量取得メソッド追加
  • (JS)Stringクラスの大幅な改善(sprintf, htmlspecialchars, chr, repeat追加など)
  • (JS)Ajaxのオプションにtimeout, scope追加
  • (JS)Eventにscope追加
  • (JS)widget.Overlayの改善(Widget.Overlayにリネーム)
  • (Task)各種ジェネレータ追加
  • (Task)バッチ実行ファイル(sabel.php)で正常なアプリケーションルートパスが定義されない問題の修正
  • (Addon-Form)Formオブジェクトが保持するHTMLを書き出すオブジェクトの初期化に不具合があったのを修正, モデルにバージョンカラムがある場合にclose()メソッドで</form>タグとともにバージョン値をhiddenで書き出すように対応
  • (Addon-Renderer)ショートタグ形式の場合にHTMLエスケープするようにSabelレンダラを改善, SabelレンダラのHTMLタグを抜き出す正規表現を最小マッチに変更
  • (Lib-Paginate)setOrderColumn()メソッドをsetOrderColumns()に変更, setDefaultOrder()メソッド追加, uriの指定を省略可能に改善
  • rewriteモジュールがロードされていない場合にInternal Server Errorになる問題の修正
  • Scaffold(sabelコマンド)にlangオプション(ja)追加
  • $_SERVER["HTTP_HOST"]を参照している箇所を$_SERVER["SERVER_NAME"]を参照するように変更

    Powered by Sabel

June 15, 2008

Javascript - mouseover, mouseout

Javascriptでdivなどのmouseoverやmouseoutイベントを扱う際、そのdivが他の要素を内包していると厄介な挙動をする。

div3
<div id="a" onmouseover="alert('over');" onmouseout="alert('out');">
  <div id="b">
    <div id="c"></div>
  </div>
</div>
例えば上記のように、a内にbがあり、b内にcがある状態で、aのmouseover, mouseoutイベントでアラートを表示すると、マウスがb上に移動すると一度outし直後に再びoverする。c上に移動した時も同様。

IEでは以前からonmouseenterやonmouseleaveがあるようで、これを使うとbやcは関係なく、aに入った時と出た時だけイベントが発生してくれる。
他のブラウザでも同様の振る舞いを実現するにはそれ用の実装をする必要があるが、Sabel JS(Sabel 1.1以降)だと以下のようにできる。
<div id="a">
  <div id="b">
    <div id="c"></div>
  </div>
</div>

<script type="text/javascript">
  var a = Sabel.get("a");
  a.observe("mouseenter", function(){ alert('over'); });
  a.observe("mouseleave", function(){ alert('out');  });
</script>
動作の様子はこちらで。

May 30, 2008

Sabel 1.1 - Mail, MimeDecode

Sabel 1.1でSabel_Mail_MimeDecodeが追加されます。PEARのMail_mimeDecodeと同じようなものですが、PEARではマルチパートの場合にpartオブジェクトの再帰構造で結果が返されるため、どこに本文があるのか、どこにHTML本文があるのかの判断が面倒です。同じ内容でもThunderbirdとOutlook Expressで送信すると構造が異なることがあるため、厄介です。

Sabel_Mail_MimeDecodeでは常に同じように本文やHTML本文などを取得できます。一般的なメールに限られますが、以下の形式に対応しています。

・本文
[本文]
・HTMLメール
[HTML本文]
・HTMLメール(インライン画像有)
multipart/related
    [HTML本文]
    [インライン画像]
    ...
・HTMLメール + 添付ファイル
multipart/mixed
    multipart/related
        [HTML本文]
        [インライン画像]
        ...

[添付ファイル]
...
・本文 + HTMLメール
multipart/alternative
    [本文]
    [HTML本文]
・本文 + HTMLメール(インライン画像有)
multipart/alternative
    [本文]
    multipart/related
        [HTML本文]
        [インライン画像]
        ...
・本文 + HTMLメール(インライン画像有)
multipart/related
    multipart/alternative
        [本文]
        [HTML本文]

[インライン画像]
...
・本文 + HTMLメール + 添付ファイル
multipart/mixed
    multipart/alternative
        [本文]
        [HTML本文]

[添付ファイル]
...
・本文 + HTMLメール(インライン画像有) + 添付ファイル
multipart/mixed
    multipart/alternative
        [本文]
        multipart/related
            [HTML本文]
            [インライン画像]
            ...

[添付ファイル]
...
・本文 + HTMLメール(インライン画像有) + 添付ファイル
multipart/mixed
    multipart/related
        multipart/alternative
            [本文]
            [HTML本文]

    [インライン画像]
    ...

[添付ファイル]
...
・ダイジェスト
multipart/digest
    message/rfc822
        [上記のいずれかの形式]
    ...
・本文 + ダイジェストメール
multipart/mixed
    [本文]
    multipart/digest
        message/rfc822
            [上記のいずれかの形式]
        ...
・本文 + ダイジェストメール + 添付ファイル
multipart/mixed
    [本文]
    multipart/digest
        message/rfc822
            [上記のいずれかの形式]
        ...

[添付ファイル]
...

使い方は以下のようになります。
$decoder = new Sabel_Mail_MimeDecode();
$decoded = $decoder->decode(file_get_contents("/path/to/mail.eml"));

if ($decoded->body) {
  echo $decoded->body->getContent();  // 本文
}

if ($decoded->html) {  // HTMLメール
  echo $decoded->html->getContent();  // HTML本文
  if ($images = $decoded->html->getImages()) {  // インライン画像
    foreach ($images as $image) {
      echo $image["cid"];       // コンテンツID
      echo $image["mimetype"];  // MIMEタイプ
      echo $image["data"];      // 画像データ
    }
  }
}

if ($decoded->attachments) {  // 添付ファイル
  foreach ($decoded->attachments as $attachement) {
    echo $attachment->getName();     // ファイル名
    echo $attachment->getType();     // MIMEタイプ
    echo $attachment->getContent();  // 添付ファイルデータ
  }
}

if ($decoded->mails) {  // ダイジェスト
  foreach ($decoded->mails as $mail) {
    // $decodedと$mailは同じように扱える
  }
}

1.1の最新版はSVNでチェックアウトできます。
http://svn.sabel.jp/branches/1_1

Sabel PHP Framework



May 25, 2008

Sabel 1.1 - Request Validation

Sabel 1.1のRCがそろそろきられるかと思います。

Sabel 1.1で、リクエストバリデータがPOST以外のメソッドにも対応しました。GETパラメータ(URIクエリー)にも使用できるようになったのは結構良いです。
例えばid=100のようなクエリを必要とする時、まずnullでないかをチェックし、数値(整数)であるかのチェックをします。この作業は(多く発生するため)面倒で、実際にこのようなチェックをしていないかのような動作をするWebアプリも少なからず存在します。

Sabel 1.1のリクエストバリデータはGETにも対応したので、アクションの@checkアノテーションを使用できます。
class SomeController extends Sabel_Controller_Page
{
  /**
   * @check id integer
   */
  public function someAction()
  {    
  }
}
また、一つの入力に対して複数のバリデーションを設定するには、スイートを作成する必要がありましたが、複数のルールをアノテーションで指定できるようになりました。
  /**
   * @check id required integer
   */
  public function someAction()
  {    
  }
アノテーションを書くだけでバリデーションが行われるため非常に楽です。バリデーションに失敗するとアクションは実行されず、GETメソッドの場合は"400 Bad Request"がクライアントに返されます。

May 16, 2008

Sabel 1.1

Sabel 1.1の開発が少し落ち着いてきました。
全てではありませんが、概要は以下の通りです。

・DIコンテナ追加 (Container)
・Aspect追加 (Aspect)
・get_temp_dir()関数追加 (Functions)
・md5hash()関数追加 (Functions)
・バイナリデータ(画像・ファイル)の保存・取得に対応 (DB)
・行のバージョニングに対応 (DB)
・sabel.db.mssql(Microsoft SQL Server)パッケージの追加 (DB)
・Sabel_DB_ModelのselectWithChildrenメソッドを削除 (DB)
・Sabel_DB_Modelの各メソッドに対する前後処理メソッドの対応が変更 (DB)
・setDefaultOrder()メソッド追加、uriの指定を省略可能に (Paginate)
・アップロードプログレスバー (JS/JS Helper)
・カレンダーによるデートピッカー (JS/JS Helper)
・Timeout機能をAjaxに追加 (JS)
・メール送信ライブラリ追加 (Mail)
・HTTPリクエスト追加 (Http)
・各種ジェネレータ追加 (Tasks)
    コントローラ (登録,一覧,編集,削除)
    フローコントローラ (登録,編集に確認画面有り)
    ログインコントローラ
    アップロードプログレスバー
・外部サイトにリダイレクトするためのurl()メソッドが正常に動作しない問題の修正 (Controller)
・rewriteモジュールがロードされていない場合にInternal Server Errorになる問題の修正

多くの機能が追加され、少しの設計の改善がされています。
リリースは5/30〜6/6になる予定です。

1.1の最新版はSVNでチェックアウトできます。
http://svn.sabel.jp/branches/1_1

Sabel PHP Framework




Sabel

Sabel PHP Frameworkを開発しています。
http://www.sabel.jp/

Search
Categories
Tags
Recent Articles
Archives