PHP code example of kylekatarnls / morph

1. Go to this page and download the library: Download kylekatarnls/morph library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

kylekatarnls / morph example snippets


class User
{
    public int $id;
    public string $name;
    public string $email;
    public string $label;
}

$user = new User();
$user->id = 42;
$user->name = 'Katherine Anderson';
$user->email = '[email protected]';
$user->label = '';

$transformer = new Morph\Sequence([
    new Morph\PublicPropertiesToArray(),
    'array_filter', // or static fn (array $value) => array_filter($value),
    new Morph\UpperKeysFirstLetter(['id' => 'ID']),
    // a transformer can be composed with any kind of callable
]);

$info = $transformer->transform($user);
// or simply:
$info = $transformer($user);

interface Morph
{
    public function transform();
}

class HashUserId implements Morph\Morph
{
    public function transform($value = null, $hashAlgo = null): array
    {
        if ($value && $hashAlgo) {
            return ['userid' => hash((string) $hashAlgo, (string) $value->id)];
        }

        return [];
    }
}

$transformer = new Morph\Merge([
    static fn ($value) => ['username' => $value->name],
    new HashUserId(),
]);

$user = (object) ['id' => 42, 'name' => 'Georgeanna Tillman'];

var_dump($transformer->transform($user, 'sha1'));
/* [
    'username' => 'Georgeanna Tillman',
    'userid' => '92cfceb39d57d914ed8b14d0e37643de0797ae56',
] */

class UserTransformer extends Morph\Merge
{
    protected function getTransformers(): array
    {
        return [
            static fn ($value) => ['username' => $value->name],
            new HashUserId(),
        ];
    }
}

$transformer = new UserTransformer();

var_dump($transformer->transform($user, 'sha1'));

class HashUserId extends Morph\MorphBase
{
    private string $hashAlgo;

    public function __construct(string $hashAlgo)
    {
        $this->hashAlgo = $hashAlgo;
    }

    public function __invoke($value = null): array
    {
        if ($value) {
            return ['userid' => hash($this->hashAlgo, (string) $value->id)];
        }

        return [];
    }
}

class UserTransformer extends Morph\Merge
{
    private string $idHashAlgo;

    public function __construct(string $idHashAlgo)
    {
        $this->idHashAlgo = $idHashAlgo;
    }

    protected function getTransformers(): array
    {
        return [
            static fn ($value) => ['username' => $value->name],
            new HashUserId($this->idHashAlgo),
        ];
    }
}

$transformer = new UserTransformer('sha1');

var_dump($transformer->transform($user));

class User implements JsonSerializable
{
    public int $id;
    public string $name;
    public string $email;
    public string $label;

    public function jsonSerialize(): array
    {
        return ModelTransformer::get()->transform($this);
    }
}

class ModelTransformer extends Morph\Sequence
{
    private static self $singleton;

    public static function get(): self
    {
        // We can cache the transformer instance
        // for better performances.
        // This can be done via a simple singleton
        // as below.
        // Or using a container (see Psr\Container\ContainerInterface)
        // such as the Symfony container.
        return self::$singleton ??= new self();
    }

    protected function getTransformers(): array
    {
        return [
            new Morph\PublicPropertiesToArray(),
            'array_filter',
            new Morph\UpperKeysFirstLetter(['id' => 'ID']),
        ];
    }
}

$user = new User();
$user->id = 42;
$user->name = 'Katherine Anderson';
$user->email = '[email protected]';
$user->label = '';

echo json_encode($user, JSON_PRETTY_PRINT);

$removePrivateKeys = new \Morph\FilterKeys(
    static fn (string $key) => $key[0] !== '_',
);
$removePrivateKeys([
    'foo' => 'A',
    '_bar' => 'B',
    'biz' => 'C',
]);

[
    'foo' => 'A',
    'biz' => 'C',
]

$removeLowValues = new \Morph\FilterValues(
    static fn ($value) => $value > 10,
);
$removeLowValues([
    'foo' => 12,
    '_bar' => 14,
    'biz' => 7,
]);

[
    'foo' => 12,
    '_bar' => 14,
]

class User
{
    public function getName(): string { return 'Bob'; }
    public function isAdmin(): bool { return false; }
    public function update(): void {}
}

$getGetters = new \Morph\Getters(['get', 'is']);
$getGetters(User::class);

[
    'Name' => new \Morph\Reflection\Method(new \ReflectionMethod(
        User::class, 'getName',
    )),
    'Admin' => new \Morph\Reflection\Method(new \ReflectionMethod(
        User::class, 'isAdmin',
    )),
]

class User
{
    public string $id = 'abc';
    public function getName(): string { return 'Bob'; }
    public function isAdmin(): bool { return false; }
    public function update(): void {}
}

$bob = new User();

$getGetters = new \Morph\GettersToArray(['get', 'is']);
$getGetters($bob);

[
    'Name' => 'Bob',
    'Admin' => false,
]

$lowerFirstLetter = new \Morph\LowerFirstLetter([
    'Special' => '***special***',
]);

$lowerFirstLetter(5); // 5, non-string input are returned as is
$lowerFirstLetter('FooBar'); // "fooBar"
$lowerFirstLetter('Special'); // "***special***"

$upperFirstLetter = new \Morph\UpperFirstLetter([
    '***special***' => 'Special',
]);

$upperFirstLetter(5); // 5, non-string input are returned as is
$upperFirstLetter('fooBar'); // "FooBar"
$upperFirstLetter('***special***'); // "Special"

$lowerFirstLetter = new \Morph\LowerKeysFirstLetter([
    'Special' => '***special***',
]);

$lowerFirstLetter([
    5 => 'abc',
    'FooBar' => 'def',
    'Special' => 'ghi',
]);

[
    5 => 'abc',
    'fooBar' => 'def',
    '***special***' => 'ghi',
]

$upperFirstLetter = new \Morph\UpperKeysFirstLetter([
    '***special***' => 'Special',
]);

$upperFirstLetter([
    5 => 'abc',
    'fooBar' => 'def',
    '***special***' => 'ghi',
]);

[
    5 => 'abc',
    'FooBar' => 'def',
    'Special' => 'ghi',
]

$itemsWithTotal = new \Morph\Merge([
    static fn ($value) => ['items' => $value],
    static fn ($value) => ['total' => count($value)],
]);

$itemsWithTotal(['A', 'B']);

[
    'items' => ['A', 'B'],
    'total' => 2,
]

class User
{
    public string $id = 'abc';
    public function getName(): string { return 'Bob'; }
    public function isAdmin(): bool { return false; }
    public function update(): void {}
}

$bob = new User();

$itemsWithTotal = new \Morph\Merge([
    new \Morph\PublicPropertiesToArray(),
    new \Morph\GettersToArray(['get', 'is']),
]);

$itemsWithTotal(['A', 'B']);

[
    'id' => 'abc',
    'Name' => 'Bob',
    'Admin' => false,
]

$info = [
    'firstName' => 'Georgia',
    'lastName' => 'Dobbins',
    'group' => 'The Marvelettes',
];

$select = new \Morph\Only(['firstName', 'lastName']);

$select($info);

[
    'firstName' => 'Georgia',
    'lastName' => 'Dobbins',
]

$info = [
    'firstName' => 'Georgia',
    'lastName' => 'Dobbins',
    'group' => 'The Marvelettes',
];

$select = new \Morph\Only('firstName');

$select($info);

[
    'firstName' => 'Georgia',
]

$info = [
    'firstName' => 'Georgia',
    'lastName' => 'Dobbins',
    'group' => 'The Marvelettes',
];

$select = new \Morph\Pick('firstName');

$select($info);

'Georgia'

class User
{
    public string $name;
    protected int $id;
    private array $cache;
}

$getProperties = new \Morph\Properties();

$getProperties(User::class);

[
    'name' => new \Morph\Reflection\Property(new \ReflectionProperty(
        User::class, 'name',
    )),
    'id' => new \Morph\Reflection\Property(new \ReflectionProperty(
        User::class, 'id',
    )),
    'cache' => new \Morph\Reflection\Property(new \ReflectionProperty(
        User::class, 'cache',
    )),
]

class User
{
    public string $name;
    protected int $id;
    private array $cache;
}

$getPublicProperties = new \Morph\PublicProperties();

$getPublicProperties(User::class);

[
    'name' => new \Morph\Reflection\Property(new \ReflectionProperty(
        User::class, 'name',
    )),
]

class User
{
    public string $name;
    protected int $id;
    private array $cache;

    public function __construct(string $name, int $id)
    {
        $this->name = $name;
        $this->id = $id;
        $this->cache = ['foo' => 'bar'];
    }
}

$getPublicValues = new \Morph\PublicPropertiesToArray();

$getPublicValues(new User('Juanita Cowart'));

[
    'name' => 'Juanita Cowart',
]

$data = [
    'singer' => [
        'firstName' => 'Ann',
        'lastName' => 'Bogan',
    ],
    'label' => [
        'name' => 'Motown',
    ],
];

$getSingerLastName = new \Morph\Sequence([
    new \Morph\Pick('singer'),
    new \Morph\Pick('lastName'),
]);

$getSingerLastName($data);

'Bogan'

$data = [
    'first_name' => 'Ann',
    'last_name' => 'Bogan',
];

$upperKeys = new \Morph\TransformKeys('mb_strtoupper');

[
    'FIRST_NAME' => 'Ann',
    'LAST_NAME' => 'Bogan',
]

$data = [
    'first_name' => 'Ann',
    'last_name' => 'Bogan',
];

$upperKeys = new \Morph\TransformValues('mb_strtoupper');

[
    'first_name' => 'ANN',
    'last_name' => 'BOGAN',
]

class UserTransformer extends \Morph\MorphBase
{
    private $nameTransformer;
    private $defaultTransformer;

    public function __construct($nameTransformer, $defaultTransformer)
    {
        $this->nameTransformer = $nameTransformer;
        $this->defaultTransformer = $defaultTransformer;
    }

    public function __invoke(User $user): array
    {
        $data = $this->mapWithTransformer($this->defaultTransformer, [
            'group' => $user->getGroup(),
            'label' => $user->getLabel(),
        ];

        return [
            'name' => $this->useTransformerWith($this->nameTransformer, $user->getName()),
        ];
    }
}

class ModelDefiner extends \Morph\Sequence
{
    protected function getTransformers(): array
    {
        return [
            new \Morph\Merge([
                new \Morph\PublicProperties(),
                new \Morph\Getters(['get', 'is']),
            ]),
            new \Morph\LowerKeysFirstLetter(),
            new \Morph\TransformValues(static fn (\Morph\Reflection\Documented $property) => array_filter([
                'type' => $property->getTypeName(),
                'description' => $property->getDescription(),
            ])),
        ];
    }
}

class User
{
    public int $id;

    /**
     * First name(s) / Surname(s).
     *
     * Includes middle name(s).
     */
    public string $firstName;

    /**
     * Last (family) name(s).
     */
    public string $lastName;

    /**
     * Bank account number.
     */
    protected string $bankAccountNumber;

    /**
     * Login password.
     */
    private string $password;

    public function __construct(
        int $id,
        string $firstName,
        string $lastName,
        string $bankAccountNumber,
        string $password
    ) {
        $this->id = $id;
        $this->firstName = $firstName;
        $this->lastName = $lastName;
        $this->bankAccountNumber = $bankAccountNumber;
        $this->password = $password;
    }

    /**
     * Complete first and last name.
     */
    public function getName(): string
    {
        return $this->firstName . ' ' . $this->lastName;
    }

    public function isSafe(): bool
    {
        return strlen($this->password) >= 8;
    }
}

echo json_encode((new ModelDefiner())(User::class), JSON_PRETTY_PRINT);

function gen() {
    yield 1;
    yield 2;
    yield 3;
    yield 4;
    yield 5;
    yield 6;
}

var_dump(
    \Morph\Transformation::take(gen())
        ->filter(static fn (int $number) => $number !== 4)
        ->map(static fn (int $number) => [
            'number' => $number,
            'odd' => $number % 2 === 0,
        ])
        ->filter(key: 'odd')
        ->values()
        ->array()
        ->get()
);

function gen() {
    yield 1;
    yield 2;
}

echo (new \Morph\Iteration\CountIterable())(gen()); // 2

function gen() {
    yield 3;
    yield 2;
}

echo (new \Morph\Iteration\SumIterable())(gen()); // 5

function gen() {
    yield 'A' => 3;
    yield 'B' => 2;
}

foreach ((new \Morph\Iteration\ValuesIterable())(gen()) as $key => $value) {
    echo "$key: $value\n";
}

function gen() {
    yield 'A' => 3;
    yield 'B' => 2;
}

foreach ((new \Morph\Iteration\ValuesIterable())(gen()) as $key => $value) {
    echo "$key: $value\n";
}

function gen() {
    yield 'A' => 3;
    yield 'B' => 2;
}

foreach ((new \Morph\Iteration\FilterIterable(
    static fn (int $number) => $number % 2 === 0,
))(gen()) as $key => $value) {
    echo "$key: $value\n";
}

function gen() {
    yield 'A' => 3;
    yield 'B' => 2;
    yield 'A' => 5;
    yield 'B' => 3;
}

foreach ((new \Morph\Iteration\FlipIterable())(gen()) as $key => $value) {
    echo "$key: $value\n";
}

function gen() {
    yield 'A' => 3;
    yield 'B' => 2;
}

foreach ((new \Morph\Iteration\MapIterable(
    static fn (int $number) => $number * 2,
))(gen()) as $key => $value) {
    echo "$key: $value\n";
}

foreach ((new \Morph\Iteration\MapIterable(
    static fn (int $number, string $letter, string $x) => "$letter/$number/$x",
))(gen(), 'x') as $key => $value) {
    echo "$value\n";
}

function gen() {
    yield 3;
    yield 2;
    yield 6;
}

echo (new \Morph\Iteration\ReduceIterable(
    static fn ($carry, $item) => $carry * $item,
))(gen(), 1); // 36

array(2) {
  [0] =>
  array(2) {
    'number' =>
    int(2)
    'odd' =>
    bool(true)
  }
  [1] =>
  array(2) {
    'number' =>
    int(6)
    'odd' =>
    bool(true)
  }
}