Add ensure unsubscribe link method to newsletters links

[MAILPOET-2245]
This commit is contained in:
Rostislav Wolny
2019-09-30 15:37:25 +02:00
committed by Jack Kitterhing
parent 2518e4d56b
commit 028c5e6de5
3 changed files with 48 additions and 9 deletions

View File

@@ -10,6 +10,7 @@ namespace MailPoet\Models;
*/ */
class NewsletterLink extends Model { class NewsletterLink extends Model {
public static $_table = MP_NEWSLETTER_LINKS_TABLE; public static $_table = MP_NEWSLETTER_LINKS_TABLE;
const UNSUBSCRIBE_LINK_SHORT_CODE = '[link:subscription_unsubscribe_url]';
/** /**
* @param Newsletter $newsletter * @param Newsletter $newsletter

View File

@@ -75,17 +75,9 @@ class Links {
$link = $extracted_link['link']; $link = $extracted_link['link'];
if (array_key_exists($link, $processed_links)) if (array_key_exists($link, $processed_links))
continue; continue;
$hash = Security::generateHash();
// Use URL as a key to map between extracted and processed links // Use URL as a key to map between extracted and processed links
// regardless of their sequential position (useful for link skips etc.) // regardless of their sequential position (useful for link skips etc.)
$processed_links[$link] = [ $processed_links[$link] = self::hashLink($link, $extracted_link['type']);
'type' => $extracted_link['type'],
'hash' => $hash,
'link' => $link,
// replace link with a temporary data tag + hash
// it will be further replaced with the proper track API URL during sending
'processed_link' => self::DATA_TAG_CLICK . '-' . $hash,
];
} }
return $processed_links; return $processed_links;
} }
@@ -170,6 +162,20 @@ class Links {
} }
} }
static function ensureUnsubscribeLink(array $processed_links) {
if (in_array(
NewsletterLink::UNSUBSCRIBE_LINK_SHORT_CODE,
\MailPoet\Util\array_column($processed_links, 'link'))
) {
return $processed_links;
}
$processed_links[] = self::hashLink(
NewsletterLink::UNSUBSCRIBE_LINK_SHORT_CODE,
Links::LINK_TYPE_SHORTCODE
);
return $processed_links;
}
static function convertHashedLinksToShortcodesAndUrls($content, $queue_id, $convert_all = false) { static function convertHashedLinksToShortcodesAndUrls($content, $queue_id, $convert_all = false) {
preg_match_all(self::getLinkRegex(), $content, $links); preg_match_all(self::getLinkRegex(), $content, $links);
$links = array_unique(Helpers::flattenArray($links)); $links = array_unique(Helpers::flattenArray($links));
@@ -221,4 +227,16 @@ class Links {
$transformed_data['preview'] = (!empty($data[4])) ? $data[4] : false; $transformed_data['preview'] = (!empty($data[4])) ? $data[4] : false;
return $transformed_data; return $transformed_data;
} }
private static function hashLink($link, $type) {
$hash = Security::generateHash();
return [
'type' => $type,
'hash' => $hash,
'link' => $link,
// replace link with a temporary data tag + hash
// it will be further replaced with the proper track API URL during sending
'processed_link' => self::DATA_TAG_CLICK . '-' . $hash,
];
}
} }

View File

@@ -8,6 +8,7 @@ use MailPoet\Models\Subscriber;
use MailPoet\Newsletter\Links\Links; use MailPoet\Newsletter\Links\Links;
use MailPoet\Newsletter\Shortcodes\Categories\Link; use MailPoet\Newsletter\Shortcodes\Categories\Link;
use MailPoet\Router\Router; use MailPoet\Router\Router;
use function MailPoetVendor\Symfony\Component\DependencyInjection\Loader\Configurator\expr;
class LinksTest extends \MailPoetTest { class LinksTest extends \MailPoetTest {
function testItOnlyExtractsLinksFromAnchorTags() { function testItOnlyExtractsLinksFromAnchorTags() {
@@ -237,6 +238,25 @@ class LinksTest extends \MailPoetTest {
expect($result)->contains('[mailpoet_click_data]-123'); expect($result)->contains('[mailpoet_click_data]-123');
} }
function testItCanEnsureThatUnsubscribeLinkIsAmongProcessedLinks() {
$links = [
[
'link' => 'http://example.com',
'type' => Links::LINK_TYPE_URL,
'processed_link' => '[mailpoet_click_data]-123',
'hash' => 'abcdfgh',
],
];
$links = Links::ensureUnsubscribeLink($links);
expect(count($links))->equals(2);
expect($links[1]['link'])->equals(NewsletterLink::UNSUBSCRIBE_LINK_SHORT_CODE);
expect($links[1]['type'])->equals(Links::LINK_TYPE_SHORTCODE);
expect($links[1])->hasKey('processed_link');
expect($links[1])->hasKey('hash');
$links = Links::ensureUnsubscribeLink($links);
expect(count($links))->equals(2);
}
function testItCanConvertAllHashedLinksToUrls() { function testItCanConvertAllHashedLinksToUrls() {
// create newsletter link associations // create newsletter link associations
$queue_id = 1; $queue_id = 1;