Code Monkey home page Code Monkey logo

fmdataapi's Introduction

FMDataAPI Ver.31 Build Status

by Masayuki Nii ([email protected])

FMDataAPI is a class developed in PHP to access FileMaker database with Claris FileMaker Data API.

Contributers

They created pull requests. Thanks for cooperating.

  • Atsushi Matsuo
  • darnel
  • Craig Smith
  • Bernhard Schulz
  • montaniasystemab
  • Rickard Andersson
  • Julien @AnnoyingTechnology
  • Tom Kuijer
  • Thijs Meijer
  • Patrick Janser
  • Roger Engström

At a Glance

The FileMaker database named "TestDB.fmp12" is hosted on localhost, and it set the "fmrest" as access privilege. The account to connect with REST API is "web" and "password". This database has the layout named "person_layout", and you can use the layout name as a property of the FMDataAPI instance. The return value of the "query" method is Iterator and can repeat in foreach statement with each record in the query result. This layout has the field named "FamilyName" and "GivenName", and can use the field name as a property.

$fmdb = new FMDataAPI("TestDB", "web", "password");
$result = $fmdb->person_layout->query();
foreach ($result as $record) {
    echo "name: {$record->FamilyName}, {$record->GivenName}";
}

For more details, I'd like to read codes and comments in file samples/FMDataAPI_Sample.php.

API Document is here: https://inter-mediator.info/FMDataAPI/packages/INTER-Mediator-FileMakerServer-RESTAPI.html

What's This?

The FileMaker Data API is the new feature of FileMaker Server 16, and it's the API with REST-based database operations. Although the Custom Web Publishing is the way to access the database for a long while, FileMaker Inc. has introduced the modern feature to operate the database. The current version of FMDataAPI works on just FileMaker 18 and 19 platform.

For now, I'm focusing to develop the web application framework "INTER-Mediator" (https://inter-mediator.com/ or https://github.com/INTER-Mediator/INTER-Mediator.git) which can develop the core features of database-driven web application with declarative descriptions. INTER-Mediator has already supported the Custom Web Publishing with FX.php, and I develop codes here for support REST APIs.

Bug reports and contribution are welcome.

Installing to Your Project

FMDataAPI has "composer.json," so you can add your composer.json file in your project as below.

...
"require": {
  ...
  "inter-mediator/fmdataapi":"31"
} ...

About Files and Directories

  • src/FMDataAPI.php
    • The core class, and you just use this for your application. This class and supporting classes are object-oriented REST API wrappers.
  • src/Supporting/*.php
    • The supporting classes for the FMDataAPI class. Perhaps you don't need to create these classes, but you have to handle methods on them.
  • composer.json, composer.lock
    • Composer information files.
  • Sample_results.ipynb
    • Sample program and results with Jupyter Notebook style. Sorry for slight old version results.
  • samples/FMDataAPI_Sample.php and cat.jpg
    • This is the sample program of FMDataAPI class, and shows how to use FMDataAPI class. It includes rich comments, but Sample_results.ipynb is more informative.
  • README.md, .gitignore
    • These are for GitHub.
  • test
    • Some files for unit testing.
  • .github, docker-compose.yml, Dockerfile
    • For the GitHub action with testing.

Licence

MIT License

Acknoledgement

  • Thanks to Atsushi Matsuo. Your script is quite helpful to implement the "localserver" feature. (https://gist.github.com/matsuo/ef5cb7c98bb494d507731886883bcbc1) Moreover thanks for updating and fixing bugs.
  • Thanks to Frank Gonzalez. Your bug report is brilliant, and I could fix it quickly.
  • Thanks to base64bits for coding about container field.
  • Thanks to phpsa for bug fix.
  • Thanks to Flexboom for bug fix.
  • Thanks to schube for bug fix.
  • Thanks to frankeg for bug fix.

History

  • April 2017: Start to create these classes and codes.
  • 2017-05-05: README.md added.
  • 2017-05-26: [Ver.2] Support the "localserver" as host name.
  • 2017-05-31: [Ver.3] The query() method of FileMakerLayout class fixed. 'Offset' and 'range' parameters could not set as an integer value.
  • 2017-11-06: [Ver.4] The getFieldNames() and getPortalNames() methods added.
  • 2018-02-03: [Ver.5] Bug fix of sorting parameters in query method.
  • 2018-02-18: [Ver.6] Bug fix of creating record with no default value.
  • 2018-03-25: [Ver.7] getSessionToken method added. OAuth handling implemented but not well debugged.
  • 2018-05-09: The Version 7 is the last version which supports FileMaker 16-based Data API.

  • 2018-05-15: [Ver.8] Update for FileMaker 17. FileMaker Data API v1 is supported from this version. The preview version of FileMaker Data API doesn't support anymore.
  • 2018-05-27: [Ver.9] composer.json is added, and can install "inter-mediator/fmdataapi". FMDataAPITrial directory deleted because it's already discontinued api. Add the "samples" directory and move sample files into it.
  • 2018-06-22: [Ver.10] Added the getContainerData method (Thanks to base64bits!), bug fix (Thanks to phpsa!).
  • 2018-07-22: [Ver.11] Global field methods bug fixed and were available in FMDataAPI class (Tanks to Mr.Matsuo). The script errors and results can get from methods in FMLayout class.
  • 2018-07-29: [Ver.12] Bug fix for UUID Supporting (Thanks to Mr.Matsuo). Unit tests implemented but now for limited methods, als integrating Travis CI.
  • 2018-11-13: [Ver.13] Added getDebugInfo method (Thanks to Mr.Matsuo), modified and fixed the getFieldNames method (Thanks to phpsa), fixed handling portal object name (Thanks to Mr.Matsuo) fixed the getModId method (Thanks to Flexboom)
  • 2018-11-17: [Ver.15] Jupyter Notebook style sample and results.
  • 2019-05-19: [Ver.16] This is the final version for FileMaker 17 platform, and bug fix (Thanks to darnel)

  • 2019-05-20: [Ver.17] Support the FileMaker 18 platform. Add getMetadataOld() and getMetadata() to FileMakerLayout class. Add getProductInfo(), getDatabaseNames(), getLayoutNames() and getScriptNames() to FMDataAPI class.
  • 2019-05-27: [Ver.18] Add getTargetTable(), getTotalCount(), getFoundCount(), getReturnedCount() to FileMakerRelation class. Add getTargetTable(), getTotalCount(), getFoundCount(), getReturnedCount() to FMDataAPI class.
  • 2019-09-12: [Ver.19] Add the duplicate() method to the FileMakerLayout class. Thanks to schube.
  • 2019-09-16: [Ver.20] The default values of limit and range parameters changed to 0 and both just applied for over 0 values. Thanks to schube.
  • 2020-08-23: [Ver.21] Bug fix about the field referencing of a related field without any portals. Thanks to frankeg. Checked on the FileMaker Server 19.
  • 2021-02-10: [Ver.22] Setting the timeout value about cURL. Thanks to @montaniasystemab. Also thanks to @AnnoyingTechnology for correcting.
  • 2021-11-11: [Ver.23] File structure is updated for PSR-4. Thanks to tkuijer.
  • 2021-12-23: [Ver.24] Bug fix for portal limit parameter. Thanks to tkuijer.
  • 2022-03-24: [Ver.25] Add methods(getFirstRecord, getLastRecord, getRecords) to the FileMakerRelation class.
  • 2022-03-26: [Ver.26] Add methods(setFieldHTMLEncoding, getFieldHTMLEncoding) to the FMDataAPI class. These are going to use for compatibility mode of FileMaker API for PHP.
  • 2022-06-06: [Ver.27] Dropped the support of PHP5, minimal version is PHP 7.1, but 7.2 or later is recommended.
  • 2022-08-04: [Ver.28] Added the getContainerData(URL) method to the FMDataAPI class for accessing container data from the url containing /Streaming/MainDB. [BUG FIX] The FileMakerRelation class's toArray method didn't return array (Thanks to Talwinder Singh).
  • 2022-12-28: [Ver.29] Fixed the 'HTTP/2 stream 0 was not closed cleanly' problem with the new FileMaker (Thanks to @thijsmeijer). Also fixed the getPortalNames issue for single record relation (Thanks to @PGMMattias).
  • 2023-06-20: [Ver.30] The toArray() method bug fixed. In same cases, it returned []. (Thanks to @PGMMattias).
  • 2023-11-24: [Ver.31] The curlErrorMessage() method returns the error message from curl (Thanks to @P1-Roger). Corrected phpdoc issue (Thanks to @patacra).

API Differences between ver.8 and 7.

FMDataAPI class

The setAPIVersion method added. This is for a future update of FileMaker Data API. As far as FMDataAPI Ver.8 goes, This isn't required.

  • public function __construct($solution, $user, $password, $host = NULL, $port = NULL, $protocol = NULL, [New]$fmDataSource = null)
  • [New]public function setAPIVersion($vNum)

FileMakerRelation class

The following methods added to script parameters. See the query method's document for specifying it. Twe methods added to portal parameter.

  • public function query($condition = NULL, $sort = NULL, $offset = -1, $range = -1, $portal = null, [New]$script = null)
  • public function getRecord($recordId, $portal = null, [New]$script = null)
  • public function create($data = null, [New]$portal = null, [New]$script = null)
  • public function delete($recordId, [New]$script = null)
  • public function update($recordId, $data, $modId = -1, [New]$portal = null, [New]$script = null)
  • [New]public function uploadFile($filePath, $recordId, $containerFieldName, $containerFieldRepetition = null, $fileName = null)

fmdataapi's People

Contributors

annoyingtechnology avatar craigatcd avatar matsuo avatar msyk avatar p1-roger avatar patacra avatar rickard2 avatar schube avatar tkuijer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fmdataapi's Issues

dataInfo and totalRecordCount

I would like to know total count of records to implement pagination. I discover there is such attribute in dataInfo by examining your source code. Unfortunately "my" response doesn't contain dataInfo key. Is there any way to enable it e.g. in request?
Thanks.

Handling error 102 Field is missing.

Hi,

Concerning Error code 102, is there a way to find which field is missing in a layout? (Error Code: 102, Error Message: Field is missing.)

Or ignore the field that does not exist and proceed with creating and filling a record with other fields that do exist?

Thanks in advance!

HTTP 400 Bad Request

I have the sample script working fine with the test database, but I'm having trouble connecting with my own database, as I receive HTTP 400 Bad Request across the board. The requests work in Postman, however. Does the wrapper have difficulty handling database files that have spaces in it's filename?

FileMaker Server 18.0.4

Hi,

Hi have 2 servers on version FMS 18 and i upgrade on 18.0.4 yesterday... Since, the FMDataAPI doesn't Work :-(

Uncaught Exception: 2020-07-23 18:58:13 cURL in PHP / Error Code: 7, Error Message: Failed connect to X.X.X.X:443; Connection refused. [URL(POST): https://X.X.X.X:443/fmi/data/vLatest/databases/experts/sessions] in /var/www/vhosts/mydomain.com/httpdocs/FMDataAPI.php:2052
Stack trace:
#0 /var/www/vhosts/mydomain.com/httpdocs/FMDataAPI.php(1920): INTERMediator\FileMakerServer\RESTAPI\Supporting\CommunicationProvider->callRestAPI(Array, false, 'POST', Array, Array)
#1 /var/www/vhosts/mydomain.com/httpdocs/FMDataAPI.php(623): INTERMediator\FileMakerServer\RESTAPI\Supporting\CommunicationProvider->login()
#2 /var/www/vhosts/mydomain.com/httpdocs/do_login.php(31): INTERMediator\FileMakerServer\RESTAPI\Supporting\FileMakerLayout->create(Array)
#3 {main}
thrown in
/var/www/vhosts/mydomain.com/httpdocs/FMDataAPI.php

accessing related field

Hi,
There are related fields on the layout
eg. event::start (not in a portal )
but
foreach ($result as $key=> $record ) {
$record->field("start", "event"); // this produce error even if I have a portal

// only way I found it to work was having a portal and accessing it like below
foreach ($record->event as $item) {
     print $item->start;
}

}

What am I missing on how to access a related field not in a portal

Thanks
Frank

Download external container file

We have big files (200MB and up) that we want to link on a website.
If we use $file->getContainerData('ContainerFile') we get the error The field 'ContainerFile' is not field name or container field..
This piece of code works fine in a database where small images are directly inside the database instead of storing them externally.
How can we receive/download the file from a container where the file is not directly stored inside the database?
Right now my data received via $file->ContainerFile looks like this:

href="file:20180125_151216.gpx\rfilewin:/C:/Users/MyUsername/Downloads/20180125_151216.gpx"

In the Filemaker Server settings under Configuration -> Folder, the "Container Data Folder" is enabled and a folder on my C:\ drive on the server is selected.

Fatal error object of class could not be converted to string

When executing any API call at the end of the debugging result I keep getting this error:

Recoverable fatal error: Object of class INTERMediator\FileMakerServer\RESTAPI\Supporting\FileMakerRelation could not be converted to string in /FMDataAPI.php on line 1446

Should I leave it and not worry about it?

I tried to fix it but it is beyond my skills at the moment.

I am using php 7.2.127.2.12

OAuth implementation.

I'm sorry, I've forgotten to implement the OAuth process on FM 17 platform. As far as Ver.20 goes, the OAuth feature isn't available. So we need to call '/oauth/getoauthurl' and whaterver. I will start to do it soon.

Token per call rather than per action

Looking at the FileMaker API logs I see that when I use the php script to perform a series of things the script creates a new token per each action, it will be nice to use only one token for all the actions and delete that token/sesion once the script is finished, let me know your thoughts.

Thanks!

Thanks!

Thanks for sharing this code, it has made my request to the API a lot easier, you guys are genius!

Arigato!

Get container data

I am enjoying FMDataAPI a lot and cannot thank you enough, today I had the need to show an image that is stored in a FileMaker container, but the simple
== base64_encode(file_get_contents($result->containerFieldName) did not work ==

After searching the web I found a solution that will be nice to have in FMDataAPI so others can also use it to get container data from FileMaker, here it is:

/* STEP 1. create a cookie file /
$ckfile = tempnam("/tmp", "CURLCOOKIE");
/
STEP 2. visit the container URL to set the cookie */
$ch = curl_init($imageURL);
curl_setopt($ch, CURLOPT_COOKIEJAR, $ckfile);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);

/* STEP 3. visit container URL again /
$ch = curl_init($imageURL);
curl_setopt($ch, CURLOPT_COOKIEFILE, $ckfile);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
/
STEP 4. process the image data as need it */
$imageData = base64_encode($output);

Once again thanks!

Documentation issue

Hi,

In the documentation for the function FileMakerLayout::query() ,the parameter $portal is described like this:

The array of the portal's object names. The query result is going to contain portals specified in this parameter. If you want to include all portals, set it null or omit it. Simple case is array('portal1', portal2'), and just includes two portals named 'portal1' and 'portal2' in the query result. If you set the range of records to a portal, you have to build associated array as like: array('portal1' => array('offset'=>1,'range'=>5), 'portal2' => null). The record 1 to 5 of portal1 include the query result, and also all records in portal2 do.

I tried using array('portal1' => array('offset'=>1,'range'=>5)), but I got a "missing array key" error. Looking at the code, it seems to expect something like this: array('portal1' => array('offset'=>1,'limit'=>5)).

However, FileMaker server does not like the request with portal parameters anyway. I will test that some more. Error message from FileMaker Server:
Error Code: 960, Error Message: Unknown parameter(s): _limit.portal1,_offset.portal1.

toArray() returns nothing for portal reords

Hello,

When iterating over portal records, I discovered that calling the toArray() method on a portal record returns an empty array.

In FileMakerRelation.php line 316 etc, the switch statement has a case for 'OK', 'PORTAL', and 'RECORD'. However my portal record's result property is 'PORTALRECORD'. So there is no matching case and the default value is returned by this method.

Simple pseudo code:
//$record is a FileMakerRelation where the result is RECORD
foreach ($record->getPortalNames() as $portalName) {
foreach ($record->$portalName as $portalRecord) {
$portalRecordArray = $portalRecord->toArray();
print_r($portalRecordArray);
}
}

Expected a dump of the values in each portal record, got empty arrays.

Thank you for this nice library!

Unknown SSL protocol error in connection

Hi, I have the following error when I try $result = $fmdb->layoutname->query(); :

ErrorNumber: 35

Unknown SSL protocol error in connection to xx.xx.com:443

Any ideas?

FileMaker Cloud

Hi,
Can you connect to files hosted on FileMaker Cloud with your FMDataApi?

Thank

Frank

Portal Limit and offset results in a error when using a query

When passing a limit and/or offset on a related portal the filemaker server responds with an error.

For example:
$filemaker->layout('layout')->query([['id' => 1]], null, 0, 0, ['related_portal' => ['limit' => 5, 'offset' => 0]);

The expected result is a response with a limited amount of portal records. This however results in a error:

{
    "messages": [
        {
            "message": "Unknown parameter(s): _limit.related_portal",
            "code": "960"
        }
    ],
    "response": {}
}

toArray return type error

When using toArray method defined in https://github.com/msyk/FMDataAPI/blob/master/src/Supporting/FileMakerRelation.php getting return type error.

This is possibly due to on line number 310, 315, 320 when encoding and decoding the object, json_decode function is missing second parameter true. Second parameter set to true assure that json_decode always return an array.

Screen Shot 2022-06-22 at 12 21 12 PM

Thanks.

getModId() method returns recordId instead of modId

Current code in the method getModId():

case "RECORD":
case "PORTALRECORD":
    if (isset($this->data) && isset($this->data->modId)) {
        $value = $this->data->recordId;
    }
    break;

$value = $this->data->recordId; should probably be changed to $value = $this->data->modId;

Error in getPortalNames() in FileMakerRelation

Perhaps I'm using this the wrong way, but I called getPortalNames() after calling getFirstRecord(), and received an error. That is because getNumberedRecord() changes the structure of the internal $data property.

What I did (leaving out the setup code):

`
$records = $fmdb->$layout->query($conditions, null, 1, 1);

$record = $records->getFirstRecord();

$portalNames = $record->getPortalNames(); //error
`

The error message: property_exists(): Argument #1 ($object_or_class) must be of type object|string, array given
File: inter-mediator/fmdataapi/src/Supporting/FileMakerRelation.php
Line: 339

One way to address this would be to change lines 257-259 from this:

$value = new FileMakerRelation( $this->data[$num], $dataInfo, ($this->result == "PORTAL") ? "PORTALRECORD" : "RECORD", $this->errorCode, $this->portalName, $this->restAPI);

into this (by surrounding the first parameter value with []):

$value = new FileMakerRelation( [$this->data[$num]], $dataInfo, ($this->result == "PORTAL") ? "PORTALRECORD" : "RECORD", $this->errorCode, $this->portalName, $this->restAPI);

That way, the array structure of the returned FileMakerRelation object stays the same as before.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.