Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Currently this package support:

- [Mailcoach](https://mailcoach.app) (built by us :-))
- [MailChimp](https://mailchimp.com)
- [MailerLite](https://mailerlite.com)

## Support us

Expand Down Expand Up @@ -88,6 +89,8 @@ return [
*
* When using the MailChimp driver, this should be a MailChimp list id.
* http://kb.mailchimp.com/lists/managing-subscribers/find-your-list-id.
*
* When using MailerLite Driver, this should be a MailerLite group ID
*/
'id' => env('NEWSLETTER_LIST_ID'),
],
Expand Down Expand Up @@ -119,6 +122,20 @@ Next, you must provide values for the API key and `list.subscribers.id`. You'll

The `endpoint` config value must be set to null.

### Using MailerLite

To use MailerLite, install this extra package.

```bash
composer require mailerlite/mailerlite-php
```

The `driver` key of the `newsletter` config file must be set to `Spatie\Newsletter\Drivers\MailerLiteDriver::class`.

You need to provide the API key and the `group.id`. These can be found in your MailerLite Dashboard under Integrations > API.

The `endpoint` config value must be set to null.

## Usage

After you've installed the package and filled in the values in the config-file working with this package will be a breeze. All the following examples use the facade. Don't forget to import it at the top of your file.
Expand Down Expand Up @@ -154,6 +171,11 @@ For MailChimp you can pass merge variables as the second argument:
Newsletter::subscribe('[email protected]', ['FNAME'=>'Rince', 'LNAME'=>'Wind']);
```

For MailerLite you can pass subscriber fields as the second argument:
```php
Newsletter::subscribe('[email protected]', ['name'=>'Rince', 'last_name'=>'Wind']);
```

You can subscribe someone to a specific list by passing a list name:
```php
Newsletter::subscribe('[email protected]', listName: 'subscribers');
Expand Down Expand Up @@ -186,6 +208,12 @@ Here's how to unsubscribe someone from a specific list:
Newsletter::unsubscribe('[email protected]', 'subscribers');
```

For MailerLite, if you provide the group ID as the second argument, the subscriber will be removed from that group. Otherwise, they will be marked as unsubscribed.

```php
Newsletter::unsubscribe('[email protected]', 'subscribers');
```

### Deleting subscribers

Deleting is not the same as unsubscribing. Unlike unsubscribing, deleting a member will result in the loss of all history (add/opt-in/edits) as well as removing them from the list. In most cases, you want to use `unsubscribe` instead of `delete`.
Expand Down
9 changes: 6 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{
"name": "spatie/laravel-newsletter",
"description": "Manage Mailcoach and MailChimp newsletters in Laravel",
"description": "Manage Mailcoach, MailChimp and MailerLite newsletters in Laravel",
"keywords": [
"laravel",
"newsletter",
"mailcoach",
"mailchimp"
"mailchimp",
"mailerlite"
],
"homepage": "https://github.com/spatie/laravel-newsletter",
"license": "MIT",
Expand All @@ -24,11 +25,13 @@
},
"suggest": {
"spatie/mailcoach-sdk-php": "For working with Mailcoach",
"drewm/mailchimp-api": "For working with MailChimp"
"drewm/mailchimp-api": "For working with MailChimp",
"mailerlite/mailerlite-php": "For working with MailerLite"
},
"require-dev": {
"drewm/mailchimp-api": "^2.5",
"guzzlehttp/guzzle": "^7.5|^7.2",
"mailerlite/mailerlite-php": "^1.0",
"mockery/mockery": "^1.4",
"orchestra/testbench": "^7.11|^8.0|^9.0|^10.0",
"pestphp/pest": "^1.20|^2.0|^3.0",
Expand Down
2 changes: 2 additions & 0 deletions config/newsletter.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
*
* When using the MailChimp driver, this should be a MailChimp list id.
* http://kb.mailchimp.com/lists/managing-subscribers/find-your-list-id.
*
* When using MailerLite Driver, this should be a MailerLite group ID
*/
'id' => env('NEWSLETTER_LIST_ID'),
],
Expand Down
135 changes: 135 additions & 0 deletions src/Drivers/MailerLiteDriver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<?php

namespace Spatie\Newsletter\Drivers;

use MailerLite\MailerLite;
use Spatie\Newsletter\Support\Lists;

class MailerLiteDriver implements Driver
{
protected MailerLite $mailerLite;
protected Lists $lists;

public static function make(array $arguments, Lists $lists): self
{
return new self($arguments, $lists);
}

public function __construct(array $arguments, Lists $lists)
{
$this->mailerLite = new MailerLite([
'api_key' => $arguments['api_key'] ?? ''
]);

$this->lists = $lists;
}

public function getApi(): MailerLite
{
return $this->mailerLite;
}

public function subscribe(
string $email,
array $properties = [],
string $listName = '',
array $options = [],
bool $unsubscribe = false
): array|false {
$groupId = $this->lists->findByName($listName)->getId();

try {
$response = $this->mailerLite->subscribers->create([
'email' => $email,
'groups' => [$groupId],
'fields' => $properties,
'status' => $unsubscribe ? 'unsubscribed' : null,
]);

return $response['body']['data'] ?? false;
} catch (\Exception $e) {
return false;
}
}

public function subscribeOrUpdate(
string $email,
array $properties = [],
string $listName = '',
array $options = []
): array|false {
return $this->subscribe($email, $properties, $listName, $options);
}

public function unsubscribe(string $email, string $listName = ''): array|false
{
if ($listName) {
$subscriber = $this->getMember($email, $listName);

if ($subscriber) {
$groupId = $this->lists->findByName($listName)->getId();
$this->mailerLite->groups->unAssignSubscriber($groupId, $subscriber['id']);

return $this->getMember($email);
}

return false;
}

return $this->subscribe($email, listName: $listName, unsubscribe: true);
}

public function delete(string $email, string $listName = ''): bool
{
$subscriber = $this->getMember($email, $listName);

if ($subscriber) {
try {
$this->mailerLite->subscribers->delete($subscriber['id']);
return true;
} catch (\Exception $e) {
return false;
}
}

return false;
}

public function getMember(string $email, string $listName = ''): array|false
{
try {
$response = $this->mailerLite->subscribers->find($email);

$groupId = $this->lists->findByName($listName)->getId();

return $this->matchGroup($response, $groupId);
} catch (\Exception $e) {
return false;
}
}

public function hasMember(string $email, string $listName = ''): bool
{
return $this->getMember($email, $listName) !== false;
}

public function isSubscribed(string $email, string $listName = ''): bool
{
$subscriber = $this->getMember($email, $listName);

return $subscriber && ($subscriber['status'] ?? null) === 'active';
}

protected function matchGroup(array $subscriber, string|int $groupId): array|false
{
$groups = $subscriber['body']['data']['groups'] ?? [];

$groupIds = array_column($groups, 'id');

if (in_array($groupId, $groupIds, true)) {
return $subscriber['body']['data'];
}

return false;
}
}
11 changes: 11 additions & 0 deletions tests/Drivers/MailerLiteDriverTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

use MailerLite\MailerLite;
use Spatie\Newsletter\Drivers\MailerLiteDriver;
use Spatie\Newsletter\Facades\Newsletter;

it('can get the MailerLite API', function () {
config()->set('newsletter.driver', MailerLiteDriver::class);

expect(Newsletter::getApi())->toBeInstanceOf(MailerLite::class);
});