123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- <?php
- /*
- * This file is part of the overtrue/easy-sms.
- *
- * (c) overtrue <i@overtrue.me>
- *
- * This source file is subject to the MIT license that is bundled
- * with this source code in the file LICENSE.
- */
- namespace Overtrue\EasySms;
- use Closure;
- use Overtrue\EasySms\Contracts\GatewayInterface;
- use Overtrue\EasySms\Contracts\MessageInterface;
- use Overtrue\EasySms\Contracts\PhoneNumberInterface;
- use Overtrue\EasySms\Contracts\StrategyInterface;
- use Overtrue\EasySms\Exceptions\InvalidArgumentException;
- use Overtrue\EasySms\Gateways\Gateway;
- use Overtrue\EasySms\Strategies\OrderStrategy;
- use Overtrue\EasySms\Support\Config;
- /**
- * Class EasySms.
- */
- class EasySms
- {
- /**
- * @var \Overtrue\EasySms\Support\Config
- */
- protected $config;
- /**
- * @var string
- */
- protected $defaultGateway;
- /**
- * @var array
- */
- protected $customCreators = [];
- /**
- * @var array
- */
- protected $gateways = [];
- /**
- * @var \Overtrue\EasySms\Messenger
- */
- protected $messenger;
- /**
- * @var array
- */
- protected $strategies = [];
- /**
- * Constructor.
- *
- * @param array $config
- */
- public function __construct(array $config)
- {
- $this->config = new Config($config);
- }
- /**
- * Send a message.
- *
- * @param string|array $to
- * @param \Overtrue\EasySms\Contracts\MessageInterface|array $message
- * @param array $gateways
- *
- * @return array
- *
- * @throws \Overtrue\EasySms\Exceptions\InvalidArgumentException
- * @throws \Overtrue\EasySms\Exceptions\NoGatewayAvailableException
- */
- public function send($to, $message, array $gateways = [])
- {
- $to = $this->formatPhoneNumber($to);
- $message = $this->formatMessage($message);
- $gateways = empty($gateways) ? $message->getGateways() : $gateways;
- if (empty($gateways)) {
- $gateways = $this->config->get('default.gateways', []);
- }
- return $this->getMessenger()->send($to, $message, $this->formatGateways($gateways));
- }
- /**
- * Create a gateway.
- *
- * @param string|null $name
- *
- * @return \Overtrue\EasySms\Contracts\GatewayInterface
- *
- * @throws \Overtrue\EasySms\Exceptions\InvalidArgumentException
- */
- public function gateway($name)
- {
- if (!isset($this->gateways[$name])) {
- $this->gateways[$name] = $this->createGateway($name);
- }
- return $this->gateways[$name];
- }
- /**
- * Get a strategy instance.
- *
- * @param string|null $strategy
- *
- * @return \Overtrue\EasySms\Contracts\StrategyInterface
- *
- * @throws \Overtrue\EasySms\Exceptions\InvalidArgumentException
- */
- public function strategy($strategy = null)
- {
- if (\is_null($strategy)) {
- $strategy = $this->config->get('default.strategy', OrderStrategy::class);
- }
- if (!\class_exists($strategy)) {
- $strategy = __NAMESPACE__.'\Strategies\\'.\ucfirst($strategy);
- }
- if (!\class_exists($strategy)) {
- throw new InvalidArgumentException("Unsupported strategy \"{$strategy}\"");
- }
- if (empty($this->strategies[$strategy]) || !($this->strategies[$strategy] instanceof StrategyInterface)) {
- $this->strategies[$strategy] = new $strategy($this);
- }
- return $this->strategies[$strategy];
- }
- /**
- * Register a custom driver creator Closure.
- *
- * @param string $name
- * @param \Closure $callback
- *
- * @return $this
- */
- public function extend($name, Closure $callback)
- {
- $this->customCreators[$name] = $callback;
- return $this;
- }
- /**
- * @return \Overtrue\EasySms\Support\Config
- */
- public function getConfig()
- {
- return $this->config;
- }
- /**
- * @return \Overtrue\EasySms\Messenger
- */
- public function getMessenger()
- {
- return $this->messenger ?: $this->messenger = new Messenger($this);
- }
- /**
- * Create a new driver instance.
- *
- * @param string $name
- *
- * @throws \InvalidArgumentException
- *
- * @return GatewayInterface
- *
- * @throws \Overtrue\EasySms\Exceptions\InvalidArgumentException
- */
- protected function createGateway($name)
- {
- $config = $this->config->get("gateways.{$name}", []);
- if (!isset($config['timeout'])) {
- $config['timeout'] = $this->config->get('timeout', Gateway::DEFAULT_TIMEOUT);
- }
- $config['options'] = $this->config->get('options', []);
- if (isset($this->customCreators[$name])) {
- $gateway = $this->callCustomCreator($name, $config);
- } else {
- $className = $this->formatGatewayClassName($name);
- $gateway = $this->makeGateway($className, $config);
- }
- if (!($gateway instanceof GatewayInterface)) {
- throw new InvalidArgumentException(\sprintf('Gateway "%s" must implement interface %s.', $name, GatewayInterface::class));
- }
- return $gateway;
- }
- /**
- * Make gateway instance.
- *
- * @param string $gateway
- * @param array $config
- *
- * @return \Overtrue\EasySms\Contracts\GatewayInterface
- *
- * @throws \Overtrue\EasySms\Exceptions\InvalidArgumentException
- */
- protected function makeGateway($gateway, $config)
- {
- if (!\class_exists($gateway) || !\in_array(GatewayInterface::class, \class_implements($gateway))) {
- throw new InvalidArgumentException(\sprintf('Class "%s" is a invalid easy-sms gateway.', $gateway));
- }
- return new $gateway($config);
- }
- /**
- * Format gateway name.
- *
- * @param string $name
- *
- * @return string
- */
- protected function formatGatewayClassName($name)
- {
- if (\class_exists($name) && \in_array(GatewayInterface::class, \class_implements($name))) {
- return $name;
- }
- $name = \ucfirst(\str_replace(['-', '_', ''], '', $name));
- return __NAMESPACE__."\\Gateways\\{$name}Gateway";
- }
- /**
- * Call a custom gateway creator.
- *
- * @param string $gateway
- * @param array $config
- *
- * @return mixed
- */
- protected function callCustomCreator($gateway, $config)
- {
- return \call_user_func($this->customCreators[$gateway], $config);
- }
- /**
- * @param string|\Overtrue\EasySms\Contracts\PhoneNumberInterface $number
- *
- * @return \Overtrue\EasySms\Contracts\PhoneNumberInterface|string
- */
- protected function formatPhoneNumber($number)
- {
- if ($number instanceof PhoneNumberInterface) {
- return $number;
- }
- return new PhoneNumber(\trim($number));
- }
- /**
- * @param array|string|\Overtrue\EasySms\Contracts\MessageInterface $message
- *
- * @return \Overtrue\EasySms\Contracts\MessageInterface
- */
- protected function formatMessage($message)
- {
- if (!($message instanceof MessageInterface)) {
- if (!\is_array($message)) {
- $message = [
- 'content' => $message,
- 'template' => $message,
- ];
- }
- $message = new Message($message);
- }
- return $message;
- }
- /**
- * @param array $gateways
- *
- * @return array
- *
- * @throws \Overtrue\EasySms\Exceptions\InvalidArgumentException
- */
- protected function formatGateways(array $gateways)
- {
- $formatted = [];
- foreach ($gateways as $gateway => $setting) {
- if (\is_int($gateway) && \is_string($setting)) {
- $gateway = $setting;
- $setting = [];
- }
- $formatted[$gateway] = $setting;
- $globalSettings = $this->config->get("gateways.{$gateway}", []);
- if (\is_string($gateway) && !empty($globalSettings) && \is_array($setting)) {
- $formatted[$gateway] = new Config(\array_merge($globalSettings, $setting));
- }
- }
- $result = [];
- foreach ($this->strategy()->apply($formatted) as $name) {
- $result[$name] = $formatted[$name];
- }
- return $result;
- }
- }
|