-
-
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
Fix addVars to allow adding vars to billing-block #18141
Conversation
(Standard links)
|
@mattwire style issue |
Code looks good to me. |
dd09a92
to
7974a6c
Compare
7974a6c
to
99c6336
Compare
@mattwire - So @eileenmcnaughton gave this testing suggestion for the original problem/motivation. I'm not really able to reproduce the problem/solution. Steps:
Based on the two configurations of the contribution-page, and based on the 4 revisions of code, that gives 8 different test-scenarios. I tested in Firefox 78.0.1 (macOS). In all 8 cases, I observed the same behavior:
Going a step further, I used the browser console to get a fully-formed
The content of these pages was identical in 99c6336 (this PR/branch) and e1c19ea (ie the immediate predecessor). So tldr: can't see how to reproduce |
@totten Ok, it's a bit tricky to reproduce but hopefully obvious once you realise what is going on. You won't be able to reproduce directly with the PR for omnipay or using Stripe because they're both using workarounds to avoid the problem (as they need to until we have something like this PR in core). For Stripe this is the bit of code that would change, and that contains the workaround:
addVars defaults to no region which means it will either get put in With this PR, or a similar one based on the work you are doing for bundles, you can specify |
Great, thanks for the description @mattwire. So to function delme_civicrm_config(&$config) {
_delme_civix_civicrm_config($config);
static $run = 0;
if ($run) return;
$run = 1;
CRM_Core_Resources::singleton()
->addVars('delme', ['time' => CRM_Utils_Time::getTime()], 'billing-block');
CRM_Core_Region::instance('billing-block')->add([
'script' => 'cj("#billing-payment-block").prepend("time="+CRM.vars.delme.time);'
]);
} Then I added two dummy payment processors on a contribution page. When switching between the payment processors, it should redraw the billing-block with an injected timestamp: This worked as expected:
|
Ohh that's aa cool way to test - I wish we could add that into CI but then it would be testing js + php together which seems hard |
} | ||
// For an ajax request we append to it | ||
else { | ||
$js = 'CRM.$.extend(true, CRM, ' . json_encode($this->getSettings()) . ');'; | ||
$js = 'CRM.$.extend(true, CRM, ' . json_encode($this->getSettings($region)) . ');'; |
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.
@colemanw @mattwire I know this is a bit of a pre-existing issue, but that conditional (if... $region === 'html-header' || ...
) is growing a bit magical. Would it be possible to either:
- Have one JS fragment that's more clever ("if
CRM
exists, then merge data -- else initialize anew."). - Simplify the rule: the only time to use
var CRM=...
is inhtml-header
. (If you use it at any other time, whether AJAX or non-AJAX, won't it produce problems?)$loader = ($region === 'html-header') ? 'var CRM = %s;' : 'CRM.$.extend(true, CRM, %s);'; $js = sprintf($loader, json_encode($this->getSettings($region))); $html .= sprintf("<script type=\"text/javascript\">\n%s\n</script>\n", $js);
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 don't think 2 would work - if a processor needs to inject code it won't necessarily have the chance to do so in html-header - because processor forms are often loaded when the processor is selected, or by webform
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've thought about getting rid of || !isAjaxMode()
because I also think it is superfluous. That might be a good goal to do before making other changes per this #18141, #18247.
In drupal 7 the html-header is always rendered if we are on a civicrm-ified page (eg. drupal_webform). But the renderSetting and definition of var CRM
is not always called. It does get called if you specify a payment processor on the webform because CRM.config.creditCardTypes
gets added which triggers the render settings code.
See: https://github.com/civicrm/civicrm-drupal/blob/7.x-master/civicrm.module#L156
As I understand it, if a payment processor is going to be loaded we will have html-header
, it's just that html-header
is static across payment processor changes so it can't be re-used by the processor (as you've cleverly reproduced in the timestamp example).
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 agree we should remove the magic region condition here. How about moving the condition to js:
I need to verify if this is superseded by #18262 |
cool - I'll close & if still required you can rebase & re-open |
Overview
@eileenmcnaughton I think this fixes the issues with paypal checkout / omnipay that we've encountered with js errors.
Specifically: eileenmcnaughton/nz.co.fuzion.omnipaymultiprocessor@b9d5719
CRM_Core_Resources::singleton()->addVars('omnipay', $jsVariables, 'billing-block');
or equivalent\Civi::resources()->addVars('omnipay', $jsVariables, 'billing-block');
does not work when adding viaCRM_Core_Payment_XX::buildForm()
because it defines CRM instead of extending it when the payment processor is the default on the page. It does not cause problems when the processor adding vars is not the default.This is because of load order - the billing-block gets "rendered" in PHP before html-header which doesn't work when the form actually loads because the js on the form then tries to extend CRM before it is defined and triggers a chain of js errors.
Lost yet?
Before
Cannot use addVars to add variables to billing-block when payment processor is default on the page.
After
Can use addVars to add variables to billingblock in all situations without issues.
Technical Details
Explained above I think!
Comments
The tests should help show what is expected to be rendered.