2017-05-16 16:20:33 +03:00
|
|
|
<?php
|
2013-08-08 03:22:19 +04:00
|
|
|
|
2016-09-18 10:56:14 +03:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2013-2016 Mailgun
|
|
|
|
*
|
|
|
|
* This software may be modified and distributed under the terms
|
2016-12-06 21:12:52 +03:00
|
|
|
* of the MIT license. See the LICENSE file for details.
|
2016-09-18 10:56:14 +03:00
|
|
|
*/
|
|
|
|
|
2013-08-08 03:22:19 +04:00
|
|
|
namespace Mailgun;
|
|
|
|
|
2016-10-24 20:01:32 +03:00
|
|
|
use Http\Client\Common\HttpMethodsClient;
|
2015-10-30 16:28:43 +03:00
|
|
|
use Http\Client\HttpClient;
|
2013-08-13 23:26:34 +04:00
|
|
|
use Mailgun\Connection\RestClient;
|
2016-07-24 14:42:47 +03:00
|
|
|
use Mailgun\Constants\ExceptionMessages;
|
2017-03-26 11:17:10 +03:00
|
|
|
use Mailgun\HttpClient\Plugin\History;
|
2013-08-16 22:20:01 +04:00
|
|
|
use Mailgun\Lists\OptInHandler;
|
2016-07-24 14:42:47 +03:00
|
|
|
use Mailgun\Messages\BatchMessage;
|
|
|
|
use Mailgun\Messages\Exceptions;
|
2013-08-08 04:41:14 +04:00
|
|
|
use Mailgun\Messages\MessageBuilder;
|
2017-03-22 09:44:08 +03:00
|
|
|
use Mailgun\Hydrator\ModelHydrator;
|
|
|
|
use Mailgun\Hydrator\Hydrator;
|
2017-03-26 11:17:10 +03:00
|
|
|
use Psr\Http\Message\ResponseInterface;
|
2013-08-08 03:22:19 +04:00
|
|
|
|
2014-11-20 21:41:25 +03:00
|
|
|
/**
|
|
|
|
* This class is the base class for the Mailgun SDK.
|
|
|
|
*/
|
2016-07-24 14:40:50 +03:00
|
|
|
class Mailgun
|
|
|
|
{
|
2014-11-20 21:41:25 +03:00
|
|
|
/**
|
|
|
|
* @var RestClient
|
2016-10-24 20:01:32 +03:00
|
|
|
*
|
|
|
|
* @depracated Will be removed in 3.0
|
2014-11-20 21:41:25 +03:00
|
|
|
*/
|
2013-08-08 03:22:19 +04:00
|
|
|
protected $restClient;
|
2014-11-20 21:41:25 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var null|string
|
|
|
|
*/
|
2014-06-25 01:36:21 +04:00
|
|
|
protected $apiKey;
|
2014-11-20 21:41:25 +03:00
|
|
|
|
|
|
|
/**
|
2016-10-24 20:01:32 +03:00
|
|
|
* @var HttpMethodsClient
|
|
|
|
*/
|
|
|
|
private $httpClient;
|
|
|
|
|
|
|
|
/**
|
2017-03-22 09:44:08 +03:00
|
|
|
* @var Hydrator
|
2016-10-24 20:01:32 +03:00
|
|
|
*/
|
2017-03-22 09:44:08 +03:00
|
|
|
private $hydrator;
|
2016-10-24 20:01:32 +03:00
|
|
|
|
|
|
|
/**
|
2016-11-23 23:55:05 +03:00
|
|
|
* @var RequestBuilder
|
2016-10-24 20:01:32 +03:00
|
|
|
*/
|
2016-11-23 23:55:05 +03:00
|
|
|
private $requestBuilder;
|
2016-10-24 20:01:32 +03:00
|
|
|
|
2017-03-26 11:17:10 +03:00
|
|
|
/**
|
|
|
|
* This is a object that holds the last response from the API.
|
|
|
|
*
|
|
|
|
* @var History
|
|
|
|
*/
|
|
|
|
private $responseHistory = null;
|
|
|
|
|
2016-10-24 20:01:32 +03:00
|
|
|
/**
|
2017-03-26 21:42:36 +03:00
|
|
|
* @param string|null $apiKey
|
|
|
|
* @param HttpClient|null $httpClient
|
|
|
|
* @param string $apiEndpoint
|
|
|
|
* @param Hydrator|null $hydrator
|
|
|
|
* @param RequestBuilder|null $requestBuilder
|
2017-05-16 15:51:25 +03:00
|
|
|
*
|
|
|
|
* @internal Use Mailgun::configure or Mailgun::create instead.
|
2014-11-20 21:41:25 +03:00
|
|
|
*/
|
2017-05-16 16:20:33 +03:00
|
|
|
public function __construct(
|
2017-03-26 21:42:36 +03:00
|
|
|
$apiKey = null, /* Deprecated, will be removed in 3.0 */
|
|
|
|
HttpClient $httpClient = null,
|
2016-10-24 20:01:32 +03:00
|
|
|
$apiEndpoint = 'api.mailgun.net', /* Deprecated, will be removed in 3.0 */
|
2017-03-22 09:44:08 +03:00
|
|
|
Hydrator $hydrator = null,
|
2016-11-23 23:55:05 +03:00
|
|
|
RequestBuilder $requestBuilder = null
|
2015-10-12 20:23:58 +03:00
|
|
|
) {
|
2014-11-20 01:29:08 +03:00
|
|
|
$this->apiKey = $apiKey;
|
2016-03-05 13:13:28 +03:00
|
|
|
$this->restClient = new RestClient($apiKey, $apiEndpoint, $httpClient);
|
2016-10-24 20:01:32 +03:00
|
|
|
|
2017-03-26 21:42:36 +03:00
|
|
|
$this->httpClient = $httpClient;
|
2016-11-23 23:55:05 +03:00
|
|
|
$this->requestBuilder = $requestBuilder ?: new RequestBuilder();
|
2017-03-22 09:44:08 +03:00
|
|
|
$this->hydrator = $hydrator ?: new ModelHydrator();
|
2013-08-08 03:22:19 +04:00
|
|
|
}
|
2013-08-08 04:41:14 +04:00
|
|
|
|
2017-03-25 15:48:03 +03:00
|
|
|
/**
|
2017-04-08 02:29:20 +03:00
|
|
|
* @param HttpClientConfigurator $configurator
|
2017-03-25 15:48:03 +03:00
|
|
|
* @param Hydrator|null $hydrator
|
|
|
|
* @param RequestBuilder|null $requestBuilder
|
|
|
|
*
|
|
|
|
* @return Mailgun
|
|
|
|
*/
|
|
|
|
public static function configure(
|
2017-04-08 02:29:20 +03:00
|
|
|
HttpClientConfigurator $configurator,
|
2017-03-25 15:48:03 +03:00
|
|
|
Hydrator $hydrator = null,
|
|
|
|
RequestBuilder $requestBuilder = null
|
|
|
|
) {
|
2017-04-08 02:29:20 +03:00
|
|
|
$httpClient = $configurator->createConfiguredClient();
|
2017-03-25 15:48:03 +03:00
|
|
|
|
2017-04-08 02:29:20 +03:00
|
|
|
return new self($configurator->getApiKey(), $httpClient, 'api.mailgun.net', $hydrator, $requestBuilder);
|
2017-03-25 15:48:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $apiKey
|
|
|
|
*
|
|
|
|
* @return Mailgun
|
|
|
|
*/
|
|
|
|
public static function create($apiKey)
|
|
|
|
{
|
|
|
|
$httpClientConfigurator = (new HttpClientConfigurator())->setApiKey($apiKey);
|
|
|
|
|
|
|
|
return self::configure($httpClientConfigurator);
|
|
|
|
}
|
|
|
|
|
2014-11-20 21:41:25 +03:00
|
|
|
/**
|
|
|
|
* This function allows the sending of a fully formed message OR a custom
|
|
|
|
* MIME string. If sending MIME, the string must be passed in to the 3rd
|
|
|
|
* position of the function call.
|
|
|
|
*
|
2016-07-24 14:41:21 +03:00
|
|
|
* @param string $workingDomain
|
|
|
|
* @param array $postData
|
|
|
|
* @param array $postFiles
|
|
|
|
*
|
2014-11-20 21:41:25 +03:00
|
|
|
* @throws Exceptions\MissingRequiredMIMEParameters
|
2016-07-24 14:42:47 +03:00
|
|
|
*
|
|
|
|
* @return \stdClass
|
2017-03-14 12:58:47 +03:00
|
|
|
*
|
|
|
|
* @deprecated Use Mailgun->message() instead. Will be removed in 3.0
|
2014-11-20 21:41:25 +03:00
|
|
|
*/
|
2016-07-24 14:42:47 +03:00
|
|
|
public function sendMessage($workingDomain, $postData, $postFiles = [])
|
2016-07-24 14:40:50 +03:00
|
|
|
{
|
2016-07-24 14:41:21 +03:00
|
|
|
if (is_array($postFiles)) {
|
2014-11-20 01:29:08 +03:00
|
|
|
return $this->post("$workingDomain/messages", $postData, $postFiles);
|
2016-07-24 14:41:21 +03:00
|
|
|
} elseif (is_string($postFiles)) {
|
|
|
|
$tempFile = tempnam(sys_get_temp_dir(), 'MG_TMP_MIME');
|
|
|
|
$fileHandle = fopen($tempFile, 'w');
|
2014-11-20 01:29:08 +03:00
|
|
|
fwrite($fileHandle, $postFiles);
|
2014-05-13 17:58:12 +04:00
|
|
|
|
2016-07-24 14:42:47 +03:00
|
|
|
$result = $this->post("$workingDomain/messages.mime", $postData, ['message' => $tempFile]);
|
2014-05-13 19:07:44 +04:00
|
|
|
fclose($fileHandle);
|
|
|
|
unlink($tempFile);
|
2016-07-24 14:41:21 +03:00
|
|
|
|
2014-11-20 01:29:08 +03:00
|
|
|
return $result;
|
2016-07-24 14:41:21 +03:00
|
|
|
} else {
|
2014-11-20 21:41:25 +03:00
|
|
|
throw new Exceptions\MissingRequiredMIMEParameters(ExceptionMessages::EXCEPTION_MISSING_REQUIRED_MIME_PARAMETERS);
|
2014-11-20 01:29:08 +03:00
|
|
|
}
|
|
|
|
}
|
2014-11-20 21:41:25 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This function checks the signature in a POST request to see if it is
|
|
|
|
* authentic.
|
|
|
|
*
|
|
|
|
* Pass an array of parameters. If you pass nothing, $_POST will be
|
|
|
|
* used instead.
|
|
|
|
*
|
|
|
|
* If this function returns FALSE, you must not process the request.
|
|
|
|
* You should reject the request with status code 403 Forbidden.
|
|
|
|
*
|
2016-07-24 14:41:21 +03:00
|
|
|
* @param array|null $postData
|
|
|
|
*
|
2014-11-20 21:41:25 +03:00
|
|
|
* @return bool
|
2017-03-14 12:58:47 +03:00
|
|
|
*
|
|
|
|
* @deprecated Use Mailgun->webhook() instead. Will be removed in 3.0
|
2014-11-20 21:41:25 +03:00
|
|
|
*/
|
2016-07-24 14:41:21 +03:00
|
|
|
public function verifyWebhookSignature($postData = null)
|
2016-07-24 14:40:50 +03:00
|
|
|
{
|
2016-07-24 14:41:21 +03:00
|
|
|
if ($postData === null) {
|
2014-11-20 01:29:08 +03:00
|
|
|
$postData = $_POST;
|
|
|
|
}
|
2016-07-24 14:41:21 +03:00
|
|
|
if (!isset($postData['timestamp']) || !isset($postData['token']) || !isset($postData['signature'])) {
|
2015-09-13 21:01:16 +03:00
|
|
|
return false;
|
|
|
|
}
|
2016-07-24 14:41:21 +03:00
|
|
|
$hmac = hash_hmac('sha256', "{$postData['timestamp']}{$postData['token']}", $this->apiKey);
|
2014-11-20 01:29:08 +03:00
|
|
|
$sig = $postData['signature'];
|
2016-07-24 14:41:21 +03:00
|
|
|
if (function_exists('hash_equals')) {
|
2014-11-20 01:29:08 +03:00
|
|
|
// hash_equals is constant time, but will not be introduced until PHP 5.6
|
|
|
|
return hash_equals($hmac, $sig);
|
2016-07-24 14:41:21 +03:00
|
|
|
} else {
|
|
|
|
return $hmac === $sig;
|
2014-11-20 01:29:08 +03:00
|
|
|
}
|
|
|
|
}
|
2017-03-26 11:17:10 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @return ResponseInterface|null
|
|
|
|
*/
|
|
|
|
public function getLastResponse()
|
|
|
|
{
|
|
|
|
return $this->responseHistory->getLastResponse();
|
|
|
|
}
|
2013-08-13 23:26:34 +04:00
|
|
|
|
2014-11-20 21:41:25 +03:00
|
|
|
/**
|
|
|
|
* @param string $endpointUrl
|
2016-07-24 14:40:50 +03:00
|
|
|
* @param array $postData
|
|
|
|
* @param array $files
|
2016-07-24 14:41:21 +03:00
|
|
|
*
|
2014-11-20 21:41:25 +03:00
|
|
|
* @return \stdClass
|
2017-03-14 12:58:47 +03:00
|
|
|
*
|
|
|
|
* @deprecated Will be removed in 3.0
|
2014-11-20 21:41:25 +03:00
|
|
|
*/
|
2016-07-24 14:42:47 +03:00
|
|
|
public function post($endpointUrl, $postData = [], $files = [])
|
2016-07-24 14:40:50 +03:00
|
|
|
{
|
2014-11-20 01:29:08 +03:00
|
|
|
return $this->restClient->post($endpointUrl, $postData, $files);
|
|
|
|
}
|
2014-10-07 02:53:33 +04:00
|
|
|
|
2014-11-20 21:41:25 +03:00
|
|
|
/**
|
|
|
|
* @param string $endpointUrl
|
2016-07-24 14:40:50 +03:00
|
|
|
* @param array $queryString
|
2016-07-24 14:41:21 +03:00
|
|
|
*
|
2014-11-20 21:41:25 +03:00
|
|
|
* @return \stdClass
|
2017-03-14 12:58:47 +03:00
|
|
|
*
|
|
|
|
* @deprecated Will be removed in 3.0
|
2014-11-20 21:41:25 +03:00
|
|
|
*/
|
2016-07-24 14:42:47 +03:00
|
|
|
public function get($endpointUrl, $queryString = [])
|
2016-07-24 14:40:50 +03:00
|
|
|
{
|
2014-11-20 01:29:08 +03:00
|
|
|
return $this->restClient->get($endpointUrl, $queryString);
|
|
|
|
}
|
2014-10-07 02:53:33 +04:00
|
|
|
|
2017-02-28 10:10:04 +03:00
|
|
|
/**
|
|
|
|
* @param string $url
|
|
|
|
*
|
|
|
|
* @return \stdClass
|
2017-03-14 12:58:47 +03:00
|
|
|
*
|
|
|
|
* @deprecated Will be removed in 3.0
|
2017-02-28 10:10:04 +03:00
|
|
|
*/
|
|
|
|
public function getAttachment($url)
|
|
|
|
{
|
|
|
|
return $this->restClient->getAttachment($url);
|
|
|
|
}
|
|
|
|
|
2014-11-20 21:41:25 +03:00
|
|
|
/**
|
|
|
|
* @param string $endpointUrl
|
2016-07-24 14:41:21 +03:00
|
|
|
*
|
2014-11-20 21:41:25 +03:00
|
|
|
* @return \stdClass
|
2017-03-14 12:58:47 +03:00
|
|
|
*
|
|
|
|
* @deprecated Will be removed in 3.0
|
2014-11-20 21:41:25 +03:00
|
|
|
*/
|
2016-07-24 14:40:50 +03:00
|
|
|
public function delete($endpointUrl)
|
|
|
|
{
|
2014-11-20 01:29:08 +03:00
|
|
|
return $this->restClient->delete($endpointUrl);
|
|
|
|
}
|
2014-10-07 02:53:33 +04:00
|
|
|
|
2014-11-20 21:41:25 +03:00
|
|
|
/**
|
|
|
|
* @param string $endpointUrl
|
2016-07-24 14:40:50 +03:00
|
|
|
* @param array $putData
|
2016-07-24 14:41:21 +03:00
|
|
|
*
|
2014-11-20 21:41:25 +03:00
|
|
|
* @return \stdClass
|
2017-03-14 12:58:47 +03:00
|
|
|
*
|
|
|
|
* @deprecated Will be removed in 3.0
|
2014-11-20 21:41:25 +03:00
|
|
|
*/
|
2016-07-24 14:40:50 +03:00
|
|
|
public function put($endpointUrl, $putData)
|
|
|
|
{
|
2014-11-20 01:29:08 +03:00
|
|
|
return $this->restClient->put($endpointUrl, $putData);
|
|
|
|
}
|
2014-10-07 02:53:33 +04:00
|
|
|
|
2016-03-05 13:13:28 +03:00
|
|
|
/**
|
|
|
|
* @param string $apiVersion
|
|
|
|
*
|
|
|
|
* @return Mailgun
|
2017-03-14 12:58:47 +03:00
|
|
|
*
|
|
|
|
* @deprecated Will be removed in 3.0
|
2016-03-05 13:13:28 +03:00
|
|
|
*/
|
|
|
|
public function setApiVersion($apiVersion)
|
|
|
|
{
|
|
|
|
$this->restClient->setApiVersion($apiVersion);
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2016-07-24 14:41:21 +03:00
|
|
|
* @param bool $sslEnabled
|
2016-03-05 13:13:28 +03:00
|
|
|
*
|
|
|
|
* @return Mailgun
|
2016-10-15 03:20:46 +03:00
|
|
|
*
|
2016-09-30 16:04:43 +03:00
|
|
|
* @deprecated This will be removed in 3.0. Mailgun does not support non-secure connections to their API.
|
2016-03-05 13:13:28 +03:00
|
|
|
*/
|
|
|
|
public function setSslEnabled($sslEnabled)
|
|
|
|
{
|
|
|
|
$this->restClient->setSslEnabled($sslEnabled);
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2014-11-20 21:41:25 +03:00
|
|
|
/**
|
|
|
|
* @return MessageBuilder
|
2017-03-14 12:58:47 +03:00
|
|
|
*
|
|
|
|
* @deprecated Will be removed in 3.0
|
2014-11-20 21:41:25 +03:00
|
|
|
*/
|
2016-07-24 14:40:50 +03:00
|
|
|
public function MessageBuilder()
|
|
|
|
{
|
2014-11-20 01:29:08 +03:00
|
|
|
return new MessageBuilder();
|
|
|
|
}
|
2014-10-07 02:53:33 +04:00
|
|
|
|
2014-11-20 21:41:25 +03:00
|
|
|
/**
|
|
|
|
* @return OptInHandler
|
2017-03-14 12:58:47 +03:00
|
|
|
*
|
|
|
|
* @deprecated Will be removed in 3.0
|
2014-11-20 21:41:25 +03:00
|
|
|
*/
|
2016-07-24 14:40:50 +03:00
|
|
|
public function OptInHandler()
|
|
|
|
{
|
2014-11-20 01:29:08 +03:00
|
|
|
return new OptInHandler();
|
|
|
|
}
|
2014-10-07 02:53:33 +04:00
|
|
|
|
2014-11-20 21:41:25 +03:00
|
|
|
/**
|
|
|
|
* @param string $workingDomain
|
2016-07-24 14:40:50 +03:00
|
|
|
* @param bool $autoSend
|
2016-07-24 14:41:21 +03:00
|
|
|
*
|
2014-11-20 21:41:25 +03:00
|
|
|
* @return BatchMessage
|
2017-03-14 12:58:47 +03:00
|
|
|
*
|
|
|
|
* @deprecated Will be removed in 3.0
|
2014-11-20 21:41:25 +03:00
|
|
|
*/
|
2016-07-24 14:40:50 +03:00
|
|
|
public function BatchMessage($workingDomain, $autoSend = true)
|
|
|
|
{
|
2014-11-20 01:29:08 +03:00
|
|
|
return new BatchMessage($this->restClient, $workingDomain, $autoSend);
|
|
|
|
}
|
2016-10-24 20:01:32 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Api\Stats
|
|
|
|
*/
|
2016-11-24 00:21:15 +03:00
|
|
|
public function stats()
|
2016-10-24 20:01:32 +03:00
|
|
|
{
|
2017-03-22 09:44:08 +03:00
|
|
|
return new Api\Stats($this->httpClient, $this->requestBuilder, $this->hydrator);
|
2016-10-24 20:01:32 +03:00
|
|
|
}
|
2016-10-27 09:34:27 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Api\Domain
|
|
|
|
*/
|
2016-11-24 00:21:15 +03:00
|
|
|
public function domains()
|
2016-10-27 09:34:27 +03:00
|
|
|
{
|
2017-03-22 09:44:08 +03:00
|
|
|
return new Api\Domain($this->httpClient, $this->requestBuilder, $this->hydrator);
|
2016-10-27 09:34:27 +03:00
|
|
|
}
|
2016-12-07 21:03:50 +03:00
|
|
|
|
2017-02-21 10:22:57 +03:00
|
|
|
/**
|
|
|
|
* @return Api\Tag
|
|
|
|
*/
|
2017-03-22 09:44:08 +03:00
|
|
|
public function tags()
|
2017-02-21 10:22:57 +03:00
|
|
|
{
|
2017-03-22 09:44:08 +03:00
|
|
|
return new Api\Tag($this->httpClient, $this->requestBuilder, $this->hydrator);
|
2017-02-21 10:22:57 +03:00
|
|
|
}
|
|
|
|
|
2016-12-07 21:03:50 +03:00
|
|
|
/**
|
|
|
|
* @return Api\Event
|
|
|
|
*/
|
2016-12-08 01:29:08 +03:00
|
|
|
public function events()
|
2016-12-07 21:03:50 +03:00
|
|
|
{
|
2017-03-22 09:44:08 +03:00
|
|
|
return new Api\Event($this->httpClient, $this->requestBuilder, $this->hydrator);
|
2016-12-07 21:03:50 +03:00
|
|
|
}
|
2016-12-08 01:29:08 +03:00
|
|
|
|
2016-12-10 01:15:06 +03:00
|
|
|
/**
|
2017-03-26 17:11:33 +03:00
|
|
|
* @return Api\Route
|
2016-12-10 01:15:06 +03:00
|
|
|
*/
|
|
|
|
public function routes()
|
|
|
|
{
|
2017-03-26 17:11:33 +03:00
|
|
|
return new Api\Route($this->httpClient, $this->requestBuilder, $this->hydrator);
|
2016-12-10 01:15:06 +03:00
|
|
|
}
|
|
|
|
|
2016-12-08 01:29:08 +03:00
|
|
|
/**
|
|
|
|
* @return Api\Webhook
|
|
|
|
*/
|
|
|
|
public function webhooks()
|
|
|
|
{
|
2017-04-08 02:29:20 +03:00
|
|
|
return new Api\Webhook($this->httpClient, $this->requestBuilder, $this->hydrator, $this->apiKey);
|
2016-12-08 01:29:08 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Api\Message
|
|
|
|
*/
|
|
|
|
public function messages()
|
|
|
|
{
|
2017-03-22 09:44:08 +03:00
|
|
|
return new Api\Message($this->httpClient, $this->requestBuilder, $this->hydrator);
|
2016-12-08 01:29:08 +03:00
|
|
|
}
|
2017-02-20 22:57:54 +03:00
|
|
|
|
|
|
|
/**
|
2017-03-22 09:44:08 +03:00
|
|
|
* @return Api\Suppression
|
2017-02-20 22:57:54 +03:00
|
|
|
*/
|
|
|
|
public function suppressions()
|
|
|
|
{
|
2017-03-22 09:44:08 +03:00
|
|
|
return new Api\Suppression($this->httpClient, $this->requestBuilder, $this->hydrator);
|
2017-02-20 22:57:54 +03:00
|
|
|
}
|
2013-08-08 03:22:19 +04:00
|
|
|
}
|