Skip to content

Commit

Permalink
php 7.4 support add ability to generate typed properties (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
dakorpar authored Feb 21, 2020
1 parent 9fd1dc2 commit dc06556
Show file tree
Hide file tree
Showing 7 changed files with 232 additions and 15 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ php:
- 7.1
- 7.2
- 7.3
- 7.4

install:
- travis_retry composer install --no-progress --prefer-dist
Expand Down Expand Up @@ -46,4 +47,4 @@ sudo: false

cache:
directories:
- $HOME/.composer/cache
- $HOME/.composer/cache
139 changes: 137 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@


## Entity generator
Typed entity generator from database. It can generate entities for whole database, table/view and from query
Highly customizable (typed) entity generator from database. It can generate entities for whole database, table/view and from raw SQL query

-----
[![Latest Stable Version](https://poser.pugx.org/dodo-it/entity-generator/v/stable)](https://packagist.org/packages/dodo-it/entity-generator)
Expand All @@ -14,8 +14,11 @@ Typed entity generator from database. It can generate entities for whole databas
## Installation

$ composer require dodo-it/entity-generator
## Entity support
- PHP 7.4 typed entities

## USAGE:
## How to run:
```php
$config = new \DodoIt\EntityGenerator\Generator\Config([
'path' => __DIR__ . '/Entities',
'extends' => \Examples\Pdo\Entities\Entity::class,
Expand All @@ -27,9 +30,141 @@ Typed entity generator from database. It can generate entities for whole databas
$generatorFactory = new \DodoIt\EntityGenerator\Factory\GeneratorPdoFactory($pdo);
$generator = $generatorFactory->create($config);
$generator->generate();
```

## What kind of entities can I get:
Tool is highly customizable and can generate various different entity types of which most interesting are:

- PHP 7.4 typed properties
```php

```
- properties with phpdoc
```php
class ArticleEntity extends YourBaseEntity
{

/** @var int */
protected $id;

/** @var string */
protected $title;

/** @var bool */
protected $published;

/** @var \DateTimeInterface */
protected $created_at;
}
```

- properties with getters and setters (methods body is customizable)

```php
class ArticleEntity extends YourBaseEntity
{

public function getId(): int
{
return $this->id;
}


public function setId(int $value): self
{
$this['id'] = $value;
return $this;
}


public function getTitle(): ?string
{
return $this->title;
}


public function setTitle(?string $value): self
{
$this['title'] = $value;
return $this;
}


public function getPublished(): bool
{
return $this->published;
}


public function setPublished(bool $value): self
{
$this['published'] = $value;
return $this;
}


public function getCreatedAt(): ?\DateTimeInterface
{
return $this->created_at;
}


public function setCreatedAt(?\DateTimeInterface $value): self
{
$this['created_at'] = $value;
return $this;
}
```

- phpdoc properties

```php
/**
* @property int $id
* @property string $title
* @property int $published
* @property \DateTimeInterface $created_at
*/
class ArticleEntity extends YourBaseEntity
{
}
```

- properties with phpdoc
```php
class ArticleEntity extends YourBaseEntity
{
/** @var int */
public $id;

/** @var string */
public $title;

/** @var bool */
public $published;

/** @var \DateTimeInterface */
public $created_at;

```

- it can generate column constants (use generateColumnConstants option)

```php
class ArticleEntity extends YourBaseEntity
{
public const TABLE_NAME = 'articles';
public const ID = 'id';
public const TITLE = 'title';
public const PUBLISHED = 'published';
public const CREATED_AT = 'created_at';

.
.
.

```
- and much more, check src/Generator/Config.php for list of all options
see example folder


Expand Down
3 changes: 1 addition & 2 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
includes:
- temp/phpstan/vendor/phpstan/phpstan-deprecation-rules/rules.neon
- temp/phpstan/vendor/phpstan/phpstan-nette/extension.neon
- temp/phpstan/vendor/phpstan/phpstan-nette/rules.neon
- temp/phpstan/vendor/phpstan/phpstan-strict-rules/rules.neon

parameters:
ignoreErrors:
- '#Variable property access on \$[a-zA-Z0-9_]+#'
- '#Variable property access on \$[a-zA-Z0-9_]+#'
15 changes: 15 additions & 0 deletions src/Generator/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ public function __construct(?array $config = null)
*/
public $suffix = 'Entity';

/**
* @var bool
*/
public $addDeclareStrictTypes = false;

/**
* @var string
*/
Expand Down Expand Up @@ -132,6 +137,16 @@ public function __construct(?array $config = null)
*/
public $generateProperties = true;

/**
* @var bool
*/
public $strictlyTypedProperties = false;

/**
* @var bool
*/
public $addPropertyVarComment = true;

/**
* @var string
*/
Expand Down
32 changes: 28 additions & 4 deletions src/Generator/Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use DodoIt\EntityGenerator\Entity\Column;
use DodoIt\EntityGenerator\Repository\IRepository;
use Exception;
use Nette\NotSupportedException;
use Nette\PhpGenerator\ClassType;
use Nette\PhpGenerator\PhpFile;
use Nette\SmartObject;
Expand Down Expand Up @@ -61,6 +62,14 @@ public function generate(?string $table = null, ?string $query = null): void
public function generateEntity(string $table): void
{
$file = new PhpFile();
if ($this->config->addDeclareStrictTypes) {
if (!method_exists($file, 'setStrictTypes')) {
throw new NotSupportedException('You have set addDeclareStrictTypes but have phpgenerator dependency <3.2.0!');
} else {
$file->setStrictTypes($this->config->addDeclareStrictTypes);
}
}

$namespace = $file->addNamespace($this->config->namespace);

$shortClassName = $this->getClassName($table);
Expand All @@ -74,7 +83,10 @@ public function generateEntity(string $table): void
$phpDocProperties = Helper::getPhpDocComments($entity->getComment() ?? '');
}

$entity->addConstant($this->config->tableConstant, $table)->setVisibility('public');
if ($this->config->tableConstant !== null) {
$entity->addConstant($this->config->tableConstant, $table)->setVisibility('public');
}

$entity->setExtends($this->config->extends);

$columns = $this->repository->getTableColumns($table);
Expand Down Expand Up @@ -127,9 +139,21 @@ protected function generateColumn(ClassType $entity, Column $column): void
$type = $this->getColumnType($column);

if ($this->config->generateProperties) {
$entity->addProperty($column->getField())
->setVisibility($this->config->propertyVisibility)
->addComment('@var ' . $type);
$property = $entity->addProperty($column->getField())
->setVisibility($this->config->propertyVisibility);

if ($this->config->addPropertyVarComment) {
$property->addComment('@var ' . $type);
}

if ($this->config->strictlyTypedProperties) {
if (!method_exists($property, 'setType')) {
throw new NotSupportedException('You have set strictlyTypedProperties but have phpgenerator dependency <3.3.0!');
} else {
$property->setType($type);
$property->setNullable($column->isNullable());
}
}
}

if ($this->config->generatePhpDocProperties) {
Expand Down
47 changes: 43 additions & 4 deletions tests/Generator/GeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
use DodoIt\EntityGenerator\Generator\Config;
use DodoIt\EntityGenerator\Generator\Generator;
use DodoIt\EntityGenerator\Repository\IRepository;
use Nette\NotSupportedException;
use Nette\PhpGenerator\ClassType;
use Nette\PhpGenerator\PhpFile;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

Expand Down Expand Up @@ -136,7 +138,7 @@ public function testGenerateEntity_WithMappingAndPhpDocProperties_ShouldGenerate

public function testGenerateEntity_WithGenerateConstant_ShouldGenerateConstants()
{
//we've put published as integer intentionally in PhpDocPropertyEntity so if we don't rewrite this should stay int and not become bool
//we've put published as integer intentionally in PhpDocPropertyEntity so if we don't rewrite this should stay int and not become bool
$this->config->generatePhpDocProperties = false;
$this->config->generateProperties = false;
$this->config->primaryKeyConstant = 'PK_CONSTANT';
Expand All @@ -149,9 +151,9 @@ public function testGenerateEntity_WithGenerateConstant_ShouldGenerateConstants(
include $entityFile;

$entityContents = file_get_contents($entityFile);
$this->assertStringContainsString('const TABLE_NAME = \'constants\'', $entityContents);
$this->assertStringContainsString('const PK_CONSTANT = \'id\'', $entityContents);
$this->assertStringContainsString('const ID = \'id\'', $entityContents);
$this->assertRegExp('/const TABLE\_NAME \= \'constants\'/', $entityContents);
$this->assertRegExp('/const PK\_CONSTANT \= \'id\'/', $entityContents);
$this->assertRegExp('/const ID \= \'id\'/', $entityContents);
unlink($entityFile);
}

Expand Down Expand Up @@ -199,4 +201,41 @@ public function testGenerate_WithQuery_ShouldGenerateEntityFromQuery()
unlink($entityFile);
}

public function testGenerateEntity_WithStrictlyTypedProperties_ShouldGenerateStrictlyTypedProperties()
{
//we've put published as integer intentionally in PhpDocPropertyEntity so if we don't rewrite this should stay int and not become bool
$this->config->generatePhpDocProperties = false;
$this->config->generateProperties = true;
$this->config->generateGetters = false;
$this->config->addDeclareStrictTypes = true;
$this->config->strictlyTypedProperties = true;
$this->config->tableConstant = null;
$this->config->propertyVisibility = 'public';
$this->config->generateColumnConstant = false;
$this->config->addPropertyVarComment = false;
$this->config->generateSetters = false;
$this->config->path = __DIR__ . '/../TestEntities';
$file = new PhpFile();
if (!method_exists($file, 'setStrictTypes')) {
$this->expectException(NotSupportedException::class);
$this->generator->generateEntity('strictly_typed');
return;
}

$this->repository->expects($this->once())->method('getTableColumns')
->with('strictly_typed')->willReturn($this->tableColumns);

$entityFile = $this->config->path . '/StrictlyTypedEntity.php';

$this->generator->generateEntity('strictly_typed');

$entityContents = file_get_contents($entityFile);
$this->assertRegExp('/declare\(strict_types/', $entityContents);
$this->assertRegExp('/public int \$id;/', $entityContents);
$this->assertRegExp('/public \?string \$title;/', $entityContents);
$this->assertRegExp('/public bool \$published;/', $entityContents);
$this->assertRegExp('/public \?\\\DateTimeInterface \$created\_at;/', $entityContents);
unlink($entityFile);
}

}
8 changes: 6 additions & 2 deletions tests/TestEntities/PhpDocPropertyEntity.php
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
<?php
<?php declare(strict_types = 1);

namespace DodoIt\EntityGenerator\Tests\TestEntities;

use DodoIt\EntityGenerator\Entity\Entity;

/**
* @property int $id
* @property string $title
* @property int $published
* @property \DateTimeInterface $created_at
*/
class PhpDocPropertyEntity extends \DodoIt\EntityGenerator\Entity\Entity
class PhpDocPropertyEntity extends Entity
{

public const TABLE_NAME = 'php_doc_properties';

public function getId(): int
Expand Down Expand Up @@ -62,4 +65,5 @@ public function setCreatedAt(?\DateTimeInterface $value): self
$this['created_at'] = $value;
return $this;
}

}

0 comments on commit dc06556

Please sign in to comment.