public static function getCampaignFilteredSubscribers(Campaign $campaign)
{
$account = $campaign->account;
$subscribersQuery = Subscriber::query()
->where('subscribers.account_id', $campaign->account_id)
->active(Subscriber::CHANNEL_EMAIL)
->notDeleted()
->select('subscribers.id');
if ($campaign->send_to_all) {
$campaign->recipient_count = $subscribersQuery->count();
$campaign->source = 'v2';
$campaign->save();
return $subscribersQuery;
}
// get campaign relations (many to many)
// tags/groups
$includedTags = collect($campaign->{CampaignRelations::MAILINGLISTS->value});
$excludedTags = collect($campaign->{CampaignRelations::EXCLUDE_MAILINGLISTS->value});
// filters/segments
$includedFilters = Filter::select('conditions')
->account($campaign->account_id)
->whereIn('id', $campaign->{CampaignRelations::FILTERS->value})
->get();
$excludedFilters = Filter::select('conditions')
->account($campaign->account_id)
->whereIn('id', $campaign->{CampaignRelations::EXCLUDE_FILTERS->value})
->get();
// If there is no tag or filters attached, we do not send to any subscriber
if (empty($includedTags) && $includedFilters->isEmpty()) {
$campaign->recipient_count = 0;
$campaign->source = 'v2';
$campaign->save();
return $subscribersQuery->where('id', 0);
}
// Including segments
if (!empty($includedTags) || $includedFilters->isNotEmpty()) {
$includedSubscribersQuery = clone($subscribersQuery);
if ($includedFilters->isNotEmpty()) {
$includedSubscribersQuery->where(
function ($includeQuery) use ($includedFilters, $account) {
foreach ($includedFilters as $includeFilter) {
$includeQuery->orWhere(
function ($q) use ($includeFilter, $account) {
(new QueryBuilder($includeFilter->conditions, $account))->build($q);
}
);
}
}
);
}
// Including tags
if (!empty($includedTags)) {
if ($includedFilters->isNotEmpty()) {
$includedSubscribersQuery->orWhereRaw("tags && ('{" . implode(',', $includedTags->toArray()) . "}')");
} else {
$includedSubscribersQuery->whereRaw("tags && ('{" . implode(',', $includedTags->toArray()) . "}')");
}
}
$subscribersQuery->WhereIn('id', $includedSubscribersQuery);
}
// Excluding segments
if (!empty($excludedTags) || $excludedFilters->isNotEmpty()) {
$excludedSubscribersQuery = clone($subscribersQuery);
if ($excludedFilters->isNotEmpty()) {
$excludedSubscribersQuery->where(
function ($excludeQuery) use ($excludedFilters, $account) {
foreach ($excludedFilters as $excludeFilter) {
$excludeQuery->orWhere(
function ($q) use ($excludeFilter, $account) {
(new QueryBuilder($excludeFilter->conditions, $account))->build($q);
}
);
}
}
);
}
// Excluding tags
if (!empty($excludedTags)) {
if ($excludedFilters->isNotEmpty()) {
$excludedSubscribersQuery->orWhereRaw("tags && ('{" . implode(',', $excludedTags->toArray()) . "}')");
} else {
$excludedSubscribersQuery->whereRaw("tags && ('{" . implode(',', $excludedTags->toArray()) . "}')");
}
}
$subscribersQuery->WhereNotIn('id', $excludedSubscribersQuery);
}
$campaign->recipient_count = $subscribersQuery->count();
$campaign->source = 'v2';
$campaign->save();
return $subscribersQuery;
}