PluginProbe ʕ •ᴥ•ʔ
MailPoet – Newsletters, Email Marketing, and Automation / 3.57.1
MailPoet – Newsletters, Email Marketing, and Automation v3.57.1
5.28.1 5.28.0 5.27.0 5.26.0 5.26.1 5.25.0 5.24.0 4.43.0 4.43.1 4.44.0 4.44.1 4.45.0 4.46.0 4.47.0 4.48.0 4.48.1 4.48.2 4.49.0 4.49.1 4.5.0 4.5.1 4.5.2 4.50.0 4.50.1 4.51.0 4.51.1 4.51.2 4.52.0 4.53.0 4.54.0 4.55.0 4.56.0 4.57.0 4.58.0 4.58.1 4.58.2 4.6.0 4.6.1 4.6.2 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 5.0.0 5.0.1 5.0.2 5.1.0 5.1.1 5.10.0 5.10.1 5.11.0 5.12.0 5.12.1 5.12.10 5.12.11 5.12.12 5.12.13 5.12.2 5.12.3 5.12.4 5.12.5 5.12.6 5.12.7 5.12.8 5.12.9 5.13.0 5.13.1 5.13.2 5.14.0 5.14.1 5.14.2 5.14.3 5.15.0 5.15.1 5.16.0 5.16.1 5.16.2 5.16.3 5.16.4 5.17.0 5.17.1 5.17.2 5.17.3 5.17.4 5.17.5 5.17.6 5.18.0 5.19.0 5.2.0 5.2.1 5.2.2 5.2.3 5.20.0 5.21.0 5.21.1 5.21.2 5.21.3 5.22.0 5.22.1 5.22.2 5.22.3 5.22.4 5.23.0 5.23.1 5.23.2 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.6.3 5.6.4 5.7.0 5.7.1 5.8.0 5.8.1 5.9.0 3.0.0-beta.15 3.7.1 3.0.0-beta.16 3.7.2 3.0.0-beta.17 3.7.3 3.0.0-beta.18 3.7.4 3.0.0-beta.19 3.7.5 3.0.0-beta.2 3.7.6 3.0.0-beta.20 3.7.8 3.0.0-beta.21 3.70.0 3.0.0-beta.22 3.71.0 3.0.0-beta.23 3.71.1 3.0.0-beta.23.1 3.71.2 3.0.0-beta.23.2 3.71.3 3.0.0-beta.24 3.72.0 3.0.0-beta.25 3.73.0 3.0.0-beta.26 3.73.1 3.0.0-beta.27 3.73.2 3.0.0-beta.28 3.74.0 3.0.0-beta.29 3.74.1 3.0.0-beta.3 3.74.2 3.0.0-beta.30 3.74.3 3.0.0-beta.31 3.75.0 3.0.0-beta.32 3.75.1 3.0.0-beta.33 3.76.0 3.0.0-beta.33.1 3.77.0 3.0.0-beta.34.0.0 3.77.1 3.0.0-beta.36.0.0 3.78.0 3.0.0-beta.36.0.1 3.79.0 3.0.0-beta.36.2.0 3.8 3.0.0-beta.36.3.0 3.8.1 3.0.0-beta.36.3.1 3.8.2 3.0.0-beta.37.0.0 3.8.3 3.0.0-beta.4 3.8.4 3.0.0-beta.5 3.8.5 3.0.0-beta.6 3.8.6 3.0.0-beta.7 3.80.0 3.0.0-beta.7.1 3.81.0 3.0.0-beta.8 3.82.0 3.0.0-beta.9 3.83.0 3.0.0-rc.1.0.0 3.84.0 3.0.0-rc.1.0.1 3.84.1 3.0.0-rc.1.0.2 3.85.0 3.0.0-rc.1.0.3 3.85.1 3.0.0-rc.1.0.4 3.86.0 3.0.0-rc.2.0.0 3.87.0 3.0.0-rc.2.0.1 3.87.1 3.0.0-rc.2.0.2 3.87.2 3.0.0-rc.2.0.3 3.88.0 3.0.1 3.88.1 3.0.2 3.88.2 3.0.3 3.89.0 3.0.4 3.89.1 3.0.5 3.89.2 3.0.6 3.89.3 3.0.7 3.89.4 3.0.8 3.9.0 3.0.9 3.9.1 3.1.0 3.90.0 3.10 3.90.1 3.10.1 3.90.2 3.100.0 3.91.0 3.100.1 3.91.1 3.100.2 3.92.0 3.101.0 3.92.1 3.101.1 3.93.0 3.102.0 3.93.1 3.102.1 3.94.0 3.103.0 3.95.0 3.103.1 3.95.1 3.11.0 3.96.0 3.11.1 3.96.1 3.11.2 3.97.0 3.11.3 3.98.0 3.11.4 3.98.1 3.11.5 3.99.0 3.12.0 3.99.1 3.12.1 4.0.0 3.13.0 4.0.1 3.14.0 4.1.0 3.14.1 4.1.1 3.15.0 4.10.0 3.16.0 4.11.0 3.16.1 4.11.1 3.16.2 4.12.0 3.16.3 4.12.1 3.17.0 4.12.2 3.17.1 4.13.0 3.17.2 4.14.0 3.18.0 4.15.0 3.18.1 4.16.0 3.18.2 4.17.0 3.19.0 4.17.1 3.19.1 4.18.0 3.19.2 4.18.1 3.19.3 4.19.0 3.2.0 4.2.0 3.2.1 4.20.0 3.2.2 4.20.1 3.2.3 4.20.2 3.2.4 4.21.0 3.2.5 4.22.0 3.20.0 4.22.1 3.21.0 4.22.2 3.21.1 4.23.0 3.22.0 4.24.0 3.23.0 4.25.0 3.23.1 4.26.0 3.23.2 4.26.1 3.24.0 4.27.0 3.25.0 4.28.0 3.25.1 4.29.0 3.26.0 4.3.0 3.26.1 4.3.1 3.27.0 4.30.0 3.28.0 4.31.0 3.29.0 4.31.1 3.3.0 4.32.0 3.3.1 4.33.0 3.3.2 4.34.0 3.3.3 4.35.0 3.3.4 4.35.1 3.3.5 4.36.0 3.3.6 4.37.0 3.30.0 4.38.0 3.31.0 4.39.0 3.31.1 4.4.0 3.32.0 4.40.0 3.32.1 4.41.0 3.32.2 4.41.1 3.33.0 4.41.2 3.34.0 4.41.3 3.34.1 4.42.0 3.34.2 4.42.1 3.34.3 3.34.4 3.35.0 3.35.1 3.35.3 3.35.4 3.36.0 3.37.0 3.37.1 3.37.2 3.37.3 3.38.0 3.38.1 3.39.0 3.39.1 3.39.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.40.0 3.40.1 3.41.0 3.41.1 3.41.2 3.42.0 3.42.1 3.42.2 3.42.3 3.43.0 3.43.1 3.44.0 3.45.0 3.45.1 3.46.0 3.46.1 3.46.10 3.46.11 3.46.12 3.46.13 3.46.14 3.46.2 3.46.3 3.46.4 3.46.5 3.46.6 3.46.7 3.46.8 3.46.9 3.47.0 3.47.1 3.47.10 3.47.11 3.47.2 3.47.3 3.47.5 3.47.6 3.47.7 3.47.9 3.48.0 3.48.1 3.49.0 3.49.1 3.5.0 3.5.1 3.50.0 3.51.0 3.51.1 3.51.2 3.52.0 3.53.0 3.54.0 3.54.1 3.54.2 3.54.3 3.55.0 3.55.1 3.56.0 3.56.1 3.56.2 3.57.0 3.57.1 3.58.0 3.59.0 3.59.1 3.59.2 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.60.0 3.60.1 3.60.10 3.60.11 3.60.12 3.60.2 3.60.3 3.60.4 3.60.6 3.60.7 3.60.8 3.60.9 3.61.0 3.62.0 3.62.1 3.63.0 3.64.0 3.64.1 3.64.2 3.64.3 3.65.0 trunk 3.65.1 3.0.0 3.66.0 3.0.0-beta.1 3.67.0 3.0.0-beta.10 3.67.1 3.0.0-beta.11 3.68.0 3.0.0-beta.12 3.69.0 3.0.0-beta.13 3.69.1 3.0.0-beta.14 3.7.0
mailpoet / lib / Newsletter / Listing / NewsletterListingRepository.php
mailpoet / lib / Newsletter / Listing Last commit date
NewsletterListingRepository.php 5 years ago index.php 6 years ago
NewsletterListingRepository.php
268 lines
1 <?php declare(strict_types = 1);
2
3 namespace MailPoet\Newsletter\Listing;
4
5 if (!defined('ABSPATH')) exit;
6
7
8 use MailPoet\Entities\NewsletterEntity;
9 use MailPoet\Listing\ListingDefinition;
10 use MailPoet\Listing\ListingRepository;
11 use MailPoet\Util\Helpers;
12 use MailPoet\WP\Functions as WPFunctions;
13 use MailPoetVendor\Doctrine\ORM\QueryBuilder;
14
15 class NewsletterListingRepository extends ListingRepository {
16 private static $supportedStatuses = [
17 NewsletterEntity::STATUS_DRAFT,
18 NewsletterEntity::STATUS_SCHEDULED,
19 NewsletterEntity::STATUS_SENDING,
20 NewsletterEntity::STATUS_SENT,
21 NewsletterEntity::STATUS_ACTIVE,
22 ];
23
24 private static $supportedTypes = [
25 NewsletterEntity::TYPE_STANDARD,
26 NewsletterEntity::TYPE_WELCOME,
27 NewsletterEntity::TYPE_AUTOMATIC,
28 NewsletterEntity::TYPE_NOTIFICATION,
29 NewsletterEntity::TYPE_NOTIFICATION_HISTORY,
30 ];
31
32 public function getFilters(ListingDefinition $definition): array {
33 $group = $definition->getGroup();
34 $typeParam = $definition->getParameters()['type'] ?? null;
35 $groupParam = $definition->getParameters()['group'] ?? null;
36
37 // newsletter types without filters
38 if (in_array($typeParam, [NewsletterEntity::TYPE_NOTIFICATION_HISTORY])) {
39 return [];
40 }
41
42 $queryBuilder = clone $this->queryBuilder;
43 $this->applyFromClause($queryBuilder);
44
45 if ($group) {
46 $this->applyGroup($queryBuilder, $group);
47 }
48
49 if ($typeParam) {
50 $this->applyType($queryBuilder, $typeParam, $groupParam);
51 }
52
53 $queryBuilder
54 ->select('s.id, s.name, COUNT(n) AS newsletterCount')
55 ->join('n.newsletterSegments', 'ns')
56 ->join('ns.segment', 's')
57 ->groupBy('s.id')
58 ->addGroupBy('s.name')
59 ->orderBy('s.name')
60 ->having('COUNT(n) > 0');
61
62 // format segment list
63 $segmentList = [
64 [
65 'label' => WPFunctions::get()->__('All Lists', 'mailpoet'),
66 'value' => '',
67 ],
68 ];
69
70 foreach ($queryBuilder->getQuery()->getResult() as $item) {
71 $segmentList[] = [
72 'label' => sprintf('%s (%d)', $item['name'], $item['newsletterCount']),
73 'value' => $item['id'],
74 ];
75 }
76 return ['segment' => $segmentList];
77 }
78
79 public function getGroups(ListingDefinition $definition): array {
80 $queryBuilder = clone $this->queryBuilder;
81 $this->applyFromClause($queryBuilder);
82 $this->applyParameters($queryBuilder, $definition->getParameters());
83
84 // total count
85 $countQueryBuilder = clone $queryBuilder;
86 $countQueryBuilder->select('COUNT(n) AS newsletterCount');
87 $countQueryBuilder->andWhere('n.deletedAt IS NULL');
88 $totalCount = (int)$countQueryBuilder->getQuery()->getSingleScalarResult();
89
90 // trashed count
91 $trashedCountQueryBuilder = clone $queryBuilder;
92 $trashedCountQueryBuilder->select('COUNT(n) AS newsletterCount');
93 $trashedCountQueryBuilder->andWhere('n.deletedAt IS NOT NULL');
94 $trashedCount = (int)$trashedCountQueryBuilder->getQuery()->getSingleScalarResult();
95
96 // count-by-status query
97 $queryBuilder->select('n.status, COUNT(n) AS newsletterCount');
98 $queryBuilder->andWhere('n.deletedAt IS NULL');
99 $queryBuilder->groupBy('n.status');
100
101 $map = [];
102 foreach ($queryBuilder->getQuery()->getResult() as $item) {
103 $map[$item['status']] = (int)$item['newsletterCount'];
104 }
105
106 $groups = [
107 [
108 'name' => 'all',
109 'label' => WPFunctions::get()->__('All', 'mailpoet'),
110 'count' => $totalCount,
111 ],
112 ];
113
114 $type = $definition->getParameters()['type'] ?? null;
115 switch ($type) {
116 case NewsletterEntity::TYPE_STANDARD:
117 $groups = array_merge($groups, [
118 [
119 'name' => NewsletterEntity::STATUS_DRAFT,
120 'label' => WPFunctions::get()->__('Draft', 'mailpoet'),
121 'count' => $map[NewsletterEntity::STATUS_DRAFT] ?? 0,
122 ],
123 [
124 'name' => NewsletterEntity::STATUS_SCHEDULED,
125 'label' => WPFunctions::get()->__('Scheduled', 'mailpoet'),
126 'count' => $map[NewsletterEntity::STATUS_SCHEDULED] ?? 0,
127 ],
128 [
129 'name' => NewsletterEntity::STATUS_SENDING,
130 'label' => WPFunctions::get()->__('Sending', 'mailpoet'),
131 'count' => $map[NewsletterEntity::STATUS_SENDING] ?? 0,
132 ],
133 [
134 'name' => NewsletterEntity::STATUS_SENT,
135 'label' => WPFunctions::get()->__('Sent', 'mailpoet'),
136 'count' => $map[NewsletterEntity::STATUS_SENT] ?? 0,
137 ],
138 ]);
139 break;
140
141 case NewsletterEntity::TYPE_NOTIFICATION_HISTORY:
142 $groups = array_merge($groups, [
143 [
144 'name' => NewsletterEntity::STATUS_SENDING,
145 'label' => WPFunctions::get()->__('Sending', 'mailpoet'),
146 'count' => $map[NewsletterEntity::STATUS_SENDING] ?? 0,
147 ],
148 [
149 'name' => NewsletterEntity::STATUS_SENT,
150 'label' => WPFunctions::get()->__('Sent', 'mailpoet'),
151 'count' => $map[NewsletterEntity::STATUS_SENT] ?? 0,
152 ],
153 ]);
154 break;
155
156 case NewsletterEntity::TYPE_WELCOME:
157 case NewsletterEntity::TYPE_NOTIFICATION:
158 case NewsletterEntity::TYPE_AUTOMATIC:
159 $groups = array_merge($groups, [
160 [
161 'name' => NewsletterEntity::STATUS_ACTIVE,
162 'label' => WPFunctions::get()->__('Active', 'mailpoet'),
163 'count' => $map[NewsletterEntity::STATUS_ACTIVE] ?? 0,
164 ],
165 [
166 'name' => NewsletterEntity::STATUS_DRAFT,
167 'label' => WPFunctions::get()->__('Not active', 'mailpoet'),
168 'count' => $map[NewsletterEntity::STATUS_DRAFT] ?? 0,
169 ],
170 ]);
171 break;
172 }
173
174 $groups[] = [
175 'name' => 'trash',
176 'label' => WPFunctions::get()->__('Trash', 'mailpoet'),
177 'count' => $trashedCount,
178 ];
179
180 return $groups;
181 }
182
183 protected function applySelectClause(QueryBuilder $queryBuilder) {
184 $queryBuilder->select("PARTIAL n.{id,subject,hash,type,status,sentAt,updatedAt,deletedAt}");
185 }
186
187 protected function applyFromClause(QueryBuilder $queryBuilder) {
188 $queryBuilder->from(NewsletterEntity::class, 'n');
189 }
190
191 protected function applyGroup(QueryBuilder $queryBuilder, string $group) {
192 // include/exclude deleted
193 if ($group === 'trash') {
194 $queryBuilder->andWhere('n.deletedAt IS NOT NULL');
195 } else {
196 $queryBuilder->andWhere('n.deletedAt IS NULL');
197 }
198
199 if (!in_array($group, self::$supportedStatuses)) {
200 return;
201 }
202
203 $queryBuilder
204 ->andWhere('n.status = :status')
205 ->setParameter('status', $group);
206 }
207
208 protected function applySearch(QueryBuilder $queryBuilder, string $search) {
209 $search = Helpers::escapeSearch($search);
210 $queryBuilder
211 ->andWhere('n.subject LIKE :search')
212 ->setParameter('search', "%$search%");
213 }
214
215 protected function applyFilters(QueryBuilder $queryBuilder, array $filters) {
216 $segmentId = $filters['segment'] ?? null;
217 if ($segmentId) {
218 $queryBuilder
219 ->join('n.newsletterSegments', 'ns')
220 ->andWhere('ns.segment = :segmentId')
221 ->setParameter('segmentId', $segmentId);
222 }
223 }
224
225 protected function applyParameters(QueryBuilder $queryBuilder, array $parameters) {
226 $type = $parameters['type'] ?? null;
227 $group = $parameters['group'] ?? null;
228 $parentId = $parameters['parentId'] ?? null;
229
230 if ($type) {
231 $this->applyType($queryBuilder, $type, $group);
232 }
233
234 if ($parentId) {
235 $queryBuilder
236 ->andWhere('n.parent = :parentId')
237 ->setParameter('parentId', $parentId);
238 }
239 }
240
241 protected function applySorting(QueryBuilder $queryBuilder, string $sortBy, string $sortOrder) {
242 if ($sortBy === 'sentAt') {
243 $queryBuilder->addSelect('CASE WHEN n.sentAt IS NULL THEN 1 ELSE 0 END AS HIDDEN sentAtIsNull');
244 $queryBuilder->addOrderBy('sentAtIsNull', 'DESC');
245 }
246 $queryBuilder->addOrderBy("n.$sortBy", $sortOrder);
247 }
248
249 private function applyType(QueryBuilder $queryBuilder, string $type, string $group = null) {
250 if (!in_array($type, self::$supportedTypes)) {
251 return;
252 }
253
254 if ($type === NewsletterEntity::TYPE_AUTOMATIC && $group) {
255 $queryBuilder
256 ->join('n.options', 'o')
257 ->join('o.optionField', 'opf')
258 ->andWhere('o.value = :group')
259 ->setParameter('group', $group)
260 ->andWhere('opf.newsletterType = n.type');
261 } else {
262 $queryBuilder
263 ->andWhere('n.type = :type')
264 ->setParameter('type', $type);
265 }
266 }
267 }
268