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