FileMaker PHP API : an Open Source project
FileMaker PHP API : an Open Source project
31 mai 2017 - Auteur : - Categories : Blog, English content, FileMaker, Technique

FileMaker PHP API : an Open Source project

Logo PHP

Version française

Is the FileMaker PHP API at end of life? This is a question that could arise since a new technology appeared in FileMaker Server 16 to allow us to share data from a FileMaker database through a website: the REST API. However, although this new API (still in beta version – [EDIT: in final version with FileMaker 17]) brings a real wind of freshness and offers beautiful prospects of evolution, it remains nonetheless limited for the instant and less adapted to a classic web architecture where the web server occupies a central role.

Therefore XML publishing combined with the FileMaker PHP API is still often the best way to share and use a solution directly on the Web.

It still suffers from some shortcomings: developed to be compatible with PHP 4 at its release (a version still widespread at the time), the original PHP API (download) has hardly changed since (except for some minor corrections) ).

Anyone who has used it, certainly remember many alerts indicating the use of deprecated methods as soon as they were run with a newer version of PHP. Although these errors have since been corrected, the advent of PHP 7 has unfortunately brought them up to date.

This lack of evolution has made its code obsolete, it is not at all in step with the new development methods that have emerged in recent years in the PHP universe, and in fact this update delay makes its integration complicated in any project using a framework or a “modern” CMS.

An update of this library had become more and more necessary to ensure its durability. But here, although PHP still has a bright future ahead of time given its steady improvements and popularity, FileMaker has decided to take a good look at the more popular technologies such as JavaScript frameworks. No need therefore to hope for any evolution on this side (the XML publication is and will never be available on FileMaker Cloud for example).

So there was only one solution: roll up his sleeves and put his hands in the grease to give a little makeover to our dear PHP API!

Méthodology

Obviously, before touching any line of code, one had to dive first, like a Cistercian monk, into a long and thorough study of the original source code, to understand its structure, its functioning and its particularities in order to grasp well the magnitude of the upcoming work.

Very quickly, two requirements were imposed: simplifying the source code as much as possible (while trying to optimize it), and modernizing it to bring it into line with current development standards, especially those recommended by the PHP-FIG group, in the goal of ensuring better interoperability with most modern PHP frameworks and CMSs.

On the simplification side, the changes mainly focused on a new error management strategy and rewriting part of the code in order to comply with the PSR-2 standard (source code writing conventions).

The new error handling is to overcome the occasional conditional tests for the benefit of a single general test structure by exception, with a block of type “try / catch” encompassing the main work instructions (see a sample code lower). The original method still remains functional, however, to ensure backward compatibility.

This first step was completed, it was now necessary to consolidate compatibility with the most recent versions of PHP and make the most of it to modernize the code as much as possible.

Therefore, concerning the modernization of the source code, the addition of namespaces, on all the classes of the API, coupled with a “self-loading” system, as recommended by the PSR-4 specification, have imposed themselves, ensuring de facto compatibility with the most popular PHP frameworks of the moment.

This technique has resulted in a profound change in the file structure, without changing the original operation of the API, in order to ensure full compatibility with projects based on the API-PHP of Original FileMaker.

structure des fichiers de l'API-PHP de FileMaker originale

Original FileMaker PHP API file structure

structure des fichiers de l'API-PHP de FileMaker réécrite

New PHP API file structure

Open to the World

We were there ! the PHP API of FileMaker was finally modernized! Then remained open to the rest of the free world!

Indeed, for some years now, PHP projects have been structured around a multitude of third-party libraries, like many other languages ​​such as java, javascript, …

In order to simplify the management of these multiple source codes and to ensure their updating without effort (the code being maintained by other developers), a very popular tool has now been created: Composer. It allows to manage, with the help of a simple configuration file (json) all the third libraries of a project, ensuring the installation and the update.

Obviously, our API had to join the community to complete its mutation, which necessitated some adaptations not without consequences: that led to abandon the original configuration file of the API (in the world of Composer, a third library should never be modified to keep the benefit of updates). This implies that it is now delivered with a “default” configuration, which you must modify at the moment of instantiation.

Evolutions

Our new API ready, we were eager to integrate it into a large project to measure its potential, which was quickly the case! A project requiring the use of a Framework (yii2) was quickly presented.

This first test run highlighted some deficiencies that did not necessarily appear during the rewrite, including the need to facilitate debugging during development and improve communication with third-party libraries.

Thus, a certain number of new features have been implemented over the water, of which here is a non-exhaustive list (some developed specifically, others resulting from functions already existing in FileMaker API-XML, but not implemented in the original FileMaker PHP-API):

  • Choice of date format input and output of the API;
  • Support for “paging” when running a script;
  • Definition of global at the execution of a search;
  • Method to retrieve the last request (URL) sent to the FileMaker server (extremely useful for debugging in the development phase);
  • The “Layout” object can now return the name of the source table (in addition to the name of the table instance) via the $ $layout->table property, allowing easier management of execution contexts;
  • Method for retrieving a list of values ​​associated with a field on a model (lists can be renamed without impact on your website).

Installation and configuration

Here are some of the main steps to install and implement this new FileMaker PHP API.

There are two methods of installing this API:

  1. Via the “Composer” solution, adding "airmoi/filemaker" : "*" to your configuration file;
  2. Manually by downloading the latest sources from the dedicated GitHub website and installing the uncompressed files in your project: GitHub Repository

For the loading and the activation of the API, it is very simple, it is enough to include the file “autoload.php” which is at the root of the project (optional in case of installation via Composer):
require ('/path/to/API/autoload.php');

You must then declare the class to use using its namespace (the autoloader is responsible for automatically finding the files to load for the proper functioning of the API):
use airmoi\FileMaker\FileMaker;

Since the configuration file was removed, two methods are available to configure your project:

  1. Using the FileMaker PHP method: setProperty('name', $value), which can be used to individually configure the different parameters of the project;
  2. Use a parameter array directly when creating the FileMaker object, for example: new FileMaker($db, $host, $user, $pass, ['dateFormat' => 'd/m/Y']) to configure the project in one single instruction.

Here is an example code illustrating all this:

// Load the API
require_once ('/path/to/API/autoload.php');

// define name space
use airmoi\FileMaker\FileMaker;

// configuration options
$options = [
    'errorHandling' => 'default',
    'locale' => 'fr',
    'prevalidate' => true,
    'dateFormat' => 'd/m/Y',
];

// FileMaker object w/ parameter array
$fm = new FileMaker($db, $host, $user, $pass, $options);

// List all layouts and view as types
$layouts = $fm->listLayouts();
foreach ($layouts as $layout) {
    echo $layout . '
';
}

Usage

Error trapping: the ‘old’ way

// Configuration
$options = [
   'errorHandling' => 'default',
];

$fm = new FileMaker($db, $host, $user, $pass, $options);

// Get a layout and test
$layout = $fm->getLayout('sample');
if (FileMaker::isError($layout)) {
    echo "Error: " . $layout->getMessage();
    exit;
}

// Execute query
$result= $fm->newFindAnyCommand('sample')->execute();
if (FileMaker::isError($record)) {
    echo "Error: " . $record->getMessage();
    exit;
}

// Get a record
$record = $result->getFirstRecord();
if (FileMaker::isError($record)) {
    echo "Error: " . $record->getMessage();
    exit;
}

// Modify a record
$record->setField('text_field', str_repeat('a', 51));
$record->commit();
if (FileMaker::isError($record)) {
    echo "Error: " . $record->getMessage();
    exit;
}

The old error management system is obtained by setting the “errorHandling” parameter to the “default” value.
As you can see, it forces you to repeat your controls for virtually every instruction.

Error Management: The Exception Method

// Exception mode is configured by default
// no need to specify it
$fm = new FileMaker($db, $host, $user, $pass);

try {
    // Try to get a layout
    $layout = $fm->getLayout('sample');

    // Get a record (in 1 line)
    $record = $fm->newFindAnyCommand('sample')->execute()->getFirstRecord();

    // Modify record
    $record->setField('text_field', str_repeat('a', 51));
    $record->commit();
} catch (FileMakerException $e) {
    // Trap errors that can have occurred on any line
    printf ('Error %d : %s ', $e->getCode(), $e->getMessage());
}

As you can see, exception handling via the try / catch block can significantly reduce the number of lines of code.
All its logic can be centralized, which simplifies the reading of the code, improves its reliability and its maintenance.

Limit the results of a script

$fm = new FileMaker($db, $host, $user, $pass);
$result = $fm->newPerformScriptCommand('sample', 'create sample data', 50)
    ->setRange(5, 20)
    ->execute();

echo $result->getFetchCount() . '/' . $result->getFoundSetCount();

Now, with this new API, you can ask which data interval to retrieve. For example, you can request to have the data corresponding to the records from 5 to 25. This allows to obtain a pagination on a script result, which was impossible before.

Set a global field on executing a query

$fm = new FileMaker($db, $host, $user, $pass);
$result = $fm->newFindCommand('sample')
    ->setGlobal('global_field', date('m/d/Y'))
    ->addFindCriterion('test_field', 1)
    ->execute();

echo $result->getFetchCount() . " enregistrements trouvés.";

Very handy feature because it now allows to define a global field at the time of the execution of a query, which will allow you for example to recover, in your results, related data through a global field.

Conclusion

As explained at the beginning of the article, FileMaker’s PHP API really needed a fresh start to adapt to the evolution of the latest technologies, especially regarding the interaction with modern PHP frameworks.

This rewriting required many hours of work and countless tests. The result is more than encouraging as this new version is now used daily in production on several professional projects managed by the 1-more-thing team.

But, although it is in the stable and mature state to be used in production, this rewrite is not yet finished, many other improvements are in progress and others to predict. If you want to contribute to its evolution, you are obviously welcome: GitHub Repository.

Many thanks to all those who participated, directly or indirectly, in the realization of this project, and a special thanks to Matthias Kühne for all his contributions.

Ajouter un commentaire