convert to central function
[civicrm-core.git] / CRM / Member / BAO / Membership.php
index 32ff6e0259103ba0c1ac2267c8deb379aa55984b..16f57a2f264811824773da3c2418447530e03a0b 100644 (file)
@@ -250,11 +250,26 @@ class CRM_Member_BAO_Membership extends CRM_Member_DAO_Membership {
     // eg pay later membership, membership update cron CRM-3984
 
     if (empty($params['is_override']) && empty($params['skipStatusCal'])) {
-      // @todo - we should be able to count on dates being correctly formatted by they time they hit the BAO.
-      // Maybe do some tests & throw some deprecation warnings if they aren't?
-      $params['start_date'] = trim($params['start_date']) ? date('Ymd', strtotime(trim($params['start_date']))) : 'null';
-      $params['end_date'] = trim($params['end_date']) ? date('Ymd', strtotime(trim($params['end_date']))) : 'null';
-      $params['join_date'] = trim($params['join_date']) ? date('Ymd', strtotime(trim($params['join_date']))) : 'null';
+      $fieldsToLoad = [];
+      foreach (['start_date', 'end_date', 'join_date'] as $dateField) {
+        if (!empty($params[$dateField]) && $params[$dateField] !== 'null' && strpos($params[$dateField], date('Ymd', strtotime(trim($params[$dateField])))) !== 0) {
+          $params[$dateField] = date('Ymd', strtotime(trim($params[$dateField])));
+          // @todo enable this once core is using the api.
+          // CRM_Core_Error::deprecatedWarning('Relying on the BAO to clean up dates is deprecated. Call membership create via the api');
+        }
+        if (!empty($params['id']) && empty($params[$dateField])) {
+          $fieldsToLoad[] = $dateField;
+        }
+      }
+      if (!empty($fieldsToLoad)) {
+        $membership = civicrm_api3('Membership', 'getsingle', ['id' => $params['id'], 'return' => $fieldsToLoad]);
+        foreach ($fieldsToLoad as $fieldToLoad) {
+          $params[$fieldToLoad] = $membership[$fieldToLoad];
+        }
+      }
+      $params['start_date'] = $params['start_date'] ?: 'null';
+      $params['end_date'] = $params['end_date'] ?: 'null';
+      $params['join_date'] = $params['join_date'] ?: 'null';
 
       //fix for CRM-3570, during import exclude the statuses those having is_admin = 1
       $excludeIsAdmin = $params['exclude_is_admin'] ?? FALSE;
@@ -320,12 +335,14 @@ class CRM_Member_BAO_Membership extends CRM_Member_DAO_Membership {
     $params['skipLineItem'] = TRUE;
 
     // Record contribution for this membership and create a MembershipPayment
+    // @todo deprecate this.
     if (!empty($params['contribution_status_id']) && empty($params['relate_contribution_id'])) {
       $memInfo = array_merge($params, ['membership_id' => $membership->id]);
       $params['contribution'] = self::recordMembershipContribution($memInfo);
     }
 
     // Add/update MembershipPayment record for this membership if it is a related contribution
+    // @todo remove this - called from one remaining place in CRM_Member_Form_Membership
     if (!empty($params['relate_contribution_id'])) {
       $membershipPaymentParams = [
         'membership_id' => $membership->id,
@@ -1125,13 +1142,13 @@ AND civicrm_membership.is_test = %2";
    *   Reference to the array.
    *   containing all values of
    *   the current membership
-   * @param string $changeToday
+   * @param string|null $changeToday
    *   In case today needs
    *   to be customised, null otherwise
    *
    * @throws \CRM_Core_Exception
    */
-  public static function fixMembershipStatusBeforeRenew(&$currentMembership, $changeToday) {
+  public static function fixMembershipStatusBeforeRenew(&$currentMembership, $changeToday = NULL) {
     $today = 'now';
     if ($changeToday) {
       $today = CRM_Utils_Date::processDate($changeToday, NULL, FALSE, 'Y-m-d');
@@ -1151,8 +1168,6 @@ AND civicrm_membership.is_test = %2";
       throw new CRM_Core_Exception(ts('Oops, it looks like there is no valid membership status corresponding to the membership start and end dates for this membership. Contact the site administrator for assistance.'));
     }
 
-    $currentMembership['today_date'] = $today;
-
     if ($status['id'] !== $currentMembership['status_id']) {
       $oldStatus = $currentMembership['status_id'];
       $memberDAO = new CRM_Member_DAO_Membership();
@@ -1181,10 +1196,7 @@ AND civicrm_membership.is_test = %2";
           $currentMembership['end_date'],
           $format
         ),
-        'modified_date' => CRM_Utils_Date::customFormat(
-          $currentMembership['today_date'],
-          $format
-        ),
+        'modified_date' => date('Y-m-d H:i:s', strtotime($today)),
         'membership_type_id' => $currentMembership['membership_type_id'],
         'max_related' => $currentMembership['max_related'] ?? 0,
       ];
@@ -1316,7 +1328,7 @@ WHERE  civicrm_membership.contact_id = civicrm_contact.id
    * @throws \CiviCRM_API3_Exception
    */
   public static function createRelatedMemberships($params, $dao) {
-
+    unset($params['membership_id']);
     $membership = new CRM_Member_DAO_Membership();
     $membership->id = $dao->id;
 
@@ -1453,11 +1465,10 @@ WHERE  civicrm_membership.contact_id = civicrm_contact.id
         // CRM-20966: Do not create membership_payment record for inherited membership.
         unset($params['relate_contribution_id']);
 
-        $ids = [];
         if (($params['status_id'] == $deceasedStatusId) || ($params['status_id'] == $expiredStatusId)) {
           // related membership is not active so does not count towards maximum
           if (!self::hasExistingInheritedMembership($params)) {
-            CRM_Member_BAO_Membership::create($params);
+            civicrm_api3('Membership', 'create', $params);
           }
         }
         else {
@@ -1518,7 +1529,10 @@ WHERE  civicrm_membership.contact_id = civicrm_contact.id
   }
 
   /**
-   * Build an array of available membership types.
+   * Build an array of available membership types in the current context.
+   *
+   * While core does not do anything context specific extensions may filter
+   * or alter amounts based on user details.
    *
    * @param CRM_Core_Form $form
    * @param array $membershipTypeID
@@ -1533,7 +1547,7 @@ WHERE  civicrm_membership.contact_id = civicrm_contact.id
    */
   public static function buildMembershipTypeValues($form, $membershipTypeID = [], $activeOnly = FALSE) {
     $membershipTypeIDS = (array) $membershipTypeID;
-    $membershipTypeValues = CRM_Member_BAO_MembershipType::getPermissionedMembershipTypes();
+    $membershipTypeValues = CRM_Member_BAO_MembershipType::getAllMembershipTypes();
 
     // MembershipTypes are already filtered by domain, filter as appropriate by is_active & a passed in list of ids.
     foreach ($membershipTypeValues as $id => $type) {
@@ -1545,13 +1559,6 @@ WHERE  civicrm_membership.contact_id = civicrm_contact.id
     }
 
     CRM_Utils_Hook::membershipTypeValues($form, $membershipTypeValues);
-
-    if (is_numeric($membershipTypeID) &&
-      $membershipTypeID > 0
-    ) {
-      CRM_Core_Error::deprecatedFunctionWarning('Non arrays deprecated');
-      return $membershipTypeValues[$membershipTypeID];
-    }
     return $membershipTypeValues;
   }
 
@@ -1756,7 +1763,7 @@ INNER JOIN  civicrm_contact contact ON ( contact.id = membership.contact_id AND
    * @param int $contributionRecurID
    * @param $membershipSource
    * @param $isPayLater
-   * @param int $campaignId
+   * @param array $memParams
    * @param array $formDates
    * @param null|CRM_Contribute_BAO_Contribution $contribution
    * @param array $lineItems
@@ -1765,7 +1772,7 @@ INNER JOIN  civicrm_contact contact ON ( contact.id = membership.contact_id AND
    * @throws \CRM_Core_Exception
    * @throws \CiviCRM_API3_Exception
    */
-  public static function processMembership($contactID, $membershipTypeID, $is_test, $changeToday, $modifiedID, $customFieldsFormatted, $numRenewTerms, $membershipID, $pending, $contributionRecurID, $membershipSource, $isPayLater, $campaignId, $formDates = [], $contribution = NULL, $lineItems = []) {
+  public static function processMembership($contactID, $membershipTypeID, $is_test, $changeToday, $modifiedID, $customFieldsFormatted, $numRenewTerms, $membershipID, $pending, $contributionRecurID, $membershipSource, $isPayLater, $memParams = [], $formDates = [], $contribution = NULL, $lineItems = []) {
     $renewalMode = $updateStatusId = FALSE;
     $allStatus = CRM_Member_PseudoConstant::membershipStatus();
     $format = '%Y%m%d';
@@ -1791,7 +1798,7 @@ INNER JOIN  civicrm_contact contact ON ( contact.id = membership.contact_id AND
         array_search('Cancelled', CRM_Member_PseudoConstant::membershipStatus(NULL, " name = 'Cancelled' ", 'name', FALSE, TRUE)),
       ])) {
 
-        $memParams = [
+        $memParams = array_merge([
           'id' => $currentMembership['id'],
           'contribution' => $contribution,
           'status_id' => $currentMembership['status_id'],
@@ -1802,7 +1809,7 @@ INNER JOIN  civicrm_contact contact ON ( contact.id = membership.contact_id AND
           'membership_type_id' => $membershipTypeID,
           'max_related' => !empty($membershipTypeDetails['max_related']) ? $membershipTypeDetails['max_related'] : NULL,
           'membership_activity_status' => ($pending || $isPayLater) ? 'Scheduled' : 'Completed',
-        ];
+        ], $memParams);
         if ($contributionRecurID) {
           $memParams['contribution_recur_id'] = $contributionRecurID;
         }
@@ -1841,7 +1848,7 @@ INNER JOIN  civicrm_contact contact ON ( contact.id = membership.contact_id AND
         if (!empty($currentMembership['id'])) {
           $ids['membership'] = $currentMembership['id'];
         }
-        $memParams = $currentMembership;
+        $memParams = array_merge($currentMembership, $memParams);
         $memParams['membership_type_id'] = $membershipTypeID;
 
         //set the log start date.
@@ -1861,7 +1868,6 @@ INNER JOIN  civicrm_contact contact ON ( contact.id = membership.contact_id AND
         );
 
         // Insert renewed dates for CURRENT membership
-        $memParams = [];
         $memParams['join_date'] = CRM_Utils_Date::isoToMysql($membership->join_date);
         $memParams['start_date'] = $formDates['start_date'] ?? CRM_Utils_Date::isoToMysql($membership->start_date);
         $memParams['end_date'] = $formDates['end_date'] ?? NULL;
@@ -1892,10 +1898,10 @@ INNER JOIN  civicrm_contact contact ON ( contact.id = membership.contact_id AND
     }
     else {
       // NEW Membership
-      $memParams = [
+      $memParams = array_merge([
         'contact_id' => $contactID,
         'membership_type_id' => $membershipTypeID,
-      ];
+      ], $memParams);
 
       if (!$pending) {
         $dates = CRM_Member_BAO_MembershipType::getDatesForMembershipType($membershipTypeID, NULL, NULL, NULL, $numRenewTerms);
@@ -1958,11 +1964,6 @@ INNER JOIN  civicrm_contact contact ON ( contact.id = membership.contact_id AND
     }
     $params['modified_id'] = $modifiedID ?? $contactID;
 
-    //inherit campaign from contrib page.
-    if (isset($campaignId)) {
-      $memParams['campaign_id'] = $campaignId;
-    }
-
     $memParams['contribution'] = $contribution;
     $memParams['custom'] = $customFieldsFormatted;
     // Load all line items & process all in membership. Don't do in contribution.
@@ -2406,7 +2407,6 @@ WHERE {$whereClause}";
    * @throws \CiviCRM_API3_Exception
    */
   public static function recordMembershipContribution(&$params) {
-    $membershipId = $params['membership_id'];
     $contributionParams = [];
     $config = CRM_Core_Config::singleton();
     $contributionParams['currency'] = $config->defaultCurrency;
@@ -2488,7 +2488,7 @@ WHERE {$whereClause}";
     ]);
     if (empty($membershipPayment['count'])) {
       civicrm_api3('MembershipPayment', 'create', [
-        'membership_id' => $membershipId,
+        'membership_id' => $params['membership_id'],
         'contribution_id' => $contribution->id,
       ]);
     }