[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/src/Form/Rule/ -> EmailRule.php (source)

   1  <?php
   2  
   3  /**
   4   * Joomla! Content Management System
   5   *
   6   * @copyright  (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
   7   * @license    GNU General Public License version 2 or later; see LICENSE.txt
   8   */
   9  
  10  namespace Joomla\CMS\Form\Rule;
  11  
  12  use Joomla\CMS\Component\ComponentHelper;
  13  use Joomla\CMS\Form\Form;
  14  use Joomla\CMS\Form\FormRule;
  15  use Joomla\CMS\Language\Text;
  16  use Joomla\CMS\String\PunycodeHelper;
  17  use Joomla\Database\DatabaseAwareInterface;
  18  use Joomla\Database\DatabaseAwareTrait;
  19  use Joomla\Database\ParameterType;
  20  use Joomla\Registry\Registry;
  21  
  22  // phpcs:disable PSR1.Files.SideEffects
  23  \defined('JPATH_PLATFORM') or die;
  24  // phpcs:enable PSR1.Files.SideEffects
  25  
  26  /**
  27   * Form Rule class for the Joomla Platform.
  28   *
  29   * @since  1.7.0
  30   */
  31  class EmailRule extends FormRule implements DatabaseAwareInterface
  32  {
  33      use DatabaseAwareTrait;
  34  
  35      /**
  36       * The regular expression to use in testing a form field value.
  37       *
  38       * @var    string
  39       * @since  1.7.0
  40       * @link   https://www.w3.org/TR/html/sec-forms.html#email-state-typeemail
  41       */
  42      protected $regex = "^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])"
  43              . "?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$";
  44  
  45      /**
  46       * Method to test the email address and optionally check for uniqueness.
  47       *
  48       * @param   \SimpleXMLElement  $element  The SimpleXMLElement object representing the `<field>` tag for the form field object.
  49       * @param   mixed              $value    The form field value to validate.
  50       * @param   string             $group    The field name group control value. This acts as an array container for the field.
  51       *                                       For example if the field has name="foo" and the group value is set to "bar" then the
  52       *                                       full field name would end up being "bar[foo]".
  53       * @param   Registry           $input    An optional Registry object with the entire data set to validate against the entire form.
  54       * @param   Form               $form     The form object for which the field is being tested.
  55       *
  56       * @return  mixed  Boolean true if field value is valid.
  57       *
  58       * @since   1.7.0
  59       * @throws  \UnexpectedValueException
  60       */
  61      public function test(\SimpleXMLElement $element, $value, $group = null, Registry $input = null, Form $form = null)
  62      {
  63          // If the field is empty and not required, the field is valid.
  64          $required = ((string) $element['required'] === 'true' || (string) $element['required'] === 'required');
  65  
  66          if (!$required && empty($value)) {
  67              return true;
  68          }
  69  
  70          // If the tld attribute is present, change the regular expression to require at least 2 characters for it.
  71          $tld = ((string) $element['tld'] === 'tld' || (string) $element['tld'] === 'required');
  72  
  73          if ($tld) {
  74              $this->regex = "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])"
  75                  . '?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$';
  76          }
  77  
  78          // Determine if the multiple attribute is present
  79          $multiple = ((string) $element['multiple'] === 'true' || (string) $element['multiple'] === 'multiple');
  80  
  81          if (!$multiple) {
  82              // Handle idn email addresses by converting to punycode.
  83              $value = PunycodeHelper::emailToPunycode($value);
  84  
  85              // Test the value against the regular expression.
  86              if (!parent::test($element, $value, $group, $input, $form)) {
  87                  throw new \UnexpectedValueException(Text::_('JLIB_DATABASE_ERROR_VALID_MAIL'));
  88              }
  89          } else {
  90              $values = explode(',', $value);
  91  
  92              foreach ($values as $value) {
  93                  // Handle idn email addresses by converting to punycode.
  94                  $value = PunycodeHelper::emailToPunycode($value);
  95  
  96                  // Test the value against the regular expression.
  97                  if (!parent::test($element, $value, $group, $input, $form)) {
  98                      throw new \UnexpectedValueException(Text::_('JLIB_DATABASE_ERROR_VALID_MAIL'));
  99                  }
 100              }
 101          }
 102  
 103          /**
 104           * validDomains value should consist of component name and the name of domain list field in component's configuration, separated by a dot.
 105           * This allows different components and contexts to use different lists.
 106           * If value is incomplete, com_users.domains is used as fallback.
 107           */
 108          $validDomains = (string) $element['validDomains'] !== '' && (string) $element['validDomains'] !== 'false';
 109  
 110          if ($validDomains && !$multiple) {
 111              $config = explode('.', $element['validDomains'], 2);
 112  
 113              if (\count($config) > 1) {
 114                  $domains = ComponentHelper::getParams($config[0])->get($config[1]);
 115              } else {
 116                  $domains = ComponentHelper::getParams('com_users')->get('domains');
 117              }
 118  
 119              if ($domains) {
 120                  $emailDomain = explode('@', $value);
 121                  $emailDomain = $emailDomain[1];
 122                  $emailParts  = array_reverse(explode('.', $emailDomain));
 123                  $emailCount  = \count($emailParts);
 124                  $allowed     = true;
 125  
 126                  foreach ($domains as $domain) {
 127                      $domainParts = array_reverse(explode('.', $domain->name));
 128                      $status      = 0;
 129  
 130                      // Don't run if the email has less segments than the rule.
 131                      if ($emailCount < \count($domainParts)) {
 132                          continue;
 133                      }
 134  
 135                      foreach ($emailParts as $key => $emailPart) {
 136                          if (!isset($domainParts[$key]) || $domainParts[$key] == $emailPart || $domainParts[$key] == '*') {
 137                              $status++;
 138                          }
 139                      }
 140  
 141                      // All segments match, check whether to allow the domain or not.
 142                      if ($status === $emailCount) {
 143                          if ($domain->rule == 0) {
 144                              $allowed = false;
 145                          } else {
 146                              $allowed = true;
 147                          }
 148                      }
 149                  }
 150  
 151                  // If domain is not allowed, fail validation. Otherwise continue.
 152                  if (!$allowed) {
 153                      throw new \UnexpectedValueException(Text::sprintf('JGLOBAL_EMAIL_DOMAIN_NOT_ALLOWED', $emailDomain));
 154                  }
 155              }
 156          }
 157  
 158          // Check if we should test for uniqueness. This only can be used if multiple is not true
 159          $unique = ((string) $element['unique'] === 'true' || (string) $element['unique'] === 'unique');
 160  
 161          if ($unique && !$multiple) {
 162              // Get the database object and a new query object.
 163              $db    = $this->getDatabase();
 164              $query = $db->getQuery(true);
 165  
 166              // Get the extra field check attribute.
 167              $userId = ($form instanceof Form) ? (int) $form->getValue('id') : 0;
 168  
 169              // Build the query.
 170              $query->select('COUNT(*)')
 171                  ->from($db->quoteName('#__users'))
 172                  ->where(
 173                      [
 174                          $db->quoteName('email') . ' = :email',
 175                          $db->quoteName('id') . ' <> :userId',
 176                      ]
 177                  )
 178                  ->bind(':email', $value)
 179                  ->bind(':userId', $userId, ParameterType::INTEGER);
 180  
 181              // Set and query the database.
 182              $db->setQuery($query);
 183              $duplicate = (bool) $db->loadResult();
 184  
 185              if ($duplicate) {
 186                  throw new \UnexpectedValueException(Text::_('JLIB_DATABASE_ERROR_EMAIL_INUSE'));
 187              }
 188          }
 189  
 190          return true;
 191      }
 192  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer