Skip to content

Commit

Permalink
Skipped properties work independently of MappedObject
Browse files Browse the repository at this point in the history
  • Loading branch information
mabar committed Jan 1, 2023
1 parent c502eb5 commit b013c9d
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 38 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"require": {
"php": ">=7.4.0 <8.3.0",
"ext-mbstring": "*",
"benmorel/weakmap-polyfill": "^0.3.0",
"nette/robot-loader": "^3.4.0",
"nette/utils": "^3.1.0",
"orisai/exceptions": "^1.0.0",
Expand Down
32 changes: 0 additions & 32 deletions src/MappedObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

use Nette\Utils\ObjectHelpers;
use Orisai\Exceptions\Logic\InvalidState;
use Orisai\ObjectMapper\Context\SkippedPropertiesContext;
use Orisai\ObjectMapper\Processing\Options;
use ReflectionException;
use ReflectionProperty;
Expand All @@ -16,42 +15,11 @@
abstract class MappedObject
{

private ?SkippedPropertiesContext $skippedPropertiesContext = null;

private bool $hasRawValues = false;

/** @var mixed */
private $rawValues;

/**
* @internal
*/
public function setSkippedPropertiesContext(?SkippedPropertiesContext $context): void
{
$this->skippedPropertiesContext = $context;
}

/**
* @internal
*/
public function hasSkippedPropertiesContext(): bool
{
return $this->skippedPropertiesContext !== null;
}

/**
* @internal
*/
public function getSkippedPropertiesContext(): SkippedPropertiesContext
{
if ($this->skippedPropertiesContext === null) {
throw InvalidState::create()
->withMessage('Check partial object existence with hasSkippedPropertiesContext()');
}

return $this->skippedPropertiesContext;
}

/**
* @param mixed $values
*
Expand Down
15 changes: 9 additions & 6 deletions src/Processing/DefaultProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,14 @@ final class DefaultProcessor implements Processor

private ObjectCreator $objectCreator;

private SkippedPropertiesContextMap $skippedMap;

public function __construct(MetaLoader $metaLoader, RuleManager $ruleManager, ObjectCreator $objectCreator)
{
$this->metaLoader = $metaLoader;
$this->ruleManager = $ruleManager;
$this->objectCreator = $objectCreator;
$this->skippedMap = new SkippedPropertiesContextMap();
}

/**
Expand Down Expand Up @@ -658,11 +661,11 @@ private function fillObject(
// Set skipped properties
$skippedProperties = $callContext->getSkippedProperties();
if ($skippedProperties !== []) {
$partial = new SkippedPropertiesContext($type, $options);
$object->setSkippedPropertiesContext($partial);
$skippedContext = new SkippedPropertiesContext($type, $options);
$this->skippedMap->setSkippedPropertiesContext($object, $skippedContext);

foreach ($skippedProperties as $propertyName => $skippedPropertyContext) {
$partial->addSkippedProperty($propertyName, $skippedPropertyContext);
$skippedContext->addSkippedProperty($propertyName, $skippedPropertyContext);
}
}
}
Expand Down Expand Up @@ -695,7 +698,7 @@ public function processSkippedProperties(
$class = get_class($object);

// Object has no skipped properties
if (!$object->hasSkippedPropertiesContext()) {
if (!$this->skippedMap->hasSkippedPropertiesContext($object)) {
throw InvalidState::create()
->withMessage(sprintf(
'Cannot initialize properties "%s" of "%s" instance because it has no skipped properties.',
Expand All @@ -704,7 +707,7 @@ public function processSkippedProperties(
));
}

$skippedPropertiesContext = $object->getSkippedPropertiesContext();
$skippedPropertiesContext = $this->skippedMap->getSkippedPropertiesContext($object);

$type = $skippedPropertiesContext->getType();
$options ??= $skippedPropertiesContext->getOptions();
Expand Down Expand Up @@ -762,7 +765,7 @@ public function processSkippedProperties(

// Object is fully initialized, remove partial context
if ($skippedPropertiesContext->getSkippedProperties() === []) {
$object->setSkippedPropertiesContext(null);
$this->skippedMap->setSkippedPropertiesContext($object, null);
}
}

Expand Down
49 changes: 49 additions & 0 deletions src/Processing/SkippedPropertiesContextMap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php declare(strict_types = 1);

namespace Orisai\ObjectMapper\Processing;

use Orisai\Exceptions\Logic\InvalidState;
use Orisai\ObjectMapper\Context\SkippedPropertiesContext;
use Orisai\ObjectMapper\MappedObject;
use WeakMap;

final class SkippedPropertiesContextMap
{

/** @var WeakMap<MappedObject, SkippedPropertiesContext|null> */
private WeakMap $map;

public function __construct()
{
$this->map = new WeakMap();
}

public function setSkippedPropertiesContext(MappedObject $object, ?SkippedPropertiesContext $context): void
{
if ($context === null) {
$this->map->offsetUnset($object);
} else {
$this->map->offsetSet($object, $context);
}
}

public function hasSkippedPropertiesContext(MappedObject $object): bool
{
return $this->map->offsetExists($object);
}

public function getSkippedPropertiesContext(MappedObject $object): SkippedPropertiesContext
{
$context = $this->map->offsetExists($object)
? $this->map->offsetGet($object)
: null;

if ($context === null) {
throw InvalidState::create()
->withMessage('Check partial object existence with hasSkippedPropertiesContext()');
}

return $context;
}

}

0 comments on commit b013c9d

Please sign in to comment.