Skip to content

Commit

Permalink
Refactored the attributes to use there own handler classes
Browse files Browse the repository at this point in the history
  • Loading branch information
WeTurkstra committed Apr 8, 2024
1 parent f076519 commit c9139a6
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 20 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
},
"scripts": {
"test": "vendor/bin/pest",
"analyse": "vendor/bin/phpstan analyse src --level=9"
"analyse": "vendor/bin/phpstan analyse src --level=9",
"tmp": "php tmp.php"
}
}
8 changes: 8 additions & 0 deletions src/Attribute/AttributeHandlerInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Tibisoft\AutoTransformer\Attribute;

interface AttributeHandlerInterface
{
public function handle(BaseAttribute $attribute, \ReflectionClass $reflectionFrom, \ReflectionProperty $property, object $to, object $from): void;
}
11 changes: 11 additions & 0 deletions src/Attribute/BaseAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Tibisoft\AutoTransformer\Attribute;

abstract class BaseAttribute
{
public function isHandledBy(): string
{
return static::class . 'Handler';
}
}
2 changes: 1 addition & 1 deletion src/Attribute/Count.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Tibisoft\AutoTransformer\Attribute;

#[\Attribute(\Attribute::TARGET_PROPERTY)]
class Count
class Count extends BaseAttribute
{

}
17 changes: 17 additions & 0 deletions src/Attribute/CountHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace Tibisoft\AutoTransformer\Attribute;

class CountHandler implements AttributeHandlerInterface
{
public function handle(BaseAttribute $attribute, \ReflectionClass $reflectionFrom, \ReflectionProperty $property, object $to, object $from): void
{
$propertyFrom = $reflectionFrom->getProperty($property->getName());
$value = $propertyFrom->getValue($from);
if(is_countable($value)) {
$property->setValue($to, count($value));
} else {
$property->setValue($to, 0);
}
}
}
2 changes: 1 addition & 1 deletion src/Attribute/Synonyms.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use Assert\Assertion;

#[\Attribute(\Attribute::TARGET_PROPERTY)]
class Synonyms
class Synonyms extends BaseAttribute
{
/**
* @param array<int, string> $synonyms
Expand Down
45 changes: 45 additions & 0 deletions src/Attribute/SynonymsHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace Tibisoft\AutoTransformer\Attribute;

use Tibisoft\AutoTransformer\Exception\TransformException;

class SynonymsHandler implements AttributeHandlerInterface
{
public function handle(BaseAttribute $attribute, \ReflectionClass $reflectionFrom, \ReflectionProperty $property, object $to, object $from): void
{
if(!($attribute instanceof Synonyms)) {
return;
}

//find the first match!
foreach ($attribute->synonyms as $synonym) {
$this->setPropertyValue($reflectionFrom, $property, $to, $from, $synonym);
}
}

/**
* @param \ReflectionClass $reflectionFrom
* @param \ReflectionProperty $property
* @param object $to
* @param object $from
* @param string $propertyName
*
* @return void
*/
public function setPropertyValue(\ReflectionClass $reflectionFrom, \ReflectionProperty $property, object $to, object $from, string $propertyName = ''): void
{
$propertyName = ($propertyName === '') ? $property->getName() : $propertyName;

try {
if (!$reflectionFrom->hasProperty($propertyName)) {
return;
}

$propertyFrom = $reflectionFrom->getProperty($propertyName);
$property->setValue($to, $propertyFrom->getValue($from));
} catch (\ReflectionException|\TypeError $typeError) {
throw new TransformException($typeError->getMessage());
}
}
}
35 changes: 18 additions & 17 deletions src/AutoTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Tibisoft\AutoTransformer;

use Tibisoft\AutoTransformer\Attribute\AttributeHandlerInterface;
use Tibisoft\AutoTransformer\Attribute\BaseAttribute;
use Tibisoft\AutoTransformer\Attribute\Count;
use Tibisoft\AutoTransformer\Attribute\Synonyms;
use Tibisoft\AutoTransformer\Exception\TransformException;
Expand All @@ -16,25 +18,23 @@ public function transform(object $from, string $to): object

foreach ($reflectionTo->getProperties() as $property) {
//look for attribute
$attributes = $property->getAttributes(Synonyms::class);
if (count($attributes) > 0) {
//find the first match!
foreach ($attributes[0]->getArguments()[0] as $synonym) {
$this->setPropertyValue($reflectionFrom, $property, $to, $from, $synonym);
continue 2;
}
}
$attributes = $property->getAttributes();

$attributes = $property->getAttributes(Count::class);
if (count($attributes) > 0) {
$propertyFrom = $reflectionFrom->getProperty($property->getName());
$value = $propertyFrom->getValue($from);
if(is_countable($value)) {
$property->setValue($to, count($value));
} else {
$property->setValue($to, 0);
var_dump($attributes);

/** @var \ReflectionAttribute $attribute */
foreach($attributes as $attribute) {
$attribute = $attribute->newInstance();
if(!($attribute instanceof BaseAttribute)) {
continue;
}
if (class_exists($attribute->isHandledBy())) {
/** @var AttributeHandlerInterface $handler */
$handler = $attribute->isHandledBy();
$handler = new $handler();
$handler->handle($attribute, $reflectionFrom, $property, $to, $from);
continue 2;
}
continue;
}

//do default
Expand All @@ -49,6 +49,7 @@ public function transform(object $from, string $to): object
* @param \ReflectionProperty $property
* @param object $to
* @param object $from
* @param string $propertyName
*
* @return void
*/
Expand Down
25 changes: 25 additions & 0 deletions tmp.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php
require 'vendor/autoload.php';

class User {
public function __construct(
private string $email,
private array $comments) {
}
}

class UserDTO {
public function __construct(
private string $email,
#[\Tibisoft\AutoTransformer\Attribute\Count]
private int $comments) {
}
}

$user = new User('[email protected]', ['Comment #1', 'Comment #2', 'Comment #3', 'Comment #4']);

$transformer = new \Tibisoft\AutoTransformer\AutoTransformer();
$userDTO = $transformer->transform($user, UserDTO::class);

var_dump($userDTO);
exit;

0 comments on commit c9139a6

Please sign in to comment.