PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 4.6.1
GiveWP – Donation Plugin and Fundraising Platform v4.6.1
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 / EventTickets / Repositories / EventTicketRepository.php
give / src / EventTickets / Repositories Last commit date
EventRepository.php 2 years ago EventTicketRepository.php 11 months ago EventTicketTypeRepository.php 2 years ago
EventTicketRepository.php
328 lines
1 <?php
2
3 namespace Give\EventTickets\Repositories;
4
5 use Give\BetaFeatures\Facades\FeatureFlag;
6 use Give\Donations\Models\Donation;
7 use Give\Donations\ValueObjects\DonationMetaKeys;
8 use Give\EventTickets\Models\EventTicket;
9 use Give\Framework\Database\DB;
10 use Give\Framework\Exceptions\Primitives\Exception;
11 use Give\Framework\Exceptions\Primitives\InvalidArgumentException;
12 use Give\Framework\Models\ModelQueryBuilder;
13 use Give\Framework\Support\Facades\DateTime\Temporal;
14 use Give\Framework\Support\ValueObjects\Money;
15 use Give\Helpers\Hooks;
16 use Give\Helpers\Table;
17 use Give\Log\Log;
18
19 /**
20 * @since 3.6.0
21 */
22 class EventTicketRepository
23 {
24
25 /**
26 * @since 3.20.0 Add "amount" column to the properties array
27 * @since 3.6.0
28 *
29 * @var string[]
30 */
31 private $requiredProperties = [
32 'eventId',
33 'ticketTypeId',
34 'donationId',
35 'amount',
36 ];
37
38 /**
39 * @since 3.6.0
40 */
41 public function getById(int $id): ?EventTicket
42 {
43 if (!$this->isFeatureActive()) {
44 return null;
45 }
46
47 return $this->prepareQuery()
48 ->where('id', $id)
49 ->get();
50 }
51
52 /**
53 * @since 3.6.0
54 */
55 public function queryById(int $id): ModelQueryBuilder
56 {
57 return $this->prepareQuery()
58 ->where('id', $id);
59 }
60
61 /**
62 * @since 3.20.0 Add "amount" column to the insert statement
63 * @since 3.6.0
64 *
65 * @throws Exception|InvalidArgumentException
66 */
67 public function insert(EventTicket $eventTicket)
68 {
69 if (!$this->isFeatureActive()) {
70 throw new Exception('Event tickets feature is not active');
71 }
72
73 $this->validate($eventTicket);
74
75 Hooks::doAction('givewp_events_event_ticket_creating', $eventTicket);
76
77 $createdDateTime = Temporal::withoutMicroseconds($eventTicket->createdAt ?: Temporal::getCurrentDateTime());
78
79 DB::query('START TRANSACTION');
80
81 try {
82 DB::table('give_event_tickets')
83 ->insert([
84 'event_id' => $eventTicket->eventId,
85 'ticket_type_id' => $eventTicket->ticketTypeId,
86 'donation_id' => $eventTicket->donationId,
87 'amount' => $eventTicket->amount->formatToMinorAmount(),
88 'created_at' => $createdDateTime->format('Y-m-d H:i:s'),
89 'updated_at' => $createdDateTime->format('Y-m-d H:i:s'),
90 ]);
91
92 $eventTicketId = DB::last_insert_id();
93 } catch (Exception $exception) {
94 DB::query('ROLLBACK');
95
96 Log::error('Failed creating an event ticket', compact('eventTicket'));
97
98 throw new $exception('Failed creating an event ticket');
99 }
100
101 $eventTicket->id = $eventTicketId;
102 $eventTicket->createdAt = $createdDateTime;
103 $eventTicket->updatedAt = $createdDateTime;
104
105 DB::query('COMMIT');
106
107 Hooks::doAction('givewp_events_event_ticket_created', $eventTicket);
108 }
109
110 /**
111 * @since 3.20.0 Add "amount" column to the update statement
112 * @since 3.6.0
113 *
114 * @throws Exception|InvalidArgumentException
115 */
116 public function update(EventTicket $eventTicket)
117 {
118 if (!$this->isFeatureActive()) {
119 throw new Exception('Event tickets feature is not active');
120 }
121
122 $this->validate($eventTicket);
123
124 Hooks::doAction('givewp_events_event_ticket_updating', $eventTicket);
125
126 $updatedDateTime = Temporal::withoutMicroseconds(Temporal::getCurrentDateTime());
127
128 DB::query('START TRANSACTION');
129
130 try {
131
132 DB::table('give_event_tickets')
133 ->where('id', $eventTicket->id)
134 ->update([
135 'event_id' => $eventTicket->eventId,
136 'ticket_type_id' => $eventTicket->ticketTypeId,
137 'donation_id' => $eventTicket->donationId,
138 'amount' => $eventTicket->amount->formatToMinorAmount(),
139 'updated_at' => $updatedDateTime->format('Y-m-d H:i:s'),
140 ]);
141 } catch (Exception $exception) {
142 DB::query('ROLLBACK');
143
144 Log::error('Failed updating an event ticket', compact('eventTicket'));
145
146 throw new $exception('Failed updating an event ticket');
147 }
148
149 $eventTicket->updatedAt = $updatedDateTime;
150
151 DB::query('COMMIT');
152
153 Hooks::doAction('givewp_events_event_ticket_updated', $eventTicket);
154 }
155
156 /**
157 * @since 3.6.0
158 *
159 * @throws Exception
160 */
161 public function delete(EventTicket $eventTicket): bool
162 {
163 if (!$this->isFeatureActive()) {
164 throw new Exception('Event tickets feature is not active');
165 }
166
167 DB::query('START TRANSACTION');
168
169 Hooks::doAction('givewp_events_event_ticket_deleting', $eventTicket);
170
171 try {
172 DB::table('give_event_tickets')
173 ->where('id', $eventTicket->id)
174 ->delete();
175 } catch (Exception $exception) {
176 DB::query('ROLLBACK');
177
178 Log::error('Failed deleting an event ticket', compact('eventTicket'));
179
180 throw new $exception('Failed deleting an event ticket');
181 }
182
183 DB::query('COMMIT');
184
185 Hooks::doAction('givewp_events_event_ticket_deleted', $eventTicket);
186
187 return true;
188 }
189
190 /**
191 * Check if the event tickets feature is active and table exists
192 *
193 * @since 4.6.0
194 * @return bool
195 */
196 private function isFeatureActive(): bool
197 {
198 return FeatureFlag::eventTickets() && $this->tableExists('give_event_tickets');
199 }
200
201 /**
202 * @since 3.6.0
203 */
204 private function validate(EventTicket $eventTicket): void
205 {
206 foreach ($this->requiredProperties as $key) {
207 if (!isset($eventTicket->$key)) {
208 throw new InvalidArgumentException("'$key' is required.");
209 }
210 }
211 }
212
213 /**
214 * @since 4.6.0 Add support for feature flag when disabled and include donation currency
215 * @since 3.20.0 Add "amount" column to the select statement
216 * @since 3.6.0
217 * @return ModelQueryBuilder<EventTicket>
218 */
219 public function prepareQuery(): ModelQueryBuilder
220 {
221 $builder = new ModelQueryBuilder(EventTicket::class);
222
223 if (!$this->isFeatureActive()) {
224 // Return a query builder that safely returns empty results
225 // Use a subquery that will never return results but handles all possible column references
226 return $builder->from(
227 DB::raw('(SELECT NULL as id, NULL as event_id, NULL as ticket_type_id, NULL as donation_id, NULL as amount, NULL as created_at, NULL as updated_at, NULL as currency WHERE 1 = 0)'),
228 'tickets'
229 );
230 }
231
232 return $builder->from('give_event_tickets', 'tickets')
233 ->select(
234 ['tickets.id', 'id'],
235 ['tickets.event_id', 'event_id'],
236 ['tickets.ticket_type_id', 'ticket_type_id'],
237 ['tickets.amount', 'amount'],
238 ['tickets.created_at', 'created_at'],
239 ['tickets.updated_at', 'updated_at'],
240 )
241 ->selectRaw("tickets.donation_id as donation_id")
242 ->attachMeta(
243 'give_donationmeta',
244 'tickets.donation_id',
245 'donation_id',
246 [DonationMetaKeys::CURRENCY, 'currency']
247 );
248 }
249
250 /**
251 * Check if a database table exists
252 *
253 * @since 4.6.0
254 */
255 private function tableExists(string $tableName): bool
256 {
257 global $wpdb;
258
259 $prefixedTableName = $wpdb->prefix . $tableName;
260 $query = $wpdb->prepare('SHOW TABLES LIKE %s', $wpdb->esc_like($prefixedTableName));
261
262 return (bool) $wpdb->get_var($query);
263 }
264
265 /**
266 * @since 3.6.0
267 */
268 public function queryByEventId(int $eventId): ModelQueryBuilder
269 {
270 return $this->prepareQuery()
271 ->where('tickets.event_id', $eventId);
272 }
273
274 /**
275 * @since 3.6.0
276 */
277 public function queryByTicketTypeId(int $ticketTypeId): ModelQueryBuilder
278 {
279 return $this->prepareQuery()
280 ->where('tickets.ticket_type_id', $ticketTypeId);
281 }
282
283 /**
284 * @since 3.6.0
285 *
286 * @param int $donationId
287 *
288 * @return ModelQueryBuilder
289 */
290 public function queryByDonationId(int $donationId): ModelQueryBuilder
291 {
292 return $this->prepareQuery()
293 ->where('tickets.donation_id', $donationId);
294 }
295
296 /**
297 * @since 4.6.0 Ensure the currency is the same as the donation amount currency
298 * @since 3.20.0 Refactored to use event ticket amount instead of ticket type price
299 * @since 3.6.0
300 */
301 public function getTotalByDonation(Donation $donation): Money
302 {
303 $eventTickets = $this->queryByDonationId($donation->id)->getAll() ?? [];
304
305 return array_reduce($eventTickets, static function (Money $carry, EventTicket $eventTicket) {
306 return $carry->add($eventTicket->amount);
307 }, new Money(0, $donation->amount->getCurrency()));
308 }
309
310 /**
311 * @since 4.6.0
312 */
313 public function getEventTicketDetails(Donation $donation): array
314 {
315 $details = [];
316 $eventTickets = $this->queryByDonationId($donation->id)->getAll() ?? [];
317
318 foreach ($eventTickets as $eventTicket) {
319 $details[] = array_merge($eventTicket->toArray(), [
320 'event' => $eventTicket->event->toArray(),
321 'ticketType' => $eventTicket->ticketType->toArray(),
322 ]);
323 }
324
325 return $details;
326 }
327 }
328