_single = FALSE; $className = CRM_Utils_System::getClassName($form); if (property_exists($form, '_context') && $form->_context != 'search' && $className == 'CRM_Contact_Form_Task_SMS' ) { $form->_single = TRUE; } $providersCount = CRM_SMS_BAO_Provider::activeProviderCount(); if (!$providersCount) { CRM_Core_Error::statusBounce(ts('There are no SMS providers configured, or no SMS providers are set active')); } if ($className == 'CRM_Activity_Form_Task_SMS') { $activityCheck = 0; foreach ($form->_activityHolderIds as $value) { if (CRM_Core_DAO::getFieldValue('CRM_Activity_DAO_Activity', $value, 'subject', 'id') != self::RECIEVED_SMS_ACTIVITY_SUBJECT) { $activityCheck++; } } if ($activityCheck == count($form->_activityHolderIds)) { CRM_Core_Error::statusBounce(ts("The Reply SMS Could only be sent for activities with '%1' subject.", array(1 => self::RECIEVED_SMS_ACTIVITY_SUBJECT) )); } } } /** * Build the form * * @access public * * @return void */ static function buildQuickForm(&$form) { $toArray = array(); $form->assign('max_sms_length', CRM_SMS_Provider::MAX_SMS_CHAR); $providers = CRM_SMS_BAO_Provider::getProviders(NULL, NULL, TRUE, 'is_default desc'); $providerSelect = array(); foreach ($providers as $provider) { $providerSelect[$provider['id']] = $provider['title']; } $suppressedSms = 0; //here we are getting logged in user id as array but we need target contact id. CRM-5988 $cid = $form->get('cid'); if ($cid) { $form->_contactIds = array($cid); } $to = $form->add('text', 'to', ts('To'), '', TRUE); $form->add('text', 'activity_subject', ts('Name The SMS'), '', TRUE); $toSetDefault = TRUE; if (property_exists($form, '_context') && $form->_context == 'standalone') { $toSetDefault = FALSE; } // when form is submitted recompute contactIds $allToSMS = array(); if ($to->getValue()) { $allToPhone = explode(',', $to->getValue()); $form->_contactIds = array(); foreach ($allToPhone as $value) { list($contactId, $phone) = explode('::', $value); if ($contactId) { $form->_contactIds[] = $contactId; $form->_toContactPhone[] = $phone; } } $toSetDefault = TRUE; } //get the group of contacts as per selected by user in case of Find Activities if (!empty($form->_activityHolderIds)) { $extendTargetContacts = 0; $invalidActivity = 0; $validActivities = 0; foreach ($form->_activityHolderIds as $key => $id) { //valid activity check if (CRM_Core_DAO::getFieldValue('CRM_Activity_DAO_Activity', $id, 'subject', 'id') != self::RECIEVED_SMS_ACTIVITY_SUBJECT) { $invalidActivity++; continue; } //target contacts limit check $ids = array_keys(CRM_Activity_BAO_ActivityTarget::getTargetNames($id)); if (count($ids) > 1) { $extendTargetContacts++; continue; } $validActivities++; $form->_contactIds = empty($form->_contactIds) ? $ids : array_unique(array_merge($form->_contactIds, $ids)); } if (!$validActivities) { $errorMess = ""; if ($extendTargetContacts) { $errorMess = ts('One selected activity consists of more than one target contact.', array( 'count' => $extendTargetContacts, 'plural' => '%count selected activities consist of more than one target contact.')); } if ($invalidActivity) { $errorMess = ($errorMess ? ' ' : ''); $errorMess .= ts('The selected activity is invalid.', array( 'count' => $invalidActivity, 'plural' => '%count selected activities are invalid.')); } CRM_Core_Error::statusBounce(ts("%1: SMS Reply will not be sent.", array(1 => $errorMess))); } } if (is_array($form->_contactIds) && !empty($form->_contactIds) && $toSetDefault) { $returnProperties = array( 'sort_name' => 1, 'phone' => 1, 'do_not_sms' => 1, 'is_deceased' => 1, 'display_name' => 1, ); list($form->_contactDetails) = CRM_Utils_Token::getTokenDetails($form->_contactIds, $returnProperties, FALSE, FALSE ); // make a copy of all contact details $form->_allContactDetails = $form->_contactDetails; foreach ($form->_contactIds as $key => $contactId) { $value = $form->_contactDetails[$contactId]; //to check if the phone type is "Mobile" $phoneTypes = CRM_Core_OptionGroup::values('phone_type', TRUE, FALSE, FALSE, NULL, 'name'); if (CRM_Utils_System::getClassName($form) == 'CRM_Activity_Form_Task_SMS') { //to check for "if the contact id belongs to a specified activity type" $actDetails = CRM_Activity_BAO_Activity::getContactActivity($contactId); if (self::RECIEVED_SMS_ACTIVITY_SUBJECT != CRM_Utils_Array::retrieveValueRecursive($actDetails, 'subject') ) { $suppressedSms++; unset($form->_contactDetails[$contactId]); continue; } } if ((isset($value['phone_type_id']) && $value['phone_type_id'] != CRM_Utils_Array::value('Mobile', $phoneTypes)) || $value['do_not_sms'] || empty($value['phone']) || CRM_Utils_Array::value('is_deceased', $value)) { //if phone is not primary check if non-primary phone is "Mobile" if (!empty($value['phone']) && $value['phone_type_id'] != CRM_Utils_Array::value('Mobile', $phoneTypes) && !CRM_Utils_Array::value('is_deceased', $value) ) { $filter = array('do_not_sms' => 0); $contactPhones = CRM_Core_BAO_Phone::allPhones($contactId, FALSE, 'Mobile', $filter); if (count($contactPhones) > 0) { $mobilePhone = CRM_Utils_Array::retrieveValueRecursive($contactPhones, 'phone'); $form->_contactDetails[$contactId]['phone_id'] = CRM_Utils_Array::retrieveValueRecursive($contactPhones, 'id'); $form->_contactDetails[$contactId]['phone'] = $mobilePhone; $form->_contactDetails[$contactId]['phone_type_id'] = CRM_Utils_Array::value('Mobile', $phoneTypes); } else { $suppressedSms++; unset($form->_contactDetails[$contactId]); continue; } } else { $suppressedSms++; unset($form->_contactDetails[$contactId]); continue; } } if (isset($mobilePhone)) { $phone = $mobilePhone; } elseif (empty($form->_toContactPhone)) { $phone = $value['phone']; } else { $phone = CRM_Utils_Array::value($key, $form->_toContactPhone); } if ($phone) { $toArray[] = array( 'name' => '"' . $value['sort_name'] . '" <' . $phone . '>', 'id' => "$contactId::{$phone}", ); } } if (empty($toArray)) { CRM_Core_Error::statusBounce(ts('Selected contact(s) do not have a valid Phone, or communication preferences specify DO NOT SMS, or they are deceased')); } } //activity related variables if (isset($invalidActivity)) { $form->assign('invalidActivity', $invalidActivity); } if (isset($extendTargetContacts)) { $form->assign('extendTargetContacts', $extendTargetContacts); } $form->assign('toContact', json_encode($toArray)); $form->assign('suppressedSms', $suppressedSms); $form->assign('totalSelectedContacts', count($form->_contactIds)); $form->add('select', 'sms_provider_id', ts('From'), $providerSelect, TRUE); CRM_Mailing_BAO_Mailing::commonCompose($form); if ($form->_single) { // also fix the user context stack if ($form->_context) { $url = CRM_Utils_System::url('civicrm/dashboard', 'reset=1'); } else { $url = CRM_Utils_System::url('civicrm/contact/view', "&show=1&action=browse&cid={$form->_contactIds[0]}&selectedChild=activity" ); } $session = CRM_Core_Session::singleton(); $session->replaceUserContext($url); $form->addDefaultButtons(ts('Send SMS'), 'upload', 'cancel'); } else { $form->addDefaultButtons(ts('Send SMS'), 'upload'); } $form->addFormRule(array('CRM_Contact_Form_Task_SMSCommon', 'formRule'), $form); } /** * form rule * * @param array $fields the input form values * @param array $dontCare * @param array $self additional values form 'this' * * @return true if no errors, else array of errors * @access public * */ static function formRule($fields, $dontCare, $self) { $errors = array(); $template = CRM_Core_Smarty::singleton(); if (!CRM_Utils_Array::value('text_message', $fields)) { $errors['text_message'] = ts('Please provide Text message.'); } else { if (CRM_Utils_Array::value('text_message', $fields)) { $messageCheck = CRM_Utils_Array::value('text_message', $fields); $messageCheck = str_replace("\r\n", "\n", $messageCheck); if ($messageCheck && (strlen($messageCheck) > CRM_SMS_Provider::MAX_SMS_CHAR)) { $errors['text_message'] = ts("You can configure the SMS message body up to %1 characters", array(1 => CRM_SMS_Provider::MAX_SMS_CHAR)); } } } //Added for CRM-1393 if (CRM_Utils_Array::value('saveTemplate', $fields) && empty($fields['saveTemplateName'])) { $errors['saveTemplateName'] = ts("Enter name to save message template"); } return empty($errors) ? TRUE : $errors; } /** * process the form after the input has been submitted and validated * * @access public * * @return None */ static function postProcess(&$form) { // check and ensure that $thisValues = $form->controller->exportValues($form->getName()); $fromSmsProviderId = $thisValues['sms_provider_id']; // process message template if (CRM_Utils_Array::value('saveTemplate', $thisValues) || CRM_Utils_Array::value('updateTemplate', $thisValues) ) { $messageTemplate = array( 'msg_text' => $thisValues['text_message'], 'is_active' => TRUE, ); if (CRM_Utils_Array::value('saveTemplate', $thisValues)) { $messageTemplate['msg_title'] = $thisValues['saveTemplateName']; CRM_Core_BAO_MessageTemplates::add($messageTemplate); } if (CRM_Utils_Array::value('template', $thisValues) && CRM_Utils_Array::value('updateTemplate', $thisValues) ) { $messageTemplate['id'] = $thisValues['template']; unset($messageTemplate['msg_title']); CRM_Core_BAO_MessageTemplates::add($messageTemplate); } } // format contact details array to handle multiple sms from same contact $formattedContactDetails = array(); $tempPhones = array(); foreach ($form->_contactIds as $key => $contactId) { $phone = $form->_toContactPhone[$key]; if ($phone) { $phoneKey = "{$contactId}::{$phone}"; if (!in_array($phoneKey, $tempPhones)) { $tempPhones[] = $phoneKey; if (CRM_Utils_Array::value($contactId, $form->_contactDetails)) { $formattedContactDetails[] = $form->_contactDetails[$contactId]; } } } } // $smsParams carries all the arguments provided on form (or via hooks), to the provider->send() method // this gives flexibity to the users / implementors to add their own args via hooks specific to their sms providers $smsParams = $thisValues; unset($smsParams['text_message']); $smsParams['provider_id'] = $fromSmsProviderId; $contactIds = array_keys($form->_contactDetails); $allContactIds = array_keys($form->_allContactDetails); list($sent, $activityId, $countSuccess) = CRM_Activity_BAO_Activity::sendSMS($formattedContactDetails, $thisValues, $smsParams, $contactIds ); if ($sent) { CRM_Core_Session::setStatus(ts('One message was sent successfully.', array('plural' => '%count messages were sent successfully.', 'count' => $countSuccess)), ts('Message Sent', array('plural' => 'Messages Sent', 'count' => $countSuccess)), 'success'); } //Display the name and number of contacts for those sms is not sent. $smsNotSent = array_diff_assoc($allContactIds, $contactIds); if (!empty($smsNotSent)) { $not_sent = array(); foreach ($smsNotSent as $index => $contactId) { $displayName = $form->_allContactDetails[$contactId]['display_name']; $phone = $form->_allContactDetails[$contactId]['phone']; $contactViewUrl = CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid=$contactId"); $not_sent[] = "$displayName"; } $status = '(' . ts('because no phone number on file or communication preferences specify DO NOT SMS or Contact is deceased'); if (CRM_Utils_System::getClassName($form) == 'CRM_Activity_Form_Task_SMS') { $status .= ' ' . ts("or the contact is not part of the activity '%1'", array(1 => self::RECIEVED_SMS_ACTIVITY_SUBJECT)); } $status .= ')'; CRM_Core_Session::setStatus($status, ts('One Message Not Sent', array('count' => count($smsNotSent), 'plural' => '%count Messages Not Sent')), 'info'); } } }