Skip to content

Commit

Permalink
Added campaign recipients in reports
Browse files Browse the repository at this point in the history
  • Loading branch information
bencroker committed Jul 6, 2021
1 parent 832f618 commit e07eecd
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 22 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

## 1.20.0 - Unreleased
### Added
- Added the ability to view, filter and sort all campaign recipients in reports ([#228](https://github.com/putyourlightson/craft-campaign/issues/228)).
- Added the ability to filter and sort all activity, locations and devices in reports ([#231](https://github.com/putyourlightson/craft-campaign/issues/231)).
- Added the ability to see which contacts a campaign was sent to in reports ([#228](https://github.com/putyourlightson/craft-campaign/issues/228)).

### Changed
- Imports now force allow CSV file uploads even if they are excluded from the `allowedFileExtensions` general config setting ([#234](https://github.com/putyourlightson/craft-campaign/issues/234)).
Expand Down
1 change: 1 addition & 0 deletions src/Campaign.php
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ protected function getCpRoutes(): array
{
return [
'campaign/reports/campaigns/<campaignId:\d+>' => ['template' => 'campaign/reports/campaigns/_view'],
'campaign/reports/campaigns/<campaignId:\d+>/recipients' => ['template' => 'campaign/reports/campaigns/_recipients'],
'campaign/reports/campaigns/<campaignId:\d+>/contact-activity' => ['template' => 'campaign/reports/campaigns/_contact-activity'],
'campaign/reports/campaigns/<campaignId:\d+>/links' => ['template' => 'campaign/reports/campaigns/_links'],
'campaign/reports/campaigns/<campaignId:\d+>/locations' => ['template' => 'campaign/reports/campaigns/_locations'],
Expand Down
7 changes: 4 additions & 3 deletions src/resources/js/Cp.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Campaign.CP = Garnish.Base.extend(
init: function() {
this.loadElementThumbs();
this.addListener($.find('.show-more'), 'click', 'showMore');
this.addListener($.find('.interaction-filter'), 'change', 'filterInteraction');
this.addListener($.find('.filter'), 'change', 'applyFilter');
},

loadElementThumbs: function() {
Expand All @@ -28,12 +28,13 @@ Campaign.CP = Garnish.Base.extend(
$this.remove();
},

filterInteraction: function(event) {
applyFilter: function(event) {
event.preventDefault();

var $this = $(event.target);
var baseUrl = window.location.href.split('?')[0];
window.location.href = $this.val() ? baseUrl + '?interaction=' + $this.val() : baseUrl;
var filterType = $this.attr('data-type');
window.location.href = $this.val() ? baseUrl + '?' + filterType + '=' + $this.val() : baseUrl;
},
}
);
Expand Down
24 changes: 24 additions & 0 deletions src/services/ReportsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,30 @@ public function getCampaignChartData(int $campaignId, string $interval = null):
);
}

/**
* Returns campaign recipients
*
* @param int $campaignId
* @param int|null $sendoutId
* @param int|null $limit
*
* @return ContactCampaignModel[]
*/
public function getCampaignRecipients(int $campaignId, int $sendoutId = null, int $limit = null): array
{
$contactCampaignQuery = ContactCampaignRecord::find()
->where(['campaignId' => $campaignId])
->orderBy(['sent' => SORT_DESC]);

if ($sendoutId !== null) {
$contactCampaignQuery->andWhere(['sendoutId' => $sendoutId]);
}

$contactCampaignRecords = $contactCampaignQuery->all();

return ContactCampaignModel::populateModels($contactCampaignRecords, false);
}

/**
* Returns campaign contact activity
*
Expand Down
6 changes: 4 additions & 2 deletions src/templates/reports/campaigns/_contact-activity.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
{% block content %}

{% set interaction = craft.app.request.param('interaction') %}
{% include 'campaign/reports/campaigns/_includes/contact-activity' with { contactActivity: craft.campaign.reports.getCampaignContactActivity(campaignId, interaction) } %}
{% include 'campaign/reports/campaigns/_includes/contact-activity' with {
contactActivity: craft.campaign.reports.getCampaignContactActivity(campaignId, interaction)
} %}

{% endblock %}
{% endblock %}
19 changes: 7 additions & 12 deletions src/templates/reports/campaigns/_includes/contact-activity.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,13 @@
{% set interaction = craft.app.request.param('interaction') %}
{{ "Filter by interaction"|t('campaign') }}:
<div class="select">
<select class="interaction-filter">
<optgroup label="{{ "Interactions"|t('campaign') }}">
<option value="">{{ "All"|t('campaign') }}</option>
<option value="opened" {{ interaction == 'opened' ? 'selected' }}>{{ "Opened"|t('campaign') }}</option>
<option value="clicked" {{ interaction == 'clicked' ? 'selected' }}>{{ "Clicked"|t('campaign') }}</option>
<option value="unsubscribed" {{ interaction == 'unsubscribed' ? 'selected' }}>{{ "Unsubscribed"|t('campaign') }}</option>
<option value="complained" {{ interaction == 'complained' ? 'selected' }}>{{ "Complained"|t('campaign') }}</option>
<option value="bounced" {{ interaction == 'bounced' ? 'selected' }}>{{ "Bounced"|t('campaign') }}</option>
</optgroup>
<optgroup label="{{ "Activity"|t('campaign') }}">
<option value="sent" {{ interaction == 'sent' ? 'selected' }}>{{ "Sent"|t('campaign') }}</option>
</optgroup>
<select class="filter" data-type="interaction">
<option value="">{{ "All"|t('campaign') }}</option>
<option value="opened" {{ interaction == 'opened' ? 'selected' }}>{{ "Opened"|t('campaign') }}</option>
<option value="clicked" {{ interaction == 'clicked' ? 'selected' }}>{{ "Clicked"|t('campaign') }}</option>
<option value="unsubscribed" {{ interaction == 'unsubscribed' ? 'selected' }}>{{ "Unsubscribed"|t('campaign') }}</option>
<option value="complained" {{ interaction == 'complained' ? 'selected' }}>{{ "Complained"|t('campaign') }}</option>
<option value="bounced" {{ interaction == 'bounced' ? 'selected' }}>{{ "Bounced"|t('campaign') }}</option>
</select>
</div>
<br/><br/>
Expand Down
63 changes: 63 additions & 0 deletions src/templates/reports/campaigns/_includes/recipients.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{% import 'campaign/_macros' as macros %}

{{ "Filter by sendout"|t('campaign') }}:
<div class="select">
<select class="filter" data-type="sendout">
<option value="">{{ "All"|t('campaign') }}</option>
{% for sendout in data.sendouts %}
<option value="{{ sendout.id }}" {{ sendoutId == sendout.id ? 'selected' }}>
{{ sendout.title }}
</option>
{% endfor %}
</select>
</div>
<br/><br/>

{% if recipients|length %}

<table id="recipients" class="display responsive nowrap">
<thead>
<th scope="col">{{ "Email"|t('campaign') }}</th>
<th scope="col">{{ "Sendout"|t('campaign') }}</th>
<th scope="col">{{ "Sent"|t('campaign') }}</th>
</thead>
<tbody>
{% for recipient in recipients %}
{% set contact = recipient.contact %}
{% if contact %}
<tr>
<th scope="row" data-title="{{ 'Email'|t('campaign') }}">
<a href="{{ contact.reportUrl }}">{{ contact.email }}</a>
</th>
<td data-title="{{ 'Sendout'|t('campaign') }}">
{% set sendout = recipient.sendout %}
{% if sendout %}
<a href="{{ sendout.cpEditUrl }}">{{ sendout.title }}</a>
{% endif %}
</td>
<td data-order="{{ recipient.sent|datetime('U') }}" data-title="{{ 'Sent'|t('campaign') }}">
{{ recipient.sent|datetime }}
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>

{% js %}
new Campaign.DataTable({
id: 'recipients',
itemName: 'recipients',
options: {
order: [[ 2, 'desc' ]],
},
});
{% endjs %}

{% else %}

<p>{{ "No recipients for this campaign."|t('campaign') }}</p>

{% endif %}

<br/><br/>
10 changes: 8 additions & 2 deletions src/templates/reports/campaigns/_includes/report.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{% macro linkInteration(campaign, interaction) -%}
{% set value = attribute(campaign, interaction) ?? 0 %}
{% if value %}
<a href="{{ campaign.reportUrl ~ '/contact-activity?interaction=' ~ interaction }}">{{ value }}</a>
<a href="{{ campaign.reportUrl ~ '/contact-activity?interaction=' ~ interaction }}">
{{- value -}}
</a>
{% else %}
{{ value }}
{% endif %}
Expand Down Expand Up @@ -58,7 +60,11 @@ <h2>{{ "Campaign Details"|t('campaign') }}</h2>
</tr>
<tr>
<th class="light">{{ 'Recipients'|t('campaign') }}</th>
<td>{{ data.campaign.recipients }}</td>
<td>
<a href="{{ campaign.reportUrl ~ '/recipients' }}">
{{ data.campaign.recipients }}
</a>
</td>
</tr>
<tr>
<th class="light">{{ 'Opened'|t('campaign') }}</th>
Expand Down
20 changes: 20 additions & 0 deletions src/templates/reports/campaigns/_recipients.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{% extends 'campaign/reports/_layout' %}

{% set campaign = craft.campaign.getCampaignById(campaignId) %}
{% set title = 'Recipients'|t('campaign') %}

{% set crumbs = [
{ label: 'Campaigns'|t('campaign'), url: url('campaign/reports/campaigns') },
{ label: campaign.title, url: campaign.reportUrl }
] %}


{% block content %}

{% set sendoutId = craft.app.request.param('sendout') %}
{% include 'campaign/reports/campaigns/_includes/recipients' with {
recipients: craft.campaign.reports.getCampaignRecipients(campaignId, sendoutId),
data: craft.campaign.reports.getCampaignReportData(campaignId),
} %}

{% endblock %}
6 changes: 5 additions & 1 deletion src/templates/sendouts/_view.html
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,11 @@ <h5 class="heading">{{ "Sent By"|t('campaign') }}</h5>
{% if sendout.status == 'sent' or sendout.recipients > 0 %}
<div class="data">
<h5 class="heading">{{ "Recipients"|t('campaign') }}</h5>
<div class="value">{{ sendout.recipients }}</div>
<div class="value">
<a href="{{ sendout.campaign.reportUrl ~ '/recipients?sendout=' ~ sendout.id }}">
{{ sendout.recipients }}
</a>
</div>
</div>
<div class="data">
<h5 class="heading">{{ "Fails"|t('campaign') }}</h5>
Expand Down
2 changes: 1 addition & 1 deletion src/translations/en/campaign.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
'Access utility' => '',
'Activate Sending' => '',
'Active' => '',
'Activity' => '',
'Add a campaign' => '',
'Add a contact' => '',
'Add a mailing list' => '',
Expand Down Expand Up @@ -249,6 +248,7 @@
'Failed' => '',
'Fails' => '',
'Filter by interaction' => '',
'Filter by sendout' => '',
'Finalising setup' => '',
'First Interaction' => '',
'First Name' => '',
Expand Down

0 comments on commit e07eecd

Please sign in to comment.