Completed
Branch BUG/double-ampersand-in-regist... (7dce02)
by
unknown
131:59 queued 62:17
created

Event::calculateImageData()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 4
nop 2
dl 0
loc 32
rs 9.408
c 0
b 0
f 0
1
<?php
2
3
namespace EventEspresso\core\libraries\rest_api\calculations;
4
5
use DomainException;
6
use EventEspresso\core\exceptions\InvalidDataTypeException;
7
use EventEspresso\core\exceptions\InvalidInterfaceException;
8
use EventEspresso\core\exceptions\UnexpectedEntityException;
9
use EventEspresso\core\libraries\rest_api\calculations\Base as EventCalculationBase;
10
use EventEspresso\core\libraries\rest_api\controllers\model\Base as EventControllerBase;
11
use EventEspresso\core\libraries\rest_api\RestException;
12
use EEM_Event;
13
use EE_Event;
14
use EE_Error;
15
use EEM_Registration;
16
use InvalidArgumentException;
17
use WP_REST_Request;
18
19
/**
20
 * Class Event_Calculations
21
 * Description here
22
 *
23
 * @package               Event Espresso
24
 * @subpackage
25
 * @author                Mike Nelson
26
 */
27
class Event extends EventCalculationBase
28
{
29
    /**
30
     * @var EEM_Event
31
     */
32
    protected $event_model;
33
34
    /**
35
     * @var EEM_Registration
36
     */
37
    protected $registration_model;
38
    public function __construct(EEM_Event $event_model, EEM_Registration $registration_model)
39
    {
40
        $this->event_model = $event_model;
41
        $this->registration_model = $registration_model;
42
    }
43
44
    /**
45
     * Calculates the total spaces on the event (not subtracting sales, but taking
46
     * sales into account; so this is the optimum sales that CAN still be achieved)
47
     * See EE_Event::total_available_spaces( true );
48
     *
49
     * @param array               $wpdb_row
50
     * @param WP_REST_Request     $request
51
     * @param EventControllerBase $controller
52
     * @return int
53
     * @throws EE_Error
54
     * @throws DomainException
55
     * @throws InvalidDataTypeException
56
     * @throws InvalidInterfaceException
57
     * @throws UnexpectedEntityException
58
     * @throws InvalidArgumentException
59
     */
60 View Code Duplication
    public function optimumSalesAtStart($wpdb_row, $request, $controller)
61
    {
62
        $event_obj = null;
63
        if (Event::wpdbRowHasEventId($wpdb_row)) {
64
            $event_obj = $this->event_model->get_one_by_ID($wpdb_row['Event_CPT.ID']);
65
        }
66
        if ($event_obj instanceof EE_Event) {
67
            return $event_obj->total_available_spaces();
68
        }
69
        throw new EE_Error(
70
            sprintf(
71
                __(
72
                // @codingStandardsIgnoreStart
73
                    'Cannot calculate optimum_sales_at_start because the event with ID %1$s (from database row %2$s) was not found',
74
                    // @codingStandardsIgnoreEnd
75
                    'event_espresso'
76
                ),
77
                $wpdb_row['Event_CPT.ID'],
78
                print_r($wpdb_row, true)
79
            )
80
        );
81
    }
82
83
84
    /**
85
     * Calculates the total spaces on the event (ignoring all sales; so this is the optimum
86
     * sales that COULD have been achieved)
87
     * See EE_Event::total_available_spaces( true );
88
     *
89
     * @param array               $wpdb_row
90
     * @param WP_REST_Request     $request
91
     * @param EventControllerBase $controller
92
     * @return int
93
     * @throws DomainException
94
     * @throws EE_Error
95
     * @throws InvalidArgumentException
96
     * @throws InvalidDataTypeException
97
     * @throws InvalidInterfaceException
98
     * @throws UnexpectedEntityException
99
     */
100 View Code Duplication
    public function optimumSalesNow($wpdb_row, $request, $controller)
101
    {
102
        $event_obj = null;
103
        if (Event::wpdbRowHasEventId($wpdb_row)) {
104
            $event_obj = $this->event_model->get_one_by_ID($wpdb_row['Event_CPT.ID']);
105
        }
106
        if ($event_obj instanceof EE_Event) {
107
            return $event_obj->total_available_spaces(true);
108
        }
109
        throw new EE_Error(
110
            sprintf(
111
                __(
112
                // @codingStandardsIgnoreStart
113
                    'Cannot calculate optimum_sales_now because the event with ID %1$s (from database row %2$s) was not found',
114
                    // @codingStandardsIgnoreEnd
115
                    'event_espresso'
116
                ),
117
                $wpdb_row['Event_CPT.ID'],
118
                print_r($wpdb_row, true)
119
            )
120
        );
121
    }
122
123
124
    /**
125
     * Like optimum_sales_now, but minus total sales so far.
126
     * See EE_Event::spaces_remaining_for_sale( true );
127
     *
128
     * @param array               $wpdb_row
129
     * @param WP_REST_Request     $request
130
     * @param EventControllerBase $controller
131
     * @return int
132
     * @throws DomainException
133
     * @throws EE_Error
134
     * @throws InvalidArgumentException
135
     * @throws InvalidDataTypeException
136
     * @throws InvalidInterfaceException
137
     * @throws UnexpectedEntityException
138
     */
139 View Code Duplication
    public function spacesRemaining($wpdb_row, $request, $controller)
140
    {
141
        $event_obj = null;
142
        if (Event::wpdbRowHasEventId($wpdb_row)) {
143
            $event_obj = $this->event_model->get_one_by_ID($wpdb_row['Event_CPT.ID']);
144
        }
145
        if ($event_obj instanceof EE_Event) {
146
            return $event_obj->spaces_remaining_for_sale();
147
        }
148
        throw new EE_Error(
149
            sprintf(
150
                __(
151
                // @codingStandardsIgnoreStart
152
                    'Cannot calculate spaces_remaining because the event with ID %1$s (from database row %2$s) was not found',
153
                    // @codingStandardsIgnoreEnd
154
                    'event_espresso'
155
                ),
156
                $wpdb_row['Event_CPT.ID'],
157
                print_r($wpdb_row, true)
158
            )
159
        );
160
    }
161
162
163
    /**
164
     * Counts the number of approved registrations for this event (regardless
165
     * of how many datetimes each registrations' ticket purchase is for)
166
     *
167
     * @param array               $wpdb_row
168
     * @param WP_REST_Request     $request
169
     * @param EventControllerBase $controller
170
     * @return int
171
     * @throws EE_Error
172
     * @throws InvalidArgumentException
173
     * @throws InvalidDataTypeException
174
     * @throws InvalidInterfaceException
175
     */
176
    public function spotsTaken($wpdb_row, $request, $controller)
177
    {
178
        if (! Event::wpdbRowHasEventId($wpdb_row)) {
179
            throw new EE_Error(
180
                sprintf(
181
                    __(
182
                    // @codingStandardsIgnoreStart
183
                        'Cannot calculate spots_taken because the database row %1$s does not have a valid entry for "Event_CPT.ID"',
184
                        // @codingStandardsIgnoreEnd
185
                        'event_espresso'
186
                    ),
187
                    print_r($wpdb_row, true)
188
                )
189
            );
190
        }
191
        return $this->registration_model->count(
192
            array(
193
                array(
194
                    'EVT_ID' => $wpdb_row['Event_CPT.ID'],
195
                    'STS_ID' => EEM_Registration::status_id_approved,
196
                ),
197
            ),
198
            'REG_ID',
199
            true
200
        );
201
    }
202
203
204
    /**
205
     * Counts the number of pending-payment registrations for this event (regardless
206
     * of how many datetimes each registrations' ticket purchase is for)
207
     *
208
     * @param array               $wpdb_row
209
     * @param WP_REST_Request     $request
210
     * @param EventControllerBase $controller
211
     * @return int
212
     * @throws EE_Error
213
     * @throws InvalidArgumentException
214
     * @throws InvalidDataTypeException
215
     * @throws InvalidInterfaceException
216
     * @throws RestException
217
     */
218 View Code Duplication
    public function spotsTakenPendingPayment($wpdb_row, $request, $controller)
219
    {
220
        if (! Event::wpdbRowHasEventId($wpdb_row)) {
221
            throw new EE_Error(
222
                sprintf(
223
                    __(
224
                    // @codingStandardsIgnoreStart
225
                        'Cannot calculate spots_taken_pending_payment because the database row %1$s does not have an entry for "Event_CPT.ID"',
226
                        // @codingStandardsIgnoreEnd
227
                        'event_espresso'
228
                    ),
229
                    print_r($wpdb_row, true)
230
                )
231
            );
232
        }
233
        $this->verifyCurrentUserCan('ee_read_registrations', 'spots_taken_pending_payment');
234
        return $this->registration_model->count(
235
            array(
236
                array(
237
                    'EVT_ID' => $wpdb_row['Event_CPT.ID'],
238
                    'STS_ID' => EEM_Registration::status_id_pending_payment,
239
                ),
240
            ),
241
            'REG_ID',
242
            true
243
        );
244
    }
245
246
247
    /**
248
     * Counts all the registrations who have checked into one of this events' datetimes
249
     * See EE_Event::total_available_spaces( false );
250
     *
251
     * @param array               $wpdb_row
252
     * @param WP_REST_Request     $request
253
     * @param EventControllerBase $controller
254
     * @return int|null if permission denied
255
     * @throws EE_Error
256
     * @throws InvalidArgumentException
257
     * @throws InvalidDataTypeException
258
     * @throws InvalidInterfaceException
259
     * @throws RestException
260
     */
261 View Code Duplication
    public function registrationsCheckedInCount($wpdb_row, $request, $controller)
262
    {
263
        if (! Event::wpdbRowHasEventId($wpdb_row)) {
264
            throw new EE_Error(
265
                sprintf(
266
                    __(
267
                    // @codingStandardsIgnoreStart
268
                        'Cannot calculate registrations_checked_in_count because the database row %1$s does not have an entry for "Event_CPT.ID"',
269
                        // @codingStandardsIgnoreEnd
270
                        'event_espresso'
271
                    ),
272
                    print_r($wpdb_row, true)
273
                )
274
            );
275
        }
276
        $this->verifyCurrentUserCan('ee_read_checkins', 'registrations_checked_in_count');
277
        return $this->registration_model->count_registrations_checked_into_event($wpdb_row['Event_CPT.ID'], true);
278
    }
279
280
281
    /**
282
     * Counts all the registrations who have checked out of one of this events' datetimes
283
     * See EE_Event::total_available_spaces( false );
284
     *
285
     * @param array               $wpdb_row
286
     * @param WP_REST_Request     $request
287
     * @param EventControllerBase $controller
288
     * @return int
289
     * @throws EE_Error
290
     * @throws InvalidArgumentException
291
     * @throws InvalidDataTypeException
292
     * @throws InvalidInterfaceException
293
     * @throws RestException
294
     */
295 View Code Duplication
    public function registrationsCheckedOutCount($wpdb_row, $request, $controller)
296
    {
297
        if (! Event::wpdbRowHasEventId($wpdb_row)) {
298
            throw new EE_Error(
299
                sprintf(
300
                    __(
301
                    // @codingStandardsIgnoreStart
302
                        'Cannot calculate registrations_checked_out_count because the database row %1$s does not have an entry for "Event_CPT.ID"',
303
                        // @codingStandardsIgnoreEnd
304
                        'event_espresso'
305
                    ),
306
                    print_r($wpdb_row, true)
307
                )
308
            );
309
        }
310
        $this->verifyCurrentUserCan('ee_read_checkins', 'registrations_checked_out_count');
311
        return $this->registration_model->count_registrations_checked_into_event($wpdb_row['Event_CPT.ID'], false);
312
    }
313
314
315
    /**
316
     * Gets the thumbnail image
317
     *
318
     * @param array               $wpdb_row
319
     * @param WP_REST_Request     $request
320
     * @param EventControllerBase $controller
321
     * @return array
322
     * @throws EE_Error
323
     */
324
    public function imageThumbnail($wpdb_row, $request, $controller)
325
    {
326
        return self::calculateImageData($wpdb_row, 'thumbnail');
327
    }
328
329
330
    /**
331
     * Gets the medium image
332
     *
333
     * @param array               $wpdb_row
334
     * @param WP_REST_Request     $request
335
     * @param EventControllerBase $controller
336
     * @return array
337
     * @throws EE_Error
338
     */
339
    public function imageMedium($wpdb_row, $request, $controller)
340
    {
341
        return self::calculateImageData($wpdb_row, 'medium');
342
    }
343
344
345
    /**
346
     * Gets the medium-large image
347
     *
348
     * @param array               $wpdb_row
349
     * @param WP_REST_Request     $request
350
     * @param EventControllerBase $controller
351
     * @return array
352
     * @throws EE_Error
353
     */
354
    public function imageMediumLarge($wpdb_row, $request, $controller)
355
    {
356
        return self::calculateImageData($wpdb_row, 'medium_large');
357
    }
358
359
360
    /**
361
     * Gets the large image
362
     *
363
     * @param array               $wpdb_row
364
     * @param WP_REST_Request     $request
365
     * @param EventControllerBase $controller
366
     * @return array
367
     * @throws EE_Error
368
     */
369
    public function imageLarge($wpdb_row, $request, $controller)
370
    {
371
        return self::calculateImageData($wpdb_row, 'large');
372
    }
373
374
375
    /**
376
     * Gets the post-thumbnail image
377
     *
378
     * @param array               $wpdb_row
379
     * @param WP_REST_Request     $request
380
     * @param EventControllerBase $controller
381
     * @return array
382
     * @throws EE_Error
383
     */
384
    public function imagePostThumbnail($wpdb_row, $request, $controller)
385
    {
386
        return self::calculateImageData($wpdb_row, 'post-thumbnail');
387
    }
388
389
390
    /**
391
     * Gets the full size image
392
     *
393
     * @param array               $wpdb_row
394
     * @param WP_REST_Request     $request
395
     * @param EventControllerBase $controller
396
     * @return array
397
     * @throws EE_Error
398
     */
399
    public function imageFull($wpdb_row, $request, $controller)
400
    {
401
        return self::calculateImageData($wpdb_row, 'full');
402
    }
403
404
405
    /**
406
     * Gets image specs and formats them for the display in the API,
407
     * according to the image size requested
408
     *
409
     * @param array  $wpdb_row
410
     * @param string $image_size one of these: thumbnail, medium, medium_large, large, post-thumbnail, full
411
     * @return array|false if no such image exists. If array it will have keys 'url', 'width', 'height' and 'original'
412
     * @throws EE_Error
413
     */
414
    protected function calculateImageData($wpdb_row, $image_size)
415
    {
416
        if (! Event::wpdbRowHasEventId($wpdb_row)) {
417
            throw new EE_Error(
418
                sprintf(
419
                    __(
420
                    // @codingStandardsIgnoreStart
421
                        'Cannot calculate image because the database row %1$s does not have an entry for "Event_CPT.ID"',
422
                        // @codingStandardsIgnoreEnd
423
                        'event_espresso'
424
                    ),
425
                    print_r($wpdb_row, true)
426
                )
427
            );
428
        }
429
        $EVT_ID = $wpdb_row['Event_CPT.ID'];
430
        $attachment_id = get_post_thumbnail_id($EVT_ID);
431
        $data = wp_get_attachment_image_src($attachment_id, $image_size);
432
        if (! $data) {
433
            return null;
434
        }
435
        $generated = true;
436
        if (isset($data[3])) {
437
            $generated = $data[3];
438
        }
439
        return array(
440
            'url'       => $data[0],
441
            'width'     => $data[1],
442
            'height'    => $data[2],
443
            'generated' => $generated,
444
        );
445
    }
446
447
448
    /**
449
     * Returns true if the array of data contains 'Event_CPT.ID'. False otherwise
450
     *
451
     * @param array $wpdb_row
452
     * @return bool
453
     */
454
    protected function wpdbRowHasEventId($wpdb_row)
455
    {
456
        return (is_array($wpdb_row) && isset($wpdb_row['Event_CPT.ID']) && absint($wpdb_row['Event_CPT.ID']));
457
    }
458
459
460
    /**
461
     * Provides an array for all the calculations possible that outlines a json schema for those calculations.
462
     * Array is indexed by calculation (snake case) and value is the schema for that calculation.
463
     *
464
     * @since $VID:$
465
     * @return array
466
     */
467
    public function schemaForCalculations()
468
    {
469
        $image_object_properties = array(
470
            'url'       => array(
471
                'type' => 'string',
472
            ),
473
            'width'     => array(
474
                'type' => 'number',
475
            ),
476
            'height'    => array(
477
                'type' => 'number',
478
            ),
479
            'generated' => array(
480
                'type' => 'boolean',
481
            ),
482
        );
483
        return array(
484
            'optimum_sales_at_start'          => array(
485
                'description' => esc_html__(
486
                    'The total spaces on the event (not subtracting sales, but taking sales into account; so this is the optimum sales that CAN still be achieved.',
487
                    'event_espresso'
488
                ),
489
                'type'        => 'number',
490
            ),
491
            'optimum_sales_now'               => array(
492
                'description' => esc_html__(
493
                    'The total spaces on the event (ignoring all sales; so this is the optimum sales that could have been achieved.',
494
                    'event_espresso'
495
                ),
496
                'type'        => 'number',
497
            ),
498
            'spaces_remaining'                => array(
499
                'description' => esc_html__(
500
                    'The optimum_sales_number result, minus total sales so far.',
501
                    'event_espresso'
502
                ),
503
                'type'        => 'number',
504
            ),
505
            'spots_taken'                     => array(
506
                'description' => esc_html__(
507
                    'The number of approved registrations for this event (regardless of how many datetimes each registration\'s ticket purchase is for)',
508
                    'event_espresso'
509
                ),
510
                'type'        => 'number',
511
            ),
512
            'spots_taken_pending_payment'     => array(
513
                'description' => esc_html__(
514
                    'The number of pending-payment registrations for this event (regardless of how many datetimes each registration\'s ticket purchase is for)',
515
                    'event_espresso'
516
                ),
517
                'type'        => 'number',
518
            ),
519
            'registrations_checked_in_count'  => array(
520
                'description' => esc_html__(
521
                    'The count of all the registrations who have checked into one of this event\'s datetimes.',
522
                    'event_espresso'
523
                ),
524
                'type'        => 'number',
525
            ),
526
            'registrations_checked_out_count' => array(
527
                'description' => esc_html__(
528
                    'The count of all registrations who have checked out of one of this event\'s datetimes.',
529
                    'event_espresso'
530
                ),
531
                'type'        => 'number',
532
            ),
533
            'image_thumbnail'                 => array(
534
                'description'          => esc_html__(
535
                    'The thumbnail image data.',
536
                    'event_espresso'
537
                ),
538
                'type'                 => 'object',
539
                'properties'           => $image_object_properties,
540
                'additionalProperties' => false,
541
            ),
542
            'image_medium'                    => array(
543
                'description'          => esc_html__(
544
                    'The medium image data.',
545
                    'event_espresso'
546
                ),
547
                'type'                 => 'object',
548
                'properties'           => $image_object_properties,
549
                'additionalProperties' => false,
550
            ),
551
            'image_medium_large'              => array(
552
                'description'          => esc_html__(
553
                    'The medium-large image data.',
554
                    'event_espresso'
555
                ),
556
                'type'                 => 'object',
557
                'properties'           => $image_object_properties,
558
                'additionalProperties' => false,
559
            ),
560
            'image_large'                     => array(
561
                'description'          => esc_html__(
562
                    'The large image data.',
563
                    'event_espresso'
564
                ),
565
                'type'                 => 'object',
566
                'properties'           => $image_object_properties,
567
                'additionalProperties' => false,
568
            ),
569
            'image_post_thumbnail'            => array(
570
                'description'          => esc_html__(
571
                    'The post-thumbnail image data.',
572
                    'event_espresso'
573
                ),
574
                'type'                 => 'object',
575
                'properties'           => $image_object_properties,
576
                'additionalProperties' => false,
577
            ),
578
            'image_full'                      => array(
579
                'description'          => esc_html__(
580
                    'The full size image data',
581
                    'event_espresso'
582
                ),
583
                'type'                 => 'object',
584
                'properties'           => $image_object_properties,
585
                'additionalProperties' => false,
586
            ),
587
        );
588
    }
589
}
590