PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 4.12.0
GiveWP – Donation Plugin and Fundraising Platform v4.12.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 / API / REST / V3 / Routes / Campaigns / GetCampaignRevenue.php
give / src / API / REST / V3 / Routes / Campaigns Last commit date
Permissions 9 months ago ValueObjects 1 year ago GetCampaignComments.php 10 months ago GetCampaignRevenue.php 9 months ago GetCampaignStatistics.php 1 year ago RegisterCampaignRoutes.php 9 months ago
GetCampaignRevenue.php
239 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 'schema' => [$this, 'getSchema'],
46 ]
47 );
48 }
49
50 /**
51 *
52 * This request returns revenue over time based on the oldest data point for the campaign in the database.
53 * The result will return an array of revenue that includes date and amount.
54 * The revenue is grouped by day, month, or year based on the date range.
55 * If the date range is less than 7 days, the result will be padded to include the last 7 days.
56 * If the date range is more than 6 months, the result will be grouped by month.
57 * If the date range is more than 5 years, the result will be grouped by year.
58 *
59 * @since 4.0.0
60 *
61 * @throws Exception
62 */
63 public function handleRequest($request): WP_REST_Response
64 {
65 $campaign = Campaign::find((int)$request->get_param('id'));
66
67 if (!$campaign) {
68 return new WP_REST_Response([], 404);
69 }
70
71 $query = new CampaignDonationQuery($campaign);
72
73 $oldestRevenueDate = $query->getOldestDonationDate();
74
75 if (!$oldestRevenueDate) {
76 return new WP_REST_Response([], 200);
77 }
78
79 $firstResultDate = new DateTime($oldestRevenueDate, wp_timezone());
80
81 // the query start date is the earliest of the first result date and the campaign start date
82 $queryStartDate = ($firstResultDate < $campaign->startDate) ? $firstResultDate : $campaign->startDate;
83 $queryEndDate = $campaign->endDate ?: current_datetime();
84
85 $groupBy = $this->getGroupByFromDateRange($queryStartDate, $queryEndDate);
86
87 $results = $query->getDonationsByDate($groupBy);
88
89 if (empty($results)) {
90 return new WP_REST_Response([], 200);
91 }
92
93 // Map the results by date
94 $resultMap = $this->mapResultsByDate($results, $groupBy);
95
96 // Get all dates between the start and end date based on the group by
97 $dates = $this->getDatesFromRange($queryStartDate, $queryEndDate->modify("+1 day"), $groupBy);
98
99 // Merge the results with the dates to ensure that all dates are included
100 $data = $this->mergeResultsWithDates($dates, $resultMap);
101
102 return new WP_REST_Response($data, 200);
103 }
104
105 /**
106 * @since 4.0.0
107 */
108 public function getDatesFromRange(DateTimeInterface $startDate, DateTimeInterface $endDate, string $groupBy): array
109 {
110 $startDateInterval = $startDate->diff($endDate);
111
112 // If the date range is less than 7 days, pad the start date to include the last 7 days
113 // This is to ensure that the chart always shows at least 7 days of data
114 if ($startDateInterval->days < 7) {
115 $defaultDays = 7 - $startDateInterval->days;
116 $startDate->modify("-$defaultDays days");
117 }
118
119 $differenceInMonths = ($startDateInterval->y * 12) + $startDateInterval->m;
120
121 $intervalTime = 'days';
122 if ($startDateInterval->y >= 5) {
123 // If the date range is more than 5 years, group by year
124 $intervalTime = 'years';
125 } elseif ($differenceInMonths >= 6) {
126 // If the date range is more than 6 months, group by month
127 $intervalTime = 'months';
128 }
129
130 $interval = DateInterval::createFromDateString("1 $intervalTime");
131 $dateRange = new DatePeriod($startDate, $interval, $endDate);
132
133 $dates = [];
134 foreach ($dateRange as $date) {
135 $dateFormatted = $this->getFormattedDateFromGroupBy($groupBy, $date);
136
137 $dates[] = $dateFormatted;
138 }
139
140 return $dates;
141 }
142
143 /**
144 * @since 4.0.0
145 */
146 public function getGroupByFromDateRange(DateTimeInterface $startDate, DateTimeInterface $endDate): string
147 {
148 $startDateInterval = $startDate->diff($endDate);
149 $differenceInMonths = ($startDateInterval->y * 12) + $startDateInterval->m;
150
151 // If the date range is more than 1 year, group by month
152 if ($startDateInterval->y >= 5) {
153 return 'YEAR';
154 }
155
156 if ($differenceInMonths >= 6) {
157 // If the date range is more than 90 days, group by week
158 return 'MONTH';
159 }
160
161 return 'DAY';
162 }
163
164 /**
165 * @since 4.0.0
166 */
167 public function getFormattedDateFromGroupBy(string $groupBy, DateTimeInterface $date): string
168 {
169 if ($groupBy === 'MONTH') {
170 return $date->format('Y-m');
171 }
172
173 if ($groupBy === 'YEAR') {
174 return $date->format('Y');
175 }
176
177 return $date->format('Y-m-d');
178 }
179
180 /**
181 * @since 4.0.0
182 */
183 public function mergeResultsWithDates(array $dates, array $resultMap): array
184 {
185 $data = [];
186 // Fill in the data with the results
187 foreach ($dates as $date) {
188 $data[] = [
189 'date' => $date,
190 'amount' => $resultMap[$date] ?? 0
191 ];
192 }
193
194 return $data;
195 }
196
197 /**
198 * @since 4.0.0
199 */
200 public function mapResultsByDate(array $results, string $groupBy): array
201 {
202 $resultMap = [];
203 foreach ($results as $result) {
204 $date = $this->getFormattedDateFromGroupBy($groupBy, date_create($result->date_created));
205
206 $resultMap[$date] = $result->amount;
207 }
208
209 return $resultMap;
210 }
211
212 /**
213 * @since 4.10.0
214 */
215 public function getSchema(): array
216 {
217 return [
218 'title' => 'campaign-revenue',
219 'description' => 'Provides daily revenue data for a specific campaign.',
220 'type' => 'object',
221 'properties' => [
222 'date' => [
223 'type' => 'string',
224 'format' => 'date',
225 'description' => esc_html__('The date for the revenue entry (YYYY-MM-DD).', 'give'),
226 ],
227 'amount' => [
228 'oneOf' => [
229 [ 'type' => 'number' ],
230 [ 'type' => 'string' ],
231 ],
232 'description' => esc_html__('The amount of revenue received on the given date.', 'give'),
233 ],
234 ],
235 'required' => ['date', 'amount'],
236 ];
237 }
238 }
239