Skip to content

Commit

Permalink
Fix partials
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenvanassche committed Jan 5, 2024
1 parent ed8d9e4 commit fdeddba
Show file tree
Hide file tree
Showing 20 changed files with 1,053 additions and 313 deletions.
10 changes: 6 additions & 4 deletions src/Commands/DataStructuresCacheCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@ public function handle(

$progressBar = $this->output->createProgressBar(count($dataClasses));

foreach ($dataClasses as $dataClass) {
$dataStructureCache->storeDataClass(
DataClass::create(new ReflectionClass($dataClass))
);
foreach ($dataClasses as $dataClassString) {
$dataClass = DataClass::create(new ReflectionClass($dataClassString));

$dataClass->prepareForCache();

$dataStructureCache->storeDataClass($dataClass);

$progressBar->advance();
}
Expand Down
2 changes: 1 addition & 1 deletion src/Concerns/ResponsableData.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public function toResponse($request)
}

return new JsonResponse(
data: $this->transform($contextFactory->get($this)),
data: $this->transform($contextFactory),
status: $request->isMethod(Request::METHOD_POST) ? Response::HTTP_CREATED : Response::HTTP_OK,
);
}
Expand Down
20 changes: 9 additions & 11 deletions src/Concerns/TransformableData.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,11 @@ trait TransformableData
public function transform(
null|TransformationContextFactory|TransformationContext $transformationContext = null,
): array {
if ($transformationContext === null) {
$transformationContext = new TransformationContext();
}

if ($transformationContext instanceof TransformationContextFactory) {
$transformationContext = $transformationContext->get($this);
}
$transformationContext = match (true) {
$transformationContext instanceof TransformationContext => $transformationContext,
$transformationContext instanceof TransformationContextFactory => $transformationContext->get($this),
$transformationContext === null => new TransformationContext()
};

$resolver = match (true) {
$this instanceof BaseDataContract => DataContainer::get()->transformedDataResolver(),
Expand All @@ -34,25 +32,25 @@ public function transform(
/** @var TransformationContext $transformationContext */

if ($dataContext->includePartials->count() > 0) {
$transformationContext->includedPartials->addAll(
$transformationContext->mergeIncludedResolvedPartials(
$dataContext->getResolvedPartialsAndRemoveTemporaryOnes($this, $dataContext->includePartials)
);
}

if ($dataContext->excludePartials->count() > 0) {
$transformationContext->excludedPartials->addAll(
$transformationContext->mergeExcludedResolvedPartials(
$dataContext->getResolvedPartialsAndRemoveTemporaryOnes($this, $dataContext->excludePartials)
);
}

if ($dataContext->onlyPartials->count() > 0) {
$transformationContext->onlyPartials->addAll(
$transformationContext->mergeOnlyResolvedPartials(
$dataContext->getResolvedPartialsAndRemoveTemporaryOnes($this, $dataContext->onlyPartials)
);
}

if ($dataContext->exceptPartials->count() > 0) {
$transformationContext->exceptPartials->addAll(
$transformationContext->mergeExceptResolvedPartials(
$dataContext->getResolvedPartialsAndRemoveTemporaryOnes($this, $dataContext->exceptPartials)
);
}
Expand Down
6 changes: 4 additions & 2 deletions src/Resolvers/RequestQueryStringPartialsResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,10 @@ protected function findField(
return $field;
}

if (array_key_exists($field, $dataClass->outputMappedProperties)) {
return $dataClass->outputMappedProperties[$field];
$outputMappedProperties = $dataClass->outputMappedProperties->resolve();

if (array_key_exists($field, $outputMappedProperties)) {
return $outputMappedProperties[$field];
}

return null;
Expand Down
6 changes: 2 additions & 4 deletions src/Resolvers/TransformedDataCollectionResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ public function execute(
? $context->setWrapExecutionType(WrapExecutionType::TemporarilyDisabled)
: $context;

// TODO: take into account that a DataCollection, PaginatedDataCollection and CursorPaginatedDataCollection also can have partials

if ($items instanceof DataCollection) {
return $this->transformItems($items->items(), $wrap, $context, $nestedContext);
}
Expand Down Expand Up @@ -83,7 +81,7 @@ protected function transformPaginator(
TransformationContext $context,
TransformationContext $nestedContext,
): array {
$paginator->through(fn (BaseData $data) => $this->transformationClosure($nestedContext)($data));
$paginator = $paginator->through(fn (BaseData $data) => $this->transformationClosure($nestedContext)($data));

if ($context->transformValues === false) {
return $paginator->all();
Expand Down Expand Up @@ -111,7 +109,7 @@ protected function transformationClosure(
return $data;
}

return $data->transform($context);
return $data->transform(clone $context);
};
}
}
24 changes: 16 additions & 8 deletions src/Resolvers/TransformedDataResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,13 @@ protected function resolvePropertyValue(
WrapExecutionType::TemporarilyDisabled => WrapExecutionType::Enabled
};

return $value->transform(
$fieldContext->setWrapExecutionType($wrapExecutionType)
);
$context = clone $fieldContext->setWrapExecutionType($wrapExecutionType);

$transformed = $value->transform($context);

$context->rollBackPartialsWhenRequired();

return $transformed;
}

if (
Expand All @@ -124,9 +128,13 @@ protected function resolvePropertyValue(
WrapExecutionType::TemporarilyDisabled => WrapExecutionType::TemporarilyDisabled
};

return $value->transform(
$fieldContext->setWrapExecutionType($wrapExecutionType)
);
$context = clone $fieldContext->setWrapExecutionType($wrapExecutionType);

$transformed = $value->transform($context);

$context->rollBackPartialsWhenRequired();

return $transformed;
}

if (
Expand All @@ -153,7 +161,7 @@ protected function resolvePotentialPartialArray(
array $value,
TransformationContext $fieldContext,
): array {
if ($fieldContext->exceptPartials->count() > 0) {
if ($fieldContext->exceptPartials && $fieldContext->exceptPartials->count() > 0) {
$partials = [];

foreach ($fieldContext->exceptPartials as $exceptPartial) {
Expand All @@ -163,7 +171,7 @@ protected function resolvePotentialPartialArray(
return Arr::except($value, $partials);
}

if ($fieldContext->onlyPartials->count() > 0) {
if ($fieldContext->onlyPartials && $fieldContext->onlyPartials->count() > 0) {
$partials = [];

foreach ($fieldContext->onlyPartials as $onlyPartial) {
Expand Down
101 changes: 54 additions & 47 deletions src/Resolvers/VisibleDataFieldsResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
use Spatie\LaravelData\Support\Lazy\ConditionalLazy;
use Spatie\LaravelData\Support\Lazy\RelationalLazy;
use Spatie\LaravelData\Support\Transformation\TransformationContext;
use SplObjectStorage;

class VisibleDataFieldsResolver
{
Expand All @@ -27,59 +26,47 @@ public function execute(
): array {
$dataInitializedFields = get_object_vars($data);

/** @var array<string, TransformationContext|null> $fields */
$fields = $dataClass
->properties
->reject(function (DataProperty $property) use (&$dataInitializedFields): bool {
if ($property->hidden) {
return true;
}
$fields = $dataClass->transformationFields->resolve();

if ($property->type->isOptional && ! array_key_exists($property->name, $dataInitializedFields)) {
return true;
}
foreach ($fields as $field => $next) {
if (! array_key_exists($field, $dataInitializedFields)) {
unset($fields[$field]);

return false;
})
->map(function (DataProperty $property) use ($transformationContext): null|TransformationContext {
if (
$property->type->kind->isDataCollectable()
|| $property->type->kind->isDataObject()
|| ($property->type->kind === DataTypeKind::Default && $property->type->type->acceptsType('array'))
) {
return new TransformationContext(
$transformationContext->transformValues,
$transformationContext->mapPropertyNames,
$transformationContext->wrapExecutionType,
new SplObjectStorage(),
new SplObjectStorage(),
new SplObjectStorage(),
new SplObjectStorage(),
);
}
continue;
}

return null;
})->all();
if ($next === true) {
$fields[$field] = new TransformationContext(
$transformationContext->transformValues,
$transformationContext->mapPropertyNames,
$transformationContext->wrapExecutionType,
);
}
}

$this->performExcept($fields, $transformationContext);
if ($transformationContext->exceptPartials) {
$this->performExcept($fields, $transformationContext);
}

if (empty($fields)) {
return [];
}

$this->performOnly($fields, $transformationContext);
if ($transformationContext->onlyPartials) {
$this->performOnly($fields, $transformationContext);
}

$includedFields = $this->resolveIncludedFields(
$includedFields = $transformationContext->includedPartials ? $this->resolveIncludedFields(
$fields,
$transformationContext,
$dataClass,
);
) : [];

$excludedFields = $this->resolveExcludedFields(
$excludedFields = $transformationContext->excludedPartials ? $this->resolveExcludedFields(
$fields,
$transformationContext,
$dataClass,
);
) : [];

foreach ($fields as $field => $fieldTransFormationContext) {
$value = $data->{$field};
Expand All @@ -95,7 +82,7 @@ public function execute(
}

if ($value instanceof RelationalLazy || $value instanceof ConditionalLazy) {
if(! $value->shouldBeIncluded()) {
if (! $value->shouldBeIncluded()) {
unset($fields[$field]);
}

Expand All @@ -118,6 +105,9 @@ public function execute(
return $fields;
}

/**
* @param array<string, TransformationContext|null> $fields
*/
protected function performExcept(
array &$fields,
TransformationContext $transformationContext
Expand All @@ -136,7 +126,7 @@ protected function performExcept(
}

if ($nested = $exceptPartial->getNested()) {
$fields[$nested]->exceptPartials->attach($exceptPartial->next());
$fields[$nested]->addExceptResolvedPartial($exceptPartial->next());

continue;
}
Expand All @@ -151,6 +141,9 @@ protected function performExcept(
}
}

/**
* @param array<string, TransformationContext|null> $fields
*/
protected function performOnly(
array &$fields,
TransformationContext $transformationContext
Expand All @@ -166,7 +159,7 @@ protected function performOnly(
$onlyFields ??= [];

if ($nested = $onlyPartial->getNested()) {
$fields[$nested]->onlyPartials->attach($onlyPartial->next());
$fields[$nested]->addOnlyResolvedPartial($onlyPartial->next());
$onlyFields[] = $nested;

continue;
Expand All @@ -190,14 +183,16 @@ protected function performOnly(
}
}

/**
* @param array<string, TransformationContext|null> $fields
*/
protected function resolveIncludedFields(
array $fields,
array &$fields,
TransformationContext $transformationContext,
DataClass $dataClass
): array {
$includedFields = [];


foreach ($transformationContext->includedPartials as $includedPartial) {
if ($includedPartial->isUndefined()) {
continue;
Expand All @@ -206,15 +201,20 @@ protected function resolveIncludedFields(
if ($includedPartial->isAll()) {
$includedFields = $dataClass
->properties
->filter(fn (DataProperty $property) => $property->type->lazyType !== null)
->filter(fn (DataProperty $property) => $property->type->lazyType !== null && array_key_exists($property->name, $fields))
->keys()
->all();

foreach ($includedFields as $includedField) {
// can be null when field is a non data object/collectable or array
$fields[$includedField]?->addIncludedResolvedPartial($includedPartial->next());
}

break;
}

if ($nested = $includedPartial->getNested()) {
$fields[$nested]->includedPartials->attach($includedPartial->next());
$fields[$nested]->addIncludedResolvedPartial($includedPartial->next());
$includedFields[] = $nested;

continue;
Expand All @@ -228,8 +228,11 @@ protected function resolveIncludedFields(
return $includedFields;
}

/**
* @param array<string, TransformationContext|null> $fields
*/
protected function resolveExcludedFields(
array $fields,
array &$fields,
TransformationContext $transformationContext,
DataClass $dataClass
): array {
Expand All @@ -243,15 +246,19 @@ protected function resolveExcludedFields(
if ($excludedPartial->isAll()) {
$excludedFields = $dataClass
->properties
->filter(fn (DataProperty $property) => $property->type->lazyType !== null)
->filter(fn (DataProperty $property) => $property->type->lazyType !== null && array_key_exists($property->name, $fields))
->keys()
->all();

foreach ($excludedFields as $excludedField) {
$fields[$excludedField]?->addExcludedResolvedPartial($excludedPartial->next());
}

break;
}

if ($nested = $excludedPartial->getNested()) {
$fields[$nested]->excludedPartials->attach($excludedPartial->next());
$fields[$nested]->addExcludedResolvedPartial($excludedPartial->next());
$excludedFields[] = $nested;

continue;
Expand Down
Loading

0 comments on commit fdeddba

Please sign in to comment.