1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FileMaker Data API を使う 2025年版 vol.14

Last updated at Posted at 2025-02-13

サンプルソリューションのデータは、新しいサンプルデータを作る を参照してください。

この記事で使用するソースコードは、FileMaker Data API を使う 2025年版 vol.12#残りの HTML ソースコードの PHP 化 にまとめてあります。

その後の変更(Find Records のテストと JSON ファイル)は、FileMaker Data API を使う 2025年版 vol.13 を参照してください。

現在の構造は以下の通りです。

.
├── css
│   ├── bootstrap-common.css
│   └── fmda-form.css
├── find-records-test.php ※ vol.13 で追加
├── find-records-test2.php ※ vol.13 で追加
├── html
│   └── edit-record.html
├── index.php
├── js
│   ├── fmda-form-check.js
│   └── fmda-select-page.js
├── json
│   ├── html-contents.json
│   ├── standings-al-east-2024.json ※ vol.13 で追加
│   └── standings-all-2024.json ※ vol.13 で追加
└── php
    ├── bs-builder-class.php
    ├── bs-frame-class.php
    ├── filemaker-data-api-class.php
    ├── php-functions.php
    └── preferences.php

利用環境

以下の環境を前提に説明しています。

  • Claris FileMaker Pro 21.1.1.41 macOS
  • Claris FileMaker Server 21.1.1.40 Ubuntu 22(AMD)
  • サーバ: Ubuntu 22.04.5 LTS
  • SSL 証明書
  • リクエストする側のサーバ(任意)

開発段階では、以下を使用した方が楽でしょう。

Web ページの作成は、以下を条件とします。

割り切った global キーワードの使用

global キーワードは、グローバルスコープの変数をローカルスコープで操作するためのキーワードで、無闇に使用すると、プログラムのメンテナンス性に問題が出ることもあります。

しかし、開発段階では、割り切って、一定のルールの元に使用すると、プログラムの構造が把握しやすくなります。
ここで採用するルールは、以下のものです。

  • 原則、ブロック単位で仮に関数化する
  • 仮の関数は、別ファイルに置く
  • 仮の関数で、必要なグローバルスコープの変数を global キーワードで設定する
  • 仮の関数は引数を与えない
  • 仮の関数は戻り値を返さない
  • 引数、戻り値が必要になったら、正規の関数として、別ファイルに移す
  • 正規の関数は、原則、global キーワードを持たない

といってもイメージが全然、湧かないと思いますので、上記、ルールで書き換えた find-records-test3.php を示します。
前回の find-records-test2.php は、HTML 出力部分を除いて、今回やろうとしていることと同じですので、比較してみてください。

find-records-test3.php

<?php

require_once(__DIR__ . '/php/bs-frame-class.php');
require_once(__DIR__ . '/php/bs-builder-class.php');
require_once(__DIR__ . '/php/php-functions.php');
require_once(__DIR__ . '/php/filemaker-data-api-class.php');

@$page_indentity    = $_POST['page-identity'];
$page_indentity     = $page_indentity === null ? 1 : $page_indentity;

require_once(__DIR__ . '/php/preferences.php');

require_once(__DIR__ . '/php/temporary-functions.php');

authorization_data();

$fmda           = new FileMakerDataApi($host, $version);

auth_login();
auth_validate_session();

$request_body_json_file = __DIR__ . '/json/standings-all-2024.json';
$request_body           = json_get_element_raw($request_body_json_file);
records_find_records();

auth_log_out();

 大変、短くなって、処理の流れが想像しやすくなったのではないでしょうか。
同様に、index.php も書き換えます。

index.php 新版

<?php

require_once(__DIR__ . '/php/bs-frame-class.php');
require_once(__DIR__ . '/php/bs-builder-class.php');
require_once(__DIR__ . '/php/php-functions.php');
require_once(__DIR__ . '/php/filemaker-data-api-class.php');

@$page_indentity        = $_POST['page-identity'];
$page_indentity         = $page_indentity === null ? 1 : $page_indentity;

require_once(__DIR__ . '/php/preferences.php');

require_once(__DIR__ . '/php/temporary-functions.php');

authorization_data();

$fmda           = new FileMakerDataApi($host, $version);

if (!isset($result)) {
    // 最初のアクセス
    auth_login();
    auth_validate_session();

    $request_body_json_file = __DIR__ . '/json/standings-all-2024.json';
    $request_body           = json_get_element_raw($request_body_json_file);
    records_find_records();

    auth_log_out();
}

BsFrame::HtmlBegin($color_modes_js, $description, $author, $title, $bootstrap_css, $bs_css_integrity, $bs_frame_css, $custom_css);
BsFrame::LoadColorModesSvg();
BsFrame::ColorModes();

BsBuilder::MainBegin($logo_svg, $logo_svg_width, $page_heading[$page_indentity], $page_lead[$page_indentity]);

BsBuilder::InfoItem($info_heading, $info_number_of_items, $info_item_heading, $info_item_content);
BsBuilder::GetInfo();

BsBuilder::CreateForm($form_preferences, $form_controls);
BsBuilder::CreatePagination($page_indentity);
BsBuilder::MainEnd();
BsBuilder::CreateFooter($copyright_year, $copyright_holder, $link_items);

BsFrame::HtmlEnd($bootstrap_js, $bs_js_integrity, $custom_js);

要するに、ソースコードの流れを把握しやすくするために、処理を隠しているだけのことです。
隠した処理は、temporary-functions.php に移っています。

temporary-functions.php

<?php

function authorization_data( ): void
{
    global $host, $version;
    global $database, $username, $password;
    global $layout, $bearer_session_token;
    // FileMaker Server 情報
    $host       = '(FileMaker Server ドメイン名)';
    $version    = 'vLatest';
    // FileMaker ソリューション情報
    $database   = '(FileMaker ソリューション名)';
    $username   = '(FileMaker ユーザ名)';
    $password   = '(パスワード)';
    // リクエスト情報
    $layout     = 'standings';
    $bearer_session_token   = null;
}

function auth_login( ): void
{
    global $fmda, $response, $bearer_session_token, $database, $username, $password;

    // ログイン
    $response = $fmda->login($database, $username, $password);

    // ログイン成功?
    if ($fmda->getMessagesCode($response) === '0') {
        // ログイン成功なら、Bearer Session Token を取得する
        $bearer_session_token   = $fmda->getBearerSessionToken($response);
    } else {
        // ログイン失敗の処理を書く
        echo "<div class=\"alert alert-danger\" role=\"alert\">FileMaker Data API へのログインに失敗しました。</div>\n";
    }
}

function auth_validate_session( ): void
{
    global $fmda, $response, $bearer_session_token;

    // セッションの検証
    $response   = $fmda->validateSession($bearer_session_token);
}

function records_find_records( ): void
{

    global $fmda, $response, $bearer_session_token, $database, $layout, $request_body;
    global $result, $data_info, $team_data;
    global $info_item_content;
    if ($fmda->getMessagesCode($response) === '0') {
        // セッション有効なら、行いたいリクエスト実行
    
        // レコードの検索
        $response   = $fmda->findRecords($database, $layout, $bearer_session_token, $request_body);
    
        // 結果セット処理
        $result = $fmda->json2array($response);
        
        if ($fmda->getMessagesCode($response) === '0') {
            $data_info  = $result['response']['dataInfo'];
            $team_data  = $result['response']['data'];
        }
    } else {
        // セッション無効なら、必要な Web データを保持して、ユーザに再ログインを促す
        echo "<div class=\"alert alert-warning\" role=\"alert\">セッションが切れました。再ログインしてください。</div>\n";
    }
}

function auth_log_out( ): void
{
    global $fmda, $response, $bearer_session_token, $database;
    // ログアウト
    $response = $fmda->logOut($database, $bearer_session_token);
}

 この作業をしていないと、temporary-functions.php とほぼ同じ長さだけ index.php が長くなってしまうということです。

正規の関数に格上げした段階で、temporary-functions.php が短くなっていくわけですが、理想は、temporary-functions.php なくなってしまうことです。

dataInfo ブロック

 前回の find-records-test2.php のデータ表示をしたいわけですが、まず、Find Records で取得したデータをここで元々使われている $info_item_content 配列の中身を、仮データから正規のものに変更する必要があります。
この処理は、temporary-functions.phprecords_find_records() 関数に追加します。

records_find_records() 関数

function records_find_records( ): void
{

    global $fmda, $response, $bearer_session_token, $database, $layout, $request_body;
    global $result, $data_info, $team_data;
    global $info_item_content;
    if ($fmda->getMessagesCode($response) === '0') {
        // セッション有効なら、行いたいリクエスト実行
    
        // レコードの検索
        $response   = $fmda->findRecords($database, $layout, $bearer_session_token, $request_body);
    
        // 結果セット処理
        $result = $fmda->json2array($response);
        
        if ($fmda->getMessagesCode($response) === '0') {
            $data_info  = $result['response']['dataInfo'];
            $team_data  = $result['response']['data'];

            // 追加部分
            array_push($info_item_content, $data_info['database']);
            array_push($info_item_content, $data_info['layout']);
            array_push($info_item_content, $data_info['table']);
            array_push($info_item_content, $team_data[0]['recordId']);
            array_push($info_item_content, $team_data[0]['modId']);
            array_push($info_item_content, $data_info['totalRecordCount']);
            array_push($info_item_content, $data_info['foundCount']);
            array_push($info_item_content, $data_info['returnedCount']);
        }
    } else {
        // セッション無効なら、必要な Web データを保持して、ユーザに再ログインを促す
        echo "<div class=\"alert alert-warning\" role=\"alert\">セッションが切れました。再ログインしてください。</div>\n";
    }
}

 現時点での状態は、最初のレコードを表示する前提で、他のことは考慮していませんので、$team_data[] 配列のインデックスは 0 になっています。

この変更に伴い、preferences.php にも変更点があります。

preferences.php 変更部分(46行目から)

$info_item_heading  = [];
$info_item_content  = [];
foreach ($temp_array['infoItems'] as $key => $value) {
  array_push($info_item_heading, $value['heading']);
}

 foreach の中にあった array_push($info_item_content, $value['content']); を削除しているだけです。

この変更に伴い dateInfo の見出しとラベルも変更が必要になります。❻ については後回しにします。
テキストコンテントは、html-contents.json に入っていますので、該当部分を変更します。

"contents" JSON オブジェクトの "infoHeading"

"infoHeading" : "FileMaker 情報",

"infoItems" JSON 配列

"infoItems" : [
        {
            "heading" : "ソリューション"
        },
        {
            "heading" : "レイアウト"
        },
        {
            "heading" : "テーブル"
        },
        {
            "heading" : "レコード ID"
        },
        {
            "heading" : "修正 ID"
        },
        {
            "heading" : "テーブルのレコード数"
        },
        {
            "heading" : "現在のレコード数"
        },
        {
            "heading" : "取得したレコード数"
        }
    ],

これで、dataInfo ブロック 改め、FileMkaer 情報ブロックに表示したい情報が表示されるようになりました。

今回、手をつけていない部分

  • FileMaker 情報ブロックの❻

これは、単純に削除する予定です。

  • 機能判別

今回は、ファーストアクセスしか考慮していません。
フッタのリンクをクリックした際の処理は、フォームデータ表示が出来てから、追加する予定です。

  • フォームデータ表示

Find Records で、$team_data 配列には、既に、フォームに表示したい情報が入っています。
これについては、次回、追加したいと思います。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?