Merge pull request #22460 from civicrm/5.46
[civicrm-core.git] / CRM / Utils / Rule.php
index 9341e173f9225563edb2fac410c70bfa2dcf5e2c..4e63ec01035caf9f9868335d9452508b35b7bb72 100644 (file)
@@ -261,10 +261,10 @@ class CRM_Utils_Rule {
   }
 
   /**
-   * @param $value
+   * @param string $value
    * @param null $default
    *
-   * @return null
+   * @return string|null
    */
   public static function date($value, $default = NULL) {
     if (is_string($value) &&
@@ -276,10 +276,10 @@ class CRM_Utils_Rule {
   }
 
   /**
-   * @param $value
+   * @param string $value
    * @param null $default
    *
-   * @return null|string
+   * @return string|null
    */
   public static function dateTime($value, $default = NULL) {
     $result = $default;
@@ -625,6 +625,10 @@ class CRM_Utils_Rule {
    * @return bool
    */
   public static function boolean($value) {
+    if ($value === TRUE || $value === FALSE) {
+      return TRUE;
+    }
+    // This is intentionally not using === comparison - but will fail on FALSE.
     return preg_match(
       '/(^(1|0)$)|(^(Y(es)?|N(o)?)$)|(^(T(rue)?|F(alse)?)$)/i', $value
     ) ? TRUE : FALSE;
@@ -635,12 +639,46 @@ class CRM_Utils_Rule {
    *
    * @return bool
    */
-  public static function email($value) {
+  public static function email($value): bool {
+    if (function_exists('idn_to_ascii')) {
+      $parts = explode('@', $value);
+      foreach ($parts as &$part) {
+        // if the function returns FALSE then let filter_var have at it.
+        $part = self::idnToAsci($part) ?: $part;
+        if ($part === 'localhost') {
+          // if we are in a dev environment add .com to trick it into accepting localhost.
+          // this is a bit best-effort - ie we don't really care that it's in a bigger if.
+          $part .= '.com';
+        }
+      }
+      $value = implode('@', $parts);
+    }
     return (bool) filter_var($value, FILTER_VALIDATE_EMAIL);
   }
 
   /**
-   * @param $list
+   * Convert domain string to ascii.
+   *
+   * See https://lab.civicrm.org/dev/core/-/issues/2769
+   * and also discussion over in guzzle land
+   * https://github.com/guzzle/guzzle/pull/2454
+   *
+   * @param string $string
+   *
+   * @return string|false
+   */
+  private static function idnToAsci(string $string) {
+    if (!\extension_loaded('intl')) {
+      return $string;
+    }
+    if (defined('INTL_IDNA_VARIANT_UTS46')) {
+      return idn_to_ascii($string, 0, INTL_IDNA_VARIANT_UTS46);
+    }
+    return idn_to_ascii($string);
+  }
+
+  /**
+   * @param string $list
    *
    * @return bool
    */
@@ -717,24 +755,6 @@ class CRM_Utils_Rule {
     return $success;
   }
 
-  /**
-   * See how file rules are written in HTML/QuickForm/file.php
-   * Checks to make sure the uploaded file is html
-   *
-   * @param array $elementValue
-   *
-   * @return bool
-   *   True if file has been uploaded, false otherwise
-   */
-  public static function htmlFile($elementValue) {
-    if ((isset($elementValue['error']) && $elementValue['error'] == 0) ||
-      (!empty($elementValue['tmp_name']) && $elementValue['tmp_name'] != 'none')
-    ) {
-      return CRM_Utils_File::isHtmlFile($elementValue['tmp_name']);
-    }
-    return FALSE;
-  }
-
   /**
    * Check if there is a record with the same name in the db.
    *