Uploaded image for project: 'CiviCRM'
  1. CiviCRM
  2. CRM-19094

cid=0 membership contribution form can overwrite data of an existing membership


    • Documentation Required?:
    • Funding Source:
      Core Team Funds


      Creating a new membership using a front-end contribution form with cid=0 can, under some circumstances, overwrite the information of an unrelated membership record if the membership_id of the existing membership record is the same as the contribution_id of the newly-created contribution record.

      If there is no existing membership record whose membership_id as the new contribution_id, there is no issue.

      I can reproduce this on our test site. After completing the "new membership" form with cid=0, there are three new entries created in the civicrm_membership_log table. Two have the membership_id of the newly-created membership; the third has a different membership_id, which is that of an older existing membership. The data in that membership is overwritten with that of the newly submitted membership. And, in several tests, the overwritten membership_id always matches the contribution_id of the form submission.

      There are also two records created in table membership_payment, one with the correct (new) membership, the other with the membership_id (incorrectly) matching the contribution_id.

      It's an insidious bug because each occurrence will silently corrupt an existing membership record. But you need to have a membership_id at least as high as the next contribution_id for it to manifest. (We have more memberships than contributions, so it does.)

      I think I may have found a logic error that, at least, leads to the duplicate membership_payment entry. In
      file: civicrm/CRM/Price/BAO/LineItem.php
      function: processPriceSet($entityId, $lineItem, $contributionDetails = NULL, $entityTable = 'civicrm_contribution', $update = FALSE)

      This function beginning at line 422 gets called with $entityId set to the contribution_id and $entityTable set to 'civicrm_contribution'.

      But down at line 439, we have:

      if (!empty($line['membership_type_id']))

      { $line['entity_table'] = 'civicrm_membership'; }

      For a membership form, $line['membership_type_id'] is, in fact, non-empty, so $line['entity_table'] does get set to 'civicrm_membership'. But $line['entity_id'] is left at its original value, that of the contribution_id.

      So that, at line 454, we have

      $lineItems = CRM_Price_BAO_LineItem::create($line);

      which, I infer, would create a new entry related to a membership record whose membership_id is equal to the contribution_id.

      Sorry I can't pin it down more closely, but I hope that is something to go on. (Note, this is same use case, but different behavior, than https://issues.civicrm.org/jira/browse/CRM-19092.)




            • Assignee:
              monish.deb Monish Deb
              rjlang Robert J. Lang
            • Votes:
              0 Vote for this issue
              3 Start watching this issue


              • Created: