PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 4.7.1
GiveWP – Donation Plugin and Fundraising Platform v4.7.1
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 / API / REST / V3 / Routes / Campaigns / GetCampaignRevenue.php
give / src / API / REST / V3 / Routes / Campaigns Last commit date
ValueObjects 1 year ago GetCampaignComments.php 1 year ago GetCampaignRevenue.php 1 year ago GetCampaignStatistics.php 1 year ago RegisterCampaignRoutes.php 1 year ago
GetCampaignRevenue.php
211 lines
1 <?php
2
3 namespace Give\API\REST\V3\Routes\Campaigns;
4
5 use DateInterval;
6 use DatePeriod;
7 use DateTime;
8 use DateTimeInterface;
9 use Exception;
10 use Give\API\REST\V3\Routes\Campaigns\ValueObjects\CampaignRoute;
11 use Give\API\RestRoute;
12 use Give\Campaigns\CampaignDonationQuery;
13 use Give\Campaigns\Models\Campaign;
14 use WP_REST_Response;
15 use WP_REST_Server;
16
17 /**
18 * @since 4.0.0
19 */
20 class GetCampaignRevenue implements RestRoute
21 {
22 /**
23 * @since 4.0.0
24 */
25 public function registerRoute()
26 {
27 register_rest_route(
28 CampaignRoute::NAMESPACE,
29 CampaignRoute::CAMPAIGN . '/revenue',
30 [
31 [
32 'methods' => WP_REST_Server::READABLE,
33 'callback' => [$this, 'handleRequest'],
34 'permission_callback' => function () {
35 return current_user_can('manage_options');
36 },
37 ],
38 'args' => [
39 'id' => [
40 'type' => 'integer',
41 'required' => true,
42 'sanitize_callback' => 'absint',
43 ],
44 ],
45 ]
46 );
47 }
48
49 /**
50 *
51 * This request returns revenue over time based on the oldest data point for the campaign in the database.
52 * The result will return an array of revenue that includes date and amount.
53 * The revenue is grouped by day, month, or year based on the date range.
54 * If the date range is less than 7 days, the result will be padded to include the last 7 days.
55 * If the date range is more than 6 months, the result will be grouped by month.
56 * If the date range is more than 5 years, the result will be grouped by year.
57 *
58 * @since 4.0.0
59 *
60 * @throws Exception
61 */
62 public function handleRequest($request): WP_REST_Response
63 {
64 $campaign = Campaign::find((int)$request->get_param('id'));
65
66 if (!$campaign) {
67 return new WP_REST_Response([], 404);
68 }
69
70 $query = new CampaignDonationQuery($campaign);
71
72 $oldestRevenueDate = $query->getOldestDonationDate();
73
74 if (!$oldestRevenueDate) {
75 return new WP_REST_Response([], 200);
76 }
77
78 $firstResultDate = new DateTime($oldestRevenueDate, wp_timezone());
79
80 // the query start date is the earliest of the first result date and the campaign start date
81 $queryStartDate = ($firstResultDate < $campaign->startDate) ? $firstResultDate : $campaign->startDate;
82 $queryEndDate = $campaign->endDate ?: current_datetime();
83
84 $groupBy = $this->getGroupByFromDateRange($queryStartDate, $queryEndDate);
85
86 $results = $query->getDonationsByDate($groupBy);
87
88 if (empty($results)) {
89 return new WP_REST_Response([], 200);
90 }
91
92 // Map the results by date
93 $resultMap = $this->mapResultsByDate($results, $groupBy);
94
95 // Get all dates between the start and end date based on the group by
96 $dates = $this->getDatesFromRange($queryStartDate, $queryEndDate->modify("+1 day"), $groupBy);
97
98 // Merge the results with the dates to ensure that all dates are included
99 $data = $this->mergeResultsWithDates($dates, $resultMap);
100
101 return new WP_REST_Response($data, 200);
102 }
103
104 /**
105 * @since 4.0.0
106 */
107 public function getDatesFromRange(DateTimeInterface $startDate, DateTimeInterface $endDate, string $groupBy): array
108 {
109 $startDateInterval = $startDate->diff($endDate);
110
111 // If the date range is less than 7 days, pad the start date to include the last 7 days
112 // This is to ensure that the chart always shows at least 7 days of data
113 if ($startDateInterval->days < 7) {
114 $defaultDays = 7 - $startDateInterval->days;
115 $startDate->modify("-$defaultDays days");
116 }
117
118 $differenceInMonths = ($startDateInterval->y * 12) + $startDateInterval->m;
119
120 $intervalTime = 'days';
121 if ($startDateInterval->y >= 5) {
122 // If the date range is more than 5 years, group by year
123 $intervalTime = 'years';
124 } elseif ($differenceInMonths >= 6) {
125 // If the date range is more than 6 months, group by month
126 $intervalTime = 'months';
127 }
128
129 $interval = DateInterval::createFromDateString("1 $intervalTime");
130 $dateRange = new DatePeriod($startDate, $interval, $endDate);
131
132 $dates = [];
133 foreach ($dateRange as $date) {
134 $dateFormatted = $this->getFormattedDateFromGroupBy($groupBy, $date);
135
136 $dates[] = $dateFormatted;
137 }
138
139 return $dates;
140 }
141
142 /**
143 * @since 4.0.0
144 */
145 public function getGroupByFromDateRange(DateTimeInterface $startDate, DateTimeInterface $endDate): string
146 {
147 $startDateInterval = $startDate->diff($endDate);
148 $differenceInMonths = ($startDateInterval->y * 12) + $startDateInterval->m;
149
150 // If the date range is more than 1 year, group by month
151 if ($startDateInterval->y >= 5) {
152 return 'YEAR';
153 }
154
155 if ($differenceInMonths >= 6) {
156 // If the date range is more than 90 days, group by week
157 return 'MONTH';
158 }
159
160 return 'DAY';
161 }
162
163 /**
164 * @since 4.0.0
165 */
166 public function getFormattedDateFromGroupBy(string $groupBy, DateTimeInterface $date): string
167 {
168 if ($groupBy === 'MONTH') {
169 return $date->format('Y-m');
170 }
171
172 if ($groupBy === 'YEAR') {
173 return $date->format('Y');
174 }
175
176 return $date->format('Y-m-d');
177 }
178
179 /**
180 * @since 4.0.0
181 */
182 public function mergeResultsWithDates(array $dates, array $resultMap): array
183 {
184 $data = [];
185 // Fill in the data with the results
186 foreach ($dates as $date) {
187 $data[] = [
188 'date' => $date,
189 'amount' => $resultMap[$date] ?? 0
190 ];
191 }
192
193 return $data;
194 }
195
196 /**
197 * @since 4.0.0
198 */
199 public function mapResultsByDate(array $results, string $groupBy): array
200 {
201 $resultMap = [];
202 foreach ($results as $result) {
203 $date = $this->getFormattedDateFromGroupBy($groupBy, date_create($result->date_created));
204
205 $resultMap[$date] = $result->amount;
206 }
207
208 return $resultMap;
209 }
210 }
211