/**
  * The function checks and updates the status of all membership records for a given domain using the
  * calc_membership_status and update_contact_membership APIs.
  *
  * IMPORTANT:
  * It uses the default Domain FROM Name and FROM Email Address as the From email address for emails sent by this api.
  * Verify that this value has been properly set from Administer > Configure > Domain Information
  * If you want to use some other FROM email address, modify line 125 and set your valid email address.
  *
  * @return array $result
  * @access public
  */
 static function updateAllMembershipStatus()
 {
     require_once 'api/api.php';
     //get all active statuses of membership, CRM-3984
     $allStatus = CRM_Member_PseudoConstant::membershipStatus();
     $statusLabels = CRM_Member_PseudoConstant::membershipStatus(NULL, NULL, 'label');
     $allTypes = CRM_Member_PseudoConstant::membershipType();
     $contribStatus = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
     $query = "\nSELECT     civicrm_membership.id                    as membership_id,\n           civicrm_membership.is_override           as is_override,\n           civicrm_membership.reminder_date         as reminder_date,\n           civicrm_membership.membership_type_id    as membership_type_id,\n           civicrm_membership.status_id             as status_id,\n           civicrm_membership.join_date             as join_date,\n           civicrm_membership.start_date            as start_date,\n           civicrm_membership.end_date              as end_date,\n           civicrm_membership.source                as source,\n           civicrm_contact.id                       as contact_id,\n           civicrm_contact.is_deceased              as is_deceased,\n           civicrm_membership.owner_membership_id   as owner_membership_id,\n           civicrm_membership.contribution_recur_id as recur_id\nFROM       civicrm_membership\nINNER JOIN civicrm_contact ON ( civicrm_membership.contact_id = civicrm_contact.id )\nWHERE      civicrm_membership.is_test = 0";
     $params = array();
     $dao = CRM_Core_DAO::executeQuery($query, $params);
     $today = date("Y-m-d");
     $processCount = 0;
     $updateCount = 0;
     $reminderCount = 0;
     $smarty = CRM_Core_Smarty::singleton();
     $domainValues = CRM_Core_BAO_Domain::getNameAndEmail();
     $domainFromEmail = "{$domainValues['0']} <{$domainValues['1']}>";
     //use domain email address as a default From email.
     $fromEmailAddress = $domainFromEmail;
     while ($dao->fetch()) {
         // echo ".";
         $processCount++;
         /**
                $count++;
                echo $dao->contact_id . ', '. CRM_Utils_System::memory( ) . "<p>\n";
         
                CRM_Core_Error::debug( 'fBegin', count( $GLOBALS['_DB_DATAOBJECT']['RESULTS'] ) );
                if ( $count > 2 ) {
                foreach ( $GLOBALS['_DB_DATAOBJECT']['RESULTS'] as $r ) {
                CRM_Core_Error::debug( 'r', $r->query );
                }
                // CRM_Core_Error::debug( 'f', $GLOBALS['_DB_DATAOBJECT']['RESULTS'] );
                exit( );
                }
                **/
         // Put common parameters into array for easy access
         $memberParams = array('id' => $dao->membership_id, 'status_id' => $dao->status_id, 'contact_id' => $dao->contact_id, 'membership_type_id' => $dao->membership_type_id, 'membership_type' => $allTypes[$dao->membership_type_id], 'join_date' => $dao->join_date, 'start_date' => $dao->start_date, 'end_date' => $dao->end_date, 'reminder_date' => $dao->reminder_date, 'source' => $dao->source, 'skipStatusCal' => TRUE, 'skipRecentView' => TRUE);
         $smarty->assign_by_ref('memberParams', $memberParams);
         //update membership record to Deceased if contact is deceased
         if ($dao->is_deceased) {
             // check for 'Deceased' membership status, CRM-5636
             $deceaseStatusId = array_search('Deceased', $allStatus);
             if (!$deceaseStatusId) {
                 CRM_Core_Error::fatal(ts("Deceased Membership status is missing or not active. <a href='%1'>Click here to check</a>.", array(1 => CRM_Utils_System::url('civicrm/admin/member/membershipStatus', 'reset=1'))));
             }
             //process only when status change.
             if ($dao->status_id != $deceaseStatusId) {
                 //take all params that need to save.
                 $deceasedMembership = $memberParams;
                 $deceasedMembership['status_id'] = $deceaseStatusId;
                 $deceasedMembership['createActivity'] = TRUE;
                 $deceasedMembership['version'] = 3;
                 //since there is change in status.
                 $statusChange = array('status_id' => $deceaseStatusId);
                 $smarty->append_by_ref('memberParams', $statusChange, TRUE);
                 //process membership record.
                 civicrm_api('membership', 'create', $deceasedMembership);
             }
             continue;
         }
         //we fetch related, since we need to check for deceased
         //now further processing is handle w/ main membership record.
         if ($dao->owner_membership_id) {
             continue;
         }
         //update membership records where status is NOT - Pending OR Cancelled.
         //as well as membership is not override.
         //skipping Expired membership records -> reduced extra processing( kiran )
         if (!$dao->is_override && !in_array($dao->status_id, array(array_search('Pending', $allStatus), array_search('Cancelled', $allStatus), array_search('Expired', $allStatus)))) {
             // CRM-7248: added excludeIsAdmin param to the following fn call to prevent moving to admin statuses
             //get the membership status as per id.
             $newStatus = civicrm_api('membership_status', 'calc', array('membership_id' => $dao->membership_id, 'version' => 3, 'ignore_admin_only' => FALSE), TRUE);
             $statusId = CRM_Utils_Array::value('id', $newStatus);
             //process only when status change.
             if ($statusId && $statusId != $dao->status_id) {
                 //take all params that need to save.
                 $memParams = $memberParams;
                 $memParams['status_id'] = $statusId;
                 $memParams['createActivity'] = TRUE;
                 $memParams['version'] = 3;
                 //since there is change in status.
                 $statusChange = array('status_id' => $statusId);
                 $smarty->append_by_ref('memberParams', $statusChange, TRUE);
                 //process member record.
                 civicrm_api('membership', 'create', $memParams);
                 $updateCount++;
             }
         }
         //convert date from string format to timestamp format
         $reminder_date = CRM_Utils_DATE::unixTime($dao->reminder_date);
         $today_date = CRM_Utils_DATE::unixTime($today);
         //send reminder for membership renewal
         if ($dao->reminder_date && $dao->reminder_date != '0000-00-00' && $reminder_date <= $today_date) {
             $memType = new CRM_Member_BAO_MembershipType();
             $memType->id = $dao->membership_type_id;
             $memType->find(TRUE);
             $renewalMsgId = $memType->renewal_msg_id;
             if ($memType->autorenewal_msg_id && $dao->recur_id) {
                 $contribStatusId = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_ContributionRecur', $dao->recur_id, 'contribution_status_id');
                 if ($contribStatusId != array_search('Cancelled', $contribStatus)) {
                     $renewalMsgId = $memType->autorenewal_msg_id;
                 }
             }
             if ($renewalMsgId) {
                 $toEmail = CRM_Contact_BAO_Contact::getPrimaryEmail($dao->contact_id);
                 if ($toEmail) {
                     $sendResult = CRM_Core_BAO_MessageTemplates::sendReminder($dao->contact_id, $toEmail, $renewalMsgId, $fromEmailAddress);
                     if (!$sendResult || is_a($sendResult, 'PEAR_Error')) {
                         // we could not send an email, for now we ignore
                         // CRM-3406
                         // at some point we might decide to do something
                     } else {
                         $reminderCount++;
                     }
                     //set membership reminder date to NULL since we've sent the reminder.
                     CRM_Core_DAO::setFieldValue('CRM_Member_DAO_Membership', $dao->membership_id, 'reminder_date', 'null');
                     // insert the activity log record.
                     $config = CRM_Core_Config::singleton();
                     $activityParams = array();
                     $activityParams['subject'] = $allTypes[$dao->membership_type_id] . ": Status - " . $statusLabels[$newStatus['id']] . ", End Date - " . CRM_Utils_Date::customFormat(CRM_Utils_Date::isoToMysql($dao->end_date), $config->dateformatFull);
                     $activityParams['source_record_id'] = $dao->membership_id;
                     $session = CRM_Core_Session::singleton();
                     $activityParams['source_contact_id'] = $session->get('userID') ? $session->get('userID') : $dao->contact_id;
                     $activityParams['assignee_contact_id'] = $dao->contact_id;
                     $activityParams['activity_date_time'] = date('YmdHis');
                     static $actRelIds = array();
                     if (!isset($actRelIds['activity_type_id'])) {
                         $actRelIds['activity_type_id'] = CRM_Core_OptionGroup::getValue('activity_type', 'Membership Renewal Reminder', 'name');
                     }
                     $activityParams['activity_type_id'] = $actRelIds['activity_type_id'];
                     if (!isset($actRelIds['activity_status_id'])) {
                         $actRelIds['activity_status_id'] = CRM_Core_OptionGroup::getValue('activity_status', 'Completed', 'name');
                     }
                     $activityParams['status_id'] = $actRelIds['activity_status_id'];
                     static $msgTpl = array();
                     if (!isset($msgTpl[$memType->renewal_msg_id])) {
                         $msgTpl[$memType->renewal_msg_id] = array();
                         $messageTemplate = new CRM_Core_DAO_MessageTemplates();
                         $messageTemplate->id = $memType->renewal_msg_id;
                         if ($messageTemplate->find(TRUE)) {
                             $msgTpl[$memType->renewal_msg_id]['subject'] = $messageTemplate->msg_subject;
                             $msgTpl[$memType->renewal_msg_id]['details'] = $messageTemplate->msg_text;
                         }
                         $messageTemplate->free();
                     }
                     $activityParams['details'] = "Subject: {$msgTpl[$memType->renewal_msg_id]['subject']}\nMessage: {$msgTpl[$memType->renewal_msg_id]['details']}\n";
                     $activity = CRM_Activity_BAO_Activity::create($activityParams);
                 }
             }
             $memType->free();
         }
         // CRM_Core_Error::debug( 'fEnd', count( $GLOBALS['_DB_DATAOBJECT']['RESULTS'] ) );
     }
     $result['is_error'] = 0;
     $result['messages'] = ts('Processed %1 membership records. Updated %2 records. Sent %3 renewal reminders.', array(1 => $processCount, 2 => $updateCount, 3 => $reminderCount));
     return $result;
 }