-
-
Notifications
You must be signed in to change notification settings - Fork 824
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
(dev/mail#83) Introduce WorkflowMessage APIs with CaseActivity example #21338
Conversation
(Standard links)
|
@totten I realise some of this is "inherited" code but I have concerns about the use of
I'm very happy with the concept of this PR by the way! |
Case-Activity Message@mattwire Right, at a high level preface -- I also dislike some specifics in the current contract for the The content in For
GeneralBut I'd like to shift your attention away from the specifics of the CaseActivity message and toward the process at higher level. We have a start-point where there are 30+ messages where inputs+outputs are all-over-the-place (incl weird/questionable elements). We want an end-point where the inputs are clear, pithy, consistent. Getting from here-to-there requires a mix of plays like:
To my thinking, it's useful to assess and provide the class as the declaration/documentation on the current-status. This makes it easier to plot other changes. From this perspective, the work can be broken into more bite-sized chunks, and the standard for the first revision is fairly modest. But there is a bit of contradiction - this PR is also adding I think the contradiction goes away if we indicate different stability levels on different artifacts, eg
So this means we need to communicate this support level a little more clearly. For example, I could imagine: /**
* @support public
*/
class GenericWorkflowMessage implements WorkflowMessageInterface { ... }
// or
/**
* @support internal
*/
class CaseActivity extends GenericWorkflowMessage { ... }
(Not sure the best wording for the support flag - but the main thing is to flag each with a different level.) |
@totten It's actually a setting in CiviCase Settings - "Allow Multiple Case Clients". I flagged it because it's an area we've got into a mess with before (some code expecting a single integer and other code expecting an array). That particular issue may have been fixed by now. I understand that it's not the main point of this PR and I don't want to hold it up over this one point as we're initially just trying to replicate "like for like" but in a better way and with a better framework going forward. I also like the smarty->token aliasing PR as that provides a neat way to transition some of that. So I'd say, if we can be clear about the level of support - ie. we're not locking in |
@mattwire Thanks for pointing out the multi-client mode. I'd never used that option. Added the Pushed up some more docblocks on |
@@ -0,0 +1,56 @@ | |||
<?php |
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.
@totten - we discussed this commit yesterday & specifically the slightly odd name - ie WorkflowMessageExample::get()
and you suggested that @colemanw would be the only one likely to have another opinion
Looking at this PR is strikes me that an entity of 'SampleData::get()` would potentially be useful - since in this specific example the sampleData is just a contact and not tied to the workflow message
However, I suspect you feel that we DO need sample data specific to the message and that perhaps it could call a more generic sampleData
in future.
I would probably choose WorkflowMessageSampleData
as the entity after thinking about it - but I think @colemanw should have the last work on,
Based on my delving to date I would merge this commit if it were in it's own PR & we had a +1 from @colemanw on the naming
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.
@eileenmcnaughton I actually think a SampleData
entity might make more sense. I had originally written as WorkflowMessageExample
, then a couple days later kicked myself when I realized 80% would be the same for a general ExampleData
. The only thing is that the file-naming convention (and therefore loader/scanner) would merit a rethink - because the current convention is tied to the WorkflowMessage
classes (e.g. CRM/Contribution/WorkflowMessage/RecurringEdit/foo.ex.php
).
(EDIT) Re-stating: Overall, I'm on the fence about whether it's better as WorkflowMessageExample
or SampleData
. The WorkflowMessageExample
has the advantage of being written at this point - but I think if you and coleman believe in a generic sample-data makes more sense, then I'll be game for it.
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.
OK - let's see if @colemanw pipes up....
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.
@totten I went through the process of adding sample data for the 2 entities that I am testing this with - going htrough the process does bring me out on the side of SampleData::get()
My other thought was that it would be able to specify simpy the entity and get something that represents a very common set of fields - in the case of contact 'alex' in the case of 'contribution' - a Completed contribution like the data I put up. My recurring example is set up to use lots of fields - but that meant choosing a cancelled status - which seems like it isn't the 'normal' scenario
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.
+1 to what @eileenmcnaughton said. Maybe it's as simple as renaming the API to SampleData
now and then adding non non-workflow-msg functionality in the future.
Civi/Api4/WorkflowMessageExample.php
Outdated
'name' => 'tags', | ||
'title' => 'Tags', | ||
'data_type' => 'String', | ||
'serialize' => \CRM_Core_DAO::SERIALIZE_SEPARATOR_BOOKEND, |
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.
Oh I get it. You serialize the value in the get action and then rely on the API output formatter to unserialize it back into an array.
That seems a bit silly. Why not just declare data_type => Array
here?
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.
Right, I originally just had it return an array, but (IIRC) the explorer was happier if you coerced it to look more like MySQL data (ie with a serialization format). In a MySQL context, data_type=>Array
seems nonsensical... but if APIv4 actually works with , then that's cool. I can give that a try...
@@ -0,0 +1,56 @@ | |||
<?php |
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.
+1 to what @eileenmcnaughton said. Maybe it's as simple as renaming the API to SampleData
now and then adding non non-workflow-msg functionality in the future.
@totten as you know I've been struggling with the addition of the case activity template for the same reasons @mattwire has and I think there is a better option than the 'it exists but we don't really support it' without losing the 'we really want it to provide the test cover' - in my testing simply moving those classes into the test folder c08b2fe allowed all the test to run without us having to figure out how we want this class to look like right now. I've been focussing on a very simple template - (the recurring edit)[https://github.com//pull/21356/commits/c08b2fe4fee988d5526c1664df952d2e0464869f] - which basically requires
|
@@ -122,7 +122,7 @@ public function onRender(TokenRenderEvent $e) { | |||
$e->string = \CRM_Utils_Token::replaceDomainTokens($e->string, $domain, $isHtml, $e->message['tokens'], $useSmarty); | |||
|
|||
if (!empty($e->context['contact'])) { | |||
\CRM_Utils_Token::replaceGreetingTokens($e->string, $e->context['contact'], $e->context['contact']['contact_id'], NULL, $useSmarty); |
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 don't want to bring it into scope for getting this merged but I've been digging into these 2 lines. It seems they basically do the same thing with subtle differences - since both actually 'replaceContactTokens' in the string.
Despite the name the way we use replaceGreetingTokens
is not to replace greeting tokens - it is to replace contact tokens (generally).
The differences seem to be:
- the extent to which they replace 'blank' tokens - the first line DOES the second doesn't,
- the extent to which they attempt to optimise by early exiting if tokens are resolved and
- the extent to which they attempt to load the missing values in the contact
Test cover is good (#21387) & this function & replaceGreetingTokens
are the only 2 places still calling replaceContactTokens
so I think the goal would be to consolidate the replacment on this class & call this class from replaceGreetingTokens
& deprecate replaceContactTokens
.
85b7dc6
to
fb413f5
Compare
… Add base test-trait.
930655c
to
910d9f6
Compare
910d9f6
to
04dbbb7
Compare
This is mostly to circumvent near-term questions on reviewing CaseActivity while still allowing it as an example-case.
04dbbb7
to
2548cc1
Compare
With those last commits I think this is mergeable once tests pass |
This seems all fine to me |
Overview
This introduces APIs for handling WorkflowMessages and, to facilitate testing, it up-converts an example workflow (
case_activity
).This is the last big extract from #20975.
Before
The great void.
After
WorkflowMessage.get
API: Lookup the list of supported workflow-messages (names/classes/descriptions/etc).WorkflowMessage.getTemplateFields()
API: Lookup the fields that are required for rendering a message.WorkflowMessage.render
API: Allow one to render a message, performing any filtering/data-loading requiredfor the given message template.
Note that the
render()
can autoload data. Consequently, there are a few security constraints:contactId=>123
), then it callsCoreUtil::checkAccessDelegated()
to see if you're allowed to read that entity.render()
remotely unless you have some administrativy privileges (e.g.render templates
oredit system workflow message templates
.ExampleData.get
API: Lookup example data that can be used when previewing/rendering the workflow-message.