Remove deprecated code lines
[civicrm-core.git] / CRM / Core / BAO / MessageTemplate.php
index f887c686d3b91b1c87d72b364e56cb9fb6d62f54..802a3f822fdce8db4fd66a4a902b15117d4cdc35 100644 (file)
@@ -15,7 +15,9 @@
  * @copyright CiviCRM LLC https://civicrm.org/licensing
  */
 
+use Civi\Api4\Email;
 use Civi\Api4\MessageTemplate;
+use Civi\WorkflowMessage\WorkflowMessage;
 
 require_once 'Mail/mime.php';
 
@@ -211,127 +213,6 @@ class CRM_Core_BAO_MessageTemplate extends CRM_Core_DAO_MessageTemplate {
     return $msgTpls;
   }
 
-  /**
-   * @param int $contactId
-   * @param $email
-   * @param int $messageTemplateID
-   * @param $from
-   *
-   * @return bool|NULL
-   * @throws \CRM_Core_Exception
-   */
-  public static function sendReminder($contactId, $email, $messageTemplateID, $from) {
-    CRM_Core_Error::deprecatedWarning('CRM_Core_BAO_MessageTemplate::sendReminder is deprecated and will be removed in a future version of CiviCRM');
-
-    $messageTemplates = new CRM_Core_DAO_MessageTemplate();
-    $messageTemplates->id = $messageTemplateID;
-
-    $domain = CRM_Core_BAO_Domain::getDomain();
-    $result = NULL;
-    $hookTokens = [];
-
-    if ($messageTemplates->find(TRUE)) {
-      $body_text = $messageTemplates->msg_text;
-      $body_html = $messageTemplates->msg_html;
-      $body_subject = $messageTemplates->msg_subject;
-      if (!$body_text) {
-        $body_text = CRM_Utils_String::htmlToText($body_html);
-      }
-
-      $params = [['contact_id', '=', $contactId, 0, 0]];
-      [$contact] = CRM_Contact_BAO_Query::apiQuery($params);
-
-      //CRM-4524
-      $contact = reset($contact);
-
-      if (!$contact || is_a($contact, 'CRM_Core_Error')) {
-        return NULL;
-      }
-
-      //CRM-5734
-
-      // get tokens to be replaced
-      $tokens = array_merge(CRM_Utils_Token::getTokens($body_text),
-        CRM_Utils_Token::getTokens($body_html),
-        CRM_Utils_Token::getTokens($body_subject));
-
-      // get replacement text for these tokens
-      $returnProperties = ["preferred_mail_format" => 1];
-      if (isset($tokens['contact'])) {
-        foreach ($tokens['contact'] as $key => $value) {
-          $returnProperties[$value] = 1;
-        }
-      }
-      [$details] = CRM_Utils_Token::getTokenDetails([$contactId],
-        $returnProperties,
-        NULL, NULL, FALSE,
-        $tokens,
-        'CRM_Core_BAO_MessageTemplate');
-      $contact = reset($details);
-
-      // call token hook
-      $hookTokens = [];
-      CRM_Utils_Hook::tokens($hookTokens);
-      $categories = array_keys($hookTokens);
-
-      // do replacements in text and html body
-      $type = ['html', 'text'];
-      foreach ($type as $key => $value) {
-        $bodyType = "body_{$value}";
-        if ($$bodyType) {
-          CRM_Utils_Token::replaceGreetingTokens($$bodyType, NULL, $contact['contact_id']);
-          $$bodyType = CRM_Utils_Token::replaceDomainTokens($$bodyType, $domain, TRUE, $tokens, TRUE);
-          $$bodyType = CRM_Utils_Token::replaceContactTokens($$bodyType, $contact, FALSE, $tokens, FALSE, TRUE);
-          $$bodyType = CRM_Utils_Token::replaceComponentTokens($$bodyType, $contact, $tokens, TRUE);
-          $$bodyType = CRM_Utils_Token::replaceHookTokens($$bodyType, $contact, $categories, TRUE);
-        }
-      }
-      $html = $body_html;
-      $text = $body_text;
-
-      $smarty = CRM_Core_Smarty::singleton();
-      foreach ([
-        'text',
-        'html',
-      ] as $elem) {
-        $$elem = $smarty->fetch("string:{$$elem}");
-      }
-
-      // do replacements in message subject
-      $messageSubject = CRM_Utils_Token::replaceContactTokens($body_subject, $contact, FALSE, $tokens);
-      $messageSubject = CRM_Utils_Token::replaceDomainTokens($messageSubject, $domain, TRUE, $tokens);
-      $messageSubject = CRM_Utils_Token::replaceComponentTokens($messageSubject, $contact, $tokens, TRUE);
-      $messageSubject = CRM_Utils_Token::replaceHookTokens($messageSubject, $contact, $categories, TRUE);
-
-      $messageSubject = $smarty->fetch("string:{$messageSubject}");
-
-      // set up the parameters for CRM_Utils_Mail::send
-      $mailParams = [
-        'groupName' => 'Scheduled Reminder Sender',
-        'from' => $from,
-        'toName' => $contact['display_name'],
-        'toEmail' => $email,
-        'subject' => $messageSubject,
-      ];
-      if (!$html || $contact['preferred_mail_format'] == 'Text' ||
-        $contact['preferred_mail_format'] == 'Both'
-      ) {
-        // render the & entities in text mode, so that the links work
-        $mailParams['text'] = str_replace('&', '&', $text);
-      }
-      if ($html && ($contact['preferred_mail_format'] == 'HTML' ||
-          $contact['preferred_mail_format'] == 'Both'
-        )
-      ) {
-        $mailParams['html'] = $html;
-      }
-
-      $result = CRM_Utils_Mail::send($mailParams);
-    }
-
-    return $result;
-  }
-
   /**
    * Revert a message template to its default subject+text+HTML state.
    *
@@ -407,22 +288,34 @@ class CRM_Core_BAO_MessageTemplate extends CRM_Core_DAO_MessageTemplate {
    * @throws \API_Exception
    */
   public static function sendTemplate($params) {
-    $defaults = [
-      // option value name of the template
+    $modelDefaults = [
+      // instance of WorkflowMessageInterface, containing a list of data to provide to the message-template
+      'model' => NULL,
+      // Symbolic name of the workflow step. Matches the option-value-name of the template.
       'valueName' => NULL,
-      // ID of the template
-      'messageTemplateID' => NULL,
-      // content of the message template
-      // Ex: ['msg_subject' => 'Hello {contact.display_name}', 'msg_html' => '...', 'msg_text' => '...']
-      // INTERNAL: 'messageTemplate' is currently only intended for use within civicrm-core only. For downstream usage, future updates will provide comparable public APIs.
-      'messageTemplate' => NULL,
-      // contact id if contact tokens are to be replaced
-      'contactId' => NULL,
       // additional template params (other than the ones already set in the template singleton)
       'tplParams' => [],
       // additional token params (passed to the TokenProcessor)
       // INTERNAL: 'tokenContext' is currently only intended for use within civicrm-core only. For downstream usage, future updates will provide comparable public APIs.
       'tokenContext' => [],
+      // properties to import directly to the model object
+      'modelProps' => NULL,
+      // contact id if contact tokens are to be replaced; alias for tokenContext.contactId
+      'contactId' => NULL,
+    ];
+    $viewDefaults = [
+      // ID of the specific template to load
+      'messageTemplateID' => NULL,
+      // content of the message template
+      // Ex: ['msg_subject' => 'Hello {contact.display_name}', 'msg_html' => '...', 'msg_text' => '...']
+      // INTERNAL: 'messageTemplate' is currently only intended for use within civicrm-core only. For downstream usage, future updates will provide comparable public APIs.
+      'messageTemplate' => NULL,
+      // whether this is a test email (and hence should include the test banner)
+      'isTest' => FALSE,
+      // Disable Smarty?
+      'disableSmarty' => FALSE,
+    ];
+    $envelopeDefaults = [
       // the From: header
       'from' => NULL,
       // the recipient’s name
@@ -437,25 +330,20 @@ class CRM_Core_BAO_MessageTemplate extends CRM_Core_DAO_MessageTemplate {
       'replyTo' => NULL,
       // email attachments
       'attachments' => NULL,
-      // whether this is a test email (and hence should include the test banner)
-      'isTest' => FALSE,
       // filename of optional PDF version to add as attachment (do not include path)
       'PDFFilename' => NULL,
-      // Disable Smarty?
-      'disableSmarty' => FALSE,
     ];
-    $params = array_merge($defaults, $params);
 
-    // Core#644 - handle Email ID passed as "From".
-    if (isset($params['from'])) {
-      $params['from'] = CRM_Utils_Mail::formatFromAddress($params['from']);
-    }
+    // Allow WorkflowMessage to run any filters/mappings/cleanups.
+    $model = $params['model'] ?? WorkflowMessage::create($params['valueName'] ?? 'UNKNOWN');
+    $params = WorkflowMessage::exportAll(WorkflowMessage::importAll($model, $params));
+    unset($params['model']);
+    // Subsequent hooks use $params. Retaining the $params['model'] might be nice - but don't do it unless you figure out how to ensure data-consistency (eg $params['tplParams'] <=> $params['model']).
+    // If you want to expose the model via hook, consider interjecting a new Hook::alterWorkflowMessage($model) between `importAll()` and `exportAll()`.
+
+    $params = array_merge($modelDefaults, $viewDefaults, $envelopeDefaults, $params);
 
     CRM_Utils_Hook::alterMailParams($params, 'messageTemplate');
-    if (!is_int($params['messageTemplateID']) && !is_null($params['messageTemplateID'])) {
-      CRM_Core_Error::deprecatedWarning('message template id should be an integer');
-      $params['messageTemplateID'] = (int) $params['messageTemplateID'];
-    }
     $mailContent = self::loadTemplate((string) $params['valueName'], $params['isTest'], $params['messageTemplateID'] ?? NULL, $params['groupName'] ?? '', $params['messageTemplate'], $params['subject'] ?? NULL);
 
     $params['tokenContext'] = array_merge([
@@ -478,21 +366,24 @@ class CRM_Core_BAO_MessageTemplate extends CRM_Core_DAO_MessageTemplate {
     $params['html'] = $mailContent['html'];
 
     if ($params['toEmail']) {
-      $contactParams = [['email', 'LIKE', $params['toEmail'], 0, 1]];
-      [$contact] = CRM_Contact_BAO_Query::apiQuery($contactParams);
-
-      $prefs = array_pop($contact);
-
-      if (isset($prefs['preferred_mail_format']) and $prefs['preferred_mail_format'] === 'HTML') {
+      // @todo - consider whether we really should be loading
+      // this based on 'the first email in the db that matches'.
+      // when we likely have the contact id. OTOH people probably barely
+      // use preferredMailFormat these days - the good fight against html
+      // emails was lost a decade ago...
+      $preferredMailFormatArray = Email::get(FALSE)->addWhere('email', '=', $params['toEmail'])->addSelect('contact_id.preferred_mail_format')->execute()->first();
+      $preferredMailFormat = $preferredMailFormatArray['contact_id.preferred_mail_format'] ?? 'Both';
+
+      if ($preferredMailFormat === 'HTML') {
         $params['text'] = NULL;
       }
-
-      if (isset($prefs['preferred_mail_format']) and $prefs['preferred_mail_format'] === 'Text') {
+      if ($preferredMailFormat === 'Text') {
         $params['html'] = NULL;
       }
 
       $config = CRM_Core_Config::singleton();
       if (isset($params['isEmailPdf']) && $params['isEmailPdf'] == 1) {
+        // FIXME: $params['contributionId'] is not modeled in the parameter list. When is it supplied? Should probably move to tokenContext.contributionId.
         $pdfHtml = CRM_Contribute_BAO_ContributionPage::addInvoicePdfToEmail($params['contributionId'], $params['contactId']);
         if (empty($params['attachments'])) {
           $params['attachments'] = [];