diff --git a/application/Espo/Core/PhoneNumber/InternationalValidator.php b/application/Espo/Core/PhoneNumber/InternationalValidator.php new file mode 100644 index 0000000000..4c1fd896d7 --- /dev/null +++ b/application/Espo/Core/PhoneNumber/InternationalValidator.php @@ -0,0 +1,91 @@ +. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU Affero General Public License version 3. + * + * In accordance with Section 7(b) of the GNU Affero General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. + ************************************************************************/ + +namespace Espo\Core\PhoneNumber; + +use Brick\PhoneNumber\PhoneNumber; +use Brick\PhoneNumber\PhoneNumberParseException; +use Espo\Core\Utils\Metadata; + +/** + * @since 9.0.3 + */ +class InternationalValidator +{ + public function __construct( + private Metadata $metadata, + ) {} + + public function isValid(string $number, bool $allowExtension = false): bool + { + if ($number === '') { + return false; + } + + $pattern = $this->metadata->get(['app', 'regExpPatterns', 'phoneNumberLoose', 'pattern']); + + if (!$pattern) { + return true; + } + + $preparedPattern = '/^' . $pattern . '$/'; + + if (!preg_match($preparedPattern, $number)) { + return false; + } + + $ext = null; + + if ($allowExtension) { + [$number, $ext] = Util::splitExtension($number); + } + + if ($ext) { + if (!preg_match('/[0-9]+/', $ext)) { + return false; + } + + if (strlen($ext) > 6) { + return false; + } + } + + try { + $numberObj = PhoneNumber::parse($number); + } catch (PhoneNumberParseException) { + return false; + } + + if ((string) $numberObj !== $number) { + return false; + } + + return $numberObj->isPossibleNumber(); + } +}