CRM-15444 fix crash on membership renewals due to ->id not being set
authorEileen McNaughton <eileen@fuzion.co.nz>
Tue, 14 Oct 2014 00:58:32 +0000 (13:58 +1300)
committerEileen McNaughton <eileen@fuzion.co.nz>
Mon, 27 Oct 2014 02:41:56 +0000 (15:41 +1300)
CRM/Contribute/BAO/Contribution.php
CRM/Core/Payment/BaseIPN.php

index 63c501a683efef982e150b2af9e5dcd01c3645cb..116f948030d14a49645291b2c690f520f2f19f1d 100644 (file)
@@ -270,21 +270,19 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution {
    * based on querying the line item table and relevant price field values
    * Note that any one contribution should only be able to have one line item relating to a particular membership
    * type
+   *
    * @param int $membershipTypeID
    *
+   * @param int $contributionID
+   *
    * @return int
    */
-  public function getNumTermsByContributionAndMembershipType($membershipTypeID) {
-    if (!is_numeric($membershipTypeID)) {
-      //precautionary measure - this is being introduced to a mature release hence adding extra checks that
-      // might be removed later
-      return 1;
-    }
-    $numTerms = CRM_Core_DAO::singleValueQuery("
+  public function getNumTermsByContributionAndMembershipType($membershipTypeID, $contributionID) {
+     $numTerms = CRM_Core_DAO::singleValueQuery("
       SELECT membership_num_terms FROM civicrm_line_item li
       LEFT JOIN civicrm_price_field_value v ON li.price_field_value_id = v.id
       WHERE contribution_id = %1 AND membership_type_id = %2",
-      array(1 => array($this->id, 'Integer') , 2 => array($membershipTypeID, 'Integer'))
+      array(1 => array($contributionID, 'Integer') , 2 => array($membershipTypeID, 'Integer'))
     );
     // default of 1 is precautionary
     return empty($numTerms) ? 1 : $numTerms;
index 0bd519486f9338d74352c7c33dd5ec79144f7af3..db7b62c65089669952ad76902dc5f2b81a857ad4 100644 (file)
@@ -107,7 +107,12 @@ class CRM_Core_Payment_BaseIPN {
     if (!$this->loadObjects($input, $ids, $objects, $required, $paymentProcessorID)) {
       return FALSE;
     }
-
+    //the process is that the loadObjects is kind of hacked by loading the objects for the original contribution and then somewhat inconsistently using them for the
+    //current contribution. Here we ensure that the original contribution is available to the complete transaction function
+    //we don't want to fix this in the payment processor classes because we would have to fix all of them - so better to fix somewhere central
+    if (isset($objects['contributionRecur'])) {
+      $objects['first_contribution'] = $objects['contribution'];
+    }
     return TRUE;
   }
 
@@ -337,6 +342,9 @@ class CRM_Core_Payment_BaseIPN {
    */
   function completeTransaction(&$input, &$ids, &$objects, &$transaction, $recur = FALSE) {
     $contribution = &$objects['contribution'];
+
+    $primaryContributionID = isset($contribution->id) ? $contribution->id : $objects['first_contribution']->id;
+
     $memberships = &$objects['membership'];
     if (is_numeric($memberships)) {
       $memberships = array($objects['membership']);
@@ -403,7 +411,7 @@ LIMIT 1;";
             // else fall back to using current membership type
             $dao->free();
 
-            $num_terms = $contribution->getNumTermsByContributionAndMembershipType($membership->membership_type_id);
+            $num_terms = $contribution->getNumTermsByContributionAndMembershipType($membership->membership_type_id, $primaryContributionID);
             if ($currentMembership) {
               /*
                * Fixed FOR CRM-4433