PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 4.15.3
GiveWP – Donation Plugin and Fundraising Platform v4.15.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 / CampaignRevenueController.php
give / src / API / REST / V3 / Routes / Campaigns Last commit date
Permissions 5 months ago ValueObjects 1 year ago ViewModels 7 months ago CampaignCommentsController.php 2 months ago CampaignController.php 2 months ago CampaignPageController.php 5 months ago CampaignRevenueController.php 5 months ago CampaignStatisticsController.php 5 months ago
CampaignRevenueController.php
257 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\Campaigns\CampaignDonationQuery;
12 use Give\Campaigns\Models\Campaign;
13 use Give\Framework\Permissions\Facades\UserPermissions;
14 use WP_Error;
15 use WP_REST_Controller;
16 use WP_REST_Response;
17 use WP_REST_Server;
18
19 /**
20 * @since 4.13.1
21 */
22 class CampaignRevenueController extends WP_REST_Controller
23 {
24 /**
25 * @var string
26 */
27 protected $namespace;
28
29 /**
30 * @since 4.13.1
31 */
32 public function __construct()
33 {
34 $this->namespace = CampaignRoute::NAMESPACE;
35 }
36
37 /**
38 * @since 4.14.0 updated permission logic with UserPermissions facade
39 * @since 4.13.1
40 */
41 public function register_routes()
42 {
43 register_rest_route(
44 $this->namespace,
45 '/' . CampaignRoute::CAMPAIGN . '/revenue',
46 [
47 [
48 'methods' => WP_REST_Server::READABLE,
49 'callback' => [$this, 'get_items'],
50 'permission_callback' => function () {
51 return UserPermissions::campaigns()->canView();
52 },
53 'args' => [
54 'id' => [
55 'type' => 'integer',
56 'required' => true,
57 'sanitize_callback' => 'absint',
58 ],
59 ],
60 ],
61 'schema' => [$this, 'get_public_item_schema'],
62 ]
63 );
64 }
65
66 /**
67 * @since 4.13.1
68 * @throws Exception
69 */
70 public function get_items($request): WP_REST_Response
71 {
72 $campaign = Campaign::find((int)$request->get_param('id'));
73
74 if (!$campaign) {
75 $response = new WP_Error('campaign_not_found', __('Campaign not found', 'give'), ['status' => 404]);
76
77 return rest_ensure_response($response);
78 }
79
80 $query = new CampaignDonationQuery($campaign);
81
82 $oldestRevenueDate = $query->getOldestDonationDate();
83
84 if (!$oldestRevenueDate) {
85 $items = new WP_REST_Response([]);
86
87 return rest_ensure_response($items);
88 }
89
90 $firstResultDate = new DateTime($oldestRevenueDate, wp_timezone());
91
92 // the query start date is the earliest of the first result date and the campaign start date
93 $queryStartDate = ($firstResultDate < $campaign->startDate) ? $firstResultDate : $campaign->startDate;
94 $queryEndDate = $campaign->endDate ?: current_datetime();
95
96 $groupBy = $this->getGroupByFromDateRange($queryStartDate, $queryEndDate);
97
98 $results = $query->getDonationsByDate($groupBy);
99
100 if (empty($results)) {
101 $items = new WP_REST_Response([]);
102
103 return rest_ensure_response($items);
104 }
105
106 // Map the results by date
107 $resultMap = $this->mapResultsByDate($results, $groupBy);
108
109 // Get all dates between the start and end date based on the group by
110 $endTimestamp = strtotime($queryEndDate->format('Y-m-d H:i:s') . ' +1 day');
111 $queryEndDatePlusOne = new DateTime(date('Y-m-d H:i:s', $endTimestamp), wp_timezone());
112 $dates = $this->getDatesFromRange($queryStartDate, $queryEndDatePlusOne, $groupBy);
113
114 // Merge the results with the dates to ensure that all dates are included
115 $data = $this->mergeResultsWithDates($dates, $resultMap);
116
117 $items = new WP_REST_Response($data);
118
119 return rest_ensure_response($items);
120 }
121
122 /**
123 * @since 4.13.1
124 */
125 public function getDatesFromRange(DateTimeInterface $startDate, DateTimeInterface $endDate, string $groupBy): array
126 {
127 $startDateInterval = $startDate->diff($endDate);
128
129 // If the date range is less than 7 days, pad the start date to include the last 7 days
130 // This is to ensure that the chart always shows at least 7 days of data
131 $start = new DateTime($startDate->format('Y-m-d H:i:s'), wp_timezone());
132 if ($startDateInterval->days < 7) {
133 $defaultDays = 7 - $startDateInterval->days;
134 $start = new DateTime(date('Y-m-d H:i:s', strtotime($start->format('Y-m-d H:i:s') . " -$defaultDays days")), wp_timezone());
135 }
136
137 $differenceInMonths = ($startDateInterval->y * 12) + $startDateInterval->m;
138
139 $intervalTime = 'days';
140 if ($startDateInterval->y >= 5) {
141 // If the date range is more than 5 years, group by year
142 $intervalTime = 'years';
143 } elseif ($differenceInMonths >= 6) {
144 // If the date range is more than 6 months, group by month
145 $intervalTime = 'months';
146 }
147
148 $interval = DateInterval::createFromDateString("1 $intervalTime");
149 $dateRange = new DatePeriod($start, $interval, $endDate);
150
151 $dates = [];
152 foreach ($dateRange as $date) {
153 $dateFormatted = $this->getFormattedDateFromGroupBy($groupBy, $date);
154
155 $dates[] = $dateFormatted;
156 }
157
158 return $dates;
159 }
160
161 /**
162 * @since 4.13.1
163 */
164 public function getGroupByFromDateRange(DateTimeInterface $startDate, DateTimeInterface $endDate): string
165 {
166 $startDateInterval = $startDate->diff($endDate);
167 $differenceInMonths = ($startDateInterval->y * 12) + $startDateInterval->m;
168
169 // If the date range is more than 1 year, group by month
170 if ($startDateInterval->y >= 5) {
171 return 'YEAR';
172 }
173
174 if ($differenceInMonths >= 6) {
175 // If the date range is more than 90 days, group by week
176 return 'MONTH';
177 }
178
179 return 'DAY';
180 }
181
182 /**
183 * @since 4.13.1
184 */
185 public function getFormattedDateFromGroupBy(string $groupBy, DateTimeInterface $date): string
186 {
187 if ($groupBy === 'MONTH') {
188 return $date->format('Y-m');
189 }
190
191 if ($groupBy === 'YEAR') {
192 return $date->format('Y');
193 }
194
195 return $date->format('Y-m-d');
196 }
197
198 /**
199 * @since 4.13.1
200 */
201 public function mergeResultsWithDates(array $dates, array $resultMap): array
202 {
203 $data = [];
204 // Fill in the data with the results
205 foreach ($dates as $date) {
206 $data[] = [
207 'date' => $date,
208 'amount' => $resultMap[$date] ?? 0
209 ];
210 }
211
212 return $data;
213 }
214
215 /**
216 * @since 4.13.1
217 */
218 public function mapResultsByDate(array $results, string $groupBy): array
219 {
220 $resultMap = [];
221 foreach ($results as $result) {
222 $date = $this->getFormattedDateFromGroupBy($groupBy, date_create($result->date_created));
223
224 $resultMap[$date] = (float)$result->amount;
225 }
226
227 return $resultMap;
228 }
229
230 /**
231 * @since 4.13.1
232 */
233 public function get_item_schema(): array
234 {
235 return [
236 'title' => 'campaign-revenue',
237 'description' => esc_html__('Provides daily revenue data for a specific campaign.', 'give'),
238 'type' => 'array',
239 'readonly' => true,
240 'items' => [
241 'type' => 'object',
242 'properties' => [
243 'date' => [
244 'type' => 'string',
245 'format' => 'date',
246 'description' => esc_html__('The date for the revenue entry (YYYY-MM-DD).', 'give'),
247 ],
248 'amount' => [
249 'type' => ['integer', 'number'],
250 'description' => esc_html__('The amount of revenue received on the given date.', 'give'),
251 ],
252 ]
253 ]
254 ];
255 }
256 }
257