PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 4.10.0
GiveWP – Donation Plugin and Fundraising Platform v4.10.0
4.16.4 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 / Campaigns / Controllers / CampaignRequestController.php
give / src / Campaigns / Controllers Last commit date
CampaignRequestController.php 9 months ago
CampaignRequestController.php
392 lines
1 <?php
2
3 namespace Give\Campaigns\Controllers;
4
5 use Exception;
6 use Give\API\REST\V3\Routes\Campaigns\ValueObjects\CampaignRoute;
7 use Give\Campaigns\Models\Campaign;
8 use Give\Campaigns\Models\CampaignPage;
9 use Give\Campaigns\Repositories\CampaignRepository;
10 use Give\Campaigns\Repositories\CampaignsDataRepository;
11 use Give\Campaigns\ValueObjects\CampaignGoalType;
12 use Give\Campaigns\ValueObjects\CampaignPageStatus;
13 use Give\Campaigns\ValueObjects\CampaignStatus;
14 use Give\Campaigns\ValueObjects\CampaignType;
15 use Give\Campaigns\ViewModels\CampaignViewModel;
16 use Give\Donations\ValueObjects\DonationMetaKeys;
17 use Give\Framework\Database\DB;
18 use Give\Framework\Models\ModelQueryBuilder;
19 use Give_Form_Duplicator;
20 use WP_Error;
21 use WP_REST_Request;
22 use WP_REST_Response;
23
24 /**
25 * @since 4.0.0
26 */
27 class CampaignRequestController
28 {
29 /**
30 * @since 4.0.0
31 *
32 * @return WP_Error | WP_REST_Response
33 */
34 public function getCampaign(WP_REST_Request $request)
35 {
36 $campaign = Campaign::find($request->get_param('id'));
37
38 if ( ! $campaign) {
39 return new WP_Error('campaign_not_found', __('Campaign not found', 'give'), ['status' => 404]);
40 }
41
42 return new WP_REST_Response((new CampaignViewModel($campaign))->exports());
43 }
44
45 /**
46 * @since 4.0.0
47 */
48 public function getCampaigns(WP_REST_Request $request): WP_REST_Response
49 {
50 $ids = $request->get_param('ids');
51 $page = $request->get_param('page');
52 $perPage = $request->get_param('per_page');
53 $status = $request->get_param('status');
54 $sortBy = $request->get_param('sortBy');
55 $orderBy = $request->get_param('orderBy');
56 $search = $request->get_param('search');
57
58 $query = Campaign::query();
59
60 $query->whereIn('status', $status);
61
62 if ( ! empty($ids)) {
63 $query->whereIn('id', $ids);
64 }
65
66 if ($search) {
67 $query->whereLike('campaign_title', '%%' . $search . '%%');
68 }
69
70 $totalQuery = clone $query;
71
72 $query
73 ->limit($perPage)
74 ->offset(($page - 1) * $perPage);
75
76 $this->orderCampaigns($query, $sortBy, $orderBy);
77
78 $campaigns = $query->getAll() ?? [];
79 $totalCampaigns = empty($campaigns) ? 0 : $totalQuery->count();
80 $totalPages = $totalCampaigns === 0 ? 0 : (int)ceil($totalCampaigns / $perPage);
81
82 $ids = array_map(function ($campaign) {
83 return $campaign->id;
84 }, $campaigns);
85
86 $campaignsData = ! empty($ids)
87 ? CampaignsDataRepository::campaigns($ids)
88 : null;
89
90 $campaigns = array_map(function ($campaign) use ($campaignsData) {
91 $view = new CampaignViewModel($campaign);
92
93 if ($campaignsData) {
94 $view->setData($campaignsData);
95 }
96
97 return $view->exports();
98 }, $campaigns);
99
100 $response = rest_ensure_response($campaigns);
101 $response->header('X-WP-Total', $totalCampaigns);
102 $response->header('X-WP-TotalPages', $totalPages);
103
104 $base = add_query_arg(
105 map_deep($request->get_query_params(), function ($value) {
106 if (is_bool($value)) {
107 $value = $value ? 'true' : 'false';
108 }
109
110 return urlencode($value);
111 }),
112 rest_url(CampaignRoute::CAMPAIGNS)
113 );
114
115 if ($page > 1) {
116 $prevPage = $page - 1;
117
118 if ($prevPage > $totalPages) {
119 $prevPage = $totalPages;
120 }
121
122 $response->link_header('prev', add_query_arg('page', $prevPage, $base));
123 }
124
125 if ($totalPages > $page) {
126 $nextPage = $page + 1;
127 $response->link_header('next', add_query_arg('page', $nextPage, $base));
128 }
129
130 return $response;
131 }
132
133 /**
134 * @since 4.0.0
135 *
136 * @return WP_Error | WP_REST_Response
137 *
138 * @throws Exception
139 */
140 public function updateCampaign(WP_REST_Request $request)
141 {
142 $campaign = Campaign::find($request->get_param('id'));
143
144 if ( ! $campaign) {
145 return new WP_Error('campaign_not_found', __('Campaign not found', 'give'), ['status' => 404]);
146 }
147
148 $statusMap = [
149 'archived' => CampaignStatus::ARCHIVED(),
150 'draft' => CampaignStatus::DRAFT(),
151 'active' => CampaignStatus::ACTIVE(),
152 ];
153
154 foreach ($request->get_params() as $key => $value) {
155 switch ($key) {
156 case 'id':
157 break;
158 case 'status':
159 $status = array_key_exists($value, $statusMap)
160 ? $statusMap[$value]
161 : CampaignStatus::DRAFT();
162
163 $campaign->status = $status;
164
165 break;
166 case 'goal':
167 $campaign->goal = (int)$value;
168 break;
169 case 'goalType':
170 $campaign->goalType = new CampaignGoalType($value);
171 break;
172 case 'defaultFormId':
173 give(CampaignRepository::class)->updateDefaultCampaignForm(
174 $campaign,
175 $request->get_param('defaultFormId')
176 );
177 break;
178 case 'pageId':
179 $campaign->pageId = (int)$value;
180 break;
181 default:
182 if ($campaign->hasProperty($key)) {
183 $campaign->$key = $value;
184 }
185 }
186 }
187
188 if ($campaign->isDirty()) {
189 $campaign->save();
190 }
191
192 return new WP_REST_Response((new CampaignViewModel($campaign))->exports());
193 }
194
195 /**
196 * @since 4.0.0
197 *
198 * @return WP_Error | WP_REST_Response
199 * @throws Exception
200 */
201 public function mergeCampaigns(WP_REST_Request $request)
202 {
203 $destinationCampaign = Campaign::find($request->get_param('id'));
204
205 if ( ! $destinationCampaign) {
206 return new WP_Error('campaign_not_found', __('Campaign not found', 'give'), ['status' => 404]);
207 }
208
209 $campaignsToMerge = Campaign::query()->whereIn('id', $request->get_param('campaignsToMergeIds'))->getAll();
210
211 $campaignsMerged = $destinationCampaign->merge(...$campaignsToMerge);
212
213 return new WP_REST_Response($campaignsMerged);
214 }
215
216
217 /**
218 * @since 4.0.0
219 *
220 * @throws Exception
221 */
222 public function createCampaign(WP_REST_Request $request): WP_REST_Response
223 {
224 $campaign = Campaign::create([
225 'type' => CampaignType::CORE(),
226 'title' => $request->get_param('title'),
227 'shortDescription' => $request->get_param('shortDescription') ?? '',
228 'longDescription' => '',
229 'logo' => '',
230 'image' => $request->get_param('image') ?? '',
231 'primaryColor' => '#0b72d9',
232 'secondaryColor' => '#27ae60',
233 'goal' => (int)$request->get_param('goal'),
234 'goalType' => new CampaignGoalType($request->get_param('goalType')),
235 'status' => CampaignStatus::ACTIVE(),
236 'startDate' => $request->get_param('startDateTime'),
237 'endDate' => $request->get_param('endDateTime'),
238 ]);
239
240 return new WP_REST_Response((new CampaignViewModel($campaign))->exports(), 201);
241 }
242
243 /**
244 * @since 4.0.0
245 *
246 * @throws Exception
247 */
248 public function createCampaignPage(WP_REST_Request $request): WP_REST_Response
249 {
250 $campaignPage = CampaignPage::create([
251 'campaignId' => (int)$request->get_param('id'),
252 'status' => CampaignPageStatus::DRAFT(),
253 ]);
254
255 return new WP_REST_Response($campaignPage->toArray(), 201);
256 }
257
258 /**
259 * @since 4.2.0
260 *
261 * @throws Exception
262 */
263 public function duplicateCampaign(WP_REST_Request $request): WP_REST_Response
264 {
265 require_once(GIVE_PLUGIN_DIR . '/includes/admin/forms/class-give-form-duplicator.php');
266
267 $campaign = Campaign::find($request->get_param('id'));
268
269 if ( ! $campaign) {
270 return new WP_REST_Response('Campaign does not exist', 404);
271 }
272
273 $forms = $campaign->forms();
274 $campaignRepository = give(CampaignRepository::class);
275
276 $campaign->id = null;
277 $campaign->title = sprintf(__('%s (copy)', 'give'), $campaign->title);
278 $campaign->save();
279
280 foreach ($forms->getAll() as $form) {
281 if ( ! $post = get_post($form->id)) {
282 continue;
283 }
284
285 $isDefaultForm = $campaign->defaultFormId === $form->id;
286
287 $newFormId = wp_insert_post([
288 'comment_status' => $post->comment_status,
289 'ping_status' => $post->ping_status,
290 'post_author' => get_current_user_id(),
291 'post_content' => $post->post_content,
292 'post_date_gmt' => current_time('mysql', true),
293 'post_excerpt' => $post->post_excerpt,
294 'post_name' => $post->post_name,
295 'post_parent' => $post->post_parent,
296 'post_password' => $post->post_password,
297 'post_status' => $isDefaultForm ? 'publish' : 'draft',
298 'post_title' => $post->post_title,
299 'post_type' => $post->post_type,
300 'to_ping' => $post->to_ping,
301 'menu_order' => $post->menu_order,
302 ]);
303
304 Give_Form_Duplicator::duplicate_taxonomies($newFormId, $post);
305 Give_Form_Duplicator::duplicate_meta_data($newFormId, $post);
306 Give_Form_Duplicator::reset_stats($newFormId);
307
308 if ($isDefaultForm) {
309 $campaign->defaultFormId = $newFormId;
310 }
311
312 $campaignRepository->addCampaignForm($campaign, $newFormId, $isDefaultForm);
313 }
314
315 if ($campaignPage = CampaignPage::find($campaign->pageId)) {
316 $campaignPage->id = null;
317 $campaignPage->status = CampaignPageStatus::DRAFT();
318 $campaignPage->campaignId = $campaign->id;
319
320 // update campaign id attribute
321 $campaignPage->content = preg_replace(
322 '/"campaignId":(\d+)/',
323 '"campaignId":' . $campaign->id,
324 $campaignPage->content
325 );
326
327 $campaignPage->save();
328
329 $campaign->pageId = $campaignPage->id;
330 }
331
332 $campaign->save();
333
334 return new WP_REST_Response([
335 'errors' => 0, // needed by the list table
336 ], 201);
337 }
338
339 /**
340 * @since 4.0.0
341 */
342 private function orderCampaigns(ModelQueryBuilder $query, $sortBy, $orderBy)
343 {
344 switch ($sortBy) {
345 case 'date':
346 $query->orderBy('date_created', $orderBy);
347
348 break;
349 case 'amount':
350 $query
351 ->selectRaw(
352 '(SELECT SUM(amount) FROM %1s WHERE campaign_id = campaigns.id) AS amount',
353 DB::prefix('give_revenue')
354 )
355 ->orderBy('amount', $orderBy);
356
357 break;
358 case 'donations':
359 $query
360 ->selectRaw(
361 '(SELECT COUNT(donation_id) FROM %1s WHERE campaign_id = campaigns.id) AS donationsCount',
362 DB::prefix('give_revenue')
363 )
364 ->orderBy('donationsCount', $orderBy);
365
366 break;
367 case 'donors':
368
369 $postsTable = DB::prefix('posts');
370 $metaTable = DB::prefix('give_donationmeta');
371 $campaignIdKey = DonationMetaKeys::CAMPAIGN_ID;
372 $donorIdKey = DonationMetaKeys::DONOR_ID;
373
374 $query
375 ->selectRaw(
376 "(
377 SELECT COUNT(DISTINCT donorId.meta_value)
378 FROM {$postsTable} AS donation
379 LEFT JOIN {$metaTable} campaignId ON donation.ID = campaignId.donation_id AND campaignId.meta_key = '{$campaignIdKey}'
380 LEFT JOIN {$metaTable} donorId ON donation.ID = donorId.donation_id AND donorId.meta_key = '{$donorIdKey}'
381 WHERE post_type = 'give_payment'
382 AND donation.post_status IN ('publish', 'give_subscription')
383 AND campaignId.meta_value = campaigns.id
384 ) AS donorsCount"
385 )
386 ->orderBy('donorsCount', $orderBy);
387
388 break;
389 }
390 }
391 }
392