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