194 lines
5.3 KiB
PHP
194 lines
5.3 KiB
PHP
<?php
|
|
namespace Stemcell\Sms\Model;
|
|
|
|
use Stemcell\Sms\Api\Data\GatewayResponseInterface;
|
|
use Magento\Backend\App\ConfigInterface;
|
|
use Magento\Framework\Exception\InvalidArgumentException;
|
|
use Magento\Framework\Exception\LocalizedException;
|
|
use Magento\Framework\Math\Random;
|
|
use Magento\Framework\Stdlib\DateTime\DateTimeFactory;
|
|
use \Magento\Framework\Api\DataObjectHelper;
|
|
|
|
/**
|
|
* property type should equal to captcha formId
|
|
* @package Stemcell\Sms\Model
|
|
*/
|
|
abstract class SmsSender implements SmsSendInterface
|
|
{
|
|
protected String $type;
|
|
protected String $mobile;
|
|
protected String $code;
|
|
protected bool $success;
|
|
protected String $message;
|
|
|
|
protected int $smsInterval = 0;
|
|
|
|
protected ConfigInterface $config;
|
|
|
|
protected Redis $redis;
|
|
|
|
protected DateTimeFactory $dateTimeFactory;
|
|
|
|
protected Random $random;
|
|
|
|
protected GatewayResponseInterface $gatewayResponse;
|
|
|
|
protected DataObjectHelper $dataObjectHelper;
|
|
|
|
public function __construct(
|
|
ConfigInterface $config,
|
|
Redis $redis,
|
|
DateTimeFactory $dateTimeFactory,
|
|
Random $random,
|
|
GatewayResponseInterface $gatewayResponse,
|
|
DataObjectHelper $dataObjectHelper,
|
|
array $data = []
|
|
) {
|
|
|
|
if (!isset($data['mobile']) || !isset($data['type'])) {
|
|
throw new LocalizedException(__('Mobile and Form Type is required'));
|
|
}
|
|
$this->mobile = $data['mobile'];
|
|
$this->random = $random;
|
|
$this->type = $data['type'];
|
|
$this->config = $config;
|
|
$this->redis = $redis;
|
|
$this->gatewayResponse = $gatewayResponse;
|
|
$this->dataObjectHelper = $dataObjectHelper;
|
|
$this->dateTimeFactory = $dateTimeFactory;
|
|
}
|
|
|
|
/**
|
|
* @return String
|
|
*/
|
|
public function getCode() {
|
|
return $this->code;
|
|
}
|
|
|
|
/**
|
|
* @return ConfigInterface
|
|
*/
|
|
public function getAppConfig() {
|
|
return $this->config;
|
|
}
|
|
|
|
public function getSmsConfig(String $field) {
|
|
$path = 'sms/'.$this->type.'/'.$field;
|
|
$value = $this->config->getValue($path);
|
|
if (!$value) {
|
|
throw new LocalizedException(__('please config %path', ['path'=>$path]));
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
/**
|
|
* @param $path
|
|
* @return mixed
|
|
*/
|
|
protected function getGlobalConfig($path) {
|
|
$value = $this->config->getValue($path);
|
|
|
|
return $value;
|
|
}
|
|
|
|
public function getSuccess() {
|
|
return $this->success;
|
|
}
|
|
|
|
public function getMessage() {
|
|
return $this->message;
|
|
}
|
|
/**
|
|
* @return int
|
|
* @throws InvalidArgumentException
|
|
*/
|
|
public function getSmsInterval() {
|
|
if (!$this->type || !$this->mobile) {
|
|
throw new InvalidArgumentException(_('Please call setMobile,setType first'));
|
|
}
|
|
|
|
$sentAt = $this->smsInterval = (int)$this->redis->getRedis()
|
|
->hGet($this->type.'-'.$this->mobile, 'sent_at');
|
|
$now = $this->dateTimeFactory->create()->gmtTimestamp();
|
|
return $now-$sentAt;
|
|
}
|
|
|
|
/**
|
|
* @throws InvalidArgumentException
|
|
* @throws LocalizedException
|
|
*/
|
|
protected function beforeSend() {
|
|
if (!$this->type || !$this->mobile) {
|
|
throw new LocalizedException(__('Please call setMobile,setType first'));
|
|
}
|
|
|
|
$configInterval = $this->getGlobalConfig('sms/sms/time_interval');
|
|
if ($this->getSmsInterval() && $this->getSmsInterval() < $configInterval) {
|
|
throw new LocalizedException(__('SMS is sent too frequently, hold on please'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return GatewayResponseInterface
|
|
* @throws InvalidArgumentException
|
|
* @throws LocalizedException
|
|
*/
|
|
public function send(): GatewayResponseInterface
|
|
{
|
|
$this->beforeSend();
|
|
$this->code = Random::getRandomNumber(99999, 999999);
|
|
$response = $this->smsSend();
|
|
if ($response->getIsSuccess() || (int)$this->getGlobalConfig('sms/sms/debug')) {
|
|
$this->redis->getRedis()->hMSet(
|
|
$this->getSmsHashKey(),
|
|
[
|
|
'code' => $this->code,
|
|
'sent_at' => $this->dateTimeFactory->create()->gmtTimestamp()
|
|
]
|
|
);
|
|
$lifetime = (int)$this->getGlobalConfig('sms/sms/lifetime');
|
|
if ($lifetime){
|
|
$this->redis->getRedis()->expire($this->getSmsHashKey(), $lifetime);
|
|
}
|
|
|
|
}
|
|
return $response;
|
|
}
|
|
|
|
/**
|
|
* redis hash key
|
|
* @return string
|
|
*/
|
|
protected function getSmsHashKey() {
|
|
return $this->type.'-'.$this->mobile;
|
|
}
|
|
|
|
/**
|
|
* sms code validate
|
|
* @param string $code
|
|
* @return bool
|
|
*/
|
|
public function validate(string $code): bool
|
|
{
|
|
$storedCode = (int)$this->redis->getRedis()->hGet($this->getSmsHashKey(),'code');
|
|
if (!$storedCode) {
|
|
return false;
|
|
}
|
|
return $storedCode === (int)$code;
|
|
}
|
|
|
|
/**
|
|
* @param array $data
|
|
* @return GatewayResponseInterface
|
|
*/
|
|
protected function convertArrayToGatewayResponse(array $data) {
|
|
$this->dataObjectHelper->populateWithArray($this->gatewayResponse, $data, GatewayResponseInterface::class);
|
|
return $this->gatewayResponse;
|
|
}
|
|
|
|
protected abstract function smsSend(): GatewayResponseInterface;
|
|
|
|
protected abstract function getSenderType(): string;
|
|
}
|