FileMaker Webアプリを実装するにあたり、FX.php, FileMaker API for PHPの使い方やパフォーマンス比較を紹介してきた。FMCakeMixの動向を追う第3回目は「OR検索のサポート」「FileMakerスクリプト実行のサポート」を中心に、FMCakeMixでOR検索を実行する場合・FileMakerスクリプトを実行する方法を取りあげる。
FMCakeMixでOR検索をおこなうには
5月11日(米国時間)に、OR検索がおこなえるように修正がおこなわれた。これはもともとFileMaker Web公開がサポートしている-lop引数を利用したもの。コントローラ(/app/controller/*.php)で検索をおこなう際に$conditionsに「or」という文字列を渡すと、dbo_fmcakemix.php側でFX.phpのSetLogicalOR()がコールされるという仕組みだ。DBOドライバの実装部分は次のとおり。
dbo_fmcakemix.php 213-251行目より
if(!empty($queryData['conditions'])) {
$conditions = array(); // a clean set of queries
$isOr = false; // a boolean indicating wether this query is logical or
foreach($queryData['conditions'] as $conditionField => $conditionValue) {
// if a logical or statement has been pased somewhere
if($conditionField == 'or') {
$isOr = true;
if(is_array($conditionValue)) {
$conditions = array_merge($conditions, $conditionValue);
}
} else {
$conditions[$conditionField] = $conditionValue;
}
}
// look for condition operators set in conditions array
// remove them then include them fx style in the query
$operators = array();
foreach($conditions as $conditionField => $conditionValue) {
$operator = $this->parseConditionField($model, $conditionField, 'operator');
$field = $this->parseConditionField($model, $conditionField, 'field');
if ($operator) {
$operators[$field] = $conditionValue;
unset($conditions[$conditionField]);
}
}
foreach($conditions as $conditionField => $conditionValue) {
$field = $this->parseConditionField($model, $conditionField, 'field');
$this->connection->AddDBParam($field, $conditionValue, isset($operators[$field]) ? $operators[$field] : 'eq');
//add or operator
if($isOr){
$this->connection->SetLogicalOR();
}
}
}
FX.php 1822-1825行目より
function SetLogicalOR ()
{
$this->AddDBParam('-lop', 'or');
}
$conditionField中に「or」が存在していれば、$isOrがtrueとなる。$isOrがtrueの場合は、引用部分の最下部で「$this->connection->SetLogicalOR();」がコールされる。実際に使用する場合のコードサンプルと、サンプルに使用するFileMakerデータベース情報は次のとおり。
- FileMakerファイル名: fmcake_test
- FileMakerレイアウト名: fmcake_setlogicalor_test
- 配置したフィールド: name(テキスト), license(テキスト)
- データベースへ接続するための/conf/database.phpは前回を参照
モデル記述例
class logicalOrList extends AppModel
{
var $fmDatabaseName = 'fmcake_test';
var $defaultLayout = 'fmcake_setlogicalor_test';
}
コントローラ記述例
function logicalOrList()
{
$this->layout = false;
$this->loadModel('logicalOrList');
$condition = array
(
'or' => true,
'license' => 'The BSD License',
'lang' => 'JavaScript'
);
$this->set('result', $this->paginate('logicalOrList', $condition));
}
ビュー記述例
<table border="1">
<thead>
<tr>
<th><?php echo $paginator->sort('ライブラリ名', 'name'); ?></th>
<th><?php echo $paginator->sort('ライセンス', 'licence'); ?></th>
<th><?php echo $paginator->sort('言語', 'lang'); ?></th>
</tr>
</thead>
<tbody>
<?php
foreach ($result as $value)
{
?>
<tr>
<td><?php echo $value['logicalOrList']['name']; ?></td>
<td><?php echo $value['logicalOrList']['license']; ?></td>
<td><?php echo $value['logicalOrList']['lang']; ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
この場合の検索条件は、「"licenseがThe BSD License"または"langがJavaScript"であること」となる。/fmi/xml/FMPXMLRESULT.xmlに発行されるクエリは「-db=fmcake_test&-lay=fmcake_setlogicalor_test&-max=20&-sortfield.1=name&-sortorder.1=ascend&license.op=eq&license=The+BSD+License&-lop=or&lang.op=eq&lang=JavaScript&-lop=or&-find」。これをWebブラウザで表示する。
「"licenseがThe BSD License"または"langがJavaScript"であること」の検索条件にマッチしたレコード一覧が表示された |
$conditionsからorを外せばAND検索となる |
FX.phpのSetLogicalOR()をそのまま使用するということでピンとくる方もおおいと思う。お察しのとおり、FMCakeMixでANDとORの複合検索を実装する場合は非常に骨が折れる。FX.phpまたはFileMaker API for PHPを使ってこれら複合検索の実装を確立している場合は、該当のコントローラ部分でのみ、その仕組みを流用するようにしてやると手っ取り早い。
FMCakeMixでFileMakerスクリプトを実行する方法
5月11日(米国時間)に、FMCakeMixからFileMakerスクリプトを実行できるように修正がおこなわれた。FileMaker Web公開マニュアル(FileMaker Server Custom Web Publishing with XML and XSLT 101-103ページ)に記載されている6種類すべての引数に対応している。
- -script: 検索・ソート実行後にスクリプトを実行
- -script.prefind: 検索実行前にスクリプトを実行
- -script.presort: ソート実行前にスクリプトを実行
- -script.param: -scriptで指定したスクリプトに引数を付与
- -script.prefind.param: -script.prefindで指定したスクリプトに引数を付与
- -script.presort.param: -script.presortで指定したスクリプトに引数を付与
処理の順番は早い順に –script.prefind > –script.presort > –script となる。これらの引数はdbo_fmcakemix.php内部で特別なパラメータとして扱われており、スキーマに格納される。
dbo_fmcakemix.php 50-59行目より
// warning: these get added to schema, but allow you to pass in values
// so that the xml api parses them as functional parameters
var $allowed_parameters = array(
'-script',
'-script.prefind',
'-script.presort',
'-script.param',
'-script.prefind.param',
'-script.presort.param'
);
dbo_fmcakemix.php 650-659行目より
// add in fm xml functional parameters so that they don't get cleaned from saves
foreach ($this->allowed_parameters as $param) {
$fieldsOut[$param] = array(
'type' => 'FM_PARAM',
'null' => null,
'default' => null,
'length' => null,
'key' => null
);
}
使用する場合はOR検索と同様、$conditionsに上記6種類のパラメータと、FileMakerスクリプト名または引数を指定してやればOKだ。試しに特定のフィールドを全置換するFileMakerスクリプトをFMCakeMixから実行させてみよう。
- FileMakerファイル名: fmcake_test
- FileMakerレイアウト名: fmcake_script_test
- 配置したフィールド: num(数字)
- 実行するFileMakerスクリプト: replaceAll_num (スクリプトステップは別画像を参照)
モデル記述例
class execFmScript extends AppModel
{
var $fmDatabaseName = 'fmcake_test';
var $defaultLayout = 'fmcake_script_test';
}
コントローラ記述例
function execFmScript()
{
$this->layout = false;
$this->loadModel('execFmScript');
$this->paginate['limit'] = 10;
$condition = array
(
'-script' => 'replaceAll_num',
);
$this->set('result', $this->paginate('execFmScript', $condition));
}
ビュー記述例
<table border="1">
<thead>
<tr>
<th><?php echo $paginator->sort('num'); ?></th>
</tr>
</thead>
<tbody>
<?php
foreach ($result as $value)
{
?>
<tr>
<td><?php echo $value['execFmScript']['num']; ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
FX.phpのPerformFMScript()やFileMaker API for PHPのsetScript()と違い、専用のメソッドを使用することはない。これをWebブラウザで表示する。
OR検索の実行、FileMakerスクリプトの実行ともにFX.phpやFileMaker API for PHPと使い勝手が違う。実行するまでの手順が違うだけなので、しっかり覚えておけばそこまで苦労することもなさそうだ。FMCakeMixでFileMaker特有の処理をしたいが書き方がわからないという方は、前回の記事と合わせてしっかりDBOドライバの実装を追ってほしい。