Merge pull request #3543 from eileenmcnaughton/CRM-14850
[civicrm-core.git] / CRM / Utils / Token.php
index 18c21bf99de85d187cb3018d1bde745e7dcc7315..bd5b16598a9155d17b8a8467afd5ef595b7ab7bc 100644 (file)
@@ -161,10 +161,12 @@ class CRM_Utils_Token {
   /**
    * Wrapper for token replacing
    *
-   * @param string $type      The token type
-   * @param string $var       The token variable
-   * @param string $value     The value to substitute for the token
-   * @param string (reference) $str       The string to replace in
+   * @param string $type The token type
+   * @param string $var The token variable
+   * @param string $value The value to substitute for the token
+   * @param string (reference) $str The string to replace in
+   *
+   * @param bool $escapeSmarty
    *
    * @return string           The processed string
    * @access public
@@ -185,7 +187,9 @@ class CRM_Utils_Token {
   /**
    * get< the regex for token replacement
    *
-   * @param string $key       a string indicating the the type of token to be used in the expression
+   * @param $token_type
+   *
+   * @internal param string $key a string indicating the the type of token to be used in the expression
    *
    * @return string           regular expression sutiable for using in preg_replace
    * @access private
@@ -209,13 +213,15 @@ class CRM_Utils_Token {
     return preg_replace(array('/{/', '/(?<!{ldelim)}/'), array('{ldelim}', '{rdelim}'), $string);
   }
 
-  /**
    /**
    * Replace all the domain-level tokens in $str
    *
-   * @param string $str       The string with tokens to be replaced
-   * @param object $domain    The domain BAO
-   * @param boolean $html     Replace tokens with HTML or plain text
+   * @param string $str The string with tokens to be replaced
+   * @param object $domain The domain BAO
+   * @param boolean $html Replace tokens with HTML or plain text
+   *
+   * @param null $knownTokens
+   * @param bool $escapeSmarty
    *
    * @return string           The processed string
    * @access public
@@ -244,6 +250,14 @@ class CRM_Utils_Token {
     return $str;
   }
 
+  /**
+   * @param $token
+   * @param $domain
+   * @param bool $html
+   * @param bool $escapeSmarty
+   *
+   * @return mixed|null|string
+   */
   public static function getDomainTokenReplacement($token, &$domain, $html = FALSE, $escapeSmarty = FALSE) {
     // check if the token we were passed is valid
     // we have to do this because this function is
@@ -301,9 +315,11 @@ class CRM_Utils_Token {
   /**
    * Replace all the org-level tokens in $str
    *
-   * @param string $str       The string with tokens to be replaced
-   * @param object $org       Associative array of org properties
-   * @param boolean $html     Replace tokens with HTML or plain text
+   * @param string $str The string with tokens to be replaced
+   * @param object $org Associative array of org properties
+   * @param boolean $html Replace tokens with HTML or plain text
+   *
+   * @param bool $escapeSmarty
    *
    * @return string           The processed string
    * @access public
@@ -379,9 +395,12 @@ class CRM_Utils_Token {
   /**
    * Replace all mailing tokens in $str
    *
-   * @param string $str       The string with tokens to be replaced
-   * @param object $mailing   The mailing BAO, or null for validation
-   * @param boolean $html     Replace tokens with HTML or plain text
+   * @param string $str The string with tokens to be replaced
+   * @param object $mailing The mailing BAO, or null for validation
+   * @param boolean $html Replace tokens with HTML or plain text
+   *
+   * @param null $knownTokens
+   * @param bool $escapeSmarty
    *
    * @return string           The processed sstring
    * @access public
@@ -409,6 +428,13 @@ class CRM_Utils_Token {
     return $str;
   }
 
+  /**
+   * @param $token
+   * @param $mailing
+   * @param bool $escapeSmarty
+   *
+   * @return string
+   */
   public static function getMailingTokenReplacement($token, &$mailing, $escapeSmarty = FALSE) {
     $value = '';
     switch ($token) {
@@ -432,8 +458,12 @@ class CRM_Utils_Token {
         break;
 
       case 'viewUrl':
+        $mailingKey = $mailing->id;
+        if ($hash = CRM_Mailing_BAO_Mailing::getMailingHash($mailingKey)) {
+          $mailingKey = $hash;
+        }
         $value = CRM_Utils_System::url('civicrm/mailing/view',
-          "reset=1&id={$mailing->id}",
+          "reset=1&id={$mailingKey}",
           TRUE, NULL, FALSE, TRUE
         );
         break;
@@ -454,7 +484,7 @@ class CRM_Utils_Token {
 
       case 'html':
         $page = new CRM_Mailing_Page_View();
-        $value = $page->run($mailing->id, NULL, FALSE);
+        $value = $page->run($mailing->id, NULL, FALSE, TRUE);
         break;
 
       case 'approvalStatus':
@@ -494,11 +524,13 @@ class CRM_Utils_Token {
   /**
    * Replace all action tokens in $str
    *
-   * @param string $str         The string with tokens to be replaced
-   * @param array $addresses    Assoc. array of VERP event addresses
-   * @param array $urls         Assoc. array of action URLs
-   * @param boolean $html       Replace tokens with HTML or plain text
-   * @param array $knownTokens  A list of tokens that are known to exist in the email body
+   * @param string $str The string with tokens to be replaced
+   * @param array $addresses Assoc. array of VERP event addresses
+   * @param array $urls Assoc. array of action URLs
+   * @param boolean $html Replace tokens with HTML or plain text
+   * @param array $knownTokens A list of tokens that are known to exist in the email body
+   *
+   * @param bool $escapeSmarty
    *
    * @return string             The processed string
    * @access public
@@ -531,6 +563,15 @@ class CRM_Utils_Token {
     return $str;
   }
 
+  /**
+   * @param $token
+   * @param $addresses
+   * @param $urls
+   * @param bool $html
+   * @param bool $escapeSmarty
+   *
+   * @return mixed|string
+   */
   public static function getActionTokenReplacement(
     $token,
     &$addresses,
@@ -572,11 +613,13 @@ class CRM_Utils_Token {
    * Replace all the contact-level tokens in $str with information from
    * $contact.
    *
-   * @param string  $str               The string with tokens to be replaced
-   * @param array   $contact           Associative array of contact properties
-   * @param boolean $html              Replace tokens with HTML or plain text
-   * @param array   $knownTokens       A list of tokens that are known to exist in the email body
-   * @param boolean $returnBlankToken  return unevaluated token if value is null
+   * @param string $str The string with tokens to be replaced
+   * @param array $contact Associative array of contact properties
+   * @param boolean $html Replace tokens with HTML or plain text
+   * @param array $knownTokens A list of tokens that are known to exist in the email body
+   * @param boolean $returnBlankToken return unevaluated token if value is null
+   *
+   * @param bool $escapeSmarty
    *
    * @return string                    The processed string
    * @access public
@@ -621,6 +664,15 @@ class CRM_Utils_Token {
     return $str;
   }
 
+  /**
+   * @param $token
+   * @param $contact
+   * @param bool $html
+   * @param bool $returnBlankToken
+   * @param bool $escapeSmarty
+   *
+   * @return bool|mixed|null|string
+   */
   public static function getContactTokenReplacement(
     $token,
     &$contact,
@@ -704,9 +756,12 @@ class CRM_Utils_Token {
    * Replace all the hook tokens in $str with information from
    * $contact.
    *
-   * @param string $str         The string with tokens to be replaced
-   * @param array $contact      Associative array of contact properties (including hook token values)
-   * @param boolean $html       Replace tokens with HTML or plain text
+   * @param string $str The string with tokens to be replaced
+   * @param array $contact Associative array of contact properties (including hook token values)
+   * @param $categories
+   * @param boolean $html Replace tokens with HTML or plain text
+   *
+   * @param bool $escapeSmarty
    *
    * @return string             The processed string
    * @access public
@@ -747,7 +802,16 @@ class CRM_Utils_Token {
     }
     return $tokenHtml;
   }
-  public static function getHookTokenReplacement(
+
+  /**
+   * @param $token
+   * @param $contact
+   * @param $category
+   * @param bool $html
+   * @param bool $escapeSmarty
+   *
+   * @return mixed|string
+   */public static function getHookTokenReplacement(
     $token,
     &$contact,
     $category,
@@ -853,9 +917,10 @@ class CRM_Utils_Token {
   /**
    * Replace subscription-confirmation-request tokens
    *
-   * @param string $str           The string with tokens to be replaced
-   * @param string $group         The name of the group being subscribed
-   * @param boolean $html         Replace tokens with html or plain text
+   * @param string $str The string with tokens to be replaced
+   * @param string $group The name of the group being subscribed
+   * @param $url
+   * @param boolean $html Replace tokens with html or plain text
    *
    * @return string               The processed string
    * @access public
@@ -950,10 +1015,13 @@ class CRM_Utils_Token {
   /**
    * Find and replace tokens for each component
    *
-   * @param string $str       The string to search
-   * @param array   $contact  Associative array of contact properties
+   * @param string $str The string to search
+   * @param array $contact Associative array of contact properties
    * @param array $components A list of tokens that are known to exist in the email body
    *
+   * @param bool $escapeSmarty
+   * @param bool $returnEmptyToken
+   *
    * @return string           The processed string
    * @access public
    * @static
@@ -986,8 +1054,7 @@ class CRM_Utils_Token {
    *
    * @param  $string the input string to parse for tokens
    *
-   * @return $tokens array of tokens mentioned in field
-   * @access public
+   * @return array $tokens array of tokens mentioned in field@access public
    * @static
    */
   static function getTokens($string) {
@@ -1017,14 +1084,16 @@ class CRM_Utils_Token {
    * gives required details of contacts in an indexed array format so we
    * can iterate in a nice loop and do token evaluation
    *
-   * @param  array   $contactIds       of contacts
-   * @param  array   $returnProperties of required properties
-   * @param  boolean $skipOnHold       don't return on_hold contact info also.
-   * @param  boolean $skipDeceased     don't return deceased contact info.
-   * @param  array   $extraParams      extra params
-   * @param  array   $tokens           the list of tokens we've extracted from the content
-   * @param  int     $jobID            the mailing list jobID - this is a legacy param
+   * @param $contactIDs
+   * @param  array $returnProperties of required properties
+   * @param  boolean $skipOnHold don't return on_hold contact info also.
+   * @param  boolean $skipDeceased don't return deceased contact info.
+   * @param  array $extraParams extra params
+   * @param  array $tokens the list of tokens we've extracted from the content
+   * @param null $className
+   * @param  int $jobID the mailing list jobID - this is a legacy param
    *
+   * @internal param array $contactIds of contacts
    * @return array
    * @access public
    * @static
@@ -1172,17 +1241,21 @@ class CRM_Utils_Token {
     );
     return $details;
   }
+
   /**
    * gives required details of contribuion in an indexed array format so we
    * can iterate in a nice loop and do token evaluation
    *
-   * @param  array   $contributionId   one contribution id
-   * @param  array   $returnProperties of required properties
-   * @param  boolean $skipOnHold       don't return on_hold contact info.
-   * @param  boolean $skipDeceased     don't return deceased contact info.
-   * @param  array   $extraParams      extra params
-   * @param  array   $tokens           the list of tokens we've extracted from the content
+   * @param $contributionIDs
+   * @param  array $returnProperties of required properties
+   * @param  array $extraParams extra params
+   * @param  array $tokens the list of tokens we've extracted from the content
+   *
+   * @param null $className
    *
+   * @internal param array $contributionId one contribution id
+   * @internal param bool $skipOnHold don't return on_hold contact info.
+   * @internal param bool $skipDeceased don't return deceased contact info.
    * @return array
    * @access public
    * @static
@@ -1193,6 +1266,7 @@ class CRM_Utils_Token {
     $tokens           = array(),
     $className        = NULL
   ) {
+    //@todo - this function basically replications calling civicrm_api3('contribution', 'get', array('id' => array('IN' => array())
     if (empty($contributionIDs)) {
       // putting a fatal here so we can track if/when this happens
       CRM_Core_Error::fatal();
@@ -1293,6 +1367,11 @@ class CRM_Utils_Token {
     }
   }
 
+  /**
+   * @param $tokens
+   *
+   * @return array
+   */
   static function flattenTokens(&$tokens) {
     $flattenTokens = array();
 
@@ -1317,7 +1396,10 @@ class CRM_Utils_Token {
   /**
    * Replace all user tokens in $str
    *
-   * @param string $str       The string with tokens to be replaced
+   * @param string $str The string with tokens to be replaced
+   *
+   * @param null $knownTokens
+   * @param bool $escapeSmarty
    *
    * @return string           The processed string
    * @access public
@@ -1341,6 +1423,12 @@ class CRM_Utils_Token {
     return $str;
   }
 
+  /**
+   * @param $token
+   * @param bool $escapeSmarty
+   *
+   * @return string
+   */
   public static function getUserTokenReplacement($token, $escapeSmarty = FALSE) {
     $value = '';
 
@@ -1363,7 +1451,9 @@ class CRM_Utils_Token {
     return $value;
   }
 
-
+  /**
+   *
+   */
   protected static function _buildContributionTokens() {
     $key = 'contribution';
     if (self::$_tokens[$key] == NULL) {
@@ -1412,17 +1502,28 @@ class CRM_Utils_Token {
     return $str;
   }
 
-  public static function &replaceContributionTokens($str, &$contribution, $html = FALSE, $knownTokens = NULL, $escapeSmarty = FALSE) {
+  /**
+   * Replace Contribution tokens in html
+   *
+   * @param string $str
+   * @param array $contribution
+   * @param bool|string $html
+   * @param string $knownTokens
+   * @param bool|string $escapeSmarty
+   *
+   * @return unknown|Ambigous <string, mixed>|mixed
+   */
+  public static function replaceContributionTokens($str, &$contribution, $html = FALSE, $knownTokens = NULL, $escapeSmarty = FALSE) {
+    $key = 'contribution';
+    if (!$knownTokens || !CRM_Utils_Array::value($key, $knownTokens)) {
+      return $str; //early return
+    }
     self::_buildContributionTokens();
 
     // here we intersect with the list of pre-configured valid tokens
     // so that we remove anything we do not recognize
     // I hope to move this step out of here soon and
     // then we will just iterate on a list of tokens that are passed to us
-    $key = 'contribution';
-    if (!$knownTokens || empty($knownTokens[$key])) {
-      return $str;
-    }
 
     $str = preg_replace_callback(
       self::tokenRegex($key),
@@ -1436,6 +1537,42 @@ class CRM_Utils_Token {
     return $str;
   }
 
+  /**
+   * We have a situation where we are rendering more than one token in each field because we are combining
+   * tokens from more than one contribution when pdf thank you letters are grouped (CRM-14367)
+   *
+   * The replaceContributionToken doesn't handle receive_date correctly in this scenario because of the formatting
+   * it applies (other tokens are OK including date fields)
+   *
+   * So we sort this out & then call the main function. Note that we are not escaping smarty on this fields like the main function
+   * does - but the fields is already being formatted through a date function
+   *
+   * @param string $separator
+   * @param string $str
+   * @param array $contribution
+   * @param bool|string $html
+   * @param string $knownTokens
+   * @param bool|string $escapeSmarty
+   *
+   * @return \Ambigous|mixed|string|\unknown
+   */
+  public static function replaceMultipleContributionTokens($separator, $str, &$contribution, $html = FALSE, $knownTokens = NULL, $escapeSmarty = FALSE) {
+    if(empty($knownTokens['contribution'])) {
+      return $str;
+    }
+
+    if(in_array('receive_date', $knownTokens['contribution'])) {
+      $formattedDates = array();
+      $dates = explode($separator, $contribution['receive_date']);
+      foreach ($dates as $date) {
+        $formattedDates[] = CRM_Utils_Date::customFormat($date, NULL, array('j', 'm', 'Y'));
+      }
+      $str = str_replace("{contribution.receive_date}", implode($separator, $formattedDates), $str);
+      unset($knownTokens['contribution']['receive_date']);
+    }
+    return self::replaceContributionTokens($str, $contribution, $html, $knownTokens, $escapeSmarty);
+  }
+
   /**
    * Get replacement strings for any membership tokens (only a small number of tokens are implemnted in the first instance
    * - this is used by the pdfLetter task from membership search
@@ -1482,6 +1619,14 @@ class CRM_Utils_Token {
     return $value;
   }
 
+  /**
+   * @param $token
+   * @param $contribution
+   * @param bool $html
+   * @param bool $escapeSmarty
+   *
+   * @return mixed|string
+   */
   public static function getContributionTokenReplacement($token, &$contribution, $html = FALSE, $escapeSmarty = FALSE) {
     self::_buildContributionTokens();
 
@@ -1515,10 +1660,6 @@ class CRM_Utils_Token {
     return $value;
   }
 
-  function getPermissionEmails($permissionName) {}
-
-  function getRoleEmails($roleName) {}
-
   /**
    * @return array: legacy_token => new_token
    */
@@ -1565,5 +1706,4 @@ class CRM_Utils_Token {
 
     return $output;
   }
-
 }