logger = $logger; $this->cachePool = $cacheUserData; $this->config = $config = $parameterBag->get('chill_main.phone_helper'); if ( array_key_exists('twilio_sid', $config) && !empty($config['twilio_sid']) && strlen($config['twilio_sid']) > 2 && array_key_exists('twilio_secret', $config) && !empty($config['twilio_secret']) && strlen($config['twilio_secret']) > 2 ) { $this->twilioClient = new Client([ 'auth' => [$config['twilio_sid'], $config['twilio_secret']], ]); $this->isConfigured = true; } $this->phoneNumberUtil = PhoneNumberUtil::getInstance(); } /** * @param string $phoneNumber A national phone number starting with + * * @throws NumberParseException */ public function format(PhoneNumber $phoneNumber): string { return $this->phoneNumberUtil ->formatOutOfCountryCallingNumber($phoneNumber, $this->config['default_carrier_code']); } /** * Get type (mobile, landline, ...) for phone number. */ public function getType(string $phonenumber): string { return $this->performTwilioLookup($phonenumber) ?? 'unknown'; } /** * Return true if the validation is configured and available. */ public function isPhonenumberValidationConfigured(): bool { return $this->isConfigured; } /** * Return true if the phonenumber is a landline or voip phone. Return always true * if the validation is not configured. * * @param string $phonenumber */ public function isValidPhonenumberAny($phonenumber): bool { if (false === $this->isPhonenumberValidationConfigured()) { return true; } $validation = $this->performTwilioLookup($phonenumber); if (null === $validation) { return false; } return in_array($validation, ['landline', 'voip', 'mobile'], true); } /** * Return true if the phonenumber is a landline or voip phone. Return always true * if the validation is not configured. * * @param string $phonenumber */ public function isValidPhonenumberLandOrVoip($phonenumber): bool { if (false === $this->isPhonenumberValidationConfigured()) { return true; } $validation = $this->performTwilioLookup($phonenumber); if (null === $validation) { return true; } return in_array($validation, ['landline', 'voip'], true); } /** * REturn true if the phonenumber is a mobile phone. Return always true * if the validation is not configured. * * @param string $phonenumber */ public function isValidPhonenumberMobile($phonenumber): bool { if (false === $this->isPhonenumberValidationConfigured()) { return true; } $validation = $this->performTwilioLookup($phonenumber); if (null === $validation) { return true; } return 'mobile' === $validation; } private function performTwilioLookup($phonenumber) { if (false === $this->isPhonenumberValidationConfigured()) { return null; } // filter only number $filtered = preg_replace('/[^0-9]/', '', $phonenumber); $item = $this->cachePool->getItem('pnum_' . $filtered); if ($item->isHit()) { return $item->get(); } try { $response = $this->twilioClient->get(sprintf(self::LOOKUP_URI, '+' . $filtered), [ 'http_errors' => true, 'query' => [ 'Type' => 'carrier', ], ]); } catch (ClientException $e) { return 'invalid'; } catch (ServerException $e) { $response = $e->getResponse(); $this->logger->error('[phonenumber helper] Could not perform validation ' . 'due to server error', [ 'message' => $response->getBody()->getContents(), 'status_code' => $response->getStatusCode(), 'phonenumber' => $phonenumber, ]); return null; } catch (ConnectException $e) { $this->logger->error('[phonenumber helper] Could not format number ' . 'due to connect error', [ 'message' => $e->getMessage(), 'phonenumber' => $phonenumber, ]); return null; } $validation = json_decode($response->getBody()->getContents())->carrier->type; $item ->set($validation) // expires after 12h ->expiresAfter(3600 * 12); $this->cachePool->save($item); return $validation; } }