[IM] FileMaker Server 17とINTER-Mediator

FileMaker 17が発売されました。そして、FileMaker Server 17がリリースされました。ちょっとずつ変わりながら毎年アップデートするFileMakerですが、サーバーは結構変わっています。大きなところでは、管理コンソールがグッと今風なデザインになり、かっこよくなりましたが、その代わり、管理コンソールで設定変更できない項目が出てきました。その辺りがINTER-Mediatorの利用に大きく関連するので、INTER-Mediatorの利用に重点を置いて、変わった部分を説明しましょう。

PHPはインストール直後は未導入

FMS16までは、セットアップ時に選択すればPHPを設定できましたが、FMS17は初期状態ではPHPは使えない状態になっています。もし、PHPを別のサーバーで動かすなら、もうFMSのWebサイトにはPHPは不要ということになりますが、FMSのWeb機能を自分のマシンで動かして検証するなどの作業をしたい方も多いでしょう。その場合、以下のようにコマンドを入れます。$に続く部分が自分で入力するコマンドで、太字にしてあります。fmsadminコマンドで、管理コンソール上では見えなくなったいくつかの機能の設定を行うようになったのです。ユーザー名とパスワードを聞かれれば、FMSの管理者のユーザー名とパスワードを入力します。

$ fmsadmin set cwpconfig enablephp=true
username (msyk):admin
password:
EnablePHP = true
Restart the FileMaker Server background processes to apply the change.

macOSの場合は、「ターミナル」を使います。ログインしているユーザーが管理者の場合には、sudoをしなくても、fmsadminは利用できます。Windows 10の場合、最近まで、スタートメニューの右クリックででてくるメニューで管理者権限でコマンドプロンプトを起動できましたが、いつの間にかこの項目はでなくなっています。スタートメニューの右クリックで「Windows PowerShell(管理者)」を選択して、PowerShellを使いましょう。「コマンドが違うのでは?」と思われるかもしれませんが、上記のfmsadminも、以下のnetコマンドもPowerShellで使えるので安心してください。

このコマンドを入力すると、最後に再起動をするように出てきます。ここで、Webサーバーだけの再起動(HTTPServerフォルダにあるstop、startというファイルをsudo touchで更新)でやってもPHPは稼働しません。それから、CWP(Custom Web Publishing)の再起動も同様です。以下のコマンドで機能の再起動を行います(松尾さん、ありがとうございます)。もちろん、FileMaker Serverの管理者のユーザー名とパスワードを入力する必要があります。

fmsadmin restart httpserver -y

以下のように、FMS全体の停止と起動を行う必要があります。macOSの場合は次のように2つのコマンドを入れます。

sudo launchctl stop com.filemaker.fms
sudo launchctl start com.filemaker.fms

Windowsの場合は、以下の2つのコマンドを入力します。なお、Windows 10の場合は、他に考慮点が色々あるので、この記事の最後の方にそれを記載をします。

net stop "FileMaker Server"
net start "FileMaker Server"

これで、phpinfo()関数を動かすと、次のように、Ver.5.6.24が稼働していることがわかります。なお、info.phpファイルの中身は、phpinfo()関数だけでなく、タイムゾーン指定を入れないと警告が出て情報は表示されません。例えば、info.phpファイルは次のように作ります。

<?php date_default_timezone_set("Japan"); phpinfo(); ?>

PHP自身は古いビルドのままですし、Ver.7.2が主要リリースな今時にVer.5.6なので、アップデートする気はないというところが感じられます。

つまり、FMS17をインストールすると、PHPの実行環境はインストールされているものの、利用できる状態になっていなかったということです。ちなみに、macOSの場合は、Apache2の主要設定ファイルである/Library/FileMaker Server/HTTPServer/conf/httpd.confの最後に、

Include '/Library/FileMaker Server/Web Publishing/publishing-engine/php/sierra/httpd.fmi.conf.php'

という行が加わり、モジュールが読み込まれます。Windowsでも、FileMaker ServerフォルダはC:¥Program Files¥FileMakerにありますが、そこからのパスはほぼ同じような場所にPHPの実行環境が用意されていますが、IISにサイトを追加してWebサーバーとして稼働するようにしています。phpinfo()関数でphp.iniファイルを確認して、必要であれば設定を変更しましょう。

db-class=”FileMaker_FX”を指定する場合

FX.phpを使ってFileMaker Serverへ接続する場合を説明しましょう。INTER-Mediator 5.7/6現在、現実にはFX.phpの一部分だけを使っていますが、何れにしても、以前からあったXML共有を利用してデータベースアクセスしています。

XML共有を利用するには、まず、Web公開エンジンをオンにします。管理コンソールで、コネクタのページを開き、左側のリストで「Web公開」を選択し、右側の「Web公開エンジン」にあるボタン(右のほうにある左右に動くスイッチ)が全体的に青くなるようにしてオンにします。しかし、これだけではありません。

XML共有をオンにするには、さらに、以下のような$以降のコマンドを入力します。もちろん、FMSの管理者アカウントで認証が必要です。このコマンドに関しては、再起動は不要です。

$ fmsadmin set cwpconfig enablexml=true
username (msyk):admin
password:
EnableXML = true

このように、「Web公開エンジン」のオン、そしてXML共有をオンにすることの両方が必要になります。

db-class=”FileMaker_DataAPI”を指定する場合

FMS16でプレビュー扱いだったFileMaker Data APIも、FMS17では正式機能となり、ライセンス価格も「ダウンロードデータ量」に関連することに決まりました。ユーザー数で考えれば幅が広くなるWebサイトの事情を考慮したという点では評価できると考えます。1年間のライセンスの場合、24GX人数までが購入価格に含まれた分量ですが、ともかく、データ転送量を見積もらないと、かかるコストが分からないという状況になりました。

FileMaker Data APIの正式版は、ある意味で「バージョン1」と呼ぶのが適切でしょう。API呼び出しのURLがプレビュー版と大きく違っており、URLに「v1」という文字があることからも、API自体にバージョン管理を今後は行うということを示唆しているものと思われます。

FileMaker Data APIに応答するようにするには、管理コンソールで、コネクタのページを開き、左側のリストで「Web Data API」を選択し、右側の「Web Data API」にあるボタン(右のほうにある左右に動くスイッチ)が全体的に青くなるようにしてオンにします。これだけでよく、コマンドの入力は不要です。

なお、INTER-Mediatorは、FMDataAPIというライブラリを利用して、FileMaker Data APIを利用しています。FMDataAPIはVer.8で、プレビュー版からバージョン1へと対応APIを変更しました。FMS17リリース直後からVer.8は公開していますが、INTER-Mediatorで利用できるようになるためには、INTER-MediatorにあるFMDataAPIをアップデートしないといけません。アップデートするのは簡単ですが、FMS16のFileMaker Data APIは使えなくなります。もっとも、プレビュー版のAPIで真剣に構築していることはないだろうという見込みもあるので、単にどどーんとアップデートしてもいいのですが、その辺り、現在は検討中というところです。アップデート情報はFacebook等で公開します。

Windows 10でFileMaker Server 17

FileMaker Serverは、以前からWindows Serverが対応OSとなっており、Windows 10は対応OSではありません。また、FMS14に関するFileMaker社の文書では、「互換性はありません」となっています。ところが、Windows 10 Pro に FileMaker Server をインストールする によると、FileMaker Server 14/15のインストールができるようにする方法が書かれています。開発者としては手元のWindowsでFMSが動いて入れば便利だと思うところでもあるので、FileMaker Server 17がWindows 10で稼働するかどうかを試してみました。前述の記事のようにインストーラが動かないということはなく、インストーラは問題なく動き、インストールは可能です。ただし、インストーラが動くとは言え、様々なエラーメッセージをうまく捌かないといけない模様であり、「簡単ではないかもしれない」と言ったところです。そこで、PHPを動かすところまでを実現するためにどうすればいいかを確認しました。なお、FileMaker社は稼働するという保証をしていないので、Windows 10でのFMS利用はご自分のリスクで進めてください。

実際に確認したのは、Windows 10 Proに、バージョン1803のアップデートを当てたPCです。IISが稼働していない状態でインストールをすると、途中で次のようなメッセージが出てきて、インストールは途中で終わってしまいます。

そこで、IISをあらかじめ起動しておきます。スタートメニューを表示した時に左端に見えるギアのアイコンの「設定」を選択して、設定ウインドウを表示します。そして、「アプリ」を選択します。そして、右端にある「プログラムと機能」を選択し、懐かしいコントールパネルの「プログラムのアンインストールまたは変更」を表示し、左側にある「Windowsの機能の有効化または無効化」を選択して「Windowsの機能」ウインドウを表示します。ここで「インターネットインフォメーションサービス」のチェックを入れます。黒い四角になるのは下位の項目が全部チェックされているわけではないということを意味しています。ここで、World Wide Webサービス>アプリケーション開発機能と階層を下り、「CGI」のチェックを入れておきます。このチェックを入れておくのがポイントです。他はそのままでいいのですが、必要に応じて他の機能を入れてもいいでしょう。OKをクリックします。もし、再起動を求められたら再起動をしてください。

この準備をした上で、FileMaker Server 17のセットアップを行えば、概ね問題なく稼働するもようです。インストール途中で以下のようなダイアログボックスが出てくれば、「Webサイトを無効にする」をクリックしてください。これはIISのデフォルトのサイトをオフにして、FileMakerでセットアップされるサイトだけを利用するためです。

こうしてセットアップが終われば、最初に説明したようにコマンドを入れればPHPが利用できるようになります。ただし、INTER-Mediatorを稼働させるという観点では、初期状態のPHPのモジュール読み込みは十分ではないので、php.ini等の設定を変更する必要があります。これについては、近日中にまとめたいと思います。

IISの設定を見るには、スタートメニューを右クリックして「コンピュータの管理」を選択します。「サービスとアプリケーション」の下位項目に、IISがあります。Default Web Siteは停止状態になり、FileMaker Serverのセットアップにより、FMWebSiteという設定が増えていることがわかります。

ここで、PHPを稼働させる設定は、「ハンドラマッピング」の中にあります。その項目の詳細設定ダイアログボックスは次のようになっています。パスは、C:¥Program Files¥FileMaker¥FileMaker Server¥Web Publishing¥publishing-engine¥php¥php-cgi.exeが指定されています。

ちなみに、WindowsでのPHPの稼働方法をチェックすることも含めて、fmsadmin set cwpconfig enablephp=trueを使わないで、IIS上でPHPを稼働できるかを試してみたのですが、その時には、以下の2つのパスのフォルダに、IIS_IUSRSグループに読み取りと実行の権限を与える必要がありました。要するにWeb公開するフォルダと、PHPの実行モジュールへのアクセス権を設定する必要があるということでしょう。

C:¥Program Files¥FileMaker¥FileMaker Server¥HTTPServer¥conf
C:¥Program Files¥FileMaker¥FileMaker Server¥Web Publishing¥publishing-engine¥php

他に、アプリケーションプールの詳細設定で、32ビットアプリケーションの有効化をtrueにしてやっと動いたということもあるのですが、FileMaker Serverに自動設定させた結果では、アプリケーションプールの設定はfalse(既定値)のままでした。

以上のように、Windows 10でもFileMaker Server 17は使えたのですが、なんども書きますが、対応OSではない点を理解した上で対処をしてください。

INTER-Mediatorのレコード数制限の実装

INTER-Mediatorのことをブログで書くのが久しぶりな気がしているが、以前のように、設計書代わりにブログを書いておく。INTER-Mediatorのコードにタッチしていない方はなんのことか分からないと思うので、最初にその点を指摘しておく。

INTER-Mediatorでは、ページネーションコントロールを自動的に生成して、例えば30レコードずつ表示するような仕組みを設定だけで実現している。しかしながら、その後に、ポップアップメニューからレコード数制限をできるようにしたり、Master/Detail形式のUIを実現したりと、1度に表示するレコード数に絡む機能を追加してきた。3年ほど前に、かなり混乱した感じになったのでリファクタリングをしたが、バグレポートをもらい、相変わらず怪しい部分があることに気づいた。ここで、根本的に直したいと思うのだが、今までの方法で欠けていたのは「ルールの明確化」だった。そこで、ルールを作って実装というか、リファクタリングをしたいと考える。

まず、現状(5.7+α)で、どんな要素が関連しているのかをまとめて見たい。レコード数に影響するUI要素は次のものである。

  1. ページネーション
  2. ポップアップメニュー(data-im=”_@limitnumber:コンテキスト名” の属性があるSELECT)
  3. Master/DetailのDetail側(navi-control=”detail”、詳細側なので常に1レコードにしたい)

コンテキスト定義のキーで、関連するものは次のとおりである。

  1. records
  2. maxrecords
  3. paging
  4. relation
  5. navi-control

さらに、関連するプロパティを挙げると次のとおりである。プロパティと言いつつ、オブジェクトは1つなので、事実上のグローバル変数である。なお、以下のプロパティの3, 4, 5は、getter/setter実装している。ローカルストレージ等を利用してページ移動してもパラメータの記憶をしたいためだ。

  1. INTERMediator.pagedAllCount
  2. INTERMediator.totalRecordCount
  3. INTERMediator.startFrom
  4. INTERMediator.pagedSize
  5. INTERMediator.pagination

これれらの仕組みをどのように解釈するかという問題である。

まず、INTERMediatorオブジェクトのプロパティについては、paging=trueのコンテキストに対してページネーションを動作させるためのものであるので、ここでは「ページングを特定のコンテキストに対して実施する」という決定がなされた後のものである。したがって、UIとコンテキスト定義の内容について、どのように解釈をすべきなのかを、まずは決めなければならない。ここを曖昧にしていたのが、バグが常に治らない原因と考える。しかし、基準も何もない。よって、「UIが自然かどうか」という観点で推測しながら決め事をしなければならない。

前提条件1:
ページネーション処理は単一のコンテキストのみ

この点は、異論はあるかもしれないが、複数のコンテキストにページングを配置すると、画面に複数のページネーションコントロールが登場して、混乱をしかねないUIとなる。適切なUI設計では複数のページネーションは不要と考える。これを前提とする。また、1コンテキストに複数のページネーションコントロールを用意するということも同様にやらないことを前提とする。

前提条件2:
Master/Detail形式のUIでは、ページネーションはMaster側にだけ適用される

MasterにもDetailにもページネーションが欲しいという声が聞こえてきそうであるが、それぞれを同時に表示することも仕組みとしては持っているため、ページネーションはMasterだけに適用させたい。Detail側にレコード移動の機能を組み込めないようにしたいのである。なお、どうしてもそうしたいと思う場合には、Master/Detailの機能を使わないで、Detailと同一内容のページファイルを用意して、普通にページネーションを利用できる。適切な対応策があるので、この前提条件はデグレードには当たらないと考える。

優先順位1:
そのコンテキストで取り出されるレコード総数はmaxrecordsを上回ることは絶対にない

この仕様の優先順位が高いとしたら、サーバー側での検証とレコード数の修正は必要であるし、通信直前に処理するなど、UIから遠いところで処理をしないといけない。

優先順位2:
navi-control=detailのコンテキスト場合、レコード数は常に1以下とする

ある時点でこの設定を入れた。優先順位を高めにして、他の設定より優先される方が、矛盾するコンテキスト設定してもうまく動く模様であるが、一方、間違いに気づきにくいということにもなる。

優先順位3:
ポップアップメニューがあればそれに従う

ポップアップメニューは、ローカルコンテキストに記録するのであるが、ローカルコンテキストのバインド処理は、ページ合成処理の最後の方にやっている。少なくとも、limitnumber:*の値の処理を、ページ合成前にもしなければならないし、本当に初めてページを開くときはローカルコンテキストがセッションに残されていないので、ノードを探る処理も結果的に入れておく必要がある。ここの改造は、コードの追加を伴う。

優先順位4:
recordsキーの値に従う

これは順当なルール。なお、relationがあるとレコード数の制限はなくすということを一瞬考えたが、関係レコードの上位3件だけ表示したいということもあると思う。結果的にrelationキーは考慮しなくてもいいのではないかと思う。

これらのルールで得られた「レコード数」を元にしてレコードを取得する。ページネーションを利用するコンテキストなら、ページネーションとの連動が必要になる。このページネーションとの連動部分が、コードとしてはうまく分離されていないのが現状である。上記のルールで決まれば、それに応じてページネーションを設定するという風に、レコード数とページネーションの処理順序を決めて、依存関係をシンプルにするようにリファクタリングを進める必要があると考えられる。すなわち、

方針:
レコード数決定プロセスとページネーション処理を分離し、レコード数の決定を先に行って結果を必要ならページネーション処理に渡す

ということになる。この方針で行ってみようと思う。