はじめに

INTER-Mediatorもバージョンを重ねてきており、以前の引き継がなくなってしまった箇所が出てきています。Ver.3 (2012/12/10) 以降の大きな変更点、つまりアプリケーション側を書き換えないといけないような変更をここにまとめておきます。

Ver.6.0での変更

対応ブラウザなどの変更

Internet Explorer Ver.11以降となる予定です。PHPはVer.7以降としたいのですが、FileMaker Serverのことがあるため、現在、どのバージョン以降にするかは検討中です(PHP 5.2系統とPHP 5.3系統は少なくともサポート対象外になります)。

完全非同期化に伴い使用できなくなるメソッド

Ver.6.0より前は、一部の通信が同期通信でしたが、完全に非同期通信だけになったことから、同期通信関連のメソッドは非実装の状態にします。以下のメソッドがなくなります。これらのメソッドを呼び出しても該当する処理は行わず、エラーログ(ページ上部に赤いバックグランドで表示される)にメッセージ(例「INTERMediator_DBAdapter.server_access method was discontinued in Ver.6」)が追加されるだけになります。

  • INTERMediator_DBAdapter.server_access
  • INTERMediator_DBAdapter.db_query
  • INTERMediator_DBAdapter.db_queryWithAuth
  • INTERMediator_DBAdapter.db_update
  • INTERMediator_DBAdapter.db_updateWithAuth
  • INTERMediator_DBAdapter.db_delete method
  • INTERMediator_DBAdapter.db_deleteWithAuth
  • INTERMediator_DBAdapter.db_createRecord
  • INTERMediator_DBAdapter.db_createRecordWithAuth
  • INTERMediator_DBAdapter.db_copy method
  • INTERMediator_DBAdapter.db_copyWithAuth

廃止されるPHPのグローバル変数

Ver.6.0ではINTER-Mediator.phpで定義されているグローバル変数($g_dbInstanceと$g_serverSideCall)が廃止される予定です。

Ver.5.12での変更

動作条件の変更

INTER-Mediator Ver.5系統ではVer.5.12でPHP 8.0に対応しましたが、PHP 5.2とPHP 5.3はサポート対象外となりました。PHP 5.4以降が必要です(推奨はPHP 7.3以降)。これに伴い、FileMaker Serverについてはバージョン13以前はサポート対象外となりました。

Ver.5.8での変更

要求されるプライベートキーの鍵長

セキュリティ上の理由から、プライベートキーの鍵長が2048bit未満のものを非推奨にしました。ネイティブ認証やLDAP認証を利用している場合には、プライベートキー(params.phpファイル内の変数 $generatedPrivateKey の値)を更新する必要があります。

Ver.5.7での変更

データベース更新処理の排他制御の変更

Ver.5.4で、IMLibUI.lockUIElementなどのメソッドを用意して、独自に排他制御をかけていましたが、ある状況でうまく機能していない場合があることがわかり、データベースへの更新処理をキューを使ってシリアライズするように変更しました。キューを使うことで、キューに登録したタスクは1つ1つが完全に終了するまで、次のタスクは実行できなくなります。データベースへの更新処理をユーザーインタフェースから呼び出すときには、必ずキューを使うので、2つの更新処理が同時に発生してしまうなどの不具合は理屈の上では発生しなくなります。また、更新前のクエリーもキューに登録されて実行されるようになります。

自分でJavaScriptでプログラムを作る場合には、キューへの登録を適切に行ってください。IMLibQueue.setTaskメソッドを使います。引数は実行するタスクを関数で指定しますが、関数には必ず引数を1つ設定してください。その引数はクロージャーが渡され、キューのタスクの終了をシステムに知らせるために、その引数のクロージャーを実行します。実行するタスクが非同期の処理を含む場合には、タスクの最後に引数のクロージャーを実行するのではなく、非同期処理の完了処理で呼び出すなどしないと、更新処理の前後が交錯して、認証の継続がうまく行かないなどのトラブルになります。以下はコードの例です。

IMLibQueue.setTask(function (completeTask) {
     INTERMediator_DBAdapter.db_query_async(
         {
             name: "execute",
             conditions: [{field: "id", operator: "=", value: id}],
             uselimit: false,
             records: 1
         },
         function (result) {
             document.getElementById("result").innerHTML = result.dbresult[0].result;
             INTERMediator.flushMessage();
             completeTask();
         },
         function () {
             INTERMediator.flushMessage();
             completeTask();
         });
});

なお、JavaScriptの以下のAPIは、内部でIMLibQueue.setTaskを呼び出しているので、キューへの設定は自動的に行われます。以下に含まれないようなINTERMediator_DBAdapter.db_query_asyncメソッドでは、上記のように、自分でキューへの登録やタスク終了の呼び出しを行う必要が発生します。

  • IMLibUI.valueChange
  • IMLibUI.copyButton
  • IMLibUI.deleteButton
  • IMLibUI.insertButton
  • IMLibContext.prototype.setDataAtLastRecord
  • IMLibContext.prototype.setDataWithKey
  • IMLibPageNavigation.copyRecordFromNavi
  • IMLibPageNavigation.deleteRecordFromNavi
  • IMLibPageNavigation.insertRecordFromNavi

データベースクラスに関してのリファクタリング

DB_PDO.phpファイルなどのように、データベースクラスは非常に行数が大きくなり、保守しづらい状況になっていました。そこで、DB_Supportフォルダにいくつかのファイルを作り、異能の分離をしています。一般のアプリケーションに影響はないようになっているはずですが、自分でデータベースクラスを作っているような場合には、DB_Interface.phpに記述されたインタフェースに基づいて機能を分離している点をご理解いただきプログラムに反映させてください。データベースクラスからは、publicなポインタを利用して、別途定義された「ハンドラ」を参照するといった仕組みです。なお、例えば認証に関連する部分はDB_Auth_Handler_PDO.phpファイルに記述されていますが、あるデータベースクラスが認証の機能を使わないのなら、このハンドラは定義不要で、ポインタとなるプロパティはnullのままで構いません。

一部プロパティの変更

内部的にINTERMediatorLogオブジェクトを導入したことで、プログラミングガイドでは言及されていなかった一部のプロパティが変更されています。もしもこれらのプロパティを個別のJavaScriptで利用している場合には書き換えが必要になります。

  • (変更前) INTERMediator.debugMode (変更後) INTERMediatorLog.debugMode
  • (変更前) INTERMediator.supressDebugMessageOnPage (変更後) INTERMediatorLog.suppressDebugMessageOnPage
  • (変更前) INTERMediator.supressErrorMessageOnPage (変更後) INTERMediatorLog.suppressErrorMessageOnPage
  • (変更前) INTERMediator.errorMessages (変更後) INTERMediatorLog.errorMessages
  • (変更前) INTERMediator.debugMessages (変更後) INTERMediatorLog.debugMessages
  • (変更前) INTERMediator.errorMessageByAlert (変更後) INTERMediatorLog.errorMessageByAlert
  • (変更前) INTERMediator.errorMessageOnAlert (変更後) INTERMediatorLog.errorMessageOnAlert

Ver.5.6での変更

テーマの新設と既存の開発物について

このバージョンより、一切のスタイル設定をしなくてもそれなりに見栄えの良いページが作成できるように、デフォルトのテーマを構築しました。また、テーマを入れ替えることで、手軽に見栄えを変更できるような機能にもなっています。しかしながら、独自にCSSを全面的に定義しているようなサイトにおいては、デフォルトのテーマの設定と当たってしまう場合もあります。その場合、「least」テーマに切り替えてください。IM_Entry関数の第2引数(オプション設定)に、"theme"がキーで、値が"least"という定義を加えまます。params.phpでは$themeName = "least"; と指定します。このテーマは、ログインパネルとページネーションの要素に適用される設定しかしていませんので、多くの場合テーマと自分のCSSが当たるということはないと思います。また、テーマのCSSは、独自のCSSファイルへのlinkタグより前に配置されるため、通常は、独自のCSSファイルでテーマの内容を上書きできるはずです。

イベント取得

キーボード関連のイベントに対する応答を登録できるグローバル変数IMLibKeyEventDispatchは、IMLibKeyDownEventDispatchとIMLibKeyUpEventDispatchに変更になりました。

Ver.5.5での変更

アドバイス定義クラスでメールの送信内容を修正する場合

データベースに対する処理のうち、Read/Update/Createの3つの処理が終了後にメールを送信する設定をコンテキスト定義に記述します。このとき、データベースで処理したレコードの配列を元にメールを送信するので、フィールドに送信時に使用する宛先や文面などのデータがあれば、コンテキスト定義上で使用するフィールドあるいは固定値を記述することでメールの送信ができます。しかしながら、状況によってはレコードにない情報を追加したり、あるいは変更してメール送信に利用したい場合もあります。その場合は、コンテキスト定義にextending-classキーの値を追加して、アドバイス定義クラスを実装します。そのクラスに、レコード作成直後にメールを送りたい場合の修正を組み込むため、doAfterCreateToDB($result)メソッドを実装します。このとき、書き直したフィールドや、追加したいフィールドは、データベースクラスのsetUpdatedRecordを利用して追加してください。通常、アドバイス定義クラスは、DB_UseSharedObjectsクラスを継承しているので、現在使用しているデータベース定義クラスは、dbClassプロパティで得られます。したがって、n番目のレコードのフィールドfに値vを書き込む場合は、「$this->dbClass->setUpdatedRecord(f, v, n)」というプログラムを書きます。これで、メール処理クラスに変更されたり追加されたフィールドを持つレコードが送信されます。なお、doAfterCreateToDBなどのメソッドは、基本は引数と同じレコードを返してください。メールの送信は、これらのメソッドの返り値ではなく、データベースクラスのインスタンスが管理して「結果のレコード」を利用します。返り値は、例えば、クエリー結果だと、ページ上に表示される値として利用されるものです。したがって、表示側もメール側も変更するのなら、setUpdatedRecordメソッドだけでなく、返り値の配列も変更が必要です。

なお、このように、setUpdatedRecordを使用する必要があるのは、これまでのバージョンは新規レコード作成時だけだったのですが、操作ごとに処理方法がバラついてしまっていたので、読み出しや更新処理も、同様にsetUpdatedRecordでメール処理に渡すレコード群の変更をするようにしました。

Ver.5.4での変更

サーバーサイドのPHPのAPIを整理

データベースアクセスクラスの基本メソッド

データベースアクセスクラスでは、CRUDおよびその関連処理のためのメソッドを既定しています。従来は、そのメソッドに処理しているコンテキスト名を引数として渡していましたが、それをやめました。また、メソッドの名称もCRUDの各単語に対応したものとなりました。現在処理しているコンテキスト名は、DB_SettingsクラスのメソッドgetDataSourceName()で取得できます。Ver.5.4-dev以降は、getFromDBは呼び出されず、readFromDBが呼び出されるようになるので、必要な修正をしてください。

従来の定義

interface DB_Interface extends DB_Spec_Behavior
{
    public function getFromDB($contextName);
    public function countQueryResult($contextName);
    public function getTotalCount($contextName);
    public function setToDB($contextName);
    public function newToDB($contextName, $bypassAuth);
    public function deleteFromDB($contextName);
    public function copyInDB($contextName);
}

新しい定義

interface DB_Interface extends DB_Spec_Behavior
{
    public function readFromDB();         // former getFromDB
    public function countQueryResult();
    public function getTotalCount();
    public function updateDB();           // former setToDB
    public function createInDB($bypassAuth);  // former newToDB
    public function deleteFromDB();
    public function copyInDB();
}

データベースアクセス処理の拡張クラス

コンテキストにextending-classキーで指定したクラス名にインプリメントするインタフェースを以下のように変更しました。名前をCRUDに対応するものにすると同時に、データソース名の引数は渡しません。拡張処理クラスがDB_UseSharedObjectsを継承している場合は、DB_SettingsクラスのインスタンスへdbSettingsプロパティでアクセスできます。これを利用すると、現在処理しているコンテキスト名は、DB_SettingsクラスのメソッドgetDataSourceName()で取得できます。Ver.5.4-dev以降は、従来の名称のメソッドは呼び出されず、新しいメソッドしか呼び出されませんので、必要な修正をしてください。

従来の定義

interface Extending_Interface_BeforeGet {
    public function doBeforeGetFromDB($dataSourceName);
}
interface Extending_Interface_AfterGet {
    public function doAfterGetFromDB($dataSourceName, $result);
}
interface Extending_Interface_AfterGet_WithNavigation {
    public function doAfterGetFromDB($dataSourceName, $result);
    public function countQueryResult($dataSourceName);
    public function getTotalCount($dataSourceName);
}
interface Extending_Interface_BeforeSet {
    public function doBeforeSetToDB($dataSourceName);
}
interface Extending_Interface_AfterSet {
    public function doAfterSetToDB($dataSourceName, $result);
}
interface Extending_Interface_BeforeDelete {
    public function doBeforeDeleteFromDB();
}
interface Extending_Interface_AfterDelete {
    public function doAfterDeleteFromDB($result);
}
interface Extending_Interface_BeforeNew {
    public function doBeforeNewToDB($dataSourceName);
}
interface Extending_Interface_AfterNew{
    public function doAfterNewToDB($dataSourceName, $result);
}

新しい定義

interface Extending_Interface_BeforeRead {
    public function doBeforeReadFromDB();
}
interface Extending_Interface_AfterRead {
    public function doAfterReadFromDB($result);
}
interface Extending_Interface_AfterRead_WithNavigation {
    public function doAfterReadFromDB( $result);
    public function countQueryResult();
    public function getTotalCount();
}
interface Extending_Interface_BeforeUpdate {
    public function doBeforeUpdateDB();
}
interface Extending_Interface_AfterUpdate {
    public function doAfterUpdateToDB($result);
}
interface Extending_Interface_BeforeCreate {
    public function doBeforeCreateToDB();
}
interface Extending_Interface_AfterCreate {
    public function doAfterCreateToDB($result);
}
interface Extending_Interface_BeforeDelete {
    public function doBeforeDeleteFromDB();
}
interface Extending_Interface_AfterDelete {
    public function doAfterDeleteFromDB($result);
}
interface Extending_Interface_BeforeCopy {
    public function doBeforeCopyInDB();
}
interface Extending_Interface_AfterCopy {
    public function doAfterCopyInDB($result);
}

DB_Settingsクラスの整理統合

以下のメソッドはVer.5.4-devでは定義されていません。代替メソッドを使ってください。

function getTargetName()
function getTargetDataSource()
function setTargetDataSource($targetDataSource)
function getIndexOfDataSource($dataSourceName)
function setTargetFields($fields)

getTargetName/getTargetDataSource/setTargetDataSourceメソッドは、ほぼ同一の動きをするgetDataSourceName/setDataSourceNameメソッドに置き換えました。setTargetFieldsとgetIndexOfDataSourceメソッドは使われていないので、削除しました。

Ver.5.3での変更

CSRF攻撃対策の追加

params.phpファイルで$webServerNameという変数を設定することでCSRF攻撃対策を実施することができるようになりました。Webサーバーのドメイン名もしくはFQDN(完全修飾ドメイン名)を配列で設定するようにしてください。
設定例1:array('inter-mediator.com');
設定例2:array('www.inter-mediator.com', 'inter-mediator.org');

Ver.5.2での変更

データベースクラスでのメソッド定義の変更

Auth_Interface_DBインタフェースで定義しているauthSuportCreateUserメソッドの引数が、LDAP対応に伴い2つから4つに増えました。 データベースクラス(DB_PDO.phpなど)については、機能を組み込んでいなくても、メソッドの引数をインタフェースでの定義に揃えなければなりません。 定義内容は、DB_Interfaces.phpファイルを参照してください。

Ver.4.7での変更

Internet Explorer Ver.8対応に関して

これまでは、Internet Explorerの最低サポートバージョンをVer.8としてきましたが、Ver.4.7現在、いくつかの機能が動かない状態になっています。これらについては、今後サポートする予定はありません。しかしながら、主要な機能はVer.4.7でも動いているので、IE8のサポートバージョンとして、最後のものがVer.4.7とします。Ver.4.7でIE8で動作に問題があるものとして、以下のものがわかっています。

  • フィールドの文字列中に改行がある場合、TEXTAREAに正しく表示されない。これは、改行をBRタグに変更してinnerHTMLに設定するという手段が、IE8ではエラーになってしまうためです。
  • Pusherをベースにしたクライアント間同期の仕組みのうち、レコード削除後の処理でエラーが出る。フィールドの更新や新規レコードは稼働します。
  • ローカルコンテキストを利用して、検索パラメータを指定する機能のうち、1ページの件数の制限と、並べ替えに使用するフィールドの指定が正しく動作しません。検索条件と、「検索」ボタンは動作します。

なお、Ver.5以降は、IE8のためのコードを削除する可能性もあり、動かない機能がより増える可能性もあります。また、Ver.5以降は、Internet Explorerでの確認は、主として最新バージョンでのみ行うことにします。Firefox、Chrome、Safariと同様な扱いにします。なお、特定のバージョンでの不具合について、対応を希望する場合には、Facebookのグループ等でリクエストを出してください。

Ver.4.6での変更

setExeucteメソッド

グローバル変数のIMLibChangeEventDispatch、IMLibKeyEventDispatch、IMLibMouseEventDispatchの初期化は、constructメソッドを呼び出す後になりました。これらのオブジェクトで利用できていた、setExeucteなどのメソッドは、constructを呼び出した後に設定してください。具体的には、INTERMediatorOnPage.doAfterConstruct = function() { } という関数の定義と代入を行い、関数内でIMLibChangeEventDispatch、IMLibKeyEventDispatch、IMLibMouseEventDispatchを利用してください。

INTERMediator.additionalCondition, additionalSortKeyプロパティ

コンテキストを利用して読み出しを行うとき、JavaScriptで検索条件や並べ替え条件を付加できるプロパティadditionalConditionとadditionalSortKeyがあります。これらは、従来までは単純にオブジェクトを記録していただけですが、Ver.4.4あたりでローカルコンテキストに記録して、ページを改めて呼び出した時にローカルコンテキストを復活させることで元に戻すという仕様を組み込みました。しかしながら、その動作を見直している時にバグが見つかりましたが、結果的に、additionalConditionとadditionalSortKeyの参照は変更ありませんが、追加や書き換えには以下のような変更が必要になります。これらの2つのプロパティにセッタとゲッタを設定しているため、セッタを稼働させるために、プロパティそのものへの代入が必要になります。あるいは、新しいAPIのaddConditionやaddSortKeyメソッドを利用してください。追加した条件を消去するclearConditions、clearSortKeysメソッドも利用できます。

INTERMediator.additionalCondition["acontext"] = [];
INTERMediator.additionalCondition["acontext"].push({field: "afield", operator: "=", value: "1001"});
INTERMediator.additionalCondition["acontext"].push({field: "live", operator: "=", value: "1"});

    ↓

(修正方法A)
INTERMediator.addCondition("acontext", {field: "afield", operator: "=", value: "1001"});
INTERMediator.addCondition("acontext", {field: "live", operator: "=", value: "1"});

(修正方法B)
var conditions = INTERMediator.additionalCondition;
conditions["acontext"] = [];
conditions["acontext"].push({field: "afield", operator: "=", value: "1001"});
conditions["acontext"].push({field: "live", operator: "=", value: "1"});
INTERMediator.additionalCondition = conditions

検索条件が1つだけの場合も、同様に、次のように書き換えが必要になります。

INTERMediator.additionalCondition["acontext"] = {field: "afield", operator: "=", value: "1001"};

    ↓

(修正方法A)
INTERMediator.addCondition("acontext", {field: "afield", operator: "=", value: "1001"});

(修正方法B)
var conditions = INTERMediator.additionalCondition;
conditions["acontext"].push({field: "afield", operator: "=", value: "1001"});
INTERMediator.additionalCondition = conditions

Ver.4.5での変更

valueChangeメソッド

INTERMediator.valueChange(idValue)はIMLibUI.valueChange(idValue)に変更されました。もしもJavaScriptのプログラム内でvalueChangeメソッドを使用している場合には書き換えが必要です。

Ver.4.1 (2014/2/7) での変更

ターゲット指定をclass属性に独自の記述方法で書いていましたが、Ver.4.1より、HTML5のdata属性での記述に移行しました。なお、従来の記述も基本的にはそのまま利用できるはずですが、大した手間にならないので、書き直すのがいいかと思います。

以前の表記法 Ver.4.1以降の表記法 利用場所
class="IM[...]" data-im="..." ページファイルのターゲット指定
class="IM_WIDGET[...]" data-im-widget="..." JavaScriptコンポーネントの指定
class="_im_enclosure" data-im-control="enclosure" エンクロージャにしたいDIV, SPANタグ
class="_im_repeater" data-im-control="repeater" リピータにしたいDIV, SPANタグ
class="_im_ignore_enc_rep" data-im-control="ignore_enc_rep" リピータあるいはエンクロージャでなくする
class="_im_for_noresult_" data-im-control="noresult" 検索結果が0レコードの時に表示されるリピータ
class="_im_post" data-im-control="post" ポストオンリーモードのエンクロージャおよび書き込みボタン
name="IM[...]" data-im-group="...." ポストオンリーモードでのラジオボタンのグループ指定

以下は書き換え例です。

<input class="IM[mytable@anyfield]" />
    ↓
<input data-im="mytable@anyfield" />

IM[]に複数のターゲット指定を書いていた場合、|で区切っていましたが、空白で区切れるようになりました。

<option class="IM[mytable@myvalue@value|mytable@myname]" />
    ↓
<option data-im="mytable@myvalue@value mytable@myname" />

Ver.4.0 (2013/12/4) での変更

INTER-Mediatorの配布ファイルのファイル構成が変わりました。ルート直下にフレームワークがあり、サンプルファイルはSamplesの下に配備しました。同時に、dist-docs/buildup.shを利用して、運用向けのフレームワークを用意する機能を加えています。こちらをごらんください。

Ver.3.8 (2013/8/22) での変更

params.phpファイルにおいて記述できていた$scriptPathPrefix、$scriptPathSufixを利用して、クライアントから呼び出すURLをコントロールできていましたが、$callURLという変数で完全にURLで指定できるようにしています。$scriptPathPrefix、$scriptPathSufixも使用できます。