singletonIf('users.sms', function ($app) { $i = $app->make(static::class); $i->init(); return $i; }); return bff('users.sms'); } /** * Отправка SMS с кодом активации для подтверждения телефона * @param string $phoneNumber номер телефона в международном формате * @param string $code код активации * @return bool результат отправки: true - отправлено false - нет */ public function sendActivationCode(string $phoneNumber, string $code): bool { # Считаем кол-во попыток отправки if ($this->retryCounter('users-sms-activation-code')) { return false; } # Формируем текст сообщения $message = _t('users', 'Activation code: [code]', [ 'site.title' => Site::title('users.sms.macros'), 'site.host' => SITEHOST, 'code' => $code, ]); # Отправляем сообщение на телефон return $this->send($phoneNumber, $message); } /** * Отправка SMS с паролем для подтверждения телефона * @param string $phoneNumber номер телефона в международном формате * @param string $password пароль * @return bool результат отправки: true - отправлено false - нет */ public function sendPassword(string $phoneNumber, string $password) { # Считаем кол-во попыток отправки if ($this->retryCounter('users-sms-activation-code')) { return false; } # Формируем текст сообщения $message = _t('users', 'Password: [password]', [ 'site.title' => Site::title('users.sms.macros'), 'site.host' => SITEHOST, 'password' => $password, ]); # Отправляем сообщение на телефон return $this->send($phoneNumber, $message); } /** * Отправка SMS сообщения на указанный номер * Провайдер указывается в системной настройке 'users.sms.provider' * @param string $phoneNumber номер телефона в международном формате * @param string $message текст сообщения * @return bool результат отправки: true - отправлено false - нет */ public function send(string $phoneNumber, string $message): bool { if ($this->app->hooksAdded('users.sms.send.before')) { $hook = $this->app->filter('users.sms.send.before', [ 'phoneNumber' => &$phoneNumber, 'message' => &$message, ]); if (isset($hook['sended'])) { return $hook['sended']; } } if (! $this->input->isPhoneNumber($phoneNumber)) { if ($this->userErrors) { $this->errors->set(_t('users', 'Incorrect phone number')); } return false; } if ($this->config('users.sms.links.short', true, TYPE_BOOL)) { Sendmail::i()->shortLinksReplace($message); } # Провайдер $provider = $this->config('users.sms.provider', '', TYPE_STR); $smsProvider = Sendmail::smsProvider($provider); if ($smsProvider) { $response = $smsProvider->send($phoneNumber, $message); if (is_string($response)) { if ($this->userErrors) { $this->errors->set($response); } return false; } return $response; } $providerCustom = $this->app->filter('users.sms.send', $provider, $phoneNumber, $message); if (is_bool($providerCustom)) { return $providerCustom; } $this->log('Hет доступных сервисов для отправки SMS'); return false; } /** * Ограничение кол-ва попыток с последующей паузой * @param string $actionKey тип действия * @return bool true - достигнут лимит повторов */ protected function retryCounter(string $actionKey) { return $this->tooManyRequests($actionKey, [ 'silent' => $this->userErrors, 'limit' => $this->config('users.sms.retry.limit', 3, TYPE_UINT), 'timeout' => ($this->config('users.sms.retry.timeout', 3, TYPE_UINT) * 60), ]); } /** * Фиксировать ошибки для пользователей * @param bool $enabled true - фиксировать * @return void */ public function userErrorsEnabled(bool $enabled) { $this->userErrors = $enabled; } }