-
-
Notifications
You must be signed in to change notification settings - Fork 825
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
APIv4 - When running validateValues(), fire an event #20184
Conversation
(Standard links)
|
ping @colemanw |
Interesting. There's some overlap with #20170 or maybe it's synergy. |
One thing I noticed right away is that this doesn't pass the name of the action to the event, it's assumed to be "create or maybe update". But those two aren't the same. In the Save action you have to tease them apart like this: 20af3ca#diff-ccb444858b7cfcd34c34786bd76003cdccad4c53fbadef2b89df5ba7a94e82f2R107 I think we're going to want to fire this event from the delete action too. |
4d54b8c
to
9eec5aa
Compare
@colemanw A few updates here:
I didn't expand the scope of Perhaps that suggestion was spurred by the idea of combining |
$e = new ValidateValuesEvent($this->getEntityName(), 'save', $this->records); | ||
\Civi::dispatcher()->dispatch('civi.api4.validate', $e); | ||
if (!empty($e->errors)) { | ||
throw new \API_Exception(ts('Found %1 error(s) in submitted %2 record(s) of type "%3": %4', [ | ||
1 => count($e->errors), | ||
2 => count(array_unique(array_column($e->errors, 'record'))), | ||
3 => $this->getEntityName(), | ||
4 => implode(', ', array_column($e->errors, 'message')), | ||
])); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this whole block ought to be inside a foreach
loop as the event is supposed to fire once per record not for an array of records. Also I think the second param (action name) shouldn't be 'save' but should be 'create' or 'update' depending on the presence of $idField
like 20af3ca#diff-ccb444858b7cfcd34c34786bd76003cdccad4c53fbadef2b89df5ba7a94e82f2R107
@totten this looks great. I think it's almost merge-ready. See my one comment on the |
9eec5aa
to
4acb9c2
Compare
@colemanw Revised it to support the |
Also, I took a stab at refactoring (EDIT) Which is a long-winded way of saying... I think there's some opportunity for making it easier to use things like |
@totten I think the problem is
|
4acb9c2
to
052490b
Compare
Good eye @colemanw. Fixed/squashed. |
The original form (`getBatchRecords()`) still returns an array of items. The alternate form (`getBatchAction()`) returns an API call for fetching the batchs - but this API call may be further refined (e.g. selecting different fields or data-pages).
052490b
to
fdea27f
Compare
fdea27f
to
9e63589
Compare
Fixed another quirky test issue (data-leak - needed to tweak @colemanw Sure, I'll take a look when I get up. |
Replaced by #20533. |
Overview
This patch introduces an internal event,
civi.api4.validate
, which can be used to introduce more fine-tuned/per-entity validation rules.Before
To validate an entity in APIv4, one would need to override each method (
MyEntity::create()
,MyEntity::save()
), then override the relevant class and override thevalidateValues()
method.After
One may listen to
civi.api4.validate
and add extra validation rules. Here's an example adapted from the docblock:Technical Details
As with
hook_civicrm_pre
andhook_civicrm_post
or Drupal form hooks, this actually dispatches synonymous events (civi.api4.validate
andcivi.api4.validate::ENTITY_NAME
). For typical/simple cases, this allows to avoid the problem of systemic over-subscription (wherein every listener as to receive every event and then do some conditionals).There is fairly light test coverage directly in this patch. There is more extensive (but implicit) coverage in a follow-up branch (
master-strings
). Specifically: