├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── composer.json ├── mkdocs.yml ├── phpspec.yml ├── spec ├── Client │ └── MailjetClientSpec.php ├── Command │ ├── EventCommandSpec.php │ ├── SyncContactMetadataCommandSpec.php │ └── SyncUserCommandSpec.php ├── Controller │ └── EventControllerSpec.php ├── DataCollector │ └── MailjetDataCollectorSpec.php ├── Event │ ├── CallbackEventSpec.php │ └── ContactEventSpec.php ├── Listener │ └── ContactListenerSpec.php ├── Manager │ ├── CampaignDraftManagerSpec.php │ ├── CampaignManagerSpec.php │ ├── ContactMetadataManagerSpec.php │ ├── ContactsListManagerSpec.php │ ├── EventCallbackUrlManagerSpec.php │ └── TemplateManagerSpec.php ├── Model │ ├── CampaignDraftSpec.php │ ├── CampaignSpec.php │ ├── ContactMetadataSpec.php │ ├── ContactSpec.php │ ├── ContactsListSpec.php │ ├── EventCallbackUrlSpec.php │ └── TemplateSpec.php └── Synchronizer │ └── ContactsListSynchronizerSpec.php └── src ├── Client └── MailjetClient.php ├── Command ├── EventCommand.php ├── SyncContactMetadataCommand.php └── SyncUserCommand.php ├── Controller └── EventController.php ├── DataCollector └── MailjetDataCollector.php ├── DependencyInjection ├── Configuration.php └── MailjetExtension.php ├── Event ├── CallbackEvent.php └── ContactEvent.php ├── Exception └── MailjetException.php ├── Listener └── ContactListener.php ├── MailjetBundle.php ├── Manager ├── CampaignDraftManager.php ├── CampaignManager.php ├── ContactMetadataManager.php ├── ContactsListManager.php ├── EventCallbackUrlManager.php └── TemplateManager.php ├── Model ├── Campaign.php ├── CampaignDraft.php ├── Contact.php ├── ContactMetadata.php ├── ContactsList.php ├── EventCallbackUrl.php └── Template.php ├── Provider ├── ExampleContactProvider.php ├── FosContactProvider.php └── ProviderInterface.php ├── Resources ├── config │ ├── routing.yml │ └── services.yml ├── doc │ ├── CONTRIBUTING.md │ ├── build-documentation.md │ ├── configuration.md │ ├── contact-provider.md │ ├── event-api.md │ ├── img │ │ ├── dataCollector.png │ │ └── sftoolbar.png │ ├── index.md │ ├── mailjet-doc.md │ ├── setup.md │ ├── swiftmailer.md │ ├── symfony-debug-toolbar.md │ ├── tests.md │ └── usage.md └── views │ └── data_collector │ └── mailjet.html.twig └── Synchronizer └── ContactsListSynchronizer.php /.gitignore: -------------------------------------------------------------------------------- 1 | # Cache and logs (Symfony2) 2 | /app/cache/* 3 | /app/logs/* 4 | !app/cache/.gitkeep 5 | !app/logs/.gitkeep 6 | 7 | # Email spool folder 8 | /app/spool/* 9 | 10 | # Cache, session files and logs (Symfony3) 11 | /var/cache/* 12 | /var/logs/* 13 | /var/sessions/* 14 | !var/cache/.gitkeep 15 | !var/logs/.gitkeep 16 | !var/sessions/.gitkeep 17 | 18 | # Parameters 19 | /app/config/parameters.yml 20 | /app/config/parameters.ini 21 | 22 | # Managed by Composer 23 | /app/bootstrap.php.cache 24 | /var/bootstrap.php.cache 25 | /bin/* 26 | !bin/console 27 | !bin/symfony_requirements 28 | /vendor/ 29 | 30 | # Assets and user uploads 31 | /web/bundles/ 32 | /web/uploads/ 33 | 34 | # Assets managed by Bower 35 | /web/assets/vendor/ 36 | 37 | # PHPUnit 38 | /app/phpunit.xml 39 | /phpunit.xml 40 | 41 | # Build data 42 | /build/ 43 | 44 | # Composer PHAR 45 | /composer.phar 46 | composer.lock 47 | 48 | # Backup entities generated with doctrine:generate:entities command 49 | */Entity/*~ 50 | 51 | # mkdocs 52 | /docs 53 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | php: 3 | - 7.1 4 | - 7.2 5 | - 7.3 6 | - 7.4 7 | - 8.0 8 | env: 9 | global: 10 | - SYMFONY_VERSION=4.4 11 | - MIN_PHP=7.1.3 12 | install: 13 | - composer update --prefer-source 14 | script: 15 | - bin/phpspec run -fpretty --verbose 16 | notifications: 17 | slack: 18 | secure: brr1IaTbOCEImnW4T+/G3lZgwmiMK4LnDMGbGKcHSn3j8HYIY4Va2QN70aGlTJZKpBu026hQNFe1nsOr0NMeisKt0zdrG9C9Q+SqW0fvvx+CozX2VpNQhfJVuUc7CXHve1BUBNg8DLqqHeaHEhQw/hUfk4X+cQe/tVWq64ytnNZImm81xXEzcO+oZs7wHOe9FLHXF0Ije1ML971U/Evi5nbfLe36RtMjxUc3IvvuTellEutgxUeH7RKtIVgVg/MEOxQZ9TVbMOoG5XxW4xaIJSypRsBwOSzzaaek3cxdbMQcBKbbTXbLZYB2acoYNmqFe+Y8WzyzWbZkOatPHaJB5b8kE8WilecowYkb1SKhfm+3rG4Bcjv9iu0cJuXw4v17mBTmg/LpTYS34StjUBO8Pb6dKkyBaIf/Ly70wdnCkYIP5ZLdkp3Gpv9pmZm/+sB6KbyNAbM/YJbkDrJLjl9MiFTMzO4ev8ku8nL98I98Hg27UmS+NXdX/Tpe3Tw6H09YPRaEjxLZsQd8o1qEY2j6njsmBk14ws40uQ+IRFocxQ6knBP5xeGF2vi2iBGM+vAgJzqdQA5PW9RUPwUSeORXbQkRUVM3l8IL1DpeteulbY3WaFPzf0KkfQBund2WlsB33YzLu+PLFpKJuCtghHnux5HwNylX+irMeQ1xaZl3l30= 19 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # CONTRIBUTING 2 | 3 | * [Contributing to Open Source guide](https://guides.github.com/activities/contributing-to-open-source/) 4 | 5 | ## Steps 6 | 7 | 1. Create an Issue 8 | 2. Pull Request 9 | 3. Merge \o/ 10 | 11 | ## Contributors 12 | 13 | * Original author: [Titouan BENOIT](https://github.com/Nightbr) 14 | * Mailjet API 15 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Mailjet 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mailjet Bundle 2 | 3 | [![Build Status](https://travis-ci.org/mailjet/mailjetBundle.svg?branch=master)](https://travis-ci.org/mailjet/mailjetBundle) 4 | [![Packagist](https://img.shields.io/packagist/v/mailjet/mailjet-bundle.svg)](https://packagist.org/packages/mailjet/mailjet-bundle) 5 | [![Packagist](https://img.shields.io/packagist/dt/mailjet/mailjet-bundle.svg)](https://packagist.org/packages/mailjet/mailjet-bundle) 6 | [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/mailjet/mailjetBundle/blob/master/LICENSE.md) 7 | [![Documentation](https://img.shields.io/badge/documentation-gh--pages-blue.svg)](https://mailjet.github.io/mailjetBundle/) 8 | 9 | Symfony bundle for handling Mailjet API V3 using this wrapper: 10 | 11 | ## Features 12 | 13 | * [x] Retrieve [\Mailjet\Client](https://github.com/mailjet/mailjet-apiv3-php) to make custom Mailjet API V3 requests 14 | * [x] [SwiftMailer Transport integration](https://github.com/mailjet/MailjetSwiftMailer) 15 | * [x] Synchronize Contact Metadata (Contact Properties) with your config 16 | * [x] Synchronize your user with Mailjet contact list 17 | * [x] Use your own userProvider (basic `FosContactProvider` included to interface with FosUserBundle) 18 | * [x] Use lifecycle event to subscribe/unsubscribe/update/delete/changeMail user from a contact List 19 | * [x] Register Event API - real time notifications (webhook) 20 | 21 | ## Setup 22 | 23 | Add `Mailjet\MailjetBundle\MailjetBundle` to your `bundles.php`: 24 | 25 | ```php 26 | $bundles = [ 27 | // ... 28 | Mailjet\MailjetBundle\MailjetBundle::class => ['all' => true] 29 | ]; 30 | ``` 31 | 32 | ## Minimal Configuration 33 | 34 | In your `config.yml` add: 35 | 36 | ```yaml 37 | mailjet: 38 | api_key: "%mailjet.api_key%" 39 | secret_key: "%mailjet.secret_key%" 40 | ``` 41 | 42 | Add bundle to your project: 43 | 44 | ```bash 45 | composer require mailjet/mailjet-bundle 46 | ``` 47 | 48 | ## ToDo 49 | 50 | * More unit tests 51 | * Functionnal tests 52 | * Other features like Campaigns, stats, ... 53 | 54 | ## Contributing 55 | 56 | If you want to contribute to this project, look at [over here](CONTRIBUTING.md) 57 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mailjet/mailjet-bundle", 3 | "description": "Symfony bundle for Mailjet API V3", 4 | "type": "symfony-bundle", 5 | "homepage": "https://github.com/mailjet/mailjetBundle", 6 | "license": "MIT", 7 | "keywords": [ 8 | "Symfony", 9 | "MailJet", 10 | "API", 11 | "V3", 12 | "User", 13 | "bundle" 14 | ], 15 | "authors": [ 16 | { 17 | "name": "Titouan BENOIT", 18 | "email": "titouan.benoit@gmx.fr", 19 | "homepage": "https://github.com/Nightbr" 20 | }, 21 | { 22 | "name": "Mailjet API", 23 | "email": "api@mailjet.com", 24 | "homepage": "https://dev.mailjet.com/" 25 | } 26 | ], 27 | "autoload": { 28 | "psr-4": { 29 | "Mailjet\\MailjetBundle\\": "src/" 30 | } 31 | }, 32 | "require": { 33 | "php": ">=7.1.3", 34 | "mailjet/mailjet-apiv3-php": "^1.2", 35 | "mailjet/mailjet-swiftmailer": "^2.0", 36 | "symfony/config": "^4.4|^5.0", 37 | "symfony/console": "^4.4|^5.0", 38 | "symfony/dependency-injection": "^4.4|^5.0", 39 | "symfony/event-dispatcher": "^4.4|^5.0", 40 | "symfony/framework-bundle": "^4.4|^5.0", 41 | "symfony/http-foundation": "^4.4|^5.0", 42 | "symfony/http-kernel": "^4.4|^5.0", 43 | "symfony/routing": "^4.4|^5.0", 44 | "symfony/yaml": "^4.4|^5.0" 45 | }, 46 | "require-dev": { 47 | "phpspec/phpspec": "^5.1|^6.0|^7.0" 48 | }, 49 | "config": { 50 | "bin-dir": "bin" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Mailjet Bundle 2 | site_description: Symfony bundle for handling Mailjet API V3. 3 | site_author: Titouan BENOIT 4 | copyright: MIT 5 | repo_url: https://github.com/mailjet/mailjetBundle 6 | edit_uri: edit/master/src/Resources/doc/ 7 | docs_dir: 'src/Resources/doc' 8 | site_dir: "docs" 9 | pages: 10 | - Home: index.md 11 | - Setup: setup.md 12 | - Configuration: configuration.md 13 | - SwiftMailer: swiftmailer.md 14 | - Contact Provider: contact-provider.md 15 | - Usage: usage.md 16 | - Event API (webhook): event-api.md 17 | - Symfony Debug Toolbar: symfony-debug-toolbar.md 18 | - Tests: tests.md 19 | - Build Documentation: build-documentation.md 20 | - Mailjet Doc: mailjet-doc.md 21 | - Contributing: CONTRIBUTING.md 22 | theme: readthedocs 23 | markdown_extensions: 24 | - pymdownx.github 25 | -------------------------------------------------------------------------------- /phpspec.yml: -------------------------------------------------------------------------------- 1 | suites: 2 | default: 3 | namespace: Mailjet\MailjetBundle 4 | psr4_prefix: Mailjet\MailjetBundle 5 | -------------------------------------------------------------------------------- /spec/Client/MailjetClientSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('api_key', 'api_secret', false); 15 | } 16 | 17 | 18 | function it_is_initializable() 19 | { 20 | $this->shouldHaveType('Mailjet\MailjetBundle\Client\MailjetClient'); 21 | $this->shouldHaveType('Mailjet\Client'); 22 | } 23 | 24 | function it_can_post() 25 | { 26 | 27 | $response = $this->post(Resources::$Campaign, ['id'=>'azrt', 'body'=>[]], ['options']); 28 | 29 | $this->getCalls()->shouldReturn([ 30 | [ 31 | 'method' => 'POST', 32 | 'resource' => Resources::$Campaign, 33 | 'args' => ['id'=>'azrt', 'body'=>[]], 34 | 'options' => ['options'], 35 | 'success' => $response->success(), 36 | 'response' => $response->getBody(), 37 | ] 38 | ]); 39 | } 40 | 41 | function it_can_get() 42 | { 43 | 44 | $response = $this->get(Resources::$Campaign, ['id'=>'azrt', 'body'=>[]], ['options']); 45 | 46 | $this->getCalls()->shouldReturn([ 47 | [ 48 | 'method' => 'GET', 49 | 'resource' => Resources::$Campaign, 50 | 'args' => ['id'=>'azrt', 'body'=>[]], 51 | 'options' => ['options'], 52 | 'success' => $response->success(), 53 | 'response' => $response->getBody(), 54 | ] 55 | ]); 56 | } 57 | 58 | function it_can_put() 59 | { 60 | 61 | $response = $this->put(Resources::$Campaign, ['id'=>'azrt', 'body'=>[]], ['options']); 62 | 63 | $this->getCalls()->shouldReturn([ 64 | [ 65 | 'method' => 'PUT', 66 | 'resource' => Resources::$Campaign, 67 | 'args' => ['id'=>'azrt', 'body'=>[]], 68 | 'options' => ['options'], 69 | 'success' => $response->success(), 70 | 'response' => $response->getBody(), 71 | ] 72 | ]); 73 | } 74 | 75 | function it_can_delete() 76 | { 77 | 78 | $response = $this->delete(Resources::$Campaign, ['id'=>'azrt', 'body'=>[]], ['options']); 79 | 80 | $this->getCalls()->shouldReturn([ 81 | [ 82 | 'method' => 'DELETE', 83 | 'resource' => Resources::$Campaign, 84 | 'args' => ['id'=>'azrt', 'body'=>[]], 85 | 'options' => ['options'], 86 | 'success' => $response->success(), 87 | 'response' => $response->getBody(), 88 | ] 89 | ]); 90 | } 91 | 92 | function it_can_retrieve_several_calls() 93 | { 94 | 95 | $response = $this->post(Resources::$Campaign, ['id'=>'azrt', 'body'=>[]], ['options']); 96 | $response = $this->get(Resources::$Campaign, ['id'=>'azrt', 'body'=>[]], ['options']); 97 | $response = $this->put(Resources::$Campaign, ['id'=>'azrt', 'body'=>[]], ['options']); 98 | $response = $this->delete(Resources::$Campaign, ['id'=>'azrt', 'body'=>[]], ['options']); 99 | 100 | $this->getCalls()->shouldReturn([ 101 | [ 102 | 'method' => 'POST', 103 | 'resource' => Resources::$Campaign, 104 | 'args' => ['id'=>'azrt', 'body'=>[]], 105 | 'options' => ['options'], 106 | 'success' => $response->success(), 107 | 'response' => $response->getBody(), 108 | ], 109 | [ 110 | 'method' => 'GET', 111 | 'resource' => Resources::$Campaign, 112 | 'args' => ['id'=>'azrt', 'body'=>[]], 113 | 'options' => ['options'], 114 | 'success' => $response->success(), 115 | 'response' => $response->getBody(), 116 | ], 117 | [ 118 | 'method' => 'PUT', 119 | 'resource' => Resources::$Campaign, 120 | 'args' => ['id'=>'azrt', 'body'=>[]], 121 | 'options' => ['options'], 122 | 'success' => $response->success(), 123 | 'response' => $response->getBody(), 124 | ], 125 | [ 126 | 'method' => 'DELETE', 127 | 'resource' => Resources::$Campaign, 128 | 'args' => ['id'=>'azrt', 'body'=>[]], 129 | 'options' => ['options'], 130 | 'success' => $response->success(), 131 | 'response' => $response->getBody(), 132 | ] 133 | ]); 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /spec/Command/EventCommandSpec.php: -------------------------------------------------------------------------------- 1 | shouldHaveType('Mailjet\MailjetBundle\Command\EventCommand'); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /spec/Command/SyncContactMetadataCommandSpec.php: -------------------------------------------------------------------------------- 1 | shouldHaveType('Mailjet\MailjetBundle\Command\SyncContactMetadataCommand'); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /spec/Command/SyncUserCommandSpec.php: -------------------------------------------------------------------------------- 1 | shouldHaveType('Mailjet\MailjetBundle\Command\SyncUserCommand'); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /spec/Controller/EventControllerSpec.php: -------------------------------------------------------------------------------- 1 | setContainer($container); 25 | } 26 | 27 | function it_is_initializable() 28 | { 29 | $this->shouldHaveType('Mailjet\MailjetBundle\Controller\EventController'); 30 | $this->shouldHaveType('Symfony\Bundle\FrameworkBundle\Controller\AbstractController'); 31 | 32 | } 33 | 34 | function it_bad_request_exception_if_token_mismatch(ContainerInterface $container) 35 | { 36 | $request = new Request(); 37 | $request->create('/mailjet/mailjet-event/endpoint/12345678', 'POST'); 38 | $request->setMethod('POST'); 39 | 40 | $container->getParameter('mailjet.event_endpoint_token')->shouldBeCalled()->willReturn('NOWAY'); 41 | 42 | $this->shouldThrow(new BadRequestHttpException('Token mismatch')) 43 | ->duringIndexAction($request, '12345678'); 44 | } 45 | 46 | function it_bad_request_exception_if_no_data(ContainerInterface $container) 47 | { 48 | $request = new Request(); 49 | $request->create('/mailjet/mailjet-event/endpoint/12345678', 'POST'); 50 | $request->setMethod('POST'); 51 | 52 | $container->getParameter('mailjet.event_endpoint_token')->shouldBeCalled()->willReturn('12345678'); 53 | 54 | $this->shouldThrow(new BadRequestHttpException('Malformatted or missing data')) 55 | ->duringIndexAction($request, '12345678'); 56 | } 57 | 58 | function it_pass_with_simple_payload(ContainerInterface $container, EventDispatcherInterface $eventDispatcher) 59 | { 60 | $data = '{ 61 | "event": "unsub", 62 | "time": 1433334941, 63 | "MessageID": 20547674933128000, 64 | "email": "admin@local.com", 65 | "mj_campaign_id": 7276, 66 | "mj_contact_id": 126, 67 | "customcampaign": "", 68 | "CustomID": "helloworld", 69 | "Payload": "", 70 | "mj_list_id": 1, 71 | "ip": "127.0.0.1", 72 | "geo": "FR", 73 | "agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36" 74 | }'; 75 | $request = new Request(); 76 | $request->initialize([], [], [], [], [], [], $data); 77 | 78 | $container->getParameter('mailjet.event_endpoint_token')->shouldBeCalled()->willReturn('12345678'); 79 | $container->get('event_dispatcher')->shouldBeCalled()->willReturn($eventDispatcher); 80 | 81 | $eventDispatcher->dispatch(new CallbackEvent(json_decode($data, true)), CallbackEvent::EVENT_UNSUB)->shouldBeCalled(); 82 | 83 | $this->indexAction($request, '12345678'); 84 | } 85 | 86 | function it_pass_with_grouped_payload(ContainerInterface $container, EventDispatcherInterface $eventDispatcher) 87 | { 88 | $data = '[ 89 | { 90 | "event": "sent", 91 | "time": 1433333949, 92 | "MessageID": 19421777835146490, 93 | "email": "api@mailjet.com", 94 | "mj_campaign_id": 7257, 95 | "mj_contact_id": 4, 96 | "customcampaign": "", 97 | "mj_message_id": "19421777835146490", 98 | "smtp_reply": "sent (250 2.0.0 OK 1433333948 fa5si855896wjc.199 - gsmtp)", 99 | "CustomID": "helloworld", 100 | "Payload": "" 101 | }, 102 | { 103 | "event": "sent", 104 | "time": 1433333949, 105 | "MessageID": 19421777835146491, 106 | "email": "api@mailjet.com", 107 | "mj_campaign_id": 7257, 108 | "mj_contact_id": 4, 109 | "customcampaign": "", 110 | "mj_message_id": "19421777835146491", 111 | "smtp_reply": "sent (250 2.0.0 OK 1433333948 fa5si855896wjc.199 - gsmtp)", 112 | "CustomID": "helloworld", 113 | "Payload": "" 114 | } 115 | ]'; 116 | $request = new Request(); 117 | $request->initialize([], [], [], [], [], [], $data); 118 | 119 | $container->getParameter('mailjet.event_endpoint_token')->shouldBeCalled()->willReturn('12345678'); 120 | $container->get('event_dispatcher')->shouldBeCalled()->willReturn($eventDispatcher); 121 | 122 | $eventDispatcher->dispatch(new CallbackEvent(json_decode($data, true)[0]), CallbackEvent::EVENT_SENT)->shouldBeCalled(); 123 | $eventDispatcher->dispatch(new CallbackEvent(json_decode($data, true)[1]),CallbackEvent::EVENT_SENT)->shouldBeCalled(); 124 | 125 | $this->indexAction($request, '12345678'); 126 | } 127 | 128 | function it_throw_exception_if_bad_eventtype(ContainerInterface $container, EventDispatcherInterface $eventDispatcher) 129 | { 130 | $data = '{ 131 | "event": "sqdfkjsqdkjqsndkqsj", 132 | "time": 1433334941, 133 | "MessageID": 20547674933128000, 134 | "email": "admin@local.com", 135 | "mj_campaign_id": 7276, 136 | "mj_contact_id": 126, 137 | "customcampaign": "", 138 | "CustomID": "helloworld", 139 | "Payload": "", 140 | "mj_list_id": 1, 141 | "ip": "127.0.0.1", 142 | "geo": "FR", 143 | "agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36" 144 | }'; 145 | $request = new Request(); 146 | $request->initialize([], [], [], [], [], [], $data); 147 | 148 | $container->getParameter('mailjet.event_endpoint_token')->shouldBeCalled()->willReturn('12345678'); 149 | $container->get('event_dispatcher')->shouldBeCalled()->willReturn($eventDispatcher); 150 | 151 | $this->shouldThrow(new BadRequestHttpException('Type mismatch')) 152 | ->duringIndexAction($request, '12345678'); 153 | } 154 | 155 | function it_test_all_event_type(ContainerInterface $container, EventDispatcherInterface $eventDispatcher) 156 | { 157 | $data = '[ 158 | { 159 | "event": "sent", 160 | "time": 1433333949, 161 | "MessageID": 19421777835146490, 162 | "email": "api@mailjet.com", 163 | "mj_campaign_id": 7257, 164 | "mj_contact_id": 4, 165 | "customcampaign": "", 166 | "mj_message_id": "19421777835146490", 167 | "smtp_reply": "sent (250 2.0.0 OK 1433333948 fa5si855896wjc.199 - gsmtp)", 168 | "CustomID": "helloworld", 169 | "Payload": "" 170 | }, 171 | { 172 | "event": "open", 173 | "time": 1433333949, 174 | "MessageID": 19421777835146491, 175 | "email": "api@mailjet.com", 176 | "mj_campaign_id": 7257, 177 | "mj_contact_id": 4, 178 | "customcampaign": "", 179 | "mj_message_id": "19421777835146491", 180 | "smtp_reply": "sent (250 2.0.0 OK 1433333948 fa5si855896wjc.199 - gsmtp)", 181 | "CustomID": "helloworld", 182 | "Payload": "" 183 | }, 184 | { 185 | "event": "click", 186 | "time": 1433333949, 187 | "MessageID": 19421777835146491, 188 | "email": "api@mailjet.com", 189 | "mj_campaign_id": 7257, 190 | "mj_contact_id": 4, 191 | "customcampaign": "", 192 | "mj_message_id": "19421777835146491", 193 | "smtp_reply": "sent (250 2.0.0 OK 1433333948 fa5si855896wjc.199 - gsmtp)", 194 | "CustomID": "helloworld", 195 | "Payload": "" 196 | }, 197 | { 198 | "event": "bounce", 199 | "time": 1433333949, 200 | "MessageID": 19421777835146491, 201 | "email": "api@mailjet.com", 202 | "mj_campaign_id": 7257, 203 | "mj_contact_id": 4, 204 | "customcampaign": "", 205 | "mj_message_id": "19421777835146491", 206 | "smtp_reply": "sent (250 2.0.0 OK 1433333948 fa5si855896wjc.199 - gsmtp)", 207 | "CustomID": "helloworld", 208 | "Payload": "" 209 | }, 210 | { 211 | "event": "spam", 212 | "time": 1433333949, 213 | "MessageID": 19421777835146491, 214 | "email": "api@mailjet.com", 215 | "mj_campaign_id": 7257, 216 | "mj_contact_id": 4, 217 | "customcampaign": "", 218 | "mj_message_id": "19421777835146491", 219 | "smtp_reply": "sent (250 2.0.0 OK 1433333948 fa5si855896wjc.199 - gsmtp)", 220 | "CustomID": "helloworld", 221 | "Payload": "" 222 | }, 223 | { 224 | "event": "blocked", 225 | "time": 1433333949, 226 | "MessageID": 19421777835146491, 227 | "email": "api@mailjet.com", 228 | "mj_campaign_id": 7257, 229 | "mj_contact_id": 4, 230 | "customcampaign": "", 231 | "mj_message_id": "19421777835146491", 232 | "smtp_reply": "sent (250 2.0.0 OK 1433333948 fa5si855896wjc.199 - gsmtp)", 233 | "CustomID": "helloworld", 234 | "Payload": "" 235 | }, { 236 | "event": "unsub", 237 | "time": 1433333949, 238 | "MessageID": 19421777835146491, 239 | "email": "api@mailjet.com", 240 | "mj_campaign_id": 7257, 241 | "mj_contact_id": 4, 242 | "customcampaign": "", 243 | "mj_message_id": "19421777835146491", 244 | "smtp_reply": "sent (250 2.0.0 OK 1433333948 fa5si855896wjc.199 - gsmtp)", 245 | "CustomID": "helloworld", 246 | "Payload": "" 247 | } 248 | ]'; 249 | $request = new Request(); 250 | $request->initialize([], [], [], [], [], [], $data); 251 | 252 | $container->getParameter('mailjet.event_endpoint_token')->shouldBeCalled()->willReturn('12345678'); 253 | $container->get('event_dispatcher')->shouldBeCalled()->willReturn($eventDispatcher); 254 | 255 | $eventDispatcher->dispatch(new CallbackEvent(json_decode($data, true)[0]), CallbackEvent::EVENT_SENT)->shouldBeCalled(); 256 | $eventDispatcher->dispatch(new CallbackEvent(json_decode($data, true)[1]), CallbackEvent::EVENT_OPEN)->shouldBeCalled(); 257 | $eventDispatcher->dispatch(new CallbackEvent(json_decode($data, true)[2]), CallbackEvent::EVENT_CLICK)->shouldBeCalled(); 258 | $eventDispatcher->dispatch(new CallbackEvent(json_decode($data, true)[3]), CallbackEvent::EVENT_BOUNCE)->shouldBeCalled(); 259 | $eventDispatcher->dispatch(new CallbackEvent(json_decode($data, true)[4]), CallbackEvent::EVENT_SPAM)->shouldBeCalled(); 260 | $eventDispatcher->dispatch(new CallbackEvent(json_decode($data, true)[5]), CallbackEvent::EVENT_BLOCKED)->shouldBeCalled(); 261 | $eventDispatcher->dispatch(new CallbackEvent(json_decode($data, true)[6]), CallbackEvent::EVENT_UNSUB)->shouldBeCalled(); 262 | 263 | $this->indexAction($request, '12345678'); 264 | } 265 | } 266 | -------------------------------------------------------------------------------- /spec/DataCollector/MailjetDataCollectorSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($mailjet, $mailjet); 15 | } 16 | 17 | function it_is_initializable() 18 | { 19 | $this->shouldHaveType('Mailjet\MailjetBundle\DataCollector\MailjetDataCollector'); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /spec/Event/CallbackEventSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith(json_decode('{ 13 | "MessageID": 18859015918863550, 14 | "customcampaign": "", 15 | "email": "api@mailjet.com", 16 | "event": "sent", 17 | "mj_campaign_id": 2970263, 18 | "mj_contact_id": 7780691, 19 | "mj_message_id": "18859015918863553", 20 | "smtp_reply": "sent (250 2.0.0 OK 1496823341 f85si1543883wmh.76 - gsmtp)", 21 | "time": 1496823342 22 | }', true)); 23 | } 24 | 25 | public function it_is_initializable() 26 | { 27 | $this->shouldHaveType('Mailjet\MailjetBundle\Event\CallbackEvent'); 28 | } 29 | 30 | public function it_can_get_data() 31 | { 32 | $this->getData()->shouldReturn(json_decode('{ 33 | "MessageID": 18859015918863550, 34 | "customcampaign": "", 35 | "email": "api@mailjet.com", 36 | "event": "sent", 37 | "mj_campaign_id": 2970263, 38 | "mj_contact_id": 7780691, 39 | "mj_message_id": "18859015918863553", 40 | "smtp_reply": "sent (250 2.0.0 OK 1496823341 f85si1543883wmh.76 - gsmtp)", 41 | "time": 1496823342 42 | }', true)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /spec/Event/ContactEventSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('listid01', $contact); 15 | } 16 | 17 | public function it_is_initializable() 18 | { 19 | $this->shouldHaveType('Mailjet\MailjetBundle\Event\ContactEvent'); 20 | } 21 | 22 | public function it_can_get_listid() 23 | { 24 | $this->getListId()->shouldReturn('listid01'); 25 | } 26 | 27 | public function it_can_get_contact(Contact $contact) 28 | { 29 | $this->getContact()->shouldReturn($contact); 30 | } 31 | 32 | public function it_get_oldemail(Contact $contact){ 33 | $this->beConstructedWith('listid01', $contact, 'oldemail@foo.bar'); 34 | 35 | $this->getOldEmail()->shouldReturn('oldemail@foo.bar'); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /spec/Listener/ContactListenerSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($contactsListManager); 17 | } 18 | 19 | public function it_is_initializable() 20 | { 21 | $this->shouldHaveType('Mailjet\MailjetBundle\Listener\ContactListener'); 22 | } 23 | 24 | public function it_on_subcribe(ContactsListManager $contactsListManager) 25 | { 26 | $event = new ContactEvent('listid01', new Contact('email@foo.bar', 'foo Bar')); 27 | $contactsListManager->subscribe($event->getListId(), $event->getContact())->shouldBeCalled(); 28 | $this->onSubscribe($event); 29 | } 30 | 31 | public function it_on_unsubcribe(ContactsListManager $contactsListManager) 32 | { 33 | $event = new ContactEvent('listid01', new Contact('email@foo.bar', 'foo Bar')); 34 | $contactsListManager->unsubscribe($event->getListId(), $event->getContact())->shouldBeCalled(); 35 | $this->onUnsubscribe($event); 36 | } 37 | 38 | public function it_on_update(ContactsListManager $contactsListManager) 39 | { 40 | $event = new ContactEvent('listid01', new Contact('email@foo.bar', 'foo Bar')); 41 | $contactsListManager->update($event->getListId(), $event->getContact())->shouldBeCalled(); 42 | $this->onUpdate($event); 43 | } 44 | 45 | public function it_on_delete(ContactsListManager $contactsListManager) 46 | { 47 | $event = new ContactEvent('listid01', new Contact('email@foo.bar', 'foo Bar')); 48 | $contactsListManager->delete($event->getListId(), $event->getContact())->shouldBeCalled(); 49 | $this->onDelete($event); 50 | } 51 | 52 | public function it_on_change_email(ContactsListManager $contactsListManager) 53 | { 54 | $event = new ContactEvent('listid01', new Contact('email@foo.bar', 'foo Bar'), 'oldemail@foo.bar'); 55 | $contactsListManager->changeEmail($event->getListId(), $event->getContact(), 'oldemail@foo.bar')->shouldBeCalled(); 56 | $this->onChangeEmail($event); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /spec/Manager/CampaignDraftManagerSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($mailjet); 16 | } 17 | 18 | public function it_is_initializable() { 19 | $this->shouldHaveType('Mailjet\MailjetBundle\Manager\CampaignDraftManager'); 20 | } 21 | 22 | public function it_create(MailjetClient $mailjet, \Mailjet\Response $response) { 23 | $campaignDraft = new CampaignDraft("foo", "bar", "foo@bar", "bar", "foo"); 24 | 25 | $response->success()->shouldBeCalled()->willReturn(true); 26 | $response->getData()->shouldBeCalled()->willReturn('successdata!'); 27 | 28 | $mailjet->post(Resources::$Campaigndraft, ['body' => $campaignDraft->format()] 29 | )->shouldBeCalled()->willReturn($response); 30 | 31 | $this->create($campaignDraft)->shouldReturn('successdata!'); 32 | } 33 | 34 | public function it_throw_error_during_create(MailjetClient $mailjet, \Mailjet\Response $response) { 35 | $campaignDraft = new CampaignDraft("foo", "bar", "foo@bar", "bar", "foo"); 36 | 37 | $response->success()->shouldBeCalled()->willReturn(false); 38 | $response->getStatus()->shouldBeCalled()->willReturn(500); 39 | $response->getReasonPhrase()->shouldBeCalled()->willReturn('test'); 40 | $response->getBody()->shouldBeCalled()->willReturn(null); 41 | 42 | $mailjet->post(Resources::$Campaigndraft, ['body' => $campaignDraft->format()] 43 | )->shouldBeCalled()->willReturn($response); 44 | 45 | 46 | $this->shouldThrow(new MailjetException(500, "CampaignDraftManager:create() failed: test")) 47 | ->duringCreate($campaignDraft); 48 | } 49 | 50 | public function it_update(MailjetClient $mailjet, \Mailjet\Response $response, $id) { 51 | $campaignDraft = new CampaignDraft("foo", "bar", "foo@bar", "bar", "foo"); 52 | $campaignDraft->setId(2); 53 | $response->success()->shouldBeCalled()->willReturn(true); 54 | $response->getData()->shouldBeCalled()->willReturn('successdata!'); 55 | 56 | $mailjet->put(Resources::$Campaigndraft, ['id' => $campaignDraft->getId(), 'body' => $campaignDraft->format()]) 57 | ->shouldBeCalled()->willReturn($response); 58 | 59 | $this->update($campaignDraft->getId(), $campaignDraft)->shouldReturn('successdata!'); 60 | } 61 | 62 | public function it_get_detail_content(MailjetClient $mailjet, \Mailjet\Response $response) { 63 | 64 | $response->success()->shouldBeCalled()->willReturn(true); 65 | $response->getData()->shouldBeCalled()->willReturn('successdata!'); 66 | $id = 11; 67 | $mailjet->get(Resources:: $CampaigndraftDetailcontent, ['id' => $id] 68 | )->shouldBeCalled()->willReturn($response); 69 | 70 | $this->getDetailContent($id)->shouldReturn('successdata!'); 71 | } 72 | 73 | public function it_create_detail_content(MailjetClient $mailjet, \Mailjet\Response $response) { 74 | 75 | $response->success()->shouldBeCalled()->willReturn(true); 76 | $contentData = [ 77 | 'Html-part' => "

Hello {{var:name}}

", 78 | 'Text-part' => "Hello {{var:name}}" 79 | ]; 80 | $response->getData()->shouldBeCalled()->willReturn('successdata!'); 81 | $id = 11; 82 | $mailjet->post(Resources:: $CampaigndraftDetailcontent, ['id' => $id, 'body' => $contentData])->shouldBeCalled()->willReturn($response); 83 | 84 | $this->createDetailContent($id, $contentData)->shouldReturn('successdata!'); 85 | } 86 | 87 | public function it_get_schedule(MailjetClient $mailjet, \Mailjet\Response $response) { 88 | 89 | $response->success()->shouldBeCalled()->willReturn(true); 90 | $response->getData()->shouldBeCalled()->willReturn('successdata!'); 91 | $id = 11; 92 | $mailjet->get(Resources:: $CampaigndraftSchedule, ['id' => $id] 93 | )->shouldBeCalled()->willReturn($response); 94 | 95 | $this->getSchedule($id)->shouldReturn('successdata!'); 96 | } 97 | 98 | public function it_get_campaign_status(MailjetClient $mailjet, \Mailjet\Response $response) { 99 | 100 | $response->success()->shouldBeCalled()->willReturn(true); 101 | $response->getData()->shouldBeCalled()->willReturn('successdata!'); 102 | $id = 11; 103 | $mailjet->get(Resources:: $CampaigndraftStatus, ['id' => $id] 104 | )->shouldBeCalled()->willReturn($response); 105 | 106 | $this->getCampaignStatus($id)->shouldReturn('successdata!'); 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /spec/Manager/CampaignManagerSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($mailjet); 16 | } 17 | 18 | public function it_is_initializable() { 19 | $this->shouldHaveType('Mailjet\MailjetBundle\Manager\CampaignManager'); 20 | } 21 | 22 | public function it_update(MailjetClient $mailjet, \Mailjet\Response $response, $id) { 23 | $campaign = new Campaign("foo"); 24 | $response->success()->shouldBeCalled()->willReturn(true); 25 | $response->getData()->shouldBeCalled()->willReturn('successdata!'); 26 | $id = 2; 27 | $mailjet->put(Resources::$Campaign, ['id' => $id, 'body' => $campaign->format()]) 28 | ->shouldBeCalled()->willReturn($response); 29 | 30 | $this->updateCampaign($id, $campaign)->shouldReturn('successdata!'); 31 | } 32 | 33 | public function it_get_all_campaigns(MailjetClient $mailjet, \Mailjet\Response $response) { 34 | 35 | $response->success()->shouldBeCalled()->willReturn(true); 36 | $response->getData()->shouldBeCalled()->willReturn('successdata!'); 37 | $filters['FromTs'] = 0; 38 | $mailjet->get(Resources::$Campaign, ['filters' => $filters])->shouldBeCalled()->willReturn($response); 39 | 40 | $this->getAllCampaigns($filters)->shouldReturn('successdata!'); 41 | } 42 | 43 | public function it_get_campaign_by_id(MailjetClient $mailjet, \Mailjet\Response $response) { 44 | 45 | $response->success()->shouldBeCalled()->willReturn(true); 46 | $response->getData()->shouldBeCalled()->willReturn('successdata!'); 47 | $id = 11; 48 | $mailjet->get(Resources::$Campaign, ['id' => $id])->shouldBeCalled()->willReturn($response); 49 | 50 | $this->findByCampaignId($id)->shouldReturn('successdata!'); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /spec/Manager/ContactMetadataManagerSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($mailjet); 17 | } 18 | 19 | function it_is_initializable() 20 | { 21 | $this->shouldHaveType('Mailjet\MailjetBundle\Manager\ContactMetadataManager'); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /spec/Manager/ContactsListManagerSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($mailjet); 18 | } 19 | 20 | public function it_is_initializable() 21 | { 22 | $this->shouldHaveType('Mailjet\MailjetBundle\Manager\ContactsListManager'); 23 | } 24 | 25 | public function it_create(MailjetClient $mailjet, \Mailjet\Response $response) 26 | { 27 | $contact = new Contact('foo@bar'); 28 | $contact->setAction(Contact::ACTION_ADDFORCE); 29 | 30 | $response->success()->shouldBeCalled()->willReturn(true); 31 | $response->getData()->shouldBeCalled()->willReturn('successdata!'); 32 | 33 | $mailjet->post(Resources::$ContactslistManagecontact, 34 | ['id' => 'list01', 'body' => $contact->format()] 35 | )->shouldBeCalled()->willReturn($response); 36 | 37 | $this->create('list01', $contact)->shouldReturn('successdata!'); 38 | } 39 | 40 | public function it_throw_error_during_create(MailjetClient $mailjet, \Mailjet\Response $response) 41 | { 42 | $contact = new Contact('foo@bar'); 43 | $contact->setAction(Contact::ACTION_ADDFORCE); 44 | 45 | $response->success()->shouldBeCalled()->willReturn(false); 46 | $response->getStatus()->shouldBeCalled()->willReturn(500); 47 | $response->getReasonPhrase()->shouldBeCalled()->willReturn('test'); 48 | $response->getBody()->shouldBeCalled()->willReturn(null); 49 | 50 | $mailjet->post(Resources::$ContactslistManagecontact, 51 | ['id' => 'list01', 'body' => $contact->format()] 52 | )->shouldBeCalled()->willReturn($response); 53 | 54 | 55 | $this->shouldThrow(new MailjetException(500, "ContactsListManager:create() failed: test")) 56 | ->duringCreate('list01', $contact); 57 | } 58 | 59 | public function it_update(MailjetClient $mailjet, \Mailjet\Response $response) 60 | { 61 | $contact = new Contact('foo@bar'); 62 | $contact->setAction(Contact::ACTION_ADDNOFORCE); 63 | 64 | $response->success()->shouldBeCalled()->willReturn(true); 65 | $response->getData()->shouldBeCalled()->willReturn('successdata!'); 66 | 67 | $mailjet->post(Resources::$ContactslistManagecontact, 68 | ['id' => 'list01', 'body' => $contact->format()] 69 | )->shouldBeCalled()->willReturn($response); 70 | 71 | $this->update('list01', $contact)->shouldReturn('successdata!'); 72 | } 73 | 74 | public function it_subscribe(MailjetClient $mailjet, \Mailjet\Response $response) 75 | { 76 | $contact = new Contact('foo@bar'); 77 | $contact->setAction(Contact::ACTION_ADDFORCE); 78 | 79 | $response->success()->shouldBeCalled()->willReturn(true); 80 | $response->getData()->shouldBeCalled()->willReturn('successdata!'); 81 | 82 | $mailjet->post(Resources::$ContactslistManagecontact, 83 | ['id' => 'list01', 'body' => $contact->format()] 84 | )->shouldBeCalled()->willReturn($response); 85 | 86 | $this->subscribe('list01', $contact)->shouldReturn('successdata!'); 87 | } 88 | 89 | public function it_unsubscribe(MailjetClient $mailjet, \Mailjet\Response $response) 90 | { 91 | $contact = new Contact('foo@bar'); 92 | $contact->setAction(Contact::ACTION_UNSUB); 93 | 94 | $response->success()->shouldBeCalled()->willReturn(true); 95 | $response->getData()->shouldBeCalled()->willReturn('successdata!'); 96 | 97 | $mailjet->post(Resources::$ContactslistManagecontact, 98 | ['id' => 'list01', 'body' => $contact->format()] 99 | )->shouldBeCalled()->willReturn($response); 100 | 101 | $this->unsubscribe('list01', $contact)->shouldReturn('successdata!'); 102 | } 103 | 104 | public function it_delete(MailjetClient $mailjet, \Mailjet\Response $response) 105 | { 106 | $contact = new Contact('foo@bar'); 107 | $contact->setAction(Contact::ACTION_REMOVE); 108 | 109 | $response->success()->shouldBeCalled()->willReturn(true); 110 | $response->getData()->shouldBeCalled()->willReturn('successdata!'); 111 | 112 | $mailjet->post(Resources::$ContactslistManagecontact, 113 | ['id' => 'list01', 'body' => $contact->format()] 114 | )->shouldBeCalled()->willReturn($response); 115 | 116 | $this->delete('list01', $contact)->shouldReturn('successdata!'); 117 | } 118 | 119 | public function it_change_email(MailjetClient $mailjet, \Mailjet\Response $response, \Mailjet\Response $responseFinal) 120 | { 121 | $contact = new Contact('foo@bar'); 122 | $contact->setAction(Contact::ACTION_ADDFORCE); 123 | 124 | $response->success()->shouldBeCalled()->willReturn(true); 125 | $response->getData()->shouldBeCalled()->willReturn(['Data' => ['foo' => 'bar']]); 126 | 127 | $mailjet->get(Resources::$Contactdata, ['id' => 'oldemail@foo.bar']) 128 | ->shouldBeCalled() 129 | ->willReturn($response); 130 | $contact->setProperties(['foo' => 'bar']); 131 | $mailjet->post(Resources::$ContactslistManagecontact, ['id' => 'list01', 'body' => $contact->format()]) 132 | ->shouldBeCalled() 133 | ->willReturn($response); 134 | 135 | $oldContact = new Contact('oldemail@foo.bar'); 136 | $oldContact->setAction(Contact::ACTION_REMOVE); 137 | 138 | $responseFinal->success()->shouldBeCalled()->willReturn(true); 139 | $responseFinal->getData()->shouldBeCalled()->willReturn('success'); 140 | 141 | $mailjet->post(Resources::$ContactslistManagecontact, ['id' => 'list01', 'body' => $oldContact->format()]) 142 | ->shouldBeCalled() 143 | ->willReturn($responseFinal); 144 | 145 | $this->changeEmail('list01', $contact, 'oldemail@foo.bar')->shouldReturn('success'); 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /spec/Manager/EventCallbackUrlManagerSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($mailjet); 14 | } 15 | 16 | public function it_is_initializable() 17 | { 18 | $this->shouldHaveType('Mailjet\MailjetBundle\Manager\EventCallbackUrlManager'); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /spec/Manager/TemplateManagerSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($mailjet); 16 | } 17 | 18 | public function it_is_initializable() { 19 | $this->shouldHaveType('Mailjet\MailjetBundle\Manager\TemplateManager'); 20 | } 21 | 22 | public function it_create(MailjetClient $mailjet, \Mailjet\Response $response, $id) { 23 | $template = new Template("foo"); 24 | $response->success()->shouldBeCalled()->willReturn(true); 25 | $response->getData()->shouldBeCalled()->willReturn('successdata!'); 26 | $mailjet->post(Resources::$Template, ['body' => $template->format()]) 27 | ->shouldBeCalled()->willReturn($response); 28 | 29 | $this->create($template)->shouldReturn('successdata!'); 30 | } 31 | 32 | public function it_update(MailjetClient $mailjet, \Mailjet\Response $response, $id) { 33 | $template = new Template("foo"); 34 | $response->success()->shouldBeCalled()->willReturn(true); 35 | $response->getData()->shouldBeCalled()->willReturn('successdata!'); 36 | $id = 2; 37 | $mailjet->put(Resources::$Template, ['id' => $id, 'body' => $template->format()]) 38 | ->shouldBeCalled()->willReturn($response); 39 | 40 | $this->update($id, $template)->shouldReturn('successdata!'); 41 | } 42 | 43 | public function it_get_all_templates(MailjetClient $mailjet, \Mailjet\Response $response) { 44 | 45 | $response->success()->shouldBeCalled()->willReturn(true); 46 | $response->getData()->shouldBeCalled()->willReturn('successdata!'); 47 | $filters['Categories'] = "sport"; 48 | $mailjet->get(Resources::$Template, ['filters' => $filters])->shouldBeCalled()->willReturn($response); 49 | 50 | $this->getAll($filters)->shouldReturn('successdata!'); 51 | } 52 | 53 | public function it_get_template_by_id(MailjetClient $mailjet, \Mailjet\Response $response) { 54 | 55 | $response->success()->shouldBeCalled()->willReturn(true); 56 | $response->getData()->shouldBeCalled()->willReturn('successdata!'); 57 | $id = 11; 58 | $mailjet->get(Resources::$Template, ['id' => $id])->shouldBeCalled()->willReturn($response); 59 | 60 | $this->get($id)->shouldReturn('successdata!'); 61 | } 62 | 63 | public function it_delete_template(MailjetClient $mailjet, \Mailjet\Response $response) { 64 | 65 | $response->success()->shouldBeCalled()->willReturn(true); 66 | $response->getData()->shouldBeCalled()->willReturn('successdata!'); 67 | $id = 11; 68 | $mailjet->delete(Resources::$Template, ['id' => $id])->shouldBeCalled()->willReturn($response); 69 | 70 | $this->delete($id)->shouldReturn('successdata!'); 71 | } 72 | 73 | public function it_get_detail_content(MailjetClient $mailjet, \Mailjet\Response $response) { 74 | 75 | $response->success()->shouldBeCalled()->willReturn(true); 76 | $response->getData()->shouldBeCalled()->willReturn('successdata!'); 77 | $id = 11; 78 | $mailjet->get(Resources:: $TemplateDetailcontent, ['id' => $id] 79 | )->shouldBeCalled()->willReturn($response); 80 | 81 | $this->getDetailContent($id)->shouldReturn('successdata!'); 82 | } 83 | 84 | public function it_create_detail_content(MailjetClient $mailjet, \Mailjet\Response $response) { 85 | 86 | $response->success()->shouldBeCalled()->willReturn(true); 87 | $contentData = [ 88 | 'Html-part' => "

Hello {{var:name}}

", 89 | 'Text-part' => "Hello {{var:name}}" 90 | ]; 91 | $response->getData()->shouldBeCalled()->willReturn('successdata!'); 92 | $id = 11; 93 | $mailjet->post(Resources:: $TemplateDetailcontent, ['id' => $id, 'body' => $contentData])->shouldBeCalled()->willReturn($response); 94 | 95 | $this->createDetailContent($id, $contentData)->shouldReturn('successdata!'); 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /spec/Model/CampaignDraftSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith("en_US", "Foo", "bar@mfoo.com", "foo", "bar"); 20 | } 21 | 22 | public function it_is_initializable() 23 | { 24 | $this->shouldHaveType('Mailjet\MailjetBundle\Model\CampaignDraft'); 25 | } 26 | 27 | 28 | public function it_can_set_optional_properties(){ 29 | $optionalProp['Title'] = 'Friday newsletter'; 30 | $this->setOptionalProperties($optionalProp); 31 | $this->getOptionalProperties()['Title']->shouldReturn('Friday newsletter'); 32 | } 33 | 34 | 35 | 36 | public function it_can_format_properly(){ 37 | $result[self::LOCALE_KEY] = "en_US"; 38 | $result[self::SENDER_KEY] = "Foo"; 39 | $result[self::SENDEREMAIL_KEY] = "bar@mfoo.com"; 40 | $result[self::SUBJECT_KEY] = "foo"; 41 | $result[self::CONTACTLISTID_KEY] ="bar"; 42 | $this->format()->shouldReturn($result); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /spec/Model/CampaignSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith("bar",$optionalProp); 17 | } 18 | 19 | public function it_is_initializable() 20 | { 21 | $this->shouldHaveType('Mailjet\MailjetBundle\Model\Campaign'); 22 | } 23 | 24 | 25 | public function it_can_get_optional_properties(){ 26 | $this->getOptionalProperties()['IsStarred']->shouldReturn(true); 27 | } 28 | 29 | 30 | 31 | public function it_can_format_properly(){ 32 | $optionalProp['IsStarred'] = true; 33 | $result[self::FROMEMAIL_KEY] = "bar"; 34 | $result = array_merge($result, $optionalProp); 35 | $this->format()->shouldReturn($result); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /spec/Model/ContactMetadataSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('var', 'str'); 13 | } 14 | 15 | function it_is_initializable() 16 | { 17 | $this->shouldHaveType('Mailjet\MailjetBundle\Model\ContactMetadata'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /spec/Model/ContactSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('toto@mail.fr', 'toto TATA', ['firstname' => 'toto', 'lastname'=>'tata', "gender" => "undefined"]); 13 | } 14 | 15 | public function it_is_initializable() 16 | { 17 | $this->shouldHaveType('Mailjet\MailjetBundle\Model\Contact'); 18 | } 19 | 20 | 21 | public function it_can_format() 22 | { 23 | $result = [ 24 | "Email" => 'toto@mail.fr', 25 | "Name" => 'toto TATA', 26 | "Properties" => [ 27 | "firstname" => "toto", 28 | "lastname" => "tata", 29 | "gender" => "undefined" 30 | ] 31 | ]; 32 | 33 | $this->format()->shouldReturn($result); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /spec/Model/ContactsListSpec.php: -------------------------------------------------------------------------------- 1 | 'bar']) 18 | ); 19 | 20 | $this->beConstructedWith('listid01', ContactsList::ACTION_ADDFORCE, $contacts); 21 | } 22 | 23 | public function it_is_initializable() 24 | { 25 | $this->shouldHaveType('Mailjet\MailjetBundle\Model\ContactsList'); 26 | } 27 | 28 | public function it_throw_error_if_bad_action() 29 | { 30 | $this->beConstructedWith('listid01', 'sqdkljqslkdhnkqsj', []); 31 | $this->shouldThrow(new \RuntimeException("sqdkljqslkdhnkqsj: is not a valide Action."))->duringInstantiation(); 32 | } 33 | 34 | public function it_can_get_listid(){ 35 | $this->getListId()->shouldReturn('listid01'); 36 | } 37 | 38 | public function it_can_get_action(){ 39 | $this->getAction()->shouldReturn(ContactsList::ACTION_ADDFORCE); 40 | } 41 | 42 | public function it_can_get_contacts(){ 43 | $contacts = array( 44 | new Contact('dede@free.fr', 'dede'), 45 | new Contact('foo@bar.fr', 'foo', ['foo' => 'bar']) 46 | ); 47 | 48 | $this->beConstructedWith('listid01', ContactsList::ACTION_ADDFORCE, $contacts); 49 | 50 | $this->getContacts()->shouldReturn($contacts); 51 | } 52 | 53 | public function it_can_format_properly(){ 54 | $result = array( 55 | 'Action' => ContactsList::ACTION_ADDFORCE 56 | ); 57 | 58 | $contacts = array( 59 | new Contact('dede@free.fr', 'dede'), 60 | new Contact('foo@bar.fr', 'foo', ['foo' => 'bar']) 61 | ); 62 | 63 | $result['Contacts'] = array_map(function (Contact $contact) { 64 | return $contact->format(); 65 | }, $contacts); 66 | 67 | 68 | $this->format()->shouldReturn($result); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /spec/Model/EventCallbackUrlSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('https://foo.bar'); 13 | } 14 | 15 | public function it_is_initializable() 16 | { 17 | $this->shouldHaveType('Mailjet\MailjetBundle\Model\EventCallbackUrl'); 18 | } 19 | 20 | public function it_can_format() 21 | { 22 | 23 | $result = array( 24 | 'Url' => 'https://foo.bar', 25 | 'EventType' => 'open', 26 | 'IsBackup' => false, 27 | 'Status' => 'alive', 28 | 'Version' => 1 29 | ); 30 | 31 | $this->format()->shouldReturn($result); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /spec/Model/TemplateSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith("bar",$optionalProp); 17 | } 18 | 19 | public function it_is_initializable() 20 | { 21 | $this->shouldHaveType('Mailjet\MailjetBundle\Model\Template'); 22 | } 23 | 24 | 25 | public function it_can_get_optional_properties(){ 26 | $this->getOptionalProperties()['Description']->shouldReturn('Foo'); 27 | } 28 | 29 | 30 | 31 | public function it_can_format_properly(){ 32 | $optionalProp['Description'] = 'Foo'; 33 | $result[self::NAME_KEY] = "bar"; 34 | $result = array_merge($result, $optionalProp); 35 | $this->format()->shouldReturn($result); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /spec/Synchronizer/ContactsListSynchronizerSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($mailjet, $manager); 15 | } 16 | 17 | public function it_is_initializable() 18 | { 19 | $this->shouldHaveType('Mailjet\MailjetBundle\Synchronizer\ContactsListSynchronizer'); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Client/MailjetClient.php: -------------------------------------------------------------------------------- 1 | calls[] = [ 23 | 'method' => 'POST', 24 | 'resource' => $resource, 25 | 'args' => $args, 26 | 'options' => $options, 27 | 'success' => $response->success(), 28 | 'response' => $response->getBody(), 29 | ]; 30 | return $response; 31 | } 32 | 33 | /** 34 | * Trigger a GET request. 35 | * 36 | * @param array $resource Mailjet Resource/Action pair 37 | * @param array $args Request arguments 38 | * @param array $options 39 | * @return Response 40 | */ 41 | public function get(array $resource, array $args = [], array $options = []): Response 42 | { 43 | $response = parent::get($resource, $args, $options); 44 | $this->calls[] = [ 45 | 'method' => 'GET', 46 | 'resource' => $resource, 47 | 'args' => $args, 48 | 'options' => $options, 49 | 'success' => $response->success(), 50 | 'response' => $response->getBody(), 51 | ]; 52 | return $response; 53 | } 54 | 55 | /** 56 | * Trigger a POST request. 57 | * 58 | * @param array $resource Mailjet Resource/Action pair 59 | * @param array $args Request arguments 60 | * @param array $options 61 | * @return Response 62 | */ 63 | public function put(array $resource, array $args = [], array $options = []): Response 64 | { 65 | $response = parent::put($resource, $args, $options); 66 | $this->calls[] = [ 67 | 'method' => 'PUT', 68 | 'resource' => $resource, 69 | 'args' => $args, 70 | 'options' => $options, 71 | 'success' => $response->success(), 72 | 'response' => $response->getBody(), 73 | ]; 74 | return $response; 75 | } 76 | 77 | /** 78 | * Trigger a GET request. 79 | * 80 | * @param array $resource Mailjet Resource/Action pair 81 | * @param array $args Request arguments 82 | * @param array $options 83 | * @return Response 84 | */ 85 | public function delete(array $resource, array $args = [], array $options = []): Response 86 | { 87 | $response = parent::delete($resource, $args, $options); 88 | $this->calls[] = [ 89 | 'method' => 'DELETE', 90 | 'resource' => $resource, 91 | 'args' => $args, 92 | 'options' => $options, 93 | 'success' => $response->success(), 94 | 'response' => $response->getBody(), 95 | ]; 96 | return $response; 97 | } 98 | /** 99 | * @return array 100 | */ 101 | public function getCalls() 102 | { 103 | return $this->calls; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/Command/EventCommand.php: -------------------------------------------------------------------------------- 1 | setName('mailjet:event-endpoint') 18 | ->setDescription('Prints URL endpoint that should be configured at mailjet.com website') 19 | ->addArgument('baseurl', InputArgument::REQUIRED, 'Baseurl with domain to be used in URL, i.e. https://example.com') 20 | ->addOption( 21 | 'event-type', 22 | null, 23 | InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 24 | 'List of eventType: ["sent", "open", "click", "bounce", "blocked", "spam", "unsub"], all by default', 25 | null 26 | ) 27 | ; 28 | } 29 | 30 | /** 31 | * @param InputInterface $input 32 | * @param OutputInterface $output 33 | */ 34 | protected function execute(InputInterface $input, OutputInterface $output) 35 | { 36 | $domain = $input->getArgument('baseurl'); 37 | $uri = $this->getRouter()->generate($this->getRouteName(), array( 38 | 'token' => $this->getToken() 39 | )); 40 | $url = sprintf('%s/%s', rtrim($domain, '/'), ltrim($uri, '/')); 41 | 42 | /** 43 | * @var EventCallbackUrlManager $manager 44 | */ 45 | $manager = $this->getContainer()->get('mailjet.service.event_callback_manager'); 46 | 47 | if ($input->getOption('event-type')) { 48 | $eventTypes = $input->getOption('event-type'); 49 | } else { 50 | $eventTypes = ["sent", "open", "click", "bounce", "blocked", "spam", "unsub"]; 51 | } 52 | 53 | foreach ($eventTypes as $eventType) { 54 | $eventCallBackUrl = new EventCallbackUrl($url, $eventType, true); 55 | 56 | try { 57 | $manager->get($eventType); 58 | $output->writeln('update '.$eventType); 59 | $manager->update($eventType, $eventCallBackUrl); 60 | } catch (\Exception $e) { 61 | $output->writeln('create '.$eventType); 62 | $manager->create($eventCallBackUrl); 63 | } 64 | } 65 | 66 | $output->writeln(sprintf('%s callback url has been added to your Mailjet account!', $url)); 67 | } 68 | 69 | /** 70 | * @return \Symfony\Component\Routing\RouterInterface 71 | */ 72 | protected function getRouter() 73 | { 74 | return $this->getContainer()->get('router'); 75 | } 76 | 77 | /** 78 | * @return string 79 | */ 80 | protected function getRouteName() 81 | { 82 | return $this->getContainer()->getParameter('mailjet.event_endpoint_route'); 83 | } 84 | 85 | /** 86 | * @return string 87 | */ 88 | protected function getToken() 89 | { 90 | return $this->getContainer()->getParameter('mailjet.event_endpoint_token'); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/Command/SyncContactMetadataCommand.php: -------------------------------------------------------------------------------- 1 | setName('mailjet:contactmetadata-sync') 34 | ->setDescription('Synchronize ContactMetadata in config with Mailjet'); 35 | } 36 | 37 | /** 38 | * {@inheritDoc} 39 | */ 40 | protected function initialize(InputInterface $input, OutputInterface $output) 41 | { 42 | $output->writeln(sprintf('%s', $this->getDescription())); 43 | 44 | $this->contactMetadata = $this->getContainer()->getParameter('mailjet.contact_metadata'); 45 | } 46 | 47 | /** 48 | * {@inheritDoc} 49 | */ 50 | protected function execute(InputInterface $input, OutputInterface $output) 51 | { 52 | // @TODO create a ContactMetadataSynchronizer 53 | // @TODO update existing ContactMetadata (in order to not throw error...) 54 | foreach ($this->contactMetadata as $contactMetadata) { 55 | 56 | $metadataObj = new ContactMetadata($contactMetadata['name'], $contactMetadata['datatype']); 57 | 58 | try { 59 | $response = $this->getContainer()->get('mailjet.service.contact_metadata_manager')->create($metadataObj); 60 | $output->writeln(sprintf('%s:%s added!', $contactMetadata['name'], $contactMetadata['datatype'])); 61 | } catch (\Exception $e) { 62 | $output->writeln(sprintf('%s', $e->getMessage())); 63 | } 64 | 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Command/SyncUserCommand.php: -------------------------------------------------------------------------------- 1 | setName('mailjet:user-sync') 41 | ->setDescription('Synchronize users with mailjet contact list') 42 | ->addOption( 43 | 'follow-sync', 44 | null, 45 | InputOption::VALUE_NONE, 46 | 'If you want to follow batches execution' 47 | ); 48 | // @TODO add params : listId, providerServiceKey 49 | } 50 | 51 | /** 52 | * {@inheritDoc} 53 | */ 54 | protected function initialize(InputInterface $input, OutputInterface $output) 55 | { 56 | $output->writeln(sprintf('%s', $this->getDescription())); 57 | 58 | $this->lists = $this->getContainer()->getParameter('mailjet.lists'); 59 | $this->synchronizer = $this->getContainer()->get('mailjet.service.contacts_list_synchronizer'); 60 | } 61 | 62 | /** 63 | * {@inheritDoc} 64 | */ 65 | protected function execute(InputInterface $input, OutputInterface $output) 66 | { 67 | foreach ($this->lists as $listId => $listParameters) { 68 | $provider = $this->getProvider($listParameters['contact_provider']); 69 | 70 | $contactList = new ContactsList($listId, ContactsList::ACTION_ADDFORCE, $provider->getContacts()); 71 | 72 | $batchesResult = $this->synchronizer->synchronize($contactList); 73 | 74 | if ($input->getOption('follow-sync')) { 75 | $batchesError = []; 76 | $batchesResult = $this->refreshBatchesResult($listId, $batchesResult, $batchesError); 77 | while (!$this->batchesFinished($batchesResult)) { 78 | $batchesResult = $this->refreshBatchesResult($listId, $batchesResult, $batchesError); 79 | foreach ($batchesResult as $key => $batch) { 80 | $output->writeln($this->displayBatchInfo($batch)); 81 | } 82 | sleep(2); 83 | $output->writeln('----------------------------------------'); 84 | } 85 | 86 | $output->writeln(sprintf('There are %d batches in error.', count($batchesError))); 87 | // Recovering error file 88 | foreach ($this->displayBatchesErrorFile($batchesError) as $line) { 89 | $output->writeln($line); 90 | } 91 | } 92 | 93 | $output->writeln(sprintf('OK listId: %s, see logs in Mailjet List', $listId)); 94 | } 95 | } 96 | 97 | /** 98 | * Get contact provider 99 | * @param string $providerServiceKey 100 | * @return ProviderInterface $provider 101 | */ 102 | private function getProvider($providerServiceKey) 103 | { 104 | try { 105 | $provider = $this->getContainer()->get($providerServiceKey); 106 | } catch (ServiceNotFoundException $e) { 107 | throw new \InvalidArgumentException(sprintf('Provider "%s" should be defined as a service.', $providerServiceKey), $e->getCode(), $e); 108 | } 109 | if (!$provider instanceof ProviderInterface) { 110 | throw new \InvalidArgumentException(sprintf('Provider "%s" should implement Mailjet\MailjetBundle\Provider\ProviderInterface.', $providerServiceKey)); 111 | } 112 | return $provider; 113 | } 114 | 115 | /** 116 | * Refresh all batch from Mailjet API 117 | * @param string $listId 118 | * @param array $batchesResult 119 | * @param &array $batchesError 120 | * @return array 121 | */ 122 | private function refreshBatchesResult($listId, $batchesResult, &$batchesError) 123 | { 124 | $refreshedBatchsResults = []; 125 | foreach ($batchesResult as $key => $batch) { 126 | $jobId = $batch['JobID']; 127 | $batch = $this->synchronizer->getJob($listId, $jobId); 128 | // We need to array merge because Mailjet API doesn't send jobid in response. 129 | if ($batch[0]['Status'] == 'Error') { 130 | array_push($batchesError, array_merge(['JobID' => $jobId], $batch[0])); 131 | } else { 132 | array_push($refreshedBatchsResults, array_merge(['JobID' => $jobId], $batch[0])); 133 | } 134 | } 135 | return $refreshedBatchsResults; 136 | } 137 | 138 | /** 139 | * Test if all batches are finished 140 | * @param array $batchesResult 141 | * @return bool 142 | */ 143 | private function batchesFinished($batchesResult) 144 | { 145 | $allfinished = true; 146 | foreach ($batchesResult as $key => $batch) { 147 | if ($batch['Status'] != 'Completed') { 148 | $allfinished = false; 149 | } 150 | } 151 | return $allfinished; 152 | } 153 | /** 154 | * Pretty display of batch info 155 | * @param array $batch 156 | * @return string 157 | */ 158 | private function displayBatchInfo($batch) 159 | { 160 | if ($batch['Status'] == 'Completed') { 161 | return sprintf('batch %s is Completed, %d operations %s', $batch['JobID'], $batch['Count'], $batch['Error']); 162 | } else { 163 | return sprintf('batch %s, current status %s, %d operations %s', $batch['JobID'], $batch['Status'], $batch['Count'], $batch['Error']); 164 | } 165 | } 166 | 167 | /** 168 | * Print Batches Errors 169 | * @param array $batchesError 170 | * @return array 171 | */ 172 | private function displayBatchesErrorFile($batchesError) 173 | { 174 | $output = []; 175 | foreach ($batchesError as $key => $batch) { 176 | $errors = $this->synchronizer->getJobJsonError($batch['JobID']); 177 | array_push($output, '
'.print_r($errors).'
'); 178 | } 179 | 180 | return $output; 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /src/Controller/EventController.php: -------------------------------------------------------------------------------- 1 | getToken() !== $token) { 36 | throw new BadRequestHttpException('Token mismatch'); 37 | } 38 | 39 | $data = $this->extractData($request); 40 | 41 | if(!$data){ 42 | throw new BadRequestHttpException('Malformatted or missing data'); 43 | } 44 | 45 | if(isset($data['event'])){ 46 | $data = array($data); 47 | } 48 | /* 49 | Please note that the event types in the collection can be mixed. 50 | We group together all the events of the last second for the same webhook url. 51 | */ 52 | // NOTE: use a better dispatcher such as rabbitMQ if you have a huge amount of events (sent, open, click can be a lot...) 53 | $dispatcher = $this->getDispatcher(); 54 | 55 | foreach ($data as $key => $callbackData) { 56 | $type = $callbackData['event']; 57 | switch ($type) { 58 | case 'sent': 59 | $dispatcher->dispatch(new CallbackEvent($callbackData), CallbackEvent::EVENT_SENT); 60 | break; 61 | case 'open': 62 | $dispatcher->dispatch(new CallbackEvent($callbackData), CallbackEvent::EVENT_OPEN); 63 | break; 64 | case 'click': 65 | $dispatcher->dispatch(new CallbackEvent($callbackData), CallbackEvent::EVENT_CLICK); 66 | break; 67 | case 'bounce': 68 | $dispatcher->dispatch(new CallbackEvent($callbackData), CallbackEvent::EVENT_BOUNCE); 69 | break; 70 | case 'spam': 71 | $dispatcher->dispatch(new CallbackEvent($callbackData), CallbackEvent::EVENT_SPAM); 72 | break; 73 | case 'blocked': 74 | $dispatcher->dispatch(new CallbackEvent($callbackData), CallbackEvent::EVENT_BLOCKED); 75 | break; 76 | case 'unsub': 77 | $dispatcher->dispatch(new CallbackEvent($callbackData), CallbackEvent::EVENT_UNSUB); 78 | break; 79 | default: 80 | throw new BadRequestHttpException('Type mismatch'); 81 | break; 82 | } 83 | } 84 | 85 | return $this->prepareResponse(200); 86 | } 87 | 88 | /** 89 | * Override this to use another event dispatcher 90 | * @return EventDispatcherInterface 91 | */ 92 | public function getDispatcher() 93 | { 94 | // NOTE: use a better dispatcher such as rabbitMQ if you have a huge amount of events 95 | return $this->get('event_dispatcher'); 96 | } 97 | 98 | /** 99 | 100 | * @param Request $request 101 | * @return array 102 | */ 103 | private function extractData(Request $request) 104 | { 105 | return json_decode($request->getContent(), true); 106 | } 107 | 108 | /** 109 | * @param int $status 110 | * @return JsonResponse 111 | */ 112 | private function prepareResponse($status) 113 | { 114 | return new JsonResponse(array('success' => true), $status); 115 | } 116 | 117 | /** 118 | * @return string 119 | */ 120 | private function getToken() 121 | { 122 | return $this->container->getParameter('mailjet.event_endpoint_token'); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/DataCollector/MailjetDataCollector.php: -------------------------------------------------------------------------------- 1 | client = $client; 34 | $this->transactionalClient = $transactionalClient; 35 | } 36 | 37 | /** 38 | * Collects data for the given Request and Response. 39 | * 40 | * @param Request $request A Request instance 41 | * @param Response $response A Response instance 42 | * @param \Exception $exception An Exception instance 43 | */ 44 | public function collect(Request $request, Response $response, \Throwable $exception = null) 45 | { 46 | 47 | $this->data = $this->client->getCalls(); 48 | $this->data = array_merge($this->data, $this->transactionalClient->getCalls()); 49 | } 50 | 51 | /** 52 | * Returns the name of the collector. 53 | * 54 | * @return string The collector name 55 | */ 56 | public function getName() 57 | { 58 | return 'mailjet'; 59 | } 60 | 61 | /** 62 | * @return array 63 | */ 64 | public function getData() 65 | { 66 | return $this->data; 67 | } 68 | 69 | /** 70 | * Return call number 71 | * @method getCallCount 72 | * @return int 73 | */ 74 | public function getCallCount() 75 | { 76 | return count($this->data); 77 | } 78 | 79 | /** 80 | * Resets this data collector to its initial state. 81 | */ 82 | public function reset() 83 | { 84 | $this->data = array(); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/DependencyInjection/Configuration.php: -------------------------------------------------------------------------------- 1 | getRootNode(); 23 | } else { 24 | // BC layer for symfony/config 4.1 and older 25 | $rootNode = $treeBuilder->root('mailjet'); 26 | } 27 | 28 | $rootNode 29 | ->children() 30 | ->scalarNode('api_key')->isRequired()->info('Mailjet API key')->end() 31 | ->scalarNode('secret_key')->isRequired()->info('Mailjet API token')->end() 32 | ->booleanNode('call')->defaultTrue()->info('Performs the API call or not')->end() 33 | ->arrayNode('options')->info('Options for Mailjet Client (url, version, call, secured)') 34 | ->children() 35 | ->scalarNode('url')->end() 36 | ->scalarNode('version')->end() 37 | ->booleanNode('call')->end() 38 | ->booleanNode('secured')->end() 39 | ->end() 40 | ->end() 41 | ->arrayNode('transactionnal')->info('Options for Mailjet client for SwiftMailer integration') 42 | ->children() 43 | ->booleanNode('call')->defaultTrue()->info('Performs the API call or not')->end() 44 | ->arrayNode('options')->info('Options for Mailjet Client (url, version, call, secured)') 45 | ->children() 46 | ->scalarNode('url')->end() 47 | ->scalarNode('version')->end() 48 | ->booleanNode('call')->end() 49 | ->booleanNode('secured')->end() 50 | ->end() 51 | ->end() 52 | ->end() 53 | ->end() 54 | ->scalarNode('event_endpoint_route') 55 | ->defaultValue('mailjet_event_endpoint') 56 | ->info('Route name of the event API endpoint') 57 | ->end() 58 | ->scalarNode('event_endpoint_token') 59 | ->defaultValue('123456789') 60 | ->info('Security token to validate endpoint request with') 61 | ->end() 62 | // lists 63 | ->arrayNode('lists') 64 | ->useAttributeAsKey('listId') 65 | ->prototype('array') 66 | ->children() 67 | ->scalarNode('contact_provider')->end() 68 | ->end() 69 | ->end() 70 | ->end() 71 | // ContactMetadata/ContactProperties 72 | ->arrayNode('contact_metadata') 73 | ->prototype('array') 74 | ->children() 75 | ->scalarNode('name') 76 | ->isRequired() 77 | ->end() 78 | ->scalarNode('datatype') 79 | ->isRequired() 80 | ->end() 81 | ->end() 82 | ->end() 83 | ->end() 84 | ->end() 85 | ; 86 | 87 | return $treeBuilder; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/DependencyInjection/MailjetExtension.php: -------------------------------------------------------------------------------- 1 | processConfiguration($configuration, $configs); 16 | 17 | # Client config 18 | $container->setParameter('mailjet.api_key', $config['api_key']); 19 | $container->setParameter('mailjet.secret_key', $config['secret_key']); 20 | $container->setParameter('mailjet.call', $config['call']); 21 | 22 | if (isset($config['options'])) { 23 | $container->setParameter('mailjet.options', $config['options']); 24 | } else { 25 | $container->setParameter('mailjet.options', array()); 26 | } 27 | 28 | # Client transactionnal config 29 | if (isset($config['transactionnal'])) { 30 | $container->setParameter('mailjet.transactionnal.call', $config['transactionnal']['call']); 31 | if (isset($config['transactionnal']['options'])) { 32 | $container->setParameter('mailjet.transactionnal.options', $config['transactionnal']['options']); 33 | } else { 34 | $container->setParameter('mailjet.transactionnal.options', array()); 35 | } 36 | } else { 37 | $container->setParameter('mailjet.transactionnal.call', true); 38 | $container->setParameter('mailjet.transactionnal.options', array()); 39 | } 40 | 41 | # Webhook config 42 | $container->setParameter('mailjet.event_endpoint_route', $config['event_endpoint_route']); 43 | $container->setParameter('mailjet.event_endpoint_token', $config['event_endpoint_token']); 44 | 45 | # List config 46 | $container->setParameter('mailjet.lists', $config['lists']); 47 | # Contact Properties config 48 | $container->setParameter('mailjet.contact_metadata', $config['contact_metadata']); 49 | 50 | //set some alias 51 | $container->setAlias('mailjet', 'swiftmailer.mailer.transport.mailjet'); 52 | 53 | $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); 54 | $loader->load('services.yml'); 55 | } 56 | 57 | public function getAlias() 58 | { 59 | return 'mailjet'; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Event/CallbackEvent.php: -------------------------------------------------------------------------------- 1 | data = $data; 36 | } 37 | 38 | /** 39 | * Get data payload from Mailjet Event 40 | * @method getData 41 | * @return array 42 | */ 43 | public function getData() 44 | { 45 | return $this->data; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/Event/ContactEvent.php: -------------------------------------------------------------------------------- 1 | listId = $listId; 23 | $this->contact = $contact; 24 | $this->oldEmail = $oldEmail; 25 | } 26 | 27 | public function getListId() 28 | { 29 | return $this->listId; 30 | } 31 | 32 | public function getContact() 33 | { 34 | return $this->contact; 35 | } 36 | 37 | public function getOldEmail() 38 | { 39 | return $this->oldEmail; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Exception/MailjetException.php: -------------------------------------------------------------------------------- 1 | getStatus(); 43 | $message = sprintf('%s: %s', $message, $response->getReasonPhrase()); 44 | $this->setErrorFromResponse($response); 45 | } 46 | 47 | parent::__construct($message, $statusCode, $previous); 48 | 49 | } 50 | 51 | /** 52 | * Configure MailjetException from Mailjet\Response 53 | * @method setErrorFromResponse 54 | * @param Response $response 55 | */ 56 | private function setErrorFromResponse(Response $response) 57 | { 58 | $this->statusCode = $response->getStatus(); 59 | 60 | $body = $response->getBody(); 61 | if(isset($body['ErrorInfo'])){ 62 | $this->errorInfo = $body['ErrorInfo']; 63 | } 64 | if(isset($body['ErrorMessage'])){ 65 | $this->errorMessage = $body['ErrorMessage']; 66 | } 67 | if(isset($body['ErrorIdentifier'])){ 68 | $this->errorIdentifier = $body['ErrorIdentifier']; 69 | } 70 | } 71 | 72 | /** 73 | * @return string 74 | */ 75 | public function getErrorInfo() 76 | { 77 | return $this->errorInfo; 78 | } 79 | 80 | /** 81 | * @return string 82 | */ 83 | public function getErrorMessage() 84 | { 85 | return $this->errorMessage; 86 | } 87 | 88 | /** 89 | * @return string 90 | */ 91 | public function getErrorIdentifier() 92 | { 93 | return $this->errorIdentifier; 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/Listener/ContactListener.php: -------------------------------------------------------------------------------- 1 | contactManager = $contactManager; 18 | } 19 | 20 | public function onSubscribe(ContactEvent $event) 21 | { 22 | $this->contactManager->subscribe( 23 | $event->getListId(), 24 | $event->getContact() 25 | ); 26 | } 27 | 28 | public function onUnsubscribe(ContactEvent $event) 29 | { 30 | $this->contactManager->unsubscribe( 31 | $event->getListId(), 32 | $event->getContact() 33 | ); 34 | } 35 | 36 | public function onUpdate(ContactEvent $event) 37 | { 38 | $this->contactManager->update( 39 | $event->getListId(), 40 | $event->getContact() 41 | ); 42 | } 43 | 44 | public function onDelete(ContactEvent $event) 45 | { 46 | $this->contactManager->delete( 47 | $event->getListId(), 48 | $event->getContact() 49 | ); 50 | } 51 | 52 | // @TODO How to change user email? (workaround: remove old, add new...) 53 | public function onChangeEmail(ContactEvent $event) 54 | { 55 | $this->contactManager->changeEmail( 56 | $event->getListId(), 57 | $event->getContact(), 58 | $event->getOldEmail() 59 | ); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/MailjetBundle.php: -------------------------------------------------------------------------------- 1 | mailjet = $mailjet; 26 | } 27 | 28 | /** 29 | * List campaigndraft resources available for this apikey 30 | * @return array 31 | */ 32 | public function getAllCampaignDrafts(array $filters = null) 33 | { 34 | $response = $this->mailjet->get(Resources::$Campaigndraft, 35 | ['filters' => $filters]); 36 | if (!$response->success()) { 37 | $this->throwError("CampaignDraftManager :getAllCampaignDrafts() failed", 38 | $response); 39 | } 40 | 41 | return $response->getData(); 42 | } 43 | 44 | /** 45 | * Access a given campaigndraft resource 46 | * @param string $CampaignId 47 | * @return array 48 | */ 49 | public function findByCampaignDraftId($CampaignId) 50 | { 51 | $response = $this->mailjet->get(Resources::$Campaigndraft, 52 | ['id' => $CampaignId]); 53 | if (!$response->success()) { 54 | $this->throwError("CampaignDraftManager:findByCampaignDraftId() failed", 55 | $response); 56 | } 57 | 58 | return $response->getData(); 59 | } 60 | 61 | /** 62 | * create a new fresh CampaignDraft 63 | * @param Campaigndraft $campaignDraft 64 | */ 65 | public function create(CampaignDraft $campaignDraft) 66 | { 67 | $response = $this->mailjet->post(Resources::$Campaigndraft, 68 | ['body' => $campaignDraft->format()]); 69 | if (!$response->success()) { 70 | $this->throwError("CampaignDraftManager:create() failed", $response); 71 | } 72 | 73 | return $response->getData(); 74 | } 75 | 76 | /** 77 | * Update one specific campaigndraft resource 78 | * @param int $id 79 | * @param Campaigndraft $campaignDraft 80 | */ 81 | public function update($CampaignId, CampaignDraft $campaignDraft) 82 | { 83 | $response = $this->mailjet->put(Resources::$Campaigndraft, 84 | ['id' => $CampaignId, 'body' => $campaignDraft->format()]); 85 | if (!$response->success()) { 86 | $this->throwError("CampaignDraftManager:update() failed", $response); 87 | } 88 | 89 | return $response->getData(); 90 | } 91 | 92 | /** 93 | * Return the text and html contents of the campaigndraft 94 | * @param string $id 95 | * @return array 96 | */ 97 | public function getDetailContent($id) 98 | { 99 | $response = $this->mailjet->get(Resources::$CampaigndraftDetailcontent, 100 | ['id' => $id]); 101 | if (!$response->success()) { 102 | $this->throwError("CampaignDraftManager:getDetailContent failed", 103 | $response); 104 | } 105 | 106 | return $response->getData(); 107 | } 108 | 109 | /** 110 | * Creates the content of a campaigndraft 111 | * @param string $id 112 | * @return array 113 | */ 114 | public function createDetailContent($id, $contentData) 115 | { 116 | $response = $this->mailjet->post(Resources::$CampaigndraftDetailcontent, 117 | ['id' => $id, 'body' => $contentData]); 118 | if (!$response->success()) { 119 | $this->throwError("CampaignDraftManager:createDetailContent failed", 120 | $response); 121 | } 122 | 123 | return $response->getData(); 124 | } 125 | 126 | /** 127 | * Return the date of the scheduled sending of the campaigndraft 128 | * @param string Campaign $id 129 | * @return array 130 | */ 131 | public function getSchedule($CampaignId) 132 | { 133 | $response = $this->mailjet->get(Resources::$CampaigndraftSchedule, 134 | ['id' => $CampaignId]); 135 | if (!$response->success()) { 136 | $this->throwError("CampaignDraftManager:getSchedule failed", 137 | $response); 138 | } 139 | 140 | return $response->getData(); 141 | } 142 | 143 | /** 144 | * Schedule when the campaigndraft will be sent 145 | * @param string Campaign $id 146 | * @param string Schedule $date 147 | * @return array 148 | */ 149 | public function scheduleCampaign($CampaignId, $date) 150 | { 151 | $response = $this->mailjet->post(Resources::$CampaigndraftSchedule, 152 | ['id' => $CampaignId, 'body' => $date]); 153 | if (!$response->success()) { 154 | $this->throwError("CampaignDraftManager:scheduleCampaign failed", 155 | $response); 156 | } 157 | 158 | return $response->getData(); 159 | } 160 | 161 | /** 162 | * Update the date when the campaigndraft will be sent 163 | * @param string Campaign $id 164 | * @param string Schedule $date 165 | * @return array 166 | */ 167 | public function updateCampaignSchedule($CampaignId, $date) 168 | { 169 | $response = $this->mailjet->put(Resources::$CampaigndraftSchedule, 170 | ['id' => $CampaignId, 'body' => $date]); 171 | if (!$response->success()) { 172 | $this->throwError("CampaignDraftManager:updateCampaignSchedule failed", 173 | $response); 174 | } 175 | 176 | return $response->getData(); 177 | } 178 | 179 | /** 180 | * Cancel a future sending 181 | * @param string Campaign $id 182 | * @return array 183 | */ 184 | public function removeSchedule($CampaignId) 185 | { 186 | $response = $this->mailjet->delete(Resources::$CampaigndraftSchedule, 187 | ['id' => $CampaignId]); 188 | if (!$response->success()) { 189 | $this->throwError("CampaignDraftManager:removeSchedule failed", 190 | $response); 191 | } 192 | 193 | return $response->getData(); 194 | } 195 | 196 | /** 197 | * Send the campaign immediately 198 | * @param string Campaign $id 199 | * @return array 200 | */ 201 | public function sendCampaign($CampaignId) 202 | { 203 | $response = $this->mailjet->post(Resources::$CampaigndraftSend, 204 | ['id' => $CampaignId]); 205 | if (!$response->success()) { 206 | $this->throwError("CampaignDraftManager:sendCampaign failed", 207 | $response); 208 | } 209 | 210 | return $response->getData(); 211 | } 212 | 213 | /** 214 | * Return the status of a CampaignDraft 215 | * @param string Campaign $id 216 | * @return array 217 | */ 218 | public function getCampaignStatus($CampaignId) 219 | { 220 | $response = $this->mailjet->get(Resources::$CampaigndraftStatus, 221 | ['id' => $CampaignId]); 222 | if (!$response->success()) { 223 | $this->throwError("CampaignDraftManager:getCampaignStatus failed", 224 | $response); 225 | } 226 | 227 | return $response->getData(); 228 | } 229 | 230 | /** 231 | * An action to test a CampaignDraft. 232 | * @param string Campaign $id 233 | * @param array of $recipients 234 | * @return array 235 | */ 236 | public function testCampaign($CampaignId, $recipients) 237 | { 238 | $response = $this->mailjet->post(Resources::$CampaigndraftTest, 239 | ['id' => $CampaignId, 'body' => $recipients]); 240 | if (!$response->success()) { 241 | $this->throwError("CampaignDraftManager:getCampaignStatus failed", 242 | $response); 243 | } 244 | 245 | return $response->getData(); 246 | } 247 | 248 | private function throwError($title, Response $response) 249 | { 250 | throw new MailjetException(0, $title, $response); 251 | } 252 | } -------------------------------------------------------------------------------- /src/Manager/CampaignManager.php: -------------------------------------------------------------------------------- 1 | mailjet = $mailjet; 25 | } 26 | 27 | /** 28 | * List campaigns resources available for this apikey 29 | * @return array 30 | */ 31 | public function getAllCampaigns(array $filters = null) { 32 | $response = $this->mailjet->get(Resources::$Campaign, ['filters' => $filters]); 33 | if (!$response->success()) { 34 | $this->throwError("CampaignDraftManager:getAllCampaigns() failed", $response); 35 | } 36 | 37 | return $response->getData(); 38 | } 39 | 40 | /** 41 | * Access a given campaign resource 42 | * @param string $CampaignId 43 | * @return array 44 | */ 45 | public function findByCampaignId($CampaignId) { 46 | $response = $this->mailjet->get(Resources::$Campaign, ['id' => $CampaignId]); 47 | if (!$response->success()) { 48 | $this->throwError("CampaignManager:findByCampaignId() failed", $response); 49 | } 50 | 51 | return $response->getData(); 52 | } 53 | 54 | /** 55 | * Update one specific campaign resource with a PUT request, providing the campaign's ID value 56 | * @param string $id 57 | * @return array 58 | */ 59 | public function updateCampaign($CampaignId, Campaign $campaign) { 60 | $response = $this->mailjet->put(Resources::$Campaign, ['id' => $CampaignId, 'body' => $campaign->format()]); 61 | if (!$response->success()) { 62 | $this->throwError("CampaignManager:updateCampaign() failed", $response); 63 | } 64 | 65 | return $response->getData(); 66 | } 67 | 68 | private function throwError($title, Response $response) { 69 | throw new MailjetException(0, $title, $response); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/Manager/ContactMetadataManager.php: -------------------------------------------------------------------------------- 1 | mailjet = $mailjet; 31 | } 32 | 33 | /** 34 | * Retrieve all ContactMetadata 35 | * @return array 36 | */ 37 | public function getAll() 38 | { 39 | $response = $this->mailjet->get(Resources::$Contactmetadata); 40 | if (!$response->success()) { 41 | $this->throwError("ContactMetadataManager:getAll() failed", $response); 42 | } 43 | 44 | return $response->getData(); 45 | } 46 | 47 | /** 48 | * Retrieve one ContactMetadata 49 | * @param string $id 50 | * @return array 51 | */ 52 | public function get($id) 53 | { 54 | $response = $this->mailjet->get(Resources::$Contactmetadata, ['id' => $id]); 55 | if (!$response->success()) { 56 | $this->throwError("ContactMetadataManager:get() failed", $response); 57 | } 58 | 59 | return $response->getData(); 60 | } 61 | 62 | /** 63 | * create a new fresh ContactMetadata 64 | * @param ContactMetadata $contactMetadata 65 | */ 66 | public function create(ContactMetadata $contactMetadata) 67 | { 68 | $response = $this->mailjet->post(Resources::$Contactmetadata, ['body' => $contactMetadata->format()]); 69 | if (!$response->success()) { 70 | $this->throwError("ContactMetadataManager:create() failed", $response); 71 | } 72 | 73 | return $response->getData(); 74 | } 75 | 76 | /** 77 | * Update one ContactMetadata 78 | * @param int $id 79 | * @param ContactMetadata $contactMetadata 80 | */ 81 | public function update($id, ContactMetadata $contactMetadata) 82 | { 83 | $response = $this->mailjet->put(Resources::$Contactmetadata, ['id' => $id,'body' => $contactMetadata->format()]); 84 | if (!$response->success()) { 85 | $this->throwError("ContactMetadataManager:update() failed", $response); 86 | } 87 | 88 | return $response->getData(); 89 | } 90 | 91 | /** 92 | * Delete one ContactMetadata 93 | * @param int $id 94 | */ 95 | public function delete($id) 96 | { 97 | $response = $this->mailjet->delete(Resources::$Contactmetadata, ['id' => $id]); 98 | if (!$response->success()) { 99 | $this->throwError("ContactMetadataManager:delete() failed", $response); 100 | } 101 | 102 | return $response->getData(); 103 | } 104 | 105 | /** 106 | * Helper to throw error 107 | * @param string $title 108 | * @param Response $response 109 | */ 110 | private function throwError($title, Response $response) 111 | { 112 | throw new MailjetException(0, $title, $response); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/Manager/ContactsListManager.php: -------------------------------------------------------------------------------- 1 | mailjet = $mailjet; 37 | } 38 | 39 | /** 40 | * create a new fresh Contact to listId 41 | * @param string $listId 42 | * @param Contact $contact 43 | * @param string $action 44 | */ 45 | public function create($listId, Contact $contact, $action=Contact::ACTION_ADDFORCE) 46 | { 47 | $contact->setAction($action); 48 | $response = $this->_exec($listId, $contact); 49 | if (!$response->success()) { 50 | $this->throwError("ContactsListManager:create() failed", $response); 51 | } 52 | 53 | return $response->getData(); 54 | } 55 | 56 | /** 57 | * update a Contact to listId 58 | * @param string $listId 59 | * @param Contact $contact 60 | * @param string $action 61 | */ 62 | public function update($listId, Contact $contact, $action=Contact::ACTION_ADDNOFORCE) 63 | { 64 | $contact->setAction($action); 65 | $response = $this->_exec($listId, $contact); 66 | if (!$response->success()) { 67 | $this->throwError("ContactsListManager:update() failed", $response); 68 | } 69 | 70 | return $response->getData(); 71 | } 72 | 73 | /** 74 | * re/subscribe a Contact to listId 75 | * @param string $listId 76 | * @param Contact $contact 77 | * @param bool $force 78 | */ 79 | public function subscribe($listId, Contact $contact, $force = true) 80 | { 81 | if ($force) { 82 | $contact->setAction(Contact::ACTION_ADDFORCE); 83 | } else { 84 | $contact->setAction(Contact::ACTION_ADDNOFORCE); 85 | } 86 | $response = $this->_exec($listId, $contact); 87 | if (!$response->success()) { 88 | $this->throwError("ContactsListManager:sub() failed", $response); 89 | } 90 | 91 | return $response->getData(); 92 | } 93 | 94 | /** 95 | * unsubscribe a Contact from listId 96 | * @param string $listId 97 | * @param Contact $contact 98 | */ 99 | public function unsubscribe($listId, Contact $contact) 100 | { 101 | $contact->setAction(Contact::ACTION_UNSUB); 102 | $response = $this->_exec($listId, $contact); 103 | if (!$response->success()) { 104 | $this->throwError("ContactsListManager:unsub() failed", $response); 105 | } 106 | 107 | return $response->getData(); 108 | } 109 | 110 | /** 111 | * Delete a Contact from listId 112 | * @param string $listId 113 | * @param Contact $contact 114 | */ 115 | public function delete($listId, Contact $contact) 116 | { 117 | $contact->setAction(Contact::ACTION_REMOVE); 118 | $response = $this->_exec($listId, $contact); 119 | if (!$response->success()) { 120 | $this->throwError("ContactsListManager:delete() failed", $response); 121 | } 122 | 123 | return $response->getData(); 124 | } 125 | 126 | /** 127 | * Change email a Contact 128 | * @param string $listId 129 | * @param Contact $contact 130 | * @param string $oldEmail 131 | */ 132 | public function changeEmail($listId, Contact $contact, $oldEmail) 133 | { 134 | // get old contact properties 135 | $response = $this->mailjet->get(Resources::$Contactdata, ['id' => $oldEmail]); 136 | if (!$response->success()) { 137 | $this->throwError("ContactsListManager:changeEmail() failed", $response); 138 | } 139 | 140 | // copy contact properties 141 | $oldContactData = $response->getData(); 142 | if (isset($oldContactData[0])) { 143 | $contact->setProperties($oldContactData[0]['Data']); 144 | } 145 | 146 | // add new contact 147 | $contact->setAction(Contact::ACTION_ADDFORCE); 148 | $response = $this->_exec($listId, $contact); 149 | if (!$response->success()) { 150 | $this->throwError("ContactsListManager:changeEmail() failed", $response); 151 | } 152 | 153 | // remove old 154 | $oldContact = new Contact($oldEmail); 155 | $oldContact->setAction(Contact::ACTION_REMOVE); 156 | $response = $this->_exec($listId, $oldContact); 157 | if (!$response->success()) { 158 | $this->throwError("ContactsListManager:changeEmail() failed", $response); 159 | } 160 | 161 | return $response->getData(); 162 | } 163 | 164 | /** 165 | * Manage Many Contacts to List 166 | * https://dev.mailjet.com/email-api/v3/contactslist-managemanycontacts/ 167 | * @param ContactsList $contactsList 168 | * @return array 169 | */ 170 | public function manageManyContactsList(ContactsList $contactsList) 171 | { 172 | $batchResults = []; 173 | // we send multiple smaller requests instead of a bigger one 174 | $contactChunks = array_chunk($contactsList->getContacts(), self::CONTACT_BATCH_SIZE); 175 | foreach ($contactChunks as $contactChunk) { 176 | // create a sub-contactList to divide large request 177 | $subContactsList = new ContactsList($contactsList->getListId(), $contactsList->getAction(), $contactChunk); 178 | $currentBatch = $this->mailjet->post(Resources::$ContactslistManagemanycontacts, 179 | ['id' => $subContactsList->getListId(), 'body' => $subContactsList->format()] 180 | ); 181 | if ($currentBatch->success()) { 182 | array_push($batchResults, $currentBatch->getData()[0]); 183 | } else { 184 | $this->throwError("ContactsListManager:manageManyContactsList() failed", $currentBatch); 185 | } 186 | } 187 | return $batchResults; 188 | } 189 | 190 | /** 191 | * An action for adding a contact to a contact list. Only POST is supported. 192 | * The API will internally create the new contact if it does not exist, 193 | * add or update the name and properties. 194 | * The properties have to be defined before they can be used. 195 | * The API then adds the contact to the contact list with active=true and 196 | * unsub=specified value if it is not already in the list, 197 | * or updates the entry with these values. On success, 198 | * the API returns a packet with the same format but with all properties available 199 | * for that contact. 200 | * @param string $listId 201 | * @param Contact $contact 202 | */ 203 | private function _exec($listId, Contact $contact) 204 | { 205 | return $this->mailjet->post(Resources::$ContactslistManagecontact, 206 | ['id' => $listId, 'body' => $contact->format()] 207 | ); 208 | } 209 | 210 | /** 211 | * Helper to throw error 212 | * @param string $title 213 | * @param Response $response 214 | */ 215 | private function throwError($title, Response $response) 216 | { 217 | throw new MailjetException(0, $title, $response); 218 | } 219 | } 220 | -------------------------------------------------------------------------------- /src/Manager/EventCallbackUrlManager.php: -------------------------------------------------------------------------------- 1 | mailjet = $mailjet; 31 | } 32 | 33 | /** 34 | * Retrieve all EventCallbackUrl 35 | * @return array 36 | */ 37 | public function getAll() 38 | { 39 | $response = $this->mailjet->get(Resources::$Eventcallbackurl); 40 | if (!$response->success()) { 41 | $this->throwError("EventCallbackUrlManager:getAll() failed", $response); 42 | } 43 | 44 | return $response->getData(); 45 | } 46 | 47 | /** 48 | * Retrieve one EventCallbackUrl 49 | * @param string $id 50 | * @return array 51 | */ 52 | public function get($id) 53 | { 54 | $response = $this->mailjet->get(Resources::$Eventcallbackurl, ['id' => $id]); 55 | if (!$response->success()) { 56 | $this->throwError("EventCallbackUrlManager:get() failed", $response); 57 | } 58 | 59 | return $response->getData(); 60 | } 61 | 62 | /** 63 | * Create one EventCallbackUrl 64 | * @param EventCallbackUrl $eventCallbackUrl 65 | * @return array 66 | */ 67 | public function create(EventCallbackUrl $eventCallbackUrl) 68 | { 69 | $response = $this->mailjet->post(Resources::$Eventcallbackurl, ['body' => $eventCallbackUrl->format()]); 70 | if (!$response->success()) { 71 | $this->throwError("EventCallbackUrlManager:create() failed", $response); 72 | } 73 | 74 | return $response->getData(); 75 | } 76 | 77 | /** 78 | * Update one EventCallbackUrl 79 | * @param string $id 80 | * @param EventCallbackUrl $eventCallbackUrl 81 | * @return array 82 | */ 83 | public function update($id, EventCallbackUrl $eventCallbackUrl) 84 | { 85 | $response = $this->mailjet->put(Resources::$Eventcallbackurl, ['id' => $id, 'body' => $eventCallbackUrl->format()]); 86 | if (!$response->success()) { 87 | $this->throwError("EventCallbackUrlManager:update() failed", $response); 88 | } 89 | 90 | return $response->getData(); 91 | } 92 | 93 | /** 94 | * Delete one EventCallbackUrl 95 | * @param string $id 96 | * @return array 97 | */ 98 | public function delete($id) 99 | { 100 | $response = $this->mailjet->delete(Resources::$Eventcallbackurl, ['id' => $id]); 101 | if (!$response->success()) { 102 | $this->throwError("EventCallbackUrlManager:delete() failed", $response); 103 | } 104 | 105 | return $response->getData(); 106 | } 107 | 108 | /** 109 | * Helper to throw error 110 | * @param string $title 111 | * @param Response $response 112 | * @param array $response 113 | */ 114 | private function throwError($title, Response $response) 115 | { 116 | throw new MailjetException(0, $title, $response); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/Manager/TemplateManager.php: -------------------------------------------------------------------------------- 1 | mailjet = $mailjet; 26 | } 27 | 28 | /** 29 | * List template resources available for this apikey, use a GET request. 30 | * Alternatively, you may want to add one or more filters. 31 | * @param array optional $filters 32 | * @return templates 33 | */ 34 | public function getAll(array $filters = null) 35 | { 36 | $response = $this->mailjet->get(Resources::$Template, 37 | ['filters' => $filters]); 38 | if (!$response->success()) { 39 | $this->throwError("TemplateManager :getAll() failed", $response); 40 | } 41 | 42 | return $response->getData(); 43 | } 44 | 45 | /** 46 | * Access a given template resource, use a GET request, providing the template's ID value 47 | * @param string $id 48 | * @return $Template 49 | */ 50 | public function get($id) 51 | { 52 | $response = $this->mailjet->get(Resources::$Template, ['id' => $id]); 53 | if (!$response->success()) { 54 | $this->throwError("TemplateManager:get() failed", $response); 55 | } 56 | 57 | return $response->getData(); 58 | } 59 | 60 | /** 61 | * Add a new template resource with a POST request. 62 | * @param Template $Template 63 | */ 64 | public function create(Template $Template) 65 | { 66 | $response = $this->mailjet->post(Resources::$Template, 67 | ['body' => $Template->format()]); 68 | if (!$response->success()) { 69 | $this->throwError("TemplateManager:create() failed", $response); 70 | } 71 | 72 | return $response->getData(); 73 | } 74 | 75 | /** 76 | * Update one specific template resource with a PUT request, providing the template's ID value 77 | * @param int $id 78 | * @param Template $Template 79 | */ 80 | public function update($id, Template $Template) 81 | { 82 | $response = $this->mailjet->put(Resources::$Template, 83 | ['id' => $id, 'body' => $Template->format()]); 84 | if (!$response->success()) { 85 | $this->throwError("TemplateManager:update() failed", $response); 86 | } 87 | 88 | return $response->getData(); 89 | } 90 | 91 | /** 92 | * delete a given template 93 | * @param string $id 94 | * @return array 95 | */ 96 | public function delete($id) 97 | { 98 | $response = $this->mailjet->delete(Resources::$Template, ['id' => $id]); 99 | if (!$response->success()) { 100 | $this->throwError("TemplateManager:delete() failed", $response); 101 | } 102 | 103 | return $response->getData(); 104 | } 105 | 106 | /** 107 | * Return the text and html contents of the Template 108 | * @param string $id 109 | * @return array 110 | */ 111 | public function getDetailContent($id) 112 | { 113 | $response = $this->mailjet->get(Resources::$TemplateDetailcontent, 114 | ['id' => $id]); 115 | if (!$response->success()) { 116 | $this->throwError("TemplateManager:getDetailContent failed", 117 | $response); 118 | } 119 | 120 | return $response->getData(); 121 | } 122 | 123 | /** 124 | * Creates the content of a Template 125 | * @return array 126 | */ 127 | public function createDetailContent($id, $contentData) 128 | { 129 | $response = $this->mailjet->post(Resources::$TemplateDetailcontent, 130 | ['id' => $id, 'body' => $contentData]); 131 | if (!$response->success()) { 132 | $this->throwError("TemplateManager:createDetailContent failed", 133 | $response); 134 | } 135 | 136 | return $response->getData(); 137 | } 138 | 139 | /** 140 | * Deletes the content of a Template 141 | * @return array 142 | */ 143 | public function deleteDetailContent($id) 144 | { 145 | $nullContent = null; 146 | $response = $this->mailjet->post(Resources::$TemplateDetailcontent, 147 | ['id' => $id, 'body' => $nullContent]); 148 | if (!$response->success()) { 149 | $this->throwError("TemplateManager:createDetailContent failed", 150 | $response); 151 | } 152 | 153 | return $response->getData(); 154 | } 155 | 156 | private function throwError($title, Response $response) 157 | { 158 | throw new MailjetException(0, $title, $response); 159 | } 160 | } -------------------------------------------------------------------------------- /src/Model/Campaign.php: -------------------------------------------------------------------------------- 1 | fromEmail = $fromEmail; 28 | $this->optionalProperties = $optionalProperties; 29 | } 30 | 31 | /** 32 | * Format Campaign for MailJet API request 33 | * @return array 34 | */ 35 | public function format() { 36 | 37 | /* * Add the mandatary props* */ 38 | if (!is_null($this->fromEmail)) { 39 | $result[self::FROMEMAIL_KEY] = $this->fromEmail; 40 | } 41 | /* * Add the optional props if any* */ 42 | if (!is_null($this->optionalProperties)) { 43 | $result = array_merge($result, $this->optionalProperties); 44 | } 45 | 46 | 47 | return $result; 48 | } 49 | 50 | /** 51 | * Correspond to properties in MailJet request 52 | * Array ['PropertyName' => value, ...] 53 | */ 54 | public function getOptionalProperties() { 55 | return $this->optionalProperties; 56 | } 57 | 58 | /** 59 | * Set array of Campaign properties 60 | * @param array $properties 61 | * @return Properties 62 | */ 63 | public function setOptionalProperties(array $properties) { 64 | $this->optionalProperties = $properties; 65 | return $this->optionalProperties; 66 | } 67 | 68 | /** 69 | * Add a new $property to Campaign 70 | * @param array $property 71 | * @return Properties 72 | */ 73 | public function addOptionalProperty($property) { 74 | $this->optionalProperties[] = $property; 75 | return $this->optionalProperties; 76 | } 77 | 78 | /** 79 | * Remove a $property from Campaign 80 | * @param array $property 81 | * @return Properties 82 | */ 83 | public function removeOptionalProperty($property) { 84 | foreach (array_keys($this->optionalProperties, $property) as $key) { 85 | unset($this->optionalProperties[$key]); 86 | } 87 | return $this->optionalProperties; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/Model/CampaignDraft.php: -------------------------------------------------------------------------------- 1 | locale = $locale; 39 | $this->sender = $sender; 40 | $this->senderEmail = $senderEmail; 41 | $this->subject = $subject; 42 | $this->contactsListID = $contactsListID; 43 | $this->optionalProperties = $optionalProperties; 44 | } 45 | 46 | /** 47 | * Format CampaignDraft for MailJet API request 48 | * @return array 49 | */ 50 | public function format() { 51 | 52 | /* * Add the mandatary props* */ 53 | if (!is_null($this->locale)) { 54 | $result[self::LOCALE_KEY] = $this->locale; 55 | } 56 | 57 | if (!is_null($this->sender)) { 58 | $result[self::SENDER_KEY] = $this->sender; 59 | } 60 | 61 | if (!is_null($this->senderEmail)) { 62 | $result[self::SENDEREMAIL_KEY] = $this->senderEmail; 63 | } 64 | if (!is_null($this->subject)) { 65 | $result[self::SUBJECT_KEY] = $this->subject; 66 | } 67 | if (!is_null($this->contactsListID)) { 68 | $result[self::CONTACTLISTID_KEY] = $this->contactsListID; 69 | } 70 | /* * Add the optional props if any* */ 71 | if (!is_null($this->optionalProperties)) { 72 | $result = array_merge($result, $this->optionalProperties); 73 | } 74 | 75 | 76 | return $result; 77 | } 78 | 79 | /** 80 | * Correspond to properties in MailJet request 81 | * Array ['PropertyName' => value, ...] 82 | */ 83 | public function getOptionalProperties() { 84 | return $this->optionalProperties; 85 | } 86 | 87 | /** 88 | * Set array of CampaignDraft properties 89 | * @param array $property 90 | * @return Properties 91 | */ 92 | public function setOptionalProperties(array $properties) { 93 | $this->optionalProperties = $properties; 94 | return $this->optionalProperties; 95 | } 96 | 97 | /** 98 | * Add a new $property to CampaignDraft 99 | * @param array $property 100 | * @return Properties 101 | */ 102 | public function addOptionalProperty($property) { 103 | $this->optionalProperties[] = $property; 104 | return $this->optionalProperties; 105 | } 106 | 107 | /** 108 | * Remove a $property from CampaignDraft 109 | * @param array $property 110 | * @return Properties 111 | */ 112 | public function removeOptionalProperty($property) { 113 | foreach (array_keys($this->optionalProperties, $property) as $key) { 114 | unset($this->optionalProperties[$key]); 115 | } 116 | return $this->optionalProperties; 117 | } 118 | 119 | /** 120 | * Get CampaignDraft content 121 | * @return $content 122 | */ 123 | public function setContent($content) { 124 | $this->content = $content; 125 | } 126 | 127 | /** 128 | * Get CampaignDraft content 129 | * @return $content 130 | */ 131 | public function getContent() { 132 | return $this->content; 133 | } 134 | 135 | /** 136 | * Get CampaignDraft id 137 | * @return $content 138 | */ 139 | public function getId() { 140 | return $this->id; 141 | } 142 | 143 | /** 144 | * Set CampaignDraft Id 145 | * @return $content 146 | */ 147 | public function setId($id) { 148 | $this->id = $id; 149 | } 150 | 151 | } 152 | -------------------------------------------------------------------------------- /src/Model/Contact.php: -------------------------------------------------------------------------------- 1 | email = $email; 29 | $this->name = $name; 30 | $this->properties = $properties; 31 | } 32 | 33 | /** 34 | * Formate contact for MailJet API request 35 | * @return array 36 | */ 37 | public function format() 38 | { 39 | $result = [ 40 | self::EMAIL_KEY => $this->email, 41 | ]; 42 | 43 | if (!is_null($this->name)) { 44 | $result[self::NAME_KEY] = $this->name; 45 | } 46 | 47 | if (!is_null($this->action)) { 48 | $result[self::ACTION_KEY] = $this->action; 49 | } 50 | 51 | if (!is_null($this->properties)) { 52 | #$result[self::PROPERTIES_KEY] = $this->removeNullProperties($this->properties); 53 | $result[self::PROPERTIES_KEY] = $this->properties; 54 | } 55 | 56 | return $result; 57 | } 58 | 59 | /** 60 | * Correspond to Email in Mailjet request 61 | */ 62 | public function getEmail() 63 | { 64 | return $this->email; 65 | } 66 | 67 | /** 68 | * Set contact email 69 | * @param string $email 70 | * @return Contact 71 | */ 72 | public function setEmail($email) 73 | { 74 | $this->email = $email; 75 | return $this; 76 | } 77 | 78 | /** 79 | * Correspond to Name in MailJet request 80 | */ 81 | public function getName() 82 | { 83 | return $this->name; 84 | } 85 | 86 | /** 87 | * Set contact name 88 | * @param string $name 89 | * @return Contact 90 | */ 91 | public function setName($name) 92 | { 93 | $this->name = $name; 94 | return $this; 95 | } 96 | 97 | /** 98 | * Correspond to Properties in MailJet request 99 | * Array ['property' => value, ...] 100 | */ 101 | public function getProperties() 102 | { 103 | return $this->properties; 104 | } 105 | 106 | /** 107 | * Set array of Contact properties 108 | * @param array $properties 109 | * @return Contact 110 | */ 111 | public function setProperties(array $properties) 112 | { 113 | $this->properties = $properties; 114 | return $this; 115 | } 116 | 117 | /** 118 | * Action to the contact for Synchronization 119 | * @return string 120 | */ 121 | public function getAction() 122 | { 123 | return $this->action; 124 | } 125 | 126 | /** 127 | * Action to the contact for Synchronization 128 | * @param string $action ACTION_* 129 | * @return Contact 130 | */ 131 | public function setAction($action) 132 | { 133 | $this->action = $action; 134 | return $this; 135 | } 136 | 137 | /** 138 | * Clean null properties to avoid conflict with API 139 | * @param array $properties 140 | * @return array 141 | */ 142 | protected function removeNullProperties(array $properties) 143 | { 144 | return array_filter($properties); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/Model/ContactMetadata.php: -------------------------------------------------------------------------------- 1 | name = $name; 23 | $this->datatype = $datatype; 24 | } 25 | 26 | /** 27 | * Formate contact for Mailjet API request 28 | * @return array 29 | */ 30 | public function format() 31 | { 32 | $result = [ 33 | 'Name' => $this->name, 34 | 'Datatype' => $this->datatype, 35 | ]; 36 | 37 | return $result; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Model/ContactsList.php: -------------------------------------------------------------------------------- 1 | validateAction($action)) { 29 | throw new \RuntimeException("$action: is not a valide Action."); 30 | } 31 | 32 | $this->listId = $listId; 33 | $this->action = $action; 34 | $this->contacts = $contacts; 35 | } 36 | 37 | /** 38 | * Formate contactList for MailJet API request 39 | * @return array 40 | */ 41 | public function format() 42 | { 43 | $result = [ 44 | 'Action' => $this->action, 45 | 'Contacts' => [], 46 | ]; 47 | 48 | $contacts = $this->contacts; 49 | $contactsArray = array_map(function (Contact $contact) { 50 | return $contact->format(); 51 | }, $contacts); 52 | 53 | $result['Contacts'] = $contactsArray; 54 | 55 | return $result; 56 | } 57 | 58 | /** 59 | * Get list id 60 | */ 61 | public function getListId() 62 | { 63 | return $this->listId; 64 | } 65 | 66 | /** 67 | * Set Action 68 | * @param string $action 69 | */ 70 | public function setAction($action) 71 | { 72 | if (!$this->validateAction($action)) { 73 | throw new \RuntimeException("$action: is not a valide Action."); 74 | } 75 | 76 | $this->action = $action; 77 | 78 | return $this; 79 | } 80 | 81 | /** 82 | * Get action 83 | */ 84 | public function getAction() 85 | { 86 | return $this->action; 87 | } 88 | 89 | /** 90 | * Get contacts 91 | */ 92 | public function getContacts() 93 | { 94 | return $this->contacts; 95 | } 96 | 97 | /** 98 | * Validate if action is authorized 99 | * @param string $action 100 | * @return bool 101 | */ 102 | private function validateAction($action) 103 | { 104 | $actionAvailable = [self::ACTION_ADDFORCE, self::ACTION_ADDNOFORCE, self::ACTION_REMOVE, self::ACTION_UNSUB]; 105 | if (in_array($action, $actionAvailable)) { 106 | return true; 107 | } 108 | return false; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/Model/EventCallbackUrl.php: -------------------------------------------------------------------------------- 1 | url = $url; 55 | $this->eventType = $eventType; 56 | $this->isBackup = $isBackup; 57 | $this->status = $status; 58 | $this->version = $version; 59 | $this->apikeyId = $apikeyId; 60 | $this->groupEvent = $groupEvent; 61 | } 62 | 63 | /** 64 | * Formate contactList for MailJet API request 65 | * @return array 66 | */ 67 | public function format() 68 | { 69 | if ($this->groupEvent) { 70 | // ugly fix for misunderstanding of this... 71 | $this->version = 2; 72 | } 73 | 74 | $result = [ 75 | 'Url' => $this->url, 76 | 'EventType' => $this->eventType, 77 | 'IsBackup' => $this->isBackup, 78 | 'Status' => $this->status, 79 | 'Version' => $this->version 80 | ]; 81 | 82 | if($this->apikeyId){ 83 | $result['APIKeyID'] = $this->apikeyId; 84 | } 85 | 86 | return $result; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/Model/Template.php: -------------------------------------------------------------------------------- 1 | name = $name; 28 | $this->optionalProperties = $optionalProperties; 29 | } 30 | 31 | /** 32 | * Format Template for MailJet API request 33 | * @return array 34 | */ 35 | public function format() { 36 | 37 | /* * Add the mandatary props* */ 38 | if (!is_null($this->name)) { 39 | $result[self::NAME_KEY] = $this->name; 40 | } 41 | 42 | /* * Add the optional props if any* */ 43 | if (!is_null($this->optionalProperties)) { 44 | $result = array_merge($result, $this->optionalProperties); 45 | } 46 | 47 | 48 | return $result; 49 | } 50 | 51 | /** 52 | * Correspond to properties in MailJet request 53 | * Array ['PropertyName' => value, ...] 54 | */ 55 | public function getOptionalProperties() { 56 | return $this->optionalProperties; 57 | } 58 | 59 | /** 60 | * Set array of Template properties 61 | * @param array $property 62 | * @return Properties 63 | */ 64 | public function setOptionalProperties(array $properties) { 65 | $this->optionalProperties = $properties; 66 | return $this->optionalProperties; 67 | } 68 | 69 | /** 70 | * Add a new $property to Template 71 | * @param array $property 72 | * @return Properties 73 | */ 74 | public function addProperty($property) { 75 | $this->optionalProperties[] = $property; 76 | return $this->optionalProperties; 77 | } 78 | 79 | /** 80 | * Remove a $property from Template 81 | * @param array $property 82 | * @return Properties 83 | */ 84 | public function removeProperty($property) { 85 | foreach (array_keys($this->optionalProperties, $property) as $key) { 86 | unset($this->optionalProperties[$key]); 87 | } 88 | return $this->optionalProperties; 89 | } 90 | 91 | /** 92 | * Get Template content 93 | * @return $content 94 | */ 95 | public function setContent($content) { 96 | $this->content = $content; 97 | } 98 | 99 | /** 100 | * Get Template content 101 | * @return $content 102 | */ 103 | public function getContent() { 104 | return $this->content; 105 | } 106 | 107 | /** 108 | * Get Template id 109 | * @return $content 110 | */ 111 | public function getId() { 112 | return $this->id; 113 | } 114 | 115 | /** 116 | * Set Template Id 117 | * @return $content 118 | */ 119 | public function setId($id) { 120 | $this->id = $id; 121 | } 122 | 123 | } 124 | -------------------------------------------------------------------------------- /src/Provider/ExampleContactProvider.php: -------------------------------------------------------------------------------- 1 | userRepository = $userRepository; 25 | } 26 | 27 | public function getContacts() 28 | { 29 | $users = $this->userRepository->findUsers(); 30 | 31 | $contacts = array_map(function(User $user) { 32 | $userProperties = [ 33 | self::PROP_NICKNAME => $user->getNickname(), 34 | self::PROP_GENDER => $user->getGender(), 35 | self::PROP_CITY => $user->getCity(), 36 | self::PROP_BIRTHDATE => $user->getBirthday() ? $user->getBirthday()->format('Y-m-d') : '', 37 | self::PROP_LAST_ACTIVITY_DATE => $user->getLastActivity() ? $user->getLastActivity()->format('Y-m-d') : '' 38 | self::PROP_REGISTRATION_DATE => $user->getRegistrateAt() ? $user->getRegistrateAt()->format('Y-m-d') : '' 39 | ]; 40 | 41 | $contact = new Contact($user->getEmail(), $user->getUsername(), $userProperties); 42 | 43 | return $contact; 44 | }, $users); 45 | 46 | return $contacts; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Provider/FosContactProvider.php: -------------------------------------------------------------------------------- 1 | userManager = $userManager; 22 | } 23 | 24 | public function getContacts() 25 | { 26 | $users = $this->userManager->findUsers(); 27 | // or find only enabled users : 28 | // $users = $this->userManager->findUserBy(array('enabled' => true)); 29 | 30 | $contacts = array_map(function (User $user) { 31 | $userProperties = [ 32 | self::PROP_ENABLED => $user->isEnabled(), 33 | self::PROP_LAST_LOGIN => $user->getLastLogin() ? $user->getLastLogin()->format('Y-m-d') : '' 34 | ]; 35 | 36 | $contact = new Contact($user->getEmail(), $user->getUsername(), $userProperties); 37 | 38 | return $contact; 39 | }, $users); 40 | 41 | return $contacts; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Provider/ProviderInterface.php: -------------------------------------------------------------------------------- 1 | 15 | -------------------------------------------------------------------------------- /src/Resources/doc/build-documentation.md: -------------------------------------------------------------------------------- 1 | # Build documentation 2 | 3 | You can read files in the folder `src/Resources/doc` or you can compile the documentation with MkDocs. 4 | 5 | ## MkDocs 6 | 7 | * Install Python 2.7 and Pip 1.5 8 | * Install MkDocs: `pip install mkdocs` 9 | * Install pymdown-extension: `pip install pymdown-extensions` 10 | * Compile the doc: `mkdocs build` 11 | * Preview the doc: `mkdocs serve` at 12 | 13 | ## Deploy to gh-pages 14 | 15 | Documentation is deployed here: 16 | 17 | In order to deploy a new version of documentation: `mkdocs gh-deploy` 18 | -------------------------------------------------------------------------------- /src/Resources/doc/configuration.md: -------------------------------------------------------------------------------- 1 | # Configuration 2 | 3 | You need to have Mailjet account available 4 | 5 | ## config.yml 6 | 7 | Define a configuration in your `config.yml`: 8 | 9 | ```yaml 10 | mailjet: 11 | api_key: "%mailjet.api_key%" 12 | secret_key: "%mailjet.secret_key%" 13 | call: true # (Default: true) - Performs the API call or not 14 | options: 15 | url: "api.mailjet.com" # (Default: api.mailjet.com) - domain name of the API 16 | version: "v3" # (Default: v3) - API version (only working for Mailjet API V3 +) 17 | call: true # (Default: true) - turns on(true) / off the call to the API 18 | secured: true # (Default: true) - turns on(true) / off the use of 'https' 19 | transactionnal: 20 | call: true # (Default: true) - Performs the API call or not 21 | options: 22 | url: "api.mailjet.com" # (Default: api.mailjet.com) - domain name of the API 23 | version: "v3" # (Default: v3) - API version (only working for Mailjet API V3 +) 24 | call: true # (Default: true) - turns on(true) / off the call to the API 25 | secured: true # (Default: true) - turns on(true) / off the use of 'https' 26 | # route name to handle the callback, if you want to change it 27 | event_endpoint_route: app_event_endpoint_route 28 | # secret to secure callback 29 | event_endpoint_token: "secretCode12345678" 30 | lists: 31 | listId1: 32 | # provider used in full synchronization 33 | contact_provider: 'yourapp.provider1' 34 | listId2: 35 | contact_provider: 'yourapp.provider2' 36 | # ... 37 | contact_metadata: 38 | - 39 | name: firstname 40 | datatype: str 41 | - 42 | name: lastname 43 | datatype: str 44 | - 45 | name: postalcode 46 | datatype: int 47 | - 48 | name: rank 49 | datatype: int 50 | - 51 | name: hasavatar 52 | datatype: bool 53 | - 54 | name: lastlogin 55 | datatype: datetime 56 | - 57 | name: createdat 58 | datatype: datetime 59 | - 60 | name: birthdate 61 | datatype: datetime 62 | # ... 63 | 64 | ``` 65 | 66 | Where `listIdX` is the list id of your Mailjet lists, and `yourapp.providerX` is the key of your provider's service that will provide the contacts that need to be synchronized in Mailjet. See the documentation on create [your own Contact provider](contact-provider.md). 67 | 68 | ## Contact Metadata (Contact Properties) 69 | 70 | * [Mailjet FAQ](https://app.mailjet.com/docs/manage_contact_lists#lists-contact-properties) 71 | * [Mailjet Documentation](https://dev.mailjet.com/email-api/v3/contactmetadata/) 72 | 73 | You can find all parameters in Mailjet documentation. 74 | 75 | Example: 76 | 77 | ```yaml 78 | contact_metadata: 79 | - 80 | name: firstname 81 | datatype: str 82 | - 83 | name: lastname 84 | datatype: str 85 | - 86 | name: organisation 87 | datatype: str 88 | - 89 | name: town 90 | datatype: str 91 | - 92 | name: postalcode 93 | datatype: int 94 | - 95 | name: gender 96 | datatype: str 97 | - 98 | name: rank 99 | datatype: int 100 | - 101 | name: hasavatar 102 | datatype: bool 103 | - 104 | name: lastlogin 105 | datatype: datetime 106 | - 107 | name: createdat 108 | datatype: datetime 109 | - 110 | name: birthdate 111 | datatype: datetime 112 | ``` 113 | 114 | Available datatype: `str, int, float, bool, datetime` 115 | -------------------------------------------------------------------------------- /src/Resources/doc/contact-provider.md: -------------------------------------------------------------------------------- 1 | # Contact Provider 2 | 3 | After [configuring your lists](configuration.md) in `config.yml`, you need to create at least one `Provider` that will be used by the SyncUser command. 4 | Your provider should be accessible via a service key (the same you reference in `contact_provider` in your configuration file): 5 | 6 | ```yaml 7 | services: 8 | yourapp.mailjet.contact_provider1: 9 | class: YourApp\AppBundle\Mailjet\MyContactProvider 10 | arguments: [@yourapp.user.repository] 11 | ``` 12 | 13 | You provider class should implement `Mailjet\MailjetBundle\Provider\ProviderInterface` and the method `getContacts` must return an array of `Mailjet\MailjetBundle\Model\Contact` objects. 14 | 15 | ## Example 16 | 17 | Here is an example of ContactProvider: 18 | 19 | ```php 20 | userRepository = $userRepository; 45 | } 46 | 47 | public function getContacts() 48 | { 49 | $users = $this->userRepository->findUsers(); 50 | 51 | $contacts = array_map(function(User $user) { 52 | $userProperties = [ 53 | self::PROP_NICKNAME => $user->getNickname(), 54 | self::PROP_GENDER => $user->getGender(), 55 | self::PROP_CITY => $user->getCity(), 56 | self::PROP_BIRTHDATE => $user->getBirthday() ? $user->getBirthday()->format('Y-m-d') : '', 57 | self::PROP_LAST_ACTIVITY_DATE => $user->getLastActivity() ? $user->getLastActivity()->format('Y-m-d') : '' 58 | self::PROP_REGISTRATION_DATE => $user->getRegistrateAt() ? $user->getRegistrateAt()->format('Y-m-d') : '' 59 | ]; 60 | 61 | $contact = new Contact($user->getEmail(), $user->getUsername(), $userProperties); 62 | 63 | return $contact; 64 | }, $users); 65 | 66 | return $contacts; 67 | } 68 | } 69 | ``` 70 | 71 | ## FosContactProvider 72 | 73 | We also provide a ready to use provider for FosUserBundle: `FosContactProvider`. You just need to register the service into your app: 74 | 75 | ```yaml 76 | services: 77 | yourapp.mailjet.fos_contact_provider: 78 | class: Mailjet\MailjetBundle\Provider\FosContactProvider 79 | arguments: [@fos_user.user_manager] 80 | ``` 81 | 82 | After this, don't forget to add the service key for your list into your `config.yml`: 83 | 84 | ```yaml 85 | ... 86 | listId1: 87 | contact_provider: 'yourapp.mailjet.fos_contact_provider' 88 | ``` 89 | 90 | Note: You need to have `enabled` and `lastlogin` in your contact properties 91 | -------------------------------------------------------------------------------- /src/Resources/doc/event-api.md: -------------------------------------------------------------------------------- 1 | # Event API: real-time notifications (webhook) 2 | 3 | * [Mailjet Dev guide](https://dev.mailjet.com/guides/#event-api-real-time-notifications) 4 | * [Mailjet Event Config](https://app.mailjet.com/account/triggers) 5 | 6 | ## Configuration 7 | 8 | You need to add the webhook routing to your app routing: 9 | 10 | `app/routing.yml` 11 | 12 | ```yaml 13 | # Mailjet webhook route 14 | myapp_mailjet_webhook: 15 | resource: "@MailjetBundle/Resources/config/routing.yml" 16 | prefix: /mailjet 17 | ``` 18 | 19 | Note: you can change the prefix as you like. 20 | 21 | This will generate an url to the webhook like this: http://domain.com/mailjet/mailjet-event/endpoint 22 | 23 | Also, Mailjet recommand to protect webhook url with a token parameter. So you need to add the secret token to your list in your config.yml 24 | 25 | config.yml 26 | 27 | ```yaml 28 | mailjet: 29 | api_key: "%mailjet.api_key%" 30 | secret_key: "%mailjet.api_secret%" 31 | ... 32 | event_endpoint_token: "thisisTheSecretPass" 33 | ``` 34 | 35 | Note: To access properly to the webhook function you will have to use the url with the secret parameter: 36 | 37 | ## Register callback urls manually 38 | 39 | You can set up manually through the Mailjet panel: [here](https://app.mailjet.com/account/triggers) 40 | 41 | You need to add the correct callback url such as: 42 | 43 | ## Command to automatically register callback Urls 44 | 45 | You can use the Symfony command to automatically register callback Urls: 46 | 47 | ```shell 48 | php app/console mailjet:event-endpoint http://domain.com 49 | ``` 50 | 51 | By default, this command will register the url to al event Type. You can specify type as options if you want to register to specific event type: 52 | 53 | ```shell 54 | php app/console mailjet:event-endpoint http://domain.com --event-type=open --event-type=unsub 55 | ``` 56 | 57 | Event type list: `["sent", "open", "click", "bounce", "blocked", "spam", "unsub"]` 58 | 59 | ## Events to listen 60 | In order to integrate MailChimp into your app workflow, you can listen to different Event. 61 | 62 | Event you can listen: 63 | 64 | ```php 65 | CallbackEvent::EVENT_SENT = 'mailjet.event.sent'; 66 | CallbackEvent::EVENT_OPEN = 'mailjet.event.open'; 67 | CallbackEvent::EVENT_CLICK = 'mailjet.event.click'; 68 | CallbackEvent::EVENT_BOUNCE = 'mailjet.event.bounce'; 69 | CallbackEvent::EVENT_SPAM = 'mailjet.event.spam'; 70 | CallbackEvent::EVENT_BLOCKED = 'mailjet.event.blocked'; 71 | CallbackEvent::EVENT_UNSUB = 'mailjet.event.unsub'; 72 | ``` 73 | 74 | ### 1- create an Event Listener 75 | 76 | ```php 77 | logger = $logger; 94 | } 95 | 96 | public static function getSubscribedEvents() 97 | { 98 | return [ 99 | CallbackEvent::EVENT_SENT => 'sent', 100 | CallbackEvent::EVENT_OPEN => 'open', 101 | CallbackEvent::EVENT_CLICK => 'click', 102 | CallbackEvent::EVENT_BOUNCE => 'bounce', 103 | CallbackEvent::EVENT_SPAM => 'spam', 104 | CallbackEvent::EVENT_BLOCKED => 'blocked', 105 | CallbackEvent::EVENT_UNSUB => 'unsub' 106 | 107 | ]; 108 | } 109 | 110 | public function sent(CallbackEvent $event){ 111 | $this->logger->info('sent Event:', $event->getData()); 112 | } 113 | 114 | public function open(CallbackEvent $event){ 115 | $this->logger->info('open Event:', $event->getData()); 116 | } 117 | 118 | public function click(CallbackEvent $event){ 119 | $this->logger->info('click Event:', $event->getData()); 120 | } 121 | 122 | public function bounce(CallbackEvent $event){ 123 | $this->logger->info('bounce Event:', $event->getData()); 124 | } 125 | 126 | public function spam(CallbackEvent $event){ 127 | $this->logger->info('spam Event:', $event->getData()); 128 | } 129 | 130 | public function blocked(CallbackEvent $event){ 131 | $this->logger->info('blocked Event:', $event->getData()); 132 | } 133 | 134 | public function unsub(CallbackEvent $event){ 135 | $this->logger->info('unsub Event:', $event->getData()); 136 | } 137 | 138 | } 139 | ``` 140 | 141 | ### 2- Register the listener into services.yml 142 | 143 | ```yaml 144 | services: 145 | app.listener.mailjet.webhook: 146 | class: AppBundle\Listener\MailjetEventListener 147 | tags: 148 | - { name: kernel.event_subscriber } 149 | arguments: 150 | - @logger 151 | ``` 152 | 153 | ### 3- Test with ngrok (or other localhost tunnel) 154 | -------------------------------------------------------------------------------- /src/Resources/doc/img/dataCollector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjetBundle/2a0f468094807bacd7e0ddfc0222396a202bb756/src/Resources/doc/img/dataCollector.png -------------------------------------------------------------------------------- /src/Resources/doc/img/sftoolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mailjet/mailjetBundle/2a0f468094807bacd7e0ddfc0222396a202bb756/src/Resources/doc/img/sftoolbar.png -------------------------------------------------------------------------------- /src/Resources/doc/index.md: -------------------------------------------------------------------------------- 1 | # Mailjet Bundle 2 | 3 | [![Build Status](https://travis-ci.org/mailjet/mailjetBundle.svg?branch=master)](https://travis-ci.org/mailjet/mailjetBundle) 4 | [![Packagist](https://img.shields.io/packagist/v/mailjet/mailjet-bundle.svg)](https://packagist.org/packages/mailjet/mailjet-bundle) 5 | [![Packagist](https://img.shields.io/packagist/dt/mailjet/mailjet-bundle.svg)](https://packagist.org/packages/mailjet/mailjet-bundle) 6 | [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/mailjet/mailjetBundle/blob/master/LICENSE.md) 7 | [![Documentation](https://img.shields.io/badge/documentation-gh--pages-blue.svg)](https://mailjet.github.io/mailjetBundle/) 8 | 9 | Symfony bundle for handling Mailjet API V3 using this wrapper: 10 | 11 | ## Features 12 | 13 | * [x] Retrieve [\Mailjet\Client](https://github.com/mailjet/mailjet-apiv3-php) to make custom Mailjet API V3 requests 14 | * [x] [SwiftMailer Transport integration](https://github.com/mailjet/MailjetSwiftMailer) 15 | * [x] Synchronize Contact Metadata (Contact Properties) with your config 16 | * [x] Synchronize your user with Mailjet contact list 17 | * [x] Use your own userProvider (basic `FosContactProvider` included to interface with FosUserBundle) 18 | * [x] Use lifecycle event to subscribe/unsubscribe/update/delete/changeEmail user from a contact List 19 | * [x] Register Event API - real time notifications (webhook) 20 | * [x] Manage Campaigns,Campaigndrafts and Templates 21 | 22 | ## Setup 23 | 24 | Add bundle to your project: 25 | 26 | ```bash 27 | composer require mailjet/mailjet-bundle 28 | ``` 29 | 30 | Add `Mailjet\MailjetBundle\MailjetBundle` to your `AppKernel.php`: 31 | 32 | ```php 33 | $bundles = [ 34 | // ... 35 | new Mailjet\MailjetBundle\MailjetBundle(), 36 | ]; 37 | ``` 38 | 39 | ## Minimal Configuration 40 | 41 | In your `config.yml`: 42 | 43 | ```yaml 44 | mailjet: 45 | api_key: "%mailjet.api_key%" 46 | secret_key: "%mailjet.secret_key%" 47 | ``` 48 | 49 | ## ToDo 50 | 51 | * More unit tests 52 | * Functionnal tests 53 | * Other features like Campaigns, stats, ... 54 | 55 | 56 | ## Contributing 57 | 58 | If you want to contribute to this project, look at [over here](CONTRIBUTING.md) 59 | -------------------------------------------------------------------------------- /src/Resources/doc/mailjet-doc.md: -------------------------------------------------------------------------------- 1 | # Mailjet Documentation 2 | 3 | * [API Guides](https://dev.mailjet.com/guides/) 4 | * [API Reference](https://dev.mailjet.com/email-api/v3/) 5 | * [Switch from Mandrill](https://dev.mailjet.com/mandrill/) 6 | * [Automation (FR)](http://devblog.lexik.fr/tips/automatisation-de-relance-email-ne-developpez-pas-3082) 7 | -------------------------------------------------------------------------------- /src/Resources/doc/setup.md: -------------------------------------------------------------------------------- 1 | # Setup 2 | 3 | Add bundle to your project: 4 | 5 | ```bash 6 | composer require mailjet/mailjet-bundle 7 | ``` 8 | 9 | Add `Mailjet\MailjetBundle\MailjetBundle` to your `AppKernel.php`: 10 | 11 | ```php 12 | $bundles = [ 13 | // ... 14 | new Mailjet\MailjetBundle\MailjetBundle(), 15 | ]; 16 | ``` 17 | 18 | ## Minimal Configuration 19 | 20 | In your `config.yml`: 21 | 22 | ```yaml 23 | mailjet: 24 | api_key: "%mailjet.api_key%" 25 | secret_key: "%mailjet.secret_key%" 26 | ``` 27 | 28 | [More configuration](configuration.md) 29 | -------------------------------------------------------------------------------- /src/Resources/doc/swiftmailer.md: -------------------------------------------------------------------------------- 1 | # Mailjet SwiftMailer Transport 2 | 3 | ## Configuration 4 | 5 | ```yaml 6 | # Swiftmailer Configuration 7 | swiftmailer: 8 | transport: mailjet 9 | ``` 10 | 11 | ## Send email example 12 | 13 | ```php 14 | $message = \Swift_Message::newInstance() 15 | ->setSubject('this is and email') 16 | ->setFrom(['no-reply@foo.bar' => 'Transactionnal']) 17 | ->setTo('to@foo.bar') 18 | ->setBody( 19 | 'hello world!', 20 | 'text/html' 21 | ); 22 | 23 | //Configure Headers 24 | $headers = $message->getHeaders(); 25 | // Mailjet header 26 | $headers->addTextHeader('X-MJ-CustomID', $this->getName()); 27 | 28 | // send email 29 | $this->get('mailer')->send($message); 30 | 31 | ``` 32 | 33 | ## Documentation 34 | 35 | [MailjetSwiftMailer github](https://github.com/mailjet/MailjetSwiftMailer) 36 | -------------------------------------------------------------------------------- /src/Resources/doc/symfony-debug-toolbar.md: -------------------------------------------------------------------------------- 1 | # Symfony debug toolbar 2 | 3 | When Mailjet API is call, you can find Request data in Symfony debug toolbar. 4 | 5 | ![sftoolbar](img/sftoolbar.png) 6 | 7 | When you click on Mailjet icon on toolbar, you can have debug data on Mailjet API calls executed. 8 | 9 | ![dataCollector](img/dataCollector.png) 10 | 11 | It's a powerfull built-in tool you can use without moderation! 12 | -------------------------------------------------------------------------------- /src/Resources/doc/tests.md: -------------------------------------------------------------------------------- 1 | # Tests 2 | 3 | * 4 | 5 | ## Unit tests 6 | 7 | bin/phpspec run --fpretty --verbose 8 | 9 | 10 | ## Events (Webhook) tests 11 | 12 | use ngrok or http://requestb.in/ 13 | 14 | ## Debug/dev mode 15 | 16 | The best solution for debug or dev environment is to create a new MailJet account and use the API key of this new "debug/dev" free Mailjet account. 17 | -------------------------------------------------------------------------------- /src/Resources/doc/usage.md: -------------------------------------------------------------------------------- 1 | # Usage 2 | 3 | ## Synchronize Contact Metadata (Contact Properties) 4 | 5 | Contact Metadata (or Contact Properties) are values you can add to your contacts (for example firstname, birthdate, isenabled, ...). 6 | You can use these metadata in your newsletters or to create segments out of them. 7 | 8 | This bundle provides a simple way to configure and synchronize these metadata with your Mailjet account. 9 | 10 | You just need to configure in your config.yml your `contact_metadata`: [see the configuration](configuration.md). 11 | 12 | Finally, you can use this command to synchronize your config with Mailjet: 13 | 14 | php app/console mailjet:contactmetadata-sync 15 | 16 | 17 | ## Full synchronization with command 18 | 19 | You can synchronize all users of your project with a Mailjet list at once by calling the Symfony command: 20 | 21 | php app/console mailjet:user-sync 22 | 23 | 24 | It will get all your User throught your Contact Provider and will add/update all your User to the configured list. 25 | 26 | You can use the option `--follow-sync` to supervise batch jobs. 27 | 28 | php app/console mailjet:user-sync --follow-sync 29 | 30 | NOTE: you must have configured and created [your own contact provider](contact-provider.md). 31 | 32 | ## Unit synchronization with events 33 | 34 | If you want realtime synchronization, you can dispatch custom events on your controllers/managers (or anywhere). The subscribe event can be used both for adding a new contact or updating an existing one. You can fired these events to trigger sync with Mailjet: 35 | 36 | ```php 37 | ContactEvent::EVENT_SUBSCRIBE = 'mailjet.mailjet.subscribe'; 38 | ContactEvent::EVENT_UNSUBSCRIBE = 'mailjet.mailjet.unsubscribe'; 39 | ContactEvent::EVENT_UPDATE = 'mailjet.mailjet.update'; 40 | ContactEvent::EVENT_DELETE = 'mailjet.mailjet.delete'; 41 | // NOT IMPLETENTED YET // ContactEvent::EVENT_CHANGE_EMAIL = 'mailjet.mailjet.change_email'; 42 | ``` 43 | 44 | ### Subscribe new User 45 | 46 | Here is an example of a subscribe event dispatch: 47 | 48 | ```php 49 | getEmail(), $user->getNickname(), [ 61 | 'firstname' => $user->getFirstname(), 62 | 'lastname' => $user->getLastname(), 63 | 'city' => $user->getCity(), 64 | 'language' => 'fr' 65 | ]); 66 | 67 | $this->container->get('event_dispatcher')->dispatch( 68 | ContactEvent::EVENT_SUBSCRIBE, 69 | new ContactEvent('your_list_id', $contact) 70 | ); 71 | } 72 | ``` 73 | 74 | ### Unsubscribe a User 75 | 76 | Unsubscribe is simpler, you only need the email: 77 | 78 | ```php 79 | getEmail()); 91 | 92 | $this->container->get('event_dispatcher')->dispatch( 93 | ContactEvent::EVENT_UNSUBSCRIBE, 94 | new ContactEvent('your_list_id', $contact) 95 | ); 96 | } 97 | ``` 98 | 99 | ### Update a User 100 | 101 | If your User changes his information, you can sync with MailChimp: 102 | 103 | ```php 104 | getEmail(), $user->getNickname(), [ 116 | 'firstname' => $user->getFirstname(), 117 | 'lastname' => $user->getLastname(), 118 | 'city' => $user->getCity(), 119 | 'language' => 'fr' 120 | ]); 121 | 122 | $this->container->get('event_dispatcher')->dispatch( 123 | ContactEvent::EVENT_UPDATE, 124 | new ContactEvent('your_list_id', $contact) 125 | ); 126 | } 127 | ``` 128 | 129 | Note: we can't change the address email of a user... MailJet API V3 doesn't permit it so far. 130 | 131 | 132 | ### Delete a User 133 | 134 | And finally delete a User: 135 | 136 | 137 | ```php 138 | getEmail()); 150 | 151 | $this->container->get('event_dispatcher')->dispatch( 152 | ContactEvent::EVENT_DELETE, 153 | new ContactEvent('your_list_id', $contact) 154 | ); 155 | } 156 | ``` 157 | 158 | ### Change User's email address 159 | 160 | ```php 161 | container->get('event_dispatcher')->dispatch( 172 | ContactEvent::EVENT_CHANGE_EMAIL, 173 | new ContactEvent('your_list_id', $contact, $oldEmail) 174 | ); 175 | 176 | } 177 | ``` 178 | 179 | WORKAROUND: remove old, add new 180 | 181 | ## Retrieve Mailjet Client Object to make custom MailJet API V3 requests 182 | 183 | You can also retrieve the MailJet Client Object which comes from the wrapper [mailjet/mailjet-apiv3-php](https://github.com/mailjet/mailjet-apiv3-php). 184 | 185 | The service key is `mailjet.client`. 186 | 187 | Example: 188 | 189 | ``` php 190 | container->get('mailjet.client'); 196 | 197 | // Resources are all located in the Resources class 198 | $response = $mailjet->get(Resources::$Contact); 199 | 200 | /* 201 | Read the response 202 | */ 203 | if ($response->success()) 204 | var_dump($response->getData()); 205 | else 206 | var_dump($response->getStatus()); 207 | 208 | ... 209 | // Send transactional emails (note: prefer using SwiftMailer to send transactionnal emails) 210 | 211 | $body = [ 212 | 'FromEmail' => "pilot@mailjet.com", 213 | 'FromName' => "Mailjet Pilot", 214 | 'Subject' => "Your email flight plan!", 215 | 'Text-part' => "Dear passenger, welcome to Mailjet! May the delivery force be with you!", 216 | 'Html-part' => "

Dear passenger, welcome to Mailjet!


May the delivery force be with you!", 217 | 'Recipients' => [['Email' => "passenger@mailjet.com"]] 218 | ]; 219 | 220 | $response = $mailjet->post(Resources::$Email, ['body' => $body]); 221 | 222 | ``` 223 | ## Campaigndraft Example 224 | 225 | You can also access the [/campaigndraft](https://dev.mailjet.com/email-api/v3/campaigndraft) api through the CampaignDraftManager 226 | 227 | Example: 228 | 229 | ``` php 230 | container->get('mailjet.service.campaign_draft_manager'); 238 | $optionalProp['Title'] = 'Friday newsletter'; 239 | $optionalProp['SenderName'] = 'Mailjet team'; 240 | $optionalProp['EditMode'] = 'html2'; 241 | $campaignDraft = new CampaignDraft("en_US", "Lyubo", "api@mailjet.com", "Symfony bundle test", "5410"); 242 | $campaignDraft->setOptionalProperties($optionalProp); 243 | $ID = $campaignDraftManager->create($campaignDraft)[0]['ID']; 244 | 245 | /* * Get the ID from the newly created CampaignDraft* */ 246 | $campaignDraft->setId($ID); 247 | /* * Set and create content** */ 248 | $content = ['Html-part' => "Hello world!", 249 | 'Text-part' => "Hello world!"]; 250 | $campaignDraft->setContent($content); 251 | $campaignDraftManager->createDetailContent($campaignDraft->getId(), $campaignDraft->getContent()); 252 | /* * Send a campaigndraft** */ 253 | $campaignDraftManager->sendCampaign($campaignDraft->getId()); 254 | } 255 | ``` 256 | ## Template Example 257 | 258 | You can also access the [/template](https://dev.mailjet.com/email-api/v3/template) api through the TemplateManager 259 | 260 | Example: 261 | 262 | ``` php 263 | container->get('mailjet.service.template_manager'); 273 | $optionalProp['Author'] = 'Mailjet team'; 274 | $optionalProp['EditMode'] = 1; 275 | $optionalProp['Purposes'] = ['transactional']; 276 | $template = new Template("Symfony Template Example!!! ", $optionalProp); 277 | 278 | $ID = $templateManager->create($template)[0]['ID']; 279 | 280 | //Add content to a template 281 | $contentData = [ 282 | 'Html-part' => "

Hello {{var:name}}

", 283 | 'Text-part' => "Hello {{var:name}}" 284 | ]; 285 | $templateManager->createDetailContent($ID, $contentData); 286 | 287 | //Example list all templates based on multiple filters 288 | $filters['OwnerType']='apikey'; 289 | $filters['EditMode']=1; 290 | $result=$templateManager->getAll($filters); 291 | } 292 | ``` 293 | ## Campaigns Example 294 | 295 | You can also access the [/campaign](https://dev.mailjet.com/email-api/v3/campaign) api through the CampaignManager 296 | 297 | Example: 298 | 299 | ``` php 300 | container->get('mailjet.service.campaign_manager'); 309 | $filters['IsStarred']=true; 310 | $result = $campaignManager->getAllCampaigns($filters); 311 | } 312 | ``` 313 | -------------------------------------------------------------------------------- /src/Resources/views/data_collector/mailjet.html.twig: -------------------------------------------------------------------------------- 1 | {% extends '@WebProfiler/Profiler/layout.html.twig' %} 2 | 3 | {% block toolbar %} 4 | {% if collector.callCount > 0 %} 5 | {% set icon %} 6 | 8 | {{ collector.callCount }} 9 | {% endset %} 10 | 11 | {% set text %} 12 |
13 | Api Calls 14 | 15 | {{ collector.callCount }} 16 | 17 |
18 | {% endset %} 19 | 20 | {{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { 'link': true }) }} 21 | {% endif %} 22 | {% endblock %} 23 | 24 | {% block menu %} 25 | 26 | 27 | 29 | 30 | Mailjet 31 | {% if collector.callCount > 0 %} 32 | 33 | {{ collector.callCount }} 34 | 35 | {% endif %} 36 | 37 | {% endblock %} 38 | 39 | {% block panel %} 40 |

Mailjet queries done

41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | {% for call in collector.data %} 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | {% endfor %} 59 |
MethodResourceArgumentsSuccessResponse
{{ call.method }}{{ dump(call.resource) }}{{ dump(call.args) }}{{ dump(call.success) }}{{ dump(call.response) }}
60 | {% endblock %} 61 | -------------------------------------------------------------------------------- /src/Synchronizer/ContactsListSynchronizer.php: -------------------------------------------------------------------------------- 1 | mailjet = $mailjet; 40 | $this->manager = $manager; 41 | } 42 | 43 | /** 44 | * Multiple contacts can be uploaded asynchronously using that action. 45 | * 46 | * @param ContactsList $contactsList 47 | * @return array 48 | */ 49 | public function synchronize(ContactsList $contactsList) 50 | { 51 | 52 | // Remove diff Contacts 53 | $batchesResultRemove = $this->batchRemoveContact($contactsList); 54 | // Add Contacts 55 | $batchesResultAdd = $this->batchAddContact($contactsList); 56 | 57 | return array_merge($batchesResultRemove, $batchesResultAdd); 58 | } 59 | 60 | /** 61 | * Get Job data 62 | * @method getJob 63 | * @param string $listId 64 | * @param string $jobId 65 | * @return array 66 | */ 67 | public function getJob($listId, $jobId) 68 | { 69 | $response = $this->mailjet->get(Resources::$ContactslistManagemanycontacts, ['id' => $listId, 'actionid' => $jobId]); 70 | if (!$response->success()) { 71 | $this->throwError("ContactsListSynchronizer:getJob() failed", $response); 72 | } 73 | 74 | return $response->getData(); 75 | } 76 | 77 | /** 78 | * Retrieve JsonError for a job 79 | * @param string $jobId 80 | * @return array 81 | */ 82 | public function getJobJsonError($jobId) 83 | { 84 | $response = $this->mailjet->get(Resources::$BatchjobJsonerror, ['id' => $jobId]); 85 | if (!$response->success()) { 86 | $this->throwError("ContactsListSynchronizer:getJobJsonError() failed", $response); 87 | } 88 | 89 | return $response->getBody(); 90 | } 91 | 92 | /** 93 | * Get contacts in Mailjet list and remove the difference with $contactsList 94 | * @param ContactsList $contactsList 95 | * @return array 96 | */ 97 | private function batchRemoveContact(ContactsList $contactsList) 98 | { 99 | $emailsOnLists = []; 100 | $offset = 0; 101 | $limit = 1000; 102 | $run = true; 103 | 104 | // Retrieve Emails from list 105 | while ($run) { 106 | $filters = ['ContactsList'=> $contactsList->getListId(),'limit' => $limit, 'offset' => $offset]; 107 | $response = $this->mailjet->get(Resources::$Contact, ['filters' => $filters]); 108 | if (!$response->success()) { 109 | $this->throwError("ContactsListSynchronizer:batchRemoveContact() failed", $response); 110 | } 111 | $data = $response->getData(); 112 | 113 | foreach ($data as $key => $contact) { 114 | array_push($emailsOnLists, $contact['Email']); 115 | } 116 | 117 | $offset += $limit; 118 | if ($response->getCount() < $limit) { 119 | $run = false; 120 | } 121 | } 122 | 123 | $emailsInternal = array_map(function (Contact $contact) { 124 | return $contact->getEmail(); 125 | }, $contactsList->getContacts()); 126 | 127 | $diffEmails = array_diff($emailsOnLists, $emailsInternal); 128 | if (sizeof($diffEmails) == 0) { 129 | return []; 130 | } 131 | 132 | // Remove difference contacts 133 | $diffContacts = array_map(function ($email) { 134 | return new Contact($email); 135 | }, $diffEmails); 136 | 137 | $diffContactsList = new ContactsList($contactsList->getListId(), ContactsList::ACTION_REMOVE, $diffContacts); 138 | 139 | return $this->manager->manageManyContactsList($diffContactsList); 140 | } 141 | 142 | /** 143 | * Create batches to add Contacts to List 144 | * @param ContactsList $contactsList 145 | * @return array 146 | */ 147 | private function batchAddContact(ContactsList $contactsList) 148 | { 149 | $contactsList->setAction(ContactsList::ACTION_ADDFORCE); 150 | return $this->manager->manageManyContactsList($contactsList); 151 | } 152 | 153 | /** 154 | * Helper to throw error 155 | * @param string $title 156 | * @param Response $response 157 | */ 158 | private function throwError($title, Response $response) 159 | { 160 | throw new MailjetException(0, $title, $response); 161 | } 162 | } 163 | --------------------------------------------------------------------------------