vijoni/class-generator

generate similar classes based on YAML configuration

v1.0.3 2022-06-29 06:18 UTC

This package is auto-updated.

Last update: 2024-04-29 04:59:55 UTC


README

Create consistent behaving classes with common functionality

Generated source code sample

<?php

declare(strict_types=1);

namespace VijoniOutput\Integration\Security\Shared\Generated;

use Vijoni\ClassGenerator\ClassBase;

class GeneratedUser extends ClassBase
{
  private string $email = '';
  private \VijoniOutput\Integration\Security\Shared\Generated\GeneratedSecret $secret;
  private array $roles = [];

  public const EMAIL = 'email';
  public const SECRET = 'secret';
  public const ROLES = 'roles';

  public function __construct()
  {
      $this->setSecret(new \VijoniOutput\Integration\Security\Shared\Generated\GeneratedSecret());
  }

  public function getEmail(): string
  {
    return $this->email;
  }

  public function setEmail(string $email): void
  {
    $this->email = $email;
    $this->modified[self::EMAIL] = true;
  }

  public function getSecret(): \VijoniOutput\Integration\Security\Shared\Generated\GeneratedSecret
  {
    return $this->secret;
  }

  public function setSecret(\VijoniOutput\Integration\Security\Shared\Generated\GeneratedSecret $secret): void
  {
    $this->secret = $secret;
    $this->modified[self::SECRET] = true;
  }

  /**
   * @return \VijoniOutput\Integration\Security\Shared\Generated\GeneratedRole[]
   */
  public function getRoles(): array
  {
    return $this->roles;
  }

  public function setRoles(array $roles): void
  {
    $this->roles = $roles;
    $this->modified[self::ROLES] = true;
  }

  public function toArray(): array
  {
    return [
      self::EMAIL => $this->getEmail(),
      self::SECRET => $this->getSecret(),
      self::ROLES => $this->getRoles(),
    ];
  }

  public function toDeepArray(): array
  {
    $asArray = $this->toArray();
    $asArray[self::SECRET] = $this->getSecret()->toDeepArray();
    $asArray[self::ROLES] = $this->collectionToArray($this->getRoles());

    return $asArray;
  }

  public function fromArray(array $properties): void
  {
    isset($properties[self::EMAIL]) && $this->setEmail($properties[self::EMAIL]);
    isset($properties[self::SECRET]) && $this->setSecret($properties[self::SECRET]);
    isset($properties[self::ROLES]) && $this->setRoles($properties[self::ROLES]);
  }
}

Class definition sample in YAML

---
outputPath: _output/Integration/Security/Shared/Generated
namespace: VijoniOutput\Integration\Security\Shared\Generated
className: GeneratedUser

fields:
  email: string
  secret: \VijoniTest\Integration\Security\Shared\Generated\GeneratedSecret
  roles: \VijoniTest\Integration\Security\Shared\Generated\GeneratedRole[]

Usage

Check tests for more details

$srcDirectory = PROJECT_DIR . '/src'; // all file paths will be related to this directory

$classGenerator = new Generator($srcDirectory, new SchemaFinder());
$classGenerator->generate('class-schema-*.yml'); // glob pattern for class definition file names

The definition files will be looked for in /src and it's subdirectories.
Generator handles dependencies on other nested generated classes, so there is no need to worry about file paths loading order.
Classes will be generated according to the provided source path and the outputPath property defined per class definition.

Class definition syntax

Classes are defined using YAML language.

# location for generated class source code, relative to the directory provided when creating Generator instance
outputPath: _output/Acceptance/Shop/Shared/Generated/ 
namespace: VijoniOutput\Acceptance\Shop\Shared\Generated
className: GeneratedCustomer

# private fields for which accessor methods and array keys will be generated
# fields consist of a field name, type and optional default value
fields:
  id: string
  firstname: string
  lastname: string
  email: string
  birthDate: \DateTime
  age: int, 0
  address: \VijoniOutput\Acceptance\Shop\Shared\Generated\Address[]

# you can also define hardcoded constants, they can be useful for child classes
constants:
  DEFAULT_DATE: "'1900-01-01 00:00:00'"

Default values for primitive data types:

string' => '',
int' => -1,
float' => -1.0,
array' => [],
?xxx => null

The generator is using strict typing. For non nullable values you need to create a child class and overwrite the generated constructor. PHP requires property initialization for strict typed properties.

<?php

declare(strict_types=1);

namespace VijoniTest\Integration\ClassGenerator;

use DateTime;
use VijoniOutput\Integration\Shop\Shared\Generated\GeneratedCustomer;

class Customer extends GeneratedCustomer
{
  public function __construct()
  {
    $this->setBirthDate(new DateTime(static::DEFAULT_DATE));
    // as all setter methods are marking property as modified, your need to unset any modifications
    $this->resetModifiedValues();
  }
}

Generated class methods

toArray(): array

collectionToArray(array $collection): array

toDeepArray(): array

fromArray(array $properties): void

intersectArray(array $map, array $source): array

intersect(array $map, array $source): void

readModifiedValues(): array

resetModifiedValues(): void

mapTo(array $mapKeys): array

mapModifiedTo(array $mapKeys): array