saasformation/magic-field

MagicField is a library to convert mixed values into desired typed values -when doable.

1.0.3 2022-08-30 16:56 UTC

This package is auto-updated.

Last update: 2024-05-29 05:21:07 UTC


README

FieldMagic is a library to convert mixed values into desired typed values -when doable.

It is very useful, for instance, when reading JSON body requests in controllers.

Installation

Use composer to require the library:

composer require saasformation/field-magic

Getting started

Let's imagine you have the following array with data (maybe from a json_decode call):

$data = [
    'name' => 'John',
    'birthdate' => '1990-02-03',
    'height' => 177,
    'alive' => true,
    'highSchoolQualificationsAverage' => 4.56,
    'professions' => [
        'computing engineer',
        'soldier'
    ]
];

Now, you can do the following:

$name = (new StandardField($data['name']))->string();
$birthdate = (new StandardField($data['birthdate']))->datetime();
$height = (new StandardField($data['height']))->integer();
$alive = (new StandardField($data['alive']))->boolean();
$highSchoolQualificationsAverage = (new StandardField($data['highSchoolQualificationsAverage']))->float();
$professions = (new StandardField($data['professions']))->array();

Two advantages:

  1. You now have the value typed.
  2. If any of the source values were not compatible with type changing, an InvalidConversionException would be thrown.

If you were going to get data from a JSON body request in a controller, you could do something as cool as this:

abstract class BaseController {
    protected function field(string $path): StandardField {
        return new StandardField($this->getFromBodyRequestByPath($path));
    }
}

class Controller extends BaseController {
    public function doSomething(): Response {
        $this->commandBus->handle(
            new CreatePersonCommand(
                $this->field('data.attributes.name')->string(),
                $this->field('data.attributes.birthdate')->datetime(),
                $this->field('data.attributes.height')->integer(),
                $this->field('data.attributes.alive')->boolean(),
                $this->field('data.attributes.highSchoolQualificationsAverage')->float(),
                $this->field('data.attributes.professions')->array(),
            )
        )
    }
}

Adding a new converter

Sometimes you don't have enough with the StandardField converters available.

To add a new one, you have to create a new trait:

trait MyConverterCapable {
    public function addOneToInteger(): integer {
        return (int)$this->value + 1;
    }
}

Bear in mind $this->value is a mixed value, so for production proposes you may validate data better than in this example.

Now, you need to create a new Field class. If you want to have all the StandardField converters also available, you can inherit from StandardField. If not, directly from Field:

class MyConverterField extends StandardField
{
    use MyConverterCapable;
}

Now you can just use the new Field based class the same way as the StandardField one:

$addedInteger = (new MyConverterField(1)->addOneToInteger(); // 2

Users of stratdes/vo

Users of stratdes/vo may find saasformation/vo-magic-field-bridge useful to add converters for single VO's and collections.

Issues

If you find some issue in the library, please feel free to open an issue here on Github.