Skip to content

Commit

Permalink
Allow profiles to execute code before/after entity values are written
Browse files Browse the repository at this point in the history
  • Loading branch information
Dominic Tubach committed Jul 30, 2024
1 parent d0df501 commit 182f992
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -217,15 +217,35 @@ public function submitCreateForm(RemoteSubmitCreateFormAction $action
throw $validationResult->toException();
}

$entityValues = $formSpec->getDataTransformer()->toEntityValues(
ReadOnlyFieldsRemover::removeReadOnlyFields($formSpec, $action->getData()),
NULL,
$action->getResolvedContactId()
);

$this->profile->onPreCreate(
$action->getArguments(),
$entityValues,
$entityFields,
$formSpec,
$action->getResolvedContactId()
);

$createdValues = $this->api4->createEntity(
$this->profile->getEntityName(),
$formSpec->getDataTransformer()->toEntityValues(
ReadOnlyFieldsRemover::removeReadOnlyFields($formSpec, $action->getData()),
NULL,
$action->getResolvedContactId()
),
$entityValues,
['checkPermissions' => $this->profile->isCheckApiPermissions($action->getResolvedContactId())],
)->single();
// Custom field values might not be part of $createdValues, so we add $entityValues
$createdValues += $entityValues;

$this->profile->onPostCreate(
$action->getArguments(),
$createdValues,
$entityFields,
$formSpec,
$action->getResolvedContactId()
);

return $this->convertToSubmitFormActionResult(
$createdValues,
Expand Down Expand Up @@ -264,6 +284,15 @@ public function submitUpdateForm(RemoteSubmitUpdateFormAction $action
$entityValues,
$action->getResolvedContactId()
);

$this->profile->onPreUpdate(
$newEntityValues,
$entityValues,
$entityFields,
$formSpec,
$action->getResolvedContactId()
);

$updatedValues = $this->api4->updateEntity(
$this->profile->getEntityName(),
$action->getId(),
Expand All @@ -274,6 +303,14 @@ public function submitUpdateForm(RemoteSubmitUpdateFormAction $action
// ones. Fields updated by triggers might be outdated, though.
$updatedValues += $entityValues;

$this->profile->onPostUpdate(
$updatedValues,
$entityValues,
$entityFields,
$formSpec,
$action->getResolvedContactId()
);

return $this->convertToSubmitFormActionResult(
$updatedValues,
$entityValues,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

use Civi\RemoteTools\ActionHandler\ActionHandlerInterface;
use Civi\RemoteTools\ActionHandler\JsonFormsRemoteActionsHandler;
use Civi\RemoteTools\DependencyInjection\Compiler\Traits\DecorateServiceTrait;
use Civi\RemoteTools\EntityProfile\EntityProfileFileDecorator;
use Civi\RemoteTools\EntityProfile\RemoteEntityProfileInterface;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
Expand All @@ -32,6 +34,8 @@
*/
final class RemoteEntityProfilePass implements CompilerPassInterface {

use DecorateServiceTrait;

private const DEFAULT_HANDLER_CLASS = JsonFormsRemoteActionsHandler::class;

public static function buildHandlerServiceId(string $entityName, string $profileName): string {
Expand Down Expand Up @@ -70,9 +74,10 @@ public function process(ContainerBuilder $container): void {
'profile_name' => $profileName,
'priority' => -1000,
]);

$this->decorateService($container, $id, EntityProfileFileDecorator::class, $profileId);

Check failure on line 78 in Civi/RemoteTools/DependencyInjection/Compiler/RemoteEntityProfilePass.php

View workflow job for this annotation

GitHub Actions / PHPStan with PHP 7.4 prefer-stable

Class Civi\RemoteTools\EntityProfile\EntityProfileFileDecorator not found.

Check failure on line 78 in Civi/RemoteTools/DependencyInjection/Compiler/RemoteEntityProfilePass.php

View workflow job for this annotation

GitHub Actions / PHPStan with PHP 7.4 prefer-lowest

Class Civi\RemoteTools\EntityProfile\EntityProfileFileDecorator not found.

Check failure on line 78 in Civi/RemoteTools/DependencyInjection/Compiler/RemoteEntityProfilePass.php

View workflow job for this annotation

GitHub Actions / PHPStan with PHP 8.0 prefer-stable

Class Civi\RemoteTools\EntityProfile\EntityProfileFileDecorator not found.

Check failure on line 78 in Civi/RemoteTools/DependencyInjection/Compiler/RemoteEntityProfilePass.php

View workflow job for this annotation

GitHub Actions / PHPStan with PHP 8.0 prefer-lowest

Class Civi\RemoteTools\EntityProfile\EntityProfileFileDecorator not found.

Check failure on line 78 in Civi/RemoteTools/DependencyInjection/Compiler/RemoteEntityProfilePass.php

View workflow job for this annotation

GitHub Actions / PHPStan with PHP 8.3 prefer-stable

Class Civi\RemoteTools\EntityProfile\EntityProfileFileDecorator not found.

Check failure on line 78 in Civi/RemoteTools/DependencyInjection/Compiler/RemoteEntityProfilePass.php

View workflow job for this annotation

GitHub Actions / PHPStan with PHP 8.3 prefer-lowest

Class Civi\RemoteTools\EntityProfile\EntityProfileFileDecorator not found.
}
}

}

/**
Expand Down
49 changes: 49 additions & 0 deletions Civi/RemoteTools/EntityProfile/AbstractRemoteEntityProfile.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use Civi\RemoteTools\Api4\Query\Comparison;
use Civi\RemoteTools\Api4\Query\ConditionInterface;
use Civi\RemoteTools\EntityProfile\Authorization\GrantResult;
use Civi\RemoteTools\Form\FormSpec\FormSpec;
use CRM_Remotetools_ExtensionUtil as E;

/**
Expand Down Expand Up @@ -118,4 +119,52 @@ public function getSaveSuccessMessage(
return E::ts('Saved successfully');
}

/**
* @inheritDoc
*/
public function onPreCreate(
array $arguments,
array &$entityValues,
array $entityFields,
FormSpec $formSpec,
?int $contactId
): void {
}

/**
* @inheritDoc
*/
public function onPostCreate(
array $arguments,
array $entityValues,
array $entityFields,
FormSpec $formSpec,
?int $contactId
): void {
}

/**
* @inheritDoc
*/
public function onPreUpdate(
array &$newValues,
array $oldValues,
array $entityFields,
FormSpec $formSpec,
?int $contactId
): void {
}

/**
* @inheritDoc
*/
public function onPostUpdate(
array $newValues,
array $oldValues,
array $entityFields,
FormSpec $formSpec,
?int $contactId
): void {
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,56 @@ public function getSaveSuccessMessage(
return $this->profile->getSaveSuccessMessage($newValues, $oldValues, $formData, $contactId);
}

/**
* @inheritDoc
*/
public function onPreCreate(
array $arguments,
array &$entityValues,
array $entityFields,
FormSpec $formSpec,
?int $contactId
): void {
$this->profile->onPreCreate($arguments, $entityValues, $entityFields, $formSpec, $contactId);
}

/**
* @inheritDoc
*/
public function onPostCreate(
array $arguments,
array $entityValues,
array $entityFields,
FormSpec $formSpec,
?int $contactId
): void {
$this->profile->onPostCreate($arguments, $entityValues, $entityFields, $formSpec, $contactId);
}

/**
* @inheritDoc
*/
public function onPreUpdate(
array &$newValues,
array $oldValues,
array $entityFields,
FormSpec $formSpec,
?int $contactId
): void {
$this->profile->onPreUpdate($newValues, $oldValues, $entityFields, $formSpec, $contactId);
}

/**
* @inheritDoc
*/
public function onPostUpdate(
array $newValues,
array $oldValues,
array $entityFields,
FormSpec $formSpec,
?int $contactId
): void {
$this->profile->onPostUpdate($newValues, $oldValues, $entityFields, $formSpec, $contactId);
}

}
74 changes: 74 additions & 0 deletions Civi/RemoteTools/EntityProfile/RemoteEntityProfileInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -262,4 +262,78 @@ public function getSaveSuccessMessage(
?int $contactId
): string;

/**
* Called before the entity is created.
*
* @phpstan-param array<int|string, mixed> $arguments
* @phpstan-param array<string, mixed> $entityValues
* The values going to be inserted. Can be modified.
* @phpstan-param array<string, array<string, mixed>> $entityFields
* Entity fields indexed by name.
* @param \Civi\RemoteTools\Form\FormSpec\FormSpec $formSpec
* @param int|null $contactId
*/
public function onPreCreate(
array $arguments,
array &$entityValues,
array $entityFields,
FormSpec $formSpec,
?int $contactId
): void;

/**
* Called after the entity was created.
*
* @phpstan-param array<int|string, mixed> $arguments
* @phpstan-param array<string, mixed> $entityValues
* @phpstan-param array<string, array<string, mixed>> $entityFields
* Entity fields indexed by name.
* @param \Civi\RemoteTools\Form\FormSpec\FormSpec $formSpec
* @param int|null $contactId
*/
public function onPostCreate(
array $arguments,
array $entityValues,
array $entityFields,
FormSpec $formSpec,
?int $contactId
): void;

/**
* Called before the entity is created.
*
* @phpstan-param array<string, mixed> $newValues
* The values going to be updated. Can be modified.
* @phpstan-param array<string, mixed> $oldValues
* @phpstan-param array<string, array<string, mixed>> $entityFields
* Entity fields indexed by name.
* @param \Civi\RemoteTools\Form\FormSpec\FormSpec $formSpec
* @param int|null $contactId
*/
public function onPreUpdate(
array &$newValues,
array $oldValues,
array $entityFields,
FormSpec $formSpec,
?int $contactId
): void;

/**
* Called after the entity was created.
*
* @phpstan-param array<string, mixed> $newValues
* @phpstan-param array<string, mixed> $oldValues
* @phpstan-param array<string, array<string, mixed>> $entityFields
* Entity fields indexed by name.
* @param \Civi\RemoteTools\Form\FormSpec\FormSpec $formSpec
* @param int|null $contactId
*/
public function onPostUpdate(
array $newValues,
array $oldValues,
array $entityFields,
FormSpec $formSpec,
?int $contactId
): void;

}
Original file line number Diff line number Diff line change
Expand Up @@ -302,10 +302,17 @@ public function testSubmitCreateForm(): void {
->willReturn(['foo' => 'bar2']);
$formSpec->setDataTransformer($dataTransformerMock);

$createdValues = ['id' => 12, 'foo' => 'bar2'];
$this->profileMock->expects(static::once())->method('onPreCreate')
->with($arguments, ['foo' => 'bar2'], $entityFields, $formSpec, self::RESOLVED_CONTACT_ID);

$createdValues = ['id' => 12];
$this->api4Mock->expects(static::once())->method('createEntity')
->with('Entity', ['foo' => 'bar2'], ['checkPermissions' => FALSE])
->willReturn(new Result([$createdValues]));
$createdValues += ['foo' => 'bar2'];

$this->profileMock->expects(static::once())->method('onPostCreate')
->with($arguments, $createdValues, $entityFields, $formSpec, self::RESOLVED_CONTACT_ID);

$this->profileMock->method('getSaveSuccessMessage')
->with($createdValues, NULL, $formData, self::RESOLVED_CONTACT_ID)
Expand Down Expand Up @@ -514,11 +521,17 @@ public function testSubmitUpdateForm(): void {
->willReturn(['foo' => 'bar2']);
$formSpec->setDataTransformer($dataTransformerMock);

$this->profileMock->expects(static::once())->method('onPreUpdate')
->with(['foo' => 'bar2'], $entityValues, $entityFields, $formSpec, self::RESOLVED_CONTACT_ID);

$this->api4Mock->expects(static::once())->method('updateEntity')
->with('Entity', 12, ['foo' => 'bar2'])
->willReturn(new Result([['foo' => 'bar2']]));

$newEntityValues = ['foo' => 'bar2'] + $entityValues;

$this->profileMock->expects(static::once())->method('onPostUpdate')
->with($newEntityValues, $entityValues, $entityFields, $formSpec, self::RESOLVED_CONTACT_ID);

$this->profileMock->method('getSaveSuccessMessage')
->with($newEntityValues, $entityValues, $formData, self::RESOLVED_CONTACT_ID)
->willReturn('Ok');
Expand Down

0 comments on commit 182f992

Please sign in to comment.