Skip to content

Commit

Permalink
Restructure and cache contexts
Browse files Browse the repository at this point in the history
  • Loading branch information
mabar committed Jan 21, 2025
1 parent 89b57e3 commit 2beb12f
Show file tree
Hide file tree
Showing 93 changed files with 1,759 additions and 1,176 deletions.
65 changes: 39 additions & 26 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,43 +9,56 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

### Added

- `ArrayShapeRule` - allows processing of arrays with predefined keys
- `ArgsFieldContext` - args validation context which adds access to the property's default value
- `Processor` - `reset()` method for resetting to initial state (clearing meta cache)

### Changed

- Composer
- Allow PHP 8.4
- Allow benmorel/weakmap-polyfill:^0.5.0
- Rules
- `ArrayShapeRule` - allows processing of arrays with predefined keys
- Processing
- `Processor` - `reset()` method for resetting to initial state (clearing meta cache)

### Changed

- Metadata
- Improved accuracy of metadata-related error messages
- `ReflectorMetaSource` is marked as `@internal`
- Check that `Callback` returns correct `Args` class type
- Callbacks in `NodeRuntimeMeta` are grouped by type (performance optimization)
- `Rule`
- `resolveArgs()` accepts `ArgsFieldContext` instead of `ArgsContext`
- all rules initialize `Type` lazily (performance optimization)
- `ArrayOfRule`
- check during metadata parsing that default value is an array when `mergeDefaults` is enabled
- `ArrayOfRule`, `ListOfRule`
- skip 2nd and 3rd validation phase for item rules that don't require it
- pass values with keys included to phase 2 (previously keys were stripped)
- `FieldContext`, `MappedObjectContext`
- initializes `Type` lazily (performance optimization)
- `ArrayShapeType`
- `getFields()` always returns the same instances
- `DefaultProcessor`
- creates `MappedObjectType` only when necessary (performance optimization)
- `MultiValueEfficientRule`
- renamed to `PhasedRule`
- `MultiValueEfficientRuleAdapter`
- renamed to `PhasedRuleAdapter`
- marked as internal
- Callbacks
- receive `FieldContext` (callback-specific) instead of `FieldContext` and `ObjectContext` instead of
`MappedObjectContext`
- Contexts
- `TypeContext`, `MappedObjectContext` and `FieldContext` replaced with `ServicesContext`, `DynamicContext`,
`PropertyContext`, `FieldContext` (for callbacks) and `ObjectContext` (callback-specific)
- performance and memory optimization to significantly reduce number of created objects
- `ArgsContext` renamed to `MetaContext`
- added child class `MetaFieldContext` with access to property's default value
- Rules
- `Rule`
- accepts `ServicesContext`, `DynamicContext` and `PropertyContext` instead of `TypeContext` and `FieldContext`
- accepts `MetaFieldContext` instead of `ArgsContext`
- all rules initialize `Type` lazily (performance optimization)
- `ArrayOfRule`
- check during metadata parsing that default value is an array when `mergeDefaults` is enabled
- `ArrayOfRule`, `ListOfRule`
- skip 2nd and 3rd validation phase for item rules that don't require it
- pass values with keys included to phase 2 (previously keys were stripped)
- `MultiValueEfficientRule`
- renamed to `PhasedRule`
- `MultiValueEfficientRuleAdapter`
- renamed to `PhasedRuleAdapter`
- marked as internal
- Types
- `ArrayShapeType`
- `getFields()` always returns the same instances
- Processing
- `DefaultProcessor`
- creates `MappedObjectType` only when necessary (performance optimization)
- automatic meta cache reset after main `process()` call (performance optimization) replaced with `reset()`
method

### Removed

- `DefaultProcessor` - automatic meta cache reset after main `process()` call (performance optimization)
- `Skipped` modifier and the related code - it was an undocumented feature that is no longer necessary

## [0.2.0](https://github.com/orisai/object-mapper/compare/0.1.0...0.2.0) - 2024-06-22
Expand Down
30 changes: 15 additions & 15 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2166,7 +2166,7 @@ Define callbacks before and after mapped objects and their fields:

```php
use Orisai\ObjectMapper\Callbacks\After;
use Orisai\ObjectMapper\Context\FieldContext;
use Orisai\ObjectMapper\Callbacks\Context\FieldContext;
use Orisai\ObjectMapper\MappedObject;
use Orisai\ObjectMapper\Rules\StringValue;

Expand All @@ -2191,7 +2191,7 @@ final class WithCallbackInput implements MappedObject

```php
use Orisai\ObjectMapper\Callbacks\After;
use Orisai\ObjectMapper\Context\FieldContext;
use Orisai\ObjectMapper\Callbacks\Context\FieldContext;
use Orisai\ObjectMapper\MappedObject;
use Orisai\ObjectMapper\Rules\StringValue;

Expand Down Expand Up @@ -2246,17 +2246,17 @@ After mapped object
<summary><code>#[Attributes()]</code></summary>

```php
use Orisai\ObjectMapper\Callbacks\Before;
use Orisai\ObjectMapper\Callbacks\After;
use Orisai\ObjectMapper\Context\MappedObjectContext;
use Orisai\ObjectMapper\Callbacks\Before;
use Orisai\ObjectMapper\Callbacks\Context\ObjectContext;
use Orisai\ObjectMapper\MappedObject;

#[Before('beforeObject')]
#[After('afterObject')]
final class WithMappedObjectCallbacksInput implements MappedObject
{

private static function beforeObject(mixed $value, MappedObjectContext $context): myInterface
private static function beforeObject(mixed $value, ObjectContext $context): myInterface
{
return $value;
}
Expand All @@ -2265,7 +2265,7 @@ final class WithMappedObjectCallbacksInput implements MappedObject
* @param array<int|string, mixed> $value
* @return array<int|string, mixed>
*/
private static function afterObject(array $value, MappedObjectContext $context): array
private static function afterObject(array $value, ObjectContext $context): array
{
return $value;
}
Expand All @@ -2278,9 +2278,9 @@ final class WithMappedObjectCallbacksInput implements MappedObject
<summary><code>@Annotations()</code></summary>

```php
use Orisai\ObjectMapper\Callbacks\Before;
use Orisai\ObjectMapper\Callbacks\After;
use Orisai\ObjectMapper\Context\MappedObjectContext;
use Orisai\ObjectMapper\Callbacks\Before;
use Orisai\ObjectMapper\Callbacks\Context\ObjectContext;
use Orisai\ObjectMapper\MappedObject;

/**
Expand All @@ -2294,7 +2294,7 @@ final class WithMappedObjectCallbacksInput implements MappedObject
* @param mixed $value
* @return mixed
*/
private static function beforeObject($value, MappedObjectContext $context)
private static function beforeObject($value, ObjectContext $context)
{
return $value;
}
Expand All @@ -2303,7 +2303,7 @@ final class WithMappedObjectCallbacksInput implements MappedObject
* @param array<int|string, mixed> $value
* @return array<int|string, mixed>
*/
private static function afterObject(array $value, MappedObjectContext $context): array
private static function afterObject(array $value, ObjectContext $context): array
{
return $value;
}
Expand Down Expand Up @@ -2334,9 +2334,9 @@ After field
<summary><code>#[Attributes()]</code></summary>

```php
use Orisai\ObjectMapper\Callbacks\Before;
use Orisai\ObjectMapper\Callbacks\After;
use Orisai\ObjectMapper\Context\FieldContext;
use Orisai\ObjectMapper\Callbacks\Before;
use Orisai\ObjectMapper\Callbacks\Context\FieldContext;
use Orisai\ObjectMapper\MappedObject;
use Orisai\ObjectMapper\Rules\StringValue;

Expand Down Expand Up @@ -2366,9 +2366,9 @@ final class WithFieldCallbacksInput implements MappedObject
<summary><code>@Annotations()</code></summary>

```php
use Orisai\ObjectMapper\Callbacks\Before;
use Orisai\ObjectMapper\Callbacks\After;
use Orisai\ObjectMapper\Context\FieldContext;
use Orisai\ObjectMapper\Callbacks\Before;
use Orisai\ObjectMapper\Callbacks\Context\FieldContext;
use Orisai\ObjectMapper\MappedObject;
use Orisai\ObjectMapper\Rules\StringValue;

Expand Down Expand Up @@ -2404,7 +2404,7 @@ Field callbacks are called only when field is sent. Callback is not invoked for

```php
use Orisai\ObjectMapper\Callbacks\After;
use Orisai\ObjectMapper\Context\FieldContext;
use Orisai\ObjectMapper\Callbacks\Context\FieldContext;
use Orisai\ObjectMapper\MappedObject;
use Orisai\ObjectMapper\Rules\StringValue;

Expand Down
20 changes: 9 additions & 11 deletions src/Callbacks/BaseCallback.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
use Orisai\Exceptions\Logic\InvalidArgument;
use Orisai\ObjectMapper\Args\Args;
use Orisai\ObjectMapper\Args\ArgsChecker;
use Orisai\ObjectMapper\Context\ArgsContext;
use Orisai\ObjectMapper\Context\BaseFieldContext;
use Orisai\ObjectMapper\Context\FieldContext;
use Orisai\ObjectMapper\Context\MappedObjectContext;
use Orisai\ObjectMapper\Callbacks\Context\CallbackBaseContext;
use Orisai\ObjectMapper\Callbacks\Context\FieldContext;
use Orisai\ObjectMapper\Callbacks\Context\ObjectContext;
use Orisai\ObjectMapper\MappedObject;
use Orisai\ObjectMapper\Meta\Context\MetaContext;
use Orisai\ObjectMapper\Processing\ObjectHolder;
use ReflectionClass;
use ReflectionMethod;
Expand Down Expand Up @@ -53,7 +53,7 @@ private function __construct()

public static function resolveArgs(
array $args,
ArgsContext $context,
MetaContext $context,
Reflector $reflector
): BaseCallbackArgs
{
Expand Down Expand Up @@ -225,14 +225,14 @@ private static function validateClassMethodContextParam(
{
if (
($type = self::getTypeName($paramContext->getType())) === null
|| !is_a($type, MappedObjectContext::class, true)
|| !is_a($type, ObjectContext::class, true)
) {
throw InvalidArgument::create()
->withMessage(sprintf(
'Second parameter of class callback method %s::%s should have "%s" type instead of %s',
$class->getName(),
$method->getName(),
MappedObjectContext::class,
ObjectContext::class,
$type ?? 'none',
));
}
Expand Down Expand Up @@ -317,16 +317,14 @@ public static function getArgsType(): string
}

/**
* @param mixed $data
* @param BaseCallbackArgs $args
* @param FieldContext|MappedObjectContext $context
* @param BaseCallbackArgs $args
* @return mixed
*/
public static function invoke(
$data,
Args $args,
ObjectHolder $holder,
BaseFieldContext $context,
CallbackBaseContext $context,
ReflectionClass $declaringClass
)
{
Expand Down
24 changes: 12 additions & 12 deletions src/Callbacks/Callback.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
namespace Orisai\ObjectMapper\Callbacks;

use Orisai\ObjectMapper\Args\Args;
use Orisai\ObjectMapper\Context\ArgsContext;
use Orisai\ObjectMapper\Context\BaseFieldContext;
use Orisai\ObjectMapper\Context\FieldContext;
use Orisai\ObjectMapper\Context\MappedObjectContext;
use Orisai\ObjectMapper\Callbacks\Context\CallbackBaseContext;
use Orisai\ObjectMapper\Callbacks\Context\FieldContext;
use Orisai\ObjectMapper\Callbacks\Context\ObjectContext;
use Orisai\ObjectMapper\Exception\InvalidData;
use Orisai\ObjectMapper\Exception\ValueDoesNotMatch;
use Orisai\ObjectMapper\MappedObject;
use Orisai\ObjectMapper\Meta\Context\MetaContext;
use Orisai\ObjectMapper\Processing\ObjectHolder;
use ReflectionClass;
use ReflectionProperty;
Expand All @@ -22,23 +22,23 @@ interface Callback
{

/**
* @param array<int|string, mixed> $args
* @param array<int|string, mixed> $args
* @param ReflectionClass<MappedObject>|ReflectionProperty $reflector
* @return T_ARGS
*/
public static function resolveArgs(array $args, ArgsContext $context, Reflector $reflector): Args;
public static function resolveArgs(array $args, MetaContext $context, Reflector $reflector): Args;

/**
* @return class-string<T_ARGS>
*/
public static function getArgsType(): string;

/**
* @param mixed $data
* @param T_ARGS $args
* @param FieldContext|MappedObjectContext $context
* @param ObjectHolder<MappedObject> $holder
* @param ReflectionClass<MappedObject> $declaringClass
* @param mixed $data
* @param T_ARGS $args
* @param ObjectContext|FieldContext $context
* @param ObjectHolder<MappedObject> $holder
* @param ReflectionClass<MappedObject> $declaringClass
* @return mixed
* @throws ValueDoesNotMatch
* @throws InvalidData
Expand All @@ -47,7 +47,7 @@ public static function invoke(
$data,
Args $args,
ObjectHolder $holder,
BaseFieldContext $context,
CallbackBaseContext $context,
ReflectionClass $declaringClass
);

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

namespace Orisai\ObjectMapper\Callbacks\Context;

use Orisai\ObjectMapper\Processing\Context\DynamicContext;
use Orisai\ObjectMapper\Processing\Context\ServicesContext;
use Orisai\ObjectMapper\Processing\Options;
use Orisai\ObjectMapper\Processing\Processor;
use Orisai\ObjectMapper\Types\Type;

abstract class CallbackBaseContext
{

private ServicesContext $services;

private DynamicContext $dynamic;

public function __construct(
ServicesContext $services,
DynamicContext $dynamic
)
{
$this->services = $services;
$this->dynamic = $dynamic;
}

abstract public function getType(): Type;

public function getProcessor(): Processor
{
return $this->services->getProcessor();
}

public function getOptions(): Options
{
return $this->dynamic->getOptions();
}

public function shouldInitializeObjects(): bool
{
return $this->dynamic->shouldInitializeObjects();
}

}
Loading

0 comments on commit 2beb12f

Please sign in to comment.