Completed
Branch fix/escaping-2 (5dcb9a)
by
unknown
13:02 queued 10:26
created
libraries/line_item_display/EE_SPCO_Line_Item_Display_Strategy.strategy.php 2 patches
Indentation   +659 added lines, -659 removed lines patch added patch discarded remove patch
@@ -12,663 +12,663 @@
 block discarded – undo
12 12
 class EE_SPCO_Line_Item_Display_Strategy implements EEI_Line_Item_Display
13 13
 {
14 14
 
15
-    /**
16
-     * array of events
17
-     *
18
-     * @type EE_Line_Item[] $_events
19
-     */
20
-    private $_events = array();
21
-
22
-    /**
23
-     * whether to display the taxes row or not
24
-     *
25
-     * @type bool $_show_taxes
26
-     */
27
-    private $_show_taxes = false;
28
-
29
-    /**
30
-     * html for any tax rows
31
-     *
32
-     * @type string $_show_taxes
33
-     */
34
-    private $_taxes_html = '';
35
-
36
-    /**
37
-     * total amount including tax we can bill for at this time
38
-     *
39
-     * @type float $_grand_total
40
-     */
41
-    private $_grand_total = 0.00;
42
-
43
-    /**
44
-     * total number of items being billed for
45
-     *
46
-     * @type int $_total_items
47
-     */
48
-    private $_total_items = 0;
49
-
50
-
51
-
52
-    /**
53
-     * @return float
54
-     */
55
-    public function grand_total()
56
-    {
57
-        return $this->_grand_total;
58
-    }
59
-
60
-
61
-
62
-    /**
63
-     * @return int
64
-     */
65
-    public function total_items()
66
-    {
67
-        return $this->_total_items;
68
-    }
69
-
70
-
71
-
72
-    /**
73
-     * @param EE_Line_Item $line_item
74
-     * @param array        $options
75
-     * @param EE_Line_Item $parent_line_item
76
-     * @return mixed
77
-     * @throws EE_Error
78
-     */
79
-    public function display_line_item(
80
-        EE_Line_Item $line_item,
81
-        $options = array(),
82
-        EE_Line_Item $parent_line_item = null
83
-    ) {
84
-        $html = '';
85
-        // set some default options and merge with incoming
86
-        $default_options = array(
87
-            'show_desc' => true,  //    true        false
88
-            'odd'       => false,
89
-        );
90
-        $options = array_merge($default_options, (array) $options);
91
-        switch ($line_item->type()) {
92
-            case EEM_Line_Item::type_line_item:
93
-                $this->_show_taxes = $line_item->is_taxable() ? true : $this->_show_taxes;
94
-                if ($line_item->OBJ_type() === 'Ticket') {
95
-                    // item row
96
-                    $html .= $this->_ticket_row($line_item, $options);
97
-                } else {
98
-                    // item row
99
-                    $html .= $this->_item_row($line_item, $options);
100
-                }
101
-                if (
102
-                    apply_filters(
103
-                        'FHEE__EE_SPCO_Line_Item_Display_Strategy__display_line_item__display_sub_line_items',
104
-                        true
105
-                    )
106
-                ) {
107
-                    // got any kids?
108
-                    foreach ($line_item->children() as $child_line_item) {
109
-                        $html .= $this->display_line_item($child_line_item, $options, $line_item);
110
-                    }
111
-                }
112
-                break;
113
-            case EEM_Line_Item::type_sub_line_item:
114
-                $html .= $this->_sub_item_row($line_item, $options, $parent_line_item);
115
-                break;
116
-            case EEM_Line_Item::type_sub_total:
117
-                static $sub_total = 0;
118
-                $event_sub_total = 0;
119
-                $text = esc_html__('Sub-Total', 'event_espresso');
120
-                if ($line_item->OBJ_type() === 'Event') {
121
-                    $options['event_id'] = $event_id = $line_item->OBJ_ID();
122
-                    if (! isset($this->_events[ $options['event_id'] ])) {
123
-                        $event = EEM_Event::instance()->get_one_by_ID($options['event_id']);
124
-                        // if event has default reg status of Not Approved, then don't display info on it
125
-                        if (
126
-                            $event instanceof EE_Event
127
-                            && $event->default_registration_status() === EEM_Registration::status_id_not_approved
128
-                        ) {
129
-                            $display_event = false;
130
-                            // unless there are registrations for it that are returning to pay
131
-                            if (isset($options['registrations']) && is_array($options['registrations'])) {
132
-                                foreach ($options['registrations'] as $registration) {
133
-                                    if (! $registration instanceof EE_Registration) {
134
-                                        continue;
135
-                                    }
136
-                                    $display_event = $registration->event_ID() === $options['event_id']
137
-                                                     && $registration->status_ID() !== EEM_Registration::status_id_not_approved
138
-                                        ? true
139
-                                        : $display_event;
140
-                                }
141
-                            }
142
-                            if (! $display_event) {
143
-                                return '';
144
-                            }
145
-                        }
146
-                        $this->_events[ $options['event_id'] ] = 0;
147
-                        $html .= $this->_event_row($line_item);
148
-                        $text = esc_html__('Event Sub-Total', 'event_espresso');
149
-                    }
150
-                }
151
-                $child_line_items = $line_item->children();
152
-                // loop thru children
153
-                foreach ($child_line_items as $child_line_item) {
154
-                    // recursively feed children back into this method
155
-                    $html .= $this->display_line_item($child_line_item, $options, $line_item);
156
-                }
157
-                $event_sub_total += isset($options['event_id']) ? $this->_events[ $options['event_id'] ] : 0;
158
-                $sub_total += $event_sub_total;
159
-                if (
160
-                    (
161
-                        // event subtotals
162
-                        $line_item->code() !== 'pre-tax-subtotal' && count($child_line_items) > 1
163
-                    )
164
-                    || (
165
-                        // pre-tax subtotals
166
-                        $line_item->code() === 'pre-tax-subtotal' && count($this->_events) > 1
167
-                    )
168
-                ) {
169
-                    $options['sub_total'] = $line_item->OBJ_type() === 'Event' ? $event_sub_total : $sub_total;
170
-                    $html .= $this->_sub_total_row($line_item, $text, $options);
171
-                }
172
-                break;
173
-            case EEM_Line_Item::type_tax:
174
-                if ($this->_show_taxes) {
175
-                    $this->_taxes_html .= $this->_tax_row($line_item, $options);
176
-                }
177
-                break;
178
-            case EEM_Line_Item::type_tax_sub_total:
179
-                if ($this->_show_taxes) {
180
-                    $child_line_items = $line_item->children();
181
-                    // loop thru children
182
-                    foreach ($child_line_items as $child_line_item) {
183
-                        // recursively feed children back into this method
184
-                        $html .= $this->display_line_item($child_line_item, $options, $line_item);
185
-                    }
186
-                    if (count($child_line_items) > 1) {
187
-                        $this->_taxes_html .= $this->_total_tax_row($line_item, esc_html__('Tax Total', 'event_espresso'));
188
-                    }
189
-                }
190
-                break;
191
-            case EEM_Line_Item::type_total:
192
-                // get all child line items
193
-                $children = $line_item->children();
194
-                // loop thru all non-tax child line items
195
-                foreach ($children as $child_line_item) {
196
-                    if ($child_line_item->type() !== EEM_Line_Item::type_tax_sub_total) {
197
-                        // recursively feed children back into this method
198
-                        $html .= $this->display_line_item($child_line_item, $options, $line_item);
199
-                    }
200
-                }
201
-                // now loop thru  tax child line items
202
-                foreach ($children as $child_line_item) {
203
-                    if ($child_line_item->type() === EEM_Line_Item::type_tax_sub_total) {
204
-                        // recursively feed children back into this method
205
-                        $html .= $this->display_line_item($child_line_item, $options, $line_item);
206
-                    }
207
-                }
208
-                $html .= $this->_taxes_html;
209
-                $html .= $this->_total_row($line_item, esc_html__('Total', 'event_espresso'));
210
-                $html .= $this->_payments_and_amount_owing_rows($line_item, $options);
211
-                break;
212
-        }
213
-        return $html;
214
-    }
215
-
216
-
217
-
218
-    /**
219
-     * _event_row - basically a Heading row displayed once above each event's ticket rows
220
-     *
221
-     * @param EE_Line_Item $line_item
222
-     * @return mixed
223
-     */
224
-    private function _event_row(EE_Line_Item $line_item)
225
-    {
226
-        // start of row
227
-        $html = EEH_HTML::tr('', 'event-cart-total-row', 'total_tr odd');
228
-        // event name td
229
-        $html .= EEH_HTML::td(
230
-            EEH_HTML::strong($line_item->name()),
231
-            '',
232
-            'event-header',
233
-            '',
234
-            ' colspan="4"'
235
-        );
236
-        // end of row
237
-        $html .= EEH_HTML::trx();
238
-        return $html;
239
-    }
240
-
241
-
242
-
243
-    /**
244
-     * _ticket_row
245
-     *
246
-     * @param EE_Line_Item $line_item
247
-     * @param array        $options
248
-     * @return mixed
249
-     * @throws EE_Error
250
-     */
251
-    private function _ticket_row(EE_Line_Item $line_item, $options = array())
252
-    {
253
-        // start of row
254
-        $row_class = $options['odd'] ? 'item odd' : 'item';
255
-        $html = EEH_HTML::tr('', '', $row_class);
256
-        // name && desc
257
-        $name_and_desc = apply_filters(
258
-            'FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__name',
259
-            $line_item->name(),
260
-            $line_item
261
-        );
262
-        $name_and_desc .= apply_filters(
263
-            'FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__desc',
264
-            (
265
-                $options['show_desc']
266
-                    ? '<span class="line-item-desc-spn smaller-text">: ' . $line_item->desc() . '</span>'
267
-                    : ''
268
-            ),
269
-            $line_item,
270
-            $options
271
-        );
272
-        $name_and_desc .= $line_item->is_taxable() ? ' * ' : '';
273
-        $name_and_desc = apply_filters(
274
-            'FHEE__EE_SPCO_Line_Item_Display_Strategy___ticket_row__name_and_desc',
275
-            $name_and_desc,
276
-            $line_item,
277
-            $options
278
-        );
279
-
280
-        // name td
281
-        $html .= EEH_HTML::td( /*__FUNCTION__ .*/
282
-            $name_and_desc,
283
-            '',
284
-            'item_l'
285
-        );
286
-        // price td
287
-        $price = apply_filters(
288
-            'FHEE__EE_SPCO_Line_Item_Display_Strategy___ticket_row__price',
289
-            $line_item->unit_price_no_code(),
290
-            $line_item
291
-        );
292
-        $html .= EEH_HTML::td($price, '', 'item_c jst-rght');
293
-        // quantity td
294
-        $html .= EEH_HTML::td($line_item->quantity(), '', 'item_l jst-rght');
295
-        $this->_total_items += $line_item->quantity();
296
-        // determine total for line item
297
-        $total = apply_filters(
298
-            'FHEE__EE_SPCO_Line_Item_Display_Strategy___ticket_row__total',
299
-            $line_item->total(),
300
-            $line_item
301
-        );
302
-        $this->_events[ $options['event_id'] ] += $total;
303
-        // total td
304
-        $html .= EEH_HTML::td(
305
-            EEH_Template::format_currency($total, false, false),
306
-            '',
307
-            'item_r jst-rght'
308
-        );
309
-        // end of row
310
-        $html .= EEH_HTML::trx();
311
-        return $html;
312
-    }
313
-
314
-
315
-
316
-    /**
317
-     * _item_row
318
-     *
319
-     * @param EE_Line_Item $line_item
320
-     * @param array        $options
321
-     * @return mixed
322
-     * @throws EE_Error
323
-     */
324
-    private function _item_row(EE_Line_Item $line_item, $options = array())
325
-    {
326
-        // start of row
327
-        $row_class = $options['odd'] ? 'item odd' : 'item';
328
-        $html = EEH_HTML::tr('', '', $row_class);
329
-        $obj_name = $line_item->OBJ_type() ? $line_item->OBJ_type_i18n() . ': ' : '';
330
-        // name && desc
331
-        $name_and_desc = apply_filters(
332
-            'FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__name',
333
-            $obj_name . $line_item->name(),
334
-            $line_item
335
-        );
336
-        $name_and_desc .= apply_filters(
337
-            'FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__desc',
338
-            (
339
-                $options['show_desc']
340
-                ? '<span class="line-item-desc-spn smaller-text">: ' . $line_item->desc() . '</span>'
341
-                : ''
342
-            ),
343
-            $line_item,
344
-            $options
345
-        );
346
-        $name_and_desc .= $line_item->is_taxable() ? ' * ' : '';
347
-        $name_and_desc = apply_filters(
348
-            'FHEE__EE_SPCO_Line_Item_Display_Strategy___item_row__name_and_desc',
349
-            $name_and_desc,
350
-            $line_item,
351
-            $options
352
-        );
353
-
354
-        // name td
355
-        $html .= EEH_HTML::td($name_and_desc, '', 'item_l');
356
-        // price td
357
-        if ($line_item->is_percent()) {
358
-            $html .= EEH_HTML::td($line_item->percent() . '%', '', 'item_c jst-rght');
359
-        } else {
360
-            $html .= EEH_HTML::td($line_item->unit_price_no_code(), '', 'item_c jst-rght');
361
-        }
362
-        // quantity td
363
-        $html .= EEH_HTML::td($line_item->quantity(), '', 'item_l jst-rght');
364
-        // $total = $line_item->total() * $line_item->quantity();
365
-        $total = $line_item->total();
366
-        if (isset($options['event_id'], $this->_events[ $options['event_id'] ])) {
367
-            $this->_events[ $options['event_id'] ] += $total;
368
-        }
369
-        // total td
370
-        $html .= EEH_HTML::td(
371
-            EEH_Template::format_currency($total, false, false),
372
-            '',
373
-            'item_r jst-rght'
374
-        );
375
-        // end of row
376
-        $html .= EEH_HTML::trx();
377
-        return $html;
378
-    }
379
-
380
-
381
-
382
-    /**
383
-     * _sub_item_row
384
-     *
385
-     * @param EE_Line_Item $line_item
386
-     * @param array        $options
387
-     * @param EE_Line_Item $parent_line_item
388
-     * @return mixed
389
-     * @throws EE_Error
390
-     */
391
-    private function _sub_item_row(EE_Line_Item $line_item, $options = array(), EE_Line_Item $parent_line_item = null)
392
-    {
393
-        if (
394
-            $parent_line_item instanceof  EE_Line_Item
395
-            && $line_item->children() === array()
396
-            && $line_item->name() === $parent_line_item->name()
397
-            && apply_filters(
398
-                'FHEE__EE_SPCO_Line_Item_Display_Strategy___sub_item_row__hide_main_sub_line_item',
399
-                true
400
-            )
401
-        ) {
402
-            return '';
403
-        }
404
-        // start of row
405
-        $html = EEH_HTML::tr('', '', 'item sub-item-row');
406
-        // name && desc
407
-        $name_and_desc = EEH_HTML::span('', '', 'sub-item-row-bullet dashicons dashicons-arrow-right')
408
-                         . $line_item->name();
409
-        $name_and_desc .= $options['show_desc'] ? '<span class="line-sub-item-desc-spn smaller-text">: '
410
-                                                  . $line_item->desc()
411
-                                                  . '</span>' : '';
412
-        // name td
413
-        $html .= EEH_HTML::td($name_and_desc, '', 'item_l sub-item');
414
-        $qty = $parent_line_item instanceof EE_Line_Item ? $parent_line_item->quantity() : 1;
415
-        // discount/surcharge td
416
-        if ($line_item->is_percent()) {
417
-            $html .= EEH_HTML::td(
418
-                EEH_Template::format_currency(
419
-                    $line_item->total() / $qty,
420
-                    false,
421
-                    false
422
-                ),
423
-                '',
424
-                'item_c jst-rght'
425
-            );
426
-        } else {
427
-            $html .= EEH_HTML::td($line_item->unit_price_no_code(), '', 'item_c jst-rght');
428
-        }
429
-        // no quantity td
430
-        $html .= EEH_HTML::td();
431
-        // no total td
432
-        $html .= EEH_HTML::td();
433
-        // end of row
434
-        $html .= EEH_HTML::trx();
435
-        $html = apply_filters(
436
-            'FHEE__EE_SPCO_Line_Item_Display_Strategy___sub_item_row__html',
437
-            $html,
438
-            $line_item,
439
-            $options,
440
-            $parent_line_item
441
-        );
442
-        return $html;
443
-    }
444
-
445
-
446
-
447
-    /**
448
-     * _tax_row
449
-     *
450
-     * @param EE_Line_Item $line_item
451
-     * @param array        $options
452
-     * @return mixed
453
-     * @throws EE_Error
454
-     */
455
-    private function _tax_row(EE_Line_Item $line_item, $options = array())
456
-    {
457
-        // start of row
458
-        $html = EEH_HTML::tr('', 'item sub-item tax-total');
459
-        // name && desc
460
-        $name_and_desc = $line_item->name();
461
-        $name_and_desc .= '<span class="smaller-text lt-grey-text" style="margin:0 0 0 2em;">'
462
-                          . esc_html__(' * taxable items', 'event_espresso') . '</span>';
463
-        $name_and_desc .= $options['show_desc'] ? '<br/>' . $line_item->desc() : '';
464
-        // name td
465
-        $html .= EEH_HTML::td( /*__FUNCTION__ .*/
466
-            $name_and_desc,
467
-            '',
468
-            'item_l sub-item'
469
-        );
470
-        // percent td
471
-        $html .= EEH_HTML::td($line_item->percent() . '%', '', ' jst-rght', '');
472
-        // empty td (price)
473
-        $html .= EEH_HTML::td(EEH_HTML::nbsp());
474
-        // total td
475
-        $html .= EEH_HTML::td(
476
-            EEH_Template::format_currency(
477
-                $line_item->total(),
478
-                false,
479
-                false
480
-            ),
481
-            '',
482
-            'item_r jst-rght'
483
-        );
484
-        // end of row
485
-        $html .= EEH_HTML::trx();
486
-        return $html;
487
-    }
488
-
489
-
490
-
491
-    /**
492
-     * _total_row
493
-     *
494
-     * @param EE_Line_Item $line_item
495
-     * @param string       $text
496
-     * @return mixed
497
-     * @throws EE_Error
498
-     */
499
-    private function _total_tax_row(EE_Line_Item $line_item, $text = '')
500
-    {
501
-        $html = '';
502
-        if ($line_item->total()) {
503
-            // start of row
504
-            $html = EEH_HTML::tr('', '', 'total_tr odd');
505
-            // total td
506
-            $html .= EEH_HTML::td(
507
-                $text,
508
-                '',
509
-                'total_currency total jst-rght',
510
-                '',
511
-                ' colspan="2"'
512
-            );
513
-            // empty td (price)
514
-            $html .= EEH_HTML::td(EEH_HTML::nbsp());
515
-            // total td
516
-            $html .= EEH_HTML::td(
517
-                EEH_Template::format_currency($line_item->total(), false, false),
518
-                '',
519
-                'total jst-rght'
520
-            );
521
-            // end of row
522
-            $html .= EEH_HTML::trx();
523
-        }
524
-        return $html;
525
-    }
526
-
527
-
528
-
529
-    /**
530
-     * _total_row
531
-     *
532
-     * @param EE_Line_Item $line_item
533
-     * @param string       $text
534
-     * @param array        $options
535
-     * @return mixed
536
-     * @throws EE_Error
537
-     */
538
-    private function _sub_total_row(EE_Line_Item $line_item, $text = '', $options = array())
539
-    {
540
-        $html = '';
541
-        if ($line_item->total()) {
542
-            // start of row
543
-            $html = EEH_HTML::tr('', '', 'total_tr odd');
544
-            // total td
545
-            $html .= EEH_HTML::td(
546
-                $text,
547
-                '',
548
-                'total_currency total jst-rght',
549
-                '',
550
-                ' colspan="3"'
551
-            );
552
-            // total td
553
-            $html .= EEH_HTML::td(
554
-                EEH_Template::format_currency($options['sub_total'], false, false),
555
-                '',
556
-                'total jst-rght'
557
-            );
558
-            // end of row
559
-            $html .= EEH_HTML::trx();
560
-        }
561
-        return $html;
562
-    }
563
-
564
-
565
-
566
-    /**
567
-     * _total_row
568
-     *
569
-     * @param EE_Line_Item $line_item
570
-     * @param string       $text
571
-     * @return mixed
572
-     * @throws EE_Error
573
-     */
574
-    private function _total_row(EE_Line_Item $line_item, $text = '')
575
-    {
576
-        // start of row
577
-        $html = EEH_HTML::tr('', '', 'spco-grand-total total_tr odd');
578
-        // total td
579
-        $html .= EEH_HTML::td($text, '', 'total_currency total jst-rght', '', ' colspan="3"');
580
-        // total td
581
-        $html .= EEH_HTML::td(
582
-            EEH_Template::format_currency($line_item->total(), false, false),
583
-            '',
584
-            'total jst-rght'
585
-        );
586
-        // end of row
587
-        $html .= EEH_HTML::trx();
588
-        return $html;
589
-    }
590
-
591
-
592
-
593
-    /**
594
-     * _payments_and_amount_owing_rows
595
-     *
596
-     * @param EE_Line_Item $line_item
597
-     * @param array        $options
598
-     * @return mixed
599
-     * @throws EE_Error
600
-     */
601
-    private function _payments_and_amount_owing_rows(EE_Line_Item $line_item, $options = array())
602
-    {
603
-        $html = '';
604
-        $owing = $line_item->total();
605
-        $transaction = EEM_Transaction::instance()->get_one_by_ID($line_item->TXN_ID());
606
-        if ($transaction instanceof EE_Transaction) {
607
-            $registration_payments = array();
608
-            $registrations = ! empty($options['registrations'])
609
-                ? $options['registrations']
610
-                : $transaction->registrations();
611
-            foreach ($registrations as $registration) {
612
-                if ($registration instanceof EE_Registration && $registration->owes_monies_and_can_pay()) {
613
-                    $registration_payments += $registration->registration_payments();
614
-                }
615
-            }
616
-            if (! empty($registration_payments)) {
617
-                foreach ($registration_payments as $registration_payment) {
618
-                    if ($registration_payment instanceof EE_Registration_Payment) {
619
-                        $owing -= $registration_payment->amount();
620
-                        $payment = $registration_payment->payment();
621
-                        $payment_desc = '';
622
-                        if ($payment instanceof EE_Payment) {
623
-                            $payment_desc = sprintf(
624
-                                esc_html__('Payment%1$s Received: %2$s', 'event_espresso'),
625
-                                $payment->txn_id_chq_nmbr() !== ''
626
-                                    ? ' <span class="small-text">(#' . $payment->txn_id_chq_nmbr() . ')</span> '
627
-                                    : '',
628
-                                $payment->timestamp()
629
-                            );
630
-                        }
631
-                        // start of row
632
-                        $html .= EEH_HTML::tr('', '', 'total_tr odd');
633
-                        // payment desc
634
-                        $html .= EEH_HTML::td($payment_desc, '', '', '', ' colspan="3"');
635
-                        // total td
636
-                        $html .= EEH_HTML::td(
637
-                            EEH_Template::format_currency(
638
-                                $registration_payment->amount(),
639
-                                false,
640
-                                false
641
-                            ),
642
-                            '',
643
-                            'total jst-rght'
644
-                        );
645
-                        // end of row
646
-                        $html .= EEH_HTML::trx();
647
-                    }
648
-                }
649
-                if ($line_item->total()) {
650
-                    // start of row
651
-                    $html .= EEH_HTML::tr('', '', 'total_tr odd');
652
-                    // total td
653
-                    $html .= EEH_HTML::td(
654
-                        esc_html__('Amount Owing', 'event_espresso'),
655
-                        '',
656
-                        'total_currency total jst-rght',
657
-                        '',
658
-                        ' colspan="3"'
659
-                    );
660
-                    // total td
661
-                    $html .= EEH_HTML::td(
662
-                        EEH_Template::format_currency($owing, false, false),
663
-                        '',
664
-                        'total jst-rght'
665
-                    );
666
-                    // end of row
667
-                    $html .= EEH_HTML::trx();
668
-                }
669
-            }
670
-        }
671
-        $this->_grand_total = $owing;
672
-        return $html;
673
-    }
15
+	/**
16
+	 * array of events
17
+	 *
18
+	 * @type EE_Line_Item[] $_events
19
+	 */
20
+	private $_events = array();
21
+
22
+	/**
23
+	 * whether to display the taxes row or not
24
+	 *
25
+	 * @type bool $_show_taxes
26
+	 */
27
+	private $_show_taxes = false;
28
+
29
+	/**
30
+	 * html for any tax rows
31
+	 *
32
+	 * @type string $_show_taxes
33
+	 */
34
+	private $_taxes_html = '';
35
+
36
+	/**
37
+	 * total amount including tax we can bill for at this time
38
+	 *
39
+	 * @type float $_grand_total
40
+	 */
41
+	private $_grand_total = 0.00;
42
+
43
+	/**
44
+	 * total number of items being billed for
45
+	 *
46
+	 * @type int $_total_items
47
+	 */
48
+	private $_total_items = 0;
49
+
50
+
51
+
52
+	/**
53
+	 * @return float
54
+	 */
55
+	public function grand_total()
56
+	{
57
+		return $this->_grand_total;
58
+	}
59
+
60
+
61
+
62
+	/**
63
+	 * @return int
64
+	 */
65
+	public function total_items()
66
+	{
67
+		return $this->_total_items;
68
+	}
69
+
70
+
71
+
72
+	/**
73
+	 * @param EE_Line_Item $line_item
74
+	 * @param array        $options
75
+	 * @param EE_Line_Item $parent_line_item
76
+	 * @return mixed
77
+	 * @throws EE_Error
78
+	 */
79
+	public function display_line_item(
80
+		EE_Line_Item $line_item,
81
+		$options = array(),
82
+		EE_Line_Item $parent_line_item = null
83
+	) {
84
+		$html = '';
85
+		// set some default options and merge with incoming
86
+		$default_options = array(
87
+			'show_desc' => true,  //    true        false
88
+			'odd'       => false,
89
+		);
90
+		$options = array_merge($default_options, (array) $options);
91
+		switch ($line_item->type()) {
92
+			case EEM_Line_Item::type_line_item:
93
+				$this->_show_taxes = $line_item->is_taxable() ? true : $this->_show_taxes;
94
+				if ($line_item->OBJ_type() === 'Ticket') {
95
+					// item row
96
+					$html .= $this->_ticket_row($line_item, $options);
97
+				} else {
98
+					// item row
99
+					$html .= $this->_item_row($line_item, $options);
100
+				}
101
+				if (
102
+					apply_filters(
103
+						'FHEE__EE_SPCO_Line_Item_Display_Strategy__display_line_item__display_sub_line_items',
104
+						true
105
+					)
106
+				) {
107
+					// got any kids?
108
+					foreach ($line_item->children() as $child_line_item) {
109
+						$html .= $this->display_line_item($child_line_item, $options, $line_item);
110
+					}
111
+				}
112
+				break;
113
+			case EEM_Line_Item::type_sub_line_item:
114
+				$html .= $this->_sub_item_row($line_item, $options, $parent_line_item);
115
+				break;
116
+			case EEM_Line_Item::type_sub_total:
117
+				static $sub_total = 0;
118
+				$event_sub_total = 0;
119
+				$text = esc_html__('Sub-Total', 'event_espresso');
120
+				if ($line_item->OBJ_type() === 'Event') {
121
+					$options['event_id'] = $event_id = $line_item->OBJ_ID();
122
+					if (! isset($this->_events[ $options['event_id'] ])) {
123
+						$event = EEM_Event::instance()->get_one_by_ID($options['event_id']);
124
+						// if event has default reg status of Not Approved, then don't display info on it
125
+						if (
126
+							$event instanceof EE_Event
127
+							&& $event->default_registration_status() === EEM_Registration::status_id_not_approved
128
+						) {
129
+							$display_event = false;
130
+							// unless there are registrations for it that are returning to pay
131
+							if (isset($options['registrations']) && is_array($options['registrations'])) {
132
+								foreach ($options['registrations'] as $registration) {
133
+									if (! $registration instanceof EE_Registration) {
134
+										continue;
135
+									}
136
+									$display_event = $registration->event_ID() === $options['event_id']
137
+													 && $registration->status_ID() !== EEM_Registration::status_id_not_approved
138
+										? true
139
+										: $display_event;
140
+								}
141
+							}
142
+							if (! $display_event) {
143
+								return '';
144
+							}
145
+						}
146
+						$this->_events[ $options['event_id'] ] = 0;
147
+						$html .= $this->_event_row($line_item);
148
+						$text = esc_html__('Event Sub-Total', 'event_espresso');
149
+					}
150
+				}
151
+				$child_line_items = $line_item->children();
152
+				// loop thru children
153
+				foreach ($child_line_items as $child_line_item) {
154
+					// recursively feed children back into this method
155
+					$html .= $this->display_line_item($child_line_item, $options, $line_item);
156
+				}
157
+				$event_sub_total += isset($options['event_id']) ? $this->_events[ $options['event_id'] ] : 0;
158
+				$sub_total += $event_sub_total;
159
+				if (
160
+					(
161
+						// event subtotals
162
+						$line_item->code() !== 'pre-tax-subtotal' && count($child_line_items) > 1
163
+					)
164
+					|| (
165
+						// pre-tax subtotals
166
+						$line_item->code() === 'pre-tax-subtotal' && count($this->_events) > 1
167
+					)
168
+				) {
169
+					$options['sub_total'] = $line_item->OBJ_type() === 'Event' ? $event_sub_total : $sub_total;
170
+					$html .= $this->_sub_total_row($line_item, $text, $options);
171
+				}
172
+				break;
173
+			case EEM_Line_Item::type_tax:
174
+				if ($this->_show_taxes) {
175
+					$this->_taxes_html .= $this->_tax_row($line_item, $options);
176
+				}
177
+				break;
178
+			case EEM_Line_Item::type_tax_sub_total:
179
+				if ($this->_show_taxes) {
180
+					$child_line_items = $line_item->children();
181
+					// loop thru children
182
+					foreach ($child_line_items as $child_line_item) {
183
+						// recursively feed children back into this method
184
+						$html .= $this->display_line_item($child_line_item, $options, $line_item);
185
+					}
186
+					if (count($child_line_items) > 1) {
187
+						$this->_taxes_html .= $this->_total_tax_row($line_item, esc_html__('Tax Total', 'event_espresso'));
188
+					}
189
+				}
190
+				break;
191
+			case EEM_Line_Item::type_total:
192
+				// get all child line items
193
+				$children = $line_item->children();
194
+				// loop thru all non-tax child line items
195
+				foreach ($children as $child_line_item) {
196
+					if ($child_line_item->type() !== EEM_Line_Item::type_tax_sub_total) {
197
+						// recursively feed children back into this method
198
+						$html .= $this->display_line_item($child_line_item, $options, $line_item);
199
+					}
200
+				}
201
+				// now loop thru  tax child line items
202
+				foreach ($children as $child_line_item) {
203
+					if ($child_line_item->type() === EEM_Line_Item::type_tax_sub_total) {
204
+						// recursively feed children back into this method
205
+						$html .= $this->display_line_item($child_line_item, $options, $line_item);
206
+					}
207
+				}
208
+				$html .= $this->_taxes_html;
209
+				$html .= $this->_total_row($line_item, esc_html__('Total', 'event_espresso'));
210
+				$html .= $this->_payments_and_amount_owing_rows($line_item, $options);
211
+				break;
212
+		}
213
+		return $html;
214
+	}
215
+
216
+
217
+
218
+	/**
219
+	 * _event_row - basically a Heading row displayed once above each event's ticket rows
220
+	 *
221
+	 * @param EE_Line_Item $line_item
222
+	 * @return mixed
223
+	 */
224
+	private function _event_row(EE_Line_Item $line_item)
225
+	{
226
+		// start of row
227
+		$html = EEH_HTML::tr('', 'event-cart-total-row', 'total_tr odd');
228
+		// event name td
229
+		$html .= EEH_HTML::td(
230
+			EEH_HTML::strong($line_item->name()),
231
+			'',
232
+			'event-header',
233
+			'',
234
+			' colspan="4"'
235
+		);
236
+		// end of row
237
+		$html .= EEH_HTML::trx();
238
+		return $html;
239
+	}
240
+
241
+
242
+
243
+	/**
244
+	 * _ticket_row
245
+	 *
246
+	 * @param EE_Line_Item $line_item
247
+	 * @param array        $options
248
+	 * @return mixed
249
+	 * @throws EE_Error
250
+	 */
251
+	private function _ticket_row(EE_Line_Item $line_item, $options = array())
252
+	{
253
+		// start of row
254
+		$row_class = $options['odd'] ? 'item odd' : 'item';
255
+		$html = EEH_HTML::tr('', '', $row_class);
256
+		// name && desc
257
+		$name_and_desc = apply_filters(
258
+			'FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__name',
259
+			$line_item->name(),
260
+			$line_item
261
+		);
262
+		$name_and_desc .= apply_filters(
263
+			'FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__desc',
264
+			(
265
+				$options['show_desc']
266
+					? '<span class="line-item-desc-spn smaller-text">: ' . $line_item->desc() . '</span>'
267
+					: ''
268
+			),
269
+			$line_item,
270
+			$options
271
+		);
272
+		$name_and_desc .= $line_item->is_taxable() ? ' * ' : '';
273
+		$name_and_desc = apply_filters(
274
+			'FHEE__EE_SPCO_Line_Item_Display_Strategy___ticket_row__name_and_desc',
275
+			$name_and_desc,
276
+			$line_item,
277
+			$options
278
+		);
279
+
280
+		// name td
281
+		$html .= EEH_HTML::td( /*__FUNCTION__ .*/
282
+			$name_and_desc,
283
+			'',
284
+			'item_l'
285
+		);
286
+		// price td
287
+		$price = apply_filters(
288
+			'FHEE__EE_SPCO_Line_Item_Display_Strategy___ticket_row__price',
289
+			$line_item->unit_price_no_code(),
290
+			$line_item
291
+		);
292
+		$html .= EEH_HTML::td($price, '', 'item_c jst-rght');
293
+		// quantity td
294
+		$html .= EEH_HTML::td($line_item->quantity(), '', 'item_l jst-rght');
295
+		$this->_total_items += $line_item->quantity();
296
+		// determine total for line item
297
+		$total = apply_filters(
298
+			'FHEE__EE_SPCO_Line_Item_Display_Strategy___ticket_row__total',
299
+			$line_item->total(),
300
+			$line_item
301
+		);
302
+		$this->_events[ $options['event_id'] ] += $total;
303
+		// total td
304
+		$html .= EEH_HTML::td(
305
+			EEH_Template::format_currency($total, false, false),
306
+			'',
307
+			'item_r jst-rght'
308
+		);
309
+		// end of row
310
+		$html .= EEH_HTML::trx();
311
+		return $html;
312
+	}
313
+
314
+
315
+
316
+	/**
317
+	 * _item_row
318
+	 *
319
+	 * @param EE_Line_Item $line_item
320
+	 * @param array        $options
321
+	 * @return mixed
322
+	 * @throws EE_Error
323
+	 */
324
+	private function _item_row(EE_Line_Item $line_item, $options = array())
325
+	{
326
+		// start of row
327
+		$row_class = $options['odd'] ? 'item odd' : 'item';
328
+		$html = EEH_HTML::tr('', '', $row_class);
329
+		$obj_name = $line_item->OBJ_type() ? $line_item->OBJ_type_i18n() . ': ' : '';
330
+		// name && desc
331
+		$name_and_desc = apply_filters(
332
+			'FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__name',
333
+			$obj_name . $line_item->name(),
334
+			$line_item
335
+		);
336
+		$name_and_desc .= apply_filters(
337
+			'FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__desc',
338
+			(
339
+				$options['show_desc']
340
+				? '<span class="line-item-desc-spn smaller-text">: ' . $line_item->desc() . '</span>'
341
+				: ''
342
+			),
343
+			$line_item,
344
+			$options
345
+		);
346
+		$name_and_desc .= $line_item->is_taxable() ? ' * ' : '';
347
+		$name_and_desc = apply_filters(
348
+			'FHEE__EE_SPCO_Line_Item_Display_Strategy___item_row__name_and_desc',
349
+			$name_and_desc,
350
+			$line_item,
351
+			$options
352
+		);
353
+
354
+		// name td
355
+		$html .= EEH_HTML::td($name_and_desc, '', 'item_l');
356
+		// price td
357
+		if ($line_item->is_percent()) {
358
+			$html .= EEH_HTML::td($line_item->percent() . '%', '', 'item_c jst-rght');
359
+		} else {
360
+			$html .= EEH_HTML::td($line_item->unit_price_no_code(), '', 'item_c jst-rght');
361
+		}
362
+		// quantity td
363
+		$html .= EEH_HTML::td($line_item->quantity(), '', 'item_l jst-rght');
364
+		// $total = $line_item->total() * $line_item->quantity();
365
+		$total = $line_item->total();
366
+		if (isset($options['event_id'], $this->_events[ $options['event_id'] ])) {
367
+			$this->_events[ $options['event_id'] ] += $total;
368
+		}
369
+		// total td
370
+		$html .= EEH_HTML::td(
371
+			EEH_Template::format_currency($total, false, false),
372
+			'',
373
+			'item_r jst-rght'
374
+		);
375
+		// end of row
376
+		$html .= EEH_HTML::trx();
377
+		return $html;
378
+	}
379
+
380
+
381
+
382
+	/**
383
+	 * _sub_item_row
384
+	 *
385
+	 * @param EE_Line_Item $line_item
386
+	 * @param array        $options
387
+	 * @param EE_Line_Item $parent_line_item
388
+	 * @return mixed
389
+	 * @throws EE_Error
390
+	 */
391
+	private function _sub_item_row(EE_Line_Item $line_item, $options = array(), EE_Line_Item $parent_line_item = null)
392
+	{
393
+		if (
394
+			$parent_line_item instanceof  EE_Line_Item
395
+			&& $line_item->children() === array()
396
+			&& $line_item->name() === $parent_line_item->name()
397
+			&& apply_filters(
398
+				'FHEE__EE_SPCO_Line_Item_Display_Strategy___sub_item_row__hide_main_sub_line_item',
399
+				true
400
+			)
401
+		) {
402
+			return '';
403
+		}
404
+		// start of row
405
+		$html = EEH_HTML::tr('', '', 'item sub-item-row');
406
+		// name && desc
407
+		$name_and_desc = EEH_HTML::span('', '', 'sub-item-row-bullet dashicons dashicons-arrow-right')
408
+						 . $line_item->name();
409
+		$name_and_desc .= $options['show_desc'] ? '<span class="line-sub-item-desc-spn smaller-text">: '
410
+												  . $line_item->desc()
411
+												  . '</span>' : '';
412
+		// name td
413
+		$html .= EEH_HTML::td($name_and_desc, '', 'item_l sub-item');
414
+		$qty = $parent_line_item instanceof EE_Line_Item ? $parent_line_item->quantity() : 1;
415
+		// discount/surcharge td
416
+		if ($line_item->is_percent()) {
417
+			$html .= EEH_HTML::td(
418
+				EEH_Template::format_currency(
419
+					$line_item->total() / $qty,
420
+					false,
421
+					false
422
+				),
423
+				'',
424
+				'item_c jst-rght'
425
+			);
426
+		} else {
427
+			$html .= EEH_HTML::td($line_item->unit_price_no_code(), '', 'item_c jst-rght');
428
+		}
429
+		// no quantity td
430
+		$html .= EEH_HTML::td();
431
+		// no total td
432
+		$html .= EEH_HTML::td();
433
+		// end of row
434
+		$html .= EEH_HTML::trx();
435
+		$html = apply_filters(
436
+			'FHEE__EE_SPCO_Line_Item_Display_Strategy___sub_item_row__html',
437
+			$html,
438
+			$line_item,
439
+			$options,
440
+			$parent_line_item
441
+		);
442
+		return $html;
443
+	}
444
+
445
+
446
+
447
+	/**
448
+	 * _tax_row
449
+	 *
450
+	 * @param EE_Line_Item $line_item
451
+	 * @param array        $options
452
+	 * @return mixed
453
+	 * @throws EE_Error
454
+	 */
455
+	private function _tax_row(EE_Line_Item $line_item, $options = array())
456
+	{
457
+		// start of row
458
+		$html = EEH_HTML::tr('', 'item sub-item tax-total');
459
+		// name && desc
460
+		$name_and_desc = $line_item->name();
461
+		$name_and_desc .= '<span class="smaller-text lt-grey-text" style="margin:0 0 0 2em;">'
462
+						  . esc_html__(' * taxable items', 'event_espresso') . '</span>';
463
+		$name_and_desc .= $options['show_desc'] ? '<br/>' . $line_item->desc() : '';
464
+		// name td
465
+		$html .= EEH_HTML::td( /*__FUNCTION__ .*/
466
+			$name_and_desc,
467
+			'',
468
+			'item_l sub-item'
469
+		);
470
+		// percent td
471
+		$html .= EEH_HTML::td($line_item->percent() . '%', '', ' jst-rght', '');
472
+		// empty td (price)
473
+		$html .= EEH_HTML::td(EEH_HTML::nbsp());
474
+		// total td
475
+		$html .= EEH_HTML::td(
476
+			EEH_Template::format_currency(
477
+				$line_item->total(),
478
+				false,
479
+				false
480
+			),
481
+			'',
482
+			'item_r jst-rght'
483
+		);
484
+		// end of row
485
+		$html .= EEH_HTML::trx();
486
+		return $html;
487
+	}
488
+
489
+
490
+
491
+	/**
492
+	 * _total_row
493
+	 *
494
+	 * @param EE_Line_Item $line_item
495
+	 * @param string       $text
496
+	 * @return mixed
497
+	 * @throws EE_Error
498
+	 */
499
+	private function _total_tax_row(EE_Line_Item $line_item, $text = '')
500
+	{
501
+		$html = '';
502
+		if ($line_item->total()) {
503
+			// start of row
504
+			$html = EEH_HTML::tr('', '', 'total_tr odd');
505
+			// total td
506
+			$html .= EEH_HTML::td(
507
+				$text,
508
+				'',
509
+				'total_currency total jst-rght',
510
+				'',
511
+				' colspan="2"'
512
+			);
513
+			// empty td (price)
514
+			$html .= EEH_HTML::td(EEH_HTML::nbsp());
515
+			// total td
516
+			$html .= EEH_HTML::td(
517
+				EEH_Template::format_currency($line_item->total(), false, false),
518
+				'',
519
+				'total jst-rght'
520
+			);
521
+			// end of row
522
+			$html .= EEH_HTML::trx();
523
+		}
524
+		return $html;
525
+	}
526
+
527
+
528
+
529
+	/**
530
+	 * _total_row
531
+	 *
532
+	 * @param EE_Line_Item $line_item
533
+	 * @param string       $text
534
+	 * @param array        $options
535
+	 * @return mixed
536
+	 * @throws EE_Error
537
+	 */
538
+	private function _sub_total_row(EE_Line_Item $line_item, $text = '', $options = array())
539
+	{
540
+		$html = '';
541
+		if ($line_item->total()) {
542
+			// start of row
543
+			$html = EEH_HTML::tr('', '', 'total_tr odd');
544
+			// total td
545
+			$html .= EEH_HTML::td(
546
+				$text,
547
+				'',
548
+				'total_currency total jst-rght',
549
+				'',
550
+				' colspan="3"'
551
+			);
552
+			// total td
553
+			$html .= EEH_HTML::td(
554
+				EEH_Template::format_currency($options['sub_total'], false, false),
555
+				'',
556
+				'total jst-rght'
557
+			);
558
+			// end of row
559
+			$html .= EEH_HTML::trx();
560
+		}
561
+		return $html;
562
+	}
563
+
564
+
565
+
566
+	/**
567
+	 * _total_row
568
+	 *
569
+	 * @param EE_Line_Item $line_item
570
+	 * @param string       $text
571
+	 * @return mixed
572
+	 * @throws EE_Error
573
+	 */
574
+	private function _total_row(EE_Line_Item $line_item, $text = '')
575
+	{
576
+		// start of row
577
+		$html = EEH_HTML::tr('', '', 'spco-grand-total total_tr odd');
578
+		// total td
579
+		$html .= EEH_HTML::td($text, '', 'total_currency total jst-rght', '', ' colspan="3"');
580
+		// total td
581
+		$html .= EEH_HTML::td(
582
+			EEH_Template::format_currency($line_item->total(), false, false),
583
+			'',
584
+			'total jst-rght'
585
+		);
586
+		// end of row
587
+		$html .= EEH_HTML::trx();
588
+		return $html;
589
+	}
590
+
591
+
592
+
593
+	/**
594
+	 * _payments_and_amount_owing_rows
595
+	 *
596
+	 * @param EE_Line_Item $line_item
597
+	 * @param array        $options
598
+	 * @return mixed
599
+	 * @throws EE_Error
600
+	 */
601
+	private function _payments_and_amount_owing_rows(EE_Line_Item $line_item, $options = array())
602
+	{
603
+		$html = '';
604
+		$owing = $line_item->total();
605
+		$transaction = EEM_Transaction::instance()->get_one_by_ID($line_item->TXN_ID());
606
+		if ($transaction instanceof EE_Transaction) {
607
+			$registration_payments = array();
608
+			$registrations = ! empty($options['registrations'])
609
+				? $options['registrations']
610
+				: $transaction->registrations();
611
+			foreach ($registrations as $registration) {
612
+				if ($registration instanceof EE_Registration && $registration->owes_monies_and_can_pay()) {
613
+					$registration_payments += $registration->registration_payments();
614
+				}
615
+			}
616
+			if (! empty($registration_payments)) {
617
+				foreach ($registration_payments as $registration_payment) {
618
+					if ($registration_payment instanceof EE_Registration_Payment) {
619
+						$owing -= $registration_payment->amount();
620
+						$payment = $registration_payment->payment();
621
+						$payment_desc = '';
622
+						if ($payment instanceof EE_Payment) {
623
+							$payment_desc = sprintf(
624
+								esc_html__('Payment%1$s Received: %2$s', 'event_espresso'),
625
+								$payment->txn_id_chq_nmbr() !== ''
626
+									? ' <span class="small-text">(#' . $payment->txn_id_chq_nmbr() . ')</span> '
627
+									: '',
628
+								$payment->timestamp()
629
+							);
630
+						}
631
+						// start of row
632
+						$html .= EEH_HTML::tr('', '', 'total_tr odd');
633
+						// payment desc
634
+						$html .= EEH_HTML::td($payment_desc, '', '', '', ' colspan="3"');
635
+						// total td
636
+						$html .= EEH_HTML::td(
637
+							EEH_Template::format_currency(
638
+								$registration_payment->amount(),
639
+								false,
640
+								false
641
+							),
642
+							'',
643
+							'total jst-rght'
644
+						);
645
+						// end of row
646
+						$html .= EEH_HTML::trx();
647
+					}
648
+				}
649
+				if ($line_item->total()) {
650
+					// start of row
651
+					$html .= EEH_HTML::tr('', '', 'total_tr odd');
652
+					// total td
653
+					$html .= EEH_HTML::td(
654
+						esc_html__('Amount Owing', 'event_espresso'),
655
+						'',
656
+						'total_currency total jst-rght',
657
+						'',
658
+						' colspan="3"'
659
+					);
660
+					// total td
661
+					$html .= EEH_HTML::td(
662
+						EEH_Template::format_currency($owing, false, false),
663
+						'',
664
+						'total jst-rght'
665
+					);
666
+					// end of row
667
+					$html .= EEH_HTML::trx();
668
+				}
669
+			}
670
+		}
671
+		$this->_grand_total = $owing;
672
+		return $html;
673
+	}
674 674
 }
Please login to merge, or discard this patch.
Spacing   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -84,7 +84,7 @@  discard block
 block discarded – undo
84 84
         $html = '';
85 85
         // set some default options and merge with incoming
86 86
         $default_options = array(
87
-            'show_desc' => true,  //    true        false
87
+            'show_desc' => true, //    true        false
88 88
             'odd'       => false,
89 89
         );
90 90
         $options = array_merge($default_options, (array) $options);
@@ -119,7 +119,7 @@  discard block
 block discarded – undo
119 119
                 $text = esc_html__('Sub-Total', 'event_espresso');
120 120
                 if ($line_item->OBJ_type() === 'Event') {
121 121
                     $options['event_id'] = $event_id = $line_item->OBJ_ID();
122
-                    if (! isset($this->_events[ $options['event_id'] ])) {
122
+                    if ( ! isset($this->_events[$options['event_id']])) {
123 123
                         $event = EEM_Event::instance()->get_one_by_ID($options['event_id']);
124 124
                         // if event has default reg status of Not Approved, then don't display info on it
125 125
                         if (
@@ -130,7 +130,7 @@  discard block
 block discarded – undo
130 130
                             // unless there are registrations for it that are returning to pay
131 131
                             if (isset($options['registrations']) && is_array($options['registrations'])) {
132 132
                                 foreach ($options['registrations'] as $registration) {
133
-                                    if (! $registration instanceof EE_Registration) {
133
+                                    if ( ! $registration instanceof EE_Registration) {
134 134
                                         continue;
135 135
                                     }
136 136
                                     $display_event = $registration->event_ID() === $options['event_id']
@@ -139,11 +139,11 @@  discard block
 block discarded – undo
139 139
                                         : $display_event;
140 140
                                 }
141 141
                             }
142
-                            if (! $display_event) {
142
+                            if ( ! $display_event) {
143 143
                                 return '';
144 144
                             }
145 145
                         }
146
-                        $this->_events[ $options['event_id'] ] = 0;
146
+                        $this->_events[$options['event_id']] = 0;
147 147
                         $html .= $this->_event_row($line_item);
148 148
                         $text = esc_html__('Event Sub-Total', 'event_espresso');
149 149
                     }
@@ -154,7 +154,7 @@  discard block
 block discarded – undo
154 154
                     // recursively feed children back into this method
155 155
                     $html .= $this->display_line_item($child_line_item, $options, $line_item);
156 156
                 }
157
-                $event_sub_total += isset($options['event_id']) ? $this->_events[ $options['event_id'] ] : 0;
157
+                $event_sub_total += isset($options['event_id']) ? $this->_events[$options['event_id']] : 0;
158 158
                 $sub_total += $event_sub_total;
159 159
                 if (
160 160
                     (
@@ -263,7 +263,7 @@  discard block
 block discarded – undo
263 263
             'FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__desc',
264 264
             (
265 265
                 $options['show_desc']
266
-                    ? '<span class="line-item-desc-spn smaller-text">: ' . $line_item->desc() . '</span>'
266
+                    ? '<span class="line-item-desc-spn smaller-text">: '.$line_item->desc().'</span>'
267 267
                     : ''
268 268
             ),
269 269
             $line_item,
@@ -299,7 +299,7 @@  discard block
 block discarded – undo
299 299
             $line_item->total(),
300 300
             $line_item
301 301
         );
302
-        $this->_events[ $options['event_id'] ] += $total;
302
+        $this->_events[$options['event_id']] += $total;
303 303
         // total td
304 304
         $html .= EEH_HTML::td(
305 305
             EEH_Template::format_currency($total, false, false),
@@ -326,18 +326,18 @@  discard block
 block discarded – undo
326 326
         // start of row
327 327
         $row_class = $options['odd'] ? 'item odd' : 'item';
328 328
         $html = EEH_HTML::tr('', '', $row_class);
329
-        $obj_name = $line_item->OBJ_type() ? $line_item->OBJ_type_i18n() . ': ' : '';
329
+        $obj_name = $line_item->OBJ_type() ? $line_item->OBJ_type_i18n().': ' : '';
330 330
         // name && desc
331 331
         $name_and_desc = apply_filters(
332 332
             'FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__name',
333
-            $obj_name . $line_item->name(),
333
+            $obj_name.$line_item->name(),
334 334
             $line_item
335 335
         );
336 336
         $name_and_desc .= apply_filters(
337 337
             'FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__desc',
338 338
             (
339 339
                 $options['show_desc']
340
-                ? '<span class="line-item-desc-spn smaller-text">: ' . $line_item->desc() . '</span>'
340
+                ? '<span class="line-item-desc-spn smaller-text">: '.$line_item->desc().'</span>'
341 341
                 : ''
342 342
             ),
343 343
             $line_item,
@@ -355,7 +355,7 @@  discard block
 block discarded – undo
355 355
         $html .= EEH_HTML::td($name_and_desc, '', 'item_l');
356 356
         // price td
357 357
         if ($line_item->is_percent()) {
358
-            $html .= EEH_HTML::td($line_item->percent() . '%', '', 'item_c jst-rght');
358
+            $html .= EEH_HTML::td($line_item->percent().'%', '', 'item_c jst-rght');
359 359
         } else {
360 360
             $html .= EEH_HTML::td($line_item->unit_price_no_code(), '', 'item_c jst-rght');
361 361
         }
@@ -363,8 +363,8 @@  discard block
 block discarded – undo
363 363
         $html .= EEH_HTML::td($line_item->quantity(), '', 'item_l jst-rght');
364 364
         // $total = $line_item->total() * $line_item->quantity();
365 365
         $total = $line_item->total();
366
-        if (isset($options['event_id'], $this->_events[ $options['event_id'] ])) {
367
-            $this->_events[ $options['event_id'] ] += $total;
366
+        if (isset($options['event_id'], $this->_events[$options['event_id']])) {
367
+            $this->_events[$options['event_id']] += $total;
368 368
         }
369 369
         // total td
370 370
         $html .= EEH_HTML::td(
@@ -459,8 +459,8 @@  discard block
 block discarded – undo
459 459
         // name && desc
460 460
         $name_and_desc = $line_item->name();
461 461
         $name_and_desc .= '<span class="smaller-text lt-grey-text" style="margin:0 0 0 2em;">'
462
-                          . esc_html__(' * taxable items', 'event_espresso') . '</span>';
463
-        $name_and_desc .= $options['show_desc'] ? '<br/>' . $line_item->desc() : '';
462
+                          . esc_html__(' * taxable items', 'event_espresso').'</span>';
463
+        $name_and_desc .= $options['show_desc'] ? '<br/>'.$line_item->desc() : '';
464 464
         // name td
465 465
         $html .= EEH_HTML::td( /*__FUNCTION__ .*/
466 466
             $name_and_desc,
@@ -468,7 +468,7 @@  discard block
 block discarded – undo
468 468
             'item_l sub-item'
469 469
         );
470 470
         // percent td
471
-        $html .= EEH_HTML::td($line_item->percent() . '%', '', ' jst-rght', '');
471
+        $html .= EEH_HTML::td($line_item->percent().'%', '', ' jst-rght', '');
472 472
         // empty td (price)
473 473
         $html .= EEH_HTML::td(EEH_HTML::nbsp());
474 474
         // total td
@@ -613,7 +613,7 @@  discard block
 block discarded – undo
613 613
                     $registration_payments += $registration->registration_payments();
614 614
                 }
615 615
             }
616
-            if (! empty($registration_payments)) {
616
+            if ( ! empty($registration_payments)) {
617 617
                 foreach ($registration_payments as $registration_payment) {
618 618
                     if ($registration_payment instanceof EE_Registration_Payment) {
619 619
                         $owing -= $registration_payment->amount();
@@ -623,7 +623,7 @@  discard block
 block discarded – undo
623 623
                             $payment_desc = sprintf(
624 624
                                 esc_html__('Payment%1$s Received: %2$s', 'event_espresso'),
625 625
                                 $payment->txn_id_chq_nmbr() !== ''
626
-                                    ? ' <span class="small-text">(#' . $payment->txn_id_chq_nmbr() . ')</span> '
626
+                                    ? ' <span class="small-text">(#'.$payment->txn_id_chq_nmbr().')</span> '
627 627
                                     : '',
628 628
                                 $payment->timestamp()
629 629
                             );
Please login to merge, or discard this patch.
core/libraries/rest_api/Capabilities.php 2 patches
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -99,7 +99,7 @@  discard block
 block discarded – undo
99 99
     ) {
100 100
         $has_password = $model->hasPassword();
101 101
         if ($has_password) {
102
-            $entity[ $model->getPasswordField()->get_name() ] = ModelDataTranslator::prepareFieldValueForJson(
102
+            $entity[$model->getPasswordField()->get_name()] = ModelDataTranslator::prepareFieldValueForJson(
103 103
                 $model->getPasswordField(),
104 104
                 $model->getPasswordField()->get_default_value(),
105 105
                 $model_version_info->requestedVersion()
@@ -109,7 +109,7 @@  discard block
 block discarded – undo
109 109
             if (
110 110
                 $has_password
111 111
                 && $model->getPasswordField()->fieldIsProtected($field_name)
112
-                && $entity[ $field_name ]
112
+                && $entity[$field_name]
113 113
             ) {
114 114
                 $replacement_value = ModelDataTranslator::prepareFieldValueForJson(
115 115
                     $field_obj,
@@ -117,10 +117,10 @@  discard block
 block discarded – undo
117 117
                     $model_version_info->requestedVersion()
118 118
                 );
119 119
                 if ($model_version_info->fieldHasRenderedFormat($field_obj)) {
120
-                    $entity[ $field_name ]['rendered'] = $replacement_value;
120
+                    $entity[$field_name]['rendered'] = $replacement_value;
121 121
                 } elseif ($model_version_info->fieldHasPrettyFormat($field_obj)) {
122
-                    $entity[ $field_name ]['raw'] = $replacement_value;
123
-                    $entity[ $field_name ]['pretty'] = ModelDataTranslator::prepareFieldValueForJson(
122
+                    $entity[$field_name]['raw'] = $replacement_value;
123
+                    $entity[$field_name]['pretty'] = ModelDataTranslator::prepareFieldValueForJson(
124 124
                         $field_obj,
125 125
                         $field_obj->prepare_for_pretty_echoing($field_obj->get_default_value()),
126 126
                         $model_version_info->requestedVersion()
@@ -131,7 +131,7 @@  discard block
 block discarded – undo
131 131
                     // so just remove it (or rather, set its default)
132 132
                     // API clients will just need to look to fields with rendered formats to know if these have
133 133
                     // been redacted. Sorry.
134
-                    $entity[ $field_name ] = $replacement_value;
134
+                    $entity[$field_name] = $replacement_value;
135 135
                 }
136 136
             }
137 137
         }
@@ -160,11 +160,11 @@  discard block
 block discarded – undo
160 160
         foreach ($model->field_settings() as $field_name => $field_obj) {
161 161
             if (
162 162
                 $model_version_info->fieldHasRenderedFormat($field_obj)
163
-                && isset($entity[ $field_name ])
164
-                && is_array($entity[ $field_name ])
165
-                && isset($entity[ $field_name ]['raw'])
163
+                && isset($entity[$field_name])
164
+                && is_array($entity[$field_name])
165
+                && isset($entity[$field_name]['raw'])
166 166
             ) {
167
-                unset($entity[ $field_name ]['raw']);
167
+                unset($entity[$field_name]['raw']);
168 168
             }
169 169
         }
170 170
         // theoretically we may want to filter out specific fields for specific models
@@ -190,7 +190,7 @@  discard block
 block discarded – undo
190 190
      */
191 191
     public static function verifyAtLeastPartialAccessTo($model, $model_action_context, $action_name = 'list')
192 192
     {
193
-        if (! Capabilities::currentUserHasPartialAccessTo($model, $model_action_context)) {
193
+        if ( ! Capabilities::currentUserHasPartialAccessTo($model, $model_action_context)) {
194 194
             $model_name_plural = EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
195 195
             throw new RestException(
196 196
                 sprintf('rest_cannot_%s_%s', strtolower($action_name), $model_name_plural),
Please login to merge, or discard this patch.
Indentation   +177 added lines, -177 removed lines patch added patch discarded remove patch
@@ -18,190 +18,190 @@
 block discarded – undo
18 18
 class Capabilities
19 19
 {
20 20
 
21
-    /**
22
-     * The current user can see at least SOME of these entities.
23
-     *
24
-     * @param EEM_Base $model
25
-     * @param string   $model_context one of the return values from EEM_Base::valid_cap_contexts()
26
-     * @return boolean
27
-     */
28
-    public static function currentUserHasPartialAccessTo($model, $model_context = EEM_Base::caps_read)
29
-    {
30
-        if (
31
-            apply_filters(
32
-                'FHEE__Capabilities__current_user_has_partial_access_to__override_begin',
33
-                false,
34
-                $model,
35
-                $model
36
-            )
37
-        ) {
38
-            return true;
39
-        }
40
-        foreach ($model->caps_missing($model_context) as $capability_name => $restriction_obj) {
41
-            if ($restriction_obj instanceof \EE_Return_None_Where_Conditions) {
42
-                return false;
43
-            }
44
-        }
45
-        if (
46
-            apply_filters(
47
-                'FHEE__Capabilities__current_user_has_partial_access_to__override_end',
48
-                false,
49
-                $model,
50
-                $model
51
-            )
52
-        ) {
53
-            return false;
54
-        }
55
-        return true;
56
-    }
21
+	/**
22
+	 * The current user can see at least SOME of these entities.
23
+	 *
24
+	 * @param EEM_Base $model
25
+	 * @param string   $model_context one of the return values from EEM_Base::valid_cap_contexts()
26
+	 * @return boolean
27
+	 */
28
+	public static function currentUserHasPartialAccessTo($model, $model_context = EEM_Base::caps_read)
29
+	{
30
+		if (
31
+			apply_filters(
32
+				'FHEE__Capabilities__current_user_has_partial_access_to__override_begin',
33
+				false,
34
+				$model,
35
+				$model
36
+			)
37
+		) {
38
+			return true;
39
+		}
40
+		foreach ($model->caps_missing($model_context) as $capability_name => $restriction_obj) {
41
+			if ($restriction_obj instanceof \EE_Return_None_Where_Conditions) {
42
+				return false;
43
+			}
44
+		}
45
+		if (
46
+			apply_filters(
47
+				'FHEE__Capabilities__current_user_has_partial_access_to__override_end',
48
+				false,
49
+				$model,
50
+				$model
51
+			)
52
+		) {
53
+			return false;
54
+		}
55
+		return true;
56
+	}
57 57
 
58 58
 
59
-    /**
60
-     * Gets an array of all the capabilities the current user is missing that affected
61
-     * the query
62
-     *
63
-     * @param EEM_Base $model
64
-     * @param string   $request_type one of the constants on WP_JSON_Server
65
-     * @return array
66
-     */
67
-    public static function getMissingPermissions($model, $request_type = EEM_Base::caps_read)
68
-    {
69
-        return $model->caps_missing($request_type);
70
-    }
59
+	/**
60
+	 * Gets an array of all the capabilities the current user is missing that affected
61
+	 * the query
62
+	 *
63
+	 * @param EEM_Base $model
64
+	 * @param string   $request_type one of the constants on WP_JSON_Server
65
+	 * @return array
66
+	 */
67
+	public static function getMissingPermissions($model, $request_type = EEM_Base::caps_read)
68
+	{
69
+		return $model->caps_missing($request_type);
70
+	}
71 71
 
72 72
 
73
-    /**
74
-     * Gets a string of all the capabilities the current user is missing that affected
75
-     * the query
76
-     *
77
-     * @param EEM_Base $model
78
-     * @param string   $model_context one of the return values from EEM_Base::valid_cap_contexts()
79
-     * @return string
80
-     */
81
-    public static function getMissingPermissionsString($model, $model_context = EEM_Base::caps_read)
82
-    {
83
-        return implode(',', array_keys(self::getMissingPermissions($model, $model_context)));
84
-    }
73
+	/**
74
+	 * Gets a string of all the capabilities the current user is missing that affected
75
+	 * the query
76
+	 *
77
+	 * @param EEM_Base $model
78
+	 * @param string   $model_context one of the return values from EEM_Base::valid_cap_contexts()
79
+	 * @return string
80
+	 */
81
+	public static function getMissingPermissionsString($model, $model_context = EEM_Base::caps_read)
82
+	{
83
+		return implode(',', array_keys(self::getMissingPermissions($model, $model_context)));
84
+	}
85 85
 
86
-    /**
87
-     * "Removes" password-protected fields. Currently that means setting their values to their default.
88
-     * @since 4.9.74.p
89
-     * @param array $entity
90
-     * @param EEM_Base $model
91
-     * @param ModelVersionInfo $model_version_info
92
-     * @return array
93
-     * @throws EE_Error
94
-     */
95
-    public static function filterOutPasswordProtectedFields(
96
-        $entity,
97
-        EEM_Base $model,
98
-        ModelVersionInfo $model_version_info
99
-    ) {
100
-        $has_password = $model->hasPassword();
101
-        if ($has_password) {
102
-            $entity[ $model->getPasswordField()->get_name() ] = ModelDataTranslator::prepareFieldValueForJson(
103
-                $model->getPasswordField(),
104
-                $model->getPasswordField()->get_default_value(),
105
-                $model_version_info->requestedVersion()
106
-            );
107
-        }
108
-        foreach ($model->field_settings() as $field_name => $field_obj) {
109
-            if (
110
-                $has_password
111
-                && $model->getPasswordField()->fieldIsProtected($field_name)
112
-                && $entity[ $field_name ]
113
-            ) {
114
-                $replacement_value = ModelDataTranslator::prepareFieldValueForJson(
115
-                    $field_obj,
116
-                    $field_obj->get_default_value(),
117
-                    $model_version_info->requestedVersion()
118
-                );
119
-                if ($model_version_info->fieldHasRenderedFormat($field_obj)) {
120
-                    $entity[ $field_name ]['rendered'] = $replacement_value;
121
-                } elseif ($model_version_info->fieldHasPrettyFormat($field_obj)) {
122
-                    $entity[ $field_name ]['raw'] = $replacement_value;
123
-                    $entity[ $field_name ]['pretty'] = ModelDataTranslator::prepareFieldValueForJson(
124
-                        $field_obj,
125
-                        $field_obj->prepare_for_pretty_echoing($field_obj->get_default_value()),
126
-                        $model_version_info->requestedVersion()
127
-                    );
128
-                } else {
129
-                    // this is most likely an excerpt field. (These should have also had "rendered" and "raw"
130
-                    // versions, but we missed that, and can't change it without breaking backward compatibility)
131
-                    // so just remove it (or rather, set its default)
132
-                    // API clients will just need to look to fields with rendered formats to know if these have
133
-                    // been redacted. Sorry.
134
-                    $entity[ $field_name ] = $replacement_value;
135
-                }
136
-            }
137
-        }
138
-        return $entity;
139
-    }
86
+	/**
87
+	 * "Removes" password-protected fields. Currently that means setting their values to their default.
88
+	 * @since 4.9.74.p
89
+	 * @param array $entity
90
+	 * @param EEM_Base $model
91
+	 * @param ModelVersionInfo $model_version_info
92
+	 * @return array
93
+	 * @throws EE_Error
94
+	 */
95
+	public static function filterOutPasswordProtectedFields(
96
+		$entity,
97
+		EEM_Base $model,
98
+		ModelVersionInfo $model_version_info
99
+	) {
100
+		$has_password = $model->hasPassword();
101
+		if ($has_password) {
102
+			$entity[ $model->getPasswordField()->get_name() ] = ModelDataTranslator::prepareFieldValueForJson(
103
+				$model->getPasswordField(),
104
+				$model->getPasswordField()->get_default_value(),
105
+				$model_version_info->requestedVersion()
106
+			);
107
+		}
108
+		foreach ($model->field_settings() as $field_name => $field_obj) {
109
+			if (
110
+				$has_password
111
+				&& $model->getPasswordField()->fieldIsProtected($field_name)
112
+				&& $entity[ $field_name ]
113
+			) {
114
+				$replacement_value = ModelDataTranslator::prepareFieldValueForJson(
115
+					$field_obj,
116
+					$field_obj->get_default_value(),
117
+					$model_version_info->requestedVersion()
118
+				);
119
+				if ($model_version_info->fieldHasRenderedFormat($field_obj)) {
120
+					$entity[ $field_name ]['rendered'] = $replacement_value;
121
+				} elseif ($model_version_info->fieldHasPrettyFormat($field_obj)) {
122
+					$entity[ $field_name ]['raw'] = $replacement_value;
123
+					$entity[ $field_name ]['pretty'] = ModelDataTranslator::prepareFieldValueForJson(
124
+						$field_obj,
125
+						$field_obj->prepare_for_pretty_echoing($field_obj->get_default_value()),
126
+						$model_version_info->requestedVersion()
127
+					);
128
+				} else {
129
+					// this is most likely an excerpt field. (These should have also had "rendered" and "raw"
130
+					// versions, but we missed that, and can't change it without breaking backward compatibility)
131
+					// so just remove it (or rather, set its default)
132
+					// API clients will just need to look to fields with rendered formats to know if these have
133
+					// been redacted. Sorry.
134
+					$entity[ $field_name ] = $replacement_value;
135
+				}
136
+			}
137
+		}
138
+		return $entity;
139
+	}
140 140
 
141 141
 
142
-    /**
143
-     * Takes a entity that's ready to be returned and removes fields which the user shouldn't be able to access.
144
-     *
145
-     * @param array $entity
146
-     * @param EEM_Base $model
147
-     * @param string $request_type one of the return values from EEM_Base::valid_cap_contexts()
148
-     * @param ModelVersionInfo $model_version_info
149
-     * @param string $primary_key_string result of EEM_Base::get_index_primary_key_string(), so that we can
150
-     *                                               use this with models that have no primary key
151
-     * @return array ready for converting into json
152
-     */
153
-    public static function filterOutInaccessibleEntityFields(
154
-        $entity,
155
-        $model,
156
-        $request_type,
157
-        $model_version_info,
158
-        $primary_key_string = null
159
-    ) {
160
-        foreach ($model->field_settings() as $field_name => $field_obj) {
161
-            if (
162
-                $model_version_info->fieldHasRenderedFormat($field_obj)
163
-                && isset($entity[ $field_name ])
164
-                && is_array($entity[ $field_name ])
165
-                && isset($entity[ $field_name ]['raw'])
166
-            ) {
167
-                unset($entity[ $field_name ]['raw']);
168
-            }
169
-        }
170
-        // theoretically we may want to filter out specific fields for specific models
171
-        return apply_filters(
172
-            'FHEE__Capabilities__filter_out_inaccessible_entity_fields',
173
-            $entity,
174
-            $model,
175
-            $request_type
176
-        );
177
-    }
142
+	/**
143
+	 * Takes a entity that's ready to be returned and removes fields which the user shouldn't be able to access.
144
+	 *
145
+	 * @param array $entity
146
+	 * @param EEM_Base $model
147
+	 * @param string $request_type one of the return values from EEM_Base::valid_cap_contexts()
148
+	 * @param ModelVersionInfo $model_version_info
149
+	 * @param string $primary_key_string result of EEM_Base::get_index_primary_key_string(), so that we can
150
+	 *                                               use this with models that have no primary key
151
+	 * @return array ready for converting into json
152
+	 */
153
+	public static function filterOutInaccessibleEntityFields(
154
+		$entity,
155
+		$model,
156
+		$request_type,
157
+		$model_version_info,
158
+		$primary_key_string = null
159
+	) {
160
+		foreach ($model->field_settings() as $field_name => $field_obj) {
161
+			if (
162
+				$model_version_info->fieldHasRenderedFormat($field_obj)
163
+				&& isset($entity[ $field_name ])
164
+				&& is_array($entity[ $field_name ])
165
+				&& isset($entity[ $field_name ]['raw'])
166
+			) {
167
+				unset($entity[ $field_name ]['raw']);
168
+			}
169
+		}
170
+		// theoretically we may want to filter out specific fields for specific models
171
+		return apply_filters(
172
+			'FHEE__Capabilities__filter_out_inaccessible_entity_fields',
173
+			$entity,
174
+			$model,
175
+			$request_type
176
+		);
177
+	}
178 178
 
179 179
 
180
-    /**
181
-     * Verifies the current user has at least partial access to do this action on this model.
182
-     * If not, throws an exception (so we can define the code that sets up this error object
183
-     * once)
184
-     *
185
-     * @param EEM_Base $model
186
-     * @param string   $model_action_context
187
-     * @param string   $action_name
188
-     * @return void
189
-     * @throws RestException
190
-     */
191
-    public static function verifyAtLeastPartialAccessTo($model, $model_action_context, $action_name = 'list')
192
-    {
193
-        if (! Capabilities::currentUserHasPartialAccessTo($model, $model_action_context)) {
194
-            $model_name_plural = EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
195
-            throw new RestException(
196
-                sprintf('rest_cannot_%s_%s', strtolower($action_name), $model_name_plural),
197
-                sprintf(
198
-                    esc_html__('Sorry, you are not allowed to %1$s %2$s. Missing permissions: %3$s', 'event_espresso'),
199
-                    $action_name,
200
-                    $model_name_plural,
201
-                    Capabilities::getMissingPermissionsString($model, $model_action_context)
202
-                ),
203
-                array('status' => 403)
204
-            );
205
-        }
206
-    }
180
+	/**
181
+	 * Verifies the current user has at least partial access to do this action on this model.
182
+	 * If not, throws an exception (so we can define the code that sets up this error object
183
+	 * once)
184
+	 *
185
+	 * @param EEM_Base $model
186
+	 * @param string   $model_action_context
187
+	 * @param string   $action_name
188
+	 * @return void
189
+	 * @throws RestException
190
+	 */
191
+	public static function verifyAtLeastPartialAccessTo($model, $model_action_context, $action_name = 'list')
192
+	{
193
+		if (! Capabilities::currentUserHasPartialAccessTo($model, $model_action_context)) {
194
+			$model_name_plural = EEH_Inflector::pluralize_and_lower($model->get_this_model_name());
195
+			throw new RestException(
196
+				sprintf('rest_cannot_%s_%s', strtolower($action_name), $model_name_plural),
197
+				sprintf(
198
+					esc_html__('Sorry, you are not allowed to %1$s %2$s. Missing permissions: %3$s', 'event_espresso'),
199
+					$action_name,
200
+					$model_name_plural,
201
+					Capabilities::getMissingPermissionsString($model, $model_action_context)
202
+				),
203
+				array('status' => 403)
204
+			);
205
+		}
206
+	}
207 207
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/RestIncomingQueryParamMetadata.php 2 patches
Indentation   +701 added lines, -701 removed lines patch added patch discarded remove patch
@@ -28,707 +28,707 @@
 block discarded – undo
28 28
  */
29 29
 class RestIncomingQueryParamMetadata
30 30
 {
31
-    private $query_param_key;
32
-    private $query_param_value;
33
-    /**
34
-     * @var RestIncomingQueryParamContext
35
-     */
36
-    private $context;
37
-
38
-    /**
39
-     * @var EE_Model_Field_Base|null
40
-     */
41
-    private $field;
42
-
43
-    /**
44
-     * @var string same as $query_param_key but has the * and anything after it removed
45
-     */
46
-    private $query_param_key_sans_stars;
47
-
48
-    /**
49
-     * @var string for timezone or timezone offset
50
-     */
51
-    private $timezone;
52
-
53
-    /**
54
-     * @var boolean if the field in $query_param_key is for a GMT field (eg `EVT_modified_gmt`)
55
-     */
56
-    private $is_gmt_field = false;
57
-
58
-    /**
59
-     * RestIncomingQueryParamMetadata constructor.
60
-     * You probably want to call
61
-     * @param string $query_param_key
62
-     * @param string $query_param_value
63
-     * @param RestIncomingQueryParamContext $context
64
-     */
65
-    public function __construct($query_param_key, $query_param_value, RestIncomingQueryParamContext $context)
66
-    {
67
-        $this->query_param_key = $query_param_key;
68
-        $this->query_param_value = $query_param_value;
69
-        $this->context = $context;
70
-        $this->determineFieldAndTimezone();
71
-    }
72
-
73
-    /**
74
-     * Gets the query parameter key. This may have been modified (see setQueryParamValue())
75
-     * @return string
76
-     */
77
-    public function getQueryParamKey()
78
-    {
79
-        return $this->query_param_key;
80
-    }
81
-
82
-    /**
83
-     * Modifies the query parameter key passed in (Eg this is done when rewriting the simplified specified operator REST
84
-     * query parameters into the legacy structure)
85
-     * @param string|array|int|float $query_param_value
86
-     */
87
-    private function setQueryParamValue($query_param_value)
88
-    {
89
-        $this->query_param_value = $query_param_value;
90
-    }
91
-
92
-    /**
93
-     * Gets the original query parameter value passed in.
94
-     * @return string
95
-     */
96
-    public function getQueryParamValue()
97
-    {
98
-        return $this->query_param_value;
99
-    }
100
-
101
-    /**
102
-     * Gets the context object.
103
-     * @return RestIncomingQueryParamContext
104
-     */
105
-    public function getContext()
106
-    {
107
-        return $this->context;
108
-    }
109
-
110
-    /**
111
-     * Sets the query parameter key. This may be used to rewrite a key into its non-GMT alternative.
112
-     * @param string $query_param_key
113
-     */
114
-    private function setQueryParamKey($query_param_key)
115
-    {
116
-        $this->query_param_key = $query_param_key;
117
-    }
118
-
119
-    /**
120
-     * Gets the field the query parameter key indicated. This may be null (in cases where the query parameter key
121
-     * did not indicate a field, eg if it were `OR`).
122
-     * @return EE_Model_Field_Base|null
123
-     */
124
-    public function getField()
125
-    {
126
-        return $this->field;
127
-    }
128
-
129
-    /**
130
-     * Gets the query parameter key (with the star and everything afterwards removed).
131
-     * @return string
132
-     */
133
-    public function getQueryParamKeySansStars()
134
-    {
135
-        return $this->query_param_key_sans_stars;
136
-    }
137
-
138
-    /**
139
-     * Gets the timezone associated with this model (the site timezone, except for GMT datetime fields).
140
-     * @return string
141
-     */
142
-    public function getTimezone()
143
-    {
144
-        return $this->timezone;
145
-    }
146
-
147
-    /**
148
-     * Returns whether or not this is a GMT field
149
-     * @return boolean
150
-     */
151
-    public function isGmtField()
152
-    {
153
-        return $this->is_gmt_field;
154
-    }
155
-
156
-    /**
157
-     * Sets the field indicated by the query parameter key (might be null).
158
-     * @param EE_Model_Field_Base|null $field
159
-     */
160
-    private function setField(EE_Model_Field_Base $field = null)
161
-    {
162
-        $this->field = $field;
163
-    }
164
-
165
-    /**
166
-     * Sets the query parameter key-with-stars-removed.
167
-     * @param string $query_param_key_sans_stars
168
-     */
169
-    private function setQueryParamKeySansStars($query_param_key_sans_stars)
170
-    {
171
-        $this->query_param_key_sans_stars = $query_param_key_sans_stars;
172
-    }
173
-
174
-    /**
175
-     * Sets the timezone (this could be a timezeon offset string).
176
-     * @param string $timezone
177
-     */
178
-    private function setTimezone($timezone)
179
-    {
180
-        $this->timezone = $timezone;
181
-    }
182
-
183
-    /**
184
-     * @param mixed $is_gmt_field
185
-     */
186
-    private function setIsGmtField($is_gmt_field)
187
-    {
188
-        $this->is_gmt_field = $is_gmt_field;
189
-    }
190
-
191
-    /**
192
-     * Determines what field, query param name, and query param name without stars, and timezone to use.
193
-     * @since 4.9.72.p
194
-     * @type EE_Model_Field_Base $field
195
-     * @return void {
196
-     * @throws EE_Error
197
-     * @throws InvalidDataTypeException
198
-     * @throws InvalidInterfaceException
199
-     * @throws InvalidArgumentException
200
-     */
201
-    private function determineFieldAndTimezone()
202
-    {
203
-        $this->setQueryParamKeySansStars(ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey(
204
-            $this->getQueryParamKey()
205
-        ));
206
-        $this->setField(ModelDataTranslator::deduceFieldFromQueryParam(
207
-            $this->getQueryParamKeySansStars(),
208
-            $this->getContext()->getModel()
209
-        ));
210
-        // double-check is it a *_gmt field?
211
-        if (
212
-            !$this->getField() instanceof EE_Model_Field_Base
213
-            && ModelDataTranslator::isGmtDateFieldName($this->getQueryParamKeySansStars())
214
-        ) {
215
-            // yep, take off '_gmt', and find the field
216
-            $this->setQueryParamKey(ModelDataTranslator::removeGmtFromFieldName($this->getQueryParamKeySansStars()));
217
-            $this->setField(ModelDataTranslator::deduceFieldFromQueryParam(
218
-                $this->getQueryParamKey(),
219
-                $this->context->getModel()
220
-            ));
221
-            $this->setTimezone('UTC');
222
-            $this->setIsGmtField(true);
223
-        } elseif ($this->getField() instanceof EE_Datetime_Field) {
224
-            // so it's not a GMT field. Set the timezone on the model to the default
225
-            $this->setTimezone(EEH_DTT_Helper::get_valid_timezone_string());
226
-        } else {
227
-            // just keep using what's already set for the timezone
228
-            $this->setTimezone($this->context->getModel()->get_timezone());
229
-        }
230
-        $this->assertOnlyAdminCanReadPasswordFields();
231
-    }
232
-
233
-    /**
234
-     * Throws an exception if a non-admin is trying to query by password.
235
-     * @since 4.9.74.p
236
-     * @throws RestException
237
-     */
238
-    private function assertOnlyAdminCanReadPasswordFields()
239
-    {
240
-        if (
241
-            $this->getField() instanceof EE_Password_Field
242
-            && ! current_user_can(EE_Restriction_Generator_Base::get_default_restrictions_cap())
243
-        ) {
244
-            // only full admins can query by password. sorry bub!
245
-            throw new RestException(
246
-                'only_admins_can_query_by_password',
247
-                // @codingStandardsIgnoreStart
248
-                esc_html__('You attempted to filter by a password field without the needed privileges. Only a full admin is allowed to do that.', 'event_espresso'),
249
-                // @codingStandardsIgnoreEnd
250
-                array(
251
-                    'status' => 403
252
-                )
253
-            );
254
-        }
255
-    }
256
-
257
-    /**
258
-     * Given a ton of input, determines the value to use for the models.
259
-     * @since 4.9.72.p
260
-     * @return array|null
261
-     * @throws DomainException
262
-     * @throws EE_Error
263
-     * @throws RestException
264
-     * @throws DomainException
265
-     */
266
-    public function determineConditionsQueryParameterValue()
267
-    {
268
-        if ($this->valueIsArrayDuringRead()) {
269
-            return $this->determineModelValueGivenRestInputArray();
270
-        }
271
-        return ModelDataTranslator::prepareFieldValueFromJson(
272
-            $this->getField(),
273
-            $this->getQueryParamValue(),
274
-            $this->getContext()->getRequestedVersion(),
275
-            $this->getTimezone()
276
-        );
277
-    }
278
-
279
-    /**
280
-     * Given that the array value provided was itself an array, handles finding the correct value to pass to the model.
281
-     * @since 4.9.72.p
282
-     * @return array|null
283
-     * @throws RestException
284
-     */
285
-    private function determineModelValueGivenRestInputArray()
286
-    {
287
-        $this->transformSimplifiedSpecifiedOperatorSyntaxIntoStandardSyntax();
288
-        // did they specify an operator?
289
-        if ($this->valueIsLegacySpecifiedOperator()) {
290
-            $query_param_value = $this->getQueryParamValue();
291
-            $sub_array_key = $query_param_value[0];
292
-            $translated_value = array($sub_array_key);
293
-            if ($this->operatorIsNAry($sub_array_key)) {
294
-                $translated_value[] = $this->prepareValuesFromJson($query_param_value[1]);
295
-            } elseif ($this->operatorIsTernary($sub_array_key)) {
296
-                $translated_value[] = array(
297
-                    $this->prepareValuesFromJson($query_param_value[1][0]),
298
-                    $this->prepareValuesFromJson($query_param_value[1][1])
299
-                );
300
-            } elseif ($this->operatorIsLike($sub_array_key)) {
301
-                // we want to leave this value mostly-as-is (eg don't force it to be a float
302
-                // or a boolean or an enum value. Leave it as-is with wildcards etc)
303
-                // but do verify it at least doesn't have any serialized data
304
-                ModelDataTranslator::throwExceptionIfContainsSerializedData($query_param_value[1]);
305
-                $translated_value[] = $query_param_value[1];
306
-            } elseif ($this->operatorIsUnary($sub_array_key)) {
307
-                // no arguments should have been provided, so don't look for any
308
-            } elseif ($this->operatorisBinary($sub_array_key)) {
309
-                // it's a valid operator, but none of the exceptions. Treat it normally.
310
-                $translated_value[] = $this->prepareValuesFromJson($query_param_value[1]);
311
-            } else {
312
-                // so they provided a valid operator, but wrong number of arguments
313
-                $this->throwWrongNumberOfArgsExceptionIfDebugging($sub_array_key);
314
-                $translated_value = null;
315
-            }
316
-        } else {
317
-            // so they didn't provide a valid operator
318
-            // if we aren't in debug mode, then just try our best to fulfill the user's request
319
-            $this->throwInvalidOperatorExceptionIfDebugging();
320
-            $translated_value = null;
321
-        }
322
-        return $translated_value;
323
-    }
324
-
325
-    /**
326
-     * Returns if this request is a "read" request and the value provided was an array.
327
-     * This will indicate is such things as `array('<', 123)` and `array('IN', array(1,2,3))` are acceptable or not.
328
-     * @since 4.9.72.p
329
-     * @return boolean
330
-     */
331
-    private function valueIsArrayDuringRead()
332
-    {
333
-        return !$this->getContext()->isWriting() && is_array($this->getQueryParamValue());
334
-    }
335
-
336
-    /**
337
-     * Returns if the value provided was an associative array (we should have already verified it's an array of some
338
-     * sort). If the value is an associative array, it had better be in the simplified specified operator structure.
339
-     * @since 4.9.72.p
340
-     * @return boolean
341
-     */
342
-    private function valueIsAssociativeArray()
343
-    {
344
-        return !EEH_Array::is_array_numerically_and_sequentially_indexed($this->getQueryParamValue());
345
-    }
346
-
347
-    /**
348
-     * Checks if the array value is itself an array that fits into the simplified specified operator structure
349
-     * (eg `array('!=' => 123)`).
350
-     * @since 4.9.72.p
351
-     * @return boolean
352
-     */
353
-    private function valueIsSimplifiedSpecifiedOperator()
354
-    {
355
-        return count($this->getQueryParamValue()) === 1
356
-            && array_key_exists(
357
-                key($this->getQueryParamValue()),
358
-                $this->getContext()->getModel()->valid_operators()
359
-            );
360
-    }
361
-
362
-    /**
363
-     * Throws an exception if the sub-value is an array (eg `array('!=' => array())`). It needs to just be a string,
364
-     * of either comma-separated-values, or a JSON array.
365
-     * @since 4.9.72.p
366
-     * @param $sub_array_key
367
-     * @param $sub_array_value
368
-     * @throws RestException
369
-     */
370
-    private function assertSubValueIsntArray($sub_array_key, $sub_array_value)
371
-    {
372
-        if (is_array($sub_array_value) && EED_Core_Rest_Api::debugMode()) {
373
-            throw new RestException(
374
-                'csv_or_json_string_only',
375
-                sprintf(
376
-                    /* translators: 1: variable name*/
377
-                    esc_html__(
378
-                        'The value provided for the operator "%1$s" should be comma-separated value string or a JSON array.',
379
-                        'event_espresso'
380
-                    ),
381
-                    $sub_array_key
382
-                ),
383
-                array(
384
-                    'status' => 400,
385
-                )
386
-            );
387
-        }
388
-    }
389
-
390
-    /**
391
-     * Determines if the sub-array key is an operator taking 3 or more operators.
392
-     * @since 4.9.72.p
393
-     * @param $sub_array_key
394
-     * @return boolean
395
-     */
396
-    private function subArrayKeyIsNonBinaryOperator($sub_array_key)
397
-    {
398
-        return array_key_exists(
399
-            $sub_array_key,
400
-            array_merge(
401
-                $this->getContext()->getModel()->valid_in_style_operators(),
402
-                $this->getContext()->getModel()->valid_between_style_operators()
403
-            )
404
-        );
405
-    }
406
-
407
-    /**
408
-     * Given that the $sub_array_key is a string, checks if it's an operator taking only 1 argument.
409
-     * @since 4.9.72.p
410
-     * @param string $sub_array_key
411
-     * @return boolean
412
-     */
413
-    private function subArrayKeyIsUnaryOperator($sub_array_key)
414
-    {
415
-        return array_key_exists(
416
-            $sub_array_key,
417
-            $this->getContext()->getModel()->valid_null_style_operators()
418
-        );
419
-    }
420
-
421
-    /**
422
-     * Parses the $sub_array_value string into an array (given it could either be a comma-separated-list or a JSON
423
-     * array). eg `"1,2,3"` or `"[1,2,3]"` into `array(1,2,3)`.
424
-     * @since 4.9.72.p
425
-     * @param $sub_array_value
426
-     * @return array|mixed|object
427
-     */
428
-    private function extractQuickStyleSpecifiedOperatorValue($sub_array_value)
429
-    {
430
-        // the value should be JSON or CSV
431
-        $values = json_decode($sub_array_value);
432
-        if (!is_array($values)) {
433
-            $values = array_filter(
434
-                array_map(
435
-                    'trim',
436
-                    explode(
437
-                        ',',
438
-                        $sub_array_value
439
-                    )
440
-                )
441
-            );
442
-        }
443
-        return $values;
444
-    }
445
-
446
-    /**
447
-     * Throws an exception if the value isn't a simplified specified operator (only called when we expect that).
448
-     * @since 4.9.72.p
449
-     * @throws RestException
450
-     */
451
-    private function assertSimplifiedSpecifiedOperator()
452
-    {
453
-        if (!$this->valueIsSimplifiedSpecifiedOperator() && EED_Core_Rest_Api::debugMode()) {
454
-            throw new RestException(
455
-                'numerically_indexed_array_of_values_only',
456
-                sprintf(
457
-                    /* translators: 1: variable name*/
458
-                    esc_html__(
459
-                        'The array provided for the parameter "%1$s" should be numerically indexed.',
460
-                        'event_espresso'
461
-                    ),
462
-                    $this->getQueryParamKey()
463
-                ),
464
-                array(
465
-                    'status' => 400,
466
-                )
467
-            );
468
-        }
469
-    }
470
-
471
-    /**
472
-     * If query_param_value were in the simplified specific operator structure, change it into the legacy structure.
473
-     * @since 4.9.72.p
474
-     * @throws RestException
475
-     */
476
-    private function transformSimplifiedSpecifiedOperatorSyntaxIntoStandardSyntax()
477
-    {
478
-        if ($this->valueIsAssociativeArray()) {
479
-            $this->assertSimplifiedSpecifiedOperator();
480
-            $query_param_value = $this->getQueryParamValue();
481
-            $sub_array_value = reset($query_param_value);
482
-            $sub_array_key = key($query_param_value);
483
-            $this->assertSubValueIsntArray($sub_array_key, $sub_array_value);
484
-            // they're doing something like "&where[EVT_ID][IN]=1,2,3" or "&where[EVT_ID][>]=5"
485
-            if ($this->subArrayKeyIsNonBinaryOperator($sub_array_key)) {
486
-                $this->setQueryParamValue(array(
487
-                    $sub_array_key,
488
-                    $this->extractQuickStyleSpecifiedOperatorValue($sub_array_value)
489
-                ));
490
-            } elseif ($this->subArrayKeyIsUnaryOperator($sub_array_key)) {
491
-                $this->setQueryParamValue(array($sub_array_key));
492
-            } else {
493
-                $this->setQueryParamValue(array($sub_array_key, $sub_array_value));
494
-            }
495
-        }
496
-    }
497
-
498
-    /**
499
-     * Returns true is the value is an array using the legacy structure to specify the operator. Eg `array('!=',123)`.
500
-     * @since 4.9.72.p
501
-     * @return boolean
502
-     */
503
-    private function valueIsLegacySpecifiedOperator()
504
-    {
505
-        $valid_operators = $this->getContext()->getModel()->valid_operators();
506
-        $query_param_value = $this->getQueryParamValue();
507
-        return isset($query_param_value[0])
508
-            && isset($valid_operators[ $query_param_value[0] ]);
509
-    }
510
-
511
-    /**
512
-     * Returns true if the value specified operator accepts arbitrary number of arguments, like "IN".
513
-     * @since 4.9.72.p
514
-     * @param $operator
515
-     * @return boolean
516
-     */
517
-    private function operatorIsNAry($operator)
518
-    {
519
-        $valueArray = $this->getQueryParamValue();
520
-        return array_key_exists(
521
-            $operator,
522
-            $this->getContext()->getModel()->valid_in_style_operators()
523
-        )
524
-            && isset($valueArray[1])
525
-            && is_array($valueArray[1])
526
-            && !isset($valueArray[2]);
527
-    }
528
-
529
-    /**
530
-     * Returns true if the operator accepts 3 arguments (eg "BETWEEN").
531
-     * So we're looking for a value that looks like
532
-     * `array('BETWEEN', array('2015-01-01T00:00:00', '2016-01-01T00:00:00'))`.
533
-     * @since 4.9.72.p
534
-     * @param $operator
535
-     * @return boolean
536
-     */
537
-    private function operatorIsTernary($operator)
538
-    {
539
-        $query_param_value = $this->getQueryParamValue();
540
-        return array_key_exists($operator, $this->getContext()->getModel()->valid_between_style_operators())
541
-            && isset($query_param_value[1])
542
-            && is_array($query_param_value[1])
543
-            && isset($query_param_value[1][0], $query_param_value[1][1])
544
-            && !isset($query_param_value[1][2])
545
-            && !isset($query_param_value[2]);
546
-    }
547
-
548
-    /**
549
-     * Returns true if the operator is a similar to LIKE, indicating the value may have wildcards we should leave alone.
550
-     * @since 4.9.72.p
551
-     * @param $operator
552
-     * @return boolean
553
-     */
554
-    private function operatorIsLike($operator)
555
-    {
556
-        $query_param_value = $this->getQueryParamValue();
557
-        return array_key_exists($operator, $this->getContext()->getModel()->valid_like_style_operators())
558
-            && isset($query_param_value[1])
559
-            && !isset($query_param_value[2]);
560
-    }
561
-
562
-    /**
563
-     * Returns true if the operator only takes one argument (eg it's like `IS NULL`).
564
-     * @since 4.9.72.p
565
-     * @param $operator
566
-     * @return boolean
567
-     */
568
-    private function operatorIsUnary($operator)
569
-    {
570
-        $query_param_value = $this->getQueryParamValue();
571
-        return array_key_exists($operator, $this->getContext()->getModel()->valid_null_style_operators())
572
-            && !isset($query_param_value[1]);
573
-    }
574
-
575
-    /**
576
-     * Returns true if the operator specified is a binary opeator (eg `=`, `!=`)
577
-     * @since 4.9.72.p
578
-     * @param $operator
579
-     * @return boolean
580
-     */
581
-    private function operatorisBinary($operator)
582
-    {
583
-        $query_param_value = $this->getQueryParamValue();
584
-        $model = $this->getContext()->getModel();
585
-        return isset($query_param_value[1])
586
-            && !isset($query_param_value[2])
587
-            && !array_key_exists(
588
-                $operator,
589
-                array_merge(
590
-                    $model->valid_in_style_operators(),
591
-                    $model->valid_null_style_operators(),
592
-                    $model->valid_like_style_operators(),
593
-                    $model->valid_between_style_operators()
594
-                )
595
-            );
596
-    }
597
-
598
-    /**
599
-     * If we're debugging, throws an exception saying that the wrong number of arguments was provided.
600
-     * @since 4.9.72.p
601
-     * @param $operator
602
-     * @throws RestException
603
-     */
604
-    private function throwWrongNumberOfArgsExceptionIfDebugging($operator)
605
-    {
606
-        if (EED_Core_Rest_Api::debugMode()) {
607
-            throw new RestException(
608
-                'wrong_number_of_arguments',
609
-                sprintf(
610
-                    esc_html__(
611
-                        'The operator you provided, "%1$s" had the wrong number of arguments',
612
-                        'event_espresso'
613
-                    ),
614
-                    $operator
615
-                ),
616
-                array(
617
-                    'status' => 400,
618
-                )
619
-            );
620
-        }
621
-    }
622
-
623
-    /**
624
-     * Wrapper for ModelDataTranslator::prepareFieldValuesFromJson(), just a tad more DRY.
625
-     * @since 4.9.72.p
626
-     * @param $value
627
-     * @return mixed
628
-     * @throws RestException
629
-     */
630
-    private function prepareValuesFromJson($value)
631
-    {
632
-        return ModelDataTranslator::prepareFieldValuesFromJson(
633
-            $this->getField(),
634
-            $value,
635
-            $this->getContext()->getRequestedVersion(),
636
-            $this->getTimezone()
637
-        );
638
-    }
639
-
640
-    /**
641
-     * Throws an exception if an invalid operator was specified and we're debugging.
642
-     * @since 4.9.72.p
643
-     * @throws RestException
644
-     */
645
-    private function throwInvalidOperatorExceptionIfDebugging()
646
-    {
647
-        // so they didn't provide a valid operator
648
-        if (EED_Core_Rest_Api::debugMode()) {
649
-            throw new RestException(
650
-                'invalid_operator',
651
-                sprintf(
652
-                    esc_html__(
653
-                        'You provided an invalid parameter, with key "%1$s" and value "%2$s"',
654
-                        'event_espresso'
655
-                    ),
656
-                    $this->getQueryParamKey(),
657
-                    $this->getQueryParamValue()
658
-                ),
659
-                array(
660
-                    'status' => 400,
661
-                )
662
-            );
663
-        }
664
-    }
665
-
666
-    /**
667
-     * Returns true if the query_param_key was a logic query parameter, eg `OR`, `AND`, `NOT`, `OR*`, etc.
668
-     * @since 4.9.72.p
669
-     * @return boolean
670
-     */
671
-    private function isLogicQueryParam()
672
-    {
673
-        return in_array($this->getQueryParamKeySansStars(), $this->getContext()->getModel()->logic_query_param_keys());
674
-    }
675
-
676
-
677
-    /**
678
-     * If the query param isn't for a field, it must be a nested query parameter which requires different logic.
679
-     * @since 4.9.72.p
680
-     * @return array
681
-     * @throws DomainException
682
-     * @throws EE_Error
683
-     * @throws RestException
684
-     * @throws InvalidDataTypeException
685
-     * @throws InvalidInterfaceException
686
-     * @throws InvalidArgumentException
687
-     */
688
-    public function determineNestedConditionQueryParameters()
689
-    {
690
-
691
-        // so this param doesn't correspond to a field eh?
692
-        if ($this->getContext()->isWriting()) {
693
-            // always tell API clients about invalid parameters when they're creating data. Otherwise,
694
-            // they are probably going to create invalid data
695
-            throw new RestException(
696
-                'invalid_field',
697
-                sprintf(
698
-                    /* translators: 1: variable name */
699
-                    esc_html__('You have provided an invalid parameter: "%1$s"', 'event_espresso'),
700
-                    $this->getQueryParamKey()
701
-                )
702
-            );
703
-        }
704
-        // so it's not for a field, is it a logic query param key?
705
-        if ($this->isLogicQueryParam()) {
706
-            return ModelDataTranslator::prepareConditionsQueryParamsForModels(
707
-                $this->getQueryParamValue(),
708
-                $this->getContext()->getModel(),
709
-                $this->getContext()->getRequestedVersion()
710
-            );
711
-        }
712
-        if (EED_Core_Rest_Api::debugMode()) {
713
-            // only tell API clients they got it wrong if we're in debug mode
714
-            // otherwise try our best ot fulfill their request by ignoring this invalid data
715
-            throw new RestException(
716
-                'invalid_parameter',
717
-                sprintf(
718
-                    /* translators: 1: variable name */
719
-                    esc_html__(
720
-                        'You provided an invalid parameter, with key "%1$s"',
721
-                        'event_espresso'
722
-                    ),
723
-                    $this->getQueryParamKey()
724
-                ),
725
-                array(
726
-                    'status' => 400,
727
-                )
728
-            );
729
-        }
730
-        return null;
731
-    }
31
+	private $query_param_key;
32
+	private $query_param_value;
33
+	/**
34
+	 * @var RestIncomingQueryParamContext
35
+	 */
36
+	private $context;
37
+
38
+	/**
39
+	 * @var EE_Model_Field_Base|null
40
+	 */
41
+	private $field;
42
+
43
+	/**
44
+	 * @var string same as $query_param_key but has the * and anything after it removed
45
+	 */
46
+	private $query_param_key_sans_stars;
47
+
48
+	/**
49
+	 * @var string for timezone or timezone offset
50
+	 */
51
+	private $timezone;
52
+
53
+	/**
54
+	 * @var boolean if the field in $query_param_key is for a GMT field (eg `EVT_modified_gmt`)
55
+	 */
56
+	private $is_gmt_field = false;
57
+
58
+	/**
59
+	 * RestIncomingQueryParamMetadata constructor.
60
+	 * You probably want to call
61
+	 * @param string $query_param_key
62
+	 * @param string $query_param_value
63
+	 * @param RestIncomingQueryParamContext $context
64
+	 */
65
+	public function __construct($query_param_key, $query_param_value, RestIncomingQueryParamContext $context)
66
+	{
67
+		$this->query_param_key = $query_param_key;
68
+		$this->query_param_value = $query_param_value;
69
+		$this->context = $context;
70
+		$this->determineFieldAndTimezone();
71
+	}
72
+
73
+	/**
74
+	 * Gets the query parameter key. This may have been modified (see setQueryParamValue())
75
+	 * @return string
76
+	 */
77
+	public function getQueryParamKey()
78
+	{
79
+		return $this->query_param_key;
80
+	}
81
+
82
+	/**
83
+	 * Modifies the query parameter key passed in (Eg this is done when rewriting the simplified specified operator REST
84
+	 * query parameters into the legacy structure)
85
+	 * @param string|array|int|float $query_param_value
86
+	 */
87
+	private function setQueryParamValue($query_param_value)
88
+	{
89
+		$this->query_param_value = $query_param_value;
90
+	}
91
+
92
+	/**
93
+	 * Gets the original query parameter value passed in.
94
+	 * @return string
95
+	 */
96
+	public function getQueryParamValue()
97
+	{
98
+		return $this->query_param_value;
99
+	}
100
+
101
+	/**
102
+	 * Gets the context object.
103
+	 * @return RestIncomingQueryParamContext
104
+	 */
105
+	public function getContext()
106
+	{
107
+		return $this->context;
108
+	}
109
+
110
+	/**
111
+	 * Sets the query parameter key. This may be used to rewrite a key into its non-GMT alternative.
112
+	 * @param string $query_param_key
113
+	 */
114
+	private function setQueryParamKey($query_param_key)
115
+	{
116
+		$this->query_param_key = $query_param_key;
117
+	}
118
+
119
+	/**
120
+	 * Gets the field the query parameter key indicated. This may be null (in cases where the query parameter key
121
+	 * did not indicate a field, eg if it were `OR`).
122
+	 * @return EE_Model_Field_Base|null
123
+	 */
124
+	public function getField()
125
+	{
126
+		return $this->field;
127
+	}
128
+
129
+	/**
130
+	 * Gets the query parameter key (with the star and everything afterwards removed).
131
+	 * @return string
132
+	 */
133
+	public function getQueryParamKeySansStars()
134
+	{
135
+		return $this->query_param_key_sans_stars;
136
+	}
137
+
138
+	/**
139
+	 * Gets the timezone associated with this model (the site timezone, except for GMT datetime fields).
140
+	 * @return string
141
+	 */
142
+	public function getTimezone()
143
+	{
144
+		return $this->timezone;
145
+	}
146
+
147
+	/**
148
+	 * Returns whether or not this is a GMT field
149
+	 * @return boolean
150
+	 */
151
+	public function isGmtField()
152
+	{
153
+		return $this->is_gmt_field;
154
+	}
155
+
156
+	/**
157
+	 * Sets the field indicated by the query parameter key (might be null).
158
+	 * @param EE_Model_Field_Base|null $field
159
+	 */
160
+	private function setField(EE_Model_Field_Base $field = null)
161
+	{
162
+		$this->field = $field;
163
+	}
164
+
165
+	/**
166
+	 * Sets the query parameter key-with-stars-removed.
167
+	 * @param string $query_param_key_sans_stars
168
+	 */
169
+	private function setQueryParamKeySansStars($query_param_key_sans_stars)
170
+	{
171
+		$this->query_param_key_sans_stars = $query_param_key_sans_stars;
172
+	}
173
+
174
+	/**
175
+	 * Sets the timezone (this could be a timezeon offset string).
176
+	 * @param string $timezone
177
+	 */
178
+	private function setTimezone($timezone)
179
+	{
180
+		$this->timezone = $timezone;
181
+	}
182
+
183
+	/**
184
+	 * @param mixed $is_gmt_field
185
+	 */
186
+	private function setIsGmtField($is_gmt_field)
187
+	{
188
+		$this->is_gmt_field = $is_gmt_field;
189
+	}
190
+
191
+	/**
192
+	 * Determines what field, query param name, and query param name without stars, and timezone to use.
193
+	 * @since 4.9.72.p
194
+	 * @type EE_Model_Field_Base $field
195
+	 * @return void {
196
+	 * @throws EE_Error
197
+	 * @throws InvalidDataTypeException
198
+	 * @throws InvalidInterfaceException
199
+	 * @throws InvalidArgumentException
200
+	 */
201
+	private function determineFieldAndTimezone()
202
+	{
203
+		$this->setQueryParamKeySansStars(ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey(
204
+			$this->getQueryParamKey()
205
+		));
206
+		$this->setField(ModelDataTranslator::deduceFieldFromQueryParam(
207
+			$this->getQueryParamKeySansStars(),
208
+			$this->getContext()->getModel()
209
+		));
210
+		// double-check is it a *_gmt field?
211
+		if (
212
+			!$this->getField() instanceof EE_Model_Field_Base
213
+			&& ModelDataTranslator::isGmtDateFieldName($this->getQueryParamKeySansStars())
214
+		) {
215
+			// yep, take off '_gmt', and find the field
216
+			$this->setQueryParamKey(ModelDataTranslator::removeGmtFromFieldName($this->getQueryParamKeySansStars()));
217
+			$this->setField(ModelDataTranslator::deduceFieldFromQueryParam(
218
+				$this->getQueryParamKey(),
219
+				$this->context->getModel()
220
+			));
221
+			$this->setTimezone('UTC');
222
+			$this->setIsGmtField(true);
223
+		} elseif ($this->getField() instanceof EE_Datetime_Field) {
224
+			// so it's not a GMT field. Set the timezone on the model to the default
225
+			$this->setTimezone(EEH_DTT_Helper::get_valid_timezone_string());
226
+		} else {
227
+			// just keep using what's already set for the timezone
228
+			$this->setTimezone($this->context->getModel()->get_timezone());
229
+		}
230
+		$this->assertOnlyAdminCanReadPasswordFields();
231
+	}
232
+
233
+	/**
234
+	 * Throws an exception if a non-admin is trying to query by password.
235
+	 * @since 4.9.74.p
236
+	 * @throws RestException
237
+	 */
238
+	private function assertOnlyAdminCanReadPasswordFields()
239
+	{
240
+		if (
241
+			$this->getField() instanceof EE_Password_Field
242
+			&& ! current_user_can(EE_Restriction_Generator_Base::get_default_restrictions_cap())
243
+		) {
244
+			// only full admins can query by password. sorry bub!
245
+			throw new RestException(
246
+				'only_admins_can_query_by_password',
247
+				// @codingStandardsIgnoreStart
248
+				esc_html__('You attempted to filter by a password field without the needed privileges. Only a full admin is allowed to do that.', 'event_espresso'),
249
+				// @codingStandardsIgnoreEnd
250
+				array(
251
+					'status' => 403
252
+				)
253
+			);
254
+		}
255
+	}
256
+
257
+	/**
258
+	 * Given a ton of input, determines the value to use for the models.
259
+	 * @since 4.9.72.p
260
+	 * @return array|null
261
+	 * @throws DomainException
262
+	 * @throws EE_Error
263
+	 * @throws RestException
264
+	 * @throws DomainException
265
+	 */
266
+	public function determineConditionsQueryParameterValue()
267
+	{
268
+		if ($this->valueIsArrayDuringRead()) {
269
+			return $this->determineModelValueGivenRestInputArray();
270
+		}
271
+		return ModelDataTranslator::prepareFieldValueFromJson(
272
+			$this->getField(),
273
+			$this->getQueryParamValue(),
274
+			$this->getContext()->getRequestedVersion(),
275
+			$this->getTimezone()
276
+		);
277
+	}
278
+
279
+	/**
280
+	 * Given that the array value provided was itself an array, handles finding the correct value to pass to the model.
281
+	 * @since 4.9.72.p
282
+	 * @return array|null
283
+	 * @throws RestException
284
+	 */
285
+	private function determineModelValueGivenRestInputArray()
286
+	{
287
+		$this->transformSimplifiedSpecifiedOperatorSyntaxIntoStandardSyntax();
288
+		// did they specify an operator?
289
+		if ($this->valueIsLegacySpecifiedOperator()) {
290
+			$query_param_value = $this->getQueryParamValue();
291
+			$sub_array_key = $query_param_value[0];
292
+			$translated_value = array($sub_array_key);
293
+			if ($this->operatorIsNAry($sub_array_key)) {
294
+				$translated_value[] = $this->prepareValuesFromJson($query_param_value[1]);
295
+			} elseif ($this->operatorIsTernary($sub_array_key)) {
296
+				$translated_value[] = array(
297
+					$this->prepareValuesFromJson($query_param_value[1][0]),
298
+					$this->prepareValuesFromJson($query_param_value[1][1])
299
+				);
300
+			} elseif ($this->operatorIsLike($sub_array_key)) {
301
+				// we want to leave this value mostly-as-is (eg don't force it to be a float
302
+				// or a boolean or an enum value. Leave it as-is with wildcards etc)
303
+				// but do verify it at least doesn't have any serialized data
304
+				ModelDataTranslator::throwExceptionIfContainsSerializedData($query_param_value[1]);
305
+				$translated_value[] = $query_param_value[1];
306
+			} elseif ($this->operatorIsUnary($sub_array_key)) {
307
+				// no arguments should have been provided, so don't look for any
308
+			} elseif ($this->operatorisBinary($sub_array_key)) {
309
+				// it's a valid operator, but none of the exceptions. Treat it normally.
310
+				$translated_value[] = $this->prepareValuesFromJson($query_param_value[1]);
311
+			} else {
312
+				// so they provided a valid operator, but wrong number of arguments
313
+				$this->throwWrongNumberOfArgsExceptionIfDebugging($sub_array_key);
314
+				$translated_value = null;
315
+			}
316
+		} else {
317
+			// so they didn't provide a valid operator
318
+			// if we aren't in debug mode, then just try our best to fulfill the user's request
319
+			$this->throwInvalidOperatorExceptionIfDebugging();
320
+			$translated_value = null;
321
+		}
322
+		return $translated_value;
323
+	}
324
+
325
+	/**
326
+	 * Returns if this request is a "read" request and the value provided was an array.
327
+	 * This will indicate is such things as `array('<', 123)` and `array('IN', array(1,2,3))` are acceptable or not.
328
+	 * @since 4.9.72.p
329
+	 * @return boolean
330
+	 */
331
+	private function valueIsArrayDuringRead()
332
+	{
333
+		return !$this->getContext()->isWriting() && is_array($this->getQueryParamValue());
334
+	}
335
+
336
+	/**
337
+	 * Returns if the value provided was an associative array (we should have already verified it's an array of some
338
+	 * sort). If the value is an associative array, it had better be in the simplified specified operator structure.
339
+	 * @since 4.9.72.p
340
+	 * @return boolean
341
+	 */
342
+	private function valueIsAssociativeArray()
343
+	{
344
+		return !EEH_Array::is_array_numerically_and_sequentially_indexed($this->getQueryParamValue());
345
+	}
346
+
347
+	/**
348
+	 * Checks if the array value is itself an array that fits into the simplified specified operator structure
349
+	 * (eg `array('!=' => 123)`).
350
+	 * @since 4.9.72.p
351
+	 * @return boolean
352
+	 */
353
+	private function valueIsSimplifiedSpecifiedOperator()
354
+	{
355
+		return count($this->getQueryParamValue()) === 1
356
+			&& array_key_exists(
357
+				key($this->getQueryParamValue()),
358
+				$this->getContext()->getModel()->valid_operators()
359
+			);
360
+	}
361
+
362
+	/**
363
+	 * Throws an exception if the sub-value is an array (eg `array('!=' => array())`). It needs to just be a string,
364
+	 * of either comma-separated-values, or a JSON array.
365
+	 * @since 4.9.72.p
366
+	 * @param $sub_array_key
367
+	 * @param $sub_array_value
368
+	 * @throws RestException
369
+	 */
370
+	private function assertSubValueIsntArray($sub_array_key, $sub_array_value)
371
+	{
372
+		if (is_array($sub_array_value) && EED_Core_Rest_Api::debugMode()) {
373
+			throw new RestException(
374
+				'csv_or_json_string_only',
375
+				sprintf(
376
+					/* translators: 1: variable name*/
377
+					esc_html__(
378
+						'The value provided for the operator "%1$s" should be comma-separated value string or a JSON array.',
379
+						'event_espresso'
380
+					),
381
+					$sub_array_key
382
+				),
383
+				array(
384
+					'status' => 400,
385
+				)
386
+			);
387
+		}
388
+	}
389
+
390
+	/**
391
+	 * Determines if the sub-array key is an operator taking 3 or more operators.
392
+	 * @since 4.9.72.p
393
+	 * @param $sub_array_key
394
+	 * @return boolean
395
+	 */
396
+	private function subArrayKeyIsNonBinaryOperator($sub_array_key)
397
+	{
398
+		return array_key_exists(
399
+			$sub_array_key,
400
+			array_merge(
401
+				$this->getContext()->getModel()->valid_in_style_operators(),
402
+				$this->getContext()->getModel()->valid_between_style_operators()
403
+			)
404
+		);
405
+	}
406
+
407
+	/**
408
+	 * Given that the $sub_array_key is a string, checks if it's an operator taking only 1 argument.
409
+	 * @since 4.9.72.p
410
+	 * @param string $sub_array_key
411
+	 * @return boolean
412
+	 */
413
+	private function subArrayKeyIsUnaryOperator($sub_array_key)
414
+	{
415
+		return array_key_exists(
416
+			$sub_array_key,
417
+			$this->getContext()->getModel()->valid_null_style_operators()
418
+		);
419
+	}
420
+
421
+	/**
422
+	 * Parses the $sub_array_value string into an array (given it could either be a comma-separated-list or a JSON
423
+	 * array). eg `"1,2,3"` or `"[1,2,3]"` into `array(1,2,3)`.
424
+	 * @since 4.9.72.p
425
+	 * @param $sub_array_value
426
+	 * @return array|mixed|object
427
+	 */
428
+	private function extractQuickStyleSpecifiedOperatorValue($sub_array_value)
429
+	{
430
+		// the value should be JSON or CSV
431
+		$values = json_decode($sub_array_value);
432
+		if (!is_array($values)) {
433
+			$values = array_filter(
434
+				array_map(
435
+					'trim',
436
+					explode(
437
+						',',
438
+						$sub_array_value
439
+					)
440
+				)
441
+			);
442
+		}
443
+		return $values;
444
+	}
445
+
446
+	/**
447
+	 * Throws an exception if the value isn't a simplified specified operator (only called when we expect that).
448
+	 * @since 4.9.72.p
449
+	 * @throws RestException
450
+	 */
451
+	private function assertSimplifiedSpecifiedOperator()
452
+	{
453
+		if (!$this->valueIsSimplifiedSpecifiedOperator() && EED_Core_Rest_Api::debugMode()) {
454
+			throw new RestException(
455
+				'numerically_indexed_array_of_values_only',
456
+				sprintf(
457
+					/* translators: 1: variable name*/
458
+					esc_html__(
459
+						'The array provided for the parameter "%1$s" should be numerically indexed.',
460
+						'event_espresso'
461
+					),
462
+					$this->getQueryParamKey()
463
+				),
464
+				array(
465
+					'status' => 400,
466
+				)
467
+			);
468
+		}
469
+	}
470
+
471
+	/**
472
+	 * If query_param_value were in the simplified specific operator structure, change it into the legacy structure.
473
+	 * @since 4.9.72.p
474
+	 * @throws RestException
475
+	 */
476
+	private function transformSimplifiedSpecifiedOperatorSyntaxIntoStandardSyntax()
477
+	{
478
+		if ($this->valueIsAssociativeArray()) {
479
+			$this->assertSimplifiedSpecifiedOperator();
480
+			$query_param_value = $this->getQueryParamValue();
481
+			$sub_array_value = reset($query_param_value);
482
+			$sub_array_key = key($query_param_value);
483
+			$this->assertSubValueIsntArray($sub_array_key, $sub_array_value);
484
+			// they're doing something like "&where[EVT_ID][IN]=1,2,3" or "&where[EVT_ID][>]=5"
485
+			if ($this->subArrayKeyIsNonBinaryOperator($sub_array_key)) {
486
+				$this->setQueryParamValue(array(
487
+					$sub_array_key,
488
+					$this->extractQuickStyleSpecifiedOperatorValue($sub_array_value)
489
+				));
490
+			} elseif ($this->subArrayKeyIsUnaryOperator($sub_array_key)) {
491
+				$this->setQueryParamValue(array($sub_array_key));
492
+			} else {
493
+				$this->setQueryParamValue(array($sub_array_key, $sub_array_value));
494
+			}
495
+		}
496
+	}
497
+
498
+	/**
499
+	 * Returns true is the value is an array using the legacy structure to specify the operator. Eg `array('!=',123)`.
500
+	 * @since 4.9.72.p
501
+	 * @return boolean
502
+	 */
503
+	private function valueIsLegacySpecifiedOperator()
504
+	{
505
+		$valid_operators = $this->getContext()->getModel()->valid_operators();
506
+		$query_param_value = $this->getQueryParamValue();
507
+		return isset($query_param_value[0])
508
+			&& isset($valid_operators[ $query_param_value[0] ]);
509
+	}
510
+
511
+	/**
512
+	 * Returns true if the value specified operator accepts arbitrary number of arguments, like "IN".
513
+	 * @since 4.9.72.p
514
+	 * @param $operator
515
+	 * @return boolean
516
+	 */
517
+	private function operatorIsNAry($operator)
518
+	{
519
+		$valueArray = $this->getQueryParamValue();
520
+		return array_key_exists(
521
+			$operator,
522
+			$this->getContext()->getModel()->valid_in_style_operators()
523
+		)
524
+			&& isset($valueArray[1])
525
+			&& is_array($valueArray[1])
526
+			&& !isset($valueArray[2]);
527
+	}
528
+
529
+	/**
530
+	 * Returns true if the operator accepts 3 arguments (eg "BETWEEN").
531
+	 * So we're looking for a value that looks like
532
+	 * `array('BETWEEN', array('2015-01-01T00:00:00', '2016-01-01T00:00:00'))`.
533
+	 * @since 4.9.72.p
534
+	 * @param $operator
535
+	 * @return boolean
536
+	 */
537
+	private function operatorIsTernary($operator)
538
+	{
539
+		$query_param_value = $this->getQueryParamValue();
540
+		return array_key_exists($operator, $this->getContext()->getModel()->valid_between_style_operators())
541
+			&& isset($query_param_value[1])
542
+			&& is_array($query_param_value[1])
543
+			&& isset($query_param_value[1][0], $query_param_value[1][1])
544
+			&& !isset($query_param_value[1][2])
545
+			&& !isset($query_param_value[2]);
546
+	}
547
+
548
+	/**
549
+	 * Returns true if the operator is a similar to LIKE, indicating the value may have wildcards we should leave alone.
550
+	 * @since 4.9.72.p
551
+	 * @param $operator
552
+	 * @return boolean
553
+	 */
554
+	private function operatorIsLike($operator)
555
+	{
556
+		$query_param_value = $this->getQueryParamValue();
557
+		return array_key_exists($operator, $this->getContext()->getModel()->valid_like_style_operators())
558
+			&& isset($query_param_value[1])
559
+			&& !isset($query_param_value[2]);
560
+	}
561
+
562
+	/**
563
+	 * Returns true if the operator only takes one argument (eg it's like `IS NULL`).
564
+	 * @since 4.9.72.p
565
+	 * @param $operator
566
+	 * @return boolean
567
+	 */
568
+	private function operatorIsUnary($operator)
569
+	{
570
+		$query_param_value = $this->getQueryParamValue();
571
+		return array_key_exists($operator, $this->getContext()->getModel()->valid_null_style_operators())
572
+			&& !isset($query_param_value[1]);
573
+	}
574
+
575
+	/**
576
+	 * Returns true if the operator specified is a binary opeator (eg `=`, `!=`)
577
+	 * @since 4.9.72.p
578
+	 * @param $operator
579
+	 * @return boolean
580
+	 */
581
+	private function operatorisBinary($operator)
582
+	{
583
+		$query_param_value = $this->getQueryParamValue();
584
+		$model = $this->getContext()->getModel();
585
+		return isset($query_param_value[1])
586
+			&& !isset($query_param_value[2])
587
+			&& !array_key_exists(
588
+				$operator,
589
+				array_merge(
590
+					$model->valid_in_style_operators(),
591
+					$model->valid_null_style_operators(),
592
+					$model->valid_like_style_operators(),
593
+					$model->valid_between_style_operators()
594
+				)
595
+			);
596
+	}
597
+
598
+	/**
599
+	 * If we're debugging, throws an exception saying that the wrong number of arguments was provided.
600
+	 * @since 4.9.72.p
601
+	 * @param $operator
602
+	 * @throws RestException
603
+	 */
604
+	private function throwWrongNumberOfArgsExceptionIfDebugging($operator)
605
+	{
606
+		if (EED_Core_Rest_Api::debugMode()) {
607
+			throw new RestException(
608
+				'wrong_number_of_arguments',
609
+				sprintf(
610
+					esc_html__(
611
+						'The operator you provided, "%1$s" had the wrong number of arguments',
612
+						'event_espresso'
613
+					),
614
+					$operator
615
+				),
616
+				array(
617
+					'status' => 400,
618
+				)
619
+			);
620
+		}
621
+	}
622
+
623
+	/**
624
+	 * Wrapper for ModelDataTranslator::prepareFieldValuesFromJson(), just a tad more DRY.
625
+	 * @since 4.9.72.p
626
+	 * @param $value
627
+	 * @return mixed
628
+	 * @throws RestException
629
+	 */
630
+	private function prepareValuesFromJson($value)
631
+	{
632
+		return ModelDataTranslator::prepareFieldValuesFromJson(
633
+			$this->getField(),
634
+			$value,
635
+			$this->getContext()->getRequestedVersion(),
636
+			$this->getTimezone()
637
+		);
638
+	}
639
+
640
+	/**
641
+	 * Throws an exception if an invalid operator was specified and we're debugging.
642
+	 * @since 4.9.72.p
643
+	 * @throws RestException
644
+	 */
645
+	private function throwInvalidOperatorExceptionIfDebugging()
646
+	{
647
+		// so they didn't provide a valid operator
648
+		if (EED_Core_Rest_Api::debugMode()) {
649
+			throw new RestException(
650
+				'invalid_operator',
651
+				sprintf(
652
+					esc_html__(
653
+						'You provided an invalid parameter, with key "%1$s" and value "%2$s"',
654
+						'event_espresso'
655
+					),
656
+					$this->getQueryParamKey(),
657
+					$this->getQueryParamValue()
658
+				),
659
+				array(
660
+					'status' => 400,
661
+				)
662
+			);
663
+		}
664
+	}
665
+
666
+	/**
667
+	 * Returns true if the query_param_key was a logic query parameter, eg `OR`, `AND`, `NOT`, `OR*`, etc.
668
+	 * @since 4.9.72.p
669
+	 * @return boolean
670
+	 */
671
+	private function isLogicQueryParam()
672
+	{
673
+		return in_array($this->getQueryParamKeySansStars(), $this->getContext()->getModel()->logic_query_param_keys());
674
+	}
675
+
676
+
677
+	/**
678
+	 * If the query param isn't for a field, it must be a nested query parameter which requires different logic.
679
+	 * @since 4.9.72.p
680
+	 * @return array
681
+	 * @throws DomainException
682
+	 * @throws EE_Error
683
+	 * @throws RestException
684
+	 * @throws InvalidDataTypeException
685
+	 * @throws InvalidInterfaceException
686
+	 * @throws InvalidArgumentException
687
+	 */
688
+	public function determineNestedConditionQueryParameters()
689
+	{
690
+
691
+		// so this param doesn't correspond to a field eh?
692
+		if ($this->getContext()->isWriting()) {
693
+			// always tell API clients about invalid parameters when they're creating data. Otherwise,
694
+			// they are probably going to create invalid data
695
+			throw new RestException(
696
+				'invalid_field',
697
+				sprintf(
698
+					/* translators: 1: variable name */
699
+					esc_html__('You have provided an invalid parameter: "%1$s"', 'event_espresso'),
700
+					$this->getQueryParamKey()
701
+				)
702
+			);
703
+		}
704
+		// so it's not for a field, is it a logic query param key?
705
+		if ($this->isLogicQueryParam()) {
706
+			return ModelDataTranslator::prepareConditionsQueryParamsForModels(
707
+				$this->getQueryParamValue(),
708
+				$this->getContext()->getModel(),
709
+				$this->getContext()->getRequestedVersion()
710
+			);
711
+		}
712
+		if (EED_Core_Rest_Api::debugMode()) {
713
+			// only tell API clients they got it wrong if we're in debug mode
714
+			// otherwise try our best ot fulfill their request by ignoring this invalid data
715
+			throw new RestException(
716
+				'invalid_parameter',
717
+				sprintf(
718
+					/* translators: 1: variable name */
719
+					esc_html__(
720
+						'You provided an invalid parameter, with key "%1$s"',
721
+						'event_espresso'
722
+					),
723
+					$this->getQueryParamKey()
724
+				),
725
+				array(
726
+					'status' => 400,
727
+				)
728
+			);
729
+		}
730
+		return null;
731
+	}
732 732
 }
733 733
 // End of file RestQueryParamMetadata.php
734 734
 // Location: EventEspresso\core\libraries\rest_api/RestQueryParamMetadata.php
Please login to merge, or discard this patch.
Spacing   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -209,7 +209,7 @@  discard block
 block discarded – undo
209 209
         ));
210 210
         // double-check is it a *_gmt field?
211 211
         if (
212
-            !$this->getField() instanceof EE_Model_Field_Base
212
+            ! $this->getField() instanceof EE_Model_Field_Base
213 213
             && ModelDataTranslator::isGmtDateFieldName($this->getQueryParamKeySansStars())
214 214
         ) {
215 215
             // yep, take off '_gmt', and find the field
@@ -330,7 +330,7 @@  discard block
 block discarded – undo
330 330
      */
331 331
     private function valueIsArrayDuringRead()
332 332
     {
333
-        return !$this->getContext()->isWriting() && is_array($this->getQueryParamValue());
333
+        return ! $this->getContext()->isWriting() && is_array($this->getQueryParamValue());
334 334
     }
335 335
 
336 336
     /**
@@ -341,7 +341,7 @@  discard block
 block discarded – undo
341 341
      */
342 342
     private function valueIsAssociativeArray()
343 343
     {
344
-        return !EEH_Array::is_array_numerically_and_sequentially_indexed($this->getQueryParamValue());
344
+        return ! EEH_Array::is_array_numerically_and_sequentially_indexed($this->getQueryParamValue());
345 345
     }
346 346
 
347 347
     /**
@@ -429,7 +429,7 @@  discard block
 block discarded – undo
429 429
     {
430 430
         // the value should be JSON or CSV
431 431
         $values = json_decode($sub_array_value);
432
-        if (!is_array($values)) {
432
+        if ( ! is_array($values)) {
433 433
             $values = array_filter(
434 434
                 array_map(
435 435
                     'trim',
@@ -450,7 +450,7 @@  discard block
 block discarded – undo
450 450
      */
451 451
     private function assertSimplifiedSpecifiedOperator()
452 452
     {
453
-        if (!$this->valueIsSimplifiedSpecifiedOperator() && EED_Core_Rest_Api::debugMode()) {
453
+        if ( ! $this->valueIsSimplifiedSpecifiedOperator() && EED_Core_Rest_Api::debugMode()) {
454 454
             throw new RestException(
455 455
                 'numerically_indexed_array_of_values_only',
456 456
                 sprintf(
@@ -505,7 +505,7 @@  discard block
 block discarded – undo
505 505
         $valid_operators = $this->getContext()->getModel()->valid_operators();
506 506
         $query_param_value = $this->getQueryParamValue();
507 507
         return isset($query_param_value[0])
508
-            && isset($valid_operators[ $query_param_value[0] ]);
508
+            && isset($valid_operators[$query_param_value[0]]);
509 509
     }
510 510
 
511 511
     /**
@@ -523,7 +523,7 @@  discard block
 block discarded – undo
523 523
         )
524 524
             && isset($valueArray[1])
525 525
             && is_array($valueArray[1])
526
-            && !isset($valueArray[2]);
526
+            && ! isset($valueArray[2]);
527 527
     }
528 528
 
529 529
     /**
@@ -541,8 +541,8 @@  discard block
 block discarded – undo
541 541
             && isset($query_param_value[1])
542 542
             && is_array($query_param_value[1])
543 543
             && isset($query_param_value[1][0], $query_param_value[1][1])
544
-            && !isset($query_param_value[1][2])
545
-            && !isset($query_param_value[2]);
544
+            && ! isset($query_param_value[1][2])
545
+            && ! isset($query_param_value[2]);
546 546
     }
547 547
 
548 548
     /**
@@ -556,7 +556,7 @@  discard block
 block discarded – undo
556 556
         $query_param_value = $this->getQueryParamValue();
557 557
         return array_key_exists($operator, $this->getContext()->getModel()->valid_like_style_operators())
558 558
             && isset($query_param_value[1])
559
-            && !isset($query_param_value[2]);
559
+            && ! isset($query_param_value[2]);
560 560
     }
561 561
 
562 562
     /**
@@ -569,7 +569,7 @@  discard block
 block discarded – undo
569 569
     {
570 570
         $query_param_value = $this->getQueryParamValue();
571 571
         return array_key_exists($operator, $this->getContext()->getModel()->valid_null_style_operators())
572
-            && !isset($query_param_value[1]);
572
+            && ! isset($query_param_value[1]);
573 573
     }
574 574
 
575 575
     /**
@@ -583,8 +583,8 @@  discard block
 block discarded – undo
583 583
         $query_param_value = $this->getQueryParamValue();
584 584
         $model = $this->getContext()->getModel();
585 585
         return isset($query_param_value[1])
586
-            && !isset($query_param_value[2])
587
-            && !array_key_exists(
586
+            && ! isset($query_param_value[2])
587
+            && ! array_key_exists(
588 588
                 $operator,
589 589
                 array_merge(
590 590
                     $model->valid_in_style_operators(),
Please login to merge, or discard this patch.
core/libraries/rest_api/changes/ChangesIn40834.php 1 patch
Indentation   +33 added lines, -33 removed lines patch added patch discarded remove patch
@@ -12,39 +12,39 @@
 block discarded – undo
12 12
 class ChangesIn40834 extends ChangesInBase
13 13
 {
14 14
 
15
-    /**
16
-     * Adds hooks so requests to 4.8.29 don't have the checkin endpoints
17
-     */
18
-    public function setHooks()
19
-    {
20
-        // set a hook to remove the checkout/checkout endpoints if the request
21
-        // is for lower than 4.8.33
22
-        add_filter(
23
-            'FHEE__EventEspresso\core\libraries\rest_api\controllers\Base___get_response_headers',
24
-            array($this, 'removeResponseHeaders'),
25
-            10,
26
-            3
27
-        );
28
-    }
15
+	/**
16
+	 * Adds hooks so requests to 4.8.29 don't have the checkin endpoints
17
+	 */
18
+	public function setHooks()
19
+	{
20
+		// set a hook to remove the checkout/checkout endpoints if the request
21
+		// is for lower than 4.8.33
22
+		add_filter(
23
+			'FHEE__EventEspresso\core\libraries\rest_api\controllers\Base___get_response_headers',
24
+			array($this, 'removeResponseHeaders'),
25
+			10,
26
+			3
27
+		);
28
+	}
29 29
 
30 30
 
31
-    /**
32
-     * Removes the checkin and checkout endpoints from the index for requests
33
-     * to api versions lowers than 4.8.33
34
-     *
35
-     * @param array  $response_headers
36
-     * @param Base   $controller
37
-     * @param string $requested_version
38
-     * @return array like $routes_on_this_version
39
-     */
40
-    public function removeResponseHeaders($response_headers, $controller, $requested_version)
41
-    {
42
-        if (
43
-            $controller instanceof Base
44
-            && $this->appliesToVersion($requested_version)
45
-        ) {
46
-            return array();
47
-        }
48
-        return $response_headers;
49
-    }
31
+	/**
32
+	 * Removes the checkin and checkout endpoints from the index for requests
33
+	 * to api versions lowers than 4.8.33
34
+	 *
35
+	 * @param array  $response_headers
36
+	 * @param Base   $controller
37
+	 * @param string $requested_version
38
+	 * @return array like $routes_on_this_version
39
+	 */
40
+	public function removeResponseHeaders($response_headers, $controller, $requested_version)
41
+	{
42
+		if (
43
+			$controller instanceof Base
44
+			&& $this->appliesToVersion($requested_version)
45
+		) {
46
+			return array();
47
+		}
48
+		return $response_headers;
49
+	}
50 50
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/RestException.php 1 patch
Indentation   +41 added lines, -41 removed lines patch added patch discarded remove patch
@@ -15,55 +15,55 @@
 block discarded – undo
15 15
 class RestException extends \EE_Error
16 16
 {
17 17
 
18
-    /**
19
-     * @var array
20
-     */
21
-    protected $wp_error_data = array();
18
+	/**
19
+	 * @var array
20
+	 */
21
+	protected $wp_error_data = array();
22 22
 
23
-    protected $wp_error_code = '';
23
+	protected $wp_error_code = '';
24 24
 
25 25
 
26 26
 
27
-    public function __construct($string_code, $message, $wp_error_data = array(), $previous = null)
28
-    {
29
-        if (
30
-            is_array($wp_error_data)
31
-            && isset($wp_error_data['status'])
32
-        ) {
33
-            $http_status_number = $wp_error_data['status'];
34
-        } else {
35
-            $http_status_number = 500;
36
-        }
37
-        parent::__construct(
38
-            $message,
39
-            $http_status_number,
40
-            $previous
41
-        );
42
-        $this->wp_error_data = $wp_error_data;
43
-        $this->wp_error_code = $string_code;
44
-    }
27
+	public function __construct($string_code, $message, $wp_error_data = array(), $previous = null)
28
+	{
29
+		if (
30
+			is_array($wp_error_data)
31
+			&& isset($wp_error_data['status'])
32
+		) {
33
+			$http_status_number = $wp_error_data['status'];
34
+		} else {
35
+			$http_status_number = 500;
36
+		}
37
+		parent::__construct(
38
+			$message,
39
+			$http_status_number,
40
+			$previous
41
+		);
42
+		$this->wp_error_data = $wp_error_data;
43
+		$this->wp_error_code = $string_code;
44
+	}
45 45
 
46 46
 
47 47
 
48
-    /**
49
-     * Array of data that may have been set during the constructor, intended for WP_Error's data
50
-     *
51
-     * @return array
52
-     */
53
-    public function getData()
54
-    {
55
-        return $this->wp_error_data;
56
-    }
48
+	/**
49
+	 * Array of data that may have been set during the constructor, intended for WP_Error's data
50
+	 *
51
+	 * @return array
52
+	 */
53
+	public function getData()
54
+	{
55
+		return $this->wp_error_data;
56
+	}
57 57
 
58 58
 
59 59
 
60
-    /**
61
-     * Gets the error string
62
-     *
63
-     * @return string
64
-     */
65
-    public function getStringCode()
66
-    {
67
-        return $this->wp_error_code;
68
-    }
60
+	/**
61
+	 * Gets the error string
62
+	 *
63
+	 * @return string
64
+	 */
65
+	public function getStringCode()
66
+	{
67
+		return $this->wp_error_code;
68
+	}
69 69
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/calculations/Registration.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -96,7 +96,7 @@
 block discarded – undo
96 96
                     $status_pretty = 'NEVER';
97 97
                     break;
98 98
             }
99
-            $checkin_stati[ $datetime_id ] = $status_pretty;
99
+            $checkin_stati[$datetime_id] = $status_pretty;
100 100
         }
101 101
         return $checkin_stati;
102 102
     }
Please login to merge, or discard this patch.
Indentation   +101 added lines, -101 removed lines patch added patch discarded remove patch
@@ -24,109 +24,109 @@
 block discarded – undo
24 24
  */
25 25
 class Registration extends RegistrationCalculationBase
26 26
 {
27
-    /**
28
-     * @var EEM_Registration
29
-     */
30
-    protected $registration_model;
27
+	/**
28
+	 * @var EEM_Registration
29
+	 */
30
+	protected $registration_model;
31 31
 
32
-    /**
33
-     * Registration constructor.
34
-     * @param EEM_Registration $registration_model
35
-     */
36
-    public function __construct(EEM_Registration $registration_model)
37
-    {
38
-        $this->registration_model = $registration_model;
39
-    }
32
+	/**
33
+	 * Registration constructor.
34
+	 * @param EEM_Registration $registration_model
35
+	 */
36
+	public function __construct(EEM_Registration $registration_model)
37
+	{
38
+		$this->registration_model = $registration_model;
39
+	}
40 40
 
41
-    /**
42
-     * Calculates the checkin status for each datetime this registration has access to
43
-     *
44
-     * @param array            $wpdb_row
45
-     * @param WP_REST_Request $request
46
-     * @param RegistrationControllerBase $controller
47
-     * @return array
48
-     * @throws EE_Error
49
-     * @throws InvalidDataTypeException
50
-     * @throws InvalidInterfaceException
51
-     * @throws InvalidArgumentException
52
-     */
53
-    public function datetimeCheckinStati($wpdb_row, $request, $controller)
54
-    {
55
-        if (is_array($wpdb_row) && isset($wpdb_row['Registration.REG_ID'])) {
56
-            $reg = $this->registration_model->get_one_by_ID($wpdb_row['Registration.REG_ID']);
57
-        } else {
58
-            $reg = null;
59
-        }
60
-        if (
61
-            ! $reg instanceof EE_Registration
62
-        ) {
63
-            throw new EE_Error(
64
-                sprintf(
65
-                    esc_html__(
66
-                    // @codingStandardsIgnoreStart
67
-                        'Cannot calculate datetime_checkin_stati because the registration with ID %1$s (from database row %2$s) was not found',
68
-                        // @codingStandardsIgnoreEnd
69
-                        'event_espresso'
70
-                    ),
71
-                    $wpdb_row['Registration.REG_ID'],
72
-                    print_r($wpdb_row, true)
73
-                )
74
-            );
75
-        }
76
-        $datetime_ids = EEM_Datetime::instance()->get_col(
77
-            [
78
-                [
79
-                    'Ticket.TKT_ID' => $reg->ticket_ID(),
80
-                ],
81
-                'default_where_conditions' => EEM_Base::default_where_conditions_minimum_all,
82
-            ]
83
-        );
84
-        $checkin_stati = array();
85
-        foreach ($datetime_ids as $datetime_id) {
86
-            $status = $reg->check_in_status_for_datetime($datetime_id);
87
-            switch ($status) {
88
-                case EE_Checkin::status_checked_out:
89
-                    $status_pretty = 'OUT';
90
-                    break;
91
-                case EE_Checkin::status_checked_in:
92
-                    $status_pretty = 'IN';
93
-                    break;
94
-                case EE_Checkin::status_checked_never:
95
-                default:
96
-                    $status_pretty = 'NEVER';
97
-                    break;
98
-            }
99
-            $checkin_stati[ $datetime_id ] = $status_pretty;
100
-        }
101
-        return $checkin_stati;
102
-    }
41
+	/**
42
+	 * Calculates the checkin status for each datetime this registration has access to
43
+	 *
44
+	 * @param array            $wpdb_row
45
+	 * @param WP_REST_Request $request
46
+	 * @param RegistrationControllerBase $controller
47
+	 * @return array
48
+	 * @throws EE_Error
49
+	 * @throws InvalidDataTypeException
50
+	 * @throws InvalidInterfaceException
51
+	 * @throws InvalidArgumentException
52
+	 */
53
+	public function datetimeCheckinStati($wpdb_row, $request, $controller)
54
+	{
55
+		if (is_array($wpdb_row) && isset($wpdb_row['Registration.REG_ID'])) {
56
+			$reg = $this->registration_model->get_one_by_ID($wpdb_row['Registration.REG_ID']);
57
+		} else {
58
+			$reg = null;
59
+		}
60
+		if (
61
+			! $reg instanceof EE_Registration
62
+		) {
63
+			throw new EE_Error(
64
+				sprintf(
65
+					esc_html__(
66
+					// @codingStandardsIgnoreStart
67
+						'Cannot calculate datetime_checkin_stati because the registration with ID %1$s (from database row %2$s) was not found',
68
+						// @codingStandardsIgnoreEnd
69
+						'event_espresso'
70
+					),
71
+					$wpdb_row['Registration.REG_ID'],
72
+					print_r($wpdb_row, true)
73
+				)
74
+			);
75
+		}
76
+		$datetime_ids = EEM_Datetime::instance()->get_col(
77
+			[
78
+				[
79
+					'Ticket.TKT_ID' => $reg->ticket_ID(),
80
+				],
81
+				'default_where_conditions' => EEM_Base::default_where_conditions_minimum_all,
82
+			]
83
+		);
84
+		$checkin_stati = array();
85
+		foreach ($datetime_ids as $datetime_id) {
86
+			$status = $reg->check_in_status_for_datetime($datetime_id);
87
+			switch ($status) {
88
+				case EE_Checkin::status_checked_out:
89
+					$status_pretty = 'OUT';
90
+					break;
91
+				case EE_Checkin::status_checked_in:
92
+					$status_pretty = 'IN';
93
+					break;
94
+				case EE_Checkin::status_checked_never:
95
+				default:
96
+					$status_pretty = 'NEVER';
97
+					break;
98
+			}
99
+			$checkin_stati[ $datetime_id ] = $status_pretty;
100
+		}
101
+		return $checkin_stati;
102
+	}
103 103
 
104 104
 
105
-    /**
106
-     * Provides an array for all the calculations possible that outlines a json schema for those calculations.
107
-     * Array is indexed by calculation (snake case) and value is the schema for that calculation.
108
-     *
109
-     * @since 4.9.68.p
110
-     * @return array
111
-     */
112
-    public function schemaForCalculations()
113
-    {
114
-        return array(
115
-            'datetime_checkin_stati' => array(
116
-                'description' => esc_html__(
117
-                    'Returns the checkin status for each datetime this registration has access to.',
118
-                    'event_espresso'
119
-                ),
120
-                'type' => 'object',
121
-                'properties' => array(),
122
-                'additionalProperties' => array(
123
-                    'description' => esc_html__(
124
-                        'Keys are date-time ids and values are the check-in status',
125
-                        'event_espresso'
126
-                    ),
127
-                    'type' => 'string'
128
-                ),
129
-            ),
130
-        );
131
-    }
105
+	/**
106
+	 * Provides an array for all the calculations possible that outlines a json schema for those calculations.
107
+	 * Array is indexed by calculation (snake case) and value is the schema for that calculation.
108
+	 *
109
+	 * @since 4.9.68.p
110
+	 * @return array
111
+	 */
112
+	public function schemaForCalculations()
113
+	{
114
+		return array(
115
+			'datetime_checkin_stati' => array(
116
+				'description' => esc_html__(
117
+					'Returns the checkin status for each datetime this registration has access to.',
118
+					'event_espresso'
119
+				),
120
+				'type' => 'object',
121
+				'properties' => array(),
122
+				'additionalProperties' => array(
123
+					'description' => esc_html__(
124
+						'Keys are date-time ids and values are the check-in status',
125
+						'event_espresso'
126
+					),
127
+					'type' => 'string'
128
+				),
129
+			),
130
+		);
131
+	}
132 132
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/CalculatedModelFields.php 2 patches
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -57,7 +57,7 @@  discard block
 block discarded – undo
57 57
      */
58 58
     public function mapping($refresh = false)
59 59
     {
60
-        if (! $this->mapping || $refresh) {
60
+        if ( ! $this->mapping || $refresh) {
61 61
             $this->mapping = $this->generateNewMapping();
62 62
         }
63 63
         return $this->mapping;
@@ -81,7 +81,7 @@  discard block
 block discarded – undo
81 81
         foreach ($models_with_calculated_fields as $model_name) {
82 82
             $calculator = $this->factory->createFromModel($model_name);
83 83
             foreach (array_keys(call_user_func(array($calculator, 'schemaForCalculations'))) as $field_name) {
84
-                $mapping[ $model_name ][ $field_name ] = get_class($calculator);
84
+                $mapping[$model_name][$field_name] = get_class($calculator);
85 85
             }
86 86
         }
87 87
         return apply_filters(
@@ -108,8 +108,8 @@  discard block
 block discarded – undo
108 108
             foreach ($map_for_model as $calculation_index => $calculations_class) {
109 109
                 $calculator = $this->factory->createFromClassname($calculations_class);
110 110
                 $schema = call_user_func(array($calculator, 'schemaForCalculation'), $calculation_index);
111
-                if (! empty($schema)) {
112
-                    $schema_map[ $map_model ][ $calculation_index ] = $schema;
111
+                if ( ! empty($schema)) {
112
+                    $schema_map[$map_model][$calculation_index] = $schema;
113 113
                 }
114 114
             }
115 115
         }
@@ -126,8 +126,8 @@  discard block
 block discarded – undo
126 126
     public function retrieveCalculatedFieldsForModel(EEM_Base $model)
127 127
     {
128 128
         $mapping = $this->mapping();
129
-        if (isset($mapping[ $model->get_this_model_name() ])) {
130
-            return array_keys($mapping[ $model->get_this_model_name() ]);
129
+        if (isset($mapping[$model->get_this_model_name()])) {
130
+            return array_keys($mapping[$model->get_this_model_name()]);
131 131
         }
132 132
         return array();
133 133
     }
@@ -140,7 +140,7 @@  discard block
 block discarded – undo
140 140
      */
141 141
     public function getJsonSchemaForModel(EEM_Base $model)
142 142
     {
143
-        if (! $this->mapping_schema) {
143
+        if ( ! $this->mapping_schema) {
144 144
             $this->mapping_schema = $this->generateNewMappingSchema();
145 145
         }
146 146
         return array(
@@ -149,8 +149,8 @@  discard block
 block discarded – undo
149 149
                 'event_espresso'
150 150
             ),
151 151
             'type' => 'object',
152
-            'properties' => isset($this->mapping_schema[ $model->get_this_model_name() ])
153
-                ? $this->mapping_schema[ $model->get_this_model_name() ]
152
+            'properties' => isset($this->mapping_schema[$model->get_this_model_name()])
153
+                ? $this->mapping_schema[$model->get_this_model_name()]
154 154
                 : array(),
155 155
             'additionalProperties' => false,
156 156
             'readonly' => true,
@@ -179,10 +179,10 @@  discard block
 block discarded – undo
179 179
     ) {
180 180
         $mapping = $this->mapping();
181 181
         if (
182
-            isset($mapping[ $model->get_this_model_name() ])
183
-            && isset($mapping[ $model->get_this_model_name() ][ $field_name ])
182
+            isset($mapping[$model->get_this_model_name()])
183
+            && isset($mapping[$model->get_this_model_name()][$field_name])
184 184
         ) {
185
-            $classname = $mapping[ $model->get_this_model_name() ][ $field_name ];
185
+            $classname = $mapping[$model->get_this_model_name()][$field_name];
186 186
             $calculator = $this->factory->createFromClassname($classname);
187 187
             $class_method_name = EEH_Inflector::camelize_all_but_first($field_name);
188 188
             return call_user_func(array($calculator, $class_method_name), $wpdb_row, $rest_request, $controller);
Please login to merge, or discard this patch.
Indentation   +174 added lines, -174 removed lines patch added patch discarded remove patch
@@ -22,178 +22,178 @@
 block discarded – undo
22 22
 class CalculatedModelFields
23 23
 {
24 24
 
25
-    /**
26
-     * @var array
27
-     */
28
-    protected $mapping;
29
-
30
-    /**
31
-     * @var array
32
-     */
33
-    protected $mapping_schema;
34
-
35
-    /**
36
-     * @var CalculatedModelFieldsFactory
37
-     */
38
-    private $factory;
39
-
40
-    /**
41
-     * CalculatedModelFields constructor.
42
-     * @param CalculatedModelFieldsFactory $factory
43
-     */
44
-    public function __construct(CalculatedModelFieldsFactory $factory)
45
-    {
46
-        $this->factory = $factory;
47
-    }
48
-    /**
49
-     * @param bool $refresh
50
-     * @return array top-level-keys are model names (eg "Event")
51
-     * next-level are the calculated field names AND method names on classes
52
-     * which perform calculations, values are the fully qualified classnames which do the calculations
53
-     * These callbacks should accept as arguments:
54
-     * the wpdb row results,
55
-     * the WP_Request object,
56
-     * the controller object
57
-     */
58
-    public function mapping($refresh = false)
59
-    {
60
-        if (! $this->mapping || $refresh) {
61
-            $this->mapping = $this->generateNewMapping();
62
-        }
63
-        return $this->mapping;
64
-    }
65
-
66
-
67
-    /**
68
-     * Generates a new mapping between model calculated fields and their callbacks
69
-     *
70
-     * @return array
71
-     */
72
-    protected function generateNewMapping()
73
-    {
74
-        $mapping = array();
75
-        $models_with_calculated_fields = array(
76
-            'Attendee',
77
-            'Datetime',
78
-            'Event',
79
-            'Registration'
80
-        );
81
-        foreach ($models_with_calculated_fields as $model_name) {
82
-            $calculator = $this->factory->createFromModel($model_name);
83
-            foreach (array_keys(call_user_func(array($calculator, 'schemaForCalculations'))) as $field_name) {
84
-                $mapping[ $model_name ][ $field_name ] = get_class($calculator);
85
-            }
86
-        }
87
-        return apply_filters(
88
-            'FHEE__EventEspresso\core\libraries\rest_api\Calculated_Model_Fields__mapping',
89
-            $mapping
90
-        );
91
-    }
92
-
93
-
94
-    /**
95
-     * Generates the schema for each calculation index in the calculation map.
96
-     *
97
-     * @return array
98
-     * @throws UnexpectedEntityException
99
-     */
100
-    protected function generateNewMappingSchema()
101
-    {
102
-        $schema_map = array();
103
-        foreach ($this->mapping() as $map_model => $map_for_model) {
104
-            /**
105
-             * @var string $calculation_index
106
-             * @var string $calculations_class
107
-             */
108
-            foreach ($map_for_model as $calculation_index => $calculations_class) {
109
-                $calculator = $this->factory->createFromClassname($calculations_class);
110
-                $schema = call_user_func(array($calculator, 'schemaForCalculation'), $calculation_index);
111
-                if (! empty($schema)) {
112
-                    $schema_map[ $map_model ][ $calculation_index ] = $schema;
113
-                }
114
-            }
115
-        }
116
-        return $schema_map;
117
-    }
118
-
119
-
120
-    /**
121
-     * Gets the known calculated fields for model
122
-     *
123
-     * @param EEM_Base $model
124
-     * @return array allowable values for this field
125
-     */
126
-    public function retrieveCalculatedFieldsForModel(EEM_Base $model)
127
-    {
128
-        $mapping = $this->mapping();
129
-        if (isset($mapping[ $model->get_this_model_name() ])) {
130
-            return array_keys($mapping[ $model->get_this_model_name() ]);
131
-        }
132
-        return array();
133
-    }
134
-
135
-
136
-    /**
137
-     * Returns the JsonSchema for the calculated fields on the given model.
138
-     * @param EEM_Base $model
139
-     * @return array
140
-     */
141
-    public function getJsonSchemaForModel(EEM_Base $model)
142
-    {
143
-        if (! $this->mapping_schema) {
144
-            $this->mapping_schema = $this->generateNewMappingSchema();
145
-        }
146
-        return array(
147
-            'description' => esc_html__(
148
-                'Available calculated fields for this model.  Fields are only present in the response if explicitly requested',
149
-                'event_espresso'
150
-            ),
151
-            'type' => 'object',
152
-            'properties' => isset($this->mapping_schema[ $model->get_this_model_name() ])
153
-                ? $this->mapping_schema[ $model->get_this_model_name() ]
154
-                : array(),
155
-            'additionalProperties' => false,
156
-            'readonly' => true,
157
-        );
158
-    }
159
-
160
-
161
-    /**
162
-     * Retrieves the value for this calculation
163
-     *
164
-     * @param EEM_Base $model
165
-     * @param string $field_name
166
-     * @param array $wpdb_row
167
-     * @param $rest_request
168
-     * @param BaseController $controller
169
-     * @return mixed|null
170
-     * @throws RestException
171
-     * @throws UnexpectedEntityException
172
-     */
173
-    public function retrieveCalculatedFieldValue(
174
-        EEM_Base $model,
175
-        $field_name,
176
-        $wpdb_row,
177
-        $rest_request,
178
-        Base $controller
179
-    ) {
180
-        $mapping = $this->mapping();
181
-        if (
182
-            isset($mapping[ $model->get_this_model_name() ])
183
-            && isset($mapping[ $model->get_this_model_name() ][ $field_name ])
184
-        ) {
185
-            $classname = $mapping[ $model->get_this_model_name() ][ $field_name ];
186
-            $calculator = $this->factory->createFromClassname($classname);
187
-            $class_method_name = EEH_Inflector::camelize_all_but_first($field_name);
188
-            return call_user_func(array($calculator, $class_method_name), $wpdb_row, $rest_request, $controller);
189
-        }
190
-        throw new RestException(
191
-            'calculated_field_does_not_exist',
192
-            sprintf(
193
-                esc_html__('There is no calculated field %1$s on resource %2$s', 'event_espresso'),
194
-                $field_name,
195
-                $model->get_this_model_name()
196
-            )
197
-        );
198
-    }
25
+	/**
26
+	 * @var array
27
+	 */
28
+	protected $mapping;
29
+
30
+	/**
31
+	 * @var array
32
+	 */
33
+	protected $mapping_schema;
34
+
35
+	/**
36
+	 * @var CalculatedModelFieldsFactory
37
+	 */
38
+	private $factory;
39
+
40
+	/**
41
+	 * CalculatedModelFields constructor.
42
+	 * @param CalculatedModelFieldsFactory $factory
43
+	 */
44
+	public function __construct(CalculatedModelFieldsFactory $factory)
45
+	{
46
+		$this->factory = $factory;
47
+	}
48
+	/**
49
+	 * @param bool $refresh
50
+	 * @return array top-level-keys are model names (eg "Event")
51
+	 * next-level are the calculated field names AND method names on classes
52
+	 * which perform calculations, values are the fully qualified classnames which do the calculations
53
+	 * These callbacks should accept as arguments:
54
+	 * the wpdb row results,
55
+	 * the WP_Request object,
56
+	 * the controller object
57
+	 */
58
+	public function mapping($refresh = false)
59
+	{
60
+		if (! $this->mapping || $refresh) {
61
+			$this->mapping = $this->generateNewMapping();
62
+		}
63
+		return $this->mapping;
64
+	}
65
+
66
+
67
+	/**
68
+	 * Generates a new mapping between model calculated fields and their callbacks
69
+	 *
70
+	 * @return array
71
+	 */
72
+	protected function generateNewMapping()
73
+	{
74
+		$mapping = array();
75
+		$models_with_calculated_fields = array(
76
+			'Attendee',
77
+			'Datetime',
78
+			'Event',
79
+			'Registration'
80
+		);
81
+		foreach ($models_with_calculated_fields as $model_name) {
82
+			$calculator = $this->factory->createFromModel($model_name);
83
+			foreach (array_keys(call_user_func(array($calculator, 'schemaForCalculations'))) as $field_name) {
84
+				$mapping[ $model_name ][ $field_name ] = get_class($calculator);
85
+			}
86
+		}
87
+		return apply_filters(
88
+			'FHEE__EventEspresso\core\libraries\rest_api\Calculated_Model_Fields__mapping',
89
+			$mapping
90
+		);
91
+	}
92
+
93
+
94
+	/**
95
+	 * Generates the schema for each calculation index in the calculation map.
96
+	 *
97
+	 * @return array
98
+	 * @throws UnexpectedEntityException
99
+	 */
100
+	protected function generateNewMappingSchema()
101
+	{
102
+		$schema_map = array();
103
+		foreach ($this->mapping() as $map_model => $map_for_model) {
104
+			/**
105
+			 * @var string $calculation_index
106
+			 * @var string $calculations_class
107
+			 */
108
+			foreach ($map_for_model as $calculation_index => $calculations_class) {
109
+				$calculator = $this->factory->createFromClassname($calculations_class);
110
+				$schema = call_user_func(array($calculator, 'schemaForCalculation'), $calculation_index);
111
+				if (! empty($schema)) {
112
+					$schema_map[ $map_model ][ $calculation_index ] = $schema;
113
+				}
114
+			}
115
+		}
116
+		return $schema_map;
117
+	}
118
+
119
+
120
+	/**
121
+	 * Gets the known calculated fields for model
122
+	 *
123
+	 * @param EEM_Base $model
124
+	 * @return array allowable values for this field
125
+	 */
126
+	public function retrieveCalculatedFieldsForModel(EEM_Base $model)
127
+	{
128
+		$mapping = $this->mapping();
129
+		if (isset($mapping[ $model->get_this_model_name() ])) {
130
+			return array_keys($mapping[ $model->get_this_model_name() ]);
131
+		}
132
+		return array();
133
+	}
134
+
135
+
136
+	/**
137
+	 * Returns the JsonSchema for the calculated fields on the given model.
138
+	 * @param EEM_Base $model
139
+	 * @return array
140
+	 */
141
+	public function getJsonSchemaForModel(EEM_Base $model)
142
+	{
143
+		if (! $this->mapping_schema) {
144
+			$this->mapping_schema = $this->generateNewMappingSchema();
145
+		}
146
+		return array(
147
+			'description' => esc_html__(
148
+				'Available calculated fields for this model.  Fields are only present in the response if explicitly requested',
149
+				'event_espresso'
150
+			),
151
+			'type' => 'object',
152
+			'properties' => isset($this->mapping_schema[ $model->get_this_model_name() ])
153
+				? $this->mapping_schema[ $model->get_this_model_name() ]
154
+				: array(),
155
+			'additionalProperties' => false,
156
+			'readonly' => true,
157
+		);
158
+	}
159
+
160
+
161
+	/**
162
+	 * Retrieves the value for this calculation
163
+	 *
164
+	 * @param EEM_Base $model
165
+	 * @param string $field_name
166
+	 * @param array $wpdb_row
167
+	 * @param $rest_request
168
+	 * @param BaseController $controller
169
+	 * @return mixed|null
170
+	 * @throws RestException
171
+	 * @throws UnexpectedEntityException
172
+	 */
173
+	public function retrieveCalculatedFieldValue(
174
+		EEM_Base $model,
175
+		$field_name,
176
+		$wpdb_row,
177
+		$rest_request,
178
+		Base $controller
179
+	) {
180
+		$mapping = $this->mapping();
181
+		if (
182
+			isset($mapping[ $model->get_this_model_name() ])
183
+			&& isset($mapping[ $model->get_this_model_name() ][ $field_name ])
184
+		) {
185
+			$classname = $mapping[ $model->get_this_model_name() ][ $field_name ];
186
+			$calculator = $this->factory->createFromClassname($classname);
187
+			$class_method_name = EEH_Inflector::camelize_all_but_first($field_name);
188
+			return call_user_func(array($calculator, $class_method_name), $wpdb_row, $rest_request, $controller);
189
+		}
190
+		throw new RestException(
191
+			'calculated_field_does_not_exist',
192
+			sprintf(
193
+				esc_html__('There is no calculated field %1$s on resource %2$s', 'event_espresso'),
194
+				$field_name,
195
+				$model->get_this_model_name()
196
+			)
197
+		);
198
+	}
199 199
 }
Please login to merge, or discard this patch.
core/libraries/rest_api/ModelVersionInfo.php 2 patches
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -114,10 +114,10 @@  discard block
 block discarded – undo
114 114
         foreach ($this->resource_changes as $version => $model_classnames) {
115 115
             foreach ($model_classnames as $model_classname => $extra_fields) {
116 116
                 foreach ($extra_fields as $fieldname => $field_data) {
117
-                    $this->resource_changes[ $model_classname ][ $fieldname ]['name'] = $fieldname;
117
+                    $this->resource_changes[$model_classname][$fieldname]['name'] = $fieldname;
118 118
                     foreach ($defaults as $attribute => $default_value) {
119
-                        if (! isset($this->resource_changes[ $model_classname ][ $fieldname ][ $attribute ])) {
120
-                            $this->resource_changes[ $model_classname ][ $fieldname ][ $attribute ] = $default_value;
119
+                        if ( ! isset($this->resource_changes[$model_classname][$fieldname][$attribute])) {
120
+                            $this->resource_changes[$model_classname][$fieldname][$attribute] = $default_value;
121 121
                         }
122 122
                     }
123 123
                 }
@@ -139,7 +139,7 @@  discard block
 block discarded – undo
139 139
             $model_changes = array();
140 140
             foreach ($this->modelChanges() as $version => $models_changed_in_version) {
141 141
                 if ($version <= EED_Core_Rest_Api::core_version() && $version > $this->requestedVersion()) {
142
-                    $model_changes[ $version ] = $models_changed_in_version;
142
+                    $model_changes[$version] = $models_changed_in_version;
143 143
                 }
144 144
             }
145 145
             $this->cached_model_changes_between_requested_version_and_current = $model_changes;
@@ -161,7 +161,7 @@  discard block
 block discarded – undo
161 161
             $resource_changes = array();
162 162
             foreach ($this->resourceChanges() as $version => $model_classnames) {
163 163
                 if ($version <= EED_Core_Rest_Api::core_version() && $version > $this->requestedVersion()) {
164
-                    $resource_changes[ $version ] = $model_classnames;
164
+                    $resource_changes[$version] = $model_classnames;
165 165
                 }
166 166
             }
167 167
             $this->cached_resource_changes_between_requested_version_and_current = $resource_changes;
@@ -212,7 +212,7 @@  discard block
 block discarded – undo
212 212
             foreach ($this->modelChangesBetweenRequestedVersionAndCurrent() as $version => $models_changed) {
213 213
                 foreach ($models_changed as $model_name => $new_indicator_or_fields_added) {
214 214
                     if ($new_indicator_or_fields_added === ModelVersionInfo::MODEL_ADDED) {
215
-                        unset($all_models_in_current_version[ $model_name ]);
215
+                        unset($all_models_in_current_version[$model_name]);
216 216
                     }
217 217
                 }
218 218
             }
@@ -237,7 +237,7 @@  discard block
 block discarded – undo
237 237
     public function isModelNameInThisVersion($model_name)
238 238
     {
239 239
         $model_names = $this->modelsForRequestedVersion();
240
-        if (isset($model_names[ $model_name ])) {
240
+        if (isset($model_names[$model_name])) {
241 241
             return true;
242 242
         } else {
243 243
             return false;
@@ -280,7 +280,7 @@  discard block
 block discarded – undo
280 280
      */
281 281
     public function fieldsOnModelInThisVersion($model)
282 282
     {
283
-        if (! isset($this->cached_fields_on_models[ $model->get_this_model_name() ])) {
283
+        if ( ! isset($this->cached_fields_on_models[$model->get_this_model_name()])) {
284 284
             // get all model changes between the requested version and current core version
285 285
             $changes = $this->modelChangesBetweenRequestedVersionAndCurrent();
286 286
             // fetch all fields currently on this model
@@ -288,12 +288,12 @@  discard block
 block discarded – undo
288 288
             // remove all fields that have been added since
289 289
             foreach ($changes as $version => $changes_in_version) {
290 290
                 if (
291
-                    isset($changes_in_version[ $model->get_this_model_name() ])
292
-                    && $changes_in_version[ $model->get_this_model_name() ] !== ModelVersionInfo::MODEL_ADDED
291
+                    isset($changes_in_version[$model->get_this_model_name()])
292
+                    && $changes_in_version[$model->get_this_model_name()] !== ModelVersionInfo::MODEL_ADDED
293 293
                 ) {
294 294
                     $current_fields = array_diff_key(
295 295
                         $current_fields,
296
-                        array_flip($changes_in_version[ $model->get_this_model_name() ])
296
+                        array_flip($changes_in_version[$model->get_this_model_name()])
297 297
                     );
298 298
                 }
299 299
             }
@@ -448,7 +448,7 @@  discard block
 block discarded – undo
448 448
         $relations = array();
449 449
         foreach ($model->relation_settings() as $relation_name => $relation_obj) {
450 450
             if ($this->isModelNameInThisVersion($relation_name)) {
451
-                $relations[ $relation_name ] = $relation_obj;
451
+                $relations[$relation_name] = $relation_obj;
452 452
             }
453 453
         }
454 454
         // filter the results, but use the old filter name
Please login to merge, or discard this patch.
Indentation   +437 added lines, -437 removed lines patch added patch discarded remove patch
@@ -21,441 +21,441 @@
 block discarded – undo
21 21
 class ModelVersionInfo
22 22
 {
23 23
 
24
-    /**
25
-     * Constant used in the $_model_changes array to indicate that a model
26
-     * was completely new in this version
27
-     */
28
-    const MODEL_ADDED = 'model_added_in_this_version';
29
-
30
-    /**
31
-     * Top-level keys are versions (major and minor version numbers, eg "4.6")
32
-     * next-level keys are model names (eg "Event") that underwent some change in that version
33
-     * and the value is either Model_Version_Info::model_added (indicating the model is completely NEW in this version),
34
-     * or it's an array where the values are model field names,
35
-     * or API resource properties (ie, non-model fields that appear in REST API results)
36
-     * If a version is missing then we don't know anything about what changes it introduced from the previous version
37
-     *
38
-     * @var array
39
-     */
40
-    protected $model_changes = array();
41
-
42
-    /**
43
-     * top-level keys are version numbers,
44
-     * next-level keys are model CLASSNAMES (even parent classnames),
45
-     * and next-level keys are extra resource properties to attach to those models' resources,
46
-     * and next-level key-value pairs, where the keys are:
47
-     * 'raw', 'type', 'nullable', 'table_alias', 'table_column',  'always_available'
48
-     *
49
-     * @var array
50
-     */
51
-    protected $resource_changes = array();
52
-
53
-    /**
54
-     * @var string indicating what version of the API was requested
55
-     * (eg although core might be at version 4.8.11, they may have sent a request
56
-     * for 4.6)
57
-     */
58
-    protected $requested_version = null;
59
-
60
-    /**
61
-     * Keys are model names, values are their classnames.
62
-     * We cache this so we only need to calculate this once per request
63
-     *
64
-     * @var array
65
-     */
66
-    protected $cached_models_for_requested_version = null;
67
-
68
-    /**
69
-     * @var array
70
-     */
71
-    protected $cached_model_changes_between_requested_version_and_current = null;
72
-
73
-    /**
74
-     * @var array
75
-     */
76
-    protected $cached_resource_changes_between_requested_version_and_current = null;
77
-
78
-    /**
79
-     * 2d array where top-level keys are model names, 2nd-level keys are field names
80
-     * and values are the actual field objects
81
-     *
82
-     * @var array
83
-     */
84
-    protected $cached_fields_on_models = array();
85
-
86
-
87
-    /**
88
-     * Model_Version_Info constructor.
89
-     *
90
-     * @param string $requested_version
91
-     */
92
-    public function __construct($requested_version)
93
-    {
94
-        $this->requested_version = (string) $requested_version;
95
-        $this->model_changes = array(
96
-            '4.8.29' => array(
97
-                // first version where the REST API is in EE core, so no need
98
-                // to specify how its different from the previous
99
-            ),
100
-        );
101
-        // setup data for "extra" fields added onto resources which don't actually exist on models
102
-        $this->resource_changes = apply_filters(
103
-            'FHEE__Model_Version_Info___construct__extra_resource_properties_for_models',
104
-            array()
105
-        );
106
-        $defaults = array(
107
-            'raw'              => false,
108
-            'type'             => 'N/A',
109
-            'nullable'         => true,
110
-            'table_alias'      => 'N/A',
111
-            'table_column'     => 'N/A',
112
-            'always_available' => true,
113
-        );
114
-        foreach ($this->resource_changes as $version => $model_classnames) {
115
-            foreach ($model_classnames as $model_classname => $extra_fields) {
116
-                foreach ($extra_fields as $fieldname => $field_data) {
117
-                    $this->resource_changes[ $model_classname ][ $fieldname ]['name'] = $fieldname;
118
-                    foreach ($defaults as $attribute => $default_value) {
119
-                        if (! isset($this->resource_changes[ $model_classname ][ $fieldname ][ $attribute ])) {
120
-                            $this->resource_changes[ $model_classname ][ $fieldname ][ $attribute ] = $default_value;
121
-                        }
122
-                    }
123
-                }
124
-            }
125
-        }
126
-    }
127
-
128
-
129
-    /**
130
-     * Returns a slice of Model_Version_Info::model_changes()'s array
131
-     * indicating exactly what changes happened between the current core version,
132
-     * and the version requested
133
-     *
134
-     * @return array
135
-     */
136
-    public function modelChangesBetweenRequestedVersionAndCurrent()
137
-    {
138
-        if ($this->cached_model_changes_between_requested_version_and_current === null) {
139
-            $model_changes = array();
140
-            foreach ($this->modelChanges() as $version => $models_changed_in_version) {
141
-                if ($version <= EED_Core_Rest_Api::core_version() && $version > $this->requestedVersion()) {
142
-                    $model_changes[ $version ] = $models_changed_in_version;
143
-                }
144
-            }
145
-            $this->cached_model_changes_between_requested_version_and_current = $model_changes;
146
-        }
147
-        return $this->cached_model_changes_between_requested_version_and_current;
148
-    }
149
-
150
-
151
-    /**
152
-     * Returns a slice of Model_Version_Info::model_changes()'s array
153
-     * indicating exactly what changes happened between the current core version,
154
-     * and the version requested
155
-     *
156
-     * @return array
157
-     */
158
-    public function resourceChangesBetweenRequestedVersionAndCurrent()
159
-    {
160
-        if ($this->cached_resource_changes_between_requested_version_and_current === null) {
161
-            $resource_changes = array();
162
-            foreach ($this->resourceChanges() as $version => $model_classnames) {
163
-                if ($version <= EED_Core_Rest_Api::core_version() && $version > $this->requestedVersion()) {
164
-                    $resource_changes[ $version ] = $model_classnames;
165
-                }
166
-            }
167
-            $this->cached_resource_changes_between_requested_version_and_current = $resource_changes;
168
-        }
169
-        return $this->cached_resource_changes_between_requested_version_and_current;
170
-    }
171
-
172
-
173
-    /**
174
-     * If a request was sent to 'wp-json/ee/v4.7/events' this would be '4.7'
175
-     *
176
-     * @return string like '4.6'
177
-     */
178
-    public function requestedVersion()
179
-    {
180
-        return $this->requested_version;
181
-    }
182
-
183
-
184
-    /**
185
-     * Returns an array describing how the models have changed in each version of core
186
-     * that supports the API (starting at 4.6)
187
-     * Top-level keys are versions (major and minor version numbers, eg "4.6")
188
-     * next-level keys are model names (eg "Event") that underwent some change in that version
189
-     * and the value is either NULL (indicating the model is completely NEW in this version),
190
-     * or it's an array where fields are value names.
191
-     * If a version is missing then we don't know anything about what changes it introduced from the previous version
192
-     *
193
-     * @return array
194
-     */
195
-    public function modelChanges()
196
-    {
197
-        return $this->model_changes;
198
-    }
199
-
200
-
201
-    /**
202
-     * Takes into account the requested version, and the current version, and
203
-     * what changed between the two, and tries to return.
204
-     * Analogous to EE_Registry::instance()->non_abstract_db_models
205
-     *
206
-     * @return array keys are model names, values are their classname
207
-     */
208
-    public function modelsForRequestedVersion()
209
-    {
210
-        if ($this->cached_models_for_requested_version === null) {
211
-            $all_models_in_current_version = EE_Registry::instance()->non_abstract_db_models;
212
-            foreach ($this->modelChangesBetweenRequestedVersionAndCurrent() as $version => $models_changed) {
213
-                foreach ($models_changed as $model_name => $new_indicator_or_fields_added) {
214
-                    if ($new_indicator_or_fields_added === ModelVersionInfo::MODEL_ADDED) {
215
-                        unset($all_models_in_current_version[ $model_name ]);
216
-                    }
217
-                }
218
-            }
219
-            $this->cached_models_for_requested_version = apply_filters(
220
-                'FHEE__EventEspresso_core_libraries_rest_api__models_for_requested_version',
221
-                $all_models_in_current_version,
222
-                $this
223
-            );
224
-        }
225
-        return $this->cached_models_for_requested_version;
226
-    }
227
-
228
-
229
-    /**
230
-     * Determines if this is a valid model name in the requested version.
231
-     * Similar to EE_Registry::instance()->is_model_name(), but takes the requested
232
-     * version's models into account
233
-     *
234
-     * @param string $model_name eg 'Event'
235
-     * @return boolean
236
-     */
237
-    public function isModelNameInThisVersion($model_name)
238
-    {
239
-        $model_names = $this->modelsForRequestedVersion();
240
-        if (isset($model_names[ $model_name ])) {
241
-            return true;
242
-        } else {
243
-            return false;
244
-        }
245
-    }
246
-
247
-
248
-    /**
249
-     * Wrapper for EE_Registry::instance()->load_model(), but takes the requested
250
-     * version's models into account
251
-     *
252
-     * @param string $model_name
253
-     * @return \EEM_Base
254
-     * @throws \EE_Error
255
-     */
256
-    public function loadModel($model_name)
257
-    {
258
-        if ($this->isModelNameInThisVersion($model_name)) {
259
-            return EE_Registry::instance()->load_model($model_name);
260
-        } else {
261
-            throw new \EE_Error(
262
-                sprintf(
263
-                    esc_html__(
264
-                        'Cannot load model "%1$s" because it does not exist in version %2$s of Event Espresso',
265
-                        'event_espresso'
266
-                    ),
267
-                    $model_name,
268
-                    $this->requestedVersion()
269
-                )
270
-            );
271
-        }
272
-    }
273
-
274
-
275
-    /**
276
-     * Gets all the fields that should exist on this model right now
277
-     *
278
-     * @param \EEM_Base $model
279
-     * @return array|\EE_Model_Field_Base[]
280
-     */
281
-    public function fieldsOnModelInThisVersion($model)
282
-    {
283
-        if (! isset($this->cached_fields_on_models[ $model->get_this_model_name() ])) {
284
-            // get all model changes between the requested version and current core version
285
-            $changes = $this->modelChangesBetweenRequestedVersionAndCurrent();
286
-            // fetch all fields currently on this model
287
-            $current_fields = $model->field_settings();
288
-            // remove all fields that have been added since
289
-            foreach ($changes as $version => $changes_in_version) {
290
-                if (
291
-                    isset($changes_in_version[ $model->get_this_model_name() ])
292
-                    && $changes_in_version[ $model->get_this_model_name() ] !== ModelVersionInfo::MODEL_ADDED
293
-                ) {
294
-                    $current_fields = array_diff_key(
295
-                        $current_fields,
296
-                        array_flip($changes_in_version[ $model->get_this_model_name() ])
297
-                    );
298
-                }
299
-            }
300
-            $this->cached_fields_on_models = $current_fields;
301
-        }
302
-        return $this->cached_fields_on_models;
303
-    }
304
-
305
-
306
-    /**
307
-     * Determines if $object is of one of the classes of $classes. Similar to
308
-     * in_array(), except this checks if $object is a subclass of the classnames provided
309
-     * in $classnames
310
-     *
311
-     * @param object $object
312
-     * @param array  $classnames
313
-     * @return boolean
314
-     */
315
-    public function isSubclassOfOne($object, $classnames)
316
-    {
317
-        foreach ($classnames as $classname) {
318
-            if (is_a($object, $classname)) {
319
-                return true;
320
-            }
321
-        }
322
-        return false;
323
-    }
324
-
325
-
326
-    /**
327
-     * Returns the list of model field classes that that the API basically ignores
328
-     *
329
-     * @return array
330
-     */
331
-    public function fieldsIgnored()
332
-    {
333
-        return apply_filters(
334
-            'FHEE__Controller_Model_Read_fields_ignored',
335
-            array()
336
-        );
337
-    }
338
-
339
-
340
-    /**
341
-     * If this field one that should be ignored by the API?
342
-     *
343
-     * @param EE_Model_Field_Base
344
-     * @return boolean
345
-     */
346
-    public function fieldIsIgnored($field_obj)
347
-    {
348
-        return $this->isSubclassOfOne($field_obj, $this->fieldsIgnored());
349
-    }
350
-
351
-
352
-    /**
353
-     * Returns the list of model field classes that have a "raw" and non-raw formats.
354
-     * Normally the "raw" versions are only accessible to those who can edit them.
355
-     *
356
-     * @return array an array of EE_Model_Field_Base child classnames
357
-     */
358
-    public function fieldsThatHaveRenderedFormat()
359
-    {
360
-        return apply_filters(
361
-            'FHEE__Controller_Model_Read__fields_raw',
362
-            array('EE_Post_Content_Field', 'EE_Full_HTML_Field')
363
-        );
364
-    }
365
-
366
-
367
-    /**
368
-     * If this field one that has a raw format
369
-     *
370
-     * @param EE_Model_Field_Base
371
-     * @return boolean
372
-     */
373
-    public function fieldHasRenderedFormat($field_obj)
374
-    {
375
-        return $this->isSubclassOfOne($field_obj, $this->fieldsThatHaveRenderedFormat());
376
-    }
377
-
378
-
379
-    /**
380
-     * Returns the list of model field classes that have a "_pretty" and non-pretty versions.
381
-     * The pretty version of the field is NOT query-able or editable, but requires no extra permissions
382
-     * to view
383
-     *
384
-     * @return array an array of EE_Model_Field_Base child classnames
385
-     */
386
-    public function fieldsThatHavePrettyFormat()
387
-    {
388
-        return apply_filters(
389
-            'FHEE__Controller_Model_Read__fields_pretty',
390
-            array('EE_Enum_Integer_Field', 'EE_Enum_Text_Field', 'EE_Money_Field')
391
-        );
392
-    }
393
-
394
-
395
-    /**
396
-     * If this field one that has a pretty equivalent
397
-     *
398
-     * @param EE_Model_Field_Base
399
-     * @return boolean
400
-     */
401
-    public function fieldHasPrettyFormat($field_obj)
402
-    {
403
-        return $this->isSubclassOfOne($field_obj, $this->fieldsThatHavePrettyFormat());
404
-    }
405
-
406
-
407
-    /**
408
-     * Returns an array describing what extra API resource properties have been added through the versions
409
-     *
410
-     * @return array @see $this->_extra_resource_properties_for_models
411
-     */
412
-    public function resourceChanges()
413
-    {
414
-        return $this->resource_changes;
415
-    }
416
-
417
-
418
-    /**
419
-     * Returns an array where keys are extra resource properties in this version of the API,
420
-     * and values are key-value pairs describing the new properties. @see Model_Version::_resource_changes
421
-     *
422
-     * @param \EEM_Base $model
423
-     * @return array
424
-     */
425
-    public function extraResourcePropertiesForModel($model)
426
-    {
427
-        $extra_properties = array();
428
-        foreach ($this->resourceChangesBetweenRequestedVersionAndCurrent() as $version => $model_classnames) {
429
-            foreach ($model_classnames as $model_classname => $properties_added_in_this_version) {
430
-                if (is_subclass_of($model, $model_classname)) {
431
-                    $extra_properties = array_merge($extra_properties, $properties_added_in_this_version);
432
-                }
433
-            }
434
-        }
435
-        return $extra_properties;
436
-    }
437
-
438
-
439
-    /**
440
-     * Gets all the related models for the specified model. It's good to use this
441
-     * in case this model didn't exist for this version or something
442
-     *
443
-     * @param \EEM_Base $model
444
-     * @return \EE_Model_Relation_Base[]
445
-     */
446
-    public function relationSettings(\EEM_Base $model)
447
-    {
448
-        $relations = array();
449
-        foreach ($model->relation_settings() as $relation_name => $relation_obj) {
450
-            if ($this->isModelNameInThisVersion($relation_name)) {
451
-                $relations[ $relation_name ] = $relation_obj;
452
-            }
453
-        }
454
-        // filter the results, but use the old filter name
455
-        return apply_filters(
456
-            'FHEE__Read__create_entity_from_wpdb_result__related_models_to_include',
457
-            $relations,
458
-            $model
459
-        );
460
-    }
24
+	/**
25
+	 * Constant used in the $_model_changes array to indicate that a model
26
+	 * was completely new in this version
27
+	 */
28
+	const MODEL_ADDED = 'model_added_in_this_version';
29
+
30
+	/**
31
+	 * Top-level keys are versions (major and minor version numbers, eg "4.6")
32
+	 * next-level keys are model names (eg "Event") that underwent some change in that version
33
+	 * and the value is either Model_Version_Info::model_added (indicating the model is completely NEW in this version),
34
+	 * or it's an array where the values are model field names,
35
+	 * or API resource properties (ie, non-model fields that appear in REST API results)
36
+	 * If a version is missing then we don't know anything about what changes it introduced from the previous version
37
+	 *
38
+	 * @var array
39
+	 */
40
+	protected $model_changes = array();
41
+
42
+	/**
43
+	 * top-level keys are version numbers,
44
+	 * next-level keys are model CLASSNAMES (even parent classnames),
45
+	 * and next-level keys are extra resource properties to attach to those models' resources,
46
+	 * and next-level key-value pairs, where the keys are:
47
+	 * 'raw', 'type', 'nullable', 'table_alias', 'table_column',  'always_available'
48
+	 *
49
+	 * @var array
50
+	 */
51
+	protected $resource_changes = array();
52
+
53
+	/**
54
+	 * @var string indicating what version of the API was requested
55
+	 * (eg although core might be at version 4.8.11, they may have sent a request
56
+	 * for 4.6)
57
+	 */
58
+	protected $requested_version = null;
59
+
60
+	/**
61
+	 * Keys are model names, values are their classnames.
62
+	 * We cache this so we only need to calculate this once per request
63
+	 *
64
+	 * @var array
65
+	 */
66
+	protected $cached_models_for_requested_version = null;
67
+
68
+	/**
69
+	 * @var array
70
+	 */
71
+	protected $cached_model_changes_between_requested_version_and_current = null;
72
+
73
+	/**
74
+	 * @var array
75
+	 */
76
+	protected $cached_resource_changes_between_requested_version_and_current = null;
77
+
78
+	/**
79
+	 * 2d array where top-level keys are model names, 2nd-level keys are field names
80
+	 * and values are the actual field objects
81
+	 *
82
+	 * @var array
83
+	 */
84
+	protected $cached_fields_on_models = array();
85
+
86
+
87
+	/**
88
+	 * Model_Version_Info constructor.
89
+	 *
90
+	 * @param string $requested_version
91
+	 */
92
+	public function __construct($requested_version)
93
+	{
94
+		$this->requested_version = (string) $requested_version;
95
+		$this->model_changes = array(
96
+			'4.8.29' => array(
97
+				// first version where the REST API is in EE core, so no need
98
+				// to specify how its different from the previous
99
+			),
100
+		);
101
+		// setup data for "extra" fields added onto resources which don't actually exist on models
102
+		$this->resource_changes = apply_filters(
103
+			'FHEE__Model_Version_Info___construct__extra_resource_properties_for_models',
104
+			array()
105
+		);
106
+		$defaults = array(
107
+			'raw'              => false,
108
+			'type'             => 'N/A',
109
+			'nullable'         => true,
110
+			'table_alias'      => 'N/A',
111
+			'table_column'     => 'N/A',
112
+			'always_available' => true,
113
+		);
114
+		foreach ($this->resource_changes as $version => $model_classnames) {
115
+			foreach ($model_classnames as $model_classname => $extra_fields) {
116
+				foreach ($extra_fields as $fieldname => $field_data) {
117
+					$this->resource_changes[ $model_classname ][ $fieldname ]['name'] = $fieldname;
118
+					foreach ($defaults as $attribute => $default_value) {
119
+						if (! isset($this->resource_changes[ $model_classname ][ $fieldname ][ $attribute ])) {
120
+							$this->resource_changes[ $model_classname ][ $fieldname ][ $attribute ] = $default_value;
121
+						}
122
+					}
123
+				}
124
+			}
125
+		}
126
+	}
127
+
128
+
129
+	/**
130
+	 * Returns a slice of Model_Version_Info::model_changes()'s array
131
+	 * indicating exactly what changes happened between the current core version,
132
+	 * and the version requested
133
+	 *
134
+	 * @return array
135
+	 */
136
+	public function modelChangesBetweenRequestedVersionAndCurrent()
137
+	{
138
+		if ($this->cached_model_changes_between_requested_version_and_current === null) {
139
+			$model_changes = array();
140
+			foreach ($this->modelChanges() as $version => $models_changed_in_version) {
141
+				if ($version <= EED_Core_Rest_Api::core_version() && $version > $this->requestedVersion()) {
142
+					$model_changes[ $version ] = $models_changed_in_version;
143
+				}
144
+			}
145
+			$this->cached_model_changes_between_requested_version_and_current = $model_changes;
146
+		}
147
+		return $this->cached_model_changes_between_requested_version_and_current;
148
+	}
149
+
150
+
151
+	/**
152
+	 * Returns a slice of Model_Version_Info::model_changes()'s array
153
+	 * indicating exactly what changes happened between the current core version,
154
+	 * and the version requested
155
+	 *
156
+	 * @return array
157
+	 */
158
+	public function resourceChangesBetweenRequestedVersionAndCurrent()
159
+	{
160
+		if ($this->cached_resource_changes_between_requested_version_and_current === null) {
161
+			$resource_changes = array();
162
+			foreach ($this->resourceChanges() as $version => $model_classnames) {
163
+				if ($version <= EED_Core_Rest_Api::core_version() && $version > $this->requestedVersion()) {
164
+					$resource_changes[ $version ] = $model_classnames;
165
+				}
166
+			}
167
+			$this->cached_resource_changes_between_requested_version_and_current = $resource_changes;
168
+		}
169
+		return $this->cached_resource_changes_between_requested_version_and_current;
170
+	}
171
+
172
+
173
+	/**
174
+	 * If a request was sent to 'wp-json/ee/v4.7/events' this would be '4.7'
175
+	 *
176
+	 * @return string like '4.6'
177
+	 */
178
+	public function requestedVersion()
179
+	{
180
+		return $this->requested_version;
181
+	}
182
+
183
+
184
+	/**
185
+	 * Returns an array describing how the models have changed in each version of core
186
+	 * that supports the API (starting at 4.6)
187
+	 * Top-level keys are versions (major and minor version numbers, eg "4.6")
188
+	 * next-level keys are model names (eg "Event") that underwent some change in that version
189
+	 * and the value is either NULL (indicating the model is completely NEW in this version),
190
+	 * or it's an array where fields are value names.
191
+	 * If a version is missing then we don't know anything about what changes it introduced from the previous version
192
+	 *
193
+	 * @return array
194
+	 */
195
+	public function modelChanges()
196
+	{
197
+		return $this->model_changes;
198
+	}
199
+
200
+
201
+	/**
202
+	 * Takes into account the requested version, and the current version, and
203
+	 * what changed between the two, and tries to return.
204
+	 * Analogous to EE_Registry::instance()->non_abstract_db_models
205
+	 *
206
+	 * @return array keys are model names, values are their classname
207
+	 */
208
+	public function modelsForRequestedVersion()
209
+	{
210
+		if ($this->cached_models_for_requested_version === null) {
211
+			$all_models_in_current_version = EE_Registry::instance()->non_abstract_db_models;
212
+			foreach ($this->modelChangesBetweenRequestedVersionAndCurrent() as $version => $models_changed) {
213
+				foreach ($models_changed as $model_name => $new_indicator_or_fields_added) {
214
+					if ($new_indicator_or_fields_added === ModelVersionInfo::MODEL_ADDED) {
215
+						unset($all_models_in_current_version[ $model_name ]);
216
+					}
217
+				}
218
+			}
219
+			$this->cached_models_for_requested_version = apply_filters(
220
+				'FHEE__EventEspresso_core_libraries_rest_api__models_for_requested_version',
221
+				$all_models_in_current_version,
222
+				$this
223
+			);
224
+		}
225
+		return $this->cached_models_for_requested_version;
226
+	}
227
+
228
+
229
+	/**
230
+	 * Determines if this is a valid model name in the requested version.
231
+	 * Similar to EE_Registry::instance()->is_model_name(), but takes the requested
232
+	 * version's models into account
233
+	 *
234
+	 * @param string $model_name eg 'Event'
235
+	 * @return boolean
236
+	 */
237
+	public function isModelNameInThisVersion($model_name)
238
+	{
239
+		$model_names = $this->modelsForRequestedVersion();
240
+		if (isset($model_names[ $model_name ])) {
241
+			return true;
242
+		} else {
243
+			return false;
244
+		}
245
+	}
246
+
247
+
248
+	/**
249
+	 * Wrapper for EE_Registry::instance()->load_model(), but takes the requested
250
+	 * version's models into account
251
+	 *
252
+	 * @param string $model_name
253
+	 * @return \EEM_Base
254
+	 * @throws \EE_Error
255
+	 */
256
+	public function loadModel($model_name)
257
+	{
258
+		if ($this->isModelNameInThisVersion($model_name)) {
259
+			return EE_Registry::instance()->load_model($model_name);
260
+		} else {
261
+			throw new \EE_Error(
262
+				sprintf(
263
+					esc_html__(
264
+						'Cannot load model "%1$s" because it does not exist in version %2$s of Event Espresso',
265
+						'event_espresso'
266
+					),
267
+					$model_name,
268
+					$this->requestedVersion()
269
+				)
270
+			);
271
+		}
272
+	}
273
+
274
+
275
+	/**
276
+	 * Gets all the fields that should exist on this model right now
277
+	 *
278
+	 * @param \EEM_Base $model
279
+	 * @return array|\EE_Model_Field_Base[]
280
+	 */
281
+	public function fieldsOnModelInThisVersion($model)
282
+	{
283
+		if (! isset($this->cached_fields_on_models[ $model->get_this_model_name() ])) {
284
+			// get all model changes between the requested version and current core version
285
+			$changes = $this->modelChangesBetweenRequestedVersionAndCurrent();
286
+			// fetch all fields currently on this model
287
+			$current_fields = $model->field_settings();
288
+			// remove all fields that have been added since
289
+			foreach ($changes as $version => $changes_in_version) {
290
+				if (
291
+					isset($changes_in_version[ $model->get_this_model_name() ])
292
+					&& $changes_in_version[ $model->get_this_model_name() ] !== ModelVersionInfo::MODEL_ADDED
293
+				) {
294
+					$current_fields = array_diff_key(
295
+						$current_fields,
296
+						array_flip($changes_in_version[ $model->get_this_model_name() ])
297
+					);
298
+				}
299
+			}
300
+			$this->cached_fields_on_models = $current_fields;
301
+		}
302
+		return $this->cached_fields_on_models;
303
+	}
304
+
305
+
306
+	/**
307
+	 * Determines if $object is of one of the classes of $classes. Similar to
308
+	 * in_array(), except this checks if $object is a subclass of the classnames provided
309
+	 * in $classnames
310
+	 *
311
+	 * @param object $object
312
+	 * @param array  $classnames
313
+	 * @return boolean
314
+	 */
315
+	public function isSubclassOfOne($object, $classnames)
316
+	{
317
+		foreach ($classnames as $classname) {
318
+			if (is_a($object, $classname)) {
319
+				return true;
320
+			}
321
+		}
322
+		return false;
323
+	}
324
+
325
+
326
+	/**
327
+	 * Returns the list of model field classes that that the API basically ignores
328
+	 *
329
+	 * @return array
330
+	 */
331
+	public function fieldsIgnored()
332
+	{
333
+		return apply_filters(
334
+			'FHEE__Controller_Model_Read_fields_ignored',
335
+			array()
336
+		);
337
+	}
338
+
339
+
340
+	/**
341
+	 * If this field one that should be ignored by the API?
342
+	 *
343
+	 * @param EE_Model_Field_Base
344
+	 * @return boolean
345
+	 */
346
+	public function fieldIsIgnored($field_obj)
347
+	{
348
+		return $this->isSubclassOfOne($field_obj, $this->fieldsIgnored());
349
+	}
350
+
351
+
352
+	/**
353
+	 * Returns the list of model field classes that have a "raw" and non-raw formats.
354
+	 * Normally the "raw" versions are only accessible to those who can edit them.
355
+	 *
356
+	 * @return array an array of EE_Model_Field_Base child classnames
357
+	 */
358
+	public function fieldsThatHaveRenderedFormat()
359
+	{
360
+		return apply_filters(
361
+			'FHEE__Controller_Model_Read__fields_raw',
362
+			array('EE_Post_Content_Field', 'EE_Full_HTML_Field')
363
+		);
364
+	}
365
+
366
+
367
+	/**
368
+	 * If this field one that has a raw format
369
+	 *
370
+	 * @param EE_Model_Field_Base
371
+	 * @return boolean
372
+	 */
373
+	public function fieldHasRenderedFormat($field_obj)
374
+	{
375
+		return $this->isSubclassOfOne($field_obj, $this->fieldsThatHaveRenderedFormat());
376
+	}
377
+
378
+
379
+	/**
380
+	 * Returns the list of model field classes that have a "_pretty" and non-pretty versions.
381
+	 * The pretty version of the field is NOT query-able or editable, but requires no extra permissions
382
+	 * to view
383
+	 *
384
+	 * @return array an array of EE_Model_Field_Base child classnames
385
+	 */
386
+	public function fieldsThatHavePrettyFormat()
387
+	{
388
+		return apply_filters(
389
+			'FHEE__Controller_Model_Read__fields_pretty',
390
+			array('EE_Enum_Integer_Field', 'EE_Enum_Text_Field', 'EE_Money_Field')
391
+		);
392
+	}
393
+
394
+
395
+	/**
396
+	 * If this field one that has a pretty equivalent
397
+	 *
398
+	 * @param EE_Model_Field_Base
399
+	 * @return boolean
400
+	 */
401
+	public function fieldHasPrettyFormat($field_obj)
402
+	{
403
+		return $this->isSubclassOfOne($field_obj, $this->fieldsThatHavePrettyFormat());
404
+	}
405
+
406
+
407
+	/**
408
+	 * Returns an array describing what extra API resource properties have been added through the versions
409
+	 *
410
+	 * @return array @see $this->_extra_resource_properties_for_models
411
+	 */
412
+	public function resourceChanges()
413
+	{
414
+		return $this->resource_changes;
415
+	}
416
+
417
+
418
+	/**
419
+	 * Returns an array where keys are extra resource properties in this version of the API,
420
+	 * and values are key-value pairs describing the new properties. @see Model_Version::_resource_changes
421
+	 *
422
+	 * @param \EEM_Base $model
423
+	 * @return array
424
+	 */
425
+	public function extraResourcePropertiesForModel($model)
426
+	{
427
+		$extra_properties = array();
428
+		foreach ($this->resourceChangesBetweenRequestedVersionAndCurrent() as $version => $model_classnames) {
429
+			foreach ($model_classnames as $model_classname => $properties_added_in_this_version) {
430
+				if (is_subclass_of($model, $model_classname)) {
431
+					$extra_properties = array_merge($extra_properties, $properties_added_in_this_version);
432
+				}
433
+			}
434
+		}
435
+		return $extra_properties;
436
+	}
437
+
438
+
439
+	/**
440
+	 * Gets all the related models for the specified model. It's good to use this
441
+	 * in case this model didn't exist for this version or something
442
+	 *
443
+	 * @param \EEM_Base $model
444
+	 * @return \EE_Model_Relation_Base[]
445
+	 */
446
+	public function relationSettings(\EEM_Base $model)
447
+	{
448
+		$relations = array();
449
+		foreach ($model->relation_settings() as $relation_name => $relation_obj) {
450
+			if ($this->isModelNameInThisVersion($relation_name)) {
451
+				$relations[ $relation_name ] = $relation_obj;
452
+			}
453
+		}
454
+		// filter the results, but use the old filter name
455
+		return apply_filters(
456
+			'FHEE__Read__create_entity_from_wpdb_result__related_models_to_include',
457
+			$relations,
458
+			$model
459
+		);
460
+	}
461 461
 }
Please login to merge, or discard this patch.
core/libraries/messages/EE_Messages_Base.lib.php 2 patches
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -196,11 +196,11 @@  discard block
 block discarded – undo
196 196
             ! empty($messenger)
197 197
             && $Message_Resource_Manager->is_message_type_active_for_messenger($messenger, $this->name)
198 198
         ) {
199
-            $settings_to_use = $active_messengers[ $messenger ]['settings'][ $messenger . '-message_types' ];
199
+            $settings_to_use = $active_messengers[$messenger]['settings'][$messenger.'-message_types'];
200 200
         }
201 201
 
202
-        $this->_existing_admin_settings = isset($settings_to_use[ $this->name ]['settings'])
203
-            ? $settings_to_use[ $this->name ]['settings']
202
+        $this->_existing_admin_settings = isset($settings_to_use[$this->name]['settings'])
203
+            ? $settings_to_use[$this->name]['settings']
204 204
             : null;
205 205
     }
206 206
 
@@ -240,7 +240,7 @@  discard block
 block discarded – undo
240 240
     public function get_valid_shortcodes()
241 241
     {
242 242
         $valid_shortcodes = apply_filters(
243
-            'FHEE__' . get_class($this) . '__get_valid_shortcodes',
243
+            'FHEE__'.get_class($this).'__get_valid_shortcodes',
244 244
             $this->_valid_shortcodes,
245 245
             $this
246 246
         );
@@ -283,19 +283,19 @@  discard block
 block discarded – undo
283 283
     protected function _get_admin_page_content($page, $action, $extra, $actives)
284 284
     {
285 285
         // we can also further refine the context by action (if present).
286
-        if (!empty($action)) {
287
-            $page = $page . '_' . $action;
286
+        if ( ! empty($action)) {
287
+            $page = $page.'_'.$action;
288 288
         }
289 289
 
290
-        if (!isset($this->admin_registered_pages[ $page ])) {
290
+        if ( ! isset($this->admin_registered_pages[$page])) {
291 291
             // todo: a place to throw an exception?
292 292
             // We need to indicate there is no registered page so this function is not being called correctly.
293 293
             return false;
294 294
         }
295 295
         // k made it here so let's call the method
296 296
         $content = call_user_func_array(
297
-            array( $this, '_get_admin_content_' . $page ),
298
-            array( $actives, $extra )
297
+            array($this, '_get_admin_content_'.$page),
298
+            array($actives, $extra)
299 299
         );
300 300
         if ($content === false) {
301 301
             // todo this needs to be an exception once we've got exceptions in place.
Please login to merge, or discard this patch.
Indentation   +265 added lines, -265 removed lines patch added patch discarded remove patch
@@ -14,44 +14,44 @@  discard block
 block discarded – undo
14 14
 abstract class EE_Messages_Base extends EE_Base
15 15
 {
16 16
 
17
-    /** DETAILS PROPERTIES **/
18
-    /**
19
-     * The following are used to hold details on the type for reference (i.e. on admin screens)
20
-     * and also used by the EE_message_type object to figure out where to get template data.
21
-     */
22
-    public $name;
23
-    public $description;
24
-    protected $_messages_item_type; // messenger OR message_type?
25
-
26
-
27
-    /**
28
-     * This is an array describing the ui facing labels
29
-     * that will be used whenever the messenger is referenced in the ui
30
-     *
31
-     * array(
32
-     *  'singular' => esc_html__('something'),
33
-     *  'plural' => esc_html__('somethings')
34
-     * )
35
-     *
36
-     * @var array
37
-     */
38
-    public $label;
39
-
40
-
41
-
42
-
43
-    /**
44
-     * This property when set will hold the slugs of all EE admin pages that we will need to retrieve fields for
45
-     * (and used to determine which callback method to call from the child class)
46
-     *
47
-     * structure should be
48
-     * array(
49
-     * 'page_action' => true
50
-     * )
51
-     *
17
+	/** DETAILS PROPERTIES **/
18
+	/**
19
+	 * The following are used to hold details on the type for reference (i.e. on admin screens)
20
+	 * and also used by the EE_message_type object to figure out where to get template data.
21
+	 */
22
+	public $name;
23
+	public $description;
24
+	protected $_messages_item_type; // messenger OR message_type?
25
+
26
+
27
+	/**
28
+	 * This is an array describing the ui facing labels
29
+	 * that will be used whenever the messenger is referenced in the ui
30
+	 *
31
+	 * array(
32
+	 *  'singular' => esc_html__('something'),
33
+	 *  'plural' => esc_html__('somethings')
34
+	 * )
35
+	 *
36
+	 * @var array
37
+	 */
38
+	public $label;
39
+
40
+
41
+
42
+
43
+	/**
44
+	 * This property when set will hold the slugs of all EE admin pages that we will need to retrieve fields for
45
+	 * (and used to determine which callback method to call from the child class)
46
+	 *
47
+	 * structure should be
48
+	 * array(
49
+	 * 'page_action' => true
50
+	 * )
51
+	 *
52 52
 *@var array
53
-     */
54
-    public $admin_registered_pages = array();
53
+	 */
54
+	public $admin_registered_pages = array();
55 55
 
56 56
 
57 57
 
@@ -60,265 +60,265 @@  discard block
 block discarded – undo
60 60
 
61 61
 
62 62
 
63
-    /**
64
-     * this property holds any specific fields for holding any settings related to a messenger (if any needed)
65
-     * @var array
66
-     */
67
-    protected $_admin_settings_fields = array();
63
+	/**
64
+	 * this property holds any specific fields for holding any settings related to a messenger (if any needed)
65
+	 * @var array
66
+	 */
67
+	protected $_admin_settings_fields = array();
68 68
 
69 69
 
70 70
 
71 71
 
72 72
 
73
-    /**
74
-     * this property will hold any existing settings that may have been set in the admin.
75
-     * @var array
76
-     */
77
-    protected $_existing_admin_settings = array();
73
+	/**
74
+	 * this property will hold any existing settings that may have been set in the admin.
75
+	 * @var array
76
+	 */
77
+	protected $_existing_admin_settings = array();
78 78
 
79 79
 
80 80
 
81 81
 
82 82
 
83
-    /**
84
-     * this property will hold an array of valid shortcodes for this message type and messengers.
85
-     * #For Message Types:
86
-     * This is an array of strings that correspond to defined EE_Shortcode libraries and per context.
87
-     * For example:
88
-     * array( 'admin' => array('transaction', 'event', 'attendee') )
89
-     * corresponds to 'EE_Transaction_Shortcodes.lib.php, EE_Event_Shortcodes.lib.php, EE_Attendee_Shortcodes.lib.php'
90
-     * for the admin context;
91
-     *
92
-     *
93
-     * #For Messengers:
94
-     * For example:
95
-     * array('subject' => array('transaction', 'event', 'attendee'))
96
-     * corresponds to 'EE_Transaction_Shortcodes.lib.php, EE_Event_Shortcodes.lib.php, EE_Attendee_Shortcodes.lib.php'
97
-     * for the 'subject' field;
98
-     * NOTE:  by default, with messengers, if the valid shortcodes for a field is left blank,
99
-     * that field will inherit whatever are set as valid shortcodes by message_type.
100
-     * This is so messenger can set specific valid codes for fields and leave other
101
-     * valid shortcodes up to the message type matched with the messenger.
102
-     *
103
-     * @access protected
104
-     * @var array
105
-     */
106
-    protected $_valid_shortcodes = array();
83
+	/**
84
+	 * this property will hold an array of valid shortcodes for this message type and messengers.
85
+	 * #For Message Types:
86
+	 * This is an array of strings that correspond to defined EE_Shortcode libraries and per context.
87
+	 * For example:
88
+	 * array( 'admin' => array('transaction', 'event', 'attendee') )
89
+	 * corresponds to 'EE_Transaction_Shortcodes.lib.php, EE_Event_Shortcodes.lib.php, EE_Attendee_Shortcodes.lib.php'
90
+	 * for the admin context;
91
+	 *
92
+	 *
93
+	 * #For Messengers:
94
+	 * For example:
95
+	 * array('subject' => array('transaction', 'event', 'attendee'))
96
+	 * corresponds to 'EE_Transaction_Shortcodes.lib.php, EE_Event_Shortcodes.lib.php, EE_Attendee_Shortcodes.lib.php'
97
+	 * for the 'subject' field;
98
+	 * NOTE:  by default, with messengers, if the valid shortcodes for a field is left blank,
99
+	 * that field will inherit whatever are set as valid shortcodes by message_type.
100
+	 * This is so messenger can set specific valid codes for fields and leave other
101
+	 * valid shortcodes up to the message type matched with the messenger.
102
+	 *
103
+	 * @access protected
104
+	 * @var array
105
+	 */
106
+	protected $_valid_shortcodes = array();
107 107
 
108 108
 
109 109
 
110 110
 
111 111
 
112
-    public function __construct()
113
-    {
114
-        $this->_set_admin_settings_fields();
115
-        $this->_set_valid_shortcodes();
116
-        $this->_set_admin_pages();
117
-    }
112
+	public function __construct()
113
+	{
114
+		$this->_set_admin_settings_fields();
115
+		$this->_set_valid_shortcodes();
116
+		$this->_set_admin_pages();
117
+	}
118 118
 
119 119
 
120 120
 
121 121
 
122 122
 
123
-    /**
124
-     * sets the _admin_settings_fields property which needs to be defined by child classes.
125
-     * You will want to set the _admin_settings_fields properties as a multi-dimensional array with the following format
126
-     * array(
127
-     *      {field_name - also used for setting index} => array(
128
-     *          'field_type' => {type of field: 'text', 'textarea', 'checkbox'},
129
-     *          'value_type' => {type of value: 'string', 'int', 'array', 'bool'},
130
-     *          'required' => {bool, required or not},
131
-     *          'validation' => {bool, true if we want validation, false if not},
132
-     *          'format' => {%d, or %s},
133
-     *          'label' => {label for the field, make sure it's localized},
134
-     *          'default' => {default value for the setting}
135
-     *      ),
136
-     * );
137
-     *
138
-     * @abstract
139
-     * @access protected
140
-     * @return void
141
-     */
142
-    abstract protected function _set_admin_settings_fields();
123
+	/**
124
+	 * sets the _admin_settings_fields property which needs to be defined by child classes.
125
+	 * You will want to set the _admin_settings_fields properties as a multi-dimensional array with the following format
126
+	 * array(
127
+	 *      {field_name - also used for setting index} => array(
128
+	 *          'field_type' => {type of field: 'text', 'textarea', 'checkbox'},
129
+	 *          'value_type' => {type of value: 'string', 'int', 'array', 'bool'},
130
+	 *          'required' => {bool, required or not},
131
+	 *          'validation' => {bool, true if we want validation, false if not},
132
+	 *          'format' => {%d, or %s},
133
+	 *          'label' => {label for the field, make sure it's localized},
134
+	 *          'default' => {default value for the setting}
135
+	 *      ),
136
+	 * );
137
+	 *
138
+	 * @abstract
139
+	 * @access protected
140
+	 * @return void
141
+	 */
142
+	abstract protected function _set_admin_settings_fields();
143 143
 
144 144
 
145 145
 
146 146
 
147 147
 
148
-    /**
149
-     * sets any properties on whether a message type or messenger interface shows up on a ee administration page.
150
-     * Child classes have to define this method but don't necessarily have to set the flags
151
-     * as they will be set to false by default.
152
-     *
153
-     * Child classes use this method to set the `_admin_registered_page` property.
154
-     * That property is to indicate what EE admin pages we have a corresponding callback for in the child class
155
-     * so Message Type/messenger fields/content is included on that admin page.
156
-     *
157
-     * @abstract
158
-     * @access protected
159
-     * @return void
160
-     */
161
-    abstract protected function _set_admin_pages();
148
+	/**
149
+	 * sets any properties on whether a message type or messenger interface shows up on a ee administration page.
150
+	 * Child classes have to define this method but don't necessarily have to set the flags
151
+	 * as they will be set to false by default.
152
+	 *
153
+	 * Child classes use this method to set the `_admin_registered_page` property.
154
+	 * That property is to indicate what EE admin pages we have a corresponding callback for in the child class
155
+	 * so Message Type/messenger fields/content is included on that admin page.
156
+	 *
157
+	 * @abstract
158
+	 * @access protected
159
+	 * @return void
160
+	 */
161
+	abstract protected function _set_admin_pages();
162 162
 
163 163
 
164 164
 
165 165
 
166 166
 
167
-    /**
168
-     * Child classes must declare the $_valid_shortcodes property using this method.
169
-     * See comments for $_valid_shortcodes property for details on what it is used for.
170
-     *
171
-     * @access protected
172
-     * @return void
173
-     */
174
-    abstract protected function _set_valid_shortcodes();
167
+	/**
168
+	 * Child classes must declare the $_valid_shortcodes property using this method.
169
+	 * See comments for $_valid_shortcodes property for details on what it is used for.
170
+	 *
171
+	 * @access protected
172
+	 * @return void
173
+	 */
174
+	abstract protected function _set_valid_shortcodes();
175 175
 
176 176
 
177 177
 
178
-    /**
179
-     * sets the _existing_admin_settings property can be overridden by child classes.
180
-     * We do this so we only do database calls if needed.
181
-     *
182
-     * @access protected
183
-     * @param string $messenger
184
-     */
185
-    protected function _set_existing_admin_settings($messenger = '')
186
-    {
187
-        /** @var EE_Message_Resource_Manager $Message_Resource_Manager */
188
-        $Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
189
-        $active_messengers = $Message_Resource_Manager->get_active_messengers_option();
190
-        $settings_to_use = $active_messengers;
191
-
192
-        /**
193
-         * This determines what will be used for the getting the settings.
194
-         */
195
-        if (
196
-            ! empty($messenger)
197
-            && $Message_Resource_Manager->is_message_type_active_for_messenger($messenger, $this->name)
198
-        ) {
199
-            $settings_to_use = $active_messengers[ $messenger ]['settings'][ $messenger . '-message_types' ];
200
-        }
201
-
202
-        $this->_existing_admin_settings = isset($settings_to_use[ $this->name ]['settings'])
203
-            ? $settings_to_use[ $this->name ]['settings']
204
-            : null;
205
-    }
206
-
207
-
208
-
209
-
210
-
211
-
212
-    /**
213
-     * get_existing_admin_settings
214
-     * (if needed) sets and returns the _existing_admin_settings property.
215
-     *
216
-     * @access public
217
-     * @param string $messenger
218
-     * @return array          settings
219
-     */
220
-    public function get_existing_admin_settings($messenger = '')
221
-    {
222
-        // if admin_settings property empty lets try setting it.
223
-        if (method_exists($this, '_set_existing_admin_settings') && empty($this->_existing_admin_settings)) {
224
-            $this->_set_existing_admin_settings($messenger);
225
-        }
226
-        return property_exists($this, '_existing_admin_settings')
227
-            ? $this->_existing_admin_settings
228
-            : null;
229
-    }
230
-
231
-
232
-
233
-
234
-
235
-
236
-    /**
237
-     * This returns the array of valid shortcodes for a message type or messenger as set by the child in the $_valid_shortcode property.
238
-     * @return array   an array of valid shortcodes.
239
-     */
240
-    public function get_valid_shortcodes()
241
-    {
242
-        $valid_shortcodes = apply_filters(
243
-            'FHEE__' . get_class($this) . '__get_valid_shortcodes',
244
-            $this->_valid_shortcodes,
245
-            $this
246
-        );
247
-        // The below filter applies to ALL messengers and message types so use with care!
248
-        $valid_shortcodes = apply_filters('FHEE__EE_Messages_Base__get_valid_shortcodes', $valid_shortcodes, $this);
249
-        return $valid_shortcodes;
250
-    }
251
-
252
-
253
-
254
-
255
-    /**
256
-     * getter that returns the protected admin_settings_fields property
257
-     *
258
-     * @access public
259
-     * @return array admin settings fields
260
-     */
261
-    public function get_admin_settings_fields()
262
-    {
263
-        return $this->_admin_settings_fields;
264
-    }
265
-
266
-
267
-
268
-
269
-
270
-    /**
271
-     * this public method accepts a page slug (for an EE_admin page)
272
-     * and will return the response from the child class callback function
273
-     * if that page is registered via the `_admin_registered_page` property set by the child class.
274
-     *
275
-     * @param string $page the slug of the EE admin page
276
-     * @param array $actives an array of active message type (or messenger) objects.
277
-     * @param string $action the page action (to allow for more specific handling - i.e. edit vs. add pages)
278
-     * @param array $extra This is just an extra argument that can be used
279
-     *                     to pass additional data for setting up page content.
280
-     * @access protected
281
-     * @return string $content for page.
282
-     */
283
-    protected function _get_admin_page_content($page, $action, $extra, $actives)
284
-    {
285
-        // we can also further refine the context by action (if present).
286
-        if (!empty($action)) {
287
-            $page = $page . '_' . $action;
288
-        }
289
-
290
-        if (!isset($this->admin_registered_pages[ $page ])) {
291
-            // todo: a place to throw an exception?
292
-            // We need to indicate there is no registered page so this function is not being called correctly.
293
-            return false;
294
-        }
295
-        // k made it here so let's call the method
296
-        $content = call_user_func_array(
297
-            array( $this, '_get_admin_content_' . $page ),
298
-            array( $actives, $extra )
299
-        );
300
-        if ($content === false) {
301
-            // todo this needs to be an exception once we've got exceptions in place.
302
-            return false;
303
-        }
304
-        return $content;
305
-    }
306
-
307
-
308
-    /**
309
-     * Allows a message type to specifically exclude template fields for the provided messenger.
310
-     * Filtered so this can be programmatically altered as well.
311
-     * @param string $messenger_name name of messenger
312
-     * @return array
313
-     */
314
-    public function excludedFieldsForMessenger($messenger_name)
315
-    {
316
-        return apply_filters(
317
-            'FHEE__EE_Messages_Base__excludedFieldForMessenger',
318
-            array(),
319
-            $messenger_name,
320
-            $this->name,
321
-            $this
322
-        );
323
-    }
178
+	/**
179
+	 * sets the _existing_admin_settings property can be overridden by child classes.
180
+	 * We do this so we only do database calls if needed.
181
+	 *
182
+	 * @access protected
183
+	 * @param string $messenger
184
+	 */
185
+	protected function _set_existing_admin_settings($messenger = '')
186
+	{
187
+		/** @var EE_Message_Resource_Manager $Message_Resource_Manager */
188
+		$Message_Resource_Manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
189
+		$active_messengers = $Message_Resource_Manager->get_active_messengers_option();
190
+		$settings_to_use = $active_messengers;
191
+
192
+		/**
193
+		 * This determines what will be used for the getting the settings.
194
+		 */
195
+		if (
196
+			! empty($messenger)
197
+			&& $Message_Resource_Manager->is_message_type_active_for_messenger($messenger, $this->name)
198
+		) {
199
+			$settings_to_use = $active_messengers[ $messenger ]['settings'][ $messenger . '-message_types' ];
200
+		}
201
+
202
+		$this->_existing_admin_settings = isset($settings_to_use[ $this->name ]['settings'])
203
+			? $settings_to_use[ $this->name ]['settings']
204
+			: null;
205
+	}
206
+
207
+
208
+
209
+
210
+
211
+
212
+	/**
213
+	 * get_existing_admin_settings
214
+	 * (if needed) sets and returns the _existing_admin_settings property.
215
+	 *
216
+	 * @access public
217
+	 * @param string $messenger
218
+	 * @return array          settings
219
+	 */
220
+	public function get_existing_admin_settings($messenger = '')
221
+	{
222
+		// if admin_settings property empty lets try setting it.
223
+		if (method_exists($this, '_set_existing_admin_settings') && empty($this->_existing_admin_settings)) {
224
+			$this->_set_existing_admin_settings($messenger);
225
+		}
226
+		return property_exists($this, '_existing_admin_settings')
227
+			? $this->_existing_admin_settings
228
+			: null;
229
+	}
230
+
231
+
232
+
233
+
234
+
235
+
236
+	/**
237
+	 * This returns the array of valid shortcodes for a message type or messenger as set by the child in the $_valid_shortcode property.
238
+	 * @return array   an array of valid shortcodes.
239
+	 */
240
+	public function get_valid_shortcodes()
241
+	{
242
+		$valid_shortcodes = apply_filters(
243
+			'FHEE__' . get_class($this) . '__get_valid_shortcodes',
244
+			$this->_valid_shortcodes,
245
+			$this
246
+		);
247
+		// The below filter applies to ALL messengers and message types so use with care!
248
+		$valid_shortcodes = apply_filters('FHEE__EE_Messages_Base__get_valid_shortcodes', $valid_shortcodes, $this);
249
+		return $valid_shortcodes;
250
+	}
251
+
252
+
253
+
254
+
255
+	/**
256
+	 * getter that returns the protected admin_settings_fields property
257
+	 *
258
+	 * @access public
259
+	 * @return array admin settings fields
260
+	 */
261
+	public function get_admin_settings_fields()
262
+	{
263
+		return $this->_admin_settings_fields;
264
+	}
265
+
266
+
267
+
268
+
269
+
270
+	/**
271
+	 * this public method accepts a page slug (for an EE_admin page)
272
+	 * and will return the response from the child class callback function
273
+	 * if that page is registered via the `_admin_registered_page` property set by the child class.
274
+	 *
275
+	 * @param string $page the slug of the EE admin page
276
+	 * @param array $actives an array of active message type (or messenger) objects.
277
+	 * @param string $action the page action (to allow for more specific handling - i.e. edit vs. add pages)
278
+	 * @param array $extra This is just an extra argument that can be used
279
+	 *                     to pass additional data for setting up page content.
280
+	 * @access protected
281
+	 * @return string $content for page.
282
+	 */
283
+	protected function _get_admin_page_content($page, $action, $extra, $actives)
284
+	{
285
+		// we can also further refine the context by action (if present).
286
+		if (!empty($action)) {
287
+			$page = $page . '_' . $action;
288
+		}
289
+
290
+		if (!isset($this->admin_registered_pages[ $page ])) {
291
+			// todo: a place to throw an exception?
292
+			// We need to indicate there is no registered page so this function is not being called correctly.
293
+			return false;
294
+		}
295
+		// k made it here so let's call the method
296
+		$content = call_user_func_array(
297
+			array( $this, '_get_admin_content_' . $page ),
298
+			array( $actives, $extra )
299
+		);
300
+		if ($content === false) {
301
+			// todo this needs to be an exception once we've got exceptions in place.
302
+			return false;
303
+		}
304
+		return $content;
305
+	}
306
+
307
+
308
+	/**
309
+	 * Allows a message type to specifically exclude template fields for the provided messenger.
310
+	 * Filtered so this can be programmatically altered as well.
311
+	 * @param string $messenger_name name of messenger
312
+	 * @return array
313
+	 */
314
+	public function excludedFieldsForMessenger($messenger_name)
315
+	{
316
+		return apply_filters(
317
+			'FHEE__EE_Messages_Base__excludedFieldForMessenger',
318
+			array(),
319
+			$messenger_name,
320
+			$this->name,
321
+			$this
322
+		);
323
+	}
324 324
 }
Please login to merge, or discard this patch.