AzineEmailOpenTrackingCodeBuilder::getPiwikUrl()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 2
Metric Value
cc 1
eloc 7
c 2
b 0
f 2
nc 1
nop 6
dl 0
loc 10
ccs 0
cts 7
cp 0
crap 2
rs 10
1
<?php
2
3
namespace Azine\EmailBundle\Services;
4
5
use Azine\EmailBundle\DependencyInjection\AzineEmailExtension;
6
use Ramsey\Uuid\Uuid;
7
8
/**
9
 * Implementation of the EmailOpenTrackingCodeBuilderInterface used to track email open events.
10
 *
11
 * This implementation will create a html snippet with the image tracker code for
12
 * either GoogleAnalytics or Piwik, depending on the configured tracking url
13
 * ( azine_email_email_open_tracking_url) in your config.yml
14
 *
15
 * Class AzineEmailOpenTrackingCodeBuilder
16
 */
17
class AzineEmailOpenTrackingCodeBuilder implements EmailOpenTrackingCodeBuilderInterface
18
{
19
    /**
20
     * @var string
21
     */
22
    protected $tracking_params_campaign_source;
23
24
    /**
25
     * @var string
26
     */
27
    protected $tracking_params_campaign_medium;
28
29
    /**
30
     * @var string
31
     */
32
    protected $tracking_params_campaign_content;
33
34
    /**
35
     * @var string
36
     */
37
    protected $tracking_params_campaign_name;
38
39
    /**
40
     * @var string
41
     */
42
    protected $tracking_params_campaign_term;
43
44
    /**
45
     * @var|null
46
     */
47
    private $trackingUrlTemplate;
48
49
    /**
50
     * @var string the html-code template
51
     */
52
    protected $imageHtmlCode = "<img src='%s' style='border:0' alt='' />";
53
54
    /**
55
     * @param string $trackingUrlTemplate the url configured in your config.yml or null if you didn't specify a tracking url.
56
     * @param array  $parameters          array with the parameter names for the campaign tracking
57
     */
58 8
    public function __construct($trackingUrlTemplate, $parameters)
59
    {
60 8
        $this->trackingUrlTemplate = $trackingUrlTemplate;
61 8
        $this->tracking_params_campaign_content = $parameters[AzineEmailExtension::TRACKING_PARAM_CAMPAIGN_CONTENT];
62 8
        $this->tracking_params_campaign_medium = $parameters[AzineEmailExtension::TRACKING_PARAM_CAMPAIGN_MEDIUM];
63 8
        $this->tracking_params_campaign_name = $parameters[AzineEmailExtension::TRACKING_PARAM_CAMPAIGN_NAME];
64 8
        $this->tracking_params_campaign_source = $parameters[AzineEmailExtension::TRACKING_PARAM_CAMPAIGN_SOURCE];
65 8
        $this->tracking_params_campaign_term = $parameters[AzineEmailExtension::TRACKING_PARAM_CAMPAIGN_TERM];
66 8
    }
67
68
    /**
69
     * @param string $templateBaseId the template used for rendering the email (without the .html.twig or .txt.twig extension)
70
     * @param array  $campaignParams the campaign-parameters used for this email
71
     * @param string $messageId      the id of the message
72
     * @param string $to             to-recipient-email(s) or null
73
     * @param string $cc             cc-recipient-email(s) or null
74
     * @param string $bcc            bcc-recipient-email(s) or null
75
     *
76
     * @return string|null Email open tracking code for google analytics or piwik or null
77
     */
78
    public function getTrackingImgCode($templateBaseId, array $campaignParams, array $emailTemplateParams, $messageId, $to, $cc, $bcc)
79
    {
80
        if (null === $this->trackingUrlTemplate) {
81
            return null;
82
        }
83
84
        $recipients = md5($this->merge($to, $cc, $bcc));
85
86
        if (false !== strpos($this->trackingUrlTemplate, 'www.google-analytics.com')) {
87
            $trackingUrl = $this->getGoogleAnalyticsUrl($this->trackingUrlTemplate, $templateBaseId, $campaignParams, $emailTemplateParams, $messageId, $recipients);
88
        } else {
89
            $trackingUrl = $this->getPiwikUrl($this->trackingUrlTemplate, $templateBaseId, $campaignParams, $emailTemplateParams, $messageId, $recipients);
90
        }
91
92
        // return the html code for the tracking image
93
        $imgTrackingCode = sprintf($this->imageHtmlCode, $trackingUrl);
94
95
        return $imgTrackingCode;
96
    }
97
98
    /**
99
     * concatenate all recipients into an array and implode with ';' to a string.
100
     *
101
     * @param string|array $to
102
     * @param string|array $cc
103
     * @param string|array $bcc
104
     *
105
     * @return string
106
     */
107
    protected function merge($to, $cc, $bcc)
108
    {
109
        if ($to && !is_array($to)) {
110
            $to = array($to);
111
        }
112
        if (!is_array($cc)) {
113
            $cc = array($cc);
114
        }
115
        if (!is_array($bcc)) {
116
            $bcc = array($bcc);
117
        }
118
        $all = array_merge($to, $cc, $bcc);
0 ignored issues
show
Bug introduced by
It seems like $to can also be of type string; however, parameter $array1 of array_merge() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

118
        $all = array_merge(/** @scrutinizer ignore-type */ $to, $cc, $bcc);
Loading history...
119
120
        return implode(';', $all);
121
    }
122
123
    /**
124
     * Build tracking image code with an URL according to these sources:
125
     * http://dyn.com/blog/tracking-email-opens-via-google-analytics/
126
     * https://developers.google.com/analytics/devguides/collection/protocol/v1/email#protocol.
127
     *
128
     * @param string       $baseUrl             string something like: https://www.google-analytics.com/collect?v=1&cm=email&t=event&ec=email&ea=open&tid=TRACKING_ID replace the TRACKING_ID with your google analytics tracking ID.
129
     * @param string       $templateBaseId
130
     * @param array        $campaignParams
131
     * @param array        $emailTemplateParams
132
     * @param string       $messageId
133
     * @param string|array $recipients
134
     *
135
     * @return string
136
     */
137
    protected function getGoogleAnalyticsUrl($baseUrl, $templateBaseId, array $campaignParams, array $emailTemplateParams, $messageId, $recipients)
0 ignored issues
show
Unused Code introduced by
The parameter $emailTemplateParams is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

137
    protected function getGoogleAnalyticsUrl($baseUrl, $templateBaseId, array $campaignParams, /** @scrutinizer ignore-unused */ array $emailTemplateParams, $messageId, $recipients)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $messageId is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

137
    protected function getGoogleAnalyticsUrl($baseUrl, $templateBaseId, array $campaignParams, array $emailTemplateParams, /** @scrutinizer ignore-unused */ $messageId, $recipients)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
138
    {
139
        $url = $baseUrl.
140
            '&uid='.$recipients.                              // anonymized id generated from the concatenated string of all recipients email addresses
0 ignored issues
show
Bug introduced by
Are you sure $recipients of type array|string can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

140
            '&uid='./** @scrutinizer ignore-type */ $recipients.                              // anonymized id generated from the concatenated string of all recipients email addresses
Loading history...
141
            '&cid='.Uuid::uuid4()->toString().                // random UUID
142
            '&el='.$recipients.                               // anonymized id generated from the concatenated string of all recipients email addresses
143
            '&dp=/email/'.$templateBaseId.                    // the email-template used for this email
144
            '&cs='.$this->getCampaignSource($campaignParams, $templateBaseId). // campaing source for this email
145
            '&cn='.$this->getCampaignName($campaignParams).   // campaign name for this email
146
            '&z='.microtime();                                // cache buster
147
148
        return $url;
149
    }
150
151
    /**
152
     * Build tracking image code with an URL according to these sources:.
153
     *
154
     *
155
     * @param string $baseUrl             string something like: https://your.host.com/piwik-directory/piwik.php?&rec=1&bots=1&e_c=email&e_a=open&e_v=1&idsite=SITE_ID replace the path to your piwik.php and the SITE_ID according to your needs.
156
     * @param string $templateBaseId      string
157
     * @param array  $campaignParams
158
     * @param array  $emailTemplateParams
159
     * @param string $messageId
160
     * @param string $recipients
161
     *
162
     * @return string
163
     */
164
    protected function getPiwikUrl($baseUrl, $templateBaseId, array $campaignParams, array $emailTemplateParams, $messageId, $recipients)
0 ignored issues
show
Unused Code introduced by
The parameter $emailTemplateParams is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

164
    protected function getPiwikUrl($baseUrl, $templateBaseId, array $campaignParams, /** @scrutinizer ignore-unused */ array $emailTemplateParams, $messageId, $recipients)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $messageId is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

164
    protected function getPiwikUrl($baseUrl, $templateBaseId, array $campaignParams, array $emailTemplateParams, /** @scrutinizer ignore-unused */ $messageId, $recipients)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
165
    {
166
        $url = $baseUrl.
167
            '&_id='.substr($recipients, 0, 16).                     // user: 16 characters hexadecimal string
168
            '&url=/email/'.$templateBaseId.                         // document path
169
            '&rand='.microtime().                                   // cache buster
170
            '&e_n='.$this->getCampaignSource($campaignParams, $templateBaseId).      // event name => will be categorized with the / => e.g. email / newsletter
171
            '&action_name='.$this->getCampaignName($campaignParams); // action name
172
173
        return $url;
174
    }
175
176
    /**
177
     * @param array  $campaignParams
178
     * @param string $templateId
179
     *
180
     * @return string if no source-value is defined in the $campaignParams, $templateId will be used
181
     */
182
    protected function getCampaignSource($campaignParams, $templateId)
183
    {
184
        if (array_key_exists($this->tracking_params_campaign_source, $campaignParams)) {
185
            return $campaignParams[$this->tracking_params_campaign_source];
186
        }
187
188
        return $templateId;
189
    }
190
191
    /**
192
     * @param array $campaignParams
193
     *
194
     * @return string if no name-value is defined in the $campaignParams, date("y-m-d") will be used
195
     */
196
    protected function getCampaignName($campaignParams)
197
    {
198
        if (array_key_exists($this->tracking_params_campaign_name, $campaignParams)) {
199
            return $campaignParams[$this->tracking_params_campaign_name];
200
        }
201
202
        return date('y-m-d');
203
    }
204
}
205