Completed
Branch master (16f63d)
by
unknown
05:48
created
modules/ticket_selector/TicketSelectorIframe.php 2 patches
Indentation   +75 added lines, -75 removed lines patch added patch discarded remove patch
@@ -21,79 +21,79 @@
 block discarded – undo
21 21
  */
22 22
 class TicketSelectorIframe extends Iframe
23 23
 {
24
-    /**
25
-     * TicketSelectorIframe constructor.
26
-     *
27
-     * @param EEM_Event        $event_model
28
-     * @param CurrentPage      $current_page
29
-     * @param RequestInterface $request
30
-     * @throws EE_Error
31
-     * @throws ReflectionException
32
-     */
33
-    public function __construct(EEM_Event $event_model, CurrentPage $current_page, RequestInterface $request)
34
-    {
35
-        $current_page->setEspressoPage(true);
36
-        $ticket_selector = LoaderFactory::getLoader()->getNew(DisplayTicketSelector::class);
37
-        $ticket_selector->setIframe();
38
-        $event = $event_model->get_one_by_ID($request->getRequestParam('event', 0, 'int'));
39
-        parent::__construct(
40
-            esc_html__('Ticket Selector', 'event_espresso'),
41
-            $ticket_selector->display($event)
42
-        );
43
-        $this->addStylesheets(
44
-            apply_filters(
45
-                'FHEE__EED_Ticket_Selector__ticket_selector_iframe__css',
46
-                array(
47
-                    'ticket_selector_embed' => TICKET_SELECTOR_ASSETS_URL
48
-                                               . 'ticket_selector_embed.css?ver='
49
-                                               . EVENT_ESPRESSO_VERSION,
50
-                    'ticket_selector'       => TICKET_SELECTOR_ASSETS_URL
51
-                                               . 'ticket_selector.css?ver='
52
-                                               . EVENT_ESPRESSO_VERSION,
53
-                ),
54
-                $this
55
-            )
56
-        );
57
-        $this->addInlineStyles('ticket_selector', EED_Ticket_Selector::accentColorStyles());
58
-        if (! apply_filters('FHEE__EED_Ticket_Selector__ticket_selector_iframe__load_theme_css', false, $this)) {
59
-            $this->addStylesheets(array('site_theme' => ''));
60
-        }
61
-        $this->addScripts(
62
-            apply_filters(
63
-                'FHEE__EventEspresso_modules_events_archive_EventsArchiveIframe__display__js',
64
-                array(
65
-                    'ticket_selector_iframe_embed' => TICKET_SELECTOR_ASSETS_URL
66
-                                                      . 'ticket_selector_iframe_embed.js?ver='
67
-                                                      . EVENT_ESPRESSO_VERSION,
68
-                ),
69
-                $this
70
-            )
71
-        );
72
-        $js_attributes = apply_filters(
73
-            'FHEE__EventEspresso_modules_ticket_selector_TicketSelectorIframe__construct__js_attributes',
74
-            array(),
75
-            $this
76
-        );
77
-        if (! empty($js_attributes)) {
78
-            $this->addScriptAttributes($js_attributes);
79
-        }
80
-        $this->addLocalizedVars(
81
-            apply_filters(
82
-                'FHEE__EventEspresso_modules_ticket_selector_TicketSelectorIframe__construct__localized_vars',
83
-                array(
84
-                    'ticket_selector_iframe' => true,
85
-                    'EEDTicketSelectorMsg'   => wp_strip_all_tags(
86
-                        __(
87
-                            'Please choose at least one ticket before continuing.',
88
-                            'event_espresso'
89
-                        )
90
-                    ),
91
-                )
92
-            )
93
-        );
94
-        do_action(
95
-            'AHEE__EventEspresso_modules_ticket_selector_TicketSelectorIframe__construct__complete',
96
-            $this
97
-        );
98
-    }
24
+	/**
25
+	 * TicketSelectorIframe constructor.
26
+	 *
27
+	 * @param EEM_Event        $event_model
28
+	 * @param CurrentPage      $current_page
29
+	 * @param RequestInterface $request
30
+	 * @throws EE_Error
31
+	 * @throws ReflectionException
32
+	 */
33
+	public function __construct(EEM_Event $event_model, CurrentPage $current_page, RequestInterface $request)
34
+	{
35
+		$current_page->setEspressoPage(true);
36
+		$ticket_selector = LoaderFactory::getLoader()->getNew(DisplayTicketSelector::class);
37
+		$ticket_selector->setIframe();
38
+		$event = $event_model->get_one_by_ID($request->getRequestParam('event', 0, 'int'));
39
+		parent::__construct(
40
+			esc_html__('Ticket Selector', 'event_espresso'),
41
+			$ticket_selector->display($event)
42
+		);
43
+		$this->addStylesheets(
44
+			apply_filters(
45
+				'FHEE__EED_Ticket_Selector__ticket_selector_iframe__css',
46
+				array(
47
+					'ticket_selector_embed' => TICKET_SELECTOR_ASSETS_URL
48
+											   . 'ticket_selector_embed.css?ver='
49
+											   . EVENT_ESPRESSO_VERSION,
50
+					'ticket_selector'       => TICKET_SELECTOR_ASSETS_URL
51
+											   . 'ticket_selector.css?ver='
52
+											   . EVENT_ESPRESSO_VERSION,
53
+				),
54
+				$this
55
+			)
56
+		);
57
+		$this->addInlineStyles('ticket_selector', EED_Ticket_Selector::accentColorStyles());
58
+		if (! apply_filters('FHEE__EED_Ticket_Selector__ticket_selector_iframe__load_theme_css', false, $this)) {
59
+			$this->addStylesheets(array('site_theme' => ''));
60
+		}
61
+		$this->addScripts(
62
+			apply_filters(
63
+				'FHEE__EventEspresso_modules_events_archive_EventsArchiveIframe__display__js',
64
+				array(
65
+					'ticket_selector_iframe_embed' => TICKET_SELECTOR_ASSETS_URL
66
+													  . 'ticket_selector_iframe_embed.js?ver='
67
+													  . EVENT_ESPRESSO_VERSION,
68
+				),
69
+				$this
70
+			)
71
+		);
72
+		$js_attributes = apply_filters(
73
+			'FHEE__EventEspresso_modules_ticket_selector_TicketSelectorIframe__construct__js_attributes',
74
+			array(),
75
+			$this
76
+		);
77
+		if (! empty($js_attributes)) {
78
+			$this->addScriptAttributes($js_attributes);
79
+		}
80
+		$this->addLocalizedVars(
81
+			apply_filters(
82
+				'FHEE__EventEspresso_modules_ticket_selector_TicketSelectorIframe__construct__localized_vars',
83
+				array(
84
+					'ticket_selector_iframe' => true,
85
+					'EEDTicketSelectorMsg'   => wp_strip_all_tags(
86
+						__(
87
+							'Please choose at least one ticket before continuing.',
88
+							'event_espresso'
89
+						)
90
+					),
91
+				)
92
+			)
93
+		);
94
+		do_action(
95
+			'AHEE__EventEspresso_modules_ticket_selector_TicketSelectorIframe__construct__complete',
96
+			$this
97
+		);
98
+	}
99 99
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -55,7 +55,7 @@  discard block
 block discarded – undo
55 55
             )
56 56
         );
57 57
         $this->addInlineStyles('ticket_selector', EED_Ticket_Selector::accentColorStyles());
58
-        if (! apply_filters('FHEE__EED_Ticket_Selector__ticket_selector_iframe__load_theme_css', false, $this)) {
58
+        if ( ! apply_filters('FHEE__EED_Ticket_Selector__ticket_selector_iframe__load_theme_css', false, $this)) {
59 59
             $this->addStylesheets(array('site_theme' => ''));
60 60
         }
61 61
         $this->addScripts(
@@ -74,7 +74,7 @@  discard block
 block discarded – undo
74 74
             array(),
75 75
             $this
76 76
         );
77
-        if (! empty($js_attributes)) {
77
+        if ( ! empty($js_attributes)) {
78 78
             $this->addScriptAttributes($js_attributes);
79 79
         }
80 80
         $this->addLocalizedVars(
Please login to merge, or discard this patch.
modules/ticket_selector/TicketSelectorRowStandard.php 1 patch
Indentation   +382 added lines, -382 removed lines patch added patch discarded remove patch
@@ -19,390 +19,390 @@
 block discarded – undo
19 19
  */
20 20
 class TicketSelectorRowStandard extends TicketSelectorRow
21 21
 {
22
-    /**
23
-     * @var TicketDetails
24
-     */
25
-    protected $ticket_details;
26
-
27
-    /**
28
-     * @var EE_Ticket_Selector_Config
29
-     */
30
-    protected $template_settings;
31
-
32
-    /**
33
-     * @var EE_Tax_Config
34
-     */
35
-    protected $tax_settings;
36
-
37
-    /**
38
-     * @var boolean
39
-     */
40
-    protected $prices_displayed_including_taxes;
41
-
42
-    /**
43
-     * @var int
44
-     */
45
-    protected $row;
46
-
47
-    /**
48
-     * @var int
49
-     */
50
-    protected $cols;
51
-
52
-    /**
53
-     * @var boolean
54
-     */
55
-    protected $hidden_input_qty = false;
56
-
57
-    /**
58
-     * @var string
59
-     */
60
-    protected $ticket_datetime_classes;
61
-
62
-    private bool $use_new_checkbox_selector;
63
-
64
-
65
-    /**
66
-     * TicketDetails constructor.
67
-     *
68
-     * @param TicketDetails $ticket_details
69
-     * @param EE_Tax_Config $tax_settings
70
-     * @param int           $total_tickets
71
-     * @param int           $max_attendees
72
-     * @param int           $row
73
-     * @param int           $cols
74
-     * @param boolean       $required_ticket_sold_out
75
-     * @param string        $event_status
76
-     * @param string        $ticket_datetime_classes
77
-     * @param bool          $use_new_checkbox_selector
78
-     * @throws EE_Error
79
-     * @throws UnexpectedEntityException
80
-     */
81
-    public function __construct(
82
-        TicketDetails $ticket_details,
83
-        EE_Tax_Config $tax_settings,
84
-        $total_tickets,
85
-        $max_attendees,
86
-        $row,
87
-        $cols,
88
-        $required_ticket_sold_out,
89
-        $event_status,
90
-        $ticket_datetime_classes,
91
-        bool $use_new_checkbox_selector = false
92
-    ) {
93
-        $this->ticket_details = $ticket_details;
94
-        $this->template_settings = $ticket_details->getTemplateSettings();
95
-        $this->tax_settings = $tax_settings;
96
-        $this->row = $row;
97
-        $this->cols = $cols;
98
-        $this->ticket_datetime_classes = $ticket_datetime_classes;
99
-        $this->use_new_checkbox_selector = $use_new_checkbox_selector;
100
-        parent::__construct(
101
-            $ticket_details->getTicket(),
102
-            $max_attendees,
103
-            $ticket_details->getDateFormat(),
104
-            $event_status,
105
-            $required_ticket_sold_out,
106
-            $total_tickets
107
-        );
108
-    }
109
-
110
-
111
-    /**
112
-     * other ticket rows will need to know if a required ticket is sold out,
113
-     * so that they are not offered for sale
114
-     *
115
-     * @return boolean
116
-     */
117
-    public function getRequiredTicketSoldOut()
118
-    {
119
-        return $this->required_ticket_sold_out;
120
-    }
121
-
122
-
123
-    /**
124
-     * @return int
125
-     */
126
-    public function getCols()
127
-    {
128
-        return $this->cols;
129
-    }
130
-
131
-
132
-    /**
133
-     * getHtml
134
-     *
135
-     * @return string
136
-     * @throws EE_Error
137
-     * @throws ReflectionException
138
-     */
139
-    public function getHtml()
140
-    {
141
-        $this->min = 0;
142
-        $this->max = $this->ticket->max();
143
-        $remaining = $this->ticket->remaining();
144
-        $this->setTicketMinAndMax($remaining);
145
-        // set flag if ticket is required (flag is set to start date so that future tickets are not blocked)
146
-        $this->required_ticket_sold_out = $this->ticket->required() && ! $remaining
147
-            ? $this->ticket->start_date()
148
-            : $this->required_ticket_sold_out;
149
-        $this->setTicketPriceDetails();
150
-        $this->setTicketStatusClasses($remaining);
151
-        $filtered_row_html = $this->getFilteredRowHtml();
152
-        if ($filtered_row_html !== false) {
153
-            return $filtered_row_html;
154
-        }
155
-        $ticket_selector_row_html = EEH_HTML::tr(
156
-            '',
157
-            '',
158
-            "tckt-slctr-tbl-tr {$this->status_class}{$this->ticket_datetime_classes} "
159
-            . espresso_get_object_css_class($this->ticket)
160
-        );
161
-        $filtered_row_content = $this->getFilteredRowContents();
162
-        if ($filtered_row_content !== false) {
163
-            if ($this->max_attendees === 1) {
164
-                return $ticket_selector_row_html
165
-                       . $filtered_row_content
166
-                       . $this->ticketQtyAndIdHiddenInputs()
167
-                       . EEH_HTML::trx();
168
-            }
169
-            return $ticket_selector_row_html
170
-                   . $filtered_row_content
171
-                   . EEH_HTML::trx();
172
-        }
173
-        $this->hidden_input_qty = $this->max_attendees > 1;
174
-
175
-        $ticket_selector_row_html .= $this->ticketNameTableCell();
176
-        $ticket_selector_row_html .= $this->ticketPriceTableCell();
177
-        $ticket_selector_row_html .= EEH_HTML::td(
178
-            '',
179
-            '',
180
-            'tckt-slctr-tbl-td-qty cntr',
181
-            '',
182
-            'headers="quantity-' . $this->EVT_ID . '"'
183
-        );
184
-        $this->setTicketStatusDisplay($remaining);
185
-        if (empty($this->ticket_status_display)) {
186
-            $this->hidden_input_qty = false;
187
-            // display submit button since we have tickets available
188
-            add_filter('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true');
189
-            if ($this->max_attendees === 1) {
190
-                // only ONE attendee is allowed to register at a time
191
-                $ticket_selector_row_html .= $this->onlyOneAttendeeCanRegister();
192
-            } else {
193
-                $ticket_selector_row_html .= $this->max === 1 && $this->use_new_checkbox_selector
194
-                    ? $this->ticketCheckboxSelector()
195
-                    : $this->ticketQuantitySelector();
196
-            }
197
-        }
198
-        $ticket_selector_row_html .= $this->ticket_status_display;
199
-        $ticket_selector_row_html .= $this->ticketQtyAndIdHiddenInputs();
200
-        $ticket_selector_row_html .= $this->ticket_details->display(
201
-            $this->ticket_price,
202
-            $remaining,
203
-            $this->cols
204
-        );
205
-        $ticket_selector_row_html .= EEH_HTML::tdx();
206
-        $ticket_selector_row_html .= EEH_HTML::trx();
207
-
208
-
209
-        $this->row++;
210
-        return $ticket_selector_row_html;
211
-    }
212
-
213
-
214
-    /**
215
-     * getTicketPriceDetails
216
-     *
217
-     * @return void
218
-     * @throws EE_Error
219
-     * @throws ReflectionException
220
-     */
221
-    protected function setTicketPriceDetails()
222
-    {
223
-        $this->ticket_price = $this->tax_settings->prices_displayed_including_taxes
224
-            ? $this->ticket->get_ticket_total_with_taxes()
225
-            : $this->ticket->get_ticket_subtotal();
226
-        $this->ticket_bundle = false;
227
-        $ticket_min = $this->ticket->min();
228
-        // for ticket bundles, set min and max qty the same
229
-        if ($ticket_min !== 0 && $ticket_min === $this->ticket->max()) {
230
-            $this->ticket_price *= $ticket_min;
231
-            $this->ticket_bundle = true;
232
-        }
233
-        $this->ticket_price = apply_filters(
234
-            'FHEE__ticket_selector_chart_template__ticket_price',
235
-            $this->ticket_price,
236
-            $this->ticket
237
-        );
238
-    }
239
-
240
-
241
-    /**
242
-     * ticketNameTableCell
243
-     *
244
-     * @return string
245
-     * @throws EE_Error
246
-     * @throws ReflectionException
247
-     */
248
-    protected function ticketNameTableCell()
249
-    {
250
-        $html = EEH_HTML::td(
251
-            '',
252
-            '',
253
-            'tckt-slctr-tbl-td-name',
254
-            '',
255
-            'headers="details-' . $this->EVT_ID . '"'
256
-        );
257
-        $html .= EEH_HTML::strong($this->ticket->get_pretty('TKT_name'));
258
-        $html .= $this->ticket_details->getShowHideLinks();
259
-        if ($this->ticket->required()) {
260
-            $html .= EEH_HTML::p(
261
-                apply_filters(
262
-                    'FHEE__ticket_selector_chart_template__ticket_required_message',
263
-                    esc_html__('This ticket is required and must be purchased.', 'event_espresso')
264
-                ),
265
-                '',
266
-                'ticket-required-pg'
267
-            );
268
-        }
269
-        $html .= EEH_HTML::tdx();
270
-        return $html;
271
-    }
272
-
273
-
274
-    /**
275
-     * ticketPriceTableCell
276
-     *
277
-     * @return string
278
-     * @throws EE_Error
279
-     * @throws ReflectionException
280
-     */
281
-    protected function ticketPriceTableCell()
282
-    {
283
-        $html = '';
284
-        if (apply_filters('FHEE__ticket_selector_chart_template__display_ticket_price_details', true)) {
285
-            $html .= EEH_HTML::td(
286
-                '',
287
-                '',
288
-                'tckt-slctr-tbl-td-price jst-rght',
289
-                '',
290
-                'headers="price-' . $this->EVT_ID . '"'
291
-            );
292
-            $html .= EEH_HTML::span(
293
-                EEH_Template::format_currency($this->ticket_price),
294
-                '',
295
-                'tckt-price--nowrap'
296
-            );
297
-            $html .= $this->ticket->taxable()
298
-                ? EEH_HTML::span('*', '', 'taxable-tickets-asterisk grey-text')
299
-                : '';
300
-            $html .= ' ';
301
-            // phpcs:disable WordPress.WP.I18n.NoEmptyStrings
302
-            $html .= EEH_HTML::span(
303
-                $this->ticket_bundle
304
-                    ? apply_filters(
305
-                        'FHEE__ticket_selector_chart_template__per_ticket_bundle_text',
306
-                        esc_html__(' / bundle', 'event_espresso')
307
-                    )
308
-                    : apply_filters(
309
-                        'FHEE__ticket_selector_chart_template__per_ticket_text',
310
-                        esc_html__('', 'event_espresso')
311
-                    ),
312
-                '',
313
-                'smaller-text no-bold'
314
-            );
315
-            $html .= ' ';
316
-            $html .= EEH_HTML::tdx();
317
-            $this->cols++;
318
-        }
319
-        return $html;
320
-    }
321
-
322
-
323
-    /**
324
-     * @return string
325
-     * @throws EE_Error
326
-     * @throws ReflectionException
327
-     */
328
-    protected function onlyOneAttendeeCanRegister(): string
329
-    {
330
-        $TKT   = $this->ticket->ID();
331
-        $label = esc_html__('Select this ticket', 'event_espresso');
332
-        $name  = "tkt-slctr-qty-$this->EVT_ID";
333
-        $class = "ticket-selector-tbl-qty-slct";
334
-        $id    = "$class-$this->EVT_ID-$this->row";
335
-        $checked = $this->total_tickets === 1 ? ' checked' : '';
336
-
337
-        return ".
22
+	/**
23
+	 * @var TicketDetails
24
+	 */
25
+	protected $ticket_details;
26
+
27
+	/**
28
+	 * @var EE_Ticket_Selector_Config
29
+	 */
30
+	protected $template_settings;
31
+
32
+	/**
33
+	 * @var EE_Tax_Config
34
+	 */
35
+	protected $tax_settings;
36
+
37
+	/**
38
+	 * @var boolean
39
+	 */
40
+	protected $prices_displayed_including_taxes;
41
+
42
+	/**
43
+	 * @var int
44
+	 */
45
+	protected $row;
46
+
47
+	/**
48
+	 * @var int
49
+	 */
50
+	protected $cols;
51
+
52
+	/**
53
+	 * @var boolean
54
+	 */
55
+	protected $hidden_input_qty = false;
56
+
57
+	/**
58
+	 * @var string
59
+	 */
60
+	protected $ticket_datetime_classes;
61
+
62
+	private bool $use_new_checkbox_selector;
63
+
64
+
65
+	/**
66
+	 * TicketDetails constructor.
67
+	 *
68
+	 * @param TicketDetails $ticket_details
69
+	 * @param EE_Tax_Config $tax_settings
70
+	 * @param int           $total_tickets
71
+	 * @param int           $max_attendees
72
+	 * @param int           $row
73
+	 * @param int           $cols
74
+	 * @param boolean       $required_ticket_sold_out
75
+	 * @param string        $event_status
76
+	 * @param string        $ticket_datetime_classes
77
+	 * @param bool          $use_new_checkbox_selector
78
+	 * @throws EE_Error
79
+	 * @throws UnexpectedEntityException
80
+	 */
81
+	public function __construct(
82
+		TicketDetails $ticket_details,
83
+		EE_Tax_Config $tax_settings,
84
+		$total_tickets,
85
+		$max_attendees,
86
+		$row,
87
+		$cols,
88
+		$required_ticket_sold_out,
89
+		$event_status,
90
+		$ticket_datetime_classes,
91
+		bool $use_new_checkbox_selector = false
92
+	) {
93
+		$this->ticket_details = $ticket_details;
94
+		$this->template_settings = $ticket_details->getTemplateSettings();
95
+		$this->tax_settings = $tax_settings;
96
+		$this->row = $row;
97
+		$this->cols = $cols;
98
+		$this->ticket_datetime_classes = $ticket_datetime_classes;
99
+		$this->use_new_checkbox_selector = $use_new_checkbox_selector;
100
+		parent::__construct(
101
+			$ticket_details->getTicket(),
102
+			$max_attendees,
103
+			$ticket_details->getDateFormat(),
104
+			$event_status,
105
+			$required_ticket_sold_out,
106
+			$total_tickets
107
+		);
108
+	}
109
+
110
+
111
+	/**
112
+	 * other ticket rows will need to know if a required ticket is sold out,
113
+	 * so that they are not offered for sale
114
+	 *
115
+	 * @return boolean
116
+	 */
117
+	public function getRequiredTicketSoldOut()
118
+	{
119
+		return $this->required_ticket_sold_out;
120
+	}
121
+
122
+
123
+	/**
124
+	 * @return int
125
+	 */
126
+	public function getCols()
127
+	{
128
+		return $this->cols;
129
+	}
130
+
131
+
132
+	/**
133
+	 * getHtml
134
+	 *
135
+	 * @return string
136
+	 * @throws EE_Error
137
+	 * @throws ReflectionException
138
+	 */
139
+	public function getHtml()
140
+	{
141
+		$this->min = 0;
142
+		$this->max = $this->ticket->max();
143
+		$remaining = $this->ticket->remaining();
144
+		$this->setTicketMinAndMax($remaining);
145
+		// set flag if ticket is required (flag is set to start date so that future tickets are not blocked)
146
+		$this->required_ticket_sold_out = $this->ticket->required() && ! $remaining
147
+			? $this->ticket->start_date()
148
+			: $this->required_ticket_sold_out;
149
+		$this->setTicketPriceDetails();
150
+		$this->setTicketStatusClasses($remaining);
151
+		$filtered_row_html = $this->getFilteredRowHtml();
152
+		if ($filtered_row_html !== false) {
153
+			return $filtered_row_html;
154
+		}
155
+		$ticket_selector_row_html = EEH_HTML::tr(
156
+			'',
157
+			'',
158
+			"tckt-slctr-tbl-tr {$this->status_class}{$this->ticket_datetime_classes} "
159
+			. espresso_get_object_css_class($this->ticket)
160
+		);
161
+		$filtered_row_content = $this->getFilteredRowContents();
162
+		if ($filtered_row_content !== false) {
163
+			if ($this->max_attendees === 1) {
164
+				return $ticket_selector_row_html
165
+					   . $filtered_row_content
166
+					   . $this->ticketQtyAndIdHiddenInputs()
167
+					   . EEH_HTML::trx();
168
+			}
169
+			return $ticket_selector_row_html
170
+				   . $filtered_row_content
171
+				   . EEH_HTML::trx();
172
+		}
173
+		$this->hidden_input_qty = $this->max_attendees > 1;
174
+
175
+		$ticket_selector_row_html .= $this->ticketNameTableCell();
176
+		$ticket_selector_row_html .= $this->ticketPriceTableCell();
177
+		$ticket_selector_row_html .= EEH_HTML::td(
178
+			'',
179
+			'',
180
+			'tckt-slctr-tbl-td-qty cntr',
181
+			'',
182
+			'headers="quantity-' . $this->EVT_ID . '"'
183
+		);
184
+		$this->setTicketStatusDisplay($remaining);
185
+		if (empty($this->ticket_status_display)) {
186
+			$this->hidden_input_qty = false;
187
+			// display submit button since we have tickets available
188
+			add_filter('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true');
189
+			if ($this->max_attendees === 1) {
190
+				// only ONE attendee is allowed to register at a time
191
+				$ticket_selector_row_html .= $this->onlyOneAttendeeCanRegister();
192
+			} else {
193
+				$ticket_selector_row_html .= $this->max === 1 && $this->use_new_checkbox_selector
194
+					? $this->ticketCheckboxSelector()
195
+					: $this->ticketQuantitySelector();
196
+			}
197
+		}
198
+		$ticket_selector_row_html .= $this->ticket_status_display;
199
+		$ticket_selector_row_html .= $this->ticketQtyAndIdHiddenInputs();
200
+		$ticket_selector_row_html .= $this->ticket_details->display(
201
+			$this->ticket_price,
202
+			$remaining,
203
+			$this->cols
204
+		);
205
+		$ticket_selector_row_html .= EEH_HTML::tdx();
206
+		$ticket_selector_row_html .= EEH_HTML::trx();
207
+
208
+
209
+		$this->row++;
210
+		return $ticket_selector_row_html;
211
+	}
212
+
213
+
214
+	/**
215
+	 * getTicketPriceDetails
216
+	 *
217
+	 * @return void
218
+	 * @throws EE_Error
219
+	 * @throws ReflectionException
220
+	 */
221
+	protected function setTicketPriceDetails()
222
+	{
223
+		$this->ticket_price = $this->tax_settings->prices_displayed_including_taxes
224
+			? $this->ticket->get_ticket_total_with_taxes()
225
+			: $this->ticket->get_ticket_subtotal();
226
+		$this->ticket_bundle = false;
227
+		$ticket_min = $this->ticket->min();
228
+		// for ticket bundles, set min and max qty the same
229
+		if ($ticket_min !== 0 && $ticket_min === $this->ticket->max()) {
230
+			$this->ticket_price *= $ticket_min;
231
+			$this->ticket_bundle = true;
232
+		}
233
+		$this->ticket_price = apply_filters(
234
+			'FHEE__ticket_selector_chart_template__ticket_price',
235
+			$this->ticket_price,
236
+			$this->ticket
237
+		);
238
+	}
239
+
240
+
241
+	/**
242
+	 * ticketNameTableCell
243
+	 *
244
+	 * @return string
245
+	 * @throws EE_Error
246
+	 * @throws ReflectionException
247
+	 */
248
+	protected function ticketNameTableCell()
249
+	{
250
+		$html = EEH_HTML::td(
251
+			'',
252
+			'',
253
+			'tckt-slctr-tbl-td-name',
254
+			'',
255
+			'headers="details-' . $this->EVT_ID . '"'
256
+		);
257
+		$html .= EEH_HTML::strong($this->ticket->get_pretty('TKT_name'));
258
+		$html .= $this->ticket_details->getShowHideLinks();
259
+		if ($this->ticket->required()) {
260
+			$html .= EEH_HTML::p(
261
+				apply_filters(
262
+					'FHEE__ticket_selector_chart_template__ticket_required_message',
263
+					esc_html__('This ticket is required and must be purchased.', 'event_espresso')
264
+				),
265
+				'',
266
+				'ticket-required-pg'
267
+			);
268
+		}
269
+		$html .= EEH_HTML::tdx();
270
+		return $html;
271
+	}
272
+
273
+
274
+	/**
275
+	 * ticketPriceTableCell
276
+	 *
277
+	 * @return string
278
+	 * @throws EE_Error
279
+	 * @throws ReflectionException
280
+	 */
281
+	protected function ticketPriceTableCell()
282
+	{
283
+		$html = '';
284
+		if (apply_filters('FHEE__ticket_selector_chart_template__display_ticket_price_details', true)) {
285
+			$html .= EEH_HTML::td(
286
+				'',
287
+				'',
288
+				'tckt-slctr-tbl-td-price jst-rght',
289
+				'',
290
+				'headers="price-' . $this->EVT_ID . '"'
291
+			);
292
+			$html .= EEH_HTML::span(
293
+				EEH_Template::format_currency($this->ticket_price),
294
+				'',
295
+				'tckt-price--nowrap'
296
+			);
297
+			$html .= $this->ticket->taxable()
298
+				? EEH_HTML::span('*', '', 'taxable-tickets-asterisk grey-text')
299
+				: '';
300
+			$html .= ' ';
301
+			// phpcs:disable WordPress.WP.I18n.NoEmptyStrings
302
+			$html .= EEH_HTML::span(
303
+				$this->ticket_bundle
304
+					? apply_filters(
305
+						'FHEE__ticket_selector_chart_template__per_ticket_bundle_text',
306
+						esc_html__(' / bundle', 'event_espresso')
307
+					)
308
+					: apply_filters(
309
+						'FHEE__ticket_selector_chart_template__per_ticket_text',
310
+						esc_html__('', 'event_espresso')
311
+					),
312
+				'',
313
+				'smaller-text no-bold'
314
+			);
315
+			$html .= ' ';
316
+			$html .= EEH_HTML::tdx();
317
+			$this->cols++;
318
+		}
319
+		return $html;
320
+	}
321
+
322
+
323
+	/**
324
+	 * @return string
325
+	 * @throws EE_Error
326
+	 * @throws ReflectionException
327
+	 */
328
+	protected function onlyOneAttendeeCanRegister(): string
329
+	{
330
+		$TKT   = $this->ticket->ID();
331
+		$label = esc_html__('Select this ticket', 'event_espresso');
332
+		$name  = "tkt-slctr-qty-$this->EVT_ID";
333
+		$class = "ticket-selector-tbl-qty-slct";
334
+		$id    = "$class-$this->EVT_ID-$this->row";
335
+		$checked = $this->total_tickets === 1 ? ' checked' : '';
336
+
337
+		return ".
338 338
         <label class='ee-a11y-screen-reader-text' for='$id' >$label</label>
339 339
         <input type='radio'$checked name='$name' id='$id' class='$class' value='$TKT-1' />";
340
-    }
341
-
342
-
343
-    /**
344
-     * @return string
345
-     * @throws EE_Error
346
-     * @throws ReflectionException
347
-     */
348
-    protected function ticketCheckboxSelector(): string
349
-    {
350
-        $TKT = $this->ticket->ID();
351
-        $label = esc_html__('Select this ticket', 'event_espresso');
352
-        $name  = "tkt-slctr-qty-$this->EVT_ID[$TKT]";
353
-        $class = 'ticket-selector-tbl-qty-slct';
354
-        $id    = "$class-$this->EVT_ID-$this->row";
355
-        $title = esc_html__('only one of this ticket can be purchased at a time', 'event_espresso');
356
-
357
-        return "
340
+	}
341
+
342
+
343
+	/**
344
+	 * @return string
345
+	 * @throws EE_Error
346
+	 * @throws ReflectionException
347
+	 */
348
+	protected function ticketCheckboxSelector(): string
349
+	{
350
+		$TKT = $this->ticket->ID();
351
+		$label = esc_html__('Select this ticket', 'event_espresso');
352
+		$name  = "tkt-slctr-qty-$this->EVT_ID[$TKT]";
353
+		$class = 'ticket-selector-tbl-qty-slct';
354
+		$id    = "$class-$this->EVT_ID-$this->row";
355
+		$title = esc_html__('only one of this ticket can be purchased at a time', 'event_espresso');
356
+
357
+		return "
358 358
         <label class='ee-a11y-screen-reader-text' for='$id' >$label</label>
359 359
         <input type='checkbox' name='$name' id='$id' class='$class' value='1' title='$title'/>";
360
-    }
361
-
362
-
363
-    /**
364
-     * @return string
365
-     * @throws EE_Error
366
-     * @throws ReflectionException
367
-     */
368
-    protected function ticketQuantitySelector(): string
369
-    {
370
-        $TKT = $this->ticket->ID();
371
-        $label = esc_html__('Quantity', 'event_espresso');
372
-        $name  = "tkt-slctr-qty-$this->EVT_ID[$TKT]";
373
-        $class = 'ticket-selector-tbl-qty-slct';
374
-        $id = "$class-{$this->EVT_ID}-{$this->row}";
375
-
376
-        $html = "<label class='ee-a11y-screen-reader-text' for='$id' >$label</label>";
377
-        $html .= "<select name='$name' id='$id' class='$class'>";
378
-        // this ensures that non-required tickets with non-zero MIN QTYs don't HAVE to be purchased
379
-        if ($this->min !== 0 && ! $this->ticket->required()) {
380
-            $html .= "<option value='0'>&nbsp;0&nbsp;</option>";
381
-        }
382
-        // offer ticket quantities from the min to the max
383
-        for ($i = $this->min; $i <= $this->max; $i++) {
384
-            $html .= "<option value='$i'>&nbsp;$i&nbsp;</option>";
385
-        }
386
-        $html .= "</select>";
387
-        return $html;
388
-    }
389
-
390
-
391
-    /**
392
-     * @return string
393
-     * @throws EE_Error
394
-     * @throws ReflectionException
395
-     */
396
-    protected function ticketQtyAndIdHiddenInputs(): string
397
-    {
398
-        $html = '';
399
-        $EVT = $this->EVT_ID;
400
-        $TKT = $this->ticket->ID();
401
-        // depending on group reg we need to change the format for qty
402
-        if ($this->hidden_input_qty) {
403
-            $html .= "<input type='hidden' name='tkt-slctr-qty-{$EVT}[]' value='0' />";
404
-        }
405
-        $html .= "<input type='hidden' name='tkt-slctr-ticket-id-{$EVT}[]' value='{$TKT}' />";
406
-        return $html;
407
-    }
360
+	}
361
+
362
+
363
+	/**
364
+	 * @return string
365
+	 * @throws EE_Error
366
+	 * @throws ReflectionException
367
+	 */
368
+	protected function ticketQuantitySelector(): string
369
+	{
370
+		$TKT = $this->ticket->ID();
371
+		$label = esc_html__('Quantity', 'event_espresso');
372
+		$name  = "tkt-slctr-qty-$this->EVT_ID[$TKT]";
373
+		$class = 'ticket-selector-tbl-qty-slct';
374
+		$id = "$class-{$this->EVT_ID}-{$this->row}";
375
+
376
+		$html = "<label class='ee-a11y-screen-reader-text' for='$id' >$label</label>";
377
+		$html .= "<select name='$name' id='$id' class='$class'>";
378
+		// this ensures that non-required tickets with non-zero MIN QTYs don't HAVE to be purchased
379
+		if ($this->min !== 0 && ! $this->ticket->required()) {
380
+			$html .= "<option value='0'>&nbsp;0&nbsp;</option>";
381
+		}
382
+		// offer ticket quantities from the min to the max
383
+		for ($i = $this->min; $i <= $this->max; $i++) {
384
+			$html .= "<option value='$i'>&nbsp;$i&nbsp;</option>";
385
+		}
386
+		$html .= "</select>";
387
+		return $html;
388
+	}
389
+
390
+
391
+	/**
392
+	 * @return string
393
+	 * @throws EE_Error
394
+	 * @throws ReflectionException
395
+	 */
396
+	protected function ticketQtyAndIdHiddenInputs(): string
397
+	{
398
+		$html = '';
399
+		$EVT = $this->EVT_ID;
400
+		$TKT = $this->ticket->ID();
401
+		// depending on group reg we need to change the format for qty
402
+		if ($this->hidden_input_qty) {
403
+			$html .= "<input type='hidden' name='tkt-slctr-qty-{$EVT}[]' value='0' />";
404
+		}
405
+		$html .= "<input type='hidden' name='tkt-slctr-ticket-id-{$EVT}[]' value='{$TKT}' />";
406
+		return $html;
407
+	}
408 408
 }
Please login to merge, or discard this patch.
modules/ticket_selector/EED_Ticket_Selector.module.php 2 patches
Indentation   +502 added lines, -502 removed lines patch added patch discarded remove patch
@@ -18,507 +18,507 @@  discard block
 block discarded – undo
18 18
  */
19 19
 class EED_Ticket_Selector extends EED_Module
20 20
 {
21
-    private static ?DisplayTicketSelector $ticket_selector = null;
22
-
23
-    private static ?TicketSelectorIframeEmbedButton $iframe_embed_button = null;
24
-
25
-
26
-    /**
27
-     * @return EED_Module|EED_Ticket_Selector
28
-     * @throws EE_Error
29
-     * @throws ReflectionException
30
-     */
31
-    public static function instance()
32
-    {
33
-        return parent::get_instance(__CLASS__);
34
-    }
35
-
36
-
37
-    /**
38
-     * @return EE_Ticket_Selector_Config
39
-     * @throws EE_Error
40
-     * @throws ReflectionException
41
-     */
42
-    public static function ticketConfig(): EE_Ticket_Selector_Config
43
-    {
44
-        EED_Ticket_Selector::instance()->set_config();
45
-        return EED_Ticket_Selector::instance()->config();
46
-    }
47
-
48
-
49
-    /**
50
-     * @return void
51
-     */
52
-    protected function set_config()
53
-    {
54
-        if ($this->_config instanceof EE_Ticket_Selector_Config) {
55
-            return;
56
-        }
57
-        $this->set_config_section('template_settings');
58
-        $this->set_config_class('EE_Ticket_Selector_Config');
59
-        $this->set_config_name('EED_Ticket_Selector');
60
-    }
61
-
62
-
63
-    /**
64
-     *    set_hooks - for hooking into EE Core, other modules, etc
65
-     *
66
-     * @return void
67
-     */
68
-    public static function set_hooks()
69
-    {
70
-        // routing
71
-        EED_Module::registerRoute(
72
-            'iframe',
73
-            'EED_Ticket_Selector',
74
-            'ticket_selector_iframe',
75
-            'ticket_selector'
76
-        );
77
-        EED_Module::registerRoute(
78
-            'process_ticket_selections',
79
-            'EED_Ticket_Selector',
80
-            'process_ticket_selections'
81
-        );
82
-        EED_Module::registerRoute(
83
-            'cancel_ticket_selections',
84
-            'EED_Ticket_Selector',
85
-            'cancel_ticket_selections'
86
-        );
87
-        add_action('wp_loaded', ['EED_Ticket_Selector', 'set_definitions'], 2);
88
-        add_action('AHEE_event_details_header_bottom', ['EED_Ticket_Selector', 'display_ticket_selector']);
89
-        add_action('wp_enqueue_scripts', ['EED_Ticket_Selector', 'translate_js_strings'], 0);
90
-        add_action('wp_enqueue_scripts', ['EED_Ticket_Selector', 'load_tckt_slctr_assets']);
91
-        EED_Ticket_Selector::loadIframeAssets();
92
-    }
93
-
94
-
95
-    /**
96
-     *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
97
-     *
98
-     * @return void
99
-     */
100
-    public static function set_hooks_admin()
101
-    {
102
-        // hook into the end of the \EE_Admin_Page::_load_page_dependencies()
103
-        // to load assets for "espresso_events" page on the "edit" route (action)
104
-        add_action(
105
-            'admin_init',
106
-            ['EED_Ticket_Selector', 'ticket_selector_iframe_embed_button']
107
-        );
108
-        /**
109
-         * Make sure assets for the ticket selector are loaded on the espresso registrations route so  admin side
110
-         * registrations work.
111
-         */
112
-        add_action(
113
-            'FHEE__EE_Admin_Page___load_page_dependencies__after_load__espresso_registrations__new_registration',
114
-            ['EED_Ticket_Selector', 'set_definitions']
115
-        );
116
-    }
117
-
118
-
119
-    /**
120
-     *    set_definitions
121
-     *
122
-     * @return void
123
-     * @throws EE_Error
124
-     * @throws ReflectionException
125
-     */
126
-    public static function set_definitions()
127
-    {
128
-        // don't do this twice
129
-        if (defined('TICKET_SELECTOR_ASSETS_URL')) {
130
-            return;
131
-        }
132
-        define('TICKET_SELECTOR_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets/');
133
-        define(
134
-            'TICKET_SELECTOR_TEMPLATES_PATH',
135
-            str_replace('\\', '/', plugin_dir_path(__FILE__)) . 'templates/'
136
-        );
137
-        // initialize config
138
-        EED_Ticket_Selector::instance()->set_config();
139
-        // if config is not set, initialize
140
-        if (
141
-            ! EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector instanceof EE_Ticket_Selector_Config
142
-        ) {
143
-            EED_Ticket_Selector::instance()->set_config();
144
-            EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector =
145
-                EED_Ticket_Selector::instance()->config();
146
-        }
147
-    }
148
-
149
-
150
-    /**
151
-     * @return DisplayTicketSelector
152
-     * @throws EE_Error
153
-     * @throws ReflectionException
154
-     */
155
-    public static function ticketSelector(): DisplayTicketSelector
156
-    {
157
-        if (! EED_Ticket_Selector::$ticket_selector instanceof DisplayTicketSelector) {
158
-            EED_Ticket_Selector::$ticket_selector = LoaderFactory::getLoader()->getShared(
159
-                DisplayTicketSelector::class,
160
-                [
161
-                    null,
162
-                    EED_Ticket_Selector::getRequest(),
163
-                    EED_Ticket_Selector::ticketConfig(),
164
-                    EED_Events_Archive::is_iframe(),
165
-                ]
166
-            );
167
-        }
168
-        return EED_Ticket_Selector::$ticket_selector;
169
-    }
170
-
171
-
172
-    /**
173
-     * gets the ball rolling
174
-     *
175
-     * @param WP $WP
176
-     * @return void
177
-     */
178
-    public function run($WP)
179
-    {
180
-    }
181
-
182
-
183
-    public static function getIframeEmbedButton(): TicketSelectorIframeEmbedButton
184
-    {
185
-        if (! self::$iframe_embed_button instanceof TicketSelectorIframeEmbedButton) {
186
-            self::$iframe_embed_button = new TicketSelectorIframeEmbedButton();
187
-        }
188
-        return self::$iframe_embed_button;
189
-    }
190
-
191
-
192
-    /**
193
-     * ticket_selector_iframe_embed_button
194
-     *
195
-     * @return void
196
-     */
197
-    public static function ticket_selector_iframe_embed_button()
198
-    {
199
-        $iframe_embed_button = EED_Ticket_Selector::getIframeEmbedButton();
200
-        $iframe_embed_button->addEventEditorIframeEmbedButton();
201
-    }
202
-
203
-
204
-    /**
205
-     * ticket_selector_iframe
206
-     *
207
-     * @return void
208
-     * @throws DomainException
209
-     */
210
-    public function ticket_selector_iframe()
211
-    {
212
-        EE_Dependency_Map::register_dependencies(
213
-            TicketSelectorIframe::class,
214
-            [
215
-                'EEM_Event'                                            => EE_Dependency_Map::load_from_cache,
216
-                'EventEspresso\core\services\request\CurrentPage'      => EE_Dependency_Map::load_from_cache,
217
-                'EventEspresso\core\services\request\RequestInterface' => EE_Dependency_Map::load_from_cache,
218
-            ]
219
-        );
220
-        $ticket_selector_iframe = LoaderFactory::getLoader()->getNew(TicketSelectorIframe::class);
221
-        $ticket_selector_iframe->display();
222
-    }
223
-
224
-
225
-    /**
226
-     * creates buttons for selecting number of attendees for an event
227
-     *
228
-     * @param WP_Post|int $event
229
-     * @param bool        $view_details
230
-     * @return string
231
-     * @throws EE_Error
232
-     * @throws ReflectionException
233
-     * @throws Throwable
234
-     */
235
-    public static function display_ticket_selector($event = null, bool $view_details = false): string
236
-    {
237
-        return EED_Ticket_Selector::ticketSelector()->display($event, $view_details);
238
-    }
239
-
240
-
241
-    /**
242
-     * @return bool
243
-     * @throws EE_Error
244
-     * @throws InvalidArgumentException
245
-     * @throws InvalidInterfaceException
246
-     * @throws InvalidDataTypeException
247
-     * @throws ReflectionException
248
-     */
249
-    public function process_ticket_selections(): bool
250
-    {
251
-        /** @var EventEspresso\modules\ticket_selector\ProcessTicketSelector $form */
252
-        $form = LoaderFactory::getLoader()->getShared('EventEspresso\modules\ticket_selector\ProcessTicketSelector');
253
-        return $form->processTicketSelections();
254
-    }
255
-
256
-
257
-    /**
258
-     * @return bool
259
-     * @throws InvalidArgumentException
260
-     * @throws InvalidInterfaceException
261
-     * @throws InvalidDataTypeException
262
-     * @throws EE_Error
263
-     * @throws ReflectionException
264
-     */
265
-    public static function cancel_ticket_selections(): bool
266
-    {
267
-        /** @var EventEspresso\modules\ticket_selector\ProcessTicketSelector $form */
268
-        $form = LoaderFactory::getLoader()->getShared('EventEspresso\modules\ticket_selector\ProcessTicketSelector');
269
-        return $form->cancelTicketSelections();
270
-    }
271
-
272
-
273
-    /**
274
-     * @return void
275
-     */
276
-    public static function translate_js_strings()
277
-    {
278
-        EE_Registry::$i18n_js_strings['please_select_date_filter_notice'] = esc_html__(
279
-            'please select a datetime',
280
-            'event_espresso'
281
-        );
282
-    }
283
-
284
-
285
-    /**
286
-     * @return void
287
-     * @throws EE_Error
288
-     * @throws ReflectionException
289
-     */
290
-    public static function load_tckt_slctr_assets()
291
-    {
292
-        if (apply_filters('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', false)) {
293
-            // add some style
294
-            wp_enqueue_style(
295
-                'ticket_selector',
296
-                TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.css',
297
-                [],
298
-                EVENT_ESPRESSO_VERSION
299
-            );
300
-            // make it dance
301
-            wp_enqueue_script(
302
-                'ticket_selector',
303
-                TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.js',
304
-                ['espresso_core'],
305
-                EVENT_ESPRESSO_VERSION,
306
-                true
307
-            );
308
-            wp_localize_script(
309
-                'ticket_selector',
310
-                'EEDTicketSelectorMsg',
311
-                [
312
-                    'please_select_date_filter_notice' => esc_html__(
313
-                        'please select a datetime',
314
-                        'event_espresso'
315
-                    ),
316
-                ]
317
-            );
318
-            wp_add_inline_style('espresso_default', EED_Ticket_Selector::accentColorStyles());
319
-            require_once EE_LIBRARIES
320
-                         . 'form_sections/strategies/display/EE_Checkbox_Dropdown_Selector_Display_Strategy.strategy.php';
321
-            EE_Checkbox_Dropdown_Selector_Display_Strategy::enqueue_styles_and_scripts();
322
-        }
323
-    }
324
-
325
-
326
-    /**
327
-     * @return void
328
-     */
329
-    public static function loadIframeAssets()
330
-    {
331
-        // for event lists
332
-        add_filter(
333
-            'FHEE__EventEspresso_modules_events_archive_EventsArchiveIframe__display__css',
334
-            ['EED_Ticket_Selector', 'iframeCss']
335
-        );
336
-        add_filter(
337
-            'FHEE__EventEspresso_modules_events_archive_EventsArchiveIframe__display__js',
338
-            ['EED_Ticket_Selector', 'iframeJs']
339
-        );
340
-        // for ticket selectors
341
-        add_filter(
342
-            'FHEE__EED_Ticket_Selector__ticket_selector_iframe__css',
343
-            ['EED_Ticket_Selector', 'iframeCss']
344
-        );
345
-    }
346
-
347
-
348
-    /**
349
-     * Informs the rest of the forms system what CSS and JS is needed to display the input
350
-     *
351
-     * @param array $iframe_css
352
-     * @return array
353
-     */
354
-    public static function iframeCss(array $iframe_css): array
355
-    {
356
-        $iframe_css['ticket_selector'] = TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.css';
357
-        return $iframe_css;
358
-    }
359
-
360
-
361
-    /**
362
-     * Informs the rest of the forms system what CSS and JS is needed to display the input
363
-     *
364
-     * @param array $iframe_js
365
-     * @return array
366
-     */
367
-    public static function iframeJs(array $iframe_js): array
368
-    {
369
-        $iframe_js['ticket_selector'] = TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.js';
370
-        return $iframe_js;
371
-    }
372
-
373
-
374
-    /****************************** DEPRECATED ******************************/
375
-
376
-
377
-    /**
378
-     * @return string
379
-     * @throws EE_Error
380
-     * @throws ReflectionException
381
-     * @deprecated
382
-     */
383
-    public static function display_view_details_btn(): string
384
-    {
385
-        // todo add doing_it_wrong() notice during next major version
386
-        return EED_Ticket_Selector::ticketSelector()->displayViewDetailsButton();
387
-    }
388
-
389
-
390
-    /**
391
-     * @return string
392
-     * @throws EE_Error
393
-     * @throws ReflectionException
394
-     * @deprecated
395
-     */
396
-    public static function display_ticket_selector_submit(): string
397
-    {
398
-        // todo add doing_it_wrong() notice during next major version
399
-        return EED_Ticket_Selector::ticketSelector()->displaySubmitButton();
400
-    }
401
-
402
-
403
-    /**
404
-     * @param string $permalink_string
405
-     * @param int    $id
406
-     * @param string $new_title
407
-     * @param string $new_slug
408
-     * @return string
409
-     * @throws InvalidArgumentException
410
-     * @throws InvalidDataTypeException
411
-     * @throws InvalidInterfaceException
412
-     * @deprecated
413
-     */
414
-    public static function iframe_code_button($permalink_string, $id, $new_title = '', $new_slug = ''): string
415
-    {
416
-        $request = self::getRequest();
417
-        // todo add doing_it_wrong() notice during next major version
418
-        if (
419
-            $request->getRequestParam('page') === 'espresso_events'
420
-            && $request->getRequestParam('action') === 'edit'
421
-        ) {
422
-            $iframe_embed_button = EED_Ticket_Selector::getIframeEmbedButton();
423
-            $iframe_embed_button->addEventEditorIframeEmbedButton();
424
-        }
425
-        return '';
426
-    }
427
-
428
-
429
-    /**
430
-     * @param int    $ID
431
-     * @param string $external_url
432
-     * @return string
433
-     * @throws EE_Error
434
-     * @throws ReflectionException
435
-     * @deprecated
436
-     */
437
-    public static function ticket_selector_form_open($ID = 0, $external_url = ''): string
438
-    {
439
-        // todo add doing_it_wrong() notice during next major version
440
-        return EED_Ticket_Selector::ticketSelector()->formOpen($ID, $external_url);
441
-    }
442
-
443
-
444
-    /**
445
-     * @return string
446
-     * @throws EE_Error
447
-     * @throws ReflectionException
448
-     * @deprecated
449
-     */
450
-    public static function ticket_selector_form_close(): string
451
-    {
452
-        // todo add doing_it_wrong() notice during next major version
453
-        return EED_Ticket_Selector::ticketSelector()->formClose();
454
-    }
455
-
456
-
457
-    /**
458
-     * @return string
459
-     * @throws EE_Error
460
-     * @throws ReflectionException
461
-     * @deprecated
462
-     */
463
-    public static function no_tkt_slctr_end_dv(): string
464
-    {
465
-        // todo add doing_it_wrong() notice during next major version
466
-        return EED_Ticket_Selector::ticketSelector()->ticketSelectorEndDiv();
467
-    }
468
-
469
-
470
-    /**
471
-     * @return string
472
-     * @throws EE_Error
473
-     * @throws ReflectionException
474
-     * @deprecated 4.9.13
475
-     */
476
-    public static function tkt_slctr_end_dv(): string
477
-    {
478
-        return EED_Ticket_Selector::ticketSelector()->clearTicketSelector();
479
-    }
480
-
481
-
482
-    /**
483
-     * @return string
484
-     * @throws EE_Error
485
-     * @throws ReflectionException
486
-     * @deprecated
487
-     */
488
-    public static function clear_tkt_slctr(): string
489
-    {
490
-        return EED_Ticket_Selector::ticketSelector()->clearTicketSelector();
491
-    }
492
-
493
-
494
-    /**
495
-     * @deprecated
496
-     */
497
-    public static function load_tckt_slctr_assets_admin()
498
-    {
499
-        $request = self::getRequest();
500
-        // todo add doing_it_wrong() notice during next major version
501
-        if (
502
-            $request->getRequestParam('page') === 'espresso_events'
503
-            && $request->getRequestParam('action') === 'edit'
504
-        ) {
505
-            $iframe_embed_button = EED_Ticket_Selector::getIframeEmbedButton();
506
-            $iframe_embed_button->embedButtonAssets();
507
-        }
508
-    }
509
-
510
-
511
-    /**
512
-     * @throws ReflectionException
513
-     * @throws EE_Error
514
-     */
515
-    public static function accentColorStyles(): string
516
-    {
517
-        $accent_color = EED_Ticket_Selector::ticketConfig()->accentColor();
518
-        $hue        = $accent_color[0] ?? 210;
519
-        $saturation = $accent_color[1] ?? 100;
520
-        $lightness  = $accent_color[2] ?? 50;
521
-        return "
21
+	private static ?DisplayTicketSelector $ticket_selector = null;
22
+
23
+	private static ?TicketSelectorIframeEmbedButton $iframe_embed_button = null;
24
+
25
+
26
+	/**
27
+	 * @return EED_Module|EED_Ticket_Selector
28
+	 * @throws EE_Error
29
+	 * @throws ReflectionException
30
+	 */
31
+	public static function instance()
32
+	{
33
+		return parent::get_instance(__CLASS__);
34
+	}
35
+
36
+
37
+	/**
38
+	 * @return EE_Ticket_Selector_Config
39
+	 * @throws EE_Error
40
+	 * @throws ReflectionException
41
+	 */
42
+	public static function ticketConfig(): EE_Ticket_Selector_Config
43
+	{
44
+		EED_Ticket_Selector::instance()->set_config();
45
+		return EED_Ticket_Selector::instance()->config();
46
+	}
47
+
48
+
49
+	/**
50
+	 * @return void
51
+	 */
52
+	protected function set_config()
53
+	{
54
+		if ($this->_config instanceof EE_Ticket_Selector_Config) {
55
+			return;
56
+		}
57
+		$this->set_config_section('template_settings');
58
+		$this->set_config_class('EE_Ticket_Selector_Config');
59
+		$this->set_config_name('EED_Ticket_Selector');
60
+	}
61
+
62
+
63
+	/**
64
+	 *    set_hooks - for hooking into EE Core, other modules, etc
65
+	 *
66
+	 * @return void
67
+	 */
68
+	public static function set_hooks()
69
+	{
70
+		// routing
71
+		EED_Module::registerRoute(
72
+			'iframe',
73
+			'EED_Ticket_Selector',
74
+			'ticket_selector_iframe',
75
+			'ticket_selector'
76
+		);
77
+		EED_Module::registerRoute(
78
+			'process_ticket_selections',
79
+			'EED_Ticket_Selector',
80
+			'process_ticket_selections'
81
+		);
82
+		EED_Module::registerRoute(
83
+			'cancel_ticket_selections',
84
+			'EED_Ticket_Selector',
85
+			'cancel_ticket_selections'
86
+		);
87
+		add_action('wp_loaded', ['EED_Ticket_Selector', 'set_definitions'], 2);
88
+		add_action('AHEE_event_details_header_bottom', ['EED_Ticket_Selector', 'display_ticket_selector']);
89
+		add_action('wp_enqueue_scripts', ['EED_Ticket_Selector', 'translate_js_strings'], 0);
90
+		add_action('wp_enqueue_scripts', ['EED_Ticket_Selector', 'load_tckt_slctr_assets']);
91
+		EED_Ticket_Selector::loadIframeAssets();
92
+	}
93
+
94
+
95
+	/**
96
+	 *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
97
+	 *
98
+	 * @return void
99
+	 */
100
+	public static function set_hooks_admin()
101
+	{
102
+		// hook into the end of the \EE_Admin_Page::_load_page_dependencies()
103
+		// to load assets for "espresso_events" page on the "edit" route (action)
104
+		add_action(
105
+			'admin_init',
106
+			['EED_Ticket_Selector', 'ticket_selector_iframe_embed_button']
107
+		);
108
+		/**
109
+		 * Make sure assets for the ticket selector are loaded on the espresso registrations route so  admin side
110
+		 * registrations work.
111
+		 */
112
+		add_action(
113
+			'FHEE__EE_Admin_Page___load_page_dependencies__after_load__espresso_registrations__new_registration',
114
+			['EED_Ticket_Selector', 'set_definitions']
115
+		);
116
+	}
117
+
118
+
119
+	/**
120
+	 *    set_definitions
121
+	 *
122
+	 * @return void
123
+	 * @throws EE_Error
124
+	 * @throws ReflectionException
125
+	 */
126
+	public static function set_definitions()
127
+	{
128
+		// don't do this twice
129
+		if (defined('TICKET_SELECTOR_ASSETS_URL')) {
130
+			return;
131
+		}
132
+		define('TICKET_SELECTOR_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets/');
133
+		define(
134
+			'TICKET_SELECTOR_TEMPLATES_PATH',
135
+			str_replace('\\', '/', plugin_dir_path(__FILE__)) . 'templates/'
136
+		);
137
+		// initialize config
138
+		EED_Ticket_Selector::instance()->set_config();
139
+		// if config is not set, initialize
140
+		if (
141
+			! EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector instanceof EE_Ticket_Selector_Config
142
+		) {
143
+			EED_Ticket_Selector::instance()->set_config();
144
+			EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector =
145
+				EED_Ticket_Selector::instance()->config();
146
+		}
147
+	}
148
+
149
+
150
+	/**
151
+	 * @return DisplayTicketSelector
152
+	 * @throws EE_Error
153
+	 * @throws ReflectionException
154
+	 */
155
+	public static function ticketSelector(): DisplayTicketSelector
156
+	{
157
+		if (! EED_Ticket_Selector::$ticket_selector instanceof DisplayTicketSelector) {
158
+			EED_Ticket_Selector::$ticket_selector = LoaderFactory::getLoader()->getShared(
159
+				DisplayTicketSelector::class,
160
+				[
161
+					null,
162
+					EED_Ticket_Selector::getRequest(),
163
+					EED_Ticket_Selector::ticketConfig(),
164
+					EED_Events_Archive::is_iframe(),
165
+				]
166
+			);
167
+		}
168
+		return EED_Ticket_Selector::$ticket_selector;
169
+	}
170
+
171
+
172
+	/**
173
+	 * gets the ball rolling
174
+	 *
175
+	 * @param WP $WP
176
+	 * @return void
177
+	 */
178
+	public function run($WP)
179
+	{
180
+	}
181
+
182
+
183
+	public static function getIframeEmbedButton(): TicketSelectorIframeEmbedButton
184
+	{
185
+		if (! self::$iframe_embed_button instanceof TicketSelectorIframeEmbedButton) {
186
+			self::$iframe_embed_button = new TicketSelectorIframeEmbedButton();
187
+		}
188
+		return self::$iframe_embed_button;
189
+	}
190
+
191
+
192
+	/**
193
+	 * ticket_selector_iframe_embed_button
194
+	 *
195
+	 * @return void
196
+	 */
197
+	public static function ticket_selector_iframe_embed_button()
198
+	{
199
+		$iframe_embed_button = EED_Ticket_Selector::getIframeEmbedButton();
200
+		$iframe_embed_button->addEventEditorIframeEmbedButton();
201
+	}
202
+
203
+
204
+	/**
205
+	 * ticket_selector_iframe
206
+	 *
207
+	 * @return void
208
+	 * @throws DomainException
209
+	 */
210
+	public function ticket_selector_iframe()
211
+	{
212
+		EE_Dependency_Map::register_dependencies(
213
+			TicketSelectorIframe::class,
214
+			[
215
+				'EEM_Event'                                            => EE_Dependency_Map::load_from_cache,
216
+				'EventEspresso\core\services\request\CurrentPage'      => EE_Dependency_Map::load_from_cache,
217
+				'EventEspresso\core\services\request\RequestInterface' => EE_Dependency_Map::load_from_cache,
218
+			]
219
+		);
220
+		$ticket_selector_iframe = LoaderFactory::getLoader()->getNew(TicketSelectorIframe::class);
221
+		$ticket_selector_iframe->display();
222
+	}
223
+
224
+
225
+	/**
226
+	 * creates buttons for selecting number of attendees for an event
227
+	 *
228
+	 * @param WP_Post|int $event
229
+	 * @param bool        $view_details
230
+	 * @return string
231
+	 * @throws EE_Error
232
+	 * @throws ReflectionException
233
+	 * @throws Throwable
234
+	 */
235
+	public static function display_ticket_selector($event = null, bool $view_details = false): string
236
+	{
237
+		return EED_Ticket_Selector::ticketSelector()->display($event, $view_details);
238
+	}
239
+
240
+
241
+	/**
242
+	 * @return bool
243
+	 * @throws EE_Error
244
+	 * @throws InvalidArgumentException
245
+	 * @throws InvalidInterfaceException
246
+	 * @throws InvalidDataTypeException
247
+	 * @throws ReflectionException
248
+	 */
249
+	public function process_ticket_selections(): bool
250
+	{
251
+		/** @var EventEspresso\modules\ticket_selector\ProcessTicketSelector $form */
252
+		$form = LoaderFactory::getLoader()->getShared('EventEspresso\modules\ticket_selector\ProcessTicketSelector');
253
+		return $form->processTicketSelections();
254
+	}
255
+
256
+
257
+	/**
258
+	 * @return bool
259
+	 * @throws InvalidArgumentException
260
+	 * @throws InvalidInterfaceException
261
+	 * @throws InvalidDataTypeException
262
+	 * @throws EE_Error
263
+	 * @throws ReflectionException
264
+	 */
265
+	public static function cancel_ticket_selections(): bool
266
+	{
267
+		/** @var EventEspresso\modules\ticket_selector\ProcessTicketSelector $form */
268
+		$form = LoaderFactory::getLoader()->getShared('EventEspresso\modules\ticket_selector\ProcessTicketSelector');
269
+		return $form->cancelTicketSelections();
270
+	}
271
+
272
+
273
+	/**
274
+	 * @return void
275
+	 */
276
+	public static function translate_js_strings()
277
+	{
278
+		EE_Registry::$i18n_js_strings['please_select_date_filter_notice'] = esc_html__(
279
+			'please select a datetime',
280
+			'event_espresso'
281
+		);
282
+	}
283
+
284
+
285
+	/**
286
+	 * @return void
287
+	 * @throws EE_Error
288
+	 * @throws ReflectionException
289
+	 */
290
+	public static function load_tckt_slctr_assets()
291
+	{
292
+		if (apply_filters('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', false)) {
293
+			// add some style
294
+			wp_enqueue_style(
295
+				'ticket_selector',
296
+				TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.css',
297
+				[],
298
+				EVENT_ESPRESSO_VERSION
299
+			);
300
+			// make it dance
301
+			wp_enqueue_script(
302
+				'ticket_selector',
303
+				TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.js',
304
+				['espresso_core'],
305
+				EVENT_ESPRESSO_VERSION,
306
+				true
307
+			);
308
+			wp_localize_script(
309
+				'ticket_selector',
310
+				'EEDTicketSelectorMsg',
311
+				[
312
+					'please_select_date_filter_notice' => esc_html__(
313
+						'please select a datetime',
314
+						'event_espresso'
315
+					),
316
+				]
317
+			);
318
+			wp_add_inline_style('espresso_default', EED_Ticket_Selector::accentColorStyles());
319
+			require_once EE_LIBRARIES
320
+						 . 'form_sections/strategies/display/EE_Checkbox_Dropdown_Selector_Display_Strategy.strategy.php';
321
+			EE_Checkbox_Dropdown_Selector_Display_Strategy::enqueue_styles_and_scripts();
322
+		}
323
+	}
324
+
325
+
326
+	/**
327
+	 * @return void
328
+	 */
329
+	public static function loadIframeAssets()
330
+	{
331
+		// for event lists
332
+		add_filter(
333
+			'FHEE__EventEspresso_modules_events_archive_EventsArchiveIframe__display__css',
334
+			['EED_Ticket_Selector', 'iframeCss']
335
+		);
336
+		add_filter(
337
+			'FHEE__EventEspresso_modules_events_archive_EventsArchiveIframe__display__js',
338
+			['EED_Ticket_Selector', 'iframeJs']
339
+		);
340
+		// for ticket selectors
341
+		add_filter(
342
+			'FHEE__EED_Ticket_Selector__ticket_selector_iframe__css',
343
+			['EED_Ticket_Selector', 'iframeCss']
344
+		);
345
+	}
346
+
347
+
348
+	/**
349
+	 * Informs the rest of the forms system what CSS and JS is needed to display the input
350
+	 *
351
+	 * @param array $iframe_css
352
+	 * @return array
353
+	 */
354
+	public static function iframeCss(array $iframe_css): array
355
+	{
356
+		$iframe_css['ticket_selector'] = TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.css';
357
+		return $iframe_css;
358
+	}
359
+
360
+
361
+	/**
362
+	 * Informs the rest of the forms system what CSS and JS is needed to display the input
363
+	 *
364
+	 * @param array $iframe_js
365
+	 * @return array
366
+	 */
367
+	public static function iframeJs(array $iframe_js): array
368
+	{
369
+		$iframe_js['ticket_selector'] = TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.js';
370
+		return $iframe_js;
371
+	}
372
+
373
+
374
+	/****************************** DEPRECATED ******************************/
375
+
376
+
377
+	/**
378
+	 * @return string
379
+	 * @throws EE_Error
380
+	 * @throws ReflectionException
381
+	 * @deprecated
382
+	 */
383
+	public static function display_view_details_btn(): string
384
+	{
385
+		// todo add doing_it_wrong() notice during next major version
386
+		return EED_Ticket_Selector::ticketSelector()->displayViewDetailsButton();
387
+	}
388
+
389
+
390
+	/**
391
+	 * @return string
392
+	 * @throws EE_Error
393
+	 * @throws ReflectionException
394
+	 * @deprecated
395
+	 */
396
+	public static function display_ticket_selector_submit(): string
397
+	{
398
+		// todo add doing_it_wrong() notice during next major version
399
+		return EED_Ticket_Selector::ticketSelector()->displaySubmitButton();
400
+	}
401
+
402
+
403
+	/**
404
+	 * @param string $permalink_string
405
+	 * @param int    $id
406
+	 * @param string $new_title
407
+	 * @param string $new_slug
408
+	 * @return string
409
+	 * @throws InvalidArgumentException
410
+	 * @throws InvalidDataTypeException
411
+	 * @throws InvalidInterfaceException
412
+	 * @deprecated
413
+	 */
414
+	public static function iframe_code_button($permalink_string, $id, $new_title = '', $new_slug = ''): string
415
+	{
416
+		$request = self::getRequest();
417
+		// todo add doing_it_wrong() notice during next major version
418
+		if (
419
+			$request->getRequestParam('page') === 'espresso_events'
420
+			&& $request->getRequestParam('action') === 'edit'
421
+		) {
422
+			$iframe_embed_button = EED_Ticket_Selector::getIframeEmbedButton();
423
+			$iframe_embed_button->addEventEditorIframeEmbedButton();
424
+		}
425
+		return '';
426
+	}
427
+
428
+
429
+	/**
430
+	 * @param int    $ID
431
+	 * @param string $external_url
432
+	 * @return string
433
+	 * @throws EE_Error
434
+	 * @throws ReflectionException
435
+	 * @deprecated
436
+	 */
437
+	public static function ticket_selector_form_open($ID = 0, $external_url = ''): string
438
+	{
439
+		// todo add doing_it_wrong() notice during next major version
440
+		return EED_Ticket_Selector::ticketSelector()->formOpen($ID, $external_url);
441
+	}
442
+
443
+
444
+	/**
445
+	 * @return string
446
+	 * @throws EE_Error
447
+	 * @throws ReflectionException
448
+	 * @deprecated
449
+	 */
450
+	public static function ticket_selector_form_close(): string
451
+	{
452
+		// todo add doing_it_wrong() notice during next major version
453
+		return EED_Ticket_Selector::ticketSelector()->formClose();
454
+	}
455
+
456
+
457
+	/**
458
+	 * @return string
459
+	 * @throws EE_Error
460
+	 * @throws ReflectionException
461
+	 * @deprecated
462
+	 */
463
+	public static function no_tkt_slctr_end_dv(): string
464
+	{
465
+		// todo add doing_it_wrong() notice during next major version
466
+		return EED_Ticket_Selector::ticketSelector()->ticketSelectorEndDiv();
467
+	}
468
+
469
+
470
+	/**
471
+	 * @return string
472
+	 * @throws EE_Error
473
+	 * @throws ReflectionException
474
+	 * @deprecated 4.9.13
475
+	 */
476
+	public static function tkt_slctr_end_dv(): string
477
+	{
478
+		return EED_Ticket_Selector::ticketSelector()->clearTicketSelector();
479
+	}
480
+
481
+
482
+	/**
483
+	 * @return string
484
+	 * @throws EE_Error
485
+	 * @throws ReflectionException
486
+	 * @deprecated
487
+	 */
488
+	public static function clear_tkt_slctr(): string
489
+	{
490
+		return EED_Ticket_Selector::ticketSelector()->clearTicketSelector();
491
+	}
492
+
493
+
494
+	/**
495
+	 * @deprecated
496
+	 */
497
+	public static function load_tckt_slctr_assets_admin()
498
+	{
499
+		$request = self::getRequest();
500
+		// todo add doing_it_wrong() notice during next major version
501
+		if (
502
+			$request->getRequestParam('page') === 'espresso_events'
503
+			&& $request->getRequestParam('action') === 'edit'
504
+		) {
505
+			$iframe_embed_button = EED_Ticket_Selector::getIframeEmbedButton();
506
+			$iframe_embed_button->embedButtonAssets();
507
+		}
508
+	}
509
+
510
+
511
+	/**
512
+	 * @throws ReflectionException
513
+	 * @throws EE_Error
514
+	 */
515
+	public static function accentColorStyles(): string
516
+	{
517
+		$accent_color = EED_Ticket_Selector::ticketConfig()->accentColor();
518
+		$hue        = $accent_color[0] ?? 210;
519
+		$saturation = $accent_color[1] ?? 100;
520
+		$lightness  = $accent_color[2] ?? 50;
521
+		return "
522 522
         :root {
523 523
             --ee-ts-accent-color: hsl($hue $saturation% $lightness%);
524 524
             --ee-ts-accent-color-hover: hsl($hue $saturation% " . ($lightness - 5) . "%);
@@ -538,5 +538,5 @@  discard block
 block discarded – undo
538 538
                 --ee-ts-button-text-color: hsl($hue " . ($saturation * .02) . "% " . (($lightness + 80) * .95) . "%);
539 539
             }
540 540
         }";
541
-    }
541
+	}
542 542
 }
Please login to merge, or discard this patch.
Spacing   +20 added lines, -20 removed lines patch added patch discarded remove patch
@@ -129,10 +129,10 @@  discard block
 block discarded – undo
129 129
         if (defined('TICKET_SELECTOR_ASSETS_URL')) {
130 130
             return;
131 131
         }
132
-        define('TICKET_SELECTOR_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets/');
132
+        define('TICKET_SELECTOR_ASSETS_URL', plugin_dir_url(__FILE__).'assets/');
133 133
         define(
134 134
             'TICKET_SELECTOR_TEMPLATES_PATH',
135
-            str_replace('\\', '/', plugin_dir_path(__FILE__)) . 'templates/'
135
+            str_replace('\\', '/', plugin_dir_path(__FILE__)).'templates/'
136 136
         );
137 137
         // initialize config
138 138
         EED_Ticket_Selector::instance()->set_config();
@@ -154,7 +154,7 @@  discard block
 block discarded – undo
154 154
      */
155 155
     public static function ticketSelector(): DisplayTicketSelector
156 156
     {
157
-        if (! EED_Ticket_Selector::$ticket_selector instanceof DisplayTicketSelector) {
157
+        if ( ! EED_Ticket_Selector::$ticket_selector instanceof DisplayTicketSelector) {
158 158
             EED_Ticket_Selector::$ticket_selector = LoaderFactory::getLoader()->getShared(
159 159
                 DisplayTicketSelector::class,
160 160
                 [
@@ -182,7 +182,7 @@  discard block
 block discarded – undo
182 182
 
183 183
     public static function getIframeEmbedButton(): TicketSelectorIframeEmbedButton
184 184
     {
185
-        if (! self::$iframe_embed_button instanceof TicketSelectorIframeEmbedButton) {
185
+        if ( ! self::$iframe_embed_button instanceof TicketSelectorIframeEmbedButton) {
186 186
             self::$iframe_embed_button = new TicketSelectorIframeEmbedButton();
187 187
         }
188 188
         return self::$iframe_embed_button;
@@ -293,14 +293,14 @@  discard block
 block discarded – undo
293 293
             // add some style
294 294
             wp_enqueue_style(
295 295
                 'ticket_selector',
296
-                TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.css',
296
+                TICKET_SELECTOR_ASSETS_URL.'ticket_selector.css',
297 297
                 [],
298 298
                 EVENT_ESPRESSO_VERSION
299 299
             );
300 300
             // make it dance
301 301
             wp_enqueue_script(
302 302
                 'ticket_selector',
303
-                TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.js',
303
+                TICKET_SELECTOR_ASSETS_URL.'ticket_selector.js',
304 304
                 ['espresso_core'],
305 305
                 EVENT_ESPRESSO_VERSION,
306 306
                 true
@@ -353,7 +353,7 @@  discard block
 block discarded – undo
353 353
      */
354 354
     public static function iframeCss(array $iframe_css): array
355 355
     {
356
-        $iframe_css['ticket_selector'] = TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.css';
356
+        $iframe_css['ticket_selector'] = TICKET_SELECTOR_ASSETS_URL.'ticket_selector.css';
357 357
         return $iframe_css;
358 358
     }
359 359
 
@@ -366,7 +366,7 @@  discard block
 block discarded – undo
366 366
      */
367 367
     public static function iframeJs(array $iframe_js): array
368 368
     {
369
-        $iframe_js['ticket_selector'] = TICKET_SELECTOR_ASSETS_URL . 'ticket_selector.js';
369
+        $iframe_js['ticket_selector'] = TICKET_SELECTOR_ASSETS_URL.'ticket_selector.js';
370 370
         return $iframe_js;
371 371
     }
372 372
 
@@ -521,21 +521,21 @@  discard block
 block discarded – undo
521 521
         return "
522 522
         :root {
523 523
             --ee-ts-accent-color: hsl($hue $saturation% $lightness%);
524
-            --ee-ts-accent-color-hover: hsl($hue $saturation% " . ($lightness - 5) . "%);
525
-            --ee-ts-background: hsl($hue " . ($saturation * .02) . "% " . ($lightness + 80) * .95 . "%);
526
-            --ee-ts-border-color: hsl($hue " . ($saturation * .05) . "% " . ($lightness - 10) . "%);
527
-            --ee-ts-input-disabled: hsl($hue " . ($saturation * .15) . "% $lightness%);
528
-            --ee-ts-text-color: hsl($hue " . ($saturation * .1) . "% " . ($lightness * .6) . "%);
529
-            --ee-ts-button-text-color: hsl($hue " . ($saturation * .02) . "% " . (($lightness + 80) * .95) . "%);
524
+            --ee-ts-accent-color-hover: hsl($hue $saturation% ".($lightness - 5)."%);
525
+            --ee-ts-background: hsl($hue ".($saturation * .02)."% ".($lightness + 80) * .95."%);
526
+            --ee-ts-border-color: hsl($hue ".($saturation * .05)."% ".($lightness - 10)."%);
527
+            --ee-ts-input-disabled: hsl($hue ".($saturation * .15)."% $lightness%);
528
+            --ee-ts-text-color: hsl($hue ".($saturation * .1)."% ".($lightness * .6)."%);
529
+            --ee-ts-button-text-color: hsl($hue ".($saturation * .02)."% ".(($lightness + 80) * .95)."%);
530 530
 
531 531
             @media (prefers-color-scheme: dark) {
532 532
                 --ee-ts-accent-color: hsl($hue $saturation% $lightness%);
533
-                --ee-ts-accent-color-hover: hsl($hue $saturation% " . ($lightness + 5) . "%);
534
-                --ee-ts-background: hsl($hue " . ($saturation * .02) . "% " . ($lightness * .35) . "%);
535
-                --ee-ts-border-color: hsl($hue " . ($saturation * .05) . "% " . ($lightness + 10) . "%);
536
-                --ee-ts-input-disabled: hsl($hue " . ($saturation * .15) . "% $lightness%);
537
-                --ee-ts-text-color: hsl($hue " . ($saturation * .02) . "% " . ($lightness * 1.7) . "%);
538
-                --ee-ts-button-text-color: hsl($hue " . ($saturation * .02) . "% " . (($lightness + 80) * .95) . "%);
533
+                --ee-ts-accent-color-hover: hsl($hue $saturation% ".($lightness + 5)."%);
534
+                --ee-ts-background: hsl($hue ".($saturation * .02)."% ".($lightness * .35)."%);
535
+                --ee-ts-border-color: hsl($hue ".($saturation * .05)."% ".($lightness + 10)."%);
536
+                --ee-ts-input-disabled: hsl($hue ".($saturation * .15)."% $lightness%);
537
+                --ee-ts-text-color: hsl($hue ".($saturation * .02)."% ".($lightness * 1.7)."%);
538
+                --ee-ts-button-text-color: hsl($hue ".($saturation * .02)."% ".(($lightness + 80) * .95)."%);
539 539
             }
540 540
         }";
541 541
     }
Please login to merge, or discard this patch.
modules/events_archive/EventsArchiveIframe.php 1 patch
Indentation   +59 added lines, -59 removed lines patch added patch discarded remove patch
@@ -22,63 +22,63 @@
 block discarded – undo
22 22
  */
23 23
 class EventsArchiveIframe extends Iframe
24 24
 {
25
-    /**
26
-     * EventsArchiveIframe constructor.
27
-     *
28
-     * @param EED_Events_Archive $EED_Events_Archive
29
-     * @throws EE_Error
30
-     * @throws ReflectionException
31
-     */
32
-    public function __construct($EED_Events_Archive)
33
-    {
34
-        /** @var CurrentPage $current_page */
35
-        $current_page = LoaderFactory::getLoader()->getShared(CurrentPage::class);
36
-        $current_page->setEspressoPage(true);
37
-        add_filter('FHEE__EED_Events_Archive__event_list_iframe', '__return_true');
38
-        $EED_Events_Archive->event_list();
39
-        /** @var EspressoEvents $event_list */
40
-        $event_list = EE_Registry::instance()->create('EventEspresso\core\domain\entities\shortcodes\EspressoEvents');
41
-        $shortcode_content = $event_list->processShortcode();
42
-        if (empty($shortcode_content)) {
43
-            return;
44
-        }
45
-        parent::__construct(
46
-            esc_html__('Event List', 'event_espresso'),
47
-            $shortcode_content
48
-        );
49
-        $this->addStylesheets(
50
-            apply_filters(
51
-                'FHEE__EventEspresso_modules_events_archive_EventsArchiveIframe__display__css',
52
-                [
53
-                    'espresso_default' => is_readable(EVENT_ESPRESSO_UPLOAD_DIR . 'css/style.css')
54
-                        ? EVENT_ESPRESSO_UPLOAD_DIR . 'css/espresso_default.css?ver=' . EVENT_ESPRESSO_VERSION
55
-                        : EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css?ver=' . EVENT_ESPRESSO_VERSION,
56
-                ],
57
-                $this
58
-            )
59
-        );
60
-        $this->addInlineStyles('ticket_selector', EED_Ticket_Selector::accentColorStyles());
61
-        $this->addScripts(
62
-            apply_filters(
63
-                'FHEE__EventEspresso_modules_events_archive_EventsArchiveIframe__display__js',
64
-                [
65
-                    'gmap_api' => sprintf(
66
-                        'https://maps.googleapis.com/maps/api/js?key=%s',
67
-                        apply_filters(
68
-                            'FHEE__EEH_Maps__espresso_google_maps_js__api_key',
69
-                            EE_Registry::instance()->CFG->map_settings->google_map_api_key
70
-                        )
71
-                    ),
72
-                    'ee_gmap'  => EE_HELPERS_ASSETS . 'ee_gmap.js?ver=1.0',
73
-                ],
74
-                $this
75
-            )
76
-        );
77
-        $this->addLocalizedVars(
78
-            [
79
-                'ee_gmap' => EEH_Maps::$gmap_vars,
80
-            ],
81
-            'ee_gmap_vars'
82
-        );
83
-    }
25
+	/**
26
+	 * EventsArchiveIframe constructor.
27
+	 *
28
+	 * @param EED_Events_Archive $EED_Events_Archive
29
+	 * @throws EE_Error
30
+	 * @throws ReflectionException
31
+	 */
32
+	public function __construct($EED_Events_Archive)
33
+	{
34
+		/** @var CurrentPage $current_page */
35
+		$current_page = LoaderFactory::getLoader()->getShared(CurrentPage::class);
36
+		$current_page->setEspressoPage(true);
37
+		add_filter('FHEE__EED_Events_Archive__event_list_iframe', '__return_true');
38
+		$EED_Events_Archive->event_list();
39
+		/** @var EspressoEvents $event_list */
40
+		$event_list = EE_Registry::instance()->create('EventEspresso\core\domain\entities\shortcodes\EspressoEvents');
41
+		$shortcode_content = $event_list->processShortcode();
42
+		if (empty($shortcode_content)) {
43
+			return;
44
+		}
45
+		parent::__construct(
46
+			esc_html__('Event List', 'event_espresso'),
47
+			$shortcode_content
48
+		);
49
+		$this->addStylesheets(
50
+			apply_filters(
51
+				'FHEE__EventEspresso_modules_events_archive_EventsArchiveIframe__display__css',
52
+				[
53
+					'espresso_default' => is_readable(EVENT_ESPRESSO_UPLOAD_DIR . 'css/style.css')
54
+						? EVENT_ESPRESSO_UPLOAD_DIR . 'css/espresso_default.css?ver=' . EVENT_ESPRESSO_VERSION
55
+						: EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css?ver=' . EVENT_ESPRESSO_VERSION,
56
+				],
57
+				$this
58
+			)
59
+		);
60
+		$this->addInlineStyles('ticket_selector', EED_Ticket_Selector::accentColorStyles());
61
+		$this->addScripts(
62
+			apply_filters(
63
+				'FHEE__EventEspresso_modules_events_archive_EventsArchiveIframe__display__js',
64
+				[
65
+					'gmap_api' => sprintf(
66
+						'https://maps.googleapis.com/maps/api/js?key=%s',
67
+						apply_filters(
68
+							'FHEE__EEH_Maps__espresso_google_maps_js__api_key',
69
+							EE_Registry::instance()->CFG->map_settings->google_map_api_key
70
+						)
71
+					),
72
+					'ee_gmap'  => EE_HELPERS_ASSETS . 'ee_gmap.js?ver=1.0',
73
+				],
74
+				$this
75
+			)
76
+		);
77
+		$this->addLocalizedVars(
78
+			[
79
+				'ee_gmap' => EEH_Maps::$gmap_vars,
80
+			],
81
+			'ee_gmap_vars'
82
+		);
83
+	}
84 84
 }
Please login to merge, or discard this patch.
admin_pages/payments/Payments_Admin_Page.core.php 2 patches
Indentation   +1295 added lines, -1295 removed lines patch added patch discarded remove patch
@@ -18,286 +18,286 @@  discard block
 block discarded – undo
18 18
  */
19 19
 class Payments_Admin_Page extends EE_Admin_Page
20 20
 {
21
-    /**
22
-     * Variables used for when we're re-sorting the logs results,
23
-     * in case we needed to do two queries, and we need to resort
24
-     *
25
-     * @var string
26
-     */
27
-    private $_sort_logs_again_direction;
28
-
29
-
30
-    /**
31
-     * @Constructor
32
-     * @access public
33
-     * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
34
-     * @throws EE_Error
35
-     * @throws InvalidArgumentException
36
-     * @throws InvalidDataTypeException
37
-     * @throws InvalidInterfaceException
38
-     * @throws ReflectionException
39
-     */
40
-    public function __construct($routing = true)
41
-    {
42
-        parent::__construct($routing);
43
-    }
44
-
45
-
46
-    protected function _init_page_props()
47
-    {
48
-        $this->page_slug        = EE_PAYMENTS_PG_SLUG;
49
-        $this->page_label       = esc_html__('Payment Methods', 'event_espresso');
50
-        $this->_admin_base_url  = EE_PAYMENTS_ADMIN_URL;
51
-        $this->_admin_base_path = EE_PAYMENTS_ADMIN;
52
-    }
53
-
54
-
55
-    protected function _ajax_hooks()
56
-    {
57
-        // todo: all hooks for ajax goes here.
58
-    }
59
-
60
-
61
-    protected function _define_page_props()
62
-    {
63
-        $this->_admin_page_title = $this->page_label;
64
-        $this->_labels           = [
65
-            'publishbox' => esc_html__('Update Settings', 'event_espresso'),
66
-        ];
67
-    }
68
-
69
-
70
-    /**
71
-     * @param string $sort_logs_again_direction
72
-     */
73
-    public function setSortLogsAgainDirection(string $sort_logs_again_direction): void
74
-    {
75
-        $this->_sort_logs_again_direction = $sort_logs_again_direction;
76
-    }
77
-
78
-
79
-    protected function _set_page_routes()
80
-    {
81
-        /**
82
-         * note that with payment method capabilities, although we've implemented
83
-         * capability mapping which will be used for accessing payment methods owned by
84
-         * other users.  This is not fully implemented yet in the payment method ui.
85
-         * Currently, only the "plural" caps are in active use.
86
-         * When cap mapping is implemented, some routes will need to use the singular form of
87
-         * capability method and also include the $id of the payment method for the route.
88
-         **/
89
-        $this->_page_routes = [
90
-            'default'                   => [
91
-                'func'       => '_payment_methods_list',
92
-                'capability' => 'ee_edit_payment_methods',
93
-            ],
94
-            'payment_settings'          => [
95
-                'func'       => '_payment_settings',
96
-                'capability' => 'ee_manage_gateways',
97
-            ],
98
-            'activate_payment_method'   => [
99
-                'func'       => '_activate_payment_method',
100
-                'noheader'   => true,
101
-                'capability' => 'ee_edit_payment_methods',
102
-            ],
103
-            'deactivate_payment_method' => [
104
-                'func'       => '_deactivate_payment_method',
105
-                'noheader'   => true,
106
-                'capability' => 'ee_delete_payment_methods',
107
-            ],
108
-            'update_payment_method'     => [
109
-                'func'               => '_update_payment_method',
110
-                'noheader'           => true,
111
-                'headers_sent_route' => 'default',
112
-                'capability'         => 'ee_edit_payment_methods',
113
-            ],
114
-            'update_payment_settings'   => [
115
-                'func'       => '_update_payment_settings',
116
-                'noheader'   => true,
117
-                'capability' => 'ee_manage_gateways',
118
-            ],
119
-            'payment_log'               => [
120
-                'func'       => '_payment_log_overview_list_table',
121
-                'capability' => 'ee_read_payment_methods',
122
-            ],
123
-            'payment_log_details'       => [
124
-                'func'       => '_payment_log_details',
125
-                'capability' => 'ee_read_payment_methods',
126
-            ],
127
-        ];
128
-    }
129
-
130
-
131
-    /**
132
-     * @throws EE_Error
133
-     * @throws ReflectionException
134
-     */
135
-    protected function _set_page_config()
136
-    {
137
-        $payment_method_list_config = [
138
-            'nav'           => [
139
-                'label' => esc_html__('Payment Methods', 'event_espresso'),
140
-                'icon'  => 'dashicons-bank',
141
-                'order' => 10,
142
-            ],
143
-            'metaboxes'     => $this->_default_espresso_metaboxes,
144
-            'help_tabs'     => array_merge(
145
-                [
146
-                    'payment_methods_overview_help_tab' => [
147
-                        'title'    => esc_html__('Payment Methods Overview', 'event_espresso'),
148
-                        'filename' => 'payment_methods_overview',
149
-                    ],
150
-                ],
151
-                $this->_add_payment_method_help_tabs()
152
-            ),
153
-            'require_nonce' => false,
154
-        ];
155
-        $this->_page_config         = [
156
-            'default'          => $payment_method_list_config,
157
-            'payment_settings' => [
158
-                'nav'           => [
159
-                    'label' => esc_html__('Settings', 'event_espresso'),
160
-                    'icon'  => 'dashicons-admin-generic',
161
-                    'order' => 20,
162
-                ],
163
-                'help_tabs'     => [
164
-                    'payment_methods_settings_help_tab' => [
165
-                        'title'    => esc_html__('Payment Method Settings', 'event_espresso'),
166
-                        'filename' => 'payment_methods_settings',
167
-                    ],
168
-                ],
169
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
170
-                'require_nonce' => false,
171
-            ],
172
-            'payment_log'      => [
173
-                'nav'           => [
174
-                    'label' => esc_html__("Logs", 'event_espresso'),
175
-                    'icon'  => 'dashicons-text-page',
176
-                    'order' => 30,
177
-                ],
178
-                'list_table'    => 'Payment_Log_Admin_List_Table',
179
-                'metaboxes'     => $this->_default_espresso_metaboxes,
180
-                'require_nonce' => false,
181
-            ],
182
-        ];
183
-    }
184
-
185
-
186
-    /**
187
-     * @return array
188
-     * @throws DomainException
189
-     * @throws EE_Error
190
-     * @throws InvalidArgumentException
191
-     * @throws InvalidDataTypeException
192
-     * @throws InvalidInterfaceException
193
-     * @throws ReflectionException
194
-     */
195
-    protected function _add_payment_method_help_tabs(): array
196
-    {
197
-        EE_Registry::instance()->load_lib('Payment_Method_Manager');
198
-        $payment_method_types     = EE_Payment_Method_Manager::instance()->payment_method_types();
199
-        $all_pmt_help_tabs_config = [];
200
-        foreach ($payment_method_types as $payment_method_type) {
201
-            if (
202
-                ! $this->capabilities->current_user_can(
203
-                    $payment_method_type->cap_name(),
204
-                    'specific_payment_method_type_access'
205
-                )
206
-            ) {
207
-                continue;
208
-            }
209
-            foreach ($payment_method_type->help_tabs_config() as $help_tab_name => $config) {
210
-                $template_args                              = $config['template_args'] ?? [];
211
-                $template_args['admin_page_obj']            = $this;
212
-                $all_pmt_help_tabs_config[ $help_tab_name ] = [
213
-                    'title'   => $config['title'],
214
-                    'content' => EEH_Template::display_template(
215
-                        $payment_method_type->file_folder() . 'help_tabs/' . $config['filename'] . '.help_tab.php',
216
-                        $template_args,
217
-                        true
218
-                    ),
219
-                ];
220
-            }
221
-        }
222
-        return $all_pmt_help_tabs_config;
223
-    }
224
-
225
-
226
-    // none of the below group are currently used for Gateway Settings
227
-    protected function _add_screen_options()
228
-    {
229
-    }
230
-
231
-
232
-    protected function _add_feature_pointers()
233
-    {
234
-    }
235
-
236
-
237
-    public function admin_init()
238
-    {
239
-    }
240
-
241
-
242
-    public function admin_notices()
243
-    {
244
-    }
245
-
246
-
247
-    public function admin_footer_scripts()
248
-    {
249
-    }
250
-
251
-
252
-    public function load_scripts_styles()
253
-    {
254
-        // styles
255
-        wp_enqueue_style('espresso-ui-theme');
256
-        wp_register_style(
257
-            'espresso_payments',
258
-            EE_PAYMENTS_ASSETS_URL . 'ee-payments.css',
259
-            [],
260
-            EVENT_ESPRESSO_VERSION
261
-        );
262
-        // scripts
263
-        wp_enqueue_script('ee_admin_js');
264
-        wp_enqueue_script('ee-text-links');
265
-        wp_enqueue_script(
266
-            'espresso_payments',
267
-            EE_PAYMENTS_ASSETS_URL . 'espresso_payments_admin.js',
268
-            ['ee-datepicker'],
269
-            EVENT_ESPRESSO_VERSION,
270
-            true
271
-        );
272
-    }
273
-
274
-
275
-    public function load_scripts_styles_default()
276
-    {
277
-        wp_enqueue_style('espresso_payments');
278
-        wp_enqueue_style('ee-text-links');
279
-    }
280
-
281
-
282
-    public function load_scripts_styles_payment_log_details()
283
-    {
284
-        wp_enqueue_style('espresso_payments');
285
-    }
286
-
287
-
288
-    /**
289
-     * @throws EE_Error
290
-     */
291
-    private function veryifyTablesExist()
292
-    {
293
-        /** @var TableAnalysis $table_analysis */
294
-        $table_analysis = LoaderFactory::getShared(TableAnalysis::class);
295
-        /** @var TableManager $table_manager */
296
-        $table_manager = LoaderFactory::getShared(TableManager::class);
297
-        if (! $table_analysis->tableExists('esp_payment_method')) {
298
-            $table_manager->createTable(
299
-                'esp_payment_method',
300
-                "PMD_ID int(11) NOT NULL AUTO_INCREMENT,
21
+	/**
22
+	 * Variables used for when we're re-sorting the logs results,
23
+	 * in case we needed to do two queries, and we need to resort
24
+	 *
25
+	 * @var string
26
+	 */
27
+	private $_sort_logs_again_direction;
28
+
29
+
30
+	/**
31
+	 * @Constructor
32
+	 * @access public
33
+	 * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
34
+	 * @throws EE_Error
35
+	 * @throws InvalidArgumentException
36
+	 * @throws InvalidDataTypeException
37
+	 * @throws InvalidInterfaceException
38
+	 * @throws ReflectionException
39
+	 */
40
+	public function __construct($routing = true)
41
+	{
42
+		parent::__construct($routing);
43
+	}
44
+
45
+
46
+	protected function _init_page_props()
47
+	{
48
+		$this->page_slug        = EE_PAYMENTS_PG_SLUG;
49
+		$this->page_label       = esc_html__('Payment Methods', 'event_espresso');
50
+		$this->_admin_base_url  = EE_PAYMENTS_ADMIN_URL;
51
+		$this->_admin_base_path = EE_PAYMENTS_ADMIN;
52
+	}
53
+
54
+
55
+	protected function _ajax_hooks()
56
+	{
57
+		// todo: all hooks for ajax goes here.
58
+	}
59
+
60
+
61
+	protected function _define_page_props()
62
+	{
63
+		$this->_admin_page_title = $this->page_label;
64
+		$this->_labels           = [
65
+			'publishbox' => esc_html__('Update Settings', 'event_espresso'),
66
+		];
67
+	}
68
+
69
+
70
+	/**
71
+	 * @param string $sort_logs_again_direction
72
+	 */
73
+	public function setSortLogsAgainDirection(string $sort_logs_again_direction): void
74
+	{
75
+		$this->_sort_logs_again_direction = $sort_logs_again_direction;
76
+	}
77
+
78
+
79
+	protected function _set_page_routes()
80
+	{
81
+		/**
82
+		 * note that with payment method capabilities, although we've implemented
83
+		 * capability mapping which will be used for accessing payment methods owned by
84
+		 * other users.  This is not fully implemented yet in the payment method ui.
85
+		 * Currently, only the "plural" caps are in active use.
86
+		 * When cap mapping is implemented, some routes will need to use the singular form of
87
+		 * capability method and also include the $id of the payment method for the route.
88
+		 **/
89
+		$this->_page_routes = [
90
+			'default'                   => [
91
+				'func'       => '_payment_methods_list',
92
+				'capability' => 'ee_edit_payment_methods',
93
+			],
94
+			'payment_settings'          => [
95
+				'func'       => '_payment_settings',
96
+				'capability' => 'ee_manage_gateways',
97
+			],
98
+			'activate_payment_method'   => [
99
+				'func'       => '_activate_payment_method',
100
+				'noheader'   => true,
101
+				'capability' => 'ee_edit_payment_methods',
102
+			],
103
+			'deactivate_payment_method' => [
104
+				'func'       => '_deactivate_payment_method',
105
+				'noheader'   => true,
106
+				'capability' => 'ee_delete_payment_methods',
107
+			],
108
+			'update_payment_method'     => [
109
+				'func'               => '_update_payment_method',
110
+				'noheader'           => true,
111
+				'headers_sent_route' => 'default',
112
+				'capability'         => 'ee_edit_payment_methods',
113
+			],
114
+			'update_payment_settings'   => [
115
+				'func'       => '_update_payment_settings',
116
+				'noheader'   => true,
117
+				'capability' => 'ee_manage_gateways',
118
+			],
119
+			'payment_log'               => [
120
+				'func'       => '_payment_log_overview_list_table',
121
+				'capability' => 'ee_read_payment_methods',
122
+			],
123
+			'payment_log_details'       => [
124
+				'func'       => '_payment_log_details',
125
+				'capability' => 'ee_read_payment_methods',
126
+			],
127
+		];
128
+	}
129
+
130
+
131
+	/**
132
+	 * @throws EE_Error
133
+	 * @throws ReflectionException
134
+	 */
135
+	protected function _set_page_config()
136
+	{
137
+		$payment_method_list_config = [
138
+			'nav'           => [
139
+				'label' => esc_html__('Payment Methods', 'event_espresso'),
140
+				'icon'  => 'dashicons-bank',
141
+				'order' => 10,
142
+			],
143
+			'metaboxes'     => $this->_default_espresso_metaboxes,
144
+			'help_tabs'     => array_merge(
145
+				[
146
+					'payment_methods_overview_help_tab' => [
147
+						'title'    => esc_html__('Payment Methods Overview', 'event_espresso'),
148
+						'filename' => 'payment_methods_overview',
149
+					],
150
+				],
151
+				$this->_add_payment_method_help_tabs()
152
+			),
153
+			'require_nonce' => false,
154
+		];
155
+		$this->_page_config         = [
156
+			'default'          => $payment_method_list_config,
157
+			'payment_settings' => [
158
+				'nav'           => [
159
+					'label' => esc_html__('Settings', 'event_espresso'),
160
+					'icon'  => 'dashicons-admin-generic',
161
+					'order' => 20,
162
+				],
163
+				'help_tabs'     => [
164
+					'payment_methods_settings_help_tab' => [
165
+						'title'    => esc_html__('Payment Method Settings', 'event_espresso'),
166
+						'filename' => 'payment_methods_settings',
167
+					],
168
+				],
169
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
170
+				'require_nonce' => false,
171
+			],
172
+			'payment_log'      => [
173
+				'nav'           => [
174
+					'label' => esc_html__("Logs", 'event_espresso'),
175
+					'icon'  => 'dashicons-text-page',
176
+					'order' => 30,
177
+				],
178
+				'list_table'    => 'Payment_Log_Admin_List_Table',
179
+				'metaboxes'     => $this->_default_espresso_metaboxes,
180
+				'require_nonce' => false,
181
+			],
182
+		];
183
+	}
184
+
185
+
186
+	/**
187
+	 * @return array
188
+	 * @throws DomainException
189
+	 * @throws EE_Error
190
+	 * @throws InvalidArgumentException
191
+	 * @throws InvalidDataTypeException
192
+	 * @throws InvalidInterfaceException
193
+	 * @throws ReflectionException
194
+	 */
195
+	protected function _add_payment_method_help_tabs(): array
196
+	{
197
+		EE_Registry::instance()->load_lib('Payment_Method_Manager');
198
+		$payment_method_types     = EE_Payment_Method_Manager::instance()->payment_method_types();
199
+		$all_pmt_help_tabs_config = [];
200
+		foreach ($payment_method_types as $payment_method_type) {
201
+			if (
202
+				! $this->capabilities->current_user_can(
203
+					$payment_method_type->cap_name(),
204
+					'specific_payment_method_type_access'
205
+				)
206
+			) {
207
+				continue;
208
+			}
209
+			foreach ($payment_method_type->help_tabs_config() as $help_tab_name => $config) {
210
+				$template_args                              = $config['template_args'] ?? [];
211
+				$template_args['admin_page_obj']            = $this;
212
+				$all_pmt_help_tabs_config[ $help_tab_name ] = [
213
+					'title'   => $config['title'],
214
+					'content' => EEH_Template::display_template(
215
+						$payment_method_type->file_folder() . 'help_tabs/' . $config['filename'] . '.help_tab.php',
216
+						$template_args,
217
+						true
218
+					),
219
+				];
220
+			}
221
+		}
222
+		return $all_pmt_help_tabs_config;
223
+	}
224
+
225
+
226
+	// none of the below group are currently used for Gateway Settings
227
+	protected function _add_screen_options()
228
+	{
229
+	}
230
+
231
+
232
+	protected function _add_feature_pointers()
233
+	{
234
+	}
235
+
236
+
237
+	public function admin_init()
238
+	{
239
+	}
240
+
241
+
242
+	public function admin_notices()
243
+	{
244
+	}
245
+
246
+
247
+	public function admin_footer_scripts()
248
+	{
249
+	}
250
+
251
+
252
+	public function load_scripts_styles()
253
+	{
254
+		// styles
255
+		wp_enqueue_style('espresso-ui-theme');
256
+		wp_register_style(
257
+			'espresso_payments',
258
+			EE_PAYMENTS_ASSETS_URL . 'ee-payments.css',
259
+			[],
260
+			EVENT_ESPRESSO_VERSION
261
+		);
262
+		// scripts
263
+		wp_enqueue_script('ee_admin_js');
264
+		wp_enqueue_script('ee-text-links');
265
+		wp_enqueue_script(
266
+			'espresso_payments',
267
+			EE_PAYMENTS_ASSETS_URL . 'espresso_payments_admin.js',
268
+			['ee-datepicker'],
269
+			EVENT_ESPRESSO_VERSION,
270
+			true
271
+		);
272
+	}
273
+
274
+
275
+	public function load_scripts_styles_default()
276
+	{
277
+		wp_enqueue_style('espresso_payments');
278
+		wp_enqueue_style('ee-text-links');
279
+	}
280
+
281
+
282
+	public function load_scripts_styles_payment_log_details()
283
+	{
284
+		wp_enqueue_style('espresso_payments');
285
+	}
286
+
287
+
288
+	/**
289
+	 * @throws EE_Error
290
+	 */
291
+	private function veryifyTablesExist()
292
+	{
293
+		/** @var TableAnalysis $table_analysis */
294
+		$table_analysis = LoaderFactory::getShared(TableAnalysis::class);
295
+		/** @var TableManager $table_manager */
296
+		$table_manager = LoaderFactory::getShared(TableManager::class);
297
+		if (! $table_analysis->tableExists('esp_payment_method')) {
298
+			$table_manager->createTable(
299
+				'esp_payment_method',
300
+				"PMD_ID int(11) NOT NULL AUTO_INCREMENT,
301 301
 				PMD_type varchar(124) DEFAULT NULL,
302 302
 				PMD_name varchar(255) DEFAULT NULL,
303 303
 				PMD_desc text,
@@ -313,1023 +313,1023 @@  discard block
 block discarded – undo
313 313
 				PRIMARY KEY  (PMD_ID),
314 314
 				UNIQUE KEY PMD_slug_UNIQUE (PMD_slug),
315 315
 				KEY PMD_type (PMD_type)",
316
-                'InnoDB'
317
-            );
318
-        }
319
-        if (! $table_analysis->tableExists('esp_currency_payment_method')) {
320
-            $table_manager->createTable(
321
-                'esp_currency_payment_method',
322
-                "CPM_ID int(11) NOT NULL AUTO_INCREMENT,
316
+				'InnoDB'
317
+			);
318
+		}
319
+		if (! $table_analysis->tableExists('esp_currency_payment_method')) {
320
+			$table_manager->createTable(
321
+				'esp_currency_payment_method',
322
+				"CPM_ID int(11) NOT NULL AUTO_INCREMENT,
323 323
 				CUR_code varchar(6) NOT NULL,
324 324
 				PMD_ID int(11) NOT NULL,
325 325
 				PRIMARY KEY  (CPM_ID),
326 326
 				KEY PMD_ID (PMD_ID)",
327
-                'InnoDB'
328
-            );
329
-        }
330
-    }
331
-
332
-
333
-    /**
334
-     * @throws EE_Error
335
-     * @throws ReflectionException
336
-     */
337
-    protected function _payment_methods_list()
338
-    {
339
-        $this->veryifyTablesExist();
340
-        /**
341
-         * first let's ensure payment methods have been set up.
342
-         * We do this here because when people activate a payment method for the first time (as an addon),
343
-         * it may not set up its capabilities or get registered correctly due to the loading process.
344
-         * However, people MUST set up the details for the payment method,
345
-         * so it's safe to do a recheck here.
346
-         */
347
-        EE_Registry::instance()->load_lib('Payment_Method_Manager');
348
-        EEM_Payment_Method::instance()->verify_button_urls();
349
-        // set up tabs, one for each payment method type
350
-        $tabs            = [];
351
-        $payment_methods = [];
352
-        foreach (EE_Payment_Method_Manager::instance()->payment_method_types() as $pmt_obj) {
353
-            // we don't want to show admin-only PMTs for now
354
-            if ($pmt_obj instanceof EE_PMT_Admin_Only) {
355
-                continue;
356
-            }
357
-            // check access
358
-            if (
359
-                ! $this->capabilities->current_user_can(
360
-                    $pmt_obj->cap_name(),
361
-                    'specific_payment_method_type_access'
362
-                )
363
-            ) {
364
-                continue;
365
-            }
366
-            // check for any active pms of that type
367
-            $payment_method = EEM_Payment_Method::instance()->get_one_of_type($pmt_obj->system_name());
368
-            if (! $payment_method instanceof EE_Payment_Method) {
369
-                $payment_method = EE_Payment_Method::new_instance(
370
-                    [
371
-                        'PMD_slug'       => sanitize_key($pmt_obj->system_name()),
372
-                        'PMD_type'       => $pmt_obj->system_name(),
373
-                        'PMD_name'       => $pmt_obj->pretty_name(),
374
-                        'PMD_admin_name' => $pmt_obj->pretty_name(),
375
-                    ]
376
-                );
377
-            }
378
-            $payment_methods[ $payment_method->slug() ] = $payment_method;
379
-        }
380
-        $payment_methods = apply_filters(
381
-            'FHEE__Payments_Admin_Page___payment_methods_list__payment_methods',
382
-            $payment_methods
383
-        );
384
-        foreach ($payment_methods as $payment_method) {
385
-            if ($payment_method instanceof EE_Payment_Method) {
386
-                $this->addMetaBox(
387
-                // html id
388
-                    'espresso_' . $payment_method->slug() . '_payment_settings',
389
-                    // title
390
-                    sprintf(esc_html__('%s Settings', 'event_espresso'), $payment_method->admin_name()),
391
-                    // callback
392
-                    [$this, 'payment_method_settings_meta_box'],
393
-                    // post type
394
-                    null,
395
-                    // context
396
-                    'normal',
397
-                    // priority
398
-                    'default',
399
-                    // callback args
400
-                    ['payment_method' => $payment_method]
401
-                );
402
-                // setup for tabbed content
403
-                $tabs[ $payment_method->slug() ] = [
404
-                    'label' => $payment_method->admin_name(),
405
-                    'class' => $payment_method->active()
406
-                        ? 'gateway-active'
407
-                        : '',
408
-                    'href'  => 'espresso_' . $payment_method->slug() . '_payment_settings',
409
-                    'title' => esc_html__('Modify this Payment Method', 'event_espresso'),
410
-                    'slug'  => $payment_method->slug(),
411
-                    'icon'  => $payment_method->active()
412
-                        ? '<span class="dashicons dashicons-yes-alt"></span>'
413
-                        : '<span class="dashicons dashicons-remove"></span>',
414
-                ];
415
-            }
416
-        }
417
-        $this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
418
-            $tabs,
419
-            'payment_method_links',
420
-            '',
421
-            $this->_get_active_payment_method_slug()
422
-        );
423
-        $this->display_admin_page_with_sidebar();
424
-    }
425
-
426
-
427
-    /**
428
-     *   _get_active_payment_method_slug
429
-     *
430
-     * @return string
431
-     * @throws EE_Error
432
-     * @throws ReflectionException
433
-     */
434
-    protected function _get_active_payment_method_slug()
435
-    {
436
-        $payment_method_slug = false;
437
-        // decide which payment method tab to open first, as dictated by the request's 'payment_method'
438
-        if (isset($this->_req_data['payment_method'])) {
439
-            // if they provided the current payment method, use it
440
-            $payment_method_slug = sanitize_key($this->_req_data['payment_method']);
441
-        }
442
-
443
-        $payment_method = EEM_Payment_Method::instance()->get_one([['PMD_slug' => $payment_method_slug]]);
444
-        // if that didn't work or wasn't provided, find another way to select the current pm
445
-        if (! $this->_verify_payment_method($payment_method)) {
446
-            // like, looking for an active one
447
-            $payment_method = EEM_Payment_Method::instance()->get_one_active(EEM_Payment_Method::scope_cart);
448
-            // test that one as well
449
-            if ($this->_verify_payment_method($payment_method)) {
450
-                $payment_method_slug = $payment_method->slug();
451
-            } else {
452
-                $payment_method_slug = 'paypal_standard';
453
-            }
454
-        }
455
-        return $payment_method_slug;
456
-    }
457
-
458
-
459
-    /**
460
-     *    payment_method_settings_meta_box
461
-     *    returns TRUE if the passed payment method is properly constructed and the logged-in user has the correct
462
-     *    capabilities to access it
463
-     *
464
-     * @param EE_Payment_Method|null $payment_method
465
-     * @return boolean
466
-     * @throws EE_Error
467
-     */
468
-    protected function _verify_payment_method(?EE_Payment_Method $payment_method): bool
469
-    {
470
-        return $payment_method instanceof EE_Payment_Method
471
-               && $payment_method->type_obj() instanceof EE_PMT_Base
472
-               && $this->capabilities->current_user_can(
473
-                   $payment_method->type_obj()->cap_name(),
474
-                   'specific_payment_method_type_access'
475
-               );
476
-    }
477
-
478
-
479
-    /**
480
-     *    payment_method_settings_meta_box
481
-     *
482
-     * @param NULL  $post_obj_which_is_null is an object containing the current post (as a $post object)
483
-     * @param array $metabox                is an array with metabox id, title, callback, and args elements. the value
484
-     *                                      at 'args' has key 'payment_method', as set within _payment_methods_list
485
-     * @return void
486
-     * @throws EE_Error
487
-     * @throws ReflectionException
488
-     */
489
-    public function payment_method_settings_meta_box($post_obj_which_is_null, array $metabox)
490
-    {
491
-        $payment_method = isset($metabox['args'], $metabox['args']['payment_method'])
492
-            ? $metabox['args']['payment_method']
493
-            : null;
494
-        if (! $payment_method instanceof EE_Payment_Method) {
495
-            throw new EE_Error(
496
-                esc_html__(
497
-                    'Payment method metabox setup incorrectly. No Payment method object was supplied',
498
-                    'event_espresso'
499
-                )
500
-            );
501
-        }
502
-        $payment_method_scopes = $payment_method->active();
503
-        // if the payment method really exists show its form, otherwise the activation template
504
-        if ($payment_method->ID() && ! empty($payment_method_scopes)) {
505
-            $form = $this->_generate_payment_method_settings_form($payment_method);
506
-            if ($form->form_data_present_in($this->_req_data)) {
507
-                $form->receive_form_submission($this->_req_data);
508
-            }
509
-            echo wp_kses(
510
-                $form->form_open() . $form->get_html_and_js() . $form->form_close(),
511
-                AllowedTags::getWithFormTags()
512
-            );
513
-        } else {
514
-            echo wp_kses(
515
-                $this->_activate_payment_method_button($payment_method)->get_html_and_js(),
516
-                AllowedTags::getWithFormTags()
517
-            );
518
-        }
519
-    }
520
-
521
-
522
-    /**
523
-     * Gets the form for all the settings related to this payment method type
524
-     *
525
-     * @access protected
526
-     * @param EE_Payment_Method|null $payment_method
527
-     * @return EE_Form_Section_Proper
528
-     * @throws EE_Error
529
-     * @throws ReflectionException
530
-     */
531
-    protected function _generate_payment_method_settings_form(
532
-        ?EE_Payment_Method $payment_method
533
-    ): EE_Form_Section_Proper {
534
-        if (! $payment_method instanceof EE_Payment_Method) {
535
-            return new EE_Form_Section_Proper();
536
-        }
537
-        $subsections = apply_filters(
538
-            'FHEE__Payments_Admin_Page___generate_payment_method_settings_form__form_subsections',
539
-            [
540
-                'pci_dss_compliance'      => $this->_pci_dss_compliance($payment_method),
541
-                'currency_support'        => $this->_currency_support($payment_method),
542
-                'payment_method_settings' => $this->_payment_method_settings($payment_method),
543
-                'update'                  => $this->_update_payment_method_button($payment_method),
544
-                'deactivate'              => $this->_deactivate_payment_method_button($payment_method),
545
-                'fine_print'              => $this->_fine_print(),
546
-            ],
547
-            $payment_method
548
-        );
549
-        return new EE_Form_Section_Proper(
550
-            [
551
-                'name'            => $payment_method->slug() . '_settings_form',
552
-                'html_id'         => $payment_method->slug() . '_settings_form',
553
-                'action'          => EE_Admin_Page::add_query_args_and_nonce(
554
-                    [
555
-                        'action'         => 'update_payment_method',
556
-                        'payment_method' => $payment_method->slug(),
557
-                    ],
558
-                    EE_PAYMENTS_ADMIN_URL
559
-                ),
560
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
561
-                'subsections'     => array_filter($subsections),
562
-            ]
563
-        );
564
-    }
565
-
566
-
567
-    /**
568
-     * _pci_dss_compliance
569
-     *
570
-     * @access protected
571
-     * @param EE_Payment_Method $payment_method
572
-     * @return EE_Form_Section_HTML|null
573
-     * @throws EE_Error
574
-     */
575
-    protected function _pci_dss_compliance(EE_Payment_Method $payment_method): ?EE_Form_Section_HTML
576
-    {
577
-        if (! $payment_method->type_obj()->requires_https()) {
578
-            return null;
579
-        }
580
-        return new EE_Form_Section_HTML(
581
-            EEH_HTML::tr(
582
-                EEH_HTML::th(
583
-                    EEH_HTML::label(
584
-                        EEH_HTML::strong(
585
-                            esc_html__('IMPORTANT', 'event_espresso'),
586
-                            '',
587
-                            'important-notice'
588
-                        )
589
-                    )
590
-                ) .
591
-                EEH_HTML::td(
592
-                    EEH_HTML::div(
593
-                        EEH_HTML::strong(
594
-                            esc_html__(
595
-                                'You are responsible for your own website security and Payment Card Industry Data Security Standards (PCI DSS) compliance.',
596
-                                'event_espresso'
597
-                            )
598
-                        ),
599
-                        '',
600
-                        'ee-status-outline ee-status-bg--warning'
601
-                    )
602
-                    . EEH_HTML::br()
603
-
604
-                    . EEH_HTML::div(
605
-                        esc_html__('Learn more about ', 'event_espresso')
606
-                        . EEH_HTML::link(
607
-                            'https://www.pcisecuritystandards.org/merchants/index.php',
608
-                            esc_html__('PCI DSS compliance', 'event_espresso')
609
-                        ),
610
-                        '',
611
-                        'ee-status-outline ee-status-bg--info'
612
-                    )
613
-                )
614
-            )
615
-        );
616
-    }
617
-
618
-
619
-    /**
620
-     * _currency_support
621
-     *
622
-     * @access protected
623
-     * @param EE_Payment_Method $payment_method
624
-     * @return EE_Form_Section_HTML|null
625
-     * @throws EE_Error
626
-     */
627
-    protected function _currency_support(EE_Payment_Method $payment_method): ?EE_Form_Section_HTML
628
-    {
629
-        if ($payment_method->usable_for_currency(EE_Config::instance()->currency->code)) {
630
-            return null;
631
-        }
632
-        return new EE_Form_Section_HTML(
633
-            EEH_HTML::tr(
634
-                EEH_HTML::th(
635
-                    EEH_HTML::label(
636
-                        EEH_HTML::strong(
637
-                            esc_html__('IMPORTANT', 'event_espresso'),
638
-                            '',
639
-                            'important-notice'
640
-                        )
641
-                    )
642
-                ) .
643
-                EEH_HTML::td(
644
-                    EEH_HTML::div(
645
-                        EEH_HTML::strong(
646
-                            sprintf(
647
-                                esc_html__(
648
-                                    'This payment method does not support the currency set on your site (%1$s). Please activate a different payment method or change your site\'s country and associated currency.',
649
-                                    'event_espresso'
650
-                                ),
651
-                                EE_Config::instance()->currency->code
652
-                            )
653
-                        ),
654
-                        '',
655
-                        'ee-status-outline ee-status-bg--warning'
656
-                    )
657
-                )
658
-            )
659
-        );
660
-    }
661
-
662
-
663
-    /**
664
-     * _update_payment_method_button
665
-     *
666
-     * @access protected
667
-     * @param EE_Payment_Method $payment_method
668
-     * @return EE_Payment_Method_Form
669
-     * @throws EE_Error
670
-     * @throws ReflectionException
671
-     */
672
-    protected function _payment_method_settings(EE_Payment_Method $payment_method): EE_Payment_Method_Form
673
-    {
674
-        // modify the form, so we only have/show fields that will be implemented for this version
675
-        return $this->_simplify_form($payment_method->type_obj()->settings_form(), $payment_method->name());
676
-    }
677
-
678
-
679
-    /**
680
-     * Simplifies the form to merely reproduce 4.1's gateway settings functionality
681
-     *
682
-     * @param EE_Form_Section_Proper $form_section
683
-     * @param string                 $payment_method_name
684
-     * @return EE_Payment_Method_Form
685
-     * @throws EE_Error
686
-     */
687
-    protected function _simplify_form(
688
-        EE_Form_Section_Proper $form_section,
689
-        string $payment_method_name = ''
690
-    ): EE_Payment_Method_Form {
691
-        if ($form_section instanceof EE_Payment_Method_Form) {
692
-            $form_section->exclude(
693
-                [
694
-                    'PMD_type', // don't want them changing the type
695
-                    'PMD_slug', // or the slug (probably never)
696
-                    'PMD_wp_user', // or the user's ID
697
-                    'Currency', // or the currency, until the rest of EE supports simultaneous currencies
698
-                ]
699
-            );
700
-            return $form_section;
701
-        }
702
-        throw new EE_Error(
703
-            sprintf(
704
-                esc_html__(
705
-                    'The EE_Payment_Method_Form for the "%1$s" payment method is missing or invalid.',
706
-                    'event_espresso'
707
-                ),
708
-                $payment_method_name
709
-            )
710
-        );
711
-    }
712
-
713
-
714
-    /**
715
-     * _update_payment_method_button
716
-     *
717
-     * @access protected
718
-     * @param EE_Payment_Method $payment_method
719
-     * @return EE_Form_Section_HTML
720
-     * @throws EE_Error
721
-     */
722
-    protected function _update_payment_method_button(EE_Payment_Method $payment_method): EE_Form_Section_HTML
723
-    {
724
-        $update_button = new EE_Submit_Input(
725
-            [
726
-                'name'       => 'submit',
727
-                'html_id'    => 'save_' . $payment_method->slug() . '_settings',
728
-                'default'    => sprintf(
729
-                    esc_html__('Update %s Payment Settings', 'event_espresso'),
730
-                    $payment_method->admin_name()
731
-                ),
732
-                'html_label' => EEH_HTML::nbsp(),
733
-            ]
734
-        );
735
-        return new EE_Form_Section_HTML(
736
-            EEH_HTML::tr(
737
-                EEH_HTML::th(
738
-                // esc_html__('Update Settings', 'event_espresso'),
739
-                    '&nbsp;',
740
-                    '',
741
-                    'ee-update-' . $payment_method->slug() . '-settings__label'
742
-                ) .
743
-                EEH_HTML::td(
744
-                    $update_button->get_html_for_input(),
745
-                    '',
746
-                    'ee-update-' . $payment_method->slug() . '-settings__input'
747
-                ),
748
-                '',
749
-                'ee-update-' . $payment_method->slug() . '-settings'
750
-            )
751
-        );
752
-    }
753
-
754
-
755
-    /**
756
-     * _deactivate_payment_method_button
757
-     *
758
-     * @access protected
759
-     * @param EE_Payment_Method $payment_method
760
-     * @return EE_Form_Section_HTML
761
-     */
762
-    protected function _deactivate_payment_method_button(EE_Payment_Method $payment_method): EE_Form_Section_HTML
763
-    {
764
-        $link_text_and_title = sprintf(
765
-            esc_html__('Deactivate %1$s Payments?', 'event_espresso'),
766
-            $payment_method->admin_name()
767
-        );
768
-        return new EE_Form_Section_HTML(
769
-            EEH_HTML::tr(
770
-                EEH_HTML::th(
771
-                // esc_html__('Deactivate Payment Method', 'event_espresso'),
772
-                    '&nbsp;',
773
-                    '',
774
-                    'ee-deactivate-' . $payment_method->slug() . '-settings__label'
775
-                ) .
776
-                EEH_HTML::td(
777
-                    EEH_HTML::link(
778
-                        EE_Admin_Page::add_query_args_and_nonce(
779
-                            [
780
-                                'action'         => 'deactivate_payment_method',
781
-                                'payment_method' => $payment_method->slug(),
782
-                            ],
783
-                            EE_PAYMENTS_ADMIN_URL
784
-                        ),
785
-                        $link_text_and_title,
786
-                        $link_text_and_title,
787
-                        'deactivate_' . $payment_method->slug(),
788
-                        'button button--secondary'
789
-                    ),
790
-                    '',
791
-                    'ee-deactivate-' . $payment_method->slug() . '-settings__input'
792
-                ),
793
-                '',
794
-                'ee-deactivate-' . $payment_method->slug() . '-settings'
795
-            )
796
-        );
797
-    }
798
-
799
-
800
-    /**
801
-     * _activate_payment_method_button
802
-     *
803
-     * @access protected
804
-     * @param EE_Payment_Method $payment_method
805
-     * @return EE_Form_Section_Proper
806
-     * @throws EE_Error
807
-     */
808
-    protected function _activate_payment_method_button(EE_Payment_Method $payment_method): EE_Form_Section_Proper
809
-    {
810
-        $link_text_and_title = sprintf(
811
-            esc_html__('Activate %1$s Payment Method?', 'event_espresso'),
812
-            $payment_method->admin_name()
813
-        );
814
-        return new EE_Form_Section_Proper(
815
-            [
816
-                'name'            => 'activate_' . $payment_method->slug() . '_settings_form',
817
-                'html_id'         => 'activate_' . $payment_method->slug() . '_settings_form',
818
-                'action'          => '#',
819
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
820
-                'subsections'     => apply_filters(
821
-                    'FHEE__Payments_Admin_Page___activate_payment_method_button__form_subsections',
822
-                    [
823
-                        new EE_Form_Section_HTML(
824
-                            EEH_HTML::table(
825
-                                EEH_HTML::tr(
826
-                                    EEH_HTML::td(
827
-                                        $payment_method->type_obj()->introductory_html(),
828
-                                        '',
829
-                                        '',
830
-                                        '',
831
-                                        'colspan="2"'
832
-                                    )
833
-                                ) .
834
-                                EEH_HTML::tr(
835
-                                    EEH_HTML::th(
836
-                                        EEH_HTML::label(esc_html__('Click to Activate ', 'event_espresso'))
837
-                                    ) .
838
-                                    EEH_HTML::td(
839
-                                        EEH_HTML::link(
840
-                                            EE_Admin_Page::add_query_args_and_nonce(
841
-                                                [
842
-                                                    'action'              => 'activate_payment_method',
843
-                                                    'payment_method_type' => $payment_method->type(),
844
-                                                ],
845
-                                                EE_PAYMENTS_ADMIN_URL
846
-                                            ),
847
-                                            $link_text_and_title,
848
-                                            $link_text_and_title,
849
-                                            'activate_' . $payment_method->slug(),
850
-                                            'button button--primary-alt'
851
-                                        )
852
-                                    )
853
-                                )
854
-                            )
855
-                        ),
856
-                    ],
857
-                    $payment_method
858
-                ),
859
-            ]
860
-        );
861
-    }
862
-
863
-
864
-    /**
865
-     * _fine_print
866
-     *
867
-     * @access protected
868
-     * @return EE_Form_Section_HTML
869
-     */
870
-    protected function _fine_print(): EE_Form_Section_HTML
871
-    {
872
-        return new EE_Form_Section_HTML(
873
-            EEH_HTML::tr(
874
-                EEH_HTML::th()
875
-                . EEH_HTML::thx()
876
-                . EEH_HTML::td(
877
-                    EEH_HTML::p(
878
-                        esc_html__('All fields marked with a * are required fields', 'event_espresso'),
879
-                        '',
880
-                        'grey-text'
881
-                    )
882
-                )
883
-            )
884
-        );
885
-    }
886
-
887
-
888
-    /**
889
-     * Activates a payment method of that type. Mostly assuming there is only 1 of that type (or none so far)
890
-     *
891
-     * @throws EE_Error
892
-     * @throws ReflectionException
893
-     * @global WP_User $current_user
894
-     */
895
-    protected function _activate_payment_method()
896
-    {
897
-        if (isset($this->_req_data['payment_method_type'])) {
898
-            $payment_method_type = sanitize_text_field($this->_req_data['payment_method_type']);
899
-            // see if one exists
900
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
901
-            $payment_method = EE_Payment_Method_Manager::instance()
902
-                                                       ->activate_a_payment_method_of_type($payment_method_type);
903
-            $this->_redirect_after_action(
904
-                1,
905
-                'Payment Method',
906
-                'activated',
907
-                ['action' => 'default', 'payment_method' => $payment_method->slug()]
908
-            );
909
-        } else {
910
-            $this->_redirect_after_action(false, 'Payment Method', 'activated', ['action' => 'default']);
911
-        }
912
-    }
913
-
914
-
915
-    /**
916
-     * @throws EE_Error
917
-     * @throws ReflectionException
918
-     */
919
-    protected function _deactivate_payment_method()
920
-    {
921
-        if (isset($this->_req_data['payment_method'])) {
922
-            $payment_method_slug = sanitize_key($this->_req_data['payment_method']);
923
-            // deactivate it
924
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
925
-            $count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method($payment_method_slug);
926
-            $this->_redirect_after_action(
927
-                $count_updated,
928
-                'Payment Method',
929
-                'deactivated',
930
-                ['action' => 'default', 'payment_method' => $payment_method_slug]
931
-            );
932
-        } else {
933
-            $this->_redirect_after_action(false, 'Payment Method', 'deactivated', ['action' => 'default']);
934
-        }
935
-    }
936
-
937
-
938
-    /**
939
-     * Processes the payment method form that was submitted. This is slightly trickier than usual form
940
-     * processing because we first need to identify WHICH form was processed and which payment method
941
-     * it corresponds to. Once we have done that, we see if the form is valid. If it is, the
942
-     * form's data is saved, and we redirect to the default payment methods page, setting the updated payment method
943
-     * as the currently-selected one. If it DOESN'T validate, we render the page with the form's errors (in the
944
-     * subsequently called 'headers_sent_func' which is _payment_methods_list)
945
-     *
946
-     * @return void
947
-     * @throws EE_Error
948
-     * @throws ReflectionException
949
-     */
950
-    protected function _update_payment_method()
951
-    {
952
-        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
953
-            // ok let's find which gateway form to use based on the form input
954
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
955
-            /** @var $correct_pmt_form_to_use EE_Payment_Method_Form */
956
-            $correct_pmt_form_to_use = null;
957
-            $payment_method          = null;
958
-            foreach (EEM_Payment_Method::instance()->get_all() as $payment_method) {
959
-                if ($payment_method instanceof EE_Payment_Method) {
960
-                    // get the form and simplify it, like what we do when we display it
961
-                    $pmt_form = $this->_generate_payment_method_settings_form($payment_method);
962
-                    if ($pmt_form->form_data_present_in($this->_req_data)) {
963
-                        $correct_pmt_form_to_use = $pmt_form;
964
-                        break;
965
-                    }
966
-                }
967
-            }
968
-            // if we couldn't find the correct payment method type...
969
-            if (! $correct_pmt_form_to_use) {
970
-                EE_Error::add_error(
971
-                    esc_html__(
972
-                        "We could not find which payment method type your form submission related to. Please contact support",
973
-                        'event_espresso'
974
-                    ),
975
-                    __FILE__,
976
-                    __FUNCTION__,
977
-                    __LINE__
978
-                );
979
-                $this->_redirect_after_action(false, 'Payment Method', 'activated', ['action' => 'default']);
980
-            }
981
-            $correct_pmt_form_to_use->receive_form_submission($this->_req_data);
982
-            if ($correct_pmt_form_to_use->is_valid()) {
983
-                $payment_settings_subform = $correct_pmt_form_to_use->get_subsection('payment_method_settings');
984
-                if (! $payment_settings_subform instanceof EE_Payment_Method_Form) {
985
-                    throw new EE_Error(
986
-                        sprintf(
987
-                            esc_html__(
988
-                                'The payment method could not be saved because the form sections were misnamed. We expected to find %1$s, but did not.',
989
-                                'event_espresso'
990
-                            ),
991
-                            'payment_method_settings'
992
-                        )
993
-                    );
994
-                }
995
-                $payment_settings_subform->save();
996
-                /** @var $pm EE_Payment_Method */
997
-                $this->_redirect_after_action(
998
-                    true,
999
-                    'Payment Method',
1000
-                    'updated',
1001
-                    ['action' => 'default', 'payment_method' => $payment_method->slug()]
1002
-                );
1003
-            } else {
1004
-                EE_Error::add_error(
1005
-                    sprintf(
1006
-                        esc_html__(
1007
-                            'Payment method of type %s was not saved because there were validation errors. They have been marked in the form',
1008
-                            'event_espresso'
1009
-                        ),
1010
-                        $payment_method instanceof EE_Payment_Method
1011
-                            ? $payment_method->type_obj()->pretty_name()
1012
-                            : esc_html__('"(unknown)"', 'event_espresso')
1013
-                    ),
1014
-                    __FILE__,
1015
-                    __FUNCTION__,
1016
-                    __LINE__
1017
-                );
1018
-            }
1019
-        }
1020
-    }
1021
-
1022
-
1023
-    /**
1024
-     * Displays payment settings (not payment METHOD settings, that's _payment_method_settings)
1025
-     *
1026
-     * @throws DomainException
1027
-     * @throws EE_Error
1028
-     * @throws InvalidArgumentException
1029
-     * @throws InvalidDataTypeException
1030
-     * @throws InvalidInterfaceException
1031
-     */
1032
-    protected function _payment_settings()
1033
-    {
1034
-        $form = $this->getPaymentSettingsForm();
1035
-        $this->_set_add_edit_form_tags('update_payment_settings');
1036
-        $this->_set_publish_post_box_vars();
1037
-        $this->_template_args['admin_page_content'] = EEH_HTML::div(
1038
-            $form->get_html_and_js(),
1039
-            '',
1040
-            'padding'
1041
-        );
1042
-        $this->display_admin_page_with_sidebar();
1043
-    }
1044
-
1045
-
1046
-    /**
1047
-     *        _update_payment_settings
1048
-     *
1049
-     * @access protected
1050
-     * @return void
1051
-     * @throws EE_Error
1052
-     * @throws InvalidArgumentException
1053
-     * @throws InvalidDataTypeException
1054
-     * @throws InvalidInterfaceException
1055
-     */
1056
-    protected function _update_payment_settings()
1057
-    {
1058
-        $form = $this->getPaymentSettingsForm();
1059
-        if ($form->was_submitted($this->_req_data)) {
1060
-            $form->receive_form_submission($this->_req_data);
1061
-            if ($form->is_valid()) {
1062
-                /**
1063
-                 * @var $reg_config EE_Registration_Config
1064
-                 */
1065
-                $loader                                   = LoaderFactory::getLoader();
1066
-                $reg_config                               = $loader->getShared('EE_Registration_Config');
1067
-                $valid_data                               = $form->valid_data();
1068
-                $show_pending_payment_options             = $valid_data['show_pending_payment_options'] ?? null;
1069
-                $reg_config->show_pending_payment_options = $show_pending_payment_options === 'ON';
1070
-                $reg_config->gateway_log_lifespan         = $valid_data['gateway_log_lifespan'];
1071
-            }
1072
-        }
1073
-        EE_Registry::instance()->CFG = apply_filters(
1074
-            'FHEE__Payments_Admin_Page___update_payment_settings__CFG',
1075
-            EE_Registry::instance()->CFG
1076
-        );
1077
-
1078
-        $what    = esc_html__('Payment Settings', 'event_espresso');
1079
-        $success = $this->_update_espresso_configuration(
1080
-            $what,
1081
-            EE_Registry::instance()->CFG,
1082
-            __FILE__,
1083
-            __FUNCTION__,
1084
-            __LINE__
1085
-        );
1086
-        $this->_redirect_after_action(
1087
-            $success,
1088
-            $what,
1089
-            esc_html__('updated', 'event_espresso'),
1090
-            ['action' => 'payment_settings']
1091
-        );
1092
-    }
1093
-
1094
-
1095
-    /**
1096
-     * Gets the form used for updating payment settings
1097
-     *
1098
-     * @return EE_Form_Section_Proper
1099
-     * @throws EE_Error
1100
-     * @throws InvalidArgumentException
1101
-     * @throws InvalidDataTypeException
1102
-     * @throws InvalidInterfaceException
1103
-     */
1104
-    protected function getPaymentSettingsForm(): EE_Form_Section_Proper
1105
-    {
1106
-        /**
1107
-         * @var $reg_config EE_Registration_Config
1108
-         */
1109
-        $reg_config = LoaderFactory::getLoader()->getShared('EE_Registration_Config');
1110
-        return new EE_Form_Section_Proper(
1111
-            [
1112
-                'name'            => 'payment-settings',
1113
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1114
-                'subsections'     => [
1115
-                    'show_pending_payment_options' => new EE_Switch_Input(
1116
-                        [
1117
-                            'default'        => $reg_config->show_pending_payment_options
1118
-                                ? EE_Switch_Input::OPTION_ON
1119
-                                : EE_Switch_Input::OPTION_OFF,
1120
-                            'html_name'      => 'show_pending_payment_options',
1121
-                            'html_help_text' => esc_html__(
1122
-                                "If a payment is marked as 'Pending Payment', or if payment is deferred (ie, an offline gateway like Check, Bank, or Invoice is used), then give registrants the option to retry payment. ",
1123
-                                'event_espresso'
1124
-                            ),
1125
-                        ],
1126
-                        [
1127
-                            EE_Switch_Input::OPTION_OFF => esc_html__(
1128
-                                'pending payment options are NOT displayed',
1129
-                                'event_espresso'
1130
-                            ),
1131
-                            EE_Switch_Input::OPTION_ON  => esc_html__(
1132
-                                'pending payment options are displayed',
1133
-                                'event_espresso'
1134
-                            ),
1135
-                        ]
1136
-                    ),
1137
-                    'gateway_log_lifespan'         => new EE_Select_Input(
1138
-                        $reg_config->gatewayLogLifespanOptions(),
1139
-                        [
1140
-                            'html_label_text' => esc_html__('Gateway Logs Lifespan', 'event_espresso'),
1141
-                            'html_help_text'  => esc_html__(
1142
-                                'If issues arise with payments being made through a payment gateway, it\'s helpful to log non-sensitive communications with the payment gateway. But it\'s a security responsibility, so it\'s a good idea to not keep them for any longer than necessary.',
1143
-                                'event_espresso'
1144
-                            ),
1145
-                            'default'         => $reg_config->gateway_log_lifespan,
1146
-                        ]
1147
-                    ),
1148
-                ],
1149
-            ]
1150
-        );
1151
-    }
1152
-
1153
-
1154
-    /**
1155
-     * @throws EE_Error
1156
-     */
1157
-    protected function _payment_log_overview_list_table()
1158
-    {
1159
-        $this->display_admin_list_table_page_with_sidebar();
1160
-    }
1161
-
1162
-
1163
-    protected function _set_list_table_views_payment_log()
1164
-    {
1165
-        $this->_views = [
1166
-            'all' => [
1167
-                'slug'  => 'all',
1168
-                'label' => esc_html__('View All Logs', 'event_espresso'),
1169
-                'count' => 0,
1170
-            ],
1171
-        ];
1172
-    }
1173
-
1174
-
1175
-    /**
1176
-     * @param int  $per_page
1177
-     * @param int  $current_page
1178
-     * @param bool $count
1179
-     * @return array|int
1180
-     * @throws EE_Error
1181
-     * @throws ReflectionException
1182
-     */
1183
-    public function get_payment_logs($per_page = 50, $current_page = 0, $count = false)
1184
-    {
1185
-        EE_Registry::instance()->load_model('Change_Log');
1186
-        // we may need to do multiple queries (joining differently), so we actually want an array of query params
1187
-        $query_params = [['LOG_type' => EEM_Change_Log::type_gateway]];
1188
-        // check if they've selected a specific payment method
1189
-        if (isset($this->_req_data['_payment_method']) && $this->_req_data['_payment_method'] !== 'all') {
1190
-            $query_params[0]['OR*pm_or_pay_pm'] = [
1191
-                'Payment.Payment_Method.PMD_ID' => $this->_req_data['_payment_method'],
1192
-                'Payment_Method.PMD_ID'         => $this->_req_data['_payment_method'],
1193
-            ];
1194
-        }
1195
-        // take into account search
1196
-        if (isset($this->_req_data['s']) && $this->_req_data['s']) {
1197
-            $similarity_string                                                              =
1198
-                ['LIKE', '%' . str_replace("", "%", $this->_req_data['s']) . '%'];
1199
-            $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_fname'] = $similarity_string;
1200
-            $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_lname'] = $similarity_string;
1201
-            $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_email'] = $similarity_string;
1202
-            $query_params[0]['OR*s']['Payment.Payment_Method.PMD_name']                     = $similarity_string;
1203
-            $query_params[0]['OR*s']['Payment.Payment_Method.PMD_admin_name']               = $similarity_string;
1204
-            $query_params[0]['OR*s']['Payment.Payment_Method.PMD_type']                     = $similarity_string;
1205
-            $query_params[0]['OR*s']['Payment_Method.PMD_name']                             = $similarity_string;
1206
-            $query_params[0]['OR*s']['Payment_Method.PMD_admin_name']                       = $similarity_string;
1207
-            $query_params[0]['OR*s']['Payment_Method.PMD_type']                             = $similarity_string;
1208
-            $query_params[0]['OR*s']['LOG_message']                                         = $similarity_string;
1209
-        }
1210
-        if (
1211
-            isset($this->_req_data['payment-filter-start-date'])
1212
-            && isset($this->_req_data['payment-filter-end-date'])
1213
-        ) {
1214
-            // add date
1215
-            $start_date = wp_strip_all_tags($this->_req_data['payment-filter-start-date']);
1216
-            $end_date   = wp_strip_all_tags($this->_req_data['payment-filter-end-date']);
1217
-            // make sure our timestamps start and end right at the boundaries for each day
1218
-            $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
1219
-            $end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
1220
-            // convert to timestamps
1221
-            $start_date = strtotime($start_date);
1222
-            $end_date   = strtotime($end_date);
1223
-            // makes sure start date is the lowest value and vice versa
1224
-            $start_date = min($start_date, $end_date);
1225
-            $end_date   = max($start_date, $end_date);
1226
-            // convert for query
1227
-            $start_date                  = EEM_Change_Log::instance()->convert_datetime_for_query(
1228
-                'LOG_time',
1229
-                date('Y-m-d H:i:s', $start_date),
1230
-                'Y-m-d H:i:s'
1231
-            );
1232
-            $end_date                    = EEM_Change_Log::instance()->convert_datetime_for_query(
1233
-                'LOG_time',
1234
-                date('Y-m-d H:i:s', $end_date),
1235
-                'Y-m-d H:i:s'
1236
-            );
1237
-            $query_params[0]['LOG_time'] = ['BETWEEN', [$start_date, $end_date]];
1238
-        }
1239
-        if ($count) {
1240
-            return EEM_Change_Log::instance()->count($query_params);
1241
-        }
1242
-        if (isset($this->_req_data['order'])) {
1243
-            $sort                     = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
1244
-                ? $this->_req_data['order']
1245
-                : 'DESC';
1246
-            $query_params['order_by'] = ['LOG_time' => $sort];
1247
-        } else {
1248
-            $query_params['order_by'] = ['LOG_time' => 'DESC'];
1249
-        }
1250
-        $offset = ($current_page - 1) * $per_page;
1251
-        if (! isset($this->_req_data['download_results'])) {
1252
-            $query_params['limit'] = [$offset, $per_page];
1253
-        }
1254
-        // now they've requested to instead just download the file instead of viewing it.
1255
-        if (isset($this->_req_data['download_results'])) {
1256
-            $wpdb_results = EEM_Change_Log::instance()->get_all_efficiently($query_params);
1257
-            header('Content-Disposition: attachment');
1258
-            header("Content-Disposition: attachment; filename=ee_payment_logs_for_" . sanitize_key(site_url()));
1259
-            echo '<h1> '
1260
-                 . sprintf(
1261
-                     esc_html__('Payment Logs for %1$s', 'event_espresso'),
1262
-                     esc_url_raw(site_url())
1263
-                 )
1264
-                 . '</h1 >';
1265
-            echo '<h3>' . esc_html__('Query:', 'event_espresso') . '</h3>';
1266
-            echo esc_html(var_export($query_params, true));
1267
-            echo '<h3>' . esc_html__('Results:', 'event_espresso') . '</h3>';
1268
-            echo esc_html(var_export($wpdb_results, true));
1269
-            die;
1270
-        }
1271
-        return EEM_Change_Log::instance()->get_all($query_params);
1272
-    }
1273
-
1274
-
1275
-    /**
1276
-     * Used by usort to RE-sort log query results, because we lose the ordering
1277
-     * because we're possibly combining the results from two queries
1278
-     *
1279
-     * @param EE_Change_Log $logA
1280
-     * @param EE_Change_Log $logB
1281
-     * @return int
1282
-     * @throws EE_Error
1283
-     * @throws ReflectionException
1284
-     */
1285
-    protected function _sort_logs_again($logA, $logB)
1286
-    {
1287
-        $timeA = $logA->get_raw('LOG_time');
1288
-        $timeB = $logB->get_raw('LOG_time');
1289
-        if ($timeA == $timeB) {
1290
-            return 0;
1291
-        }
1292
-        $comparison = $timeA < $timeB
1293
-            ? -1
1294
-            : 1;
1295
-        if (strtoupper($this->_sort_logs_again_direction) == 'DESC') {
1296
-            return $comparison * -1;
1297
-        }
1298
-        return $comparison;
1299
-    }
1300
-
1301
-
1302
-    /**
1303
-     * @throws EE_Error
1304
-     * @throws ReflectionException
1305
-     */
1306
-    protected function _payment_log_details()
1307
-    {
1308
-        EE_Registry::instance()->load_model('Change_Log');
1309
-        /** @var $payment_log EE_Change_Log */
1310
-        $payment_log    = EEM_Change_Log::instance()->get_one_by_ID($this->_req_data['ID']);
1311
-        $payment_method = null;
1312
-        $transaction    = null;
1313
-        if ($payment_log instanceof EE_Change_Log) {
1314
-            if ($payment_log->object() instanceof EE_Payment) {
1315
-                $payment_method = $payment_log->object()->payment_method();
1316
-                $transaction    = $payment_log->object()->transaction();
1317
-            } elseif ($payment_log->object() instanceof EE_Payment_Method) {
1318
-                $payment_method = $payment_log->object();
1319
-            } elseif ($payment_log->object() instanceof EE_Transaction) {
1320
-                $transaction    = $payment_log->object();
1321
-                $payment_method = $transaction->payment_method();
1322
-            }
1323
-        }
1324
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1325
-            EE_PAYMENTS_TEMPLATE_PATH . 'payment_log_details.template.php',
1326
-            [
1327
-                'payment_log'    => $payment_log,
1328
-                'payment_method' => $payment_method,
1329
-                'transaction'    => $transaction,
1330
-            ],
1331
-            true
1332
-        );
1333
-        $this->display_admin_page_with_no_sidebar();
1334
-    }
327
+				'InnoDB'
328
+			);
329
+		}
330
+	}
331
+
332
+
333
+	/**
334
+	 * @throws EE_Error
335
+	 * @throws ReflectionException
336
+	 */
337
+	protected function _payment_methods_list()
338
+	{
339
+		$this->veryifyTablesExist();
340
+		/**
341
+		 * first let's ensure payment methods have been set up.
342
+		 * We do this here because when people activate a payment method for the first time (as an addon),
343
+		 * it may not set up its capabilities or get registered correctly due to the loading process.
344
+		 * However, people MUST set up the details for the payment method,
345
+		 * so it's safe to do a recheck here.
346
+		 */
347
+		EE_Registry::instance()->load_lib('Payment_Method_Manager');
348
+		EEM_Payment_Method::instance()->verify_button_urls();
349
+		// set up tabs, one for each payment method type
350
+		$tabs            = [];
351
+		$payment_methods = [];
352
+		foreach (EE_Payment_Method_Manager::instance()->payment_method_types() as $pmt_obj) {
353
+			// we don't want to show admin-only PMTs for now
354
+			if ($pmt_obj instanceof EE_PMT_Admin_Only) {
355
+				continue;
356
+			}
357
+			// check access
358
+			if (
359
+				! $this->capabilities->current_user_can(
360
+					$pmt_obj->cap_name(),
361
+					'specific_payment_method_type_access'
362
+				)
363
+			) {
364
+				continue;
365
+			}
366
+			// check for any active pms of that type
367
+			$payment_method = EEM_Payment_Method::instance()->get_one_of_type($pmt_obj->system_name());
368
+			if (! $payment_method instanceof EE_Payment_Method) {
369
+				$payment_method = EE_Payment_Method::new_instance(
370
+					[
371
+						'PMD_slug'       => sanitize_key($pmt_obj->system_name()),
372
+						'PMD_type'       => $pmt_obj->system_name(),
373
+						'PMD_name'       => $pmt_obj->pretty_name(),
374
+						'PMD_admin_name' => $pmt_obj->pretty_name(),
375
+					]
376
+				);
377
+			}
378
+			$payment_methods[ $payment_method->slug() ] = $payment_method;
379
+		}
380
+		$payment_methods = apply_filters(
381
+			'FHEE__Payments_Admin_Page___payment_methods_list__payment_methods',
382
+			$payment_methods
383
+		);
384
+		foreach ($payment_methods as $payment_method) {
385
+			if ($payment_method instanceof EE_Payment_Method) {
386
+				$this->addMetaBox(
387
+				// html id
388
+					'espresso_' . $payment_method->slug() . '_payment_settings',
389
+					// title
390
+					sprintf(esc_html__('%s Settings', 'event_espresso'), $payment_method->admin_name()),
391
+					// callback
392
+					[$this, 'payment_method_settings_meta_box'],
393
+					// post type
394
+					null,
395
+					// context
396
+					'normal',
397
+					// priority
398
+					'default',
399
+					// callback args
400
+					['payment_method' => $payment_method]
401
+				);
402
+				// setup for tabbed content
403
+				$tabs[ $payment_method->slug() ] = [
404
+					'label' => $payment_method->admin_name(),
405
+					'class' => $payment_method->active()
406
+						? 'gateway-active'
407
+						: '',
408
+					'href'  => 'espresso_' . $payment_method->slug() . '_payment_settings',
409
+					'title' => esc_html__('Modify this Payment Method', 'event_espresso'),
410
+					'slug'  => $payment_method->slug(),
411
+					'icon'  => $payment_method->active()
412
+						? '<span class="dashicons dashicons-yes-alt"></span>'
413
+						: '<span class="dashicons dashicons-remove"></span>',
414
+				];
415
+			}
416
+		}
417
+		$this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
418
+			$tabs,
419
+			'payment_method_links',
420
+			'',
421
+			$this->_get_active_payment_method_slug()
422
+		);
423
+		$this->display_admin_page_with_sidebar();
424
+	}
425
+
426
+
427
+	/**
428
+	 *   _get_active_payment_method_slug
429
+	 *
430
+	 * @return string
431
+	 * @throws EE_Error
432
+	 * @throws ReflectionException
433
+	 */
434
+	protected function _get_active_payment_method_slug()
435
+	{
436
+		$payment_method_slug = false;
437
+		// decide which payment method tab to open first, as dictated by the request's 'payment_method'
438
+		if (isset($this->_req_data['payment_method'])) {
439
+			// if they provided the current payment method, use it
440
+			$payment_method_slug = sanitize_key($this->_req_data['payment_method']);
441
+		}
442
+
443
+		$payment_method = EEM_Payment_Method::instance()->get_one([['PMD_slug' => $payment_method_slug]]);
444
+		// if that didn't work or wasn't provided, find another way to select the current pm
445
+		if (! $this->_verify_payment_method($payment_method)) {
446
+			// like, looking for an active one
447
+			$payment_method = EEM_Payment_Method::instance()->get_one_active(EEM_Payment_Method::scope_cart);
448
+			// test that one as well
449
+			if ($this->_verify_payment_method($payment_method)) {
450
+				$payment_method_slug = $payment_method->slug();
451
+			} else {
452
+				$payment_method_slug = 'paypal_standard';
453
+			}
454
+		}
455
+		return $payment_method_slug;
456
+	}
457
+
458
+
459
+	/**
460
+	 *    payment_method_settings_meta_box
461
+	 *    returns TRUE if the passed payment method is properly constructed and the logged-in user has the correct
462
+	 *    capabilities to access it
463
+	 *
464
+	 * @param EE_Payment_Method|null $payment_method
465
+	 * @return boolean
466
+	 * @throws EE_Error
467
+	 */
468
+	protected function _verify_payment_method(?EE_Payment_Method $payment_method): bool
469
+	{
470
+		return $payment_method instanceof EE_Payment_Method
471
+			   && $payment_method->type_obj() instanceof EE_PMT_Base
472
+			   && $this->capabilities->current_user_can(
473
+				   $payment_method->type_obj()->cap_name(),
474
+				   'specific_payment_method_type_access'
475
+			   );
476
+	}
477
+
478
+
479
+	/**
480
+	 *    payment_method_settings_meta_box
481
+	 *
482
+	 * @param NULL  $post_obj_which_is_null is an object containing the current post (as a $post object)
483
+	 * @param array $metabox                is an array with metabox id, title, callback, and args elements. the value
484
+	 *                                      at 'args' has key 'payment_method', as set within _payment_methods_list
485
+	 * @return void
486
+	 * @throws EE_Error
487
+	 * @throws ReflectionException
488
+	 */
489
+	public function payment_method_settings_meta_box($post_obj_which_is_null, array $metabox)
490
+	{
491
+		$payment_method = isset($metabox['args'], $metabox['args']['payment_method'])
492
+			? $metabox['args']['payment_method']
493
+			: null;
494
+		if (! $payment_method instanceof EE_Payment_Method) {
495
+			throw new EE_Error(
496
+				esc_html__(
497
+					'Payment method metabox setup incorrectly. No Payment method object was supplied',
498
+					'event_espresso'
499
+				)
500
+			);
501
+		}
502
+		$payment_method_scopes = $payment_method->active();
503
+		// if the payment method really exists show its form, otherwise the activation template
504
+		if ($payment_method->ID() && ! empty($payment_method_scopes)) {
505
+			$form = $this->_generate_payment_method_settings_form($payment_method);
506
+			if ($form->form_data_present_in($this->_req_data)) {
507
+				$form->receive_form_submission($this->_req_data);
508
+			}
509
+			echo wp_kses(
510
+				$form->form_open() . $form->get_html_and_js() . $form->form_close(),
511
+				AllowedTags::getWithFormTags()
512
+			);
513
+		} else {
514
+			echo wp_kses(
515
+				$this->_activate_payment_method_button($payment_method)->get_html_and_js(),
516
+				AllowedTags::getWithFormTags()
517
+			);
518
+		}
519
+	}
520
+
521
+
522
+	/**
523
+	 * Gets the form for all the settings related to this payment method type
524
+	 *
525
+	 * @access protected
526
+	 * @param EE_Payment_Method|null $payment_method
527
+	 * @return EE_Form_Section_Proper
528
+	 * @throws EE_Error
529
+	 * @throws ReflectionException
530
+	 */
531
+	protected function _generate_payment_method_settings_form(
532
+		?EE_Payment_Method $payment_method
533
+	): EE_Form_Section_Proper {
534
+		if (! $payment_method instanceof EE_Payment_Method) {
535
+			return new EE_Form_Section_Proper();
536
+		}
537
+		$subsections = apply_filters(
538
+			'FHEE__Payments_Admin_Page___generate_payment_method_settings_form__form_subsections',
539
+			[
540
+				'pci_dss_compliance'      => $this->_pci_dss_compliance($payment_method),
541
+				'currency_support'        => $this->_currency_support($payment_method),
542
+				'payment_method_settings' => $this->_payment_method_settings($payment_method),
543
+				'update'                  => $this->_update_payment_method_button($payment_method),
544
+				'deactivate'              => $this->_deactivate_payment_method_button($payment_method),
545
+				'fine_print'              => $this->_fine_print(),
546
+			],
547
+			$payment_method
548
+		);
549
+		return new EE_Form_Section_Proper(
550
+			[
551
+				'name'            => $payment_method->slug() . '_settings_form',
552
+				'html_id'         => $payment_method->slug() . '_settings_form',
553
+				'action'          => EE_Admin_Page::add_query_args_and_nonce(
554
+					[
555
+						'action'         => 'update_payment_method',
556
+						'payment_method' => $payment_method->slug(),
557
+					],
558
+					EE_PAYMENTS_ADMIN_URL
559
+				),
560
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
561
+				'subsections'     => array_filter($subsections),
562
+			]
563
+		);
564
+	}
565
+
566
+
567
+	/**
568
+	 * _pci_dss_compliance
569
+	 *
570
+	 * @access protected
571
+	 * @param EE_Payment_Method $payment_method
572
+	 * @return EE_Form_Section_HTML|null
573
+	 * @throws EE_Error
574
+	 */
575
+	protected function _pci_dss_compliance(EE_Payment_Method $payment_method): ?EE_Form_Section_HTML
576
+	{
577
+		if (! $payment_method->type_obj()->requires_https()) {
578
+			return null;
579
+		}
580
+		return new EE_Form_Section_HTML(
581
+			EEH_HTML::tr(
582
+				EEH_HTML::th(
583
+					EEH_HTML::label(
584
+						EEH_HTML::strong(
585
+							esc_html__('IMPORTANT', 'event_espresso'),
586
+							'',
587
+							'important-notice'
588
+						)
589
+					)
590
+				) .
591
+				EEH_HTML::td(
592
+					EEH_HTML::div(
593
+						EEH_HTML::strong(
594
+							esc_html__(
595
+								'You are responsible for your own website security and Payment Card Industry Data Security Standards (PCI DSS) compliance.',
596
+								'event_espresso'
597
+							)
598
+						),
599
+						'',
600
+						'ee-status-outline ee-status-bg--warning'
601
+					)
602
+					. EEH_HTML::br()
603
+
604
+					. EEH_HTML::div(
605
+						esc_html__('Learn more about ', 'event_espresso')
606
+						. EEH_HTML::link(
607
+							'https://www.pcisecuritystandards.org/merchants/index.php',
608
+							esc_html__('PCI DSS compliance', 'event_espresso')
609
+						),
610
+						'',
611
+						'ee-status-outline ee-status-bg--info'
612
+					)
613
+				)
614
+			)
615
+		);
616
+	}
617
+
618
+
619
+	/**
620
+	 * _currency_support
621
+	 *
622
+	 * @access protected
623
+	 * @param EE_Payment_Method $payment_method
624
+	 * @return EE_Form_Section_HTML|null
625
+	 * @throws EE_Error
626
+	 */
627
+	protected function _currency_support(EE_Payment_Method $payment_method): ?EE_Form_Section_HTML
628
+	{
629
+		if ($payment_method->usable_for_currency(EE_Config::instance()->currency->code)) {
630
+			return null;
631
+		}
632
+		return new EE_Form_Section_HTML(
633
+			EEH_HTML::tr(
634
+				EEH_HTML::th(
635
+					EEH_HTML::label(
636
+						EEH_HTML::strong(
637
+							esc_html__('IMPORTANT', 'event_espresso'),
638
+							'',
639
+							'important-notice'
640
+						)
641
+					)
642
+				) .
643
+				EEH_HTML::td(
644
+					EEH_HTML::div(
645
+						EEH_HTML::strong(
646
+							sprintf(
647
+								esc_html__(
648
+									'This payment method does not support the currency set on your site (%1$s). Please activate a different payment method or change your site\'s country and associated currency.',
649
+									'event_espresso'
650
+								),
651
+								EE_Config::instance()->currency->code
652
+							)
653
+						),
654
+						'',
655
+						'ee-status-outline ee-status-bg--warning'
656
+					)
657
+				)
658
+			)
659
+		);
660
+	}
661
+
662
+
663
+	/**
664
+	 * _update_payment_method_button
665
+	 *
666
+	 * @access protected
667
+	 * @param EE_Payment_Method $payment_method
668
+	 * @return EE_Payment_Method_Form
669
+	 * @throws EE_Error
670
+	 * @throws ReflectionException
671
+	 */
672
+	protected function _payment_method_settings(EE_Payment_Method $payment_method): EE_Payment_Method_Form
673
+	{
674
+		// modify the form, so we only have/show fields that will be implemented for this version
675
+		return $this->_simplify_form($payment_method->type_obj()->settings_form(), $payment_method->name());
676
+	}
677
+
678
+
679
+	/**
680
+	 * Simplifies the form to merely reproduce 4.1's gateway settings functionality
681
+	 *
682
+	 * @param EE_Form_Section_Proper $form_section
683
+	 * @param string                 $payment_method_name
684
+	 * @return EE_Payment_Method_Form
685
+	 * @throws EE_Error
686
+	 */
687
+	protected function _simplify_form(
688
+		EE_Form_Section_Proper $form_section,
689
+		string $payment_method_name = ''
690
+	): EE_Payment_Method_Form {
691
+		if ($form_section instanceof EE_Payment_Method_Form) {
692
+			$form_section->exclude(
693
+				[
694
+					'PMD_type', // don't want them changing the type
695
+					'PMD_slug', // or the slug (probably never)
696
+					'PMD_wp_user', // or the user's ID
697
+					'Currency', // or the currency, until the rest of EE supports simultaneous currencies
698
+				]
699
+			);
700
+			return $form_section;
701
+		}
702
+		throw new EE_Error(
703
+			sprintf(
704
+				esc_html__(
705
+					'The EE_Payment_Method_Form for the "%1$s" payment method is missing or invalid.',
706
+					'event_espresso'
707
+				),
708
+				$payment_method_name
709
+			)
710
+		);
711
+	}
712
+
713
+
714
+	/**
715
+	 * _update_payment_method_button
716
+	 *
717
+	 * @access protected
718
+	 * @param EE_Payment_Method $payment_method
719
+	 * @return EE_Form_Section_HTML
720
+	 * @throws EE_Error
721
+	 */
722
+	protected function _update_payment_method_button(EE_Payment_Method $payment_method): EE_Form_Section_HTML
723
+	{
724
+		$update_button = new EE_Submit_Input(
725
+			[
726
+				'name'       => 'submit',
727
+				'html_id'    => 'save_' . $payment_method->slug() . '_settings',
728
+				'default'    => sprintf(
729
+					esc_html__('Update %s Payment Settings', 'event_espresso'),
730
+					$payment_method->admin_name()
731
+				),
732
+				'html_label' => EEH_HTML::nbsp(),
733
+			]
734
+		);
735
+		return new EE_Form_Section_HTML(
736
+			EEH_HTML::tr(
737
+				EEH_HTML::th(
738
+				// esc_html__('Update Settings', 'event_espresso'),
739
+					'&nbsp;',
740
+					'',
741
+					'ee-update-' . $payment_method->slug() . '-settings__label'
742
+				) .
743
+				EEH_HTML::td(
744
+					$update_button->get_html_for_input(),
745
+					'',
746
+					'ee-update-' . $payment_method->slug() . '-settings__input'
747
+				),
748
+				'',
749
+				'ee-update-' . $payment_method->slug() . '-settings'
750
+			)
751
+		);
752
+	}
753
+
754
+
755
+	/**
756
+	 * _deactivate_payment_method_button
757
+	 *
758
+	 * @access protected
759
+	 * @param EE_Payment_Method $payment_method
760
+	 * @return EE_Form_Section_HTML
761
+	 */
762
+	protected function _deactivate_payment_method_button(EE_Payment_Method $payment_method): EE_Form_Section_HTML
763
+	{
764
+		$link_text_and_title = sprintf(
765
+			esc_html__('Deactivate %1$s Payments?', 'event_espresso'),
766
+			$payment_method->admin_name()
767
+		);
768
+		return new EE_Form_Section_HTML(
769
+			EEH_HTML::tr(
770
+				EEH_HTML::th(
771
+				// esc_html__('Deactivate Payment Method', 'event_espresso'),
772
+					'&nbsp;',
773
+					'',
774
+					'ee-deactivate-' . $payment_method->slug() . '-settings__label'
775
+				) .
776
+				EEH_HTML::td(
777
+					EEH_HTML::link(
778
+						EE_Admin_Page::add_query_args_and_nonce(
779
+							[
780
+								'action'         => 'deactivate_payment_method',
781
+								'payment_method' => $payment_method->slug(),
782
+							],
783
+							EE_PAYMENTS_ADMIN_URL
784
+						),
785
+						$link_text_and_title,
786
+						$link_text_and_title,
787
+						'deactivate_' . $payment_method->slug(),
788
+						'button button--secondary'
789
+					),
790
+					'',
791
+					'ee-deactivate-' . $payment_method->slug() . '-settings__input'
792
+				),
793
+				'',
794
+				'ee-deactivate-' . $payment_method->slug() . '-settings'
795
+			)
796
+		);
797
+	}
798
+
799
+
800
+	/**
801
+	 * _activate_payment_method_button
802
+	 *
803
+	 * @access protected
804
+	 * @param EE_Payment_Method $payment_method
805
+	 * @return EE_Form_Section_Proper
806
+	 * @throws EE_Error
807
+	 */
808
+	protected function _activate_payment_method_button(EE_Payment_Method $payment_method): EE_Form_Section_Proper
809
+	{
810
+		$link_text_and_title = sprintf(
811
+			esc_html__('Activate %1$s Payment Method?', 'event_espresso'),
812
+			$payment_method->admin_name()
813
+		);
814
+		return new EE_Form_Section_Proper(
815
+			[
816
+				'name'            => 'activate_' . $payment_method->slug() . '_settings_form',
817
+				'html_id'         => 'activate_' . $payment_method->slug() . '_settings_form',
818
+				'action'          => '#',
819
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
820
+				'subsections'     => apply_filters(
821
+					'FHEE__Payments_Admin_Page___activate_payment_method_button__form_subsections',
822
+					[
823
+						new EE_Form_Section_HTML(
824
+							EEH_HTML::table(
825
+								EEH_HTML::tr(
826
+									EEH_HTML::td(
827
+										$payment_method->type_obj()->introductory_html(),
828
+										'',
829
+										'',
830
+										'',
831
+										'colspan="2"'
832
+									)
833
+								) .
834
+								EEH_HTML::tr(
835
+									EEH_HTML::th(
836
+										EEH_HTML::label(esc_html__('Click to Activate ', 'event_espresso'))
837
+									) .
838
+									EEH_HTML::td(
839
+										EEH_HTML::link(
840
+											EE_Admin_Page::add_query_args_and_nonce(
841
+												[
842
+													'action'              => 'activate_payment_method',
843
+													'payment_method_type' => $payment_method->type(),
844
+												],
845
+												EE_PAYMENTS_ADMIN_URL
846
+											),
847
+											$link_text_and_title,
848
+											$link_text_and_title,
849
+											'activate_' . $payment_method->slug(),
850
+											'button button--primary-alt'
851
+										)
852
+									)
853
+								)
854
+							)
855
+						),
856
+					],
857
+					$payment_method
858
+				),
859
+			]
860
+		);
861
+	}
862
+
863
+
864
+	/**
865
+	 * _fine_print
866
+	 *
867
+	 * @access protected
868
+	 * @return EE_Form_Section_HTML
869
+	 */
870
+	protected function _fine_print(): EE_Form_Section_HTML
871
+	{
872
+		return new EE_Form_Section_HTML(
873
+			EEH_HTML::tr(
874
+				EEH_HTML::th()
875
+				. EEH_HTML::thx()
876
+				. EEH_HTML::td(
877
+					EEH_HTML::p(
878
+						esc_html__('All fields marked with a * are required fields', 'event_espresso'),
879
+						'',
880
+						'grey-text'
881
+					)
882
+				)
883
+			)
884
+		);
885
+	}
886
+
887
+
888
+	/**
889
+	 * Activates a payment method of that type. Mostly assuming there is only 1 of that type (or none so far)
890
+	 *
891
+	 * @throws EE_Error
892
+	 * @throws ReflectionException
893
+	 * @global WP_User $current_user
894
+	 */
895
+	protected function _activate_payment_method()
896
+	{
897
+		if (isset($this->_req_data['payment_method_type'])) {
898
+			$payment_method_type = sanitize_text_field($this->_req_data['payment_method_type']);
899
+			// see if one exists
900
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
901
+			$payment_method = EE_Payment_Method_Manager::instance()
902
+													   ->activate_a_payment_method_of_type($payment_method_type);
903
+			$this->_redirect_after_action(
904
+				1,
905
+				'Payment Method',
906
+				'activated',
907
+				['action' => 'default', 'payment_method' => $payment_method->slug()]
908
+			);
909
+		} else {
910
+			$this->_redirect_after_action(false, 'Payment Method', 'activated', ['action' => 'default']);
911
+		}
912
+	}
913
+
914
+
915
+	/**
916
+	 * @throws EE_Error
917
+	 * @throws ReflectionException
918
+	 */
919
+	protected function _deactivate_payment_method()
920
+	{
921
+		if (isset($this->_req_data['payment_method'])) {
922
+			$payment_method_slug = sanitize_key($this->_req_data['payment_method']);
923
+			// deactivate it
924
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
925
+			$count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method($payment_method_slug);
926
+			$this->_redirect_after_action(
927
+				$count_updated,
928
+				'Payment Method',
929
+				'deactivated',
930
+				['action' => 'default', 'payment_method' => $payment_method_slug]
931
+			);
932
+		} else {
933
+			$this->_redirect_after_action(false, 'Payment Method', 'deactivated', ['action' => 'default']);
934
+		}
935
+	}
936
+
937
+
938
+	/**
939
+	 * Processes the payment method form that was submitted. This is slightly trickier than usual form
940
+	 * processing because we first need to identify WHICH form was processed and which payment method
941
+	 * it corresponds to. Once we have done that, we see if the form is valid. If it is, the
942
+	 * form's data is saved, and we redirect to the default payment methods page, setting the updated payment method
943
+	 * as the currently-selected one. If it DOESN'T validate, we render the page with the form's errors (in the
944
+	 * subsequently called 'headers_sent_func' which is _payment_methods_list)
945
+	 *
946
+	 * @return void
947
+	 * @throws EE_Error
948
+	 * @throws ReflectionException
949
+	 */
950
+	protected function _update_payment_method()
951
+	{
952
+		if ($_SERVER['REQUEST_METHOD'] == 'POST') {
953
+			// ok let's find which gateway form to use based on the form input
954
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
955
+			/** @var $correct_pmt_form_to_use EE_Payment_Method_Form */
956
+			$correct_pmt_form_to_use = null;
957
+			$payment_method          = null;
958
+			foreach (EEM_Payment_Method::instance()->get_all() as $payment_method) {
959
+				if ($payment_method instanceof EE_Payment_Method) {
960
+					// get the form and simplify it, like what we do when we display it
961
+					$pmt_form = $this->_generate_payment_method_settings_form($payment_method);
962
+					if ($pmt_form->form_data_present_in($this->_req_data)) {
963
+						$correct_pmt_form_to_use = $pmt_form;
964
+						break;
965
+					}
966
+				}
967
+			}
968
+			// if we couldn't find the correct payment method type...
969
+			if (! $correct_pmt_form_to_use) {
970
+				EE_Error::add_error(
971
+					esc_html__(
972
+						"We could not find which payment method type your form submission related to. Please contact support",
973
+						'event_espresso'
974
+					),
975
+					__FILE__,
976
+					__FUNCTION__,
977
+					__LINE__
978
+				);
979
+				$this->_redirect_after_action(false, 'Payment Method', 'activated', ['action' => 'default']);
980
+			}
981
+			$correct_pmt_form_to_use->receive_form_submission($this->_req_data);
982
+			if ($correct_pmt_form_to_use->is_valid()) {
983
+				$payment_settings_subform = $correct_pmt_form_to_use->get_subsection('payment_method_settings');
984
+				if (! $payment_settings_subform instanceof EE_Payment_Method_Form) {
985
+					throw new EE_Error(
986
+						sprintf(
987
+							esc_html__(
988
+								'The payment method could not be saved because the form sections were misnamed. We expected to find %1$s, but did not.',
989
+								'event_espresso'
990
+							),
991
+							'payment_method_settings'
992
+						)
993
+					);
994
+				}
995
+				$payment_settings_subform->save();
996
+				/** @var $pm EE_Payment_Method */
997
+				$this->_redirect_after_action(
998
+					true,
999
+					'Payment Method',
1000
+					'updated',
1001
+					['action' => 'default', 'payment_method' => $payment_method->slug()]
1002
+				);
1003
+			} else {
1004
+				EE_Error::add_error(
1005
+					sprintf(
1006
+						esc_html__(
1007
+							'Payment method of type %s was not saved because there were validation errors. They have been marked in the form',
1008
+							'event_espresso'
1009
+						),
1010
+						$payment_method instanceof EE_Payment_Method
1011
+							? $payment_method->type_obj()->pretty_name()
1012
+							: esc_html__('"(unknown)"', 'event_espresso')
1013
+					),
1014
+					__FILE__,
1015
+					__FUNCTION__,
1016
+					__LINE__
1017
+				);
1018
+			}
1019
+		}
1020
+	}
1021
+
1022
+
1023
+	/**
1024
+	 * Displays payment settings (not payment METHOD settings, that's _payment_method_settings)
1025
+	 *
1026
+	 * @throws DomainException
1027
+	 * @throws EE_Error
1028
+	 * @throws InvalidArgumentException
1029
+	 * @throws InvalidDataTypeException
1030
+	 * @throws InvalidInterfaceException
1031
+	 */
1032
+	protected function _payment_settings()
1033
+	{
1034
+		$form = $this->getPaymentSettingsForm();
1035
+		$this->_set_add_edit_form_tags('update_payment_settings');
1036
+		$this->_set_publish_post_box_vars();
1037
+		$this->_template_args['admin_page_content'] = EEH_HTML::div(
1038
+			$form->get_html_and_js(),
1039
+			'',
1040
+			'padding'
1041
+		);
1042
+		$this->display_admin_page_with_sidebar();
1043
+	}
1044
+
1045
+
1046
+	/**
1047
+	 *        _update_payment_settings
1048
+	 *
1049
+	 * @access protected
1050
+	 * @return void
1051
+	 * @throws EE_Error
1052
+	 * @throws InvalidArgumentException
1053
+	 * @throws InvalidDataTypeException
1054
+	 * @throws InvalidInterfaceException
1055
+	 */
1056
+	protected function _update_payment_settings()
1057
+	{
1058
+		$form = $this->getPaymentSettingsForm();
1059
+		if ($form->was_submitted($this->_req_data)) {
1060
+			$form->receive_form_submission($this->_req_data);
1061
+			if ($form->is_valid()) {
1062
+				/**
1063
+				 * @var $reg_config EE_Registration_Config
1064
+				 */
1065
+				$loader                                   = LoaderFactory::getLoader();
1066
+				$reg_config                               = $loader->getShared('EE_Registration_Config');
1067
+				$valid_data                               = $form->valid_data();
1068
+				$show_pending_payment_options             = $valid_data['show_pending_payment_options'] ?? null;
1069
+				$reg_config->show_pending_payment_options = $show_pending_payment_options === 'ON';
1070
+				$reg_config->gateway_log_lifespan         = $valid_data['gateway_log_lifespan'];
1071
+			}
1072
+		}
1073
+		EE_Registry::instance()->CFG = apply_filters(
1074
+			'FHEE__Payments_Admin_Page___update_payment_settings__CFG',
1075
+			EE_Registry::instance()->CFG
1076
+		);
1077
+
1078
+		$what    = esc_html__('Payment Settings', 'event_espresso');
1079
+		$success = $this->_update_espresso_configuration(
1080
+			$what,
1081
+			EE_Registry::instance()->CFG,
1082
+			__FILE__,
1083
+			__FUNCTION__,
1084
+			__LINE__
1085
+		);
1086
+		$this->_redirect_after_action(
1087
+			$success,
1088
+			$what,
1089
+			esc_html__('updated', 'event_espresso'),
1090
+			['action' => 'payment_settings']
1091
+		);
1092
+	}
1093
+
1094
+
1095
+	/**
1096
+	 * Gets the form used for updating payment settings
1097
+	 *
1098
+	 * @return EE_Form_Section_Proper
1099
+	 * @throws EE_Error
1100
+	 * @throws InvalidArgumentException
1101
+	 * @throws InvalidDataTypeException
1102
+	 * @throws InvalidInterfaceException
1103
+	 */
1104
+	protected function getPaymentSettingsForm(): EE_Form_Section_Proper
1105
+	{
1106
+		/**
1107
+		 * @var $reg_config EE_Registration_Config
1108
+		 */
1109
+		$reg_config = LoaderFactory::getLoader()->getShared('EE_Registration_Config');
1110
+		return new EE_Form_Section_Proper(
1111
+			[
1112
+				'name'            => 'payment-settings',
1113
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1114
+				'subsections'     => [
1115
+					'show_pending_payment_options' => new EE_Switch_Input(
1116
+						[
1117
+							'default'        => $reg_config->show_pending_payment_options
1118
+								? EE_Switch_Input::OPTION_ON
1119
+								: EE_Switch_Input::OPTION_OFF,
1120
+							'html_name'      => 'show_pending_payment_options',
1121
+							'html_help_text' => esc_html__(
1122
+								"If a payment is marked as 'Pending Payment', or if payment is deferred (ie, an offline gateway like Check, Bank, or Invoice is used), then give registrants the option to retry payment. ",
1123
+								'event_espresso'
1124
+							),
1125
+						],
1126
+						[
1127
+							EE_Switch_Input::OPTION_OFF => esc_html__(
1128
+								'pending payment options are NOT displayed',
1129
+								'event_espresso'
1130
+							),
1131
+							EE_Switch_Input::OPTION_ON  => esc_html__(
1132
+								'pending payment options are displayed',
1133
+								'event_espresso'
1134
+							),
1135
+						]
1136
+					),
1137
+					'gateway_log_lifespan'         => new EE_Select_Input(
1138
+						$reg_config->gatewayLogLifespanOptions(),
1139
+						[
1140
+							'html_label_text' => esc_html__('Gateway Logs Lifespan', 'event_espresso'),
1141
+							'html_help_text'  => esc_html__(
1142
+								'If issues arise with payments being made through a payment gateway, it\'s helpful to log non-sensitive communications with the payment gateway. But it\'s a security responsibility, so it\'s a good idea to not keep them for any longer than necessary.',
1143
+								'event_espresso'
1144
+							),
1145
+							'default'         => $reg_config->gateway_log_lifespan,
1146
+						]
1147
+					),
1148
+				],
1149
+			]
1150
+		);
1151
+	}
1152
+
1153
+
1154
+	/**
1155
+	 * @throws EE_Error
1156
+	 */
1157
+	protected function _payment_log_overview_list_table()
1158
+	{
1159
+		$this->display_admin_list_table_page_with_sidebar();
1160
+	}
1161
+
1162
+
1163
+	protected function _set_list_table_views_payment_log()
1164
+	{
1165
+		$this->_views = [
1166
+			'all' => [
1167
+				'slug'  => 'all',
1168
+				'label' => esc_html__('View All Logs', 'event_espresso'),
1169
+				'count' => 0,
1170
+			],
1171
+		];
1172
+	}
1173
+
1174
+
1175
+	/**
1176
+	 * @param int  $per_page
1177
+	 * @param int  $current_page
1178
+	 * @param bool $count
1179
+	 * @return array|int
1180
+	 * @throws EE_Error
1181
+	 * @throws ReflectionException
1182
+	 */
1183
+	public function get_payment_logs($per_page = 50, $current_page = 0, $count = false)
1184
+	{
1185
+		EE_Registry::instance()->load_model('Change_Log');
1186
+		// we may need to do multiple queries (joining differently), so we actually want an array of query params
1187
+		$query_params = [['LOG_type' => EEM_Change_Log::type_gateway]];
1188
+		// check if they've selected a specific payment method
1189
+		if (isset($this->_req_data['_payment_method']) && $this->_req_data['_payment_method'] !== 'all') {
1190
+			$query_params[0]['OR*pm_or_pay_pm'] = [
1191
+				'Payment.Payment_Method.PMD_ID' => $this->_req_data['_payment_method'],
1192
+				'Payment_Method.PMD_ID'         => $this->_req_data['_payment_method'],
1193
+			];
1194
+		}
1195
+		// take into account search
1196
+		if (isset($this->_req_data['s']) && $this->_req_data['s']) {
1197
+			$similarity_string                                                              =
1198
+				['LIKE', '%' . str_replace("", "%", $this->_req_data['s']) . '%'];
1199
+			$query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_fname'] = $similarity_string;
1200
+			$query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_lname'] = $similarity_string;
1201
+			$query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_email'] = $similarity_string;
1202
+			$query_params[0]['OR*s']['Payment.Payment_Method.PMD_name']                     = $similarity_string;
1203
+			$query_params[0]['OR*s']['Payment.Payment_Method.PMD_admin_name']               = $similarity_string;
1204
+			$query_params[0]['OR*s']['Payment.Payment_Method.PMD_type']                     = $similarity_string;
1205
+			$query_params[0]['OR*s']['Payment_Method.PMD_name']                             = $similarity_string;
1206
+			$query_params[0]['OR*s']['Payment_Method.PMD_admin_name']                       = $similarity_string;
1207
+			$query_params[0]['OR*s']['Payment_Method.PMD_type']                             = $similarity_string;
1208
+			$query_params[0]['OR*s']['LOG_message']                                         = $similarity_string;
1209
+		}
1210
+		if (
1211
+			isset($this->_req_data['payment-filter-start-date'])
1212
+			&& isset($this->_req_data['payment-filter-end-date'])
1213
+		) {
1214
+			// add date
1215
+			$start_date = wp_strip_all_tags($this->_req_data['payment-filter-start-date']);
1216
+			$end_date   = wp_strip_all_tags($this->_req_data['payment-filter-end-date']);
1217
+			// make sure our timestamps start and end right at the boundaries for each day
1218
+			$start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
1219
+			$end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
1220
+			// convert to timestamps
1221
+			$start_date = strtotime($start_date);
1222
+			$end_date   = strtotime($end_date);
1223
+			// makes sure start date is the lowest value and vice versa
1224
+			$start_date = min($start_date, $end_date);
1225
+			$end_date   = max($start_date, $end_date);
1226
+			// convert for query
1227
+			$start_date                  = EEM_Change_Log::instance()->convert_datetime_for_query(
1228
+				'LOG_time',
1229
+				date('Y-m-d H:i:s', $start_date),
1230
+				'Y-m-d H:i:s'
1231
+			);
1232
+			$end_date                    = EEM_Change_Log::instance()->convert_datetime_for_query(
1233
+				'LOG_time',
1234
+				date('Y-m-d H:i:s', $end_date),
1235
+				'Y-m-d H:i:s'
1236
+			);
1237
+			$query_params[0]['LOG_time'] = ['BETWEEN', [$start_date, $end_date]];
1238
+		}
1239
+		if ($count) {
1240
+			return EEM_Change_Log::instance()->count($query_params);
1241
+		}
1242
+		if (isset($this->_req_data['order'])) {
1243
+			$sort                     = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
1244
+				? $this->_req_data['order']
1245
+				: 'DESC';
1246
+			$query_params['order_by'] = ['LOG_time' => $sort];
1247
+		} else {
1248
+			$query_params['order_by'] = ['LOG_time' => 'DESC'];
1249
+		}
1250
+		$offset = ($current_page - 1) * $per_page;
1251
+		if (! isset($this->_req_data['download_results'])) {
1252
+			$query_params['limit'] = [$offset, $per_page];
1253
+		}
1254
+		// now they've requested to instead just download the file instead of viewing it.
1255
+		if (isset($this->_req_data['download_results'])) {
1256
+			$wpdb_results = EEM_Change_Log::instance()->get_all_efficiently($query_params);
1257
+			header('Content-Disposition: attachment');
1258
+			header("Content-Disposition: attachment; filename=ee_payment_logs_for_" . sanitize_key(site_url()));
1259
+			echo '<h1> '
1260
+				 . sprintf(
1261
+					 esc_html__('Payment Logs for %1$s', 'event_espresso'),
1262
+					 esc_url_raw(site_url())
1263
+				 )
1264
+				 . '</h1 >';
1265
+			echo '<h3>' . esc_html__('Query:', 'event_espresso') . '</h3>';
1266
+			echo esc_html(var_export($query_params, true));
1267
+			echo '<h3>' . esc_html__('Results:', 'event_espresso') . '</h3>';
1268
+			echo esc_html(var_export($wpdb_results, true));
1269
+			die;
1270
+		}
1271
+		return EEM_Change_Log::instance()->get_all($query_params);
1272
+	}
1273
+
1274
+
1275
+	/**
1276
+	 * Used by usort to RE-sort log query results, because we lose the ordering
1277
+	 * because we're possibly combining the results from two queries
1278
+	 *
1279
+	 * @param EE_Change_Log $logA
1280
+	 * @param EE_Change_Log $logB
1281
+	 * @return int
1282
+	 * @throws EE_Error
1283
+	 * @throws ReflectionException
1284
+	 */
1285
+	protected function _sort_logs_again($logA, $logB)
1286
+	{
1287
+		$timeA = $logA->get_raw('LOG_time');
1288
+		$timeB = $logB->get_raw('LOG_time');
1289
+		if ($timeA == $timeB) {
1290
+			return 0;
1291
+		}
1292
+		$comparison = $timeA < $timeB
1293
+			? -1
1294
+			: 1;
1295
+		if (strtoupper($this->_sort_logs_again_direction) == 'DESC') {
1296
+			return $comparison * -1;
1297
+		}
1298
+		return $comparison;
1299
+	}
1300
+
1301
+
1302
+	/**
1303
+	 * @throws EE_Error
1304
+	 * @throws ReflectionException
1305
+	 */
1306
+	protected function _payment_log_details()
1307
+	{
1308
+		EE_Registry::instance()->load_model('Change_Log');
1309
+		/** @var $payment_log EE_Change_Log */
1310
+		$payment_log    = EEM_Change_Log::instance()->get_one_by_ID($this->_req_data['ID']);
1311
+		$payment_method = null;
1312
+		$transaction    = null;
1313
+		if ($payment_log instanceof EE_Change_Log) {
1314
+			if ($payment_log->object() instanceof EE_Payment) {
1315
+				$payment_method = $payment_log->object()->payment_method();
1316
+				$transaction    = $payment_log->object()->transaction();
1317
+			} elseif ($payment_log->object() instanceof EE_Payment_Method) {
1318
+				$payment_method = $payment_log->object();
1319
+			} elseif ($payment_log->object() instanceof EE_Transaction) {
1320
+				$transaction    = $payment_log->object();
1321
+				$payment_method = $transaction->payment_method();
1322
+			}
1323
+		}
1324
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
1325
+			EE_PAYMENTS_TEMPLATE_PATH . 'payment_log_details.template.php',
1326
+			[
1327
+				'payment_log'    => $payment_log,
1328
+				'payment_method' => $payment_method,
1329
+				'transaction'    => $transaction,
1330
+			],
1331
+			true
1332
+		);
1333
+		$this->display_admin_page_with_no_sidebar();
1334
+	}
1335 1335
 }
Please login to merge, or discard this patch.
Spacing   +48 added lines, -48 removed lines patch added patch discarded remove patch
@@ -152,7 +152,7 @@  discard block
 block discarded – undo
152 152
             ),
153 153
             'require_nonce' => false,
154 154
         ];
155
-        $this->_page_config         = [
155
+        $this->_page_config = [
156 156
             'default'          => $payment_method_list_config,
157 157
             'payment_settings' => [
158 158
                 'nav'           => [
@@ -209,10 +209,10 @@  discard block
 block discarded – undo
209 209
             foreach ($payment_method_type->help_tabs_config() as $help_tab_name => $config) {
210 210
                 $template_args                              = $config['template_args'] ?? [];
211 211
                 $template_args['admin_page_obj']            = $this;
212
-                $all_pmt_help_tabs_config[ $help_tab_name ] = [
212
+                $all_pmt_help_tabs_config[$help_tab_name] = [
213 213
                     'title'   => $config['title'],
214 214
                     'content' => EEH_Template::display_template(
215
-                        $payment_method_type->file_folder() . 'help_tabs/' . $config['filename'] . '.help_tab.php',
215
+                        $payment_method_type->file_folder().'help_tabs/'.$config['filename'].'.help_tab.php',
216 216
                         $template_args,
217 217
                         true
218 218
                     ),
@@ -255,7 +255,7 @@  discard block
 block discarded – undo
255 255
         wp_enqueue_style('espresso-ui-theme');
256 256
         wp_register_style(
257 257
             'espresso_payments',
258
-            EE_PAYMENTS_ASSETS_URL . 'ee-payments.css',
258
+            EE_PAYMENTS_ASSETS_URL.'ee-payments.css',
259 259
             [],
260 260
             EVENT_ESPRESSO_VERSION
261 261
         );
@@ -264,7 +264,7 @@  discard block
 block discarded – undo
264 264
         wp_enqueue_script('ee-text-links');
265 265
         wp_enqueue_script(
266 266
             'espresso_payments',
267
-            EE_PAYMENTS_ASSETS_URL . 'espresso_payments_admin.js',
267
+            EE_PAYMENTS_ASSETS_URL.'espresso_payments_admin.js',
268 268
             ['ee-datepicker'],
269 269
             EVENT_ESPRESSO_VERSION,
270 270
             true
@@ -294,7 +294,7 @@  discard block
 block discarded – undo
294 294
         $table_analysis = LoaderFactory::getShared(TableAnalysis::class);
295 295
         /** @var TableManager $table_manager */
296 296
         $table_manager = LoaderFactory::getShared(TableManager::class);
297
-        if (! $table_analysis->tableExists('esp_payment_method')) {
297
+        if ( ! $table_analysis->tableExists('esp_payment_method')) {
298 298
             $table_manager->createTable(
299 299
                 'esp_payment_method',
300 300
                 "PMD_ID int(11) NOT NULL AUTO_INCREMENT,
@@ -316,7 +316,7 @@  discard block
 block discarded – undo
316 316
                 'InnoDB'
317 317
             );
318 318
         }
319
-        if (! $table_analysis->tableExists('esp_currency_payment_method')) {
319
+        if ( ! $table_analysis->tableExists('esp_currency_payment_method')) {
320 320
             $table_manager->createTable(
321 321
                 'esp_currency_payment_method',
322 322
                 "CPM_ID int(11) NOT NULL AUTO_INCREMENT,
@@ -365,7 +365,7 @@  discard block
 block discarded – undo
365 365
             }
366 366
             // check for any active pms of that type
367 367
             $payment_method = EEM_Payment_Method::instance()->get_one_of_type($pmt_obj->system_name());
368
-            if (! $payment_method instanceof EE_Payment_Method) {
368
+            if ( ! $payment_method instanceof EE_Payment_Method) {
369 369
                 $payment_method = EE_Payment_Method::new_instance(
370 370
                     [
371 371
                         'PMD_slug'       => sanitize_key($pmt_obj->system_name()),
@@ -375,7 +375,7 @@  discard block
 block discarded – undo
375 375
                     ]
376 376
                 );
377 377
             }
378
-            $payment_methods[ $payment_method->slug() ] = $payment_method;
378
+            $payment_methods[$payment_method->slug()] = $payment_method;
379 379
         }
380 380
         $payment_methods = apply_filters(
381 381
             'FHEE__Payments_Admin_Page___payment_methods_list__payment_methods',
@@ -385,7 +385,7 @@  discard block
 block discarded – undo
385 385
             if ($payment_method instanceof EE_Payment_Method) {
386 386
                 $this->addMetaBox(
387 387
                 // html id
388
-                    'espresso_' . $payment_method->slug() . '_payment_settings',
388
+                    'espresso_'.$payment_method->slug().'_payment_settings',
389 389
                     // title
390 390
                     sprintf(esc_html__('%s Settings', 'event_espresso'), $payment_method->admin_name()),
391 391
                     // callback
@@ -400,12 +400,12 @@  discard block
 block discarded – undo
400 400
                     ['payment_method' => $payment_method]
401 401
                 );
402 402
                 // setup for tabbed content
403
-                $tabs[ $payment_method->slug() ] = [
403
+                $tabs[$payment_method->slug()] = [
404 404
                     'label' => $payment_method->admin_name(),
405 405
                     'class' => $payment_method->active()
406 406
                         ? 'gateway-active'
407 407
                         : '',
408
-                    'href'  => 'espresso_' . $payment_method->slug() . '_payment_settings',
408
+                    'href'  => 'espresso_'.$payment_method->slug().'_payment_settings',
409 409
                     'title' => esc_html__('Modify this Payment Method', 'event_espresso'),
410 410
                     'slug'  => $payment_method->slug(),
411 411
                     'icon'  => $payment_method->active()
@@ -442,7 +442,7 @@  discard block
 block discarded – undo
442 442
 
443 443
         $payment_method = EEM_Payment_Method::instance()->get_one([['PMD_slug' => $payment_method_slug]]);
444 444
         // if that didn't work or wasn't provided, find another way to select the current pm
445
-        if (! $this->_verify_payment_method($payment_method)) {
445
+        if ( ! $this->_verify_payment_method($payment_method)) {
446 446
             // like, looking for an active one
447 447
             $payment_method = EEM_Payment_Method::instance()->get_one_active(EEM_Payment_Method::scope_cart);
448 448
             // test that one as well
@@ -491,7 +491,7 @@  discard block
 block discarded – undo
491 491
         $payment_method = isset($metabox['args'], $metabox['args']['payment_method'])
492 492
             ? $metabox['args']['payment_method']
493 493
             : null;
494
-        if (! $payment_method instanceof EE_Payment_Method) {
494
+        if ( ! $payment_method instanceof EE_Payment_Method) {
495 495
             throw new EE_Error(
496 496
                 esc_html__(
497 497
                     'Payment method metabox setup incorrectly. No Payment method object was supplied',
@@ -507,7 +507,7 @@  discard block
 block discarded – undo
507 507
                 $form->receive_form_submission($this->_req_data);
508 508
             }
509 509
             echo wp_kses(
510
-                $form->form_open() . $form->get_html_and_js() . $form->form_close(),
510
+                $form->form_open().$form->get_html_and_js().$form->form_close(),
511 511
                 AllowedTags::getWithFormTags()
512 512
             );
513 513
         } else {
@@ -531,7 +531,7 @@  discard block
 block discarded – undo
531 531
     protected function _generate_payment_method_settings_form(
532 532
         ?EE_Payment_Method $payment_method
533 533
     ): EE_Form_Section_Proper {
534
-        if (! $payment_method instanceof EE_Payment_Method) {
534
+        if ( ! $payment_method instanceof EE_Payment_Method) {
535 535
             return new EE_Form_Section_Proper();
536 536
         }
537 537
         $subsections = apply_filters(
@@ -548,8 +548,8 @@  discard block
 block discarded – undo
548 548
         );
549 549
         return new EE_Form_Section_Proper(
550 550
             [
551
-                'name'            => $payment_method->slug() . '_settings_form',
552
-                'html_id'         => $payment_method->slug() . '_settings_form',
551
+                'name'            => $payment_method->slug().'_settings_form',
552
+                'html_id'         => $payment_method->slug().'_settings_form',
553 553
                 'action'          => EE_Admin_Page::add_query_args_and_nonce(
554 554
                     [
555 555
                         'action'         => 'update_payment_method',
@@ -574,7 +574,7 @@  discard block
 block discarded – undo
574 574
      */
575 575
     protected function _pci_dss_compliance(EE_Payment_Method $payment_method): ?EE_Form_Section_HTML
576 576
     {
577
-        if (! $payment_method->type_obj()->requires_https()) {
577
+        if ( ! $payment_method->type_obj()->requires_https()) {
578 578
             return null;
579 579
         }
580 580
         return new EE_Form_Section_HTML(
@@ -587,7 +587,7 @@  discard block
 block discarded – undo
587 587
                             'important-notice'
588 588
                         )
589 589
                     )
590
-                ) .
590
+                ).
591 591
                 EEH_HTML::td(
592 592
                     EEH_HTML::div(
593 593
                         EEH_HTML::strong(
@@ -639,7 +639,7 @@  discard block
 block discarded – undo
639 639
                             'important-notice'
640 640
                         )
641 641
                     )
642
-                ) .
642
+                ).
643 643
                 EEH_HTML::td(
644 644
                     EEH_HTML::div(
645 645
                         EEH_HTML::strong(
@@ -724,7 +724,7 @@  discard block
 block discarded – undo
724 724
         $update_button = new EE_Submit_Input(
725 725
             [
726 726
                 'name'       => 'submit',
727
-                'html_id'    => 'save_' . $payment_method->slug() . '_settings',
727
+                'html_id'    => 'save_'.$payment_method->slug().'_settings',
728 728
                 'default'    => sprintf(
729 729
                     esc_html__('Update %s Payment Settings', 'event_espresso'),
730 730
                     $payment_method->admin_name()
@@ -738,15 +738,15 @@  discard block
 block discarded – undo
738 738
                 // esc_html__('Update Settings', 'event_espresso'),
739 739
                     '&nbsp;',
740 740
                     '',
741
-                    'ee-update-' . $payment_method->slug() . '-settings__label'
742
-                ) .
741
+                    'ee-update-'.$payment_method->slug().'-settings__label'
742
+                ).
743 743
                 EEH_HTML::td(
744 744
                     $update_button->get_html_for_input(),
745 745
                     '',
746
-                    'ee-update-' . $payment_method->slug() . '-settings__input'
746
+                    'ee-update-'.$payment_method->slug().'-settings__input'
747 747
                 ),
748 748
                 '',
749
-                'ee-update-' . $payment_method->slug() . '-settings'
749
+                'ee-update-'.$payment_method->slug().'-settings'
750 750
             )
751 751
         );
752 752
     }
@@ -771,8 +771,8 @@  discard block
 block discarded – undo
771 771
                 // esc_html__('Deactivate Payment Method', 'event_espresso'),
772 772
                     '&nbsp;',
773 773
                     '',
774
-                    'ee-deactivate-' . $payment_method->slug() . '-settings__label'
775
-                ) .
774
+                    'ee-deactivate-'.$payment_method->slug().'-settings__label'
775
+                ).
776 776
                 EEH_HTML::td(
777 777
                     EEH_HTML::link(
778 778
                         EE_Admin_Page::add_query_args_and_nonce(
@@ -784,14 +784,14 @@  discard block
 block discarded – undo
784 784
                         ),
785 785
                         $link_text_and_title,
786 786
                         $link_text_and_title,
787
-                        'deactivate_' . $payment_method->slug(),
787
+                        'deactivate_'.$payment_method->slug(),
788 788
                         'button button--secondary'
789 789
                     ),
790 790
                     '',
791
-                    'ee-deactivate-' . $payment_method->slug() . '-settings__input'
791
+                    'ee-deactivate-'.$payment_method->slug().'-settings__input'
792 792
                 ),
793 793
                 '',
794
-                'ee-deactivate-' . $payment_method->slug() . '-settings'
794
+                'ee-deactivate-'.$payment_method->slug().'-settings'
795 795
             )
796 796
         );
797 797
     }
@@ -813,8 +813,8 @@  discard block
 block discarded – undo
813 813
         );
814 814
         return new EE_Form_Section_Proper(
815 815
             [
816
-                'name'            => 'activate_' . $payment_method->slug() . '_settings_form',
817
-                'html_id'         => 'activate_' . $payment_method->slug() . '_settings_form',
816
+                'name'            => 'activate_'.$payment_method->slug().'_settings_form',
817
+                'html_id'         => 'activate_'.$payment_method->slug().'_settings_form',
818 818
                 'action'          => '#',
819 819
                 'layout_strategy' => new EE_Admin_Two_Column_Layout(),
820 820
                 'subsections'     => apply_filters(
@@ -830,11 +830,11 @@  discard block
 block discarded – undo
830 830
                                         '',
831 831
                                         'colspan="2"'
832 832
                                     )
833
-                                ) .
833
+                                ).
834 834
                                 EEH_HTML::tr(
835 835
                                     EEH_HTML::th(
836 836
                                         EEH_HTML::label(esc_html__('Click to Activate ', 'event_espresso'))
837
-                                    ) .
837
+                                    ).
838 838
                                     EEH_HTML::td(
839 839
                                         EEH_HTML::link(
840 840
                                             EE_Admin_Page::add_query_args_and_nonce(
@@ -846,7 +846,7 @@  discard block
 block discarded – undo
846 846
                                             ),
847 847
                                             $link_text_and_title,
848 848
                                             $link_text_and_title,
849
-                                            'activate_' . $payment_method->slug(),
849
+                                            'activate_'.$payment_method->slug(),
850 850
                                             'button button--primary-alt'
851 851
                                         )
852 852
                                     )
@@ -966,7 +966,7 @@  discard block
 block discarded – undo
966 966
                 }
967 967
             }
968 968
             // if we couldn't find the correct payment method type...
969
-            if (! $correct_pmt_form_to_use) {
969
+            if ( ! $correct_pmt_form_to_use) {
970 970
                 EE_Error::add_error(
971 971
                     esc_html__(
972 972
                         "We could not find which payment method type your form submission related to. Please contact support",
@@ -981,7 +981,7 @@  discard block
 block discarded – undo
981 981
             $correct_pmt_form_to_use->receive_form_submission($this->_req_data);
982 982
             if ($correct_pmt_form_to_use->is_valid()) {
983 983
                 $payment_settings_subform = $correct_pmt_form_to_use->get_subsection('payment_method_settings');
984
-                if (! $payment_settings_subform instanceof EE_Payment_Method_Form) {
984
+                if ( ! $payment_settings_subform instanceof EE_Payment_Method_Form) {
985 985
                     throw new EE_Error(
986 986
                         sprintf(
987 987
                             esc_html__(
@@ -1195,7 +1195,7 @@  discard block
 block discarded – undo
1195 1195
         // take into account search
1196 1196
         if (isset($this->_req_data['s']) && $this->_req_data['s']) {
1197 1197
             $similarity_string                                                              =
1198
-                ['LIKE', '%' . str_replace("", "%", $this->_req_data['s']) . '%'];
1198
+                ['LIKE', '%'.str_replace("", "%", $this->_req_data['s']).'%'];
1199 1199
             $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_fname'] = $similarity_string;
1200 1200
             $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_lname'] = $similarity_string;
1201 1201
             $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_email'] = $similarity_string;
@@ -1215,8 +1215,8 @@  discard block
 block discarded – undo
1215 1215
             $start_date = wp_strip_all_tags($this->_req_data['payment-filter-start-date']);
1216 1216
             $end_date   = wp_strip_all_tags($this->_req_data['payment-filter-end-date']);
1217 1217
             // make sure our timestamps start and end right at the boundaries for each day
1218
-            $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
1219
-            $end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
1218
+            $start_date = date('Y-m-d', strtotime($start_date)).' 00:00:00';
1219
+            $end_date   = date('Y-m-d', strtotime($end_date)).' 23:59:59';
1220 1220
             // convert to timestamps
1221 1221
             $start_date = strtotime($start_date);
1222 1222
             $end_date   = strtotime($end_date);
@@ -1224,12 +1224,12 @@  discard block
 block discarded – undo
1224 1224
             $start_date = min($start_date, $end_date);
1225 1225
             $end_date   = max($start_date, $end_date);
1226 1226
             // convert for query
1227
-            $start_date                  = EEM_Change_Log::instance()->convert_datetime_for_query(
1227
+            $start_date = EEM_Change_Log::instance()->convert_datetime_for_query(
1228 1228
                 'LOG_time',
1229 1229
                 date('Y-m-d H:i:s', $start_date),
1230 1230
                 'Y-m-d H:i:s'
1231 1231
             );
1232
-            $end_date                    = EEM_Change_Log::instance()->convert_datetime_for_query(
1232
+            $end_date = EEM_Change_Log::instance()->convert_datetime_for_query(
1233 1233
                 'LOG_time',
1234 1234
                 date('Y-m-d H:i:s', $end_date),
1235 1235
                 'Y-m-d H:i:s'
@@ -1248,23 +1248,23 @@  discard block
 block discarded – undo
1248 1248
             $query_params['order_by'] = ['LOG_time' => 'DESC'];
1249 1249
         }
1250 1250
         $offset = ($current_page - 1) * $per_page;
1251
-        if (! isset($this->_req_data['download_results'])) {
1251
+        if ( ! isset($this->_req_data['download_results'])) {
1252 1252
             $query_params['limit'] = [$offset, $per_page];
1253 1253
         }
1254 1254
         // now they've requested to instead just download the file instead of viewing it.
1255 1255
         if (isset($this->_req_data['download_results'])) {
1256 1256
             $wpdb_results = EEM_Change_Log::instance()->get_all_efficiently($query_params);
1257 1257
             header('Content-Disposition: attachment');
1258
-            header("Content-Disposition: attachment; filename=ee_payment_logs_for_" . sanitize_key(site_url()));
1258
+            header("Content-Disposition: attachment; filename=ee_payment_logs_for_".sanitize_key(site_url()));
1259 1259
             echo '<h1> '
1260 1260
                  . sprintf(
1261 1261
                      esc_html__('Payment Logs for %1$s', 'event_espresso'),
1262 1262
                      esc_url_raw(site_url())
1263 1263
                  )
1264 1264
                  . '</h1 >';
1265
-            echo '<h3>' . esc_html__('Query:', 'event_espresso') . '</h3>';
1265
+            echo '<h3>'.esc_html__('Query:', 'event_espresso').'</h3>';
1266 1266
             echo esc_html(var_export($query_params, true));
1267
-            echo '<h3>' . esc_html__('Results:', 'event_espresso') . '</h3>';
1267
+            echo '<h3>'.esc_html__('Results:', 'event_espresso').'</h3>';
1268 1268
             echo esc_html(var_export($wpdb_results, true));
1269 1269
             die;
1270 1270
         }
@@ -1322,7 +1322,7 @@  discard block
 block discarded – undo
1322 1322
             }
1323 1323
         }
1324 1324
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1325
-            EE_PAYMENTS_TEMPLATE_PATH . 'payment_log_details.template.php',
1325
+            EE_PAYMENTS_TEMPLATE_PATH.'payment_log_details.template.php',
1326 1326
             [
1327 1327
                 'payment_log'    => $payment_log,
1328 1328
                 'payment_method' => $payment_method,
Please login to merge, or discard this patch.
admin_pages/events/Events_Admin_Page.core.php 2 patches
Indentation   +2975 added lines, -2975 removed lines patch added patch discarded remove patch
@@ -22,2982 +22,2982 @@
 block discarded – undo
22 22
  */
23 23
 class Events_Admin_Page extends EE_Admin_Page_CPT
24 24
 {
25
-    /**
26
-     * primary key for the event model
27
-     */
28
-    private int $EVT_ID = 0;
29
-
30
-    /**
31
-     * This will hold the event object for event_details screen.
32
-     *
33
-     * @var EE_Event|null $_event
34
-     */
35
-    protected ?EE_Event $_event = null;
36
-
37
-    /**
38
-     * This will hold the category object for category_details screen.
39
-     */
40
-    protected ?stdClass $_category = null;
41
-
42
-    protected ?EEM_Event $_event_model = null;
43
-
44
-    /**
45
-     * @var EE_Event|EE_CPT_Base|null $_cpt_model_obj
46
-     */
47
-    protected $_cpt_model_obj;
48
-
49
-    protected ?NodeGroupDao $model_obj_node_group_persister = null;
50
-
51
-    protected ?AdvancedEditorAdminFormSection $advanced_editor_admin_form = null;
52
-
53
-
54
-    /**
55
-     * Initialize page props for this admin page group.
56
-     */
57
-    protected function _init_page_props()
58
-    {
59
-        // is there a evt_id in the request?
60
-        $this->EVT_ID = $this->request->getRequestParam('EVT_ID', 0, DataType::INT);
61
-        $this->EVT_ID = $this->request->getRequestParam('post', $this->EVT_ID, DataType::INT);
62
-        $this->EVT_ID = $this->request->getRequestParam('post_ID', $this->EVT_ID, DataType::INT);
63
-
64
-        $this->page_slug        = EVENTS_PG_SLUG;
65
-        $this->page_label       = EVENTS_LABEL;
66
-        $this->_admin_base_url  = EVENTS_ADMIN_URL;
67
-        $this->_admin_base_path = EVENTS_ADMIN;
68
-        $this->_cpt_model_names = [
69
-            'create_new' => 'EEM_Event',
70
-            'edit'       => 'EEM_Event',
71
-        ];
72
-        $this->_cpt_edit_routes = [
73
-            'espresso_events' => 'edit',
74
-        ];
75
-        add_action(
76
-            'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
77
-            [$this, 'verify_event_edit'],
78
-            10,
79
-            2
80
-        );
81
-    }
82
-
83
-
84
-    /**
85
-     * Sets the ajax hooks used for this admin page group.
86
-     */
87
-    protected function _ajax_hooks()
88
-    {
89
-        add_action('wp_ajax_ee_save_timezone_setting', [$this, 'saveTimezoneString']);
90
-    }
91
-
92
-
93
-    /**
94
-     * Sets the page properties for this admin page group.
95
-     */
96
-    protected function _define_page_props()
97
-    {
98
-        $this->_admin_page_title = EVENTS_LABEL;
99
-        $this->_labels           = [
100
-            'buttons'      => [
101
-                'add'             => esc_html__('Add New Event', 'event_espresso'),
102
-                'edit'            => esc_html__('Edit Event', 'event_espresso'),
103
-                'delete'          => esc_html__('Delete Event', 'event_espresso'),
104
-                'add_category'    => esc_html__('Add New Category', 'event_espresso'),
105
-                'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
106
-                'delete_category' => esc_html__('Delete Category', 'event_espresso'),
107
-            ],
108
-            'editor_title' => [
109
-                'espresso_events' => esc_html__('Edit Event', 'event_espresso'),
110
-            ],
111
-            'publishbox'   => [
112
-                'create_new'        => esc_html__('Save New Event', 'event_espresso'),
113
-                'edit'              => esc_html__('Update Event', 'event_espresso'),
114
-                'add_category'      => esc_html__('Save New Category', 'event_espresso'),
115
-                'edit_category'     => esc_html__('Update Category', 'event_espresso'),
116
-                'template_settings' => esc_html__('Update Settings', 'event_espresso'),
117
-            ],
118
-        ];
119
-    }
120
-
121
-
122
-    /**
123
-     * Sets the page routes property for this admin page group.
124
-     */
125
-    protected function _set_page_routes()
126
-    {
127
-        $this->_page_routes = [
128
-            'default'                       => [
129
-                'func'       => [$this, '_events_overview_list_table'],
130
-                'capability' => 'ee_read_events',
131
-            ],
132
-            'create_new'                    => [
133
-                'func'       => [$this, '_create_new_cpt_item'],
134
-                'capability' => 'ee_edit_events',
135
-            ],
136
-            'edit'                          => [
137
-                'func'       => [$this, '_edit_cpt_item'],
138
-                'capability' => 'ee_edit_event',
139
-                'obj_id'     => $this->EVT_ID,
140
-            ],
141
-            'copy_event'                    => [
142
-                'func'       => [$this, '_copy_events'],
143
-                'capability' => 'ee_edit_event',
144
-                'obj_id'     => $this->EVT_ID,
145
-                'noheader'   => true,
146
-            ],
147
-            'trash_event'                   => [
148
-                'func'       => [$this, '_trash_or_restore_event'],
149
-                'args'       => ['event_status' => 'trash'],
150
-                'capability' => 'ee_delete_event',
151
-                'obj_id'     => $this->EVT_ID,
152
-                'noheader'   => true,
153
-            ],
154
-            'trash_events'                  => [
155
-                'func'       => [$this, '_trash_or_restore_events'],
156
-                'args'       => ['event_status' => 'trash'],
157
-                'capability' => 'ee_delete_events',
158
-                'noheader'   => true,
159
-            ],
160
-            'restore_event'                 => [
161
-                'func'       => [$this, '_trash_or_restore_event'],
162
-                'args'       => ['event_status' => 'draft'],
163
-                'capability' => 'ee_delete_event',
164
-                'obj_id'     => $this->EVT_ID,
165
-                'noheader'   => true,
166
-            ],
167
-            'restore_events'                => [
168
-                'func'       => [$this, '_trash_or_restore_events'],
169
-                'args'       => ['event_status' => 'draft'],
170
-                'capability' => 'ee_delete_events',
171
-                'noheader'   => true,
172
-            ],
173
-            'delete_event'                  => [
174
-                'func'       => [$this, '_delete_event'],
175
-                'capability' => 'ee_delete_event',
176
-                'obj_id'     => $this->EVT_ID,
177
-                'noheader'   => true,
178
-            ],
179
-            'delete_events'                 => [
180
-                'func'       => [$this, '_delete_events'],
181
-                'capability' => 'ee_delete_events',
182
-                'noheader'   => true,
183
-            ],
184
-            'view_report'                   => [
185
-                'func'       => [$this, '_view_report'],
186
-                'capability' => 'ee_edit_events',
187
-            ],
188
-            'default_event_settings'        => [
189
-                'func'       => [$this, '_default_event_settings'],
190
-                'capability' => 'manage_options',
191
-            ],
192
-            'update_default_event_settings' => [
193
-                'func'       => [$this, '_update_default_event_settings'],
194
-                'capability' => 'manage_options',
195
-                'noheader'   => true,
196
-            ],
197
-            'template_settings'             => [
198
-                'func'       => [$this, '_template_settings'],
199
-                'capability' => 'manage_options',
200
-            ],
201
-            // event category tab related
202
-            'add_category'                  => [
203
-                'func'       => [$this, '_category_details'],
204
-                'capability' => 'ee_edit_event_category',
205
-                'args'       => ['view' => 'add'],
206
-            ],
207
-            'edit_category'                 => [
208
-                'func'       => [$this, '_category_details'],
209
-                'capability' => 'ee_edit_event_category',
210
-                'args'       => ['view' => 'edit'],
211
-            ],
212
-            'delete_categories'             => [
213
-                'func'       => [$this, '_delete_categories'],
214
-                'capability' => 'ee_delete_event_category',
215
-                'noheader'   => true,
216
-            ],
217
-            'delete_category'               => [
218
-                'func'       => [$this, '_delete_categories'],
219
-                'capability' => 'ee_delete_event_category',
220
-                'noheader'   => true,
221
-            ],
222
-            'insert_category'               => [
223
-                'func'       => [$this, '_insert_or_update_category'],
224
-                'args'       => ['new_category' => true],
225
-                'capability' => 'ee_edit_event_category',
226
-                'noheader'   => true,
227
-            ],
228
-            'update_category'               => [
229
-                'func'       => [$this, '_insert_or_update_category'],
230
-                'args'       => ['new_category' => false],
231
-                'capability' => 'ee_edit_event_category',
232
-                'noheader'   => true,
233
-            ],
234
-            'category_list'                 => [
235
-                'func'       => [$this, '_category_list_table'],
236
-                'capability' => 'ee_manage_event_categories',
237
-            ],
238
-            'preview_deletion'              => [
239
-                'func'       => [$this, 'previewDeletion'],
240
-                'capability' => 'ee_delete_events',
241
-            ],
242
-            'confirm_deletion'              => [
243
-                'func'       => [$this, 'confirmDeletion'],
244
-                'capability' => 'ee_delete_events',
245
-                'noheader'   => true,
246
-            ],
247
-        ];
248
-    }
249
-
250
-
251
-    /**
252
-     * Set the _page_config property for this admin page group.
253
-     */
254
-    protected function _set_page_config()
255
-    {
256
-        $post_id            = $this->request->getRequestParam('post', 0, DataType::INT);
257
-        $EVT_CAT_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
258
-        $this->_page_config = [
259
-            'default'                => [
260
-                'nav'           => [
261
-                    'label' => esc_html__('Overview', 'event_espresso'),
262
-                    'icon'  => 'dashicons-list-view',
263
-                    'order' => 10,
264
-                ],
265
-                'list_table'    => 'Events_Admin_List_Table',
266
-                'help_tabs'     => [
267
-                    'events_overview_help_tab'                       => [
268
-                        'title'    => esc_html__('Events Overview', 'event_espresso'),
269
-                        'filename' => 'events_overview',
270
-                    ],
271
-                    'events_overview_table_column_headings_help_tab' => [
272
-                        'title'    => esc_html__('Events Overview Table Column Headings', 'event_espresso'),
273
-                        'filename' => 'events_overview_table_column_headings',
274
-                    ],
275
-                    'events_overview_filters_help_tab'               => [
276
-                        'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
277
-                        'filename' => 'events_overview_filters',
278
-                    ],
279
-                    'events_overview_view_help_tab'                  => [
280
-                        'title'    => esc_html__('Events Overview Views', 'event_espresso'),
281
-                        'filename' => 'events_overview_views',
282
-                    ],
283
-                    'events_overview_other_help_tab'                 => [
284
-                        'title'    => esc_html__('Events Overview Other', 'event_espresso'),
285
-                        'filename' => 'events_overview_other',
286
-                    ],
287
-                ],
288
-                'require_nonce' => false,
289
-            ],
290
-            'create_new'             => [
291
-                'nav'           => [
292
-                    'label'      => esc_html__('Add New Event', 'event_espresso'),
293
-                    'icon'       => 'dashicons-plus-alt',
294
-                    'order'      => 15,
295
-                    'persistent' => false,
296
-                ],
297
-                'metaboxes'     => ['_register_event_editor_meta_boxes'],
298
-                'help_tabs'     => [
299
-                    'event_editor_help_tab'                            => [
300
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
301
-                        'filename' => 'event_editor',
302
-                    ],
303
-                    'event_editor_title_richtexteditor_help_tab'       => [
304
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
305
-                        'filename' => 'event_editor_title_richtexteditor',
306
-                    ],
307
-                    'event_editor_venue_details_help_tab'              => [
308
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
309
-                        'filename' => 'event_editor_venue_details',
310
-                    ],
311
-                    'event_editor_event_datetimes_help_tab'            => [
312
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
313
-                        'filename' => 'event_editor_event_datetimes',
314
-                    ],
315
-                    'event_editor_event_tickets_help_tab'              => [
316
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
317
-                        'filename' => 'event_editor_event_tickets',
318
-                    ],
319
-                    'event_editor_event_registration_options_help_tab' => [
320
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
321
-                        'filename' => 'event_editor_event_registration_options',
322
-                    ],
323
-                    'event_editor_tags_categories_help_tab'            => [
324
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
325
-                        'filename' => 'event_editor_tags_categories',
326
-                    ],
327
-                    'event_editor_questions_registrants_help_tab'      => [
328
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
329
-                        'filename' => 'event_editor_questions_registrants',
330
-                    ],
331
-                    'event_editor_save_new_event_help_tab'             => [
332
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
333
-                        'filename' => 'event_editor_save_new_event',
334
-                    ],
335
-                    'event_editor_other_help_tab'                      => [
336
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
337
-                        'filename' => 'event_editor_other',
338
-                    ],
339
-                ],
340
-                'qtips'         => ['EE_Event_Editor_Decaf_Tips'],
341
-                'require_nonce' => false,
342
-            ],
343
-            'edit'                   => [
344
-                'nav'           => [
345
-                    'label'      => esc_html__('Edit Event', 'event_espresso'),
346
-                    'icon'       => 'dashicons-edit',
347
-                    'order'      => 15,
348
-                    'persistent' => false,
349
-                    'url'        => $post_id
350
-                        ? EE_Admin_Page::add_query_args_and_nonce(
351
-                            ['post' => $post_id, 'action' => 'edit'],
352
-                            $this->_current_page_view_url
353
-                        )
354
-                        : $this->_admin_base_url,
355
-                ],
356
-                'metaboxes'     => ['_register_event_editor_meta_boxes'],
357
-                'help_tabs'     => [
358
-                    'event_editor_help_tab'                            => [
359
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
360
-                        'filename' => 'event_editor',
361
-                    ],
362
-                    'event_editor_title_richtexteditor_help_tab'       => [
363
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
364
-                        'filename' => 'event_editor_title_richtexteditor',
365
-                    ],
366
-                    'event_editor_venue_details_help_tab'              => [
367
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
368
-                        'filename' => 'event_editor_venue_details',
369
-                    ],
370
-                    'event_editor_event_datetimes_help_tab'            => [
371
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
372
-                        'filename' => 'event_editor_event_datetimes',
373
-                    ],
374
-                    'event_editor_event_tickets_help_tab'              => [
375
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
376
-                        'filename' => 'event_editor_event_tickets',
377
-                    ],
378
-                    'event_editor_event_registration_options_help_tab' => [
379
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
380
-                        'filename' => 'event_editor_event_registration_options',
381
-                    ],
382
-                    'event_editor_tags_categories_help_tab'            => [
383
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
384
-                        'filename' => 'event_editor_tags_categories',
385
-                    ],
386
-                    'event_editor_questions_registrants_help_tab'      => [
387
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
388
-                        'filename' => 'event_editor_questions_registrants',
389
-                    ],
390
-                    'event_editor_save_new_event_help_tab'             => [
391
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
392
-                        'filename' => 'event_editor_save_new_event',
393
-                    ],
394
-                    'event_editor_other_help_tab'                      => [
395
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
396
-                        'filename' => 'event_editor_other',
397
-                    ],
398
-                ],
399
-                'require_nonce' => false,
400
-            ],
401
-            'default_event_settings' => [
402
-                'nav'           => [
403
-                    'label' => esc_html__('Default Settings', 'event_espresso'),
404
-                    'icon'  => 'dashicons-admin-generic',
405
-                    'order' => 40,
406
-                ],
407
-                'metaboxes'     => array_merge(['_publish_post_box'], $this->_default_espresso_metaboxes),
408
-                'labels'        => [
409
-                    'publishbox' => esc_html__('Update Settings', 'event_espresso'),
410
-                ],
411
-                'help_tabs'     => [
412
-                    'default_settings_help_tab'        => [
413
-                        'title'    => esc_html__('Default Event Settings', 'event_espresso'),
414
-                        'filename' => 'events_default_settings',
415
-                    ],
416
-                    'default_settings_status_help_tab' => [
417
-                        'title'    => esc_html__('Default Registration Status', 'event_espresso'),
418
-                        'filename' => 'events_default_settings_status',
419
-                    ],
420
-                    'default_maximum_tickets_help_tab' => [
421
-                        'title'    => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
422
-                        'filename' => 'events_default_settings_max_tickets',
423
-                    ],
424
-                ],
425
-                'require_nonce' => false,
426
-            ],
427
-            // template settings
428
-            'template_settings'      => [
429
-                'nav'           => [
430
-                    'label' => esc_html__('Templates', 'event_espresso'),
431
-                    'icon'  => 'dashicons-layout',
432
-                    'order' => 30,
433
-                ],
434
-                'metaboxes'     => $this->_default_espresso_metaboxes,
435
-                'help_tabs'     => [
436
-                    'general_settings_templates_help_tab' => [
437
-                        'title'    => esc_html__('Templates', 'event_espresso'),
438
-                        'filename' => 'general_settings_templates',
439
-                    ],
440
-                ],
441
-                'require_nonce' => false,
442
-            ],
443
-            // event category stuff
444
-            'add_category'           => [
445
-                'nav'           => [
446
-                    'label'      => esc_html__('Add Category', 'event_espresso'),
447
-                    'icon'       => 'dashicons-plus-alt',
448
-                    'order'      => 25,
449
-                    'persistent' => false,
450
-                ],
451
-                'help_tabs'     => [
452
-                    'add_category_help_tab' => [
453
-                        'title'    => esc_html__('Add New Event Category', 'event_espresso'),
454
-                        'filename' => 'events_add_category',
455
-                    ],
456
-                ],
457
-                'metaboxes'     => ['_publish_post_box'],
458
-                'require_nonce' => false,
459
-            ],
460
-            'edit_category'          => [
461
-                'nav'           => [
462
-                    'label'      => esc_html__('Edit Category', 'event_espresso'),
463
-                    'icon'       => 'dashicons-edit',
464
-                    'order'      => 25,
465
-                    'persistent' => false,
466
-                    'url'        => $EVT_CAT_ID
467
-                        ? add_query_arg(
468
-                            ['EVT_CAT_ID' => $EVT_CAT_ID],
469
-                            $this->_current_page_view_url
470
-                        )
471
-                        : $this->_admin_base_url,
472
-                ],
473
-                'help_tabs'     => [
474
-                    'edit_category_help_tab' => [
475
-                        'title'    => esc_html__('Edit Event Category', 'event_espresso'),
476
-                        'filename' => 'events_edit_category',
477
-                    ],
478
-                ],
479
-                'metaboxes'     => ['_publish_post_box'],
480
-                'require_nonce' => false,
481
-            ],
482
-            'category_list'          => [
483
-                'nav'           => [
484
-                    'label' => esc_html__('Categories', 'event_espresso'),
485
-                    'icon'  => 'dashicons-networking',
486
-                    'order' => 20,
487
-                ],
488
-                'list_table'    => 'Event_Categories_Admin_List_Table',
489
-                'help_tabs'     => [
490
-                    'events_categories_help_tab'                       => [
491
-                        'title'    => esc_html__('Event Categories', 'event_espresso'),
492
-                        'filename' => 'events_categories',
493
-                    ],
494
-                    'events_categories_table_column_headings_help_tab' => [
495
-                        'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
496
-                        'filename' => 'events_categories_table_column_headings',
497
-                    ],
498
-                    'events_categories_view_help_tab'                  => [
499
-                        'title'    => esc_html__('Event Categories Views', 'event_espresso'),
500
-                        'filename' => 'events_categories_views',
501
-                    ],
502
-                    'events_categories_other_help_tab'                 => [
503
-                        'title'    => esc_html__('Event Categories Other', 'event_espresso'),
504
-                        'filename' => 'events_categories_other',
505
-                    ],
506
-                ],
507
-                'metaboxes'     => $this->_default_espresso_metaboxes,
508
-                'require_nonce' => false,
509
-            ],
510
-            'preview_deletion'       => [
511
-                'nav'           => [
512
-                    'label'      => esc_html__('Preview Deletion', 'event_espresso'),
513
-                    'icon'       => 'dashicons-remove',
514
-                    'order'      => 15,
515
-                    'persistent' => false,
516
-                    'url'        => '',
517
-                ],
518
-                'require_nonce' => false,
519
-            ],
520
-        ];
521
-    }
522
-
523
-
524
-    /**
525
-     * Used to register any global screen options if necessary for every route in this admin page group.
526
-     */
527
-    protected function _add_screen_options()
528
-    {
529
-    }
530
-
531
-
532
-    /**
533
-     * Implementing the screen options for the 'default' route.
534
-     *
535
-     * @throws InvalidArgumentException
536
-     * @throws InvalidDataTypeException
537
-     * @throws InvalidInterfaceException
538
-     */
539
-    protected function _add_screen_options_default()
540
-    {
541
-        $this->_per_page_screen_option();
542
-    }
543
-
544
-
545
-    /**
546
-     * Implementing screen options for the category list route.
547
-     *
548
-     * @throws InvalidArgumentException
549
-     * @throws InvalidDataTypeException
550
-     * @throws InvalidInterfaceException
551
-     */
552
-    protected function _add_screen_options_category_list()
553
-    {
554
-        $page_title              = $this->_admin_page_title;
555
-        $this->_admin_page_title = esc_html__('Categories', 'event_espresso');
556
-        $this->_per_page_screen_option();
557
-        $this->_admin_page_title = $page_title;
558
-    }
559
-
560
-
561
-    /**
562
-     * Used to register any global feature pointers for the admin page group.
563
-     */
564
-    protected function _add_feature_pointers()
565
-    {
566
-    }
567
-
568
-
569
-    /**
570
-     * Registers and enqueues any global scripts and styles for the entire admin page group.
571
-     */
572
-    public function load_scripts_styles()
573
-    {
574
-        wp_enqueue_style(
575
-            'events-admin-css',
576
-            EVENTS_ASSETS_URL . 'events-admin-page.css',
577
-            [],
578
-            EVENT_ESPRESSO_VERSION
579
-        );
580
-        wp_enqueue_style(
581
-            'ee-cat-admin',
582
-            EVENTS_ASSETS_URL . 'ee-cat-admin.css',
583
-            ['editor-buttons'],
584
-            EVENT_ESPRESSO_VERSION
585
-        );
586
-    }
587
-
588
-
589
-    /**
590
-     * Enqueuing scripts and styles specific to this view
591
-     */
592
-    public function load_scripts_styles_create_new()
593
-    {
594
-        $this->load_scripts_styles_edit();
595
-    }
596
-
597
-
598
-    /**
599
-     * Enqueuing scripts and styles specific to this view
600
-     */
601
-    public function load_scripts_styles_edit()
602
-    {
603
-        // styles
604
-        wp_enqueue_style('espresso-ui-theme');
605
-        wp_enqueue_style(
606
-            'event-editor-css',
607
-            EVENTS_ASSETS_URL . 'event-editor.css',
608
-            ['ee-admin-css'],
609
-            EVENT_ESPRESSO_VERSION
610
-        );
611
-        // scripts
612
-        wp_enqueue_script(
613
-            'event_editor_js',
614
-            EVENTS_ASSETS_URL . 'event_editor.js',
615
-            [
616
-                EspressoLegacyAdminAssetManager::JS_HANDLE_EE_ADMIN,
617
-                JqueryAssetManager::JS_HANDLE_JQUERY_UI_SLIDER,
618
-                JqueryAssetManager::JS_HANDLE_JQUERY_UI_TIMEPICKER_ADDON
619
-            ],
620
-            EVENT_ESPRESSO_VERSION,
621
-            true
622
-        );
623
-        if (! $this->admin_config->useAdvancedEditor()) {
624
-            wp_enqueue_script(
625
-                'event-datetime-metabox',
626
-                EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
627
-                ['event_editor_js', 'ee-datepicker'],
628
-                EVENT_ESPRESSO_VERSION
629
-            );
630
-        }
631
-    }
632
-
633
-
634
-    /**
635
-     * Populating the _views property for the category list table view.
636
-     */
637
-    protected function _set_list_table_views_category_list()
638
-    {
639
-        $this->_views = [
640
-            'all' => [
641
-                'slug'        => 'all',
642
-                'label'       => esc_html__('All', 'event_espresso'),
643
-                'count'       => 0,
644
-                'bulk_action' => [
645
-                    'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
646
-                ],
647
-            ],
648
-        ];
649
-    }
650
-
651
-
652
-    /**
653
-     * For adding anything that fires on the admin_init hook for any route within this admin page group.
654
-     */
655
-    public function admin_init()
656
-    {
657
-        EE_Registry::$i18n_js_strings['image_confirm'] = wp_strip_all_tags(
658
-            esc_html__(
659
-                'Do you really want to delete this image? Please remember to update your event to complete the removal.',
660
-                'event_espresso'
661
-            )
662
-        );
663
-
664
-        EE_Registry::$i18n_js_strings['entity_locked'] = wp_strip_all_tags(
665
-            __(
666
-                'This item can not be deleted because it it as locked. It may be in use by the system or have been sold.',
667
-                'event_espresso'
668
-            )
669
-        );
670
-    }
671
-
672
-
673
-    /**
674
-     * For adding anything that should be triggered on the admin_notices hook for any route within this admin page
675
-     * group.
676
-     */
677
-    public function admin_notices()
678
-    {
679
-    }
680
-
681
-
682
-    /**
683
-     * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within
684
-     * this admin page group.
685
-     */
686
-    public function admin_footer_scripts()
687
-    {
688
-    }
689
-
690
-
691
-    /**
692
-     * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
693
-     * warning (via EE_Error::add_error());
694
-     *
695
-     * @param EE_Event|null $event Event object
696
-     * @param string        $req_type
697
-     * @return void
698
-     * @throws EE_Error
699
-     * @throws ReflectionException
700
-     */
701
-    public function verify_event_edit(?EE_Base_Class $event = null, string $req_type = '')
702
-    {
703
-        // don't need to do this when processing
704
-        if (! empty($req_type)) {
705
-            return;
706
-        }
707
-        // no event?
708
-        if (! $event instanceof EE_Event) {
709
-            $event = $this->_cpt_model_obj;
710
-        }
711
-        // STILL no event?
712
-        if (! $event instanceof EE_Event) {
713
-            return;
714
-        }
715
-        // don't need to keep calling this
716
-        remove_action(
717
-            'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
718
-            [$this, 'verify_event_edit']
719
-        );
720
-        $orig_status = $event->status();
721
-        // first check if event is active.
722
-        if (
723
-            $orig_status === EEM_Event::cancelled
724
-            || $orig_status === EEM_Event::postponed
725
-            || $event->is_expired()
726
-            || $event->is_inactive()
727
-        ) {
728
-            return;
729
-        }
730
-        // made it here so it IS active... next check that any of the tickets are sold.
731
-        if ($event->is_sold_out(true)) {
732
-            if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
733
-                EE_Error::add_attention(
734
-                    sprintf(
735
-                        esc_html__(
736
-                            'Please note that the Event Status has automatically been changed to %s because there are no more spaces available for this event.  However, this change is not permanent until you update the event.  You can change the status back to something else before updating if you wish.',
737
-                            'event_espresso'
738
-                        ),
739
-                        EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
740
-                    )
741
-                );
742
-            }
743
-            return;
744
-        }
745
-        if ($orig_status === EEM_Event::sold_out) {
746
-            EE_Error::add_attention(
747
-                sprintf(
748
-                    esc_html__(
749
-                        'Please note that the Event Status has automatically been changed to %s because more spaces have become available for this event, most likely due to abandoned transactions freeing up reserved tickets.  However, this change is not permanent until you update the event. If you wish, you can change the status back to something else before updating.',
750
-                        'event_espresso'
751
-                    ),
752
-                    EEH_Template::pretty_status($event->status(), false, 'sentence')
753
-                )
754
-            );
755
-        }
756
-        // now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
757
-        if (! $event->tickets_on_sale()) {
758
-            return;
759
-        }
760
-        // made it here so show warning
761
-        $this->_edit_event_warning();
762
-    }
763
-
764
-
765
-    /**
766
-     * This is the text used for when an event is being edited that is public and has tickets for sale.
767
-     * When needed, hook this into a EE_Error::add_error() notice.
768
-     *
769
-     * @access protected
770
-     * @return void
771
-     */
772
-    protected function _edit_event_warning()
773
-    {
774
-        // we don't want to add warnings during these requests
775
-        if ($this->request->getRequestParam('action') === 'editpost') {
776
-            return;
777
-        }
778
-        EE_Error::add_attention(
779
-            sprintf(
780
-                esc_html__(
781
-                    'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s',
782
-                    'event_espresso'
783
-                ),
784
-                '<a class="espresso-help-tab-lnk ee-help-tab-link">',
785
-                '</a>'
786
-            )
787
-        );
788
-    }
789
-
790
-
791
-    /**
792
-     * When a user is creating a new event, notify them if they haven't set their timezone.
793
-     * Otherwise, do the normal logic
25
+	/**
26
+	 * primary key for the event model
27
+	 */
28
+	private int $EVT_ID = 0;
29
+
30
+	/**
31
+	 * This will hold the event object for event_details screen.
32
+	 *
33
+	 * @var EE_Event|null $_event
34
+	 */
35
+	protected ?EE_Event $_event = null;
36
+
37
+	/**
38
+	 * This will hold the category object for category_details screen.
39
+	 */
40
+	protected ?stdClass $_category = null;
41
+
42
+	protected ?EEM_Event $_event_model = null;
43
+
44
+	/**
45
+	 * @var EE_Event|EE_CPT_Base|null $_cpt_model_obj
46
+	 */
47
+	protected $_cpt_model_obj;
48
+
49
+	protected ?NodeGroupDao $model_obj_node_group_persister = null;
50
+
51
+	protected ?AdvancedEditorAdminFormSection $advanced_editor_admin_form = null;
52
+
53
+
54
+	/**
55
+	 * Initialize page props for this admin page group.
56
+	 */
57
+	protected function _init_page_props()
58
+	{
59
+		// is there a evt_id in the request?
60
+		$this->EVT_ID = $this->request->getRequestParam('EVT_ID', 0, DataType::INT);
61
+		$this->EVT_ID = $this->request->getRequestParam('post', $this->EVT_ID, DataType::INT);
62
+		$this->EVT_ID = $this->request->getRequestParam('post_ID', $this->EVT_ID, DataType::INT);
63
+
64
+		$this->page_slug        = EVENTS_PG_SLUG;
65
+		$this->page_label       = EVENTS_LABEL;
66
+		$this->_admin_base_url  = EVENTS_ADMIN_URL;
67
+		$this->_admin_base_path = EVENTS_ADMIN;
68
+		$this->_cpt_model_names = [
69
+			'create_new' => 'EEM_Event',
70
+			'edit'       => 'EEM_Event',
71
+		];
72
+		$this->_cpt_edit_routes = [
73
+			'espresso_events' => 'edit',
74
+		];
75
+		add_action(
76
+			'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
77
+			[$this, 'verify_event_edit'],
78
+			10,
79
+			2
80
+		);
81
+	}
82
+
83
+
84
+	/**
85
+	 * Sets the ajax hooks used for this admin page group.
86
+	 */
87
+	protected function _ajax_hooks()
88
+	{
89
+		add_action('wp_ajax_ee_save_timezone_setting', [$this, 'saveTimezoneString']);
90
+	}
91
+
92
+
93
+	/**
94
+	 * Sets the page properties for this admin page group.
95
+	 */
96
+	protected function _define_page_props()
97
+	{
98
+		$this->_admin_page_title = EVENTS_LABEL;
99
+		$this->_labels           = [
100
+			'buttons'      => [
101
+				'add'             => esc_html__('Add New Event', 'event_espresso'),
102
+				'edit'            => esc_html__('Edit Event', 'event_espresso'),
103
+				'delete'          => esc_html__('Delete Event', 'event_espresso'),
104
+				'add_category'    => esc_html__('Add New Category', 'event_espresso'),
105
+				'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
106
+				'delete_category' => esc_html__('Delete Category', 'event_espresso'),
107
+			],
108
+			'editor_title' => [
109
+				'espresso_events' => esc_html__('Edit Event', 'event_espresso'),
110
+			],
111
+			'publishbox'   => [
112
+				'create_new'        => esc_html__('Save New Event', 'event_espresso'),
113
+				'edit'              => esc_html__('Update Event', 'event_espresso'),
114
+				'add_category'      => esc_html__('Save New Category', 'event_espresso'),
115
+				'edit_category'     => esc_html__('Update Category', 'event_espresso'),
116
+				'template_settings' => esc_html__('Update Settings', 'event_espresso'),
117
+			],
118
+		];
119
+	}
120
+
121
+
122
+	/**
123
+	 * Sets the page routes property for this admin page group.
124
+	 */
125
+	protected function _set_page_routes()
126
+	{
127
+		$this->_page_routes = [
128
+			'default'                       => [
129
+				'func'       => [$this, '_events_overview_list_table'],
130
+				'capability' => 'ee_read_events',
131
+			],
132
+			'create_new'                    => [
133
+				'func'       => [$this, '_create_new_cpt_item'],
134
+				'capability' => 'ee_edit_events',
135
+			],
136
+			'edit'                          => [
137
+				'func'       => [$this, '_edit_cpt_item'],
138
+				'capability' => 'ee_edit_event',
139
+				'obj_id'     => $this->EVT_ID,
140
+			],
141
+			'copy_event'                    => [
142
+				'func'       => [$this, '_copy_events'],
143
+				'capability' => 'ee_edit_event',
144
+				'obj_id'     => $this->EVT_ID,
145
+				'noheader'   => true,
146
+			],
147
+			'trash_event'                   => [
148
+				'func'       => [$this, '_trash_or_restore_event'],
149
+				'args'       => ['event_status' => 'trash'],
150
+				'capability' => 'ee_delete_event',
151
+				'obj_id'     => $this->EVT_ID,
152
+				'noheader'   => true,
153
+			],
154
+			'trash_events'                  => [
155
+				'func'       => [$this, '_trash_or_restore_events'],
156
+				'args'       => ['event_status' => 'trash'],
157
+				'capability' => 'ee_delete_events',
158
+				'noheader'   => true,
159
+			],
160
+			'restore_event'                 => [
161
+				'func'       => [$this, '_trash_or_restore_event'],
162
+				'args'       => ['event_status' => 'draft'],
163
+				'capability' => 'ee_delete_event',
164
+				'obj_id'     => $this->EVT_ID,
165
+				'noheader'   => true,
166
+			],
167
+			'restore_events'                => [
168
+				'func'       => [$this, '_trash_or_restore_events'],
169
+				'args'       => ['event_status' => 'draft'],
170
+				'capability' => 'ee_delete_events',
171
+				'noheader'   => true,
172
+			],
173
+			'delete_event'                  => [
174
+				'func'       => [$this, '_delete_event'],
175
+				'capability' => 'ee_delete_event',
176
+				'obj_id'     => $this->EVT_ID,
177
+				'noheader'   => true,
178
+			],
179
+			'delete_events'                 => [
180
+				'func'       => [$this, '_delete_events'],
181
+				'capability' => 'ee_delete_events',
182
+				'noheader'   => true,
183
+			],
184
+			'view_report'                   => [
185
+				'func'       => [$this, '_view_report'],
186
+				'capability' => 'ee_edit_events',
187
+			],
188
+			'default_event_settings'        => [
189
+				'func'       => [$this, '_default_event_settings'],
190
+				'capability' => 'manage_options',
191
+			],
192
+			'update_default_event_settings' => [
193
+				'func'       => [$this, '_update_default_event_settings'],
194
+				'capability' => 'manage_options',
195
+				'noheader'   => true,
196
+			],
197
+			'template_settings'             => [
198
+				'func'       => [$this, '_template_settings'],
199
+				'capability' => 'manage_options',
200
+			],
201
+			// event category tab related
202
+			'add_category'                  => [
203
+				'func'       => [$this, '_category_details'],
204
+				'capability' => 'ee_edit_event_category',
205
+				'args'       => ['view' => 'add'],
206
+			],
207
+			'edit_category'                 => [
208
+				'func'       => [$this, '_category_details'],
209
+				'capability' => 'ee_edit_event_category',
210
+				'args'       => ['view' => 'edit'],
211
+			],
212
+			'delete_categories'             => [
213
+				'func'       => [$this, '_delete_categories'],
214
+				'capability' => 'ee_delete_event_category',
215
+				'noheader'   => true,
216
+			],
217
+			'delete_category'               => [
218
+				'func'       => [$this, '_delete_categories'],
219
+				'capability' => 'ee_delete_event_category',
220
+				'noheader'   => true,
221
+			],
222
+			'insert_category'               => [
223
+				'func'       => [$this, '_insert_or_update_category'],
224
+				'args'       => ['new_category' => true],
225
+				'capability' => 'ee_edit_event_category',
226
+				'noheader'   => true,
227
+			],
228
+			'update_category'               => [
229
+				'func'       => [$this, '_insert_or_update_category'],
230
+				'args'       => ['new_category' => false],
231
+				'capability' => 'ee_edit_event_category',
232
+				'noheader'   => true,
233
+			],
234
+			'category_list'                 => [
235
+				'func'       => [$this, '_category_list_table'],
236
+				'capability' => 'ee_manage_event_categories',
237
+			],
238
+			'preview_deletion'              => [
239
+				'func'       => [$this, 'previewDeletion'],
240
+				'capability' => 'ee_delete_events',
241
+			],
242
+			'confirm_deletion'              => [
243
+				'func'       => [$this, 'confirmDeletion'],
244
+				'capability' => 'ee_delete_events',
245
+				'noheader'   => true,
246
+			],
247
+		];
248
+	}
249
+
250
+
251
+	/**
252
+	 * Set the _page_config property for this admin page group.
253
+	 */
254
+	protected function _set_page_config()
255
+	{
256
+		$post_id            = $this->request->getRequestParam('post', 0, DataType::INT);
257
+		$EVT_CAT_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
258
+		$this->_page_config = [
259
+			'default'                => [
260
+				'nav'           => [
261
+					'label' => esc_html__('Overview', 'event_espresso'),
262
+					'icon'  => 'dashicons-list-view',
263
+					'order' => 10,
264
+				],
265
+				'list_table'    => 'Events_Admin_List_Table',
266
+				'help_tabs'     => [
267
+					'events_overview_help_tab'                       => [
268
+						'title'    => esc_html__('Events Overview', 'event_espresso'),
269
+						'filename' => 'events_overview',
270
+					],
271
+					'events_overview_table_column_headings_help_tab' => [
272
+						'title'    => esc_html__('Events Overview Table Column Headings', 'event_espresso'),
273
+						'filename' => 'events_overview_table_column_headings',
274
+					],
275
+					'events_overview_filters_help_tab'               => [
276
+						'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
277
+						'filename' => 'events_overview_filters',
278
+					],
279
+					'events_overview_view_help_tab'                  => [
280
+						'title'    => esc_html__('Events Overview Views', 'event_espresso'),
281
+						'filename' => 'events_overview_views',
282
+					],
283
+					'events_overview_other_help_tab'                 => [
284
+						'title'    => esc_html__('Events Overview Other', 'event_espresso'),
285
+						'filename' => 'events_overview_other',
286
+					],
287
+				],
288
+				'require_nonce' => false,
289
+			],
290
+			'create_new'             => [
291
+				'nav'           => [
292
+					'label'      => esc_html__('Add New Event', 'event_espresso'),
293
+					'icon'       => 'dashicons-plus-alt',
294
+					'order'      => 15,
295
+					'persistent' => false,
296
+				],
297
+				'metaboxes'     => ['_register_event_editor_meta_boxes'],
298
+				'help_tabs'     => [
299
+					'event_editor_help_tab'                            => [
300
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
301
+						'filename' => 'event_editor',
302
+					],
303
+					'event_editor_title_richtexteditor_help_tab'       => [
304
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
305
+						'filename' => 'event_editor_title_richtexteditor',
306
+					],
307
+					'event_editor_venue_details_help_tab'              => [
308
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
309
+						'filename' => 'event_editor_venue_details',
310
+					],
311
+					'event_editor_event_datetimes_help_tab'            => [
312
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
313
+						'filename' => 'event_editor_event_datetimes',
314
+					],
315
+					'event_editor_event_tickets_help_tab'              => [
316
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
317
+						'filename' => 'event_editor_event_tickets',
318
+					],
319
+					'event_editor_event_registration_options_help_tab' => [
320
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
321
+						'filename' => 'event_editor_event_registration_options',
322
+					],
323
+					'event_editor_tags_categories_help_tab'            => [
324
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
325
+						'filename' => 'event_editor_tags_categories',
326
+					],
327
+					'event_editor_questions_registrants_help_tab'      => [
328
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
329
+						'filename' => 'event_editor_questions_registrants',
330
+					],
331
+					'event_editor_save_new_event_help_tab'             => [
332
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
333
+						'filename' => 'event_editor_save_new_event',
334
+					],
335
+					'event_editor_other_help_tab'                      => [
336
+						'title'    => esc_html__('Event Other', 'event_espresso'),
337
+						'filename' => 'event_editor_other',
338
+					],
339
+				],
340
+				'qtips'         => ['EE_Event_Editor_Decaf_Tips'],
341
+				'require_nonce' => false,
342
+			],
343
+			'edit'                   => [
344
+				'nav'           => [
345
+					'label'      => esc_html__('Edit Event', 'event_espresso'),
346
+					'icon'       => 'dashicons-edit',
347
+					'order'      => 15,
348
+					'persistent' => false,
349
+					'url'        => $post_id
350
+						? EE_Admin_Page::add_query_args_and_nonce(
351
+							['post' => $post_id, 'action' => 'edit'],
352
+							$this->_current_page_view_url
353
+						)
354
+						: $this->_admin_base_url,
355
+				],
356
+				'metaboxes'     => ['_register_event_editor_meta_boxes'],
357
+				'help_tabs'     => [
358
+					'event_editor_help_tab'                            => [
359
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
360
+						'filename' => 'event_editor',
361
+					],
362
+					'event_editor_title_richtexteditor_help_tab'       => [
363
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
364
+						'filename' => 'event_editor_title_richtexteditor',
365
+					],
366
+					'event_editor_venue_details_help_tab'              => [
367
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
368
+						'filename' => 'event_editor_venue_details',
369
+					],
370
+					'event_editor_event_datetimes_help_tab'            => [
371
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
372
+						'filename' => 'event_editor_event_datetimes',
373
+					],
374
+					'event_editor_event_tickets_help_tab'              => [
375
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
376
+						'filename' => 'event_editor_event_tickets',
377
+					],
378
+					'event_editor_event_registration_options_help_tab' => [
379
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
380
+						'filename' => 'event_editor_event_registration_options',
381
+					],
382
+					'event_editor_tags_categories_help_tab'            => [
383
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
384
+						'filename' => 'event_editor_tags_categories',
385
+					],
386
+					'event_editor_questions_registrants_help_tab'      => [
387
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
388
+						'filename' => 'event_editor_questions_registrants',
389
+					],
390
+					'event_editor_save_new_event_help_tab'             => [
391
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
392
+						'filename' => 'event_editor_save_new_event',
393
+					],
394
+					'event_editor_other_help_tab'                      => [
395
+						'title'    => esc_html__('Event Other', 'event_espresso'),
396
+						'filename' => 'event_editor_other',
397
+					],
398
+				],
399
+				'require_nonce' => false,
400
+			],
401
+			'default_event_settings' => [
402
+				'nav'           => [
403
+					'label' => esc_html__('Default Settings', 'event_espresso'),
404
+					'icon'  => 'dashicons-admin-generic',
405
+					'order' => 40,
406
+				],
407
+				'metaboxes'     => array_merge(['_publish_post_box'], $this->_default_espresso_metaboxes),
408
+				'labels'        => [
409
+					'publishbox' => esc_html__('Update Settings', 'event_espresso'),
410
+				],
411
+				'help_tabs'     => [
412
+					'default_settings_help_tab'        => [
413
+						'title'    => esc_html__('Default Event Settings', 'event_espresso'),
414
+						'filename' => 'events_default_settings',
415
+					],
416
+					'default_settings_status_help_tab' => [
417
+						'title'    => esc_html__('Default Registration Status', 'event_espresso'),
418
+						'filename' => 'events_default_settings_status',
419
+					],
420
+					'default_maximum_tickets_help_tab' => [
421
+						'title'    => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
422
+						'filename' => 'events_default_settings_max_tickets',
423
+					],
424
+				],
425
+				'require_nonce' => false,
426
+			],
427
+			// template settings
428
+			'template_settings'      => [
429
+				'nav'           => [
430
+					'label' => esc_html__('Templates', 'event_espresso'),
431
+					'icon'  => 'dashicons-layout',
432
+					'order' => 30,
433
+				],
434
+				'metaboxes'     => $this->_default_espresso_metaboxes,
435
+				'help_tabs'     => [
436
+					'general_settings_templates_help_tab' => [
437
+						'title'    => esc_html__('Templates', 'event_espresso'),
438
+						'filename' => 'general_settings_templates',
439
+					],
440
+				],
441
+				'require_nonce' => false,
442
+			],
443
+			// event category stuff
444
+			'add_category'           => [
445
+				'nav'           => [
446
+					'label'      => esc_html__('Add Category', 'event_espresso'),
447
+					'icon'       => 'dashicons-plus-alt',
448
+					'order'      => 25,
449
+					'persistent' => false,
450
+				],
451
+				'help_tabs'     => [
452
+					'add_category_help_tab' => [
453
+						'title'    => esc_html__('Add New Event Category', 'event_espresso'),
454
+						'filename' => 'events_add_category',
455
+					],
456
+				],
457
+				'metaboxes'     => ['_publish_post_box'],
458
+				'require_nonce' => false,
459
+			],
460
+			'edit_category'          => [
461
+				'nav'           => [
462
+					'label'      => esc_html__('Edit Category', 'event_espresso'),
463
+					'icon'       => 'dashicons-edit',
464
+					'order'      => 25,
465
+					'persistent' => false,
466
+					'url'        => $EVT_CAT_ID
467
+						? add_query_arg(
468
+							['EVT_CAT_ID' => $EVT_CAT_ID],
469
+							$this->_current_page_view_url
470
+						)
471
+						: $this->_admin_base_url,
472
+				],
473
+				'help_tabs'     => [
474
+					'edit_category_help_tab' => [
475
+						'title'    => esc_html__('Edit Event Category', 'event_espresso'),
476
+						'filename' => 'events_edit_category',
477
+					],
478
+				],
479
+				'metaboxes'     => ['_publish_post_box'],
480
+				'require_nonce' => false,
481
+			],
482
+			'category_list'          => [
483
+				'nav'           => [
484
+					'label' => esc_html__('Categories', 'event_espresso'),
485
+					'icon'  => 'dashicons-networking',
486
+					'order' => 20,
487
+				],
488
+				'list_table'    => 'Event_Categories_Admin_List_Table',
489
+				'help_tabs'     => [
490
+					'events_categories_help_tab'                       => [
491
+						'title'    => esc_html__('Event Categories', 'event_espresso'),
492
+						'filename' => 'events_categories',
493
+					],
494
+					'events_categories_table_column_headings_help_tab' => [
495
+						'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
496
+						'filename' => 'events_categories_table_column_headings',
497
+					],
498
+					'events_categories_view_help_tab'                  => [
499
+						'title'    => esc_html__('Event Categories Views', 'event_espresso'),
500
+						'filename' => 'events_categories_views',
501
+					],
502
+					'events_categories_other_help_tab'                 => [
503
+						'title'    => esc_html__('Event Categories Other', 'event_espresso'),
504
+						'filename' => 'events_categories_other',
505
+					],
506
+				],
507
+				'metaboxes'     => $this->_default_espresso_metaboxes,
508
+				'require_nonce' => false,
509
+			],
510
+			'preview_deletion'       => [
511
+				'nav'           => [
512
+					'label'      => esc_html__('Preview Deletion', 'event_espresso'),
513
+					'icon'       => 'dashicons-remove',
514
+					'order'      => 15,
515
+					'persistent' => false,
516
+					'url'        => '',
517
+				],
518
+				'require_nonce' => false,
519
+			],
520
+		];
521
+	}
522
+
523
+
524
+	/**
525
+	 * Used to register any global screen options if necessary for every route in this admin page group.
526
+	 */
527
+	protected function _add_screen_options()
528
+	{
529
+	}
530
+
531
+
532
+	/**
533
+	 * Implementing the screen options for the 'default' route.
534
+	 *
535
+	 * @throws InvalidArgumentException
536
+	 * @throws InvalidDataTypeException
537
+	 * @throws InvalidInterfaceException
538
+	 */
539
+	protected function _add_screen_options_default()
540
+	{
541
+		$this->_per_page_screen_option();
542
+	}
543
+
544
+
545
+	/**
546
+	 * Implementing screen options for the category list route.
547
+	 *
548
+	 * @throws InvalidArgumentException
549
+	 * @throws InvalidDataTypeException
550
+	 * @throws InvalidInterfaceException
551
+	 */
552
+	protected function _add_screen_options_category_list()
553
+	{
554
+		$page_title              = $this->_admin_page_title;
555
+		$this->_admin_page_title = esc_html__('Categories', 'event_espresso');
556
+		$this->_per_page_screen_option();
557
+		$this->_admin_page_title = $page_title;
558
+	}
559
+
560
+
561
+	/**
562
+	 * Used to register any global feature pointers for the admin page group.
563
+	 */
564
+	protected function _add_feature_pointers()
565
+	{
566
+	}
567
+
568
+
569
+	/**
570
+	 * Registers and enqueues any global scripts and styles for the entire admin page group.
571
+	 */
572
+	public function load_scripts_styles()
573
+	{
574
+		wp_enqueue_style(
575
+			'events-admin-css',
576
+			EVENTS_ASSETS_URL . 'events-admin-page.css',
577
+			[],
578
+			EVENT_ESPRESSO_VERSION
579
+		);
580
+		wp_enqueue_style(
581
+			'ee-cat-admin',
582
+			EVENTS_ASSETS_URL . 'ee-cat-admin.css',
583
+			['editor-buttons'],
584
+			EVENT_ESPRESSO_VERSION
585
+		);
586
+	}
587
+
588
+
589
+	/**
590
+	 * Enqueuing scripts and styles specific to this view
591
+	 */
592
+	public function load_scripts_styles_create_new()
593
+	{
594
+		$this->load_scripts_styles_edit();
595
+	}
596
+
597
+
598
+	/**
599
+	 * Enqueuing scripts and styles specific to this view
600
+	 */
601
+	public function load_scripts_styles_edit()
602
+	{
603
+		// styles
604
+		wp_enqueue_style('espresso-ui-theme');
605
+		wp_enqueue_style(
606
+			'event-editor-css',
607
+			EVENTS_ASSETS_URL . 'event-editor.css',
608
+			['ee-admin-css'],
609
+			EVENT_ESPRESSO_VERSION
610
+		);
611
+		// scripts
612
+		wp_enqueue_script(
613
+			'event_editor_js',
614
+			EVENTS_ASSETS_URL . 'event_editor.js',
615
+			[
616
+				EspressoLegacyAdminAssetManager::JS_HANDLE_EE_ADMIN,
617
+				JqueryAssetManager::JS_HANDLE_JQUERY_UI_SLIDER,
618
+				JqueryAssetManager::JS_HANDLE_JQUERY_UI_TIMEPICKER_ADDON
619
+			],
620
+			EVENT_ESPRESSO_VERSION,
621
+			true
622
+		);
623
+		if (! $this->admin_config->useAdvancedEditor()) {
624
+			wp_enqueue_script(
625
+				'event-datetime-metabox',
626
+				EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
627
+				['event_editor_js', 'ee-datepicker'],
628
+				EVENT_ESPRESSO_VERSION
629
+			);
630
+		}
631
+	}
632
+
633
+
634
+	/**
635
+	 * Populating the _views property for the category list table view.
636
+	 */
637
+	protected function _set_list_table_views_category_list()
638
+	{
639
+		$this->_views = [
640
+			'all' => [
641
+				'slug'        => 'all',
642
+				'label'       => esc_html__('All', 'event_espresso'),
643
+				'count'       => 0,
644
+				'bulk_action' => [
645
+					'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
646
+				],
647
+			],
648
+		];
649
+	}
650
+
651
+
652
+	/**
653
+	 * For adding anything that fires on the admin_init hook for any route within this admin page group.
654
+	 */
655
+	public function admin_init()
656
+	{
657
+		EE_Registry::$i18n_js_strings['image_confirm'] = wp_strip_all_tags(
658
+			esc_html__(
659
+				'Do you really want to delete this image? Please remember to update your event to complete the removal.',
660
+				'event_espresso'
661
+			)
662
+		);
663
+
664
+		EE_Registry::$i18n_js_strings['entity_locked'] = wp_strip_all_tags(
665
+			__(
666
+				'This item can not be deleted because it it as locked. It may be in use by the system or have been sold.',
667
+				'event_espresso'
668
+			)
669
+		);
670
+	}
671
+
672
+
673
+	/**
674
+	 * For adding anything that should be triggered on the admin_notices hook for any route within this admin page
675
+	 * group.
676
+	 */
677
+	public function admin_notices()
678
+	{
679
+	}
680
+
681
+
682
+	/**
683
+	 * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within
684
+	 * this admin page group.
685
+	 */
686
+	public function admin_footer_scripts()
687
+	{
688
+	}
689
+
690
+
691
+	/**
692
+	 * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
693
+	 * warning (via EE_Error::add_error());
694
+	 *
695
+	 * @param EE_Event|null $event Event object
696
+	 * @param string        $req_type
697
+	 * @return void
698
+	 * @throws EE_Error
699
+	 * @throws ReflectionException
700
+	 */
701
+	public function verify_event_edit(?EE_Base_Class $event = null, string $req_type = '')
702
+	{
703
+		// don't need to do this when processing
704
+		if (! empty($req_type)) {
705
+			return;
706
+		}
707
+		// no event?
708
+		if (! $event instanceof EE_Event) {
709
+			$event = $this->_cpt_model_obj;
710
+		}
711
+		// STILL no event?
712
+		if (! $event instanceof EE_Event) {
713
+			return;
714
+		}
715
+		// don't need to keep calling this
716
+		remove_action(
717
+			'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
718
+			[$this, 'verify_event_edit']
719
+		);
720
+		$orig_status = $event->status();
721
+		// first check if event is active.
722
+		if (
723
+			$orig_status === EEM_Event::cancelled
724
+			|| $orig_status === EEM_Event::postponed
725
+			|| $event->is_expired()
726
+			|| $event->is_inactive()
727
+		) {
728
+			return;
729
+		}
730
+		// made it here so it IS active... next check that any of the tickets are sold.
731
+		if ($event->is_sold_out(true)) {
732
+			if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
733
+				EE_Error::add_attention(
734
+					sprintf(
735
+						esc_html__(
736
+							'Please note that the Event Status has automatically been changed to %s because there are no more spaces available for this event.  However, this change is not permanent until you update the event.  You can change the status back to something else before updating if you wish.',
737
+							'event_espresso'
738
+						),
739
+						EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
740
+					)
741
+				);
742
+			}
743
+			return;
744
+		}
745
+		if ($orig_status === EEM_Event::sold_out) {
746
+			EE_Error::add_attention(
747
+				sprintf(
748
+					esc_html__(
749
+						'Please note that the Event Status has automatically been changed to %s because more spaces have become available for this event, most likely due to abandoned transactions freeing up reserved tickets.  However, this change is not permanent until you update the event. If you wish, you can change the status back to something else before updating.',
750
+						'event_espresso'
751
+					),
752
+					EEH_Template::pretty_status($event->status(), false, 'sentence')
753
+				)
754
+			);
755
+		}
756
+		// now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
757
+		if (! $event->tickets_on_sale()) {
758
+			return;
759
+		}
760
+		// made it here so show warning
761
+		$this->_edit_event_warning();
762
+	}
763
+
764
+
765
+	/**
766
+	 * This is the text used for when an event is being edited that is public and has tickets for sale.
767
+	 * When needed, hook this into a EE_Error::add_error() notice.
768
+	 *
769
+	 * @access protected
770
+	 * @return void
771
+	 */
772
+	protected function _edit_event_warning()
773
+	{
774
+		// we don't want to add warnings during these requests
775
+		if ($this->request->getRequestParam('action') === 'editpost') {
776
+			return;
777
+		}
778
+		EE_Error::add_attention(
779
+			sprintf(
780
+				esc_html__(
781
+					'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s',
782
+					'event_espresso'
783
+				),
784
+				'<a class="espresso-help-tab-lnk ee-help-tab-link">',
785
+				'</a>'
786
+			)
787
+		);
788
+	}
789
+
790
+
791
+	/**
792
+	 * When a user is creating a new event, notify them if they haven't set their timezone.
793
+	 * Otherwise, do the normal logic
794
+	 *
795
+	 * @return void
796
+	 * @throws EE_Error
797
+	 * @throws InvalidArgumentException
798
+	 * @throws InvalidDataTypeException
799
+	 * @throws InvalidInterfaceException
800
+	 * @throws ReflectionException
801
+	 */
802
+	protected function _create_new_cpt_item()
803
+	{
804
+		$has_timezone_string = get_option('timezone_string');
805
+		// only nag them about setting their timezone if it's their first event, and they haven't already done it
806
+		if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
807
+			EE_Error::add_attention(
808
+				sprintf(
809
+					esc_html__(
810
+						'Your website\'s timezone is currently set to a UTC offset. We recommend updating your timezone to a city or region near you before you create an event. Change your timezone now:%1$s%2$s%3$sChange Timezone%4$s',
811
+						'event_espresso'
812
+					),
813
+					'<br>',
814
+					'<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">'
815
+					. EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale())
816
+					. '</select>',
817
+					'<button class="button button--secondary timezone-submit">',
818
+					'</button><span class="spinner"></span>'
819
+				),
820
+				__FILE__,
821
+				__FUNCTION__,
822
+				__LINE__
823
+			);
824
+		}
825
+		parent::_create_new_cpt_item();
826
+	}
827
+
828
+
829
+	/**
830
+	 * Sets the _views property for the default route in this admin page group.
831
+	 */
832
+	protected function _set_list_table_views_default()
833
+	{
834
+		$this->_views = [
835
+			'all'   => [
836
+				'slug'        => 'all',
837
+				'label'       => esc_html__('View All Events', 'event_espresso'),
838
+				'count'       => 0,
839
+				'bulk_action' => [
840
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
841
+				],
842
+			],
843
+			'draft' => [
844
+				'slug'        => 'draft',
845
+				'label'       => esc_html__('Draft', 'event_espresso'),
846
+				'count'       => 0,
847
+				'bulk_action' => [
848
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
849
+				],
850
+			],
851
+		];
852
+		if ($this->capabilities->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
853
+			$this->_views['trash'] = [
854
+				'slug'        => 'trash',
855
+				'label'       => esc_html__('Trash', 'event_espresso'),
856
+				'count'       => 0,
857
+				'bulk_action' => [
858
+					'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
859
+					'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
860
+				],
861
+			];
862
+		}
863
+	}
864
+
865
+
866
+	/**
867
+	 * Provides the legend item array for the default list table view.
868
+	 *
869
+	 * @return array
870
+	 * @throws EE_Error
871
+	 * @throws EE_Error
872
+	 */
873
+	protected function _event_legend_items(): array
874
+	{
875
+		$items    = [
876
+			'view_details'   => [
877
+				'class' => 'dashicons dashicons-visibility',
878
+				'desc'  => esc_html__('View Event', 'event_espresso'),
879
+			],
880
+			'edit_event'     => [
881
+				'class' => 'dashicons dashicons-calendar-alt',
882
+				'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
883
+			],
884
+			'view_attendees' => [
885
+				'class' => 'dashicons dashicons-groups',
886
+				'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
887
+			],
888
+		];
889
+		$items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
890
+		$statuses = [
891
+			'sold_out_status'  => [
892
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::sold_out,
893
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
894
+			],
895
+			'active_status'    => [
896
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::active,
897
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
898
+			],
899
+			'upcoming_status'  => [
900
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::upcoming,
901
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
902
+			],
903
+			'postponed_status' => [
904
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::postponed,
905
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
906
+			],
907
+			'cancelled_status' => [
908
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::cancelled,
909
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
910
+			],
911
+			'expired_status'   => [
912
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::expired,
913
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
914
+			],
915
+			'inactive_status'  => [
916
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::inactive,
917
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
918
+			],
919
+		];
920
+		$statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
921
+		return array_merge($items, $statuses);
922
+	}
923
+
924
+
925
+	/**
926
+	 * @return EEM_Event
927
+	 * @throws EE_Error
928
+	 * @throws InvalidArgumentException
929
+	 * @throws InvalidDataTypeException
930
+	 * @throws InvalidInterfaceException
931
+	 * @throws ReflectionException
932
+	 */
933
+	private function _event_model(): EEM_Event
934
+	{
935
+		if (! $this->_event_model instanceof EEM_Event) {
936
+			$this->_event_model = EE_Registry::instance()->load_model('Event');
937
+		}
938
+		return $this->_event_model;
939
+	}
940
+
941
+
942
+	/**
943
+	 * Adds extra buttons to the WP CPT permalink field row.
944
+	 * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
945
+	 *
946
+	 * @param string      $return    the current html
947
+	 * @param int         $id        the post id for the page
948
+	 * @param string|null $new_title What the title is
949
+	 * @param string|null $new_slug  what the slug is
950
+	 * @return string            The new html string for the permalink area
951
+	 * @deprecated 5.0.0.p
952
+	 * @see        TicketSelectorShortcodeButton::addButton
953
+	 */
954
+	public function extra_permalink_field_buttons(
955
+		string $return,
956
+		int $id,
957
+		?string $new_title,
958
+		?string $new_slug
959
+	): string {
960
+		return TicketSelectorShortcodeButton::addButton($return, $id, $new_title, $new_slug);
961
+	}
962
+
963
+
964
+	/**
965
+	 * _events_overview_list_table
966
+	 * This contains the logic for showing the events_overview list
967
+	 *
968
+	 * @access protected
969
+	 * @return void
970
+	 * @throws DomainException
971
+	 * @throws EE_Error
972
+	 * @throws InvalidArgumentException
973
+	 * @throws InvalidDataTypeException
974
+	 * @throws InvalidInterfaceException
975
+	 */
976
+	protected function _events_overview_list_table()
977
+	{
978
+		$after_list_table = [];
979
+		$links_html       = EEH_HTML::div('', '', 'ee-admin-section ee-layout-stack');
980
+		$links_html       .= EEH_HTML::h3(esc_html__('Links', 'event_espresso'));
981
+		$links_html       .= EEH_HTML::div(
982
+			EEH_Template::get_button_or_link(
983
+				get_post_type_archive_link(EspressoPostType::EVENTS),
984
+				esc_html__('View Event Archive Page', 'event_espresso'),
985
+				'button button--small button--secondary'
986
+			),
987
+			'',
988
+			'ee-admin-button-row ee-admin-button-row--align-start'
989
+		);
990
+		$links_html       .= EEH_HTML::divx();
991
+
992
+		$after_list_table['view_event_list_button'] = $links_html;
993
+
994
+		$after_list_table['legend'] = $this->_display_legend($this->_event_legend_items());
995
+		$this->_admin_page_title    .= ' ' . $this->get_action_link_or_button(
996
+			'create_new',
997
+			'add',
998
+			[],
999
+			'add-new-h2'
1000
+		);
1001
+
1002
+		$this->_template_args['after_list_table'] = array_merge(
1003
+			(array) $this->_template_args['after_list_table'],
1004
+			$after_list_table
1005
+		);
1006
+		$this->display_admin_list_table_page_with_no_sidebar();
1007
+	}
1008
+
1009
+
1010
+	/**
1011
+	 * this allows for extra misc actions in the default WP publish box
1012
+	 *
1013
+	 * @return void
1014
+	 * @throws DomainException
1015
+	 * @throws EE_Error
1016
+	 * @throws InvalidArgumentException
1017
+	 * @throws InvalidDataTypeException
1018
+	 * @throws InvalidInterfaceException
1019
+	 * @throws ReflectionException
1020
+	 */
1021
+	public function extra_misc_actions_publish_box()
1022
+	{
1023
+		$this->_generate_publish_box_extra_content();
1024
+	}
1025
+
1026
+
1027
+	/**
1028
+	 * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
1029
+	 * saved.
1030
+	 * Typically you would use this to save any additional data.
1031
+	 * Keep in mind also that "save_post" runs on EVERY post update to the database.
1032
+	 * ALSO very important.  When a post transitions from scheduled to published,
1033
+	 * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from
1034
+	 * other meta saves. So MAKE sure that you handle this accordingly.
1035
+	 *
1036
+	 * @access protected
1037
+	 * @abstract
1038
+	 * @param string  $post_id The ID of the cpt that was saved (so you can link relationally)
1039
+	 * @param WP_Post $post    The post object of the cpt that was saved.
1040
+	 * @return void
1041
+	 * @throws EE_Error
1042
+	 * @throws InvalidArgumentException
1043
+	 * @throws InvalidDataTypeException
1044
+	 * @throws InvalidInterfaceException
1045
+	 * @throws ReflectionException
1046
+	 */
1047
+	protected function _insert_update_cpt_item($post_id, $post)
1048
+	{
1049
+		if ($post instanceof WP_Post && $post->post_type !== EspressoPostType::EVENTS) {
1050
+			// get out we're not processing an event save.
1051
+			return;
1052
+		}
1053
+		$event_values = [
1054
+			'EVT_member_only'     => $this->request->getRequestParam('member_only', false, DataType::BOOL),
1055
+			'EVT_allow_overflow'  => $this->request->getRequestParam('EVT_allow_overflow', false, DataType::BOOL),
1056
+			'EVT_timezone_string' => $this->request->getRequestParam('timezone_string'),
1057
+		];
1058
+		// check if the new EDTR reg options meta box is being used, and if so, don't run updates for legacy version
1059
+		if (! $this->admin_config->useAdvancedEditor() || ! $this->feature->allowed('use_reg_options_meta_box')) {
1060
+			$event_values['EVT_display_ticket_selector']     = $this->request->getRequestParam(
1061
+				'display_ticket_selector',
1062
+				false,
1063
+				'bool'
1064
+			);
1065
+			$event_values['EVT_additional_limit']            = min(
1066
+				apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1067
+				$this->request->getRequestParam(
1068
+					'additional_limit',
1069
+					EEM_Event::get_default_additional_limit(),
1070
+					'int'
1071
+				)
1072
+			);
1073
+			$event_values['EVT_default_registration_status'] = $this->request->getRequestParam(
1074
+				'EVT_default_registration_status',
1075
+				EE_Registry::instance()->CFG->registration->default_STS_ID
1076
+			);
1077
+
1078
+			$event_values['EVT_external_URL'] = $this->request->getRequestParam('externalURL');
1079
+			$event_values['EVT_phone']        = $this->request->getRequestParam('event_phone');
1080
+			$event_values['EVT_display_desc'] = $this->request->getRequestParam('display_desc', false, DataType::BOOL);
1081
+		} elseif ($post instanceof WP_Post) {
1082
+			$event_values['EVT_name'] = $post->post_title;
1083
+			$event_values['EVT_desc'] = $post->post_content;
1084
+		}
1085
+		// update event
1086
+		$success = $this->_event_model()->update_by_ID($event_values, $post_id);
1087
+		// get event_object for other metaboxes...
1088
+		// though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id )..
1089
+		// i have to set up where conditions to override the filters in the model
1090
+		// that filter out auto-draft and inherit statuses so we GET the inherit id!
1091
+		/** @var EE_Event $event */
1092
+		$event = $this->_event_model()->get_one(
1093
+			[
1094
+				[
1095
+					$this->_event_model()->primary_key_name() => $post_id,
1096
+					'OR'                                      => [
1097
+						'status'   => $post->post_status,
1098
+						// if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db,
1099
+						// but the returned object here has a status of "publish", so use the original post status as well
1100
+						'status*1' => $this->request->getRequestParam('original_post_status'),
1101
+					],
1102
+					'status' => ['NOT IN', ['auto-draft']],
1103
+				],
1104
+			]
1105
+		);
1106
+
1107
+		if (! $event instanceof EE_Event) {
1108
+			return;
1109
+		}
1110
+
1111
+		// the following are default callbacks for event attachment updates
1112
+		// that can be overridden by caffeinated functionality and/or addons.
1113
+		$event_update_callbacks = [];
1114
+		if (! $this->admin_config->useAdvancedEditor()) {
1115
+			$event_update_callbacks['_default_venue_update']   = [$this, '_default_venue_update'];
1116
+			$event_update_callbacks['_default_tickets_update'] = [$this, '_default_tickets_update'];
1117
+		}
1118
+		$event_update_callbacks = apply_filters(
1119
+			'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
1120
+			$event_update_callbacks
1121
+		);
1122
+
1123
+		$att_success = true;
1124
+		foreach ($event_update_callbacks as $e_callback) {
1125
+			$_success = is_callable($e_callback)
1126
+				? $e_callback($event, $this->request->requestParams())
1127
+				: false;
1128
+			// if ANY of these updates fail then we want the appropriate global error message
1129
+			$att_success = $_success !== false ? $att_success : false;
1130
+		}
1131
+		// any errors?
1132
+		if ($success && $att_success === false) {
1133
+			EE_Error::add_error(
1134
+				esc_html__(
1135
+					'Event Details saved successfully but something went wrong with saving attachments.',
1136
+					'event_espresso'
1137
+				),
1138
+				__FILE__,
1139
+				__FUNCTION__,
1140
+				__LINE__
1141
+			);
1142
+		} elseif ($success === false) {
1143
+			EE_Error::add_error(
1144
+				esc_html__('Event Details did not save successfully.', 'event_espresso'),
1145
+				__FILE__,
1146
+				__FUNCTION__,
1147
+				__LINE__
1148
+			);
1149
+		}
1150
+	}
1151
+
1152
+
1153
+	/**
1154
+	 * @param int $post_id
1155
+	 * @param int $revision_id
1156
+	 * @throws EE_Error
1157
+	 * @throws EE_Error
1158
+	 * @throws ReflectionException
1159
+	 * @see parent::restore_item()
1160
+	 */
1161
+	protected function _restore_cpt_item(int $post_id, int $revision_id)
1162
+	{
1163
+		// copy existing event meta to new post
1164
+		$post_evt = $this->_event_model()->get_one_by_ID($post_id);
1165
+		if ($post_evt instanceof EE_Event) {
1166
+			// meta revision restore
1167
+			$post_evt->restore_revision($revision_id);
1168
+			// related objs restore
1169
+			$post_evt->restore_revision($revision_id, ['Venue', 'Datetime', 'Price']);
1170
+		}
1171
+	}
1172
+
1173
+
1174
+	/**
1175
+	 * Attach the venue to the Event
1176
+	 *
1177
+	 * @param EE_Event $event Event Object to add the venue to
1178
+	 * @param array    $data  The request data from the form
1179
+	 * @return bool           Success or fail.
1180
+	 * @throws EE_Error
1181
+	 * @throws ReflectionException
1182
+	 */
1183
+	protected function _default_venue_update(EE_Event $event, array $data): bool
1184
+	{
1185
+		require_once(EE_MODELS . 'EEM_Venue.model.php');
1186
+		$venue_model = EE_Registry::instance()->load_model('Venue');
1187
+		$venue_id    = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1188
+		// very important.  If we don't have a venue name...
1189
+		// then we'll get out because not necessary to create empty venue
1190
+		if (empty($data['venue_title'])) {
1191
+			return false;
1192
+		}
1193
+		$venue_array = [
1194
+			'VNU_wp_user'         => $event->get('EVT_wp_user'),
1195
+			'VNU_name'            => $data['venue_title'],
1196
+			'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1197
+			'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1198
+			'VNU_short_desc'      => ! empty($data['venue_short_description'])
1199
+				? $data['venue_short_description']
1200
+				: null,
1201
+			'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1202
+			'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1203
+			'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1204
+			'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1205
+			'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1206
+			'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1207
+			'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1208
+			'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1209
+			'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1210
+			'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1211
+			'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1212
+			'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1213
+			'status'              => 'publish',
1214
+		];
1215
+		// if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1216
+		if (! empty($venue_id)) {
1217
+			$update_where  = [$venue_model->primary_key_name() => $venue_id];
1218
+			$rows_affected = $venue_model->update($venue_array, [$update_where]);
1219
+			// we've gotta make sure that the venue is always attached to a revision..
1220
+			// add_relation_to should take care of making sure that the relation is already present.
1221
+			$event->_add_relation_to($venue_id, 'Venue');
1222
+			return $rows_affected > 0;
1223
+		}
1224
+		// we insert the venue
1225
+		$venue_id = $venue_model->insert($venue_array);
1226
+		$event->_add_relation_to($venue_id, 'Venue');
1227
+		return ! empty($venue_id);
1228
+		// when we have the ancestor come in it's already been handled by the revision save.
1229
+	}
1230
+
1231
+
1232
+	/**
1233
+	 * Handles saving everything related to Tickets (datetimes, tickets, prices)
1234
+	 *
1235
+	 * @param EE_Event $event The Event object we're attaching data to
1236
+	 * @param array    $data  The request data from the form
1237
+	 * @return array
1238
+	 * @throws EE_Error
1239
+	 * @throws ReflectionException
1240
+	 * @throws Exception
1241
+	 */
1242
+	protected function _default_tickets_update(EE_Event $event, array $data): array
1243
+	{
1244
+		if ($this->admin_config->useAdvancedEditor()) {
1245
+			return [];
1246
+		}
1247
+		$datetime       = null;
1248
+		$saved_tickets  = [];
1249
+		$event_timezone = $event->get_timezone();
1250
+		$date_formats   = ['Y-m-d', 'h:i a'];
1251
+		foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
1252
+			// trim all values to ensure any excess whitespace is removed.
1253
+			$datetime_data                = array_map('trim', $datetime_data);
1254
+			$datetime_data['DTT_EVT_end'] = ! empty($datetime_data['DTT_EVT_end'])
1255
+					? $datetime_data['DTT_EVT_end']
1256
+					: $datetime_data['DTT_EVT_start'];
1257
+			$datetime_values              = [
1258
+				'DTT_ID'        => ! empty($datetime_data['DTT_ID']) ? $datetime_data['DTT_ID'] : null,
1259
+				'DTT_EVT_start' => $datetime_data['DTT_EVT_start'],
1260
+				'DTT_EVT_end'   => $datetime_data['DTT_EVT_end'],
1261
+				'DTT_reg_limit' => empty($datetime_data['DTT_reg_limit']) ? EE_INF : $datetime_data['DTT_reg_limit'],
1262
+				'DTT_order'     => $row,
1263
+			];
1264
+			// if we have an id then let's get existing object first and then set the new values.
1265
+			//  Otherwise we instantiate a new object for save.
1266
+			if (! empty($datetime_data['DTT_ID'])) {
1267
+				$datetime = EEM_Datetime::instance($event_timezone)->get_one_by_ID($datetime_data['DTT_ID']);
1268
+				if (! $datetime instanceof EE_Datetime) {
1269
+					throw new RuntimeException(
1270
+						sprintf(
1271
+							esc_html__(
1272
+								'Something went wrong! A valid Datetime could not be retrieved from the database using the supplied ID: %1$d',
1273
+								'event_espresso'
1274
+							),
1275
+							$datetime_data['DTT_ID']
1276
+						)
1277
+					);
1278
+				}
1279
+				$datetime->set_date_format($date_formats[0]);
1280
+				$datetime->set_time_format($date_formats[1]);
1281
+				foreach ($datetime_values as $field => $value) {
1282
+					$datetime->set($field, $value);
1283
+				}
1284
+			} else {
1285
+				$datetime = EE_Datetime::new_instance($datetime_values, $event_timezone, $date_formats);
1286
+			}
1287
+			if (! $datetime instanceof EE_Datetime) {
1288
+				throw new RuntimeException(
1289
+					sprintf(
1290
+						esc_html__(
1291
+							'Something went wrong! A valid Datetime could not be generated or retrieved using the supplied data: %1$s',
1292
+							'event_espresso'
1293
+						),
1294
+						print_r($datetime_values, true)
1295
+					)
1296
+				);
1297
+			}
1298
+			// before going any further make sure our dates are setup correctly
1299
+			// so that the end date is always equal or greater than the start date.
1300
+			if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
1301
+				$datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
1302
+				$datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
1303
+			}
1304
+			$datetime->save();
1305
+			$event->_add_relation_to($datetime, 'Datetime');
1306
+		}
1307
+		// no datetimes get deleted so we don't do any of that logic here.
1308
+		// update tickets next
1309
+		$old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : [];
1310
+
1311
+		// set up some default start and end dates in case those are not present in the incoming data
1312
+		$default_start_date = new DateTime('now', new DateTimeZone($event->get_timezone()));
1313
+		$default_start_date = $default_start_date->format($date_formats[0] . ' ' . $date_formats[1]);
1314
+		// use the start date of the first datetime for the end date
1315
+		$first_datetime   = $event->first_datetime();
1316
+		$default_end_date = $first_datetime->start_date_and_time($date_formats[0], $date_formats[1]);
1317
+
1318
+		// now process the incoming data
1319
+		foreach ($data['edit_tickets'] as $row => $ticket_data) {
1320
+			$update_prices = false;
1321
+			$ticket_price  = $data['edit_prices'][ $row ][1]['PRC_amount'] ?? 0;
1322
+			// trim inputs to ensure any excess whitespace is removed.
1323
+			$ticket_data   = array_map('trim', $ticket_data);
1324
+			$ticket_values = [
1325
+				'TKT_ID'          => ! empty($ticket_data['TKT_ID']) ? $ticket_data['TKT_ID'] : null,
1326
+				'TTM_ID'          => ! empty($ticket_data['TTM_ID']) ? $ticket_data['TTM_ID'] : 0,
1327
+				'TKT_name'        => ! empty($ticket_data['TKT_name']) ? $ticket_data['TKT_name'] : '',
1328
+				'TKT_description' => ! empty($ticket_data['TKT_description']) ? $ticket_data['TKT_description'] : '',
1329
+				'TKT_start_date'  => ! empty($ticket_data['TKT_start_date'])
1330
+					? $ticket_data['TKT_start_date']
1331
+					: $default_start_date,
1332
+				'TKT_end_date'    => ! empty($ticket_data['TKT_end_date'])
1333
+					? $ticket_data['TKT_end_date']
1334
+					: $default_end_date,
1335
+				'TKT_qty'         => ! empty($ticket_data['TKT_qty'])
1336
+									 || (isset($ticket_data['TKT_qty']) && (int) $ticket_data['TKT_qty'] === 0)
1337
+					? $ticket_data['TKT_qty']
1338
+					: EE_INF,
1339
+				'TKT_uses'        => ! empty($ticket_data['TKT_uses'])
1340
+									 || (isset($ticket_data['TKT_uses']) && (int) $ticket_data['TKT_uses'] === 0)
1341
+					? $ticket_data['TKT_uses']
1342
+					: EE_INF,
1343
+				'TKT_min'         => ! empty($ticket_data['TKT_min']) ? $ticket_data['TKT_min'] : 0,
1344
+				'TKT_max'         => ! empty($ticket_data['TKT_max']) ? $ticket_data['TKT_max'] : EE_INF,
1345
+				'TKT_order'       => $ticket_data['TKT_order'] ?? $row,
1346
+				'TKT_price'       => (float) $ticket_price,
1347
+				'TKT_row'         => $row,
1348
+			];
1349
+			// if this is a default ticket, then we need to set the TKT_ID to 0 and update accordingly,
1350
+			// which means in turn that the prices will become new prices as well.
1351
+			if (isset($ticket_data['TKT_is_default']) && $ticket_data['TKT_is_default']) {
1352
+				$ticket_values['TKT_ID']         = 0;
1353
+				$ticket_values['TKT_is_default'] = 0;
1354
+				$update_prices                   = true;
1355
+			}
1356
+			// if we have a TKT_ID then we need to get that existing TKT_obj and update it
1357
+			// we actually do our saves ahead of adding any relations because its entirely possible that this
1358
+			// ticket didn't get removed or added to any datetime in the session but DID have it's items modified.
1359
+			// keep in mind that if the ticket has been sold (and we have changed pricing information),
1360
+			// then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1361
+			if (! empty($ticket_data['TKT_ID'])) {
1362
+				$existing_ticket = EEM_Ticket::instance($event_timezone)->get_one_by_ID($ticket_data['TKT_ID']);
1363
+				if (! $existing_ticket instanceof EE_Ticket) {
1364
+					throw new RuntimeException(
1365
+						sprintf(
1366
+							esc_html__(
1367
+								'Something went wrong! A valid Ticket could not be retrieved from the database using the supplied ID: %1$d',
1368
+								'event_espresso'
1369
+							),
1370
+							$ticket_data['TKT_ID']
1371
+						)
1372
+					);
1373
+				}
1374
+				$ticket_sold = $existing_ticket->count_related(
1375
+					'Registration',
1376
+					[
1377
+							[
1378
+								'STS_ID' => [
1379
+									'NOT IN',
1380
+									[RegStatus::INCOMPLETE],
1381
+								],
1382
+							],
1383
+						]
1384
+				) > 0;
1385
+				// let's just check the total price for the existing ticket and determine if it matches the new total price.
1386
+				// if they are different then we create a new ticket (if $ticket_sold)
1387
+				// if they aren't different then we go ahead and modify existing ticket.
1388
+				$create_new_ticket = $ticket_sold
1389
+									 && EEH_Money::compare_floats($ticket_price, $existing_ticket->price(), '!=')
1390
+									 && ! $existing_ticket->deleted();
1391
+				$existing_ticket->set_date_format($date_formats[0]);
1392
+				$existing_ticket->set_time_format($date_formats[1]);
1393
+				// set new values
1394
+				foreach ($ticket_values as $field => $value) {
1395
+					if ($field == 'TKT_qty') {
1396
+						$existing_ticket->set_qty($value);
1397
+					} elseif ($field == 'TKT_price') {
1398
+						$existing_ticket->set('TKT_price', $ticket_price);
1399
+					} else {
1400
+						$existing_ticket->set($field, $value);
1401
+					}
1402
+				}
1403
+				$ticket = $existing_ticket;
1404
+				// if $create_new_ticket is false then we can safely update the existing ticket.
1405
+				//  Otherwise we have to create a new ticket.
1406
+				if ($create_new_ticket) {
1407
+					// archive the old ticket first
1408
+					$existing_ticket->set('TKT_deleted', 1);
1409
+					$existing_ticket->save();
1410
+					// make sure this ticket is still recorded in our $saved_tickets
1411
+					// so we don't run it through the regular trash routine.
1412
+					$saved_tickets[ $existing_ticket->ID() ] = $existing_ticket;
1413
+					// create new ticket that's a copy of the existing except,
1414
+					// (a new id of course and not archived) AND has the new TKT_price associated with it.
1415
+					$new_ticket = clone $existing_ticket;
1416
+					$new_ticket->set('TKT_ID', 0);
1417
+					$new_ticket->set('TKT_deleted', 0);
1418
+					$new_ticket->set('TKT_sold', 0);
1419
+					// now we need to make sure that $new prices are created as well and attached to new ticket.
1420
+					$update_prices = true;
1421
+					$ticket        = $new_ticket;
1422
+				}
1423
+			} else {
1424
+				// no TKT_id so a new ticket
1425
+				$ticket_values['TKT_price'] = $ticket_price;
1426
+				$ticket                     = EE_Ticket::new_instance($ticket_values, $event_timezone, $date_formats);
1427
+				$update_prices              = true;
1428
+			}
1429
+			if (! $ticket instanceof EE_Ticket) {
1430
+				throw new RuntimeException(
1431
+					sprintf(
1432
+						esc_html__(
1433
+							'Something went wrong! A valid Ticket could not be generated or retrieved using the supplied data: %1$s',
1434
+							'event_espresso'
1435
+						),
1436
+						print_r($ticket_values, true)
1437
+					)
1438
+				);
1439
+			}
1440
+			// cap ticket qty by datetime reg limits
1441
+			$ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
1442
+			// update ticket.
1443
+			$ticket->save();
1444
+			// before going any further make sure our dates are setup correctly
1445
+			// so that the end date is always equal or greater than the start date.
1446
+			if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
1447
+				$ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
1448
+				$ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
1449
+				$ticket->save();
1450
+			}
1451
+			// initially let's add the ticket to the datetime
1452
+			$datetime->_add_relation_to($ticket, 'Ticket');
1453
+			$saved_tickets[ $ticket->ID() ] = $ticket;
1454
+			// add prices to ticket
1455
+			$prices_data = isset($data['edit_prices'][ $row ]) && is_array($data['edit_prices'][ $row ])
1456
+				? $data['edit_prices'][ $row ]
1457
+				: [];
1458
+			$this->_add_prices_to_ticket($prices_data, $ticket, $update_prices);
1459
+		}
1460
+		// however now we need to handle permanently deleting tickets via the ui.
1461
+		// Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.
1462
+		// However, it does allow for deleting tickets that have no tickets sold,
1463
+		// in which case we want to get rid of permanently because there is no need to save in db.
1464
+		$old_tickets     = isset($old_tickets[0]) && $old_tickets[0] === '' ? [] : $old_tickets;
1465
+		$tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1466
+		foreach ($tickets_removed as $id) {
1467
+			$id = absint($id);
1468
+			// get the ticket for this id
1469
+			$ticket_to_remove = EEM_Ticket::instance()->get_one_by_ID($id);
1470
+			if (! $ticket_to_remove instanceof EE_Ticket) {
1471
+				continue;
1472
+			}
1473
+			// need to get all the related datetimes on this ticket and remove from every single one of them
1474
+			// (remember this process can ONLY kick off if there are NO tickets sold)
1475
+			$related_datetimes = $ticket_to_remove->get_many_related('Datetime');
1476
+			foreach ($related_datetimes as $related_datetime) {
1477
+				$ticket_to_remove->_remove_relation_to($related_datetime, 'Datetime');
1478
+			}
1479
+			// need to do the same for prices (except these prices can also be deleted because again,
1480
+			// tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
1481
+			$ticket_to_remove->delete_related_permanently('Price');
1482
+			// finally let's delete this ticket
1483
+			// (which should not be blocked at this point b/c we've removed all our relationships)
1484
+			$ticket_to_remove->delete_permanently();
1485
+		}
1486
+		return [$datetime, $saved_tickets];
1487
+	}
1488
+
1489
+
1490
+	/**
1491
+	 * This attaches a list of given prices to a ticket.
1492
+	 * Note we dont' have to worry about ever removing relationships (or archiving prices)
1493
+	 * because if there is a change in price information on a ticket, a new ticket is created anyways
1494
+	 * so the archived ticket will retain the old price info and prices are automatically "archived" via the ticket.
1495
+	 *
1496
+	 * @access  private
1497
+	 * @param array     $prices_data Array of prices from the form.
1498
+	 * @param EE_Ticket $ticket      EE_Ticket object that prices are being attached to.
1499
+	 * @param bool      $new_prices  Whether attach existing incoming prices or create new ones.
1500
+	 * @return  void
1501
+	 * @throws EE_Error
1502
+	 * @throws ReflectionException
1503
+	 */
1504
+	private function _add_prices_to_ticket(array $prices_data, EE_Ticket $ticket, bool $new_prices = false)
1505
+	{
1506
+		$timezone = $ticket->get_timezone();
1507
+		foreach ($prices_data as $row => $price_data) {
1508
+			$price_values = [
1509
+				'PRC_ID'         => ! empty($price_data['PRC_ID']) ? $price_data['PRC_ID'] : null,
1510
+				'PRT_ID'         => ! empty($price_data['PRT_ID']) ? $price_data['PRT_ID'] : null,
1511
+				'PRC_amount'     => ! empty($price_data['PRC_amount']) ? $price_data['PRC_amount'] : 0,
1512
+				'PRC_name'       => ! empty($price_data['PRC_name']) ? $price_data['PRC_name'] : '',
1513
+				'PRC_desc'       => ! empty($price_data['PRC_desc']) ? $price_data['PRC_desc'] : '',
1514
+				'PRC_is_default' => 0, // make sure prices are NOT set as default from this context
1515
+				'PRC_order'      => $row,
1516
+			];
1517
+			if ($new_prices || empty($price_values['PRC_ID'])) {
1518
+				$price_values['PRC_ID'] = 0;
1519
+				$price                  = EE_Price::new_instance($price_values, $timezone);
1520
+			} else {
1521
+				$price = EEM_Price::instance($timezone)->get_one_by_ID($price_data['PRC_ID']);
1522
+				// update this price with new values
1523
+				foreach ($price_values as $field => $new_price) {
1524
+					$price->set($field, $new_price);
1525
+				}
1526
+			}
1527
+			if (! $price instanceof EE_Price) {
1528
+				throw new RuntimeException(
1529
+					sprintf(
1530
+						esc_html__(
1531
+							'Something went wrong! A valid Price could not be generated or retrieved using the supplied data: %1$s',
1532
+							'event_espresso'
1533
+						),
1534
+						print_r($price_values, true)
1535
+					)
1536
+				);
1537
+			}
1538
+			$price->save();
1539
+			$ticket->_add_relation_to($price, 'Price');
1540
+		}
1541
+	}
1542
+
1543
+
1544
+	/**
1545
+	 * Add in our autosave ajax handlers
1546
+	 */
1547
+	protected function _ee_autosave_create_new()
1548
+	{
1549
+	}
1550
+
1551
+
1552
+	/**
1553
+	 * More autosave handlers.
1554
+	 */
1555
+	protected function _ee_autosave_edit()
1556
+	{
1557
+	}
1558
+
1559
+
1560
+	/**
1561
+	 * @throws EE_Error
1562
+	 * @throws ReflectionException
1563
+	 */
1564
+	private function _generate_publish_box_extra_content()
1565
+	{
1566
+		// load formatter helper
1567
+		// args for getting related registrations
1568
+		$approved_query_args        = [
1569
+			[
1570
+				'REG_deleted' => 0,
1571
+				'STS_ID'      => RegStatus::APPROVED,
1572
+			],
1573
+		];
1574
+		$not_approved_query_args    = [
1575
+			[
1576
+				'REG_deleted' => 0,
1577
+				'STS_ID'      => RegStatus::AWAITING_REVIEW,
1578
+			],
1579
+		];
1580
+		$pending_payment_query_args = [
1581
+			[
1582
+				'REG_deleted' => 0,
1583
+				'STS_ID'      => RegStatus::PENDING_PAYMENT,
1584
+			],
1585
+		];
1586
+		// publish box
1587
+		$publish_box_extra_args = [
1588
+			'view_approved_reg_url'        => add_query_arg(
1589
+				[
1590
+					'action'      => 'default',
1591
+					'event_id'    => $this->_cpt_model_obj->ID(),
1592
+					'_reg_status' => RegStatus::APPROVED,
1593
+					'use_filters' => true,
1594
+				],
1595
+				REG_ADMIN_URL
1596
+			),
1597
+			'view_not_approved_reg_url'    => add_query_arg(
1598
+				[
1599
+					'action'      => 'default',
1600
+					'event_id'    => $this->_cpt_model_obj->ID(),
1601
+					'_reg_status' => RegStatus::AWAITING_REVIEW,
1602
+					'use_filters' => true,
1603
+				],
1604
+				REG_ADMIN_URL
1605
+			),
1606
+			'view_pending_payment_reg_url' => add_query_arg(
1607
+				[
1608
+					'action'      => 'default',
1609
+					'event_id'    => $this->_cpt_model_obj->ID(),
1610
+					'_reg_status' => RegStatus::PENDING_PAYMENT,
1611
+					'use_filters' => true,
1612
+				],
1613
+				REG_ADMIN_URL
1614
+			),
1615
+			'approved_regs'                => $this->_cpt_model_obj->count_related(
1616
+				'Registration',
1617
+				$approved_query_args
1618
+			),
1619
+			'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1620
+				'Registration',
1621
+				$not_approved_query_args
1622
+			),
1623
+			'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1624
+				'Registration',
1625
+				$pending_payment_query_args
1626
+			),
1627
+			'misc_pub_section_class'       => apply_filters(
1628
+				'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1629
+				'misc-pub-section'
1630
+			),
1631
+		];
1632
+		ob_start();
1633
+		do_action(
1634
+			'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1635
+			$this->_cpt_model_obj
1636
+		);
1637
+		$publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1638
+		// load template
1639
+		EEH_Template::display_template(
1640
+			EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1641
+			$publish_box_extra_args
1642
+		);
1643
+	}
1644
+
1645
+
1646
+	/**
1647
+	 * @return EE_Event
1648
+	 */
1649
+	public function get_event_object()
1650
+	{
1651
+		return $this->_cpt_model_obj;
1652
+	}
1653
+
1654
+
1655
+
1656
+
1657
+	/** METABOXES * */
1658
+	/**
1659
+	 * _register_event_editor_meta_boxes
1660
+	 * add all metaboxes related to the event_editor
1661
+	 *
1662
+	 * @return void
1663
+	 * @throws EE_Error
1664
+	 * @throws ReflectionException
1665
+	 */
1666
+	protected function _register_event_editor_meta_boxes()
1667
+	{
1668
+		$this->verify_cpt_object();
1669
+		$use_advanced_editor = $this->admin_config->useAdvancedEditor();
1670
+		// check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
1671
+		if (! $use_advanced_editor || ! $this->feature->allowed('use_reg_options_meta_box')) {
1672
+			$this->addMetaBox(
1673
+				'espresso_event_editor_event_options',
1674
+				esc_html__('Event Registration Options', 'event_espresso'),
1675
+				[$this, 'registration_options_meta_box'],
1676
+				$this->page_slug,
1677
+				'side'
1678
+			);
1679
+		}
1680
+		if (! $use_advanced_editor) {
1681
+			$this->addMetaBox(
1682
+				'espresso_event_editor_tickets',
1683
+				esc_html__('Event Datetime & Ticket', 'event_espresso'),
1684
+				[$this, 'ticket_metabox'],
1685
+				$this->page_slug,
1686
+				'normal',
1687
+				'high'
1688
+			);
1689
+		} elseif ($this->feature->allowed('use_reg_options_meta_box')) {
1690
+			add_action(
1691
+				'add_meta_boxes_espresso_events',
1692
+				function () {
1693
+					global $current_screen;
1694
+					remove_meta_box('authordiv', $current_screen, 'normal');
1695
+				},
1696
+				99
1697
+			);
1698
+		}
1699
+		// NOTE: if you're looking for other metaboxes in here,
1700
+		// where a metabox has a related management page in the admin
1701
+		// you will find it setup in the related management page's "_Hooks" file.
1702
+		// i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1703
+	}
1704
+
1705
+
1706
+	/**
1707
+	 * @throws DomainException
1708
+	 * @throws EE_Error
1709
+	 * @throws ReflectionException
1710
+	 */
1711
+	public function ticket_metabox()
1712
+	{
1713
+		$existing_datetime_ids = $existing_ticket_ids = [];
1714
+		// defaults for template args
1715
+		$template_args = [
1716
+			'ticket_rows'       => '',
1717
+			'total_ticket_rows' => 1,
1718
+			'trash_icon'        => 'dashicons dashicons-lock',
1719
+			'disabled'          => '',
1720
+		];
1721
+		$event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1722
+		/**
1723
+		 * 1. Start with retrieving Datetimes
1724
+		 * 2. Fore each datetime get related tickets
1725
+		 * 3. For each ticket get related prices
1726
+		 */
1727
+		/** @var EEM_Datetime $datetime_model */
1728
+		$datetime_model = EE_Registry::instance()->load_model('Datetime');
1729
+		/** @var EEM_Ticket $datetime_model */
1730
+		$ticket_model = EE_Registry::instance()->load_model('Ticket');
1731
+		$times        = $datetime_model->get_all_event_dates($event_id);
1732
+		/** @type EE_Datetime $first_datetime */
1733
+		$first_datetime = reset($times);
1734
+		// do we get related tickets?
1735
+		if (
1736
+			$first_datetime instanceof EE_Datetime
1737
+			&& $first_datetime->ID() !== 0
1738
+		) {
1739
+			$existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1740
+			$template_args['time']   = $first_datetime;
1741
+			$related_tickets         = $first_datetime->tickets(
1742
+				[
1743
+					['OR' => ['TKT_deleted' => 1, 'TKT_deleted*' => 0]],
1744
+					'default_where_conditions' => 'none',
1745
+				]
1746
+			);
1747
+			if (! empty($related_tickets)) {
1748
+				$template_args['total_ticket_rows'] = count($related_tickets);
1749
+				$row                                = 0;
1750
+				foreach ($related_tickets as $ticket) {
1751
+					$existing_ticket_ids[]        = $ticket->get('TKT_ID');
1752
+					$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1753
+					$row++;
1754
+				}
1755
+			} else {
1756
+				$template_args['total_ticket_rows'] = 1;
1757
+				/** @type EE_Ticket $ticket */
1758
+				$ticket                       = $ticket_model->create_default_object();
1759
+				$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1760
+			}
1761
+		} else {
1762
+			$template_args['time'] = $times[0];
1763
+			/** @type EE_Ticket[] $tickets */
1764
+			$tickets                      = $ticket_model->get_all_default_tickets();
1765
+			$template_args['ticket_rows'] .= $this->_get_ticket_row($tickets[1]);
1766
+			// NOTE: we're just sending the first default row
1767
+			// (decaf can't manage default tickets so this should be sufficient);
1768
+		}
1769
+		$template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1770
+			'event_editor_event_datetimes_help_tab'
1771
+		);
1772
+		$template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1773
+		$template_args['existing_datetime_ids']    = implode(',', $existing_datetime_ids);
1774
+		$template_args['existing_ticket_ids']      = implode(',', $existing_ticket_ids);
1775
+		$template_args['ticket_js_structure']      = $this->_get_ticket_row(
1776
+			$ticket_model->create_default_object(),
1777
+			true
1778
+		);
1779
+		$template                                  = apply_filters(
1780
+			'FHEE__Events_Admin_Page__ticket_metabox__template',
1781
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1782
+		);
1783
+		EEH_Template::display_template($template, $template_args);
1784
+	}
1785
+
1786
+
1787
+	/**
1788
+	 * Setup an individual ticket form for the decaf event editor page
1789
+	 *
1790
+	 * @access private
1791
+	 * @param EE_Ticket $ticket   the ticket object
1792
+	 * @param boolean   $skeleton whether we're generating a skeleton for js manipulation
1793
+	 * @param int       $row
1794
+	 * @return string generated html for the ticket row.
1795
+	 * @throws EE_Error
1796
+	 * @throws ReflectionException
1797
+	 */
1798
+	private function _get_ticket_row(EE_Ticket $ticket, bool $skeleton = false, int $row = 0): string
1799
+	{
1800
+		$template_args = [
1801
+			'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1802
+			'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton
1803
+				? ' tkt-archived'
1804
+				: '',
1805
+			'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1806
+			'TKT_ID'              => $ticket->get('TKT_ID'),
1807
+			'TKT_name'            => $ticket->get('TKT_name'),
1808
+			'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1809
+			'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1810
+			'TKT_is_default'      => $ticket->get('TKT_is_default'),
1811
+			'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1812
+			'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1813
+			'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1814
+			'trash_icon'          => ($skeleton || (! $ticket->get('TKT_deleted')))
1815
+									 && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1816
+				? 'dashicons dashicons-post-trash clickable'
1817
+				: 'dashicons dashicons-lock entity-locked',
1818
+			'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1819
+				: ' disabled=disabled',
1820
+		];
1821
+
1822
+		$price         = $ticket->ID() !== 0
1823
+			? $ticket->get_first_related('Price', ['default_where_conditions' => 'none'])
1824
+			: null;
1825
+		$price         = $price instanceof EE_Price
1826
+			? $price
1827
+			: EEM_Price::instance()->create_default_object();
1828
+		$price_args    = [
1829
+			'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1830
+			'PRC_amount'            => $price->get('PRC_amount'),
1831
+			'PRT_ID'                => $price->get('PRT_ID'),
1832
+			'PRC_ID'                => $price->get('PRC_ID'),
1833
+			'PRC_is_default'        => $price->get('PRC_is_default'),
1834
+		];
1835
+		// make sure we have default start and end dates if skeleton
1836
+		// handle rows that should NOT be empty
1837
+		if (empty($template_args['TKT_start_date'])) {
1838
+			// if empty then the start date will be now.
1839
+			$template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1840
+		}
1841
+		if (empty($template_args['TKT_end_date'])) {
1842
+			// get the earliest datetime (if present);
1843
+			$earliest_datetime             = $this->_cpt_model_obj->ID() > 0
1844
+				? $this->_cpt_model_obj->get_first_related(
1845
+					'Datetime',
1846
+					['order_by' => ['DTT_EVT_start' => 'ASC']]
1847
+				)
1848
+				: null;
1849
+			$template_args['TKT_end_date'] = $earliest_datetime instanceof EE_Datetime
1850
+				? $earliest_datetime->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a')
1851
+				: date('Y-m-d h:i a', mktime(0, 0, 0, date('m'), date('d') + 7, date('Y')));
1852
+		}
1853
+		$template_args = array_merge($template_args, $price_args);
1854
+		$template      = apply_filters(
1855
+			'FHEE__Events_Admin_Page__get_ticket_row__template',
1856
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1857
+			$ticket
1858
+		);
1859
+		return EEH_Template::display_template($template, $template_args, true);
1860
+	}
1861
+
1862
+
1863
+	/**
1864
+	 * @throws EE_Error
1865
+	 * @throws ReflectionException
1866
+	 */
1867
+	public function registration_options_meta_box()
1868
+	{
1869
+		$yes_no_values             = [
1870
+			['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1871
+			['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1872
+		];
1873
+		$default_reg_status_values = EEM_Registration::reg_status_array(
1874
+			[
1875
+				RegStatus::CANCELLED,
1876
+				RegStatus::DECLINED,
1877
+				RegStatus::INCOMPLETE,
1878
+			],
1879
+			true
1880
+		);
1881
+		// $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1882
+		$template_args['_event']                          = $this->_cpt_model_obj;
1883
+		$template_args['event']                           = $this->_cpt_model_obj;
1884
+		$template_args['active_status']                   = $this->_cpt_model_obj->pretty_active_status(false);
1885
+		$template_args['additional_limit']                = $this->_cpt_model_obj->additional_limit();
1886
+		$template_args['default_registration_status']     = EEH_Form_Fields::select_input(
1887
+			'default_reg_status',
1888
+			$default_reg_status_values,
1889
+			$this->_cpt_model_obj->default_registration_status(),
1890
+			'',
1891
+			'ee-input-width--reg',
1892
+			false
1893
+		);
1894
+		$template_args['display_description']             = EEH_Form_Fields::select_input(
1895
+			'display_desc',
1896
+			$yes_no_values,
1897
+			$this->_cpt_model_obj->display_description()
1898
+		);
1899
+		$template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1900
+			'display_ticket_selector',
1901
+			$yes_no_values,
1902
+			$this->_cpt_model_obj->display_ticket_selector(),
1903
+			'',
1904
+			'ee-input-width--small',
1905
+			false
1906
+		);
1907
+		$template_args['additional_registration_options'] = apply_filters(
1908
+			'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1909
+			'',
1910
+			$template_args,
1911
+			$yes_no_values,
1912
+			$default_reg_status_values
1913
+		);
1914
+		EEH_Template::display_template(
1915
+			EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1916
+			$template_args
1917
+		);
1918
+	}
1919
+
1920
+
1921
+	/**
1922
+	 * _get_events()
1923
+	 * This method simply returns all the events (for the given _view and paging)
1924
+	 *
1925
+	 * @access public
1926
+	 * @param int  $per_page     count of items per page (20 default);
1927
+	 * @param int  $current_page what is the current page being viewed.
1928
+	 * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1929
+	 *                           If FALSE then we return an array of event objects
1930
+	 *                           that match the given _view and paging parameters.
1931
+	 * @return array|int         an array of event objects or a count of them.
1932
+	 * @throws Exception
1933
+	 */
1934
+	public function get_events(int $per_page = 10, int $current_page = 1, bool $count = false)
1935
+	{
1936
+		$EEM_Event   = $this->_event_model();
1937
+		$offset      = ($current_page - 1) * $per_page;
1938
+		$limit       = $count ? null : $offset . ',' . $per_page;
1939
+		$orderby     = $this->request->getRequestParam('orderby', 'EVT_ID');
1940
+		$order       = $this->request->getRequestParam('order', 'DESC');
1941
+		$month_range = $this->request->getRequestParam('month_range');
1942
+		$where  = [];
1943
+		$status = $this->request->getRequestParam('status');
1944
+		$timezone_string = EEH_DTT_Helper::get_valid_timezone_string();
1945
+		// determine what post_status our condition will have for the query.
1946
+		switch ($status) {
1947
+			case 'month':
1948
+			case 'today':
1949
+			case null:
1950
+			case 'all':
1951
+				break;
1952
+			case 'draft':
1953
+				$where['status'] = ['IN', ['draft', 'auto-draft']];
1954
+				break;
1955
+			default:
1956
+				$where['status'] = $status;
1957
+		}
1958
+		// categories? The default for all categories is -1
1959
+		$category = $this->request->getRequestParam('EVT_CAT', -1, DataType::INT);
1960
+		if ($category !== -1) {
1961
+			$where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1962
+			$where['Term_Taxonomy.term_id']  = $category;
1963
+		}
1964
+		// date where conditions
1965
+		$start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1966
+		if ($month_range) {
1967
+			$where['Datetime.DTT_EVT_start'] = $this->whereParamsForDatetimeMonthRange($month_range, $timezone_string);
1968
+		} elseif ($status === 'today') {
1969
+			$DateTime                        = new DateTime(
1970
+				'now',
1971
+				new DateTimeZone($timezone_string)
1972
+			);
1973
+			$start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1974
+			$end                             = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1975
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1976
+		} elseif ($status === 'month') {
1977
+			$now                             = date('Y-m-01');
1978
+			$DateTime                        = new DateTime(
1979
+				$now,
1980
+				new DateTimeZone($timezone_string)
1981
+			);
1982
+			$start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1983
+			$end                             = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1984
+														->setTime(23, 59, 59)
1985
+														->format(implode(' ', $start_formats));
1986
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1987
+		}
1988
+		if (! $this->capabilities->current_user_can('ee_read_others_events', 'get_events')) {
1989
+			$where['EVT_wp_user'] = get_current_user_id();
1990
+		} else {
1991
+			if (! isset($where['status'])) {
1992
+				if (! $this->capabilities->current_user_can('ee_read_private_events', 'get_events')) {
1993
+					$where['OR'] = [
1994
+						'status*restrict_private' => ['!=', 'private'],
1995
+						'AND'                     => [
1996
+							'status*inclusive' => ['=', 'private'],
1997
+							'EVT_wp_user'      => get_current_user_id(),
1998
+						],
1999
+					];
2000
+				}
2001
+			}
2002
+		}
2003
+		$wp_user = $this->request->getRequestParam('EVT_wp_user', 0, DataType::INT);
2004
+		if (
2005
+			$wp_user
2006
+			&& $wp_user !== get_current_user_id()
2007
+			&& $this->capabilities->current_user_can('ee_read_others_events', 'get_events')
2008
+		) {
2009
+			$where['EVT_wp_user'] = $wp_user;
2010
+		}
2011
+		// search query handling
2012
+		$search_term = $this->request->getRequestParam('s');
2013
+		if ($search_term) {
2014
+			$search_term = '%' . $search_term . '%';
2015
+			$where['OR'] = [
2016
+				'EVT_name'       => ['LIKE', $search_term],
2017
+				'EVT_desc'       => ['LIKE', $search_term],
2018
+				'EVT_short_desc' => ['LIKE', $search_term],
2019
+			];
2020
+		}
2021
+		// filter events by venue.
2022
+		$venue = $this->request->getRequestParam('venue', 0, DataType::INT);
2023
+		if ($venue) {
2024
+			$where['Venue.VNU_ID'] = $venue;
2025
+		}
2026
+		$request_params = $this->request->requestParams();
2027
+		$where          = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $request_params);
2028
+		$query_params   = apply_filters(
2029
+			'FHEE__Events_Admin_Page__get_events__query_params',
2030
+			[
2031
+				$where,
2032
+				'limit'    => $limit,
2033
+				'order_by' => $orderby,
2034
+				'order'    => $order,
2035
+				'group_by' => 'EVT_ID',
2036
+			],
2037
+			$request_params
2038
+		);
2039
+
2040
+		// let's first check if we have special requests coming in.
2041
+		$active_status = $this->request->getRequestParam('active_status');
2042
+		if ($active_status) {
2043
+			switch ($active_status) {
2044
+				case 'upcoming':
2045
+					return $EEM_Event->get_upcoming_events($query_params, $count);
2046
+				case 'expired':
2047
+					return $EEM_Event->get_expired_events($query_params, $count);
2048
+				case 'active':
2049
+					return $EEM_Event->get_active_events($query_params, $count);
2050
+				case 'inactive':
2051
+					return $EEM_Event->get_inactive_events($query_params, $count);
2052
+			}
2053
+		}
2054
+
2055
+		return $count ? $EEM_Event->count([$where], 'EVT_ID', true) : $EEM_Event->get_all($query_params);
2056
+	}
2057
+
2058
+
2059
+	/**
2060
+	 * @param string $month_range
2061
+	 * @param string $timezone_string
2062
+	 * @return array
2063
+	 * @throws Exception
2064
+	 * @since 5.0.21.p
2065
+	 */
2066
+	public function whereParamsForDatetimeMonthRange(string $month_range, string $timezone_string = ''): array
2067
+	{
2068
+		$timezone_string = $timezone_string ?: EEH_DTT_Helper::get_valid_timezone_string();
2069
+		$pieces = explode(' ', $month_range, 3);
2070
+		// simulate the FIRST day of the month, that fixes issues for months like February
2071
+		// where PHP doesn't know what to assume for date.
2072
+		// @see https://events.codebasehq.com/projects/event-espresso/tickets/10437
2073
+		$month_r = ! empty($pieces[0]) ? date('m', EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
2074
+		$year_r  = ! empty($pieces[1]) ? $pieces[1] : '';
2075
+		$DateTime = new DateTime(
2076
+			"$year_r-$month_r-01 00:00:00",
2077
+			new DateTimeZone($timezone_string)
2078
+		);
2079
+		$start    = $DateTime->getTimestamp();
2080
+		// set the datetime to be the end of the month
2081
+		$DateTime->setDate(
2082
+			$year_r,
2083
+			$month_r,
2084
+			$DateTime->format('t')
2085
+		)->setTime(23, 59, 59);
2086
+		$end                             = $DateTime->getTimestamp();
2087
+		return ['BETWEEN', [$start, $end]];
2088
+	}
2089
+
2090
+
2091
+	/**
2092
+	 * handling for WordPress CPT actions (trash, restore, delete)
2093
+	 *
2094
+	 * @param string $post_id
2095
+	 * @throws EE_Error
2096
+	 * @throws ReflectionException
2097
+	 */
2098
+	public function trash_cpt_item($post_id)
2099
+	{
2100
+		$this->request->setRequestParam('EVT_ID', $post_id);
2101
+		$this->_trash_or_restore_event('trash', false);
2102
+	}
2103
+
2104
+
2105
+	/**
2106
+	 * @param string $post_id
2107
+	 * @throws EE_Error
2108
+	 * @throws ReflectionException
2109
+	 */
2110
+	public function restore_cpt_item($post_id)
2111
+	{
2112
+		$this->request->setRequestParam('EVT_ID', $post_id);
2113
+		$this->_trash_or_restore_event('draft', false);
2114
+	}
2115
+
2116
+
2117
+	/**
2118
+	 * @param string $post_id
2119
+	 * @throws EE_Error
2120
+	 * @throws EE_Error
2121
+	 */
2122
+	public function delete_cpt_item($post_id)
2123
+	{
2124
+		throw new EE_Error(
2125
+			esc_html__(
2126
+				'Please contact Event Espresso support with the details of the steps taken to produce this error.',
2127
+				'event_espresso'
2128
+			)
2129
+		);
2130
+		// $this->request->setRequestParam('EVT_ID', $post_id);
2131
+		// $this->_delete_event();
2132
+	}
2133
+
2134
+
2135
+	/**
2136
+	 * _trash_or_restore_event
2137
+	 *
2138
+	 * @access protected
2139
+	 * @param string $event_status
2140
+	 * @param bool   $redirect_after
2141
+	 * @throws EE_Error
2142
+	 * @throws EE_Error
2143
+	 * @throws ReflectionException
2144
+	 */
2145
+	protected function _trash_or_restore_event(string $event_status = 'trash', bool $redirect_after = true)
2146
+	{
2147
+		// loop thru events
2148
+		if ($this->EVT_ID) {
2149
+			// clean status
2150
+			$event_status = sanitize_key($event_status);
2151
+			// grab status
2152
+			if (! empty($event_status)) {
2153
+				$success = $this->_change_event_status($this->EVT_ID, $event_status);
2154
+			} else {
2155
+				$success = false;
2156
+				$msg     = esc_html__(
2157
+					'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2158
+					'event_espresso'
2159
+				);
2160
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2161
+			}
2162
+		} else {
2163
+			$success = false;
2164
+			$msg     = esc_html__(
2165
+				'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
2166
+				'event_espresso'
2167
+			);
2168
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2169
+		}
2170
+		$action = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2171
+		if ($redirect_after) {
2172
+			$this->_redirect_after_action($success, 'Event', $action, ['action' => 'default']);
2173
+		}
2174
+	}
2175
+
2176
+
2177
+	/**
2178
+	 * _trash_or_restore_events
2179
+	 *
2180
+	 * @access protected
2181
+	 * @param string $event_status
2182
+	 * @return void
2183
+	 * @throws EE_Error
2184
+	 * @throws EE_Error
2185
+	 * @throws ReflectionException
2186
+	 */
2187
+	protected function _trash_or_restore_events(string $event_status = 'trash')
2188
+	{
2189
+		// clean status
2190
+		$event_status = sanitize_key($event_status);
2191
+		// grab status
2192
+		if (! empty($event_status)) {
2193
+			$success = true;
2194
+			// determine the event id and set to array.
2195
+			$EVT_IDs = $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2196
+			// loop thru events
2197
+			foreach ($EVT_IDs as $EVT_ID) {
2198
+				if ($EVT_ID = absint($EVT_ID)) {
2199
+					$results = $this->_change_event_status($EVT_ID, $event_status);
2200
+					$success = $results !== false ? $success : false;
2201
+				} else {
2202
+					$msg = sprintf(
2203
+						esc_html__(
2204
+							'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
2205
+							'event_espresso'
2206
+						),
2207
+						$EVT_ID
2208
+					);
2209
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2210
+					$success = false;
2211
+				}
2212
+			}
2213
+		} else {
2214
+			$success = false;
2215
+			$msg     = esc_html__(
2216
+				'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2217
+				'event_espresso'
2218
+			);
2219
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2220
+		}
2221
+		// in order to force a pluralized result message we need to send back a success status greater than 1
2222
+		$success = $success ? 2 : false;
2223
+		$action  = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2224
+		$this->_redirect_after_action($success, 'Events', $action, ['action' => 'default']);
2225
+	}
2226
+
2227
+
2228
+	/**
2229
+	 * @param int    $EVT_ID
2230
+	 * @param string $event_status
2231
+	 * @return bool
2232
+	 * @throws EE_Error
2233
+	 * @throws ReflectionException
2234
+	 */
2235
+	private function _change_event_status(int $EVT_ID = 0, string $event_status = ''): bool
2236
+	{
2237
+		// grab event id
2238
+		if (! $EVT_ID) {
2239
+			$msg = esc_html__(
2240
+				'An error occurred. No Event ID or an invalid Event ID was received.',
2241
+				'event_espresso'
2242
+			);
2243
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2244
+			return false;
2245
+		}
2246
+		$this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2247
+		// clean status
2248
+		$event_status = sanitize_key($event_status);
2249
+		// grab status
2250
+		if (empty($event_status)) {
2251
+			$msg = esc_html__(
2252
+				'An error occurred. No Event Status or an invalid Event Status was received.',
2253
+				'event_espresso'
2254
+			);
2255
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2256
+			return false;
2257
+		}
2258
+		// was event trashed or restored ?
2259
+		switch ($event_status) {
2260
+			case 'draft':
2261
+				$action = 'restored from the trash';
2262
+				$hook   = 'AHEE_event_restored_from_trash';
2263
+				break;
2264
+			case 'trash':
2265
+				$action = 'moved to the trash';
2266
+				$hook   = 'AHEE_event_moved_to_trash';
2267
+				break;
2268
+			default:
2269
+				$action = 'updated';
2270
+				$hook   = false;
2271
+		}
2272
+		// use class to change status
2273
+		$this->_cpt_model_obj->set_status($event_status);
2274
+		$success = $this->_cpt_model_obj->save();
2275
+		if (! $success) {
2276
+			$msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2277
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2278
+			return false;
2279
+		}
2280
+		if ($hook) {
2281
+			do_action($hook);
2282
+			// fake the action hook in EE_Soft_Delete_Base_Class::delete_or_restore()
2283
+			// because events side step that and it otherwise won't get called
2284
+			do_action(
2285
+				'AHEE__EE_Soft_Delete_Base_Class__delete_or_restore__after',
2286
+				$this->_cpt_model_obj,
2287
+				$hook === 'AHEE_event_moved_to_trash',
2288
+				$success
2289
+			);
2290
+		}
2291
+		return true;
2292
+	}
2293
+
2294
+
2295
+	/**
2296
+	 * @param array $event_ids
2297
+	 * @return array
2298
+	 * @since   4.10.23.p
2299
+	 */
2300
+	private function cleanEventIds(array $event_ids): array
2301
+	{
2302
+		return array_map('absint', $event_ids);
2303
+	}
2304
+
2305
+
2306
+	/**
2307
+	 * @return array
2308
+	 * @since   4.10.23.p
2309
+	 */
2310
+	private function getEventIdsFromRequest(): array
2311
+	{
2312
+		if ($this->request->requestParamIsSet('EVT_IDs')) {
2313
+			return $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2314
+		} else {
2315
+			return $this->request->getRequestParam('EVT_ID', [], 'int', true);
2316
+		}
2317
+	}
2318
+
2319
+
2320
+	/**
2321
+	 * @param bool $preview_delete
2322
+	 * @throws EE_Error
2323
+	 * @throws ReflectionException
2324
+	 */
2325
+	protected function _delete_event(bool $preview_delete = true)
2326
+	{
2327
+		$this->_delete_events($preview_delete);
2328
+	}
2329
+
2330
+
2331
+	/**
2332
+	 * Gets the tree traversal batch persister.
2333
+	 *
2334
+	 * @return NodeGroupDao
2335
+	 * @throws InvalidArgumentException
2336
+	 * @throws InvalidDataTypeException
2337
+	 * @throws InvalidInterfaceException
2338
+	 * @since 4.10.12.p
2339
+	 */
2340
+	protected function getModelObjNodeGroupPersister(): NodeGroupDao
2341
+	{
2342
+		if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2343
+			$this->model_obj_node_group_persister =
2344
+				$this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2345
+		}
2346
+		return $this->model_obj_node_group_persister;
2347
+	}
2348
+
2349
+
2350
+	/**
2351
+	 * @param bool $preview_delete
2352
+	 * @return void
2353
+	 * @throws EE_Error
2354
+	 * @throws ReflectionException
2355
+	 */
2356
+	protected function _delete_events(bool $preview_delete = true)
2357
+	{
2358
+		$event_ids = $this->getEventIdsFromRequest();
2359
+		if ($preview_delete) {
2360
+			$this->generateDeletionPreview($event_ids);
2361
+		} else {
2362
+			foreach ($event_ids as $event_id) {
2363
+				$event = EEM_Event::instance()->get_one_by_ID($event_id);
2364
+				if ($event instanceof EE_Event) {
2365
+					$event->delete_permanently();
2366
+				}
2367
+			}
2368
+		}
2369
+	}
2370
+
2371
+
2372
+	/**
2373
+	 * @param array $event_ids
2374
+	 */
2375
+	protected function generateDeletionPreview(array $event_ids)
2376
+	{
2377
+		$event_ids = $this->cleanEventIds($event_ids);
2378
+		// Set a code we can use to reference this deletion task in the batch jobs and preview page.
2379
+		$deletion_job_code = $this->getModelObjNodeGroupPersister()->generateGroupCode();
2380
+		$return_url        = EE_Admin_Page::add_query_args_and_nonce(
2381
+			[
2382
+				'action'            => 'preview_deletion',
2383
+				'deletion_job_code' => $deletion_job_code,
2384
+			],
2385
+			$this->_admin_base_url
2386
+		);
2387
+		EEH_URL::safeRedirectAndExit(
2388
+			EE_Admin_Page::add_query_args_and_nonce(
2389
+				[
2390
+					'page'              => EED_Batch::PAGE_SLUG,
2391
+					'batch'             => EED_Batch::batch_job,
2392
+					'EVT_IDs'           => $event_ids,
2393
+					'deletion_job_code' => $deletion_job_code,
2394
+					'job_handler'       => urlencode('EventEspresso\core\libraries\batch\JobHandlers\PreviewEventDeletion'),
2395
+					'return_url'        => urlencode($return_url),
2396
+				],
2397
+				admin_url()
2398
+			)
2399
+		);
2400
+	}
2401
+
2402
+
2403
+	/**
2404
+	 * Checks for a POST submission
2405
+	 *
2406
+	 * @since 4.10.12.p
2407
+	 */
2408
+	protected function confirmDeletion()
2409
+	{
2410
+		$deletion_redirect_logic = $this->getLoader()->getShared(
2411
+			'EventEspresso\core\domain\services\admin\events\data\ConfirmDeletion'
2412
+		);
2413
+		$deletion_redirect_logic->handle($this->get_request_data(), $this->admin_base_url());
2414
+	}
2415
+
2416
+
2417
+	/**
2418
+	 * A page for users to preview what exactly will be deleted, and confirm they want to delete it.
2419
+	 *
2420
+	 * @throws EE_Error
2421
+	 * @since 4.10.12.p
2422
+	 */
2423
+	protected function previewDeletion()
2424
+	{
2425
+		$preview_deletion_logic = $this->getLoader()->getShared(
2426
+			'EventEspresso\core\domain\services\admin\events\data\PreviewDeletion'
2427
+		);
2428
+		$this->set_template_args($preview_deletion_logic->handle($this->get_request_data(), $this->admin_base_url()));
2429
+		$this->display_admin_page_with_no_sidebar();
2430
+	}
2431
+
2432
+
2433
+	/**
2434
+	 * get total number of events
2435
+	 *
2436
+	 * @access public
2437
+	 * @return int
2438
+	 * @throws EE_Error
2439
+	 * @throws EE_Error
2440
+	 * @throws ReflectionException
2441
+	 */
2442
+	public function total_events(): int
2443
+	{
2444
+		return EEM_Event::instance()->count(
2445
+			['caps' => 'read_admin'],
2446
+			'EVT_ID',
2447
+			true
2448
+		);
2449
+	}
2450
+
2451
+
2452
+	/**
2453
+	 * get total number of draft events
2454
+	 *
2455
+	 * @access public
2456
+	 * @return int
2457
+	 * @throws EE_Error
2458
+	 * @throws EE_Error
2459
+	 * @throws ReflectionException
2460
+	 */
2461
+	public function total_events_draft(): int
2462
+	{
2463
+		return EEM_Event::instance()->count(
2464
+			[
2465
+				['status' => ['IN', ['draft', 'auto-draft']]],
2466
+				'caps' => 'read_admin',
2467
+			],
2468
+			'EVT_ID',
2469
+			true
2470
+		);
2471
+	}
2472
+
2473
+
2474
+	/**
2475
+	 * get total number of trashed events
2476
+	 *
2477
+	 * @access public
2478
+	 * @return int
2479
+	 * @throws EE_Error
2480
+	 * @throws EE_Error
2481
+	 * @throws ReflectionException
2482
+	 */
2483
+	public function total_trashed_events(): int
2484
+	{
2485
+		return EEM_Event::instance()->count(
2486
+			[
2487
+				['status' => 'trash'],
2488
+				'caps' => 'read_admin',
2489
+			],
2490
+			'EVT_ID',
2491
+			true
2492
+		);
2493
+	}
2494
+
2495
+
2496
+	/**
2497
+	 *    _default_event_settings
2498
+	 *    This generates the Default Settings Tab
2499
+	 *
2500
+	 * @return void
2501
+	 * @throws DomainException
2502
+	 * @throws EE_Error
2503
+	 * @throws InvalidArgumentException
2504
+	 * @throws InvalidDataTypeException
2505
+	 * @throws InvalidInterfaceException
2506
+	 * @throws ReflectionException
2507
+	 */
2508
+	protected function _default_event_settings()
2509
+	{
2510
+		$this->_set_add_edit_form_tags('update_default_event_settings');
2511
+		$this->_set_publish_post_box_vars();
2512
+		$this->_template_args['admin_page_content'] = EEH_HTML::div(
2513
+			$this->_default_event_settings_form()->get_html(),
2514
+			'',
2515
+			'padding'
2516
+		);
2517
+		$this->display_admin_page_with_sidebar();
2518
+	}
2519
+
2520
+
2521
+	/**
2522
+	 * Return the form for event settings.
2523
+	 *
2524
+	 * @return EE_Form_Section_Proper
2525
+	 * @throws EE_Error
2526
+	 * @throws ReflectionException
2527
+	 */
2528
+	protected function _default_event_settings_form(): EE_Form_Section_Proper
2529
+	{
2530
+		$registration_config              = EE_Registry::instance()->CFG->registration;
2531
+		$registration_stati_for_selection = EEM_Registration::reg_status_array(
2532
+		// exclude
2533
+			[
2534
+				RegStatus::CANCELLED,
2535
+				RegStatus::DECLINED,
2536
+				RegStatus::INCOMPLETE,
2537
+				RegStatus::WAIT_LIST,
2538
+			],
2539
+			true
2540
+		);
2541
+		// setup Advanced Editor ???
2542
+		if (
2543
+			$this->raw_req_action === 'default_event_settings'
2544
+			|| $this->raw_req_action === 'update_default_event_settings'
2545
+		) {
2546
+			$this->advanced_editor_admin_form = $this->loader->getShared(AdvancedEditorAdminFormSection::class);
2547
+		}
2548
+		return new EE_Form_Section_Proper(
2549
+			[
2550
+				'name'            => 'update_default_event_settings',
2551
+				'html_id'         => 'update_default_event_settings',
2552
+				'html_class'      => 'form-table',
2553
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2554
+				'subsections'     => apply_filters(
2555
+					'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2556
+					[
2557
+						'defaults_section_header' => new EE_Form_Section_HTML(
2558
+							EEH_HTML::h2(
2559
+								esc_html__('Default Settings', 'event_espresso'),
2560
+								'',
2561
+								'ee-admin-settings-hdr'
2562
+							)
2563
+						),
2564
+						'default_reg_status'      => new EE_Select_Input(
2565
+							$registration_stati_for_selection,
2566
+							[
2567
+								'default'         => isset($registration_config->default_STS_ID)
2568
+													 && array_key_exists(
2569
+														 $registration_config->default_STS_ID,
2570
+														 $registration_stati_for_selection
2571
+													 )
2572
+									? sanitize_text_field($registration_config->default_STS_ID)
2573
+									: RegStatus::PENDING_PAYMENT,
2574
+								'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2575
+													 . EEH_Template::get_help_tab_link(
2576
+														 'default_settings_status_help_tab'
2577
+													 ),
2578
+								'html_help_text'  => esc_html__(
2579
+									'This setting allows you to preselect what the default registration status setting is when creating an event.  Note that changing this setting does NOT retroactively apply it to existing events.',
2580
+									'event_espresso'
2581
+								),
2582
+								'html_class'      => 'ee-input-width--small',
2583
+							]
2584
+						),
2585
+						'default_max_tickets'     => new EE_Integer_Input(
2586
+							[
2587
+								'default'         => $registration_config->default_maximum_number_of_tickets
2588
+													 ?? EEM_Event::get_default_additional_limit(),
2589
+								'html_label_text' => esc_html__(
2590
+									'Default Maximum Tickets Allowed Per Order:',
2591
+									'event_espresso'
2592
+								)
2593
+													 . EEH_Template::get_help_tab_link(
2594
+														 'default_maximum_tickets_help_tab"'
2595
+													 ),
2596
+								'html_help_text'  => esc_html__(
2597
+									'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2598
+									'event_espresso'
2599
+								),
2600
+								'html_class'      => 'ee-input-width--tiny',
2601
+							]
2602
+						),
2603
+					]
2604
+				),
2605
+			]
2606
+		);
2607
+	}
2608
+
2609
+
2610
+	/**
2611
+	 * @return void
2612
+	 * @throws EE_Error
2613
+	 * @throws InvalidArgumentException
2614
+	 * @throws InvalidDataTypeException
2615
+	 * @throws InvalidInterfaceException
2616
+	 * @throws ReflectionException
2617
+	 */
2618
+	protected function _update_default_event_settings()
2619
+	{
2620
+		$form = $this->_default_event_settings_form();
2621
+		if ($form->was_submitted()) {
2622
+			$form->receive_form_submission();
2623
+			if ($form->is_valid()) {
2624
+				$registration_config = EE_Registry::instance()->CFG->registration;
2625
+				$valid_data          = $form->valid_data();
2626
+				if (isset($valid_data['default_reg_status'])) {
2627
+					$registration_config->default_STS_ID = $valid_data['default_reg_status'];
2628
+				}
2629
+				if (isset($valid_data['default_max_tickets'])) {
2630
+					$registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2631
+				}
2632
+				do_action(
2633
+					'AHEE__Events_Admin_Page___update_default_event_settings',
2634
+					$valid_data,
2635
+					EE_Registry::instance()->CFG,
2636
+					$this
2637
+				);
2638
+				// update because data was valid!
2639
+				EE_Registry::instance()->CFG->update_espresso_config();
2640
+				EE_Error::overwrite_success();
2641
+				EE_Error::add_success(
2642
+					esc_html__('Default Event Settings were updated', 'event_espresso')
2643
+				);
2644
+			}
2645
+		}
2646
+		$this->_redirect_after_action(0, '', '', ['action' => 'default_event_settings'], true);
2647
+	}
2648
+
2649
+
2650
+	/*************        Templates        *************
794 2651
      *
795
-     * @return void
796
-     * @throws EE_Error
797
-     * @throws InvalidArgumentException
798
-     * @throws InvalidDataTypeException
799
-     * @throws InvalidInterfaceException
800
-     * @throws ReflectionException
801
-     */
802
-    protected function _create_new_cpt_item()
803
-    {
804
-        $has_timezone_string = get_option('timezone_string');
805
-        // only nag them about setting their timezone if it's their first event, and they haven't already done it
806
-        if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
807
-            EE_Error::add_attention(
808
-                sprintf(
809
-                    esc_html__(
810
-                        'Your website\'s timezone is currently set to a UTC offset. We recommend updating your timezone to a city or region near you before you create an event. Change your timezone now:%1$s%2$s%3$sChange Timezone%4$s',
811
-                        'event_espresso'
812
-                    ),
813
-                    '<br>',
814
-                    '<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">'
815
-                    . EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale())
816
-                    . '</select>',
817
-                    '<button class="button button--secondary timezone-submit">',
818
-                    '</button><span class="spinner"></span>'
819
-                ),
820
-                __FILE__,
821
-                __FUNCTION__,
822
-                __LINE__
823
-            );
824
-        }
825
-        parent::_create_new_cpt_item();
826
-    }
827
-
828
-
829
-    /**
830
-     * Sets the _views property for the default route in this admin page group.
831
-     */
832
-    protected function _set_list_table_views_default()
833
-    {
834
-        $this->_views = [
835
-            'all'   => [
836
-                'slug'        => 'all',
837
-                'label'       => esc_html__('View All Events', 'event_espresso'),
838
-                'count'       => 0,
839
-                'bulk_action' => [
840
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
841
-                ],
842
-            ],
843
-            'draft' => [
844
-                'slug'        => 'draft',
845
-                'label'       => esc_html__('Draft', 'event_espresso'),
846
-                'count'       => 0,
847
-                'bulk_action' => [
848
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
849
-                ],
850
-            ],
851
-        ];
852
-        if ($this->capabilities->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
853
-            $this->_views['trash'] = [
854
-                'slug'        => 'trash',
855
-                'label'       => esc_html__('Trash', 'event_espresso'),
856
-                'count'       => 0,
857
-                'bulk_action' => [
858
-                    'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
859
-                    'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
860
-                ],
861
-            ];
862
-        }
863
-    }
864
-
865
-
866
-    /**
867
-     * Provides the legend item array for the default list table view.
868
-     *
869
-     * @return array
870
-     * @throws EE_Error
871
-     * @throws EE_Error
872
-     */
873
-    protected function _event_legend_items(): array
874
-    {
875
-        $items    = [
876
-            'view_details'   => [
877
-                'class' => 'dashicons dashicons-visibility',
878
-                'desc'  => esc_html__('View Event', 'event_espresso'),
879
-            ],
880
-            'edit_event'     => [
881
-                'class' => 'dashicons dashicons-calendar-alt',
882
-                'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
883
-            ],
884
-            'view_attendees' => [
885
-                'class' => 'dashicons dashicons-groups',
886
-                'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
887
-            ],
888
-        ];
889
-        $items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
890
-        $statuses = [
891
-            'sold_out_status'  => [
892
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::sold_out,
893
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
894
-            ],
895
-            'active_status'    => [
896
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::active,
897
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
898
-            ],
899
-            'upcoming_status'  => [
900
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::upcoming,
901
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
902
-            ],
903
-            'postponed_status' => [
904
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::postponed,
905
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
906
-            ],
907
-            'cancelled_status' => [
908
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::cancelled,
909
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
910
-            ],
911
-            'expired_status'   => [
912
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::expired,
913
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
914
-            ],
915
-            'inactive_status'  => [
916
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::inactive,
917
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
918
-            ],
919
-        ];
920
-        $statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
921
-        return array_merge($items, $statuses);
922
-    }
923
-
924
-
925
-    /**
926
-     * @return EEM_Event
927
-     * @throws EE_Error
928
-     * @throws InvalidArgumentException
929
-     * @throws InvalidDataTypeException
930
-     * @throws InvalidInterfaceException
931
-     * @throws ReflectionException
932
-     */
933
-    private function _event_model(): EEM_Event
934
-    {
935
-        if (! $this->_event_model instanceof EEM_Event) {
936
-            $this->_event_model = EE_Registry::instance()->load_model('Event');
937
-        }
938
-        return $this->_event_model;
939
-    }
940
-
941
-
942
-    /**
943
-     * Adds extra buttons to the WP CPT permalink field row.
944
-     * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
945
-     *
946
-     * @param string      $return    the current html
947
-     * @param int         $id        the post id for the page
948
-     * @param string|null $new_title What the title is
949
-     * @param string|null $new_slug  what the slug is
950
-     * @return string            The new html string for the permalink area
951
-     * @deprecated 5.0.0.p
952
-     * @see        TicketSelectorShortcodeButton::addButton
953
-     */
954
-    public function extra_permalink_field_buttons(
955
-        string $return,
956
-        int $id,
957
-        ?string $new_title,
958
-        ?string $new_slug
959
-    ): string {
960
-        return TicketSelectorShortcodeButton::addButton($return, $id, $new_title, $new_slug);
961
-    }
962
-
963
-
964
-    /**
965
-     * _events_overview_list_table
966
-     * This contains the logic for showing the events_overview list
967
-     *
968
-     * @access protected
969
-     * @return void
970
-     * @throws DomainException
971
-     * @throws EE_Error
972
-     * @throws InvalidArgumentException
973
-     * @throws InvalidDataTypeException
974
-     * @throws InvalidInterfaceException
975
-     */
976
-    protected function _events_overview_list_table()
977
-    {
978
-        $after_list_table = [];
979
-        $links_html       = EEH_HTML::div('', '', 'ee-admin-section ee-layout-stack');
980
-        $links_html       .= EEH_HTML::h3(esc_html__('Links', 'event_espresso'));
981
-        $links_html       .= EEH_HTML::div(
982
-            EEH_Template::get_button_or_link(
983
-                get_post_type_archive_link(EspressoPostType::EVENTS),
984
-                esc_html__('View Event Archive Page', 'event_espresso'),
985
-                'button button--small button--secondary'
986
-            ),
987
-            '',
988
-            'ee-admin-button-row ee-admin-button-row--align-start'
989
-        );
990
-        $links_html       .= EEH_HTML::divx();
991
-
992
-        $after_list_table['view_event_list_button'] = $links_html;
993
-
994
-        $after_list_table['legend'] = $this->_display_legend($this->_event_legend_items());
995
-        $this->_admin_page_title    .= ' ' . $this->get_action_link_or_button(
996
-            'create_new',
997
-            'add',
998
-            [],
999
-            'add-new-h2'
1000
-        );
1001
-
1002
-        $this->_template_args['after_list_table'] = array_merge(
1003
-            (array) $this->_template_args['after_list_table'],
1004
-            $after_list_table
1005
-        );
1006
-        $this->display_admin_list_table_page_with_no_sidebar();
1007
-    }
1008
-
1009
-
1010
-    /**
1011
-     * this allows for extra misc actions in the default WP publish box
1012
-     *
1013
-     * @return void
1014
-     * @throws DomainException
1015
-     * @throws EE_Error
1016
-     * @throws InvalidArgumentException
1017
-     * @throws InvalidDataTypeException
1018
-     * @throws InvalidInterfaceException
1019
-     * @throws ReflectionException
1020
-     */
1021
-    public function extra_misc_actions_publish_box()
1022
-    {
1023
-        $this->_generate_publish_box_extra_content();
1024
-    }
1025
-
1026
-
1027
-    /**
1028
-     * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
1029
-     * saved.
1030
-     * Typically you would use this to save any additional data.
1031
-     * Keep in mind also that "save_post" runs on EVERY post update to the database.
1032
-     * ALSO very important.  When a post transitions from scheduled to published,
1033
-     * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from
1034
-     * other meta saves. So MAKE sure that you handle this accordingly.
1035
-     *
1036
-     * @access protected
1037
-     * @abstract
1038
-     * @param string  $post_id The ID of the cpt that was saved (so you can link relationally)
1039
-     * @param WP_Post $post    The post object of the cpt that was saved.
1040
-     * @return void
1041
-     * @throws EE_Error
1042
-     * @throws InvalidArgumentException
1043
-     * @throws InvalidDataTypeException
1044
-     * @throws InvalidInterfaceException
1045
-     * @throws ReflectionException
1046
-     */
1047
-    protected function _insert_update_cpt_item($post_id, $post)
1048
-    {
1049
-        if ($post instanceof WP_Post && $post->post_type !== EspressoPostType::EVENTS) {
1050
-            // get out we're not processing an event save.
1051
-            return;
1052
-        }
1053
-        $event_values = [
1054
-            'EVT_member_only'     => $this->request->getRequestParam('member_only', false, DataType::BOOL),
1055
-            'EVT_allow_overflow'  => $this->request->getRequestParam('EVT_allow_overflow', false, DataType::BOOL),
1056
-            'EVT_timezone_string' => $this->request->getRequestParam('timezone_string'),
1057
-        ];
1058
-        // check if the new EDTR reg options meta box is being used, and if so, don't run updates for legacy version
1059
-        if (! $this->admin_config->useAdvancedEditor() || ! $this->feature->allowed('use_reg_options_meta_box')) {
1060
-            $event_values['EVT_display_ticket_selector']     = $this->request->getRequestParam(
1061
-                'display_ticket_selector',
1062
-                false,
1063
-                'bool'
1064
-            );
1065
-            $event_values['EVT_additional_limit']            = min(
1066
-                apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1067
-                $this->request->getRequestParam(
1068
-                    'additional_limit',
1069
-                    EEM_Event::get_default_additional_limit(),
1070
-                    'int'
1071
-                )
1072
-            );
1073
-            $event_values['EVT_default_registration_status'] = $this->request->getRequestParam(
1074
-                'EVT_default_registration_status',
1075
-                EE_Registry::instance()->CFG->registration->default_STS_ID
1076
-            );
1077
-
1078
-            $event_values['EVT_external_URL'] = $this->request->getRequestParam('externalURL');
1079
-            $event_values['EVT_phone']        = $this->request->getRequestParam('event_phone');
1080
-            $event_values['EVT_display_desc'] = $this->request->getRequestParam('display_desc', false, DataType::BOOL);
1081
-        } elseif ($post instanceof WP_Post) {
1082
-            $event_values['EVT_name'] = $post->post_title;
1083
-            $event_values['EVT_desc'] = $post->post_content;
1084
-        }
1085
-        // update event
1086
-        $success = $this->_event_model()->update_by_ID($event_values, $post_id);
1087
-        // get event_object for other metaboxes...
1088
-        // though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id )..
1089
-        // i have to set up where conditions to override the filters in the model
1090
-        // that filter out auto-draft and inherit statuses so we GET the inherit id!
1091
-        /** @var EE_Event $event */
1092
-        $event = $this->_event_model()->get_one(
1093
-            [
1094
-                [
1095
-                    $this->_event_model()->primary_key_name() => $post_id,
1096
-                    'OR'                                      => [
1097
-                        'status'   => $post->post_status,
1098
-                        // if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db,
1099
-                        // but the returned object here has a status of "publish", so use the original post status as well
1100
-                        'status*1' => $this->request->getRequestParam('original_post_status'),
1101
-                    ],
1102
-                    'status' => ['NOT IN', ['auto-draft']],
1103
-                ],
1104
-            ]
1105
-        );
1106
-
1107
-        if (! $event instanceof EE_Event) {
1108
-            return;
1109
-        }
1110
-
1111
-        // the following are default callbacks for event attachment updates
1112
-        // that can be overridden by caffeinated functionality and/or addons.
1113
-        $event_update_callbacks = [];
1114
-        if (! $this->admin_config->useAdvancedEditor()) {
1115
-            $event_update_callbacks['_default_venue_update']   = [$this, '_default_venue_update'];
1116
-            $event_update_callbacks['_default_tickets_update'] = [$this, '_default_tickets_update'];
1117
-        }
1118
-        $event_update_callbacks = apply_filters(
1119
-            'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
1120
-            $event_update_callbacks
1121
-        );
1122
-
1123
-        $att_success = true;
1124
-        foreach ($event_update_callbacks as $e_callback) {
1125
-            $_success = is_callable($e_callback)
1126
-                ? $e_callback($event, $this->request->requestParams())
1127
-                : false;
1128
-            // if ANY of these updates fail then we want the appropriate global error message
1129
-            $att_success = $_success !== false ? $att_success : false;
1130
-        }
1131
-        // any errors?
1132
-        if ($success && $att_success === false) {
1133
-            EE_Error::add_error(
1134
-                esc_html__(
1135
-                    'Event Details saved successfully but something went wrong with saving attachments.',
1136
-                    'event_espresso'
1137
-                ),
1138
-                __FILE__,
1139
-                __FUNCTION__,
1140
-                __LINE__
1141
-            );
1142
-        } elseif ($success === false) {
1143
-            EE_Error::add_error(
1144
-                esc_html__('Event Details did not save successfully.', 'event_espresso'),
1145
-                __FILE__,
1146
-                __FUNCTION__,
1147
-                __LINE__
1148
-            );
1149
-        }
1150
-    }
1151
-
1152
-
1153
-    /**
1154
-     * @param int $post_id
1155
-     * @param int $revision_id
1156
-     * @throws EE_Error
1157
-     * @throws EE_Error
1158
-     * @throws ReflectionException
1159
-     * @see parent::restore_item()
1160
-     */
1161
-    protected function _restore_cpt_item(int $post_id, int $revision_id)
1162
-    {
1163
-        // copy existing event meta to new post
1164
-        $post_evt = $this->_event_model()->get_one_by_ID($post_id);
1165
-        if ($post_evt instanceof EE_Event) {
1166
-            // meta revision restore
1167
-            $post_evt->restore_revision($revision_id);
1168
-            // related objs restore
1169
-            $post_evt->restore_revision($revision_id, ['Venue', 'Datetime', 'Price']);
1170
-        }
1171
-    }
1172
-
1173
-
1174
-    /**
1175
-     * Attach the venue to the Event
1176
-     *
1177
-     * @param EE_Event $event Event Object to add the venue to
1178
-     * @param array    $data  The request data from the form
1179
-     * @return bool           Success or fail.
1180
-     * @throws EE_Error
1181
-     * @throws ReflectionException
1182
-     */
1183
-    protected function _default_venue_update(EE_Event $event, array $data): bool
1184
-    {
1185
-        require_once(EE_MODELS . 'EEM_Venue.model.php');
1186
-        $venue_model = EE_Registry::instance()->load_model('Venue');
1187
-        $venue_id    = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1188
-        // very important.  If we don't have a venue name...
1189
-        // then we'll get out because not necessary to create empty venue
1190
-        if (empty($data['venue_title'])) {
1191
-            return false;
1192
-        }
1193
-        $venue_array = [
1194
-            'VNU_wp_user'         => $event->get('EVT_wp_user'),
1195
-            'VNU_name'            => $data['venue_title'],
1196
-            'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1197
-            'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1198
-            'VNU_short_desc'      => ! empty($data['venue_short_description'])
1199
-                ? $data['venue_short_description']
1200
-                : null,
1201
-            'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1202
-            'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1203
-            'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1204
-            'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1205
-            'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1206
-            'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1207
-            'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1208
-            'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1209
-            'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1210
-            'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1211
-            'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1212
-            'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1213
-            'status'              => 'publish',
1214
-        ];
1215
-        // if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1216
-        if (! empty($venue_id)) {
1217
-            $update_where  = [$venue_model->primary_key_name() => $venue_id];
1218
-            $rows_affected = $venue_model->update($venue_array, [$update_where]);
1219
-            // we've gotta make sure that the venue is always attached to a revision..
1220
-            // add_relation_to should take care of making sure that the relation is already present.
1221
-            $event->_add_relation_to($venue_id, 'Venue');
1222
-            return $rows_affected > 0;
1223
-        }
1224
-        // we insert the venue
1225
-        $venue_id = $venue_model->insert($venue_array);
1226
-        $event->_add_relation_to($venue_id, 'Venue');
1227
-        return ! empty($venue_id);
1228
-        // when we have the ancestor come in it's already been handled by the revision save.
1229
-    }
1230
-
1231
-
1232
-    /**
1233
-     * Handles saving everything related to Tickets (datetimes, tickets, prices)
1234
-     *
1235
-     * @param EE_Event $event The Event object we're attaching data to
1236
-     * @param array    $data  The request data from the form
1237
-     * @return array
1238
-     * @throws EE_Error
1239
-     * @throws ReflectionException
1240
-     * @throws Exception
1241
-     */
1242
-    protected function _default_tickets_update(EE_Event $event, array $data): array
1243
-    {
1244
-        if ($this->admin_config->useAdvancedEditor()) {
1245
-            return [];
1246
-        }
1247
-        $datetime       = null;
1248
-        $saved_tickets  = [];
1249
-        $event_timezone = $event->get_timezone();
1250
-        $date_formats   = ['Y-m-d', 'h:i a'];
1251
-        foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
1252
-            // trim all values to ensure any excess whitespace is removed.
1253
-            $datetime_data                = array_map('trim', $datetime_data);
1254
-            $datetime_data['DTT_EVT_end'] = ! empty($datetime_data['DTT_EVT_end'])
1255
-                    ? $datetime_data['DTT_EVT_end']
1256
-                    : $datetime_data['DTT_EVT_start'];
1257
-            $datetime_values              = [
1258
-                'DTT_ID'        => ! empty($datetime_data['DTT_ID']) ? $datetime_data['DTT_ID'] : null,
1259
-                'DTT_EVT_start' => $datetime_data['DTT_EVT_start'],
1260
-                'DTT_EVT_end'   => $datetime_data['DTT_EVT_end'],
1261
-                'DTT_reg_limit' => empty($datetime_data['DTT_reg_limit']) ? EE_INF : $datetime_data['DTT_reg_limit'],
1262
-                'DTT_order'     => $row,
1263
-            ];
1264
-            // if we have an id then let's get existing object first and then set the new values.
1265
-            //  Otherwise we instantiate a new object for save.
1266
-            if (! empty($datetime_data['DTT_ID'])) {
1267
-                $datetime = EEM_Datetime::instance($event_timezone)->get_one_by_ID($datetime_data['DTT_ID']);
1268
-                if (! $datetime instanceof EE_Datetime) {
1269
-                    throw new RuntimeException(
1270
-                        sprintf(
1271
-                            esc_html__(
1272
-                                'Something went wrong! A valid Datetime could not be retrieved from the database using the supplied ID: %1$d',
1273
-                                'event_espresso'
1274
-                            ),
1275
-                            $datetime_data['DTT_ID']
1276
-                        )
1277
-                    );
1278
-                }
1279
-                $datetime->set_date_format($date_formats[0]);
1280
-                $datetime->set_time_format($date_formats[1]);
1281
-                foreach ($datetime_values as $field => $value) {
1282
-                    $datetime->set($field, $value);
1283
-                }
1284
-            } else {
1285
-                $datetime = EE_Datetime::new_instance($datetime_values, $event_timezone, $date_formats);
1286
-            }
1287
-            if (! $datetime instanceof EE_Datetime) {
1288
-                throw new RuntimeException(
1289
-                    sprintf(
1290
-                        esc_html__(
1291
-                            'Something went wrong! A valid Datetime could not be generated or retrieved using the supplied data: %1$s',
1292
-                            'event_espresso'
1293
-                        ),
1294
-                        print_r($datetime_values, true)
1295
-                    )
1296
-                );
1297
-            }
1298
-            // before going any further make sure our dates are setup correctly
1299
-            // so that the end date is always equal or greater than the start date.
1300
-            if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
1301
-                $datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
1302
-                $datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
1303
-            }
1304
-            $datetime->save();
1305
-            $event->_add_relation_to($datetime, 'Datetime');
1306
-        }
1307
-        // no datetimes get deleted so we don't do any of that logic here.
1308
-        // update tickets next
1309
-        $old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : [];
1310
-
1311
-        // set up some default start and end dates in case those are not present in the incoming data
1312
-        $default_start_date = new DateTime('now', new DateTimeZone($event->get_timezone()));
1313
-        $default_start_date = $default_start_date->format($date_formats[0] . ' ' . $date_formats[1]);
1314
-        // use the start date of the first datetime for the end date
1315
-        $first_datetime   = $event->first_datetime();
1316
-        $default_end_date = $first_datetime->start_date_and_time($date_formats[0], $date_formats[1]);
1317
-
1318
-        // now process the incoming data
1319
-        foreach ($data['edit_tickets'] as $row => $ticket_data) {
1320
-            $update_prices = false;
1321
-            $ticket_price  = $data['edit_prices'][ $row ][1]['PRC_amount'] ?? 0;
1322
-            // trim inputs to ensure any excess whitespace is removed.
1323
-            $ticket_data   = array_map('trim', $ticket_data);
1324
-            $ticket_values = [
1325
-                'TKT_ID'          => ! empty($ticket_data['TKT_ID']) ? $ticket_data['TKT_ID'] : null,
1326
-                'TTM_ID'          => ! empty($ticket_data['TTM_ID']) ? $ticket_data['TTM_ID'] : 0,
1327
-                'TKT_name'        => ! empty($ticket_data['TKT_name']) ? $ticket_data['TKT_name'] : '',
1328
-                'TKT_description' => ! empty($ticket_data['TKT_description']) ? $ticket_data['TKT_description'] : '',
1329
-                'TKT_start_date'  => ! empty($ticket_data['TKT_start_date'])
1330
-                    ? $ticket_data['TKT_start_date']
1331
-                    : $default_start_date,
1332
-                'TKT_end_date'    => ! empty($ticket_data['TKT_end_date'])
1333
-                    ? $ticket_data['TKT_end_date']
1334
-                    : $default_end_date,
1335
-                'TKT_qty'         => ! empty($ticket_data['TKT_qty'])
1336
-                                     || (isset($ticket_data['TKT_qty']) && (int) $ticket_data['TKT_qty'] === 0)
1337
-                    ? $ticket_data['TKT_qty']
1338
-                    : EE_INF,
1339
-                'TKT_uses'        => ! empty($ticket_data['TKT_uses'])
1340
-                                     || (isset($ticket_data['TKT_uses']) && (int) $ticket_data['TKT_uses'] === 0)
1341
-                    ? $ticket_data['TKT_uses']
1342
-                    : EE_INF,
1343
-                'TKT_min'         => ! empty($ticket_data['TKT_min']) ? $ticket_data['TKT_min'] : 0,
1344
-                'TKT_max'         => ! empty($ticket_data['TKT_max']) ? $ticket_data['TKT_max'] : EE_INF,
1345
-                'TKT_order'       => $ticket_data['TKT_order'] ?? $row,
1346
-                'TKT_price'       => (float) $ticket_price,
1347
-                'TKT_row'         => $row,
1348
-            ];
1349
-            // if this is a default ticket, then we need to set the TKT_ID to 0 and update accordingly,
1350
-            // which means in turn that the prices will become new prices as well.
1351
-            if (isset($ticket_data['TKT_is_default']) && $ticket_data['TKT_is_default']) {
1352
-                $ticket_values['TKT_ID']         = 0;
1353
-                $ticket_values['TKT_is_default'] = 0;
1354
-                $update_prices                   = true;
1355
-            }
1356
-            // if we have a TKT_ID then we need to get that existing TKT_obj and update it
1357
-            // we actually do our saves ahead of adding any relations because its entirely possible that this
1358
-            // ticket didn't get removed or added to any datetime in the session but DID have it's items modified.
1359
-            // keep in mind that if the ticket has been sold (and we have changed pricing information),
1360
-            // then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1361
-            if (! empty($ticket_data['TKT_ID'])) {
1362
-                $existing_ticket = EEM_Ticket::instance($event_timezone)->get_one_by_ID($ticket_data['TKT_ID']);
1363
-                if (! $existing_ticket instanceof EE_Ticket) {
1364
-                    throw new RuntimeException(
1365
-                        sprintf(
1366
-                            esc_html__(
1367
-                                'Something went wrong! A valid Ticket could not be retrieved from the database using the supplied ID: %1$d',
1368
-                                'event_espresso'
1369
-                            ),
1370
-                            $ticket_data['TKT_ID']
1371
-                        )
1372
-                    );
1373
-                }
1374
-                $ticket_sold = $existing_ticket->count_related(
1375
-                    'Registration',
1376
-                    [
1377
-                            [
1378
-                                'STS_ID' => [
1379
-                                    'NOT IN',
1380
-                                    [RegStatus::INCOMPLETE],
1381
-                                ],
1382
-                            ],
1383
-                        ]
1384
-                ) > 0;
1385
-                // let's just check the total price for the existing ticket and determine if it matches the new total price.
1386
-                // if they are different then we create a new ticket (if $ticket_sold)
1387
-                // if they aren't different then we go ahead and modify existing ticket.
1388
-                $create_new_ticket = $ticket_sold
1389
-                                     && EEH_Money::compare_floats($ticket_price, $existing_ticket->price(), '!=')
1390
-                                     && ! $existing_ticket->deleted();
1391
-                $existing_ticket->set_date_format($date_formats[0]);
1392
-                $existing_ticket->set_time_format($date_formats[1]);
1393
-                // set new values
1394
-                foreach ($ticket_values as $field => $value) {
1395
-                    if ($field == 'TKT_qty') {
1396
-                        $existing_ticket->set_qty($value);
1397
-                    } elseif ($field == 'TKT_price') {
1398
-                        $existing_ticket->set('TKT_price', $ticket_price);
1399
-                    } else {
1400
-                        $existing_ticket->set($field, $value);
1401
-                    }
1402
-                }
1403
-                $ticket = $existing_ticket;
1404
-                // if $create_new_ticket is false then we can safely update the existing ticket.
1405
-                //  Otherwise we have to create a new ticket.
1406
-                if ($create_new_ticket) {
1407
-                    // archive the old ticket first
1408
-                    $existing_ticket->set('TKT_deleted', 1);
1409
-                    $existing_ticket->save();
1410
-                    // make sure this ticket is still recorded in our $saved_tickets
1411
-                    // so we don't run it through the regular trash routine.
1412
-                    $saved_tickets[ $existing_ticket->ID() ] = $existing_ticket;
1413
-                    // create new ticket that's a copy of the existing except,
1414
-                    // (a new id of course and not archived) AND has the new TKT_price associated with it.
1415
-                    $new_ticket = clone $existing_ticket;
1416
-                    $new_ticket->set('TKT_ID', 0);
1417
-                    $new_ticket->set('TKT_deleted', 0);
1418
-                    $new_ticket->set('TKT_sold', 0);
1419
-                    // now we need to make sure that $new prices are created as well and attached to new ticket.
1420
-                    $update_prices = true;
1421
-                    $ticket        = $new_ticket;
1422
-                }
1423
-            } else {
1424
-                // no TKT_id so a new ticket
1425
-                $ticket_values['TKT_price'] = $ticket_price;
1426
-                $ticket                     = EE_Ticket::new_instance($ticket_values, $event_timezone, $date_formats);
1427
-                $update_prices              = true;
1428
-            }
1429
-            if (! $ticket instanceof EE_Ticket) {
1430
-                throw new RuntimeException(
1431
-                    sprintf(
1432
-                        esc_html__(
1433
-                            'Something went wrong! A valid Ticket could not be generated or retrieved using the supplied data: %1$s',
1434
-                            'event_espresso'
1435
-                        ),
1436
-                        print_r($ticket_values, true)
1437
-                    )
1438
-                );
1439
-            }
1440
-            // cap ticket qty by datetime reg limits
1441
-            $ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
1442
-            // update ticket.
1443
-            $ticket->save();
1444
-            // before going any further make sure our dates are setup correctly
1445
-            // so that the end date is always equal or greater than the start date.
1446
-            if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
1447
-                $ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
1448
-                $ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
1449
-                $ticket->save();
1450
-            }
1451
-            // initially let's add the ticket to the datetime
1452
-            $datetime->_add_relation_to($ticket, 'Ticket');
1453
-            $saved_tickets[ $ticket->ID() ] = $ticket;
1454
-            // add prices to ticket
1455
-            $prices_data = isset($data['edit_prices'][ $row ]) && is_array($data['edit_prices'][ $row ])
1456
-                ? $data['edit_prices'][ $row ]
1457
-                : [];
1458
-            $this->_add_prices_to_ticket($prices_data, $ticket, $update_prices);
1459
-        }
1460
-        // however now we need to handle permanently deleting tickets via the ui.
1461
-        // Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.
1462
-        // However, it does allow for deleting tickets that have no tickets sold,
1463
-        // in which case we want to get rid of permanently because there is no need to save in db.
1464
-        $old_tickets     = isset($old_tickets[0]) && $old_tickets[0] === '' ? [] : $old_tickets;
1465
-        $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1466
-        foreach ($tickets_removed as $id) {
1467
-            $id = absint($id);
1468
-            // get the ticket for this id
1469
-            $ticket_to_remove = EEM_Ticket::instance()->get_one_by_ID($id);
1470
-            if (! $ticket_to_remove instanceof EE_Ticket) {
1471
-                continue;
1472
-            }
1473
-            // need to get all the related datetimes on this ticket and remove from every single one of them
1474
-            // (remember this process can ONLY kick off if there are NO tickets sold)
1475
-            $related_datetimes = $ticket_to_remove->get_many_related('Datetime');
1476
-            foreach ($related_datetimes as $related_datetime) {
1477
-                $ticket_to_remove->_remove_relation_to($related_datetime, 'Datetime');
1478
-            }
1479
-            // need to do the same for prices (except these prices can also be deleted because again,
1480
-            // tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
1481
-            $ticket_to_remove->delete_related_permanently('Price');
1482
-            // finally let's delete this ticket
1483
-            // (which should not be blocked at this point b/c we've removed all our relationships)
1484
-            $ticket_to_remove->delete_permanently();
1485
-        }
1486
-        return [$datetime, $saved_tickets];
1487
-    }
1488
-
1489
-
1490
-    /**
1491
-     * This attaches a list of given prices to a ticket.
1492
-     * Note we dont' have to worry about ever removing relationships (or archiving prices)
1493
-     * because if there is a change in price information on a ticket, a new ticket is created anyways
1494
-     * so the archived ticket will retain the old price info and prices are automatically "archived" via the ticket.
1495
-     *
1496
-     * @access  private
1497
-     * @param array     $prices_data Array of prices from the form.
1498
-     * @param EE_Ticket $ticket      EE_Ticket object that prices are being attached to.
1499
-     * @param bool      $new_prices  Whether attach existing incoming prices or create new ones.
1500
-     * @return  void
1501
-     * @throws EE_Error
1502
-     * @throws ReflectionException
1503
-     */
1504
-    private function _add_prices_to_ticket(array $prices_data, EE_Ticket $ticket, bool $new_prices = false)
1505
-    {
1506
-        $timezone = $ticket->get_timezone();
1507
-        foreach ($prices_data as $row => $price_data) {
1508
-            $price_values = [
1509
-                'PRC_ID'         => ! empty($price_data['PRC_ID']) ? $price_data['PRC_ID'] : null,
1510
-                'PRT_ID'         => ! empty($price_data['PRT_ID']) ? $price_data['PRT_ID'] : null,
1511
-                'PRC_amount'     => ! empty($price_data['PRC_amount']) ? $price_data['PRC_amount'] : 0,
1512
-                'PRC_name'       => ! empty($price_data['PRC_name']) ? $price_data['PRC_name'] : '',
1513
-                'PRC_desc'       => ! empty($price_data['PRC_desc']) ? $price_data['PRC_desc'] : '',
1514
-                'PRC_is_default' => 0, // make sure prices are NOT set as default from this context
1515
-                'PRC_order'      => $row,
1516
-            ];
1517
-            if ($new_prices || empty($price_values['PRC_ID'])) {
1518
-                $price_values['PRC_ID'] = 0;
1519
-                $price                  = EE_Price::new_instance($price_values, $timezone);
1520
-            } else {
1521
-                $price = EEM_Price::instance($timezone)->get_one_by_ID($price_data['PRC_ID']);
1522
-                // update this price with new values
1523
-                foreach ($price_values as $field => $new_price) {
1524
-                    $price->set($field, $new_price);
1525
-                }
1526
-            }
1527
-            if (! $price instanceof EE_Price) {
1528
-                throw new RuntimeException(
1529
-                    sprintf(
1530
-                        esc_html__(
1531
-                            'Something went wrong! A valid Price could not be generated or retrieved using the supplied data: %1$s',
1532
-                            'event_espresso'
1533
-                        ),
1534
-                        print_r($price_values, true)
1535
-                    )
1536
-                );
1537
-            }
1538
-            $price->save();
1539
-            $ticket->_add_relation_to($price, 'Price');
1540
-        }
1541
-    }
1542
-
1543
-
1544
-    /**
1545
-     * Add in our autosave ajax handlers
1546
-     */
1547
-    protected function _ee_autosave_create_new()
1548
-    {
1549
-    }
1550
-
1551
-
1552
-    /**
1553
-     * More autosave handlers.
1554
-     */
1555
-    protected function _ee_autosave_edit()
1556
-    {
1557
-    }
1558
-
1559
-
1560
-    /**
1561
-     * @throws EE_Error
1562
-     * @throws ReflectionException
1563
-     */
1564
-    private function _generate_publish_box_extra_content()
1565
-    {
1566
-        // load formatter helper
1567
-        // args for getting related registrations
1568
-        $approved_query_args        = [
1569
-            [
1570
-                'REG_deleted' => 0,
1571
-                'STS_ID'      => RegStatus::APPROVED,
1572
-            ],
1573
-        ];
1574
-        $not_approved_query_args    = [
1575
-            [
1576
-                'REG_deleted' => 0,
1577
-                'STS_ID'      => RegStatus::AWAITING_REVIEW,
1578
-            ],
1579
-        ];
1580
-        $pending_payment_query_args = [
1581
-            [
1582
-                'REG_deleted' => 0,
1583
-                'STS_ID'      => RegStatus::PENDING_PAYMENT,
1584
-            ],
1585
-        ];
1586
-        // publish box
1587
-        $publish_box_extra_args = [
1588
-            'view_approved_reg_url'        => add_query_arg(
1589
-                [
1590
-                    'action'      => 'default',
1591
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1592
-                    '_reg_status' => RegStatus::APPROVED,
1593
-                    'use_filters' => true,
1594
-                ],
1595
-                REG_ADMIN_URL
1596
-            ),
1597
-            'view_not_approved_reg_url'    => add_query_arg(
1598
-                [
1599
-                    'action'      => 'default',
1600
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1601
-                    '_reg_status' => RegStatus::AWAITING_REVIEW,
1602
-                    'use_filters' => true,
1603
-                ],
1604
-                REG_ADMIN_URL
1605
-            ),
1606
-            'view_pending_payment_reg_url' => add_query_arg(
1607
-                [
1608
-                    'action'      => 'default',
1609
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1610
-                    '_reg_status' => RegStatus::PENDING_PAYMENT,
1611
-                    'use_filters' => true,
1612
-                ],
1613
-                REG_ADMIN_URL
1614
-            ),
1615
-            'approved_regs'                => $this->_cpt_model_obj->count_related(
1616
-                'Registration',
1617
-                $approved_query_args
1618
-            ),
1619
-            'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1620
-                'Registration',
1621
-                $not_approved_query_args
1622
-            ),
1623
-            'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1624
-                'Registration',
1625
-                $pending_payment_query_args
1626
-            ),
1627
-            'misc_pub_section_class'       => apply_filters(
1628
-                'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1629
-                'misc-pub-section'
1630
-            ),
1631
-        ];
1632
-        ob_start();
1633
-        do_action(
1634
-            'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1635
-            $this->_cpt_model_obj
1636
-        );
1637
-        $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1638
-        // load template
1639
-        EEH_Template::display_template(
1640
-            EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1641
-            $publish_box_extra_args
1642
-        );
1643
-    }
1644
-
1645
-
1646
-    /**
1647
-     * @return EE_Event
1648
-     */
1649
-    public function get_event_object()
1650
-    {
1651
-        return $this->_cpt_model_obj;
1652
-    }
1653
-
1654
-
1655
-
1656
-
1657
-    /** METABOXES * */
1658
-    /**
1659
-     * _register_event_editor_meta_boxes
1660
-     * add all metaboxes related to the event_editor
1661
-     *
1662
-     * @return void
1663
-     * @throws EE_Error
1664
-     * @throws ReflectionException
1665
-     */
1666
-    protected function _register_event_editor_meta_boxes()
1667
-    {
1668
-        $this->verify_cpt_object();
1669
-        $use_advanced_editor = $this->admin_config->useAdvancedEditor();
1670
-        // check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
1671
-        if (! $use_advanced_editor || ! $this->feature->allowed('use_reg_options_meta_box')) {
1672
-            $this->addMetaBox(
1673
-                'espresso_event_editor_event_options',
1674
-                esc_html__('Event Registration Options', 'event_espresso'),
1675
-                [$this, 'registration_options_meta_box'],
1676
-                $this->page_slug,
1677
-                'side'
1678
-            );
1679
-        }
1680
-        if (! $use_advanced_editor) {
1681
-            $this->addMetaBox(
1682
-                'espresso_event_editor_tickets',
1683
-                esc_html__('Event Datetime & Ticket', 'event_espresso'),
1684
-                [$this, 'ticket_metabox'],
1685
-                $this->page_slug,
1686
-                'normal',
1687
-                'high'
1688
-            );
1689
-        } elseif ($this->feature->allowed('use_reg_options_meta_box')) {
1690
-            add_action(
1691
-                'add_meta_boxes_espresso_events',
1692
-                function () {
1693
-                    global $current_screen;
1694
-                    remove_meta_box('authordiv', $current_screen, 'normal');
1695
-                },
1696
-                99
1697
-            );
1698
-        }
1699
-        // NOTE: if you're looking for other metaboxes in here,
1700
-        // where a metabox has a related management page in the admin
1701
-        // you will find it setup in the related management page's "_Hooks" file.
1702
-        // i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1703
-    }
1704
-
1705
-
1706
-    /**
1707
-     * @throws DomainException
1708
-     * @throws EE_Error
1709
-     * @throws ReflectionException
1710
-     */
1711
-    public function ticket_metabox()
1712
-    {
1713
-        $existing_datetime_ids = $existing_ticket_ids = [];
1714
-        // defaults for template args
1715
-        $template_args = [
1716
-            'ticket_rows'       => '',
1717
-            'total_ticket_rows' => 1,
1718
-            'trash_icon'        => 'dashicons dashicons-lock',
1719
-            'disabled'          => '',
1720
-        ];
1721
-        $event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1722
-        /**
1723
-         * 1. Start with retrieving Datetimes
1724
-         * 2. Fore each datetime get related tickets
1725
-         * 3. For each ticket get related prices
1726
-         */
1727
-        /** @var EEM_Datetime $datetime_model */
1728
-        $datetime_model = EE_Registry::instance()->load_model('Datetime');
1729
-        /** @var EEM_Ticket $datetime_model */
1730
-        $ticket_model = EE_Registry::instance()->load_model('Ticket');
1731
-        $times        = $datetime_model->get_all_event_dates($event_id);
1732
-        /** @type EE_Datetime $first_datetime */
1733
-        $first_datetime = reset($times);
1734
-        // do we get related tickets?
1735
-        if (
1736
-            $first_datetime instanceof EE_Datetime
1737
-            && $first_datetime->ID() !== 0
1738
-        ) {
1739
-            $existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1740
-            $template_args['time']   = $first_datetime;
1741
-            $related_tickets         = $first_datetime->tickets(
1742
-                [
1743
-                    ['OR' => ['TKT_deleted' => 1, 'TKT_deleted*' => 0]],
1744
-                    'default_where_conditions' => 'none',
1745
-                ]
1746
-            );
1747
-            if (! empty($related_tickets)) {
1748
-                $template_args['total_ticket_rows'] = count($related_tickets);
1749
-                $row                                = 0;
1750
-                foreach ($related_tickets as $ticket) {
1751
-                    $existing_ticket_ids[]        = $ticket->get('TKT_ID');
1752
-                    $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1753
-                    $row++;
1754
-                }
1755
-            } else {
1756
-                $template_args['total_ticket_rows'] = 1;
1757
-                /** @type EE_Ticket $ticket */
1758
-                $ticket                       = $ticket_model->create_default_object();
1759
-                $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1760
-            }
1761
-        } else {
1762
-            $template_args['time'] = $times[0];
1763
-            /** @type EE_Ticket[] $tickets */
1764
-            $tickets                      = $ticket_model->get_all_default_tickets();
1765
-            $template_args['ticket_rows'] .= $this->_get_ticket_row($tickets[1]);
1766
-            // NOTE: we're just sending the first default row
1767
-            // (decaf can't manage default tickets so this should be sufficient);
1768
-        }
1769
-        $template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1770
-            'event_editor_event_datetimes_help_tab'
1771
-        );
1772
-        $template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1773
-        $template_args['existing_datetime_ids']    = implode(',', $existing_datetime_ids);
1774
-        $template_args['existing_ticket_ids']      = implode(',', $existing_ticket_ids);
1775
-        $template_args['ticket_js_structure']      = $this->_get_ticket_row(
1776
-            $ticket_model->create_default_object(),
1777
-            true
1778
-        );
1779
-        $template                                  = apply_filters(
1780
-            'FHEE__Events_Admin_Page__ticket_metabox__template',
1781
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1782
-        );
1783
-        EEH_Template::display_template($template, $template_args);
1784
-    }
1785
-
1786
-
1787
-    /**
1788
-     * Setup an individual ticket form for the decaf event editor page
1789
-     *
1790
-     * @access private
1791
-     * @param EE_Ticket $ticket   the ticket object
1792
-     * @param boolean   $skeleton whether we're generating a skeleton for js manipulation
1793
-     * @param int       $row
1794
-     * @return string generated html for the ticket row.
1795
-     * @throws EE_Error
1796
-     * @throws ReflectionException
1797
-     */
1798
-    private function _get_ticket_row(EE_Ticket $ticket, bool $skeleton = false, int $row = 0): string
1799
-    {
1800
-        $template_args = [
1801
-            'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1802
-            'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton
1803
-                ? ' tkt-archived'
1804
-                : '',
1805
-            'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1806
-            'TKT_ID'              => $ticket->get('TKT_ID'),
1807
-            'TKT_name'            => $ticket->get('TKT_name'),
1808
-            'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1809
-            'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1810
-            'TKT_is_default'      => $ticket->get('TKT_is_default'),
1811
-            'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1812
-            'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1813
-            'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1814
-            'trash_icon'          => ($skeleton || (! $ticket->get('TKT_deleted')))
1815
-                                     && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1816
-                ? 'dashicons dashicons-post-trash clickable'
1817
-                : 'dashicons dashicons-lock entity-locked',
1818
-            'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1819
-                : ' disabled=disabled',
1820
-        ];
1821
-
1822
-        $price         = $ticket->ID() !== 0
1823
-            ? $ticket->get_first_related('Price', ['default_where_conditions' => 'none'])
1824
-            : null;
1825
-        $price         = $price instanceof EE_Price
1826
-            ? $price
1827
-            : EEM_Price::instance()->create_default_object();
1828
-        $price_args    = [
1829
-            'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1830
-            'PRC_amount'            => $price->get('PRC_amount'),
1831
-            'PRT_ID'                => $price->get('PRT_ID'),
1832
-            'PRC_ID'                => $price->get('PRC_ID'),
1833
-            'PRC_is_default'        => $price->get('PRC_is_default'),
1834
-        ];
1835
-        // make sure we have default start and end dates if skeleton
1836
-        // handle rows that should NOT be empty
1837
-        if (empty($template_args['TKT_start_date'])) {
1838
-            // if empty then the start date will be now.
1839
-            $template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1840
-        }
1841
-        if (empty($template_args['TKT_end_date'])) {
1842
-            // get the earliest datetime (if present);
1843
-            $earliest_datetime             = $this->_cpt_model_obj->ID() > 0
1844
-                ? $this->_cpt_model_obj->get_first_related(
1845
-                    'Datetime',
1846
-                    ['order_by' => ['DTT_EVT_start' => 'ASC']]
1847
-                )
1848
-                : null;
1849
-            $template_args['TKT_end_date'] = $earliest_datetime instanceof EE_Datetime
1850
-                ? $earliest_datetime->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a')
1851
-                : date('Y-m-d h:i a', mktime(0, 0, 0, date('m'), date('d') + 7, date('Y')));
1852
-        }
1853
-        $template_args = array_merge($template_args, $price_args);
1854
-        $template      = apply_filters(
1855
-            'FHEE__Events_Admin_Page__get_ticket_row__template',
1856
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1857
-            $ticket
1858
-        );
1859
-        return EEH_Template::display_template($template, $template_args, true);
1860
-    }
1861
-
1862
-
1863
-    /**
1864
-     * @throws EE_Error
1865
-     * @throws ReflectionException
1866
-     */
1867
-    public function registration_options_meta_box()
1868
-    {
1869
-        $yes_no_values             = [
1870
-            ['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1871
-            ['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1872
-        ];
1873
-        $default_reg_status_values = EEM_Registration::reg_status_array(
1874
-            [
1875
-                RegStatus::CANCELLED,
1876
-                RegStatus::DECLINED,
1877
-                RegStatus::INCOMPLETE,
1878
-            ],
1879
-            true
1880
-        );
1881
-        // $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1882
-        $template_args['_event']                          = $this->_cpt_model_obj;
1883
-        $template_args['event']                           = $this->_cpt_model_obj;
1884
-        $template_args['active_status']                   = $this->_cpt_model_obj->pretty_active_status(false);
1885
-        $template_args['additional_limit']                = $this->_cpt_model_obj->additional_limit();
1886
-        $template_args['default_registration_status']     = EEH_Form_Fields::select_input(
1887
-            'default_reg_status',
1888
-            $default_reg_status_values,
1889
-            $this->_cpt_model_obj->default_registration_status(),
1890
-            '',
1891
-            'ee-input-width--reg',
1892
-            false
1893
-        );
1894
-        $template_args['display_description']             = EEH_Form_Fields::select_input(
1895
-            'display_desc',
1896
-            $yes_no_values,
1897
-            $this->_cpt_model_obj->display_description()
1898
-        );
1899
-        $template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1900
-            'display_ticket_selector',
1901
-            $yes_no_values,
1902
-            $this->_cpt_model_obj->display_ticket_selector(),
1903
-            '',
1904
-            'ee-input-width--small',
1905
-            false
1906
-        );
1907
-        $template_args['additional_registration_options'] = apply_filters(
1908
-            'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1909
-            '',
1910
-            $template_args,
1911
-            $yes_no_values,
1912
-            $default_reg_status_values
1913
-        );
1914
-        EEH_Template::display_template(
1915
-            EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1916
-            $template_args
1917
-        );
1918
-    }
1919
-
1920
-
1921
-    /**
1922
-     * _get_events()
1923
-     * This method simply returns all the events (for the given _view and paging)
1924
-     *
1925
-     * @access public
1926
-     * @param int  $per_page     count of items per page (20 default);
1927
-     * @param int  $current_page what is the current page being viewed.
1928
-     * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1929
-     *                           If FALSE then we return an array of event objects
1930
-     *                           that match the given _view and paging parameters.
1931
-     * @return array|int         an array of event objects or a count of them.
1932
-     * @throws Exception
1933
-     */
1934
-    public function get_events(int $per_page = 10, int $current_page = 1, bool $count = false)
1935
-    {
1936
-        $EEM_Event   = $this->_event_model();
1937
-        $offset      = ($current_page - 1) * $per_page;
1938
-        $limit       = $count ? null : $offset . ',' . $per_page;
1939
-        $orderby     = $this->request->getRequestParam('orderby', 'EVT_ID');
1940
-        $order       = $this->request->getRequestParam('order', 'DESC');
1941
-        $month_range = $this->request->getRequestParam('month_range');
1942
-        $where  = [];
1943
-        $status = $this->request->getRequestParam('status');
1944
-        $timezone_string = EEH_DTT_Helper::get_valid_timezone_string();
1945
-        // determine what post_status our condition will have for the query.
1946
-        switch ($status) {
1947
-            case 'month':
1948
-            case 'today':
1949
-            case null:
1950
-            case 'all':
1951
-                break;
1952
-            case 'draft':
1953
-                $where['status'] = ['IN', ['draft', 'auto-draft']];
1954
-                break;
1955
-            default:
1956
-                $where['status'] = $status;
1957
-        }
1958
-        // categories? The default for all categories is -1
1959
-        $category = $this->request->getRequestParam('EVT_CAT', -1, DataType::INT);
1960
-        if ($category !== -1) {
1961
-            $where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1962
-            $where['Term_Taxonomy.term_id']  = $category;
1963
-        }
1964
-        // date where conditions
1965
-        $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1966
-        if ($month_range) {
1967
-            $where['Datetime.DTT_EVT_start'] = $this->whereParamsForDatetimeMonthRange($month_range, $timezone_string);
1968
-        } elseif ($status === 'today') {
1969
-            $DateTime                        = new DateTime(
1970
-                'now',
1971
-                new DateTimeZone($timezone_string)
1972
-            );
1973
-            $start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1974
-            $end                             = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1975
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1976
-        } elseif ($status === 'month') {
1977
-            $now                             = date('Y-m-01');
1978
-            $DateTime                        = new DateTime(
1979
-                $now,
1980
-                new DateTimeZone($timezone_string)
1981
-            );
1982
-            $start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1983
-            $end                             = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1984
-                                                        ->setTime(23, 59, 59)
1985
-                                                        ->format(implode(' ', $start_formats));
1986
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1987
-        }
1988
-        if (! $this->capabilities->current_user_can('ee_read_others_events', 'get_events')) {
1989
-            $where['EVT_wp_user'] = get_current_user_id();
1990
-        } else {
1991
-            if (! isset($where['status'])) {
1992
-                if (! $this->capabilities->current_user_can('ee_read_private_events', 'get_events')) {
1993
-                    $where['OR'] = [
1994
-                        'status*restrict_private' => ['!=', 'private'],
1995
-                        'AND'                     => [
1996
-                            'status*inclusive' => ['=', 'private'],
1997
-                            'EVT_wp_user'      => get_current_user_id(),
1998
-                        ],
1999
-                    ];
2000
-                }
2001
-            }
2002
-        }
2003
-        $wp_user = $this->request->getRequestParam('EVT_wp_user', 0, DataType::INT);
2004
-        if (
2005
-            $wp_user
2006
-            && $wp_user !== get_current_user_id()
2007
-            && $this->capabilities->current_user_can('ee_read_others_events', 'get_events')
2008
-        ) {
2009
-            $where['EVT_wp_user'] = $wp_user;
2010
-        }
2011
-        // search query handling
2012
-        $search_term = $this->request->getRequestParam('s');
2013
-        if ($search_term) {
2014
-            $search_term = '%' . $search_term . '%';
2015
-            $where['OR'] = [
2016
-                'EVT_name'       => ['LIKE', $search_term],
2017
-                'EVT_desc'       => ['LIKE', $search_term],
2018
-                'EVT_short_desc' => ['LIKE', $search_term],
2019
-            ];
2020
-        }
2021
-        // filter events by venue.
2022
-        $venue = $this->request->getRequestParam('venue', 0, DataType::INT);
2023
-        if ($venue) {
2024
-            $where['Venue.VNU_ID'] = $venue;
2025
-        }
2026
-        $request_params = $this->request->requestParams();
2027
-        $where          = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $request_params);
2028
-        $query_params   = apply_filters(
2029
-            'FHEE__Events_Admin_Page__get_events__query_params',
2030
-            [
2031
-                $where,
2032
-                'limit'    => $limit,
2033
-                'order_by' => $orderby,
2034
-                'order'    => $order,
2035
-                'group_by' => 'EVT_ID',
2036
-            ],
2037
-            $request_params
2038
-        );
2039
-
2040
-        // let's first check if we have special requests coming in.
2041
-        $active_status = $this->request->getRequestParam('active_status');
2042
-        if ($active_status) {
2043
-            switch ($active_status) {
2044
-                case 'upcoming':
2045
-                    return $EEM_Event->get_upcoming_events($query_params, $count);
2046
-                case 'expired':
2047
-                    return $EEM_Event->get_expired_events($query_params, $count);
2048
-                case 'active':
2049
-                    return $EEM_Event->get_active_events($query_params, $count);
2050
-                case 'inactive':
2051
-                    return $EEM_Event->get_inactive_events($query_params, $count);
2052
-            }
2053
-        }
2054
-
2055
-        return $count ? $EEM_Event->count([$where], 'EVT_ID', true) : $EEM_Event->get_all($query_params);
2056
-    }
2057
-
2058
-
2059
-    /**
2060
-     * @param string $month_range
2061
-     * @param string $timezone_string
2062
-     * @return array
2063
-     * @throws Exception
2064
-     * @since 5.0.21.p
2065
-     */
2066
-    public function whereParamsForDatetimeMonthRange(string $month_range, string $timezone_string = ''): array
2067
-    {
2068
-        $timezone_string = $timezone_string ?: EEH_DTT_Helper::get_valid_timezone_string();
2069
-        $pieces = explode(' ', $month_range, 3);
2070
-        // simulate the FIRST day of the month, that fixes issues for months like February
2071
-        // where PHP doesn't know what to assume for date.
2072
-        // @see https://events.codebasehq.com/projects/event-espresso/tickets/10437
2073
-        $month_r = ! empty($pieces[0]) ? date('m', EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
2074
-        $year_r  = ! empty($pieces[1]) ? $pieces[1] : '';
2075
-        $DateTime = new DateTime(
2076
-            "$year_r-$month_r-01 00:00:00",
2077
-            new DateTimeZone($timezone_string)
2078
-        );
2079
-        $start    = $DateTime->getTimestamp();
2080
-        // set the datetime to be the end of the month
2081
-        $DateTime->setDate(
2082
-            $year_r,
2083
-            $month_r,
2084
-            $DateTime->format('t')
2085
-        )->setTime(23, 59, 59);
2086
-        $end                             = $DateTime->getTimestamp();
2087
-        return ['BETWEEN', [$start, $end]];
2088
-    }
2089
-
2090
-
2091
-    /**
2092
-     * handling for WordPress CPT actions (trash, restore, delete)
2093
-     *
2094
-     * @param string $post_id
2095
-     * @throws EE_Error
2096
-     * @throws ReflectionException
2097
-     */
2098
-    public function trash_cpt_item($post_id)
2099
-    {
2100
-        $this->request->setRequestParam('EVT_ID', $post_id);
2101
-        $this->_trash_or_restore_event('trash', false);
2102
-    }
2103
-
2104
-
2105
-    /**
2106
-     * @param string $post_id
2107
-     * @throws EE_Error
2108
-     * @throws ReflectionException
2109
-     */
2110
-    public function restore_cpt_item($post_id)
2111
-    {
2112
-        $this->request->setRequestParam('EVT_ID', $post_id);
2113
-        $this->_trash_or_restore_event('draft', false);
2114
-    }
2115
-
2116
-
2117
-    /**
2118
-     * @param string $post_id
2119
-     * @throws EE_Error
2120
-     * @throws EE_Error
2121
-     */
2122
-    public function delete_cpt_item($post_id)
2123
-    {
2124
-        throw new EE_Error(
2125
-            esc_html__(
2126
-                'Please contact Event Espresso support with the details of the steps taken to produce this error.',
2127
-                'event_espresso'
2128
-            )
2129
-        );
2130
-        // $this->request->setRequestParam('EVT_ID', $post_id);
2131
-        // $this->_delete_event();
2132
-    }
2133
-
2134
-
2135
-    /**
2136
-     * _trash_or_restore_event
2137
-     *
2138
-     * @access protected
2139
-     * @param string $event_status
2140
-     * @param bool   $redirect_after
2141
-     * @throws EE_Error
2142
-     * @throws EE_Error
2143
-     * @throws ReflectionException
2144
-     */
2145
-    protected function _trash_or_restore_event(string $event_status = 'trash', bool $redirect_after = true)
2146
-    {
2147
-        // loop thru events
2148
-        if ($this->EVT_ID) {
2149
-            // clean status
2150
-            $event_status = sanitize_key($event_status);
2151
-            // grab status
2152
-            if (! empty($event_status)) {
2153
-                $success = $this->_change_event_status($this->EVT_ID, $event_status);
2154
-            } else {
2155
-                $success = false;
2156
-                $msg     = esc_html__(
2157
-                    'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2158
-                    'event_espresso'
2159
-                );
2160
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2161
-            }
2162
-        } else {
2163
-            $success = false;
2164
-            $msg     = esc_html__(
2165
-                'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
2166
-                'event_espresso'
2167
-            );
2168
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2169
-        }
2170
-        $action = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2171
-        if ($redirect_after) {
2172
-            $this->_redirect_after_action($success, 'Event', $action, ['action' => 'default']);
2173
-        }
2174
-    }
2175
-
2176
-
2177
-    /**
2178
-     * _trash_or_restore_events
2179
-     *
2180
-     * @access protected
2181
-     * @param string $event_status
2182
-     * @return void
2183
-     * @throws EE_Error
2184
-     * @throws EE_Error
2185
-     * @throws ReflectionException
2186
-     */
2187
-    protected function _trash_or_restore_events(string $event_status = 'trash')
2188
-    {
2189
-        // clean status
2190
-        $event_status = sanitize_key($event_status);
2191
-        // grab status
2192
-        if (! empty($event_status)) {
2193
-            $success = true;
2194
-            // determine the event id and set to array.
2195
-            $EVT_IDs = $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2196
-            // loop thru events
2197
-            foreach ($EVT_IDs as $EVT_ID) {
2198
-                if ($EVT_ID = absint($EVT_ID)) {
2199
-                    $results = $this->_change_event_status($EVT_ID, $event_status);
2200
-                    $success = $results !== false ? $success : false;
2201
-                } else {
2202
-                    $msg = sprintf(
2203
-                        esc_html__(
2204
-                            'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
2205
-                            'event_espresso'
2206
-                        ),
2207
-                        $EVT_ID
2208
-                    );
2209
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2210
-                    $success = false;
2211
-                }
2212
-            }
2213
-        } else {
2214
-            $success = false;
2215
-            $msg     = esc_html__(
2216
-                'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2217
-                'event_espresso'
2218
-            );
2219
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2220
-        }
2221
-        // in order to force a pluralized result message we need to send back a success status greater than 1
2222
-        $success = $success ? 2 : false;
2223
-        $action  = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2224
-        $this->_redirect_after_action($success, 'Events', $action, ['action' => 'default']);
2225
-    }
2226
-
2227
-
2228
-    /**
2229
-     * @param int    $EVT_ID
2230
-     * @param string $event_status
2231
-     * @return bool
2232
-     * @throws EE_Error
2233
-     * @throws ReflectionException
2234
-     */
2235
-    private function _change_event_status(int $EVT_ID = 0, string $event_status = ''): bool
2236
-    {
2237
-        // grab event id
2238
-        if (! $EVT_ID) {
2239
-            $msg = esc_html__(
2240
-                'An error occurred. No Event ID or an invalid Event ID was received.',
2241
-                'event_espresso'
2242
-            );
2243
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2244
-            return false;
2245
-        }
2246
-        $this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2247
-        // clean status
2248
-        $event_status = sanitize_key($event_status);
2249
-        // grab status
2250
-        if (empty($event_status)) {
2251
-            $msg = esc_html__(
2252
-                'An error occurred. No Event Status or an invalid Event Status was received.',
2253
-                'event_espresso'
2254
-            );
2255
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2256
-            return false;
2257
-        }
2258
-        // was event trashed or restored ?
2259
-        switch ($event_status) {
2260
-            case 'draft':
2261
-                $action = 'restored from the trash';
2262
-                $hook   = 'AHEE_event_restored_from_trash';
2263
-                break;
2264
-            case 'trash':
2265
-                $action = 'moved to the trash';
2266
-                $hook   = 'AHEE_event_moved_to_trash';
2267
-                break;
2268
-            default:
2269
-                $action = 'updated';
2270
-                $hook   = false;
2271
-        }
2272
-        // use class to change status
2273
-        $this->_cpt_model_obj->set_status($event_status);
2274
-        $success = $this->_cpt_model_obj->save();
2275
-        if (! $success) {
2276
-            $msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2277
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2278
-            return false;
2279
-        }
2280
-        if ($hook) {
2281
-            do_action($hook);
2282
-            // fake the action hook in EE_Soft_Delete_Base_Class::delete_or_restore()
2283
-            // because events side step that and it otherwise won't get called
2284
-            do_action(
2285
-                'AHEE__EE_Soft_Delete_Base_Class__delete_or_restore__after',
2286
-                $this->_cpt_model_obj,
2287
-                $hook === 'AHEE_event_moved_to_trash',
2288
-                $success
2289
-            );
2290
-        }
2291
-        return true;
2292
-    }
2293
-
2294
-
2295
-    /**
2296
-     * @param array $event_ids
2297
-     * @return array
2298
-     * @since   4.10.23.p
2299
-     */
2300
-    private function cleanEventIds(array $event_ids): array
2301
-    {
2302
-        return array_map('absint', $event_ids);
2303
-    }
2304
-
2305
-
2306
-    /**
2307
-     * @return array
2308
-     * @since   4.10.23.p
2309
-     */
2310
-    private function getEventIdsFromRequest(): array
2311
-    {
2312
-        if ($this->request->requestParamIsSet('EVT_IDs')) {
2313
-            return $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2314
-        } else {
2315
-            return $this->request->getRequestParam('EVT_ID', [], 'int', true);
2316
-        }
2317
-    }
2318
-
2319
-
2320
-    /**
2321
-     * @param bool $preview_delete
2322
-     * @throws EE_Error
2323
-     * @throws ReflectionException
2324
-     */
2325
-    protected function _delete_event(bool $preview_delete = true)
2326
-    {
2327
-        $this->_delete_events($preview_delete);
2328
-    }
2329
-
2330
-
2331
-    /**
2332
-     * Gets the tree traversal batch persister.
2333
-     *
2334
-     * @return NodeGroupDao
2335
-     * @throws InvalidArgumentException
2336
-     * @throws InvalidDataTypeException
2337
-     * @throws InvalidInterfaceException
2338
-     * @since 4.10.12.p
2339
-     */
2340
-    protected function getModelObjNodeGroupPersister(): NodeGroupDao
2341
-    {
2342
-        if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2343
-            $this->model_obj_node_group_persister =
2344
-                $this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2345
-        }
2346
-        return $this->model_obj_node_group_persister;
2347
-    }
2348
-
2349
-
2350
-    /**
2351
-     * @param bool $preview_delete
2352
-     * @return void
2353
-     * @throws EE_Error
2354
-     * @throws ReflectionException
2355
-     */
2356
-    protected function _delete_events(bool $preview_delete = true)
2357
-    {
2358
-        $event_ids = $this->getEventIdsFromRequest();
2359
-        if ($preview_delete) {
2360
-            $this->generateDeletionPreview($event_ids);
2361
-        } else {
2362
-            foreach ($event_ids as $event_id) {
2363
-                $event = EEM_Event::instance()->get_one_by_ID($event_id);
2364
-                if ($event instanceof EE_Event) {
2365
-                    $event->delete_permanently();
2366
-                }
2367
-            }
2368
-        }
2369
-    }
2370
-
2371
-
2372
-    /**
2373
-     * @param array $event_ids
2374
-     */
2375
-    protected function generateDeletionPreview(array $event_ids)
2376
-    {
2377
-        $event_ids = $this->cleanEventIds($event_ids);
2378
-        // Set a code we can use to reference this deletion task in the batch jobs and preview page.
2379
-        $deletion_job_code = $this->getModelObjNodeGroupPersister()->generateGroupCode();
2380
-        $return_url        = EE_Admin_Page::add_query_args_and_nonce(
2381
-            [
2382
-                'action'            => 'preview_deletion',
2383
-                'deletion_job_code' => $deletion_job_code,
2384
-            ],
2385
-            $this->_admin_base_url
2386
-        );
2387
-        EEH_URL::safeRedirectAndExit(
2388
-            EE_Admin_Page::add_query_args_and_nonce(
2389
-                [
2390
-                    'page'              => EED_Batch::PAGE_SLUG,
2391
-                    'batch'             => EED_Batch::batch_job,
2392
-                    'EVT_IDs'           => $event_ids,
2393
-                    'deletion_job_code' => $deletion_job_code,
2394
-                    'job_handler'       => urlencode('EventEspresso\core\libraries\batch\JobHandlers\PreviewEventDeletion'),
2395
-                    'return_url'        => urlencode($return_url),
2396
-                ],
2397
-                admin_url()
2398
-            )
2399
-        );
2400
-    }
2401
-
2402
-
2403
-    /**
2404
-     * Checks for a POST submission
2405
-     *
2406
-     * @since 4.10.12.p
2407
-     */
2408
-    protected function confirmDeletion()
2409
-    {
2410
-        $deletion_redirect_logic = $this->getLoader()->getShared(
2411
-            'EventEspresso\core\domain\services\admin\events\data\ConfirmDeletion'
2412
-        );
2413
-        $deletion_redirect_logic->handle($this->get_request_data(), $this->admin_base_url());
2414
-    }
2415
-
2416
-
2417
-    /**
2418
-     * A page for users to preview what exactly will be deleted, and confirm they want to delete it.
2419
-     *
2420
-     * @throws EE_Error
2421
-     * @since 4.10.12.p
2422
-     */
2423
-    protected function previewDeletion()
2424
-    {
2425
-        $preview_deletion_logic = $this->getLoader()->getShared(
2426
-            'EventEspresso\core\domain\services\admin\events\data\PreviewDeletion'
2427
-        );
2428
-        $this->set_template_args($preview_deletion_logic->handle($this->get_request_data(), $this->admin_base_url()));
2429
-        $this->display_admin_page_with_no_sidebar();
2430
-    }
2431
-
2432
-
2433
-    /**
2434
-     * get total number of events
2435
-     *
2436
-     * @access public
2437
-     * @return int
2438
-     * @throws EE_Error
2439
-     * @throws EE_Error
2440
-     * @throws ReflectionException
2441
-     */
2442
-    public function total_events(): int
2443
-    {
2444
-        return EEM_Event::instance()->count(
2445
-            ['caps' => 'read_admin'],
2446
-            'EVT_ID',
2447
-            true
2448
-        );
2449
-    }
2450
-
2451
-
2452
-    /**
2453
-     * get total number of draft events
2454
-     *
2455
-     * @access public
2456
-     * @return int
2457
-     * @throws EE_Error
2458
-     * @throws EE_Error
2459
-     * @throws ReflectionException
2460
-     */
2461
-    public function total_events_draft(): int
2462
-    {
2463
-        return EEM_Event::instance()->count(
2464
-            [
2465
-                ['status' => ['IN', ['draft', 'auto-draft']]],
2466
-                'caps' => 'read_admin',
2467
-            ],
2468
-            'EVT_ID',
2469
-            true
2470
-        );
2471
-    }
2472
-
2473
-
2474
-    /**
2475
-     * get total number of trashed events
2476
-     *
2477
-     * @access public
2478
-     * @return int
2479
-     * @throws EE_Error
2480
-     * @throws EE_Error
2481
-     * @throws ReflectionException
2482
-     */
2483
-    public function total_trashed_events(): int
2484
-    {
2485
-        return EEM_Event::instance()->count(
2486
-            [
2487
-                ['status' => 'trash'],
2488
-                'caps' => 'read_admin',
2489
-            ],
2490
-            'EVT_ID',
2491
-            true
2492
-        );
2493
-    }
2494
-
2495
-
2496
-    /**
2497
-     *    _default_event_settings
2498
-     *    This generates the Default Settings Tab
2499
-     *
2500
-     * @return void
2501
-     * @throws DomainException
2502
-     * @throws EE_Error
2503
-     * @throws InvalidArgumentException
2504
-     * @throws InvalidDataTypeException
2505
-     * @throws InvalidInterfaceException
2506
-     * @throws ReflectionException
2507
-     */
2508
-    protected function _default_event_settings()
2509
-    {
2510
-        $this->_set_add_edit_form_tags('update_default_event_settings');
2511
-        $this->_set_publish_post_box_vars();
2512
-        $this->_template_args['admin_page_content'] = EEH_HTML::div(
2513
-            $this->_default_event_settings_form()->get_html(),
2514
-            '',
2515
-            'padding'
2516
-        );
2517
-        $this->display_admin_page_with_sidebar();
2518
-    }
2519
-
2520
-
2521
-    /**
2522
-     * Return the form for event settings.
2523
-     *
2524
-     * @return EE_Form_Section_Proper
2525
-     * @throws EE_Error
2526
-     * @throws ReflectionException
2527
-     */
2528
-    protected function _default_event_settings_form(): EE_Form_Section_Proper
2529
-    {
2530
-        $registration_config              = EE_Registry::instance()->CFG->registration;
2531
-        $registration_stati_for_selection = EEM_Registration::reg_status_array(
2532
-        // exclude
2533
-            [
2534
-                RegStatus::CANCELLED,
2535
-                RegStatus::DECLINED,
2536
-                RegStatus::INCOMPLETE,
2537
-                RegStatus::WAIT_LIST,
2538
-            ],
2539
-            true
2540
-        );
2541
-        // setup Advanced Editor ???
2542
-        if (
2543
-            $this->raw_req_action === 'default_event_settings'
2544
-            || $this->raw_req_action === 'update_default_event_settings'
2545
-        ) {
2546
-            $this->advanced_editor_admin_form = $this->loader->getShared(AdvancedEditorAdminFormSection::class);
2547
-        }
2548
-        return new EE_Form_Section_Proper(
2549
-            [
2550
-                'name'            => 'update_default_event_settings',
2551
-                'html_id'         => 'update_default_event_settings',
2552
-                'html_class'      => 'form-table',
2553
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2554
-                'subsections'     => apply_filters(
2555
-                    'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2556
-                    [
2557
-                        'defaults_section_header' => new EE_Form_Section_HTML(
2558
-                            EEH_HTML::h2(
2559
-                                esc_html__('Default Settings', 'event_espresso'),
2560
-                                '',
2561
-                                'ee-admin-settings-hdr'
2562
-                            )
2563
-                        ),
2564
-                        'default_reg_status'      => new EE_Select_Input(
2565
-                            $registration_stati_for_selection,
2566
-                            [
2567
-                                'default'         => isset($registration_config->default_STS_ID)
2568
-                                                     && array_key_exists(
2569
-                                                         $registration_config->default_STS_ID,
2570
-                                                         $registration_stati_for_selection
2571
-                                                     )
2572
-                                    ? sanitize_text_field($registration_config->default_STS_ID)
2573
-                                    : RegStatus::PENDING_PAYMENT,
2574
-                                'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2575
-                                                     . EEH_Template::get_help_tab_link(
2576
-                                                         'default_settings_status_help_tab'
2577
-                                                     ),
2578
-                                'html_help_text'  => esc_html__(
2579
-                                    'This setting allows you to preselect what the default registration status setting is when creating an event.  Note that changing this setting does NOT retroactively apply it to existing events.',
2580
-                                    'event_espresso'
2581
-                                ),
2582
-                                'html_class'      => 'ee-input-width--small',
2583
-                            ]
2584
-                        ),
2585
-                        'default_max_tickets'     => new EE_Integer_Input(
2586
-                            [
2587
-                                'default'         => $registration_config->default_maximum_number_of_tickets
2588
-                                                     ?? EEM_Event::get_default_additional_limit(),
2589
-                                'html_label_text' => esc_html__(
2590
-                                    'Default Maximum Tickets Allowed Per Order:',
2591
-                                    'event_espresso'
2592
-                                )
2593
-                                                     . EEH_Template::get_help_tab_link(
2594
-                                                         'default_maximum_tickets_help_tab"'
2595
-                                                     ),
2596
-                                'html_help_text'  => esc_html__(
2597
-                                    'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2598
-                                    'event_espresso'
2599
-                                ),
2600
-                                'html_class'      => 'ee-input-width--tiny',
2601
-                            ]
2602
-                        ),
2603
-                    ]
2604
-                ),
2605
-            ]
2606
-        );
2607
-    }
2608
-
2609
-
2610
-    /**
2611
-     * @return void
2612
-     * @throws EE_Error
2613
-     * @throws InvalidArgumentException
2614
-     * @throws InvalidDataTypeException
2615
-     * @throws InvalidInterfaceException
2616
-     * @throws ReflectionException
2617
-     */
2618
-    protected function _update_default_event_settings()
2619
-    {
2620
-        $form = $this->_default_event_settings_form();
2621
-        if ($form->was_submitted()) {
2622
-            $form->receive_form_submission();
2623
-            if ($form->is_valid()) {
2624
-                $registration_config = EE_Registry::instance()->CFG->registration;
2625
-                $valid_data          = $form->valid_data();
2626
-                if (isset($valid_data['default_reg_status'])) {
2627
-                    $registration_config->default_STS_ID = $valid_data['default_reg_status'];
2628
-                }
2629
-                if (isset($valid_data['default_max_tickets'])) {
2630
-                    $registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2631
-                }
2632
-                do_action(
2633
-                    'AHEE__Events_Admin_Page___update_default_event_settings',
2634
-                    $valid_data,
2635
-                    EE_Registry::instance()->CFG,
2636
-                    $this
2637
-                );
2638
-                // update because data was valid!
2639
-                EE_Registry::instance()->CFG->update_espresso_config();
2640
-                EE_Error::overwrite_success();
2641
-                EE_Error::add_success(
2642
-                    esc_html__('Default Event Settings were updated', 'event_espresso')
2643
-                );
2644
-            }
2645
-        }
2646
-        $this->_redirect_after_action(0, '', '', ['action' => 'default_event_settings'], true);
2647
-    }
2648
-
2649
-
2650
-    /*************        Templates        *************
2651
-     *
2652
-     * @throws EE_Error
2653
-     */
2654
-    protected function _template_settings()
2655
-    {
2656
-        $this->_admin_page_title              = esc_html__('Template Settings (Preview)', 'event_espresso');
2657
-        $this->_template_args['preview_img']  = '<img src="'
2658
-                                                . EVENTS_ASSETS_URL
2659
-                                                . '/images/'
2660
-                                                . 'caffeinated_template_features.jpg" alt="'
2661
-                                                . esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2662
-                                                . '" />';
2663
-        $this->_template_args['preview_text'] = '<strong>'
2664
-                                                . esc_html__(
2665
-                                                    'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.',
2666
-                                                    'event_espresso'
2667
-                                                ) . '</strong>';
2668
-        $this->display_admin_caf_preview_page('template_settings_tab');
2669
-    }
2670
-
2671
-
2672
-    /** Event Category Stuff **/
2673
-    /**
2674
-     * set the _category property with the category object for the loaded page.
2675
-     *
2676
-     * @access private
2677
-     * @return void
2678
-     */
2679
-    private function _set_category_object()
2680
-    {
2681
-        if (isset($this->_category->id) && ! empty($this->_category->id)) {
2682
-            return;
2683
-        } //already have the category object so get out.
2684
-        // set default category object
2685
-        $this->_set_empty_category_object();
2686
-        // only set if we've got an id
2687
-        $category_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
2688
-        if (! $category_ID) {
2689
-            return;
2690
-        }
2691
-        $term = get_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2692
-        if (! empty($term)) {
2693
-            $this->_category->category_name       = $term->name;
2694
-            $this->_category->category_identifier = $term->slug;
2695
-            $this->_category->category_desc       = $term->description;
2696
-            $this->_category->id                  = $term->term_id;
2697
-            $this->_category->parent              = $term->parent;
2698
-        }
2699
-    }
2700
-
2701
-
2702
-    /**
2703
-     * Clears out category properties.
2704
-     */
2705
-    private function _set_empty_category_object()
2706
-    {
2707
-        $this->_category                = new stdClass();
2708
-        $this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2709
-        $this->_category->id            = $this->_category->parent = 0;
2710
-    }
2711
-
2712
-
2713
-    /**
2714
-     * @throws DomainException
2715
-     * @throws EE_Error
2716
-     * @throws InvalidArgumentException
2717
-     * @throws InvalidDataTypeException
2718
-     * @throws InvalidInterfaceException
2719
-     */
2720
-    protected function _category_list_table()
2721
-    {
2722
-        $this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2723
-        $this->_admin_page_title .= ' ';
2724
-        $this->_admin_page_title .= $this->get_action_link_or_button(
2725
-            'add_category',
2726
-            'add_category',
2727
-            [],
2728
-            'add-new-h2'
2729
-        );
2730
-        $this->display_admin_list_table_page_with_sidebar();
2731
-    }
2732
-
2733
-
2734
-    /**
2735
-     * Output category details view.
2736
-     *
2737
-     * @throws EE_Error
2738
-     * @throws EE_Error
2739
-     */
2740
-    protected function _category_details($view)
2741
-    {
2742
-        $route = $view === 'edit' ? 'update_category' : 'insert_category';
2743
-        $this->_set_add_edit_form_tags($route);
2744
-        $this->_set_category_object();
2745
-        $id            = ! empty($this->_category->id) ? $this->_category->id : '';
2746
-        $delete_action = 'delete_category';
2747
-        // custom redirect
2748
-        $redirect = EE_Admin_Page::add_query_args_and_nonce(
2749
-            ['action' => 'category_list'],
2750
-            $this->_admin_base_url
2751
-        );
2752
-        $this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2753
-        // take care of contents
2754
-        $this->_template_args['admin_page_content'] = $this->_category_details_content();
2755
-        $this->display_admin_page_with_sidebar();
2756
-    }
2757
-
2758
-
2759
-    /**
2760
-     * Output category details content.
2761
-     *
2762
-     * @throws DomainException
2763
-     */
2764
-    protected function _category_details_content(): string
2765
-    {
2766
-        $editor_args['category_desc'] = [
2767
-            'type'          => 'wp_editor',
2768
-            'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2769
-            'class'         => 'my_editor_custom',
2770
-            'wpeditor_args' => ['media_buttons' => false],
2771
-        ];
2772
-        $_wp_editor                   = $this->_generate_admin_form_fields($editor_args, 'array');
2773
-        $all_terms                    = get_terms(
2774
-            [EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY],
2775
-            ['hide_empty' => 0, 'exclude' => [$this->_category->id]]
2776
-        );
2777
-        // setup category select for term parents.
2778
-        $category_select_values[] = [
2779
-            'text' => esc_html__('No Parent', 'event_espresso'),
2780
-            'id'   => 0,
2781
-        ];
2782
-        foreach ($all_terms as $term) {
2783
-            $category_select_values[] = [
2784
-                'text' => $term->name,
2785
-                'id'   => $term->term_id,
2786
-            ];
2787
-        }
2788
-        $category_select = EEH_Form_Fields::select_input(
2789
-            'category_parent',
2790
-            $category_select_values,
2791
-            $this->_category->parent
2792
-        );
2793
-        $template_args   = [
2794
-            'category'                 => $this->_category,
2795
-            'category_select'          => $category_select,
2796
-            'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2797
-            'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2798
-            'disable'                  => '',
2799
-            'disabled_message'         => false,
2800
-        ];
2801
-        $template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2802
-        return EEH_Template::display_template($template, $template_args, true);
2803
-    }
2804
-
2805
-
2806
-    /**
2807
-     * Handles deleting categories.
2808
-     *
2809
-     * @throws EE_Error
2810
-     */
2811
-    protected function _delete_categories()
2812
-    {
2813
-        $category_IDs = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int', true);
2814
-        foreach ($category_IDs as $category_ID) {
2815
-            $this->_delete_category($category_ID);
2816
-        }
2817
-        // doesn't matter what page we're coming from... we're going to the same place after delete.
2818
-        $query_args = [
2819
-            'action' => 'category_list',
2820
-        ];
2821
-        $this->_redirect_after_action(0, '', '', $query_args);
2822
-    }
2823
-
2824
-
2825
-    /**
2826
-     * Handles deleting specific category.
2827
-     *
2828
-     * @param int $cat_id
2829
-     */
2830
-    protected function _delete_category(int $cat_id)
2831
-    {
2832
-        $cat_id = absint($cat_id);
2833
-        wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2834
-    }
2835
-
2836
-
2837
-    /**
2838
-     * Handles triggering the update or insertion of a new category.
2839
-     *
2840
-     * @param bool $new_category true means we're triggering the insert of a new category.
2841
-     * @throws EE_Error
2842
-     * @throws EE_Error
2843
-     */
2844
-    protected function _insert_or_update_category(bool $new_category)
2845
-    {
2846
-        $cat_id  = $this->_insert_category($new_category);
2847
-        $success = 0; // we already have a success message so lets not send another.
2848
-        if ($cat_id) {
2849
-            $query_args = [
2850
-                'action'     => 'edit_category',
2851
-                'EVT_CAT_ID' => $cat_id,
2852
-            ];
2853
-        } else {
2854
-            $query_args = ['action' => 'add_category'];
2855
-        }
2856
-        $this->_redirect_after_action($success, '', '', $query_args, true);
2857
-    }
2858
-
2859
-
2860
-    /**
2861
-     * Inserts or updates category
2862
-     *
2863
-     * @param bool $new_category (true indicates we're updating a category).
2864
-     * @return bool|mixed|string
2865
-     */
2866
-    private function _insert_category(bool $new_category)
2867
-    {
2868
-        $category_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
2869
-        $category_name       = $this->request->getRequestParam('category_name', '');
2870
-        $category_desc       = $this->request->getRequestParam('category_desc', '', DataType::HTML);
2871
-        $category_parent     = $this->request->getRequestParam('category_parent', 0, DataType::INT);
2872
-        $category_identifier = $this->request->getRequestParam('category_identifier', '');
2873
-
2874
-        if (empty($category_name)) {
2875
-            $msg = esc_html__('You must add a name for the category.', 'event_espresso');
2876
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2877
-            return 0;
2878
-        }
2879
-        $term_args = [
2880
-            'name'        => $category_name,
2881
-            'description' => $category_desc,
2882
-            'parent'      => $category_parent,
2883
-        ];
2884
-        // was the category_identifier input disabled?
2885
-        if ($category_identifier) {
2886
-            $term_args['slug'] = $category_identifier;
2887
-        }
2888
-        $insert_ids = $new_category
2889
-            ? wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2890
-            : wp_update_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2891
-
2892
-        if ($insert_ids instanceof WP_Error) {
2893
-            EE_Error::add_error($insert_ids->get_error_message(), __FILE__, __FUNCTION__, __LINE__);
2894
-            return 0;
2895
-        }
2896
-        $category_ID = $insert_ids['term_id'] ?? 0;
2897
-        if (! $category_ID) {
2898
-            EE_Error::add_error(
2899
-                esc_html__(
2900
-                    'An error occurred and the category has not been saved to the database.',
2901
-                    'event_espresso'
2902
-                ),
2903
-                __FILE__,
2904
-                __FUNCTION__,
2905
-                __LINE__
2906
-            );
2907
-            return 0;
2908
-        }
2909
-        EE_Error::add_success(
2910
-            sprintf(
2911
-                esc_html__('The category %s was successfully saved', 'event_espresso'),
2912
-                $category_name
2913
-            )
2914
-        );
2915
-        return $category_ID;
2916
-    }
2917
-
2918
-
2919
-    /**
2920
-     * Gets categories or count of categories matching the arguments in the request.
2921
-     *
2922
-     * @param int  $per_page
2923
-     * @param int  $current_page
2924
-     * @param bool $count
2925
-     * @return EE_Term_Taxonomy[]|int
2926
-     * @throws EE_Error
2927
-     * @throws ReflectionException
2928
-     */
2929
-    public function get_categories(int $per_page = 10, int $current_page = 1, bool $count = false)
2930
-    {
2931
-        // testing term stuff
2932
-        $orderby     = $this->request->getRequestParam('orderby', 'Term.term_id');
2933
-        $order       = $this->request->getRequestParam('order', 'DESC');
2934
-        $limit       = ($current_page - 1) * $per_page;
2935
-        $where       = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2936
-        $search_term = $this->request->getRequestParam('s');
2937
-        if ($search_term) {
2938
-            $search_term = '%' . $search_term . '%';
2939
-            $where['OR'] = [
2940
-                'Term.name'   => ['LIKE', $search_term],
2941
-                'description' => ['LIKE', $search_term],
2942
-            ];
2943
-        }
2944
-        $query_params = [
2945
-            $where,
2946
-            'order_by'   => [$orderby => $order],
2947
-            'limit'      => $limit . ',' . $per_page,
2948
-            'force_join' => ['Term'],
2949
-        ];
2950
-        return $count
2951
-            ? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2952
-            : EEM_Term_Taxonomy::instance()->get_all($query_params);
2953
-    }
2954
-
2955
-    /* end category stuff */
2956
-
2957
-
2958
-    /**************/
2959
-
2960
-
2961
-    /**
2962
-     * Callback for the `ee_save_timezone_setting` ajax action.
2963
-     *
2964
-     * @throws EE_Error
2965
-     * @throws InvalidArgumentException
2966
-     * @throws InvalidDataTypeException
2967
-     * @throws InvalidInterfaceException
2968
-     */
2969
-    public function saveTimezoneString()
2970
-    {
2971
-        if (! $this->capabilities->current_user_can('manage_options', __FUNCTION__)) {
2972
-            wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
2973
-        }
2974
-        $timezone_string = $this->request->getRequestParam('timezone_selected');
2975
-        if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) {
2976
-            EE_Error::add_error(
2977
-                esc_html__('An invalid timezone string submitted.', 'event_espresso'),
2978
-                __FILE__,
2979
-                __FUNCTION__,
2980
-                __LINE__
2981
-            );
2982
-            $this->_template_args['error'] = true;
2983
-            $this->_return_json();
2984
-        }
2985
-
2986
-        update_option('timezone_string', $timezone_string);
2987
-        EE_Error::add_success(
2988
-            esc_html__('Your timezone string was updated.', 'event_espresso')
2989
-        );
2990
-        $this->_template_args['success'] = true;
2991
-        $this->_return_json(true, ['action' => 'create_new']);
2992
-    }
2993
-
2994
-
2995
-    /**
2996 2652
      * @throws EE_Error
2997
-     * @deprecated 4.10.25.p
2998 2653
      */
2999
-    public function save_timezonestring_setting()
3000
-    {
3001
-        $this->saveTimezoneString();
3002
-    }
2654
+	protected function _template_settings()
2655
+	{
2656
+		$this->_admin_page_title              = esc_html__('Template Settings (Preview)', 'event_espresso');
2657
+		$this->_template_args['preview_img']  = '<img src="'
2658
+												. EVENTS_ASSETS_URL
2659
+												. '/images/'
2660
+												. 'caffeinated_template_features.jpg" alt="'
2661
+												. esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2662
+												. '" />';
2663
+		$this->_template_args['preview_text'] = '<strong>'
2664
+												. esc_html__(
2665
+													'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.',
2666
+													'event_espresso'
2667
+												) . '</strong>';
2668
+		$this->display_admin_caf_preview_page('template_settings_tab');
2669
+	}
2670
+
2671
+
2672
+	/** Event Category Stuff **/
2673
+	/**
2674
+	 * set the _category property with the category object for the loaded page.
2675
+	 *
2676
+	 * @access private
2677
+	 * @return void
2678
+	 */
2679
+	private function _set_category_object()
2680
+	{
2681
+		if (isset($this->_category->id) && ! empty($this->_category->id)) {
2682
+			return;
2683
+		} //already have the category object so get out.
2684
+		// set default category object
2685
+		$this->_set_empty_category_object();
2686
+		// only set if we've got an id
2687
+		$category_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
2688
+		if (! $category_ID) {
2689
+			return;
2690
+		}
2691
+		$term = get_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2692
+		if (! empty($term)) {
2693
+			$this->_category->category_name       = $term->name;
2694
+			$this->_category->category_identifier = $term->slug;
2695
+			$this->_category->category_desc       = $term->description;
2696
+			$this->_category->id                  = $term->term_id;
2697
+			$this->_category->parent              = $term->parent;
2698
+		}
2699
+	}
2700
+
2701
+
2702
+	/**
2703
+	 * Clears out category properties.
2704
+	 */
2705
+	private function _set_empty_category_object()
2706
+	{
2707
+		$this->_category                = new stdClass();
2708
+		$this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2709
+		$this->_category->id            = $this->_category->parent = 0;
2710
+	}
2711
+
2712
+
2713
+	/**
2714
+	 * @throws DomainException
2715
+	 * @throws EE_Error
2716
+	 * @throws InvalidArgumentException
2717
+	 * @throws InvalidDataTypeException
2718
+	 * @throws InvalidInterfaceException
2719
+	 */
2720
+	protected function _category_list_table()
2721
+	{
2722
+		$this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2723
+		$this->_admin_page_title .= ' ';
2724
+		$this->_admin_page_title .= $this->get_action_link_or_button(
2725
+			'add_category',
2726
+			'add_category',
2727
+			[],
2728
+			'add-new-h2'
2729
+		);
2730
+		$this->display_admin_list_table_page_with_sidebar();
2731
+	}
2732
+
2733
+
2734
+	/**
2735
+	 * Output category details view.
2736
+	 *
2737
+	 * @throws EE_Error
2738
+	 * @throws EE_Error
2739
+	 */
2740
+	protected function _category_details($view)
2741
+	{
2742
+		$route = $view === 'edit' ? 'update_category' : 'insert_category';
2743
+		$this->_set_add_edit_form_tags($route);
2744
+		$this->_set_category_object();
2745
+		$id            = ! empty($this->_category->id) ? $this->_category->id : '';
2746
+		$delete_action = 'delete_category';
2747
+		// custom redirect
2748
+		$redirect = EE_Admin_Page::add_query_args_and_nonce(
2749
+			['action' => 'category_list'],
2750
+			$this->_admin_base_url
2751
+		);
2752
+		$this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2753
+		// take care of contents
2754
+		$this->_template_args['admin_page_content'] = $this->_category_details_content();
2755
+		$this->display_admin_page_with_sidebar();
2756
+	}
2757
+
2758
+
2759
+	/**
2760
+	 * Output category details content.
2761
+	 *
2762
+	 * @throws DomainException
2763
+	 */
2764
+	protected function _category_details_content(): string
2765
+	{
2766
+		$editor_args['category_desc'] = [
2767
+			'type'          => 'wp_editor',
2768
+			'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2769
+			'class'         => 'my_editor_custom',
2770
+			'wpeditor_args' => ['media_buttons' => false],
2771
+		];
2772
+		$_wp_editor                   = $this->_generate_admin_form_fields($editor_args, 'array');
2773
+		$all_terms                    = get_terms(
2774
+			[EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY],
2775
+			['hide_empty' => 0, 'exclude' => [$this->_category->id]]
2776
+		);
2777
+		// setup category select for term parents.
2778
+		$category_select_values[] = [
2779
+			'text' => esc_html__('No Parent', 'event_espresso'),
2780
+			'id'   => 0,
2781
+		];
2782
+		foreach ($all_terms as $term) {
2783
+			$category_select_values[] = [
2784
+				'text' => $term->name,
2785
+				'id'   => $term->term_id,
2786
+			];
2787
+		}
2788
+		$category_select = EEH_Form_Fields::select_input(
2789
+			'category_parent',
2790
+			$category_select_values,
2791
+			$this->_category->parent
2792
+		);
2793
+		$template_args   = [
2794
+			'category'                 => $this->_category,
2795
+			'category_select'          => $category_select,
2796
+			'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2797
+			'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2798
+			'disable'                  => '',
2799
+			'disabled_message'         => false,
2800
+		];
2801
+		$template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2802
+		return EEH_Template::display_template($template, $template_args, true);
2803
+	}
2804
+
2805
+
2806
+	/**
2807
+	 * Handles deleting categories.
2808
+	 *
2809
+	 * @throws EE_Error
2810
+	 */
2811
+	protected function _delete_categories()
2812
+	{
2813
+		$category_IDs = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int', true);
2814
+		foreach ($category_IDs as $category_ID) {
2815
+			$this->_delete_category($category_ID);
2816
+		}
2817
+		// doesn't matter what page we're coming from... we're going to the same place after delete.
2818
+		$query_args = [
2819
+			'action' => 'category_list',
2820
+		];
2821
+		$this->_redirect_after_action(0, '', '', $query_args);
2822
+	}
2823
+
2824
+
2825
+	/**
2826
+	 * Handles deleting specific category.
2827
+	 *
2828
+	 * @param int $cat_id
2829
+	 */
2830
+	protected function _delete_category(int $cat_id)
2831
+	{
2832
+		$cat_id = absint($cat_id);
2833
+		wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2834
+	}
2835
+
2836
+
2837
+	/**
2838
+	 * Handles triggering the update or insertion of a new category.
2839
+	 *
2840
+	 * @param bool $new_category true means we're triggering the insert of a new category.
2841
+	 * @throws EE_Error
2842
+	 * @throws EE_Error
2843
+	 */
2844
+	protected function _insert_or_update_category(bool $new_category)
2845
+	{
2846
+		$cat_id  = $this->_insert_category($new_category);
2847
+		$success = 0; // we already have a success message so lets not send another.
2848
+		if ($cat_id) {
2849
+			$query_args = [
2850
+				'action'     => 'edit_category',
2851
+				'EVT_CAT_ID' => $cat_id,
2852
+			];
2853
+		} else {
2854
+			$query_args = ['action' => 'add_category'];
2855
+		}
2856
+		$this->_redirect_after_action($success, '', '', $query_args, true);
2857
+	}
2858
+
2859
+
2860
+	/**
2861
+	 * Inserts or updates category
2862
+	 *
2863
+	 * @param bool $new_category (true indicates we're updating a category).
2864
+	 * @return bool|mixed|string
2865
+	 */
2866
+	private function _insert_category(bool $new_category)
2867
+	{
2868
+		$category_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
2869
+		$category_name       = $this->request->getRequestParam('category_name', '');
2870
+		$category_desc       = $this->request->getRequestParam('category_desc', '', DataType::HTML);
2871
+		$category_parent     = $this->request->getRequestParam('category_parent', 0, DataType::INT);
2872
+		$category_identifier = $this->request->getRequestParam('category_identifier', '');
2873
+
2874
+		if (empty($category_name)) {
2875
+			$msg = esc_html__('You must add a name for the category.', 'event_espresso');
2876
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2877
+			return 0;
2878
+		}
2879
+		$term_args = [
2880
+			'name'        => $category_name,
2881
+			'description' => $category_desc,
2882
+			'parent'      => $category_parent,
2883
+		];
2884
+		// was the category_identifier input disabled?
2885
+		if ($category_identifier) {
2886
+			$term_args['slug'] = $category_identifier;
2887
+		}
2888
+		$insert_ids = $new_category
2889
+			? wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2890
+			: wp_update_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2891
+
2892
+		if ($insert_ids instanceof WP_Error) {
2893
+			EE_Error::add_error($insert_ids->get_error_message(), __FILE__, __FUNCTION__, __LINE__);
2894
+			return 0;
2895
+		}
2896
+		$category_ID = $insert_ids['term_id'] ?? 0;
2897
+		if (! $category_ID) {
2898
+			EE_Error::add_error(
2899
+				esc_html__(
2900
+					'An error occurred and the category has not been saved to the database.',
2901
+					'event_espresso'
2902
+				),
2903
+				__FILE__,
2904
+				__FUNCTION__,
2905
+				__LINE__
2906
+			);
2907
+			return 0;
2908
+		}
2909
+		EE_Error::add_success(
2910
+			sprintf(
2911
+				esc_html__('The category %s was successfully saved', 'event_espresso'),
2912
+				$category_name
2913
+			)
2914
+		);
2915
+		return $category_ID;
2916
+	}
2917
+
2918
+
2919
+	/**
2920
+	 * Gets categories or count of categories matching the arguments in the request.
2921
+	 *
2922
+	 * @param int  $per_page
2923
+	 * @param int  $current_page
2924
+	 * @param bool $count
2925
+	 * @return EE_Term_Taxonomy[]|int
2926
+	 * @throws EE_Error
2927
+	 * @throws ReflectionException
2928
+	 */
2929
+	public function get_categories(int $per_page = 10, int $current_page = 1, bool $count = false)
2930
+	{
2931
+		// testing term stuff
2932
+		$orderby     = $this->request->getRequestParam('orderby', 'Term.term_id');
2933
+		$order       = $this->request->getRequestParam('order', 'DESC');
2934
+		$limit       = ($current_page - 1) * $per_page;
2935
+		$where       = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2936
+		$search_term = $this->request->getRequestParam('s');
2937
+		if ($search_term) {
2938
+			$search_term = '%' . $search_term . '%';
2939
+			$where['OR'] = [
2940
+				'Term.name'   => ['LIKE', $search_term],
2941
+				'description' => ['LIKE', $search_term],
2942
+			];
2943
+		}
2944
+		$query_params = [
2945
+			$where,
2946
+			'order_by'   => [$orderby => $order],
2947
+			'limit'      => $limit . ',' . $per_page,
2948
+			'force_join' => ['Term'],
2949
+		];
2950
+		return $count
2951
+			? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2952
+			: EEM_Term_Taxonomy::instance()->get_all($query_params);
2953
+	}
2954
+
2955
+	/* end category stuff */
2956
+
2957
+
2958
+	/**************/
2959
+
2960
+
2961
+	/**
2962
+	 * Callback for the `ee_save_timezone_setting` ajax action.
2963
+	 *
2964
+	 * @throws EE_Error
2965
+	 * @throws InvalidArgumentException
2966
+	 * @throws InvalidDataTypeException
2967
+	 * @throws InvalidInterfaceException
2968
+	 */
2969
+	public function saveTimezoneString()
2970
+	{
2971
+		if (! $this->capabilities->current_user_can('manage_options', __FUNCTION__)) {
2972
+			wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
2973
+		}
2974
+		$timezone_string = $this->request->getRequestParam('timezone_selected');
2975
+		if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) {
2976
+			EE_Error::add_error(
2977
+				esc_html__('An invalid timezone string submitted.', 'event_espresso'),
2978
+				__FILE__,
2979
+				__FUNCTION__,
2980
+				__LINE__
2981
+			);
2982
+			$this->_template_args['error'] = true;
2983
+			$this->_return_json();
2984
+		}
2985
+
2986
+		update_option('timezone_string', $timezone_string);
2987
+		EE_Error::add_success(
2988
+			esc_html__('Your timezone string was updated.', 'event_espresso')
2989
+		);
2990
+		$this->_template_args['success'] = true;
2991
+		$this->_return_json(true, ['action' => 'create_new']);
2992
+	}
2993
+
2994
+
2995
+	/**
2996
+	 * @throws EE_Error
2997
+	 * @deprecated 4.10.25.p
2998
+	 */
2999
+	public function save_timezonestring_setting()
3000
+	{
3001
+		$this->saveTimezoneString();
3002
+	}
3003 3003
 }
Please login to merge, or discard this patch.
Spacing   +87 added lines, -87 removed lines patch added patch discarded remove patch
@@ -573,13 +573,13 @@  discard block
 block discarded – undo
573 573
     {
574 574
         wp_enqueue_style(
575 575
             'events-admin-css',
576
-            EVENTS_ASSETS_URL . 'events-admin-page.css',
576
+            EVENTS_ASSETS_URL.'events-admin-page.css',
577 577
             [],
578 578
             EVENT_ESPRESSO_VERSION
579 579
         );
580 580
         wp_enqueue_style(
581 581
             'ee-cat-admin',
582
-            EVENTS_ASSETS_URL . 'ee-cat-admin.css',
582
+            EVENTS_ASSETS_URL.'ee-cat-admin.css',
583 583
             ['editor-buttons'],
584 584
             EVENT_ESPRESSO_VERSION
585 585
         );
@@ -604,14 +604,14 @@  discard block
 block discarded – undo
604 604
         wp_enqueue_style('espresso-ui-theme');
605 605
         wp_enqueue_style(
606 606
             'event-editor-css',
607
-            EVENTS_ASSETS_URL . 'event-editor.css',
607
+            EVENTS_ASSETS_URL.'event-editor.css',
608 608
             ['ee-admin-css'],
609 609
             EVENT_ESPRESSO_VERSION
610 610
         );
611 611
         // scripts
612 612
         wp_enqueue_script(
613 613
             'event_editor_js',
614
-            EVENTS_ASSETS_URL . 'event_editor.js',
614
+            EVENTS_ASSETS_URL.'event_editor.js',
615 615
             [
616 616
                 EspressoLegacyAdminAssetManager::JS_HANDLE_EE_ADMIN,
617 617
                 JqueryAssetManager::JS_HANDLE_JQUERY_UI_SLIDER,
@@ -620,10 +620,10 @@  discard block
 block discarded – undo
620 620
             EVENT_ESPRESSO_VERSION,
621 621
             true
622 622
         );
623
-        if (! $this->admin_config->useAdvancedEditor()) {
623
+        if ( ! $this->admin_config->useAdvancedEditor()) {
624 624
             wp_enqueue_script(
625 625
                 'event-datetime-metabox',
626
-                EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
626
+                EVENTS_ASSETS_URL.'event-datetime-metabox.js',
627 627
                 ['event_editor_js', 'ee-datepicker'],
628 628
                 EVENT_ESPRESSO_VERSION
629 629
             );
@@ -701,15 +701,15 @@  discard block
 block discarded – undo
701 701
     public function verify_event_edit(?EE_Base_Class $event = null, string $req_type = '')
702 702
     {
703 703
         // don't need to do this when processing
704
-        if (! empty($req_type)) {
704
+        if ( ! empty($req_type)) {
705 705
             return;
706 706
         }
707 707
         // no event?
708
-        if (! $event instanceof EE_Event) {
708
+        if ( ! $event instanceof EE_Event) {
709 709
             $event = $this->_cpt_model_obj;
710 710
         }
711 711
         // STILL no event?
712
-        if (! $event instanceof EE_Event) {
712
+        if ( ! $event instanceof EE_Event) {
713 713
             return;
714 714
         }
715 715
         // don't need to keep calling this
@@ -754,7 +754,7 @@  discard block
 block discarded – undo
754 754
             );
755 755
         }
756 756
         // now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
757
-        if (! $event->tickets_on_sale()) {
757
+        if ( ! $event->tickets_on_sale()) {
758 758
             return;
759 759
         }
760 760
         // made it here so show warning
@@ -803,7 +803,7 @@  discard block
 block discarded – undo
803 803
     {
804 804
         $has_timezone_string = get_option('timezone_string');
805 805
         // only nag them about setting their timezone if it's their first event, and they haven't already done it
806
-        if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
806
+        if ( ! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
807 807
             EE_Error::add_attention(
808 808
                 sprintf(
809 809
                     esc_html__(
@@ -872,7 +872,7 @@  discard block
 block discarded – undo
872 872
      */
873 873
     protected function _event_legend_items(): array
874 874
     {
875
-        $items    = [
875
+        $items = [
876 876
             'view_details'   => [
877 877
                 'class' => 'dashicons dashicons-visibility',
878 878
                 'desc'  => esc_html__('View Event', 'event_espresso'),
@@ -889,31 +889,31 @@  discard block
 block discarded – undo
889 889
         $items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
890 890
         $statuses = [
891 891
             'sold_out_status'  => [
892
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::sold_out,
892
+                'class' => 'ee-status-legend ee-status-bg--'.EE_Datetime::sold_out,
893 893
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
894 894
             ],
895 895
             'active_status'    => [
896
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::active,
896
+                'class' => 'ee-status-legend ee-status-bg--'.EE_Datetime::active,
897 897
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
898 898
             ],
899 899
             'upcoming_status'  => [
900
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::upcoming,
900
+                'class' => 'ee-status-legend ee-status-bg--'.EE_Datetime::upcoming,
901 901
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
902 902
             ],
903 903
             'postponed_status' => [
904
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::postponed,
904
+                'class' => 'ee-status-legend ee-status-bg--'.EE_Datetime::postponed,
905 905
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
906 906
             ],
907 907
             'cancelled_status' => [
908
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::cancelled,
908
+                'class' => 'ee-status-legend ee-status-bg--'.EE_Datetime::cancelled,
909 909
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
910 910
             ],
911 911
             'expired_status'   => [
912
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::expired,
912
+                'class' => 'ee-status-legend ee-status-bg--'.EE_Datetime::expired,
913 913
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
914 914
             ],
915 915
             'inactive_status'  => [
916
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::inactive,
916
+                'class' => 'ee-status-legend ee-status-bg--'.EE_Datetime::inactive,
917 917
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
918 918
             ],
919 919
         ];
@@ -932,7 +932,7 @@  discard block
 block discarded – undo
932 932
      */
933 933
     private function _event_model(): EEM_Event
934 934
     {
935
-        if (! $this->_event_model instanceof EEM_Event) {
935
+        if ( ! $this->_event_model instanceof EEM_Event) {
936 936
             $this->_event_model = EE_Registry::instance()->load_model('Event');
937 937
         }
938 938
         return $this->_event_model;
@@ -987,12 +987,12 @@  discard block
 block discarded – undo
987 987
             '',
988 988
             'ee-admin-button-row ee-admin-button-row--align-start'
989 989
         );
990
-        $links_html       .= EEH_HTML::divx();
990
+        $links_html .= EEH_HTML::divx();
991 991
 
992 992
         $after_list_table['view_event_list_button'] = $links_html;
993 993
 
994 994
         $after_list_table['legend'] = $this->_display_legend($this->_event_legend_items());
995
-        $this->_admin_page_title    .= ' ' . $this->get_action_link_or_button(
995
+        $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
996 996
             'create_new',
997 997
             'add',
998 998
             [],
@@ -1056,13 +1056,13 @@  discard block
 block discarded – undo
1056 1056
             'EVT_timezone_string' => $this->request->getRequestParam('timezone_string'),
1057 1057
         ];
1058 1058
         // check if the new EDTR reg options meta box is being used, and if so, don't run updates for legacy version
1059
-        if (! $this->admin_config->useAdvancedEditor() || ! $this->feature->allowed('use_reg_options_meta_box')) {
1060
-            $event_values['EVT_display_ticket_selector']     = $this->request->getRequestParam(
1059
+        if ( ! $this->admin_config->useAdvancedEditor() || ! $this->feature->allowed('use_reg_options_meta_box')) {
1060
+            $event_values['EVT_display_ticket_selector'] = $this->request->getRequestParam(
1061 1061
                 'display_ticket_selector',
1062 1062
                 false,
1063 1063
                 'bool'
1064 1064
             );
1065
-            $event_values['EVT_additional_limit']            = min(
1065
+            $event_values['EVT_additional_limit'] = min(
1066 1066
                 apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1067 1067
                 $this->request->getRequestParam(
1068 1068
                     'additional_limit',
@@ -1104,14 +1104,14 @@  discard block
 block discarded – undo
1104 1104
             ]
1105 1105
         );
1106 1106
 
1107
-        if (! $event instanceof EE_Event) {
1107
+        if ( ! $event instanceof EE_Event) {
1108 1108
             return;
1109 1109
         }
1110 1110
 
1111 1111
         // the following are default callbacks for event attachment updates
1112 1112
         // that can be overridden by caffeinated functionality and/or addons.
1113 1113
         $event_update_callbacks = [];
1114
-        if (! $this->admin_config->useAdvancedEditor()) {
1114
+        if ( ! $this->admin_config->useAdvancedEditor()) {
1115 1115
             $event_update_callbacks['_default_venue_update']   = [$this, '_default_venue_update'];
1116 1116
             $event_update_callbacks['_default_tickets_update'] = [$this, '_default_tickets_update'];
1117 1117
         }
@@ -1182,7 +1182,7 @@  discard block
 block discarded – undo
1182 1182
      */
1183 1183
     protected function _default_venue_update(EE_Event $event, array $data): bool
1184 1184
     {
1185
-        require_once(EE_MODELS . 'EEM_Venue.model.php');
1185
+        require_once(EE_MODELS.'EEM_Venue.model.php');
1186 1186
         $venue_model = EE_Registry::instance()->load_model('Venue');
1187 1187
         $venue_id    = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1188 1188
         // very important.  If we don't have a venue name...
@@ -1213,7 +1213,7 @@  discard block
 block discarded – undo
1213 1213
             'status'              => 'publish',
1214 1214
         ];
1215 1215
         // if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1216
-        if (! empty($venue_id)) {
1216
+        if ( ! empty($venue_id)) {
1217 1217
             $update_where  = [$venue_model->primary_key_name() => $venue_id];
1218 1218
             $rows_affected = $venue_model->update($venue_array, [$update_where]);
1219 1219
             // we've gotta make sure that the venue is always attached to a revision..
@@ -1263,9 +1263,9 @@  discard block
 block discarded – undo
1263 1263
             ];
1264 1264
             // if we have an id then let's get existing object first and then set the new values.
1265 1265
             //  Otherwise we instantiate a new object for save.
1266
-            if (! empty($datetime_data['DTT_ID'])) {
1266
+            if ( ! empty($datetime_data['DTT_ID'])) {
1267 1267
                 $datetime = EEM_Datetime::instance($event_timezone)->get_one_by_ID($datetime_data['DTT_ID']);
1268
-                if (! $datetime instanceof EE_Datetime) {
1268
+                if ( ! $datetime instanceof EE_Datetime) {
1269 1269
                     throw new RuntimeException(
1270 1270
                         sprintf(
1271 1271
                             esc_html__(
@@ -1284,7 +1284,7 @@  discard block
 block discarded – undo
1284 1284
             } else {
1285 1285
                 $datetime = EE_Datetime::new_instance($datetime_values, $event_timezone, $date_formats);
1286 1286
             }
1287
-            if (! $datetime instanceof EE_Datetime) {
1287
+            if ( ! $datetime instanceof EE_Datetime) {
1288 1288
                 throw new RuntimeException(
1289 1289
                     sprintf(
1290 1290
                         esc_html__(
@@ -1310,7 +1310,7 @@  discard block
 block discarded – undo
1310 1310
 
1311 1311
         // set up some default start and end dates in case those are not present in the incoming data
1312 1312
         $default_start_date = new DateTime('now', new DateTimeZone($event->get_timezone()));
1313
-        $default_start_date = $default_start_date->format($date_formats[0] . ' ' . $date_formats[1]);
1313
+        $default_start_date = $default_start_date->format($date_formats[0].' '.$date_formats[1]);
1314 1314
         // use the start date of the first datetime for the end date
1315 1315
         $first_datetime   = $event->first_datetime();
1316 1316
         $default_end_date = $first_datetime->start_date_and_time($date_formats[0], $date_formats[1]);
@@ -1318,7 +1318,7 @@  discard block
 block discarded – undo
1318 1318
         // now process the incoming data
1319 1319
         foreach ($data['edit_tickets'] as $row => $ticket_data) {
1320 1320
             $update_prices = false;
1321
-            $ticket_price  = $data['edit_prices'][ $row ][1]['PRC_amount'] ?? 0;
1321
+            $ticket_price  = $data['edit_prices'][$row][1]['PRC_amount'] ?? 0;
1322 1322
             // trim inputs to ensure any excess whitespace is removed.
1323 1323
             $ticket_data   = array_map('trim', $ticket_data);
1324 1324
             $ticket_values = [
@@ -1358,9 +1358,9 @@  discard block
 block discarded – undo
1358 1358
             // ticket didn't get removed or added to any datetime in the session but DID have it's items modified.
1359 1359
             // keep in mind that if the ticket has been sold (and we have changed pricing information),
1360 1360
             // then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1361
-            if (! empty($ticket_data['TKT_ID'])) {
1361
+            if ( ! empty($ticket_data['TKT_ID'])) {
1362 1362
                 $existing_ticket = EEM_Ticket::instance($event_timezone)->get_one_by_ID($ticket_data['TKT_ID']);
1363
-                if (! $existing_ticket instanceof EE_Ticket) {
1363
+                if ( ! $existing_ticket instanceof EE_Ticket) {
1364 1364
                     throw new RuntimeException(
1365 1365
                         sprintf(
1366 1366
                             esc_html__(
@@ -1409,7 +1409,7 @@  discard block
 block discarded – undo
1409 1409
                     $existing_ticket->save();
1410 1410
                     // make sure this ticket is still recorded in our $saved_tickets
1411 1411
                     // so we don't run it through the regular trash routine.
1412
-                    $saved_tickets[ $existing_ticket->ID() ] = $existing_ticket;
1412
+                    $saved_tickets[$existing_ticket->ID()] = $existing_ticket;
1413 1413
                     // create new ticket that's a copy of the existing except,
1414 1414
                     // (a new id of course and not archived) AND has the new TKT_price associated with it.
1415 1415
                     $new_ticket = clone $existing_ticket;
@@ -1426,7 +1426,7 @@  discard block
 block discarded – undo
1426 1426
                 $ticket                     = EE_Ticket::new_instance($ticket_values, $event_timezone, $date_formats);
1427 1427
                 $update_prices              = true;
1428 1428
             }
1429
-            if (! $ticket instanceof EE_Ticket) {
1429
+            if ( ! $ticket instanceof EE_Ticket) {
1430 1430
                 throw new RuntimeException(
1431 1431
                     sprintf(
1432 1432
                         esc_html__(
@@ -1450,10 +1450,10 @@  discard block
 block discarded – undo
1450 1450
             }
1451 1451
             // initially let's add the ticket to the datetime
1452 1452
             $datetime->_add_relation_to($ticket, 'Ticket');
1453
-            $saved_tickets[ $ticket->ID() ] = $ticket;
1453
+            $saved_tickets[$ticket->ID()] = $ticket;
1454 1454
             // add prices to ticket
1455
-            $prices_data = isset($data['edit_prices'][ $row ]) && is_array($data['edit_prices'][ $row ])
1456
-                ? $data['edit_prices'][ $row ]
1455
+            $prices_data = isset($data['edit_prices'][$row]) && is_array($data['edit_prices'][$row])
1456
+                ? $data['edit_prices'][$row]
1457 1457
                 : [];
1458 1458
             $this->_add_prices_to_ticket($prices_data, $ticket, $update_prices);
1459 1459
         }
@@ -1467,7 +1467,7 @@  discard block
 block discarded – undo
1467 1467
             $id = absint($id);
1468 1468
             // get the ticket for this id
1469 1469
             $ticket_to_remove = EEM_Ticket::instance()->get_one_by_ID($id);
1470
-            if (! $ticket_to_remove instanceof EE_Ticket) {
1470
+            if ( ! $ticket_to_remove instanceof EE_Ticket) {
1471 1471
                 continue;
1472 1472
             }
1473 1473
             // need to get all the related datetimes on this ticket and remove from every single one of them
@@ -1524,7 +1524,7 @@  discard block
 block discarded – undo
1524 1524
                     $price->set($field, $new_price);
1525 1525
                 }
1526 1526
             }
1527
-            if (! $price instanceof EE_Price) {
1527
+            if ( ! $price instanceof EE_Price) {
1528 1528
                 throw new RuntimeException(
1529 1529
                     sprintf(
1530 1530
                         esc_html__(
@@ -1565,13 +1565,13 @@  discard block
 block discarded – undo
1565 1565
     {
1566 1566
         // load formatter helper
1567 1567
         // args for getting related registrations
1568
-        $approved_query_args        = [
1568
+        $approved_query_args = [
1569 1569
             [
1570 1570
                 'REG_deleted' => 0,
1571 1571
                 'STS_ID'      => RegStatus::APPROVED,
1572 1572
             ],
1573 1573
         ];
1574
-        $not_approved_query_args    = [
1574
+        $not_approved_query_args = [
1575 1575
             [
1576 1576
                 'REG_deleted' => 0,
1577 1577
                 'STS_ID'      => RegStatus::AWAITING_REVIEW,
@@ -1637,7 +1637,7 @@  discard block
 block discarded – undo
1637 1637
         $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1638 1638
         // load template
1639 1639
         EEH_Template::display_template(
1640
-            EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1640
+            EVENTS_TEMPLATE_PATH.'event_publish_box_extras.template.php',
1641 1641
             $publish_box_extra_args
1642 1642
         );
1643 1643
     }
@@ -1668,7 +1668,7 @@  discard block
 block discarded – undo
1668 1668
         $this->verify_cpt_object();
1669 1669
         $use_advanced_editor = $this->admin_config->useAdvancedEditor();
1670 1670
         // check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
1671
-        if (! $use_advanced_editor || ! $this->feature->allowed('use_reg_options_meta_box')) {
1671
+        if ( ! $use_advanced_editor || ! $this->feature->allowed('use_reg_options_meta_box')) {
1672 1672
             $this->addMetaBox(
1673 1673
                 'espresso_event_editor_event_options',
1674 1674
                 esc_html__('Event Registration Options', 'event_espresso'),
@@ -1677,7 +1677,7 @@  discard block
 block discarded – undo
1677 1677
                 'side'
1678 1678
             );
1679 1679
         }
1680
-        if (! $use_advanced_editor) {
1680
+        if ( ! $use_advanced_editor) {
1681 1681
             $this->addMetaBox(
1682 1682
                 'espresso_event_editor_tickets',
1683 1683
                 esc_html__('Event Datetime & Ticket', 'event_espresso'),
@@ -1689,7 +1689,7 @@  discard block
 block discarded – undo
1689 1689
         } elseif ($this->feature->allowed('use_reg_options_meta_box')) {
1690 1690
             add_action(
1691 1691
                 'add_meta_boxes_espresso_events',
1692
-                function () {
1692
+                function() {
1693 1693
                     global $current_screen;
1694 1694
                     remove_meta_box('authordiv', $current_screen, 'normal');
1695 1695
                 },
@@ -1718,7 +1718,7 @@  discard block
 block discarded – undo
1718 1718
             'trash_icon'        => 'dashicons dashicons-lock',
1719 1719
             'disabled'          => '',
1720 1720
         ];
1721
-        $event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1721
+        $event_id = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1722 1722
         /**
1723 1723
          * 1. Start with retrieving Datetimes
1724 1724
          * 2. Fore each datetime get related tickets
@@ -1744,24 +1744,24 @@  discard block
 block discarded – undo
1744 1744
                     'default_where_conditions' => 'none',
1745 1745
                 ]
1746 1746
             );
1747
-            if (! empty($related_tickets)) {
1747
+            if ( ! empty($related_tickets)) {
1748 1748
                 $template_args['total_ticket_rows'] = count($related_tickets);
1749 1749
                 $row                                = 0;
1750 1750
                 foreach ($related_tickets as $ticket) {
1751
-                    $existing_ticket_ids[]        = $ticket->get('TKT_ID');
1751
+                    $existing_ticket_ids[] = $ticket->get('TKT_ID');
1752 1752
                     $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1753 1753
                     $row++;
1754 1754
                 }
1755 1755
             } else {
1756 1756
                 $template_args['total_ticket_rows'] = 1;
1757 1757
                 /** @type EE_Ticket $ticket */
1758
-                $ticket                       = $ticket_model->create_default_object();
1758
+                $ticket = $ticket_model->create_default_object();
1759 1759
                 $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1760 1760
             }
1761 1761
         } else {
1762 1762
             $template_args['time'] = $times[0];
1763 1763
             /** @type EE_Ticket[] $tickets */
1764
-            $tickets                      = $ticket_model->get_all_default_tickets();
1764
+            $tickets = $ticket_model->get_all_default_tickets();
1765 1765
             $template_args['ticket_rows'] .= $this->_get_ticket_row($tickets[1]);
1766 1766
             // NOTE: we're just sending the first default row
1767 1767
             // (decaf can't manage default tickets so this should be sufficient);
@@ -1776,9 +1776,9 @@  discard block
 block discarded – undo
1776 1776
             $ticket_model->create_default_object(),
1777 1777
             true
1778 1778
         );
1779
-        $template                                  = apply_filters(
1779
+        $template = apply_filters(
1780 1780
             'FHEE__Events_Admin_Page__ticket_metabox__template',
1781
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1781
+            EVENTS_TEMPLATE_PATH.'event_tickets_metabox_main.template.php'
1782 1782
         );
1783 1783
         EEH_Template::display_template($template, $template_args);
1784 1784
     }
@@ -1798,7 +1798,7 @@  discard block
 block discarded – undo
1798 1798
     private function _get_ticket_row(EE_Ticket $ticket, bool $skeleton = false, int $row = 0): string
1799 1799
     {
1800 1800
         $template_args = [
1801
-            'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1801
+            'tkt_status_class'    => ' tkt-status-'.$ticket->ticket_status(),
1802 1802
             'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton
1803 1803
                 ? ' tkt-archived'
1804 1804
                 : '',
@@ -1811,11 +1811,11 @@  discard block
 block discarded – undo
1811 1811
             'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1812 1812
             'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1813 1813
             'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1814
-            'trash_icon'          => ($skeleton || (! $ticket->get('TKT_deleted')))
1815
-                                     && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1814
+            'trash_icon'          => ($skeleton || ( ! $ticket->get('TKT_deleted')))
1815
+                                     && ( ! empty($ticket) && $ticket->get('TKT_sold') === 0)
1816 1816
                 ? 'dashicons dashicons-post-trash clickable'
1817 1817
                 : 'dashicons dashicons-lock entity-locked',
1818
-            'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1818
+            'disabled'            => $skeleton || ( ! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1819 1819
                 : ' disabled=disabled',
1820 1820
         ];
1821 1821
 
@@ -1840,7 +1840,7 @@  discard block
 block discarded – undo
1840 1840
         }
1841 1841
         if (empty($template_args['TKT_end_date'])) {
1842 1842
             // get the earliest datetime (if present);
1843
-            $earliest_datetime             = $this->_cpt_model_obj->ID() > 0
1843
+            $earliest_datetime = $this->_cpt_model_obj->ID() > 0
1844 1844
                 ? $this->_cpt_model_obj->get_first_related(
1845 1845
                     'Datetime',
1846 1846
                     ['order_by' => ['DTT_EVT_start' => 'ASC']]
@@ -1853,7 +1853,7 @@  discard block
 block discarded – undo
1853 1853
         $template_args = array_merge($template_args, $price_args);
1854 1854
         $template      = apply_filters(
1855 1855
             'FHEE__Events_Admin_Page__get_ticket_row__template',
1856
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1856
+            EVENTS_TEMPLATE_PATH.'event_tickets_metabox_ticket_row.template.php',
1857 1857
             $ticket
1858 1858
         );
1859 1859
         return EEH_Template::display_template($template, $template_args, true);
@@ -1866,7 +1866,7 @@  discard block
 block discarded – undo
1866 1866
      */
1867 1867
     public function registration_options_meta_box()
1868 1868
     {
1869
-        $yes_no_values             = [
1869
+        $yes_no_values = [
1870 1870
             ['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1871 1871
             ['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1872 1872
         ];
@@ -1891,12 +1891,12 @@  discard block
 block discarded – undo
1891 1891
             'ee-input-width--reg',
1892 1892
             false
1893 1893
         );
1894
-        $template_args['display_description']             = EEH_Form_Fields::select_input(
1894
+        $template_args['display_description'] = EEH_Form_Fields::select_input(
1895 1895
             'display_desc',
1896 1896
             $yes_no_values,
1897 1897
             $this->_cpt_model_obj->display_description()
1898 1898
         );
1899
-        $template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1899
+        $template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
1900 1900
             'display_ticket_selector',
1901 1901
             $yes_no_values,
1902 1902
             $this->_cpt_model_obj->display_ticket_selector(),
@@ -1912,7 +1912,7 @@  discard block
 block discarded – undo
1912 1912
             $default_reg_status_values
1913 1913
         );
1914 1914
         EEH_Template::display_template(
1915
-            EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1915
+            EVENTS_TEMPLATE_PATH.'event_registration_options.template.php',
1916 1916
             $template_args
1917 1917
         );
1918 1918
     }
@@ -1935,7 +1935,7 @@  discard block
 block discarded – undo
1935 1935
     {
1936 1936
         $EEM_Event   = $this->_event_model();
1937 1937
         $offset      = ($current_page - 1) * $per_page;
1938
-        $limit       = $count ? null : $offset . ',' . $per_page;
1938
+        $limit       = $count ? null : $offset.','.$per_page;
1939 1939
         $orderby     = $this->request->getRequestParam('orderby', 'EVT_ID');
1940 1940
         $order       = $this->request->getRequestParam('order', 'DESC');
1941 1941
         $month_range = $this->request->getRequestParam('month_range');
@@ -1985,11 +1985,11 @@  discard block
 block discarded – undo
1985 1985
                                                         ->format(implode(' ', $start_formats));
1986 1986
             $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1987 1987
         }
1988
-        if (! $this->capabilities->current_user_can('ee_read_others_events', 'get_events')) {
1988
+        if ( ! $this->capabilities->current_user_can('ee_read_others_events', 'get_events')) {
1989 1989
             $where['EVT_wp_user'] = get_current_user_id();
1990 1990
         } else {
1991
-            if (! isset($where['status'])) {
1992
-                if (! $this->capabilities->current_user_can('ee_read_private_events', 'get_events')) {
1991
+            if ( ! isset($where['status'])) {
1992
+                if ( ! $this->capabilities->current_user_can('ee_read_private_events', 'get_events')) {
1993 1993
                     $where['OR'] = [
1994 1994
                         'status*restrict_private' => ['!=', 'private'],
1995 1995
                         'AND'                     => [
@@ -2011,7 +2011,7 @@  discard block
 block discarded – undo
2011 2011
         // search query handling
2012 2012
         $search_term = $this->request->getRequestParam('s');
2013 2013
         if ($search_term) {
2014
-            $search_term = '%' . $search_term . '%';
2014
+            $search_term = '%'.$search_term.'%';
2015 2015
             $where['OR'] = [
2016 2016
                 'EVT_name'       => ['LIKE', $search_term],
2017 2017
                 'EVT_desc'       => ['LIKE', $search_term],
@@ -2076,14 +2076,14 @@  discard block
 block discarded – undo
2076 2076
             "$year_r-$month_r-01 00:00:00",
2077 2077
             new DateTimeZone($timezone_string)
2078 2078
         );
2079
-        $start    = $DateTime->getTimestamp();
2079
+        $start = $DateTime->getTimestamp();
2080 2080
         // set the datetime to be the end of the month
2081 2081
         $DateTime->setDate(
2082 2082
             $year_r,
2083 2083
             $month_r,
2084 2084
             $DateTime->format('t')
2085 2085
         )->setTime(23, 59, 59);
2086
-        $end                             = $DateTime->getTimestamp();
2086
+        $end = $DateTime->getTimestamp();
2087 2087
         return ['BETWEEN', [$start, $end]];
2088 2088
     }
2089 2089
 
@@ -2149,7 +2149,7 @@  discard block
 block discarded – undo
2149 2149
             // clean status
2150 2150
             $event_status = sanitize_key($event_status);
2151 2151
             // grab status
2152
-            if (! empty($event_status)) {
2152
+            if ( ! empty($event_status)) {
2153 2153
                 $success = $this->_change_event_status($this->EVT_ID, $event_status);
2154 2154
             } else {
2155 2155
                 $success = false;
@@ -2189,7 +2189,7 @@  discard block
 block discarded – undo
2189 2189
         // clean status
2190 2190
         $event_status = sanitize_key($event_status);
2191 2191
         // grab status
2192
-        if (! empty($event_status)) {
2192
+        if ( ! empty($event_status)) {
2193 2193
             $success = true;
2194 2194
             // determine the event id and set to array.
2195 2195
             $EVT_IDs = $this->request->getRequestParam('EVT_IDs', [], 'int', true);
@@ -2235,7 +2235,7 @@  discard block
 block discarded – undo
2235 2235
     private function _change_event_status(int $EVT_ID = 0, string $event_status = ''): bool
2236 2236
     {
2237 2237
         // grab event id
2238
-        if (! $EVT_ID) {
2238
+        if ( ! $EVT_ID) {
2239 2239
             $msg = esc_html__(
2240 2240
                 'An error occurred. No Event ID or an invalid Event ID was received.',
2241 2241
                 'event_espresso'
@@ -2272,7 +2272,7 @@  discard block
 block discarded – undo
2272 2272
         // use class to change status
2273 2273
         $this->_cpt_model_obj->set_status($event_status);
2274 2274
         $success = $this->_cpt_model_obj->save();
2275
-        if (! $success) {
2275
+        if ( ! $success) {
2276 2276
             $msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2277 2277
             EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2278 2278
             return false;
@@ -2339,7 +2339,7 @@  discard block
 block discarded – undo
2339 2339
      */
2340 2340
     protected function getModelObjNodeGroupPersister(): NodeGroupDao
2341 2341
     {
2342
-        if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2342
+        if ( ! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2343 2343
             $this->model_obj_node_group_persister =
2344 2344
                 $this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2345 2345
         }
@@ -2664,7 +2664,7 @@  discard block
 block discarded – undo
2664 2664
                                                 . esc_html__(
2665 2665
                                                     'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.',
2666 2666
                                                     'event_espresso'
2667
-                                                ) . '</strong>';
2667
+                                                ).'</strong>';
2668 2668
         $this->display_admin_caf_preview_page('template_settings_tab');
2669 2669
     }
2670 2670
 
@@ -2685,11 +2685,11 @@  discard block
 block discarded – undo
2685 2685
         $this->_set_empty_category_object();
2686 2686
         // only set if we've got an id
2687 2687
         $category_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
2688
-        if (! $category_ID) {
2688
+        if ( ! $category_ID) {
2689 2689
             return;
2690 2690
         }
2691 2691
         $term = get_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2692
-        if (! empty($term)) {
2692
+        if ( ! empty($term)) {
2693 2693
             $this->_category->category_name       = $term->name;
2694 2694
             $this->_category->category_identifier = $term->slug;
2695 2695
             $this->_category->category_desc       = $term->description;
@@ -2790,7 +2790,7 @@  discard block
 block discarded – undo
2790 2790
             $category_select_values,
2791 2791
             $this->_category->parent
2792 2792
         );
2793
-        $template_args   = [
2793
+        $template_args = [
2794 2794
             'category'                 => $this->_category,
2795 2795
             'category_select'          => $category_select,
2796 2796
             'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
@@ -2798,7 +2798,7 @@  discard block
 block discarded – undo
2798 2798
             'disable'                  => '',
2799 2799
             'disabled_message'         => false,
2800 2800
         ];
2801
-        $template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2801
+        $template = EVENTS_TEMPLATE_PATH.'event_category_details.template.php';
2802 2802
         return EEH_Template::display_template($template, $template_args, true);
2803 2803
     }
2804 2804
 
@@ -2894,7 +2894,7 @@  discard block
 block discarded – undo
2894 2894
             return 0;
2895 2895
         }
2896 2896
         $category_ID = $insert_ids['term_id'] ?? 0;
2897
-        if (! $category_ID) {
2897
+        if ( ! $category_ID) {
2898 2898
             EE_Error::add_error(
2899 2899
                 esc_html__(
2900 2900
                     'An error occurred and the category has not been saved to the database.',
@@ -2935,7 +2935,7 @@  discard block
 block discarded – undo
2935 2935
         $where       = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2936 2936
         $search_term = $this->request->getRequestParam('s');
2937 2937
         if ($search_term) {
2938
-            $search_term = '%' . $search_term . '%';
2938
+            $search_term = '%'.$search_term.'%';
2939 2939
             $where['OR'] = [
2940 2940
                 'Term.name'   => ['LIKE', $search_term],
2941 2941
                 'description' => ['LIKE', $search_term],
@@ -2944,7 +2944,7 @@  discard block
 block discarded – undo
2944 2944
         $query_params = [
2945 2945
             $where,
2946 2946
             'order_by'   => [$orderby => $order],
2947
-            'limit'      => $limit . ',' . $per_page,
2947
+            'limit'      => $limit.','.$per_page,
2948 2948
             'force_join' => ['Term'],
2949 2949
         ];
2950 2950
         return $count
@@ -2968,7 +2968,7 @@  discard block
 block discarded – undo
2968 2968
      */
2969 2969
     public function saveTimezoneString()
2970 2970
     {
2971
-        if (! $this->capabilities->current_user_can('manage_options', __FUNCTION__)) {
2971
+        if ( ! $this->capabilities->current_user_can('manage_options', __FUNCTION__)) {
2972 2972
             wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
2973 2973
         }
2974 2974
         $timezone_string = $this->request->getRequestParam('timezone_selected');
Please login to merge, or discard this patch.
admin/extend/registrations/Extend_Registrations_Admin_Page.core.php 2 patches
Indentation   +1278 added lines, -1278 removed lines patch added patch discarded remove patch
@@ -16,1289 +16,1289 @@
 block discarded – undo
16 16
  */
17 17
 class Extend_Registrations_Admin_Page extends Registrations_Admin_Page
18 18
 {
19
-    /**
20
-     * This is used to hold the reports template data which is setup early in the request.
21
-     *
22
-     * @type array
23
-     */
24
-    protected array $_reports_template_data = [];
25
-
26
-
27
-    /**
28
-     * Extend_Registrations_Admin_Page constructor.
29
-     *
30
-     * @param bool $routing
31
-     * @throws ReflectionException
32
-     */
33
-    public function __construct($routing = true)
34
-    {
35
-        parent::__construct($routing);
36
-        if (! defined('REG_CAF_TEMPLATE_PATH')) {
37
-            define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/templates/');
38
-            define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/assets/');
39
-            define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registrations/assets/');
40
-        }
41
-    }
42
-
43
-
44
-    protected function _set_page_config()
45
-    {
46
-        parent::_set_page_config();
47
-
48
-        $this->_admin_base_path                           = EE_CORE_CAF_ADMIN_EXTEND . 'registrations';
49
-        $reg_id                                           =
50
-            ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
51
-                ? $this->_req_data['_REG_ID']
52
-                : 0;
53
-        $new_page_routes                                  = [
54
-            'reports'                      => [
55
-                'func'       => [$this, '_registration_reports'],
56
-                'capability' => 'ee_read_registrations',
57
-            ],
58
-            'registration_checkins'        => [
59
-                'func'       => [$this, '_registration_checkin_list_table'],
60
-                'capability' => 'ee_read_checkins',
61
-            ],
62
-            'newsletter_selected_send'     => [
63
-                'func'       => [$this, '_newsletter_selected_send'],
64
-                'noheader'   => true,
65
-                'capability' => 'ee_send_message',
66
-            ],
67
-            'delete_checkin_rows'          => [
68
-                'func'       => [$this, '_delete_checkin_rows'],
69
-                'noheader'   => true,
70
-                'capability' => 'ee_delete_checkins',
71
-            ],
72
-            'delete_checkin_row'           => [
73
-                'func'       => [$this, '_delete_checkin_row'],
74
-                'noheader'   => true,
75
-                'capability' => 'ee_delete_checkin',
76
-                'obj_id'     => $reg_id,
77
-            ],
78
-            'toggle_checkin_status'        => [
79
-                'func'       => [$this, '_toggle_checkin_status'],
80
-                'noheader'   => true,
81
-                'capability' => 'ee_edit_checkin',
82
-                'obj_id'     => $reg_id,
83
-            ],
84
-            'toggle_checkin_status_bulk'   => [
85
-                'func'       => [$this, '_toggle_checkin_status'],
86
-                'noheader'   => true,
87
-                'capability' => 'ee_edit_checkins',
88
-            ],
89
-            'event_registrations'          => [
90
-                'func'       => [$this, '_event_registrations_list_table'],
91
-                'capability' => 'ee_read_checkins',
92
-            ],
93
-            'registrations_checkin_report' => [
94
-                'func'       => [$this, '_registrations_checkin_report'],
95
-                'noheader'   => true,
96
-                'capability' => 'ee_read_registrations',
97
-            ],
98
-        ];
99
-        $this->_page_routes                               = array_merge($this->_page_routes, $new_page_routes);
100
-        $new_page_config                                  = [
101
-            'reports'               => [
102
-                'nav'           => [
103
-                    'label' => esc_html__('Reports', 'event_espresso'),
104
-                    'icon'  => 'dashicons-chart-bar',
105
-                    'order' => 30,
106
-                ],
107
-                'help_tabs'     => [
108
-                    'registrations_reports_help_tab' => [
109
-                        'title'    => esc_html__('Registration Reports', 'event_espresso'),
110
-                        'filename' => 'registrations_reports',
111
-                    ],
112
-                ],
113
-                'require_nonce' => false,
114
-            ],
115
-            'event_registrations'   => [
116
-                'nav'           => [
117
-                    'label'      => esc_html__('Event Check-In', 'event_espresso'),
118
-                    'icon'       => 'dashicons-yes-alt',
119
-                    'order'      => 10,
120
-                    'persistent' => true,
121
-                ],
122
-                'help_tabs'     => [
123
-                    'registrations_event_checkin_help_tab'                       => [
124
-                        'title'    => esc_html__('Registrations Event Check-In', 'event_espresso'),
125
-                        'filename' => 'registrations_event_checkin',
126
-                    ],
127
-                    'registrations_event_checkin_table_column_headings_help_tab' => [
128
-                        'title'    => esc_html__('Event Check-In Table Column Headings', 'event_espresso'),
129
-                        'filename' => 'registrations_event_checkin_table_column_headings',
130
-                    ],
131
-                    'registrations_event_checkin_filters_help_tab'               => [
132
-                        'title'    => esc_html__('Event Check-In Filters', 'event_espresso'),
133
-                        'filename' => 'registrations_event_checkin_filters',
134
-                    ],
135
-                    'registrations_event_checkin_views_help_tab'                 => [
136
-                        'title'    => esc_html__('Event Check-In Views', 'event_espresso'),
137
-                        'filename' => 'registrations_event_checkin_views',
138
-                    ],
139
-                    'registrations_event_checkin_other_help_tab'                 => [
140
-                        'title'    => esc_html__('Event Check-In Other', 'event_espresso'),
141
-                        'filename' => 'registrations_event_checkin_other',
142
-                    ],
143
-                ],
144
-                'list_table'    => 'EE_Event_Registrations_List_Table',
145
-                'metaboxes'     => [],
146
-                'require_nonce' => false,
147
-            ],
148
-            'registration_checkins' => [
149
-                'nav'           => [
150
-                    'label'      => esc_html__('Check-In Records', 'event_espresso'),
151
-                    'icon'       => 'dashicons-list-view',
152
-                    'order'      => 15,
153
-                    'persistent' => false,
154
-                    'url'        => '',
155
-                ],
156
-                'list_table'    => 'EE_Registration_CheckIn_List_Table',
157
-                'metaboxes'     => [],
158
-                'require_nonce' => false,
159
-            ],
160
-        ];
161
-        $this->_page_config                               = array_merge($this->_page_config, $new_page_config);
162
-        $this->_page_config['contact_list']['list_table'] = 'Extend_EE_Attendee_Contact_List_Table';
163
-        $this->_page_config['default']['list_table']      = 'Extend_EE_Registrations_List_Table';
164
-    }
165
-
166
-
167
-    /**
168
-     * Ajax hooks for all routes in this page.
169
-     */
170
-    protected function _ajax_hooks()
171
-    {
172
-        parent::_ajax_hooks();
173
-        add_action('wp_ajax_get_newsletter_form_content', [$this, 'get_newsletter_form_content']);
174
-        add_action('wp_ajax_toggle_checkin_status', [$this, 'toggle_checkin_status']);
175
-    }
176
-
177
-
178
-    /**
179
-     * Global scripts for all routes in this page.
180
-     *
181
-     * @throws EE_Error
182
-     * *@throws ReflectionException
183
-     */
184
-    public function load_scripts_styles()
185
-    {
186
-        parent::load_scripts_styles();
187
-        // if newsletter message type is active then let's add filter and load js for it.
188
-        if (EEH_MSG_Template::is_mt_active('newsletter')) {
189
-            wp_enqueue_style(
190
-                'ee_message_shortcodes',
191
-                EE_MSG_ASSETS_URL . 'ee_message_shortcodes.css',
192
-                [EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_ADMIN],
193
-                EVENT_ESPRESSO_VERSION
194
-            );
195
-            // enqueue newsletter js
196
-            wp_enqueue_script(
197
-                'ee-newsletter-trigger',
198
-                REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.js',
199
-                ['ee-dialog'],
200
-                EVENT_ESPRESSO_VERSION,
201
-                true
202
-            );
203
-            // hook in buttons for newsletter message type trigger.
204
-            add_action(
205
-                'AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons',
206
-                [$this, 'add_newsletter_action_buttons']
207
-            );
208
-        }
209
-    }
210
-
211
-
212
-    /**
213
-     * Scripts and styles for just the reports route.
214
-     *
215
-     * @throws EE_Error
216
-     * @throws ReflectionException
217
-     */
218
-    public function load_scripts_styles_reports()
219
-    {
220
-        wp_register_script(
221
-            'ee-reg-reports-js',
222
-            REG_CAF_ASSETS_URL . 'ee-registration-admin-reports.js',
223
-            ['google-charts'],
224
-            EVENT_ESPRESSO_VERSION,
225
-            true
226
-        );
227
-        wp_enqueue_script('ee-reg-reports-js');
228
-        $this->_registration_reports_js_setup();
229
-    }
230
-
231
-
232
-    /**
233
-     * Register screen options for event_registrations route.
234
-     */
235
-    protected function _add_screen_options_event_registrations()
236
-    {
237
-        $this->_per_page_screen_option();
238
-    }
239
-
240
-
241
-    /**
242
-     * Register screen options for registration_checkins route
243
-     */
244
-    protected function _add_screen_options_registration_checkins()
245
-    {
246
-        $page_title              = $this->_admin_page_title;
247
-        $this->_admin_page_title = esc_html__('Check-In Records', 'event_espresso');
248
-        $this->_per_page_screen_option();
249
-        $this->_admin_page_title = $page_title;
250
-    }
251
-
252
-
253
-    /**
254
-     * Set views property for event_registrations route.
255
-     */
256
-    protected function _set_list_table_views_event_registrations()
257
-    {
258
-        $DTT_ID = $this->request->getRequestParam('DTT_ID', 0, DataType::INTEGER);
259
-        $this->_views = [
260
-            'all' => [
261
-                'slug'        => 'all',
262
-                'label'       => esc_html__('All', 'event_espresso'),
263
-                'count'       => 0,
264
-                'bulk_action' => $DTT_ID
265
-                    ? ['toggle_checkin_status_bulk' => esc_html__('Toggle Check-In', 'event_espresso')]
266
-                    : [],
267
-            ],
268
-        ];
269
-    }
270
-
271
-
272
-    /**
273
-     * Set views property for registration_checkins route.
274
-     */
275
-    protected function _set_list_table_views_registration_checkins()
276
-    {
277
-        $this->_views = [
278
-            'all' => [
279
-                'slug'        => 'all',
280
-                'label'       => esc_html__('All', 'event_espresso'),
281
-                'count'       => 0,
282
-                'bulk_action' => ['delete_checkin_rows' => esc_html__('Delete Check-In Rows', 'event_espresso')],
283
-            ],
284
-        ];
285
-    }
286
-
287
-
288
-    /**
289
-     * callback for ajax action.
290
-     *
291
-     * @return void (JSON)
292
-     * @throws EE_Error
293
-     * @throws ReflectionException
294
-     * @since 4.3.0
295
-     */
296
-    public function get_newsletter_form_content()
297
-    {
298
-        if (! $this->capabilities->current_user_can('ee_read_messages', __FUNCTION__)) {
299
-            wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
300
-        }
301
-        // do a nonce check because we're not coming in from a normal route here.
302
-        $nonce     = isset($this->_req_data['get_newsletter_form_content_nonce']) ? sanitize_text_field(
303
-            $this->_req_data['get_newsletter_form_content_nonce']
304
-        ) : '';
305
-        $nonce_ref = 'get_newsletter_form_content_nonce';
306
-        $this->_verify_nonce($nonce, $nonce_ref);
307
-        // let's get the mtp for the incoming MTP_ ID
308
-        if (! isset($this->_req_data['GRP_ID'])) {
309
-            EE_Error::add_error(
310
-                esc_html__(
311
-                    'There must be something broken with the js or html structure because the required data for getting a message template group is not present (need an GRP_ID).',
312
-                    'event_espresso'
313
-                ),
314
-                __FILE__,
315
-                __FUNCTION__,
316
-                __LINE__
317
-            );
318
-            $this->_template_args['success'] = false;
319
-            $this->_template_args['error']   = true;
320
-            $this->_return_json();
321
-        }
322
-        $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID($this->_req_data['GRP_ID']);
323
-        if (! $MTPG instanceof EE_Message_Template_Group) {
324
-            EE_Error::add_error(
325
-                sprintf(
326
-                    esc_html__(
327
-                        'The GRP_ID given (%d) does not appear to have a corresponding row in the database.',
328
-                        'event_espresso'
329
-                    ),
330
-                    $this->_req_data['GRP_ID']
331
-                ),
332
-                __FILE__,
333
-                __FUNCTION__,
334
-                __LINE__
335
-            );
336
-            $this->_template_args['success'] = false;
337
-            $this->_template_args['error']   = true;
338
-            $this->_return_json();
339
-        }
340
-        $MTPs            = $MTPG->context_templates();
341
-        $MTPs            = $MTPs['attendee'];
342
-        $template_fields = [];
343
-        /** @var EE_Message_Template $MTP */
344
-        foreach ($MTPs as $MTP) {
345
-            $field = $MTP->get('MTP_template_field');
346
-            if ($field === 'content') {
347
-                $content = $MTP->get('MTP_content');
348
-                if (! empty($content['newsletter_content'])) {
349
-                    $template_fields['newsletter_content'] = $content['newsletter_content'];
350
-                }
351
-                continue;
352
-            }
353
-            $template_fields[ $MTP->get('MTP_template_field') ] = $MTP->get('MTP_content');
354
-        }
355
-        $this->_template_args['success'] = true;
356
-        $this->_template_args['error']   = false;
357
-        $this->_template_args['data']    = [
358
-            'batch_message_from'    => $template_fields['from'] ?? '',
359
-            'batch_message_subject' => $template_fields['subject'] ?? '',
360
-            'batch_message_content' => $template_fields['newsletter_content'] ?? '',
361
-        ];
362
-        $this->_return_json();
363
-    }
364
-
365
-
366
-    /**
367
-     * callback for AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons action
368
-     *
369
-     * @param EE_Admin_List_Table $list_table
370
-     * @return void
371
-     * @since 4.3.0
372
-     */
373
-    public function add_newsletter_action_buttons(EE_Admin_List_Table $list_table)
374
-    {
375
-        if (
376
-            ! EE_Registry::instance()->CAP->current_user_can(
377
-                'ee_send_message',
378
-                'espresso_registrations_newsletter_selected_send'
379
-            )
380
-        ) {
381
-            return;
382
-        }
383
-        $routes_to_add_to = [
384
-            'contact_list',
385
-            'event_registrations',
386
-            'default',
387
-        ];
388
-        if ($this->_current_page === 'espresso_registrations' && in_array($this->_req_action, $routes_to_add_to)) {
389
-            if (
390
-                ($this->_req_action === 'event_registrations' && empty($this->_req_data['event_id']))
391
-                || (isset($this->_req_data['status']) && $this->_req_data['status'] === 'trash')
392
-            ) {
393
-                echo '';
394
-            } else {
395
-                $button_text = sprintf(
396
-                    esc_html__('Send Batch Message (%s selected)', 'event_espresso'),
397
-                    '<span class="send-selected-newsletter-count">0</span>'
398
-                );
399
-                echo '<button id="selected-batch-send-trigger" class="button button--secondary">'
400
-                    . '<span class="dashicons dashicons-email "></span>'
401
-                    . $button_text
402
-                    . '</button>';
403
-                add_action('admin_footer', [$this, 'newsletter_send_form_skeleton']);
404
-            }
405
-        }
406
-    }
407
-
408
-
409
-    /**
410
-     * @throws DomainException
411
-     * @throws EE_Error
412
-     * @throws ReflectionException
413
-     */
414
-    public function newsletter_send_form_skeleton()
415
-    {
416
-        $list_table = $this->_list_table_object;
417
-        $codes      = [];
418
-        // need to templates for the newsletter message type for the template selector.
419
-        $values[] = ['text' => esc_html__('Select Template to Use', 'event_espresso'), 'id' => 0];
420
-        $mtps     = EEM_Message_Template_Group::instance()->get_all(
421
-            [['MTP_message_type' => 'newsletter', 'MTP_messenger' => 'email']]
422
-        );
423
-        foreach ($mtps as $mtp) {
424
-            $name     = $mtp->name();
425
-            $values[] = [
426
-                'text' => empty($name) ? esc_html__('Global', 'event_espresso') : $name,
427
-                'id'   => $mtp->ID(),
428
-            ];
429
-        }
430
-        // need to get a list of shortcodes that are available for the newsletter message type.
431
-        $shortcodes = EEH_MSG_Template::get_shortcodes(
432
-            'newsletter',
433
-            'email',
434
-            [],
435
-            'attendee'
436
-        );
437
-
438
-        foreach ($shortcodes as $field => $shortcode_array) {
439
-            $available_shortcodes = [];
440
-            foreach ($shortcode_array as $shortcode => $shortcode_details) {
441
-                $field_id               = $field === '[NEWSLETTER_CONTENT]'
442
-                    ? 'content'
443
-                    : strtolower($field);
444
-                $field_id               = "batch-message-$field_id";
445
-                $available_shortcodes[] = '
19
+	/**
20
+	 * This is used to hold the reports template data which is setup early in the request.
21
+	 *
22
+	 * @type array
23
+	 */
24
+	protected array $_reports_template_data = [];
25
+
26
+
27
+	/**
28
+	 * Extend_Registrations_Admin_Page constructor.
29
+	 *
30
+	 * @param bool $routing
31
+	 * @throws ReflectionException
32
+	 */
33
+	public function __construct($routing = true)
34
+	{
35
+		parent::__construct($routing);
36
+		if (! defined('REG_CAF_TEMPLATE_PATH')) {
37
+			define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/templates/');
38
+			define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/assets/');
39
+			define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registrations/assets/');
40
+		}
41
+	}
42
+
43
+
44
+	protected function _set_page_config()
45
+	{
46
+		parent::_set_page_config();
47
+
48
+		$this->_admin_base_path                           = EE_CORE_CAF_ADMIN_EXTEND . 'registrations';
49
+		$reg_id                                           =
50
+			! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
51
+				? $this->_req_data['_REG_ID']
52
+				: 0;
53
+		$new_page_routes                                  = [
54
+			'reports'                      => [
55
+				'func'       => [$this, '_registration_reports'],
56
+				'capability' => 'ee_read_registrations',
57
+			],
58
+			'registration_checkins'        => [
59
+				'func'       => [$this, '_registration_checkin_list_table'],
60
+				'capability' => 'ee_read_checkins',
61
+			],
62
+			'newsletter_selected_send'     => [
63
+				'func'       => [$this, '_newsletter_selected_send'],
64
+				'noheader'   => true,
65
+				'capability' => 'ee_send_message',
66
+			],
67
+			'delete_checkin_rows'          => [
68
+				'func'       => [$this, '_delete_checkin_rows'],
69
+				'noheader'   => true,
70
+				'capability' => 'ee_delete_checkins',
71
+			],
72
+			'delete_checkin_row'           => [
73
+				'func'       => [$this, '_delete_checkin_row'],
74
+				'noheader'   => true,
75
+				'capability' => 'ee_delete_checkin',
76
+				'obj_id'     => $reg_id,
77
+			],
78
+			'toggle_checkin_status'        => [
79
+				'func'       => [$this, '_toggle_checkin_status'],
80
+				'noheader'   => true,
81
+				'capability' => 'ee_edit_checkin',
82
+				'obj_id'     => $reg_id,
83
+			],
84
+			'toggle_checkin_status_bulk'   => [
85
+				'func'       => [$this, '_toggle_checkin_status'],
86
+				'noheader'   => true,
87
+				'capability' => 'ee_edit_checkins',
88
+			],
89
+			'event_registrations'          => [
90
+				'func'       => [$this, '_event_registrations_list_table'],
91
+				'capability' => 'ee_read_checkins',
92
+			],
93
+			'registrations_checkin_report' => [
94
+				'func'       => [$this, '_registrations_checkin_report'],
95
+				'noheader'   => true,
96
+				'capability' => 'ee_read_registrations',
97
+			],
98
+		];
99
+		$this->_page_routes                               = array_merge($this->_page_routes, $new_page_routes);
100
+		$new_page_config                                  = [
101
+			'reports'               => [
102
+				'nav'           => [
103
+					'label' => esc_html__('Reports', 'event_espresso'),
104
+					'icon'  => 'dashicons-chart-bar',
105
+					'order' => 30,
106
+				],
107
+				'help_tabs'     => [
108
+					'registrations_reports_help_tab' => [
109
+						'title'    => esc_html__('Registration Reports', 'event_espresso'),
110
+						'filename' => 'registrations_reports',
111
+					],
112
+				],
113
+				'require_nonce' => false,
114
+			],
115
+			'event_registrations'   => [
116
+				'nav'           => [
117
+					'label'      => esc_html__('Event Check-In', 'event_espresso'),
118
+					'icon'       => 'dashicons-yes-alt',
119
+					'order'      => 10,
120
+					'persistent' => true,
121
+				],
122
+				'help_tabs'     => [
123
+					'registrations_event_checkin_help_tab'                       => [
124
+						'title'    => esc_html__('Registrations Event Check-In', 'event_espresso'),
125
+						'filename' => 'registrations_event_checkin',
126
+					],
127
+					'registrations_event_checkin_table_column_headings_help_tab' => [
128
+						'title'    => esc_html__('Event Check-In Table Column Headings', 'event_espresso'),
129
+						'filename' => 'registrations_event_checkin_table_column_headings',
130
+					],
131
+					'registrations_event_checkin_filters_help_tab'               => [
132
+						'title'    => esc_html__('Event Check-In Filters', 'event_espresso'),
133
+						'filename' => 'registrations_event_checkin_filters',
134
+					],
135
+					'registrations_event_checkin_views_help_tab'                 => [
136
+						'title'    => esc_html__('Event Check-In Views', 'event_espresso'),
137
+						'filename' => 'registrations_event_checkin_views',
138
+					],
139
+					'registrations_event_checkin_other_help_tab'                 => [
140
+						'title'    => esc_html__('Event Check-In Other', 'event_espresso'),
141
+						'filename' => 'registrations_event_checkin_other',
142
+					],
143
+				],
144
+				'list_table'    => 'EE_Event_Registrations_List_Table',
145
+				'metaboxes'     => [],
146
+				'require_nonce' => false,
147
+			],
148
+			'registration_checkins' => [
149
+				'nav'           => [
150
+					'label'      => esc_html__('Check-In Records', 'event_espresso'),
151
+					'icon'       => 'dashicons-list-view',
152
+					'order'      => 15,
153
+					'persistent' => false,
154
+					'url'        => '',
155
+				],
156
+				'list_table'    => 'EE_Registration_CheckIn_List_Table',
157
+				'metaboxes'     => [],
158
+				'require_nonce' => false,
159
+			],
160
+		];
161
+		$this->_page_config                               = array_merge($this->_page_config, $new_page_config);
162
+		$this->_page_config['contact_list']['list_table'] = 'Extend_EE_Attendee_Contact_List_Table';
163
+		$this->_page_config['default']['list_table']      = 'Extend_EE_Registrations_List_Table';
164
+	}
165
+
166
+
167
+	/**
168
+	 * Ajax hooks for all routes in this page.
169
+	 */
170
+	protected function _ajax_hooks()
171
+	{
172
+		parent::_ajax_hooks();
173
+		add_action('wp_ajax_get_newsletter_form_content', [$this, 'get_newsletter_form_content']);
174
+		add_action('wp_ajax_toggle_checkin_status', [$this, 'toggle_checkin_status']);
175
+	}
176
+
177
+
178
+	/**
179
+	 * Global scripts for all routes in this page.
180
+	 *
181
+	 * @throws EE_Error
182
+	 * *@throws ReflectionException
183
+	 */
184
+	public function load_scripts_styles()
185
+	{
186
+		parent::load_scripts_styles();
187
+		// if newsletter message type is active then let's add filter and load js for it.
188
+		if (EEH_MSG_Template::is_mt_active('newsletter')) {
189
+			wp_enqueue_style(
190
+				'ee_message_shortcodes',
191
+				EE_MSG_ASSETS_URL . 'ee_message_shortcodes.css',
192
+				[EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_ADMIN],
193
+				EVENT_ESPRESSO_VERSION
194
+			);
195
+			// enqueue newsletter js
196
+			wp_enqueue_script(
197
+				'ee-newsletter-trigger',
198
+				REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.js',
199
+				['ee-dialog'],
200
+				EVENT_ESPRESSO_VERSION,
201
+				true
202
+			);
203
+			// hook in buttons for newsletter message type trigger.
204
+			add_action(
205
+				'AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons',
206
+				[$this, 'add_newsletter_action_buttons']
207
+			);
208
+		}
209
+	}
210
+
211
+
212
+	/**
213
+	 * Scripts and styles for just the reports route.
214
+	 *
215
+	 * @throws EE_Error
216
+	 * @throws ReflectionException
217
+	 */
218
+	public function load_scripts_styles_reports()
219
+	{
220
+		wp_register_script(
221
+			'ee-reg-reports-js',
222
+			REG_CAF_ASSETS_URL . 'ee-registration-admin-reports.js',
223
+			['google-charts'],
224
+			EVENT_ESPRESSO_VERSION,
225
+			true
226
+		);
227
+		wp_enqueue_script('ee-reg-reports-js');
228
+		$this->_registration_reports_js_setup();
229
+	}
230
+
231
+
232
+	/**
233
+	 * Register screen options for event_registrations route.
234
+	 */
235
+	protected function _add_screen_options_event_registrations()
236
+	{
237
+		$this->_per_page_screen_option();
238
+	}
239
+
240
+
241
+	/**
242
+	 * Register screen options for registration_checkins route
243
+	 */
244
+	protected function _add_screen_options_registration_checkins()
245
+	{
246
+		$page_title              = $this->_admin_page_title;
247
+		$this->_admin_page_title = esc_html__('Check-In Records', 'event_espresso');
248
+		$this->_per_page_screen_option();
249
+		$this->_admin_page_title = $page_title;
250
+	}
251
+
252
+
253
+	/**
254
+	 * Set views property for event_registrations route.
255
+	 */
256
+	protected function _set_list_table_views_event_registrations()
257
+	{
258
+		$DTT_ID = $this->request->getRequestParam('DTT_ID', 0, DataType::INTEGER);
259
+		$this->_views = [
260
+			'all' => [
261
+				'slug'        => 'all',
262
+				'label'       => esc_html__('All', 'event_espresso'),
263
+				'count'       => 0,
264
+				'bulk_action' => $DTT_ID
265
+					? ['toggle_checkin_status_bulk' => esc_html__('Toggle Check-In', 'event_espresso')]
266
+					: [],
267
+			],
268
+		];
269
+	}
270
+
271
+
272
+	/**
273
+	 * Set views property for registration_checkins route.
274
+	 */
275
+	protected function _set_list_table_views_registration_checkins()
276
+	{
277
+		$this->_views = [
278
+			'all' => [
279
+				'slug'        => 'all',
280
+				'label'       => esc_html__('All', 'event_espresso'),
281
+				'count'       => 0,
282
+				'bulk_action' => ['delete_checkin_rows' => esc_html__('Delete Check-In Rows', 'event_espresso')],
283
+			],
284
+		];
285
+	}
286
+
287
+
288
+	/**
289
+	 * callback for ajax action.
290
+	 *
291
+	 * @return void (JSON)
292
+	 * @throws EE_Error
293
+	 * @throws ReflectionException
294
+	 * @since 4.3.0
295
+	 */
296
+	public function get_newsletter_form_content()
297
+	{
298
+		if (! $this->capabilities->current_user_can('ee_read_messages', __FUNCTION__)) {
299
+			wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
300
+		}
301
+		// do a nonce check because we're not coming in from a normal route here.
302
+		$nonce     = isset($this->_req_data['get_newsletter_form_content_nonce']) ? sanitize_text_field(
303
+			$this->_req_data['get_newsletter_form_content_nonce']
304
+		) : '';
305
+		$nonce_ref = 'get_newsletter_form_content_nonce';
306
+		$this->_verify_nonce($nonce, $nonce_ref);
307
+		// let's get the mtp for the incoming MTP_ ID
308
+		if (! isset($this->_req_data['GRP_ID'])) {
309
+			EE_Error::add_error(
310
+				esc_html__(
311
+					'There must be something broken with the js or html structure because the required data for getting a message template group is not present (need an GRP_ID).',
312
+					'event_espresso'
313
+				),
314
+				__FILE__,
315
+				__FUNCTION__,
316
+				__LINE__
317
+			);
318
+			$this->_template_args['success'] = false;
319
+			$this->_template_args['error']   = true;
320
+			$this->_return_json();
321
+		}
322
+		$MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID($this->_req_data['GRP_ID']);
323
+		if (! $MTPG instanceof EE_Message_Template_Group) {
324
+			EE_Error::add_error(
325
+				sprintf(
326
+					esc_html__(
327
+						'The GRP_ID given (%d) does not appear to have a corresponding row in the database.',
328
+						'event_espresso'
329
+					),
330
+					$this->_req_data['GRP_ID']
331
+				),
332
+				__FILE__,
333
+				__FUNCTION__,
334
+				__LINE__
335
+			);
336
+			$this->_template_args['success'] = false;
337
+			$this->_template_args['error']   = true;
338
+			$this->_return_json();
339
+		}
340
+		$MTPs            = $MTPG->context_templates();
341
+		$MTPs            = $MTPs['attendee'];
342
+		$template_fields = [];
343
+		/** @var EE_Message_Template $MTP */
344
+		foreach ($MTPs as $MTP) {
345
+			$field = $MTP->get('MTP_template_field');
346
+			if ($field === 'content') {
347
+				$content = $MTP->get('MTP_content');
348
+				if (! empty($content['newsletter_content'])) {
349
+					$template_fields['newsletter_content'] = $content['newsletter_content'];
350
+				}
351
+				continue;
352
+			}
353
+			$template_fields[ $MTP->get('MTP_template_field') ] = $MTP->get('MTP_content');
354
+		}
355
+		$this->_template_args['success'] = true;
356
+		$this->_template_args['error']   = false;
357
+		$this->_template_args['data']    = [
358
+			'batch_message_from'    => $template_fields['from'] ?? '',
359
+			'batch_message_subject' => $template_fields['subject'] ?? '',
360
+			'batch_message_content' => $template_fields['newsletter_content'] ?? '',
361
+		];
362
+		$this->_return_json();
363
+	}
364
+
365
+
366
+	/**
367
+	 * callback for AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons action
368
+	 *
369
+	 * @param EE_Admin_List_Table $list_table
370
+	 * @return void
371
+	 * @since 4.3.0
372
+	 */
373
+	public function add_newsletter_action_buttons(EE_Admin_List_Table $list_table)
374
+	{
375
+		if (
376
+			! EE_Registry::instance()->CAP->current_user_can(
377
+				'ee_send_message',
378
+				'espresso_registrations_newsletter_selected_send'
379
+			)
380
+		) {
381
+			return;
382
+		}
383
+		$routes_to_add_to = [
384
+			'contact_list',
385
+			'event_registrations',
386
+			'default',
387
+		];
388
+		if ($this->_current_page === 'espresso_registrations' && in_array($this->_req_action, $routes_to_add_to)) {
389
+			if (
390
+				($this->_req_action === 'event_registrations' && empty($this->_req_data['event_id']))
391
+				|| (isset($this->_req_data['status']) && $this->_req_data['status'] === 'trash')
392
+			) {
393
+				echo '';
394
+			} else {
395
+				$button_text = sprintf(
396
+					esc_html__('Send Batch Message (%s selected)', 'event_espresso'),
397
+					'<span class="send-selected-newsletter-count">0</span>'
398
+				);
399
+				echo '<button id="selected-batch-send-trigger" class="button button--secondary">'
400
+					. '<span class="dashicons dashicons-email "></span>'
401
+					. $button_text
402
+					. '</button>';
403
+				add_action('admin_footer', [$this, 'newsletter_send_form_skeleton']);
404
+			}
405
+		}
406
+	}
407
+
408
+
409
+	/**
410
+	 * @throws DomainException
411
+	 * @throws EE_Error
412
+	 * @throws ReflectionException
413
+	 */
414
+	public function newsletter_send_form_skeleton()
415
+	{
416
+		$list_table = $this->_list_table_object;
417
+		$codes      = [];
418
+		// need to templates for the newsletter message type for the template selector.
419
+		$values[] = ['text' => esc_html__('Select Template to Use', 'event_espresso'), 'id' => 0];
420
+		$mtps     = EEM_Message_Template_Group::instance()->get_all(
421
+			[['MTP_message_type' => 'newsletter', 'MTP_messenger' => 'email']]
422
+		);
423
+		foreach ($mtps as $mtp) {
424
+			$name     = $mtp->name();
425
+			$values[] = [
426
+				'text' => empty($name) ? esc_html__('Global', 'event_espresso') : $name,
427
+				'id'   => $mtp->ID(),
428
+			];
429
+		}
430
+		// need to get a list of shortcodes that are available for the newsletter message type.
431
+		$shortcodes = EEH_MSG_Template::get_shortcodes(
432
+			'newsletter',
433
+			'email',
434
+			[],
435
+			'attendee'
436
+		);
437
+
438
+		foreach ($shortcodes as $field => $shortcode_array) {
439
+			$available_shortcodes = [];
440
+			foreach ($shortcode_array as $shortcode => $shortcode_details) {
441
+				$field_id               = $field === '[NEWSLETTER_CONTENT]'
442
+					? 'content'
443
+					: strtolower($field);
444
+				$field_id               = "batch-message-$field_id";
445
+				$available_shortcodes[] = '
446 446
                 <span class="js-shortcode-selection"
447 447
                       data-value="' . $shortcode . '"
448 448
                       data-linked-input-id="' . $field_id . '"
449 449
                 >' . $shortcode . '</span>';
450
-            }
451
-            $codes[ $field ] = '<ul><li>' . implode('</li><li>', $available_shortcodes) . '</li></ul>';
452
-        }
453
-
454
-        EEH_Template::display_template(
455
-            REG_CAF_TEMPLATE_PATH . 'newsletter-send-form.template.php',
456
-            [
457
-                'form_action'       => admin_url('admin.php?page=espresso_registrations'),
458
-                'form_route'        => 'newsletter_selected_send',
459
-                'form_nonce_name'   => 'newsletter_selected_send_nonce',
460
-                'form_nonce'        => wp_create_nonce('newsletter_selected_send_nonce'),
461
-                'redirect_back_to'  => $this->_req_action,
462
-                'ajax_nonce'        => wp_create_nonce('get_newsletter_form_content_nonce'),
463
-                'template_selector' => EEH_Form_Fields::select_input('newsletter_mtp_selected', $values),
464
-                'shortcodes'        => $codes,
465
-                'id_type'           => $list_table instanceof EE_Attendee_Contact_List_Table ? 'contact'
466
-                    : 'registration',
467
-            ]
468
-        );
469
-    }
470
-
471
-
472
-    /**
473
-     * Handles sending selected registrations/contacts a newsletter.
474
-     *
475
-     * @return void
476
-     * @throws EE_Error
477
-     * @throws ReflectionException
478
-     * @since  4.3.0
479
-     */
480
-    protected function _newsletter_selected_send()
481
-    {
482
-        $success = true;
483
-        // first we need to make sure we have a GRP_ID so we know what template we're sending and updating!
484
-        if (empty($this->_req_data['newsletter_mtp_selected'])) {
485
-            EE_Error::add_error(
486
-                esc_html__(
487
-                    'In order to send a message, a Message Template GRP_ID is needed. It was not provided so messages were not sent.',
488
-                    'event_espresso'
489
-                ),
490
-                __FILE__,
491
-                __FUNCTION__,
492
-                __LINE__
493
-            );
494
-            $success = false;
495
-        }
496
-        if ($success) {
497
-            // update Message template in case there are any changes
498
-            $Message_Template_Group = EEM_Message_Template_Group::instance()->get_one_by_ID(
499
-                $this->_req_data['newsletter_mtp_selected']
500
-            );
501
-            $Message_Templates      = $Message_Template_Group instanceof EE_Message_Template_Group
502
-                ? $Message_Template_Group->context_templates()
503
-                : [];
504
-            if (empty($Message_Templates)) {
505
-                EE_Error::add_error(
506
-                    esc_html__(
507
-                        'Unable to retrieve message template fields from the db. Messages not sent.',
508
-                        'event_espresso'
509
-                    ),
510
-                    __FILE__,
511
-                    __FUNCTION__,
512
-                    __LINE__
513
-                );
514
-            }
515
-            // let's just update the specific fields
516
-            foreach ($Message_Templates['attendee'] as $Message_Template) {
517
-                if ($Message_Template instanceof EE_Message_Template) {
518
-                    $field   = $Message_Template->get('MTP_template_field');
519
-                    $content = $Message_Template->get('MTP_content');
520
-                    switch ($field) {
521
-                        case 'from':
522
-                            $new_content = ! empty($this->_req_data['batch_message']['from'])
523
-                                ? $this->_req_data['batch_message']['from']
524
-                                : $content;
525
-                            break;
526
-                        case 'subject':
527
-                            $new_content = ! empty($this->_req_data['batch_message']['subject'])
528
-                                ? $this->_req_data['batch_message']['subject']
529
-                                : $content;
530
-                            break;
531
-                        case 'content':
532
-                            $new_content                       = $content;
533
-                            $new_content['newsletter_content'] = ! empty($this->_req_data['batch_message']['content'])
534
-                                ? $this->_req_data['batch_message']['content']
535
-                                : $content['newsletter_content'];
536
-                            break;
537
-                        default:
538
-                            // continue the foreach loop, we don't want to set $new_content nor save.
539
-                            continue 2;
540
-                    }
541
-                    $Message_Template->set('MTP_content', $new_content);
542
-                    $Message_Template->save();
543
-                }
544
-            }
545
-            // great fields are updated!  now let's make sure we just have contact objects (EE_Attendee).
546
-            $id_type = ! empty($this->_req_data['batch_message']['id_type'])
547
-                ? $this->_req_data['batch_message']['id_type']
548
-                : 'registration';
549
-            // id_type will affect how we assemble the ids.
550
-            $ids                                 = ! empty($this->_req_data['batch_message']['ids'])
551
-                ? json_decode(stripslashes($this->_req_data['batch_message']['ids']))
552
-                : [];
553
-            $registrations_used_for_contact_data = [];
554
-            // using switch because eventually we'll have other contexts that will be used for generating messages.
555
-            switch ($id_type) {
556
-                case 'registration':
557
-                    $registrations_used_for_contact_data = EEM_Registration::instance()->get_all(
558
-                        [
559
-                            [
560
-                                'REG_ID' => ['IN', $ids],
561
-                            ],
562
-                        ]
563
-                    );
564
-                    break;
565
-                case 'contact':
566
-                    $registrations_used_for_contact_data = EEM_Registration::instance()
567
-                                                                           ->get_latest_registration_for_each_of_given_contacts(
568
-                                                                               $ids
569
-                                                                           );
570
-                    break;
571
-            }
572
-            do_action_ref_array(
573
-                'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send__with_registrations',
574
-                [
575
-                    $registrations_used_for_contact_data,
576
-                    $Message_Template_Group->ID(),
577
-                ]
578
-            );
579
-            // kept for backward compat, internally we no longer use this action.
580
-            // @deprecated 4.8.36.rc.002
581
-            $contacts = $id_type === 'registration'
582
-                ? EEM_Attendee::instance()->get_array_of_contacts_from_reg_ids($ids)
583
-                : EEM_Attendee::instance()->get_all([['ATT_ID' => ['in', $ids]]]);
584
-            do_action_ref_array(
585
-                'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send',
586
-                [
587
-                    $contacts,
588
-                    $Message_Template_Group->ID(),
589
-                ]
590
-            );
591
-        }
592
-        $query_args = [
593
-            'action' => ! empty($this->_req_data['redirect_back_to'])
594
-                ? $this->_req_data['redirect_back_to']
595
-                : 'default',
596
-        ];
597
-        $this->_redirect_after_action(false, '', '', $query_args, true);
598
-    }
599
-
600
-
601
-    /**
602
-     * This is called when javascript is being enqueued to setup the various data needed for the reports js.
603
-     * Also $this->{$_reports_template_data} property is set for later usage by the _registration_reports method.
604
-     *
605
-     * @throws EE_Error
606
-     * @throws ReflectionException
607
-     */
608
-    protected function _registration_reports_js_setup()
609
-    {
610
-        $this->_reports_template_data['admin_reports'][] = $this->_registrations_per_day_report();
611
-        $this->_reports_template_data['admin_reports'][] = $this->_registrations_per_event_report();
612
-    }
613
-
614
-
615
-    /**
616
-     * generates Business Reports regarding Registrations
617
-     *
618
-     * @return void
619
-     * @throws DomainException
620
-     * @throws EE_Error
621
-     */
622
-    protected function _registration_reports()
623
-    {
624
-        $template_path                              = EE_ADMIN_TEMPLATE . 'admin_reports.template.php';
625
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
626
-            $template_path,
627
-            $this->_reports_template_data,
628
-            true
629
-        );
630
-        // the final template wrapper
631
-        $this->display_admin_page_with_no_sidebar();
632
-    }
633
-
634
-
635
-    /**
636
-     * Generates Business Report showing total registrations per day.
637
-     *
638
-     * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated.
639
-     * @return string
640
-     * @throws EE_Error
641
-     * @throws ReflectionException
642
-     * @throws Exception
643
-     * @throws Exception
644
-     * @throws Exception
645
-     */
646
-    private function _registrations_per_day_report(string $period = '-1 month'): string
647
-    {
648
-        $report_ID = 'reg-admin-registrations-per-day-report-dv';
649
-        $results   = EEM_Registration::instance()->get_registrations_per_day_and_per_status_report($period);
650
-        $regs      = [];
651
-        $subtitle  = '';
652
-        if ($results) {
653
-            $column_titles = [];
654
-            $tracker       = 0;
655
-            foreach ($results as $result) {
656
-                $report_column_values = [];
657
-                foreach ($result as $property_name => $property_value) {
658
-                    $property_value         = $property_name === 'Registration_REG_date' ? $property_value
659
-                        : (int) $property_value;
660
-                    $report_column_values[] = $property_value;
661
-                    if ($tracker === 0) {
662
-                        if ($property_name === 'Registration_REG_date') {
663
-                            $column_titles[] = esc_html__(
664
-                                'Date (only days with registrations are shown)',
665
-                                'event_espresso'
666
-                            );
667
-                        } else {
668
-                            $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence');
669
-                        }
670
-                    }
671
-                }
672
-                $tracker++;
673
-                $regs[] = $report_column_values;
674
-            }
675
-            // make sure the column_titles is pushed to the beginning of the array
676
-            array_unshift($regs, $column_titles);
677
-            // setup the date range.
678
-            $DateTimeZone   = new DateTimeZone(EEH_DTT_Helper::get_timezone());
679
-            $beginning_date = new DateTime("now " . $period, $DateTimeZone);
680
-            $ending_date    = new DateTime("now", $DateTimeZone);
681
-            $subtitle       = sprintf(
682
-                wp_strip_all_tags(
683
-                    _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso')
684
-                ),
685
-                $beginning_date->format('Y-m-d'),
686
-                $ending_date->format('Y-m-d')
687
-            );
688
-        }
689
-        $report_title  = wp_strip_all_tags(__('Total Registrations per Day', 'event_espresso'));
690
-        $report_params = [
691
-            'title'     => $report_title,
692
-            'subtitle'  => $subtitle,
693
-            'id'        => $report_ID,
694
-            'regs'      => $regs,
695
-            'noResults' => empty($regs),
696
-            'noRegsMsg' => sprintf(
697
-                wp_strip_all_tags(
698
-                    __(
699
-                        '%sThere are currently no registration records in the last month for this report.%s',
700
-                        'event_espresso'
701
-                    )
702
-                ),
703
-                '<h2>' . $report_title . '</h2><p>',
704
-                '</p>'
705
-            ),
706
-        ];
707
-        wp_localize_script('ee-reg-reports-js', 'regPerDay', $report_params);
708
-        return $report_ID;
709
-    }
710
-
711
-
712
-    /**
713
-     * Generates Business Report showing total registrations per event.
714
-     *
715
-     * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated.
716
-     * @return string
717
-     * @throws EE_Error
718
-     * @throws ReflectionException
719
-     * @throws Exception
720
-     * @throws Exception
721
-     * @throws Exception
722
-     */
723
-    private function _registrations_per_event_report(string $period = '-1 month'): string
724
-    {
725
-        $report_ID = 'reg-admin-registrations-per-event-report-dv';
726
-        $results   = EEM_Registration::instance()->get_registrations_per_event_and_per_status_report($period);
727
-        $regs      = [];
728
-        $subtitle  = '';
729
-        if ($results) {
730
-            $column_titles = [];
731
-            $tracker       = 0;
732
-            foreach ($results as $result) {
733
-                $report_column_values = [];
734
-                foreach ($result as $property_name => $property_value) {
735
-                    $property_value         = $property_name === 'Registration_Event' ? wp_trim_words(
736
-                        $property_value,
737
-                        4,
738
-                        '...'
739
-                    ) : (int) $property_value;
740
-                    $report_column_values[] = $property_value;
741
-                    if ($tracker === 0) {
742
-                        if ($property_name === 'Registration_Event') {
743
-                            $column_titles[] = esc_html__('Event', 'event_espresso');
744
-                        } else {
745
-                            $column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence');
746
-                        }
747
-                    }
748
-                }
749
-                $tracker++;
750
-                $regs[] = $report_column_values;
751
-            }
752
-            // make sure the column_titles is pushed to the beginning of the array
753
-            array_unshift($regs, $column_titles);
754
-            // setup the date range.
755
-            $DateTimeZone   = new DateTimeZone(EEH_DTT_Helper::get_timezone());
756
-            $beginning_date = new DateTime("now " . $period, $DateTimeZone);
757
-            $ending_date    = new DateTime("now", $DateTimeZone);
758
-            $subtitle       = sprintf(
759
-                wp_strip_all_tags(
760
-                    _x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso')
761
-                ),
762
-                $beginning_date->format('Y-m-d'),
763
-                $ending_date->format('Y-m-d')
764
-            );
765
-        }
766
-        $report_title  = wp_strip_all_tags(__('Total Registrations per Event', 'event_espresso'));
767
-        $report_params = [
768
-            'title'     => $report_title,
769
-            'subtitle'  => $subtitle,
770
-            'id'        => $report_ID,
771
-            'regs'      => $regs,
772
-            'noResults' => empty($regs),
773
-            'noRegsMsg' => sprintf(
774
-                wp_strip_all_tags(
775
-                    __(
776
-                        '%sThere are currently no registration records in the last month for this report.%s',
777
-                        'event_espresso'
778
-                    )
779
-                ),
780
-                '<h2>' . $report_title . '</h2><p>',
781
-                '</p>'
782
-            ),
783
-        ];
784
-        wp_localize_script('ee-reg-reports-js', 'regPerEvent', $report_params);
785
-        return $report_ID;
786
-    }
787
-
788
-
789
-    /**
790
-     * generates HTML for the Registration Check-in list table (showing all Check-ins for a specific registration)
791
-     *
792
-     * @return void
793
-     * @throws EE_Error
794
-     * @throws EntityNotFoundException
795
-     * @throws ReflectionException
796
-     */
797
-    protected function _registration_checkin_list_table()
798
-    {
799
-        $REG_ID = $this->request->getRequestParam('_REG_ID', 0, DataType::INTEGER);
800
-        /** @var EE_Registration $registration */
801
-        $registration = EEM_Registration::instance()->get_one_by_ID($REG_ID);
802
-        if (! $registration instanceof EE_Registration) {
803
-            throw new EE_Error(
804
-                sprintf(
805
-                    esc_html__('An error occurred. There is no registration with ID (%d)', 'event_espresso'),
806
-                    $REG_ID
807
-                )
808
-            );
809
-        }
810
-        $attendee                                 = $registration->attendee();
811
-        $this->_admin_page_title                  .= $this->get_action_link_or_button(
812
-            'new_registration',
813
-            'add-registrant',
814
-            ['event_id' => $registration->event_ID()],
815
-            'add-new-h2'
816
-        );
817
-        $checked_in                               = new CheckinStatusDashicon(EE_Checkin::status_checked_in);
818
-        $checked_out                              = new CheckinStatusDashicon(EE_Checkin::status_checked_out);
819
-        $legend_items                             = [
820
-            'checkin'  => [
821
-                'class' => $checked_in->cssClasses(),
822
-                'desc'  => $checked_in->legendLabel(),
823
-            ],
824
-            'checkout' => [
825
-                'class' => $checked_out->cssClasses(),
826
-                'desc'  => $checked_out->legendLabel(),
827
-            ],
828
-        ];
829
-        $this->_template_args['after_list_table'] = $this->_display_legend($legend_items);
830
-
831
-        $DTT_ID         = $this->request->getRequestParam('DTT_ID', 0, DataType::INTEGER);
832
-        $datetime       = EEM_Datetime::instance()->get_one_by_ID($DTT_ID);
833
-        $datetime_label = '';
834
-        if ($datetime instanceof EE_Datetime) {
835
-            $datetime_label = $datetime->get_dtt_display_name(true);
836
-            $datetime_label .= ! empty($datetime_label)
837
-                ? ' (' . $datetime->get_dtt_display_name() . ')'
838
-                : $datetime->get_dtt_display_name();
839
-        }
840
-        $datetime_link                                    = ! $DTT_ID
841
-            ? EE_Admin_Page::add_query_args_and_nonce(
842
-                [
843
-                    'action'   => 'event_registrations',
844
-                    'event_id' => $registration->event_ID(),
845
-                    'DTT_ID'   => $DTT_ID,
846
-                ],
847
-                $this->_admin_base_url
848
-            )
849
-            : '';
850
-        $datetime_link                                    = ! empty($datetime_link)
851
-            ? '<a href="' . $datetime_link . '">'
852
-            . '<span id="checkin-dtt">'
853
-            . $datetime_label
854
-            . '</span></a>'
855
-            : $datetime_label;
856
-        $attendee_name                                    = $attendee instanceof EE_Attendee
857
-            ? $attendee->full_name()
858
-            : '';
859
-        $attendee_link                                    = $attendee instanceof EE_Attendee
860
-            ? $attendee->get_admin_details_link()
861
-            : '';
862
-        $attendee_link                                    = ! empty($attendee_link)
863
-            ? '<a href="' . $attendee->get_admin_details_link() . '"'
864
-            . ' aria-label="' . esc_html__('Click for attendee details', 'event_espresso') . '">'
865
-            . '<span id="checkin-attendee-name">'
866
-            . $attendee_name
867
-            . '</span></a>'
868
-            : '';
869
-        $event_link                                       = $registration->event() instanceof EE_Event
870
-            ? $registration->event()->get_admin_details_link()
871
-            : '';
872
-        $event_link                                       = ! empty($event_link)
873
-            ? '<a href="' . $event_link . '"'
874
-            . ' aria-label="' . esc_html__('Click here to edit event.', 'event_espresso') . '">'
875
-            . '<span id="checkin-event-name">'
876
-            . $registration->event_name()
877
-            . '</span>'
878
-            . '</a>'
879
-            : '';
880
-        $this->_template_args['before_list_table']        = $REG_ID && $DTT_ID
881
-            ? '<h2>' . sprintf(
882
-                esc_html__('Displaying check in records for %1$s for %2$s at the event, %3$s', 'event_espresso'),
883
-                $attendee_link,
884
-                $datetime_link,
885
-                $event_link
886
-            ) . '</h2>'
887
-            : '';
888
-        $this->_template_args['list_table_hidden_fields'] = $REG_ID
889
-            ? '<input type="hidden" name="_REG_ID" value="' . $REG_ID . '">'
890
-            : '';
891
-        $this->_template_args['list_table_hidden_fields'] .= $DTT_ID
892
-            ? '<input type="hidden" name="DTT_ID" value="' . $DTT_ID . '">'
893
-            : '';
894
-        $this->display_admin_list_table_page_with_no_sidebar();
895
-    }
896
-
897
-
898
-    /**
899
-     * toggle the Check-in status for the given registration (coming from ajax)
900
-     *
901
-     * @return void (JSON)
902
-     * @throws EE_Error
903
-     * @throws ReflectionException
904
-     */
905
-    public function toggle_checkin_status()
906
-    {
907
-        if (! $this->capabilities->current_user_can('ee_edit_checkins', __FUNCTION__)) {
908
-            wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
909
-        }
910
-        // first make sure we have the necessary data
911
-        if (! isset($this->_req_data['_regid'])) {
912
-            EE_Error::add_error(
913
-                esc_html__(
914
-                    'There must be something broken with the html structure because the required data for toggling the Check-in status is not being sent via ajax',
915
-                    'event_espresso'
916
-                ),
917
-                __FILE__,
918
-                __FUNCTION__,
919
-                __LINE__
920
-            );
921
-            $this->_template_args['success'] = false;
922
-            $this->_template_args['error']   = true;
923
-            $this->_return_json();
924
-        }
925
-        // do a nonce check because we're not coming in from a normal route here.
926
-        $nonce     = isset($this->_req_data['checkinnonce']) ? sanitize_text_field($this->_req_data['checkinnonce'])
927
-            : '';
928
-        $nonce_ref = 'checkin_nonce';
929
-        $this->_verify_nonce($nonce, $nonce_ref);
930
-        // beautiful! Made it this far so let's get the status.
931
-        $new_status = new CheckinStatusDashicon($this->_toggle_checkin_status());
932
-        // setup new class to return via ajax
933
-        $this->_template_args['admin_page_content'] = 'clickable trigger-checkin ' . $new_status->cssClasses();
934
-        $this->_template_args['success']            = true;
935
-        $this->_return_json();
936
-    }
937
-
938
-
939
-    /**
940
-     * handles toggling the checkin status for the registration,
941
-     *
942
-     * @return int|void
943
-     * @throws EE_Error
944
-     * @throws ReflectionException
945
-     */
946
-    protected function _toggle_checkin_status()
947
-    {
948
-        $DTT_ID = $this->request->getRequestParam('DTT_ID', 0, DataType::INTEGER);
949
-        $DTT_ID = $this->request->getRequestParam('dttid', $DTT_ID, DataType::INTEGER);
950
-        $DTT_ID = $this->request->getRequestParam('datetime_id', $DTT_ID, DataType::INTEGER);
951
-        $_REG_ID = $this->request->getRequestParam('_regid', 0, DataType::INTEGER);
952
-        $checkboxes = $this->request->getRequestParam('checkbox', [], DataType::INTEGER, true);
953
-
954
-        $new_status = false;
955
-        // bulk action check in toggle
956
-        if (! empty($checkboxes)) {
957
-            foreach ($checkboxes as $REG_ID) {
958
-                $new_status = $this->_toggle_checkin($REG_ID, $DTT_ID);
959
-            }
960
-        } elseif ($_REG_ID) {
961
-            $new_status = $this->_toggle_checkin($_REG_ID, $DTT_ID);
962
-        } else {
963
-            EE_Error::add_error(
964
-                esc_html__('Missing some required data to toggle the Check-in', 'event_espresso'),
965
-                __FILE__,
966
-                __FUNCTION__,
967
-                __LINE__
968
-            );
969
-        }
970
-        if (defined('DOING_AJAX') && DOING_AJAX) {
971
-            return $new_status;
972
-        }
973
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, DataType::INTEGER);
974
-        $EVT_ID = $this->request->getRequestParam('event_id', $EVT_ID, DataType::INTEGER);
975
-        $redirect_args = [
976
-            'action' => 'event_registrations',
977
-            'EVT_ID' => $EVT_ID,
978
-            'DTT_ID' => $DTT_ID,
979
-        ];
980
-        $this->_redirect_after_action(false, '', '', $redirect_args, true);
981
-    }
982
-
983
-
984
-    /**
985
-     * This is toggles a single Check-in for the given registration and datetime.
986
-     *
987
-     * @param int $REG_ID The registration we're toggling
988
-     * @param int $DTT_ID The datetime we're toggling
989
-     * @return bool|int   the chk_in status toggled to OR false if nothing got changed.
990
-     * @throws EE_Error
991
-     * @throws ReflectionException
992
-     */
993
-    private function _toggle_checkin(int $REG_ID, int $DTT_ID)
994
-    {
995
-        /** @var EE_Registration $REG */
996
-        $REG        = EEM_Registration::instance()->get_one_by_ID($REG_ID);
997
-        if (! $REG instanceof EE_Registration) {
998
-            EE_Error::add_error(
999
-                sprintf(
1000
-                    esc_html__('There is no registration with ID (%d)', 'event_espresso'),
1001
-                    $REG_ID
1002
-                ),
1003
-                __FILE__,
1004
-                __FUNCTION__,
1005
-                __LINE__
1006
-            );
1007
-            return false;
1008
-        }
1009
-        $new_status = $REG->toggle_checkin_status($DTT_ID);
1010
-        if ($new_status !== false) {
1011
-            EE_Error::add_success($REG->get_checkin_msg($DTT_ID));
1012
-        } else {
1013
-            EE_Error::add_error($REG->get_checkin_msg($DTT_ID, true), __FILE__, __FUNCTION__, __LINE__);
1014
-            $new_status = false;
1015
-        }
1016
-        return $new_status;
1017
-    }
1018
-
1019
-
1020
-    /**
1021
-     * Takes care of deleting multiple EE_Checkin table rows
1022
-     *
1023
-     * @return void
1024
-     * @throws EE_Error
1025
-     * @throws ReflectionException
1026
-     */
1027
-    protected function _delete_checkin_rows()
1028
-    {
1029
-        $query_args = [
1030
-            'action'  => 'registration_checkins',
1031
-            'DTT_ID'  => $this->_req_data['DTT_ID'] ?? 0,
1032
-            '_REG_ID' => $this->_req_data['_REG_ID'] ?? 0,
1033
-        ];
1034
-        $errors     = 0;
1035
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1036
-            $checkboxes = $this->_req_data['checkbox'];
1037
-            foreach (array_keys($checkboxes) as $CHK_ID) {
1038
-                if (! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) {
1039
-                    $errors++;
1040
-                }
1041
-            }
1042
-        } else {
1043
-            EE_Error::add_error(
1044
-                esc_html__(
1045
-                    'So, something went wrong with the bulk delete because there was no data received for instructions on WHAT to delete!',
1046
-                    'event_espresso'
1047
-                ),
1048
-                __FILE__,
1049
-                __FUNCTION__,
1050
-                __LINE__
1051
-            );
1052
-            $this->_redirect_after_action(false, '', '', $query_args, true);
1053
-        }
1054
-        if ($errors > 0) {
1055
-            EE_Error::add_error(
1056
-                sprintf(
1057
-                    esc_html__('There were %d records that did not delete successfully', 'event_espresso'),
1058
-                    $errors
1059
-                ),
1060
-                __FILE__,
1061
-                __FUNCTION__,
1062
-                __LINE__
1063
-            );
1064
-        } else {
1065
-            EE_Error::add_success(esc_html__('Records were successfully deleted', 'event_espresso'));
1066
-        }
1067
-        $this->_redirect_after_action(false, '', '', $query_args, true);
1068
-    }
1069
-
1070
-
1071
-    /**
1072
-     * Deletes a single EE_Checkin row
1073
-     *
1074
-     * @return void
1075
-     * @throws EE_Error
1076
-     * @throws ReflectionException
1077
-     */
1078
-    protected function _delete_checkin_row()
1079
-    {
1080
-        $query_args = [
1081
-            'action'  => 'registration_checkins',
1082
-            'DTT_ID'  => $this->_req_data['DTT_ID'] ?? 0,
1083
-            '_REG_ID' => $this->_req_data['_REG_ID'] ?? 0,
1084
-        ];
1085
-        if (! empty($this->_req_data['CHK_ID'])) {
1086
-            if (! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) {
1087
-                EE_Error::add_error(
1088
-                    esc_html__('Something went wrong and this check-in record was not deleted', 'event_espresso'),
1089
-                    __FILE__,
1090
-                    __FUNCTION__,
1091
-                    __LINE__
1092
-                );
1093
-            } else {
1094
-                EE_Error::add_success(esc_html__('Check-In record successfully deleted', 'event_espresso'));
1095
-            }
1096
-        } else {
1097
-            EE_Error::add_error(
1098
-                esc_html__(
1099
-                    'In order to delete a Check-in record, there must be a Check-In ID available. There is not. It is not your fault, there is just a gremlin living in the code',
1100
-                    'event_espresso'
1101
-                ),
1102
-                __FILE__,
1103
-                __FUNCTION__,
1104
-                __LINE__
1105
-            );
1106
-        }
1107
-        $this->_redirect_after_action(false, '', '', $query_args, true);
1108
-    }
1109
-
1110
-
1111
-    /**
1112
-     * @return void
1113
-     * @throws EE_Error
1114
-     */
1115
-    protected function _event_registrations_list_table()
1116
-    {
1117
-        $EVT_ID                  = $this->request->getRequestParam('EVT_ID', 0, DataType::INTEGER);
1118
-        $this->_admin_page_title .= $EVT_ID
1119
-            ? $this->get_action_link_or_button(
1120
-                'new_registration',
1121
-                'add-registrant',
1122
-                ['event_id' => $EVT_ID],
1123
-                'add-new-h2'
1124
-            )
1125
-            : '';
1126
-
1127
-        $this->_template_args['before_list_table'] = $this->generateListTableHeaderText();
1128
-        $this->_template_args['after_list_table']  = $this->generateListTableLegend();
1129
-
1130
-        $this->display_admin_list_table_page_with_no_sidebar();
1131
-    }
1132
-
1133
-
1134
-    /**
1135
-     * @return string
1136
-     * @since 5.0.24.p
1137
-     */
1138
-    private function generateListTableHeaderText(): string
1139
-    {
1140
-        $header_text                  = '';
1141
-        $admin_page_header_decorators = [
1142
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\AttendeeFilterHeader',
1143
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\EventFilterHeader',
1144
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\DateFilterHeader',
1145
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\TicketFilterHeader',
1146
-        ];
1147
-        foreach ($admin_page_header_decorators as $admin_page_header_decorator) {
1148
-            $filter_header_decorator = $this->loader->getNew($admin_page_header_decorator);
1149
-            $header_text             = $filter_header_decorator->getHeaderText($header_text);
1150
-        }
1151
-        $header_text .= '
450
+			}
451
+			$codes[ $field ] = '<ul><li>' . implode('</li><li>', $available_shortcodes) . '</li></ul>';
452
+		}
453
+
454
+		EEH_Template::display_template(
455
+			REG_CAF_TEMPLATE_PATH . 'newsletter-send-form.template.php',
456
+			[
457
+				'form_action'       => admin_url('admin.php?page=espresso_registrations'),
458
+				'form_route'        => 'newsletter_selected_send',
459
+				'form_nonce_name'   => 'newsletter_selected_send_nonce',
460
+				'form_nonce'        => wp_create_nonce('newsletter_selected_send_nonce'),
461
+				'redirect_back_to'  => $this->_req_action,
462
+				'ajax_nonce'        => wp_create_nonce('get_newsletter_form_content_nonce'),
463
+				'template_selector' => EEH_Form_Fields::select_input('newsletter_mtp_selected', $values),
464
+				'shortcodes'        => $codes,
465
+				'id_type'           => $list_table instanceof EE_Attendee_Contact_List_Table ? 'contact'
466
+					: 'registration',
467
+			]
468
+		);
469
+	}
470
+
471
+
472
+	/**
473
+	 * Handles sending selected registrations/contacts a newsletter.
474
+	 *
475
+	 * @return void
476
+	 * @throws EE_Error
477
+	 * @throws ReflectionException
478
+	 * @since  4.3.0
479
+	 */
480
+	protected function _newsletter_selected_send()
481
+	{
482
+		$success = true;
483
+		// first we need to make sure we have a GRP_ID so we know what template we're sending and updating!
484
+		if (empty($this->_req_data['newsletter_mtp_selected'])) {
485
+			EE_Error::add_error(
486
+				esc_html__(
487
+					'In order to send a message, a Message Template GRP_ID is needed. It was not provided so messages were not sent.',
488
+					'event_espresso'
489
+				),
490
+				__FILE__,
491
+				__FUNCTION__,
492
+				__LINE__
493
+			);
494
+			$success = false;
495
+		}
496
+		if ($success) {
497
+			// update Message template in case there are any changes
498
+			$Message_Template_Group = EEM_Message_Template_Group::instance()->get_one_by_ID(
499
+				$this->_req_data['newsletter_mtp_selected']
500
+			);
501
+			$Message_Templates      = $Message_Template_Group instanceof EE_Message_Template_Group
502
+				? $Message_Template_Group->context_templates()
503
+				: [];
504
+			if (empty($Message_Templates)) {
505
+				EE_Error::add_error(
506
+					esc_html__(
507
+						'Unable to retrieve message template fields from the db. Messages not sent.',
508
+						'event_espresso'
509
+					),
510
+					__FILE__,
511
+					__FUNCTION__,
512
+					__LINE__
513
+				);
514
+			}
515
+			// let's just update the specific fields
516
+			foreach ($Message_Templates['attendee'] as $Message_Template) {
517
+				if ($Message_Template instanceof EE_Message_Template) {
518
+					$field   = $Message_Template->get('MTP_template_field');
519
+					$content = $Message_Template->get('MTP_content');
520
+					switch ($field) {
521
+						case 'from':
522
+							$new_content = ! empty($this->_req_data['batch_message']['from'])
523
+								? $this->_req_data['batch_message']['from']
524
+								: $content;
525
+							break;
526
+						case 'subject':
527
+							$new_content = ! empty($this->_req_data['batch_message']['subject'])
528
+								? $this->_req_data['batch_message']['subject']
529
+								: $content;
530
+							break;
531
+						case 'content':
532
+							$new_content                       = $content;
533
+							$new_content['newsletter_content'] = ! empty($this->_req_data['batch_message']['content'])
534
+								? $this->_req_data['batch_message']['content']
535
+								: $content['newsletter_content'];
536
+							break;
537
+						default:
538
+							// continue the foreach loop, we don't want to set $new_content nor save.
539
+							continue 2;
540
+					}
541
+					$Message_Template->set('MTP_content', $new_content);
542
+					$Message_Template->save();
543
+				}
544
+			}
545
+			// great fields are updated!  now let's make sure we just have contact objects (EE_Attendee).
546
+			$id_type = ! empty($this->_req_data['batch_message']['id_type'])
547
+				? $this->_req_data['batch_message']['id_type']
548
+				: 'registration';
549
+			// id_type will affect how we assemble the ids.
550
+			$ids                                 = ! empty($this->_req_data['batch_message']['ids'])
551
+				? json_decode(stripslashes($this->_req_data['batch_message']['ids']))
552
+				: [];
553
+			$registrations_used_for_contact_data = [];
554
+			// using switch because eventually we'll have other contexts that will be used for generating messages.
555
+			switch ($id_type) {
556
+				case 'registration':
557
+					$registrations_used_for_contact_data = EEM_Registration::instance()->get_all(
558
+						[
559
+							[
560
+								'REG_ID' => ['IN', $ids],
561
+							],
562
+						]
563
+					);
564
+					break;
565
+				case 'contact':
566
+					$registrations_used_for_contact_data = EEM_Registration::instance()
567
+																		   ->get_latest_registration_for_each_of_given_contacts(
568
+																			   $ids
569
+																		   );
570
+					break;
571
+			}
572
+			do_action_ref_array(
573
+				'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send__with_registrations',
574
+				[
575
+					$registrations_used_for_contact_data,
576
+					$Message_Template_Group->ID(),
577
+				]
578
+			);
579
+			// kept for backward compat, internally we no longer use this action.
580
+			// @deprecated 4.8.36.rc.002
581
+			$contacts = $id_type === 'registration'
582
+				? EEM_Attendee::instance()->get_array_of_contacts_from_reg_ids($ids)
583
+				: EEM_Attendee::instance()->get_all([['ATT_ID' => ['in', $ids]]]);
584
+			do_action_ref_array(
585
+				'AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send',
586
+				[
587
+					$contacts,
588
+					$Message_Template_Group->ID(),
589
+				]
590
+			);
591
+		}
592
+		$query_args = [
593
+			'action' => ! empty($this->_req_data['redirect_back_to'])
594
+				? $this->_req_data['redirect_back_to']
595
+				: 'default',
596
+		];
597
+		$this->_redirect_after_action(false, '', '', $query_args, true);
598
+	}
599
+
600
+
601
+	/**
602
+	 * This is called when javascript is being enqueued to setup the various data needed for the reports js.
603
+	 * Also $this->{$_reports_template_data} property is set for later usage by the _registration_reports method.
604
+	 *
605
+	 * @throws EE_Error
606
+	 * @throws ReflectionException
607
+	 */
608
+	protected function _registration_reports_js_setup()
609
+	{
610
+		$this->_reports_template_data['admin_reports'][] = $this->_registrations_per_day_report();
611
+		$this->_reports_template_data['admin_reports'][] = $this->_registrations_per_event_report();
612
+	}
613
+
614
+
615
+	/**
616
+	 * generates Business Reports regarding Registrations
617
+	 *
618
+	 * @return void
619
+	 * @throws DomainException
620
+	 * @throws EE_Error
621
+	 */
622
+	protected function _registration_reports()
623
+	{
624
+		$template_path                              = EE_ADMIN_TEMPLATE . 'admin_reports.template.php';
625
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
626
+			$template_path,
627
+			$this->_reports_template_data,
628
+			true
629
+		);
630
+		// the final template wrapper
631
+		$this->display_admin_page_with_no_sidebar();
632
+	}
633
+
634
+
635
+	/**
636
+	 * Generates Business Report showing total registrations per day.
637
+	 *
638
+	 * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated.
639
+	 * @return string
640
+	 * @throws EE_Error
641
+	 * @throws ReflectionException
642
+	 * @throws Exception
643
+	 * @throws Exception
644
+	 * @throws Exception
645
+	 */
646
+	private function _registrations_per_day_report(string $period = '-1 month'): string
647
+	{
648
+		$report_ID = 'reg-admin-registrations-per-day-report-dv';
649
+		$results   = EEM_Registration::instance()->get_registrations_per_day_and_per_status_report($period);
650
+		$regs      = [];
651
+		$subtitle  = '';
652
+		if ($results) {
653
+			$column_titles = [];
654
+			$tracker       = 0;
655
+			foreach ($results as $result) {
656
+				$report_column_values = [];
657
+				foreach ($result as $property_name => $property_value) {
658
+					$property_value         = $property_name === 'Registration_REG_date' ? $property_value
659
+						: (int) $property_value;
660
+					$report_column_values[] = $property_value;
661
+					if ($tracker === 0) {
662
+						if ($property_name === 'Registration_REG_date') {
663
+							$column_titles[] = esc_html__(
664
+								'Date (only days with registrations are shown)',
665
+								'event_espresso'
666
+							);
667
+						} else {
668
+							$column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence');
669
+						}
670
+					}
671
+				}
672
+				$tracker++;
673
+				$regs[] = $report_column_values;
674
+			}
675
+			// make sure the column_titles is pushed to the beginning of the array
676
+			array_unshift($regs, $column_titles);
677
+			// setup the date range.
678
+			$DateTimeZone   = new DateTimeZone(EEH_DTT_Helper::get_timezone());
679
+			$beginning_date = new DateTime("now " . $period, $DateTimeZone);
680
+			$ending_date    = new DateTime("now", $DateTimeZone);
681
+			$subtitle       = sprintf(
682
+				wp_strip_all_tags(
683
+					_x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso')
684
+				),
685
+				$beginning_date->format('Y-m-d'),
686
+				$ending_date->format('Y-m-d')
687
+			);
688
+		}
689
+		$report_title  = wp_strip_all_tags(__('Total Registrations per Day', 'event_espresso'));
690
+		$report_params = [
691
+			'title'     => $report_title,
692
+			'subtitle'  => $subtitle,
693
+			'id'        => $report_ID,
694
+			'regs'      => $regs,
695
+			'noResults' => empty($regs),
696
+			'noRegsMsg' => sprintf(
697
+				wp_strip_all_tags(
698
+					__(
699
+						'%sThere are currently no registration records in the last month for this report.%s',
700
+						'event_espresso'
701
+					)
702
+				),
703
+				'<h2>' . $report_title . '</h2><p>',
704
+				'</p>'
705
+			),
706
+		];
707
+		wp_localize_script('ee-reg-reports-js', 'regPerDay', $report_params);
708
+		return $report_ID;
709
+	}
710
+
711
+
712
+	/**
713
+	 * Generates Business Report showing total registrations per event.
714
+	 *
715
+	 * @param string $period The period (acceptable by PHP Datetime constructor) for which the report is generated.
716
+	 * @return string
717
+	 * @throws EE_Error
718
+	 * @throws ReflectionException
719
+	 * @throws Exception
720
+	 * @throws Exception
721
+	 * @throws Exception
722
+	 */
723
+	private function _registrations_per_event_report(string $period = '-1 month'): string
724
+	{
725
+		$report_ID = 'reg-admin-registrations-per-event-report-dv';
726
+		$results   = EEM_Registration::instance()->get_registrations_per_event_and_per_status_report($period);
727
+		$regs      = [];
728
+		$subtitle  = '';
729
+		if ($results) {
730
+			$column_titles = [];
731
+			$tracker       = 0;
732
+			foreach ($results as $result) {
733
+				$report_column_values = [];
734
+				foreach ($result as $property_name => $property_value) {
735
+					$property_value         = $property_name === 'Registration_Event' ? wp_trim_words(
736
+						$property_value,
737
+						4,
738
+						'...'
739
+					) : (int) $property_value;
740
+					$report_column_values[] = $property_value;
741
+					if ($tracker === 0) {
742
+						if ($property_name === 'Registration_Event') {
743
+							$column_titles[] = esc_html__('Event', 'event_espresso');
744
+						} else {
745
+							$column_titles[] = EEH_Template::pretty_status($property_name, false, 'sentence');
746
+						}
747
+					}
748
+				}
749
+				$tracker++;
750
+				$regs[] = $report_column_values;
751
+			}
752
+			// make sure the column_titles is pushed to the beginning of the array
753
+			array_unshift($regs, $column_titles);
754
+			// setup the date range.
755
+			$DateTimeZone   = new DateTimeZone(EEH_DTT_Helper::get_timezone());
756
+			$beginning_date = new DateTime("now " . $period, $DateTimeZone);
757
+			$ending_date    = new DateTime("now", $DateTimeZone);
758
+			$subtitle       = sprintf(
759
+				wp_strip_all_tags(
760
+					_x('For the period: %1$s to %2$s', 'Used to give date range', 'event_espresso')
761
+				),
762
+				$beginning_date->format('Y-m-d'),
763
+				$ending_date->format('Y-m-d')
764
+			);
765
+		}
766
+		$report_title  = wp_strip_all_tags(__('Total Registrations per Event', 'event_espresso'));
767
+		$report_params = [
768
+			'title'     => $report_title,
769
+			'subtitle'  => $subtitle,
770
+			'id'        => $report_ID,
771
+			'regs'      => $regs,
772
+			'noResults' => empty($regs),
773
+			'noRegsMsg' => sprintf(
774
+				wp_strip_all_tags(
775
+					__(
776
+						'%sThere are currently no registration records in the last month for this report.%s',
777
+						'event_espresso'
778
+					)
779
+				),
780
+				'<h2>' . $report_title . '</h2><p>',
781
+				'</p>'
782
+			),
783
+		];
784
+		wp_localize_script('ee-reg-reports-js', 'regPerEvent', $report_params);
785
+		return $report_ID;
786
+	}
787
+
788
+
789
+	/**
790
+	 * generates HTML for the Registration Check-in list table (showing all Check-ins for a specific registration)
791
+	 *
792
+	 * @return void
793
+	 * @throws EE_Error
794
+	 * @throws EntityNotFoundException
795
+	 * @throws ReflectionException
796
+	 */
797
+	protected function _registration_checkin_list_table()
798
+	{
799
+		$REG_ID = $this->request->getRequestParam('_REG_ID', 0, DataType::INTEGER);
800
+		/** @var EE_Registration $registration */
801
+		$registration = EEM_Registration::instance()->get_one_by_ID($REG_ID);
802
+		if (! $registration instanceof EE_Registration) {
803
+			throw new EE_Error(
804
+				sprintf(
805
+					esc_html__('An error occurred. There is no registration with ID (%d)', 'event_espresso'),
806
+					$REG_ID
807
+				)
808
+			);
809
+		}
810
+		$attendee                                 = $registration->attendee();
811
+		$this->_admin_page_title                  .= $this->get_action_link_or_button(
812
+			'new_registration',
813
+			'add-registrant',
814
+			['event_id' => $registration->event_ID()],
815
+			'add-new-h2'
816
+		);
817
+		$checked_in                               = new CheckinStatusDashicon(EE_Checkin::status_checked_in);
818
+		$checked_out                              = new CheckinStatusDashicon(EE_Checkin::status_checked_out);
819
+		$legend_items                             = [
820
+			'checkin'  => [
821
+				'class' => $checked_in->cssClasses(),
822
+				'desc'  => $checked_in->legendLabel(),
823
+			],
824
+			'checkout' => [
825
+				'class' => $checked_out->cssClasses(),
826
+				'desc'  => $checked_out->legendLabel(),
827
+			],
828
+		];
829
+		$this->_template_args['after_list_table'] = $this->_display_legend($legend_items);
830
+
831
+		$DTT_ID         = $this->request->getRequestParam('DTT_ID', 0, DataType::INTEGER);
832
+		$datetime       = EEM_Datetime::instance()->get_one_by_ID($DTT_ID);
833
+		$datetime_label = '';
834
+		if ($datetime instanceof EE_Datetime) {
835
+			$datetime_label = $datetime->get_dtt_display_name(true);
836
+			$datetime_label .= ! empty($datetime_label)
837
+				? ' (' . $datetime->get_dtt_display_name() . ')'
838
+				: $datetime->get_dtt_display_name();
839
+		}
840
+		$datetime_link                                    = ! $DTT_ID
841
+			? EE_Admin_Page::add_query_args_and_nonce(
842
+				[
843
+					'action'   => 'event_registrations',
844
+					'event_id' => $registration->event_ID(),
845
+					'DTT_ID'   => $DTT_ID,
846
+				],
847
+				$this->_admin_base_url
848
+			)
849
+			: '';
850
+		$datetime_link                                    = ! empty($datetime_link)
851
+			? '<a href="' . $datetime_link . '">'
852
+			. '<span id="checkin-dtt">'
853
+			. $datetime_label
854
+			. '</span></a>'
855
+			: $datetime_label;
856
+		$attendee_name                                    = $attendee instanceof EE_Attendee
857
+			? $attendee->full_name()
858
+			: '';
859
+		$attendee_link                                    = $attendee instanceof EE_Attendee
860
+			? $attendee->get_admin_details_link()
861
+			: '';
862
+		$attendee_link                                    = ! empty($attendee_link)
863
+			? '<a href="' . $attendee->get_admin_details_link() . '"'
864
+			. ' aria-label="' . esc_html__('Click for attendee details', 'event_espresso') . '">'
865
+			. '<span id="checkin-attendee-name">'
866
+			. $attendee_name
867
+			. '</span></a>'
868
+			: '';
869
+		$event_link                                       = $registration->event() instanceof EE_Event
870
+			? $registration->event()->get_admin_details_link()
871
+			: '';
872
+		$event_link                                       = ! empty($event_link)
873
+			? '<a href="' . $event_link . '"'
874
+			. ' aria-label="' . esc_html__('Click here to edit event.', 'event_espresso') . '">'
875
+			. '<span id="checkin-event-name">'
876
+			. $registration->event_name()
877
+			. '</span>'
878
+			. '</a>'
879
+			: '';
880
+		$this->_template_args['before_list_table']        = $REG_ID && $DTT_ID
881
+			? '<h2>' . sprintf(
882
+				esc_html__('Displaying check in records for %1$s for %2$s at the event, %3$s', 'event_espresso'),
883
+				$attendee_link,
884
+				$datetime_link,
885
+				$event_link
886
+			) . '</h2>'
887
+			: '';
888
+		$this->_template_args['list_table_hidden_fields'] = $REG_ID
889
+			? '<input type="hidden" name="_REG_ID" value="' . $REG_ID . '">'
890
+			: '';
891
+		$this->_template_args['list_table_hidden_fields'] .= $DTT_ID
892
+			? '<input type="hidden" name="DTT_ID" value="' . $DTT_ID . '">'
893
+			: '';
894
+		$this->display_admin_list_table_page_with_no_sidebar();
895
+	}
896
+
897
+
898
+	/**
899
+	 * toggle the Check-in status for the given registration (coming from ajax)
900
+	 *
901
+	 * @return void (JSON)
902
+	 * @throws EE_Error
903
+	 * @throws ReflectionException
904
+	 */
905
+	public function toggle_checkin_status()
906
+	{
907
+		if (! $this->capabilities->current_user_can('ee_edit_checkins', __FUNCTION__)) {
908
+			wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
909
+		}
910
+		// first make sure we have the necessary data
911
+		if (! isset($this->_req_data['_regid'])) {
912
+			EE_Error::add_error(
913
+				esc_html__(
914
+					'There must be something broken with the html structure because the required data for toggling the Check-in status is not being sent via ajax',
915
+					'event_espresso'
916
+				),
917
+				__FILE__,
918
+				__FUNCTION__,
919
+				__LINE__
920
+			);
921
+			$this->_template_args['success'] = false;
922
+			$this->_template_args['error']   = true;
923
+			$this->_return_json();
924
+		}
925
+		// do a nonce check because we're not coming in from a normal route here.
926
+		$nonce     = isset($this->_req_data['checkinnonce']) ? sanitize_text_field($this->_req_data['checkinnonce'])
927
+			: '';
928
+		$nonce_ref = 'checkin_nonce';
929
+		$this->_verify_nonce($nonce, $nonce_ref);
930
+		// beautiful! Made it this far so let's get the status.
931
+		$new_status = new CheckinStatusDashicon($this->_toggle_checkin_status());
932
+		// setup new class to return via ajax
933
+		$this->_template_args['admin_page_content'] = 'clickable trigger-checkin ' . $new_status->cssClasses();
934
+		$this->_template_args['success']            = true;
935
+		$this->_return_json();
936
+	}
937
+
938
+
939
+	/**
940
+	 * handles toggling the checkin status for the registration,
941
+	 *
942
+	 * @return int|void
943
+	 * @throws EE_Error
944
+	 * @throws ReflectionException
945
+	 */
946
+	protected function _toggle_checkin_status()
947
+	{
948
+		$DTT_ID = $this->request->getRequestParam('DTT_ID', 0, DataType::INTEGER);
949
+		$DTT_ID = $this->request->getRequestParam('dttid', $DTT_ID, DataType::INTEGER);
950
+		$DTT_ID = $this->request->getRequestParam('datetime_id', $DTT_ID, DataType::INTEGER);
951
+		$_REG_ID = $this->request->getRequestParam('_regid', 0, DataType::INTEGER);
952
+		$checkboxes = $this->request->getRequestParam('checkbox', [], DataType::INTEGER, true);
953
+
954
+		$new_status = false;
955
+		// bulk action check in toggle
956
+		if (! empty($checkboxes)) {
957
+			foreach ($checkboxes as $REG_ID) {
958
+				$new_status = $this->_toggle_checkin($REG_ID, $DTT_ID);
959
+			}
960
+		} elseif ($_REG_ID) {
961
+			$new_status = $this->_toggle_checkin($_REG_ID, $DTT_ID);
962
+		} else {
963
+			EE_Error::add_error(
964
+				esc_html__('Missing some required data to toggle the Check-in', 'event_espresso'),
965
+				__FILE__,
966
+				__FUNCTION__,
967
+				__LINE__
968
+			);
969
+		}
970
+		if (defined('DOING_AJAX') && DOING_AJAX) {
971
+			return $new_status;
972
+		}
973
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, DataType::INTEGER);
974
+		$EVT_ID = $this->request->getRequestParam('event_id', $EVT_ID, DataType::INTEGER);
975
+		$redirect_args = [
976
+			'action' => 'event_registrations',
977
+			'EVT_ID' => $EVT_ID,
978
+			'DTT_ID' => $DTT_ID,
979
+		];
980
+		$this->_redirect_after_action(false, '', '', $redirect_args, true);
981
+	}
982
+
983
+
984
+	/**
985
+	 * This is toggles a single Check-in for the given registration and datetime.
986
+	 *
987
+	 * @param int $REG_ID The registration we're toggling
988
+	 * @param int $DTT_ID The datetime we're toggling
989
+	 * @return bool|int   the chk_in status toggled to OR false if nothing got changed.
990
+	 * @throws EE_Error
991
+	 * @throws ReflectionException
992
+	 */
993
+	private function _toggle_checkin(int $REG_ID, int $DTT_ID)
994
+	{
995
+		/** @var EE_Registration $REG */
996
+		$REG        = EEM_Registration::instance()->get_one_by_ID($REG_ID);
997
+		if (! $REG instanceof EE_Registration) {
998
+			EE_Error::add_error(
999
+				sprintf(
1000
+					esc_html__('There is no registration with ID (%d)', 'event_espresso'),
1001
+					$REG_ID
1002
+				),
1003
+				__FILE__,
1004
+				__FUNCTION__,
1005
+				__LINE__
1006
+			);
1007
+			return false;
1008
+		}
1009
+		$new_status = $REG->toggle_checkin_status($DTT_ID);
1010
+		if ($new_status !== false) {
1011
+			EE_Error::add_success($REG->get_checkin_msg($DTT_ID));
1012
+		} else {
1013
+			EE_Error::add_error($REG->get_checkin_msg($DTT_ID, true), __FILE__, __FUNCTION__, __LINE__);
1014
+			$new_status = false;
1015
+		}
1016
+		return $new_status;
1017
+	}
1018
+
1019
+
1020
+	/**
1021
+	 * Takes care of deleting multiple EE_Checkin table rows
1022
+	 *
1023
+	 * @return void
1024
+	 * @throws EE_Error
1025
+	 * @throws ReflectionException
1026
+	 */
1027
+	protected function _delete_checkin_rows()
1028
+	{
1029
+		$query_args = [
1030
+			'action'  => 'registration_checkins',
1031
+			'DTT_ID'  => $this->_req_data['DTT_ID'] ?? 0,
1032
+			'_REG_ID' => $this->_req_data['_REG_ID'] ?? 0,
1033
+		];
1034
+		$errors     = 0;
1035
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1036
+			$checkboxes = $this->_req_data['checkbox'];
1037
+			foreach (array_keys($checkboxes) as $CHK_ID) {
1038
+				if (! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) {
1039
+					$errors++;
1040
+				}
1041
+			}
1042
+		} else {
1043
+			EE_Error::add_error(
1044
+				esc_html__(
1045
+					'So, something went wrong with the bulk delete because there was no data received for instructions on WHAT to delete!',
1046
+					'event_espresso'
1047
+				),
1048
+				__FILE__,
1049
+				__FUNCTION__,
1050
+				__LINE__
1051
+			);
1052
+			$this->_redirect_after_action(false, '', '', $query_args, true);
1053
+		}
1054
+		if ($errors > 0) {
1055
+			EE_Error::add_error(
1056
+				sprintf(
1057
+					esc_html__('There were %d records that did not delete successfully', 'event_espresso'),
1058
+					$errors
1059
+				),
1060
+				__FILE__,
1061
+				__FUNCTION__,
1062
+				__LINE__
1063
+			);
1064
+		} else {
1065
+			EE_Error::add_success(esc_html__('Records were successfully deleted', 'event_espresso'));
1066
+		}
1067
+		$this->_redirect_after_action(false, '', '', $query_args, true);
1068
+	}
1069
+
1070
+
1071
+	/**
1072
+	 * Deletes a single EE_Checkin row
1073
+	 *
1074
+	 * @return void
1075
+	 * @throws EE_Error
1076
+	 * @throws ReflectionException
1077
+	 */
1078
+	protected function _delete_checkin_row()
1079
+	{
1080
+		$query_args = [
1081
+			'action'  => 'registration_checkins',
1082
+			'DTT_ID'  => $this->_req_data['DTT_ID'] ?? 0,
1083
+			'_REG_ID' => $this->_req_data['_REG_ID'] ?? 0,
1084
+		];
1085
+		if (! empty($this->_req_data['CHK_ID'])) {
1086
+			if (! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) {
1087
+				EE_Error::add_error(
1088
+					esc_html__('Something went wrong and this check-in record was not deleted', 'event_espresso'),
1089
+					__FILE__,
1090
+					__FUNCTION__,
1091
+					__LINE__
1092
+				);
1093
+			} else {
1094
+				EE_Error::add_success(esc_html__('Check-In record successfully deleted', 'event_espresso'));
1095
+			}
1096
+		} else {
1097
+			EE_Error::add_error(
1098
+				esc_html__(
1099
+					'In order to delete a Check-in record, there must be a Check-In ID available. There is not. It is not your fault, there is just a gremlin living in the code',
1100
+					'event_espresso'
1101
+				),
1102
+				__FILE__,
1103
+				__FUNCTION__,
1104
+				__LINE__
1105
+			);
1106
+		}
1107
+		$this->_redirect_after_action(false, '', '', $query_args, true);
1108
+	}
1109
+
1110
+
1111
+	/**
1112
+	 * @return void
1113
+	 * @throws EE_Error
1114
+	 */
1115
+	protected function _event_registrations_list_table()
1116
+	{
1117
+		$EVT_ID                  = $this->request->getRequestParam('EVT_ID', 0, DataType::INTEGER);
1118
+		$this->_admin_page_title .= $EVT_ID
1119
+			? $this->get_action_link_or_button(
1120
+				'new_registration',
1121
+				'add-registrant',
1122
+				['event_id' => $EVT_ID],
1123
+				'add-new-h2'
1124
+			)
1125
+			: '';
1126
+
1127
+		$this->_template_args['before_list_table'] = $this->generateListTableHeaderText();
1128
+		$this->_template_args['after_list_table']  = $this->generateListTableLegend();
1129
+
1130
+		$this->display_admin_list_table_page_with_no_sidebar();
1131
+	}
1132
+
1133
+
1134
+	/**
1135
+	 * @return string
1136
+	 * @since 5.0.24.p
1137
+	 */
1138
+	private function generateListTableHeaderText(): string
1139
+	{
1140
+		$header_text                  = '';
1141
+		$admin_page_header_decorators = [
1142
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\AttendeeFilterHeader',
1143
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\EventFilterHeader',
1144
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\DateFilterHeader',
1145
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\TicketFilterHeader',
1146
+		];
1147
+		foreach ($admin_page_header_decorators as $admin_page_header_decorator) {
1148
+			$filter_header_decorator = $this->loader->getNew($admin_page_header_decorator);
1149
+			$header_text             = $filter_header_decorator->getHeaderText($header_text);
1150
+		}
1151
+		$header_text .= '
1152 1152
             <div class="description ee-status-outline ee-status-bg--info ee-status-outline--fit-content">
1153 1153
                 <strong>' . esc_html__(
1154
-            'In this view, the check-in status represents the latest check-in record for the registration in that row.',
1155
-            'event_espresso'
1156
-        ) . '</strong>
1154
+			'In this view, the check-in status represents the latest check-in record for the registration in that row.',
1155
+			'event_espresso'
1156
+		) . '</strong>
1157 1157
             </div>';
1158
-        return $header_text;
1159
-    }
1160
-
1161
-
1162
-    /**
1163
-     * @return string
1164
-     * @throws EE_Error
1165
-     * @since 5.0.24.p
1166
-     */
1167
-    private function generateListTableLegend(): string
1168
-    {
1169
-        $checked_in      = new CheckinStatusDashicon(EE_Checkin::status_checked_in);
1170
-        $checked_out     = new CheckinStatusDashicon(EE_Checkin::status_checked_out);
1171
-        $checked_never   = new CheckinStatusDashicon(EE_Checkin::status_checked_never);
1172
-        $checkin_invalid = new CheckinStatusDashicon(EE_Checkin::status_invalid);
1173
-
1174
-        $legend_items = [
1175
-            'star-icon'        => [
1176
-                'class' => 'dashicons dashicons-star-filled gold-icon',
1177
-                'desc'  => esc_html__('This Registrant is the Primary Registrant', 'event_espresso'),
1178
-            ],
1179
-            'checkin'          => [
1180
-                'class' => $checked_in->cssClasses(),
1181
-                'desc'  => $checked_in->legendLabel(),
1182
-            ],
1183
-            'checkout'         => [
1184
-                'class' => $checked_out->cssClasses(),
1185
-                'desc'  => $checked_out->legendLabel(),
1186
-            ],
1187
-            'nocheckinrecord'  => [
1188
-                'class' => $checked_never->cssClasses(),
1189
-                'desc'  => $checked_never->legendLabel(),
1190
-            ],
1191
-            'canNotCheckin'    => [
1192
-                'class' => $checkin_invalid->cssClasses(),
1193
-                'desc'  => $checkin_invalid->legendLabel(),
1194
-            ],
1195
-            'approved_status'  => [
1196
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::APPROVED,
1197
-                'desc'  => EEH_Template::pretty_status(RegStatus::APPROVED, false, 'sentence'),
1198
-            ],
1199
-            'cancelled_status' => [
1200
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::CANCELLED,
1201
-                'desc'  => EEH_Template::pretty_status(RegStatus::CANCELLED, false, 'sentence'),
1202
-            ],
1203
-            'declined_status'  => [
1204
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::DECLINED,
1205
-                'desc'  => EEH_Template::pretty_status(RegStatus::DECLINED, false, 'sentence'),
1206
-            ],
1207
-            'not_approved'     => [
1208
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::AWAITING_REVIEW,
1209
-                'desc'  => EEH_Template::pretty_status(RegStatus::AWAITING_REVIEW, false, 'sentence'),
1210
-            ],
1211
-            'pending_status'   => [
1212
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::PENDING_PAYMENT,
1213
-                'desc'  => EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'sentence'),
1214
-            ],
1215
-            'wait_list'        => [
1216
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::WAIT_LIST,
1217
-                'desc'  => EEH_Template::pretty_status(RegStatus::WAIT_LIST, false, 'sentence'),
1218
-            ],
1219
-        ];
1220
-        return $this->_display_legend($legend_items);
1221
-    }
1222
-
1223
-
1224
-    /**
1225
-     * Download the registrations check-in report (same as the normal registration report, but with different where
1226
-     * conditions)
1227
-     *
1228
-     * @return void ends the request by a redirect or download
1229
-     */
1230
-    public function _registrations_checkin_report()
1231
-    {
1232
-        $this->_registrations_report_base('_get_checkin_query_params_from_request');
1233
-    }
1234
-
1235
-
1236
-    /**
1237
-     * Gets the query params from the request, plus adds a where condition for the registration status,
1238
-     * because on the checkin page we only ever want to see approved and pending-approval registrations
1239
-     *
1240
-     * @param array $query_params
1241
-     * @param int   $per_page
1242
-     * @param bool  $count
1243
-     * @return array
1244
-     * @throws EE_Error
1245
-     */
1246
-    protected function _get_checkin_query_params_from_request(
1247
-        array $query_params,
1248
-        int $per_page = 10,
1249
-        bool $count = false
1250
-    ): array {
1251
-        $query_params = $this->_get_registration_query_parameters($query_params, $per_page, $count);
1252
-        // unlike the regular registrations list table,
1253
-        $status_ids_array          = apply_filters(
1254
-            'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
1255
-            [RegStatus::PENDING_PAYMENT, RegStatus::APPROVED]
1256
-        );
1257
-        $query_params[0]['STS_ID'] = ['IN', $status_ids_array];
1258
-        return $query_params;
1259
-    }
1260
-
1261
-
1262
-    /**
1263
-     * Gets registrations for an event
1264
-     *
1265
-     * @param int    $per_page
1266
-     * @param bool   $count whether to return count or data.
1267
-     * @param bool   $trash
1268
-     * @param string $orderby
1269
-     * @return EE_Registration[]|int
1270
-     * @throws EE_Error
1271
-     * @throws ReflectionException
1272
-     */
1273
-    public function get_event_attendees(
1274
-        int $per_page = 10,
1275
-        bool $count = false,
1276
-        bool $trash = false,
1277
-        string $orderby = 'ATT_fname'
1278
-    ) {
1279
-        // set some defaults, these will get overridden if included in the actual request parameters
1280
-        $defaults = [
1281
-            'orderby' => $orderby,
1282
-            'order'   => 'ASC',
1283
-        ];
1284
-        if ($trash) {
1285
-            $defaults['status'] = 'trash';
1286
-        }
1287
-        $query_params = $this->_get_checkin_query_params_from_request($defaults, $per_page, $count);
1288
-
1289
-        /**
1290
-         * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1291
-         *
1292
-         * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1293
-         * @see  https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1294
-         *                             or if you have the development copy of EE you can view this at the path:
1295
-         *                             /docs/G--Model-System/model-query-params.md
1296
-         */
1297
-        $query_params['group_by'] = '';
1298
-
1299
-        return $count
1300
-            ? EEM_Registration::instance()->count($query_params)
1301
-            /** @type EE_Registration[] */
1302
-            : EEM_Registration::instance()->get_all($query_params);
1303
-    }
1158
+		return $header_text;
1159
+	}
1160
+
1161
+
1162
+	/**
1163
+	 * @return string
1164
+	 * @throws EE_Error
1165
+	 * @since 5.0.24.p
1166
+	 */
1167
+	private function generateListTableLegend(): string
1168
+	{
1169
+		$checked_in      = new CheckinStatusDashicon(EE_Checkin::status_checked_in);
1170
+		$checked_out     = new CheckinStatusDashicon(EE_Checkin::status_checked_out);
1171
+		$checked_never   = new CheckinStatusDashicon(EE_Checkin::status_checked_never);
1172
+		$checkin_invalid = new CheckinStatusDashicon(EE_Checkin::status_invalid);
1173
+
1174
+		$legend_items = [
1175
+			'star-icon'        => [
1176
+				'class' => 'dashicons dashicons-star-filled gold-icon',
1177
+				'desc'  => esc_html__('This Registrant is the Primary Registrant', 'event_espresso'),
1178
+			],
1179
+			'checkin'          => [
1180
+				'class' => $checked_in->cssClasses(),
1181
+				'desc'  => $checked_in->legendLabel(),
1182
+			],
1183
+			'checkout'         => [
1184
+				'class' => $checked_out->cssClasses(),
1185
+				'desc'  => $checked_out->legendLabel(),
1186
+			],
1187
+			'nocheckinrecord'  => [
1188
+				'class' => $checked_never->cssClasses(),
1189
+				'desc'  => $checked_never->legendLabel(),
1190
+			],
1191
+			'canNotCheckin'    => [
1192
+				'class' => $checkin_invalid->cssClasses(),
1193
+				'desc'  => $checkin_invalid->legendLabel(),
1194
+			],
1195
+			'approved_status'  => [
1196
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::APPROVED,
1197
+				'desc'  => EEH_Template::pretty_status(RegStatus::APPROVED, false, 'sentence'),
1198
+			],
1199
+			'cancelled_status' => [
1200
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::CANCELLED,
1201
+				'desc'  => EEH_Template::pretty_status(RegStatus::CANCELLED, false, 'sentence'),
1202
+			],
1203
+			'declined_status'  => [
1204
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::DECLINED,
1205
+				'desc'  => EEH_Template::pretty_status(RegStatus::DECLINED, false, 'sentence'),
1206
+			],
1207
+			'not_approved'     => [
1208
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::AWAITING_REVIEW,
1209
+				'desc'  => EEH_Template::pretty_status(RegStatus::AWAITING_REVIEW, false, 'sentence'),
1210
+			],
1211
+			'pending_status'   => [
1212
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::PENDING_PAYMENT,
1213
+				'desc'  => EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'sentence'),
1214
+			],
1215
+			'wait_list'        => [
1216
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::WAIT_LIST,
1217
+				'desc'  => EEH_Template::pretty_status(RegStatus::WAIT_LIST, false, 'sentence'),
1218
+			],
1219
+		];
1220
+		return $this->_display_legend($legend_items);
1221
+	}
1222
+
1223
+
1224
+	/**
1225
+	 * Download the registrations check-in report (same as the normal registration report, but with different where
1226
+	 * conditions)
1227
+	 *
1228
+	 * @return void ends the request by a redirect or download
1229
+	 */
1230
+	public function _registrations_checkin_report()
1231
+	{
1232
+		$this->_registrations_report_base('_get_checkin_query_params_from_request');
1233
+	}
1234
+
1235
+
1236
+	/**
1237
+	 * Gets the query params from the request, plus adds a where condition for the registration status,
1238
+	 * because on the checkin page we only ever want to see approved and pending-approval registrations
1239
+	 *
1240
+	 * @param array $query_params
1241
+	 * @param int   $per_page
1242
+	 * @param bool  $count
1243
+	 * @return array
1244
+	 * @throws EE_Error
1245
+	 */
1246
+	protected function _get_checkin_query_params_from_request(
1247
+		array $query_params,
1248
+		int $per_page = 10,
1249
+		bool $count = false
1250
+	): array {
1251
+		$query_params = $this->_get_registration_query_parameters($query_params, $per_page, $count);
1252
+		// unlike the regular registrations list table,
1253
+		$status_ids_array          = apply_filters(
1254
+			'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
1255
+			[RegStatus::PENDING_PAYMENT, RegStatus::APPROVED]
1256
+		);
1257
+		$query_params[0]['STS_ID'] = ['IN', $status_ids_array];
1258
+		return $query_params;
1259
+	}
1260
+
1261
+
1262
+	/**
1263
+	 * Gets registrations for an event
1264
+	 *
1265
+	 * @param int    $per_page
1266
+	 * @param bool   $count whether to return count or data.
1267
+	 * @param bool   $trash
1268
+	 * @param string $orderby
1269
+	 * @return EE_Registration[]|int
1270
+	 * @throws EE_Error
1271
+	 * @throws ReflectionException
1272
+	 */
1273
+	public function get_event_attendees(
1274
+		int $per_page = 10,
1275
+		bool $count = false,
1276
+		bool $trash = false,
1277
+		string $orderby = 'ATT_fname'
1278
+	) {
1279
+		// set some defaults, these will get overridden if included in the actual request parameters
1280
+		$defaults = [
1281
+			'orderby' => $orderby,
1282
+			'order'   => 'ASC',
1283
+		];
1284
+		if ($trash) {
1285
+			$defaults['status'] = 'trash';
1286
+		}
1287
+		$query_params = $this->_get_checkin_query_params_from_request($defaults, $per_page, $count);
1288
+
1289
+		/**
1290
+		 * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1291
+		 *
1292
+		 * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1293
+		 * @see  https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1294
+		 *                             or if you have the development copy of EE you can view this at the path:
1295
+		 *                             /docs/G--Model-System/model-query-params.md
1296
+		 */
1297
+		$query_params['group_by'] = '';
1298
+
1299
+		return $count
1300
+			? EEM_Registration::instance()->count($query_params)
1301
+			/** @type EE_Registration[] */
1302
+			: EEM_Registration::instance()->get_all($query_params);
1303
+	}
1304 1304
 }
Please login to merge, or discard this patch.
Spacing   +61 added lines, -61 removed lines patch added patch discarded remove patch
@@ -33,10 +33,10 @@  discard block
 block discarded – undo
33 33
     public function __construct($routing = true)
34 34
     {
35 35
         parent::__construct($routing);
36
-        if (! defined('REG_CAF_TEMPLATE_PATH')) {
37
-            define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/templates/');
38
-            define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/assets/');
39
-            define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registrations/assets/');
36
+        if ( ! defined('REG_CAF_TEMPLATE_PATH')) {
37
+            define('REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND.'registrations/templates/');
38
+            define('REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND.'registrations/assets/');
39
+            define('REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL.'registrations/assets/');
40 40
         }
41 41
     }
42 42
 
@@ -45,12 +45,12 @@  discard block
 block discarded – undo
45 45
     {
46 46
         parent::_set_page_config();
47 47
 
48
-        $this->_admin_base_path                           = EE_CORE_CAF_ADMIN_EXTEND . 'registrations';
48
+        $this->_admin_base_path                           = EE_CORE_CAF_ADMIN_EXTEND.'registrations';
49 49
         $reg_id                                           =
50 50
             ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
51 51
                 ? $this->_req_data['_REG_ID']
52 52
                 : 0;
53
-        $new_page_routes                                  = [
53
+        $new_page_routes = [
54 54
             'reports'                      => [
55 55
                 'func'       => [$this, '_registration_reports'],
56 56
                 'capability' => 'ee_read_registrations',
@@ -188,14 +188,14 @@  discard block
 block discarded – undo
188 188
         if (EEH_MSG_Template::is_mt_active('newsletter')) {
189 189
             wp_enqueue_style(
190 190
                 'ee_message_shortcodes',
191
-                EE_MSG_ASSETS_URL . 'ee_message_shortcodes.css',
191
+                EE_MSG_ASSETS_URL.'ee_message_shortcodes.css',
192 192
                 [EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_ADMIN],
193 193
                 EVENT_ESPRESSO_VERSION
194 194
             );
195 195
             // enqueue newsletter js
196 196
             wp_enqueue_script(
197 197
                 'ee-newsletter-trigger',
198
-                REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.js',
198
+                REG_CAF_ASSETS_URL.'ee-newsletter-trigger.js',
199 199
                 ['ee-dialog'],
200 200
                 EVENT_ESPRESSO_VERSION,
201 201
                 true
@@ -219,7 +219,7 @@  discard block
 block discarded – undo
219 219
     {
220 220
         wp_register_script(
221 221
             'ee-reg-reports-js',
222
-            REG_CAF_ASSETS_URL . 'ee-registration-admin-reports.js',
222
+            REG_CAF_ASSETS_URL.'ee-registration-admin-reports.js',
223 223
             ['google-charts'],
224 224
             EVENT_ESPRESSO_VERSION,
225 225
             true
@@ -295,7 +295,7 @@  discard block
 block discarded – undo
295 295
      */
296 296
     public function get_newsletter_form_content()
297 297
     {
298
-        if (! $this->capabilities->current_user_can('ee_read_messages', __FUNCTION__)) {
298
+        if ( ! $this->capabilities->current_user_can('ee_read_messages', __FUNCTION__)) {
299 299
             wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
300 300
         }
301 301
         // do a nonce check because we're not coming in from a normal route here.
@@ -305,7 +305,7 @@  discard block
 block discarded – undo
305 305
         $nonce_ref = 'get_newsletter_form_content_nonce';
306 306
         $this->_verify_nonce($nonce, $nonce_ref);
307 307
         // let's get the mtp for the incoming MTP_ ID
308
-        if (! isset($this->_req_data['GRP_ID'])) {
308
+        if ( ! isset($this->_req_data['GRP_ID'])) {
309 309
             EE_Error::add_error(
310 310
                 esc_html__(
311 311
                     'There must be something broken with the js or html structure because the required data for getting a message template group is not present (need an GRP_ID).',
@@ -320,7 +320,7 @@  discard block
 block discarded – undo
320 320
             $this->_return_json();
321 321
         }
322 322
         $MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID($this->_req_data['GRP_ID']);
323
-        if (! $MTPG instanceof EE_Message_Template_Group) {
323
+        if ( ! $MTPG instanceof EE_Message_Template_Group) {
324 324
             EE_Error::add_error(
325 325
                 sprintf(
326 326
                     esc_html__(
@@ -345,12 +345,12 @@  discard block
 block discarded – undo
345 345
             $field = $MTP->get('MTP_template_field');
346 346
             if ($field === 'content') {
347 347
                 $content = $MTP->get('MTP_content');
348
-                if (! empty($content['newsletter_content'])) {
348
+                if ( ! empty($content['newsletter_content'])) {
349 349
                     $template_fields['newsletter_content'] = $content['newsletter_content'];
350 350
                 }
351 351
                 continue;
352 352
             }
353
-            $template_fields[ $MTP->get('MTP_template_field') ] = $MTP->get('MTP_content');
353
+            $template_fields[$MTP->get('MTP_template_field')] = $MTP->get('MTP_content');
354 354
         }
355 355
         $this->_template_args['success'] = true;
356 356
         $this->_template_args['error']   = false;
@@ -444,15 +444,15 @@  discard block
 block discarded – undo
444 444
                 $field_id               = "batch-message-$field_id";
445 445
                 $available_shortcodes[] = '
446 446
                 <span class="js-shortcode-selection"
447
-                      data-value="' . $shortcode . '"
448
-                      data-linked-input-id="' . $field_id . '"
449
-                >' . $shortcode . '</span>';
447
+                      data-value="' . $shortcode.'"
448
+                      data-linked-input-id="' . $field_id.'"
449
+                >' . $shortcode.'</span>';
450 450
             }
451
-            $codes[ $field ] = '<ul><li>' . implode('</li><li>', $available_shortcodes) . '</li></ul>';
451
+            $codes[$field] = '<ul><li>'.implode('</li><li>', $available_shortcodes).'</li></ul>';
452 452
         }
453 453
 
454 454
         EEH_Template::display_template(
455
-            REG_CAF_TEMPLATE_PATH . 'newsletter-send-form.template.php',
455
+            REG_CAF_TEMPLATE_PATH.'newsletter-send-form.template.php',
456 456
             [
457 457
                 'form_action'       => admin_url('admin.php?page=espresso_registrations'),
458 458
                 'form_route'        => 'newsletter_selected_send',
@@ -621,7 +621,7 @@  discard block
 block discarded – undo
621 621
      */
622 622
     protected function _registration_reports()
623 623
     {
624
-        $template_path                              = EE_ADMIN_TEMPLATE . 'admin_reports.template.php';
624
+        $template_path                              = EE_ADMIN_TEMPLATE.'admin_reports.template.php';
625 625
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
626 626
             $template_path,
627 627
             $this->_reports_template_data,
@@ -676,7 +676,7 @@  discard block
 block discarded – undo
676 676
             array_unshift($regs, $column_titles);
677 677
             // setup the date range.
678 678
             $DateTimeZone   = new DateTimeZone(EEH_DTT_Helper::get_timezone());
679
-            $beginning_date = new DateTime("now " . $period, $DateTimeZone);
679
+            $beginning_date = new DateTime("now ".$period, $DateTimeZone);
680 680
             $ending_date    = new DateTime("now", $DateTimeZone);
681 681
             $subtitle       = sprintf(
682 682
                 wp_strip_all_tags(
@@ -700,7 +700,7 @@  discard block
 block discarded – undo
700 700
                         'event_espresso'
701 701
                     )
702 702
                 ),
703
-                '<h2>' . $report_title . '</h2><p>',
703
+                '<h2>'.$report_title.'</h2><p>',
704 704
                 '</p>'
705 705
             ),
706 706
         ];
@@ -732,7 +732,7 @@  discard block
 block discarded – undo
732 732
             foreach ($results as $result) {
733 733
                 $report_column_values = [];
734 734
                 foreach ($result as $property_name => $property_value) {
735
-                    $property_value         = $property_name === 'Registration_Event' ? wp_trim_words(
735
+                    $property_value = $property_name === 'Registration_Event' ? wp_trim_words(
736 736
                         $property_value,
737 737
                         4,
738 738
                         '...'
@@ -753,7 +753,7 @@  discard block
 block discarded – undo
753 753
             array_unshift($regs, $column_titles);
754 754
             // setup the date range.
755 755
             $DateTimeZone   = new DateTimeZone(EEH_DTT_Helper::get_timezone());
756
-            $beginning_date = new DateTime("now " . $period, $DateTimeZone);
756
+            $beginning_date = new DateTime("now ".$period, $DateTimeZone);
757 757
             $ending_date    = new DateTime("now", $DateTimeZone);
758 758
             $subtitle       = sprintf(
759 759
                 wp_strip_all_tags(
@@ -777,7 +777,7 @@  discard block
 block discarded – undo
777 777
                         'event_espresso'
778 778
                     )
779 779
                 ),
780
-                '<h2>' . $report_title . '</h2><p>',
780
+                '<h2>'.$report_title.'</h2><p>',
781 781
                 '</p>'
782 782
             ),
783 783
         ];
@@ -799,7 +799,7 @@  discard block
 block discarded – undo
799 799
         $REG_ID = $this->request->getRequestParam('_REG_ID', 0, DataType::INTEGER);
800 800
         /** @var EE_Registration $registration */
801 801
         $registration = EEM_Registration::instance()->get_one_by_ID($REG_ID);
802
-        if (! $registration instanceof EE_Registration) {
802
+        if ( ! $registration instanceof EE_Registration) {
803 803
             throw new EE_Error(
804 804
                 sprintf(
805 805
                     esc_html__('An error occurred. There is no registration with ID (%d)', 'event_espresso'),
@@ -807,8 +807,8 @@  discard block
 block discarded – undo
807 807
                 )
808 808
             );
809 809
         }
810
-        $attendee                                 = $registration->attendee();
811
-        $this->_admin_page_title                  .= $this->get_action_link_or_button(
810
+        $attendee = $registration->attendee();
811
+        $this->_admin_page_title .= $this->get_action_link_or_button(
812 812
             'new_registration',
813 813
             'add-registrant',
814 814
             ['event_id' => $registration->event_ID()],
@@ -834,10 +834,10 @@  discard block
 block discarded – undo
834 834
         if ($datetime instanceof EE_Datetime) {
835 835
             $datetime_label = $datetime->get_dtt_display_name(true);
836 836
             $datetime_label .= ! empty($datetime_label)
837
-                ? ' (' . $datetime->get_dtt_display_name() . ')'
837
+                ? ' ('.$datetime->get_dtt_display_name().')'
838 838
                 : $datetime->get_dtt_display_name();
839 839
         }
840
-        $datetime_link                                    = ! $DTT_ID
840
+        $datetime_link = ! $DTT_ID
841 841
             ? EE_Admin_Page::add_query_args_and_nonce(
842 842
                 [
843 843
                     'action'   => 'event_registrations',
@@ -847,8 +847,8 @@  discard block
 block discarded – undo
847 847
                 $this->_admin_base_url
848 848
             )
849 849
             : '';
850
-        $datetime_link                                    = ! empty($datetime_link)
851
-            ? '<a href="' . $datetime_link . '">'
850
+        $datetime_link = ! empty($datetime_link)
851
+            ? '<a href="'.$datetime_link.'">'
852 852
             . '<span id="checkin-dtt">'
853 853
             . $datetime_label
854 854
             . '</span></a>'
@@ -860,8 +860,8 @@  discard block
 block discarded – undo
860 860
             ? $attendee->get_admin_details_link()
861 861
             : '';
862 862
         $attendee_link                                    = ! empty($attendee_link)
863
-            ? '<a href="' . $attendee->get_admin_details_link() . '"'
864
-            . ' aria-label="' . esc_html__('Click for attendee details', 'event_espresso') . '">'
863
+            ? '<a href="'.$attendee->get_admin_details_link().'"'
864
+            . ' aria-label="'.esc_html__('Click for attendee details', 'event_espresso').'">'
865 865
             . '<span id="checkin-attendee-name">'
866 866
             . $attendee_name
867 867
             . '</span></a>'
@@ -870,26 +870,26 @@  discard block
 block discarded – undo
870 870
             ? $registration->event()->get_admin_details_link()
871 871
             : '';
872 872
         $event_link                                       = ! empty($event_link)
873
-            ? '<a href="' . $event_link . '"'
874
-            . ' aria-label="' . esc_html__('Click here to edit event.', 'event_espresso') . '">'
873
+            ? '<a href="'.$event_link.'"'
874
+            . ' aria-label="'.esc_html__('Click here to edit event.', 'event_espresso').'">'
875 875
             . '<span id="checkin-event-name">'
876 876
             . $registration->event_name()
877 877
             . '</span>'
878 878
             . '</a>'
879 879
             : '';
880
-        $this->_template_args['before_list_table']        = $REG_ID && $DTT_ID
881
-            ? '<h2>' . sprintf(
880
+        $this->_template_args['before_list_table'] = $REG_ID && $DTT_ID
881
+            ? '<h2>'.sprintf(
882 882
                 esc_html__('Displaying check in records for %1$s for %2$s at the event, %3$s', 'event_espresso'),
883 883
                 $attendee_link,
884 884
                 $datetime_link,
885 885
                 $event_link
886
-            ) . '</h2>'
886
+            ).'</h2>'
887 887
             : '';
888 888
         $this->_template_args['list_table_hidden_fields'] = $REG_ID
889
-            ? '<input type="hidden" name="_REG_ID" value="' . $REG_ID . '">'
889
+            ? '<input type="hidden" name="_REG_ID" value="'.$REG_ID.'">'
890 890
             : '';
891 891
         $this->_template_args['list_table_hidden_fields'] .= $DTT_ID
892
-            ? '<input type="hidden" name="DTT_ID" value="' . $DTT_ID . '">'
892
+            ? '<input type="hidden" name="DTT_ID" value="'.$DTT_ID.'">'
893 893
             : '';
894 894
         $this->display_admin_list_table_page_with_no_sidebar();
895 895
     }
@@ -904,11 +904,11 @@  discard block
 block discarded – undo
904 904
      */
905 905
     public function toggle_checkin_status()
906 906
     {
907
-        if (! $this->capabilities->current_user_can('ee_edit_checkins', __FUNCTION__)) {
907
+        if ( ! $this->capabilities->current_user_can('ee_edit_checkins', __FUNCTION__)) {
908 908
             wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
909 909
         }
910 910
         // first make sure we have the necessary data
911
-        if (! isset($this->_req_data['_regid'])) {
911
+        if ( ! isset($this->_req_data['_regid'])) {
912 912
             EE_Error::add_error(
913 913
                 esc_html__(
914 914
                     'There must be something broken with the html structure because the required data for toggling the Check-in status is not being sent via ajax',
@@ -930,7 +930,7 @@  discard block
 block discarded – undo
930 930
         // beautiful! Made it this far so let's get the status.
931 931
         $new_status = new CheckinStatusDashicon($this->_toggle_checkin_status());
932 932
         // setup new class to return via ajax
933
-        $this->_template_args['admin_page_content'] = 'clickable trigger-checkin ' . $new_status->cssClasses();
933
+        $this->_template_args['admin_page_content'] = 'clickable trigger-checkin '.$new_status->cssClasses();
934 934
         $this->_template_args['success']            = true;
935 935
         $this->_return_json();
936 936
     }
@@ -953,7 +953,7 @@  discard block
 block discarded – undo
953 953
 
954 954
         $new_status = false;
955 955
         // bulk action check in toggle
956
-        if (! empty($checkboxes)) {
956
+        if ( ! empty($checkboxes)) {
957 957
             foreach ($checkboxes as $REG_ID) {
958 958
                 $new_status = $this->_toggle_checkin($REG_ID, $DTT_ID);
959 959
             }
@@ -993,8 +993,8 @@  discard block
 block discarded – undo
993 993
     private function _toggle_checkin(int $REG_ID, int $DTT_ID)
994 994
     {
995 995
         /** @var EE_Registration $REG */
996
-        $REG        = EEM_Registration::instance()->get_one_by_ID($REG_ID);
997
-        if (! $REG instanceof EE_Registration) {
996
+        $REG = EEM_Registration::instance()->get_one_by_ID($REG_ID);
997
+        if ( ! $REG instanceof EE_Registration) {
998 998
             EE_Error::add_error(
999 999
                 sprintf(
1000 1000
                     esc_html__('There is no registration with ID (%d)', 'event_espresso'),
@@ -1031,11 +1031,11 @@  discard block
 block discarded – undo
1031 1031
             'DTT_ID'  => $this->_req_data['DTT_ID'] ?? 0,
1032 1032
             '_REG_ID' => $this->_req_data['_REG_ID'] ?? 0,
1033 1033
         ];
1034
-        $errors     = 0;
1035
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1034
+        $errors = 0;
1035
+        if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1036 1036
             $checkboxes = $this->_req_data['checkbox'];
1037 1037
             foreach (array_keys($checkboxes) as $CHK_ID) {
1038
-                if (! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) {
1038
+                if ( ! EEM_Checkin::instance()->delete_by_ID($CHK_ID)) {
1039 1039
                     $errors++;
1040 1040
                 }
1041 1041
             }
@@ -1082,8 +1082,8 @@  discard block
 block discarded – undo
1082 1082
             'DTT_ID'  => $this->_req_data['DTT_ID'] ?? 0,
1083 1083
             '_REG_ID' => $this->_req_data['_REG_ID'] ?? 0,
1084 1084
         ];
1085
-        if (! empty($this->_req_data['CHK_ID'])) {
1086
-            if (! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) {
1085
+        if ( ! empty($this->_req_data['CHK_ID'])) {
1086
+            if ( ! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'])) {
1087 1087
                 EE_Error::add_error(
1088 1088
                     esc_html__('Something went wrong and this check-in record was not deleted', 'event_espresso'),
1089 1089
                     __FILE__,
@@ -1114,7 +1114,7 @@  discard block
 block discarded – undo
1114 1114
      */
1115 1115
     protected function _event_registrations_list_table()
1116 1116
     {
1117
-        $EVT_ID                  = $this->request->getRequestParam('EVT_ID', 0, DataType::INTEGER);
1117
+        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, DataType::INTEGER);
1118 1118
         $this->_admin_page_title .= $EVT_ID
1119 1119
             ? $this->get_action_link_or_button(
1120 1120
                 'new_registration',
@@ -1153,7 +1153,7 @@  discard block
 block discarded – undo
1153 1153
                 <strong>' . esc_html__(
1154 1154
             'In this view, the check-in status represents the latest check-in record for the registration in that row.',
1155 1155
             'event_espresso'
1156
-        ) . '</strong>
1156
+        ).'</strong>
1157 1157
             </div>';
1158 1158
         return $header_text;
1159 1159
     }
@@ -1193,27 +1193,27 @@  discard block
 block discarded – undo
1193 1193
                 'desc'  => $checkin_invalid->legendLabel(),
1194 1194
             ],
1195 1195
             'approved_status'  => [
1196
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::APPROVED,
1196
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::APPROVED,
1197 1197
                 'desc'  => EEH_Template::pretty_status(RegStatus::APPROVED, false, 'sentence'),
1198 1198
             ],
1199 1199
             'cancelled_status' => [
1200
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::CANCELLED,
1200
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::CANCELLED,
1201 1201
                 'desc'  => EEH_Template::pretty_status(RegStatus::CANCELLED, false, 'sentence'),
1202 1202
             ],
1203 1203
             'declined_status'  => [
1204
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::DECLINED,
1204
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::DECLINED,
1205 1205
                 'desc'  => EEH_Template::pretty_status(RegStatus::DECLINED, false, 'sentence'),
1206 1206
             ],
1207 1207
             'not_approved'     => [
1208
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::AWAITING_REVIEW,
1208
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::AWAITING_REVIEW,
1209 1209
                 'desc'  => EEH_Template::pretty_status(RegStatus::AWAITING_REVIEW, false, 'sentence'),
1210 1210
             ],
1211 1211
             'pending_status'   => [
1212
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::PENDING_PAYMENT,
1212
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::PENDING_PAYMENT,
1213 1213
                 'desc'  => EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'sentence'),
1214 1214
             ],
1215 1215
             'wait_list'        => [
1216
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::WAIT_LIST,
1216
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::WAIT_LIST,
1217 1217
                 'desc'  => EEH_Template::pretty_status(RegStatus::WAIT_LIST, false, 'sentence'),
1218 1218
             ],
1219 1219
         ];
@@ -1250,7 +1250,7 @@  discard block
 block discarded – undo
1250 1250
     ): array {
1251 1251
         $query_params = $this->_get_registration_query_parameters($query_params, $per_page, $count);
1252 1252
         // unlike the regular registrations list table,
1253
-        $status_ids_array          = apply_filters(
1253
+        $status_ids_array = apply_filters(
1254 1254
             'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
1255 1255
             [RegStatus::PENDING_PAYMENT, RegStatus::APPROVED]
1256 1256
         );
Please login to merge, or discard this patch.
caffeinated/admin/extend/registrations/RegistrationsListTableFilters.php 2 patches
Indentation   +208 added lines, -208 removed lines patch added patch discarded remove patch
@@ -23,249 +23,249 @@
 block discarded – undo
23 23
  */
24 24
 class RegistrationsListTableFilters
25 25
 {
26
-    protected RequestInterface $request;
26
+	protected RequestInterface $request;
27 27
 
28
-    /**
29
-     * This property will hold the related Datetimes on an event IF the event ID is included in the request.
30
-     */
31
-    protected DatetimesForEventCheckIn $datetimes_for_event;
28
+	/**
29
+	 * This property will hold the related Datetimes on an event IF the event ID is included in the request.
30
+	 */
31
+	protected DatetimesForEventCheckIn $datetimes_for_event;
32 32
 
33
-    protected ?EE_Datetime $datetime = null;
33
+	protected ?EE_Datetime $datetime = null;
34 34
 
35
-    protected ?EE_Event $event = null;
35
+	protected ?EE_Event $event = null;
36 36
 
37
-    /**
38
-     * The DTT_ID if the current view has a specified datetime.
39
-     */
40
-    protected int $DTT_ID = 0;
37
+	/**
38
+	 * The DTT_ID if the current view has a specified datetime.
39
+	 */
40
+	protected int $DTT_ID = 0;
41 41
 
42
-    /**
43
-     * The event ID if one is specified in the request
44
-     */
45
-    protected int $EVT_ID = 0;
42
+	/**
43
+	 * The event ID if one is specified in the request
44
+	 */
45
+	protected int $EVT_ID = 0;
46 46
 
47
-    protected bool $hide_expired = false;
47
+	protected bool $hide_expired = false;
48 48
 
49
-    protected bool $hide_upcoming = false;
49
+	protected bool $hide_upcoming = false;
50 50
 
51
-    protected string $label = '';
51
+	protected string $label = '';
52 52
 
53
-
54
-    /**
55
-     * @param RequestInterface $request
56
-     */
57
-    public function __construct(RequestInterface $request)
58
-    {
59
-        $this->request = $request;
60
-    }
61
-
62
-
63
-    /**
64
-     * @throws EE_Error
65
-     * @throws ReflectionException
66
-     * @since 5.0.0.p
67
-     */
68
-    public function resolveRequestVars()
69
-    {
70
-        $this->EVT_ID = $this->request->getRequestParam('EVT_ID', 0, DataType::INTEGER);
71
-        $this->EVT_ID = $this->request->getRequestParam('event_id', $this->EVT_ID, DataType::INTEGER);
72
-        $this->DTT_ID        = $this->request->getRequestParam('DTT_ID', $this->DTT_ID, DataType::INTEGER);
73
-        $this->DTT_ID        = $this->request->getRequestParam('datetime_id', $this->DTT_ID, DataType::INTEGER);
74
-        $this->hide_expired  = $this->request->getRequestParam('hide_expired', false, DataType::BOOL);
75
-        $this->hide_upcoming = $this->request->getRequestParam('hide_upcoming', false, DataType::BOOL);
76
-
77
-        $this->event  = EEM_Event::instance()->get_one_by_ID($this->EVT_ID);
78
-        $this->datetimes_for_event = new DatetimesForEventCheckIn(EE_Capabilities::instance(), $this->event);
79
-        // if we're filtering for a specific event and it only has one datetime, then grab its ID
80
-        $this->datetime = $this->datetimes_for_event->getOneDatetimeForEvent($this->DTT_ID, $this->hide_expired, $this->hide_upcoming);
81
-        // use the above datetime ID (and hope it matches any in the request if BOTH exist, LOLZ)
82
-        $this->DTT_ID = $this->datetime instanceof EE_Datetime ? $this->datetime->ID() : $this->DTT_ID;
83
-        if ($this->DTT_ID) {
84
-            // in case datetime ID was not set in the request, add it so that other filters can use it
85
-            $this->request->setRequestParam('DTT_ID', $this->DTT_ID);
86
-        }
87
-    }
88
-
89
-
90
-    public function datetime(): ?EE_Datetime
91
-    {
92
-        return $this->datetime;
93
-    }
94
-
95
-
96
-    public function datetimeID(): int
97
-    {
98
-        return $this->DTT_ID;
99
-    }
100
-
101
-
102
-    public function event(): ?EE_Event
103
-    {
104
-        return $this->event;
105
-    }
106
-
107
-
108
-    public function eventID(): int
109
-    {
110
-        return $this->EVT_ID;
111
-    }
112
-
113
-
114
-    /**
115
-     * @throws EE_Error
116
-     * @throws ReflectionException
117
-     */
118
-    public function addFiltersAfter(array $filters): array
119
-    {
120
-        return array_merge($filters, $this->getFilters());
121
-    }
122
-
123
-
124
-    /**
125
-     * @throws EE_Error
126
-     * @throws ReflectionException
127
-     */
128
-    public function addFiltersBefore(array $filters): array
129
-    {
130
-        return array_merge($this->getFilters(), $filters);
131
-    }
132
-
133
-
134
-    public function setLabel(string $label): void
135
-    {
136
-        $this->label = $label;
137
-    }
138
-
139
-
140
-    private function getLabel(): string
141
-    {
142
-        return $this->label
143
-            ? '<label class="ee-event-filter-main-label">' . esc_html($this->label) . '</label>'
144
-            : '';
145
-    }
146
-
147
-
148
-    /**
149
-     * @throws EE_Error
150
-     * @throws ReflectionException
151
-     */
152
-    public function getFilters(): array
153
-    {
154
-        $filters               = [];
155
-        $hide_expired_checked  = $this->hide_expired ? 'checked' : '';
156
-        $hide_upcoming_checked = $this->hide_upcoming ? 'checked' : '';
157
-        // get datetimes for ALL active events (note possible capability restrictions)
158
-        $events          = $this->datetimes_for_event->getAllEvents();
159
-        $event_options[] = [
160
-            'id'   => 0,
161
-            'text' => esc_html__('Select an Event', 'event_espresso'),
162
-        ];
163
-        foreach ($events as $event) {
164
-            // any registrations for this event?
165
-            if (! $event instanceof EE_Event) {
166
-                continue;
167
-            }
168
-            $expired_class  = $event->is_expired() ? 'ee-expired-event' : '';
169
-            $upcoming_class = $event->is_upcoming() ? ' ee-upcoming-event' : '';
170
-
171
-            $event_options[] = [
172
-                'id'    => $event->ID(),
173
-                'text'  => apply_filters(
174
-                    'FHEE__EE_Event_Registrations___get_table_filters__event_name',
175
-                    $event->name(),
176
-                    $event
177
-                ),
178
-                'class' => $expired_class . $upcoming_class,
179
-            ];
180
-            if ($event->ID() === $this->EVT_ID) {
181
-                $this->hide_expired    = $expired_class === '' ? $this->hide_expired : false;
182
-                $hide_expired_checked  = $expired_class === '' ? $hide_expired_checked : '';
183
-                $this->hide_upcoming   = $upcoming_class === '' ? $this->hide_upcoming : false;
184
-                $hide_upcoming_checked = $upcoming_class === '' ? $hide_upcoming_checked : '';
185
-            }
186
-        }
187
-
188
-        $select_class = $this->hide_expired ? 'ee-hide-expired-events' : '';
189
-        $select_class .= $this->hide_upcoming ? ' ee-hide-upcoming-events' : '';
190
-        $select_input = EEH_Form_Fields::select_input(
191
-            'EVT_ID',
192
-            $event_options,
193
-            $this->EVT_ID,
194
-            '',
195
-            $select_class
196
-        );
197
-
198
-        $filters[] = $this->getLabel() . '
53
+
54
+	/**
55
+	 * @param RequestInterface $request
56
+	 */
57
+	public function __construct(RequestInterface $request)
58
+	{
59
+		$this->request = $request;
60
+	}
61
+
62
+
63
+	/**
64
+	 * @throws EE_Error
65
+	 * @throws ReflectionException
66
+	 * @since 5.0.0.p
67
+	 */
68
+	public function resolveRequestVars()
69
+	{
70
+		$this->EVT_ID = $this->request->getRequestParam('EVT_ID', 0, DataType::INTEGER);
71
+		$this->EVT_ID = $this->request->getRequestParam('event_id', $this->EVT_ID, DataType::INTEGER);
72
+		$this->DTT_ID        = $this->request->getRequestParam('DTT_ID', $this->DTT_ID, DataType::INTEGER);
73
+		$this->DTT_ID        = $this->request->getRequestParam('datetime_id', $this->DTT_ID, DataType::INTEGER);
74
+		$this->hide_expired  = $this->request->getRequestParam('hide_expired', false, DataType::BOOL);
75
+		$this->hide_upcoming = $this->request->getRequestParam('hide_upcoming', false, DataType::BOOL);
76
+
77
+		$this->event  = EEM_Event::instance()->get_one_by_ID($this->EVT_ID);
78
+		$this->datetimes_for_event = new DatetimesForEventCheckIn(EE_Capabilities::instance(), $this->event);
79
+		// if we're filtering for a specific event and it only has one datetime, then grab its ID
80
+		$this->datetime = $this->datetimes_for_event->getOneDatetimeForEvent($this->DTT_ID, $this->hide_expired, $this->hide_upcoming);
81
+		// use the above datetime ID (and hope it matches any in the request if BOTH exist, LOLZ)
82
+		$this->DTT_ID = $this->datetime instanceof EE_Datetime ? $this->datetime->ID() : $this->DTT_ID;
83
+		if ($this->DTT_ID) {
84
+			// in case datetime ID was not set in the request, add it so that other filters can use it
85
+			$this->request->setRequestParam('DTT_ID', $this->DTT_ID);
86
+		}
87
+	}
88
+
89
+
90
+	public function datetime(): ?EE_Datetime
91
+	{
92
+		return $this->datetime;
93
+	}
94
+
95
+
96
+	public function datetimeID(): int
97
+	{
98
+		return $this->DTT_ID;
99
+	}
100
+
101
+
102
+	public function event(): ?EE_Event
103
+	{
104
+		return $this->event;
105
+	}
106
+
107
+
108
+	public function eventID(): int
109
+	{
110
+		return $this->EVT_ID;
111
+	}
112
+
113
+
114
+	/**
115
+	 * @throws EE_Error
116
+	 * @throws ReflectionException
117
+	 */
118
+	public function addFiltersAfter(array $filters): array
119
+	{
120
+		return array_merge($filters, $this->getFilters());
121
+	}
122
+
123
+
124
+	/**
125
+	 * @throws EE_Error
126
+	 * @throws ReflectionException
127
+	 */
128
+	public function addFiltersBefore(array $filters): array
129
+	{
130
+		return array_merge($this->getFilters(), $filters);
131
+	}
132
+
133
+
134
+	public function setLabel(string $label): void
135
+	{
136
+		$this->label = $label;
137
+	}
138
+
139
+
140
+	private function getLabel(): string
141
+	{
142
+		return $this->label
143
+			? '<label class="ee-event-filter-main-label">' . esc_html($this->label) . '</label>'
144
+			: '';
145
+	}
146
+
147
+
148
+	/**
149
+	 * @throws EE_Error
150
+	 * @throws ReflectionException
151
+	 */
152
+	public function getFilters(): array
153
+	{
154
+		$filters               = [];
155
+		$hide_expired_checked  = $this->hide_expired ? 'checked' : '';
156
+		$hide_upcoming_checked = $this->hide_upcoming ? 'checked' : '';
157
+		// get datetimes for ALL active events (note possible capability restrictions)
158
+		$events          = $this->datetimes_for_event->getAllEvents();
159
+		$event_options[] = [
160
+			'id'   => 0,
161
+			'text' => esc_html__('Select an Event', 'event_espresso'),
162
+		];
163
+		foreach ($events as $event) {
164
+			// any registrations for this event?
165
+			if (! $event instanceof EE_Event) {
166
+				continue;
167
+			}
168
+			$expired_class  = $event->is_expired() ? 'ee-expired-event' : '';
169
+			$upcoming_class = $event->is_upcoming() ? ' ee-upcoming-event' : '';
170
+
171
+			$event_options[] = [
172
+				'id'    => $event->ID(),
173
+				'text'  => apply_filters(
174
+					'FHEE__EE_Event_Registrations___get_table_filters__event_name',
175
+					$event->name(),
176
+					$event
177
+				),
178
+				'class' => $expired_class . $upcoming_class,
179
+			];
180
+			if ($event->ID() === $this->EVT_ID) {
181
+				$this->hide_expired    = $expired_class === '' ? $this->hide_expired : false;
182
+				$hide_expired_checked  = $expired_class === '' ? $hide_expired_checked : '';
183
+				$this->hide_upcoming   = $upcoming_class === '' ? $this->hide_upcoming : false;
184
+				$hide_upcoming_checked = $upcoming_class === '' ? $hide_upcoming_checked : '';
185
+			}
186
+		}
187
+
188
+		$select_class = $this->hide_expired ? 'ee-hide-expired-events' : '';
189
+		$select_class .= $this->hide_upcoming ? ' ee-hide-upcoming-events' : '';
190
+		$select_input = EEH_Form_Fields::select_input(
191
+			'EVT_ID',
192
+			$event_options,
193
+			$this->EVT_ID,
194
+			'',
195
+			$select_class
196
+		);
197
+
198
+		$filters[] = $this->getLabel() . '
199 199
         <div class="ee-event-filter">
200 200
             <span class="ee-event-selector">
201 201
                 <label for="event_selector">' . esc_html__('Event', 'event_espresso') . '</label>
202 202
                 ' . $select_input . '
203 203
             </span>';
204
-        // DTT datetimes filter
205
-        $datetimes_for_event = $this->datetimes_for_event->getAllDatetimesForEvent(
206
-            $hide_upcoming_checked === 'checked'
207
-        );
208
-        if (count($datetimes_for_event) === 1) {
209
-            $filters[] = EEH_Form_Fields::adminHidden('', '', 'DTT_ID', $this->DTT_ID);
210
-        } elseif (count($datetimes_for_event) > 1) {
211
-            $datetimes[0] = esc_html__(' - select a datetime - ', 'event_espresso');
212
-            foreach ($datetimes_for_event as $datetime) {
213
-                if ($datetime instanceof EE_Datetime) {
214
-                    $datetime_string = $datetime->name();
215
-                    $datetime_string = ! empty($datetime_string) ? $datetime_string . ': ' : '';
216
-                    $datetime_string .= $datetime->date_and_time_range();
217
-                    $datetime_string .= $datetime->is_active() ? ' ∗' : '';
218
-                    $datetime_string .= $datetime->is_expired() ? ' «' : '';
219
-                    $datetime_string .= $datetime->is_upcoming() ? ' »' : '';
220
-                    // now put it all together
221
-                    $datetimes[ $datetime->ID() ] = $datetime_string;
222
-                }
223
-            }
224
-            $filters[] = '
204
+		// DTT datetimes filter
205
+		$datetimes_for_event = $this->datetimes_for_event->getAllDatetimesForEvent(
206
+			$hide_upcoming_checked === 'checked'
207
+		);
208
+		if (count($datetimes_for_event) === 1) {
209
+			$filters[] = EEH_Form_Fields::adminHidden('', '', 'DTT_ID', $this->DTT_ID);
210
+		} elseif (count($datetimes_for_event) > 1) {
211
+			$datetimes[0] = esc_html__(' - select a datetime - ', 'event_espresso');
212
+			foreach ($datetimes_for_event as $datetime) {
213
+				if ($datetime instanceof EE_Datetime) {
214
+					$datetime_string = $datetime->name();
215
+					$datetime_string = ! empty($datetime_string) ? $datetime_string . ': ' : '';
216
+					$datetime_string .= $datetime->date_and_time_range();
217
+					$datetime_string .= $datetime->is_active() ? ' ∗' : '';
218
+					$datetime_string .= $datetime->is_expired() ? ' «' : '';
219
+					$datetime_string .= $datetime->is_upcoming() ? ' »' : '';
220
+					// now put it all together
221
+					$datetimes[ $datetime->ID() ] = $datetime_string;
222
+				}
223
+			}
224
+			$filters[] = '
225 225
             <span class="ee-datetime-selector">
226 226
                 <label for="DTT_ID">' . esc_html__('Datetime', 'event_espresso') . '</label>
227 227
                 ' . EEH_Form_Fields::select_input(
228
-                    'DTT_ID',
229
-                    $datetimes,
230
-                    $this->DTT_ID
231
-                ) . '
228
+					'DTT_ID',
229
+					$datetimes,
230
+					$this->DTT_ID
231
+				) . '
232 232
             </span>';
233
-        }
234
-        $filters[] = '
233
+		}
234
+		$filters[] = '
235 235
             <span class="ee-hide-upcoming-check">
236 236
                 <label for="js-ee-hide-upcoming-events">
237 237
                     <input type="checkbox" id="js-ee-hide-upcoming-events" name="hide_upcoming" '
238
-            . $hide_upcoming_checked
239
-            . '>
238
+			. $hide_upcoming_checked
239
+			. '>
240 240
                             '
241
-            . esc_html__('Hide Upcoming Events', 'event_espresso')
242
-            . '
241
+			. esc_html__('Hide Upcoming Events', 'event_espresso')
242
+			. '
243 243
                 </label>
244 244
                 <span class="ee-help-btn dashicons dashicons-editor-help ee-aria-tooltip"
245 245
                       aria-label="'
246
-            . esc_html__(
247
-                'Will not display events in the preceding event selector with start dates in the future (ie: have not yet begun)',
248
-                'event_espresso'
249
-            ) . '"
246
+			. esc_html__(
247
+				'Will not display events in the preceding event selector with start dates in the future (ie: have not yet begun)',
248
+				'event_espresso'
249
+			) . '"
250 250
                 ></span>
251 251
             </span>
252 252
             <span class="ee-hide-expired-check">
253 253
                 <label for="js-ee-hide-expired-events">
254 254
                     <input type="checkbox" id="js-ee-hide-expired-events" name="hide_expired" '
255
-            . $hide_expired_checked
256
-            . '>
255
+			. $hide_expired_checked
256
+			. '>
257 257
                         ' . esc_html__('Hide Expired Events', 'event_espresso') . '
258 258
                 </label>
259 259
                 <span class="ee-help-btn dashicons dashicons-editor-help ee-aria-tooltip"
260 260
                       aria-label="'
261
-            . esc_html__(
262
-                'Will not display events in the preceding event selector with end dates in the past (ie: have already finished)',
263
-                'event_espresso'
264
-            )
265
-            . '"
261
+			. esc_html__(
262
+				'Will not display events in the preceding event selector with end dates in the past (ie: have already finished)',
263
+				'event_espresso'
264
+			)
265
+			. '"
266 266
                 ></span>
267 267
             </span>
268 268
         </div>';
269
-        return $filters;
270
-    }
269
+		return $filters;
270
+	}
271 271
 }
Please login to merge, or discard this patch.
Spacing   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -74,7 +74,7 @@  discard block
 block discarded – undo
74 74
         $this->hide_expired  = $this->request->getRequestParam('hide_expired', false, DataType::BOOL);
75 75
         $this->hide_upcoming = $this->request->getRequestParam('hide_upcoming', false, DataType::BOOL);
76 76
 
77
-        $this->event  = EEM_Event::instance()->get_one_by_ID($this->EVT_ID);
77
+        $this->event = EEM_Event::instance()->get_one_by_ID($this->EVT_ID);
78 78
         $this->datetimes_for_event = new DatetimesForEventCheckIn(EE_Capabilities::instance(), $this->event);
79 79
         // if we're filtering for a specific event and it only has one datetime, then grab its ID
80 80
         $this->datetime = $this->datetimes_for_event->getOneDatetimeForEvent($this->DTT_ID, $this->hide_expired, $this->hide_upcoming);
@@ -140,7 +140,7 @@  discard block
 block discarded – undo
140 140
     private function getLabel(): string
141 141
     {
142 142
         return $this->label
143
-            ? '<label class="ee-event-filter-main-label">' . esc_html($this->label) . '</label>'
143
+            ? '<label class="ee-event-filter-main-label">'.esc_html($this->label).'</label>'
144 144
             : '';
145 145
     }
146 146
 
@@ -162,7 +162,7 @@  discard block
 block discarded – undo
162 162
         ];
163 163
         foreach ($events as $event) {
164 164
             // any registrations for this event?
165
-            if (! $event instanceof EE_Event) {
165
+            if ( ! $event instanceof EE_Event) {
166 166
                 continue;
167 167
             }
168 168
             $expired_class  = $event->is_expired() ? 'ee-expired-event' : '';
@@ -175,7 +175,7 @@  discard block
 block discarded – undo
175 175
                     $event->name(),
176 176
                     $event
177 177
                 ),
178
-                'class' => $expired_class . $upcoming_class,
178
+                'class' => $expired_class.$upcoming_class,
179 179
             ];
180 180
             if ($event->ID() === $this->EVT_ID) {
181 181
                 $this->hide_expired    = $expired_class === '' ? $this->hide_expired : false;
@@ -195,11 +195,11 @@  discard block
 block discarded – undo
195 195
             $select_class
196 196
         );
197 197
 
198
-        $filters[] = $this->getLabel() . '
198
+        $filters[] = $this->getLabel().'
199 199
         <div class="ee-event-filter">
200 200
             <span class="ee-event-selector">
201
-                <label for="event_selector">' . esc_html__('Event', 'event_espresso') . '</label>
202
-                ' . $select_input . '
201
+                <label for="event_selector">' . esc_html__('Event', 'event_espresso').'</label>
202
+                ' . $select_input.'
203 203
             </span>';
204 204
         // DTT datetimes filter
205 205
         $datetimes_for_event = $this->datetimes_for_event->getAllDatetimesForEvent(
@@ -212,23 +212,23 @@  discard block
 block discarded – undo
212 212
             foreach ($datetimes_for_event as $datetime) {
213 213
                 if ($datetime instanceof EE_Datetime) {
214 214
                     $datetime_string = $datetime->name();
215
-                    $datetime_string = ! empty($datetime_string) ? $datetime_string . ': ' : '';
215
+                    $datetime_string = ! empty($datetime_string) ? $datetime_string.': ' : '';
216 216
                     $datetime_string .= $datetime->date_and_time_range();
217 217
                     $datetime_string .= $datetime->is_active() ? ' ∗' : '';
218 218
                     $datetime_string .= $datetime->is_expired() ? ' «' : '';
219 219
                     $datetime_string .= $datetime->is_upcoming() ? ' »' : '';
220 220
                     // now put it all together
221
-                    $datetimes[ $datetime->ID() ] = $datetime_string;
221
+                    $datetimes[$datetime->ID()] = $datetime_string;
222 222
                 }
223 223
             }
224 224
             $filters[] = '
225 225
             <span class="ee-datetime-selector">
226
-                <label for="DTT_ID">' . esc_html__('Datetime', 'event_espresso') . '</label>
226
+                <label for="DTT_ID">' . esc_html__('Datetime', 'event_espresso').'</label>
227 227
                 ' . EEH_Form_Fields::select_input(
228 228
                     'DTT_ID',
229 229
                     $datetimes,
230 230
                     $this->DTT_ID
231
-                ) . '
231
+                ).'
232 232
             </span>';
233 233
         }
234 234
         $filters[] = '
@@ -246,7 +246,7 @@  discard block
 block discarded – undo
246 246
             . esc_html__(
247 247
                 'Will not display events in the preceding event selector with start dates in the future (ie: have not yet begun)',
248 248
                 'event_espresso'
249
-            ) . '"
249
+            ).'"
250 250
                 ></span>
251 251
             </span>
252 252
             <span class="ee-hide-expired-check">
@@ -254,7 +254,7 @@  discard block
 block discarded – undo
254 254
                     <input type="checkbox" id="js-ee-hide-expired-events" name="hide_expired" '
255 255
             . $hide_expired_checked
256 256
             . '>
257
-                        ' . esc_html__('Hide Expired Events', 'event_espresso') . '
257
+                        ' . esc_html__('Hide Expired Events', 'event_espresso').'
258 258
                 </label>
259 259
                 <span class="ee-help-btn dashicons dashicons-editor-help ee-aria-tooltip"
260 260
                       aria-label="'
Please login to merge, or discard this patch.
admin/extend/registrations/EE_Event_Registrations_List_Table.class.php 2 patches
Indentation   +350 added lines, -350 removed lines patch added patch discarded remove patch
@@ -18,373 +18,373 @@
 block discarded – undo
18 18
  */
19 19
 class EE_Event_Registrations_List_Table extends EE_Registrations_List_Table
20 20
 {
21
-    /**
22
-     * @var Extend_Registrations_Admin_Page
23
-     */
24
-    protected EE_Admin_Page $_admin_page;
25
-
26
-    /**
27
-     * This property will hold the related Datetimes on an event IF the event id is included in the request.
28
-     */
29
-    protected ?DatetimesForEventCheckIn $datetimes_for_current_row = null;
30
-
31
-    protected array $_status       = [];
32
-
33
-    private RegistrationsListTableFilters $filters;
34
-
35
-
36
-    /**
37
-     * EE_Event_Registrations_List_Table constructor.
38
-     *
39
-     * @param Registrations_Admin_Page $admin_page
40
-     * @throws EE_Error
41
-     * @throws ReflectionException
42
-     */
43
-    public function __construct($admin_page)
44
-    {
45
-        $this->request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
46
-        $this->filters = new RegistrationsListTableFilters($this->request);
47
-        $this->filters->resolveRequestVars();
48
-        $this->filters->setLabel(__('Check-in Status for', 'event_espresso'));
49
-        parent::__construct($admin_page);
50
-    }
51
-
52
-
53
-    /**
54
-     * @throws EE_Error
55
-     * @throws ReflectionException
56
-     */
57
-    protected function _setup_data()
58
-    {
59
-        $this->_data = $this->_view !== 'trash'
60
-            ? $this->_admin_page->get_event_attendees($this->_per_page)
61
-            : $this->_admin_page->get_event_attendees($this->_per_page, false, true);
62
-
63
-        $this->_all_data_count = $this->_view !== 'trash'
64
-            ? $this->_admin_page->get_event_attendees($this->_per_page, true)
65
-            : $this->_admin_page->get_event_attendees($this->_per_page, true, true);
66
-    }
67
-
68
-
69
-    protected function _set_properties()
70
-    {
71
-        $this->_wp_list_args = [
72
-            'singular' => esc_html__('registrant', 'event_espresso'),
73
-            'plural'   => esc_html__('registrants', 'event_espresso'),
74
-            'ajax'     => true,
75
-            'screen'   => $this->_admin_page->get_current_screen()->id,
76
-        ];
77
-        $columns             = [];
78
-
79
-        $this->_columns = [
80
-            '_REG_att_checked_in' => '<span class="dashicons dashicons-yes-alt"></span>',
81
-            'ATT_name'            => esc_html__('Registrant', 'event_espresso'),
82
-            'ATT_email'           => esc_html__('Email Address', 'event_espresso'),
83
-            'Event'               => esc_html__('Event', 'event_espresso'),
84
-            'REG_ticket'          => esc_html__('Ticket', 'event_espresso'),
85
-            '_REG_final_price'    => esc_html__('Price', 'event_espresso'),
86
-            '_REG_paid'           => esc_html__('REG Paid', 'event_espresso'),
87
-            'TXN_total'           => esc_html__('TXN Paid/Total', 'event_espresso'),
88
-        ];
89
-        // Add/remove columns when an event or datetime has been selected
90
-        if (! empty($this->filters->eventID())) {
91
-            // Remove the 'Event' column
92
-            unset($this->_columns['Event']);
93
-        }
94
-        if (! empty($this->filters->datetimeID())) {
95
-            // Render a checkbox column for triggering bulk check-ins
96
-            $columns['cb']              = '<input type="checkbox" />';
97
-            $this->_has_checkbox_column = true;
98
-        }
99
-        $this->_columns        = array_merge($columns, $this->_columns);
100
-        $this->_primary_column = '_REG_att_checked_in';
101
-
102
-        $csv_report = RegistrationsCsvReportParams::getRequestParams(
103
-            $this->getReturnUrl(),
104
-            $this->_admin_page->get_request_data(),
105
-            $this->filters->eventID(),
106
-            $this->filters->datetimeID()
107
-        );
108
-        if (! empty($csv_report)) {
109
-            $this->_bottom_buttons['csv_reg_report'] = $csv_report;
110
-        }
111
-
112
-        $this->_sortable_columns = [
113
-            /**
114
-             * Allows users to change the default sort if they wish.
115
-             * Returning a falsey on this filter will result in the default sort to be by firstname rather than last name.
116
-             * Note: usual naming conventions for filters aren't followed here so that just one filter can be used to
117
-             * change the sorts on any list table involving registration contacts.  If you want to only change the filter
118
-             * for a specific list table you can use the provided reference to this object instance.
119
-             */
120
-            'ATT_name' => [
121
-                'FHEE__EE_Registrations_List_Table___set_properties__default_sort_by_registration_last_name',
122
-                true,
123
-                $this,
124
-            ]
125
-                ? ['ATT_lname' => true]
126
-                : ['ATT_fname' => true],
127
-            'Event'    => ['Event.EVT_name' => false],
128
-        ];
129
-        $this->_hidden_columns   = [];
130
-    }
131
-
132
-
133
-    /**
134
-     * @param EE_Registration $item
135
-     * @return string
136
-     */
137
-    protected function _get_row_class($item): string
138
-    {
139
-        $class = parent::_get_row_class($item);
140
-        if ($this->_has_checkbox_column) {
141
-            $class .= ' has-checkbox-column';
142
-        }
143
-        return $class;
144
-    }
145
-
146
-
147
-    /**
148
-     * @return array
149
-     * @throws EE_Error
150
-     * @throws ReflectionException
151
-     */
152
-    protected function _get_table_filters()
153
-    {
154
-        return $this->filters->getFilters();
155
-    }
156
-
157
-
158
-    /**
159
-     * @throws EE_Error
160
-     * @throws ReflectionException
161
-     */
162
-    protected function _add_view_counts()
163
-    {
164
-        $this->_views['all']['count'] = $this->_get_total_event_attendees();
165
-    }
166
-
167
-
168
-    /**
169
-     * @return int
170
-     * @throws EE_Error
171
-     * @throws ReflectionException
172
-     */
173
-    protected function _get_total_event_attendees(): int
174
-    {
175
-        $query_params = [];
176
-        if ($this->filters->eventID()) {
177
-            $query_params[0]['EVT_ID'] = $this->filters->eventID();
178
-        }
179
-        // if DTT is included we only show for that datetime.  Otherwise we're showing for all datetimes (the event).
180
-        if ($this->filters->datetimeID()) {
181
-            $query_params[0]['Ticket.Datetime.DTT_ID'] = $this->filters->datetimeID();
182
-        }
183
-        $status_ids_array          = apply_filters(
184
-            'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
185
-            [RegStatus::PENDING_PAYMENT, RegStatus::APPROVED]
186
-        );
187
-        $query_params[0]['STS_ID'] = ['IN', $status_ids_array];
188
-        return EEM_Registration::instance()->count($query_params);
189
-    }
190
-
191
-
192
-    /**
193
-     * @param EE_Registration $item
194
-     * @return string
195
-     * @throws EE_Error
196
-     * @throws ReflectionException
197
-     */
198
-    public function column_cb($item): string
199
-    {
200
-        return sprintf('<input class="bulk-check-in" type="checkbox" name="checkbox[%1$s]" value="%1$s" />', $item->ID());
201
-    }
202
-
203
-
204
-    /**
205
-     * column_REG_att_checked_in
206
-     *
207
-     * @param EE_Registration $registration
208
-     * @return string
209
-     * @throws EE_Error
210
-     * @throws InvalidArgumentException
211
-     * @throws InvalidDataTypeException
212
-     * @throws InvalidInterfaceException
213
-     * @throws ReflectionException
214
-     */
215
-    public function column__REG_att_checked_in(EE_Registration $registration): string
216
-    {
217
-        // we need a local variable for the datetime for each row
218
-        // (so that we don't pollute state for the entire table)
219
-        // so let's try to get it from the registration's event
220
-        $DTT_ID = $this->filters->datetimeID();
221
-        if (! $DTT_ID) {
222
-            $reg_ticket_datetimes = $registration->ticket()->datetimes();
223
-            if (count($reg_ticket_datetimes) === 1) {
224
-                $reg_ticket_datetime = reset($reg_ticket_datetimes);
225
-                $DTT_ID              = $reg_ticket_datetime instanceof EE_Datetime ? $reg_ticket_datetime->ID() : 0;
226
-            }
227
-        }
228
-
229
-        if (! $DTT_ID) {
230
-            $this->datetimes_for_current_row = DatetimesForEventCheckIn::fromRegistration($registration);
231
-            $datetime                        = $this->datetimes_for_current_row->getOneDatetimeForEvent($DTT_ID);
232
-            $DTT_ID                          = $datetime instanceof EE_Datetime ? $datetime->ID() : 0;
233
-        }
234
-
235
-        $checkin_status_dashicon = CheckinStatusDashicon::fromRegistrationAndDatetimeId(
236
-            $registration,
237
-            $DTT_ID
238
-        );
239
-
240
-        $aria_label     = $checkin_status_dashicon->ariaLabel();
241
-        $dashicon_class = $checkin_status_dashicon->cssClasses();
242
-        $attributes     = ' onClick="return false"';
243
-        $button_class   = 'button button--secondary button--icon-only ee-aria-tooltip ee-aria-tooltip--big-box';
244
-
245
-        if ($DTT_ID && $this->caps_handler->userCanEditRegistrationCheckin($registration)) {
246
-            // overwrite the disabled attribute with data attributes for performing checkin
247
-            $attributes   = 'data-_regid="' . $registration->ID() . '"';
248
-            $attributes   .= ' data-dttid="' . $DTT_ID . '"';
249
-            $attributes   .= ' data-nonce="' . wp_create_nonce('checkin_nonce') . '"';
250
-            $button_class .= ' clickable trigger-checkin';
251
-        }
252
-
253
-        $content = '
21
+	/**
22
+	 * @var Extend_Registrations_Admin_Page
23
+	 */
24
+	protected EE_Admin_Page $_admin_page;
25
+
26
+	/**
27
+	 * This property will hold the related Datetimes on an event IF the event id is included in the request.
28
+	 */
29
+	protected ?DatetimesForEventCheckIn $datetimes_for_current_row = null;
30
+
31
+	protected array $_status       = [];
32
+
33
+	private RegistrationsListTableFilters $filters;
34
+
35
+
36
+	/**
37
+	 * EE_Event_Registrations_List_Table constructor.
38
+	 *
39
+	 * @param Registrations_Admin_Page $admin_page
40
+	 * @throws EE_Error
41
+	 * @throws ReflectionException
42
+	 */
43
+	public function __construct($admin_page)
44
+	{
45
+		$this->request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
46
+		$this->filters = new RegistrationsListTableFilters($this->request);
47
+		$this->filters->resolveRequestVars();
48
+		$this->filters->setLabel(__('Check-in Status for', 'event_espresso'));
49
+		parent::__construct($admin_page);
50
+	}
51
+
52
+
53
+	/**
54
+	 * @throws EE_Error
55
+	 * @throws ReflectionException
56
+	 */
57
+	protected function _setup_data()
58
+	{
59
+		$this->_data = $this->_view !== 'trash'
60
+			? $this->_admin_page->get_event_attendees($this->_per_page)
61
+			: $this->_admin_page->get_event_attendees($this->_per_page, false, true);
62
+
63
+		$this->_all_data_count = $this->_view !== 'trash'
64
+			? $this->_admin_page->get_event_attendees($this->_per_page, true)
65
+			: $this->_admin_page->get_event_attendees($this->_per_page, true, true);
66
+	}
67
+
68
+
69
+	protected function _set_properties()
70
+	{
71
+		$this->_wp_list_args = [
72
+			'singular' => esc_html__('registrant', 'event_espresso'),
73
+			'plural'   => esc_html__('registrants', 'event_espresso'),
74
+			'ajax'     => true,
75
+			'screen'   => $this->_admin_page->get_current_screen()->id,
76
+		];
77
+		$columns             = [];
78
+
79
+		$this->_columns = [
80
+			'_REG_att_checked_in' => '<span class="dashicons dashicons-yes-alt"></span>',
81
+			'ATT_name'            => esc_html__('Registrant', 'event_espresso'),
82
+			'ATT_email'           => esc_html__('Email Address', 'event_espresso'),
83
+			'Event'               => esc_html__('Event', 'event_espresso'),
84
+			'REG_ticket'          => esc_html__('Ticket', 'event_espresso'),
85
+			'_REG_final_price'    => esc_html__('Price', 'event_espresso'),
86
+			'_REG_paid'           => esc_html__('REG Paid', 'event_espresso'),
87
+			'TXN_total'           => esc_html__('TXN Paid/Total', 'event_espresso'),
88
+		];
89
+		// Add/remove columns when an event or datetime has been selected
90
+		if (! empty($this->filters->eventID())) {
91
+			// Remove the 'Event' column
92
+			unset($this->_columns['Event']);
93
+		}
94
+		if (! empty($this->filters->datetimeID())) {
95
+			// Render a checkbox column for triggering bulk check-ins
96
+			$columns['cb']              = '<input type="checkbox" />';
97
+			$this->_has_checkbox_column = true;
98
+		}
99
+		$this->_columns        = array_merge($columns, $this->_columns);
100
+		$this->_primary_column = '_REG_att_checked_in';
101
+
102
+		$csv_report = RegistrationsCsvReportParams::getRequestParams(
103
+			$this->getReturnUrl(),
104
+			$this->_admin_page->get_request_data(),
105
+			$this->filters->eventID(),
106
+			$this->filters->datetimeID()
107
+		);
108
+		if (! empty($csv_report)) {
109
+			$this->_bottom_buttons['csv_reg_report'] = $csv_report;
110
+		}
111
+
112
+		$this->_sortable_columns = [
113
+			/**
114
+			 * Allows users to change the default sort if they wish.
115
+			 * Returning a falsey on this filter will result in the default sort to be by firstname rather than last name.
116
+			 * Note: usual naming conventions for filters aren't followed here so that just one filter can be used to
117
+			 * change the sorts on any list table involving registration contacts.  If you want to only change the filter
118
+			 * for a specific list table you can use the provided reference to this object instance.
119
+			 */
120
+			'ATT_name' => [
121
+				'FHEE__EE_Registrations_List_Table___set_properties__default_sort_by_registration_last_name',
122
+				true,
123
+				$this,
124
+			]
125
+				? ['ATT_lname' => true]
126
+				: ['ATT_fname' => true],
127
+			'Event'    => ['Event.EVT_name' => false],
128
+		];
129
+		$this->_hidden_columns   = [];
130
+	}
131
+
132
+
133
+	/**
134
+	 * @param EE_Registration $item
135
+	 * @return string
136
+	 */
137
+	protected function _get_row_class($item): string
138
+	{
139
+		$class = parent::_get_row_class($item);
140
+		if ($this->_has_checkbox_column) {
141
+			$class .= ' has-checkbox-column';
142
+		}
143
+		return $class;
144
+	}
145
+
146
+
147
+	/**
148
+	 * @return array
149
+	 * @throws EE_Error
150
+	 * @throws ReflectionException
151
+	 */
152
+	protected function _get_table_filters()
153
+	{
154
+		return $this->filters->getFilters();
155
+	}
156
+
157
+
158
+	/**
159
+	 * @throws EE_Error
160
+	 * @throws ReflectionException
161
+	 */
162
+	protected function _add_view_counts()
163
+	{
164
+		$this->_views['all']['count'] = $this->_get_total_event_attendees();
165
+	}
166
+
167
+
168
+	/**
169
+	 * @return int
170
+	 * @throws EE_Error
171
+	 * @throws ReflectionException
172
+	 */
173
+	protected function _get_total_event_attendees(): int
174
+	{
175
+		$query_params = [];
176
+		if ($this->filters->eventID()) {
177
+			$query_params[0]['EVT_ID'] = $this->filters->eventID();
178
+		}
179
+		// if DTT is included we only show for that datetime.  Otherwise we're showing for all datetimes (the event).
180
+		if ($this->filters->datetimeID()) {
181
+			$query_params[0]['Ticket.Datetime.DTT_ID'] = $this->filters->datetimeID();
182
+		}
183
+		$status_ids_array          = apply_filters(
184
+			'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
185
+			[RegStatus::PENDING_PAYMENT, RegStatus::APPROVED]
186
+		);
187
+		$query_params[0]['STS_ID'] = ['IN', $status_ids_array];
188
+		return EEM_Registration::instance()->count($query_params);
189
+	}
190
+
191
+
192
+	/**
193
+	 * @param EE_Registration $item
194
+	 * @return string
195
+	 * @throws EE_Error
196
+	 * @throws ReflectionException
197
+	 */
198
+	public function column_cb($item): string
199
+	{
200
+		return sprintf('<input class="bulk-check-in" type="checkbox" name="checkbox[%1$s]" value="%1$s" />', $item->ID());
201
+	}
202
+
203
+
204
+	/**
205
+	 * column_REG_att_checked_in
206
+	 *
207
+	 * @param EE_Registration $registration
208
+	 * @return string
209
+	 * @throws EE_Error
210
+	 * @throws InvalidArgumentException
211
+	 * @throws InvalidDataTypeException
212
+	 * @throws InvalidInterfaceException
213
+	 * @throws ReflectionException
214
+	 */
215
+	public function column__REG_att_checked_in(EE_Registration $registration): string
216
+	{
217
+		// we need a local variable for the datetime for each row
218
+		// (so that we don't pollute state for the entire table)
219
+		// so let's try to get it from the registration's event
220
+		$DTT_ID = $this->filters->datetimeID();
221
+		if (! $DTT_ID) {
222
+			$reg_ticket_datetimes = $registration->ticket()->datetimes();
223
+			if (count($reg_ticket_datetimes) === 1) {
224
+				$reg_ticket_datetime = reset($reg_ticket_datetimes);
225
+				$DTT_ID              = $reg_ticket_datetime instanceof EE_Datetime ? $reg_ticket_datetime->ID() : 0;
226
+			}
227
+		}
228
+
229
+		if (! $DTT_ID) {
230
+			$this->datetimes_for_current_row = DatetimesForEventCheckIn::fromRegistration($registration);
231
+			$datetime                        = $this->datetimes_for_current_row->getOneDatetimeForEvent($DTT_ID);
232
+			$DTT_ID                          = $datetime instanceof EE_Datetime ? $datetime->ID() : 0;
233
+		}
234
+
235
+		$checkin_status_dashicon = CheckinStatusDashicon::fromRegistrationAndDatetimeId(
236
+			$registration,
237
+			$DTT_ID
238
+		);
239
+
240
+		$aria_label     = $checkin_status_dashicon->ariaLabel();
241
+		$dashicon_class = $checkin_status_dashicon->cssClasses();
242
+		$attributes     = ' onClick="return false"';
243
+		$button_class   = 'button button--secondary button--icon-only ee-aria-tooltip ee-aria-tooltip--big-box';
244
+
245
+		if ($DTT_ID && $this->caps_handler->userCanEditRegistrationCheckin($registration)) {
246
+			// overwrite the disabled attribute with data attributes for performing checkin
247
+			$attributes   = 'data-_regid="' . $registration->ID() . '"';
248
+			$attributes   .= ' data-dttid="' . $DTT_ID . '"';
249
+			$attributes   .= ' data-nonce="' . wp_create_nonce('checkin_nonce') . '"';
250
+			$button_class .= ' clickable trigger-checkin';
251
+		}
252
+
253
+		$content = '
254 254
         <button aria-label="' . $aria_label . '" class="' . $button_class . '" ' . $attributes . '>
255 255
             <span class="' . $dashicon_class . '" ></span>
256 256
         </button>
257 257
         <span class="show-on-mobile-view-only">' . $this->column_ATT_name($registration) . '</span>';
258
-        return $this->columnContent('_REG_att_checked_in', $content, 'center');
259
-    }
260
-
261
-
262
-    /**
263
-     * @param EE_Registration $registration
264
-     * @return string
265
-     * @throws EE_Error
266
-     * @throws ReflectionException
267
-     */
268
-    public function column_ATT_name(EE_Registration $registration): string
269
-    {
270
-        $attendee = $registration->attendee();
271
-        if (! $attendee instanceof EE_Attendee) {
272
-            return esc_html__('No contact record for this registration.', 'event_espresso');
273
-        }
274
-        // edit attendee link
275
-        $edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
276
-            ['action' => 'view_registration', '_REG_ID' => $registration->ID()],
277
-            REG_ADMIN_URL
278
-        );
279
-        $name_link    = '
258
+		return $this->columnContent('_REG_att_checked_in', $content, 'center');
259
+	}
260
+
261
+
262
+	/**
263
+	 * @param EE_Registration $registration
264
+	 * @return string
265
+	 * @throws EE_Error
266
+	 * @throws ReflectionException
267
+	 */
268
+	public function column_ATT_name(EE_Registration $registration): string
269
+	{
270
+		$attendee = $registration->attendee();
271
+		if (! $attendee instanceof EE_Attendee) {
272
+			return esc_html__('No contact record for this registration.', 'event_espresso');
273
+		}
274
+		// edit attendee link
275
+		$edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
276
+			['action' => 'view_registration', '_REG_ID' => $registration->ID()],
277
+			REG_ADMIN_URL
278
+		);
279
+		$name_link    = '
280 280
             <span class="ee-status-dot ee-status-bg--' . esc_attr($registration->status_ID()) . ' ee-aria-tooltip"
281 281
             aria-label="' . EEH_Template::pretty_status($registration->status_ID(), false, 'sentence') . '">
282 282
             </span>';
283
-        $status        = esc_attr($registration->status_ID());
284
-        $name_link    .= $this->caps_handler->userCanEditContacts()
285
-            ? '
283
+		$status        = esc_attr($registration->status_ID());
284
+		$name_link    .= $this->caps_handler->userCanEditContacts()
285
+			? '
286 286
             <a class="ee-aria-tooltip ee-status-color--' . $status . '"
287 287
                href="' . $edit_lnk_url . '"
288 288
                aria-label="' . esc_attr__('View Registration Details', 'event_espresso') . '"
289 289
             >
290 290
                 ' . $registration->attendee()->full_name() . '
291 291
             </a>'
292
-            : $registration->attendee()->full_name();
293
-        $name_link    .= $registration->count() === 1
294
-            ? '&nbsp;<sup><div class="dashicons dashicons-star-filled gold-icon"></div></sup>	'
295
-            : '';
296
-        // add group details
297
-        $name_link .= '&nbsp;' . sprintf(
298
-            esc_html__('(%s of %s)', 'event_espresso'),
299
-            $registration->count(),
300
-            $registration->group_size()
301
-        );
302
-        // add regcode
303
-        $link      = EE_Admin_Page::add_query_args_and_nonce(
304
-            ['action' => 'view_registration', '_REG_ID' => $registration->ID()],
305
-            REG_ADMIN_URL
306
-        );
307
-        $name_link .= '<br>';
308
-        $name_link .= $this->caps_handler->userCanReadRegistration($registration)
309
-            ? '<a class="ee-aria-tooltip" href="' . $link . '" aria-label="' . esc_attr__(
310
-                'View Registration Details',
311
-                'event_espresso'
312
-            ) . '">'
313
-              . $registration->reg_code()
314
-              . '</a>'
315
-            : $registration->reg_code();
316
-
317
-        $actions = [];
318
-        $DTT_ID = $this->filters->datetimeID();
319
-        if ($DTT_ID && $this->caps_handler->userCanReadRegistrationCheckins()) {
320
-            $checkin_list_url = EE_Admin_Page::add_query_args_and_nonce(
321
-                ['action' => 'registration_checkins', '_REG_ID' => $registration->ID(), 'DTT_ID' => $DTT_ID],
322
-                REG_ADMIN_URL
323
-            );
324
-            // get the timestamps for this registration's checkins, related to the selected datetime
325
-            /** @var EE_Checkin[] $checkins */
326
-            $checkins = $registration->get_many_related('Checkin', [['DTT_ID' => $DTT_ID]]);
327
-            if (! empty($checkins)) {
328
-                // get the last timestamp
329
-                $last_checkin = end($checkins);
330
-                // get timestamp string
331
-                $timestamp_string   = $last_checkin->get_datetime('CHK_timestamp');
332
-                $actions['checkin'] = '
292
+			: $registration->attendee()->full_name();
293
+		$name_link    .= $registration->count() === 1
294
+			? '&nbsp;<sup><div class="dashicons dashicons-star-filled gold-icon"></div></sup>	'
295
+			: '';
296
+		// add group details
297
+		$name_link .= '&nbsp;' . sprintf(
298
+			esc_html__('(%s of %s)', 'event_espresso'),
299
+			$registration->count(),
300
+			$registration->group_size()
301
+		);
302
+		// add regcode
303
+		$link      = EE_Admin_Page::add_query_args_and_nonce(
304
+			['action' => 'view_registration', '_REG_ID' => $registration->ID()],
305
+			REG_ADMIN_URL
306
+		);
307
+		$name_link .= '<br>';
308
+		$name_link .= $this->caps_handler->userCanReadRegistration($registration)
309
+			? '<a class="ee-aria-tooltip" href="' . $link . '" aria-label="' . esc_attr__(
310
+				'View Registration Details',
311
+				'event_espresso'
312
+			) . '">'
313
+			  . $registration->reg_code()
314
+			  . '</a>'
315
+			: $registration->reg_code();
316
+
317
+		$actions = [];
318
+		$DTT_ID = $this->filters->datetimeID();
319
+		if ($DTT_ID && $this->caps_handler->userCanReadRegistrationCheckins()) {
320
+			$checkin_list_url = EE_Admin_Page::add_query_args_and_nonce(
321
+				['action' => 'registration_checkins', '_REG_ID' => $registration->ID(), 'DTT_ID' => $DTT_ID],
322
+				REG_ADMIN_URL
323
+			);
324
+			// get the timestamps for this registration's checkins, related to the selected datetime
325
+			/** @var EE_Checkin[] $checkins */
326
+			$checkins = $registration->get_many_related('Checkin', [['DTT_ID' => $DTT_ID]]);
327
+			if (! empty($checkins)) {
328
+				// get the last timestamp
329
+				$last_checkin = end($checkins);
330
+				// get timestamp string
331
+				$timestamp_string   = $last_checkin->get_datetime('CHK_timestamp');
332
+				$actions['checkin'] = '
333 333
                     <a  class="ee-aria-tooltip"
334 334
                         href="' . $checkin_list_url . '"
335 335
                         aria-label="' . esc_attr__(
336
-                            'View this registrant\'s check-ins/checkouts for the datetime',
337
-                            'event_espresso'
338
-                        ) . '"
336
+							'View this registrant\'s check-ins/checkouts for the datetime',
337
+							'event_espresso'
338
+						) . '"
339 339
                     >
340 340
                         ' . $last_checkin->getCheckInText() . ': ' . $timestamp_string . '
341 341
                     </a>';
342
-            }
343
-        }
344
-        $content = (! empty($DTT_ID) && ! empty($checkins))
345
-            ? $name_link . $this->row_actions($actions, true)
346
-            : $name_link;
347
-        return $this->columnContent('ATT_name', $content);
348
-    }
349
-
350
-
351
-    /**
352
-     * @param EE_Registration $registration
353
-     * @return string
354
-     * @throws EE_Error
355
-     * @throws ReflectionException
356
-     */
357
-    public function column_Event(EE_Registration $registration): string
358
-    {
359
-        try {
360
-            $event = $this->filters->event() instanceof EE_Event
361
-                ? $this->filters->event()
362
-                : $registration->event();
363
-            $checkin_link_url = EE_Admin_Page::add_query_args_and_nonce(
364
-                ['action' => 'event_registrations', 'event_id' => $event->ID()],
365
-                REG_ADMIN_URL
366
-            );
367
-            $content          = $this->caps_handler->userCanReadRegistrationCheckins()
368
-                ? '<a class="ee-aria-tooltip" href="' . $checkin_link_url . '" aria-label="'
369
-                . esc_attr__(
370
-                    'View Check-ins for this Event',
371
-                    'event_espresso'
372
-                ) . '">' . $event->name() . '</a>' : $event->name();
373
-        } catch (EntityNotFoundException $e) {
374
-            $content = esc_html__('Unknown', 'event_espresso');
375
-        }
376
-        return $this->columnContent('Event', $content);
377
-    }
378
-
379
-
380
-    /**
381
-     * @param EE_Registration $registration
382
-     * @return string
383
-     * @throws EE_Error
384
-     * @throws ReflectionException
385
-     */
386
-    public function column_PRC_name(EE_Registration $registration): string
387
-    {
388
-        return $this->column_REG_ticket($registration);
389
-    }
342
+			}
343
+		}
344
+		$content = (! empty($DTT_ID) && ! empty($checkins))
345
+			? $name_link . $this->row_actions($actions, true)
346
+			: $name_link;
347
+		return $this->columnContent('ATT_name', $content);
348
+	}
349
+
350
+
351
+	/**
352
+	 * @param EE_Registration $registration
353
+	 * @return string
354
+	 * @throws EE_Error
355
+	 * @throws ReflectionException
356
+	 */
357
+	public function column_Event(EE_Registration $registration): string
358
+	{
359
+		try {
360
+			$event = $this->filters->event() instanceof EE_Event
361
+				? $this->filters->event()
362
+				: $registration->event();
363
+			$checkin_link_url = EE_Admin_Page::add_query_args_and_nonce(
364
+				['action' => 'event_registrations', 'event_id' => $event->ID()],
365
+				REG_ADMIN_URL
366
+			);
367
+			$content          = $this->caps_handler->userCanReadRegistrationCheckins()
368
+				? '<a class="ee-aria-tooltip" href="' . $checkin_link_url . '" aria-label="'
369
+				. esc_attr__(
370
+					'View Check-ins for this Event',
371
+					'event_espresso'
372
+				) . '">' . $event->name() . '</a>' : $event->name();
373
+		} catch (EntityNotFoundException $e) {
374
+			$content = esc_html__('Unknown', 'event_espresso');
375
+		}
376
+		return $this->columnContent('Event', $content);
377
+	}
378
+
379
+
380
+	/**
381
+	 * @param EE_Registration $registration
382
+	 * @return string
383
+	 * @throws EE_Error
384
+	 * @throws ReflectionException
385
+	 */
386
+	public function column_PRC_name(EE_Registration $registration): string
387
+	{
388
+		return $this->column_REG_ticket($registration);
389
+	}
390 390
 }
Please login to merge, or discard this patch.
Spacing   +37 added lines, -37 removed lines patch added patch discarded remove patch
@@ -28,7 +28,7 @@  discard block
 block discarded – undo
28 28
      */
29 29
     protected ?DatetimesForEventCheckIn $datetimes_for_current_row = null;
30 30
 
31
-    protected array $_status       = [];
31
+    protected array $_status = [];
32 32
 
33 33
     private RegistrationsListTableFilters $filters;
34 34
 
@@ -74,7 +74,7 @@  discard block
 block discarded – undo
74 74
             'ajax'     => true,
75 75
             'screen'   => $this->_admin_page->get_current_screen()->id,
76 76
         ];
77
-        $columns             = [];
77
+        $columns = [];
78 78
 
79 79
         $this->_columns = [
80 80
             '_REG_att_checked_in' => '<span class="dashicons dashicons-yes-alt"></span>',
@@ -87,11 +87,11 @@  discard block
 block discarded – undo
87 87
             'TXN_total'           => esc_html__('TXN Paid/Total', 'event_espresso'),
88 88
         ];
89 89
         // Add/remove columns when an event or datetime has been selected
90
-        if (! empty($this->filters->eventID())) {
90
+        if ( ! empty($this->filters->eventID())) {
91 91
             // Remove the 'Event' column
92 92
             unset($this->_columns['Event']);
93 93
         }
94
-        if (! empty($this->filters->datetimeID())) {
94
+        if ( ! empty($this->filters->datetimeID())) {
95 95
             // Render a checkbox column for triggering bulk check-ins
96 96
             $columns['cb']              = '<input type="checkbox" />';
97 97
             $this->_has_checkbox_column = true;
@@ -105,7 +105,7 @@  discard block
 block discarded – undo
105 105
             $this->filters->eventID(),
106 106
             $this->filters->datetimeID()
107 107
         );
108
-        if (! empty($csv_report)) {
108
+        if ( ! empty($csv_report)) {
109 109
             $this->_bottom_buttons['csv_reg_report'] = $csv_report;
110 110
         }
111 111
 
@@ -126,7 +126,7 @@  discard block
 block discarded – undo
126 126
                 : ['ATT_fname' => true],
127 127
             'Event'    => ['Event.EVT_name' => false],
128 128
         ];
129
-        $this->_hidden_columns   = [];
129
+        $this->_hidden_columns = [];
130 130
     }
131 131
 
132 132
 
@@ -180,7 +180,7 @@  discard block
 block discarded – undo
180 180
         if ($this->filters->datetimeID()) {
181 181
             $query_params[0]['Ticket.Datetime.DTT_ID'] = $this->filters->datetimeID();
182 182
         }
183
-        $status_ids_array          = apply_filters(
183
+        $status_ids_array = apply_filters(
184 184
             'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array',
185 185
             [RegStatus::PENDING_PAYMENT, RegStatus::APPROVED]
186 186
         );
@@ -218,7 +218,7 @@  discard block
 block discarded – undo
218 218
         // (so that we don't pollute state for the entire table)
219 219
         // so let's try to get it from the registration's event
220 220
         $DTT_ID = $this->filters->datetimeID();
221
-        if (! $DTT_ID) {
221
+        if ( ! $DTT_ID) {
222 222
             $reg_ticket_datetimes = $registration->ticket()->datetimes();
223 223
             if (count($reg_ticket_datetimes) === 1) {
224 224
                 $reg_ticket_datetime = reset($reg_ticket_datetimes);
@@ -226,7 +226,7 @@  discard block
 block discarded – undo
226 226
             }
227 227
         }
228 228
 
229
-        if (! $DTT_ID) {
229
+        if ( ! $DTT_ID) {
230 230
             $this->datetimes_for_current_row = DatetimesForEventCheckIn::fromRegistration($registration);
231 231
             $datetime                        = $this->datetimes_for_current_row->getOneDatetimeForEvent($DTT_ID);
232 232
             $DTT_ID                          = $datetime instanceof EE_Datetime ? $datetime->ID() : 0;
@@ -244,17 +244,17 @@  discard block
 block discarded – undo
244 244
 
245 245
         if ($DTT_ID && $this->caps_handler->userCanEditRegistrationCheckin($registration)) {
246 246
             // overwrite the disabled attribute with data attributes for performing checkin
247
-            $attributes   = 'data-_regid="' . $registration->ID() . '"';
248
-            $attributes   .= ' data-dttid="' . $DTT_ID . '"';
249
-            $attributes   .= ' data-nonce="' . wp_create_nonce('checkin_nonce') . '"';
247
+            $attributes = 'data-_regid="'.$registration->ID().'"';
248
+            $attributes   .= ' data-dttid="'.$DTT_ID.'"';
249
+            $attributes   .= ' data-nonce="'.wp_create_nonce('checkin_nonce').'"';
250 250
             $button_class .= ' clickable trigger-checkin';
251 251
         }
252 252
 
253 253
         $content = '
254
-        <button aria-label="' . $aria_label . '" class="' . $button_class . '" ' . $attributes . '>
255
-            <span class="' . $dashicon_class . '" ></span>
254
+        <button aria-label="' . $aria_label.'" class="'.$button_class.'" '.$attributes.'>
255
+            <span class="' . $dashicon_class.'" ></span>
256 256
         </button>
257
-        <span class="show-on-mobile-view-only">' . $this->column_ATT_name($registration) . '</span>';
257
+        <span class="show-on-mobile-view-only">' . $this->column_ATT_name($registration).'</span>';
258 258
         return $this->columnContent('_REG_att_checked_in', $content, 'center');
259 259
     }
260 260
 
@@ -268,7 +268,7 @@  discard block
 block discarded – undo
268 268
     public function column_ATT_name(EE_Registration $registration): string
269 269
     {
270 270
         $attendee = $registration->attendee();
271
-        if (! $attendee instanceof EE_Attendee) {
271
+        if ( ! $attendee instanceof EE_Attendee) {
272 272
             return esc_html__('No contact record for this registration.', 'event_espresso');
273 273
         }
274 274
         // edit attendee link
@@ -276,40 +276,40 @@  discard block
 block discarded – undo
276 276
             ['action' => 'view_registration', '_REG_ID' => $registration->ID()],
277 277
             REG_ADMIN_URL
278 278
         );
279
-        $name_link    = '
280
-            <span class="ee-status-dot ee-status-bg--' . esc_attr($registration->status_ID()) . ' ee-aria-tooltip"
281
-            aria-label="' . EEH_Template::pretty_status($registration->status_ID(), false, 'sentence') . '">
279
+        $name_link = '
280
+            <span class="ee-status-dot ee-status-bg--' . esc_attr($registration->status_ID()).' ee-aria-tooltip"
281
+            aria-label="' . EEH_Template::pretty_status($registration->status_ID(), false, 'sentence').'">
282 282
             </span>';
283 283
         $status        = esc_attr($registration->status_ID());
284 284
         $name_link    .= $this->caps_handler->userCanEditContacts()
285 285
             ? '
286
-            <a class="ee-aria-tooltip ee-status-color--' . $status . '"
287
-               href="' . $edit_lnk_url . '"
288
-               aria-label="' . esc_attr__('View Registration Details', 'event_espresso') . '"
286
+            <a class="ee-aria-tooltip ee-status-color--' . $status.'"
287
+               href="' . $edit_lnk_url.'"
288
+               aria-label="' . esc_attr__('View Registration Details', 'event_espresso').'"
289 289
             >
290
-                ' . $registration->attendee()->full_name() . '
290
+                ' . $registration->attendee()->full_name().'
291 291
             </a>'
292 292
             : $registration->attendee()->full_name();
293
-        $name_link    .= $registration->count() === 1
293
+        $name_link .= $registration->count() === 1
294 294
             ? '&nbsp;<sup><div class="dashicons dashicons-star-filled gold-icon"></div></sup>	'
295 295
             : '';
296 296
         // add group details
297
-        $name_link .= '&nbsp;' . sprintf(
297
+        $name_link .= '&nbsp;'.sprintf(
298 298
             esc_html__('(%s of %s)', 'event_espresso'),
299 299
             $registration->count(),
300 300
             $registration->group_size()
301 301
         );
302 302
         // add regcode
303
-        $link      = EE_Admin_Page::add_query_args_and_nonce(
303
+        $link = EE_Admin_Page::add_query_args_and_nonce(
304 304
             ['action' => 'view_registration', '_REG_ID' => $registration->ID()],
305 305
             REG_ADMIN_URL
306 306
         );
307 307
         $name_link .= '<br>';
308 308
         $name_link .= $this->caps_handler->userCanReadRegistration($registration)
309
-            ? '<a class="ee-aria-tooltip" href="' . $link . '" aria-label="' . esc_attr__(
309
+            ? '<a class="ee-aria-tooltip" href="'.$link.'" aria-label="'.esc_attr__(
310 310
                 'View Registration Details',
311 311
                 'event_espresso'
312
-            ) . '">'
312
+            ).'">'
313 313
               . $registration->reg_code()
314 314
               . '</a>'
315 315
             : $registration->reg_code();
@@ -324,25 +324,25 @@  discard block
 block discarded – undo
324 324
             // get the timestamps for this registration's checkins, related to the selected datetime
325 325
             /** @var EE_Checkin[] $checkins */
326 326
             $checkins = $registration->get_many_related('Checkin', [['DTT_ID' => $DTT_ID]]);
327
-            if (! empty($checkins)) {
327
+            if ( ! empty($checkins)) {
328 328
                 // get the last timestamp
329 329
                 $last_checkin = end($checkins);
330 330
                 // get timestamp string
331 331
                 $timestamp_string   = $last_checkin->get_datetime('CHK_timestamp');
332 332
                 $actions['checkin'] = '
333 333
                     <a  class="ee-aria-tooltip"
334
-                        href="' . $checkin_list_url . '"
334
+                        href="' . $checkin_list_url.'"
335 335
                         aria-label="' . esc_attr__(
336 336
                             'View this registrant\'s check-ins/checkouts for the datetime',
337 337
                             'event_espresso'
338
-                        ) . '"
338
+                        ).'"
339 339
                     >
340
-                        ' . $last_checkin->getCheckInText() . ': ' . $timestamp_string . '
340
+                        ' . $last_checkin->getCheckInText().': '.$timestamp_string.'
341 341
                     </a>';
342 342
             }
343 343
         }
344
-        $content = (! empty($DTT_ID) && ! empty($checkins))
345
-            ? $name_link . $this->row_actions($actions, true)
344
+        $content = ( ! empty($DTT_ID) && ! empty($checkins))
345
+            ? $name_link.$this->row_actions($actions, true)
346 346
             : $name_link;
347 347
         return $this->columnContent('ATT_name', $content);
348 348
     }
@@ -364,12 +364,12 @@  discard block
 block discarded – undo
364 364
                 ['action' => 'event_registrations', 'event_id' => $event->ID()],
365 365
                 REG_ADMIN_URL
366 366
             );
367
-            $content          = $this->caps_handler->userCanReadRegistrationCheckins()
368
-                ? '<a class="ee-aria-tooltip" href="' . $checkin_link_url . '" aria-label="'
367
+            $content = $this->caps_handler->userCanReadRegistrationCheckins()
368
+                ? '<a class="ee-aria-tooltip" href="'.$checkin_link_url.'" aria-label="'
369 369
                 . esc_attr__(
370 370
                     'View Check-ins for this Event',
371 371
                     'event_espresso'
372
-                ) . '">' . $event->name() . '</a>' : $event->name();
372
+                ).'">'.$event->name().'</a>' : $event->name();
373 373
         } catch (EntityNotFoundException $e) {
374 374
             $content = esc_html__('Unknown', 'event_espresso');
375 375
         }
Please login to merge, or discard this patch.