-
-
Notifications
You must be signed in to change notification settings - Fork 817
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
CRM-19690 - CRM_Mailing_Tokens - Add TokenProcessor support #9563
Conversation
This includes support for both `{mailing.*}` and `{action.*}` tokens used in CiviMail.
This is more significant with mailing tokens because some of them are fairly sizeable/expensive.
Aside: The |
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.
just a view notes
} | ||
|
||
/** | ||
* Check something about being active. |
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.
same here .. you can just use @inheritdoc for this and other methods in this class
} | ||
|
||
/** | ||
* Evaluate the content of a single token. |
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.
you can just use @inheritdoc 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.
Hmm, well, I have pretty mixed feelings about this, e.g.
- The tool I use most (PHPStorm) doesn't do anything special with
inheritDoc
, so it's easier to read the docs if you copy the docblock. (Would be really nice to cmd-click or hover or something to see the docs in situ.) - Copying sucks. (Duplication/stale info/etal.)
- Civi coding standards (de jure) extend Drupal standards as a baseline, which means we ought to follow https://www.drupal.org/docs/develop/coding-standards/api-documentation-and-comment-standards#inheritdoc -- i.e.
{@inheritDoc}
- Civi code standards (de facto) use
@inheritDoc
instead of{@inheritDoc}
. - The vast majority of cases of
@inheritDoc
are redundant/useless (you can just omit the docblock and the docs say it will assume inheritance).
Do you see a concrete upside in resolving this? What is 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.
actually phpstorm do something about @inheritdoc ,, try to point to the method and press ctrl+Q or view >> quick documentation . So I think adding it is better than omitting it as in the last option you provided above.
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, nice. (For OSX, I had to use Ctlr-J or F1.) It seems to inherit docs correctly with each of these variations: {@inheritDoc}
, @inheritDoc
, and non-existent docblock. (Although with extended docs, {@inheritDoc}
doesn't seem to interpolate docs in the expected way.) I'll change it to match the de facto convention from other Civi classes (@inheritDoc
)
class CRM_Mailing_ActionTokens extends \Civi\Token\AbstractTokenSubscriber { | ||
|
||
/** | ||
* Class constructor. |
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 (Class constructor ) is uneeded .. same in CRM_Mailing_Tokens class
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.
We need it to declare the list of tokens ($this->tokenNames
) which is used in a couple ways:
- Optimizing the list of token to process (eg
$activeTokens = array_intersect($messageTokens[$this->entity], array_keys($this->tokenNames));
) - Providing metadata about the list of available tokens.
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.
sorry ... I meant the docblock .. not the constructor itself ..
$field, $verp, $urls, TRUE)); | ||
} | ||
|
||
protected function getTrackOpenUrl(\Civi\Token\TokenRow $row) { |
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.
you are not using this method so I think it is better to remove it for now
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.
Good catch. It was a leftover from an earlier/misconceived approach to open-tracking. I'll remove it.
$row->context['mailingActionTarget']['email'] | ||
); | ||
|
||
$row->format('text/plain')->tokens($entity, $field, |
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.
maybe this is a bit cleaner :
$formats = ['text/plain' => FALSE, 'text/html' => true];
foreach($formats as $format => $isHTML) {
CRM_Utils_Token::getActionTokenReplacement( $field, $verp, $urls, $isHTML));
}
@@ -203,8 +203,12 @@ public function createContainer() { | |||
'Civi\Token\TokenCompatSubscriber', | |||
array() | |||
))->addTag('kernel.event_subscriber'); | |||
$container->setDefinition("crm_mailing_action_tokens", new Definition( |
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.
a space before this line would make it easier to read .. by the way I don't like the way how are these events are registered here and this method may go bigger and bigger with time .. but I see there is already a plan to fix that https://github.com/totten/civicrm-core/blob/e0c753854db4ed1bcd3b0659a29b79f535c1aa08/Civi/Core/Container.php#L112
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.
Yup, the intent is to address that readability issue by moving the declarations to smaller/separate files. Outside scope of the current PR, though.
|
||
foreach (array('Activity', 'Contribute', 'Event', 'Member') as $comp) { | ||
foreach (array('Activity', 'Contribute', 'Event', 'Mailing', 'Member') as $comp) { |
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 was thinking that it may make much sense to fetch the components list dynamically and then checking if CRM_{$comp}_Tokens is their for that component ... but I think this might affect performance unless some sort of caching is performed .
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.
We do cache the container definitions now-a-days (v4.7+; see loadContainer()
), but I'd rather not create a sui-generis mechanism just for locating the CRM_*_Token
classes. Rather, cleaning this bit should wait until we have a generally decent way to locate/discover service definitions (e.g. via annotation or YAML -- as hinted by https://github.com/totten/civicrm-core/blob/e0c753854db4ed1bcd3b0659a29b79f535c1aa08/Civi/Core/Container.php#L112 ).
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.
got it
/** | ||
* @group headless | ||
*/ | ||
class CRM_Mailing_TokensTest extends \CiviUnitTestCase { |
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.
why not just implement the headless interface instead of the heavy CiviUnitTestCase class .. the tests should perform much faster ..
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.
Mostly because I reflexively want to reason about tests at the suite level -- e.g. "all the tests in CRM_AllTests
extend CiviUnitTestCase
" or "all the tests in org.example.foo
extend PHPUnit_Framework_TestCase
. (This way of thinking probably arose as a defensive reaction all the heaviness in CiviUnitTestCase
...) Using something else (not CiviUnitTestsCase
) would make the suite more... nuanced/diverse.
I think your suggestion has better-than-even odds of working, but I don't want to put that issue question in this scope-of-work.
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.
yup I think you can just ignore this note ... because away from diversity thing you had talked about ... it would time consuming to use PHPUnit_Framework_TestCase instead of CiviUnitTestCase for these tests .
} | ||
$this->assertEquals(1, $count); | ||
} | ||
|
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.
maybe a negative test could be added where neither mailingId or mailingObject is provided .
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.
Good idea
During development of FlexMailer, I flirted with using a special token (e.g. `{actions.trackOpen}`) but ultimately found that was positioned well in the order of operations.
@omarabuhussein Thanks for the review. I've pushed updates for the unused function and the negative test scenario. Unless the style issues seem critical, I'm inclined to merge on pass. |
Thanks @totten ... the style issues is not critical but I replied to your point though .. not sure what are u going to decide but the generally it is approved . |
This is an offshoot from the conversation on civicrm#9563.
This includes support for both
{mailing.*}
and{action.*}
tokens usedin CiviMail -- and includes a performance optimization to ignore unused
tokens in
AbstractTokenSubscriber
.Notably, this provides support for CiviMail tokens in
TokenProcessor
...but the CiviMail engine will not use
TokenProcessor
. Rather, this helpsother/future delivery-engines (such as the upcoming FlexMailer) get access to
the CiviMail tokens. The existing CiviMail engine should remain unchanged.