Fix: duplicated entries when exporting subscribers of dynamic segments

This commit fixes a bug in the code that exports subscribers to a CSV
file. This bug caused duplicated entries when exporting subscribers of
dynamic segments. Instead of a given subscriber appearing only once in the
CSV file, they would be included multiple times, and the number of times
would depend on the number of static segments that they had subscribed to.

This bug was caused by a problem in the code that generates the SQL
query used to fetch the subscribers that will be exported. The same
method is used for subscribers not linked to a segment, static
segments, and dynamic segments. The table wp_mailpoet_segments was
included in the query in the three cases, but it should not be included
for dynamic segments as this type of segment does not have a
corresponding entry in this table. Including this table without
specifying a segment ID (as there is not one for dynamic segments),
meant that MySQL would return an extra entry for a given subscriber for
each static segment that they had subscribed to.

[MAILPOET-3900]
This commit is contained in:
Rodrigo Primo
2021-11-11 15:41:29 -03:00
committed by Veljko V
parent 21792b0a0b
commit 5c6000bed6
2 changed files with 33 additions and 3 deletions

View File

@@ -172,6 +172,13 @@ class ImportExportRepository {
$qb = $this->createSubscribersQueryBuilder($limit, $offset);
$qb = $this->addSubscriberCustomFieldsToQueryBuilder($qb);
if (!$segment || $segment->isStatic()) {
// joining with the segments table is used only when there is no segment or for static segments.
// this because dynamic segments don't have a corresponding entry in the segments table.
$qb->leftJoin($subscriberSegmentTable, $segmentTable, $segmentTable, "{$segmentTable}.id = {$subscriberSegmentTable}.segment_id")
->groupBy("{$subscriberTable}.id, {$segmentTable}.id");
}
if (!$segment) {
// if there are subscribers who do not belong to any segment, use
// a CASE function to group them under "Not In Segment"
@@ -190,7 +197,8 @@ class ImportExportRepository {
// Dynamic segments don't have a relation to the segment table,
// So we need to use a placeholder
$qb->addSelect(":segmentName AS segment_name")
->setParameter('segmentName', $segment->getName());
->setParameter('segmentName', $segment->getName())
->groupBy("{$subscriberTable}.id");
$qb = $this->filterHandler->apply($qb, $segment);
}
@@ -217,9 +225,7 @@ class ImportExportRepository {
")
->from($subscriberTable)
->leftJoin($subscriberTable, $subscriberSegmentTable, $subscriberSegmentTable, "{$subscriberTable}.id = {$subscriberSegmentTable}.subscriber_id")
->leftJoin($subscriberSegmentTable, $segmentTable, $segmentTable, "{$segmentTable}.id = {$subscriberSegmentTable}.segment_id")
->andWhere("{$subscriberTable}.deleted_at IS NULL")
->groupBy("{$subscriberTable}.id, {$segmentTable}.id")
->orderBy("{$subscriberTable}.id")
->setFirstResult($offset)
->setMaxResults($limit);