Skip to content

Commit

Permalink
feat: TryProperty command, or rekalogika:mapper:tryproperty in co…
Browse files Browse the repository at this point in the history
…nsole.
  • Loading branch information
priyadi committed Jan 13, 2024
1 parent 0962c05 commit 0f66736
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* fix: PropertyAccessor `UninitializedPropertyException` error now is regarded
as null.
* fix: Transformer `SearchResult` was not properly ordered.
* feat: `TryProperty` command, or `rekalogika:mapper:tryproperty` in console.

## 0.5.7

Expand Down
115 changes: 115 additions & 0 deletions src/Command/TryPropertyCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?php

declare(strict_types=1);

/*
* This file is part of rekalogika/mapper package.
*
* (c) Priyadi Iman Nurcahyo <https://rekalogika.dev>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Rekalogika\Mapper\Command;

use Rekalogika\Mapper\Transformer\Contracts\MixedType;
use Rekalogika\Mapper\TransformerRegistry\TransformerRegistryInterface;
use Rekalogika\Mapper\TypeResolver\TypeResolverInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\PropertyInfo\PropertyInfoExtractorInterface;

#[AsCommand(name: 'rekalogika:mapper:tryproperty', description: 'Gets the mapping result by providing the class and property name of the source and target.')]
class TryPropertyCommand extends Command
{
public function __construct(
private TransformerRegistryInterface $transformerRegistry,
private TypeResolverInterface $typeResolver,
private PropertyInfoExtractorInterface $propertyInfoExtractor,
) {
parent::__construct();
}

protected function configure(): void
{
$this
->addArgument('sourceClass', InputArgument::REQUIRED, 'The source class')
->addArgument('sourceProperty', InputArgument::REQUIRED, 'The source property')
->addArgument('targetClass', InputArgument::REQUIRED, 'The target class')
->addArgument('targetProperty', InputArgument::REQUIRED, 'The target property')
->setHelp("The <info>%command.name%</info> displays the mapping result by providing the class and property name of the source and target.");
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$rows = [];

//
// source type
//

/** @var string */
$sourceClass = $input->getArgument('sourceClass');
/** @var string */
$sourceProperty = $input->getArgument('sourceProperty');
/** @var string */
$targetClass = $input->getArgument('targetClass');
/** @var string */
$targetProperty = $input->getArgument('targetProperty');

$sourceTypes = $this->propertyInfoExtractor
->getTypes($sourceClass, $sourceProperty);

if ($sourceTypes === null || count($sourceTypes) === 0) {
$sourceTypes = [MixedType::instance()];
}

$targetTypes = $this->propertyInfoExtractor
->getTypes($targetClass, $targetProperty);

if ($targetTypes === null || count($targetTypes) === 0) {
$targetTypes = [MixedType::instance()];
}


$results = $this->transformerRegistry
->findBySourceAndTargetTypes($sourceTypes, $targetTypes);

foreach ($results as $result) {
$rows[] = [
$result->getMappingOrder(),
$this->typeResolver->getTypeString($result->getSourceType()),
$this->typeResolver->getTypeString($result->getTargetType()),
$result->getTransformer()::class,
];
}

//
// render
//

$io->section('<info>Applicable Transformers</info>');

if (count($rows) === 0) {
$io->error('No applicable transformers found.');

return Command::SUCCESS;
}

$table = new Table($output);
$table->setVertical();
$table->setHeaders(['Mapping Order', 'Source Type', 'Target Type', 'Transformer']);
$table->setStyle('box');
$table->setRows($rows);
$table->render();

return Command::SUCCESS;
}
}
16 changes: 16 additions & 0 deletions src/MapperFactory/MapperFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Psr\Container\ContainerInterface;
use Rekalogika\Mapper\Command\MappingCommand;
use Rekalogika\Mapper\Command\TryCommand;
use Rekalogika\Mapper\Command\TryPropertyCommand;
use Rekalogika\Mapper\MainTransformer\MainTransformer;
use Rekalogika\Mapper\Mapper;
use Rekalogika\Mapper\MapperInterface;
Expand Down Expand Up @@ -102,6 +103,7 @@ class MapperFactory

private ?MappingCommand $mappingCommand = null;
private ?TryCommand $tryCommand = null;
private ?TryPropertyCommand $tryPropertyCommand = null;
private ?Application $application = null;

/**
Expand Down Expand Up @@ -527,12 +529,26 @@ protected function getTryCommand(): TryCommand
return $this->tryCommand;
}

protected function getTryPropertyCommand(): TryPropertyCommand
{
if (null === $this->tryPropertyCommand) {
$this->tryPropertyCommand = new TryPropertyCommand(
$this->getTransformerRegistry(),
$this->getTypeResolver(),
$this->getPropertyInfoExtractor(),
);
}

return $this->tryPropertyCommand;
}

public function getApplication(): Application
{
if (null === $this->application) {
$this->application = new Application();
$this->application->add($this->getMappingCommand());
$this->application->add($this->getTryCommand());
$this->application->add($this->getTryPropertyCommand());
}

return $this->application;
Expand Down

0 comments on commit 0f66736

Please sign in to comment.