PrepareEmailHtmlAction::trackOpens()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Spatie\EmailCampaigns\Actions;
4
5
use DOMElement;
6
use DOMDocument;
7
use ErrorException;
8
use Illuminate\Support\Str;
9
use Spatie\EmailCampaigns\Models\Campaign;
10
use Spatie\EmailCampaigns\Exceptions\CouldNotSendCampaign;
11
use Spatie\EmailCampaigns\Http\Controllers\TrackOpensController;
12
13
class PrepareEmailHtmlAction
14
{
15
    public function execute(Campaign $campaign)
16
    {
17
        $campaign->email_html = $campaign->html;
18
19
        $this->ensureEmailHtmlHasSingleRootElement($campaign);
20
21
        if ($campaign->track_clicks) {
22
            $this->trackClicks($campaign);
23
        }
24
25
        if ($campaign->track_opens) {
26
            $this->trackOpens($campaign);
27
        }
28
29
        $this->replacePlaceholders($campaign);
30
31
        $campaign->save();
32
    }
33
34
    protected function ensureEmailHtmlHasSingleRootElement($campaign)
35
    {
36
        if (! Str::startsWith(trim($campaign->email_html), '<html')) {
37
            $campaign->email_html = '<html>'.$campaign->email_html;
38
        }
39
40
        if (! Str::endsWith(trim($campaign->email_html), '</html>')) {
41
            $campaign->email_html = $campaign->email_html.'</html>';
42
        }
43
    }
44
45
    protected function trackClicks(Campaign $campaign)
46
    {
47
        $dom = new DOMDocument('1.0', 'UTF-8');
48
49
        try {
50
            $dom->loadHTML($campaign->email_html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD | LIBXML_NOWARNING);
51
        } catch (ErrorException $errorException) {
0 ignored issues
show
Bug introduced by
The class ErrorException does not exist. Is this class maybe located in a folder that is not analyzed, or in a newer version of your dependencies than listed in your composer.lock/composer.json?
Loading history...
52
            throw CouldNotSendCampaign::invalidContent($campaign, $errorException);
53
        }
54
55
        collect($dom->getElementsByTagName('a'))
56
            ->filter(function (DOMElement $linkElement) {
57
                return Str::startsWith(
58
                    $linkElement->getAttribute('href'),
59
                    ['http://', 'https://']
60
                );
61
            })
62
            ->each(function (DOMElement $linkElement) use ($campaign) {
63
                $originalHref = $linkElement->getAttribute('href');
64
65
                $campaignLink = $campaign->links()->create([
66
                    'original_link' => $originalHref,
67
                ]);
68
69
                $linkElement->setAttribute('href', $campaignLink->url);
70
            });
71
72
        $campaign->email_html = trim($dom->saveHtml());
73
    }
74
75
    protected function trackOpens(Campaign $campaign)
76
    {
77
        $webBeaconUrl = action(TrackOpensController::class, '::campaignSendUuid::');
78
79
        $webBeaconHtml = "<img alt='beacon' src='{$webBeaconUrl}' />";
80
81
        $campaign->email_html = Str::replaceLast('</body>', $webBeaconHtml.'</body>', $campaign->email_html);
82
    }
83
84
    protected function replacePlaceholders(Campaign $campaign): void
85
    {
86
        $webviewUrl = $campaign->webViewUrl();
87
88
        $campaign->email_html = str_replace('::webviewUrl::', $webviewUrl, $campaign->email_html);
89
    }
90
}
91