Completed
Push — master ( 932c41...b4ccf7 )
by Roman
03:16
created

Sender::send()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 25
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 25
ccs 19
cts 19
cp 1
rs 8.5806
cc 4
eloc 21
nc 3
nop 1
crap 4
1
<?php
2
3
namespace RM\SMSender\EuroSms;
4
5
use Nette\Utils\Strings;
6
use RM;
7
use RM\SMSender\BaseSender;
8
use RM\SMSender\ISender;
9
use RM\SMSender\IMessage;
10
use RM\SMSender\ConfigurationException;
11
use RM\SMSender\GatewayException;
12
use RM\SMSender\MissingParameterException;
13
14
/**
15
 * Sender for service EuroSms.sk
16
 */
17 1
class Sender extends BaseSender implements ISender
18
{
19
	CONST URL = 'https://as.eurosms.com/sms/Sender';
20
21
	/** @var string */
22
	private $id;
23
24
	/** @var string */
25
	private $key;
26
27
	/**
28
	 * @param  array $config
29
	 * @return self
30
	 */
31
	public function config($config)
32
	{
33 1
		$this->checkConfig($config['id'], $config['key']);
34
35 1
		$this->id = $config['id'];
36 1
		$this->key = $config['key'];
37 1
		return $this;
38
	}
39
40
	/**
41
	 * @param  IMessage $message
42
	 * @throws RM\SMSender\Exception
43
	 * @return bool|string ID of Message
44
	 */
45
	public function send(IMessage $message)
46
	{
47 1
		$this->check($message);
0 ignored issues
show
Compatibility introduced by
$message of type object<RM\SMSender\IMessage> is not a sub-type of object<RM\SMSender\EuroSms\Message>. It seems like you assume a concrete implementation of the interface RM\SMSender\IMessage to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
48 1
		$this->onBeforeSend($message);
0 ignored issues
show
Documentation Bug introduced by
The method onBeforeSend does not exist on object<RM\SMSender\EuroSms\Sender>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
49 1
		$res = $this->getHttpClient()->request('GET', self::URL . '?' . str_replace(urlencode($message->getTo()), $message->getTo(), http_build_query([
50 1
				'action' => ($this->debug ? 'validate' : 'send') . '1SMSHTTP',
51 1
				'i' => $this->id,
52 1
				's' => $this->getSignature($message),
0 ignored issues
show
Compatibility introduced by
$message of type object<RM\SMSender\IMessage> is not a sub-type of object<RM\SMSender\EuroSms\Message>. It seems like you assume a concrete implementation of the interface RM\SMSender\IMessage to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
53 1
				'd' => 1,
54 1
				'sender' => $message->getFrom(),
55 1
				'number' => $message->getTo(),
56 1
				'msg' => urlencode($message->getText()),
57
			])));
58 1
		$response = $res->getBody();
59 1
		if ($this->isSuccess($response)) {
60 1
			$this->onSuccess($message, $response);
0 ignored issues
show
Documentation Bug introduced by
The method onSuccess does not exist on object<RM\SMSender\EuroSms\Sender>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
61
		} else {
62 1
			$e = new GatewayException($response);
63 1
			$this->onError($message, $response, $e);
0 ignored issues
show
Documentation Bug introduced by
The method onError does not exist on object<RM\SMSender\EuroSms\Sender>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
64 1
			throw $e;
65
		}
66 1
		return ($this->debug)
67 1
			? TRUE
68 1
			: substr(Strings::trim((string)$response), 3);
69
	}
70
71
	/**
72
	 * @param  Message $message
73
	 * @return string
74
	 */
75
	public function getSignature(Message $message)
76
	{
77 1
		return substr(md5($this->key . str_replace('+', '', $message->getTo())), 10, 11);
78
	}
79
80
	/**
81
	 * @param  string  $response
82
	 * @return boolean
83
	 */
84
	public function isSuccess($response)
85
	{
86 1
		$response = Strings::trim((string)$response);
87 1
		return ($this->debug && $response === 'SMSValid') || (!$this->debug && substr($response, 0, 2) === 'ok');
88
	}
89
90
	/**
91
	 * @param  string $id
92
	 * @param  string $key
93
	 * @throws ConfigurationException
94
	 * @return bool
95
	 */
96
	private function checkConfig($id, $key)
97
	{
98 1
		if (!Strings::match($id, '~^1-[0-9a-zA-Z]{6}$~'))
99 1
			throw new ConfigurationException('Parameter "id" must be in format "1-[0-9a-zA-Z]{6}".');
100 1
		if (strlen($key) !== 8)
101 1
			throw new ConfigurationException('Parameter "key" must have 8 charactest. It has ' . strlen($key) . ' characters.');
102 1
		return TRUE;
103
	}
104
105
	/**
106
	 * @param  Message $message
107
	 * @throws MissingParameterException
108
	 * @return bool
109
	 */
110
	private function check(Message $message)
111
	{
112 1
		if (empty($message->getTo()))
113
			throw new MissingParameterException('Message has empty recipent number. Use method setTo().');
114 1
		if (empty($message->getFrom()))
115
			throw new MissingParameterException('Message has empty sender. Use method setFrom().');
116 1
		if (empty($message->getText()))
117
			throw new MissingParameterException('Message has empty text. Use method setText().');
118 1
		return TRUE;
119
	}
120
}
121