Employee Spotlight: meet Adrian Pellus

Meet the team

Adrian Pellus
Employee Spotlight: meet Adrian Pellus

Our “Employee Spotlight” blog series places the spotlight on Lesterius employees who tell us about why they decided to join Lesterius and what they do here. At Lesterius, we want employees to look back at their time here and say they did the work of their life at Lesterius. This week we sat down with Adrian Pellus to learn more about his career.

 

Can you tell us a little bit about yourself? About Adrian Pellus Quesada when he is not working.
I like to spend time with my family. If I need some headspace, we take short family trips together. We like to go hiking or visit museums and feed our curiosity. Being a curious person, that’s vital to me.

How did you become interested in this field and what do you find unique in your professional field?
At first I only saw a job opportunity because FileMaker is a technology to develop applications like any other (or at least that’s what I thought) but as I got deeper into the development of solutions with FileMaker I could see the versatility and scalability that it offered me allowing me to do very fast work in an intuitive way. And have fun along the way! The flexibility that the Claris platform brings is something I have never seen in any other technology. It allows me and my team to create simple solutions to complex problems in the most creative way!

What jobs and experiences have led you to your current position?
I have created and supported so many solutions and businesses, hard to keep track. From small applications for a freelancer who was selling bread in his van and could manage his sales and customers to large enterprise-level applications such as a franchise of museums around the world that could control their sales, online shopping, logistics, etc. All the projects I have worked on have made me acquire both broad and specific experiences and these have always helped me to solve problems in the following projects. This yearlong experience together with my strong desire to make an impact have led me to join Lesterius.

What the best part of working with Lesterius?
I am obsessed with tweaking and optimising applications. Out of necessity, I had to make applications where optimisation was key to the success of the program because it handled large amounts of data. Implementing unconventional optimisations to increase the overall performance is what I love.

How do you and your team prepare for a new project?
Every new project is a challenge not only at the development level but also at the organisational level. Before tackling a new project, our team meets to explain the objectives of the project, then we carefully analyse each point of the project and assign the most suitable person to solve each point. These meetings and workshops also help us to detect any lack of information or any inconsistency in the project in order to anticipate any problem, which sometimes even helps us to propose improvements to the client based on our experiences and thus be able to provide a better service with the highest quality and speed.

If you could give one piece of advice to your younger self, what would that be?
Life will throw you some challenges and obstacles. Persist, learn and listen. Doing this will help you grow as a person.

  • Custom solutions

    Curious what we can do for your company?

    Read more

  • Lesterius helps

    We offer three services

    Consultancy

    Training

    Hosting

  • Upcoming event

    Join us and discover what’s new in Claris FileMaker 19
  • Lesterius in’s and out’s

    Stay tuned

  • Claris Platinum Partner

You might find these articles interesting too

Developer Notes: Bad practices that slow down your solution
Pedro Gallego

Developer Notes

Importing data in a FileMaker database from a “flat file”

Claris FileMaker

Create nice looking progress elements in FileMaker easily with the FMProgressIndicator
Kevin van den Brande

Claris FileMaker

Developer Notes: Bad practices that slow down your solution

Developer Notes

Pedro Gallego
Developer Notes: Bad practices that slow down your solution

Summary fields: Summary fields in list views are one of the main reasons for poor performance in many FileMaker applications. Often we enter a list view layout in which we want to show several hundred or thousands of records and we get a tiresome message saying “Calculating [x quantity] records …” and we simply have to wait for these calculations to be executed.

Solution: Evaluate if field is needed on this particular layout. Apply hide conditions so this summary field only show in specifics scenarios and certain foundcounts.

Calculation fields: This type of field is also more often used in the list views. The typical presentation that shows a list of invoices with valued sums (tax base, VAT amount, total invoice …), as was the case with the previous example, this type of field can be a cause for despair, especially if you display this field on layouts which are heavily used?.

Solution: try storing this kind of data in index/stored fields. This might imply some scripting routines which perform heavy calculations server side on certain intervals.

SQL executions: SQL functions in FileMaker can help to obtain information without having to resort to complex table relationships or obtaining data through a more elaborate script, but sometimes the execution of SQL itself on calculated fields can reach cause slowness. Wim Decorte from Soliant Consulting wrote a clear summary of the pro’s and con’s which you can read here.

Solution: Use SQL sparingly. Or perform server side with routines/server side scripts.

Multiple windows in script execution: Sometimes we need to execute a script that opens several windows with different data tables and also all of this put in a loop that repeatedly opens or closes these windows or jumps from one to another. Every time that process is carried out within the loop, upon reaching the active window, the content in records and the type of fields it shows can be a determining factor that causes a slowness in the execution of any request that we make to our application.

Solution: Try to perform this script on the server instead of the client.

There are solutions to all of these problems that take your FileMaker application from being a huge, tired, dragging elephant to an agile, powerful, effective and user-friendly tool.

Still struggling with optimising your solutions performance?

Fill in the below form and and one of our experienced consultants will contact you to discuss together what the best approach to optimising these issues are. Without any commitments.

 

Fill in the below form and and one of our experienced consultants will contact you to discuss together what the best approach to optimising these issues are. Without any commitments.

  • Custom solutions

    Curious what we can do for your company?

    Read more

  • Lesterius helps

    We offer three services

    Consultancy

    Training

    Hosting

  • Upcoming event

    Join us and discover what’s new in Claris FileMaker 19
  • Lesterius in’s and out’s

    Stay tuned

  • Claris Platinum Partner

You might find these articles interesting too

Creating more gender-inclusive solutions
Vincent Miano

Claris FileMaker

Lesterius and Atatiki join forces

Corporate News

Create nice looking progress elements in FileMaker easily with the FMProgressIndicator
Kevin van den Brande

Claris FileMaker

Interview: Kurt De Jaeger

Kurt De Jaeger
Interview with Kurt De Jaeger

Hoe ben je geïnteresseerd geraakt in dit vakgebied?

Ik heb altijd een grote affiniteit gehad met ICT. Via mijn oudere broer kwam ik al van kinds af aan in aanraking met de eerste spel- en homecomputers. Onze eerste volwaardige PC was een XT en snel hierna kwam de opmars van AT, waarbij de chipset meestal kortweg 286, 386 of 486 werd genoemd. Deze hebben geleid tot de beginstappen in het programmeren in talen zoals Basic, Pascal, Turbo Pascal en later VB.Net; welke destijds een grote hindernis vormden in mijn nachtrust.
Door de release van Windows 3.1 en Windows for Workgroups 3.11 had ik een nieuwe passie gevonden en zou later de grondlegger zijn voor mijn professionele carrière als IT-er.

Welke professionele ervaringen hebben je naar jouw huidige functie geleid?

Na mijn studies ben ik destijds gestart als ICT Engineer waarbij ik verantwoordelijk was voor de installatie van IT Infrastructuur, dit voornamelijk in B2C, B2B en kleine KMO’s. Al snel lag hier de oorsprong voor mijn gedrevenheid om klant- en oplossingsgericht te denken.
Na 17 jaar te fungeren als Network & System Engineer heb ik in 2015 de stap gezet naar een fulltime management functie en klom ik hogerop als Service Desk Manager waar ik mijn eerste team leidde. Omwille van mijn leergierigheid heb ik ook nog andere rollen zoals Project Manager en Service Delivery Manager vervult, die mijn expertise in het vak en affiniteit met klanten des temeer vergrootte.

Als Business Unit Manager, wat is je management stijl?

Ik geloof in het delegeren van verantwoordelijkheden en in het bouwen van een hecht team. Elk lid van het team moet duidelijkheid hebben over zijn rol, het verwachtingspatroon en de visie van het bedrijf, weten waar ze in passen en het gevoel hebben dat ze kunnen vertrouwen op mij.
Ik wil iedereen de kans geven om te groeien, hun sterktes te zien en hun te motiveren op een manier die resulteert in de beste versie van zichzelf te kunnen zijn wat de algemene groei van het bedrijf ten goede komt.

Het menselijk aspect is heel belangrijk. Ik geloof in real-time feedback. Mochten er zaken zijn die niet naar verwachting verlopen, moet daar meteen actie op ondernomen worden. Loopt alles naar behoren dan hoort daar de nodige appreciatie bij.

Hoe bereiden jullie zich voor op de start van een nieuw project?

Out-of-the-box denken en onze aanpak via co-creatie, is de basis van ons succes.
Co-creatie is een vorm van samenwerking tussen de klant en onze consultants, waarbij alle partijen inspraak en invloed hebben op het project en het resultaat hiervan.

De fundering van elk project is een projectplan, wat samen met de klant besproken wordt zodat deze weet wanneer welke module kan worden getest of opgeleverd wordt.

De sleutel bij dit soort projecten is het toepassen van de AGILE-methode waarbij het ontwikkelen in korte en overzichtelijke periodes gebeurt.
Bij het opleveren van een nieuwe module, gaat de klant dit testen en geeft ons de nodige feedback, waardoor wij de module terug onder de loep nemen en de eventuele oneffenheden platstrijken.

Wat zou je nu zeggen tegen je jongere zelf?

If you’re not making mistakes, you’re not learning.
Enjoy and just be yourself!

  • Custom solutions

    Curious what we can do for your company?

    Read more

  • Lesterius helps

    We offer three services

    Consultancy

    Training

    Hosting

  • Upcoming event

    Join us and discover what’s new in Claris FileMaker 19
  • Lesterius in’s and out’s

    Stay tuned

  • Claris Platinum Partner

You might find these articles interesting too

How I integrated myFMApiLibrary for PHP with Symfony 3.4
Lucie Guilbert

Web technologies

Lesterius and Atatiki join forces

Corporate News

FMDataMigration for the FileMaker Data Migration Tool
Kevin van den Brande

Claris FileMaker

Developer Notes: NFC and Claris FileMaker

Developer Notes

Lowie Sanctobin
Developer Notes: NFC and Claris FileMaker

Hi fellow Developer!

I’ve dived into the possibilities of working with NFC Tags and Claris FileMaker recently.  Leveraging the power of NFC technologie is possible thanks to a new set of functions and script steps shipped in FileMaker 19.

In this blog I’ll share some bite-sized bits of information and notes that can serve as a reference and quick overview of technical specs for fellow developers to get a jumpstart.

Have fun!

 

But wait, what is NFC again?

NFC (near field communication) is a set of communication protocols by which two electronic devices communicate when they are within close proximity of one another.

Some uses of NFC devices include contactless payment systems, similar to those used in credit cards and electronic ticket smart cards, and allow mobile payment to replace or supplement these systems, social networking and for sharing contacts, photos, videos, and other files. NFC devices can also act as electronic identity documents and keycards.

FileMaker Go 19 now has the ability to scan or stop scanning for NFC tags using the new script step: Configure NFC Reading

The options include an action (Read or Cancel scanning for NFC tags), a script to be run when a tag is read, an optional script parameter, an optional timeout to cancel the read operation after <n> seconds, and an optional Continuous Reading until the user cancels or the timeout parameter is met.

FileMaker Go supports NFC tags using the following formats:

  • “Well Known” format of type text
  • “Well Known” format of type URI
  • “Well Known” format of type “smart poster” (which is a combination of URI and text)
  • “Media” format of type “text/x-vCard”

FileMaker Go can read NFC tags of types 1 through 5 that contain data in the NFC Data Exchange Format (NDEF).

Claris & NFC in 19.0

NFC technology supported since version. 19.0. FileMaker GO only for now.

Since version 19.1.2 the format results as JSON .

The script step:

Script step: Configure NFC Reading (Read/Cancel) .

Purpose: Start or stop scanning for NFC tags.

Full script step documentation by Claris: https://help.claris.com/en/pro-help/content/configure-nfc.html

 

While testing I noticed:

  1. This script step needs to be the last script step in your script. When other steps follow, they will be executed even before you scanned a tag. You will need to build your logic inside the script which runs after scanning (see options below)
  2. When continuously scanning and saving the values to variable, make sure you use a global variable. The main script reruns the sub script when a tag was scanned.

 

Options

Script (req.)

Run a script when NFC tag is read.

! Important: In this script you must call the script step Get(ScriptParameter) to get the NFC data from the read tag.

Parameter (opt.)

Specify parameter for required script.

Timeout (opt.)

Cancels ‘read’ after specified number of seconds.

Continuous Reading (opt.)

Scanning multiple NFC tags? No problem, set a non-zero value for this option to read multiple tags.

 

Format Result as JSON since 19.1.2 (opt. but highly recommended)

Set value to non-zero to format the results as JSON. Easier to handle the NFC results with the built-in Filemaker JSON functions.

Useful variables while scripting

Set Variable [ $nfcdata ; Value: Get(ScriptParameter) ]

(Required in subscripts, see script option)

 

Set Variable [ $action ; Value: JSONGetElement ( $nfcdata ; “action” ) ]

Returns “TagRead” when a tag was read successfully.

Returns “CanceledByUser” when the user presses cancel or done.

 

 

Set Variable [ $serial ; Value: JSONGetElement ( $nfcdata ; “payloads[0].primary” ) ]

Returns the data written on the NFC tag.

Multiple payloads are possible, depends on how the tag was programmed.

 

 

Differences in device behaviour:

iPhone Xs, Xr, 11, 11 Pro, 12 and 12 Pro

Read

Requires iOS 11 or later.

Background scanning (No app needed to read): iPhone Xs, Xr, 11, 11 Pro, 12 and 12 Pro

Data on the tag is required. Empty tags do nothing. (Android phones tell you the tag is empty)

Write

Requires iOS13 or later.

NFC app required to write data to a tag.  (NFC tools for example)

 

iPhone 7, 8 and X

Read

Pre-iOS14 an app was needed. Now you can find it in the control center.

Data on the tag is required. Empty tags do nothing. (Android phones tell you the tag is empty)

Write

Requires iOS13 or later.

NFC app required to write data to a tag.  (NFC tools for example)

iPhone 7 & 8 can only read with an NFC app found on the app store. (or with FM go of course)

 

NFC tags

Be mindful of different kinds of NFC standards. If you buy tags, make sure your phone supports them.

Only data in NDEF format can be read.

 

Advantages of use shortcuts in combination with NFC

Attention: NFC automation in Shortcuts app is only available on iPhone XS or newer

If you want to launch a shortcut on an older device, you will need an NFC reader/writer app (free) + you will need to write the URL shortcut on the NFC tag

https://support.apple.com/en-gb/guide/shortcuts/apd624386f42/ios

shortcuts://run-shortcut?name=[NameOfShortcut]

 

Security Considerations:

Write

Possible to password protect. To write, you first need to unlock the tag with the password.

Read

An NFC tag can be read by any compatible device. It’s better to not store sensitive information on an NFC tag. What you program on the tag, is your responsibility.

For our use case, we programmed some NFC tags with their own serial number.

This number is linked to assets in a secured database.

So, someone who has no business with the tag would only see the NFC tag serial number when scanned.

!Attention: to stick NFC tags to metal object, you’ll need special NFC tags

 

Some use cases that came to mind:

Inventory Management:

Tracking and identifying assets, inventory, …

Scanning lend items out and in, …

NFC can be valuable alternative to barcodes:

  • Data instead of text
  • Make items ‘smart’
  • Waterproof
  • Easily reprogrammable if there’s a mistake
  • No need to pair devices
  • Very fast when multiple scanning. No need to focus camera for example

 

Sources:

https://help.claris.com/en/pro-help/content/configure-nfc.html

https://seritag.com/news/ios14-iphone-nfc-reader

https://seritag.com/learn/nfc-enabled-phones/

https://help.gototags.com/article/writing-nfc-tags-iphone/

https://skeletonkey.com/nfc-near-field-communication-in-claris-filemaker-go-19/

https://seritag.com/learn/using-nfc/nfc-logos

 

  • Custom solutions

    Curious what we can do for your company?

    Read more

  • Lesterius helps

    We offer three services

    Consultancy

    Training

    Hosting

  • Upcoming event

    Join us and discover what’s new in Claris FileMaker 19
  • Lesterius in’s and out’s

    Stay tuned

  • Claris Platinum Partner

You might find these articles interesting too

ProgramDesign joins the Lesterius Group.
Andreas Lauwaert

Communication

Creating more gender-inclusive solutions
Vincent Miano

Claris FileMaker

Lesterius and Atatiki join forces

Corporate News

ProgramDesign joins the Lesterius Group

Communication

Andreas Lauwaert
ProgramDesign joins the Lesterius Group.

Although this year has been challenging, we are happy to be able to close it off with a some exciting news. On the back of consistent efforts and investments this last year we are thrilled to announce that the Norwegian consultancy Firm ProgramDesign has joined the Lesterius Group.

Oslo will harbour our tenth office alongside Brussels, Stockholm, Paris, Gent, Barcelona, Lisbon, London, Alicante and Almere.

The Oslo office will support both local and global clients and channel partners. The Norway operations will be headed by Bjørn Haugland who has more than 20 years of experience in the FileMaker Community and as a business consultant. Bjørn comes to Lesterius through the merger with his firm ProgramDesign, and will be the Business Unit Manager for our Oslo office.

The Norway office will be supported in its endeavours by our expanding European team. Expect Bjorn and our entire team to engage projects across the continent, helping our partners understand, control and amplify the way their organisation and teams work.

  • Custom solutions

    Curious what we can do for your company?

    Read more

  • Lesterius helps

    We offer three services

    Consultancy

    Training

    Hosting

  • Upcoming event

    Join us and discover what’s new in Claris FileMaker 19
  • Lesterius in’s and out’s

    Stay tuned

  • Claris Platinum Partner

You might find these articles interesting too

News from the Swedish front!

Communication

Creating more gender-inclusive solutions
Vincent Miano

Claris FileMaker

Importing data in a FileMaker database from a “flat file”

Claris FileMaker

News from the Swedish front!

Communication

News from the Swedish front!

As mentioned earlier on our blog, in February 2020, Lesterius Group and Atatiki, two major IT companies, joined forces. The new group becomes the primary European partner to deliver solutions for companies, based on Claris FileMaker technology, the leading Workplace Innovation Platform. The new Lesterius Group now has a local presence in 8 European countries: Belgium, France, the Netherlands, Norway, Portugal, Spain, Sweden, and the United-Kingdom.

Our story started over 20 years ago as a Platinum Partner of Claris International Inc., the company who created the FileMaker platform. Lesterius is a team of creative consultants in business IT, who assist companies in their digital journey to digital transformation, by co-creating tailor-made solutions. We optimise business processes, together with our clients, with IT-solutions that answer directly to the specific needs of the users and that can be easily implemented.

Since we set foot in Sweden, we also offer our vast hosting and training offer to the Swedish market.

The exciting news does not end there. As of last week, company veteran Annicka Wallentin is our new Business Unit Manager for our Swedish Unit.
Wallentin, previously Project Manager in Stockholm has assumed the post as of last week. We are very pleased to have her years’ long experience put to service on management level. We are confident that her leadership and vision will further reinforce our swedish team and thus contribute to the best service imaginable.

 

Fortsättning följer! ????????

  • Custom solutions

    Curious what we can do for your company?

    Read more

  • Lesterius helps

    We offer three services

    Consultancy

    Training

    Hosting

  • Upcoming event

    Join us and discover what’s new in Claris FileMaker 19
  • Lesterius in’s and out’s

    Stay tuned

  • Claris Platinum Partner

You might find these articles interesting too

Importing data in a FileMaker database from a “flat file”

Claris FileMaker

FMDataMigration for the FileMaker Data Migration Tool
Kevin van den Brande

Claris FileMaker

myFMApiLibrary for Javascript, one library to rule them all, again

Web technologies

FM Progress Indicator

Claris FileMaker

Kevin van den Brande
Create nice looking progress elements in FileMaker easily with the FMProgressIndicator

Are you too always struggling with creating nice looking progress elements in FileMaker to show the user the status of the current task? Well, look no further!

FMProgressIndicator will provide you with the right tools you need to implement such a progress element in FileMaker that is supported on all platforms! All it requires is some basic knowledge on FileMaker. If you have some basic knowledge on Bootstrap this will help you in making full use of the formatting options.

Progress indicators?

We all know that, whenever we are running a long task, the best practice is to inform the user about this. For a task that runs longer than 1 second, it’s best to use an indicator. This way the user always has feedback that the app is still working and performing the task.

How do we usually do this?

  1. By simply doing nothing. Most of the times the cursor switches to a load icon and that’s it. But wait… Isn’t this the same icon that we see whenever the app is stuck and we need to force quit? Yup, that’s the one! It’s up to the user to determine if this time this icon is actually an indicator of a running task. As you can understand this might be confusing for the user, especially whenever a task is long.
  2. We forward the user to a FileMaker layout where we display the text “Loading…”. This is already a better practice but without animation or an indication of the progress itself this is static content and does not give the user dynamic feedback on the actual status of the task.
    How we should actually be doing it
    Every time we perform a task that is longer than 1 second, we should forward the user to a layout where he or she can track the process or can confirm the application is still working. FileMaker provides us with various window types that we can use for displaying a dynamic progress indicator.

How does FMProgressIndicator help you with this?

FMProgressIndicator

Inside the configuration tab you will see that you have two possible progress indicators that can be used (a bar and a spinner). By selecting one of these two you can configure and style the progress element to your needs.

Each progress indicator has its own values that can be configured and styled. As an addition for displaying dynamic text you can make use of Bootstrap classes. FMProgressIndicator supports the latest Bootstrap version. If you are familiar with Bootstrap, you can use this knowledge to your advantage.

Below you will find some examples of the limitless possibilities. Please also take a look at the examples inside the FileMaker file. This should give you a good idea of its capabilities.

Progress bar indicator — Example 1

Progress bar indicator — Example 2

Spinner indicator — Example 3

How is it made?

We make use of the FileMaker web viewer and HTML technology powered by Bootstrap to give us a rich environment to create kickass, nice looking progress indicators.

Now how do I set this up?

The complete guide on how to install an indicator can be found within the tool, but just to show you how easy it is:

  1. Copy and paste the required custom function inside your FileMaker solution (use the appropriate function you intend to use):
    • CF_ProgressIndicator_CreateProgressbar — required for display of the progress bar indicator
    • CF_ProgressIndicator_CreateSpinner —required for display of the spinner indicator
  2. Copy and paste the script “FMProgressIndicator.Show” to your FileMaker solution.
  3. Build and style your own progress indicator by using the configuration tab.
  4. Create an empty web viewer with minimal configuration and give the web viewer object a proper name.
  5. Create a script where you execute the script step “Perform Script” and call the script “FMProgressIndicator.Show”. The script parameter is the result of your custom configuration.
    (tip: take a look at the example scripts. Don’t forget to add your custom web viewer object name and pause time as parameters!).

That’s all folks!

Once the first two steps are completed, you can create various configurations and paste them as script parameters to see the result. The configuration tab should always give you a perfect example of how the progress element will look.

Now the most interesting part… The FMProgressIndicator tool is completely free, written in FileMaker Pro 18 Advanced and completely open-source under the GNU license. Enjoy!

Written by Kevin van den Brande

Discover the product page.

  • Custom solutions

    Curious what we can do for your company?

    Read more

  • Lesterius helps

    We offer three services

    Consultancy

    Training

    Hosting

  • Upcoming event

    Join us and discover what’s new in Claris FileMaker 19
  • Lesterius in’s and out’s

    Stay tuned

  • Claris Platinum Partner

You might find these articles interesting too

Lesterius and Atatiki join forces

Corporate News

How I integrated myFMApiLibrary for PHP with Symfony 3.4
Lucie Guilbert

Web technologies

Importing data in a FileMaker database from a “flat file”

Claris FileMaker

Lesterius and Atatiki join forces

Corporate News

Lesterius and Atatiki join forces

Ghent, Belgium | 27 February 2020

Lesterius becomes a major player in FileMaker-based solutions for businesses

Today, Lesterius and Atatiki, two major IT companies, join forces. The new group becomes the biggest European partner to deliver solutions for companies, based on Claris FileMaker technology, the leading Workplace Innovation Platform. The new Lesterius has now subsidiaries in 8 European countries (Belgium, France, the Netherlands, Norway, Portugal, Spain, Sweden, and United-Kingdom).

Lesterius has a history that goes back 20+ years and is a Platinum Partner of Claris, the company who created the FileMaker platform. Lesterius is a team of creative consultants in business IT, who assist companies in their digital journey, by co-creating FileMaker-based solutions. We optimize business processes, together with our clients, with IT-solutions that answer directly to the specific needs of the users and that can be easily implemented. On top of that, Lesterius provides training and hosting services related to all aspects of FileMaker.

The combination of Lesterius and Atatiki creates one of the biggest designers of FileMaker-based solutions, in the world. Why is this good for our clients? “The need for our solutions is expanding rapidly. The market is also changing at a pace never seen before. Therefor a bigger, stronger company is needed to be able to always offer the best know-how in digital transformation. Lesterius can now support a wide range of companies in search for higher efficiency and competitiveness,” said Olivier Devriese, Sales & Marketing Manager at Lesterius.

The choice of Lesterius and Atatiki to join forces is a logical one. Both are experts in FileMaker-based solutions, and are present in different countries. We can now offer services all over Europe, with over fifty specialized consultants, who are the bridge between the needs of our clients and the best technological possibilities. This is what we mean by co-creation: our consultants work together with the client to make absolutely sure our solutions are fit to purpose.

Journalists can call for more information to:
Frank Steyaert, CEO,
Olivier Devriese, Sales & Marketing Manager.

For more information on Lesterius, please visit our website www.lesterius.com
Also www.claris.com

  • Custom solutions

    Curious what we can do for your company?

    Read more

  • Lesterius helps

    We offer three services

    Consultancy

    Training

    Hosting

  • Upcoming event

    Join us and discover what’s new in Claris FileMaker 19
  • Lesterius in’s and out’s

    Stay tuned

  • Claris Platinum Partner

You might find these articles interesting too

Importing data in a FileMaker database from a “flat file”

Claris FileMaker

myFMApiLibrary for Javascript, one library to rule them all, again

Web technologies

FMDataMigration for the FileMaker Data Migration Tool
Kevin van den Brande

Claris FileMaker

FMDataMigration for the FileMaker Data Migration Tool

Claris FileMaker

Kevin van den Brande
FMDataMigration for the FileMaker Data Migration Tool

An interface with configurable options for the good execution of the data/accounts migration before going to live environment.

With the launch of the FileMaker 17 Platform, the new FileMaker User Licensing program was introduced. Each FileMaker User Licensing contract includes 3 licenses of FileMaker Server. An organisation can, for example, have a production server, backup server, and development server.

FileMaker is a unique product that gives us the possibility of developing in a live environment while users are actively using the FileMaker database. However this does have as implication that the programmer needs to be careful not to break anything when altering structure / code. For larger scale applications this way of programming is not an option and a separate development / production environment is essential.

When you have such a separate environment, at a certain point you will decide that the current development you have done on the development server needs to published to the live environment. This means that you will have to migrate all the production data / accounts into the current development database. This was time consuming process. As a developer you had to take care that each table got correctly imported. Let alone update the possible serial numbers inside a table.

With the release of the FileMaker Data Migration tool this all changes.

What is the FileMaker Data Migration Tool?

The FileMaker data migration tool is a command-line tool from FileMaker, Inc. to migration all record data and user accounts from a source file in the FileMaker Pro 12 format (FMP12) to a target file.

This tool is cross platform (macOS and Windows) and dramatically speeds up the data migration process.

When you run this command line tool a full access user account or an account with the “fmmigration extended privilege” is required. When using the extended privilege, the specified user does not require access to any table, scripts or layouts and thus provides a secure method for migration.

The specified account you will use for the migration process does need to be present in the source and clone file. Do mind when using the extended privilege, the option for verbose logging is not available. Verbose logging is only full access accounts.

After the migration this tool gives either a brief overview of the migration result or a verbose log depending on your given account.

The FileMaker Data Migration tool is available to people who have bought a FileMaker Developer Subscription (FDS). Please refer to your community profile for downloading after you have purchased a FDS.

How to migrate your data?

  1. Open the file to be cloned.
  2. Choose File menu > Save a Copy As, then choose clone (no records).
  3. Make sure the source file and the clone are closed.
  4. Download the file Win_FMDataMigration_x64.zip (Windows) or Mac_FMDataMigration.zip (macOS).
  5. Unzip the downloaded file and move the contents to a location of your choice.
  6. Use the following command at the command-line prompt:
FMDataMigration -src_path <path> -clone_path <path>

The parameters -src_path and -clone_path are required. All the other parameters are optional. The optional parameters are:

-src_path: Source filename and path.
-src_account: Account name used for opening the source file. The default is Admin.
-src_pwd: Password for accessing the source file.
-src_key: Encryption password for decrypting the source file.
-clone_path: Clone filename and path.
-clone_account: Account name for accessing the clone. The default is Admin.
-clone_pwd: Password for accessing the clone.
-clone_key: Encryption password for decrypting the clone.
-target_path: Target filename and path. The default target file, source filename migrated.fmp12, is located in the same folder as the source file.
-force: Overwrites an existing target file. If you have an existing target file, you must use a different name for the new target file, or use -force to overwrite the existing file.
-ignore_valuelists: Uses custom value lists from the clone instead of the source file.
-ignore_accounts: Uses the account names, passwords, and the encryption password from the clone instead of the source file.
-ignore_fonts: Doesn’t check the font mapping for field contents.
-v (verbose mode): For accounts with the Full Access privilege set, provides a detailed report about the data migration process. For accounts with the fmmigration extended privilege, in both normal and verbose modes, the tool provides only a brief report without displaying any information about the schema.
-q (quiet mode): Doesn’t provide a report.

More information about the FileMaker Data Migration tool can be found here.

FMDataMigration

Since the FileMaker Data Migration is a command line it does require some knowledge for executing this correctly. You have to compose a correct command with valid paths and options.

This is where the FMDataMigration comes in. This tool will automate the migration process for you. It gives you a FileMaker interface with configurable options before executing the migration.

FMDataMigration — Database

The result of the migration process is a log file that does include a detailed report of the migration process itself. It is important to use a full access account in order to receive a detailed log result as described above.

The FileMaker database FMDataMigration was build with purpose to either help the developer for migration your data by using a FileMaker interface that guides you through the process AND to give a detailed report of the migration process itself.

After the migration, the created log file gets imported and parsed into the FileMaker database. This gives you a clear view of possible warnings / errors where you should have a second look at before using this file again in a production environment. Below is an example of a possible result:

FMDataMigration — Result summary

FMDataMigration — Result tables

How does the FMDataMigration works?

At launch this tool will verify if you have the required plugin (BaseElements, FREE plugin) installed. If not, this will be installed automatically. This FREE plugin is used for executing the command line in the backend.

Before using this tool you must upload a .zip file off the “FileMaker Data Migration command line tool” which you have downloaded from your FileMaker community profile.

FMDataMigration — Settings — Migration tool

After you have uploaded a valid .zip for for macOS / Windows you are ready to go.

Inside the configuration tab, specify a valid source-/clone- and target path. Provide a full access account to make fully use of the FMDataMigration tool.

Verify after the configured options. Verbose logging is ticked on by default. You are now ready to migrate your data / account.

The FMDataMigration will first verify if all parameters are configured properly. After, the migration itself will start. You will get a good overview how many % of the migration is completed.

FMDataMigration — Migrating

After the migration the FMDataMigration database will parse the created log file into native FileMaker tables for a detailed report. The progress bar gives you an idea of how long it will take.

FMDataMigration — Parsing result

After this stage the migration is completed and the result can be checked. The detailed result gives an in dept view of possible warnings / errors that are reported by the migration process.

Inside the detailed report you will get an overview of the following parts:

  • Accounts
  • Privileges
  • Value Lists
  • Tables
  • Fields
  • Fonts

Each warning / error will be logged. It is important to know as a developer what happend during the migration process as this is crucial information before deciding if the new file is ready for production.

The FMDataMigration tool is free, written in FileMaker Pro 17 Advanced and completely open-source under the GNU license.


Written by Kevin van den Brande

Discover the product page on myFMbutler.com.

  • Custom solutions

    Curious what we can do for your company?

    Read more

  • Lesterius helps

    We offer three services

    Consultancy

    Training

    Hosting

  • Upcoming event

    Join us and discover what’s new in Claris FileMaker 19
  • Lesterius in’s and out’s

    Stay tuned

  • Claris Platinum Partner

You might find these articles interesting too

Creating more gender-inclusive solutions
Vincent Miano

Claris FileMaker

Importing data in a FileMaker database from a “flat file”

Claris FileMaker

myFMApiLibrary for Javascript, one library to rule them all, again

Web technologies

How I integrated myFMApiLibrary for PHP with Symfony 3.4

Web technologies

Lucie Guilbert
How I integrated myFMApiLibrary for PHP with Symfony 3.4

Lesterius recently published the myFMApiLibrary for PHP. The myFMApiLibrary for PHP is a REST client library for PHP that allows you to easily interact with the FileMaker Data API and integrate it faster. But how do you use it?

In this article I will show you how I use it with Symfony 3.4, a popular Web Application framework based on a set of PHP Components.

Feel free to improve it.

This article assumes that you already have experience with Symfony.

Before using the DataApi from FileMaker, make sure that your FileMaker Server has a proper SSL certificate installed.

First you need to get the library using composer:

composer require myfmbutler/myfmapilibrary-for-php

You will also need JMS serializer library (follow documentation found here) and doctrine annotations to be able to link FileMaker fields with your PHP properties:

composer require jms/serializer
composer require doctrine/doctrine-bundle

Then create 4 parameters in parameters.yml file: database_api_urldatabase_namedatabase_user and database_password.

Now that everything is fine, we’ll create 2 services in services.yml:

  • One to set the myFMAPI library
  • The other one to set-up the Event Subscriber.

The first one needed is used to set-up the myFMAPI library:

Lesterius\FileMakerApi\DataApi:
    arguments: ['%database_api_url%','%database_name%', null, null, true]

The second one is used to set-up the connection to the DataApi to be able to use our first service:

AppBundle\EventSubscriber\RequestEventSubscriber:
    arguments: ['@Lesterius\FileMakerApi\DataApi', '%database_user%', '%database_password%']

Here follows the class RequestEventSubscriber.php that must be put in src/AppBundle/EventSubscriber repository:

<?php

namespace AppBundle\EventSubscriber;

use Lesterius\FileMakerApi\DataApi;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class RequestEventSubscriber implements EventSubscriberInterface
{
    /**
     * @var string
     */
    private $apiUser;
    /**
     * @var string
     */
    private $apiPassword;
    /**
     * @var DataApi
     */
    private $dataApi;

    public function __construct(DataApi $dataApi, string $apiUser, string $apiPassword)
    {
        $this->apiUser     = $apiUser;
        $this->apiPassword = $apiPassword;
        $this->dataApi     = $dataApi;
    }

    /**
     * Returns an array of event names this subscriber wants to listen to.
     *
     * The array keys are event names and the value can be:
     *
     *  * The method name to call (priority defaults to 0)
     *  * An array composed of the method name to call and the priority
     *  * An array of arrays composed of the method names to call and respective
     *    priorities, or 0 if unset
     *
     * For instance:
     *
     *  * array('eventName' => 'methodName')
     *  * array('eventName' => array('methodName', $priority))
     *  * array('eventName' => array(array('methodName1', $priority), array('methodName2')))
     *
     * @return array The event names to listen to
     */
    public static function getSubscribedEvents()
    {
        return [
              KernelEvents::REQUEST => ['apiLogin']
        ];
    }

    /**
     * @param GetResponseEvent $event
     *
     * @throws \AppBundle\Service\FileMakerApi\Exception\Exception
     */
    public function apiLogin(GetResponseEvent $event)
    {
        if (is_null($this->dataApi->getApiToken())) {
            $this->dataApi->login($this->apiUser, $this->apiPassword);
        }
    }
}

With the old FileMaker Php library I used to create a table with the field names and the property names. In Symfony, I can use annotations to link fields with properties.

An example of using annotations

Usually you need a lot of entities. I think it is best to make an abstract class for all of them. In this class, I create methods to manage the internal FileMaker id and to get the field names found in FileMaker.

Here follows my AbstractEntity.php in src/AppBundle/Entity:

<?php

namespace AppBundle\Entity;

use Doctrine\Common\Annotations\AnnotationReader;
use JMS\Serializer\Annotation as Serializer;
use Symfony\Component\Serializer\Normalizer\DataUriNormalizer;

/**
 * Class AbstractEntity
 *
 * @package AppBundle\Entity
 */

abstract class AbstractEntity
{
    /**
     * @Serializer\SerializedName("recordId")
     * @Serializer\Type("integer")
     * @Serializer\Groups({"internal"})
     */
    public $idRecordFileMaker;

    /**
     * @Serializer\SerializedName("modId")
     * @Serializer\Type("integer")
     * @Serializer\Groups({"internal"})
     */
    public $idModificationFileMaker;

    const SEPARATOR = "\r";

    /**
     * @return int
     */
    public function getInternalFmId()
    {
        return $this->idRecordFileMaker;
    }



    /**
     * @param int $idRecordFileMaker
     */
    public function setInternalFmId($idRecordFileMaker)
    {
        $this->idRecordFileMaker = $idRecordFileMaker;
    }


    /**
     * Get the name of Annotation Name with the property name
     *
     * @param $name
     * @return mixed
     * @throws \Doctrine\Common\Annotations\AnnotationException
     * @throws \ReflectionException
     */
    public static function getSerializedNameByPropertyName($name)
    {
        $reflectionClass = new \ReflectionClass(get_called_class());
        $property        = $reflectionClass->getProperty($name);

        $annotationReader = new AnnotationReader();
        $classAnnotations = $annotationReader->getPropertyAnnotation(
            $property,
            'JMS\Serializer\Annotation\SerializedName'
        );

        return $classAnnotations->name;
    }
}

Now in my entity, I’ll need to use:

use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as Serializer;

Every class that extends the AbstractEntity Class will need an “IdNameClass” property. The name of the property must start with “id”, followed by the name of the class in camel case, otherwise it will not work. As an example if I have Class Attendee, I’ll need a property with the name $idAttendee.

Next, I’ll put my FileMaker field names in “Serializer\SerializedName” annotations.

In “Serializer\Type” we store the data type. Here‘s the types you can find:

  • int
  • string
  • Datetime (with UTC format)
  • boolean

In “Serializer\Groups” you define the actions that can be done on the field:

  • create
  • update
  • internal
  • excluded
  • default

These groups are managed in the AbstractRepository class. The “default” group is set if you didn’t define it.

The group will be used when needed, in a “create” case to insert some data you choose not to update, or in an “internal” case where you only need to retrieve data (i.e. modification timestamps).


A example of using Types and Groups

You need to create a repository for your entity. Like entities, I made a AbstractRepository to simulate a database call, similar to what I did for Doctrine.

For my own reading comfort I prefer writing all my database functions in my repositories files.


An example of repository with a script call and an upload to container instruction

A simple example of findBy

A complexe example of findBy with OMIT

Here follows my AbstractRepository.php in src/AppBundle/Repository:

<?php

namespace AppBundle\Repository;

use JMS\Serializer\SerializationContext;
use JMS\Serializer\SerializerBuilder;
use Lesterius\FileMakerApi\DataApi;
use Psr\Http\Message\ResponseInterface;

abstract class AbstractRepository
{
    const SORT_ASC          = 'ascend';
    const SORT_DESC         = 'descend';
    const BIG_RANGE_VALUE   = '10000';
    const OMIT              = 'omit';

    protected $em;
    protected $entityName;
    protected $layout;
    protected $serializer;

    /**
     * AbstractRepository constructor
     *
     * @param DataApi        $em
     * @param                           $entityName
     */
    public function __construct(DataApi $em, $entityName, $layout)
    {
        $this->em         = $em;
        $this->entityName = $entityName;
        $this->layout     = $layout;
    }

    /**
     *  Get entity name
     *
     * @return mixed
     */
    protected function getEntityName()
    {
        return $this->entityName;
    }

    /**
     * Hydrate a list of Objects
     *
     * @param array $data
     *
     * @return array
     * @throws \Exception
     */
    protected function hydrateListObjects(array $data)
    {
        $list_objects = [];

        foreach ($data as $record) {
            $list_objects[] = $this->hydrateObject($record);
        }

        return $list_objects;
    }

    /**
     * @param array $data
     *
     * @return object
     * @throws \Exception
     */
    protected function hydrateObject(array $data)
    {
        $data = $this->prepareDataForObject($data);

        if (is_null($this->serializer)) {
            $this->serializer = SerializerBuilder::create()->build();
        }
        //--
        
        $object = $this->serializer->deserialize(json_encode($data), $this->getEntityName(), 'json');

        return $object;
    }

    /**
     *
     * @param array $data
     *
     * @return array
     * @throws \Exception
     */
    private function prepareDataForObject(array $data)
    {
        $result = [];

        $result['recordId'] = (isset($data['recordId']) ? $data['recordId'] : null);
        $result['modId']    = (isset($data['modId']) ? $data['modId'] : null);

        if (isset($data['fieldData'])) {
            $result = array_merge($result, $data['fieldData']);
            if (isset($data['portalData']) && !empty($data['portalData'])) {
                $result = array_merge($result, $data['portalData']);
            }
        }else {
            $result = array_merge($result, $data);
        }

        return $result;
    }

    /**
     *  Search by Array
     *
     * @param array $criterions
     * @param array $sortArray
     *
     * @param null  $offset
     * @param null  $range
     * @param null  $portal
     *
     * @return array|Object
     * @throws \Exception
     */
    public function findBy(array $criterions = [], array $sortArray = [], $offset = null, $range = null, $portal = [])
    {
        $sort = null;

        $preparedQuery = $this->prepareFindCriterions($criterions);

        if (!empty($sortArray)) {
            foreach ($sortArray as $fieldName => $sortOrder) {
                $sort[] = ['fieldName' => $fieldName, 'sortOrder' => $sortOrder];
            }
        }

        if (is_null($range)) {
            $range = self::BIG_RANGE_VALUE;
        }

        $results = $this->em->findRecords($this->layout, $preparedQuery, $sort, $offset, $range, $portal);

        $return  = $this->hydrateListObjects($results);

        return $return;
    }

    /**
     *  Find All records
     *
     * @return array
     * @throws \Exception
     */
    public function findAll()
    {
        $results = $this->em->getRecords($this->layout);
        $return  = $this->hydrateListObjects($results);

        return $return;
    }

    /**
     *  Search by ID
     *
     * @return Object|array
     * @throws \Exception
     */
    public function find($idObject)
    {
        $propertyName   = 'id'.str_replace('AppBundle\Entity\', '', $this->entityName);
        $annotationName = call_user_func($this->entityName.'::getSerializedNameByPropertyName', $propertyName);
        $criterions     = $this->prepareFindCriterions([$annotationName => $idObject]);

        $results = $this->em->findRecords($this->layout, $criterions);
        $return  = $this->hydrateListObjects($results);

        if (isset($return[0])) {
            return $return[0];
        }

        return null;
    }

    /**
     *
     * Create objet
     *
     * @param $object
     *
     * @return object
     *
     * @throws \Exception
     */
    public function create($object)
    {
        if ($object instanceof $this->entityName) {
            $serializer = SerializerBuilder::create()->build();
            $data       = $serializer->serialize($object, 'json',
                SerializationContext::create()->setGroups(['Default', 'create']));
            $data       = json_decode($data, true);

            $recordId = $this->em->createRecord($this->layout, $data);

            if ($recordId instanceof ResponseInterface) {
                throw new \Exception('Error, creation fail : '.$recordId);
            }

            $results = $this->em->getRecord($this->layout, $recordId);
            $return  = $this->hydrateObject($results);

            return $return;
        }

        throw new \Exception('Error, object is not a instance of the object repository');
    }

    /**
     * Edit object
     *
     * @param $object
     *
     * @param array $scripts
     * @return object
     *
     * @throws \AppBundle\Service\FileMakerApi\Exception\Exception
     * @throws \Exception
     */
    public function set($object, $scripts = [])
    {
        if ($object instanceof $this->entityName && !empty($object->{'getInternalFmId'}())) {
            $serializer = SerializerBuilder::create()->build();
            $data       = $serializer->serialize($object, 'json',
                SerializationContext::create()->setGroups(['Default', 'update']));
            $data       = json_decode($data, true);

            $modId = $this->em->editRecord($this->layout, $object->{'getInternalFmId'}(), $data, null, [], $scripts);

            if ($modId instanceof ResponseInterface) {
                throw new \Exception('Error, update fail : '.$object->{'getInternalFmId'}());
            }

            $results = $this->em->getRecord($this->layout, $object->{'getInternalFmId'}());
            $return  = $this->hydrateObject($results);

            return $return;
        }

        throw new \Exception('Error, object is not a instance of the object repository');
    }

    /**
     * @param $object
     * @param array $fileOption
     * @param int $repetition
     * @return object
     * @throws \AppBundle\Service\FileMakerApi\Exception\Exception
     * @throws \Exception
     */
    public function setFile($object, $fileOption = [], $repetition = 1)
    {
        if ($object instanceof $this->entityName && !empty($object->{'getInternalFmId'}()) && !empty($fileOption)) {
            foreach ($fileOption as $fieldName => $filePath) {
                $modId = $this->em->uploadToContainer($this->layout,  $object->{'getInternalFmId'}(), $fieldName, $repetition, $filePath);
                if ($modId instanceof ResponseInterface) {
                    throw new \Exception('Error, update fail : '.$object->{'getInternalFmId'}());
                }
            }

            $results = $this->em->getRecord($this->layout, $object->{'getInternalFmId'}());
            $return  = $this->hydrateObject($results);

            return $return;
        }
    }

    /**
     * @param array $criterions
     *
     * @return array
     */
    private function prepareFindCriterions(array $criterions)
    {
        $preparedCriterions = [];
        foreach ($criterions as $index => $criterion) {

            if (is_array($criterion)) {
                $fields = [];

                foreach ($criterion as $field => $value) {
                    $fields[] = ['fieldname' => $field, 'fieldvalue' => $value];
                }

                $preparedCriterions[]['fields'] = $fields;
            } else {
                $fields[] = ['fieldname' => $index, 'fieldvalue' => $criterion];
            }
        }

        if (empty($preparedCriterions) && !empty($criterions)) {
            $preparedCriterions[]['fields'] = $fields;
        }

        return $preparedCriterions;
    }

    /**
     * @return DataApi
     */
    public function getEm(): DataApi
    {
        return $this->em;
    }

    /**
     * @param DataApi $em
     */
    public function setEm(DataApi $em)
    {
        $this->em = $em;
    }

    /**
     * @return mixed
     */
    public function getLayout()
    {
        return $this->layout;
    }

    /**
     * @param mixed $layout
     */
    public function setLayout($layout)
    {
        $this->layout = $layout;
    }

    /**
     * @return mixed
     */
    public function getSerializer()
    {
        return $this->serializer;
    }

    /**
     * @param mixed $serializer
     */
    public function setSerializer($serializer)
    {
        $this->serializer = $serializer;
    }
}

I created 2 functions in my BaseController.php:

  • one to call the myFMApiLibrary-for-PHP service and connect to the database.
  • one to close the connection (don’t forget this part!).

Then in my controller, I can create my repository object and my object:


An example of using with a creation, an upload to container and a script execution

The error messages you could have should be explicit (and with their FileMaker error code). DataApi works the same way as another FileMaker Client. As an example, two users can’t edit the same record at the same time, and will throw an error.

Follow these steps, and you will be able to easily connect your Symfony to the FileMaker 17 DataAPI (with myFMApiLibrary for PHP), and significantly save your work time, which is good for you, but even better for your clients!

What were your thoughts on this tutorial? Please let me know in the comments.

Don’t forget to subscribe to follow our reviews and updates of this article once the FileMaker 18 DataAPI will be released.

If you choose “int” as “Serializer\Type” annotation, be sure the field is always filled. “Empty” is not an int nor a boolean, change to “string” to avoid this.

@Serializer\Type(“DateTime<’m/d/Y’, ‘Europe/Paris’>”) can be @Serializer\Type(“DateTime<’m/d/Y H:i:s’, ‘Europe/Paris’>”), for example.

If you don’t put @Serializer annotation, the property won’t be linked to FileMaker.

And please, don’t forget to set stricter privileges to your DataApi user for more security.

Written by Lucie Guilbert.

  • Custom solutions

    Curious what we can do for your company?

    Read more

  • Lesterius helps

    We offer three services

    Consultancy

    Training

    Hosting

  • Upcoming event

    Join us and discover what’s new in Claris FileMaker 19
  • Lesterius in’s and out’s

    Stay tuned

  • Claris Platinum Partner

You might find these articles interesting too

Creating more gender-inclusive solutions
Vincent Miano

Claris FileMaker

Importing data in a FileMaker database from a “flat file”

Claris FileMaker

myFMApiLibrary for Javascript, one library to rule them all, again

Web technologies