PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 4.8.0
GiveWP – Donation Plugin and Fundraising Platform v4.8.0
4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / src / Donations / Endpoints / ListDonations.php
give / src / Donations / Endpoints Last commit date
DonationActions.php 11 months ago Endpoint.php 1 year ago ListDonations.php 9 months ago SwitchDonationView.php 4 years ago
ListDonations.php
336 lines
1 <?php
2
3 namespace Give\Donations\Endpoints;
4
5 use Give\Donations\ListTable\DonationsListTable;
6 use Give\Donations\ValueObjects\DonationMetaKeys;
7 use Give\Donations\ValueObjects\DonationMode;
8 use Give\Framework\Database\DB;
9 use Give\Framework\ListTable\Exceptions\ColumnIdCollisionException;
10 use Give\Framework\QueryBuilder\QueryBuilder;
11 use Give\Framework\QueryBuilder\Types\Operator;
12 use WP_REST_Request;
13 use WP_REST_Response;
14
15 /**
16 * @since 4.0.0 replace form with campaignId.
17 * @since 3.4.0 The class is extendable
18 */
19 class ListDonations extends Endpoint
20 {
21 /**
22 * @var string
23 */
24 protected $endpoint = 'admin/donations';
25
26 /**
27 * @var WP_REST_Request
28 */
29 protected $request;
30
31 /**
32 * @var DonationsListTable
33 */
34 protected $listTable;
35
36 /**
37 * @since 4.6.0 add status parameter to filter donations by status
38 * @since 3.4.0
39 * @access public
40 */
41 public function __construct(DonationsListTable $listTable)
42 {
43 $this->listTable = $listTable;
44 }
45
46 /**
47 * @inheritDoc
48 */
49 public function registerRoute()
50 {
51 register_rest_route(
52 'give-api/v2',
53 $this->endpoint,
54 [
55 [
56 'methods' => 'GET',
57 'callback' => [$this, 'handleRequest'],
58 'permission_callback' => [$this, 'permissionsCheck'],
59 ],
60 'args' => [
61 'page' => [
62 'type' => 'integer',
63 'required' => false,
64 'default' => 1,
65 'minimum' => 1
66 ],
67 'perPage' => [
68 'type' => 'integer',
69 'required' => false,
70 'default' => 30,
71 'minimum' => 1
72 ],
73 'campaignId' => [
74 'type' => 'integer',
75 'required' => false,
76 'default' => 0
77 ],
78 'search' => [
79 'type' => 'string',
80 'required' => false,
81 'sanitize_callback' => 'sanitize_text_field',
82 ],
83 'start' => [
84 'type' => 'string',
85 'required' => false,
86 'validate_callback' => [$this, 'validateDate']
87 ],
88 'end' => [
89 'type' => 'string',
90 'required' => false,
91 'validate_callback' => [$this, 'validateDate']
92 ],
93 'donor' => [
94 'type' => 'string',
95 'required' => false,
96 'sanitize_callback' => 'sanitize_text_field',
97 ],
98 'sortColumn' => [
99 'type' => 'string',
100 'required' => false,
101 'sanitize_callback' => 'sanitize_text_field',
102 ],
103 'sortDirection' => [
104 'type' => 'string',
105 'required' => false,
106 'enum' => [
107 'asc',
108 'desc',
109 ],
110 ],
111 'locale' => [
112 'type' => 'string',
113 'required' => false,
114 'default' => get_locale(),
115 ],
116 'testMode' => [
117 'type' => 'boolean',
118 'required' => false,
119 'default' => give_is_test_mode(),
120 ],
121 'return' => [
122 'type' => 'string',
123 'required' => false,
124 'default' => 'columns',
125 'enum' => [
126 'model',
127 'columns',
128 ],
129 ],
130 'status' => [
131 'type' => 'string',
132 'required' => false,
133 'default' => 'active',
134 'enum' => [
135 'active',
136 'trash',
137 ],
138 'description' => 'Filter donations by status: active (all except trash), or trash.'
139 ],
140 ],
141 ]
142 );
143 }
144
145 /**
146 * @since 2.24.0 Change this to use the new ListTable class
147 * @since 2.20.0
148 *
149 * @param WP_REST_Request $request
150 *
151 * @return WP_REST_Response
152 * @throws ColumnIdCollisionException
153 */
154 public function handleRequest(WP_REST_Request $request): WP_REST_Response
155 {
156 $this->request = $request;
157
158 $donations = $this->getDonations();
159 $donationsCount = $this->getTotalDonationsCount();
160 $totalPages = (int)ceil($donationsCount / $this->request->get_param('perPage'));
161
162 if ('model' === $this->request->get_param('return')) {
163 $items = $donations;
164 } else {
165 $this->listTable->items($donations, $this->request->get_param('locale') ?? '');
166 $items = $this->listTable->getItems();
167 }
168
169 return new WP_REST_Response(
170 [
171 'items' => $items,
172 'totalItems' => $donationsCount,
173 'totalPages' => $totalPages,
174 ]
175 );
176 }
177
178 /**
179 * @since 2.24.0 Replace Query Builder with Donations model
180 * @since 2.21.0
181 *
182 * @return array
183 */
184 public function getDonations(): array
185 {
186 $page = $this->request->get_param('page');
187 $perPage = $this->request->get_param('perPage');
188 $sortColumns = $this->listTable->getSortColumnById($this->request->get_param('sortColumn') ?: 'id');
189 $sortDirection = $this->request->get_param('sortDirection') ?: 'desc';
190
191 $query = give()->donations->prepareQuery();
192 list($query) = $this->getWhereConditions($query);
193
194 foreach ($sortColumns as $sortColumn) {
195 $query->orderBy($sortColumn, $sortDirection);
196 }
197
198 $query->limit($perPage)
199 ->offset(($page - 1) * $perPage);
200
201 $donations = $query->getAll();
202
203 if (!$donations) {
204 return [];
205 }
206
207 return $donations;
208 }
209
210 /**
211 * @since 2.24.0 Replace Query Builder with Donations model
212 * @since 2.21.0
213 *
214 * @return int
215 */
216 public function getTotalDonationsCount(): int
217 {
218 $query = DB::table('posts')
219 ->where('post_type', 'give_payment')
220 ->groupBy('mode');
221
222 list($query, $dependencies) = $this->getWhereConditions($query);
223
224 $query->attachMeta(
225 'give_donationmeta',
226 'ID',
227 'donation_id',
228 ...DonationMetaKeys::getColumnsForAttachMetaQueryFromArray($dependencies)
229 );
230
231 return $query->count();
232 }
233
234 /**
235 * @since 4.8.0 Added support for subscriptionId parameter to filter donations
236 * @since 4.6.0 add status status condition to filter donations
237 * @since 3.4.0 Make this method protected so it can be extended
238 * @since 3.2.0 Updated query to account for possible null and empty values for _give_payment_mode meta
239 * @since 2.24.0 Remove joins as it uses ModelQueryBuilder and change clauses to use attach_meta
240 * @since 2.21.0
241 *
242 * @param QueryBuilder $query
243 *
244 * @return array{0: QueryBuilder, 1: array<DonationMetaKeys>}
245 */
246 protected function getWhereConditions(QueryBuilder $query): array
247 {
248 $search = $this->request->get_param('search');
249 $start = $this->request->get_param('start');
250 $end = $this->request->get_param('end');
251 $donor = $this->request->get_param('donor');
252 $testMode = $this->request->get_param('testMode');
253 $campaignId = $this->request->get_param('campaignId');
254 $subscriptionId = $this->request->get_param('subscriptionId');
255 $status = $this->request->get_param('status');
256
257 $dependencies = [
258 DonationMetaKeys::MODE(),
259 ];
260
261 $hasWhereConditions = $search || $start || $end || $campaignId || $subscriptionId || $donor;
262
263 $query->where('post_type', 'give_payment');
264
265 if ($status === 'trash') {
266 $query->where('post_status', 'trash');
267 } elseif ($status === 'active') {
268 $query->where('post_status', 'trash', '<>');
269 }
270
271 if ($search) {
272 if (ctype_digit($search)) {
273 $query->where('id', $search);
274 } elseif (strpos($search, '@') !== false) {
275 $query
276 ->whereLike('give_donationmeta_attach_meta_email.meta_value', $search);
277 $dependencies[] = DonationMetaKeys::EMAIL();
278 } else {
279 $query
280 ->whereLike('give_donationmeta_attach_meta_firstName.meta_value', $search)
281 ->orWhereLike('give_donationmeta_attach_meta_lastName.meta_value', $search);
282 $dependencies[] = DonationMetaKeys::FIRST_NAME();
283 $dependencies[] = DonationMetaKeys::LAST_NAME();
284 }
285 }
286
287 if ($donor) {
288 if (ctype_digit($donor)) {
289 $query
290 ->where('give_donationmeta_attach_meta_donorId.meta_value', $donor);
291 $dependencies[] = DonationMetaKeys::DONOR_ID();
292 } else {
293 $query
294 ->whereLike('give_donationmeta_attach_meta_firstName.meta_value', $donor)
295 ->orWhereLike('give_donationmeta_attach_meta_lastName.meta_value', $donor);
296 $dependencies[] = DonationMetaKeys::FIRST_NAME();
297 $dependencies[] = DonationMetaKeys::LAST_NAME();
298 }
299 }
300
301 if ($campaignId) {
302 $query
303 ->where('give_donationmeta_attach_meta_campaignId.meta_value', $campaignId);
304 $dependencies[] = DonationMetaKeys::CAMPAIGN_ID();
305 }
306
307 if ($subscriptionId) {
308 $query
309 ->where('give_donationmeta_attach_meta_subscriptionId.meta_value', $subscriptionId);
310 $dependencies[] = DonationMetaKeys::SUBSCRIPTION_ID();
311 }
312
313 if ($start && $end) {
314 $query->whereBetween('post_date', $start, $end);
315 } elseif ($start) {
316 $query->where('post_date', $start, '>=');
317 } elseif ($end) {
318 $query->where('post_date', $end, '<=');
319 }
320
321 if ($hasWhereConditions) {
322 $query->havingRaw('HAVING COALESCE(give_donationmeta_attach_meta_mode.meta_value, %s) = %s', DonationMode::LIVE, $testMode ? DonationMode::TEST : DonationMode::LIVE);
323 } elseif ($testMode) {
324 $query->where('give_donationmeta_attach_meta_mode.meta_value', DonationMode::TEST);
325 } else {
326 $query->whereIsNull('give_donationmeta_attach_meta_mode.meta_value')
327 ->orWhere('give_donationmeta_attach_meta_mode.meta_value', DonationMode::TEST, '<>');
328 }
329
330 return [
331 $query,
332 $dependencies,
333 ];
334 }
335 }
336