Download the PHP package didix16/php-apidatamapper without Composer

On this page you can find all versions of the php package didix16/php-apidatamapper. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package php-apidatamapper

PHP API DataMapper

An extensible DTO library that allows map incoming API data to any of your entities/models by using a simple filed mapping language with filters and functions.

Content

What is an API DataMapper

An API DataMapper is a class that allows to map incoming data to a model or entity class you have without much effort. The only have to do is instruct which incoming fields should be mapped to you entity class fields and how. In other words, to allows to use the DTO pattern with every class you have.

It is able to preprocess data and transform it before the final data is set to an entity field.

What is a Model Map

So a model map is a class that handle all the tough stuff of mapping an incoming data into a model of your application. It has the configuration of which fields should be mappend into which ones and how. This is where all DTO magic happens. It uses a FieldInterpreter to archive this task.

Installation

Usage

In the following list you will see how to use each important part of this package:

Field language

This is the language that is being used by a model mapper. It syntax is very easy to understand: it allows to select which field do you want to extract and process from an APIDataObject.

The syntax allows to select a single field from an object, a field from a list (array, vector, whatever..)and transform incoming data ( i.e string to PHP DateTime). Also allows the use of aggregate functions for list items. For example, get the Maximum value of certain amount inside a list.

SYNTAX

Supose we have this JSON $data

Select first lvl field: warrior

Select specific field from object and apply a filter ( in this case BooleanFilter)

There is "no limit" on depth to select a deepest property.

We can stack filters as much as we need.

For example:

NOTE: those filter does not exists, you have to register them. In sections below you will see how.

The transformation pipeline order follows the specified in syntax, from left to right. In the example above, capitalize filter will be executed first, then snakecase, and so on...

Now, supose we have this JSON $data

Select a field inside a list:

Use an aggregate function inside a list:

NOTE: At the moment only MAX and MIN are available. However, you can extend the field language by adding the functions you need like: SUM, AVG, MEAN, etc...

BTW: You can only use aggregate functions with list fields inside! I.e: MAX(name) won't work, but MAX(warrior_list[].name) yep.

FieldInterpreter

As we saw above, to make FieldInterpreter do its work, we need a FieldParser.

The FieldLexer receives the Field Language input syntax. The FieldParser receives the FieldLexer as the only argument.

Finally you have to pass the FieldParser to FieldInterpreter and an APIDataObject instance to make its magic :).

If for some reason the syntax is invalid, you will get an Exception.

Finally, you need to call the #run method from the interpreter. The result will be an associative array where the key is the processed input and value the final processed data.

NOTE: If you specify a field which is not coming in incoming data, then the value for that field will be:

So you must check with ApiDataObject::isUndefined($res[$field]) if the result is correct or is an undefined field.

FieldFilter

As we saw, filters allows to pipeline data and transform it. We can add filters as much as we need.

By default there are two filters: DateFilter and BooleanFilter.

BooleanFilter transforms potential values to be casted as boolean value. For example: "yes", 1, "1", "true", true, "True", "tRUE", and so on... will be transformed to PHP true value. However, "no", 0, "1", "false", false, "FALSE", "fAlse" and so on... will be transformed into PHP false value.

You can instante a new BooleanFilter with an associative array that tells the filter which values should be treat as true and which as false:

DateFilter allows to parse any standard date formats into a PHP DateTime class.

First of all, it will try to transform by testing each of these formats:

If none of them were found, then $fromFormat='Y-m-d' constructor option will be used as last chance.

Also you can pass a timezone as a second optional argument

Feel free to extend both if you need.

To make your own filter you need to extend from:

Finally, to register a filter you need to call #loadFilter(FieldFilter $filter) method from FieldInterpreter BEFORE call #run method

IMPORTANT: filters name MUST BE the same in field language syntax. If you named "capitalize" your filter, then in $input syntax, the filter should be "capitalize" as well.

FieldFilter receive as mandatory parameter its name. If you look inside BooleanFilter and DateFilter, you will see that there is a

and

lines respectively inside their constructors

FieldFunction

Like FieldFilter but for AggregateFunctions. As I wrote before, aggregate functions only works with lists, so be carefully.

There are MAX and MIN functions ( self explanatory).

If you need to add your own functions, you have to extend

Finally, to register a function you need to call #loadFunction(InterpreterFunction $function) method from FieldInterpreter BEFORE call #run method

IMPORTANT: function name MUST BE the same in field language syntax. If you named "AVG" your function, then in $input syntax, the filter should be "AVG" as well.

ModelMap

As I explained before, the model map is the key of the api data mapper. It handles all the ugly tasks to parse and manage data.

Fortunately, the only thing we have to do is tell to a model map how we need to map the fields and if we need to preprocess and postproces them.

For example, imagine we have these entity classes:

And imagine we have this source of data:

How we should map that data into our Monster entity?

Without a data mapper, we will probably design an specific DTO or similar. Maybe some people hardcode transformation ( yeah I see a lot of things in this live), whatever.

But what if I told you that only you need is a mapping configuration (and maybe a model map factory)?

WOW, that's a lot information! Yeah I know. But for the moment pay attention to MonsterModelMap and look mapFields method. It sounds familiar to you, right? Correct, the field language! As we can see, a model map uses the field interpreter to map the fields for us but also is able to execute a "post-parsing" function before set the final value to our entity. What does that means? Well, look at the color property of our monster.

It is not just an "ordinary" value like a string or number, is a class! Well it is true that we could made some filter that transforms a value into a class but, filters only have access to a single value. What happens if we need more data? Well the answer is the ModelMapFunction. This kind of function allows to us make last data transformations before set to our entity and also has access to the APIDataObject.

Remember the color property? Yeah, the color is a class, so, we can add a model map function that resolves a value and turns into our Color class. If we have complex classes that require more data that comes from API, we can access that data but also we can call any service from our app, like DDBB storage or something and do the things we have to do with it :).

ModelMapFunction

Model map functions are very easy to implement: just need the run(...$args) method.

$args 0 contains the value coming from interpreter (after filter pipeline)

$args 1 holds the entire APIDataObject.

NOTE: Data may not be the original one because the Interpreter may changed the value by applying your filters.

Finally how we tell to our model map that use this function?

Well that is simple. Remember this line?

Perfect! As you deducted, the key of the mapFields array is the input of the field language and the value must be the field of our entity but optinally it can be suffixed by a colon and a function name. Usually, the name of the function is the camel case of the name class without the MapFunction suffix, thus is why the class names of every MapFunction should be:

But that's not all, we have to register the function to our model map.

Well there is a #use() method that allows us to register not one but three kind of objects:

This way we can extend our language field mapping though a model map instead of talking directly with the fieldparser.

ModelMapFactory

Why we need a factory to instnatiate model maps? Well this is a pice of the amazing ApiDataMapper that allows to pass a class of any kind ( the ones we have in our ModelMapFactory) and let configure our model maps in runtime as well as leave the tough work to ApiDataMapper.

Remember that our goal is only to configure the mapping and leave the rest to APIDataMapper :)

As we saw before, this is an example of a factory that can generate mappings for Warrior and Monster classes.

In the future I'll change this because no one wants to have a gigantic switch for each class :)

In the mean time, you can generate different model maps factories and have different api data mappers.

ApiDataObject

ApiDataMapper

And here we are, the API functionality usage of this marvelous package :)

Basically, from this packge we will need:

Examples

You will find some examples at examples folder

You sould look at:

They are ready to go, so if you open your terminal after installation:

OR

You should see a few results from the examples

Credits

Feel free to use this library but do not forget to mention that I'm the owner :).

Sorry for my bad english. I'll try to fix any grammar errors in the future.

Also feel free to send me an issue, report bugs, suggestions, etc.


All versions of php-apidatamapper with dependencies

PHP Build Version
Package Version
Requires php Version >=7.4
didix16/php-interpreter Version ^1.0
didix16/php-hydrator Version ^1.0
didix16/php-grammar Version ^1.0
didix16/php-apidataobject Version >= 1.0.3
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package didix16/php-apidatamapper contains the following files

Loading the files please wait ....