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