[IM]ドラッグ&ドロップでファイルアップロード

ファイルのドラッグ&ドロップによるアップロードをINTER-Mediatorに実装しました。動作条件を整える方法はドキュメントを改めて書きますが、ページファイル上は、

class=”IM[testtable@vc1] IM_WIDGET[im_fileupload]”

のように、IM_WIDGETで、利用するコンポーネントを書くだけで、以下のムービーのようなドラッグ&ドロップによるファイルのアップロードができるようになっています。

dragdrop

[IM]PHP Ver.5.3 on OS Xで、APCを稼働させる方法

ファイルのアップロードをするときのプログレスバーを出す方法が「A Simple PHP Upload Progress Bar」というページに紹介されています。シンプルなのでやりやすそうと思われるのか、このサイトのスクリプトを単にコピーしただけのサイトなんかもあります(せめて出展くらい出すべきでしょう)。

当初、動かし方を紹介したサイトはないかと思って探したのが「Mac OS XのPHP 5.3にAPC(Alternative PHP Cache)をインストールする方法」というサイトでした。OS X Lion時代のものなのかこの通りでは動かなかったので、追加で必要な作業をまとめてみました。

プログレスバーを出す仕組みはちょっとややこしいのですが、ポイントの1つはPHPのAPC(Alternative PHP Cache)という機能を利用することです。残念ながら、PHP 5.3では生の状態ではこの機能は使えません。この機能を、OS X Moutain Lion + OS X Server Ver.2.2 + FileMaker Server 12という状況で使えるようにする方法を解説します。PHPは、Ver.5.3.13です。FileMaker Serverでない場合php.iniファイルの扱いが違ってくると思われます。

  1. Webサーバ稼働マシンに、Xcodeをインストールしてください。Xcode 4.6.2で以下の動作は確認しています。
  2. MacPortsをインストールします(インストール済みならもちろん何もしなくてもOKです)。まず、以下のコマンドでダウンロードします。以下のURLはアップデートにより変更されるかもしれません。
    curl -O https://distfiles.macports.org/MacPorts/MacPorts-2.1.3-10.8-MountainLion.pkg
  3. 以下のコマンドでインストーラを使ってMacPortsをインストールします。
    sudo installer -target / -pkg MacPorts-2.1.3-10.8-MountainLion.pkg
  4. 以下のコマンドで、autoconfiをインストールします。
    sudo port install autoconf
  5. 以下のコマンドで、pcreをインストールします。
    sudo port install pcre
  6. 以下のコマンドで、ヘッダファイルの1つをコンパイラが認識するディレクトリにコピーします(参考)。
    sudo cp /opt/local/include/pcre.h /usr/include
  7. APCのソースをダウンロードします。URLはアップデートによって変更があるかもしれません。
    curl -O http://pecl.php.net/get/APC-3.1.13.tgz
  8. アーカイブを展開します。
    tar zfvx APC-3.1.13.tgz
  9. カレントディレクトリに移動します。
    cd APC-3.1.13
  10. 以下のコマンドを入れます。
    phpize
  11. 次のように表示されます。warningがありますが、問題ない模様です。
    Configuring for:
    PHP Api Version: 20090626
    Zend Module Api No: 20090626
    Zend Extension Api No: 220090626
    configure.in:3: warning: prefer named diversions
    configure.in:3: warning: prefer named diversions
  12. おなじみの以下のコマンドでコンパイルします。
    make
    sudo make install
  13. 最後のコマンドで以下のようなメッセージが表示されます。1行目のパスをphp.iniファイルに記述するので、コピーしておくといいでしょう。
    Installing shared extensions: /usr/lib/php/extensions/no-debug-non-zts-20090626/
    Installing header files: /usr/include/php/
  14. php.iniファイルを変更します。以下のパスは、Mountain Lion + FMS12の場合です。使用する状況に合わせて正しいphp.iniファイルを編集します。もし、ない場合は、/etc/php.iniあたりに作成します。使用しているphp.iniファイルのパスを調べるには、phpinfo関数の出力を利用しましょう。
    sudo nano ‘/Library/FileMaker Server/Web Publishing/publishing-engine/php/mountain lion/lib/php.ini’
  15. php.iniファイルに以下の3行を追加します。これらの設定をいままで全く行っていないのなら、そのまま追加でかまいません。すでに設定がないかどうかは検索して確認しましょう。
    extension_dir=/usr/lib/php/extensions/no-debug-non-zts-20090626/
    extension=apc.so
    apc.rfc1867=on
  16. 以下のコマンドを入力して、Apacheに設定変更を適用させます。
    sudo apachectl graceful
  17. phpinfo関数の出力を見て、APCのカテゴリがあることと、apc.rfc1867の値が「On」になっていることを確認します。

ポイントとしては、APCのコンパイルのために、autoconf、pcreが必要である点です。また、APCの設定は既定値ではrfc1867はOffですので、設定ファイルで記述してオンにしておく必要があります。

なぜ、この記事のカテゴリにINTER-Mediatorがあるかというと、この仕組みをINTER-Mediatorに組み込んだからです。

スクリーンショット 2013-06-16 16.44.40

[IM]新規レコード作成時の挙動

INTER-Mediatorで、テーブルに新たにレコードを作るときの挙動にバグがあり、全体的に見直しをしました。以下の内容は、Ver.3.4以降で有効です。

まず、「新規レコード作成」のクライアント側でのAPI、つまり、JavaScriptベースでの呼び出しは4カ所あります。最初の3つは、主としてINTER-Mediator自身が使うものです。

  • INTERMediator.insertButton(…):レコードの繰り返しの下などに表示されるボタン
  • INTERMediator.insertRecordFromNavi(…):ナビゲーションのボタン
  • INTERMediator.clickPostOnlyButton(node):新規レコード作成専用モード
  • INTERMediator_DBAdapter.db_createRecordWithAuth(args, completion):汎用

最後のメソッドは、INTERMediator_DBAdapter.db_createRecordでもかまいませんが、上記のメソッドだと認証のある場合、ない場合、どちらでも利用できます。

さて、データベース処理に関係する定義ファイル内のコンテキストのキーはまとめるとこんな感じです。ここでは、レコード作成に絞って考えます。

  • name:コンテキスト名、tableがないとこの名前のテーブルにINSERTする
  • table:実際のテーブル名を記述
  • view:(無視)
  • records:(ナビゲーションのボタンでレコードを作ったときの動作に影響)
  • key:(同上)
  • relation:(関連レコードの作成時に利用)
  • query:(この設定は無視する)
  • sort:(無意味)
  • default-values:(フィールドの初期値)
  • script:(新規レコード作成時に実行するスクリプトを指定、主にFileMaker)
  • アクセス権設定:(新規レコードの認可の定義)

一時期のINTER-Mediatorでは、queryキーで指定した内容を、初期値として設定するようなプログラムが組み込まれていました。そうしないと、新規レコードを作った後に「検索されない」という状況が発生するからです。しかし、それはdefault-valuesキーで指定をすることで、検索される状態は設定できるので、あえて、queryキーを無視するようにしました。

一方、relationキーについては、関連レコードのテンプレート処理側では、これに対応した外部キーへの値の設定がないと、新しく作ったレコードは関連レコードになりません。なので、INTERMediator.insertbuttonメソッド内で、コンテキストのこの情報を見て、外部キーのフィールドの初期値を自動的に与えています。なお、演算子は無視しているので、演算子に>があるような場合などは要注意です。INTERMediator.insertRecordFromNaviメソッドは、ナビゲーションのボタンで呼び出されます。従って、通常は関連レコードのコンテキストには適用されず、relationキーは無視します。INTERMediator_DBAdapter.db_createRecordWithAuthについても、relationキーは無視します。

一方、JavaScriptのプログラムで、検索条件、ソート条件、さらに新規レコードの初期値を指定するプロパティが以下のように定義されています。新規レコードの初期値はVer.3.4が初出です。

  • INTERMediator.additionalCondition:(無視する)
  • INTERMediator.additionalSortKey:(無意味)
  • INTERMediator.additionalFieldValueOnNewRecord:(初期値として適用される)

新規レコードではソート条件は関係ありません。検索条件のINTERMediator.additionalConditionについては、新規レコード作成時は一切無視されます。一方、すべての新規レコード作成時に、INTERMediator.additionalFieldValueOnNewRecordに指定した値が初期値として設定されます。

まとめると、新規レコード作成時には検索条件は一切利用しません。その代わり、スタティックな初期値としてのdefault-valuesキー、ダイナミックな初期値としてのINTERMediator.additionalFieldValueOnNewRecordが適用されます。また、関連レコード内でのInsertボタンを押したときにはrelationキーの値が利用されますが、その他の場合にはrelationキーは適用されません。