Skip to content

Instantly share code, notes, and snippets.

@genxoft
Last active July 18, 2022 17:13

Revisions

  1. genxoft revised this gist Jul 18, 2022. No changes.
  2. genxoft created this gist Jul 18, 2022.
    72 changes: 72 additions & 0 deletions JsonSerializableTrait.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,72 @@
    <?php

    declare(strict_types=1);

    use RuntimeException;
    use ReflectionClass;
    use ReflectionProperty;

    /**
    * Model to json serrializaton helper
    */
    trait JsonSerializableTrait
    {

    /**
    * @return array|null
    */
    public function fields(): ?array
    {
    return null;
    }

    /**
    * @see \JsonSerializable
    */
    public function jsonSerialize(): array
    {
    $fields = $this->fields();
    $props = [];
    if ($fields !== null) {
    foreach ($fields as $attribute => $callable) {
    if (!is_string($attribute)) {
    if (!$this->canGetProperty($callable)) {
    throw new RuntimeException("Property $callable is undefined");
    }
    $props[$callable] = $this->$callable;
    continue;
    }
    if (is_string($callable)) {
    if (!$this->canGetProperty($callable)) {
    throw new RuntimeException("Property $callable is undefined");
    }
    $props[$attribute] = $this->$callable;
    } else if (is_callable($callable)) {
    $props[$attribute] = ($callable)();
    } else {
    throw new RuntimeException("Property $callable is undefined");
    }
    }
    } else {
    $reflect = new ReflectionClass($this);
    $properties = $reflect->getProperties(ReflectionProperty::IS_PUBLIC);
    foreach ($properties as $property) {
    $props[$property->getName()] = $this->{$property->getName()};
    }
    }
    return $props;
    }

    /**
    * @param string $property
    * @return bool
    */
    public function canGetProperty(string $property): bool
    {
    if (isset($this->$property)) {
    return true;
    }

    return false;
    }
    }
    27 changes: 27 additions & 0 deletions Model.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,27 @@
    <?php

    declare(strict_types=1);

    class Model
    {
    use JsonSerializableTrait;

    const STATUSES = ['pass', 'warn', 'fail'];

    public string $title = "Default title";

    public string $shortDescription = "Some description";

    private int $status = 0;

    public function fields(): array
    {
    return [
    'title',
    'short_description' => 'shortDescription',
    'status' => function () {
    return self::STATUSES[$this->status];
    },
    ];
    }
    }
    5 changes: 5 additions & 0 deletions result.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,5 @@
    {
    "title": "Default title",
    "short_description": "Some description",
    "status": "pass"
    }