├── .gitignore ├── src ├── ExpertSender │ ├── Enum │ │ ├── TemplatesType.php │ │ ├── ContentFromUrlFtpAuth.php │ │ ├── DeliverySettingsThrottlingMethod.php │ │ ├── RemovedSubscribersRemoveType.php │ │ ├── SubscribersOption.php │ │ └── SubscribersMode.php │ ├── Request │ │ ├── Post │ │ │ ├── SnoozedSubscribers.php │ │ │ ├── Lists.php │ │ │ ├── ListExport.php │ │ │ ├── ListImport.php │ │ │ ├── Newsletters.php │ │ │ ├── Subscribers.php │ │ │ ├── SuppressionLists.php │ │ │ ├── Triggers.php │ │ │ └── Transactionals.php │ │ ├── Get │ │ │ ├── Segments.php │ │ │ ├── Time.php │ │ │ ├── Templates.php │ │ │ ├── Lists.php │ │ │ ├── MessageInfo.php │ │ │ ├── ExportProgress.php │ │ │ ├── ListImportProgress.php │ │ │ ├── MessageList.php │ │ │ ├── MessageStatistics.php │ │ │ ├── RemovedSubscribers.php │ │ │ ├── Subscribers.php │ │ │ ├── Messages.php │ │ │ └── SnoozedSubscribers.php │ │ ├── Delete │ │ │ ├── SuppressionLists.php │ │ │ └── Subscribers.php │ │ └── Put │ │ │ ├── Lists.php │ │ │ └── Newsletters.php │ ├── Response │ │ ├── SegmentTagType.php │ │ ├── ListsType.php │ │ ├── EventsType.php │ │ ├── MessagesType.php │ │ ├── SegmentsType.php │ │ ├── TemplatesType.php │ │ ├── ErrorMessageType.php │ │ ├── SuppressionListType.php │ │ ├── ExportProgressType.php │ │ ├── GoogleAnalyticsTagType.php │ │ ├── RemovedSubscribersType.php │ │ ├── SnoozedSubscribersType.php │ │ ├── TemplateType.php │ │ ├── StateOnListType.php │ │ ├── SnoozedSubscriberType.php │ │ ├── RemovedSubscriberType.php │ │ ├── SegmentType.php │ │ ├── ListImportProgressType.php │ │ ├── ListImportType.php │ │ ├── ListType.php │ │ ├── EventType.php │ │ ├── MessageStatisticsType.php │ │ ├── SubscriberType.php │ │ ├── PropertyType.php │ │ └── MessageType.php │ ├── Entity │ │ ├── ListImportSourceType.php │ │ ├── UrlIntegrationType.php │ │ ├── FieldType.php │ │ ├── SegmentPropertyType.php │ │ ├── ChannelType.php │ │ ├── SubscriberMultidataType.php │ │ ├── ListImportTargetType.php │ │ ├── ListImportType.php │ │ ├── ActionType.php │ │ ├── TriggerType.php │ │ ├── PropertyType.php │ │ ├── SnippetType.php │ │ ├── GoogleAnalyticsTagsType.php │ │ ├── SubscriberMultiDataType.php │ │ ├── ContentFromUrlType.php │ │ ├── SnoozedSubscriberType.php │ │ ├── NewsletterType.php │ │ ├── DataType.php │ │ ├── ListType.php │ │ ├── AddressSettingsType.php │ │ ├── ComfirmationEmailType.php │ │ ├── DomainSettingsType.php │ │ ├── SubscriberSettingsType.php │ │ ├── TransactionalType.php │ │ ├── RecipientsType.php │ │ ├── AttachmentType.php │ │ ├── ListSettingsType.php │ │ ├── ListExportType.php │ │ ├── DeliverySettingsType.php │ │ ├── ReceiverType.php │ │ ├── SubscriberType.php │ │ ├── GeneralSettingsType.php │ │ ├── ContentType.php │ │ └── PropertyValueType.php │ ├── Http.php │ ├── Response.php │ ├── Request.php │ ├── Service.php │ ├── Unbound.php │ ├── XmlParser.php │ └── BaseType.php ├── Http.php └── Services │ ├── AbstractService.php │ ├── EmailService.php │ └── SubscriberService.php ├── composer.json ├── README.md ├── examples ├── getOneMessage.php ├── getServerTime.php ├── getMessages.php ├── postSnoozedSubscriber.php ├── getTemplates.php ├── deleteSubscriber.php ├── getLists.php ├── getSegments.php ├── deleteFromSuppressionList.php ├── getSnoozedSubscribers.php ├── getSubscriber.php ├── getRemovedSubscribers.php ├── createNewList.php ├── getSubscriberEvents.php └── addSubscriber.php ├── list.txt └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | /index.php 2 | /vendor* 3 | /.idea 4 | 5 | -------------------------------------------------------------------------------- /src/ExpertSender/Enum/TemplatesType.php: -------------------------------------------------------------------------------- 1 | array( 15 | 'type' => 'string', 16 | 'xmlName' => 'Tag', 17 | ), 18 | ); 19 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/ListImportSourceType.php: -------------------------------------------------------------------------------- 1 | array( 15 | 'type' => 'string', 16 | 'xmlName' => 'Url', 17 | ) 18 | ); 19 | } -------------------------------------------------------------------------------- /src/ExpertSender/Request/Get/Templates.php: -------------------------------------------------------------------------------- 1 | urlParams['type'] = $type; 16 | } 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /src/ExpertSender/Request/Get/Lists.php: -------------------------------------------------------------------------------- 1 | urlParams['seedLists'] = $seedLists === true ? 'true' : 'false'; 15 | } 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/UrlIntegrationType.php: -------------------------------------------------------------------------------- 1 | array( 16 | 'type' => 'integer', 17 | 'xmlName' => 'Id' 18 | ) 19 | ); 20 | 21 | public function __construct($id) 22 | { 23 | $this->id = $id; 24 | } 25 | } -------------------------------------------------------------------------------- /src/ExpertSender/Response/ListsType.php: -------------------------------------------------------------------------------- 1 | array( 15 | 'type' => 'App\\Extensions\\ExpertSender\\Response\\ListType', 16 | 'xmlName' => 'Lists', 17 | 'unbound' => true, 18 | 'unboundTag' => 'List' 19 | ), 20 | ); 21 | } -------------------------------------------------------------------------------- /src/ExpertSender/Request/Delete/SuppressionLists.php: -------------------------------------------------------------------------------- 1 | endPoint .= '/' . $id; 18 | 19 | $this->urlParams['entry'] = $entry; 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /src/ExpertSender/Response/EventsType.php: -------------------------------------------------------------------------------- 1 | array( 15 | 'type' => 'App\\Extensions\\ExpertSender\\Response\\EventType', 16 | 'xmlName' => 'Events', 17 | 'unbound' => true, 18 | 'unboundTag' => 'Event' 19 | ), 20 | ); 21 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/FieldType.php: -------------------------------------------------------------------------------- 1 | array( 17 | 'type' => 'string', 18 | 'xmlName' => 'Field' 19 | ), 20 | ); 21 | 22 | public function __construct($field) 23 | { 24 | $this->Field = $field; 25 | } 26 | } -------------------------------------------------------------------------------- /src/ExpertSender/Request/Post/SuppressionLists.php: -------------------------------------------------------------------------------- 1 | endPoint .= '/' . $id; 19 | $this->urlParams['entry'] = $entry; 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This plugin is used to be a client for API service of Expertsender email marketing platform. 2 | 3 | The most requests are based on XML syntax and used POST method of http protocol. To make the building of query easier this library introduces **Entities** 4 | 5 | Entities are mirrors for XML request or response. If you wish to make query to service, you must create an instance of an Entity with specified type (if API query supports). 6 | 7 | Every XML node - is an entity, excluding scalar values, such as strings, integers, or date. 8 | 9 | Use object oriented interface to build entity of the required type. -------------------------------------------------------------------------------- /src/ExpertSender/Request/Post/Triggers.php: -------------------------------------------------------------------------------- 1 | endPoint .= "/{$id}"; 20 | parent::__construct($data); 21 | } 22 | } -------------------------------------------------------------------------------- /src/ExpertSender/Response/MessagesType.php: -------------------------------------------------------------------------------- 1 | array( 15 | 'type' => 'App\\Extensions\\ExpertSender\\Response\\MessageType', 16 | 'xmlName' => 'Messages', 17 | 'unbound' => true, 18 | 'unboundTag' => 'Message' 19 | ), 20 | ); 21 | } -------------------------------------------------------------------------------- /src/ExpertSender/Response/SegmentsType.php: -------------------------------------------------------------------------------- 1 | array( 15 | 'type' => 'App\\Extensions\\ExpertSender\\Response\\SegmentType', 16 | 'xmlName' => 'Segments', 17 | 'unbound' => true, 18 | 'unboundTag' => 'Segment' 19 | ), 20 | ); 21 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/SegmentPropertyType.php: -------------------------------------------------------------------------------- 1 | array( 16 | 'type' => 'integer', 17 | 'xmlName' => 'Property' 18 | ), 19 | ); 20 | 21 | public function __construct($property) 22 | { 23 | $this->Property = $property; 24 | } 25 | } -------------------------------------------------------------------------------- /src/ExpertSender/Request/Get/MessageInfo.php: -------------------------------------------------------------------------------- 1 | endPoint = '/Api/Messages/' . $id; 20 | } 21 | } -------------------------------------------------------------------------------- /src/ExpertSender/Response/TemplatesType.php: -------------------------------------------------------------------------------- 1 | array( 15 | 'type' => 'App\\Extensions\\ExpertSender\\Response\\TemplateType', 16 | 'xmlName' => 'Templates', 17 | 'unbound' => true, 18 | 'unboundTag' => 'Template' 19 | ), 20 | ); 21 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/ChannelType.php: -------------------------------------------------------------------------------- 1 | array( 16 | 'type' => 'string', 17 | 'xmlName' => 'Ip' 18 | ), 19 | 'percentage' => array( 20 | 'type' => 'integer', 21 | 'xmlName' => 'Percentage', 22 | ) 23 | ); 24 | } -------------------------------------------------------------------------------- /src/ExpertSender/Request/Post/Transactionals.php: -------------------------------------------------------------------------------- 1 | endPoint .= "/{$id}"; 20 | parent::__construct($data); 21 | } 22 | } -------------------------------------------------------------------------------- /src/ExpertSender/Enum/SubscribersMode.php: -------------------------------------------------------------------------------- 1 | array( 15 | 'type' => 'Zhmi\\ExpertSender\\Entity\\SubscriberType', 16 | 'xmlName' => 'Subscriber', 17 | 'unbound' => true, 18 | 'unboundTag' => 'MultiData' 19 | ), 20 | ); 21 | } -------------------------------------------------------------------------------- /src/ExpertSender/Response/ErrorMessageType.php: -------------------------------------------------------------------------------- 1 | array( 17 | 'type' => 'integer', 18 | 'xmlName' => 'Code' 19 | ), 20 | 'Message' => array( 21 | 'type' => 'string', 22 | 'xmlName' => 'Message', 23 | ) 24 | ); 25 | } -------------------------------------------------------------------------------- /src/ExpertSender/Response/SuppressionListType.php: -------------------------------------------------------------------------------- 1 | array( 16 | 'type' => 'integer', 17 | 'xmlName' => 'Status', 18 | ), 19 | 'Name' => array( 20 | 'type' => 'string', 21 | 'xmlName' => 'Name', 22 | ), 23 | 24 | ); 25 | } -------------------------------------------------------------------------------- /src/ExpertSender/Request/Put/Lists.php: -------------------------------------------------------------------------------- 1 | endPoint .= "/{$id}"; 21 | 22 | parent::__construct($data); 23 | } 24 | } -------------------------------------------------------------------------------- /src/ExpertSender/Request/Get/ExportProgress.php: -------------------------------------------------------------------------------- 1 | endPoint .= "/{$exportId}"; 21 | } 22 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/ListImportTargetType.php: -------------------------------------------------------------------------------- 1 | array( 16 | 'type' => 'string', 17 | 'xmlName' => 'Name', 18 | ), 19 | 'subscriberList' => array( 20 | 'type' => 'integer', 21 | 'xmlName' => 'SubscriberList', 22 | ), 23 | ); 24 | } -------------------------------------------------------------------------------- /src/ExpertSender/Response/ExportProgressType.php: -------------------------------------------------------------------------------- 1 | array( 16 | 'type' => 'string', 17 | 'xmlName' => 'Status', 18 | ), 19 | 'DownloadUrl' => array( 20 | 'type' => 'string', 21 | 'xmlName' => 'DownloadUrl', 22 | ), 23 | ); 24 | } -------------------------------------------------------------------------------- /src/ExpertSender/Request/Get/ListImportProgress.php: -------------------------------------------------------------------------------- 1 | endPoint .= "/{$importId}"; 21 | } 22 | } -------------------------------------------------------------------------------- /src/ExpertSender/Request/Put/Newsletters.php: -------------------------------------------------------------------------------- 1 | endPoint .= "/{$id}"; 22 | 23 | parent::__construct($data); 24 | } 25 | } -------------------------------------------------------------------------------- /src/ExpertSender/Response/GoogleAnalyticsTagType.php: -------------------------------------------------------------------------------- 1 | array( 17 | 'type' => 'string', 18 | 'xmlName' => 'Name' 19 | ), 20 | 'Value' => array( 21 | 'type' => 'string', 22 | 'xmlName' => 'Value', 23 | ), 24 | ); 25 | } -------------------------------------------------------------------------------- /src/ExpertSender/Response/RemovedSubscribersType.php: -------------------------------------------------------------------------------- 1 | array( 15 | 'type' => 'App\\Extensions\\ExpertSender\\Response\\RemovedSubscriberType', 16 | 'xmlName' => 'RemovedSubscribers', 17 | 'unbound' => true, 18 | 'unboundTag' => 'RemovedSubscriber' 19 | ), 20 | ); 21 | } -------------------------------------------------------------------------------- /src/ExpertSender/Response/SnoozedSubscribersType.php: -------------------------------------------------------------------------------- 1 | array( 15 | 'type' => 'App\\Extensions\\ExpertSender\\Response\\SnoozedSubscriberType', 16 | 'xmlName' => 'SnoozedSubscribers', 17 | 'unbound' => true, 18 | 'unboundTag' => 'SnoozedSubscriber' 19 | ), 20 | ); 21 | } -------------------------------------------------------------------------------- /examples/getOneMessage.php: -------------------------------------------------------------------------------- 1 | setKey('YOUR_API_KEY'); 9 | 10 | try 11 | { 12 | $request = new ES\Request\Get\Messages(1); 13 | $response = $service->call($request); 14 | $e = $response->getEntity(); 15 | /** @var ES\Response\MessageType $e */ 16 | echo $e->Subject; 17 | } 18 | catch (ES\ServiceException $e) 19 | { 20 | print_r('Ошибка выполнения запроса к сервису:' . "\n"); 21 | echo $e->getCode() . " - " . $e->getMessage(); 22 | } 23 | catch (\Exception $e) 24 | { 25 | var_dump($e); 26 | } 27 | -------------------------------------------------------------------------------- /src/ExpertSender/Entity/ListImportType.php: -------------------------------------------------------------------------------- 1 | array( 16 | 'type' => 'App\\Extensions\\ExpertSender\\Entity\\ListImportSourceType', 17 | 'xmlName' => 'Source', 18 | ), 19 | 'target' => array( 20 | 'type' => 'App\\Extensions\\ExpertSender\\Entity\\ListImportTargetType', 21 | 'xmlName' => 'Target', 22 | ), 23 | ); 24 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/ActionType.php: -------------------------------------------------------------------------------- 1 | array( 24 | 'type' => 'string', 25 | 'xmlName' => 'Action', 26 | ), 27 | ); 28 | 29 | public function __construct($action) 30 | { 31 | $this->action = $action; 32 | } 33 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/TriggerType.php: -------------------------------------------------------------------------------- 1 | array( 21 | 'type' => 'App\\Extensions\\ExpertSender\\Entity\\ReceiverType', 22 | 'xmlName' => 'Receiver', 23 | 'unbound' => true, 24 | 'unboundTag' => 'Receivers' 25 | ) 26 | ); 27 | } -------------------------------------------------------------------------------- /src/ExpertSender/Response/TemplateType.php: -------------------------------------------------------------------------------- 1 | array( 17 | 'type' => 'integer', 18 | 'xmlName' => 'Id', 19 | ), 20 | 'Type' => array( 21 | 'type' => 'string', 22 | 'xmlName' => 'Type', 23 | ), 24 | 'Name' => array( 25 | 'type' => 'string', 26 | 'xmlName' => 'Name', 27 | ), 28 | ); 29 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/PropertyType.php: -------------------------------------------------------------------------------- 1 | array( 17 | 'type' => 'integer', 18 | 'xmlName' => 'Id' 19 | ), 20 | 'value' => array( 21 | 'type' => 'App\\Extensions\\ExpertSender\\Entity\\PropertyValueType', 22 | ), 23 | ); 24 | 25 | public function __construct($id, PropertyValueType $value) 26 | { 27 | $this->id = $id; 28 | $this->value = $value; 29 | } 30 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/SnippetType.php: -------------------------------------------------------------------------------- 1 | array( 17 | 'type' => 'string', 18 | 'xmlName' => 'Name' 19 | ), 20 | 'value' => array( 21 | 'type' => 'string', 22 | 'xmlName' => 'Value', 23 | 'cdata' => true 24 | ), 25 | ); 26 | 27 | public function __construct($name, $value) 28 | { 29 | $this->name = $name; 30 | $this->value = $value; 31 | } 32 | } -------------------------------------------------------------------------------- /src/ExpertSender/Response/StateOnListType.php: -------------------------------------------------------------------------------- 1 | array( 17 | 'type' => 'integer', 18 | 'xmlName' => 'ListId', 19 | ), 20 | 'Status' => array( 21 | 'type' => 'string', 22 | 'xmlName' => 'Status', 23 | ), 24 | 'Name' => array( 25 | 'type' => 'string', 26 | 'xmlName' => 'Name', 27 | ), 28 | 29 | ); 30 | } -------------------------------------------------------------------------------- /examples/getServerTime.php: -------------------------------------------------------------------------------- 1 | setKey('YOUR_API_KEY'); 10 | 11 | try 12 | { 13 | //Initialize request 14 | $request = new ES\Request\Get\Time; 15 | 16 | //Making a request call 17 | $response = $service->call($request); 18 | $entity = $response->getEntity(); 19 | 20 | /** @var DateTime $entity */ 21 | echo $entity->format('d.m.Y H:i:s'); 22 | } 23 | catch (ES\ServiceException $e) 24 | { 25 | print_r('Ошибка выполнения запроса к сервису:' . "\n"); 26 | echo $e->getCode() . " - " . $e->getMessage(); 27 | } 28 | catch (\Exception $e) 29 | { 30 | var_dump($e); 31 | } -------------------------------------------------------------------------------- /examples/getMessages.php: -------------------------------------------------------------------------------- 1 | setKey('YOUR_API_KEY'); 9 | 10 | try 11 | { 12 | $request = new ES\Request\Get\Messages(); 13 | $response = $service->call($request); 14 | $e = $response->getEntity(); 15 | foreach ($e->Messages as $message) 16 | { 17 | /** @var ES\Response\MessageType $e */ 18 | echo $message->Subject . '
'; 19 | } 20 | } 21 | catch (ES\ServiceException $e) 22 | { 23 | print_r('Ошибка выполнения запроса к сервису:' . "\n"); 24 | echo $e->getCode() . " - " . $e->getMessage(); 25 | } 26 | catch (\Exception $e) 27 | { 28 | var_dump($e); 29 | } 30 | -------------------------------------------------------------------------------- /examples/postSnoozedSubscriber.php: -------------------------------------------------------------------------------- 1 | setKey('YOUR_API_KEY'); 9 | 10 | try 11 | { 12 | $entity = new ES\Entity\SnoozedSubscriberType(); 13 | $entity->email = 'user.email@email.com'; 14 | $entity->snoozeWeeks = 1; 15 | 16 | $request = new ES\Request\Post\SnoozedSubscribers( $entity ); 17 | $response = $service->call($request); 18 | var_dump($response); 19 | } 20 | catch (ES\ServiceException $e) 21 | { 22 | print_r('Ошибка выполнения запроса к сервису:' . "\n"); 23 | echo $e->getCode() . " - " . $e->getMessage(); 24 | } 25 | catch (\Exception $e) 26 | { 27 | var_dump($e); 28 | } 29 | -------------------------------------------------------------------------------- /examples/getTemplates.php: -------------------------------------------------------------------------------- 1 | setKey('YOUR_API_KEY'); 9 | 10 | try 11 | { 12 | $request = new ES\Request\Get\Templates(); 13 | $response = $service->call($request); 14 | $e = $response->getEntity(); 15 | foreach ($e->Templates as $template) 16 | { 17 | /** @var ES\Response\TemplateType $template */ 18 | echo $template->Name . '
'; 19 | } 20 | } 21 | catch (ES\ServiceException $e) 22 | { 23 | print_r('Ошибка выполнения запроса к сервису:' . "\n"); 24 | echo $e->getCode() . " - " . $e->getMessage(); 25 | } 26 | catch (\Exception $e) 27 | { 28 | var_dump($e); 29 | } 30 | -------------------------------------------------------------------------------- /src/ExpertSender/Entity/GoogleAnalyticsTagsType.php: -------------------------------------------------------------------------------- 1 | array( 17 | 'type' => 'string', 18 | 'xmlName' => 'Campaign' 19 | ), 20 | 'source' => array( 21 | 'type' => 'string', 22 | 'xmlName' => 'Source', 23 | ), 24 | 'content' => array( 25 | 'type' => 'string', 26 | 'xmlName' => 'Content', 27 | ) 28 | ); 29 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/SubscriberMultiDataType.php: -------------------------------------------------------------------------------- 1 | array( 24 | 'type' => 'App\\Extensions\\ExpertSender\\Entity\\SubscriberType', 25 | 'xmlName' => 'Subscriber', 26 | 'unbound' => true, 27 | 'unboundTag' => 'MultiData' 28 | ), 29 | ); 30 | } -------------------------------------------------------------------------------- /examples/deleteSubscriber.php: -------------------------------------------------------------------------------- 1 | setKey('YOUR_API_KEY'); 9 | 10 | try 11 | { 12 | $request = new ES\Request\Delete\Subscribers(11234); 13 | 14 | //Making a request call 15 | $response = $service->call( $request ); 16 | if ($response->isOk()) 17 | { 18 | echo 'success'; 19 | } 20 | else 21 | { 22 | echo $response->getCode(); 23 | } 24 | 25 | } 26 | catch (ES\ServiceException $e) 27 | { 28 | print_r('Ошибка выполнения запроса к сервису:' . "\n"); 29 | echo $e->getCode() . " - " . $e->getMessage(); 30 | } 31 | catch (\Exception $e) 32 | { 33 | var_dump($e); 34 | } 35 | -------------------------------------------------------------------------------- /src/ExpertSender/Response/SnoozedSubscriberType.php: -------------------------------------------------------------------------------- 1 | array( 17 | 'type' => 'string', 18 | 'xmlName' => 'Email', 19 | ), 20 | 'ListId' => array( 21 | 'type' => 'integer', 22 | 'xmlName' => 'ListId', 23 | ), 24 | 'SnoozedUntil' => array( 25 | 'type' => 'DateTime', 26 | 'xmlName' => 'SnoozedUntil' 27 | ), 28 | ); 29 | } -------------------------------------------------------------------------------- /examples/getLists.php: -------------------------------------------------------------------------------- 1 | setKey('YOUR_API_KEY'); 9 | 10 | try 11 | { 12 | $request = new ES\Request\Get\Lists(); 13 | $response = $service->call($request); 14 | $e = $response->getEntity(); 15 | /** @var ES\Response\ListsType $e */ 16 | foreach ($e->Lists as $list) 17 | { 18 | /** @var ES\Response\ListType $segment */ 19 | echo $list->Name .'
'; 20 | } 21 | } 22 | catch (ES\ServiceException $e) 23 | { 24 | print_r('Ошибка выполнения запроса к сервису:' . "\n"); 25 | echo $e->getCode() . " - " . $e->getMessage(); 26 | } 27 | catch (\Exception $e) 28 | { 29 | var_dump($e); 30 | } 31 | -------------------------------------------------------------------------------- /src/ExpertSender/Response/RemovedSubscriberType.php: -------------------------------------------------------------------------------- 1 | array( 17 | 'type' => 'string', 18 | 'xmlName' => 'Email', 19 | ), 20 | 'ListId' => array( 21 | 'type' => 'integer', 22 | 'xmlName' => 'ListId', 23 | ), 24 | 'UnsubscribedOn' => array( 25 | 'type' => 'DateTime', 26 | 'xmlName' => 'UnsubscribedOn' 27 | ), 28 | ); 29 | } -------------------------------------------------------------------------------- /src/ExpertSender/Response/SegmentType.php: -------------------------------------------------------------------------------- 1 | array( 16 | 'type' => 'integer', 17 | 'xmlName' => 'Id', 18 | ), 19 | 'Name' => array( 20 | 'type' => 'string', 21 | 'xmlName' => 'Name', 22 | ), 23 | 'Tags' => array( 24 | 'type' => 'App\\Extensions\\ExpertSender\\Response\\SegmentTagType', 25 | 'xmlName' => 'Tags', 26 | 'unbound' => true, 27 | 'unboundTag' => 'Tag' 28 | ), 29 | ); 30 | } -------------------------------------------------------------------------------- /examples/getSegments.php: -------------------------------------------------------------------------------- 1 | setKey('YOUR_API_KEY'); 9 | 10 | try 11 | { 12 | $request = new ES\Request\Get\Segments(); 13 | $response = $service->call($request); 14 | $e = $response->getEntity(); 15 | /** @var ES\Response\SegmentsType $e */ 16 | foreach ($e->Segments as $segment) 17 | { 18 | /** @var ES\Response\SegmentType $segment */ 19 | echo $segment->Name .'
'; 20 | } 21 | } 22 | catch (ES\ServiceException $e) 23 | { 24 | print_r('Ошибка выполнения запроса к сервису:' . "\n"); 25 | echo $e->getCode() . " - " . $e->getMessage(); 26 | } 27 | catch (\Exception $e) 28 | { 29 | var_dump($e); 30 | } 31 | -------------------------------------------------------------------------------- /list.txt: -------------------------------------------------------------------------------- 1 | GET Time + 2 | GET Subscribers + 3 | POST Subscribers + 4 | DELETE Subscribers + 5 | GET Messages + 6 | GET MessageStatistics - 7 | GET LinkStatistics - 8 | GET VendorStatistics - 9 | POST Triggers + 10 | POST Transactionals + 11 | POST SuppressionLists + 12 | DELETE SuppressionLists + 13 | GET Activities - csv 14 | GET Lists + 15 | POST Lists + 16 | GET Segments + 17 | GET ImportToListTasks - 18 | POST ImportToListTasks - 19 | POST Newsletters + 20 | GET RemovedSubscribers + 21 | GET Bounces - csv 22 | POST Goals - ?? 23 | GET Exports - 24 | POST Exports - 25 | GET DataTablesGetTables - 26 | POST DataTablesGetData - 27 | POST DataTablesGetDataCount - 28 | POST DataTablesAddRow - 29 | POST DataTablesUpdateRow - 30 | POST DataTablesDeleteRow - -------------------------------------------------------------------------------- /examples/deleteFromSuppressionList.php: -------------------------------------------------------------------------------- 1 | setKey('YOUR_API_KEY'); 9 | 10 | try 11 | { 12 | $request = new ES\Request\Delete\SuppressionLists(12, 'user.email@email.com'); 13 | 14 | //Making a request call 15 | $response = $service->call( $request ); 16 | if ($response->isOk()) 17 | { 18 | echo 'success'; 19 | } 20 | else 21 | { 22 | echo $response->getCode(); 23 | } 24 | 25 | } 26 | catch (ES\ServiceException $e) 27 | { 28 | print_r('Ошибка выполнения запроса к сервису:' . "\n"); 29 | echo $e->getCode() . " - " . $e->getMessage(); 30 | } 31 | catch (\Exception $e) 32 | { 33 | var_dump($e); 34 | } 35 | -------------------------------------------------------------------------------- /examples/getSnoozedSubscribers.php: -------------------------------------------------------------------------------- 1 | setKey('YOUR_API_KEY'); 9 | 10 | try 11 | { 12 | $request = new ES\Request\Get\SnoozedSubscribers(array(13)); 13 | $response = $service->call($request); 14 | $e = $response->getEntity(); 15 | foreach ($e->SnoozedSubscribers as $snoozedSubscriber) 16 | { 17 | /** @var ES\Response\SnoozedSubscriberType $snoozedSubscriber */ 18 | echo $snoozedSubscriber->Email . '
'; 19 | } 20 | } 21 | catch (ES\ServiceException $e) 22 | { 23 | print_r('Ошибка выполнения запроса к сервису:' . "\n"); 24 | echo $e->getCode() . " - " . $e->getMessage(); 25 | } 26 | catch (\Exception $e) 27 | { 28 | var_dump($e); 29 | } 30 | -------------------------------------------------------------------------------- /examples/getSubscriber.php: -------------------------------------------------------------------------------- 1 | setKey('YOUR_API_KEY'); 9 | 10 | try 11 | { 12 | //Initialize request 13 | $request = new ES\Request\Get\Subscribers('harry@potter.com', ES\Enum\SubscribersOption::FULL); 14 | 15 | //Making a request call 16 | $response = $service->call($request); 17 | $entity = $response->getEntity(); 18 | 19 | /** @var ES\Response\SubscriberType $entity */ 20 | echo "{$entity->Lastname} {$entity->Ip}"; 21 | 22 | } 23 | catch (ES\ServiceException $e) 24 | { 25 | print_r('Ошибка выполнения запроса к сервису:' . "\n"); 26 | echo $e->getCode() . " - " . $e->getMessage(); 27 | } 28 | catch (\Exception $e) 29 | { 30 | var_dump($e); 31 | } -------------------------------------------------------------------------------- /src/ExpertSender/Request/Delete/Subscribers.php: -------------------------------------------------------------------------------- 1 | endPoint .= '/' . (int)$identifier; 16 | } 17 | elseif (filter_var($identifier, FILTER_VALIDATE_EMAIL)) 18 | { 19 | $this->urlParams['email'] = $identifier; 20 | } 21 | else 22 | { 23 | throw new \InvalidArgumentException('Identifier must be a valid email or integer'); 24 | } 25 | 26 | if ($listId !== null) 27 | { 28 | $this->urlParams['listId'] = $listId; 29 | } 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /src/ExpertSender/Request/Get/MessageList.php: -------------------------------------------------------------------------------- 1 | urlParams['type'] = $type; 16 | } 17 | 18 | if ($tag) { 19 | $this->urlParams['tag'] = $tag; 20 | } 21 | 22 | if (!is_null($startDate)) { 23 | $this->urlParams['startDate'] = $startDate->format('Y-m-d'); 24 | } 25 | 26 | if (!is_null($endDate)) { 27 | $this->urlParams['endDate'] = $startDate->format('Y-m-d'); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /examples/getRemovedSubscribers.php: -------------------------------------------------------------------------------- 1 | setKey('YOUR_API_KEY'); 9 | 10 | try 11 | { 12 | $request = new ES\Request\Get\RemovedSubscribers(array(13), array(ES\Enum\RemovedSubscribersRemoveType::UI)); 13 | $response = $service->call($request); 14 | $e = $response->getEntity(); 15 | foreach ($e->RemovedSubscribers as $removedSubscriber) 16 | { 17 | /** @var ES\Response\RemovedSubscriberType $removedSubscriber */ 18 | echo $removedSubscriber->Email . '
'; 19 | } 20 | } 21 | catch (ES\ServiceException $e) 22 | { 23 | print_r('Ошибка выполнения запроса к сервису:' . "\n"); 24 | echo $e->getCode() . " - " . $e->getMessage(); 25 | } 26 | catch (\Exception $e) 27 | { 28 | var_dump($e); 29 | } 30 | -------------------------------------------------------------------------------- /src/ExpertSender/Entity/ContentFromUrlType.php: -------------------------------------------------------------------------------- 1 | array( 18 | 'type' => 'string', 19 | 'xmlName' => 'Url' 20 | ), 21 | 'username' => array( 22 | 'type' => 'string', 23 | 'xmlName' => 'Username', 24 | ), 25 | 'password' => array( 26 | 'type' => 'string', 27 | 'xmlName' => 'Password', 28 | ), 29 | 'ftpAuth' => array( 30 | 'type' => 'string', 31 | 'xmlName' => 'FtpAuth', 32 | ) 33 | ); 34 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/SnoozedSubscriberType.php: -------------------------------------------------------------------------------- 1 | array( 18 | 'type' => 'integer', 19 | 'xmlName' => 'Id', 20 | ), 21 | 'email' => array( 22 | 'type' => 'string', 23 | 'xmlName' => 'Email' 24 | ), 25 | 'listId' => array( 26 | 'type' => 'integer', 27 | 'xmlName' => 'ListId', 28 | ), 29 | 'snoozeWeeks' => array( 30 | 'type' => 'integer', 31 | 'xmlName' => 'SnoozeWeeks', 32 | ), 33 | ); 34 | } -------------------------------------------------------------------------------- /examples/createNewList.php: -------------------------------------------------------------------------------- 1 | setKey('YOUR_API_KEY'); 9 | 10 | try 11 | { 12 | $setting = new ES\Entity\ListSettingsType(); 13 | $g = new ES\Entity\GeneralSettingsType(); 14 | $g->name = 'API Created'; 15 | $g->defaultFromName = 'Johnny'; 16 | $g->defaultFromEmail = 'user.email@email.com'; 17 | $setting->generalSettings = $g; 18 | 19 | $request = new ES\Request\Post\Lists( $setting ); 20 | 21 | $response = $service->call($request); 22 | echo 'Идентификатор нового листа - ' . $response->getEntity(); 23 | } 24 | catch (ES\ServiceException $e) 25 | { 26 | print_r('Ошибка выполнения запроса к сервису:' . "\n"); 27 | echo $e->getCode() . " - " . $e->getMessage(); 28 | } 29 | catch (\Exception $e) 30 | { 31 | var_dump($e); 32 | } 33 | -------------------------------------------------------------------------------- /src/ExpertSender/Request/Get/MessageStatistics.php: -------------------------------------------------------------------------------- 1 | endPoint = '/Api/MessageStatistics/' . $id; 20 | 21 | if (!is_null($startDate)) { 22 | $this->urlParams['startDate'] = $startDate->format('Y-m-d'); 23 | } 24 | 25 | if (!is_null($endDate)) { 26 | $this->urlParams['endDate'] = $startDate->format('Y-m-d'); 27 | } 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/NewsletterType.php: -------------------------------------------------------------------------------- 1 | array( 18 | 'type' => 'App\\Extensions\\ExpertSender\\Entity\\RecipientsType', 19 | 'xmlName' => 'Recipients', 20 | ), 21 | 'content' => array( 22 | 'type' => 'App\\Extensions\\ExpertSender\\Entity\\ContentType', 23 | 'xmlName' => 'Content', 24 | ), 25 | 'deliverySettings' => array( 26 | 'type' => 'App\\Extensions\\ExpertSender\\Entity\\DeliverySettingsType', 27 | 'xmlName' => 'DeliverySettings', 28 | ) 29 | ); 30 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/DataType.php: -------------------------------------------------------------------------------- 1 | array( 18 | 'type' => 'App\\Extensions\\ExpertSender\\BaseType', 19 | 'xmlName' => 'Data', 20 | ), 21 | 'type' => array( 22 | 'type' => 'string', 23 | 'attribute' => true, 24 | 'attributeName' => 'xsi:type' 25 | ) 26 | ); 27 | 28 | /** 29 | * @deprecated 30 | */ 31 | public function __construct(BaseType $entity) 32 | { 33 | $this->data = $entity; 34 | 35 | $xsi = $entity->getXsiType(); 36 | if ($xsi !== null) 37 | { 38 | $this->type = $xsi; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /examples/getSubscriberEvents.php: -------------------------------------------------------------------------------- 1 | setKey('YOUR_API_KEY'); 10 | 11 | try 12 | { 13 | //Initialize request 14 | $request = new ES\Request\Get\Subscribers('harry@potter.com', ES\Enum\SubscribersOption::EVENTS_HISTORY); 15 | 16 | //Making a request call 17 | $response = $service->call($request); 18 | $entity = $response->getEntity(); 19 | 20 | foreach ($entity->Events as $event) 21 | { 22 | /** @var ES\Response\EventType $event */ 23 | echo $event->StartDate->format('d.m.Y H:i:s') . ' - ' . $event->MessageSubject . '
'; 24 | } 25 | } 26 | catch (ES\ServiceException $e) 27 | { 28 | print_r('Ошибка выполнения запроса к сервису:' . "\n"); 29 | echo $e->getCode() . " - " . $e->getMessage(); 30 | } 31 | catch (\Exception $e) 32 | { 33 | var_dump($e); 34 | } 35 | -------------------------------------------------------------------------------- /src/ExpertSender/Response/ListImportProgressType.php: -------------------------------------------------------------------------------- 1 | array( 18 | 'type' => 'string', 19 | 'xmlName' => 'Name', 20 | ), 21 | 'List' => array( 22 | 'type' => 'string', 23 | 'xmlName' => 'List', 24 | ), 25 | 'Url' => array( 26 | 'type' => 'string', 27 | 'xmlName' => 'Url', 28 | ), 29 | 'History' => array( 30 | 'type' => 'App\\Extensions\\ExpertSender\\Response\\ListImportType', 31 | 'xmlName' => 'History', 32 | 'unbound' => true, 33 | 'unboundTag' => 'Import' 34 | ), 35 | ); 36 | } -------------------------------------------------------------------------------- /src/ExpertSender/Response/ListImportType.php: -------------------------------------------------------------------------------- 1 | array( 18 | 'type' => 'string', 19 | 'xmlName' => 'StartedAt', 20 | ), 21 | 'UpdatedAt' => array( 22 | 'type' => 'string', 23 | 'xmlName' => 'UpdatedAt', 24 | ), 25 | 'Status' => array( 26 | 'type' => 'string', 27 | 'xmlName' => 'Status', 28 | ), 29 | 'Details' => array( 30 | 'type' => 'string', 31 | 'xmlName' => 'Details', 32 | ), 33 | ); 34 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/ListType.php: -------------------------------------------------------------------------------- 1 | array( 20 | 'type' => 'integer', 21 | 'xmlName' => 'Id', 22 | ), 23 | 'name' => array( 24 | 'type' => 'string', 25 | 'xmlName' => 'Name', 26 | ), 27 | 'friendlyName' => array( 28 | 'type' => 'string', 29 | 'xmlName' => 'FriendlyName', 30 | ), 31 | 'language' => array( 32 | 'type' => 'string', 33 | 'xmlName' => 'Language', 34 | ), 35 | 'optInMode' => array( 36 | 'type' => 'string', 37 | 'xmlName' => 'OptInMode', 38 | ), 39 | ); 40 | } -------------------------------------------------------------------------------- /src/ExpertSender/Response/ListType.php: -------------------------------------------------------------------------------- 1 | array( 19 | 'type' => 'integer', 20 | 'xmlName' => 'Id', 21 | ), 22 | 'Name' => array( 23 | 'type' => 'string', 24 | 'xmlName' => 'Name', 25 | ), 26 | 'FriendlyName' => array( 27 | 'type' => 'string', 28 | 'xmlName' => 'FriendlyName', 29 | ), 30 | 'Language' => array( 31 | 'type' => 'string', 32 | 'xmlName' => 'Language', 33 | ), 34 | 'OptInMode' => array( 35 | 'type' => 'string', 36 | 'xmlName' => 'OptInMode', 37 | ), 38 | ); 39 | } -------------------------------------------------------------------------------- /src/ExpertSender/Request/Get/RemovedSubscribers.php: -------------------------------------------------------------------------------- 1 | urlParams['ListIds'] = implode(',', $listIds); 17 | } 18 | 19 | if (!empty($removeTypes)) 20 | { 21 | $this->urlParams['removeTypes'] = implode(',', $removeTypes); 22 | } 23 | 24 | if (!is_null($startDate)) 25 | { 26 | $this->urlParams['startDate'] = $startDate->format('Y-m-d'); 27 | } 28 | 29 | if (!is_null($endDate)) 30 | { 31 | $this->urlParams['endDate'] = $startDate->format('Y-m-d'); 32 | } 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/AddressSettingsType.php: -------------------------------------------------------------------------------- 1 | array( 20 | 'type' => 'string', 21 | 'xmlName' => 'Company', 22 | ), 23 | 'city' => array( 24 | 'type' => 'string', 25 | 'xmlName' => 'City', 26 | ), 27 | 'zipPostalCode' => array( 28 | 'type' => 'string', 29 | 'xmlName' => 'ZipPostalCode', 30 | ), 31 | 'address' => array( 32 | 'type' => 'string', 33 | 'xmlName' => 'Address', 34 | ), 35 | 'address2' => array( 36 | 'type' => 'string', 37 | 'xmlName' => 'Address2', 38 | ), 39 | ); 40 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/ComfirmationEmailType.php: -------------------------------------------------------------------------------- 1 | array( 20 | 'type' => 'string', 21 | 'xmlName' => 'FromName', 22 | ), 23 | 'fromEmail' => array( 24 | 'type' => 'string', 25 | 'xmlName' => 'FromEmail', 26 | ), 27 | 'subject' => array( 28 | 'type' => 'string', 29 | 'xmlName' => 'Subject', 30 | ), 31 | 'html' => array( 32 | 'type' => 'string', 33 | 'xmlName' => 'Html', 34 | 'cdata' => true, 35 | ), 36 | 'plain' => array( 37 | 'type' => 'string', 38 | 'xmlName' => 'Plain', 39 | ), 40 | ); 41 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Mikhail Zhurov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /src/ExpertSender/Entity/DomainSettingsType.php: -------------------------------------------------------------------------------- 1 | array( 20 | 'type' => 'string', 21 | 'xmlName' => 'ClickTrackingDomain', 22 | ), 23 | 'address' => array( 24 | 'type' => 'string', 25 | 'xmlName' => 'Address', 26 | ), 27 | 'address2' => array( 28 | 'type' => 'string', 29 | 'xmlName' => 'Address2', 30 | ), 31 | 'city' => array( 32 | 'type' => 'string', 33 | 'xmlName' => 'City', 34 | ), 35 | 'zipPostalCode' => array( 36 | 'type' => 'string', 37 | 'xmlName' => 'ZipPostalCode', 38 | ), 39 | ); 40 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/SubscriberSettingsType.php: -------------------------------------------------------------------------------- 1 | array( 19 | 'type' => 'integer', 20 | 'xmlName' => 'FrequencyCappingTime', 21 | ), 22 | 'disableStandardMessageFooter' => array( 23 | 'type' => 'boolean', 24 | 'xmlName' => 'DisableStandardMessageFooter', 25 | ), 26 | 'disableListUnsubscribeHeader' => array( 27 | 'type' => 'boolean', 28 | 'xmlName' => 'DisableListUnsubscribeHeader', 29 | ), 30 | 'askBeforeUnsubscribing' => array( 31 | 'type' => 'boolean', 32 | 'xmlName' => 'AskBeforeUnsubscribing', 33 | ), 34 | ); 35 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/TransactionalType.php: -------------------------------------------------------------------------------- 1 | array( 21 | 'type' => 'App\\Extensions\\ExpertSender\\Entity\\ReceiverType', 22 | 'xmlName' => 'Receiver', 23 | ), 24 | 'snippets' => array( 25 | 'type' => 'App\\Extensions\\ExpertSender\\Entity\\SnippetType', 26 | 'xmlName' => 'Snippet', 27 | 'unbound' => true, 28 | 'unboundTag' => 'Snippets' 29 | ), 30 | 'attachments' => array( 31 | 'type' => 'App\\Extensions\\ExpertSender\\Entity\\AttachmentType', 32 | 'xmlName' => 'Attachment', 33 | 'unbound' => true, 34 | 'unboundTag' => 'Attachments' 35 | ) 36 | ); 37 | } -------------------------------------------------------------------------------- /src/ExpertSender/Request/Get/Subscribers.php: -------------------------------------------------------------------------------- 1 | urlParams['email'] = $email; 29 | $this->urlParams['option'] = $option !== null ? $option : SubscribersOption::FULL; 30 | 31 | if ($this->urlParams['option'] == SubscribersOption::EVENTS_HISTORY) 32 | { 33 | $this->responseEntity = 'App\\Extensions\\ExpertSender\\Response\\EventsType'; 34 | } 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /src/ExpertSender/Request/Get/Messages.php: -------------------------------------------------------------------------------- 1 | endPoint = '/Api/Messages/' . $id; 20 | $this->responseEntity = 'Zhmi\\ExpertSender\\Response\\MessageType'; 21 | } 22 | else 23 | { 24 | if ($tag !== null) 25 | { 26 | $this->urlParams['tag'] = $tag; 27 | } 28 | 29 | if (!is_null($startDate)) 30 | { 31 | $this->urlParams['startDate'] = $startDate->format('Y-m-d'); 32 | } 33 | 34 | if (!is_null($endDate)) 35 | { 36 | $this->urlParams['endDate'] = $startDate->format('Y-m-d'); 37 | } 38 | } 39 | 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/RecipientsType.php: -------------------------------------------------------------------------------- 1 | array( 19 | 'type' => 'integer', 20 | 'xmlName' => 'SubscriberList', 21 | 'unbound' => true, 22 | 'unboundTag' => 'SubscriberLists' 23 | ), 24 | 'subscriberSegments' => array( 25 | 'type' => 'integer', 26 | 'xmlName' => 'SubscriberSegment', 27 | 'unbound' => true, 28 | 'unboundTag' => 'SubscriberSegments' 29 | ), 30 | 'seedLists' => array( 31 | 'type' => 'integer', 32 | 'xmlName' => 'SeedList', 33 | 'unbound' => true, 34 | 'unboundTag' => 'SeedLists' 35 | ), 36 | 'supressionLists' => array( 37 | 'type' => 'integer', 38 | 'xmlName' => 'SuppressionList', 39 | 'unbound' => true, 40 | 'unboundTag' => 'SuppressionLists' 41 | ) 42 | ); 43 | } -------------------------------------------------------------------------------- /src/Http.php: -------------------------------------------------------------------------------- 1 | $method, 19 | 'header' => '', 20 | 'timeout' => $timeout, 21 | 'ignore_errors' => true 22 | ); 23 | 24 | if ($content && $method === 'POST') { 25 | $http['content'] = $content; 26 | $http['header'] = "Content-Type: application/xml;charset=UTF-8\r\n"; 27 | } 28 | 29 | $context = stream_context_create(array('http' => $http)); 30 | 31 | $start_microtime = microtime(true); 32 | 33 | $body = @file_get_contents($url, false, $context); 34 | 35 | $used_microtime = microtime(true) - $start_microtime; 36 | 37 | if ($body === false) { 38 | throw new \Exception("Request ExpertSender Failure, used_microtime={$used_microtime}", self::CONNECTION_ERROR); 39 | } 40 | 41 | // http_response_header is php autoregister var 42 | return [ 43 | 'body' => $body, 44 | 'headers' => $http_response_header, 45 | 'used_microtime' => $used_microtime 46 | ]; 47 | } 48 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/AttachmentType.php: -------------------------------------------------------------------------------- 1 | array( 18 | 'type' => 'string', 19 | 'xmlName' => 'FileName' 20 | ), 21 | 'mimeType' => array( 22 | 'type' => 'string', 23 | 'xmlName' => 'MimeType', 24 | ), 25 | 'content' => array( 26 | 'type' => 'string', 27 | 'xmlName' => 'Content', 28 | ), 29 | ); 30 | 31 | public function __construct($file) 32 | { 33 | $this->makeFromFile($file); 34 | } 35 | 36 | private function checkFileExists($file) 37 | { 38 | if (!file_exists($file)) 39 | { 40 | throw new \InvalidArgumentException('Bad path to file'); 41 | } 42 | } 43 | 44 | public function makeFromFile($file) 45 | { 46 | $this->checkFileExists($file); 47 | 48 | $this->filename = basename($file); 49 | $finfo = finfo_open(FILEINFO_MIME_TYPE); 50 | $this->mimeType = finfo_file($finfo, $this->filename); 51 | $this->content = base64_encode($file); 52 | } 53 | 54 | } -------------------------------------------------------------------------------- /src/ExpertSender/Response/EventType.php: -------------------------------------------------------------------------------- 1 | array( 21 | 'type' => 'DateTime', 22 | 'xmlName' => 'StartDate', 23 | ), 24 | 'EndDate' => array( 25 | 'type' => 'DateTime', 26 | 'xmlName' => 'EndDate', 27 | ), 28 | 'MessageType' => array( 29 | 'type' => 'string', 30 | 'xmlName' => 'MessageType' 31 | ), 32 | 'EventType' => array( 33 | 'type' => 'string', 34 | 'xmlName' => 'EventType', 35 | ), 36 | 'EventCount' => array( 37 | 'type' => 'integer', 38 | 'xmlName' => 'EventCount', 39 | ), 40 | 'MessageSubject' => array( 41 | 'type' => 'string', 42 | 'xmlName' => 'MessageSubject', 43 | ), 44 | 'MessageId' => array( 45 | 'type' => 'integer', 46 | 'xmlName' => 'MessageId', 47 | ), 48 | ); 49 | } -------------------------------------------------------------------------------- /src/ExpertSender/Request/Get/SnoozedSubscribers.php: -------------------------------------------------------------------------------- 1 | urlParams['ListIds'] = implode(',', $listIds); 27 | } 28 | 29 | if (!is_null($startDate)) 30 | { 31 | $this->urlParams['startDate'] = $startDate->format('Y-m-d'); 32 | } 33 | 34 | if (!is_null($endDate)) 35 | { 36 | $this->urlParams['endDate'] = $startDate->format('Y-m-d'); 37 | } 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/ListSettingsType.php: -------------------------------------------------------------------------------- 1 | array( 20 | 'type' => 'App\\Extensions\\ExpertSender\\Entity\\GeneralSettingsType', 21 | 'xmlName' => 'GeneralSettings', 22 | ), 23 | 'addressSettings' => array( 24 | 'type' => 'App\\Extensions\\ExpertSender\\Entity\\AddressSettingsType', 25 | 'xmlName' => 'AddressSettings', 26 | ), 27 | 'subscriberSettings' => array( 28 | 'type' => 'App\\Extensions\\ExpertSender\\Entity\\SubscriberSettingsType', 29 | 'xmlName' => 'SubscriberSettings', 30 | ), 31 | 'domainSettings' => array( 32 | 'type' => 'App\\Extensions\\ExpertSender\\Entity\\DomainSettingsType', 33 | 'xmlName' => 'DomainSettings', 34 | ), 35 | 'confirmationEmail' => array( 36 | 'type' => 'App\\Extensions\\ExpertSender\\Entity\\ConfirmationEmailType', 37 | 'xmlName' => 'ConfirmationEmail', 38 | ), 39 | ); 40 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/ListExportType.php: -------------------------------------------------------------------------------- 1 | array( 19 | 'type' => 'string', 20 | 'xmlName' => 'Type', 21 | ), 22 | 'listId' => array( 23 | 'type' => 'integer', 24 | 'xmlName' => 'ListId', 25 | ), 26 | 'segmentId' => array( 27 | 'type' => 'integer', 28 | 'xmlName' => 'SegmentId', 29 | ), 30 | 'fields' => array( 31 | 'type' => 'string', 32 | 'xmlName' => 'Field', 33 | 'unbound' => true, 34 | 'unboundTag' => 'Fields' 35 | ), 36 | 'properties' => array( 37 | 'type' => 'integer', 38 | 'xmlName' => 'Property', 39 | 'unbound' => true, 40 | 'unboundTag' => 'Properties' 41 | ), 42 | ); 43 | 44 | /** 45 | * @deprecated 46 | */ 47 | public function __construct($type='', $listId=0, $segmentId=0, array $fields=[], array $properties=[]) 48 | { 49 | $this->type = $type; 50 | $this->listId = $listId; 51 | $this->segmentId = $segmentId; 52 | $this->fields = $fields; 53 | if (count($properties) > 0) { 54 | $this->properties = $properties; 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/DeliverySettingsType.php: -------------------------------------------------------------------------------- 1 | array( 21 | 'type' => 'DateTime', 22 | 'xmlName' => 'DeliveryDate' 23 | ), 24 | 'timeZone' => array( 25 | 'type' => 'string', 26 | 'xmlName' => 'TimeZone', 27 | ), 28 | 'overrideDeliveryCap' => array( 29 | 'type' => 'boolean', 30 | 'xmlName' => 'OverrideDeliveryCap', 31 | ), 32 | 'throttlingMethod' => array( 33 | 'type' => 'string', 34 | 'xmlName' => 'ThrottlingMethod', 35 | ), 36 | 'manualThrottlingTime' => array( 37 | 'type' => 'integer', 38 | 'xmlName' => 'ManualThrottlingTime', 39 | ), 40 | 'timeOptimizationPeriod' => array( 41 | 'type' => 'string', 42 | 'xmlName' => 'TimeOptimizationPeriod', 43 | ), 44 | 'channels' => array( 45 | 'type' => 'App\\Extensions\\ExpertSender\\Entity\\ChannelType', 46 | 'xmlName' => 'Channel', 47 | 'unbound' => true, 48 | 'unboundTag' => 'Channels' 49 | ), 50 | ); 51 | } -------------------------------------------------------------------------------- /src/Services/AbstractService.php: -------------------------------------------------------------------------------- 1 | service = new ExpertSender\Service($apiKey, $apiUri); 32 | } 33 | 34 | /** 35 | * @author huangnie 36 | * @email 980484578@qq.com 37 | * @date 2019-08-20 38 | * @return string 39 | */ 40 | public function getUri() 41 | { 42 | return $this->service->getUri(); 43 | } 44 | 45 | /** 46 | * @author huangnie 47 | * @email 980484578@qq.com 48 | * @date 2019-08-20 49 | * @param string $uri 50 | */ 51 | public function setUri($uri) 52 | { 53 | $this->service->setUri($uri); 54 | } 55 | 56 | /** 57 | * @author huangnie 58 | * @email 980484578@qq.com 59 | * @date 2019-08-20 60 | * @return string 61 | */ 62 | public function getKey() 63 | { 64 | return $this->service->getKey(); 65 | } 66 | 67 | /** 68 | * @author huangnie 69 | * @email 980484578@qq.com 70 | * @date 2019-08-20 71 | * @param string $key 72 | */ 73 | public function setKey($key) 74 | { 75 | $this->service->setKey($key); 76 | } 77 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/ReceiverType.php: -------------------------------------------------------------------------------- 1 | array( 18 | 'type' => 'integer', 19 | 'xmlName' => 'Id' 20 | ), 21 | 'email' => array( 22 | 'type' => 'string', 23 | 'xmlName' => 'Email', 24 | ), 25 | 'listId' => array( 26 | 'type' => 'integer', 27 | 'xmlName' => 'ListId' 28 | ) 29 | ); 30 | 31 | public function __construct($id = null, $email = null, $listId = null) 32 | { 33 | if ($email !== null && !filter_var($email, FILTER_VALIDATE_EMAIL)) 34 | { 35 | throw new \InvalidArgumentException('Invalid email'); 36 | } 37 | 38 | if ($id !== null) 39 | { 40 | $this->id = $id; 41 | } 42 | 43 | if ($email !== null) 44 | { 45 | $this->email = $email; 46 | } 47 | 48 | if ($listId !== null) 49 | { 50 | $this->listId = $listId; 51 | } 52 | } 53 | 54 | private function check() 55 | { 56 | if (&& $this->id === null $this->email === null && $this->listId === null) 57 | { 58 | throw new \InvalidArgumentException('Must be set one or more receiver parameters'); 59 | } 60 | } 61 | 62 | public function __set($name, $value) 63 | { 64 | parent::__set($name, $value); 65 | $this->check(); 66 | } 67 | } -------------------------------------------------------------------------------- /src/ExpertSender/Response/MessageStatisticsType.php: -------------------------------------------------------------------------------- 1 | array( 27 | 'type' => 'integer', 28 | 'xmlName' => 'Sent' 29 | ), 30 | 'Bounced' => array( 31 | 'type' => 'integer', 32 | 'xmlName' => 'Bounced' 33 | ), 34 | 'Delivered' => array( 35 | 'type' => 'integer', 36 | 'xmlName' => 'Delivered' 37 | ), 38 | 'Opens' => array( 39 | 'type' => 'integer', 40 | 'xmlName' => 'Opens' 41 | ), 42 | 'UniqueOpens' => array( 43 | 'type' => 'integer', 44 | 'xmlName' => 'UniqueOpens' 45 | ), 46 | 'Clicks' => array( 47 | 'type' => 'integer', 48 | 'xmlName' => 'Clicks' 49 | ), 50 | 'UniqueClicks' => array( 51 | 'type' => 'integer', 52 | 'xmlName' => 'UniqueClicks' 53 | ), 54 | 'Clickers' => array( 55 | 'type' => 'integer', 56 | 'xmlName' => 'Clickers' 57 | ), 58 | 'Complaints' => array( 59 | 'type' => 'integer', 60 | 'xmlName' => 'Complaints' 61 | ), 62 | 'Unsubscribes' => array( 63 | 'type' => 'integer', 64 | 'xmlName' => 'Unsubscribes' 65 | ), 66 | ); 67 | } -------------------------------------------------------------------------------- /examples/addSubscriber.php: -------------------------------------------------------------------------------- 1 | setKey('YOUR_API_KEY'); 9 | 10 | try 11 | { 12 | //Create entity with it fields 13 | $entity = new ES\Entity\SubscriberType(); 14 | $entity->email = 'user.email@email.com'; 15 | $entity->lastname = 'David'; 16 | $entity->firstname = 'Suey'; 17 | $entity->listId = 13; 18 | $entity->ip = '127.0.0.1'; 19 | $entity->force = true; 20 | $entity->mode = ES\Enum\SubscribersMode::ADD_AND_UPDATE; 21 | $entity->trackingCode = 'subscription_form'; 22 | $entity->vendor = 'Google'; 23 | $entity->properties = array( 24 | new ES\Entity\PropertyType(7, new ES\Entity\PropertyValueType( 111111 )), //Integer 25 | new ES\Entity\PropertyType(11, new ES\Entity\PropertyValueType( false )), //Boolean 26 | new ES\Entity\PropertyType(6, new ES\Entity\PropertyValueType( '+77777777777' )), //String 27 | new ES\Entity\PropertyType(9, new ES\Entity\PropertyValueType( new \DateTime() )),//DateTime 28 | new ES\Entity\PropertyType(27, new ES\Entity\PropertyValueType( '1920-01-01' )), //Date 29 | new ES\Entity\PropertyType(32, new ES\Entity\PropertyValueType( 'M' )), //SingleSelection 30 | ); 31 | 32 | //Initialize request with Data wrapper with entity 33 | $request = new ES\Request\Post\Subscribers( $entity ); 34 | 35 | //Making a request call 36 | $response = $service->call( $request ); 37 | if ($response->isOk()) 38 | { 39 | echo 'success'; 40 | } 41 | else 42 | { 43 | echo $response->getCode(); 44 | } 45 | 46 | } 47 | catch (ES\ServiceException $e) 48 | { 49 | print_r('Ошибка выполнения запроса к сервису:' . "\n"); 50 | echo $e->getCode() . " - " . $e->getMessage(); 51 | } 52 | catch (\Exception $e) 53 | { 54 | var_dump($e); 55 | } 56 | -------------------------------------------------------------------------------- /src/ExpertSender/Response/SubscriberType.php: -------------------------------------------------------------------------------- 1 | array( 22 | 'type' => 'boolean', 23 | 'xmlName' => 'BlackList' 24 | ), 25 | 'StateOnLists' => array( 26 | 'type' => 'App\\Extensions\\ExpertSender\\Response\\StateOnListType', 27 | 'xmlName' => 'StateOnLists', 28 | 'unbound' => true, 29 | 'unboundTag' => 'StateOnList' 30 | ), 31 | 'SuppressionLists' => array( 32 | 'type' => 'App\\Extensions\\ExpertSender\\Response\\SuppressionListType', 33 | 'xmlName' => 'SuppressionLists', 34 | 'unbound' => true, 35 | 'unboundTag' => 'SuppressionList' 36 | ), 37 | 'Id' => array( 38 | 'type' => 'integer', 39 | 'xmlName' => 'Id', 40 | ), 41 | 'Lastname' => array( 42 | 'type' => 'string', 43 | 'xmlName' => 'Lastname', 44 | ), 45 | 'Vendor' => array( 46 | 'type' => 'string', 47 | 'xmlName' => 'Vendor', 48 | ), 49 | 'Ip' => array( 50 | 'type' => 'string', 51 | 'xmlName' => 'Ip', 52 | ), 53 | 'Properties' => array( 54 | 'type' => 'App\\Extensions\\ExpertSender\\Response\\PropertyType', 55 | 'xmlName' => 'Properties', 56 | 'unbound' => true, 57 | 'unboundTag' => 'Property' 58 | ), 59 | ); 60 | } -------------------------------------------------------------------------------- /src/ExpertSender/Http.php: -------------------------------------------------------------------------------- 1 | $method, 20 | 'header' => '', 21 | 'timeout' => $timeout, 22 | 'ignore_errors' => true 23 | ); 24 | 25 | if ($content && in_array($method, ['POST', 'PUT'])) { 26 | $http['content'] = $content; 27 | $http['length'] = strlen($content); 28 | $http['header'] = "Content-Type: application/xml;charset=UTF-8\r\n"; 29 | } 30 | 31 | $context = stream_context_create(array('http' => $http)); 32 | 33 | $start_microtime = microtime(true); 34 | 35 | $body = @file_get_contents($url, false, $context); 36 | 37 | $used_microtime = microtime(true) - $start_microtime; 38 | 39 | if ($body === false) { 40 | throw new \Exception("Request ExpertSender Failure, used_microtime={$used_microtime} ", self::CONNECTION_ERROR); 41 | } 42 | 43 | // http_response_header is php autoregister var 44 | return [ 45 | 'body' => $body, 46 | 'headers' => $http_response_header, 47 | 'used_microtime' => $used_microtime 48 | ]; 49 | } 50 | 51 | public static function post($url, $body, $timeout=600) 52 | { 53 | return self::query($url, 'POST', $body, $timeout); 54 | } 55 | 56 | public static function get($url, $data, $timeout=600) 57 | { 58 | return self::query($url . '?' . http_build_query($data), 'GET', null, $timeout); 59 | } 60 | 61 | public static function delete($url, $data, $timeout=600) 62 | { 63 | return self::query($url . '?' . http_build_query($data), 'DELETE', null, $timeout); 64 | } 65 | } -------------------------------------------------------------------------------- /src/ExpertSender/Response/PropertyType.php: -------------------------------------------------------------------------------- 1 | array( 25 | 'type' => 'integer', 26 | 'xmlName' => 'Id', 27 | ), 28 | 'Source' => array( 29 | 'type' => 'string', 30 | 'xmlName' => 'Source' 31 | ), 32 | 'DateTimeValue' => array( 33 | 'type' => 'DateTime', 34 | 'xmlName' => 'DateTimeValue', 35 | ), 36 | 'IntValue' => array( 37 | 'type' => 'integer', 38 | 'xmlName' => 'IntValue', 39 | ), 40 | 'StringValue' => array( 41 | 'type' => 'string', 42 | 'xmlName' => 'StringValue', 43 | ), 44 | 'Type' => array( 45 | 'type' => 'string', 46 | 'xmlName' => 'Type', 47 | ), 48 | 'FriendlyName' => array( 49 | 'type' => 'string', 50 | 'xmlName' => 'FriendlyName', 51 | ), 52 | 'Name' => array( 53 | 'type' => 'string', 54 | 'xmlName' => 'Name', 55 | ), 56 | 'DefaultStringValue' => array( 57 | 'type' => 'string', 58 | 'xmlName' => 'DefaultStringValue', 59 | ), 60 | 'DefaultIntValue' => array( 61 | 'type' => 'integer', 62 | 'xmlName' => 'DefaultIntValue', 63 | ), 64 | 'DefaultDateTimeValue' => array( 65 | 'type' => 'DateTime', 66 | 'xmlName' => 'DefaultDateTimeValue', 67 | ), 68 | ); 69 | } -------------------------------------------------------------------------------- /src/ExpertSender/Response.php: -------------------------------------------------------------------------------- 1 | responseBody = $body; 39 | $this->responseHeaders = $headers; 40 | 41 | $responseCode = null; 42 | foreach ($headers as $header) 43 | { 44 | if (preg_match('~HTTP.+ ([0-9]+).+~', $header, $matches)) 45 | { 46 | $responseCode = trim($matches[1]); 47 | } 48 | } 49 | 50 | $responseEntity = null; 51 | if ($body !== null) 52 | { 53 | $expectedEntity = strpos($body, 'ErrorMessage') !== false ? 'App\\Extensions\\ExpertSender\\Response\\ErrorMessageType' : $responseEntityType; 54 | $responseEntity = (new XmlParser( $expectedEntity ))->parse( $body ); 55 | } 56 | 57 | $this->responseCode = $responseCode; 58 | $this->responseEntity = $responseEntity; 59 | } 60 | 61 | public function getHeades() 62 | { 63 | return $this->responseHeaders; 64 | } 65 | 66 | public function getBody() 67 | { 68 | return $this->responseBody; 69 | } 70 | 71 | public function getCode() 72 | { 73 | return $this->responseCode; 74 | } 75 | 76 | public function getResponseEntity() 77 | { 78 | return $this->responseEntity; 79 | } 80 | 81 | /** 82 | * request state 83 | * @return bool 84 | */ 85 | public function isOk() 86 | { 87 | return strpos($this->responseCode, '2') === 0; 88 | } 89 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/SubscriberType.php: -------------------------------------------------------------------------------- 1 | array( 30 | 'type' => 'string', 31 | 'xmlName' => 'Mode' 32 | ), 33 | 'force' => array( 34 | 'type' => 'boolean', 35 | 'xmlName' => 'Force', 36 | ), 37 | 'listId' => array( 38 | 'type' => 'integer', 39 | 'xmlName' => 'ListId', 40 | ), 41 | 'id' => array( 42 | 'type' => 'integer', 43 | 'xmlName' => 'Id', 44 | ), 45 | 'email' => array( 46 | 'type' => 'string', 47 | 'xmlName' => 'Email', 48 | ), 49 | 'phone' => array( 50 | 'type' => 'string', 51 | 'xmlName' => 'Phone', 52 | ), 53 | 'firstname' => array( 54 | 'type' => 'string', 55 | 'xmlName' => 'Firstname', 56 | ), 57 | 'lastname' => array( 58 | 'type' => 'string', 59 | 'xmlName' => 'Lastname', 60 | ), 61 | 'trackingCode' => array( 62 | 'type' => 'string', 63 | 'xmlName' => 'TrackingCode', 64 | ), 65 | 'name' => array( 66 | 'type' => 'string', 67 | 'xmlName' => 'Name', 68 | ), 69 | 'vendor' => array( 70 | 'type' => 'string', 71 | 'xmlName' => 'Vendor', 72 | ), 73 | 'ip' => array( 74 | 'type' => 'string', 75 | 'xmlName' => 'Ip', 76 | ), 77 | 'properties' => array( 78 | 'type' => 'App\\Extensions\\ExpertSender\\Entity\\PropertyType', 79 | 'xmlName' => 'Property', 80 | 'unbound' => true, 81 | 'unboundTag' => 'Properties' 82 | ), 83 | ); 84 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/GeneralSettingsType.php: -------------------------------------------------------------------------------- 1 | array( 28 | 'type' => 'string', 29 | 'xmlName' => 'Name', 30 | ), 31 | 'friendlyName' => array( 32 | 'type' => 'string', 33 | 'xmlName' => 'FriendlyName', 34 | ), 35 | 'description' => array( 36 | 'type' => 'string', 37 | 'xmlName' => 'Description', 38 | ), 39 | 'language' => array( 40 | 'type' => 'string', 41 | 'xmlName' => 'Language', 42 | ), 43 | 'optInMode' => array( 44 | 'type' => 'string', 45 | 'xmlName' => 'OptInMode', 46 | ), 47 | 'defaultFromName' => array( 48 | 'type' => 'string', 49 | 'xmlName' => 'DefaultFromName', 50 | ), 51 | 'defaultFromEmail' => array( 52 | 'type' => 'string', 53 | 'xmlName' => 'DefaultFromEmail', 54 | ), 55 | 'defaultReplyToName' => array( 56 | 'type' => 'string', 57 | 'xmlName' => 'DefaultReplyToName', 58 | ), 59 | 'charset' => array( 60 | 'type' => 'string', 61 | 'xmlName' => 'Charset', 62 | ), 63 | 'subscriptionConfirmPageUrl' => array( 64 | 'type' => 'string', 65 | 'xmlName' => 'SubscriptionConfirmPageUrl', 66 | ), 67 | 'subscriptionThankYouPageUrl' => array( 68 | 'type' => 'string', 69 | 'xmlName' => 'SubscriptionThankYouPageUrl', 70 | ), 71 | 'removalPageUrl' => array( 72 | 'type' => 'string', 73 | 'xmlName' => 'RemovalPageUrl', 74 | ), 75 | 'preferencesChangeUrl' => array( 76 | 'type' => 'string', 77 | 'xmlName' => 'PreferencesChangeUrl', 78 | ), 79 | ); 80 | } -------------------------------------------------------------------------------- /src/ExpertSender/Response/MessageType.php: -------------------------------------------------------------------------------- 1 | array( 23 | 'type' => 'integer', 24 | 'xmlName' => 'Id', 25 | ), 26 | 'Type' => array( 27 | 'type' => 'string', 28 | 'xmlName' => 'Type', 29 | ), 30 | 'FromName' => array( 31 | 'type' => 'string', 32 | 'xmlName' => 'FromName' 33 | ), 34 | 'FromEmail' => array( 35 | 'type' => 'string', 36 | 'xmlName' => 'FromEmail', 37 | ), 38 | 'Subject' => array( 39 | 'type' => 'string', 40 | 'xmlName' => 'Subject', 41 | ), 42 | 'SentDate' => array( 43 | 'type' => 'DateTime', 44 | 'xmlName' => 'SentDate', 45 | ), 46 | 'Tags' => array( 47 | 'type' => 'string', 48 | 'xmlName' => 'Tags', 49 | ), 50 | 'YandexListId' => array( 51 | 'type' => 'integer', 52 | 'xmlName' => 'YandexListId', 53 | ), 54 | 'Channels' => array( 55 | 'type' => 'string', 56 | 'xmlName' => 'Channels', 57 | ), 58 | 'ThrottlingMethod' => array( 59 | 'type' => 'string', 60 | 'xmlName' => 'ThrottlingMethod', 61 | ), 62 | 'Throttling' => array( 63 | 'type' => 'integer', 64 | 'xmlName' => 'Throttling', 65 | ), 66 | 'Status' => array( 67 | 'type' => 'string', 68 | 'xmlName' => 'Status', 69 | ), 70 | 'Lists' => array( 71 | 'type' => 'App\\Extensions\\ExpertSender\\Response\\ListType', 72 | 'xmlName' => 'Lists', 73 | 'unbound' => true, 74 | 'unboundTag' => 'List' 75 | ), 76 | 'Segments' => array( 77 | 'type' => 'App\\Extensions\\ExpertSender\\Response\\SegmentType', 78 | 'xmlName' => 'Segments', 79 | 'unbound' => true, 80 | 'unboundTag' => 'Segment' 81 | ), 82 | 'GoogleAnalyticsTags' => array( 83 | 'type' => 'App\\Extensions\\ExpertSender\\Response\\GoogleAnalyticsTagType', 84 | 'xmlName' => 'GoogleAnalyticsTags', 85 | 'unbound' => true, 86 | 'unboundTag' => 'GoogleAnalyticsTag' 87 | ), 88 | ); 89 | } -------------------------------------------------------------------------------- /src/ExpertSender/Request.php: -------------------------------------------------------------------------------- 1 | requestEntity = $entity; 42 | } 43 | 44 | /** 45 | * 请求数据结构 46 | * 47 | * @return [type] [description] 48 | */ 49 | public function getResponseEntity() 50 | { 51 | return $this->responseEntity; 52 | } 53 | 54 | /** 55 | * Получает адрес запроса на основании текущего состояния класса 56 | * @param array $additionalParams 57 | * @return string Адрес запроса 58 | */ 59 | public function getRequestUrl(array $additionalParams = array()) 60 | { 61 | if (!empty($additionalParams)) { 62 | $this->urlParams = array_merge($additionalParams, $this->urlParams); 63 | } 64 | 65 | if (count($this->urlParams) > 0) { 66 | return $this->endPoint . '?' . http_build_query($this->urlParams); 67 | } else { 68 | return $this->endPoint; 69 | } 70 | } 71 | 72 | /** 73 | * Получает тело запроса 74 | * @param string $apiKey Api ключ, который нужно исопльзовать при построении тела запроса 75 | * @return string 76 | */ 77 | public function getRequestBody($apiKey) 78 | { 79 | $xml = ''; 80 | if (!is_null($this->requestEntity)) { 81 | $xml .= '' . $apiKey . ''; 82 | 83 | $xmlContent = $this->requestEntity->toXml(); 84 | if ($this->requestEntity->getPosition() == 'root') { 85 | $xml .= $xmlContent; 86 | } else { 87 | $xsi = $this->requestEntity->getXsiType(); 88 | if ($xsi) { 89 | $xml .= ''; 90 | } else { 91 | $xml .= ''; 92 | } 93 | 94 | $xml .= $this->requestEntity->toXml(); 95 | $xml .= ''; 96 | } 97 | 98 | $xml .= ''; 99 | } 100 | return $xml; 101 | } 102 | 103 | /** 104 | * Получает имя метода запроса по его пространству имен 105 | * @return string 106 | */ 107 | public function getRequestMethod() 108 | { 109 | $ns = explode('\\', get_class($this)); 110 | return strtoupper($ns[ count($ns)-2 ]); 111 | } 112 | 113 | } -------------------------------------------------------------------------------- /src/ExpertSender/Service.php: -------------------------------------------------------------------------------- 1 | setKey( $key ); 32 | } 33 | if ($uri) { 34 | $this->setUri( $uri ); 35 | } 36 | } 37 | 38 | /** 39 | * @return string 40 | */ 41 | public function getUri() 42 | { 43 | return $this->uri; 44 | } 45 | 46 | /** 47 | * @param string $uri 48 | */ 49 | public function setUri($uri) 50 | { 51 | $this->uri = $uri; 52 | } 53 | 54 | /** 55 | * @return string 56 | */ 57 | public function getKey() 58 | { 59 | return $this->key; 60 | } 61 | 62 | /** 63 | * @param string $key 64 | */ 65 | public function setKey($key) 66 | { 67 | $this->key = $key; 68 | } 69 | 70 | /** 71 | * Производит обращение к сервису с помощью переданного в него заранее сформированного запроса 72 | * @param Request $request 73 | * @return Response 74 | * @throws ServiceException 75 | */ 76 | function call(Request $request, $debug = false) 77 | { 78 | // 接口方法 79 | $method = $request->getRequestMethod(); 80 | 81 | // 接口参数 82 | $xmlBody = $request->getRequestBody($this->key); 83 | $queryParams = array(); 84 | if (strlen($xmlBody) == 0) { 85 | $queryParams['apiKey'] = $this->key; 86 | } 87 | 88 | // 接口地址 89 | $url = trim($this->uri, '/') . $request->getRequestUrl($queryParams); 90 | 91 | if ($debug) { 92 | print_r([ 93 | 'url' => $url, 94 | 'method' => $method, 95 | 'xmlBody' => $xmlBody 96 | ]); 97 | exit(); 98 | } 99 | 100 | // 请求结果 101 | $result = Http::query($url, $method, $xmlBody); 102 | 103 | // 解析结果 104 | $response = new Response($result['body'], $result['headers'], $request->getResponseEntity()); 105 | 106 | // 若接口返回警告(或错误) 107 | $entity = $response->getResponseEntity(); 108 | if ($entity instanceof ErrorMessageType) { 109 | if ($entity->Message) { 110 | throw new \Exception($entity->Message, $entity->Code); 111 | } else { 112 | throw new \Exception("ApiWarning: Unknown, RequestBody={$xmlBody}, ResposeBody={$result['body']}", $response->getCode()); 113 | } 114 | } 115 | 116 | // 若请求返回失败(或异常) 117 | if (!$response->isOk()) { 118 | $warning = is_object($entity) ? get_object_vars($entity) : $entity; 119 | if (is_array($warning)) { 120 | $warning = json_encode($warning); 121 | } 122 | throw new \Exception("ReqFailure: {$warning}", $response->getCode()); 123 | } 124 | 125 | return $response; 126 | } 127 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/ContentType.php: -------------------------------------------------------------------------------- 1 | array( 26 | 'type' => 'string', 27 | 'xmlName' => 'FromName' 28 | ), 29 | 'fromEmail' => array( 30 | 'type' => 'string', 31 | 'xmlName' => 'FromEmail', 32 | ), 33 | 'replyToName' => array( 34 | 'type' => 'string', 35 | 'xmlName' => 'ReplyToName', 36 | ), 37 | 'replyToEmail' => array( 38 | 'type' => 'string', 39 | 'xmlName' => 'ReplyToEmail', 40 | ), 41 | 'subject' => array( 42 | 'type' => 'string', 43 | 'xmlName' => 'Subject', 44 | ), 45 | 'plain' => array( 46 | 'type' => 'string', 47 | 'xmlName' => 'Plain', 48 | ), 49 | 'html' => array( 50 | 'type' => 'string', 51 | 'xmlName' => 'Html', 52 | 'cdata' => true, 53 | ), 54 | 'ampHtml' => array( 55 | 'type' => 'string', 56 | 'xmlName' => 'AmpHtml', 57 | 'cdata' => true, 58 | ), 59 | 'header' => array( 60 | 'type' => 'integer', 61 | 'xmlName' => 'Header', 62 | 'cdata' => true, 63 | ), 64 | 'footer' => array( 65 | 'type' => 'integer', 66 | 'xmlName' => 'Footer', 67 | ), 68 | 'tags' => array( 69 | 'type' => 'string', 70 | 'xmlName' => 'Tag', 71 | 'unbound' => true, 72 | 'unboundTag' => 'Tags' 73 | ), 74 | 'contentFromUrl' => array( 75 | 'type' => 'App\\Extensions\\ExpertSender\\Entity\\ContentFromUrlType', 76 | 'xmlName' => 'ContentFromUrl', 77 | ), 78 | 'googleAnalyticsTags' => array( 79 | 'type' => 'App\\Extensions\\ExpertSender\\Entity\\GoogleAnalyticsTagsType', 80 | 'xmlName' => 'GoogleAnalyticsTags', 81 | ), 82 | 'attachments' => array( 83 | 'type' => 'App\\Extensions\\ExpertSender\\Entity\\AttachmentType', 84 | 'xmlName' => 'Attachment', 85 | 'unbound' => true, 86 | 'unboundTag' => 'Attachments' 87 | ), 88 | 'urlIntegrations' => array( 89 | 'type' => 'App\\Extensions\\ExpertSender\\Entity\\UrlIntegrationType', 90 | 'xmlName' => 'UrlIntegration', 91 | 'unbound' => true, 92 | 'unboundTag' => 'UrlIntegrations' 93 | ), 94 | 'enableOpenTrack' => array( 95 | 'type' => 'boolean', 96 | 'xmlName' => 'EnableClickTrack', 97 | ), 98 | 'enableOpenTrack' => array( 99 | 'type' => 'boolean', 100 | 'xmlName' => 'EnableOpenTrack', 101 | ), 102 | ); 103 | } -------------------------------------------------------------------------------- /src/ExpertSender/Entity/PropertyValueType.php: -------------------------------------------------------------------------------- 1 | array( 16 | 'type' => 'mixed', 17 | 'xmlName' => 'Value', 18 | ), 19 | 'type' => array( 20 | 'type' => 'string', 21 | 'attribute' => true, 22 | 'attributeName' => 'xsi:type', 23 | ) 24 | ); 25 | 26 | private $realValue; 27 | 28 | private $availableXsiMap = array( 29 | 'string' => 'string', 30 | 'boolean' => 'boolean', 31 | 'integer' => 'integer', 32 | 'double' => 'double', 33 | 'DateTime' => 'dateTime', 34 | ); 35 | 36 | /** 37 | * @param mixed $value Значение свойства 38 | * @param null $type Тип свойства. При указании типа значение будет приведено к строке, поэтому при установке 39 | * собственного типа необходимо позаботиться заранее о приведении значения в нужный вид 40 | */ 41 | public function __construct($value, $type = null) 42 | { 43 | if ($type === null) 44 | { 45 | $this->value = $value; 46 | } 47 | else 48 | { 49 | if (!$this->isAvailableXsi($type)) 50 | { 51 | throw new \InvalidArgumentException("Unexpected type '{$type}' of PropertyValue"); 52 | } 53 | $this->type = $type; 54 | parent::__set('value', (string)$value); 55 | } 56 | 57 | } 58 | 59 | /** 60 | * Собственный сеттер для класса. Необходим, чтобы задать произвольную логику установки значения свойства 61 | * @param string $name 62 | * @param mixed $value 63 | */ 64 | public function __set($name, $value) 65 | { 66 | if ($name === 'value') 67 | { 68 | $this->setValue($value); 69 | } 70 | else 71 | { 72 | parent::__set($name, $value); 73 | } 74 | } 75 | 76 | /** 77 | * Приведение класса к строке приведет к тому, что объект будет содержать строковое значение свойства 78 | * @return mixed 79 | */ 80 | public function __toString() 81 | { 82 | return $this->value; 83 | } 84 | 85 | /** 86 | * Вспомогательная функция, которая по опредленной логике задает значение свойства и преобразует его в строку. 87 | * Также функция задает тип свойства в зависимости от типа значения 88 | * @param mixed $value 89 | */ 90 | private function setValue($value) 91 | { 92 | $this->realValue = $value; 93 | 94 | $actualType = $this->getActualType($value); 95 | if (!$this->isAvailableType($actualType)) 96 | { 97 | throw new \InvalidArgumentException("Unexpected type '{$actualType}' of the PropertyValue"); 98 | } 99 | 100 | $xsi = $this->availableXsiMap[ $actualType ]; 101 | 102 | switch ($actualType) 103 | { 104 | case 'DateTime': 105 | $value = $value->format('Y-m-d\TH:i:s'); 106 | break; 107 | case 'integer': 108 | case 'double': 109 | $value = (string)$value; 110 | break; 111 | case 'boolean': 112 | $value = $value === true ? 'true' : 'false'; 113 | break; 114 | case 'string': 115 | default: 116 | $xsi = 'string'; 117 | $this->realValue = (string)$value; 118 | break; 119 | } 120 | 121 | if (preg_match('/^\d{4}-\d{2}-\d{2}&/', $value)) 122 | { 123 | $xsi = 'date'; 124 | } 125 | 126 | $this->type = 'xs:'.$xsi; 127 | parent::__set('value', $value); 128 | 129 | } 130 | 131 | /** 132 | * Получает реальное значение свойства 133 | * @return mixed 134 | */ 135 | public function getRealValue() 136 | { 137 | return $this->realValue; 138 | } 139 | 140 | /** 141 | * Проверяет, доступен ли тип 142 | * @param string $actualType 143 | * @return bool 144 | */ 145 | private function isAvailableType($actualType) 146 | { 147 | return isset($this->availableXsiMap[ $actualType ]); 148 | } 149 | 150 | /** 151 | * Проверяет, доступен ли тип xsi 152 | * @param string $xsi 153 | * @return bool 154 | */ 155 | private function isAvailableXsi($xsi) 156 | { 157 | return in_array($xsi, $this->availableXsiMap); 158 | } 159 | } -------------------------------------------------------------------------------- /src/ExpertSender/Unbound.php: -------------------------------------------------------------------------------- 1 | property = $property; 38 | $this->expectedType = $expectedType; 39 | } 40 | 41 | public function getExpectedType() 42 | { 43 | return $this->expectedType; 44 | } 45 | 46 | /** 47 | * Реализация ArrayAccess 48 | * Определяет наличие элемента в массиве. 49 | * 50 | * @param integer $offset Индекс массива, который нужно проверить 51 | * @returns boolean 52 | */ 53 | public function offsetExists($offset) 54 | { 55 | return isset($this->data[$offset]); 56 | } 57 | 58 | /** 59 | * Реализация ArrayAccess 60 | * Возвращает значение массива, хранящееся под заданным индексом 61 | * 62 | * @param integer $offset Индекс массива 63 | * @returns mixed Значение массива или null, если его нет 64 | */ 65 | public function offsetGet($offset) 66 | { 67 | return $this->offsetExists($offset) ? $this->data[$offset] : null; 68 | } 69 | 70 | /** 71 | * Реализация ArrayAccess 72 | * Устанавливает значение массива 73 | * 74 | * @param mixed $offset Индекс массива или null, куда добавить значение массива 75 | * @throws \InvalidPropertyTypeException Если значение имеет неожидаемый тип, будет выброшено исключение 76 | */ 77 | public function offsetSet($offset, $value) 78 | { 79 | self::ensurePropertyType($value); 80 | 81 | if (is_null($offset)) { 82 | $this->data[] = $value; 83 | } else { 84 | $this->data[$offset] = $value; 85 | } 86 | } 87 | 88 | /** 89 | * Реализация ArrayAccess 90 | * Удаляет значение под заданным индексом 91 | * 92 | * @param integer $offset Индекс массива 93 | */ 94 | public function offsetUnset($offset) 95 | { 96 | unset($this->data[$offset]); 97 | } 98 | 99 | /** 100 | * Реализация Countable 101 | * @returns integer Количество элементов массива 102 | */ 103 | public function count() 104 | { 105 | return count($this->data); 106 | } 107 | 108 | /** 109 | * Реализация Iterator 110 | * @returns mixed Значение текущего элемента массива 111 | */ 112 | public function current() 113 | { 114 | return $this->offsetGet($this->position); 115 | } 116 | 117 | /** 118 | * Реализация Iterator 119 | * @returns integer Позиция указателя массива 120 | */ 121 | public function key() 122 | { 123 | return $this->position; 124 | } 125 | 126 | /** 127 | * Реализация Iterator 128 | * Перемещает указатель массива к следующему элементу массива 129 | */ 130 | public function next() 131 | { 132 | $this->position++; 133 | } 134 | 135 | /** 136 | * Реализация Iterator 137 | * Перемещает указатель массива в начало массива 138 | */ 139 | public function rewind() 140 | { 141 | $this->position = 0; 142 | } 143 | 144 | /** 145 | * Реализация Iterator 146 | * @returns boolean Возвращает true, если текущий элемент массива с текущим индексом существует 147 | */ 148 | public function valid() 149 | { 150 | return $this->offsetExists($this->position); 151 | } 152 | 153 | /** 154 | * Проверяет тип свойства для присваиваемого значения 155 | * 156 | * @param mixed $value Значение, которое устанавливается для элемента массива 157 | */ 158 | private function ensurePropertyType($value) 159 | { 160 | $actualType = gettype($value); 161 | if ('object' === $actualType) { 162 | $actualType = get_class($value); 163 | } 164 | if ($this->expectedType !== $actualType) { 165 | throw new \InvalidArgumentException("Incorrect type"); 166 | } 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/ExpertSender/XmlParser.php: -------------------------------------------------------------------------------- 1 | rootObjectClass = $rootObjectClass ?? 'string'; 18 | 19 | $this->stack = new \SplStack(); 20 | } 21 | 22 | /** 23 | * Метод, который запускает механизм парсинга XML строки 24 | * @param string $xml 25 | * @return BaseType 26 | */ 27 | public function parse($xml) 28 | { 29 | $parser = xml_parser_create('UTF-8'); 30 | 31 | xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); 32 | xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); 33 | xml_set_object($parser, $this); 34 | xml_set_element_handler($parser, 'startElementHandler', 'endElementHandler'); 35 | xml_set_character_data_handler($parser, 'valueHandler'); 36 | 37 | xml_parse($parser, $xml, true); 38 | 39 | xml_parser_free($parser); 40 | 41 | return $this->rootObject; 42 | } 43 | 44 | /** 45 | * Callback метод для обработки начального элемента XML 46 | * @param resource $parser 47 | * @param string $name 48 | * @param array $attributes 49 | * @return bool 50 | */ 51 | private function startElementHandler($parser, $name, array $attributes) 52 | { 53 | if ($name == 'ApiResponse') { 54 | return false; 55 | } 56 | 57 | $this->stack->push($this->getPhpMeta($name, $attributes)); 58 | } 59 | 60 | /** 61 | * Callback метод для обработки скалярного значения между тегами 62 | * @param resource $parser 63 | * @param string $value 64 | * @return bool 65 | */ 66 | private function valueHandler($parser, $value) 67 | { 68 | $value = trim($value); 69 | if (strlen($value) === 0) { 70 | return false; 71 | } 72 | $this->stack->top()->strData .= $value; 73 | } 74 | 75 | /** 76 | * Callback метод для обработкик конечного элемента XML 77 | * @param resource $parser 78 | * @param string $name 79 | * @return bool 80 | */ 81 | private function endElementHandler($parser, $name) 82 | { 83 | if ($name == 'ApiResponse') { 84 | return false; 85 | } 86 | 87 | $meta = $this->stack->pop(); 88 | 89 | if (!$this->stack->isEmpty()) { 90 | if ($meta->propertyName !== '') { 91 | $parentObject = $this->getParentObject(); 92 | 93 | if ($parentObject) { 94 | $parentObject->{$meta->propertyName} = $this->getValueToAssign($meta); 95 | } 96 | } else { 97 | $parentObject = $this->getParentObject($meta); 98 | if ($parentObject instanceof Unbound) { 99 | $parentObject[] = $meta->phpObject; 100 | } 101 | } 102 | } else { 103 | $this->rootObject = $meta->phpObject === null ? $this->getValueToAssign($meta) : $meta->phpObject; 104 | } 105 | } 106 | 107 | /** 108 | * Получает верхний элемент стека объектов 109 | * @return mixed 110 | */ 111 | private function getParentObject() 112 | { 113 | return $this->stack->top()->phpObject; 114 | } 115 | 116 | /** 117 | * Формирует мета-объект, сущность XML документа 118 | * @param $elementName 119 | * @param $attributes 120 | * @return mixed|\StdClass 121 | */ 122 | private function getPhpMeta($elementName, $attributes) 123 | { 124 | $meta = new \StdClass(); 125 | $meta->propertyName = ''; 126 | $meta->phpType = ''; 127 | $meta->unbound = false; 128 | $meta->attribute = false; 129 | $meta->elementName = ''; 130 | $meta->strData = ''; 131 | $meta->unboundTag = ''; 132 | 133 | if (!$this->stack->isEmpty()) { 134 | $parentObject = $this->getParentObject(); 135 | 136 | if ($parentObject instanceof Unbound) { 137 | $meta->phpType = $parentObject->getExpectedType(); 138 | } elseif ($parentObject) { 139 | /** @var BaseType $parentObject */ 140 | $elementMeta = $parentObject->elementMeta($elementName); 141 | if ($elementMeta) { 142 | $meta = $elementMeta; 143 | } 144 | } 145 | } else { 146 | $meta->phpType = $this->rootObjectClass; 147 | } 148 | 149 | $meta->phpObject = $this->newPhpObject($meta); 150 | 151 | // if ($meta->phpObject) { 152 | // foreach ($attributes as $attribute => $value) { 153 | // $attributeMeta = $meta->phpObject->elementMeta($attribute); 154 | // if ($attributeMeta) { 155 | // $attributeMeta->strData = $value; 156 | // $meta->phpObject->{$attributeMeta->propertyName} = $this->getValueToAssignToProperty($attributeMeta); 157 | // } 158 | // } 159 | // } 160 | 161 | return $meta; 162 | } 163 | 164 | /** 165 | * Создает новый экземпляр класса заданного типа 166 | * @param mixed $meta 167 | * @return null|Unbound 168 | */ 169 | private function newPhpObject($meta) 170 | { 171 | if ($meta->unbound) { 172 | return new Unbound($meta->elementName, $meta->phpType); 173 | } else { 174 | $object = null; 175 | switch ($meta->phpType) { 176 | case 'integer': 177 | case 'string': 178 | case 'double': 179 | case 'boolean': 180 | break; 181 | default: 182 | $object = $meta->phpType !== '' ? new $meta->phpType() : null; 183 | } 184 | 185 | return $object; 186 | } 187 | } 188 | 189 | /** 190 | * Возвращает реальное значение, которое нужно присвоить полю экземпляра класса 191 | * @param $meta 192 | * @return mixed 193 | */ 194 | private function getValueToAssign($meta) 195 | { 196 | if ($this->isSimplePhpType($meta)) { 197 | return $this->getValueToAssignToProperty($meta); 198 | } else { 199 | $meta->phpObject->value = $meta->strData; 200 | return $meta->phpObject; 201 | } 202 | } 203 | 204 | /** 205 | * Выполняет проверку на то, является ли объект в meta информации простым php типом или DateTime 206 | * @param $meta 207 | * @return bool 208 | */ 209 | private function isSimplePhpType($meta) 210 | { 211 | switch ($meta->phpType) { 212 | case 'integer': 213 | case 'string': 214 | case 'double': 215 | case 'boolean': 216 | case 'DateTime': 217 | return true; 218 | default: 219 | return false; 220 | } 221 | } 222 | 223 | /** 224 | * Получает значение из мета-информации для простых php типов 225 | * @param $meta 226 | * @return mixed 227 | */ 228 | private function getValueToAssignToProperty($meta) 229 | { 230 | switch ($meta->phpType) { 231 | case 'integer': 232 | return (integer)$meta->strData; 233 | case 'double': 234 | return (double)$meta->strData; 235 | case 'boolean': 236 | return strtolower($meta->strData) === 'true'; 237 | case 'DateTime': 238 | return new \DateTime($meta->strData, new \DateTimeZone('UTC')); 239 | case 'string': 240 | default: 241 | return $meta->strData; 242 | } 243 | } 244 | } 245 | -------------------------------------------------------------------------------- /src/Services/EmailService.php: -------------------------------------------------------------------------------- 1 | 'None', 28 | 'auto' => 'Auto', 29 | 'manual' => 'Manual', 30 | 'timetravel' => 'TimeTravel', 31 | 'timeoptimized' => 'TimeOptimized', 32 | ]; 33 | 34 | /** 35 | * 36 | * @var array 37 | */ 38 | private $states = [ 39 | 'PauseMessage', 40 | 'ResumeMessage' 41 | ]; 42 | 43 | /** 44 | * 数组是否存在非整型元素 45 | * 46 | * @author huangnie 47 | * @email 980484578@qq.com 48 | * @date 2019-11-25 49 | * 50 | * @param array $arr [description] 51 | * @return [type] [description] 52 | */ 53 | private function notWholeIntegerArray(array $arr) 54 | { 55 | if (count($arr) == 0) { 56 | return false; 57 | } 58 | return preg_match('/[^\d]/', implode('', array_map('intval', $arr))); 59 | } 60 | 61 | /** 62 | * 创建和发送邮件 63 | * 附件等信息,暂无需处理,需有需要变更,需参考文档进行特殊转化 64 | * @author huangnie 65 | * @email 980484578@qq.com 66 | * @date 2019-11-22 67 | * 68 | * @param array $recieves 目标收件人参数[列表或明细或测试对象或禁止] 69 | * @param string $fromName 发送方名称 70 | * @param string $fromEmail 发送方邮箱 71 | * @param string $subject 主题 72 | * @param string $html 内容 73 | * @param string $tags 标签 74 | * @param string $header 页眉 75 | * @param string $footer 页脚 76 | * @param string $throttlingMethod 发送控制方式, 默认立即发送 77 | * 78 | * @return integer 79 | */ 80 | public function create(array $recieves, string $fromName, string $fromEmail, string $subject, string $html, $tags='', int $header=0, int $footer=0, $throttlingMethod='') 81 | { 82 | $subscriberListIds = array_unique(array_filter(array_get($recieves,'subscriberListIds', []))); 83 | $subscriberSegmentIds = array_unique(array_filter(array_get($recieves,'subscriberSegmentIds', []))); 84 | $suppressionListIds = array_unique(array_filter(array_get($recieves,'suppressionListIds',[]))); 85 | $seedListIds = array_unique(array_filter(array_get($recieves,'seedListIds', []))); 86 | 87 | // 收件列表,收件明细,测试列表三者不可同时为空 88 | if ($this->notWholeIntegerArray($subscriberListIds) || $this->notWholeIntegerArray($subscriberSegmentIds) || $this->notWholeIntegerArray($seedListIds)) { 89 | throw new \Exception("email::create param:recieves.subscriberList, recieves.subscriberSegmentIds, recieves.seedListIds all empty or some one not integer array"); 90 | } 91 | else if (!$fromName) { 92 | throw new \Exception("email::create param:fromName must not be empty"); 93 | } 94 | else if (strpos($fromEmail, '@') === false) { 95 | throw new \Exception("email::create param:fromEmail={$fromEmail} is wrong"); 96 | } 97 | else if (!$subject) { 98 | throw new \Exception("email::create param:subject must not be empty"); 99 | } 100 | else if (!$html) { 101 | throw new \Exception("email::create param:html must not be empty"); 102 | } 103 | 104 | // 邮件内容 105 | $content = new ExpertSender\Entity\ContentType(); 106 | $content->fromName = $fromName; 107 | $content->fromEmail = $fromEmail; 108 | $content->subject = $subject; 109 | $content->html = $html; 110 | if ($tags > 0) { 111 | $content->tags = $tags; 112 | } 113 | if ($header > 0) { 114 | $content->header = $header; 115 | } 116 | if ($footer > 0) { 117 | $content->footer = $footer; 118 | } 119 | 120 | // 接收列表 121 | $recipients = new ExpertSender\Entity\RecipientsType(); 122 | if (count($subscriberListIds) > 0) { 123 | $recipients->subscriberLists = $subscriberListIds; 124 | } 125 | if (count($subscriberSegmentIds) > 0) { 126 | $recipients->subscriberSegments = $subscriberSegmentIds; 127 | } 128 | if (count($suppressionListIds) > 0) { 129 | $recipients->suppressionLists = $suppressionListIds; 130 | } 131 | if (count($seedListIds) > 0) { 132 | $recipients->seedLists = $seedListIds; 133 | } 134 | 135 | $newsletterType = new ExpertSender\Entity\NewsletterType(); 136 | $newsletterType->content = $content; 137 | $newsletterType->recipients = $recipients; 138 | 139 | // 寄件配置,默认立即发送 140 | if ($throttlingMethod) { 141 | $throttlingMethodkey = ucfirst(strtolower($throttlingMethod)); 142 | if (!array_key_exists($throttlingMethodkey, $this->throttling_method_supports)) { 143 | throw new \Exception("email::create throttlingMethod={$throttlingMethod} must be of [" . implode(' , ', $this->throttling_method_supports) . "]"); 144 | } 145 | 146 | $deliverySettings = new ExpertSender\Entity\DeliverySettingsType(); 147 | $deliverySettings->throttlingMethod = $this->throttling_method_supports[$throttlingMethodkey]; 148 | 149 | $newsletterType->deliverySettings = $deliverySettings; 150 | } 151 | 152 | // Initialize request with Data wrapper with entity 153 | $request = new ExpertSender\Request\Post\Newsletters( $newsletterType); 154 | 155 | // Making a request call 156 | $response = $this->service->call( $request ); 157 | 158 | return $response->getResponseEntity(); 159 | } 160 | 161 | /** 162 | * 查询单条发件记录 163 | * 164 | * @author huangnie 165 | * @email 980484578@qq.com 166 | * @date 2019-11-25 167 | * @param string $listName 168 | * @param string $friendlyName 169 | * @param string $description 170 | * @return integer 171 | */ 172 | public function getInfo($newsletterId) 173 | { 174 | // Initialize request with Data wrapper with entity 175 | $request = new ExpertSender\Request\Get\MessageInfo( $newsletterId ); 176 | 177 | // Making a request call 178 | $response = $this->service->call( $request ); 179 | 180 | // id integer 唯一ID 181 | // from_name string 发送方名称 182 | // from_email string 发送方邮箱 183 | // subject string 主题 184 | // status string 状态 185 | // sent_data DateTime 发送时间 186 | // lists array[[id=>0, name=>'']] 收件列表 187 | // tags string 标签 188 | return $response->getResponseEntity()->useUnderlineFieldName(true)->toArray(); 189 | } 190 | 191 | /** 192 | * 查询多条发件记录 193 | * 194 | * @author huangnie 195 | * @email 980484578@qq.com 196 | * @date 2019-11-25 197 | * 198 | * @param string|null $tag 199 | * @param \DateTime|null $startDate 200 | * @param \DateTime|null $endDate 201 | * @return array 202 | */ 203 | public function getList(string $tag=null, \DateTime $startDate=null, \DateTime $endDate=null) 204 | { 205 | // Initialize request with Data wrapper with entity 206 | $request = new ExpertSender\Request\Get\MessageList('Newsletter', $tag, $startDate, $endDate); 207 | 208 | // Making a request call 209 | $response = $this->service->call( $request ); 210 | 211 | $result = $response->getResponseEntity()->useUnderlineFieldName(true)->toArray(); 212 | 213 | $messages = array_get($result, 'messages', []); 214 | 215 | if (count($messages) > 0) { 216 | // id integer 唯一ID 217 | // from_name string 发送方名称 218 | // from_email string 发送方邮箱 219 | // subject string 主题 220 | // status string 状态 221 | // sent_data DateTime 发送时间 222 | // lists array[[id=>0, name=>'']] 收件列表 223 | // tags string 标签 224 | $messages = array_combine(array_column($messages, 'id'), $messages); 225 | 226 | ksort($messages); 227 | 228 | return $messages; 229 | } else { 230 | return []; 231 | } 232 | } 233 | 234 | /** 235 | * 查询收件投递状态 236 | * 237 | * @author huangnie 238 | * @email 980484578@qq.com 239 | * @date 2019-11-22 240 | * @param string $listName 241 | * @param string $friendlyName 242 | * @param string $description 243 | * @return integer 244 | */ 245 | public function getProgress($newsletterId) 246 | { 247 | // Initialize request with Data wrapper with entity 248 | $request = new ExpertSender\Request\Get\MessageStatistics( $newsletterId ); 249 | 250 | // Making a request call 251 | $response = $this->service->call( $request ); 252 | 253 | // sent 已发送邮件数目 254 | // bounced 退信邮件数目 255 | // delivered 已送达邮件数目 (已发送减去信)' 256 | // opens 已打开邮件数目. 257 | // unique_opens 打开邮件的收件人数目. 258 | // clicks 链接点击数目. 259 | // unique_clicks 各个链接被不同收件人第一次点击的总次数. 260 | // clickers 点击链接的收件人数目. 261 | // complaints 垃圾邮件投诉数目. 262 | // unsubscribes 退订链接点击数目. 263 | return $response->getResponseEntity()->useUnderlineFieldName(true)->toArray(); 264 | } 265 | 266 | /** 267 | * 暂停Newsletter 268 | * 269 | * @author huangnie 270 | * @email 980484578@qq.com 271 | * @date 2019-11-22 272 | * @param string $listName 273 | * @param string $friendlyName 274 | * @param string $description 275 | * @return integer 276 | */ 277 | public function pause($newsletterId) 278 | { 279 | return $this->pauseOrResume($newsletterId, 'PauseMessage'); 280 | } 281 | 282 | /** 283 | * 继续Newsletter 284 | * 285 | * @author huangnie 286 | * @email 980484578@qq.com 287 | * @date 2019-11-22 288 | * @param string $listName 289 | * @param string $friendlyName 290 | * @param string $description 291 | * @return integer 292 | */ 293 | public function resume($newsletterId) 294 | { 295 | return $this->pauseOrResume($newsletterId, 'ResumeMessage'); 296 | } 297 | 298 | /** 299 | * 暂停和继续Newsletter 300 | * 301 | * @author huangnie 302 | * @email 980484578@qq.com 303 | * @date 2019-11-22 304 | * @param string $listName 305 | * @param string $friendlyName 306 | * @param string $description 307 | * @return integer 308 | */ 309 | private function pauseOrResume($newsletterId, $action) 310 | { 311 | if (!in_array($action, $this->states)) { 312 | throw new \Exception("email::pauseOrResume action={$action} must be of [" . implode(' , ', $this->states) . "]"); 313 | } 314 | 315 | $actionType = new ExpertSender\Entity\ActionType($action); 316 | 317 | // Initialize request with Data wrapper with entity 318 | $request = new ExpertSender\Request\Put\Newsletters( $newsletterId, $actionType ); 319 | 320 | // Making a request call 321 | $response = $this->service->call( $request ); 322 | 323 | return $response->getResponseEntity(); 324 | } 325 | 326 | } -------------------------------------------------------------------------------- /src/Services/SubscriberService.php: -------------------------------------------------------------------------------- 1 | service->call($request); 30 | 31 | return $response->getResponseEntity(); 32 | } 33 | 34 | /** 35 | * 导出明细 36 | * @author huangnie 37 | * @email 980484578@qq.com 38 | * @date 2019-08-22 39 | * @param integer $importId 40 | * @return mixed 41 | */ 42 | public function exportSegment($segmentId, array $properties=[]) 43 | { 44 | $listExportType = new ExpertSender\Entity\ListExportType(); 45 | $listExportType->type = 'Segment'; 46 | $listExportType->segmentId = intval($segmentId); 47 | $listExportType->fields = [ 48 | 'Id', // 明细ID 49 | 'Name', // 明细名称 50 | ]; 51 | 52 | $properties = array_unique(array_filter($properties)); 53 | if (count($properties) > 0) { 54 | $listExportType->properties = $properties; 55 | } 56 | 57 | $request = new ExpertSender\Request\Post\ListExport( $listExportType ); 58 | 59 | // Making a request call 60 | $response = $this->service->call($request); 61 | 62 | return $response->getResponseEntity(); 63 | } 64 | 65 | /** 66 | * 导出列表 67 | * @author huangnie 68 | * @email 980484578@qq.com 69 | * @date 2019-08-22 70 | * @param integer $importId 71 | * @return mixed 72 | */ 73 | public function exportList($listId) 74 | { 75 | $listExportType = new ExpertSender\Entity\ListExportType(); 76 | $listExportType->type = 'List'; 77 | $listExportType->listId = intval($listId); 78 | $listExportType->fields = [ 79 | 'Email', // 收件人email 80 | 'FirstName', // 收件人名字 81 | 'LastName', // 收件人姓氏 82 | 'Vendor', // 收件人来源 83 | 'TrackingCode', // 收件人加入列表中时追踪代码 84 | 'GeoCountry', // 收件人上次动作/行为 IP地址所对应的国家 85 | 'GeoState', // 收件人上次动作/行为 IP地址所对应的省市自治区 86 | 'GeoCity', // 收件人上次动作/行为 IP地址所对应的城市 87 | 'GeoZipCode', // 收件人上次动作/行为 IP地址所对应的邮编 88 | 'LastActivity', // 收件人上次动作/行为 发生的时间 (点击, 打开, 进入个人中心等等) 89 | 'LastMessage', // 上次发送给收件人消息的时间 90 | 'LastEmail', // 上次发送给收件人消息的日期 91 | 'LastOpenEmail', // 收件人上次打开邮件的时间 92 | 'LastClickEmail', // 收件人上次点击邮件某一链接 93 | 'SubscriptionDate', // 收件人被添加至列表的日期(如果导出的类型是收件人细分,那么此处就是收件人被加入后台数据库的时间). 94 | ]; 95 | 96 | $request = new ExpertSender\Request\Post\ListExport( $listExportType ); 97 | 98 | // Making a request call 99 | $response = $this->service->call($request); 100 | 101 | return $response->getResponseEntity(); 102 | } 103 | 104 | /** 105 | * 导入收件列表进度 106 | * @author huangnie 107 | * @email 980484578@qq.com 108 | * @date 2019-08-22 109 | * @param integer $importId 110 | * @return mixed 111 | */ 112 | public function importListProgress($importId) 113 | { 114 | // 查询导入进度 115 | $request = new ExpertSender\Request\Get\ListImportProgress($importId); 116 | 117 | // Making a request call 118 | $response = $this->service->call($request); 119 | 120 | return $response->getResponseEntity(); 121 | } 122 | 123 | /** 124 | * 导入列表到新列 125 | * @author huangnie 126 | * @email 980484578@qq.com 127 | * @date 2019-08-20 128 | * @param string $downloadUrl 129 | * @param string $targetListId 130 | * @param string $targetListName 131 | * @return mixed 132 | */ 133 | public function importList($downloadUrl, $targetListId, $targetListName) 134 | { 135 | $listSource = new ExpertSender\Entity\ListImportSourceType(); 136 | $listSource->url = $downloadUrl; 137 | 138 | $listTarget = new ExpertSender\Entity\ListImportTargetType(); 139 | $listTarget->name = $targetListName; 140 | $listTarget->subscriberList = $targetListId; 141 | 142 | $listImportType = new ExpertSender\Entity\ListImportType(); 143 | $listImportType->source = $listSource; 144 | $listImportType->target = $listTarget; 145 | 146 | // Initialize request with Data wrapper with entity 147 | $request = new ExpertSender\Request\Post\ListImport( $listImportType ); 148 | 149 | // Making a request call 150 | $response = $this->service->call($request); 151 | 152 | return $response->getResponseEntity(); 153 | } 154 | 155 | /** 156 | * 收件人信息实体 157 | * @author huangnie 158 | * @email 980484578@qq.com 159 | * @date 2019-08-20 160 | * @param integer $listId 161 | * @param string $email 162 | * @param array $option 163 | * @return mixed 164 | */ 165 | public function buildSubscriberEntity($listId, $email, array $option=[]) 166 | { 167 | // Create entity with it fields 168 | // If want set phone, the SMS channel has to be activated to use element'Phone' 169 | $entity = new ExpertSender\Entity\SubscriberType(); 170 | $entity->listId = $listId; 171 | $entity->email = $email; 172 | $entity->force = true; 173 | $entity->mode = ExpertSender\Enum\SubscribersMode::ADD_AND_UPDATE; 174 | 175 | // name can include space 176 | if (isset($option['lastname']) && $option['lastname']) { 177 | $entity->lastname = $option['lastname']; 178 | } 179 | 180 | if (isset($option['firstname']) && $option['firstname']) { 181 | $entity->firstname = $option['firstname']; 182 | } 183 | 184 | if ($entity->lastname && $entity->firstname) { 185 | $entity->name = "{$entity->firstname} {$entity->lastname}"; 186 | } 187 | 188 | if (isset($option['trackingCode']) && $option['trackingCode']) { 189 | $entity->trackingCode = $option['trackingCode']; 190 | } 191 | 192 | if (isset($option['vendor']) && $option['vendor']) { 193 | $entity->vendor = $option['vendor']; 194 | } 195 | 196 | return $entity; 197 | } 198 | 199 | /** 200 | * 添加一个收件人 201 | * @author huangnie 202 | * @email 980484578@qq.com 203 | * @date 2019-11-22 204 | * 205 | * @param string $identifier 收件人ID 或 收件人email 206 | * @param integer $listId 207 | * @return mixed 208 | */ 209 | public function deleteOneSubscriber($identifier, $listId=0) 210 | { 211 | if (!$identifier) { 212 | throw new \Exception("param error: identifier must not be empty", 400); 213 | } 214 | 215 | // Initialize request with Data wrapper with entity 216 | $request = new ExpertSender\Request\Delete\Subscribers( $identifier, $listId ); 217 | 218 | // Making a request call 219 | $response = $this->service->call($request); 220 | 221 | return true; 222 | } 223 | 224 | /** 225 | * 添加一个收件人 226 | * @author huangnie 227 | * @email 980484578@qq.com 228 | * @date 2019-08-20 229 | * @param integer $listId 230 | * @param string $email 231 | * @param array $option 232 | * @return mixed 233 | */ 234 | public function addOneSubscriber($listId, $email, array $option) 235 | { 236 | if (!$listId || !$email) { 237 | throw new \Exception("param error: listId or email is none", 400); 238 | } 239 | 240 | $subscriberEntity = $this->buildSubscriberEntity($listId, $email, $option); 241 | 242 | // Initialize request with Data wrapper with entity 243 | $request = new ExpertSender\Request\Post\Subscribers( $subscriberEntity ); 244 | 245 | // Making a request call 246 | $response = $this->service->call($request); 247 | 248 | return true; 249 | } 250 | 251 | /** 252 | * 添加多个个收件人 253 | * @author huangnie 254 | * @email 980484578@qq.com 255 | * @date 2019-08-20 256 | * @param array $subscriberArr 257 | * @return mixed 258 | */ 259 | public function addMultiSubscribers(array $subscriberArr) 260 | { 261 | $subscriberMultiData = new ExpertSender\Entity\SubscriberMultiDataType(); 262 | $subscriberMultiData->subscribers = $subscriberArr; 263 | 264 | // Initialize request with Data wrapper with entity 265 | $request = new ExpertSender\Request\Post\Subscribers( $subscriberMultiData ); 266 | 267 | // Making a request call 268 | $response = $this->service->call($request); 269 | 270 | return true; 271 | } 272 | 273 | /** 274 | * 新建收件列表 275 | * @author huangnie 276 | * @email 980484578@qq.com 277 | * @date 2019-08-20 278 | * @param string $listName 279 | * @param string $friendlyName 280 | * @param string $description 281 | * @return integer 282 | */ 283 | public function createList($listName, $friendlyName='', $description='') 284 | { 285 | $listSetting = new ExpertSender\Entity\ListSettingsType(); 286 | $generalSetting = new ExpertSender\Entity\GeneralSettingsType(); 287 | $generalSetting->name = $listName; 288 | $generalSetting->friendlyName = $friendlyName; 289 | $generalSetting->description = $description; 290 | $generalSetting->language = 'en-US'; 291 | $generalSetting->charset = 'UTF-8'; 292 | $generalSetting->defaultFromName = ''; 293 | $generalSetting->defaultFromEmail = ''; 294 | 295 | $listSetting->generalSettings = $generalSetting; 296 | 297 | $request = new ExpertSender\Request\Post\Lists( $listSetting ); 298 | 299 | // Making a request call 300 | $response = $this->service->call($request); 301 | 302 | return $response->getResponseEntity(); 303 | } 304 | 305 | /** 306 | * 新建收件列表 307 | * @author huangnie 308 | * @email 980484578@qq.com 309 | * @date 2019-08-20 310 | * @param integer $listId 311 | * @param string $listName 312 | * @param string $friendlyName 313 | * @param string $description 314 | * @return integer 315 | */ 316 | public function updateList($listId, $listName, $friendlyName='', $description='') 317 | { 318 | $listSetting = new ExpertSender\Entity\ListSettingsType(); 319 | $generalSetting = new ExpertSender\Entity\GeneralSettingsType(); 320 | $generalSetting->name = $listName; 321 | $generalSetting->friendlyName = $friendlyName; 322 | $generalSetting->description = $description; 323 | $generalSetting->language = 'en-US'; 324 | $generalSetting->charset = 'UTF-8'; 325 | 326 | $listSetting->generalSettings = $generalSetting; 327 | 328 | $request = new ExpertSender\Request\Put\Lists( $listId, $listSetting ); 329 | 330 | // Making a request call 331 | $response = $this->service->call($request); 332 | 333 | return $response->getResponseEntity(); 334 | } 335 | 336 | /** 337 | * 获取收件列表 338 | * @author huangnie 339 | * @email 980484578@qq.com 340 | * @date 2019-08-20 341 | * @return array 342 | */ 343 | public function getList() 344 | { 345 | $request = new ExpertSender\Request\Get\Lists(); 346 | 347 | // Making a request call 348 | $response = $this->service->call($request); 349 | 350 | if (!$response->isOk()) { 351 | $entity = $response->getResponseEntity(); 352 | $error = is_object($entity) ? get_object_vars($entity) : $entity; 353 | throw new \Exception("Subscriber:getList error: {$error}", $response->getCode()); 354 | } 355 | 356 | return $response->getResponseEntity(); 357 | } 358 | 359 | /** 360 | * 获取明细列表 361 | * @author huangnie 362 | * @email 980484578@qq.com 363 | * @date 2019-09-03 364 | * @return array 365 | */ 366 | public function getSegment() 367 | { 368 | $request = new ExpertSender\Request\Get\Segments(); 369 | 370 | // Making a request call 371 | $response = $this->service->call($request); 372 | 373 | return $response->getResponseEntity(); 374 | } 375 | } -------------------------------------------------------------------------------- /src/ExpertSender/BaseType.php: -------------------------------------------------------------------------------- 1 | 15 | *
  • (string) type - тип значения свойства. Может содержать скалярные типы или имя класса
  • 16 | *
  • (string) xmlName - имя тега, которое будет исопльзовано при сериализации объекта в xml
  • 17 | *
  • (boolean) attribute - флаг, является ли данное свойство атрибутом для данной сущности
  • 18 | *
  • (string) attributeName - имя атрибута, которое будет использовано при сериализации объекта в xml
  • 19 | *
  • (boolean) unbound - этот флаг ставится для того свойства, которое должно быть множественным. В этом 20 | * случае создается экземпляр класса, который реализовывает итератор и доступ к массиву, а значение свойства задается 21 | * с помощью массива
  • 22 | *
  • (string) unboundTag - название тега для множественных свойств класса
  • 23 | * 24 | */ 25 | protected $params = array(); 26 | 27 | /** 28 | * @var array Хранилище ключ => значение, в котором хранятся значения всех свойств класса 29 | */ 30 | protected $values = array(); 31 | 32 | /** 33 | * 在 xml 中的节点位置 34 | * auto 由属性定义自动关联 35 | * root 仅次于root 36 | * 37 | * @var string 38 | */ 39 | protected $position = 'auto'; 40 | 41 | /** 42 | * @var string|null Строковое имя типа сущности, используется не во всех сущностях 43 | */ 44 | protected $xsiType = null; 45 | 46 | /** 47 | * 调用 toArray 方法时, 是否将接口的大陀封命名, 转换为下划线连接的全小写命名 48 | * 49 | * @var boolean 50 | */ 51 | private $array_use_underline_field_name = false; 52 | 53 | 54 | /** 55 | * Все свойства наследников определены в поле @params, а их значения в поле @values. Для доступа к свойствам используем 56 | * магическую функцию, чтобы динамически проверять значение, существование свойства, а также определять кастомную 57 | * логику для установки значения 58 | * 59 | * @param $name 60 | * @param $value 61 | */ 62 | function __set($name, $value) 63 | { 64 | self::checkPropertyExists($name); 65 | self::checkPropertyType($name, $value); 66 | 67 | $propInfo = $this->getPropertyInfo($name); 68 | if ($propInfo['unbound'] === false) { 69 | $this->values[ $name ] = $value; 70 | } elseif ($propInfo['unbound'] === true && !($value instanceof Unbound)) { 71 | $this->values[ $name ] = new Unbound($name, $propInfo[ 'type' ]); 72 | foreach ($value as $item) { 73 | $this->values[ $name ][ ] = $item; 74 | } 75 | } else { 76 | $this->values[ $name ] = $value; 77 | } 78 | 79 | } 80 | 81 | /** 82 | * Геттер, который получает значения свойства по их имени 83 | * 84 | * @param $name 85 | * @return null 86 | */ 87 | function __get($name) 88 | { 89 | $propInfo = $this->getPropertyInfo($name); 90 | if ($propInfo[ 'unbound' ] === true && !array_key_exists($name, $this->values)) { 91 | $this->values[ $name ] = new Unbound($name, $propInfo[ 'type' ]); 92 | } 93 | 94 | return array_key_exists($name, $this->values) ? $this->values[ $name ] : null; 95 | } 96 | 97 | /** 98 | * Проверка существования свойства 99 | * @param $name 100 | * @return bool 101 | */ 102 | function __isset($name) 103 | { 104 | return array_key_exists($name, $this->values); 105 | } 106 | 107 | /** 108 | * Вспомогательная функция, которая проверяет тип свойства и в случае ошибки выбрасывает исключение 109 | * @param string $name Имя свойства 110 | * @param mixed $value Значение свойства 111 | * @throws \InvalidArgumentException 112 | */ 113 | private function checkPropertyType($name, $value) 114 | { 115 | $propInfo = $this->getPropertyInfo($name); 116 | if ($propInfo[ 'type' ] === 'mixed') { 117 | return false; 118 | } 119 | 120 | $actualType = $this->getActualType($value); 121 | 122 | $class = get_called_class(); 123 | if ( 124 | $propInfo[ 'unbound' ] === false 125 | && $actualType !== $propInfo[ 'type' ] 126 | && !is_a($value, $propInfo['type']) 127 | ) { 128 | throw new \InvalidArgumentException("Incorrect type '{$actualType}' for attribute '{$name}' in '{$class}'. '{$propInfo['type']}' expected"); 129 | } 130 | elseif ( 131 | $propInfo[ 'unbound' ] === true 132 | && ($actualType !== 'array' && !($value instanceof Unbound)) 133 | ) { 134 | throw new \InvalidArgumentException("Incorrect type '{$actualType}' for attribute '{$name}' in '{$class}'. Array of '{$propInfo['type']}' expected"); 135 | } 136 | } 137 | 138 | /** 139 | * Вспомогательная функция, которая проверяет наличие свойства в перечне допустимых, и в случае ошибки выбрасывает 140 | * исключение 141 | * 142 | * @param $name 143 | * @throws \InvalidArgumentException 144 | */ 145 | private function checkPropertyExists($name) 146 | { 147 | $propInfo = $this->getPropertyInfo($name); 148 | if (!$propInfo) { 149 | $class = get_called_class(); 150 | throw new \InvalidArgumentException("Unexpected attribute '{$name}' in class {$class}. This attribute is not implemented, params:". json_encode($this->params)); 151 | } 152 | } 153 | 154 | /** 155 | * Вспомогательная функция, которая получает информацию о свойстве 156 | * 157 | * @param $name 158 | * @return mixed 159 | */ 160 | private function getPropertyInfo($name) 161 | { 162 | $propInfo = $this->params[ $name ]; 163 | if (!isset( $propInfo[ 'unbound' ] ) || !is_bool($propInfo[ 'unbound' ])) { 164 | $propInfo[ 'unbound' ] = false; 165 | $propInfo[ 'unboundTag' ] = null; 166 | } 167 | 168 | if (!isset( $propInfo['cdata']) || !is_bool($propInfo['cdata'])) { 169 | $propInfo['cdata'] = false; 170 | } else { 171 | $propInfo['cdata'] = true; 172 | } 173 | 174 | if (!isset( $propInfo[ 'attribute' ] ) || !is_bool($propInfo[ 'attribute' ])) { 175 | $propInfo[ 'attribute' ] = false; 176 | } 177 | 178 | return $propInfo; 179 | } 180 | 181 | /** 182 | * Вспомогательная функция, которая получает реальный тип переменной. Если в качестве аргумента передан экземпляр 183 | * класса, то вернется имя класса 184 | * @param mixed $value 185 | * @return string 186 | */ 187 | protected function getActualType($value) 188 | { 189 | $actualType = gettype($value); 190 | if ($actualType == 'object') { 191 | $actualType = get_class($value); 192 | } 193 | 194 | return $actualType; 195 | } 196 | 197 | /** 198 | * 数据结构-节点位置 199 | * 200 | * @return string 201 | */ 202 | public function getPosition() 203 | { 204 | return $this->position; 205 | } 206 | 207 | /** 208 | * Функция сериализации объекта в xml 209 | * @return string 210 | */ 211 | public function toXml() 212 | { 213 | $xml = ''; 214 | 215 | foreach (array_keys($this->params) as $name) { 216 | $propInfo = $this->getPropertyInfo($name); 217 | if (isset($this->{$name}) && $propInfo['attribute'] !== true) { 218 | $propertyValue = $this->{$name}; 219 | if ($propInfo['unbound'] === true) { 220 | $xml .= "<{$propInfo['unboundTag']}>"; 221 | foreach ($propertyValue as $value) { 222 | if ($propInfo['xmlName']) { 223 | $xml .= "<{$propInfo['xmlName']}{$this->attributesToXml()}>"; 224 | if (gettype($value) == 'object') { 225 | $xml .= $value->toXml(); 226 | } else { 227 | $xml .= $value; 228 | } 229 | $xml .= ""; 230 | } else { 231 | $xml .= $value->toXml(); 232 | } 233 | } 234 | $xml .= ""; 235 | } elseif(!is_scalar($propertyValue)) { 236 | if ($propInfo['xmlName']) { 237 | $xml .= "<{$propInfo['xmlName']}{$this->attributesToXml()}>{$propertyValue->toXml()}"; 238 | } else { 239 | $xml .= $propertyValue->toXml(); 240 | } 241 | } else { 242 | $cdata = isset($propInfo['cdata']) && $propInfo['cdata'] === true; 243 | if ($propInfo['xmlName']) { 244 | $tag = $propInfo['xmlName']; 245 | $xml .= "<{$tag}{$this->attributesToXml()}>"; 246 | if ($cdata) $xml .= 'encodeXmlValue($propertyValue)}"; 248 | if ($cdata) $xml .= ']]>'; 249 | $xml .= ""; 250 | } else { 251 | if ($cdata) $xml .= 'encodeXmlValue($propertyValue); 253 | if ($cdata) $xml .= ']]>'; 254 | } 255 | } 256 | } 257 | } 258 | 259 | return $xml; 260 | } 261 | 262 | /** 263 | * 解析后的对象属性转为数组格式 264 | * 265 | * @return array 266 | */ 267 | public function toArray($use_underline_field_name=false) 268 | { 269 | $arr = []; 270 | 271 | if($use_underline_field_name) { 272 | $this->array_use_underline_field_name = $use_underline_field_name; 273 | } else { 274 | $use_underline_field_name = $this->array_use_underline_field_name; 275 | } 276 | 277 | foreach (array_keys($this->params) as $name) { 278 | $value = array_get($this->values, $name, null); 279 | if (gettype($value) == 'object') { 280 | if (method_exists($value, 'toArray')) { 281 | $value = $value->toArray(); 282 | } else if (substr(get_class($value), -7) == 'Unbound') { 283 | $subArr = []; 284 | foreach ($value as $item) { 285 | if (gettype($item) == 'object' && method_exists($item, 'toArray')) { 286 | $subArr[] = $item->toArray($this->array_use_underline_field_name); 287 | } else { 288 | $subArr[] = $item; 289 | } 290 | } 291 | $value = $subArr; 292 | } 293 | } 294 | 295 | $propInfo = $this->getPropertyInfo($name); 296 | if (isset($propInfo[ 'type' ])) { 297 | switch ($propInfo[ 'type' ]) { 298 | case 'DateTime': 299 | /** @var \DateTime $val */ 300 | $value = $value instanceof \DateTime ? $value->format('Y-m-d H:i:s') : string($value); 301 | break; 302 | case 'integer': 303 | $value = intval($value); 304 | break; 305 | case 'boolean': 306 | $value = boolval($value); 307 | break; 308 | case 'string': 309 | $value = strval($value); 310 | break; 311 | default: 312 | if (!$value && isset($propInfo[ 'unbound' ]) && $propInfo[ 'unbound' ] === true) { 313 | $value = []; 314 | } 315 | break; 316 | } 317 | } 318 | 319 | if ($this->array_use_underline_field_name) { 320 | $name = preg_replace_callback('/[A-Z]+/', function ($val) { return '_' . strtolower($val[0]); }, $name); 321 | $name = preg_replace('/^_+/', '', strtolower($name)); 322 | } 323 | 324 | $arr[$name] = $value; 325 | } 326 | 327 | return $arr; 328 | } 329 | 330 | /** 331 | * 转为下划线连接(大写字母转下划线和小写字母)命名 332 | * 333 | * @param string $name 334 | * @return string 335 | */ 336 | public function useUnderlineFieldName($use_underline_field_name=true) 337 | { 338 | $this->array_use_underline_field_name = $use_underline_field_name; 339 | 340 | return $this; 341 | } 342 | 343 | /** 344 | * Вспомогательная функция для преобразования атрибутов в xml 345 | * @return string 346 | */ 347 | private function attributesToXml() 348 | { 349 | $arr = []; 350 | foreach (array_keys($this->params) as $name) { 351 | $propInfo = $this->getPropertyInfo($name); 352 | if ($propInfo['attribute'] !== true) { 353 | continue; 354 | } 355 | if (!isset($this->{$name})) { 356 | continue; 357 | } 358 | 359 | $arr[] = implode('', [$propInfo['attributeName'], '="', $this->{$name}, '"']); 360 | } 361 | return implode(' ', $arr); 362 | } 363 | 364 | /** 365 | * Вспомогательная функция, которая кодирует значение переменной в xml 366 | * @param $val 367 | * @return string 368 | */ 369 | private function encodeXmlValue($val) 370 | { 371 | $type = $this->getActualType($val); 372 | switch ($type) { 373 | case 'DateTime': 374 | /** @var \DateTime $val */ 375 | $val = $val->format('Y-m-dTH:i:s'); 376 | break; 377 | case 'integer': 378 | case 'double': 379 | $val = (string)$val; 380 | break; 381 | case 'boolean': 382 | $val = $val === true ? 'true' : 'false'; 383 | break; 384 | case 'string': 385 | default: 386 | break; 387 | } 388 | 389 | return $val; 390 | } 391 | 392 | /** 393 | * Геттер для получения типа сущности 394 | * @return null|string 395 | */ 396 | public function getXsiType() 397 | { 398 | return $this->xsiType; 399 | } 400 | 401 | /** 402 | * Получает мета-данные для элемента сущности 403 | * 404 | * Этот метод используется при десериализации XML в объект в тот момент, когда парсится имя свойства 405 | * 406 | * @param string $elementName Имя XML элемента, для которого нужно получить мета данные 407 | * @return mixed Мета-данные о свойтсве или null 408 | */ 409 | public function elementMeta($elementName) 410 | { 411 | if (array_key_exists($elementName, $this->params)) { 412 | $info = $this->getPropertyInfo($elementName); 413 | $isAttribute = $info['attribute'] === true; 414 | 415 | $nameKey = $isAttribute ? 'attributeName' : 'xmlName'; 416 | 417 | if (array_key_exists($nameKey, $info)) { 418 | if ($info[$nameKey] === $elementName) { 419 | $meta = new \StdClass(); 420 | $meta->propertyName = $elementName; 421 | $meta->phpType = $info['type']; 422 | $meta->unbound = $info['unbound']; 423 | $meta->unboundTag = $info['unboundTag']; 424 | $meta->attribute = $info['attribute']; 425 | $meta->elementName = $info[$nameKey]; 426 | $meta->strData = ''; 427 | 428 | return $meta; 429 | } 430 | } 431 | } 432 | 433 | return null; 434 | } 435 | } --------------------------------------------------------------------------------