Skip to content

Commit dd04e30

Browse files
authored
Merge pull request #24 from picamator/development
Release 2.1.2
2 parents 622620d + 774c715 commit dd04e30

32 files changed

Lines changed: 167 additions & 128 deletions

README.md

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,10 @@
88
Transfer Object Generator
99
==========================
1010

11-
Would you like to build Symfony-compatible Transfer Objects easily?
11+
Would you like to build Symfony-compatible Transfer Objects?
1212

1313
You're in the right place! 🎉
1414

15-
Build Transfer Object by Blueprint
16-
----------------------------------
17-
1815
Imagine you have a Rest API response:
1916

2017
```json
@@ -59,18 +56,33 @@ Key Features
5956

6057
**Symfony Compatability:**
6158

62-
* includes Symfony console commands: [TransferGeneratorCommand](/src/Command/TransferGeneratorCommand.php) and [DefinitionGeneratorCommand](/src/Command/DefinitionGeneratorCommand.php)
63-
* includes Symfony services: [TransferGeneratorFacade](/src/TransferGenerator/TransferGeneratorFacade.php) and [DefinitionGeneratorFacade](/src/DefinitionGenerator/DefinitionGeneratorFacade.php)
64-
* supports mapping Symfony request
59+
* includes Symfony console commands:
60+
* [TransferGeneratorCommand](/src/Command/TransferGeneratorCommand.php)
61+
* [DefinitionGeneratorCommand](/src/Command/DefinitionGeneratorCommand.php)
62+
* includes Symfony services:
63+
* [TransferGeneratorFacade](/src/TransferGenerator/TransferGeneratorFacade.php)
64+
* [DefinitionGeneratorFacade](/src/DefinitionGenerator/DefinitionGeneratorFacade.php)
65+
* supports Symfony request data mapping
6566

6667
**Transfer Object:**
67-
* implements methods: `fromArray()`, `toArray()`, and `toFilterArray()`
68-
* implements standard interfaces: `IteratorAggregate`, `JsonSerializable`, and `Countable`
69-
* supports embedded, collections Transfer Objects
70-
* supports PHP primitive data types
71-
* supports `BackedEnum`, `DateTime`, `DateTimeImmutable`, and `BcMath\Number`
72-
* supports asymmetric property visibility
73-
* integrates external Transfer Objects
68+
69+
* implements methods:
70+
* `fromArray()`
71+
* `toArray()`
72+
* `toFilterArray()`
73+
* implements standard interfaces:
74+
* `IteratorAggregate`
75+
* `JsonSerializable`
76+
* `Countable`
77+
* supports embedded and collection Transfer Objects
78+
* supports PHP primitive data types
79+
* supports:
80+
* `BackedEnum`
81+
* `DateTime`
82+
* `DateTimeImmutable`
83+
* `BcMath\Number`
84+
* supports asymmetric property visibility
85+
* integrates external Transfer Objects
7486

7587
Installation
7688
------------
@@ -81,18 +93,25 @@ Composer installation:
8193
$ composer require picamator/transfer-object
8294
```
8395

96+
Samples
97+
-------
98+
99+
* [Definition Generator](/doc/samples/try-definition-generator.php)
100+
* [Transfer Generator](/doc/samples/try-transfer-generator.php)
101+
* [Advanced Transfer Generator](/doc/samples/try-advanced-transfer-generator.php)
102+
84103
Usage Tests
85104
-----------
86105

87-
Definition Files and Transfer Object generators have been tested against API responses such as:
106+
Definition Files and Transfer Object generators have been tested against following APIs:
88107

89108
* [NASA Open Api](https://api.nasa.gov/neo/rest/v1/neo/2465633?api_key=DEMO_KEY)
90109
* [OpenWeather](https://openweathermap.org/current#example_JSON)
91110
* [Content API for Shopping](https://developers.google.com/shopping-content/guides/products/products-api?hl=en)
92111
* [Frankfurter is a free, open-source currency data API](https://api.frankfurter.dev/v1/latest)
93112
* [Tagesschau API](https://tagesschau.api.bund.dev)
94113

95-
### Test Scenario
114+
### Scenario
96115

97116
1. Rest API response is used as a blueprint to generate Definition Files
98117
2. Transfer Objects are generated based on Definition Files
@@ -104,16 +123,6 @@ In all cases, data **100%** are matched ✅.
104123

105124
For detailed information, please check [DefinitionGeneratorFacadeTest](/tests/integration/DefinitionGenerator/DefinitionGeneratorFacadeTest.php).
106125

107-
### Samples
108-
109-
- [Definition Generator](/doc/samples/try-definition-generator.php)
110-
- [Transfer Generator](/doc/samples/try-transfer-generator.php)
111-
- [Advanced Transfer Generator](/doc/samples/try-advanced-transfer-generator.php)
112-
113-
### Practice
114-
115-
Definition Files and Transfer Objects generators use [Transfer Objects](/src/Generated).
116-
117126
Acknowledgment
118127
--------------
119128

@@ -127,8 +136,8 @@ Follow the project to stay updated with all activities.
127136

128137
If you have suggestions for improvements or new features, feel free to:
129138

130-
- Create an issue
131-
- Submit a pull request
139+
* Create an issue
140+
* Submit a pull request
132141

133142
Here is a [Contribution Guide](CONTRIBUTING.md).
134143

bin/definition-generate

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ use Symfony\Component\Console\Application;
99
include $_composer_autoload_path ?? __DIR__ . '/../vendor/autoload.php';
1010

1111
$application = new Application(name:'TransferObject', version:'current');
12+
1213
$command = new DefinitionGeneratorCommand();
1314

1415
$application->add($command);
16+
$application->setDefaultCommand($command->getName(), isSingleCommand: true);
1517

16-
$application->setDefaultCommand($command->getName(), true);
1718
$application->run();

bin/transfer-generate

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ use Symfony\Component\Console\Application;
99
include $_composer_autoload_path ?? __DIR__ . '/../vendor/autoload.php';
1010

1111
$application = new Application(name:'TransferObject', version:'current');
12+
1213
$command = new TransferGeneratorCommand();
1314

1415
$application->add($command);
16+
$application->setDefaultCommand($command->getName(), isSingleCommand: true);
1517

16-
$application->setDefaultCommand($command->getName(), true);
1718
$application->run();

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
"squizlabs/php_codesniffer": "^3.11"
5454
},
5555
"suggest": {
56-
"ext-bcmath": "Required for supporting the `numberType` in Transfer Object Definition Files."
56+
"ext-bcmath": "Required for supporting BcMath Number."
5757
},
5858
"bin": [
5959
"bin/transfer-generate",

docker/sdk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ case $1 in
101101
$DOCKER_EXEC composer captainhook $2
102102
;;
103103
to-generate)
104-
$DOCKER_EXEC composer transfer-generate -- -c ./config/generator.config.yml
104+
$DOCKER_EXEC composer transfer-generate -- -c ./config/generator.config.yml -v
105105
;;
106106
df-generate)
107107
$DOCKER_EXEC composer definition-generate

src/Command/DefinitionGeneratorCommand.php

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Picamator\TransferObject\DefinitionGenerator\DefinitionGeneratorFacadeInterface;
1010
use Picamator\TransferObject\DefinitionGenerator\Generator\Builder\DefinitionGeneratorBuilderInterface;
1111
use Picamator\TransferObject\Generated\DefinitionGeneratorTransfer;
12+
use Symfony\Component\Console\Attribute\AsCommand;
1213
use Symfony\Component\Console\Command\Command;
1314
use Symfony\Component\Console\Helper\QuestionHelper;
1415
use Symfony\Component\Console\Input\InputInterface;
@@ -17,12 +18,14 @@
1718
use Symfony\Component\Console\Style\SymfonyStyle;
1819
use Throwable;
1920

21+
#[AsCommand(
22+
name: 'picamator:definition:generate',
23+
description: 'Generate Transfer Object definition files from a JSON blueprint.'
24+
)]
2025
class DefinitionGeneratorCommand extends Command
2126
{
2227
use InputNormalizerTrait;
2328

24-
private const string NAME = 'picamator:definition:generate';
25-
private const string DESCRIPTION = 'Generate Transfer Object definition files from a JSON blueprint.';
2629
private const string HELP = <<<'HELP'
2730
This command allows you to generate Transfer Object definition files based on a JSON file as a blueprint.
2831
@@ -51,12 +54,7 @@ public function __construct(
5154

5255
protected function configure(): void
5356
{
54-
if ($this->getName() === null) {
55-
$this->setName(name: self::NAME);
56-
}
57-
58-
$this->setDescription(description: self::DESCRIPTION)
59-
->setHelp(help: self::HELP);
57+
$this->setHelp(help: self::HELP);
6058
}
6159

6260
protected function execute(InputInterface $input, OutputInterface $output): int

src/Command/TransferGeneratorCommand.php

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,21 @@
88
use Picamator\TransferObject\Generated\TransferGeneratorTransfer;
99
use Picamator\TransferObject\TransferGenerator\TransferGeneratorFacade;
1010
use Picamator\TransferObject\TransferGenerator\TransferGeneratorFacadeInterface;
11+
use Symfony\Component\Console\Attribute\AsCommand;
1112
use Symfony\Component\Console\Command\Command;
1213
use Symfony\Component\Console\Input\InputInterface;
1314
use Symfony\Component\Console\Input\InputOption;
1415
use Symfony\Component\Console\Output\OutputInterface;
1516
use Symfony\Component\Console\Style\SymfonyStyle;
1617

18+
#[AsCommand(
19+
name: 'picamator:definition:generate',
20+
description: 'Generate Transfer Objects from definition templates.'
21+
)]
1722
class TransferGeneratorCommand extends Command
1823
{
1924
use InputNormalizerTrait;
2025

21-
private const string NAME = 'picamator:transfer:generate';
22-
private const string DESCRIPTION = 'Generate Transfer Objects from definition templates.';
2326
private const string HELP = <<<'HELP'
2427
This command generates Transfer Objects based on YML definitions.
2528
The command requires a path to the configuration file in YML format.
@@ -40,8 +43,10 @@ class TransferGeneratorCommand extends Command
4043
The required -c option is missing. Please provide the path to the YML configuration file.
4144
MESSAGE;
4245

43-
private const string TRANSFER_OBJECT_MESSAGE_TEMPLATE = 'Processing Transfer Object: "%s".';
44-
private const string DEFINITION_MESSAGE_TEMPLATE = 'Using definition file: "%s".';
46+
private const string TRANSFER_OBJECT_MESSAGE_TEMPLATE = 'Processing Transfer Object: <info>%s</info>.';
47+
private const string DEFINITION_MESSAGE_TEMPLATE = 'Using Definition File: <comment>%s</comment>.';
48+
49+
private const string DEBUG_MESSAGE_TEMPLATE = '<comment>%s</comment>: <info>%s</info>';
4550

4651
private const string SUCCESS_MESSAGE = 'All Transfer Objects were generated successfully! 🎉';
4752

@@ -54,12 +59,7 @@ public function __construct(
5459

5560
protected function configure(): void
5661
{
57-
if ($this->getName() === null) {
58-
$this->setName(name:self::NAME);
59-
}
60-
61-
$this->setDescription(description: self::DESCRIPTION)
62-
->setHelp(help: self::HELP);
62+
$this->setHelp(help: self::HELP);
6363

6464
$this->addOption(
6565
name: self::OPTION_NAME_CONFIGURATION,
@@ -93,30 +93,67 @@ private function generateTransfers(string $configPath, SymfonyStyle $styleOutput
9393
$generatorFiber = $this->generatorFacade->getTransferGeneratorFiber();
9494

9595
$generatorTransfer = $generatorFiber->start($configPath);
96-
$this->writelnGeneratorError($generatorTransfer, $styleOutput);
96+
97+
$this->writelnErrorMessages($generatorTransfer, $styleOutput);
98+
$this->writelnDebugMessages($generatorTransfer, $styleOutput);
9799

98100
while (!$generatorFiber->isTerminated()) {
99101
$generatorTransfer = $generatorFiber->resume();
100-
$this->writelnGeneratorError($generatorTransfer, $styleOutput);
102+
103+
$this->writelnErrorMessages($generatorTransfer, $styleOutput);
104+
$this->writelnDebugMessages($generatorTransfer, $styleOutput);
101105
}
102106

103107
return $generatorFiber->getReturn();
104108
}
105109

106-
private function writelnGeneratorError(
110+
private function writelnDebugMessages(
111+
?TransferGeneratorTransfer $generatorTransfer,
112+
SymfonyStyle $styleOutput,
113+
): void {
114+
if (
115+
!$styleOutput->isVerbose()
116+
|| $generatorTransfer === null
117+
|| $generatorTransfer->validator->isValid === false
118+
|| $generatorTransfer->fileName === null
119+
|| $generatorTransfer->className === null
120+
) {
121+
return;
122+
}
123+
124+
static $fileName = $generatorTransfer->fileName;
125+
126+
if ($fileName !== $generatorTransfer->fileName) {
127+
$fileName = $generatorTransfer->fileName;
128+
129+
$styleOutput->newLine();
130+
}
131+
132+
$styleOutput->writeln(
133+
sprintf(
134+
self::DEBUG_MESSAGE_TEMPLATE,
135+
$generatorTransfer->fileName,
136+
$generatorTransfer->className,
137+
)
138+
);
139+
}
140+
141+
private function writelnErrorMessages(
107142
?TransferGeneratorTransfer $generatorTransfer,
108143
SymfonyStyle $styleOutput,
109144
): void {
110145
if ($generatorTransfer === null || $generatorTransfer->validator->isValid === true) {
111146
return;
112147
}
113148

114-
if ($generatorTransfer->className !== null) {
115-
$styleOutput->info(sprintf(self::TRANSFER_OBJECT_MESSAGE_TEMPLATE, $generatorTransfer->className));
149+
$className = $generatorTransfer->className ?? '';
150+
if ($className !== '') {
151+
$styleOutput->writeln(sprintf(self::TRANSFER_OBJECT_MESSAGE_TEMPLATE, $className));
116152
}
117153

118-
if ($generatorTransfer->fileName !== null) {
119-
$styleOutput->info(sprintf(self::DEFINITION_MESSAGE_TEMPLATE, $generatorTransfer->fileName));
154+
$fileName = $generatorTransfer->fileName ?? '';
155+
if ($fileName !== '') {
156+
$styleOutput->writeln(sprintf(self::DEFINITION_MESSAGE_TEMPLATE, $fileName));
120157
}
121158

122159
foreach ($generatorTransfer->validator->errorMessages as $errorMessage) {

src/DefinitionGenerator/Exception/DefinitionGeneratorException.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
namespace Picamator\TransferObject\DefinitionGenerator\Exception;
66

7-
use Exception;
87
use Picamator\TransferObject\Shared\Exception\TransferExceptionInterface;
8+
use RuntimeException;
99

10-
class DefinitionGeneratorException extends Exception implements TransferExceptionInterface
10+
class DefinitionGeneratorException extends RuntimeException implements TransferExceptionInterface
1111
{
1212
}

src/Dependency/DependencyContainer.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace Picamator\TransferObject\Dependency;
66

7-
use Picamator\TransferObject\Dependency\Exception\DependencyNotFoundException;
7+
use Picamator\TransferObject\Dependency\Exception\ServiceNotFoundException;
88
use Picamator\TransferObject\Dependency\Filesystem\FilesystemBridge;
99
use Picamator\TransferObject\Dependency\Finder\FinderBridge;
1010
use Picamator\TransferObject\Dependency\YmlParser\YmlParserBridge;
@@ -30,16 +30,17 @@ class DependencyContainer implements ContainerInterface
3030
protected static array $container = [];
3131

3232
/**
33-
* @uses static::createYmlParser()
33+
*
3434
* @uses static::createFinder()
3535
* @uses static::createFileSystem()
36+
* @uses static::createYmlParser()
3637
*
37-
* @throws \Picamator\TransferObject\Dependency\Exception\DependencyNotFoundException
38+
* @throws \Picamator\TransferObject\Dependency\Exception\ServiceNotFoundException
3839
*/
3940
public function get(string $id): mixed
4041
{
4142
if (!$this->has($id)) {
42-
throw new DependencyNotFoundException(
43+
throw new ServiceNotFoundException(
4344
sprintf('Dependency "%s" not found.', $id),
4445
);
4546
}

src/Dependency/DependencyFactoryTrait.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@
1111
trait DependencyFactoryTrait
1212
{
1313
/**
14-
* @throws \Picamator\TransferObject\Dependency\Exception\DependencyNotFoundException
14+
* @throws \Picamator\TransferObject\Dependency\Exception\ServiceNotFoundException
1515
*/
1616
final protected function getDependency(string $id): mixed
1717
{
1818
return new DependencyContainer()->get($id);
1919
}
2020

2121
/**
22-
* @throws \Picamator\TransferObject\Dependency\Exception\DependencyNotFoundException
22+
* @throws \Picamator\TransferObject\Dependency\Exception\ServiceNotFoundException
2323
*/
2424
final protected function getFilesystem(): FilesystemInterface
2525
{
@@ -30,7 +30,7 @@ final protected function getFilesystem(): FilesystemInterface
3030
}
3131

3232
/**
33-
* @throws \Picamator\TransferObject\Dependency\Exception\DependencyNotFoundException
33+
* @throws \Picamator\TransferObject\Dependency\Exception\ServiceNotFoundException
3434
*/
3535
final protected function getFinder(): FinderInterface
3636
{
@@ -41,7 +41,7 @@ final protected function getFinder(): FinderInterface
4141
}
4242

4343
/**
44-
* @throws \Picamator\TransferObject\Dependency\Exception\DependencyNotFoundException
44+
* @throws \Picamator\TransferObject\Dependency\Exception\ServiceNotFoundException
4545
*/
4646
final protected function getYmlParser(): YmlParserInterface
4747
{

0 commit comments

Comments
 (0)