Skip to content
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/core#2425 - php 7.4 - E_NOTICE every time you save a contribution #19978

Merged
merged 1 commit into from
Apr 7, 2021

Conversation

demeritcowboy
Copy link
Contributor

Overview

https://lab.civicrm.org/dev/core/-/issues/2425

Before

  1. Use php 7.4
  2. Make a contribution in the backend.
  3. Save it.

Notice: Trying to access array offset on value of type null in CRM_Contribute_Form_Contribution::formRule() (line 915 of CRM\Contribute\Form\Contribution.php).

After

No notice.

If you want to check that the financial account validation is still working you can:

  1. Turn on deferred revenue in civicontribute settings.
  2. Make a contribution with a price set that uses a financial type that doesn't have a corresponding deferred revenue account, like Donation by default.
  3. Enter a recognition date on the form.
  4. You should get an alert box validation error.

Technical Details

See lab ticket. The gist is to not calculate the line items from the _priceSet variable which is missing and instead get the line items from the order and pass it in.

In terms of the affected scope:

  • If deferred revenue isn't enabled nothing changes and it just returns early.
  • If you don't fill in a recognition date, nothing changes it just returns early.
  • If it's a new contribution and you don't use a price set, the line items are empty and both before and after it skips trying to get them (line 401), so again nothing changes.
  • When you're editing a contribution, I'm not sure what 'prevContribution' is or when it would be present, but when it isn't then again it returns early.
  • checkFinancialTypeHasDeferred() is only called from the one place in the contribution formRule, in core at least.
  • In the call to processAmount() before, $params was passed by reference and updated, however it's never used again in checkFinancialTypeHasDeferred() and was passed into there by value, so removing the call to processAmount() doesn't change that.
  • The purpose of calling processAmount() was to get the line items, but we already have it now.
  • The only element of the line item it actually uses is the financial_type_id.

So the scope is pretty limited. It might miss the validation warning if for some reason the order'ized version of the line items is somehow different than before. I don't know enough about it so I'm just assuming it always matches up.

I'm sure there is more here to clean up but I really just want the problem to go away since it comes up every single time you save a contribution.

Comments

Has test. Note it passes on php 7.3 or lower even before the patch, but fails on php 7.4.

@civibot
Copy link

civibot bot commented Apr 6, 2021

(Standard links)

}
if (!empty($items)) {
$lineItems[] = $items;
if (!empty($orderLineItems)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need the if (!empty ) here - I feel like it has carried over from the original but I suspect it is no longer needed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I change the function signature to default [] instead of null then I think that would be ok, since then the loop won't choke iterating over null.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah - it looks like the only 'live' call to this would always pass an array but the test calls don't

@@ -399,15 +399,8 @@ public static function checkFinancialTypeHasDeferred($params, $contributionID =
$financialTypeID = $params['prevContribution']->financial_type_id;
}
if (($contributionID || !empty($params['price_set_id'])) && empty($lineItems)) {
if (!$contributionID) {
CRM_Price_BAO_PriceSet::processAmount($priceSetFields,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel so happy seeing the demise of this line

@monishdeb
Copy link
Member

Tested on test build http://core-19978-75go.test-1.civicrm.org:8001/ (cred - admin / aPshklfG1cPf), on contribution back office form, encountered no regression or breakage. Reviewed the patch looks good to me. Added unit-test passed on php 7.4 on my local m/c. Hence merging the PR

@monishdeb monishdeb merged commit fb1057e into civicrm:master Apr 7, 2021
@demeritcowboy
Copy link
Contributor Author

Thanks! @monishdeb

@demeritcowboy demeritcowboy deleted the php74-contribution branch April 7, 2021 18:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants