├── .gitignore ├── Api.php ├── Auth ├── AbstractAuth.php ├── ApiIdAuth.php ├── AuthInterface.php ├── LoginPasswordAuth.php ├── LoginPasswordSecureAuth.php └── TokenCache │ ├── ArrayCache.php │ ├── CacheInterface.php │ ├── DummyCache.php │ └── FileCache.php ├── Client ├── Client.php └── ClientInterface.php ├── Entity ├── AbstractSms.php ├── Sms.php ├── SmsPool.php └── StoplistPhone.php ├── Exception └── Exception.php ├── LICENSE ├── Response ├── AbstractResponse.php ├── AuthCheckResponse.php ├── MyBalanceResponse.php ├── MyLimitResponse.php ├── MySendersResponse.php ├── SmsCostResponse.php ├── SmsResponse.php ├── SmsStatusResponse.php ├── StoplistAddResponse.php ├── StoplistDelResponse.php └── StoplistGetResponse.php ├── composer.json └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | vendor/ -------------------------------------------------------------------------------- /Api.php: -------------------------------------------------------------------------------- 1 | auth = $auth; 41 | $this->auth->setContext($this); 42 | $this->client = $client; 43 | } 44 | 45 | /** 46 | * @param AbstractSms $sms 47 | * 48 | * @return SmsResponse 49 | * @throws Exception 50 | */ 51 | public function smsSend(AbstractSms $sms) 52 | { 53 | $params = []; 54 | 55 | if ($sms instanceof Sms) { 56 | $params['to'] = $sms->to; 57 | $params['text'] = $sms->text; 58 | } else if ($sms instanceof SmsPool) { 59 | foreach ($sms->messages as $message) { 60 | $params['multi'][$message->to] = $message->text; 61 | } 62 | } else { 63 | throw new Exception('Only Sms or SmsPool instances'); 64 | } 65 | 66 | if ($sms->from) { 67 | $params['from'] = $sms->from; 68 | } 69 | 70 | if ($sms->time && $sms->time < (time() + 7 * 24 * 60 * 60)) { 71 | $params['time'] = $sms->time; 72 | } 73 | 74 | if ($sms->translit) { 75 | $params['translit'] = 1; 76 | } 77 | 78 | if ($sms->test) { 79 | $params['test'] = 1; 80 | } 81 | 82 | if ($sms->partner_id) { 83 | $params['partner_id'] = $sms->partner_id; 84 | } else if ($this->getAuth()->getPartnerId()) { 85 | $params['partner_id'] = $this->getAuth()->getPartnerId(); 86 | } 87 | 88 | $response = $this->request('sms/send', $params); 89 | $response = explode("\n", $response); 90 | 91 | $smsResponse = new SmsResponse(array_shift($response)); 92 | 93 | if ($smsResponse->code == 100) { 94 | foreach ($response as $id) { 95 | if (!preg_match('/=/', $id)) { 96 | $smsResponse->ids[] = $id; 97 | } 98 | // else { 99 | // $result = explode('=', $id); 100 | // $response[$result[0]] = $result[1]; 101 | // } 102 | } 103 | } 104 | 105 | return $smsResponse; 106 | } 107 | 108 | /** 109 | * @param string $id 110 | * 111 | * @return SmsStatusResponse 112 | */ 113 | public function smsStatus($id) 114 | { 115 | $response = $this->request( 116 | 'sms/status', 117 | [ 118 | 'id' => $id, 119 | ] 120 | ); 121 | 122 | $response = explode("\n", $response); 123 | 124 | return new SmsStatusResponse(array_shift($response)); 125 | } 126 | 127 | /** 128 | * @param Sms $sms 129 | * 130 | * @return SmsCostResponse 131 | */ 132 | public function smsCost(Sms $sms) 133 | { 134 | $params = [ 135 | 'to' => $sms->to, 136 | 'text' => $sms->text, 137 | ]; 138 | 139 | $response = $this->request('sms/cost', $params); 140 | $response = explode("\n", $response); 141 | 142 | $smsCostResponse = new SmsCostResponse(array_shift($response)); 143 | $smsCostResponse->price = (float)$response[0]; 144 | $smsCostResponse->length = (int)$response[1]; 145 | 146 | return $smsCostResponse; 147 | } 148 | 149 | /** 150 | * @return MyBalanceResponse 151 | */ 152 | public function myBalance() 153 | { 154 | $response = $this->request('my/balance'); 155 | $response = explode("\n", $response); 156 | 157 | $myBalanceResponse = new MyBalanceResponse(array_shift($response)); 158 | $myBalanceResponse->balance = (float)$response[0]; 159 | 160 | return $myBalanceResponse; 161 | } 162 | 163 | /** 164 | * @return MyLimitResponse 165 | */ 166 | public function myLimit() 167 | { 168 | $response = $this->request('my/limit'); 169 | $response = explode("\n", $response); 170 | 171 | $myLimitResponse = new MyLimitResponse(array_shift($response)); 172 | $myLimitResponse->limit = (int)$response[0]; 173 | $myLimitResponse->current = (int)$response[1]; 174 | 175 | return $myLimitResponse; 176 | } 177 | 178 | /** 179 | * @return MySendersResponse 180 | */ 181 | public function mySenders() 182 | { 183 | $response = $this->request('my/senders'); 184 | $response = explode("\n", $response); 185 | 186 | $mySendersResponse = new MySendersResponse(array_shift($response)); 187 | 188 | foreach ($response as $phone) { 189 | if ($phone) { 190 | $mySendersResponse->phones[] = $phone; 191 | } 192 | } 193 | 194 | return $mySendersResponse; 195 | } 196 | 197 | /** 198 | * @return AuthCheckResponse 199 | */ 200 | public function authCheck() 201 | { 202 | $response = $this->request('auth/check'); 203 | $response = explode("\n", $response); 204 | 205 | return new AuthCheckResponse(array_shift($response)); 206 | } 207 | 208 | /** 209 | * @param string $stoplistPhone 210 | * @param string $stoplistText 211 | * 212 | * @return StoplistAddResponse 213 | */ 214 | public function stoplistAdd($stoplistPhone, $stoplistText) 215 | { 216 | $response = $this->request( 217 | 'stoplist/add', 218 | [ 219 | 'stoplist_phone' => $stoplistPhone, 220 | 'stoplist_text' => $stoplistText, 221 | ] 222 | ); 223 | 224 | $response = explode("\n", $response); 225 | 226 | return new StoplistAddResponse(array_shift($response)); 227 | } 228 | 229 | /** 230 | * @param string $stoplistPhone 231 | * 232 | * @return StoplistDelResponse 233 | */ 234 | public function stoplistDel($stoplistPhone) 235 | { 236 | $response = $this->request( 237 | 'stoplist/del', 238 | [ 239 | 'stoplist_phone' => $stoplistPhone, 240 | ] 241 | ); 242 | 243 | $response = explode("\n", $response); 244 | 245 | return new StoplistDelResponse(array_shift($response)); 246 | } 247 | 248 | /** 249 | * @return StoplistGetResponse 250 | */ 251 | public function stoplistGet() 252 | { 253 | $response = $this->request('stoplist/get'); 254 | $response = explode("\n", $response); 255 | 256 | $stoplistGetResponse = new StoplistGetResponse(array_shift($response)); 257 | 258 | foreach ($response as $phone) { 259 | $phone = explode(';', $phone); 260 | $stoplistGetResponse->phones[] = new StoplistPhone($phone[0], $phone[1]); 261 | } 262 | 263 | return $stoplistGetResponse; 264 | } 265 | 266 | /** 267 | * @param string $method 268 | * @param array $params 269 | * 270 | * @return string 271 | */ 272 | public function request($method, $params = []) 273 | { 274 | return $this->client->request($method, array_merge($params, $this->getAuth()->getAuthParams())); 275 | } 276 | 277 | /** 278 | * @return AuthInterface 279 | */ 280 | private function getAuth() 281 | { 282 | return $this->auth; 283 | } 284 | } 285 | -------------------------------------------------------------------------------- /Auth/AbstractAuth.php: -------------------------------------------------------------------------------- 1 | context; 31 | } 32 | 33 | /** 34 | * @param Api $context 35 | */ 36 | public function setContext(Api $context) 37 | { 38 | $this->context = $context; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Auth/ApiIdAuth.php: -------------------------------------------------------------------------------- 1 | apiId = $apiId; 25 | $this->partnerId = $partnerId; 26 | } 27 | 28 | /** 29 | * @return array 30 | */ 31 | public function getAuthParams() 32 | { 33 | return [ 34 | 'api_id' => $this->apiId, 35 | ]; 36 | } 37 | 38 | /** 39 | * @return string 40 | */ 41 | public function getApiId() 42 | { 43 | return $this->apiId; 44 | } 45 | 46 | /** 47 | * @return null|string 48 | */ 49 | public function getPartnerId() 50 | { 51 | return $this->partnerId; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Auth/AuthInterface.php: -------------------------------------------------------------------------------- 1 | login = $login; 30 | $this->password = $password; 31 | $this->partnerId = $partnerId; 32 | } 33 | 34 | /** 35 | * @return array 36 | */ 37 | public function getAuthParams() 38 | { 39 | return [ 40 | 'login' => $this->login, 41 | 'password' => $this->password, 42 | ]; 43 | } 44 | 45 | /** 46 | * @return null|string 47 | */ 48 | public function getPartnerId() 49 | { 50 | return $this->partnerId; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Auth/LoginPasswordSecureAuth.php: -------------------------------------------------------------------------------- 1 | login = $login; 51 | $this->password = $password; 52 | $this->apiId = $apiId; 53 | $this->cache = $cache === null ? new DummyCache() : $cache; 54 | $this->partnerId = $partnerId; 55 | } 56 | 57 | /** 58 | * @return array 59 | */ 60 | public function getAuthParams() 61 | { 62 | $token = $this->authGetToken(); 63 | 64 | return [ 65 | 'login' => $this->login, 66 | 'token' => $token, 67 | 'sha512' => !empty($this->apiId) 68 | ? hash('sha512', $this->password . $token . $this->apiId) 69 | : hash('sha512', $this->password . $token), 70 | ]; 71 | } 72 | 73 | /** 74 | * @return null|string 75 | */ 76 | public function getApiId() 77 | { 78 | return $this->apiId; 79 | } 80 | 81 | /** 82 | * @return null|string 83 | */ 84 | public function getPartnerId() 85 | { 86 | return $this->partnerId; 87 | } 88 | 89 | /** 90 | * @return string 91 | */ 92 | private function authGetToken() 93 | { 94 | $token = null; 95 | if ($this->cache->exists($this->cacheKey)) { 96 | $token = $this->cache->get($this->cacheKey); 97 | } 98 | 99 | if (!$token) { 100 | $token = $this->requestAuthToken(); 101 | $this->cache->set($this->cacheKey, $token, 60 * 9); 102 | } 103 | 104 | return $token; 105 | } 106 | 107 | /** 108 | * @return string 109 | */ 110 | private function requestAuthToken() 111 | { 112 | return $this->getContext() 113 | ->getClient() 114 | ->request('auth/get_token'); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /Auth/TokenCache/ArrayCache.php: -------------------------------------------------------------------------------- 1 | cache[$key]) && ($this->cache[$key][1] === 0 || $this->cache[$key][1] > microtime(true)); 19 | } 20 | 21 | /** 22 | * @inheritdoc 23 | */ 24 | public function get($key) 25 | { 26 | return isset($this->cache[$key]) && ($this->cache[$key][1] === 0 || $this->cache[$key][1] > microtime(true)) 27 | ? $this->cache[$key][0] 28 | : false; 29 | } 30 | 31 | /** 32 | * @inheritdoc 33 | */ 34 | public function set($key, $value, $ttl = null) 35 | { 36 | $ttl = (int)$ttl; 37 | $ttl = empty($ttl) 38 | ? 31536000 // 1 year 39 | : $ttl; 40 | $this->cache[$key] = [$value, microtime(true) + $ttl]; 41 | 42 | return true; 43 | } 44 | 45 | /** 46 | * @inheritdoc 47 | */ 48 | public function remove($key) 49 | { 50 | unset($this->cache[$key]); 51 | 52 | return true; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Auth/TokenCache/CacheInterface.php: -------------------------------------------------------------------------------- 1 | path = empty($path) 22 | ? implode(DIRECTORY_SEPARATOR, [sys_get_temp_dir(), 'cache']) 23 | : $path; 24 | 25 | if (!is_dir($this->path)) { 26 | $this->mkdir($this->path); 27 | } 28 | 29 | if (!is_writable($this->path)) { 30 | throw new Exception(sprintf('Cache directory is not writable: %s', $path)); 31 | } 32 | } 33 | 34 | /** 35 | * @inheritdoc 36 | */ 37 | public function exists($key) 38 | { 39 | $cacheFile = $this->getCacheFile($key); 40 | 41 | return @filemtime($cacheFile) > time(); 42 | } 43 | 44 | /** 45 | * @inheritdoc 46 | */ 47 | public function get($key) 48 | { 49 | $cacheFile = $this->getCacheFile($key); 50 | 51 | if (@filemtime($cacheFile) > time()) { 52 | $fp = @fopen($cacheFile, 'r'); 53 | if ($fp !== false) { 54 | @flock($fp, LOCK_SH); 55 | $cacheValue = @stream_get_contents($fp); 56 | @flock($fp, LOCK_UN); 57 | @fclose($fp); 58 | 59 | return empty($cacheValue) ? false : $cacheValue; 60 | } 61 | } 62 | 63 | return false; 64 | } 65 | 66 | /** 67 | * @inheritdoc 68 | */ 69 | public function set($key, $value, $ttl = null) 70 | { 71 | $cacheFile = $this->getCacheFile($key); 72 | 73 | if (@file_put_contents($cacheFile, $value, LOCK_EX) !== false) { 74 | @chmod($cacheFile, 0666); 75 | 76 | $ttl = (int)$ttl; 77 | $ttl = empty($ttl) 78 | ? 31536000 // 1 year 79 | : $ttl; 80 | 81 | return @touch($cacheFile, $ttl + time()); 82 | } else { 83 | $error = error_get_last(); 84 | 85 | throw new Exception(sprintf('Unable to write cache file "%s": %s', $cacheFile, $error['message'])); 86 | } 87 | } 88 | 89 | /** 90 | * @inheritdoc 91 | */ 92 | public function remove($key) 93 | { 94 | $cacheFile = $this->getCacheFile($key); 95 | 96 | return @unlink($cacheFile); 97 | } 98 | 99 | /** 100 | * @param string $key 101 | * 102 | * @return string 103 | */ 104 | private function getCacheFile($key) 105 | { 106 | return $this->path . DIRECTORY_SEPARATOR . $key . '.bin'; 107 | } 108 | 109 | /** 110 | * @param string $path 111 | * @param integer $mode 112 | * @param bool $recursive 113 | * 114 | * @return bool 115 | * @throws Exception 116 | */ 117 | private function mkdir($path, $mode = 0775, $recursive = true) 118 | { 119 | if (is_dir($path)) { 120 | return true; 121 | } 122 | 123 | $parentDir = dirname($path); 124 | // recurse if parent dir does not exist and we are not at the root of the file system. 125 | if ($recursive && !is_dir($parentDir) && $parentDir !== $path) { 126 | $this->mkdir($parentDir, $mode, true); 127 | } 128 | 129 | try { 130 | if (!mkdir($path, $mode)) { 131 | return false; 132 | } 133 | } catch (\Exception $e) { 134 | if (!is_dir($path)) { 135 | throw new Exception(sprintf('Failed to create directory "%s": %s', $path, $e->getMessage()), $e->getCode(), $e); 136 | } 137 | } 138 | 139 | try { 140 | return chmod($path, $mode); 141 | } catch (\Exception $e) { 142 | throw new Exception(sprintf('Failed to change permissions for directory "%s": %s', $path, $e->getMessage()), $e->getCode(), $e); 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /Client/Client.php: -------------------------------------------------------------------------------- 1 | client = new \GuzzleHttp\Client($config); 25 | } 26 | 27 | /** 28 | * @param string $method 29 | * @param array $params 30 | * 31 | * @return string 32 | * 33 | * @throws Exception 34 | */ 35 | public function request($method, $params = []) 36 | { 37 | $response = $this->client->post($this->getUrl($method), ['query' => $params]); 38 | 39 | if ($response->getStatusCode() === 200) { 40 | return (string)$response->getBody(); 41 | } else { 42 | throw new Exception(sprintf('Sms.ru problem. Status code is %s', $response->getStatusCode()), $response->getStatusCode()); 43 | } 44 | } 45 | 46 | /** 47 | * @param string $method 48 | * 49 | * @return string 50 | */ 51 | private function getUrl($method) 52 | { 53 | return strtr($this->baseUrl, ['{method}' => $method]); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Client/ClientInterface.php: -------------------------------------------------------------------------------- 1 | to = $to; 25 | $this->text = $text; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Entity/SmsPool.php: -------------------------------------------------------------------------------- 1 | messages = $messages; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Entity/StoplistPhone.php: -------------------------------------------------------------------------------- 1 | phone = $phone; 25 | $this->text = $text; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Exception/Exception.php: -------------------------------------------------------------------------------- 1 | code = $code; 24 | } 25 | 26 | /** 27 | * @return null|string 28 | */ 29 | public function getDescription() 30 | { 31 | return isset($this->availableDescriptions[$this->code]) 32 | ? $this->availableDescriptions[$this->code] 33 | : null; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Response/AuthCheckResponse.php: -------------------------------------------------------------------------------- 1 | 'ОК, номер телефона и пароль совпадают.', 13 | '300' => 'Неправильный token (возможно истек срок действия, либо ваш IP изменился).', 14 | '301' => 'Неправильный пароль, либо пользователь не найден.', 15 | '302' => 'Пользователь авторизован, но аккаунт не подтвержден (пользователь не ввел код, присланный в регистрационной смс).', 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /Response/MyBalanceResponse.php: -------------------------------------------------------------------------------- 1 | 'Запрос выполнен. На второй строчке вы найдете ваше текущее состояние баланса.', 18 | '200' => 'Неправильный api_id.', 19 | '210' => 'Используется GET, где необходимо использовать POST.', 20 | '211' => 'Метод не найден.', 21 | '220' => 'Сервис временно недоступен, попробуйте чуть позже.', 22 | '300' => 'Неправильный token (возможно истек срок действия, либо ваш IP изменился).', 23 | '301' => 'Неправильный пароль, либо пользователь не найден.', 24 | '302' => 'Пользователь авторизован, но аккаунт не подтвержден (пользователь не ввел код, присланный в регистрационной смс).', 25 | ]; 26 | } 27 | -------------------------------------------------------------------------------- /Response/MyLimitResponse.php: -------------------------------------------------------------------------------- 1 | 'Запрос выполнен. На второй строчке вы найдете ваше текущее дневное ограничение. На третьей строчке количество сообщений, отправленных вами в текущий день.', 23 | '200' => 'Неправильный api_id.', 24 | '210' => 'Используется GET, где необходимо использовать POST.', 25 | '211' => 'Метод не найден.', 26 | '220' => 'Сервис временно недоступен, попробуйте чуть позже.', 27 | '300' => 'Неправильный token (возможно истек срок действия, либо ваш IP изменился).', 28 | '301' => 'Неправильный пароль, либо пользователь не найден.', 29 | '302' => 'Пользователь авторизован, но аккаунт не подтвержден (пользователь не ввел код, присланный в регистрационной смс).', 30 | ]; 31 | } 32 | -------------------------------------------------------------------------------- /Response/MySendersResponse.php: -------------------------------------------------------------------------------- 1 | 'Запрос выполнен. На второй и последующих строчках вы найдете ваших одобренных отправителей, которые можно использовать в параметре &from= метода sms/send.', 18 | '200' => 'Неправильный api_id.', 19 | '210' => 'Используется GET, где необходимо использовать POST.', 20 | '211' => 'Метод не найден.', 21 | '220' => 'Сервис временно недоступен, попробуйте чуть позже.', 22 | '300' => 'Неправильный token (возможно истек срок действия, либо ваш IP изменился).', 23 | '301' => 'Неправильный пароль, либо пользователь не найден.', 24 | '302' => 'Пользователь авторизован, но аккаунт не подтвержден (пользователь не ввел код, присланный в регистрационной смс).', 25 | ]; 26 | } 27 | -------------------------------------------------------------------------------- /Response/SmsCostResponse.php: -------------------------------------------------------------------------------- 1 | 'Запрос выполнен. На второй строчке будет указана стоимость сообщения. На третьей строчке будет указана его длина.', 23 | '200' => 'Неправильный api_id.', 24 | '202' => 'Неправильно указан получатель.', 25 | '207' => 'На этот номер нельзя отправлять сообщения.', 26 | '210' => 'Используется GET, где необходимо использовать POST.', 27 | '211' => 'Метод не найден.', 28 | '220' => 'Сервис временно недоступен, попробуйте чуть позже.', 29 | '300' => 'Неправильный token (возможно истек срок действия, либо ваш IP изменился).', 30 | '301' => 'Неправильный пароль, либо пользователь не найден.', 31 | '302' => 'Пользователь авторизован, но аккаунт не подтвержден (пользователь не ввел код, присланный в регистрационной смс).', 32 | ]; 33 | } 34 | -------------------------------------------------------------------------------- /Response/SmsResponse.php: -------------------------------------------------------------------------------- 1 | 'Сообщение принято к отправке. На следующих строчках вы найдете идентификаторы отправленных сообщений в том же порядке, в котором вы указали номера, на которых совершалась отправка.', 18 | '200' => 'Неправильный api_id.', 19 | '201' => 'Не хватает средств на лицевом счету.', 20 | '202' => 'Неправильно указан получатель.', 21 | '203' => 'Нет текста сообщения.', 22 | '204' => 'Имя отправителя не согласовано с администрацией.', 23 | '205' => 'Сообщение слишком длинное (превышает 8 СМС).', 24 | '206' => 'Будет превышен или уже превышен дневной лимит на отправку сообщений.', 25 | '207' => 'На этот номер (или один из номеров) нельзя отправлять сообщения, либо указано более 100 номеров в списке получателей.', 26 | '208' => 'Параметр time указан неправильно.', 27 | '209' => 'Вы добавили этот номер (или один из номеров) в стоп-лист.', 28 | '210' => 'Используется GET, где необходимо использовать POST.', 29 | '211' => 'Метод не найден.', 30 | '212' => 'Текст сообщения необходимо передать в кодировке UTF-8 (вы передали в другой кодировке).', 31 | '220' => 'Сервис временно недоступен, попробуйте чуть позже.', 32 | '230' => 'Сообщение не принято к отправке, так как на один номер в день нельзя отправлять более 60 сообщений.', 33 | '300' => 'Неправильный token (возможно истек срок действия, либо ваш IP изменился).', 34 | '301' => 'Неправильный пароль, либо пользователь не найден.', 35 | '302' => 'Пользователь авторизован, но аккаунт не подтвержден (пользователь не ввел код, присланный в регистрационной смс).', 36 | ]; 37 | } 38 | -------------------------------------------------------------------------------- /Response/SmsStatusResponse.php: -------------------------------------------------------------------------------- 1 | 'Сообщение не найдено.', 13 | '100' => 'Сообщение находится в нашей очереди.', 14 | '101' => 'Сообщение передается оператору.', 15 | '102' => 'Сообщение отправлено (в пути).', 16 | '103' => 'Сообщение доставлено.', 17 | '104' => 'Не может быть доставлено: время жизни истекло.', 18 | '105' => 'Не может быть доставлено: удалено оператором.', 19 | '106' => 'Не может быть доставлено: сбой в телефоне.', 20 | '107' => 'Не может быть доставлено: неизвестная причина.', 21 | '108' => 'Не может быть доставлено: отклонено.', 22 | '200' => 'Неправильный api_id.', 23 | '210' => 'Используется GET, где необходимо использовать POST.', 24 | '211' => 'Метод не найден.', 25 | '220' => 'Сервис временно недоступен, попробуйте чуть позже.', 26 | '300' => 'Неправильный token (возможно истек срок действия, либо ваш IP изменился).', 27 | '301' => 'Неправильный пароль, либо пользователь не найден.', 28 | '302' => 'Пользователь авторизован, но аккаунт не подтвержден (пользователь не ввел код, присланный в регистрационной смс).', 29 | ]; 30 | } 31 | -------------------------------------------------------------------------------- /Response/StoplistAddResponse.php: -------------------------------------------------------------------------------- 1 | 'Номер добавлен в стоплист.', 13 | '202' => 'Номер телефона в неправильном формате.', 14 | ]; 15 | } 16 | -------------------------------------------------------------------------------- /Response/StoplistDelResponse.php: -------------------------------------------------------------------------------- 1 | 'Номер удален из стоплиста.', 13 | '202' => 'Номер телефона в неправильном формате.', 14 | ]; 15 | } 16 | -------------------------------------------------------------------------------- /Response/StoplistGetResponse.php: -------------------------------------------------------------------------------- 1 | 'Запрос обработан. На последующих строчках будут идти номера телефонов, указанных в стоплисте в формате номер;примечание.', 20 | ]; 21 | } 22 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zelenin/smsru", 3 | "description": "PHP-класс для работы с api сервиса [sms.ru](http://sms.ru)", 4 | "type": "library", 5 | "keywords": [ 6 | "sms", 7 | "sms.ru", 8 | "api" 9 | ], 10 | "homepage": "https://github.com/zelenin/sms_ru", 11 | "license": "MIT", 12 | "authors": [ 13 | { 14 | "name": "Aleksandr Zelenin", 15 | "email": "aleksandr@zelenin.me", 16 | "homepage": "http://zelenin.me", 17 | "role": "Developer" 18 | } 19 | ], 20 | "support": { 21 | "issues": "https://github.com/zelenin/sms_ru/issues", 22 | "source": "https://github.com/zelenin/sms_ru" 23 | }, 24 | "require": { 25 | "php": ">=5.5.0", 26 | "guzzlehttp/guzzle": "~6 || ~7" 27 | }, 28 | "autoload": { 29 | "psr-4": { 30 | "Zelenin\\SmsRu\\": "" 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # sms_ru 2 | 3 | PHP-класс для работы с api сервиса [sms.ru](http://sms.ru) 4 | 5 | ## Установка 6 | 7 | ### Предупреждение 8 | 9 | Версия 4 имеет отличное от предыдущих версий API. 10 | 11 | ### Установка через Composer 12 | 13 | Запустите 14 | 15 | ``` 16 | php composer.phar require zelenin/smsru "~5" 17 | ``` 18 | 19 | или добавьте 20 | 21 | ``` 22 | "zelenin/smsru": "~5" 23 | ``` 24 | 25 | в секцию ```require``` вашего composer.json 26 | 27 | ## Использование 28 | 29 | Простая авторизация (с помощью api_id): 30 | 31 | ```php 32 | $client = new \Zelenin\SmsRu\Api(new \Zelenin\SmsRu\Auth\ApiIdAuth($apiId), new \Zelenin\SmsRu\Client\Client()); 33 | ``` 34 | 35 | Усиленная авторизация (с помощью api_id, логина и пароля): 36 | 37 | ```php 38 | $client = new \Zelenin\SmsRu\Api(new \Zelenin\SmsRu\Auth\LoginPasswordSecureAuth($login, $password, $apiId), new \Zelenin\SmsRu\Client\Client()); 39 | ``` 40 | 41 | Усиленная авторизация (с помощью логина и пароля): 42 | 43 | ```php 44 | $client = new \Zelenin\SmsRu\Api(new \Zelenin\SmsRu\Auth\LoginPasswordAuth($login, $password), new \Zelenin\SmsRu\Client\Client()); 45 | ``` 46 | 47 | Отправка SMS: 48 | 49 | ```php 50 | $sms1 = new \Zelenin\SmsRu\Entity\Sms($phone1, $text1); 51 | $sms1->translit = 1; 52 | $sms2 = new \Zelenin\SmsRu\Entity\Sms($phone2, $text2); 53 | 54 | $client->smsSend($sms1); 55 | $client->smsSend($sms2); 56 | 57 | $client->smsSend(new \Zelenin\SmsRu\Entity\SmsPool([$sms1, $sms2])); 58 | ``` 59 | 60 | Статус SMS: 61 | 62 | ```php 63 | $send = $client->smsSend($sms); 64 | $smsId = $send->ids[0]; 65 | $client->smsStatus($smsId); 66 | ``` 67 | 68 | Стоимость SMS: 69 | 70 | ```php 71 | $client->smsCost(new \Zelenin\SmsRu\Entity\Sms($phone, $text)); 72 | ``` 73 | 74 | Баланс: 75 | 76 | ```php 77 | $client->myBalance(); 78 | ``` 79 | 80 | Дневной лимит: 81 | 82 | ```php 83 | $client->myLimit(); 84 | ``` 85 | 86 | Отправители: 87 | 88 | ```php 89 | $client->mySenders(); 90 | ``` 91 | 92 | Проверка валидности логина и пароля: 93 | 94 | ```php 95 | $client->authCheck(); 96 | ``` 97 | 98 | Добавить номер в стоплист: 99 | 100 | ```php 101 | $client->stoplistAdd($phone, $text); 102 | ``` 103 | 104 | Удалить номер из стоп-листа: 105 | 106 | ```php 107 | $client->stoplistDel($phone); 108 | ``` 109 | 110 | Получить номера стоплиста: 111 | 112 | ```php 113 | $client->stoplistGet(); 114 | ``` 115 | 116 | ## Автор 117 | 118 | [Александр Зеленин](https://github.com/zelenin/), e-mail: [aleksandr@zelenin.me](mailto:aleksandr@zelenin.me) 119 | --------------------------------------------------------------------------------