Completed
Branch BUG/11187/saving-session-data (f78eb0)
by
unknown
98:37 queued 87:23
created
core/db_classes/EE_WP_User.class.php 2 patches
Indentation   +80 added lines, -80 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if (! defined('EVENT_ESPRESSO_VERSION')) {
2
-    exit('No direct script access allowed');
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 
5 5
 /**
@@ -13,93 +13,93 @@  discard block
 block discarded – undo
13 13
 class EE_WP_User extends EE_Base_Class implements EEI_Admin_Links
14 14
 {
15 15
 
16
-    /**
17
-     * @var WP_User
18
-     */
19
-    protected $_wp_user_obj;
16
+	/**
17
+	 * @var WP_User
18
+	 */
19
+	protected $_wp_user_obj;
20 20
 
21
-    /**
22
-     * @param array $props_n_values
23
-     * @return EE_WP_User|mixed
24
-     */
25
-    public static function new_instance($props_n_values = array())
26
-    {
27
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__);
28
-        return $has_object ? $has_object : new self($props_n_values);
29
-    }
21
+	/**
22
+	 * @param array $props_n_values
23
+	 * @return EE_WP_User|mixed
24
+	 */
25
+	public static function new_instance($props_n_values = array())
26
+	{
27
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__);
28
+		return $has_object ? $has_object : new self($props_n_values);
29
+	}
30 30
 
31 31
 
32
-    /**
33
-     * @param array $props_n_values
34
-     * @return EE_WP_User
35
-     */
36
-    public static function new_instance_from_db($props_n_values = array())
37
-    {
38
-        return new self($props_n_values, true);
39
-    }
32
+	/**
33
+	 * @param array $props_n_values
34
+	 * @return EE_WP_User
35
+	 */
36
+	public static function new_instance_from_db($props_n_values = array())
37
+	{
38
+		return new self($props_n_values, true);
39
+	}
40 40
 
41
-    /**
42
-     * Return a normal WP_User object (caches the object for future calls)
43
-     *
44
-     * @return WP_User
45
-     */
46
-    public function wp_user_obj()
47
-    {
48
-        if (! $this->_wp_user_obj) {
49
-            $this->_wp_user_obj = get_user_by('ID', $this->ID());
50
-        }
51
-        return $this->_wp_user_obj;
52
-    }
41
+	/**
42
+	 * Return a normal WP_User object (caches the object for future calls)
43
+	 *
44
+	 * @return WP_User
45
+	 */
46
+	public function wp_user_obj()
47
+	{
48
+		if (! $this->_wp_user_obj) {
49
+			$this->_wp_user_obj = get_user_by('ID', $this->ID());
50
+		}
51
+		return $this->_wp_user_obj;
52
+	}
53 53
 
54
-    /**
55
-     * Return the link to the admin details for the object.
56
-     *
57
-     * @return string
58
-     */
59
-    public function get_admin_details_link()
60
-    {
61
-        return $this->get_admin_edit_link();
62
-    }
54
+	/**
55
+	 * Return the link to the admin details for the object.
56
+	 *
57
+	 * @return string
58
+	 */
59
+	public function get_admin_details_link()
60
+	{
61
+		return $this->get_admin_edit_link();
62
+	}
63 63
 
64
-    /**
65
-     * Returns the link to the editor for the object.  Sometimes this is the same as the details.
66
-     *
67
-     * @return string
68
-     */
69
-    public function get_admin_edit_link()
70
-    {
71
-        return esc_url(
72
-            add_query_arg(
73
-                'wp_http_referer',
74
-                urlencode(
75
-                    wp_unslash(
76
-                        $_SERVER['REQUEST_URI']
77
-                    )
78
-                ),
79
-                get_edit_user_link($this->ID())
80
-            )
81
-        );
82
-    }
64
+	/**
65
+	 * Returns the link to the editor for the object.  Sometimes this is the same as the details.
66
+	 *
67
+	 * @return string
68
+	 */
69
+	public function get_admin_edit_link()
70
+	{
71
+		return esc_url(
72
+			add_query_arg(
73
+				'wp_http_referer',
74
+				urlencode(
75
+					wp_unslash(
76
+						$_SERVER['REQUEST_URI']
77
+					)
78
+				),
79
+				get_edit_user_link($this->ID())
80
+			)
81
+		);
82
+	}
83 83
 
84
-    /**
85
-     * Returns the link to a settings page for the object.
86
-     *
87
-     * @return string
88
-     */
89
-    public function get_admin_settings_link()
90
-    {
91
-        return $this->get_admin_edit_link();
92
-    }
84
+	/**
85
+	 * Returns the link to a settings page for the object.
86
+	 *
87
+	 * @return string
88
+	 */
89
+	public function get_admin_settings_link()
90
+	{
91
+		return $this->get_admin_edit_link();
92
+	}
93 93
 
94
-    /**
95
-     * Returns the link to the "overview" for the object (typically the "list table" view).
96
-     *
97
-     * @return string
98
-     */
99
-    public function get_admin_overview_link()
100
-    {
101
-        return admin_url('users.php');
102
-    }
94
+	/**
95
+	 * Returns the link to the "overview" for the object (typically the "list table" view).
96
+	 *
97
+	 * @return string
98
+	 */
99
+	public function get_admin_overview_link()
100
+	{
101
+		return admin_url('users.php');
102
+	}
103 103
 
104 104
 
105 105
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -1,4 +1,4 @@  discard block
 block discarded – undo
1
-<?php if (! defined('EVENT_ESPRESSO_VERSION')) {
1
+<?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2 2
     exit('No direct script access allowed');
3 3
 }
4 4
 
@@ -45,7 +45,7 @@  discard block
 block discarded – undo
45 45
      */
46 46
     public function wp_user_obj()
47 47
     {
48
-        if (! $this->_wp_user_obj) {
48
+        if ( ! $this->_wp_user_obj) {
49 49
             $this->_wp_user_obj = get_user_by('ID', $this->ID());
50 50
         }
51 51
         return $this->_wp_user_obj;
Please login to merge, or discard this patch.
caffeinated/admin/new/pricing/espresso_events_Pricing_Hooks.class.php 1 patch
Indentation   +2108 added lines, -2108 removed lines patch added patch discarded remove patch
@@ -15,2114 +15,2114 @@
 block discarded – undo
15 15
 class espresso_events_Pricing_Hooks extends EE_Admin_Hooks
16 16
 {
17 17
 
18
-    /**
19
-     * This property is just used to hold the status of whether an event is currently being
20
-     * created (true) or edited (false)
21
-     *
22
-     * @access protected
23
-     * @var bool
24
-     */
25
-    protected $_is_creating_event;
26
-
27
-
28
-    /**
29
-     * Used to contain the format strings for date and time that will be used for php date and
30
-     * time.
31
-     * Is set in the _set_hooks_properties() method.
32
-     *
33
-     * @var array
34
-     */
35
-    protected $_date_format_strings;
36
-
37
-
38
-    /**
39
-     * @var string $_date_time_format
40
-     */
41
-    protected $_date_time_format;
42
-
43
-
44
-
45
-    /**
46
-     *
47
-     */
48
-    protected function _set_hooks_properties()
49
-    {
50
-        $this->_name = 'pricing';
51
-        //capability check
52
-        if (! EE_Registry::instance()->CAP->current_user_can(
53
-            'ee_read_default_prices',
54
-            'advanced_ticket_datetime_metabox'
55
-        )) {
56
-            return;
57
-        }
58
-        $this->_setup_metaboxes();
59
-        $this->_set_date_time_formats();
60
-        $this->_validate_format_strings();
61
-        $this->_set_scripts_styles();
62
-        // commented out temporarily until logic is implemented in callback
63
-        // add_action(
64
-        //     'AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_Extend_Events_Admin_Page',
65
-        //     array($this, 'autosave_handling')
66
-        // );
67
-        add_filter(
68
-            'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
69
-            array($this, 'caf_updates')
70
-        );
71
-    }
72
-
73
-
74
-
75
-    /**
76
-     * @return void
77
-     */
78
-    protected function _setup_metaboxes()
79
-    {
80
-        //if we were going to add our own metaboxes we'd use the below.
81
-        $this->_metaboxes = array(
82
-            0 => array(
83
-                'page_route' => array('edit', 'create_new'),
84
-                'func'       => 'pricing_metabox',
85
-                'label'      => esc_html__('Event Tickets & Datetimes', 'event_espresso'),
86
-                'priority'   => 'high',
87
-                'context'    => 'normal',
88
-            ),
89
-        );
90
-        $this->_remove_metaboxes = array(
91
-            0 => array(
92
-                'page_route' => array('edit', 'create_new'),
93
-                'id'         => 'espresso_event_editor_tickets',
94
-                'context'    => 'normal',
95
-            ),
96
-        );
97
-    }
98
-
99
-
100
-
101
-    /**
102
-     * @return void
103
-     */
104
-    protected function _set_date_time_formats()
105
-    {
106
-        /**
107
-         * Format strings for date and time.  Defaults are existing behaviour from 4.1.
108
-         * Note, that if you return null as the value for 'date', and 'time' in the array, then
109
-         * EE will automatically use the set wp_options, 'date_format', and 'time_format'.
110
-         *
111
-         * @since 4.6.7
112
-         * @var array  Expected an array returned with 'date' and 'time' keys.
113
-         */
114
-        $this->_date_format_strings = apply_filters(
115
-            'FHEE__espresso_events_Pricing_Hooks___set_hooks_properties__date_format_strings',
116
-            array(
117
-                'date' => 'Y-m-d',
118
-                'time' => 'h:i a',
119
-            )
120
-        );
121
-        //validate
122
-        $this->_date_format_strings['date'] = isset($this->_date_format_strings['date'])
123
-            ? $this->_date_format_strings['date']
124
-            : null;
125
-        $this->_date_format_strings['time'] = isset($this->_date_format_strings['time'])
126
-            ? $this->_date_format_strings['time']
127
-            : null;
128
-        $this->_date_time_format = $this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time'];
129
-    }
130
-
131
-
132
-
133
-    /**
134
-     * @return void
135
-     */
136
-    protected function _validate_format_strings()
137
-    {
138
-        //validate format strings
139
-        $format_validation = EEH_DTT_Helper::validate_format_string(
140
-            $this->_date_time_format
141
-        );
142
-        if (is_array($format_validation)) {
143
-            $msg = '<p>';
144
-            $msg .= sprintf(
145
-                esc_html__(
146
-                    'The format "%s" was likely added via a filter and is invalid for the following reasons:',
147
-                    'event_espresso'
148
-                ),
149
-                $this->_date_time_format
150
-            );
151
-            $msg .= '</p><ul>';
152
-            foreach ($format_validation as $error) {
153
-                $msg .= '<li>' . $error . '</li>';
154
-            }
155
-            $msg .= '</ul><p>';
156
-            $msg .= sprintf(
157
-                esc_html__(
158
-                    '%sPlease note that your date and time formats have been reset to "Y-m-d" and "h:i a" respectively.%s',
159
-                    'event_espresso'
160
-                ),
161
-                '<span style="color:#D54E21;">',
162
-                '</span>'
163
-            );
164
-            $msg .= '</p>';
165
-            EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
166
-            $this->_date_format_strings = array(
167
-                'date' => 'Y-m-d',
168
-                'time' => 'h:i a',
169
-            );
170
-        }
171
-    }
172
-
173
-
174
-
175
-    /**
176
-     * @return void
177
-     */
178
-    protected function _set_scripts_styles()
179
-    {
180
-        $this->_scripts_styles = array(
181
-            'registers'   => array(
182
-                'ee-tickets-datetimes-css' => array(
183
-                    'url'  => PRICING_ASSETS_URL . 'event-tickets-datetimes.css',
184
-                    'type' => 'css',
185
-                ),
186
-                'ee-dtt-ticket-metabox'    => array(
187
-                    'url'     => PRICING_ASSETS_URL . 'ee-datetime-ticket-metabox.js',
188
-                    'depends' => array('ee-datepicker', 'ee-dialog', 'underscore'),
189
-                ),
190
-            ),
191
-            'deregisters' => array(
192
-                'event-editor-css'       => array('type' => 'css'),
193
-                'event-datetime-metabox' => array('type' => 'js'),
194
-            ),
195
-            'enqueues'    => array(
196
-                'ee-tickets-datetimes-css' => array('edit', 'create_new'),
197
-                'ee-dtt-ticket-metabox'    => array('edit', 'create_new'),
198
-            ),
199
-            'localize'    => array(
200
-                'ee-dtt-ticket-metabox' => array(
201
-                    'DTT_TRASH_BLOCK'       => array(
202
-                        'main_warning'            => esc_html__(
203
-                            'The Datetime you are attempting to trash is the only datetime selected for the following ticket(s):',
204
-                            'event_espresso'
205
-                        ),
206
-                        'after_warning'           => esc_html__(
207
-                            'In order to trash this datetime you must first make sure the above ticket(s) are assigned to other datetimes.',
208
-                            'event_espresso'
209
-                        ),
210
-                        'cancel_button'           => '<button class="button-secondary ee-modal-cancel">'
211
-                                                     . esc_html__('Cancel', 'event_espresso') . '</button>',
212
-                        'close_button'            => '<button class="button-secondary ee-modal-cancel">'
213
-                                                     . esc_html__('Close', 'event_espresso') . '</button>',
214
-                        'single_warning_from_tkt' => esc_html__(
215
-                            'The Datetime you are attempting to unassign from this ticket is the only remaining datetime for this ticket. Tickets must always have at least one datetime assigned to them.',
216
-                            'event_espresso'
217
-                        ),
218
-                        'single_warning_from_dtt' => esc_html__(
219
-                            'The ticket you are attempting to unassign from this datetime cannot be unassigned because the datetime is the only remaining datetime for the ticket.  Tickets must always have at least one datetime assigned to them.',
220
-                            'event_espresso'
221
-                        ),
222
-                        'dismiss_button'          => '<button class="button-secondary ee-modal-cancel">'
223
-                                                     . esc_html__('Dismiss', 'event_espresso') . '</button>',
224
-                    ),
225
-                    'DTT_ERROR_MSG'         => array(
226
-                        'no_ticket_name' => esc_html__('General Admission', 'event_espresso'),
227
-                        'dismiss_button' => '<div class="save-cancel-button-container"><button class="button-secondary ee-modal-cancel">'
228
-                                            . esc_html__('Dismiss', 'event_espresso') . '</button></div>',
229
-                    ),
230
-                    'DTT_OVERSELL_WARNING'  => array(
231
-                        'datetime_ticket' => esc_html__(
232
-                            'You cannot add this ticket to this datetime because it has a sold amount that is greater than the amount of spots remaining for this datetime.',
233
-                            'event_espresso'
234
-                        ),
235
-                        'ticket_datetime' => esc_html__(
236
-                            'You cannot add this datetime to this ticket because the ticket has a sold amount that is greater than the amount of spots remaining on the datetime.',
237
-                            'event_espresso'
238
-                        ),
239
-                    ),
240
-                    'DTT_CONVERTED_FORMATS' => EEH_DTT_Helper::convert_php_to_js_and_moment_date_formats(
241
-                        $this->_date_format_strings['date'],
242
-                        $this->_date_format_strings['time']
243
-                    ),
244
-                    'DTT_START_OF_WEEK'     => array('dayValue' => (int)get_option('start_of_week')),
245
-                ),
246
-            ),
247
-        );
248
-    }
249
-
250
-
251
-
252
-    /**
253
-     * @param array $update_callbacks
254
-     * @return array
255
-     */
256
-    public function caf_updates(array $update_callbacks)
257
-    {
258
-        foreach ($update_callbacks as $key => $callback) {
259
-            if ($callback[1] === '_default_tickets_update') {
260
-                unset($update_callbacks[$key]);
261
-            }
262
-        }
263
-        $update_callbacks[] = array($this, 'datetime_and_tickets_caf_update');
264
-        return $update_callbacks;
265
-    }
266
-
267
-
268
-    /**
269
-     * Handles saving everything related to Tickets (datetimes, tickets, prices)
270
-     *
271
-     * @param  EE_Event $event The Event object we're attaching data to
272
-     * @param  array $data The request data from the form
273
-     * @throws EE_Error
274
-     * @throws InvalidArgumentException
275
-     */
276
-    public function datetime_and_tickets_caf_update($event, $data)
277
-    {
278
-        //first we need to start with datetimes cause they are the "root" items attached to events.
279
-        $saved_datetimes = $this->_update_datetimes($event, $data);
280
-        //next tackle the tickets (and prices?)
281
-        $this->_update_tickets($event, $saved_datetimes, $data);
282
-    }
283
-
284
-
285
-    /**
286
-     * update event_datetimes
287
-     *
288
-     * @param  EE_Event $event Event being updated
289
-     * @param  array $data the request data from the form
290
-     * @return EE_Datetime[]
291
-     * @throws InvalidArgumentException
292
-     * @throws EE_Error
293
-     */
294
-    protected function _update_datetimes($event, $data)
295
-    {
296
-        $timezone = isset($data['timezone_string']) ? $data['timezone_string'] : null;
297
-        $saved_dtt_ids = array();
298
-        $saved_dtt_objs = array();
299
-        if (empty($data['edit_event_datetimes']) || !is_array($data['edit_event_datetimes'])) {
300
-            throw new InvalidArgumentException(
301
-                esc_html__(
302
-                    'The "edit_event_datetimes" array is invalid therefore the event can not be updated.',
303
-                    'event_espresso'
304
-                )
305
-            );
306
-        }
307
-        foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
308
-            //trim all values to ensure any excess whitespace is removed.
309
-            $datetime_data = array_map(
310
-                function ($datetime_data) {
311
-                    return is_array($datetime_data) ? $datetime_data : trim($datetime_data);
312
-                },
313
-                $datetime_data
314
-            );
315
-            $datetime_data['DTT_EVT_end'] = isset($datetime_data['DTT_EVT_end'])
316
-                                            && ! empty($datetime_data['DTT_EVT_end'])
317
-                ? $datetime_data['DTT_EVT_end']
318
-                : $datetime_data['DTT_EVT_start'];
319
-            $datetime_values = array(
320
-                'DTT_ID'          => ! empty($datetime_data['DTT_ID'])
321
-                    ? $datetime_data['DTT_ID']
322
-                    : null,
323
-                'DTT_name'        => ! empty($datetime_data['DTT_name'])
324
-                    ? $datetime_data['DTT_name']
325
-                    : '',
326
-                'DTT_description' => ! empty($datetime_data['DTT_description'])
327
-                    ? $datetime_data['DTT_description']
328
-                    : '',
329
-                'DTT_EVT_start'   => $datetime_data['DTT_EVT_start'],
330
-                'DTT_EVT_end'     => $datetime_data['DTT_EVT_end'],
331
-                'DTT_reg_limit'   => empty($datetime_data['DTT_reg_limit'])
332
-                    ? EE_INF
333
-                    : $datetime_data['DTT_reg_limit'],
334
-                'DTT_order'       => ! isset($datetime_data['DTT_order'])
335
-                    ? $row
336
-                    : $datetime_data['DTT_order'],
337
-            );
338
-            // if we have an id then let's get existing object first and then set the new values.
339
-            // Otherwise we instantiate a new object for save.
340
-            if (! empty($datetime_data['DTT_ID'])) {
341
-                $datetime = EE_Registry::instance()
342
-                                       ->load_model('Datetime', array($timezone))
343
-                                       ->get_one_by_ID($datetime_data['DTT_ID']);
344
-                //set date and time format according to what is set in this class.
345
-                $datetime->set_date_format($this->_date_format_strings['date']);
346
-                $datetime->set_time_format($this->_date_format_strings['time']);
347
-                foreach ($datetime_values as $field => $value) {
348
-                    $datetime->set($field, $value);
349
-                }
350
-                // make sure the $dtt_id here is saved just in case
351
-                // after the add_relation_to() the autosave replaces it.
352
-                // We need to do this so we dont' TRASH the parent DTT.
353
-                // (save the ID for both key and value to avoid duplications)
354
-                $saved_dtt_ids[$datetime->ID()] = $datetime->ID();
355
-            } else {
356
-                $datetime = EE_Registry::instance()->load_class(
357
-                    'Datetime',
358
-                    array(
359
-                        $datetime_values,
360
-                        $timezone,
361
-                        array($this->_date_format_strings['date'], $this->_date_format_strings['time']),
362
-                    ),
363
-                    false,
364
-                    false
365
-                );
366
-                foreach ($datetime_values as $field => $value) {
367
-                    $datetime->set($field, $value);
368
-                }
369
-            }
370
-            $datetime->save();
371
-            $datetime = $event->_add_relation_to($datetime, 'Datetime');
372
-            // before going any further make sure our dates are setup correctly
373
-            // so that the end date is always equal or greater than the start date.
374
-            if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
375
-                $datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
376
-                $datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
377
-                $datetime->save();
378
-            }
379
-            //	now we have to make sure we add the new DTT_ID to the $saved_dtt_ids array
380
-            // because it is possible there was a new one created for the autosave.
381
-            // (save the ID for both key and value to avoid duplications)
382
-            $DTT_ID = $datetime->ID();
383
-            $saved_dtt_ids[$DTT_ID] = $DTT_ID;
384
-            $saved_dtt_objs[$row] = $datetime;
385
-            //todo if ANY of these updates fail then we want the appropriate global error message.
386
-        }
387
-        $event->save();
388
-        // now we need to REMOVE any datetimes that got deleted.
389
-        // Keep in mind that this process will only kick in for datetimes that don't have any DTT_sold on them.
390
-        // So its safe to permanently delete at this point.
391
-        $old_datetimes = explode(',', $data['datetime_IDs']);
392
-        $old_datetimes = $old_datetimes[0] === '' ? array() : $old_datetimes;
393
-        if (is_array($old_datetimes)) {
394
-            $datetimes_to_delete = array_diff($old_datetimes, $saved_dtt_ids);
395
-            foreach ($datetimes_to_delete as $id) {
396
-                $id = absint($id);
397
-                if (empty($id)) {
398
-                    continue;
399
-                }
400
-                $dtt_to_remove = EE_Registry::instance()->load_model('Datetime')->get_one_by_ID($id);
401
-                //remove tkt relationships.
402
-                $related_tickets = $dtt_to_remove->get_many_related('Ticket');
403
-                foreach ($related_tickets as $tkt) {
404
-                    $dtt_to_remove->_remove_relation_to($tkt, 'Ticket');
405
-                }
406
-                $event->_remove_relation_to($id, 'Datetime');
407
-                $dtt_to_remove->refresh_cache_of_related_objects();
408
-            }
409
-        }
410
-        return $saved_dtt_objs;
411
-    }
412
-
413
-
414
-    /**
415
-     * update tickets
416
-     *
417
-     * @param  EE_Event $event Event object being updated
418
-     * @param  EE_Datetime[] $saved_datetimes an array of datetime ids being updated
419
-     * @param  array $data incoming request data
420
-     * @return EE_Ticket[]
421
-     * @throws InvalidArgumentException
422
-     * @throws EE_Error
423
-     */
424
-    protected function _update_tickets($event, $saved_datetimes, $data)
425
-    {
426
-        $new_tkt = null;
427
-        $new_default = null;
428
-        //stripslashes because WP filtered the $_POST ($data) array to add slashes
429
-        $data = stripslashes_deep($data);
430
-        $timezone = isset($data['timezone_string']) ? $data['timezone_string'] : null;
431
-        $saved_tickets = $datetimes_on_existing = array();
432
-        $old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array();
433
-        if(empty($data['edit_tickets']) || ! is_array($data['edit_tickets'])){
434
-            throw new InvalidArgumentException(
435
-                esc_html__(
436
-                    'The "edit_tickets" array is invalid therefore the event can not be updated.',
437
-                    'event_espresso'
438
-                )
439
-            );
440
-        }
441
-        foreach ($data['edit_tickets'] as $row => $tkt) {
442
-            $update_prices = $create_new_TKT = false;
443
-            // figure out what datetimes were added to the ticket
444
-            // and what datetimes were removed from the ticket in the session.
445
-            $starting_tkt_dtt_rows = explode(',', $data['starting_ticket_datetime_rows'][$row]);
446
-            $tkt_dtt_rows = explode(',', $data['ticket_datetime_rows'][$row]);
447
-            $datetimes_added = array_diff($tkt_dtt_rows, $starting_tkt_dtt_rows);
448
-            $datetimes_removed = array_diff($starting_tkt_dtt_rows, $tkt_dtt_rows);
449
-            // trim inputs to ensure any excess whitespace is removed.
450
-            $tkt = array_map(
451
-                function ($ticket_data) {
452
-                    return is_array($ticket_data) ? $ticket_data : trim($ticket_data);
453
-                },
454
-                $tkt
455
-            );
456
-            // note we are doing conversions to floats here instead of allowing EE_Money_Field to handle
457
-            // because we're doing calculations prior to using the models.
458
-            // note incoming ['TKT_price'] value is already in standard notation (via js).
459
-            $ticket_price = isset($tkt['TKT_price'])
460
-                ? round((float)$tkt['TKT_price'], 3)
461
-                : 0;
462
-            //note incoming base price needs converted from localized value.
463
-            $base_price = isset($tkt['TKT_base_price'])
464
-                ? EEH_Money::convert_to_float_from_localized_money($tkt['TKT_base_price'])
465
-                : 0;
466
-            //if ticket price == 0 and $base_price != 0 then ticket price == base_price
467
-            $ticket_price = $ticket_price === 0 && $base_price !== 0
468
-                ? $base_price
469
-                : $ticket_price;
470
-            $base_price_id = isset($tkt['TKT_base_price_ID'])
471
-                ? $tkt['TKT_base_price_ID']
472
-                : 0;
473
-            $price_rows = is_array($data['edit_prices']) && isset($data['edit_prices'][$row])
474
-                ? $data['edit_prices'][$row]
475
-                : array();
476
-            $now = null;
477
-            if (empty($tkt['TKT_start_date'])) {
478
-                //lets' use now in the set timezone.
479
-                $now = new DateTime('now', new DateTimeZone($event->get_timezone()));
480
-                $tkt['TKT_start_date'] = $now->format($this->_date_time_format);
481
-            }
482
-            if (empty($tkt['TKT_end_date'])) {
483
-                /**
484
-                 * set the TKT_end_date to the first datetime attached to the ticket.
485
-                 */
486
-                $first_dtt = $saved_datetimes[reset($tkt_dtt_rows)];
487
-                $tkt['TKT_end_date'] = $first_dtt->start_date_and_time($this->_date_time_format);
488
-            }
489
-            $TKT_values = array(
490
-                'TKT_ID'          => ! empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : null,
491
-                'TTM_ID'          => ! empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0,
492
-                'TKT_name'        => ! empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '',
493
-                'TKT_description' => ! empty($tkt['TKT_description'])
494
-                                     && $tkt['TKT_description'] !== esc_html__(
495
-                    'You can modify this description',
496
-                    'event_espresso'
497
-                )
498
-                    ? $tkt['TKT_description']
499
-                    : '',
500
-                'TKT_start_date'  => $tkt['TKT_start_date'],
501
-                'TKT_end_date'    => $tkt['TKT_end_date'],
502
-                'TKT_qty'         => ! isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === ''
503
-                    ? EE_INF
504
-                    : $tkt['TKT_qty'],
505
-                'TKT_uses'        => ! isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === ''
506
-                    ? EE_INF
507
-                    : $tkt['TKT_uses'],
508
-                'TKT_min'         => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'],
509
-                'TKT_max'         => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'],
510
-                'TKT_row'         => $row,
511
-                'TKT_order'       => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : 0,
512
-                'TKT_taxable'     => ! empty($tkt['TKT_taxable']) ? 1 : 0,
513
-                'TKT_required'    => ! empty($tkt['TKT_required']) ? 1 : 0,
514
-                'TKT_price'       => $ticket_price,
515
-            );
516
-            // if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly,
517
-            // which means in turn that the prices will become new prices as well.
518
-            if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
519
-                $TKT_values['TKT_ID'] = 0;
520
-                $TKT_values['TKT_is_default'] = 0;
521
-                $update_prices = true;
522
-            }
523
-            // if we have a TKT_ID then we need to get that existing TKT_obj and update it
524
-            // we actually do our saves ahead of doing any add_relations to
525
-            // because its entirely possible that this ticket wasn't removed or added to any datetime in the session
526
-            // but DID have it's items modified.
527
-            // keep in mind that if the TKT has been sold (and we have changed pricing information),
528
-            // then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
529
-            if (absint($TKT_values['TKT_ID'])) {
530
-                $ticket = EE_Registry::instance()
531
-                                     ->load_model('Ticket', array($timezone))
532
-                                     ->get_one_by_ID($tkt['TKT_ID']);
533
-                if ($ticket instanceof EE_Ticket) {
534
-                    $ticket = $this->_update_ticket_datetimes(
535
-                        $ticket,
536
-                        $saved_datetimes,
537
-                        $datetimes_added,
538
-                        $datetimes_removed
539
-                    );
540
-                    // are there any registrations using this ticket ?
541
-                    $tickets_sold = $ticket->count_related(
542
-                        'Registration',
543
-                        array(
544
-                            array(
545
-                                'STS_ID' => array('NOT IN', array(EEM_Registration::status_id_incomplete)),
546
-                            ),
547
-                        )
548
-                    );
549
-                    //set ticket formats
550
-                    $ticket->set_date_format($this->_date_format_strings['date']);
551
-                    $ticket->set_time_format($this->_date_format_strings['time']);
552
-                    // let's just check the total price for the existing ticket
553
-                    // and determine if it matches the new total price.
554
-                    // if they are different then we create a new ticket (if tickets sold)
555
-                    // if they aren't different then we go ahead and modify existing ticket.
556
-                    $create_new_TKT = $tickets_sold > 0 && $ticket_price !== $ticket->price() && ! $ticket->deleted();
557
-                    //set new values
558
-                    foreach ($TKT_values as $field => $value) {
559
-                        if ($field === 'TKT_qty') {
560
-                            $ticket->set_qty($value);
561
-                        } else {
562
-                            $ticket->set($field, $value);
563
-                        }
564
-                    }
565
-                    // if $create_new_TKT is false then we can safely update the existing ticket.
566
-                    // Otherwise we have to create a new ticket.
567
-                    if ($create_new_TKT) {
568
-                        $new_tkt = $this->_duplicate_ticket($ticket, $price_rows, $ticket_price, $base_price,
569
-                            $base_price_id);
570
-                    }
571
-                }
572
-            } else {
573
-                // no TKT_id so a new TKT
574
-                $ticket = EE_Ticket::new_instance(
575
-                    $TKT_values,
576
-                    $timezone,
577
-                    array($this->_date_format_strings['date'], $this->_date_format_strings['time'])
578
-                );
579
-                if ($ticket instanceof EE_Ticket) {
580
-                    // make sure ticket has an ID of setting relations won't work
581
-                    $ticket->save();
582
-                    $ticket = $this->_update_ticket_datetimes(
583
-                        $ticket,
584
-                        $saved_datetimes,
585
-                        $datetimes_added,
586
-                        $datetimes_removed
587
-                    );
588
-                    $update_prices = true;
589
-                }
590
-            }
591
-            //make sure any current values have been saved.
592
-            //$ticket->save();
593
-            // before going any further make sure our dates are setup correctly
594
-            // so that the end date is always equal or greater than the start date.
595
-            if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
596
-                $ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
597
-                $ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
598
-            }
599
-            //let's make sure the base price is handled
600
-            $ticket = ! $create_new_TKT ? $this->_add_prices_to_ticket(array(), $ticket, $update_prices, $base_price,
601
-                $base_price_id) : $ticket;
602
-            //add/update price_modifiers
603
-            $ticket = ! $create_new_TKT ? $this->_add_prices_to_ticket($price_rows, $ticket, $update_prices) : $ticket;
604
-            //need to make sue that the TKT_price is accurate after saving the prices.
605
-            $ticket->ensure_TKT_Price_correct();
606
-            //handle CREATING a default tkt from the incoming tkt but ONLY if this isn't an autosave.
607
-            if (! defined('DOING_AUTOSAVE') && ! empty($tkt['TKT_is_default_selector'])) {
608
-                $update_prices = true;
609
-                $new_default = clone $ticket;
610
-                $new_default->set('TKT_ID', 0);
611
-                $new_default->set('TKT_is_default', 1);
612
-                $new_default->set('TKT_row', 1);
613
-                $new_default->set('TKT_price', $ticket_price);
614
-                // remove any dtt relations cause we DON'T want dtt relations attached
615
-                // (note this is just removing the cached relations in the object)
616
-                $new_default->_remove_relations('Datetime');
617
-                //todo we need to add the current attached prices as new prices to the new default ticket.
618
-                $new_default = $this->_add_prices_to_ticket($price_rows, $new_default, $update_prices);
619
-                //don't forget the base price!
620
-                $new_default = $this->_add_prices_to_ticket(
621
-                    array(),
622
-                    $new_default,
623
-                    $update_prices,
624
-                    $base_price,
625
-                    $base_price_id
626
-                );
627
-                $new_default->save();
628
-                do_action(
629
-                    'AHEE__espresso_events_Pricing_Hooks___update_tkts_new_default_ticket',
630
-                    $new_default,
631
-                    $row,
632
-                    $ticket,
633
-                    $data
634
-                );
635
-            }
636
-            // DO ALL dtt relationships for both current tickets and any archived tickets
637
-            // for the given dtt that are related to the current ticket.
638
-            // TODO... not sure exactly how we're going to do this considering we don't know
639
-            // what current ticket the archived tickets are related to
640
-            // (and TKT_parent is used for autosaves so that's not a field we can reliably use).
641
-            //let's assign any tickets that have been setup to the saved_tickets tracker
642
-            //save existing TKT
643
-            $ticket->save();
644
-            if ($create_new_TKT && $new_tkt instanceof EE_Ticket) {
645
-                //save new TKT
646
-                $new_tkt->save();
647
-                //add new ticket to array
648
-                $saved_tickets[$new_tkt->ID()] = $new_tkt;
649
-                do_action(
650
-                    'AHEE__espresso_events_Pricing_Hooks___update_tkts_new_ticket',
651
-                    $new_tkt,
652
-                    $row,
653
-                    $tkt,
654
-                    $data
655
-                );
656
-            } else {
657
-                //add tkt to saved tkts
658
-                $saved_tickets[$ticket->ID()] = $ticket;
659
-                do_action(
660
-                    'AHEE__espresso_events_Pricing_Hooks___update_tkts_update_ticket',
661
-                    $ticket,
662
-                    $row,
663
-                    $tkt,
664
-                    $data
665
-                );
666
-            }
667
-        }
668
-        // now we need to handle tickets actually "deleted permanently".
669
-        // There are cases where we'd want this to happen
670
-        // (i.e. autosaves are happening and then in between autosaves the user trashes a ticket).
671
-        // Or a draft event was saved and in the process of editing a ticket is trashed.
672
-        // No sense in keeping all the related data in the db!
673
-        $old_tickets = isset($old_tickets[0]) && $old_tickets[0] === '' ? array() : $old_tickets;
674
-        $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
675
-        foreach ($tickets_removed as $id) {
676
-            $id = absint($id);
677
-            //get the ticket for this id
678
-            $tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
679
-            //if this tkt is a default tkt we leave it alone cause it won't be attached to the datetime
680
-            if ($tkt_to_remove->get('TKT_is_default')) {
681
-                continue;
682
-            }
683
-            // if this tkt has any registrations attached so then we just ARCHIVE
684
-            // because we don't actually permanently delete these tickets.
685
-            if ($tkt_to_remove->count_related('Registration') > 0) {
686
-                $tkt_to_remove->delete();
687
-                continue;
688
-            }
689
-            // need to get all the related datetimes on this ticket and remove from every single one of them
690
-            // (remember this process can ONLY kick off if there are NO tkts_sold)
691
-            $datetimes = $tkt_to_remove->get_many_related('Datetime');
692
-            foreach ($datetimes as $datetime) {
693
-                $tkt_to_remove->_remove_relation_to($datetime, 'Datetime');
694
-            }
695
-            // need to do the same for prices (except these prices can also be deleted because again,
696
-            // tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
697
-            $tkt_to_remove->delete_related_permanently('Price');
698
-            do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_delete_ticket', $tkt_to_remove);
699
-            // finally let's delete this ticket
700
-            // (which should not be blocked at this point b/c we've removed all our relationships)
701
-            $tkt_to_remove->delete_permanently();
702
-        }
703
-        return $saved_tickets;
704
-    }
705
-
706
-
707
-
708
-    /**
709
-     * @access  protected
710
-     * @param \EE_Ticket     $ticket
711
-     * @param \EE_Datetime[] $saved_datetimes
712
-     * @param \EE_Datetime[] $added_datetimes
713
-     * @param \EE_Datetime[] $removed_datetimes
714
-     * @return \EE_Ticket
715
-     * @throws \EE_Error
716
-     */
717
-    protected function _update_ticket_datetimes(
718
-        EE_Ticket $ticket,
719
-        $saved_datetimes = array(),
720
-        $added_datetimes = array(),
721
-        $removed_datetimes = array()
722
-    ) {
723
-        // to start we have to add the ticket to all the datetimes its supposed to be with,
724
-        // and removing the ticket from datetimes it got removed from.
725
-        // first let's add datetimes
726
-        if (! empty($added_datetimes) && is_array($added_datetimes)) {
727
-            foreach ($added_datetimes as $row_id) {
728
-                $row_id = (int)$row_id;
729
-                if (isset($saved_datetimes[$row_id]) && $saved_datetimes[$row_id] instanceof EE_Datetime) {
730
-                    $ticket->_add_relation_to($saved_datetimes[$row_id], 'Datetime');
731
-                    // Is this an existing ticket (has an ID) and does it have any sold?
732
-                    // If so, then we need to add that to the DTT sold because this DTT is getting added.
733
-                    if ($ticket->ID() && $ticket->sold() > 0) {
734
-                        $saved_datetimes[$row_id]->increase_sold($ticket->sold());
735
-                        $saved_datetimes[$row_id]->save();
736
-                    }
737
-                }
738
-            }
739
-        }
740
-        // then remove datetimes
741
-        if (! empty($removed_datetimes) && is_array($removed_datetimes)) {
742
-            foreach ($removed_datetimes as $row_id) {
743
-                $row_id = (int)$row_id;
744
-                // its entirely possible that a datetime got deleted (instead of just removed from relationship.
745
-                // So make sure we skip over this if the dtt isn't in the $saved_datetimes array)
746
-                if (isset($saved_datetimes[$row_id]) && $saved_datetimes[$row_id] instanceof EE_Datetime) {
747
-                    $ticket->_remove_relation_to($saved_datetimes[$row_id], 'Datetime');
748
-                    // Is this an existing ticket (has an ID) and does it have any sold?
749
-                    // If so, then we need to remove it's sold from the DTT_sold.
750
-                    if ($ticket->ID() && $ticket->sold() > 0) {
751
-                        $saved_datetimes[$row_id]->decrease_sold($ticket->sold());
752
-                        $saved_datetimes[$row_id]->save();
753
-                    }
754
-                }
755
-            }
756
-        }
757
-        // cap ticket qty by datetime reg limits
758
-        $ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
759
-        return $ticket;
760
-    }
761
-
762
-
763
-
764
-    /**
765
-     * @access  protected
766
-     * @param \EE_Ticket $ticket
767
-     * @param array      $price_rows
768
-     * @param int        $ticket_price
769
-     * @param int        $base_price
770
-     * @param int        $base_price_id
771
-     * @return \EE_Ticket
772
-     * @throws \EE_Error
773
-     */
774
-    protected function _duplicate_ticket(
775
-        EE_Ticket $ticket,
776
-        $price_rows = array(),
777
-        $ticket_price = 0,
778
-        $base_price = 0,
779
-        $base_price_id = 0
780
-    ) {
781
-        // create new ticket that's a copy of the existing
782
-        // except a new id of course (and not archived)
783
-        // AND has the new TKT_price associated with it.
784
-        $new_ticket = clone $ticket;
785
-        $new_ticket->set('TKT_ID', 0);
786
-        $new_ticket->set_deleted(0);
787
-        $new_ticket->set_price($ticket_price);
788
-        $new_ticket->set_sold(0);
789
-        // let's get a new ID for this ticket
790
-        $new_ticket->save();
791
-        // we also need to make sure this new ticket gets the same datetime attachments as the archived ticket
792
-        $datetimes_on_existing = $ticket->datetimes();
793
-        $new_ticket = $this->_update_ticket_datetimes(
794
-            $new_ticket,
795
-            $datetimes_on_existing,
796
-            array_keys($datetimes_on_existing)
797
-        );
798
-        // $ticket will get archived later b/c we are NOT adding it to the saved_tickets array.
799
-        // if existing $ticket has sold amount, then we need to adjust the qty for the new TKT to = the remaining
800
-        // available.
801
-        if ($ticket->sold() > 0) {
802
-            $new_qty = $ticket->qty() - $ticket->sold();
803
-            $new_ticket->set_qty($new_qty);
804
-        }
805
-        //now we update the prices just for this ticket
806
-        $new_ticket = $this->_add_prices_to_ticket($price_rows, $new_ticket, true);
807
-        //and we update the base price
808
-        $new_ticket = $this->_add_prices_to_ticket(array(), $new_ticket, true, $base_price, $base_price_id);
809
-        return $new_ticket;
810
-    }
811
-
812
-
813
-
814
-    /**
815
-     * This attaches a list of given prices to a ticket.
816
-     * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
817
-     * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
818
-     * price info and prices are automatically "archived" via the ticket.
819
-     *
820
-     * @access  private
821
-     * @param array     $prices        Array of prices from the form.
822
-     * @param EE_Ticket $ticket        EE_Ticket object that prices are being attached to.
823
-     * @param bool      $new_prices    Whether attach existing incoming prices or create new ones.
824
-     * @param int|bool  $base_price    if FALSE then NOT doing a base price add.
825
-     * @param int|bool  $base_price_id if present then this is the base_price_id being updated.
826
-     * @return EE_Ticket
827
-     * @throws EE_Error
828
-     */
829
-    protected function _add_prices_to_ticket(
830
-        $prices = array(),
831
-        EE_Ticket $ticket,
832
-        $new_prices = false,
833
-        $base_price = false,
834
-        $base_price_id = false
835
-    ) {
836
-        // let's just get any current prices that may exist on the given ticket
837
-        // so we can remove any prices that got trashed in this session.
838
-        $current_prices_on_ticket = $base_price !== false
839
-            ? $ticket->base_price(true)
840
-            : $ticket->price_modifiers();
841
-        $updated_prices = array();
842
-        // if $base_price ! FALSE then updating a base price.
843
-        if ($base_price !== false) {
844
-            $prices[1] = array(
845
-                'PRC_ID'     => $new_prices || $base_price_id === 1 ? null : $base_price_id,
846
-                'PRT_ID'     => 1,
847
-                'PRC_amount' => $base_price,
848
-                'PRC_name'   => $ticket->get('TKT_name'),
849
-                'PRC_desc'   => $ticket->get('TKT_description'),
850
-            );
851
-        }
852
-        //possibly need to save tkt
853
-        if (! $ticket->ID()) {
854
-            $ticket->save();
855
-        }
856
-        foreach ($prices as $row => $prc) {
857
-            $prt_id = ! empty($prc['PRT_ID']) ? $prc['PRT_ID'] : null;
858
-            if (empty($prt_id)) {
859
-                continue;
860
-            } //prices MUST have a price type id.
861
-            $PRC_values = array(
862
-                'PRC_ID'         => ! empty($prc['PRC_ID']) ? $prc['PRC_ID'] : null,
863
-                'PRT_ID'         => $prt_id,
864
-                'PRC_amount'     => ! empty($prc['PRC_amount']) ? $prc['PRC_amount'] : 0,
865
-                'PRC_name'       => ! empty($prc['PRC_name']) ? $prc['PRC_name'] : '',
866
-                'PRC_desc'       => ! empty($prc['PRC_desc']) ? $prc['PRC_desc'] : '',
867
-                'PRC_is_default' => false,
868
-                //make sure we set PRC_is_default to false for all ticket saves from event_editor
869
-                'PRC_order'      => $row,
870
-            );
871
-            if ($new_prices || empty($PRC_values['PRC_ID'])) {
872
-                $PRC_values['PRC_ID'] = 0;
873
-                $price = EE_Registry::instance()->load_class(
874
-                    'Price',
875
-                    array($PRC_values),
876
-                    false,
877
-                    false
878
-                );
879
-            } else {
880
-                $price = EE_Registry::instance()->load_model('Price')->get_one_by_ID($prc['PRC_ID']);
881
-                //update this price with new values
882
-                foreach ($PRC_values as $field => $value) {
883
-                    $price->set($field, $value);
884
-                }
885
-            }
886
-            $price->save();
887
-            $updated_prices[$price->ID()] = $price;
888
-            $ticket->_add_relation_to($price, 'Price');
889
-        }
890
-        //now let's remove any prices that got removed from the ticket
891
-        if (! empty ($current_prices_on_ticket)) {
892
-            $current = array_keys($current_prices_on_ticket);
893
-            $updated = array_keys($updated_prices);
894
-            $prices_to_remove = array_diff($current, $updated);
895
-            if (! empty($prices_to_remove)) {
896
-                foreach ($prices_to_remove as $prc_id) {
897
-                    $p = $current_prices_on_ticket[$prc_id];
898
-                    $ticket->_remove_relation_to($p, 'Price');
899
-                    //delete permanently the price
900
-                    $p->delete_permanently();
901
-                }
902
-            }
903
-        }
904
-        return $ticket;
905
-    }
906
-
907
-
908
-
909
-    /**
910
-     * @param Events_Admin_Page $event_admin_obj
911
-     * @return Events_Admin_Page
912
-     */
913
-    public function autosave_handling( Events_Admin_Page $event_admin_obj)
914
-    {
915
-        return $event_admin_obj;
916
-        //doing nothing for the moment.
917
-        // todo when I get to this remember that I need to set the template args on the $event_admin_obj
918
-        // (use the set_template_args() method)
919
-        /**
920
-         * need to remember to handle TICKET DEFAULT saves correctly:  I've got two input fields in the dom:
921
-         * 1. TKT_is_default_selector (visible)
922
-         * 2. TKT_is_default (hidden)
923
-         * I think we'll use the TKT_is_default for recording whether the ticket displayed IS a default ticket
924
-         * (on new event creations). Whereas the TKT_is_default_selector is for the user to indicate they want
925
-         * this ticket to be saved as a default.
926
-         * The tricky part is, on an initial display on create or edit (or after manually updating),
927
-         * the TKT_is_default_selector will always be unselected and the TKT_is_default will only be true
928
-         * if this is a create.  However, after an autosave, users will want some sort of indicator that
929
-         * the TKT HAS been saved as a default..
930
-         * in other words we don't want to remove the check on TKT_is_default_selector. So here's what I'm thinking.
931
-         * On Autosave:
932
-         * 1. If TKT_is_default is true: we create a new TKT, send back the new id and add id to related elements,
933
-         * then set the TKT_is_default to false.
934
-         * 2. If TKT_is_default_selector is true: we create/edit existing ticket (following conditions above as well).
935
-         *  We do NOT create a new default ticket.  The checkbox stays selected after autosave.
936
-         * 3. only on MANUAL update do we check for the selection and if selected create the new default ticket.
937
-         */
938
-    }
939
-
940
-
941
-
942
-    /**
943
-     * @throws DomainException
944
-     * @throws EE_Error
945
-     */
946
-    public function pricing_metabox()
947
-    {
948
-        $existing_datetime_ids = $existing_ticket_ids = $datetime_tickets = $ticket_datetimes = array();
949
-        $event = $this->_adminpage_obj->get_cpt_model_obj();
950
-        //set is_creating_event property.
951
-        $EVT_ID = $event->ID();
952
-        $this->_is_creating_event = absint($EVT_ID) === 0;
953
-        //default main template args
954
-        $main_template_args = array(
955
-            'event_datetime_help_link' => EEH_Template::get_help_tab_link(
956
-                'event_editor_event_datetimes_help_tab',
957
-                $this->_adminpage_obj->page_slug,
958
-                $this->_adminpage_obj->get_req_action(),
959
-                false,
960
-                false
961
-            ),
962
-            // todo need to add a filter to the template for the help text
963
-            // in the Events_Admin_Page core file so we can add further help
964
-            'existing_datetime_ids'    => '',
965
-            'total_dtt_rows'           => 1,
966
-            'add_new_dtt_help_link'    => EEH_Template::get_help_tab_link(
967
-                'add_new_dtt_info',
968
-                $this->_adminpage_obj->page_slug,
969
-                $this->_adminpage_obj->get_req_action(),
970
-                false,
971
-                false
972
-            ),
973
-            //todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
974
-            'datetime_rows'            => '',
975
-            'show_tickets_container'   => '',
976
-            //$this->_adminpage_obj->get_cpt_model_obj()->ID() > 1 ? ' style="display:none;"' : '',
977
-            'ticket_rows'              => '',
978
-            'existing_ticket_ids'      => '',
979
-            'total_ticket_rows'        => 1,
980
-            'ticket_js_structure'      => '',
981
-            'ee_collapsible_status'    => ' ee-collapsible-open'
982
-            //$this->_adminpage_obj->get_cpt_model_obj()->ID() > 0 ? ' ee-collapsible-closed' : ' ee-collapsible-open'
983
-        );
984
-        $timezone = $event instanceof EE_Event ? $event->timezone_string() : null;
985
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
986
-        /**
987
-         * 1. Start with retrieving Datetimes
988
-         * 2. For each datetime get related tickets
989
-         * 3. For each ticket get related prices
990
-         */
991
-        /** @var EEM_Datetime $datetime_model */
992
-        $datetime_model = EE_Registry::instance()->load_model('Datetime', array($timezone));
993
-        $datetimes = $datetime_model->get_all_event_dates($EVT_ID);
994
-        $main_template_args['total_dtt_rows'] = count($datetimes);
995
-        /**
996
-         * @see https://events.codebasehq.com/projects/event-espresso/tickets/9486
997
-         * for why we are counting $datetime_row and then setting that on the Datetime object
998
-         */
999
-        $datetime_row = 1;
1000
-        foreach ($datetimes as $datetime) {
1001
-            $DTT_ID = $datetime->get('DTT_ID');
1002
-            $datetime->set('DTT_order', $datetime_row);
1003
-            $existing_datetime_ids[] = $DTT_ID;
1004
-            //tickets attached
1005
-            $related_tickets = $datetime->ID() > 0
1006
-                ? $datetime->get_many_related(
1007
-                    'Ticket',
1008
-                    array(
1009
-                        array(
1010
-                            'OR' => array('TKT_deleted' => 1, 'TKT_deleted*' => 0),
1011
-                        ),
1012
-                        'default_where_conditions' => 'none',
1013
-                        'order_by'                 => array('TKT_order' => 'ASC'),
1014
-                    )
1015
-                )
1016
-                : array();
1017
-            //if there are no related tickets this is likely a new event OR autodraft
1018
-            // event so we need to generate the default tickets because datetimes
1019
-            // ALWAYS have at least one related ticket!!.  EXCEPT, we dont' do this if there is already more than one
1020
-            // datetime on the event.
1021
-            if (empty ($related_tickets) && count($datetimes) < 2) {
1022
-                /** @var EEM_Ticket $ticket_model */
1023
-                $ticket_model = EE_Registry::instance()->load_model('Ticket');
1024
-                $related_tickets = $ticket_model->get_all_default_tickets();
1025
-                // this should be ordered by TKT_ID, so let's grab the first default ticket
1026
-                // (which will be the main default) and ensure it has any default prices added to it (but do NOT save).
1027
-                $default_prices = EEM_Price::instance()->get_all_default_prices();
1028
-                $main_default_ticket = reset($related_tickets);
1029
-                if ($main_default_ticket instanceof EE_Ticket) {
1030
-                    foreach ($default_prices as $default_price) {
1031
-                        if ($default_price instanceof EE_Price && $default_price->is_base_price()) {
1032
-                            continue;
1033
-                        }
1034
-                        $main_default_ticket->cache('Price', $default_price);
1035
-                    }
1036
-                }
1037
-            }
1038
-            // we can't actually setup rows in this loop yet cause we don't know all
1039
-            // the unique tickets for this event yet (tickets are linked through all datetimes).
1040
-            // So we're going to temporarily cache some of that information.
1041
-            //loop through and setup the ticket rows and make sure the order is set.
1042
-            foreach ($related_tickets as $ticket) {
1043
-                $TKT_ID = $ticket->get('TKT_ID');
1044
-                $ticket_row = $ticket->get('TKT_row');
1045
-                //we only want unique tickets in our final display!!
1046
-                if (! in_array($TKT_ID, $existing_ticket_ids, true)) {
1047
-                    $existing_ticket_ids[] = $TKT_ID;
1048
-                    $all_tickets[] = $ticket;
1049
-                }
1050
-                //temporary cache of this ticket info for this datetime for later processing of datetime rows.
1051
-                $datetime_tickets[$DTT_ID][] = $ticket_row;
1052
-                //temporary cache of this datetime info for this ticket for later processing of ticket rows.
1053
-                if (
1054
-                    ! isset($ticket_datetimes[$TKT_ID])
1055
-                    || ! in_array($datetime_row, $ticket_datetimes[$TKT_ID], true)
1056
-                ) {
1057
-                    $ticket_datetimes[$TKT_ID][] = $datetime_row;
1058
-                }
1059
-            }
1060
-            $datetime_row++;
1061
-        }
1062
-        $main_template_args['total_ticket_rows'] = count($existing_ticket_ids);
1063
-        $main_template_args['existing_ticket_ids'] = implode(',', $existing_ticket_ids);
1064
-        $main_template_args['existing_datetime_ids'] = implode(',', $existing_datetime_ids);
1065
-        //sort $all_tickets by order
1066
-        usort(
1067
-            $all_tickets,
1068
-            function (EE_Ticket $a, EE_Ticket $b) {
1069
-                $a_order = (int)$a->get('TKT_order');
1070
-                $b_order = (int)$b->get('TKT_order');
1071
-                if ($a_order === $b_order) {
1072
-                    return 0;
1073
-                }
1074
-                return ($a_order < $b_order) ? -1 : 1;
1075
-            }
1076
-        );
1077
-        // k NOW we have all the data we need for setting up the dtt rows
1078
-        // and ticket rows so we start our dtt loop again.
1079
-        $datetime_row = 1;
1080
-        foreach ($datetimes as $datetime) {
1081
-            $main_template_args['datetime_rows'] .= $this->_get_datetime_row(
1082
-                $datetime_row,
1083
-                $datetime,
1084
-                $datetime_tickets,
1085
-                $all_tickets,
1086
-                false,
1087
-                $datetimes
1088
-            );
1089
-            $datetime_row++;
1090
-        }
1091
-        //then loop through all tickets for the ticket rows.
1092
-        $ticket_row = 1;
1093
-        foreach ($all_tickets as $ticket) {
1094
-            $main_template_args['ticket_rows'] .= $this->_get_ticket_row(
1095
-                $ticket_row,
1096
-                $ticket,
1097
-                $ticket_datetimes,
1098
-                $datetimes,
1099
-                false,
1100
-                $all_tickets
1101
-            );
1102
-            $ticket_row++;
1103
-        }
1104
-        $main_template_args['ticket_js_structure'] = $this->_get_ticket_js_structure($datetimes, $all_tickets);
1105
-        EEH_Template::display_template(
1106
-            PRICING_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php',
1107
-            $main_template_args
1108
-        );
1109
-    }
1110
-
1111
-
1112
-
1113
-    /**
1114
-     * @param int         $datetime_row
1115
-     * @param EE_Datetime $datetime
1116
-     * @param array       $datetime_tickets
1117
-     * @param array       $all_tickets
1118
-     * @param bool        $default
1119
-     * @param array       $all_datetimes
1120
-     * @return mixed
1121
-     * @throws DomainException
1122
-     * @throws EE_Error
1123
-     */
1124
-    protected function _get_datetime_row(
1125
-        $datetime_row,
1126
-        EE_Datetime $datetime,
1127
-        $datetime_tickets = array(),
1128
-        $all_tickets = array(),
1129
-        $default = false,
1130
-        $all_datetimes = array()
1131
-    ) {
1132
-        $dtt_display_template_args = array(
1133
-            'dtt_edit_row'             => $this->_get_dtt_edit_row($datetime_row, $datetime, $default, $all_datetimes),
1134
-            'dtt_attached_tickets_row' => $this->_get_dtt_attached_tickets_row(
1135
-                $datetime_row,
1136
-                $datetime,
1137
-                $datetime_tickets,
1138
-                $all_tickets,
1139
-                $default
1140
-            ),
1141
-            'dtt_row'                  => $default ? 'DTTNUM' : $datetime_row,
1142
-        );
1143
-        return EEH_Template::display_template(
1144
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_row_wrapper.template.php',
1145
-            $dtt_display_template_args,
1146
-            true
1147
-        );
1148
-    }
1149
-
1150
-
1151
-
1152
-    /**
1153
-     * This method is used to generate a dtt fields  edit row.
1154
-     * The same row is used to generate a row with valid DTT objects
1155
-     * and the default row that is used as the skeleton by the js.
1156
-     *
1157
-     * @param int           $datetime_row  The row number for the row being generated.
1158
-     * @param EE_Datetime   $datetime
1159
-     * @param bool          $default       Whether a default row is being generated or not.
1160
-     * @param EE_Datetime[] $all_datetimes This is the array of all datetimes used in the editor.
1161
-     * @return string
1162
-     * @throws DomainException
1163
-     * @throws EE_Error
1164
-     */
1165
-    protected function _get_dtt_edit_row($datetime_row, $datetime, $default, $all_datetimes)
1166
-    {
1167
-        // if the incoming $datetime object is NOT an instance of EE_Datetime then force default to true.
1168
-        $default = ! $datetime instanceof EE_Datetime ? true : $default;
1169
-        $template_args = array(
1170
-            'dtt_row'              => $default ? 'DTTNUM' : $datetime_row,
1171
-            'event_datetimes_name' => $default ? 'DTTNAMEATTR' : 'edit_event_datetimes',
1172
-            'edit_dtt_expanded'    => '',
1173
-            'DTT_ID'               => $default ? '' : $datetime->ID(),
1174
-            'DTT_name'             => $default ? '' : $datetime->name(),
1175
-            'DTT_description'      => $default ? '' : $datetime->description(),
1176
-            'DTT_EVT_start'        => $default ? '' : $datetime->start_date($this->_date_time_format),
1177
-            'DTT_EVT_end'          => $default ? '' : $datetime->end_date($this->_date_time_format),
1178
-            'DTT_reg_limit'        => $default
1179
-                ? ''
1180
-                : $datetime->get_pretty(
1181
-                    'DTT_reg_limit',
1182
-                    'input'
1183
-                ),
1184
-            'DTT_order'            => $default ? 'DTTNUM' : $datetime_row,
1185
-            'dtt_sold'             => $default ? '0' : $datetime->get('DTT_sold'),
1186
-            'dtt_reserved'         => $default ? '0' : $datetime->reserved(),
1187
-            'clone_icon'           => ! empty($datetime) && $datetime->get('DTT_sold') > 0
1188
-                ? ''
1189
-                : 'clone-icon ee-icon ee-icon-clone clickable',
1190
-            'trash_icon'           => ! empty($datetime) && $datetime->get('DTT_sold') > 0
1191
-                ? 'ee-lock-icon'
1192
-                : 'trash-icon dashicons dashicons-post-trash clickable',
1193
-            'reg_list_url'         => $default || ! $datetime->event() instanceof \EE_Event
1194
-                ? ''
1195
-                : EE_Admin_Page::add_query_args_and_nonce(
1196
-                    array('event_id' => $datetime->event()->ID(), 'datetime_id' => $datetime->ID()),
1197
-                    REG_ADMIN_URL
1198
-                ),
1199
-        );
1200
-        $template_args['show_trash'] = count($all_datetimes) === 1 && $template_args['trash_icon'] !== 'ee-lock-icon'
1201
-            ? ' style="display:none"'
1202
-            : '';
1203
-        //allow filtering of template args at this point.
1204
-        $template_args = apply_filters(
1205
-            'FHEE__espresso_events_Pricing_Hooks___get_dtt_edit_row__template_args',
1206
-            $template_args,
1207
-            $datetime_row,
1208
-            $datetime,
1209
-            $default,
1210
-            $all_datetimes,
1211
-            $this->_is_creating_event
1212
-        );
1213
-        return EEH_Template::display_template(
1214
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_edit_row.template.php',
1215
-            $template_args,
1216
-            true
1217
-        );
1218
-    }
1219
-
1220
-
1221
-
1222
-    /**
1223
-     * @param int         $datetime_row
1224
-     * @param EE_Datetime $datetime
1225
-     * @param array       $datetime_tickets
1226
-     * @param array       $all_tickets
1227
-     * @param bool        $default
1228
-     * @return mixed
1229
-     * @throws DomainException
1230
-     * @throws EE_Error
1231
-     */
1232
-    protected function _get_dtt_attached_tickets_row(
1233
-        $datetime_row,
1234
-        $datetime,
1235
-        $datetime_tickets = array(),
1236
-        $all_tickets = array(),
1237
-        $default
1238
-    ) {
1239
-        $template_args = array(
1240
-            'dtt_row'                           => $default ? 'DTTNUM' : $datetime_row,
1241
-            'event_datetimes_name'              => $default ? 'DTTNAMEATTR' : 'edit_event_datetimes',
1242
-            'DTT_description'                   => $default ? '' : $datetime->description(),
1243
-            'datetime_tickets_list'             => $default ? '<li class="hidden"></li>' : '',
1244
-            'show_tickets_row'                  => ' style="display:none;"',
1245
-            'add_new_datetime_ticket_help_link' => EEH_Template::get_help_tab_link(
1246
-                'add_new_ticket_via_datetime',
1247
-                $this->_adminpage_obj->page_slug,
1248
-                $this->_adminpage_obj->get_req_action(),
1249
-                false,
1250
-                false
1251
-            ),
1252
-            //todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
1253
-            'DTT_ID'                            => $default ? '' : $datetime->ID(),
1254
-        );
1255
-        //need to setup the list items (but only if this isn't a default skeleton setup)
1256
-        if (! $default) {
1257
-            $ticket_row = 1;
1258
-            foreach ($all_tickets as $ticket) {
1259
-                $template_args['datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item(
1260
-                    $datetime_row,
1261
-                    $ticket_row,
1262
-                    $datetime,
1263
-                    $ticket,
1264
-                    $datetime_tickets,
1265
-                    $default
1266
-                );
1267
-                $ticket_row++;
1268
-            }
1269
-        }
1270
-        //filter template args at this point
1271
-        $template_args = apply_filters(
1272
-            'FHEE__espresso_events_Pricing_Hooks___get_dtt_attached_ticket_row__template_args',
1273
-            $template_args,
1274
-            $datetime_row,
1275
-            $datetime,
1276
-            $datetime_tickets,
1277
-            $all_tickets,
1278
-            $default,
1279
-            $this->_is_creating_event
1280
-        );
1281
-        return EEH_Template::display_template(
1282
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_attached_tickets_row.template.php',
1283
-            $template_args,
1284
-            true
1285
-        );
1286
-    }
1287
-
1288
-
1289
-
1290
-    /**
1291
-     * @param int         $datetime_row
1292
-     * @param int         $ticket_row
1293
-     * @param EE_Datetime $datetime
1294
-     * @param EE_Ticket   $ticket
1295
-     * @param array       $datetime_tickets
1296
-     * @param bool        $default
1297
-     * @return mixed
1298
-     * @throws DomainException
1299
-     * @throws EE_Error
1300
-     */
1301
-    protected function _get_datetime_tickets_list_item(
1302
-        $datetime_row,
1303
-        $ticket_row,
1304
-        $datetime,
1305
-        $ticket,
1306
-        $datetime_tickets = array(),
1307
-        $default
1308
-    ) {
1309
-        $dtt_tkts = $datetime instanceof EE_Datetime && isset($datetime_tickets[$datetime->ID()])
1310
-            ? $datetime_tickets[$datetime->ID()]
1311
-            : array();
1312
-        $display_row = $ticket instanceof EE_Ticket ? $ticket->get('TKT_row') : 0;
1313
-        $no_ticket = $default && empty($ticket);
1314
-        $template_args = array(
1315
-            'dtt_row'                 => $default
1316
-                ? 'DTTNUM'
1317
-                : $datetime_row,
1318
-            'tkt_row'                 => $no_ticket
1319
-                ? 'TICKETNUM'
1320
-                : $ticket_row,
1321
-            'datetime_ticket_checked' => in_array($display_row, $dtt_tkts, true)
1322
-                ? ' checked="checked"'
1323
-                : '',
1324
-            'ticket_selected'         => in_array($display_row, $dtt_tkts, true)
1325
-                ? ' ticket-selected'
1326
-                : '',
1327
-            'TKT_name'                => $no_ticket
1328
-                ? 'TKTNAME'
1329
-                : $ticket->get('TKT_name'),
1330
-            'tkt_status_class'        => $no_ticket || $this->_is_creating_event
1331
-                ? ' tkt-status-' . EE_Ticket::onsale
1332
-                : ' tkt-status-' . $ticket->ticket_status(),
1333
-        );
1334
-        //filter template args
1335
-        $template_args = apply_filters(
1336
-            'FHEE__espresso_events_Pricing_Hooks___get_datetime_tickets_list_item__template_args',
1337
-            $template_args,
1338
-            $datetime_row,
1339
-            $ticket_row,
1340
-            $datetime,
1341
-            $ticket,
1342
-            $datetime_tickets,
1343
-            $default,
1344
-            $this->_is_creating_event
1345
-        );
1346
-        return EEH_Template::display_template(
1347
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_dtt_tickets_list.template.php',
1348
-            $template_args,
1349
-            true
1350
-        );
1351
-    }
1352
-
1353
-
1354
-
1355
-    /**
1356
-     * This generates the ticket row for tickets.
1357
-     * This same method is used to generate both the actual rows and the js skeleton row
1358
-     * (when default === true)
1359
-     *
1360
-     * @param int           $ticket_row       Represents the row number being generated.
1361
-     * @param               $ticket
1362
-     * @param EE_Datetime[] $ticket_datetimes Either an array of all datetimes on all tickets indexed by each ticket
1363
-     *                                        or empty for default
1364
-     * @param EE_Datetime[] $all_datetimes    All Datetimes on the event or empty for default.
1365
-     * @param bool          $default          Whether default row being generated or not.
1366
-     * @param EE_Ticket[]   $all_tickets      This is an array of all tickets attached to the event
1367
-     *                                        (or empty in the case of defaults)
1368
-     * @return mixed
1369
-     * @throws DomainException
1370
-     * @throws EE_Error
1371
-     */
1372
-    protected function _get_ticket_row(
1373
-        $ticket_row,
1374
-        $ticket,
1375
-        $ticket_datetimes,
1376
-        $all_datetimes,
1377
-        $default = false,
1378
-        $all_tickets = array()
1379
-    ) {
1380
-        // if $ticket is not an instance of EE_Ticket then force default to true.
1381
-        $default = ! $ticket instanceof EE_Ticket ? true : $default;
1382
-        $prices = ! empty($ticket) && ! $default ? $ticket->get_many_related('Price',
1383
-            array('default_where_conditions' => 'none', 'order_by' => array('PRC_order' => 'ASC'))) : array();
1384
-        // if there is only one price (which would be the base price)
1385
-        // or NO prices and this ticket is a default ticket,
1386
-        // let's just make sure there are no cached default prices on the object.
1387
-        // This is done by not including any query_params.
1388
-        if ($ticket instanceof EE_Ticket && $ticket->is_default() && (count($prices) === 1 || empty($prices))) {
1389
-            $prices = $ticket->prices();
1390
-        }
1391
-        // check if we're dealing with a default ticket in which case
1392
-        // we don't want any starting_ticket_datetime_row values set
1393
-        // (otherwise there won't be any new relationships created for tickets based off of the default ticket).
1394
-        // This will future proof in case there is ever any behaviour change between what the primary_key defaults to.
1395
-        $default_dtt = $default || ($ticket instanceof EE_Ticket && $ticket->is_default());
1396
-        $tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[$ticket->ID()])
1397
-            ? $ticket_datetimes[$ticket->ID()]
1398
-            : array();
1399
-        $ticket_subtotal = $default ? 0 : $ticket->get_ticket_subtotal();
1400
-        $base_price = $default ? null : $ticket->base_price();
1401
-        $count_price_mods = EEM_Price::instance()->get_all_default_prices(true);
1402
-        //breaking out complicated condition for ticket_status
1403
-        if ($default) {
1404
-            $ticket_status_class = ' tkt-status-' . EE_Ticket::onsale;
1405
-        } else {
1406
-            $ticket_status_class = $ticket->is_default()
1407
-                ? ' tkt-status-' . EE_Ticket::onsale
1408
-                : ' tkt-status-' . $ticket->ticket_status();
1409
-        }
1410
-        //breaking out complicated condition for TKT_taxable
1411
-        if ($default) {
1412
-            $TKT_taxable = '';
1413
-        } else {
1414
-            $TKT_taxable = $ticket->taxable()
1415
-                ? ' checked="checked"'
1416
-                : '';
1417
-        }
1418
-        if ($default) {
1419
-            $TKT_status = EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence');
1420
-        } elseif ($ticket->is_default()) {
1421
-            $TKT_status = EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence');
1422
-        } else {
1423
-            $TKT_status = $ticket->ticket_status(true);
1424
-        }
1425
-        if ($default) {
1426
-            $TKT_min = '';
1427
-        } else {
1428
-            $TKT_min = $ticket->min();
1429
-            if ($TKT_min === -1 || $TKT_min === 0) {
1430
-                $TKT_min = '';
1431
-            }
1432
-        }
1433
-        $template_args = array(
1434
-            'tkt_row'                       => $default ? 'TICKETNUM' : $ticket_row,
1435
-            'TKT_order'                     => $default ? 'TICKETNUM' : $ticket_row,
1436
-            //on initial page load this will always be the correct order.
1437
-            'tkt_status_class'              => $ticket_status_class,
1438
-            'display_edit_tkt_row'          => ' style="display:none;"',
1439
-            'edit_tkt_expanded'             => '',
1440
-            'edit_tickets_name'             => $default ? 'TICKETNAMEATTR' : 'edit_tickets',
1441
-            'TKT_name'                      => $default ? '' : $ticket->name(),
1442
-            'TKT_start_date'                => $default
1443
-                ? ''
1444
-                : $ticket->get_date('TKT_start_date', $this->_date_time_format),
1445
-            'TKT_end_date'                  => $default
1446
-                ? ''
1447
-                : $ticket->get_date('TKT_end_date', $this->_date_time_format),
1448
-            'TKT_status'                    => $TKT_status,
1449
-            'TKT_price'                     => $default
1450
-                ? ''
1451
-                : EEH_Template::format_currency(
1452
-                    $ticket->get_ticket_total_with_taxes(),
1453
-                    false,
1454
-                    false
1455
-                ),
1456
-            'TKT_price_code'                => EE_Registry::instance()->CFG->currency->code,
1457
-            'TKT_price_amount'              => $default ? 0 : $ticket_subtotal,
1458
-            'TKT_qty'                       => $default
1459
-                ? ''
1460
-                : $ticket->get_pretty('TKT_qty', 'symbol'),
1461
-            'TKT_qty_for_input'             => $default
1462
-                ? ''
1463
-                : $ticket->get_pretty('TKT_qty', 'input'),
1464
-            'TKT_uses'                      => $default
1465
-                ? ''
1466
-                : $ticket->get_pretty('TKT_uses', 'input'),
1467
-            'TKT_min'                       => $TKT_min,
1468
-            'TKT_max'                       => $default
1469
-                ? ''
1470
-                : $ticket->get_pretty('TKT_max', 'input'),
1471
-            'TKT_sold'                      => $default ? 0 : $ticket->tickets_sold('ticket'),
1472
-            'TKT_reserved'                  => $default ? 0 : $ticket->reserved(),
1473
-            'TKT_registrations'             => $default
1474
-                ? 0
1475
-                : $ticket->count_registrations(
1476
-                    array(
1477
-                        array(
1478
-                            'STS_ID' => array(
1479
-                                '!=',
1480
-                                EEM_Registration::status_id_incomplete,
1481
-                            ),
1482
-                        ),
1483
-                    )
1484
-                ),
1485
-            'TKT_ID'                        => $default ? 0 : $ticket->ID(),
1486
-            'TKT_description'               => $default ? '' : $ticket->get_pretty('TKT_description', 'form_input'),
1487
-            'TKT_is_default'                => $default ? 0 : $ticket->is_default(),
1488
-            'TKT_required'                  => $default ? 0 : $ticket->required(),
1489
-            'TKT_is_default_selector'       => '',
1490
-            'ticket_price_rows'             => '',
1491
-            'TKT_base_price'                => $default || ! $base_price instanceof EE_Price
1492
-                ? ''
1493
-                : $base_price->get_pretty('PRC_amount', 'localized_float'),
1494
-            'TKT_base_price_ID'             => $default || ! $base_price instanceof EE_Price ? 0 : $base_price->ID(),
1495
-            'show_price_modifier'           => count($prices) > 1 || ($default && $count_price_mods > 0)
1496
-                ? ''
1497
-                : ' style="display:none;"',
1498
-            'show_price_mod_button'         => count($prices) > 1
1499
-                                               || ($default && $count_price_mods > 0)
1500
-                                               || (! $default && $ticket->deleted())
1501
-                ? ' style="display:none;"'
1502
-                : '',
1503
-            'total_price_rows'              => count($prices) > 1 ? count($prices) : 1,
1504
-            'ticket_datetimes_list'         => $default ? '<li class="hidden"></li>' : '',
1505
-            'starting_ticket_datetime_rows' => $default || $default_dtt ? '' : implode(',', $tkt_datetimes),
1506
-            'ticket_datetime_rows'          => $default ? '' : implode(',', $tkt_datetimes),
1507
-            'existing_ticket_price_ids'     => $default ? '' : implode(',', array_keys($prices)),
1508
-            'ticket_template_id'            => $default ? 0 : $ticket->get('TTM_ID'),
1509
-            'TKT_taxable'                   => $TKT_taxable,
1510
-            'display_subtotal'              => $ticket instanceof EE_Ticket && $ticket->taxable()
1511
-                ? ''
1512
-                : ' style="display:none"',
1513
-            'price_currency_symbol'         => EE_Registry::instance()->CFG->currency->sign,
1514
-            'TKT_subtotal_amount_display'   => EEH_Template::format_currency(
1515
-                $ticket_subtotal,
1516
-                false,
1517
-                false
1518
-            ),
1519
-            'TKT_subtotal_amount'           => $ticket_subtotal,
1520
-            'tax_rows'                      => $this->_get_tax_rows($ticket_row, $ticket),
1521
-            'disabled'                      => $ticket instanceof EE_Ticket && $ticket->deleted(),
1522
-            'ticket_archive_class'          => $ticket instanceof EE_Ticket && $ticket->deleted()
1523
-                ? ' ticket-archived'
1524
-                : '',
1525
-            'trash_icon'                    => $ticket instanceof EE_Ticket
1526
-                                               && $ticket->deleted()
1527
-                                               && ! $ticket->is_permanently_deleteable()
1528
-                ? 'ee-lock-icon '
1529
-                : 'trash-icon dashicons dashicons-post-trash clickable',
1530
-            'clone_icon'                    => $ticket instanceof EE_Ticket && $ticket->deleted()
1531
-                ? ''
1532
-                : 'clone-icon ee-icon ee-icon-clone clickable',
1533
-        );
1534
-        $template_args['trash_hidden'] = count($all_tickets) === 1 && $template_args['trash_icon'] !== 'ee-lock-icon'
1535
-            ? ' style="display:none"'
1536
-            : '';
1537
-        //handle rows that should NOT be empty
1538
-        if (empty($template_args['TKT_start_date'])) {
1539
-            //if empty then the start date will be now.
1540
-            $template_args['TKT_start_date'] = date($this->_date_time_format,
1541
-                current_time('timestamp'));
1542
-            $template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1543
-        }
1544
-        if (empty($template_args['TKT_end_date'])) {
1545
-            //get the earliest datetime (if present);
1546
-            $earliest_dtt = $this->_adminpage_obj->get_cpt_model_obj()->ID() > 0
1547
-                ? $this->_adminpage_obj->get_cpt_model_obj()->get_first_related(
1548
-                    'Datetime',
1549
-                    array('order_by' => array('DTT_EVT_start' => 'ASC'))
1550
-                )
1551
-                : null;
1552
-            if (! empty($earliest_dtt)) {
1553
-                $template_args['TKT_end_date'] = $earliest_dtt->get_datetime(
1554
-                    'DTT_EVT_start',
1555
-                    $this->_date_time_format
1556
-                );
1557
-            } else {
1558
-                //default so let's just use what's been set for the default date-time which is 30 days from now.
1559
-                $template_args['TKT_end_date'] = date(
1560
-                    $this->_date_time_format,
1561
-                    mktime(24, 0, 0, date('m'), date('d') + 29, date('Y')
1562
-                    )
1563
-                );
1564
-            }
1565
-            $template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1566
-        }
1567
-        //generate ticket_datetime items
1568
-        if (! $default) {
1569
-            $datetime_row = 1;
1570
-            foreach ($all_datetimes as $datetime) {
1571
-                $template_args['ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item(
1572
-                    $datetime_row,
1573
-                    $ticket_row,
1574
-                    $datetime,
1575
-                    $ticket,
1576
-                    $ticket_datetimes,
1577
-                    $default
1578
-                );
1579
-                $datetime_row++;
1580
-            }
1581
-        }
1582
-        $price_row = 1;
1583
-        foreach ($prices as $price) {
1584
-            if (! $price instanceof EE_Price)  {
1585
-                continue;
1586
-            }
1587
-            if ($price->is_base_price()) {
1588
-                $price_row++;
1589
-                continue;
1590
-            }
1591
-            $show_trash = !((count($prices) > 1 && $price_row === 1) || count($prices) === 1);
1592
-            $show_create = !(count($prices) > 1 && count($prices) !== $price_row);
1593
-            $template_args['ticket_price_rows'] .= $this->_get_ticket_price_row(
1594
-                $ticket_row,
1595
-                $price_row,
1596
-                $price,
1597
-                $default,
1598
-                $ticket,
1599
-                $show_trash,
1600
-                $show_create
1601
-            );
1602
-            $price_row++;
1603
-        }
1604
-        //filter $template_args
1605
-        $template_args = apply_filters(
1606
-            'FHEE__espresso_events_Pricing_Hooks___get_ticket_row__template_args',
1607
-            $template_args,
1608
-            $ticket_row,
1609
-            $ticket,
1610
-            $ticket_datetimes,
1611
-            $all_datetimes,
1612
-            $default,
1613
-            $all_tickets,
1614
-            $this->_is_creating_event
1615
-        );
1616
-        return EEH_Template::display_template(
1617
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_row.template.php',
1618
-            $template_args,
1619
-            true
1620
-        );
1621
-    }
1622
-
1623
-
1624
-
1625
-    /**
1626
-     * @param int            $ticket_row
1627
-     * @param EE_Ticket|null $ticket
1628
-     * @return string
1629
-     * @throws DomainException
1630
-     * @throws EE_Error
1631
-     */
1632
-    protected function _get_tax_rows($ticket_row, $ticket)
1633
-    {
1634
-        $tax_rows = '';
1635
-        /** @var EE_Price[] $taxes */
1636
-        $taxes = empty($ticket) ? EE_Taxes::get_taxes_for_admin() : $ticket->get_ticket_taxes_for_admin();
1637
-        foreach ($taxes as $tax) {
1638
-            $tax_added = $this->_get_tax_added($tax, $ticket);
1639
-            $template_args = array(
1640
-                'display_tax'       => ! empty($ticket) && $ticket->get('TKT_taxable')
1641
-                    ? ''
1642
-                    : ' style="display:none;"',
1643
-                'tax_id'            => $tax->ID(),
1644
-                'tkt_row'           => $ticket_row,
1645
-                'tax_label'         => $tax->get('PRC_name'),
1646
-                'tax_added'         => $tax_added,
1647
-                'tax_added_display' => EEH_Template::format_currency($tax_added, false, false),
1648
-                'tax_amount'        => $tax->get('PRC_amount'),
1649
-            );
1650
-            $template_args = apply_filters(
1651
-                'FHEE__espresso_events_Pricing_Hooks___get_tax_rows__template_args',
1652
-                $template_args,
1653
-                $ticket_row,
1654
-                $ticket,
1655
-                $this->_is_creating_event
1656
-            );
1657
-            $tax_rows .= EEH_Template::display_template(
1658
-                PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_tax_row.template.php',
1659
-                $template_args,
1660
-                true
1661
-            );
1662
-        }
1663
-        return $tax_rows;
1664
-    }
1665
-
1666
-
1667
-
1668
-    /**
1669
-     * @param EE_Price       $tax
1670
-     * @param EE_Ticket|null $ticket
1671
-     * @return float|int
1672
-     * @throws EE_Error
1673
-     */
1674
-    protected function _get_tax_added(EE_Price $tax, $ticket)
1675
-    {
1676
-        $subtotal = empty($ticket) ? 0 : $ticket->get_ticket_subtotal();
1677
-        return $subtotal * $tax->get('PRC_amount') / 100;
1678
-    }
1679
-
1680
-
1681
-
1682
-    /**
1683
-     * @param int            $ticket_row
1684
-     * @param int            $price_row
1685
-     * @param EE_Price|null  $price
1686
-     * @param bool           $default
1687
-     * @param EE_Ticket|null $ticket
1688
-     * @param bool           $show_trash
1689
-     * @param bool           $show_create
1690
-     * @return mixed
1691
-     * @throws DomainException
1692
-     * @throws EE_Error
1693
-     */
1694
-    protected function _get_ticket_price_row(
1695
-        $ticket_row,
1696
-        $price_row,
1697
-        $price,
1698
-        $default,
1699
-        $ticket,
1700
-        $show_trash = true,
1701
-        $show_create = true
1702
-    ) {
1703
-        $send_disabled = ! empty($ticket) && $ticket->get('TKT_deleted');
1704
-        $template_args = array(
1705
-            'tkt_row'               => $default && empty($ticket)
1706
-                ? 'TICKETNUM'
1707
-                : $ticket_row,
1708
-            'PRC_order'             => $default && empty($price)
1709
-                ? 'PRICENUM'
1710
-                : $price_row,
1711
-            'edit_prices_name'      => $default && empty($price)
1712
-                ? 'PRICENAMEATTR'
1713
-                : 'edit_prices',
1714
-            'price_type_selector'   => $default && empty($price)
1715
-                ? $this->_get_base_price_template($ticket_row, $price_row, $price, $default)
1716
-                : $this->_get_price_type_selector($ticket_row, $price_row, $price, $default, $send_disabled),
1717
-            'PRC_ID'                => $default && empty($price)
1718
-                ? 0
1719
-                : $price->ID(),
1720
-            'PRC_is_default'        => $default && empty($price)
1721
-                ? 0
1722
-                : $price->get('PRC_is_default'),
1723
-            'PRC_name'              => $default && empty($price)
1724
-                ? ''
1725
-                : $price->get('PRC_name'),
1726
-            'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1727
-            'show_plus_or_minus'    => $default && empty($price)
1728
-                ? ''
1729
-                : ' style="display:none;"',
1730
-            'show_plus'             => ($default && empty($price)) || ($price->is_discount() || $price->is_base_price())
1731
-                ? ' style="display:none;"'
1732
-                : '',
1733
-            'show_minus'            => ($default && empty($price)) || ! $price->is_discount()
1734
-                ? ' style="display:none;"'
1735
-                : '',
1736
-            'show_currency_symbol'  => ($default && empty($price)) || $price->is_percent()
1737
-                ? ' style="display:none"'
1738
-                : '',
1739
-            'PRC_amount'            => $default && empty($price)
1740
-                ? 0
1741
-                : $price->get_pretty('PRC_amount',
1742
-                    'localized_float'),
1743
-            'show_percentage'       => ($default && empty($price)) || ! $price->is_percent()
1744
-                ? ' style="display:none;"'
1745
-                : '',
1746
-            'show_trash_icon'       => $show_trash
1747
-                ? ''
1748
-                : ' style="display:none;"',
1749
-            'show_create_button'    => $show_create
1750
-                ? ''
1751
-                : ' style="display:none;"',
1752
-            'PRC_desc'              => $default && empty($price)
1753
-                ? ''
1754
-                : $price->get('PRC_desc'),
1755
-            'disabled'              => ! empty($ticket) && $ticket->get('TKT_deleted'),
1756
-        );
1757
-        $template_args = apply_filters(
1758
-            'FHEE__espresso_events_Pricing_Hooks___get_ticket_price_row__template_args',
1759
-            $template_args,
1760
-            $ticket_row,
1761
-            $price_row,
1762
-            $price,
1763
-            $default,
1764
-            $ticket,
1765
-            $show_trash,
1766
-            $show_create,
1767
-            $this->_is_creating_event
1768
-        );
1769
-        return EEH_Template::display_template(
1770
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_price_row.template.php',
1771
-            $template_args,
1772
-            true
1773
-        );
1774
-    }
1775
-
1776
-
1777
-
1778
-    /**
1779
-     * @param int      $ticket_row
1780
-     * @param int      $price_row
1781
-     * @param EE_Price $price
1782
-     * @param bool     $default
1783
-     * @param bool     $disabled
1784
-     * @return mixed
1785
-     * @throws DomainException
1786
-     * @throws EE_Error
1787
-     */
1788
-    protected function _get_price_type_selector($ticket_row, $price_row, $price, $default, $disabled = false)
1789
-    {
1790
-        if ($price->is_base_price()) {
1791
-            return $this->_get_base_price_template($ticket_row, $price_row, $price, $default);
1792
-        }
1793
-        return $this->_get_price_modifier_template($ticket_row, $price_row, $price, $default, $disabled);
1794
-    }
1795
-
1796
-
1797
-
1798
-    /**
1799
-     * @param int      $ticket_row
1800
-     * @param int      $price_row
1801
-     * @param EE_Price $price
1802
-     * @param bool     $default
1803
-     * @return mixed
1804
-     * @throws DomainException
1805
-     * @throws EE_Error
1806
-     */
1807
-    protected function _get_base_price_template($ticket_row, $price_row, $price, $default)
1808
-    {
1809
-        $template_args = array(
1810
-            'tkt_row'                   => $default ? 'TICKETNUM' : $ticket_row,
1811
-            'PRC_order'                 => $default && empty($price) ? 'PRICENUM' : $price_row,
1812
-            'PRT_ID'                    => $default && empty($price) ? 1 : $price->get('PRT_ID'),
1813
-            'PRT_name'                  => esc_html__('Price', 'event_espresso'),
1814
-            'price_selected_operator'   => '+',
1815
-            'price_selected_is_percent' => 0,
1816
-        );
1817
-        $template_args = apply_filters(
1818
-            'FHEE__espresso_events_Pricing_Hooks___get_base_price_template__template_args',
1819
-            $template_args,
1820
-            $ticket_row,
1821
-            $price_row,
1822
-            $price,
1823
-            $default,
1824
-            $this->_is_creating_event
1825
-        );
1826
-        return EEH_Template::display_template(
1827
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_type_base.template.php',
1828
-            $template_args,
1829
-            true
1830
-        );
1831
-    }
1832
-
1833
-
1834
-
1835
-    /**
1836
-     * @param int      $ticket_row
1837
-     * @param int      $price_row
1838
-     * @param EE_Price $price
1839
-     * @param bool     $default
1840
-     * @param bool     $disabled
1841
-     * @return mixed
1842
-     * @throws DomainException
1843
-     * @throws EE_Error
1844
-     */
1845
-    protected function _get_price_modifier_template(
1846
-        $ticket_row,
1847
-        $price_row,
1848
-        $price,
1849
-        $default,
1850
-        $disabled = false
1851
-    ) {
1852
-        $select_name = $default && ! $price instanceof EE_Price
1853
-            ? 'edit_prices[TICKETNUM][PRICENUM][PRT_ID]'
1854
-            : 'edit_prices[' . $ticket_row . '][' . $price_row . '][PRT_ID]';
1855
-        /** @var EEM_Price_Type $price_type_model */
1856
-        $price_type_model = EE_Registry::instance()->load_model('Price_Type');
1857
-        $price_types = $price_type_model->get_all(array(
1858
-            array(
1859
-                'OR' => array(
1860
-                    'PBT_ID'  => '2',
1861
-                    'PBT_ID*' => '3',
1862
-                ),
1863
-            ),
1864
-        ));
1865
-        $all_price_types = $default && ! $price instanceof EE_Price
1866
-            ? array(esc_html__('Select Modifier', 'event_espresso'))
1867
-            : array();
1868
-        $selected_price_type_id = $default && ! $price instanceof EE_Price ? 0 : $price->type();
1869
-        $price_option_spans = '';
1870
-        //setup price types for selector
1871
-        foreach ($price_types as $price_type) {
1872
-            if (! $price_type instanceof EE_Price_Type) {
1873
-                continue;
1874
-            }
1875
-            $all_price_types[$price_type->ID()] = $price_type->get('PRT_name');
1876
-            //while we're in the loop let's setup the option spans used by js
1877
-            $span_args = array(
1878
-                'PRT_ID'         => $price_type->ID(),
1879
-                'PRT_operator'   => $price_type->is_discount() ? '-' : '+',
1880
-                'PRT_is_percent' => $price_type->get('PRT_is_percent') ? 1 : 0,
1881
-            );
1882
-            $price_option_spans .= EEH_Template::display_template(
1883
-                PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_option_span.template.php',
1884
-                $span_args,
1885
-                true
1886
-            );
1887
-        }
1888
-        $select_name = $disabled ? 'archive_price[' . $ticket_row . '][' . $price_row . '][PRT_ID]' : $select_name;
1889
-        $select_input = new EE_Select_Input(
1890
-            $all_price_types,
1891
-            array(
1892
-                'default'               => $selected_price_type_id,
1893
-                'html_name'             => $select_name,
1894
-                'html_class'            => 'edit-price-PRT_ID',
1895
-                'html_other_attributes' => $disabled ? 'style="width:auto;" disabled' : 'style="width:auto;"',
1896
-            )
1897
-        );
1898
-        $price_selected_operator = $price instanceof EE_Price && $price->is_discount() ? '-' : '+';
1899
-        $price_selected_operator = $default && ! $price instanceof EE_Price ? '' : $price_selected_operator;
1900
-        $price_selected_is_percent = $price instanceof EE_Price && $price->is_percent() ? 1 : 0;
1901
-        $price_selected_is_percent = $default && ! $price instanceof EE_Price ? '' : $price_selected_is_percent;
1902
-        $template_args = array(
1903
-            'tkt_row'                   => $default ? 'TICKETNUM' : $ticket_row,
1904
-            'PRC_order'                 => $default && ! $price instanceof EE_Price ? 'PRICENUM' : $price_row,
1905
-            'price_modifier_selector'   => $select_input->get_html_for_input(),
1906
-            'main_name'                 => $select_name,
1907
-            'selected_price_type_id'    => $selected_price_type_id,
1908
-            'price_option_spans'        => $price_option_spans,
1909
-            'price_selected_operator'   => $price_selected_operator,
1910
-            'price_selected_is_percent' => $price_selected_is_percent,
1911
-            'disabled'                  => $disabled,
1912
-        );
1913
-        $template_args = apply_filters(
1914
-            'FHEE__espresso_events_Pricing_Hooks___get_price_modifier_template__template_args',
1915
-            $template_args,
1916
-            $ticket_row,
1917
-            $price_row,
1918
-            $price,
1919
-            $default,
1920
-            $disabled,
1921
-            $this->_is_creating_event
1922
-        );
1923
-        return EEH_Template::display_template(
1924
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_modifier_selector.template.php',
1925
-            $template_args,
1926
-            true
1927
-        );
1928
-    }
1929
-
1930
-
1931
-
1932
-    /**
1933
-     * @param int              $datetime_row
1934
-     * @param int              $ticket_row
1935
-     * @param EE_Datetime|null $datetime
1936
-     * @param EE_Ticket|null   $ticket
1937
-     * @param array            $ticket_datetimes
1938
-     * @param bool             $default
1939
-     * @return mixed
1940
-     * @throws DomainException
1941
-     * @throws EE_Error
1942
-     */
1943
-    protected function _get_ticket_datetime_list_item(
1944
-        $datetime_row,
1945
-        $ticket_row,
1946
-        $datetime,
1947
-        $ticket,
1948
-        $ticket_datetimes = array(),
1949
-        $default
1950
-    ) {
1951
-        $tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[$ticket->ID()])
1952
-            ? $ticket_datetimes[$ticket->ID()]
1953
-            : array();
1954
-        $template_args = array(
1955
-            'dtt_row'                  => $default && ! $datetime instanceof EE_Datetime
1956
-                ? 'DTTNUM'
1957
-                : $datetime_row,
1958
-            'tkt_row'                  => $default
1959
-                ? 'TICKETNUM'
1960
-                : $ticket_row,
1961
-            'ticket_datetime_selected' => in_array($datetime_row, $tkt_datetimes, true)
1962
-                ? ' ticket-selected'
1963
-                : '',
1964
-            'ticket_datetime_checked'  => in_array($datetime_row, $tkt_datetimes, true)
1965
-                ? ' checked="checked"'
1966
-                : '',
1967
-            'DTT_name'                 => $default && empty($datetime)
1968
-                ? 'DTTNAME'
1969
-                : $datetime->get_dtt_display_name(true),
1970
-            'tkt_status_class'         => '',
1971
-        );
1972
-        $template_args = apply_filters(
1973
-            'FHEE__espresso_events_Pricing_Hooks___get_ticket_datetime_list_item__template_args',
1974
-            $template_args,
1975
-            $datetime_row,
1976
-            $ticket_row,
1977
-            $datetime,
1978
-            $ticket,
1979
-            $ticket_datetimes,
1980
-            $default,
1981
-            $this->_is_creating_event
1982
-        );
1983
-        return EEH_Template::display_template(
1984
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_datetimes_list_item.template.php',
1985
-            $template_args,
1986
-            true
1987
-        );
1988
-    }
1989
-
1990
-
1991
-
1992
-    /**
1993
-     * @param array $all_datetimes
1994
-     * @param array $all_tickets
1995
-     * @return mixed
1996
-     * @throws DomainException
1997
-     * @throws EE_Error
1998
-     */
1999
-    protected function _get_ticket_js_structure($all_datetimes = array(), $all_tickets = array())
2000
-    {
2001
-        $template_args = array(
2002
-            'default_datetime_edit_row'                => $this->_get_dtt_edit_row(
2003
-                'DTTNUM',
2004
-                null,
2005
-                true,
2006
-                $all_datetimes
2007
-            ),
2008
-            'default_ticket_row'                       => $this->_get_ticket_row(
2009
-                'TICKETNUM',
2010
-                null,
2011
-                array(),
2012
-                array(),
2013
-                true
2014
-            ),
2015
-            'default_price_row'                        => $this->_get_ticket_price_row(
2016
-                'TICKETNUM',
2017
-                'PRICENUM',
2018
-                null,
2019
-                true,
2020
-                null
2021
-            ),
2022
-            'default_price_rows'                       => '',
2023
-            'default_base_price_amount'                => 0,
2024
-            'default_base_price_name'                  => '',
2025
-            'default_base_price_description'           => '',
2026
-            'default_price_modifier_selector_row'      => $this->_get_price_modifier_template(
2027
-                'TICKETNUM',
2028
-                'PRICENUM',
2029
-                null,
2030
-                true
2031
-            ),
2032
-            'default_available_tickets_for_datetime'   => $this->_get_dtt_attached_tickets_row(
2033
-                'DTTNUM',
2034
-                null,
2035
-                array(),
2036
-                array(),
2037
-                true
2038
-            ),
2039
-            'existing_available_datetime_tickets_list' => '',
2040
-            'existing_available_ticket_datetimes_list' => '',
2041
-            'new_available_datetime_ticket_list_item'  => $this->_get_datetime_tickets_list_item(
2042
-                'DTTNUM',
2043
-                'TICKETNUM',
2044
-                null,
2045
-                null,
2046
-                array(),
2047
-                true
2048
-            ),
2049
-            'new_available_ticket_datetime_list_item'  => $this->_get_ticket_datetime_list_item(
2050
-                'DTTNUM',
2051
-                'TICKETNUM',
2052
-                null,
2053
-                null,
2054
-                array(),
2055
-                true
2056
-            ),
2057
-        );
2058
-        $ticket_row = 1;
2059
-        foreach ($all_tickets as $ticket) {
2060
-            $template_args['existing_available_datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item(
2061
-                'DTTNUM',
2062
-                $ticket_row,
2063
-                null,
2064
-                $ticket,
2065
-                array(),
2066
-                true
2067
-            );
2068
-            $ticket_row++;
2069
-        }
2070
-        $datetime_row = 1;
2071
-        foreach ($all_datetimes as $datetime) {
2072
-            $template_args['existing_available_ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item(
2073
-                $datetime_row,
2074
-                'TICKETNUM',
2075
-                $datetime,
2076
-                null,
2077
-                array(),
2078
-                true
2079
-            );
2080
-            $datetime_row++;
2081
-        }
2082
-        /** @var EEM_Price $price_model */
2083
-        $price_model = EE_Registry::instance()->load_model('Price');
2084
-        $default_prices = $price_model->get_all_default_prices();
2085
-        $price_row = 1;
2086
-        foreach ($default_prices as $price) {
2087
-            if (! $price instanceof EE_Price) {
2088
-                continue;
2089
-            }
2090
-            if ($price->is_base_price()) {
2091
-                $template_args['default_base_price_amount'] = $price->get_pretty(
2092
-                    'PRC_amount',
2093
-                    'localized_float'
2094
-                );
2095
-                $template_args['default_base_price_name'] = $price->get('PRC_name');
2096
-                $template_args['default_base_price_description'] = $price->get('PRC_desc');
2097
-                $price_row++;
2098
-                continue;
2099
-            }
2100
-            $show_trash = !((count($default_prices) > 1 && $price_row === 1) || count($default_prices) === 1);
2101
-            $show_create = !(count($default_prices) > 1 && count($default_prices) !== $price_row);
2102
-            $template_args['default_price_rows'] .= $this->_get_ticket_price_row(
2103
-                'TICKETNUM',
2104
-                $price_row,
2105
-                $price,
2106
-                true,
2107
-                null,
2108
-                $show_trash,
2109
-                $show_create
2110
-            );
2111
-            $price_row++;
2112
-        }
2113
-        $template_args = apply_filters(
2114
-            'FHEE__espresso_events_Pricing_Hooks___get_ticket_js_structure__template_args',
2115
-            $template_args,
2116
-            $all_datetimes,
2117
-            $all_tickets,
2118
-            $this->_is_creating_event
2119
-        );
2120
-        return EEH_Template::display_template(
2121
-            PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_js_structure.template.php',
2122
-            $template_args,
2123
-            true
2124
-        );
2125
-    }
18
+	/**
19
+	 * This property is just used to hold the status of whether an event is currently being
20
+	 * created (true) or edited (false)
21
+	 *
22
+	 * @access protected
23
+	 * @var bool
24
+	 */
25
+	protected $_is_creating_event;
26
+
27
+
28
+	/**
29
+	 * Used to contain the format strings for date and time that will be used for php date and
30
+	 * time.
31
+	 * Is set in the _set_hooks_properties() method.
32
+	 *
33
+	 * @var array
34
+	 */
35
+	protected $_date_format_strings;
36
+
37
+
38
+	/**
39
+	 * @var string $_date_time_format
40
+	 */
41
+	protected $_date_time_format;
42
+
43
+
44
+
45
+	/**
46
+	 *
47
+	 */
48
+	protected function _set_hooks_properties()
49
+	{
50
+		$this->_name = 'pricing';
51
+		//capability check
52
+		if (! EE_Registry::instance()->CAP->current_user_can(
53
+			'ee_read_default_prices',
54
+			'advanced_ticket_datetime_metabox'
55
+		)) {
56
+			return;
57
+		}
58
+		$this->_setup_metaboxes();
59
+		$this->_set_date_time_formats();
60
+		$this->_validate_format_strings();
61
+		$this->_set_scripts_styles();
62
+		// commented out temporarily until logic is implemented in callback
63
+		// add_action(
64
+		//     'AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_Extend_Events_Admin_Page',
65
+		//     array($this, 'autosave_handling')
66
+		// );
67
+		add_filter(
68
+			'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
69
+			array($this, 'caf_updates')
70
+		);
71
+	}
72
+
73
+
74
+
75
+	/**
76
+	 * @return void
77
+	 */
78
+	protected function _setup_metaboxes()
79
+	{
80
+		//if we were going to add our own metaboxes we'd use the below.
81
+		$this->_metaboxes = array(
82
+			0 => array(
83
+				'page_route' => array('edit', 'create_new'),
84
+				'func'       => 'pricing_metabox',
85
+				'label'      => esc_html__('Event Tickets & Datetimes', 'event_espresso'),
86
+				'priority'   => 'high',
87
+				'context'    => 'normal',
88
+			),
89
+		);
90
+		$this->_remove_metaboxes = array(
91
+			0 => array(
92
+				'page_route' => array('edit', 'create_new'),
93
+				'id'         => 'espresso_event_editor_tickets',
94
+				'context'    => 'normal',
95
+			),
96
+		);
97
+	}
98
+
99
+
100
+
101
+	/**
102
+	 * @return void
103
+	 */
104
+	protected function _set_date_time_formats()
105
+	{
106
+		/**
107
+		 * Format strings for date and time.  Defaults are existing behaviour from 4.1.
108
+		 * Note, that if you return null as the value for 'date', and 'time' in the array, then
109
+		 * EE will automatically use the set wp_options, 'date_format', and 'time_format'.
110
+		 *
111
+		 * @since 4.6.7
112
+		 * @var array  Expected an array returned with 'date' and 'time' keys.
113
+		 */
114
+		$this->_date_format_strings = apply_filters(
115
+			'FHEE__espresso_events_Pricing_Hooks___set_hooks_properties__date_format_strings',
116
+			array(
117
+				'date' => 'Y-m-d',
118
+				'time' => 'h:i a',
119
+			)
120
+		);
121
+		//validate
122
+		$this->_date_format_strings['date'] = isset($this->_date_format_strings['date'])
123
+			? $this->_date_format_strings['date']
124
+			: null;
125
+		$this->_date_format_strings['time'] = isset($this->_date_format_strings['time'])
126
+			? $this->_date_format_strings['time']
127
+			: null;
128
+		$this->_date_time_format = $this->_date_format_strings['date'] . ' ' . $this->_date_format_strings['time'];
129
+	}
130
+
131
+
132
+
133
+	/**
134
+	 * @return void
135
+	 */
136
+	protected function _validate_format_strings()
137
+	{
138
+		//validate format strings
139
+		$format_validation = EEH_DTT_Helper::validate_format_string(
140
+			$this->_date_time_format
141
+		);
142
+		if (is_array($format_validation)) {
143
+			$msg = '<p>';
144
+			$msg .= sprintf(
145
+				esc_html__(
146
+					'The format "%s" was likely added via a filter and is invalid for the following reasons:',
147
+					'event_espresso'
148
+				),
149
+				$this->_date_time_format
150
+			);
151
+			$msg .= '</p><ul>';
152
+			foreach ($format_validation as $error) {
153
+				$msg .= '<li>' . $error . '</li>';
154
+			}
155
+			$msg .= '</ul><p>';
156
+			$msg .= sprintf(
157
+				esc_html__(
158
+					'%sPlease note that your date and time formats have been reset to "Y-m-d" and "h:i a" respectively.%s',
159
+					'event_espresso'
160
+				),
161
+				'<span style="color:#D54E21;">',
162
+				'</span>'
163
+			);
164
+			$msg .= '</p>';
165
+			EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
166
+			$this->_date_format_strings = array(
167
+				'date' => 'Y-m-d',
168
+				'time' => 'h:i a',
169
+			);
170
+		}
171
+	}
172
+
173
+
174
+
175
+	/**
176
+	 * @return void
177
+	 */
178
+	protected function _set_scripts_styles()
179
+	{
180
+		$this->_scripts_styles = array(
181
+			'registers'   => array(
182
+				'ee-tickets-datetimes-css' => array(
183
+					'url'  => PRICING_ASSETS_URL . 'event-tickets-datetimes.css',
184
+					'type' => 'css',
185
+				),
186
+				'ee-dtt-ticket-metabox'    => array(
187
+					'url'     => PRICING_ASSETS_URL . 'ee-datetime-ticket-metabox.js',
188
+					'depends' => array('ee-datepicker', 'ee-dialog', 'underscore'),
189
+				),
190
+			),
191
+			'deregisters' => array(
192
+				'event-editor-css'       => array('type' => 'css'),
193
+				'event-datetime-metabox' => array('type' => 'js'),
194
+			),
195
+			'enqueues'    => array(
196
+				'ee-tickets-datetimes-css' => array('edit', 'create_new'),
197
+				'ee-dtt-ticket-metabox'    => array('edit', 'create_new'),
198
+			),
199
+			'localize'    => array(
200
+				'ee-dtt-ticket-metabox' => array(
201
+					'DTT_TRASH_BLOCK'       => array(
202
+						'main_warning'            => esc_html__(
203
+							'The Datetime you are attempting to trash is the only datetime selected for the following ticket(s):',
204
+							'event_espresso'
205
+						),
206
+						'after_warning'           => esc_html__(
207
+							'In order to trash this datetime you must first make sure the above ticket(s) are assigned to other datetimes.',
208
+							'event_espresso'
209
+						),
210
+						'cancel_button'           => '<button class="button-secondary ee-modal-cancel">'
211
+													 . esc_html__('Cancel', 'event_espresso') . '</button>',
212
+						'close_button'            => '<button class="button-secondary ee-modal-cancel">'
213
+													 . esc_html__('Close', 'event_espresso') . '</button>',
214
+						'single_warning_from_tkt' => esc_html__(
215
+							'The Datetime you are attempting to unassign from this ticket is the only remaining datetime for this ticket. Tickets must always have at least one datetime assigned to them.',
216
+							'event_espresso'
217
+						),
218
+						'single_warning_from_dtt' => esc_html__(
219
+							'The ticket you are attempting to unassign from this datetime cannot be unassigned because the datetime is the only remaining datetime for the ticket.  Tickets must always have at least one datetime assigned to them.',
220
+							'event_espresso'
221
+						),
222
+						'dismiss_button'          => '<button class="button-secondary ee-modal-cancel">'
223
+													 . esc_html__('Dismiss', 'event_espresso') . '</button>',
224
+					),
225
+					'DTT_ERROR_MSG'         => array(
226
+						'no_ticket_name' => esc_html__('General Admission', 'event_espresso'),
227
+						'dismiss_button' => '<div class="save-cancel-button-container"><button class="button-secondary ee-modal-cancel">'
228
+											. esc_html__('Dismiss', 'event_espresso') . '</button></div>',
229
+					),
230
+					'DTT_OVERSELL_WARNING'  => array(
231
+						'datetime_ticket' => esc_html__(
232
+							'You cannot add this ticket to this datetime because it has a sold amount that is greater than the amount of spots remaining for this datetime.',
233
+							'event_espresso'
234
+						),
235
+						'ticket_datetime' => esc_html__(
236
+							'You cannot add this datetime to this ticket because the ticket has a sold amount that is greater than the amount of spots remaining on the datetime.',
237
+							'event_espresso'
238
+						),
239
+					),
240
+					'DTT_CONVERTED_FORMATS' => EEH_DTT_Helper::convert_php_to_js_and_moment_date_formats(
241
+						$this->_date_format_strings['date'],
242
+						$this->_date_format_strings['time']
243
+					),
244
+					'DTT_START_OF_WEEK'     => array('dayValue' => (int)get_option('start_of_week')),
245
+				),
246
+			),
247
+		);
248
+	}
249
+
250
+
251
+
252
+	/**
253
+	 * @param array $update_callbacks
254
+	 * @return array
255
+	 */
256
+	public function caf_updates(array $update_callbacks)
257
+	{
258
+		foreach ($update_callbacks as $key => $callback) {
259
+			if ($callback[1] === '_default_tickets_update') {
260
+				unset($update_callbacks[$key]);
261
+			}
262
+		}
263
+		$update_callbacks[] = array($this, 'datetime_and_tickets_caf_update');
264
+		return $update_callbacks;
265
+	}
266
+
267
+
268
+	/**
269
+	 * Handles saving everything related to Tickets (datetimes, tickets, prices)
270
+	 *
271
+	 * @param  EE_Event $event The Event object we're attaching data to
272
+	 * @param  array $data The request data from the form
273
+	 * @throws EE_Error
274
+	 * @throws InvalidArgumentException
275
+	 */
276
+	public function datetime_and_tickets_caf_update($event, $data)
277
+	{
278
+		//first we need to start with datetimes cause they are the "root" items attached to events.
279
+		$saved_datetimes = $this->_update_datetimes($event, $data);
280
+		//next tackle the tickets (and prices?)
281
+		$this->_update_tickets($event, $saved_datetimes, $data);
282
+	}
283
+
284
+
285
+	/**
286
+	 * update event_datetimes
287
+	 *
288
+	 * @param  EE_Event $event Event being updated
289
+	 * @param  array $data the request data from the form
290
+	 * @return EE_Datetime[]
291
+	 * @throws InvalidArgumentException
292
+	 * @throws EE_Error
293
+	 */
294
+	protected function _update_datetimes($event, $data)
295
+	{
296
+		$timezone = isset($data['timezone_string']) ? $data['timezone_string'] : null;
297
+		$saved_dtt_ids = array();
298
+		$saved_dtt_objs = array();
299
+		if (empty($data['edit_event_datetimes']) || !is_array($data['edit_event_datetimes'])) {
300
+			throw new InvalidArgumentException(
301
+				esc_html__(
302
+					'The "edit_event_datetimes" array is invalid therefore the event can not be updated.',
303
+					'event_espresso'
304
+				)
305
+			);
306
+		}
307
+		foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
308
+			//trim all values to ensure any excess whitespace is removed.
309
+			$datetime_data = array_map(
310
+				function ($datetime_data) {
311
+					return is_array($datetime_data) ? $datetime_data : trim($datetime_data);
312
+				},
313
+				$datetime_data
314
+			);
315
+			$datetime_data['DTT_EVT_end'] = isset($datetime_data['DTT_EVT_end'])
316
+											&& ! empty($datetime_data['DTT_EVT_end'])
317
+				? $datetime_data['DTT_EVT_end']
318
+				: $datetime_data['DTT_EVT_start'];
319
+			$datetime_values = array(
320
+				'DTT_ID'          => ! empty($datetime_data['DTT_ID'])
321
+					? $datetime_data['DTT_ID']
322
+					: null,
323
+				'DTT_name'        => ! empty($datetime_data['DTT_name'])
324
+					? $datetime_data['DTT_name']
325
+					: '',
326
+				'DTT_description' => ! empty($datetime_data['DTT_description'])
327
+					? $datetime_data['DTT_description']
328
+					: '',
329
+				'DTT_EVT_start'   => $datetime_data['DTT_EVT_start'],
330
+				'DTT_EVT_end'     => $datetime_data['DTT_EVT_end'],
331
+				'DTT_reg_limit'   => empty($datetime_data['DTT_reg_limit'])
332
+					? EE_INF
333
+					: $datetime_data['DTT_reg_limit'],
334
+				'DTT_order'       => ! isset($datetime_data['DTT_order'])
335
+					? $row
336
+					: $datetime_data['DTT_order'],
337
+			);
338
+			// if we have an id then let's get existing object first and then set the new values.
339
+			// Otherwise we instantiate a new object for save.
340
+			if (! empty($datetime_data['DTT_ID'])) {
341
+				$datetime = EE_Registry::instance()
342
+									   ->load_model('Datetime', array($timezone))
343
+									   ->get_one_by_ID($datetime_data['DTT_ID']);
344
+				//set date and time format according to what is set in this class.
345
+				$datetime->set_date_format($this->_date_format_strings['date']);
346
+				$datetime->set_time_format($this->_date_format_strings['time']);
347
+				foreach ($datetime_values as $field => $value) {
348
+					$datetime->set($field, $value);
349
+				}
350
+				// make sure the $dtt_id here is saved just in case
351
+				// after the add_relation_to() the autosave replaces it.
352
+				// We need to do this so we dont' TRASH the parent DTT.
353
+				// (save the ID for both key and value to avoid duplications)
354
+				$saved_dtt_ids[$datetime->ID()] = $datetime->ID();
355
+			} else {
356
+				$datetime = EE_Registry::instance()->load_class(
357
+					'Datetime',
358
+					array(
359
+						$datetime_values,
360
+						$timezone,
361
+						array($this->_date_format_strings['date'], $this->_date_format_strings['time']),
362
+					),
363
+					false,
364
+					false
365
+				);
366
+				foreach ($datetime_values as $field => $value) {
367
+					$datetime->set($field, $value);
368
+				}
369
+			}
370
+			$datetime->save();
371
+			$datetime = $event->_add_relation_to($datetime, 'Datetime');
372
+			// before going any further make sure our dates are setup correctly
373
+			// so that the end date is always equal or greater than the start date.
374
+			if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
375
+				$datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
376
+				$datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
377
+				$datetime->save();
378
+			}
379
+			//	now we have to make sure we add the new DTT_ID to the $saved_dtt_ids array
380
+			// because it is possible there was a new one created for the autosave.
381
+			// (save the ID for both key and value to avoid duplications)
382
+			$DTT_ID = $datetime->ID();
383
+			$saved_dtt_ids[$DTT_ID] = $DTT_ID;
384
+			$saved_dtt_objs[$row] = $datetime;
385
+			//todo if ANY of these updates fail then we want the appropriate global error message.
386
+		}
387
+		$event->save();
388
+		// now we need to REMOVE any datetimes that got deleted.
389
+		// Keep in mind that this process will only kick in for datetimes that don't have any DTT_sold on them.
390
+		// So its safe to permanently delete at this point.
391
+		$old_datetimes = explode(',', $data['datetime_IDs']);
392
+		$old_datetimes = $old_datetimes[0] === '' ? array() : $old_datetimes;
393
+		if (is_array($old_datetimes)) {
394
+			$datetimes_to_delete = array_diff($old_datetimes, $saved_dtt_ids);
395
+			foreach ($datetimes_to_delete as $id) {
396
+				$id = absint($id);
397
+				if (empty($id)) {
398
+					continue;
399
+				}
400
+				$dtt_to_remove = EE_Registry::instance()->load_model('Datetime')->get_one_by_ID($id);
401
+				//remove tkt relationships.
402
+				$related_tickets = $dtt_to_remove->get_many_related('Ticket');
403
+				foreach ($related_tickets as $tkt) {
404
+					$dtt_to_remove->_remove_relation_to($tkt, 'Ticket');
405
+				}
406
+				$event->_remove_relation_to($id, 'Datetime');
407
+				$dtt_to_remove->refresh_cache_of_related_objects();
408
+			}
409
+		}
410
+		return $saved_dtt_objs;
411
+	}
412
+
413
+
414
+	/**
415
+	 * update tickets
416
+	 *
417
+	 * @param  EE_Event $event Event object being updated
418
+	 * @param  EE_Datetime[] $saved_datetimes an array of datetime ids being updated
419
+	 * @param  array $data incoming request data
420
+	 * @return EE_Ticket[]
421
+	 * @throws InvalidArgumentException
422
+	 * @throws EE_Error
423
+	 */
424
+	protected function _update_tickets($event, $saved_datetimes, $data)
425
+	{
426
+		$new_tkt = null;
427
+		$new_default = null;
428
+		//stripslashes because WP filtered the $_POST ($data) array to add slashes
429
+		$data = stripslashes_deep($data);
430
+		$timezone = isset($data['timezone_string']) ? $data['timezone_string'] : null;
431
+		$saved_tickets = $datetimes_on_existing = array();
432
+		$old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array();
433
+		if(empty($data['edit_tickets']) || ! is_array($data['edit_tickets'])){
434
+			throw new InvalidArgumentException(
435
+				esc_html__(
436
+					'The "edit_tickets" array is invalid therefore the event can not be updated.',
437
+					'event_espresso'
438
+				)
439
+			);
440
+		}
441
+		foreach ($data['edit_tickets'] as $row => $tkt) {
442
+			$update_prices = $create_new_TKT = false;
443
+			// figure out what datetimes were added to the ticket
444
+			// and what datetimes were removed from the ticket in the session.
445
+			$starting_tkt_dtt_rows = explode(',', $data['starting_ticket_datetime_rows'][$row]);
446
+			$tkt_dtt_rows = explode(',', $data['ticket_datetime_rows'][$row]);
447
+			$datetimes_added = array_diff($tkt_dtt_rows, $starting_tkt_dtt_rows);
448
+			$datetimes_removed = array_diff($starting_tkt_dtt_rows, $tkt_dtt_rows);
449
+			// trim inputs to ensure any excess whitespace is removed.
450
+			$tkt = array_map(
451
+				function ($ticket_data) {
452
+					return is_array($ticket_data) ? $ticket_data : trim($ticket_data);
453
+				},
454
+				$tkt
455
+			);
456
+			// note we are doing conversions to floats here instead of allowing EE_Money_Field to handle
457
+			// because we're doing calculations prior to using the models.
458
+			// note incoming ['TKT_price'] value is already in standard notation (via js).
459
+			$ticket_price = isset($tkt['TKT_price'])
460
+				? round((float)$tkt['TKT_price'], 3)
461
+				: 0;
462
+			//note incoming base price needs converted from localized value.
463
+			$base_price = isset($tkt['TKT_base_price'])
464
+				? EEH_Money::convert_to_float_from_localized_money($tkt['TKT_base_price'])
465
+				: 0;
466
+			//if ticket price == 0 and $base_price != 0 then ticket price == base_price
467
+			$ticket_price = $ticket_price === 0 && $base_price !== 0
468
+				? $base_price
469
+				: $ticket_price;
470
+			$base_price_id = isset($tkt['TKT_base_price_ID'])
471
+				? $tkt['TKT_base_price_ID']
472
+				: 0;
473
+			$price_rows = is_array($data['edit_prices']) && isset($data['edit_prices'][$row])
474
+				? $data['edit_prices'][$row]
475
+				: array();
476
+			$now = null;
477
+			if (empty($tkt['TKT_start_date'])) {
478
+				//lets' use now in the set timezone.
479
+				$now = new DateTime('now', new DateTimeZone($event->get_timezone()));
480
+				$tkt['TKT_start_date'] = $now->format($this->_date_time_format);
481
+			}
482
+			if (empty($tkt['TKT_end_date'])) {
483
+				/**
484
+				 * set the TKT_end_date to the first datetime attached to the ticket.
485
+				 */
486
+				$first_dtt = $saved_datetimes[reset($tkt_dtt_rows)];
487
+				$tkt['TKT_end_date'] = $first_dtt->start_date_and_time($this->_date_time_format);
488
+			}
489
+			$TKT_values = array(
490
+				'TKT_ID'          => ! empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : null,
491
+				'TTM_ID'          => ! empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0,
492
+				'TKT_name'        => ! empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '',
493
+				'TKT_description' => ! empty($tkt['TKT_description'])
494
+									 && $tkt['TKT_description'] !== esc_html__(
495
+					'You can modify this description',
496
+					'event_espresso'
497
+				)
498
+					? $tkt['TKT_description']
499
+					: '',
500
+				'TKT_start_date'  => $tkt['TKT_start_date'],
501
+				'TKT_end_date'    => $tkt['TKT_end_date'],
502
+				'TKT_qty'         => ! isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === ''
503
+					? EE_INF
504
+					: $tkt['TKT_qty'],
505
+				'TKT_uses'        => ! isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === ''
506
+					? EE_INF
507
+					: $tkt['TKT_uses'],
508
+				'TKT_min'         => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'],
509
+				'TKT_max'         => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'],
510
+				'TKT_row'         => $row,
511
+				'TKT_order'       => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : 0,
512
+				'TKT_taxable'     => ! empty($tkt['TKT_taxable']) ? 1 : 0,
513
+				'TKT_required'    => ! empty($tkt['TKT_required']) ? 1 : 0,
514
+				'TKT_price'       => $ticket_price,
515
+			);
516
+			// if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly,
517
+			// which means in turn that the prices will become new prices as well.
518
+			if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
519
+				$TKT_values['TKT_ID'] = 0;
520
+				$TKT_values['TKT_is_default'] = 0;
521
+				$update_prices = true;
522
+			}
523
+			// if we have a TKT_ID then we need to get that existing TKT_obj and update it
524
+			// we actually do our saves ahead of doing any add_relations to
525
+			// because its entirely possible that this ticket wasn't removed or added to any datetime in the session
526
+			// but DID have it's items modified.
527
+			// keep in mind that if the TKT has been sold (and we have changed pricing information),
528
+			// then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
529
+			if (absint($TKT_values['TKT_ID'])) {
530
+				$ticket = EE_Registry::instance()
531
+									 ->load_model('Ticket', array($timezone))
532
+									 ->get_one_by_ID($tkt['TKT_ID']);
533
+				if ($ticket instanceof EE_Ticket) {
534
+					$ticket = $this->_update_ticket_datetimes(
535
+						$ticket,
536
+						$saved_datetimes,
537
+						$datetimes_added,
538
+						$datetimes_removed
539
+					);
540
+					// are there any registrations using this ticket ?
541
+					$tickets_sold = $ticket->count_related(
542
+						'Registration',
543
+						array(
544
+							array(
545
+								'STS_ID' => array('NOT IN', array(EEM_Registration::status_id_incomplete)),
546
+							),
547
+						)
548
+					);
549
+					//set ticket formats
550
+					$ticket->set_date_format($this->_date_format_strings['date']);
551
+					$ticket->set_time_format($this->_date_format_strings['time']);
552
+					// let's just check the total price for the existing ticket
553
+					// and determine if it matches the new total price.
554
+					// if they are different then we create a new ticket (if tickets sold)
555
+					// if they aren't different then we go ahead and modify existing ticket.
556
+					$create_new_TKT = $tickets_sold > 0 && $ticket_price !== $ticket->price() && ! $ticket->deleted();
557
+					//set new values
558
+					foreach ($TKT_values as $field => $value) {
559
+						if ($field === 'TKT_qty') {
560
+							$ticket->set_qty($value);
561
+						} else {
562
+							$ticket->set($field, $value);
563
+						}
564
+					}
565
+					// if $create_new_TKT is false then we can safely update the existing ticket.
566
+					// Otherwise we have to create a new ticket.
567
+					if ($create_new_TKT) {
568
+						$new_tkt = $this->_duplicate_ticket($ticket, $price_rows, $ticket_price, $base_price,
569
+							$base_price_id);
570
+					}
571
+				}
572
+			} else {
573
+				// no TKT_id so a new TKT
574
+				$ticket = EE_Ticket::new_instance(
575
+					$TKT_values,
576
+					$timezone,
577
+					array($this->_date_format_strings['date'], $this->_date_format_strings['time'])
578
+				);
579
+				if ($ticket instanceof EE_Ticket) {
580
+					// make sure ticket has an ID of setting relations won't work
581
+					$ticket->save();
582
+					$ticket = $this->_update_ticket_datetimes(
583
+						$ticket,
584
+						$saved_datetimes,
585
+						$datetimes_added,
586
+						$datetimes_removed
587
+					);
588
+					$update_prices = true;
589
+				}
590
+			}
591
+			//make sure any current values have been saved.
592
+			//$ticket->save();
593
+			// before going any further make sure our dates are setup correctly
594
+			// so that the end date is always equal or greater than the start date.
595
+			if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
596
+				$ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
597
+				$ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
598
+			}
599
+			//let's make sure the base price is handled
600
+			$ticket = ! $create_new_TKT ? $this->_add_prices_to_ticket(array(), $ticket, $update_prices, $base_price,
601
+				$base_price_id) : $ticket;
602
+			//add/update price_modifiers
603
+			$ticket = ! $create_new_TKT ? $this->_add_prices_to_ticket($price_rows, $ticket, $update_prices) : $ticket;
604
+			//need to make sue that the TKT_price is accurate after saving the prices.
605
+			$ticket->ensure_TKT_Price_correct();
606
+			//handle CREATING a default tkt from the incoming tkt but ONLY if this isn't an autosave.
607
+			if (! defined('DOING_AUTOSAVE') && ! empty($tkt['TKT_is_default_selector'])) {
608
+				$update_prices = true;
609
+				$new_default = clone $ticket;
610
+				$new_default->set('TKT_ID', 0);
611
+				$new_default->set('TKT_is_default', 1);
612
+				$new_default->set('TKT_row', 1);
613
+				$new_default->set('TKT_price', $ticket_price);
614
+				// remove any dtt relations cause we DON'T want dtt relations attached
615
+				// (note this is just removing the cached relations in the object)
616
+				$new_default->_remove_relations('Datetime');
617
+				//todo we need to add the current attached prices as new prices to the new default ticket.
618
+				$new_default = $this->_add_prices_to_ticket($price_rows, $new_default, $update_prices);
619
+				//don't forget the base price!
620
+				$new_default = $this->_add_prices_to_ticket(
621
+					array(),
622
+					$new_default,
623
+					$update_prices,
624
+					$base_price,
625
+					$base_price_id
626
+				);
627
+				$new_default->save();
628
+				do_action(
629
+					'AHEE__espresso_events_Pricing_Hooks___update_tkts_new_default_ticket',
630
+					$new_default,
631
+					$row,
632
+					$ticket,
633
+					$data
634
+				);
635
+			}
636
+			// DO ALL dtt relationships for both current tickets and any archived tickets
637
+			// for the given dtt that are related to the current ticket.
638
+			// TODO... not sure exactly how we're going to do this considering we don't know
639
+			// what current ticket the archived tickets are related to
640
+			// (and TKT_parent is used for autosaves so that's not a field we can reliably use).
641
+			//let's assign any tickets that have been setup to the saved_tickets tracker
642
+			//save existing TKT
643
+			$ticket->save();
644
+			if ($create_new_TKT && $new_tkt instanceof EE_Ticket) {
645
+				//save new TKT
646
+				$new_tkt->save();
647
+				//add new ticket to array
648
+				$saved_tickets[$new_tkt->ID()] = $new_tkt;
649
+				do_action(
650
+					'AHEE__espresso_events_Pricing_Hooks___update_tkts_new_ticket',
651
+					$new_tkt,
652
+					$row,
653
+					$tkt,
654
+					$data
655
+				);
656
+			} else {
657
+				//add tkt to saved tkts
658
+				$saved_tickets[$ticket->ID()] = $ticket;
659
+				do_action(
660
+					'AHEE__espresso_events_Pricing_Hooks___update_tkts_update_ticket',
661
+					$ticket,
662
+					$row,
663
+					$tkt,
664
+					$data
665
+				);
666
+			}
667
+		}
668
+		// now we need to handle tickets actually "deleted permanently".
669
+		// There are cases where we'd want this to happen
670
+		// (i.e. autosaves are happening and then in between autosaves the user trashes a ticket).
671
+		// Or a draft event was saved and in the process of editing a ticket is trashed.
672
+		// No sense in keeping all the related data in the db!
673
+		$old_tickets = isset($old_tickets[0]) && $old_tickets[0] === '' ? array() : $old_tickets;
674
+		$tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
675
+		foreach ($tickets_removed as $id) {
676
+			$id = absint($id);
677
+			//get the ticket for this id
678
+			$tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
679
+			//if this tkt is a default tkt we leave it alone cause it won't be attached to the datetime
680
+			if ($tkt_to_remove->get('TKT_is_default')) {
681
+				continue;
682
+			}
683
+			// if this tkt has any registrations attached so then we just ARCHIVE
684
+			// because we don't actually permanently delete these tickets.
685
+			if ($tkt_to_remove->count_related('Registration') > 0) {
686
+				$tkt_to_remove->delete();
687
+				continue;
688
+			}
689
+			// need to get all the related datetimes on this ticket and remove from every single one of them
690
+			// (remember this process can ONLY kick off if there are NO tkts_sold)
691
+			$datetimes = $tkt_to_remove->get_many_related('Datetime');
692
+			foreach ($datetimes as $datetime) {
693
+				$tkt_to_remove->_remove_relation_to($datetime, 'Datetime');
694
+			}
695
+			// need to do the same for prices (except these prices can also be deleted because again,
696
+			// tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
697
+			$tkt_to_remove->delete_related_permanently('Price');
698
+			do_action('AHEE__espresso_events_Pricing_Hooks___update_tkts_delete_ticket', $tkt_to_remove);
699
+			// finally let's delete this ticket
700
+			// (which should not be blocked at this point b/c we've removed all our relationships)
701
+			$tkt_to_remove->delete_permanently();
702
+		}
703
+		return $saved_tickets;
704
+	}
705
+
706
+
707
+
708
+	/**
709
+	 * @access  protected
710
+	 * @param \EE_Ticket     $ticket
711
+	 * @param \EE_Datetime[] $saved_datetimes
712
+	 * @param \EE_Datetime[] $added_datetimes
713
+	 * @param \EE_Datetime[] $removed_datetimes
714
+	 * @return \EE_Ticket
715
+	 * @throws \EE_Error
716
+	 */
717
+	protected function _update_ticket_datetimes(
718
+		EE_Ticket $ticket,
719
+		$saved_datetimes = array(),
720
+		$added_datetimes = array(),
721
+		$removed_datetimes = array()
722
+	) {
723
+		// to start we have to add the ticket to all the datetimes its supposed to be with,
724
+		// and removing the ticket from datetimes it got removed from.
725
+		// first let's add datetimes
726
+		if (! empty($added_datetimes) && is_array($added_datetimes)) {
727
+			foreach ($added_datetimes as $row_id) {
728
+				$row_id = (int)$row_id;
729
+				if (isset($saved_datetimes[$row_id]) && $saved_datetimes[$row_id] instanceof EE_Datetime) {
730
+					$ticket->_add_relation_to($saved_datetimes[$row_id], 'Datetime');
731
+					// Is this an existing ticket (has an ID) and does it have any sold?
732
+					// If so, then we need to add that to the DTT sold because this DTT is getting added.
733
+					if ($ticket->ID() && $ticket->sold() > 0) {
734
+						$saved_datetimes[$row_id]->increase_sold($ticket->sold());
735
+						$saved_datetimes[$row_id]->save();
736
+					}
737
+				}
738
+			}
739
+		}
740
+		// then remove datetimes
741
+		if (! empty($removed_datetimes) && is_array($removed_datetimes)) {
742
+			foreach ($removed_datetimes as $row_id) {
743
+				$row_id = (int)$row_id;
744
+				// its entirely possible that a datetime got deleted (instead of just removed from relationship.
745
+				// So make sure we skip over this if the dtt isn't in the $saved_datetimes array)
746
+				if (isset($saved_datetimes[$row_id]) && $saved_datetimes[$row_id] instanceof EE_Datetime) {
747
+					$ticket->_remove_relation_to($saved_datetimes[$row_id], 'Datetime');
748
+					// Is this an existing ticket (has an ID) and does it have any sold?
749
+					// If so, then we need to remove it's sold from the DTT_sold.
750
+					if ($ticket->ID() && $ticket->sold() > 0) {
751
+						$saved_datetimes[$row_id]->decrease_sold($ticket->sold());
752
+						$saved_datetimes[$row_id]->save();
753
+					}
754
+				}
755
+			}
756
+		}
757
+		// cap ticket qty by datetime reg limits
758
+		$ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
759
+		return $ticket;
760
+	}
761
+
762
+
763
+
764
+	/**
765
+	 * @access  protected
766
+	 * @param \EE_Ticket $ticket
767
+	 * @param array      $price_rows
768
+	 * @param int        $ticket_price
769
+	 * @param int        $base_price
770
+	 * @param int        $base_price_id
771
+	 * @return \EE_Ticket
772
+	 * @throws \EE_Error
773
+	 */
774
+	protected function _duplicate_ticket(
775
+		EE_Ticket $ticket,
776
+		$price_rows = array(),
777
+		$ticket_price = 0,
778
+		$base_price = 0,
779
+		$base_price_id = 0
780
+	) {
781
+		// create new ticket that's a copy of the existing
782
+		// except a new id of course (and not archived)
783
+		// AND has the new TKT_price associated with it.
784
+		$new_ticket = clone $ticket;
785
+		$new_ticket->set('TKT_ID', 0);
786
+		$new_ticket->set_deleted(0);
787
+		$new_ticket->set_price($ticket_price);
788
+		$new_ticket->set_sold(0);
789
+		// let's get a new ID for this ticket
790
+		$new_ticket->save();
791
+		// we also need to make sure this new ticket gets the same datetime attachments as the archived ticket
792
+		$datetimes_on_existing = $ticket->datetimes();
793
+		$new_ticket = $this->_update_ticket_datetimes(
794
+			$new_ticket,
795
+			$datetimes_on_existing,
796
+			array_keys($datetimes_on_existing)
797
+		);
798
+		// $ticket will get archived later b/c we are NOT adding it to the saved_tickets array.
799
+		// if existing $ticket has sold amount, then we need to adjust the qty for the new TKT to = the remaining
800
+		// available.
801
+		if ($ticket->sold() > 0) {
802
+			$new_qty = $ticket->qty() - $ticket->sold();
803
+			$new_ticket->set_qty($new_qty);
804
+		}
805
+		//now we update the prices just for this ticket
806
+		$new_ticket = $this->_add_prices_to_ticket($price_rows, $new_ticket, true);
807
+		//and we update the base price
808
+		$new_ticket = $this->_add_prices_to_ticket(array(), $new_ticket, true, $base_price, $base_price_id);
809
+		return $new_ticket;
810
+	}
811
+
812
+
813
+
814
+	/**
815
+	 * This attaches a list of given prices to a ticket.
816
+	 * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
817
+	 * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
818
+	 * price info and prices are automatically "archived" via the ticket.
819
+	 *
820
+	 * @access  private
821
+	 * @param array     $prices        Array of prices from the form.
822
+	 * @param EE_Ticket $ticket        EE_Ticket object that prices are being attached to.
823
+	 * @param bool      $new_prices    Whether attach existing incoming prices or create new ones.
824
+	 * @param int|bool  $base_price    if FALSE then NOT doing a base price add.
825
+	 * @param int|bool  $base_price_id if present then this is the base_price_id being updated.
826
+	 * @return EE_Ticket
827
+	 * @throws EE_Error
828
+	 */
829
+	protected function _add_prices_to_ticket(
830
+		$prices = array(),
831
+		EE_Ticket $ticket,
832
+		$new_prices = false,
833
+		$base_price = false,
834
+		$base_price_id = false
835
+	) {
836
+		// let's just get any current prices that may exist on the given ticket
837
+		// so we can remove any prices that got trashed in this session.
838
+		$current_prices_on_ticket = $base_price !== false
839
+			? $ticket->base_price(true)
840
+			: $ticket->price_modifiers();
841
+		$updated_prices = array();
842
+		// if $base_price ! FALSE then updating a base price.
843
+		if ($base_price !== false) {
844
+			$prices[1] = array(
845
+				'PRC_ID'     => $new_prices || $base_price_id === 1 ? null : $base_price_id,
846
+				'PRT_ID'     => 1,
847
+				'PRC_amount' => $base_price,
848
+				'PRC_name'   => $ticket->get('TKT_name'),
849
+				'PRC_desc'   => $ticket->get('TKT_description'),
850
+			);
851
+		}
852
+		//possibly need to save tkt
853
+		if (! $ticket->ID()) {
854
+			$ticket->save();
855
+		}
856
+		foreach ($prices as $row => $prc) {
857
+			$prt_id = ! empty($prc['PRT_ID']) ? $prc['PRT_ID'] : null;
858
+			if (empty($prt_id)) {
859
+				continue;
860
+			} //prices MUST have a price type id.
861
+			$PRC_values = array(
862
+				'PRC_ID'         => ! empty($prc['PRC_ID']) ? $prc['PRC_ID'] : null,
863
+				'PRT_ID'         => $prt_id,
864
+				'PRC_amount'     => ! empty($prc['PRC_amount']) ? $prc['PRC_amount'] : 0,
865
+				'PRC_name'       => ! empty($prc['PRC_name']) ? $prc['PRC_name'] : '',
866
+				'PRC_desc'       => ! empty($prc['PRC_desc']) ? $prc['PRC_desc'] : '',
867
+				'PRC_is_default' => false,
868
+				//make sure we set PRC_is_default to false for all ticket saves from event_editor
869
+				'PRC_order'      => $row,
870
+			);
871
+			if ($new_prices || empty($PRC_values['PRC_ID'])) {
872
+				$PRC_values['PRC_ID'] = 0;
873
+				$price = EE_Registry::instance()->load_class(
874
+					'Price',
875
+					array($PRC_values),
876
+					false,
877
+					false
878
+				);
879
+			} else {
880
+				$price = EE_Registry::instance()->load_model('Price')->get_one_by_ID($prc['PRC_ID']);
881
+				//update this price with new values
882
+				foreach ($PRC_values as $field => $value) {
883
+					$price->set($field, $value);
884
+				}
885
+			}
886
+			$price->save();
887
+			$updated_prices[$price->ID()] = $price;
888
+			$ticket->_add_relation_to($price, 'Price');
889
+		}
890
+		//now let's remove any prices that got removed from the ticket
891
+		if (! empty ($current_prices_on_ticket)) {
892
+			$current = array_keys($current_prices_on_ticket);
893
+			$updated = array_keys($updated_prices);
894
+			$prices_to_remove = array_diff($current, $updated);
895
+			if (! empty($prices_to_remove)) {
896
+				foreach ($prices_to_remove as $prc_id) {
897
+					$p = $current_prices_on_ticket[$prc_id];
898
+					$ticket->_remove_relation_to($p, 'Price');
899
+					//delete permanently the price
900
+					$p->delete_permanently();
901
+				}
902
+			}
903
+		}
904
+		return $ticket;
905
+	}
906
+
907
+
908
+
909
+	/**
910
+	 * @param Events_Admin_Page $event_admin_obj
911
+	 * @return Events_Admin_Page
912
+	 */
913
+	public function autosave_handling( Events_Admin_Page $event_admin_obj)
914
+	{
915
+		return $event_admin_obj;
916
+		//doing nothing for the moment.
917
+		// todo when I get to this remember that I need to set the template args on the $event_admin_obj
918
+		// (use the set_template_args() method)
919
+		/**
920
+		 * need to remember to handle TICKET DEFAULT saves correctly:  I've got two input fields in the dom:
921
+		 * 1. TKT_is_default_selector (visible)
922
+		 * 2. TKT_is_default (hidden)
923
+		 * I think we'll use the TKT_is_default for recording whether the ticket displayed IS a default ticket
924
+		 * (on new event creations). Whereas the TKT_is_default_selector is for the user to indicate they want
925
+		 * this ticket to be saved as a default.
926
+		 * The tricky part is, on an initial display on create or edit (or after manually updating),
927
+		 * the TKT_is_default_selector will always be unselected and the TKT_is_default will only be true
928
+		 * if this is a create.  However, after an autosave, users will want some sort of indicator that
929
+		 * the TKT HAS been saved as a default..
930
+		 * in other words we don't want to remove the check on TKT_is_default_selector. So here's what I'm thinking.
931
+		 * On Autosave:
932
+		 * 1. If TKT_is_default is true: we create a new TKT, send back the new id and add id to related elements,
933
+		 * then set the TKT_is_default to false.
934
+		 * 2. If TKT_is_default_selector is true: we create/edit existing ticket (following conditions above as well).
935
+		 *  We do NOT create a new default ticket.  The checkbox stays selected after autosave.
936
+		 * 3. only on MANUAL update do we check for the selection and if selected create the new default ticket.
937
+		 */
938
+	}
939
+
940
+
941
+
942
+	/**
943
+	 * @throws DomainException
944
+	 * @throws EE_Error
945
+	 */
946
+	public function pricing_metabox()
947
+	{
948
+		$existing_datetime_ids = $existing_ticket_ids = $datetime_tickets = $ticket_datetimes = array();
949
+		$event = $this->_adminpage_obj->get_cpt_model_obj();
950
+		//set is_creating_event property.
951
+		$EVT_ID = $event->ID();
952
+		$this->_is_creating_event = absint($EVT_ID) === 0;
953
+		//default main template args
954
+		$main_template_args = array(
955
+			'event_datetime_help_link' => EEH_Template::get_help_tab_link(
956
+				'event_editor_event_datetimes_help_tab',
957
+				$this->_adminpage_obj->page_slug,
958
+				$this->_adminpage_obj->get_req_action(),
959
+				false,
960
+				false
961
+			),
962
+			// todo need to add a filter to the template for the help text
963
+			// in the Events_Admin_Page core file so we can add further help
964
+			'existing_datetime_ids'    => '',
965
+			'total_dtt_rows'           => 1,
966
+			'add_new_dtt_help_link'    => EEH_Template::get_help_tab_link(
967
+				'add_new_dtt_info',
968
+				$this->_adminpage_obj->page_slug,
969
+				$this->_adminpage_obj->get_req_action(),
970
+				false,
971
+				false
972
+			),
973
+			//todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
974
+			'datetime_rows'            => '',
975
+			'show_tickets_container'   => '',
976
+			//$this->_adminpage_obj->get_cpt_model_obj()->ID() > 1 ? ' style="display:none;"' : '',
977
+			'ticket_rows'              => '',
978
+			'existing_ticket_ids'      => '',
979
+			'total_ticket_rows'        => 1,
980
+			'ticket_js_structure'      => '',
981
+			'ee_collapsible_status'    => ' ee-collapsible-open'
982
+			//$this->_adminpage_obj->get_cpt_model_obj()->ID() > 0 ? ' ee-collapsible-closed' : ' ee-collapsible-open'
983
+		);
984
+		$timezone = $event instanceof EE_Event ? $event->timezone_string() : null;
985
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
986
+		/**
987
+		 * 1. Start with retrieving Datetimes
988
+		 * 2. For each datetime get related tickets
989
+		 * 3. For each ticket get related prices
990
+		 */
991
+		/** @var EEM_Datetime $datetime_model */
992
+		$datetime_model = EE_Registry::instance()->load_model('Datetime', array($timezone));
993
+		$datetimes = $datetime_model->get_all_event_dates($EVT_ID);
994
+		$main_template_args['total_dtt_rows'] = count($datetimes);
995
+		/**
996
+		 * @see https://events.codebasehq.com/projects/event-espresso/tickets/9486
997
+		 * for why we are counting $datetime_row and then setting that on the Datetime object
998
+		 */
999
+		$datetime_row = 1;
1000
+		foreach ($datetimes as $datetime) {
1001
+			$DTT_ID = $datetime->get('DTT_ID');
1002
+			$datetime->set('DTT_order', $datetime_row);
1003
+			$existing_datetime_ids[] = $DTT_ID;
1004
+			//tickets attached
1005
+			$related_tickets = $datetime->ID() > 0
1006
+				? $datetime->get_many_related(
1007
+					'Ticket',
1008
+					array(
1009
+						array(
1010
+							'OR' => array('TKT_deleted' => 1, 'TKT_deleted*' => 0),
1011
+						),
1012
+						'default_where_conditions' => 'none',
1013
+						'order_by'                 => array('TKT_order' => 'ASC'),
1014
+					)
1015
+				)
1016
+				: array();
1017
+			//if there are no related tickets this is likely a new event OR autodraft
1018
+			// event so we need to generate the default tickets because datetimes
1019
+			// ALWAYS have at least one related ticket!!.  EXCEPT, we dont' do this if there is already more than one
1020
+			// datetime on the event.
1021
+			if (empty ($related_tickets) && count($datetimes) < 2) {
1022
+				/** @var EEM_Ticket $ticket_model */
1023
+				$ticket_model = EE_Registry::instance()->load_model('Ticket');
1024
+				$related_tickets = $ticket_model->get_all_default_tickets();
1025
+				// this should be ordered by TKT_ID, so let's grab the first default ticket
1026
+				// (which will be the main default) and ensure it has any default prices added to it (but do NOT save).
1027
+				$default_prices = EEM_Price::instance()->get_all_default_prices();
1028
+				$main_default_ticket = reset($related_tickets);
1029
+				if ($main_default_ticket instanceof EE_Ticket) {
1030
+					foreach ($default_prices as $default_price) {
1031
+						if ($default_price instanceof EE_Price && $default_price->is_base_price()) {
1032
+							continue;
1033
+						}
1034
+						$main_default_ticket->cache('Price', $default_price);
1035
+					}
1036
+				}
1037
+			}
1038
+			// we can't actually setup rows in this loop yet cause we don't know all
1039
+			// the unique tickets for this event yet (tickets are linked through all datetimes).
1040
+			// So we're going to temporarily cache some of that information.
1041
+			//loop through and setup the ticket rows and make sure the order is set.
1042
+			foreach ($related_tickets as $ticket) {
1043
+				$TKT_ID = $ticket->get('TKT_ID');
1044
+				$ticket_row = $ticket->get('TKT_row');
1045
+				//we only want unique tickets in our final display!!
1046
+				if (! in_array($TKT_ID, $existing_ticket_ids, true)) {
1047
+					$existing_ticket_ids[] = $TKT_ID;
1048
+					$all_tickets[] = $ticket;
1049
+				}
1050
+				//temporary cache of this ticket info for this datetime for later processing of datetime rows.
1051
+				$datetime_tickets[$DTT_ID][] = $ticket_row;
1052
+				//temporary cache of this datetime info for this ticket for later processing of ticket rows.
1053
+				if (
1054
+					! isset($ticket_datetimes[$TKT_ID])
1055
+					|| ! in_array($datetime_row, $ticket_datetimes[$TKT_ID], true)
1056
+				) {
1057
+					$ticket_datetimes[$TKT_ID][] = $datetime_row;
1058
+				}
1059
+			}
1060
+			$datetime_row++;
1061
+		}
1062
+		$main_template_args['total_ticket_rows'] = count($existing_ticket_ids);
1063
+		$main_template_args['existing_ticket_ids'] = implode(',', $existing_ticket_ids);
1064
+		$main_template_args['existing_datetime_ids'] = implode(',', $existing_datetime_ids);
1065
+		//sort $all_tickets by order
1066
+		usort(
1067
+			$all_tickets,
1068
+			function (EE_Ticket $a, EE_Ticket $b) {
1069
+				$a_order = (int)$a->get('TKT_order');
1070
+				$b_order = (int)$b->get('TKT_order');
1071
+				if ($a_order === $b_order) {
1072
+					return 0;
1073
+				}
1074
+				return ($a_order < $b_order) ? -1 : 1;
1075
+			}
1076
+		);
1077
+		// k NOW we have all the data we need for setting up the dtt rows
1078
+		// and ticket rows so we start our dtt loop again.
1079
+		$datetime_row = 1;
1080
+		foreach ($datetimes as $datetime) {
1081
+			$main_template_args['datetime_rows'] .= $this->_get_datetime_row(
1082
+				$datetime_row,
1083
+				$datetime,
1084
+				$datetime_tickets,
1085
+				$all_tickets,
1086
+				false,
1087
+				$datetimes
1088
+			);
1089
+			$datetime_row++;
1090
+		}
1091
+		//then loop through all tickets for the ticket rows.
1092
+		$ticket_row = 1;
1093
+		foreach ($all_tickets as $ticket) {
1094
+			$main_template_args['ticket_rows'] .= $this->_get_ticket_row(
1095
+				$ticket_row,
1096
+				$ticket,
1097
+				$ticket_datetimes,
1098
+				$datetimes,
1099
+				false,
1100
+				$all_tickets
1101
+			);
1102
+			$ticket_row++;
1103
+		}
1104
+		$main_template_args['ticket_js_structure'] = $this->_get_ticket_js_structure($datetimes, $all_tickets);
1105
+		EEH_Template::display_template(
1106
+			PRICING_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php',
1107
+			$main_template_args
1108
+		);
1109
+	}
1110
+
1111
+
1112
+
1113
+	/**
1114
+	 * @param int         $datetime_row
1115
+	 * @param EE_Datetime $datetime
1116
+	 * @param array       $datetime_tickets
1117
+	 * @param array       $all_tickets
1118
+	 * @param bool        $default
1119
+	 * @param array       $all_datetimes
1120
+	 * @return mixed
1121
+	 * @throws DomainException
1122
+	 * @throws EE_Error
1123
+	 */
1124
+	protected function _get_datetime_row(
1125
+		$datetime_row,
1126
+		EE_Datetime $datetime,
1127
+		$datetime_tickets = array(),
1128
+		$all_tickets = array(),
1129
+		$default = false,
1130
+		$all_datetimes = array()
1131
+	) {
1132
+		$dtt_display_template_args = array(
1133
+			'dtt_edit_row'             => $this->_get_dtt_edit_row($datetime_row, $datetime, $default, $all_datetimes),
1134
+			'dtt_attached_tickets_row' => $this->_get_dtt_attached_tickets_row(
1135
+				$datetime_row,
1136
+				$datetime,
1137
+				$datetime_tickets,
1138
+				$all_tickets,
1139
+				$default
1140
+			),
1141
+			'dtt_row'                  => $default ? 'DTTNUM' : $datetime_row,
1142
+		);
1143
+		return EEH_Template::display_template(
1144
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_row_wrapper.template.php',
1145
+			$dtt_display_template_args,
1146
+			true
1147
+		);
1148
+	}
1149
+
1150
+
1151
+
1152
+	/**
1153
+	 * This method is used to generate a dtt fields  edit row.
1154
+	 * The same row is used to generate a row with valid DTT objects
1155
+	 * and the default row that is used as the skeleton by the js.
1156
+	 *
1157
+	 * @param int           $datetime_row  The row number for the row being generated.
1158
+	 * @param EE_Datetime   $datetime
1159
+	 * @param bool          $default       Whether a default row is being generated or not.
1160
+	 * @param EE_Datetime[] $all_datetimes This is the array of all datetimes used in the editor.
1161
+	 * @return string
1162
+	 * @throws DomainException
1163
+	 * @throws EE_Error
1164
+	 */
1165
+	protected function _get_dtt_edit_row($datetime_row, $datetime, $default, $all_datetimes)
1166
+	{
1167
+		// if the incoming $datetime object is NOT an instance of EE_Datetime then force default to true.
1168
+		$default = ! $datetime instanceof EE_Datetime ? true : $default;
1169
+		$template_args = array(
1170
+			'dtt_row'              => $default ? 'DTTNUM' : $datetime_row,
1171
+			'event_datetimes_name' => $default ? 'DTTNAMEATTR' : 'edit_event_datetimes',
1172
+			'edit_dtt_expanded'    => '',
1173
+			'DTT_ID'               => $default ? '' : $datetime->ID(),
1174
+			'DTT_name'             => $default ? '' : $datetime->name(),
1175
+			'DTT_description'      => $default ? '' : $datetime->description(),
1176
+			'DTT_EVT_start'        => $default ? '' : $datetime->start_date($this->_date_time_format),
1177
+			'DTT_EVT_end'          => $default ? '' : $datetime->end_date($this->_date_time_format),
1178
+			'DTT_reg_limit'        => $default
1179
+				? ''
1180
+				: $datetime->get_pretty(
1181
+					'DTT_reg_limit',
1182
+					'input'
1183
+				),
1184
+			'DTT_order'            => $default ? 'DTTNUM' : $datetime_row,
1185
+			'dtt_sold'             => $default ? '0' : $datetime->get('DTT_sold'),
1186
+			'dtt_reserved'         => $default ? '0' : $datetime->reserved(),
1187
+			'clone_icon'           => ! empty($datetime) && $datetime->get('DTT_sold') > 0
1188
+				? ''
1189
+				: 'clone-icon ee-icon ee-icon-clone clickable',
1190
+			'trash_icon'           => ! empty($datetime) && $datetime->get('DTT_sold') > 0
1191
+				? 'ee-lock-icon'
1192
+				: 'trash-icon dashicons dashicons-post-trash clickable',
1193
+			'reg_list_url'         => $default || ! $datetime->event() instanceof \EE_Event
1194
+				? ''
1195
+				: EE_Admin_Page::add_query_args_and_nonce(
1196
+					array('event_id' => $datetime->event()->ID(), 'datetime_id' => $datetime->ID()),
1197
+					REG_ADMIN_URL
1198
+				),
1199
+		);
1200
+		$template_args['show_trash'] = count($all_datetimes) === 1 && $template_args['trash_icon'] !== 'ee-lock-icon'
1201
+			? ' style="display:none"'
1202
+			: '';
1203
+		//allow filtering of template args at this point.
1204
+		$template_args = apply_filters(
1205
+			'FHEE__espresso_events_Pricing_Hooks___get_dtt_edit_row__template_args',
1206
+			$template_args,
1207
+			$datetime_row,
1208
+			$datetime,
1209
+			$default,
1210
+			$all_datetimes,
1211
+			$this->_is_creating_event
1212
+		);
1213
+		return EEH_Template::display_template(
1214
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_edit_row.template.php',
1215
+			$template_args,
1216
+			true
1217
+		);
1218
+	}
1219
+
1220
+
1221
+
1222
+	/**
1223
+	 * @param int         $datetime_row
1224
+	 * @param EE_Datetime $datetime
1225
+	 * @param array       $datetime_tickets
1226
+	 * @param array       $all_tickets
1227
+	 * @param bool        $default
1228
+	 * @return mixed
1229
+	 * @throws DomainException
1230
+	 * @throws EE_Error
1231
+	 */
1232
+	protected function _get_dtt_attached_tickets_row(
1233
+		$datetime_row,
1234
+		$datetime,
1235
+		$datetime_tickets = array(),
1236
+		$all_tickets = array(),
1237
+		$default
1238
+	) {
1239
+		$template_args = array(
1240
+			'dtt_row'                           => $default ? 'DTTNUM' : $datetime_row,
1241
+			'event_datetimes_name'              => $default ? 'DTTNAMEATTR' : 'edit_event_datetimes',
1242
+			'DTT_description'                   => $default ? '' : $datetime->description(),
1243
+			'datetime_tickets_list'             => $default ? '<li class="hidden"></li>' : '',
1244
+			'show_tickets_row'                  => ' style="display:none;"',
1245
+			'add_new_datetime_ticket_help_link' => EEH_Template::get_help_tab_link(
1246
+				'add_new_ticket_via_datetime',
1247
+				$this->_adminpage_obj->page_slug,
1248
+				$this->_adminpage_obj->get_req_action(),
1249
+				false,
1250
+				false
1251
+			),
1252
+			//todo need to add this help info id to the Events_Admin_Page core file so we can access it here.
1253
+			'DTT_ID'                            => $default ? '' : $datetime->ID(),
1254
+		);
1255
+		//need to setup the list items (but only if this isn't a default skeleton setup)
1256
+		if (! $default) {
1257
+			$ticket_row = 1;
1258
+			foreach ($all_tickets as $ticket) {
1259
+				$template_args['datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item(
1260
+					$datetime_row,
1261
+					$ticket_row,
1262
+					$datetime,
1263
+					$ticket,
1264
+					$datetime_tickets,
1265
+					$default
1266
+				);
1267
+				$ticket_row++;
1268
+			}
1269
+		}
1270
+		//filter template args at this point
1271
+		$template_args = apply_filters(
1272
+			'FHEE__espresso_events_Pricing_Hooks___get_dtt_attached_ticket_row__template_args',
1273
+			$template_args,
1274
+			$datetime_row,
1275
+			$datetime,
1276
+			$datetime_tickets,
1277
+			$all_tickets,
1278
+			$default,
1279
+			$this->_is_creating_event
1280
+		);
1281
+		return EEH_Template::display_template(
1282
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_attached_tickets_row.template.php',
1283
+			$template_args,
1284
+			true
1285
+		);
1286
+	}
1287
+
1288
+
1289
+
1290
+	/**
1291
+	 * @param int         $datetime_row
1292
+	 * @param int         $ticket_row
1293
+	 * @param EE_Datetime $datetime
1294
+	 * @param EE_Ticket   $ticket
1295
+	 * @param array       $datetime_tickets
1296
+	 * @param bool        $default
1297
+	 * @return mixed
1298
+	 * @throws DomainException
1299
+	 * @throws EE_Error
1300
+	 */
1301
+	protected function _get_datetime_tickets_list_item(
1302
+		$datetime_row,
1303
+		$ticket_row,
1304
+		$datetime,
1305
+		$ticket,
1306
+		$datetime_tickets = array(),
1307
+		$default
1308
+	) {
1309
+		$dtt_tkts = $datetime instanceof EE_Datetime && isset($datetime_tickets[$datetime->ID()])
1310
+			? $datetime_tickets[$datetime->ID()]
1311
+			: array();
1312
+		$display_row = $ticket instanceof EE_Ticket ? $ticket->get('TKT_row') : 0;
1313
+		$no_ticket = $default && empty($ticket);
1314
+		$template_args = array(
1315
+			'dtt_row'                 => $default
1316
+				? 'DTTNUM'
1317
+				: $datetime_row,
1318
+			'tkt_row'                 => $no_ticket
1319
+				? 'TICKETNUM'
1320
+				: $ticket_row,
1321
+			'datetime_ticket_checked' => in_array($display_row, $dtt_tkts, true)
1322
+				? ' checked="checked"'
1323
+				: '',
1324
+			'ticket_selected'         => in_array($display_row, $dtt_tkts, true)
1325
+				? ' ticket-selected'
1326
+				: '',
1327
+			'TKT_name'                => $no_ticket
1328
+				? 'TKTNAME'
1329
+				: $ticket->get('TKT_name'),
1330
+			'tkt_status_class'        => $no_ticket || $this->_is_creating_event
1331
+				? ' tkt-status-' . EE_Ticket::onsale
1332
+				: ' tkt-status-' . $ticket->ticket_status(),
1333
+		);
1334
+		//filter template args
1335
+		$template_args = apply_filters(
1336
+			'FHEE__espresso_events_Pricing_Hooks___get_datetime_tickets_list_item__template_args',
1337
+			$template_args,
1338
+			$datetime_row,
1339
+			$ticket_row,
1340
+			$datetime,
1341
+			$ticket,
1342
+			$datetime_tickets,
1343
+			$default,
1344
+			$this->_is_creating_event
1345
+		);
1346
+		return EEH_Template::display_template(
1347
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_dtt_tickets_list.template.php',
1348
+			$template_args,
1349
+			true
1350
+		);
1351
+	}
1352
+
1353
+
1354
+
1355
+	/**
1356
+	 * This generates the ticket row for tickets.
1357
+	 * This same method is used to generate both the actual rows and the js skeleton row
1358
+	 * (when default === true)
1359
+	 *
1360
+	 * @param int           $ticket_row       Represents the row number being generated.
1361
+	 * @param               $ticket
1362
+	 * @param EE_Datetime[] $ticket_datetimes Either an array of all datetimes on all tickets indexed by each ticket
1363
+	 *                                        or empty for default
1364
+	 * @param EE_Datetime[] $all_datetimes    All Datetimes on the event or empty for default.
1365
+	 * @param bool          $default          Whether default row being generated or not.
1366
+	 * @param EE_Ticket[]   $all_tickets      This is an array of all tickets attached to the event
1367
+	 *                                        (or empty in the case of defaults)
1368
+	 * @return mixed
1369
+	 * @throws DomainException
1370
+	 * @throws EE_Error
1371
+	 */
1372
+	protected function _get_ticket_row(
1373
+		$ticket_row,
1374
+		$ticket,
1375
+		$ticket_datetimes,
1376
+		$all_datetimes,
1377
+		$default = false,
1378
+		$all_tickets = array()
1379
+	) {
1380
+		// if $ticket is not an instance of EE_Ticket then force default to true.
1381
+		$default = ! $ticket instanceof EE_Ticket ? true : $default;
1382
+		$prices = ! empty($ticket) && ! $default ? $ticket->get_many_related('Price',
1383
+			array('default_where_conditions' => 'none', 'order_by' => array('PRC_order' => 'ASC'))) : array();
1384
+		// if there is only one price (which would be the base price)
1385
+		// or NO prices and this ticket is a default ticket,
1386
+		// let's just make sure there are no cached default prices on the object.
1387
+		// This is done by not including any query_params.
1388
+		if ($ticket instanceof EE_Ticket && $ticket->is_default() && (count($prices) === 1 || empty($prices))) {
1389
+			$prices = $ticket->prices();
1390
+		}
1391
+		// check if we're dealing with a default ticket in which case
1392
+		// we don't want any starting_ticket_datetime_row values set
1393
+		// (otherwise there won't be any new relationships created for tickets based off of the default ticket).
1394
+		// This will future proof in case there is ever any behaviour change between what the primary_key defaults to.
1395
+		$default_dtt = $default || ($ticket instanceof EE_Ticket && $ticket->is_default());
1396
+		$tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[$ticket->ID()])
1397
+			? $ticket_datetimes[$ticket->ID()]
1398
+			: array();
1399
+		$ticket_subtotal = $default ? 0 : $ticket->get_ticket_subtotal();
1400
+		$base_price = $default ? null : $ticket->base_price();
1401
+		$count_price_mods = EEM_Price::instance()->get_all_default_prices(true);
1402
+		//breaking out complicated condition for ticket_status
1403
+		if ($default) {
1404
+			$ticket_status_class = ' tkt-status-' . EE_Ticket::onsale;
1405
+		} else {
1406
+			$ticket_status_class = $ticket->is_default()
1407
+				? ' tkt-status-' . EE_Ticket::onsale
1408
+				: ' tkt-status-' . $ticket->ticket_status();
1409
+		}
1410
+		//breaking out complicated condition for TKT_taxable
1411
+		if ($default) {
1412
+			$TKT_taxable = '';
1413
+		} else {
1414
+			$TKT_taxable = $ticket->taxable()
1415
+				? ' checked="checked"'
1416
+				: '';
1417
+		}
1418
+		if ($default) {
1419
+			$TKT_status = EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence');
1420
+		} elseif ($ticket->is_default()) {
1421
+			$TKT_status = EEH_Template::pretty_status(EE_Ticket::onsale, false, 'sentence');
1422
+		} else {
1423
+			$TKT_status = $ticket->ticket_status(true);
1424
+		}
1425
+		if ($default) {
1426
+			$TKT_min = '';
1427
+		} else {
1428
+			$TKT_min = $ticket->min();
1429
+			if ($TKT_min === -1 || $TKT_min === 0) {
1430
+				$TKT_min = '';
1431
+			}
1432
+		}
1433
+		$template_args = array(
1434
+			'tkt_row'                       => $default ? 'TICKETNUM' : $ticket_row,
1435
+			'TKT_order'                     => $default ? 'TICKETNUM' : $ticket_row,
1436
+			//on initial page load this will always be the correct order.
1437
+			'tkt_status_class'              => $ticket_status_class,
1438
+			'display_edit_tkt_row'          => ' style="display:none;"',
1439
+			'edit_tkt_expanded'             => '',
1440
+			'edit_tickets_name'             => $default ? 'TICKETNAMEATTR' : 'edit_tickets',
1441
+			'TKT_name'                      => $default ? '' : $ticket->name(),
1442
+			'TKT_start_date'                => $default
1443
+				? ''
1444
+				: $ticket->get_date('TKT_start_date', $this->_date_time_format),
1445
+			'TKT_end_date'                  => $default
1446
+				? ''
1447
+				: $ticket->get_date('TKT_end_date', $this->_date_time_format),
1448
+			'TKT_status'                    => $TKT_status,
1449
+			'TKT_price'                     => $default
1450
+				? ''
1451
+				: EEH_Template::format_currency(
1452
+					$ticket->get_ticket_total_with_taxes(),
1453
+					false,
1454
+					false
1455
+				),
1456
+			'TKT_price_code'                => EE_Registry::instance()->CFG->currency->code,
1457
+			'TKT_price_amount'              => $default ? 0 : $ticket_subtotal,
1458
+			'TKT_qty'                       => $default
1459
+				? ''
1460
+				: $ticket->get_pretty('TKT_qty', 'symbol'),
1461
+			'TKT_qty_for_input'             => $default
1462
+				? ''
1463
+				: $ticket->get_pretty('TKT_qty', 'input'),
1464
+			'TKT_uses'                      => $default
1465
+				? ''
1466
+				: $ticket->get_pretty('TKT_uses', 'input'),
1467
+			'TKT_min'                       => $TKT_min,
1468
+			'TKT_max'                       => $default
1469
+				? ''
1470
+				: $ticket->get_pretty('TKT_max', 'input'),
1471
+			'TKT_sold'                      => $default ? 0 : $ticket->tickets_sold('ticket'),
1472
+			'TKT_reserved'                  => $default ? 0 : $ticket->reserved(),
1473
+			'TKT_registrations'             => $default
1474
+				? 0
1475
+				: $ticket->count_registrations(
1476
+					array(
1477
+						array(
1478
+							'STS_ID' => array(
1479
+								'!=',
1480
+								EEM_Registration::status_id_incomplete,
1481
+							),
1482
+						),
1483
+					)
1484
+				),
1485
+			'TKT_ID'                        => $default ? 0 : $ticket->ID(),
1486
+			'TKT_description'               => $default ? '' : $ticket->get_pretty('TKT_description', 'form_input'),
1487
+			'TKT_is_default'                => $default ? 0 : $ticket->is_default(),
1488
+			'TKT_required'                  => $default ? 0 : $ticket->required(),
1489
+			'TKT_is_default_selector'       => '',
1490
+			'ticket_price_rows'             => '',
1491
+			'TKT_base_price'                => $default || ! $base_price instanceof EE_Price
1492
+				? ''
1493
+				: $base_price->get_pretty('PRC_amount', 'localized_float'),
1494
+			'TKT_base_price_ID'             => $default || ! $base_price instanceof EE_Price ? 0 : $base_price->ID(),
1495
+			'show_price_modifier'           => count($prices) > 1 || ($default && $count_price_mods > 0)
1496
+				? ''
1497
+				: ' style="display:none;"',
1498
+			'show_price_mod_button'         => count($prices) > 1
1499
+											   || ($default && $count_price_mods > 0)
1500
+											   || (! $default && $ticket->deleted())
1501
+				? ' style="display:none;"'
1502
+				: '',
1503
+			'total_price_rows'              => count($prices) > 1 ? count($prices) : 1,
1504
+			'ticket_datetimes_list'         => $default ? '<li class="hidden"></li>' : '',
1505
+			'starting_ticket_datetime_rows' => $default || $default_dtt ? '' : implode(',', $tkt_datetimes),
1506
+			'ticket_datetime_rows'          => $default ? '' : implode(',', $tkt_datetimes),
1507
+			'existing_ticket_price_ids'     => $default ? '' : implode(',', array_keys($prices)),
1508
+			'ticket_template_id'            => $default ? 0 : $ticket->get('TTM_ID'),
1509
+			'TKT_taxable'                   => $TKT_taxable,
1510
+			'display_subtotal'              => $ticket instanceof EE_Ticket && $ticket->taxable()
1511
+				? ''
1512
+				: ' style="display:none"',
1513
+			'price_currency_symbol'         => EE_Registry::instance()->CFG->currency->sign,
1514
+			'TKT_subtotal_amount_display'   => EEH_Template::format_currency(
1515
+				$ticket_subtotal,
1516
+				false,
1517
+				false
1518
+			),
1519
+			'TKT_subtotal_amount'           => $ticket_subtotal,
1520
+			'tax_rows'                      => $this->_get_tax_rows($ticket_row, $ticket),
1521
+			'disabled'                      => $ticket instanceof EE_Ticket && $ticket->deleted(),
1522
+			'ticket_archive_class'          => $ticket instanceof EE_Ticket && $ticket->deleted()
1523
+				? ' ticket-archived'
1524
+				: '',
1525
+			'trash_icon'                    => $ticket instanceof EE_Ticket
1526
+											   && $ticket->deleted()
1527
+											   && ! $ticket->is_permanently_deleteable()
1528
+				? 'ee-lock-icon '
1529
+				: 'trash-icon dashicons dashicons-post-trash clickable',
1530
+			'clone_icon'                    => $ticket instanceof EE_Ticket && $ticket->deleted()
1531
+				? ''
1532
+				: 'clone-icon ee-icon ee-icon-clone clickable',
1533
+		);
1534
+		$template_args['trash_hidden'] = count($all_tickets) === 1 && $template_args['trash_icon'] !== 'ee-lock-icon'
1535
+			? ' style="display:none"'
1536
+			: '';
1537
+		//handle rows that should NOT be empty
1538
+		if (empty($template_args['TKT_start_date'])) {
1539
+			//if empty then the start date will be now.
1540
+			$template_args['TKT_start_date'] = date($this->_date_time_format,
1541
+				current_time('timestamp'));
1542
+			$template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1543
+		}
1544
+		if (empty($template_args['TKT_end_date'])) {
1545
+			//get the earliest datetime (if present);
1546
+			$earliest_dtt = $this->_adminpage_obj->get_cpt_model_obj()->ID() > 0
1547
+				? $this->_adminpage_obj->get_cpt_model_obj()->get_first_related(
1548
+					'Datetime',
1549
+					array('order_by' => array('DTT_EVT_start' => 'ASC'))
1550
+				)
1551
+				: null;
1552
+			if (! empty($earliest_dtt)) {
1553
+				$template_args['TKT_end_date'] = $earliest_dtt->get_datetime(
1554
+					'DTT_EVT_start',
1555
+					$this->_date_time_format
1556
+				);
1557
+			} else {
1558
+				//default so let's just use what's been set for the default date-time which is 30 days from now.
1559
+				$template_args['TKT_end_date'] = date(
1560
+					$this->_date_time_format,
1561
+					mktime(24, 0, 0, date('m'), date('d') + 29, date('Y')
1562
+					)
1563
+				);
1564
+			}
1565
+			$template_args['tkt_status_class'] = ' tkt-status-' . EE_Ticket::onsale;
1566
+		}
1567
+		//generate ticket_datetime items
1568
+		if (! $default) {
1569
+			$datetime_row = 1;
1570
+			foreach ($all_datetimes as $datetime) {
1571
+				$template_args['ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item(
1572
+					$datetime_row,
1573
+					$ticket_row,
1574
+					$datetime,
1575
+					$ticket,
1576
+					$ticket_datetimes,
1577
+					$default
1578
+				);
1579
+				$datetime_row++;
1580
+			}
1581
+		}
1582
+		$price_row = 1;
1583
+		foreach ($prices as $price) {
1584
+			if (! $price instanceof EE_Price)  {
1585
+				continue;
1586
+			}
1587
+			if ($price->is_base_price()) {
1588
+				$price_row++;
1589
+				continue;
1590
+			}
1591
+			$show_trash = !((count($prices) > 1 && $price_row === 1) || count($prices) === 1);
1592
+			$show_create = !(count($prices) > 1 && count($prices) !== $price_row);
1593
+			$template_args['ticket_price_rows'] .= $this->_get_ticket_price_row(
1594
+				$ticket_row,
1595
+				$price_row,
1596
+				$price,
1597
+				$default,
1598
+				$ticket,
1599
+				$show_trash,
1600
+				$show_create
1601
+			);
1602
+			$price_row++;
1603
+		}
1604
+		//filter $template_args
1605
+		$template_args = apply_filters(
1606
+			'FHEE__espresso_events_Pricing_Hooks___get_ticket_row__template_args',
1607
+			$template_args,
1608
+			$ticket_row,
1609
+			$ticket,
1610
+			$ticket_datetimes,
1611
+			$all_datetimes,
1612
+			$default,
1613
+			$all_tickets,
1614
+			$this->_is_creating_event
1615
+		);
1616
+		return EEH_Template::display_template(
1617
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_row.template.php',
1618
+			$template_args,
1619
+			true
1620
+		);
1621
+	}
1622
+
1623
+
1624
+
1625
+	/**
1626
+	 * @param int            $ticket_row
1627
+	 * @param EE_Ticket|null $ticket
1628
+	 * @return string
1629
+	 * @throws DomainException
1630
+	 * @throws EE_Error
1631
+	 */
1632
+	protected function _get_tax_rows($ticket_row, $ticket)
1633
+	{
1634
+		$tax_rows = '';
1635
+		/** @var EE_Price[] $taxes */
1636
+		$taxes = empty($ticket) ? EE_Taxes::get_taxes_for_admin() : $ticket->get_ticket_taxes_for_admin();
1637
+		foreach ($taxes as $tax) {
1638
+			$tax_added = $this->_get_tax_added($tax, $ticket);
1639
+			$template_args = array(
1640
+				'display_tax'       => ! empty($ticket) && $ticket->get('TKT_taxable')
1641
+					? ''
1642
+					: ' style="display:none;"',
1643
+				'tax_id'            => $tax->ID(),
1644
+				'tkt_row'           => $ticket_row,
1645
+				'tax_label'         => $tax->get('PRC_name'),
1646
+				'tax_added'         => $tax_added,
1647
+				'tax_added_display' => EEH_Template::format_currency($tax_added, false, false),
1648
+				'tax_amount'        => $tax->get('PRC_amount'),
1649
+			);
1650
+			$template_args = apply_filters(
1651
+				'FHEE__espresso_events_Pricing_Hooks___get_tax_rows__template_args',
1652
+				$template_args,
1653
+				$ticket_row,
1654
+				$ticket,
1655
+				$this->_is_creating_event
1656
+			);
1657
+			$tax_rows .= EEH_Template::display_template(
1658
+				PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_tax_row.template.php',
1659
+				$template_args,
1660
+				true
1661
+			);
1662
+		}
1663
+		return $tax_rows;
1664
+	}
1665
+
1666
+
1667
+
1668
+	/**
1669
+	 * @param EE_Price       $tax
1670
+	 * @param EE_Ticket|null $ticket
1671
+	 * @return float|int
1672
+	 * @throws EE_Error
1673
+	 */
1674
+	protected function _get_tax_added(EE_Price $tax, $ticket)
1675
+	{
1676
+		$subtotal = empty($ticket) ? 0 : $ticket->get_ticket_subtotal();
1677
+		return $subtotal * $tax->get('PRC_amount') / 100;
1678
+	}
1679
+
1680
+
1681
+
1682
+	/**
1683
+	 * @param int            $ticket_row
1684
+	 * @param int            $price_row
1685
+	 * @param EE_Price|null  $price
1686
+	 * @param bool           $default
1687
+	 * @param EE_Ticket|null $ticket
1688
+	 * @param bool           $show_trash
1689
+	 * @param bool           $show_create
1690
+	 * @return mixed
1691
+	 * @throws DomainException
1692
+	 * @throws EE_Error
1693
+	 */
1694
+	protected function _get_ticket_price_row(
1695
+		$ticket_row,
1696
+		$price_row,
1697
+		$price,
1698
+		$default,
1699
+		$ticket,
1700
+		$show_trash = true,
1701
+		$show_create = true
1702
+	) {
1703
+		$send_disabled = ! empty($ticket) && $ticket->get('TKT_deleted');
1704
+		$template_args = array(
1705
+			'tkt_row'               => $default && empty($ticket)
1706
+				? 'TICKETNUM'
1707
+				: $ticket_row,
1708
+			'PRC_order'             => $default && empty($price)
1709
+				? 'PRICENUM'
1710
+				: $price_row,
1711
+			'edit_prices_name'      => $default && empty($price)
1712
+				? 'PRICENAMEATTR'
1713
+				: 'edit_prices',
1714
+			'price_type_selector'   => $default && empty($price)
1715
+				? $this->_get_base_price_template($ticket_row, $price_row, $price, $default)
1716
+				: $this->_get_price_type_selector($ticket_row, $price_row, $price, $default, $send_disabled),
1717
+			'PRC_ID'                => $default && empty($price)
1718
+				? 0
1719
+				: $price->ID(),
1720
+			'PRC_is_default'        => $default && empty($price)
1721
+				? 0
1722
+				: $price->get('PRC_is_default'),
1723
+			'PRC_name'              => $default && empty($price)
1724
+				? ''
1725
+				: $price->get('PRC_name'),
1726
+			'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1727
+			'show_plus_or_minus'    => $default && empty($price)
1728
+				? ''
1729
+				: ' style="display:none;"',
1730
+			'show_plus'             => ($default && empty($price)) || ($price->is_discount() || $price->is_base_price())
1731
+				? ' style="display:none;"'
1732
+				: '',
1733
+			'show_minus'            => ($default && empty($price)) || ! $price->is_discount()
1734
+				? ' style="display:none;"'
1735
+				: '',
1736
+			'show_currency_symbol'  => ($default && empty($price)) || $price->is_percent()
1737
+				? ' style="display:none"'
1738
+				: '',
1739
+			'PRC_amount'            => $default && empty($price)
1740
+				? 0
1741
+				: $price->get_pretty('PRC_amount',
1742
+					'localized_float'),
1743
+			'show_percentage'       => ($default && empty($price)) || ! $price->is_percent()
1744
+				? ' style="display:none;"'
1745
+				: '',
1746
+			'show_trash_icon'       => $show_trash
1747
+				? ''
1748
+				: ' style="display:none;"',
1749
+			'show_create_button'    => $show_create
1750
+				? ''
1751
+				: ' style="display:none;"',
1752
+			'PRC_desc'              => $default && empty($price)
1753
+				? ''
1754
+				: $price->get('PRC_desc'),
1755
+			'disabled'              => ! empty($ticket) && $ticket->get('TKT_deleted'),
1756
+		);
1757
+		$template_args = apply_filters(
1758
+			'FHEE__espresso_events_Pricing_Hooks___get_ticket_price_row__template_args',
1759
+			$template_args,
1760
+			$ticket_row,
1761
+			$price_row,
1762
+			$price,
1763
+			$default,
1764
+			$ticket,
1765
+			$show_trash,
1766
+			$show_create,
1767
+			$this->_is_creating_event
1768
+		);
1769
+		return EEH_Template::display_template(
1770
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_price_row.template.php',
1771
+			$template_args,
1772
+			true
1773
+		);
1774
+	}
1775
+
1776
+
1777
+
1778
+	/**
1779
+	 * @param int      $ticket_row
1780
+	 * @param int      $price_row
1781
+	 * @param EE_Price $price
1782
+	 * @param bool     $default
1783
+	 * @param bool     $disabled
1784
+	 * @return mixed
1785
+	 * @throws DomainException
1786
+	 * @throws EE_Error
1787
+	 */
1788
+	protected function _get_price_type_selector($ticket_row, $price_row, $price, $default, $disabled = false)
1789
+	{
1790
+		if ($price->is_base_price()) {
1791
+			return $this->_get_base_price_template($ticket_row, $price_row, $price, $default);
1792
+		}
1793
+		return $this->_get_price_modifier_template($ticket_row, $price_row, $price, $default, $disabled);
1794
+	}
1795
+
1796
+
1797
+
1798
+	/**
1799
+	 * @param int      $ticket_row
1800
+	 * @param int      $price_row
1801
+	 * @param EE_Price $price
1802
+	 * @param bool     $default
1803
+	 * @return mixed
1804
+	 * @throws DomainException
1805
+	 * @throws EE_Error
1806
+	 */
1807
+	protected function _get_base_price_template($ticket_row, $price_row, $price, $default)
1808
+	{
1809
+		$template_args = array(
1810
+			'tkt_row'                   => $default ? 'TICKETNUM' : $ticket_row,
1811
+			'PRC_order'                 => $default && empty($price) ? 'PRICENUM' : $price_row,
1812
+			'PRT_ID'                    => $default && empty($price) ? 1 : $price->get('PRT_ID'),
1813
+			'PRT_name'                  => esc_html__('Price', 'event_espresso'),
1814
+			'price_selected_operator'   => '+',
1815
+			'price_selected_is_percent' => 0,
1816
+		);
1817
+		$template_args = apply_filters(
1818
+			'FHEE__espresso_events_Pricing_Hooks___get_base_price_template__template_args',
1819
+			$template_args,
1820
+			$ticket_row,
1821
+			$price_row,
1822
+			$price,
1823
+			$default,
1824
+			$this->_is_creating_event
1825
+		);
1826
+		return EEH_Template::display_template(
1827
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_type_base.template.php',
1828
+			$template_args,
1829
+			true
1830
+		);
1831
+	}
1832
+
1833
+
1834
+
1835
+	/**
1836
+	 * @param int      $ticket_row
1837
+	 * @param int      $price_row
1838
+	 * @param EE_Price $price
1839
+	 * @param bool     $default
1840
+	 * @param bool     $disabled
1841
+	 * @return mixed
1842
+	 * @throws DomainException
1843
+	 * @throws EE_Error
1844
+	 */
1845
+	protected function _get_price_modifier_template(
1846
+		$ticket_row,
1847
+		$price_row,
1848
+		$price,
1849
+		$default,
1850
+		$disabled = false
1851
+	) {
1852
+		$select_name = $default && ! $price instanceof EE_Price
1853
+			? 'edit_prices[TICKETNUM][PRICENUM][PRT_ID]'
1854
+			: 'edit_prices[' . $ticket_row . '][' . $price_row . '][PRT_ID]';
1855
+		/** @var EEM_Price_Type $price_type_model */
1856
+		$price_type_model = EE_Registry::instance()->load_model('Price_Type');
1857
+		$price_types = $price_type_model->get_all(array(
1858
+			array(
1859
+				'OR' => array(
1860
+					'PBT_ID'  => '2',
1861
+					'PBT_ID*' => '3',
1862
+				),
1863
+			),
1864
+		));
1865
+		$all_price_types = $default && ! $price instanceof EE_Price
1866
+			? array(esc_html__('Select Modifier', 'event_espresso'))
1867
+			: array();
1868
+		$selected_price_type_id = $default && ! $price instanceof EE_Price ? 0 : $price->type();
1869
+		$price_option_spans = '';
1870
+		//setup price types for selector
1871
+		foreach ($price_types as $price_type) {
1872
+			if (! $price_type instanceof EE_Price_Type) {
1873
+				continue;
1874
+			}
1875
+			$all_price_types[$price_type->ID()] = $price_type->get('PRT_name');
1876
+			//while we're in the loop let's setup the option spans used by js
1877
+			$span_args = array(
1878
+				'PRT_ID'         => $price_type->ID(),
1879
+				'PRT_operator'   => $price_type->is_discount() ? '-' : '+',
1880
+				'PRT_is_percent' => $price_type->get('PRT_is_percent') ? 1 : 0,
1881
+			);
1882
+			$price_option_spans .= EEH_Template::display_template(
1883
+				PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_option_span.template.php',
1884
+				$span_args,
1885
+				true
1886
+			);
1887
+		}
1888
+		$select_name = $disabled ? 'archive_price[' . $ticket_row . '][' . $price_row . '][PRT_ID]' : $select_name;
1889
+		$select_input = new EE_Select_Input(
1890
+			$all_price_types,
1891
+			array(
1892
+				'default'               => $selected_price_type_id,
1893
+				'html_name'             => $select_name,
1894
+				'html_class'            => 'edit-price-PRT_ID',
1895
+				'html_other_attributes' => $disabled ? 'style="width:auto;" disabled' : 'style="width:auto;"',
1896
+			)
1897
+		);
1898
+		$price_selected_operator = $price instanceof EE_Price && $price->is_discount() ? '-' : '+';
1899
+		$price_selected_operator = $default && ! $price instanceof EE_Price ? '' : $price_selected_operator;
1900
+		$price_selected_is_percent = $price instanceof EE_Price && $price->is_percent() ? 1 : 0;
1901
+		$price_selected_is_percent = $default && ! $price instanceof EE_Price ? '' : $price_selected_is_percent;
1902
+		$template_args = array(
1903
+			'tkt_row'                   => $default ? 'TICKETNUM' : $ticket_row,
1904
+			'PRC_order'                 => $default && ! $price instanceof EE_Price ? 'PRICENUM' : $price_row,
1905
+			'price_modifier_selector'   => $select_input->get_html_for_input(),
1906
+			'main_name'                 => $select_name,
1907
+			'selected_price_type_id'    => $selected_price_type_id,
1908
+			'price_option_spans'        => $price_option_spans,
1909
+			'price_selected_operator'   => $price_selected_operator,
1910
+			'price_selected_is_percent' => $price_selected_is_percent,
1911
+			'disabled'                  => $disabled,
1912
+		);
1913
+		$template_args = apply_filters(
1914
+			'FHEE__espresso_events_Pricing_Hooks___get_price_modifier_template__template_args',
1915
+			$template_args,
1916
+			$ticket_row,
1917
+			$price_row,
1918
+			$price,
1919
+			$default,
1920
+			$disabled,
1921
+			$this->_is_creating_event
1922
+		);
1923
+		return EEH_Template::display_template(
1924
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_price_modifier_selector.template.php',
1925
+			$template_args,
1926
+			true
1927
+		);
1928
+	}
1929
+
1930
+
1931
+
1932
+	/**
1933
+	 * @param int              $datetime_row
1934
+	 * @param int              $ticket_row
1935
+	 * @param EE_Datetime|null $datetime
1936
+	 * @param EE_Ticket|null   $ticket
1937
+	 * @param array            $ticket_datetimes
1938
+	 * @param bool             $default
1939
+	 * @return mixed
1940
+	 * @throws DomainException
1941
+	 * @throws EE_Error
1942
+	 */
1943
+	protected function _get_ticket_datetime_list_item(
1944
+		$datetime_row,
1945
+		$ticket_row,
1946
+		$datetime,
1947
+		$ticket,
1948
+		$ticket_datetimes = array(),
1949
+		$default
1950
+	) {
1951
+		$tkt_datetimes = $ticket instanceof EE_Ticket && isset($ticket_datetimes[$ticket->ID()])
1952
+			? $ticket_datetimes[$ticket->ID()]
1953
+			: array();
1954
+		$template_args = array(
1955
+			'dtt_row'                  => $default && ! $datetime instanceof EE_Datetime
1956
+				? 'DTTNUM'
1957
+				: $datetime_row,
1958
+			'tkt_row'                  => $default
1959
+				? 'TICKETNUM'
1960
+				: $ticket_row,
1961
+			'ticket_datetime_selected' => in_array($datetime_row, $tkt_datetimes, true)
1962
+				? ' ticket-selected'
1963
+				: '',
1964
+			'ticket_datetime_checked'  => in_array($datetime_row, $tkt_datetimes, true)
1965
+				? ' checked="checked"'
1966
+				: '',
1967
+			'DTT_name'                 => $default && empty($datetime)
1968
+				? 'DTTNAME'
1969
+				: $datetime->get_dtt_display_name(true),
1970
+			'tkt_status_class'         => '',
1971
+		);
1972
+		$template_args = apply_filters(
1973
+			'FHEE__espresso_events_Pricing_Hooks___get_ticket_datetime_list_item__template_args',
1974
+			$template_args,
1975
+			$datetime_row,
1976
+			$ticket_row,
1977
+			$datetime,
1978
+			$ticket,
1979
+			$ticket_datetimes,
1980
+			$default,
1981
+			$this->_is_creating_event
1982
+		);
1983
+		return EEH_Template::display_template(
1984
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_datetimes_list_item.template.php',
1985
+			$template_args,
1986
+			true
1987
+		);
1988
+	}
1989
+
1990
+
1991
+
1992
+	/**
1993
+	 * @param array $all_datetimes
1994
+	 * @param array $all_tickets
1995
+	 * @return mixed
1996
+	 * @throws DomainException
1997
+	 * @throws EE_Error
1998
+	 */
1999
+	protected function _get_ticket_js_structure($all_datetimes = array(), $all_tickets = array())
2000
+	{
2001
+		$template_args = array(
2002
+			'default_datetime_edit_row'                => $this->_get_dtt_edit_row(
2003
+				'DTTNUM',
2004
+				null,
2005
+				true,
2006
+				$all_datetimes
2007
+			),
2008
+			'default_ticket_row'                       => $this->_get_ticket_row(
2009
+				'TICKETNUM',
2010
+				null,
2011
+				array(),
2012
+				array(),
2013
+				true
2014
+			),
2015
+			'default_price_row'                        => $this->_get_ticket_price_row(
2016
+				'TICKETNUM',
2017
+				'PRICENUM',
2018
+				null,
2019
+				true,
2020
+				null
2021
+			),
2022
+			'default_price_rows'                       => '',
2023
+			'default_base_price_amount'                => 0,
2024
+			'default_base_price_name'                  => '',
2025
+			'default_base_price_description'           => '',
2026
+			'default_price_modifier_selector_row'      => $this->_get_price_modifier_template(
2027
+				'TICKETNUM',
2028
+				'PRICENUM',
2029
+				null,
2030
+				true
2031
+			),
2032
+			'default_available_tickets_for_datetime'   => $this->_get_dtt_attached_tickets_row(
2033
+				'DTTNUM',
2034
+				null,
2035
+				array(),
2036
+				array(),
2037
+				true
2038
+			),
2039
+			'existing_available_datetime_tickets_list' => '',
2040
+			'existing_available_ticket_datetimes_list' => '',
2041
+			'new_available_datetime_ticket_list_item'  => $this->_get_datetime_tickets_list_item(
2042
+				'DTTNUM',
2043
+				'TICKETNUM',
2044
+				null,
2045
+				null,
2046
+				array(),
2047
+				true
2048
+			),
2049
+			'new_available_ticket_datetime_list_item'  => $this->_get_ticket_datetime_list_item(
2050
+				'DTTNUM',
2051
+				'TICKETNUM',
2052
+				null,
2053
+				null,
2054
+				array(),
2055
+				true
2056
+			),
2057
+		);
2058
+		$ticket_row = 1;
2059
+		foreach ($all_tickets as $ticket) {
2060
+			$template_args['existing_available_datetime_tickets_list'] .= $this->_get_datetime_tickets_list_item(
2061
+				'DTTNUM',
2062
+				$ticket_row,
2063
+				null,
2064
+				$ticket,
2065
+				array(),
2066
+				true
2067
+			);
2068
+			$ticket_row++;
2069
+		}
2070
+		$datetime_row = 1;
2071
+		foreach ($all_datetimes as $datetime) {
2072
+			$template_args['existing_available_ticket_datetimes_list'] .= $this->_get_ticket_datetime_list_item(
2073
+				$datetime_row,
2074
+				'TICKETNUM',
2075
+				$datetime,
2076
+				null,
2077
+				array(),
2078
+				true
2079
+			);
2080
+			$datetime_row++;
2081
+		}
2082
+		/** @var EEM_Price $price_model */
2083
+		$price_model = EE_Registry::instance()->load_model('Price');
2084
+		$default_prices = $price_model->get_all_default_prices();
2085
+		$price_row = 1;
2086
+		foreach ($default_prices as $price) {
2087
+			if (! $price instanceof EE_Price) {
2088
+				continue;
2089
+			}
2090
+			if ($price->is_base_price()) {
2091
+				$template_args['default_base_price_amount'] = $price->get_pretty(
2092
+					'PRC_amount',
2093
+					'localized_float'
2094
+				);
2095
+				$template_args['default_base_price_name'] = $price->get('PRC_name');
2096
+				$template_args['default_base_price_description'] = $price->get('PRC_desc');
2097
+				$price_row++;
2098
+				continue;
2099
+			}
2100
+			$show_trash = !((count($default_prices) > 1 && $price_row === 1) || count($default_prices) === 1);
2101
+			$show_create = !(count($default_prices) > 1 && count($default_prices) !== $price_row);
2102
+			$template_args['default_price_rows'] .= $this->_get_ticket_price_row(
2103
+				'TICKETNUM',
2104
+				$price_row,
2105
+				$price,
2106
+				true,
2107
+				null,
2108
+				$show_trash,
2109
+				$show_create
2110
+			);
2111
+			$price_row++;
2112
+		}
2113
+		$template_args = apply_filters(
2114
+			'FHEE__espresso_events_Pricing_Hooks___get_ticket_js_structure__template_args',
2115
+			$template_args,
2116
+			$all_datetimes,
2117
+			$all_tickets,
2118
+			$this->_is_creating_event
2119
+		);
2120
+		return EEH_Template::display_template(
2121
+			PRICING_TEMPLATE_PATH . 'event_tickets_datetime_ticket_js_structure.template.php',
2122
+			$template_args,
2123
+			true
2124
+		);
2125
+	}
2126 2126
 
2127 2127
 
2128 2128
 } //end class espresso_events_Pricing_Hooks
Please login to merge, or discard this patch.
core/db_models/fields/EE_Text_Field_Base.php 2 patches
Indentation   +44 added lines, -44 removed lines patch added patch discarded remove patch
@@ -7,50 +7,50 @@
 block discarded – undo
7 7
 abstract class EE_Text_Field_Base extends EE_Model_Field_Base
8 8
 {
9 9
 
10
-    /**
11
-     * Gets the value in the format expected when being set.
12
-     * For display on the front-end, usually you would use prepare_for_pretty_echoing() instead.
13
-     * @param mixed $value_of_field_on_model_object
14
-     * @return mixed|string
15
-     */
16
-    public function prepare_for_get($value_of_field_on_model_object)
17
-    {
18
-        return is_string($value_of_field_on_model_object)
19
-            ? stripslashes($value_of_field_on_model_object)
20
-            : $value_of_field_on_model_object;
21
-    }
10
+	/**
11
+	 * Gets the value in the format expected when being set.
12
+	 * For display on the front-end, usually you would use prepare_for_pretty_echoing() instead.
13
+	 * @param mixed $value_of_field_on_model_object
14
+	 * @return mixed|string
15
+	 */
16
+	public function prepare_for_get($value_of_field_on_model_object)
17
+	{
18
+		return is_string($value_of_field_on_model_object)
19
+			? stripslashes($value_of_field_on_model_object)
20
+			: $value_of_field_on_model_object;
21
+	}
22 22
 
23
-    /**
24
-     * Accepts schema of 'form_input' which formats the string for echoing in form input's value.
25
-     *
26
-     * @param string $value_on_field_to_be_outputted
27
-     * @param string $schema
28
-     * @return string
29
-     */
30
-    public function prepare_for_pretty_echoing($value_on_field_to_be_outputted, $schema = null)
31
-    {
32
-        if ($schema === 'form_input') {
33
-            $value_on_field_to_be_outputted = (string)htmlentities(
34
-                $value_on_field_to_be_outputted,
35
-                ENT_QUOTES,
36
-                'UTF-8'
37
-            );
38
-        }
39
-        return parent::prepare_for_pretty_echoing($value_on_field_to_be_outputted);
40
-    }
23
+	/**
24
+	 * Accepts schema of 'form_input' which formats the string for echoing in form input's value.
25
+	 *
26
+	 * @param string $value_on_field_to_be_outputted
27
+	 * @param string $schema
28
+	 * @return string
29
+	 */
30
+	public function prepare_for_pretty_echoing($value_on_field_to_be_outputted, $schema = null)
31
+	{
32
+		if ($schema === 'form_input') {
33
+			$value_on_field_to_be_outputted = (string)htmlentities(
34
+				$value_on_field_to_be_outputted,
35
+				ENT_QUOTES,
36
+				'UTF-8'
37
+			);
38
+		}
39
+		return parent::prepare_for_pretty_echoing($value_on_field_to_be_outputted);
40
+	}
41 41
 
42
-    /**
43
-     * Data received from the user should be exactly as they hope to save it in the DB, with the exception that
44
-     * quotes need to have slashes added to it. (We used to call html_entity_decode on the value here,
45
-     * because we called htmlentities when in EE_Text_Field_Base::prepare_for_pretty_echoing, but that's not necessary
46
-     * because web browsers always decode HTML entities in element attributes, like a form element's value attribute.
47
-     * So if we do it again here, we'll be removing HTML entities the user intended to have.)
48
-     *
49
-     * @param string $value_inputted_for_field_on_model_object
50
-     * @return string
51
-     */
52
-    public function prepare_for_set($value_inputted_for_field_on_model_object)
53
-    {
54
-        return stripslashes(parent::prepare_for_set($value_inputted_for_field_on_model_object));
55
-    }
42
+	/**
43
+	 * Data received from the user should be exactly as they hope to save it in the DB, with the exception that
44
+	 * quotes need to have slashes added to it. (We used to call html_entity_decode on the value here,
45
+	 * because we called htmlentities when in EE_Text_Field_Base::prepare_for_pretty_echoing, but that's not necessary
46
+	 * because web browsers always decode HTML entities in element attributes, like a form element's value attribute.
47
+	 * So if we do it again here, we'll be removing HTML entities the user intended to have.)
48
+	 *
49
+	 * @param string $value_inputted_for_field_on_model_object
50
+	 * @return string
51
+	 */
52
+	public function prepare_for_set($value_inputted_for_field_on_model_object)
53
+	{
54
+		return stripslashes(parent::prepare_for_set($value_inputted_for_field_on_model_object));
55
+	}
56 56
 }
57 57
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -30,7 +30,7 @@
 block discarded – undo
30 30
     public function prepare_for_pretty_echoing($value_on_field_to_be_outputted, $schema = null)
31 31
     {
32 32
         if ($schema === 'form_input') {
33
-            $value_on_field_to_be_outputted = (string)htmlentities(
33
+            $value_on_field_to_be_outputted = (string) htmlentities(
34 34
                 $value_on_field_to_be_outputted,
35 35
                 ENT_QUOTES,
36 36
                 'UTF-8'
Please login to merge, or discard this patch.
core/admin/EE_Admin_Page_Loader.core.php 2 patches
Indentation   +742 added lines, -742 removed lines patch added patch discarded remove patch
@@ -28,748 +28,748 @@
 block discarded – undo
28 28
 class EE_Admin_Page_Loader
29 29
 {
30 30
 
31
-    /**
32
-     * _installed_pages
33
-     * objects for page_init objects detected and loaded
34
-     *
35
-     * @access private
36
-     * @var \EE_Admin_Page_Init[]
37
-     */
38
-    private $_installed_pages = array();
39
-
40
-
41
-
42
-    /**
43
-     * this is used to hold the registry of menu slugs for all the installed admin pages
44
-     *
45
-     * @var array
46
-     */
47
-    private $_menu_slugs = array();
48
-
49
-
50
-    /**
51
-     * _caffeinated_extends
52
-     * This array is the generated configuration array for which core EE_Admin pages are extended (and the bits and
53
-     * pieces needed to do so).  This property is defined in the _set_caffeinated method.
54
-     *
55
-     * @var array
56
-     */
57
-    private $_caffeinated_extends = array();
58
-
59
-
60
-
61
-    /**
62
-     * _current_caf_extend_slug
63
-     * This property is used for holding the page slug that is required for referencing the correct
64
-     * _caffeinated_extends index when the corresponding core child EE_Admin_Page_init hooks are executed.
65
-     *
66
-     * @var array
67
-     */
68
-    private $_current_caf_extend_slug;
69
-
70
-
71
-
72
-    /**
73
-     * _caf_autoloader
74
-     * This property is used for holding an array of folder names of any NEW EE_Admin_Pages found in the
75
-     * caffeinated/new directory.  This array is then used to setup a corresponding dynamic autoloader for these pages
76
-     * classes.
77
-     *
78
-     * @var array
79
-     */
80
-    //	private $_caf_autoloader = array();
81
-    /**
82
-     * _prepped_menu_maps
83
-     * This is the prepared array of EE_Admin_Page_Menu_Maps for adding to the admin_menu.
84
-     *
85
-     * @since  4.4.0
86
-     * @var EE_Admin_Page_Menu_Map[]
87
-     */
88
-    private $_prepped_menu_maps = array();
89
-
90
-
91
-
92
-    /**
93
-     * _admin_menu_groups
94
-     * array that holds the group headings and details for
95
-     *
96
-     * @access private
97
-     * @var array
98
-     */
99
-    private $_admin_menu_groups = array();
100
-
101
-
102
-
103
-    /**
104
-     * This property will hold the hook file for setting up the filter that does all the connections between admin
105
-     * pages.
106
-     *
107
-     * @var string
108
-     */
109
-    public $hook_file;
110
-
111
-
112
-
113
-    /**
114
-     * constructor
115
-     *
116
-     * @access public
117
-     * @return \EE_Admin_Page_Loader
118
-     */
119
-    public function __construct()
120
-    {
121
-        //load menu_map classes
122
-        EE_Registry::instance()->load_file(EE_ADMIN, 'EE_Admin_Page_Menu_Map', 'core');
123
-        //define the default "groups" for the admin_pages
124
-        $this->_set_menu_groups();
125
-        //let's set default autoloaders.  Note that this just sets autoloaders for root admin files.
126
-        //		spl_autoload_register( array( $this, 'init_autoloaders') );
127
-        //let's do a scan and see what installed pages we have
128
-        $this->_get_installed_pages();
129
-        //set menus (has to be done on every load - we're not actually loading the page just setting the menus and where they point to).
130
-        add_action('admin_menu', array($this, 'set_menus'));
131
-        add_action('network_admin_menu', array($this, 'set_network_menus'));
132
-    }
133
-
134
-
135
-
136
-    /**
137
-     * When caffeinated system is detected, this method is called to setup the caffeinated directory constants used by
138
-     * files in the caffeinated folder.
139
-     *
140
-     * @access private
141
-     * @return void
142
-     */
143
-    private function _define_caffeinated_constants()
144
-    {
145
-        if (! defined('EE_CORE_CAF_ADMIN')) {
146
-            define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH . 'caffeinated/admin/');
147
-            define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL . 'caffeinated/admin/');
148
-            define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN . 'new/');
149
-            define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN . 'extend/');
150
-            define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL . 'extend/');
151
-            define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN . 'hooks/');
152
-        }
153
-    }
154
-
155
-
156
-
157
-    /**
158
-     * _set_menu_groups
159
-     * sets the filterable _admin_menu_groups property (list of various "groupings" within the EE admin menu array)
160
-     *
161
-     * @access private
162
-     * @return void
163
-     */
164
-    private function _set_menu_groups()
165
-    {
166
-
167
-        //set array of EE_Admin_Page_Menu_Group objects
168
-        $groups = array(
169
-            'main'       => new EE_Admin_Page_Menu_Group(
170
-                array(
171
-                    'menu_label'   => __('Main', 'event_espresso'),
172
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::NONE,
173
-                    'menu_slug'    => 'main',
174
-                    'capability'   => 'ee_read_ee',
175
-                    'menu_order'   => 0,
176
-                    'parent_slug'  => 'espresso_events',
177
-                )
178
-            ),
179
-            'management' => new EE_Admin_Page_Menu_Group(
180
-                array(
181
-                    'menu_label'   => __('Management', 'event_espresso'),
182
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
183
-                    'menu_slug'    => 'management',
184
-                    'capability'   => 'ee_read_ee',
185
-                    'menu_order'   => 10,
186
-                    'parent_slug'  => 'espresso_events',
187
-                )
188
-            ),
189
-            'settings'   => new EE_Admin_Page_Menu_Group(
190
-                array(
191
-                    'menu_label'   => __('Settings', 'event_espresso'),
192
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
193
-                    'menu_slug'    => 'settings',
194
-                    'capability'   => 'ee_read_ee',
195
-                    'menu_order'   => 30,
196
-                    'parent_slug'  => 'espresso_events',
197
-                )
198
-            ),
199
-            'templates'  => new EE_Admin_Page_Menu_Group(
200
-                array(
201
-                    'menu_label'   => __('Templates', 'event_espresso'),
202
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
203
-                    'menu_slug'    => 'templates',
204
-                    'capability'   => 'ee_read_ee',
205
-                    'menu_order'   => 40,
206
-                    'parent_slug'  => 'espresso_events',
207
-                )
208
-            ),
209
-            'extras'     => new EE_Admin_Page_Menu_Group(
210
-                array(
211
-                    'menu_label'              => __('Extras', 'event_espresso'),
212
-                    'show_on_menu'            => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN,
213
-                    'menu_slug'               => 'extras',
214
-                    'capability'              => 'ee_read_ee',
215
-                    'menu_order'              => 50,
216
-                    'parent_slug'             => 'espresso_events',
217
-                    'maintenance_mode_parent' => 'espresso_maintenance_settings',
218
-                )
219
-            ),
220
-            'tools'      => new EE_Admin_Page_Menu_Group(
221
-                array(
222
-                    'menu_label'   => __("Tools", "event_espresso"),
223
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
224
-                    'menu_slug'    => 'tools',
225
-                    'capability'   => 'ee_read_ee',
226
-                    'menu_order'   => 60,
227
-                    'parent_slug'  => 'espresso_events',
228
-                )
229
-            ),
230
-            'addons'     => new EE_Admin_Page_Menu_Group(
231
-                array(
232
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN,
233
-                    'menu_label'   => __('Add-ons', 'event_espresso'),
234
-                    'menu_slug'    => 'addons',
235
-                    'capability'   => 'ee_read_ee',
236
-                    'menu_order'   => 20,
237
-                    'parent_slug'  => 'espresso_events',
238
-                )
239
-            ),
240
-        );
241
-        $this->_admin_menu_groups = apply_filters(
242
-            'FHEE__EE_Admin_Page_Loader___set_menu_groups__admin_menu_groups',
243
-            $groups
244
-        );
245
-    }
246
-
247
-
248
-
249
-    /**
250
-     * This takes all the groups in the _admin_menu_groups array and returns the array indexed by group
251
-     * slug.  The other utility with this function is it validates that all the groups are instances of
252
-     * EE_Admin_Page_Menu_Group (cause some invalid things might have slipped in via addons).
253
-     *
254
-     * @since  4.4.0
255
-     * @throws \EE_Error
256
-     * @return EE_Admin_Page_Menu_Group[]
257
-     */
258
-    private function _rearrange_menu_groups()
259
-    {
260
-        $groups = array();
261
-        //first let's order the menu groups by their internal menu order (note usort type hinting to ensure the incoming array is EE_Admin_Page_Menu_Map objects )
262
-        usort($this->_admin_menu_groups, array($this, '_sort_menu_maps'));
263
-        foreach ($this->_admin_menu_groups as $group) {
264
-            if (! $group instanceof EE_Admin_Page_Menu_Group) {
265
-                throw new EE_Error(
266
-                    sprintf(
267
-                        __(
268
-                            'Unable to continue sorting the menu groups array because there is an invalid value for the menu groups.  All values in this array are required to be a EE_Admin_Page_Menu_Group object.  Instead there was: %s',
269
-                            'event_espresso'
270
-                        ),
271
-                        print_r($group, true)
272
-                    )
273
-                );
274
-            }
275
-            $groups[$group->menu_slug] = $group;
276
-        }
277
-        return $groups;
278
-    }
279
-
280
-
281
-
282
-    /**
283
-     * _get_installed_pages
284
-     * This just gets the list of installed EE_Admin_pages.
285
-     *
286
-     * @access private
287
-     * @throws EE_Error
288
-     * @return void
289
-     */
290
-    private function _get_installed_pages()
291
-    {
292
-        $installed_refs = array();
293
-        $exclude        = array('assets', 'templates');
294
-        // grab everything in the  admin core directory
295
-        $admin_screens = glob(EE_ADMIN_PAGES . '*', GLOB_ONLYDIR);
296
-        if ($admin_screens) {
297
-            foreach ($admin_screens as $admin_screen) {
298
-                // files and anything in the exclude array need not apply
299
-                if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) {
300
-                    // these folders represent the different EE admin pages
301
-                    $installed_refs[basename($admin_screen)] = $admin_screen;
302
-                }
303
-            }
304
-        }
305
-        if (empty($installed_refs)) {
306
-            $error_msg[] = __(
307
-                'There are no EE_Admin pages detected, it looks like EE did not install properly',
308
-                'event_espresso'
309
-            );
310
-            $error_msg[] = $error_msg[0] . "\r\n" . sprintf(
311
-                    __(
312
-                        'Check that the %s folder exists and is writable. Maybe try deactivating, then reactivating Event Espresso again.',
313
-                        'event_espresso'
314
-                    ),
315
-                    EE_ADMIN_PAGES
316
-                );
317
-            throw new EE_Error(implode('||', $error_msg));
318
-        }
319
-        //this just checks the caffeinated folder and takes care of setting up any caffeinated stuff.
320
-        $installed_refs = $this->_set_caffeinated($installed_refs);
321
-        //allow plugins to add in their own pages (note at this point they will need to have an autoloader defined for their class) OR hook into EEH_Autoloader::load_admin_page() to add their path.;
322
-        $installed_refs             = apply_filters(
323
-            'FHEE__EE_Admin_Page_Loader___get_installed_pages__installed_refs',
324
-            $installed_refs
325
-        );
326
-        $this->_caffeinated_extends = apply_filters(
327
-            'FHEE__EE_Admin_Page_Loader___get_installed_pages__caffeinated_extends',
328
-            $this->_caffeinated_extends
329
-        );
330
-        //loop through admin pages and setup the $_installed_pages array.
331
-        $hooks_ref = array();
332
-        foreach ($installed_refs as $page => $path) {
333
-            // set autoloaders for our admin page classes based on included path information
334
-            EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($path);
335
-            // build list of installed pages
336
-            $this->_installed_pages[$page] = $this->_load_admin_page($page, $path);
337
-            // verify returned object
338
-            if ($this->_installed_pages[$page] instanceof EE_Admin_Page_Init) {
339
-                if (! $this->_installed_pages[$page]->get_menu_map() instanceof EE_Admin_Page_Menu_Map) {
340
-                    continue;
341
-                }
342
-                //skip if in full maintenance mode and maintenance_mode_parent is set
343
-                $maintenance_mode_parent = $this->_installed_pages[$page]->get_menu_map()->maintenance_mode_parent;
344
-                if (empty($maintenance_mode_parent)
345
-                    && EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance
346
-                ) {
347
-                    unset($installed_refs[$page]);
348
-                    continue;
349
-                }
350
-                $menu_slug = $this->_installed_pages[$page]->get_menu_map()->menu_slug;
351
-                $this->_menu_slugs[$menu_slug] = $page;
352
-                //flag for register hooks on extended pages b/c extended pages use the default INIT.
353
-                $extend = false;
354
-                //now that we've got the admin_init objects... lets see if there are any caffeinated pages extending the originals.  If there are then let's hook into the init admin filter and load our extend instead.
355
-                if (isset($this->_caffeinated_extends[$page])) {
356
-                    $this->_current_caf_extend_slug = $page;
357
-                    $admin_page_name = $this->_installed_pages[$page]->get_admin_page_name();
358
-                    $caf_path = $this->_caffeinated_extends[$this->_current_caf_extend_slug]['path'];
359
-                    $caf_admin_page = $this->_caffeinated_extends[$this->_current_caf_extend_slug]['admin_page'];
360
-                    add_filter(
361
-                        "FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$menu_slug}_{$admin_page_name}",
362
-                        function($path_to_file) use ($caf_path) {
363
-                            return $caf_path;
364
-                        }
365
-                    );
366
-                    add_filter(
367
-                        "FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$menu_slug}_{$admin_page_name}",
368
-                        function ($admin_page) use ($caf_admin_page)
369
-                        {
370
-                            return $caf_admin_page;
371
-                        }
372
-                    );
373
-                    $extend = true;
374
-                }
375
-                //let's do the registered hooks
376
-                $extended_hooks = $this->_installed_pages[$page]->register_hooks($extend);
377
-                $hooks_ref      = array_merge($hooks_ref, $extended_hooks);
378
-            }
379
-        }
380
-        //the hooks_ref is all the pages where we have $extended _Hooks files that will extend a class in a different folder.  So we want to make sure we load the file for the parent.
381
-        //first make sure we've got unique values
382
-        $hooks_ref = array_unique($hooks_ref);
383
-        //now let's loop and require!
384
-        foreach ($hooks_ref as $path) {
385
-            require_once($path);
386
-        }
387
-        //make sure we have menu slugs global setup. Used in EE_Admin_Page->page_setup() to ensure we don't do a full class load for an admin page that isn't requested.
388
-        global $ee_menu_slugs;
389
-        $ee_menu_slugs = $this->_menu_slugs;
390
-        //we need to loop again to run any early code
391
-        foreach ($installed_refs as $page => $path) {
392
-            if ($this->_installed_pages[$page] instanceof EE_Admin_Page_Init) {
393
-                $this->_installed_pages[$page]->do_initial_loads();
394
-            }
395
-        }
396
-        do_action('AHEE__EE_Admin_Page_Loader___get_installed_pages_loaded', $this->_installed_pages);
397
-    }
398
-
399
-
400
-
401
-    /**
402
-     * get_admin_page_object
403
-     *
404
-     * @param string $page_slug
405
-     * @return EE_Admin_Page
406
-     */
407
-    public function get_admin_page_object($page_slug = '')
408
-    {
409
-        if (isset($this->_installed_pages[$page_slug])) {
410
-            return $this->_installed_pages[$page_slug]->loaded_page_object();
411
-        }
412
-        return null;
413
-    }
414
-
415
-
416
-
417
-    /**
418
-     * _get_classname_for_admin_page
419
-     * generates an "Admin Page" class based on the directory  name
420
-     *
421
-     * @param $dir_name
422
-     * @return string
423
-     */
424
-    private function _get_classname_for_admin_page($dir_name = '')
425
-    {
426
-        $class_name = str_replace('_', ' ', strtolower($dir_name));
427
-        return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page';
428
-    }
429
-
430
-
431
-
432
-    /**
433
-     * _get_classname_for_admin_init_page
434
-     * generates an "Admin Page Init" class based on the directory  name
435
-     *
436
-     * @param $dir_name
437
-     * @return string
438
-     */
439
-    private function _get_classname_for_admin_init_page($dir_name = '')
440
-    {
441
-        $class_name = str_replace('_', ' ', strtolower($dir_name));
442
-        return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page_Init';
443
-    }
444
-
445
-
446
-
447
-    /**
448
-     * _load_admin_page
449
-     * Loads and instantiates page_init object for a single EE_admin page.
450
-     *
451
-     * @param  string $page page_reference
452
-     * @param string  $path
453
-     * @throws EE_Error
454
-     * @return object|bool  return page object if valid, bool false if not.
455
-     */
456
-    private function _load_admin_page($page = '', $path = '')
457
-    {
458
-        $class_name = $this->_get_classname_for_admin_init_page($page);
459
-        EE_Registry::instance()->load_file($path, $class_name, 'core');
460
-        if (! class_exists($class_name)) {
461
-            $inner_error_msg = '<br />' . sprintf(
462
-                    esc_html__(
463
-                        'Make sure you have %1$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class',
464
-                        'event_espresso'
465
-                    ),
466
-                    '<strong>' . $class_name . '</strong>'
467
-                );
468
-            $error_msg[]     = sprintf(
469
-                __('Something went wrong with loading the %s admin page.', 'event_espresso'),
470
-                $page
471
-            );
472
-            $error_msg[]     = $error_msg[0]
473
-                               . "\r\n"
474
-                               . sprintf(
475
-                                   esc_html__(
476
-                                       'There is no Init class in place for the %s admin page.',
477
-                                       'event_espresso'
478
-                                   ),
479
-                                   $page
480
-                               )
481
-                               . $inner_error_msg;
482
-            throw new EE_Error(implode('||', $error_msg));
483
-        }
484
-        $a = new ReflectionClass($class_name);
485
-        return $a->newInstance();
486
-    }
487
-
488
-
489
-
490
-    /**
491
-     * set_menus
492
-     * This method sets up the menus for EE Admin Pages
493
-     *
494
-     * @access private
495
-     * @return void
496
-     */
497
-    public function set_menus()
498
-    {
499
-        //prep the menu pages (sort, group.)
500
-        $this->_prep_pages();
501
-        foreach ($this->_prepped_menu_maps as $menu_map) {
502
-            if (EE_Registry::instance()->CAP->current_user_can($menu_map->capability, $menu_map->menu_slug)) {
503
-                $menu_map->add_menu_page(false);
504
-            }
505
-        }
506
-    }
507
-
508
-
509
-    /**
510
-     * set_network_menus
511
-     * This method sets up the menus for network EE Admin Pages.
512
-     * Almost identical to EE_Admin_Page_Loader::set_menus() except pages
513
-     * are only added to the menu map if they are intended for the admin menu
514
-     *
515
-     * @return void
516
-     */
517
-    public function set_network_menus()
518
-    {
519
-        $this->_prep_pages();
520
-        foreach ($this->_prepped_menu_maps as $menu_map) {
521
-            if (EE_Registry::instance()->CAP->current_user_can($menu_map->capability, $menu_map->menu_slug)) {
522
-                $menu_map->add_menu_page(true);
523
-            }
524
-        }
525
-    }
526
-
527
-
528
-
529
-    /**
530
-     * _prep_pages
531
-     * sets the _prepped_menu_maps property
532
-     *
533
-     * @access private
534
-     * @throws EE_Error
535
-     * @return void
536
-     */
537
-    private function _prep_pages()
538
-    {
539
-        $pages_array = array();
540
-        //rearrange _admin_menu_groups to be indexed by group slug.
541
-        $menu_groups = $this->_rearrange_menu_groups();
542
-        foreach ($this->_installed_pages as $page) {
543
-            if ($page instanceof EE_Admin_page_Init) {
544
-                $page_map = $page->get_menu_map();
545
-                //if we've got an array then the menu map is in the old format so let's throw a persistent notice that the admin system isn't setup correctly for this item.
546
-                if (is_array($page_map) || empty($page_map)) {
547
-                      new PersistentAdminNotice(
548
-                        'menu_map_warning_' . str_replace(' ', '_', $page->label) . '_' . EVENT_ESPRESSO_VERSION,
549
-                        sprintf(
550
-                            __(
551
-                                'The admin page for %s was not correctly setup because it is using an older method for integrating with Event Espresso Core.  This means that full functionality for this component is not available.  This error message usually appears with an Add-on that is out of date.  Make sure you update all your Event Espresso 4 add-ons to the latest version to ensure they have necessary compatibility updates in place.',
552
-                                'event_espresso'
553
-                            ),
554
-                            $page->label
555
-                        )
556
-                    );
557
-                    continue;
558
-                }
559
-                //if page map is NOT a EE_Admin_Page_Menu_Map object then throw error.
560
-                if (! $page_map instanceof EE_Admin_Page_Menu_Map) {
561
-                    throw new EE_Error(
562
-                        sprintf(
563
-                            __(
564
-                                'The menu map for %s must be an EE_Admin_Page_Menu_Map object.  Instead it is %s.  Please double check that the menu map has been configured correctly.',
565
-                                'event_espresso'
566
-                            ),
567
-                            $page->label,
568
-                            $page_map
569
-                        )
570
-                    );
571
-                }
572
-                //use the maintenance_mode_parent property and maintenance mode status to determine if this page even gets added to array.
573
-                if (empty($page_map->maintenance_mode_parent)
574
-                    && EE_Maintenance_Mode::instance()->level()
575
-                       == EE_Maintenance_Mode::level_2_complete_maintenance) {
576
-                    continue;
577
-                }
578
-                //assign to group (remember $page_map has the admin page stored in it).
579
-                $pages_array[$page_map->menu_group][] = $page_map;
580
-            }
581
-        }
582
-        if (empty($pages_array)) {
583
-            throw new EE_Error(__('Something went wrong when prepping the admin pages', 'event_espresso'));
584
-        }
585
-        //let's sort the groups, make sure it's a valid group, add header (if to show).
586
-        foreach ($pages_array as $group => $menu_maps) {
587
-            //valid_group?
588
-            if (! array_key_exists($group, $menu_groups)) {
589
-                continue;
590
-            }
591
-            //sort pages.
592
-            usort($menu_maps, array($this, '_sort_menu_maps'));
593
-            //prepend header
594
-            array_unshift($menu_maps, $menu_groups[$group]);
595
-            //reset $pages_array with prepped data
596
-            $pages_array[$group] = $menu_maps;
597
-        }
598
-        //now let's setup the _prepped_menu_maps property
599
-        foreach ($menu_groups as $group => $group_objs) {
600
-            if (isset($pages_array[$group])) {
601
-                $this->_prepped_menu_maps = array_merge($this->_prepped_menu_maps, $pages_array[$group]);
602
-            }
603
-        }/**/
604
-    }
605
-
606
-
607
-    /**
608
-     * This method is the "workhorse" for detecting and setting up caffeinated functionality.
609
-     * In this method there are three checks being done:
610
-     * 1. Do we have any NEW admin page sets.  If we do, lets add them into the menu setup (via the $installed_refs
611
-     * array) etc.  (new page sets are found in caffeinated/new/{page})
612
-     * 2. Do we have any EXTENDED page sets.  Basically an extended EE_Admin Page extends the core {child}_Admin_Page
613
-     * class.  eg. would be caffeinated/extend/events/Extend_Events_Admin_Page.core.php and in there would be a class:
614
-     * Extend_Events_Admin_Page extends Events_Admin_Page.
615
-     * 3. Do we have any files just for setting up hooks into other core pages.  The files can be any name in
616
-     * "caffeinated/hooks" EXCEPT they need a ".class.php" extension and the file name must correspond with the
617
-     * classname inside.  These classes are instantiated really early so that any hooks in them are run before the
618
-     * corresponding apply_filters/do_actions that are found in any future loaded EE_Admin pages (INCLUDING caffeinated
619
-     * admin_pages)
620
-     *
621
-     * @param array $installed_refs the original installed_refs array that may contain our NEW EE_Admin_Pages to be
622
-     *                              loaded.
623
-     * @return array
624
-     */
625
-    private function _set_caffeinated($installed_refs)
626
-    {
627
-
628
-        //first let's check if there IS a caffeinated folder. If there is not then lets get out.
629
-        if (! is_dir(EE_PLUGIN_DIR_PATH . 'caffeinated' . DS . 'admin') || (defined('EE_DECAF') && EE_DECAF)) {
630
-            return $installed_refs;
631
-        }
632
-        $this->_define_caffeinated_constants();
633
-        $exclude = array('tickets');
634
-        //okay let's setup an "New" pages first (we'll return installed refs later)
635
-        $new_admin_screens = glob(EE_CORE_CAF_ADMIN . 'new/*', GLOB_ONLYDIR);
636
-        if ($new_admin_screens) {
637
-            foreach ($new_admin_screens as $admin_screen) {
638
-                // files and anything in the exclude array need not apply
639
-                if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) {
640
-                    // these folders represent the different NEW EE admin pages
641
-                    $installed_refs[basename($admin_screen)] = $admin_screen;
642
-                    // set autoloaders for our admin page classes based on included path information
643
-                    EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($admin_screen);
644
-                    //					$this->_caf_autoloader[] = array(
645
-                    //						'dir' => 'new',
646
-                    //						'folder' => basename( $admin_screen )
647
-                    //					);
648
-                }
649
-            }
650
-        }
651
-        //let's see if there are any EXTENDS to setup in the $_caffeinated_extends array (that will be used later for hooking into the _initialize_admin_age in the related core_init admin page)
652
-        $extends = glob(EE_CORE_CAF_ADMIN . 'extend/*', GLOB_ONLYDIR);
653
-        if ($extends) {
654
-            foreach ($extends as $extend) {
655
-                if (is_dir($extend)) {
656
-                    $extend_ref = basename($extend);
657
-                    //now let's make sure there is a file that matches the expected format
658
-                    $filename                                              = str_replace(
659
-                        ' ',
660
-                        '_',
661
-                        ucwords(
662
-                            str_replace(
663
-                                '_',
664
-                                ' ',
665
-                                $extend_ref
666
-                            )
667
-                        )
668
-                    );
669
-                    $filename                                              = 'Extend_' . $filename . '_Admin_Page';
670
-                    $this->_caffeinated_extends[$extend_ref]['path']       = str_replace(
671
-                        array('\\', '/'),
672
-                        DS,
673
-                        EE_CORE_CAF_ADMIN
674
-                        . 'extend'
675
-                        . DS
676
-                        . $extend_ref
677
-                        . DS
678
-                        . $filename
679
-                        . '.core.php'
680
-                    );
681
-                    $this->_caffeinated_extends[$extend_ref]['admin_page'] = $filename;
682
-                    // set autoloaders for our admin page classes based on included path information
683
-                    EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($extend);
684
-                    //					$this->_caf_autoloader[] = array(
685
-                    //						'dir' => 'extend',
686
-                    //						'folder' => $extend_ref
687
-                    //					);
688
-                }
689
-            }
690
-        }
691
-        //let's see if there are any HOOK files and instantiate them if there are (so that hooks are loaded early!).
692
-        $ee_admin_hooks = array();
693
-        $hooks          = glob(EE_CORE_CAF_ADMIN . 'hooks/*.class.php');
694
-        if ($hooks) {
695
-            foreach ($hooks as $hook) {
696
-                if (is_readable($hook)) {
697
-                    require_once $hook;
698
-                    $classname = str_replace(EE_CORE_CAF_ADMIN . 'hooks/', '', $hook);
699
-                    $classname = str_replace('.class.php', '', $classname);
700
-                    if (class_exists($classname)) {
701
-                        $a                = new ReflectionClass($classname);
702
-                        $ee_admin_hooks[] = $a->newInstance();
703
-                    }
704
-                }
705
-            }
706
-        }/**/
707
-        $ee_admin_hooks = apply_filters('FHEE__EE_Admin_Page_Loader__set_caffeinated__ee_admin_hooks', $ee_admin_hooks);
708
-        return $installed_refs;
709
-    }
710
-
711
-
712
-
713
-
714
-
715
-    /**
716
-     * Initial autoloader registration
717
-     * This just sets up the autoloader for the root admin files
718
-     *
719
-     * @param  string $className incoming classname to check for autoload
720
-     * @return void
721
-     */
722
-    //	public function init_autoloaders( $className ) {
723
-    //		$dir_ref = array(
724
-    //			EE_ADMIN => array('core', 'class')
725
-    //		);
726
-    //		EEH_Autoloader::try_autoload($dir_ref, $className );
727
-    //	}
728
-    /**
729
-     * This method takes care of setting up the autoloader dynamically for any NEW EE_Admin pages found in the
730
-     * caffeinated folders.
731
-     *
732
-     * @access public
733
-     * @param  string $className in coming classname being called
734
-     * @return void
735
-     */
736
-    //	public function caffeinated_autoloaders( $className ) {
737
-    //		//let's setup an array of paths to check (for each subsystem)
738
-    //		$dir_ref = array();
739
-    //		foreach ( $this->_caf_autoloader as $pathinfo) {
740
-    //			$dir_ref[ EE_CORE_CAF_ADMIN . $pathinfo['dir'] . DS . $pathinfo['folder'] . DS] = array('core', 'class');
741
-    //		}
742
-    //
743
-    //		EEH_Autoloader::try_autoload($dir_ref, $className );
744
-    //	}
745
-    /**
746
-     * Utility method for sorting the _menu_maps (callback for usort php function)
747
-     *
748
-     * @since  4.4.0
749
-     * @param  EE_Admin_Page_Menu_Map $a menu_map object
750
-     * @param  EE_Admin_Page_Menu_Map $b being compared to
751
-     * @return int    sort order
752
-     */
753
-    private function _sort_menu_maps(EE_Admin_Page_Menu_Map $a, EE_Admin_Page_Menu_Map $b)
754
-    {
755
-        if ($a->menu_order == $b->menu_order) {
756
-            return 0;
757
-        }
758
-        return ($a->menu_order < $b->menu_order) ? -1 : 1;
759
-    }
760
-
761
-
762
-
763
-    /**
764
-     * _default_header_link
765
-     * This is just a dummy method to use with header submenu items
766
-     *
767
-     * @return bool false
768
-     */
769
-    public function _default_header_link()
770
-    {
771
-        return false;
772
-    }
31
+	/**
32
+	 * _installed_pages
33
+	 * objects for page_init objects detected and loaded
34
+	 *
35
+	 * @access private
36
+	 * @var \EE_Admin_Page_Init[]
37
+	 */
38
+	private $_installed_pages = array();
39
+
40
+
41
+
42
+	/**
43
+	 * this is used to hold the registry of menu slugs for all the installed admin pages
44
+	 *
45
+	 * @var array
46
+	 */
47
+	private $_menu_slugs = array();
48
+
49
+
50
+	/**
51
+	 * _caffeinated_extends
52
+	 * This array is the generated configuration array for which core EE_Admin pages are extended (and the bits and
53
+	 * pieces needed to do so).  This property is defined in the _set_caffeinated method.
54
+	 *
55
+	 * @var array
56
+	 */
57
+	private $_caffeinated_extends = array();
58
+
59
+
60
+
61
+	/**
62
+	 * _current_caf_extend_slug
63
+	 * This property is used for holding the page slug that is required for referencing the correct
64
+	 * _caffeinated_extends index when the corresponding core child EE_Admin_Page_init hooks are executed.
65
+	 *
66
+	 * @var array
67
+	 */
68
+	private $_current_caf_extend_slug;
69
+
70
+
71
+
72
+	/**
73
+	 * _caf_autoloader
74
+	 * This property is used for holding an array of folder names of any NEW EE_Admin_Pages found in the
75
+	 * caffeinated/new directory.  This array is then used to setup a corresponding dynamic autoloader for these pages
76
+	 * classes.
77
+	 *
78
+	 * @var array
79
+	 */
80
+	//	private $_caf_autoloader = array();
81
+	/**
82
+	 * _prepped_menu_maps
83
+	 * This is the prepared array of EE_Admin_Page_Menu_Maps for adding to the admin_menu.
84
+	 *
85
+	 * @since  4.4.0
86
+	 * @var EE_Admin_Page_Menu_Map[]
87
+	 */
88
+	private $_prepped_menu_maps = array();
89
+
90
+
91
+
92
+	/**
93
+	 * _admin_menu_groups
94
+	 * array that holds the group headings and details for
95
+	 *
96
+	 * @access private
97
+	 * @var array
98
+	 */
99
+	private $_admin_menu_groups = array();
100
+
101
+
102
+
103
+	/**
104
+	 * This property will hold the hook file for setting up the filter that does all the connections between admin
105
+	 * pages.
106
+	 *
107
+	 * @var string
108
+	 */
109
+	public $hook_file;
110
+
111
+
112
+
113
+	/**
114
+	 * constructor
115
+	 *
116
+	 * @access public
117
+	 * @return \EE_Admin_Page_Loader
118
+	 */
119
+	public function __construct()
120
+	{
121
+		//load menu_map classes
122
+		EE_Registry::instance()->load_file(EE_ADMIN, 'EE_Admin_Page_Menu_Map', 'core');
123
+		//define the default "groups" for the admin_pages
124
+		$this->_set_menu_groups();
125
+		//let's set default autoloaders.  Note that this just sets autoloaders for root admin files.
126
+		//		spl_autoload_register( array( $this, 'init_autoloaders') );
127
+		//let's do a scan and see what installed pages we have
128
+		$this->_get_installed_pages();
129
+		//set menus (has to be done on every load - we're not actually loading the page just setting the menus and where they point to).
130
+		add_action('admin_menu', array($this, 'set_menus'));
131
+		add_action('network_admin_menu', array($this, 'set_network_menus'));
132
+	}
133
+
134
+
135
+
136
+	/**
137
+	 * When caffeinated system is detected, this method is called to setup the caffeinated directory constants used by
138
+	 * files in the caffeinated folder.
139
+	 *
140
+	 * @access private
141
+	 * @return void
142
+	 */
143
+	private function _define_caffeinated_constants()
144
+	{
145
+		if (! defined('EE_CORE_CAF_ADMIN')) {
146
+			define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH . 'caffeinated/admin/');
147
+			define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL . 'caffeinated/admin/');
148
+			define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN . 'new/');
149
+			define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN . 'extend/');
150
+			define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL . 'extend/');
151
+			define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN . 'hooks/');
152
+		}
153
+	}
154
+
155
+
156
+
157
+	/**
158
+	 * _set_menu_groups
159
+	 * sets the filterable _admin_menu_groups property (list of various "groupings" within the EE admin menu array)
160
+	 *
161
+	 * @access private
162
+	 * @return void
163
+	 */
164
+	private function _set_menu_groups()
165
+	{
166
+
167
+		//set array of EE_Admin_Page_Menu_Group objects
168
+		$groups = array(
169
+			'main'       => new EE_Admin_Page_Menu_Group(
170
+				array(
171
+					'menu_label'   => __('Main', 'event_espresso'),
172
+					'show_on_menu' => EE_Admin_Page_Menu_Map::NONE,
173
+					'menu_slug'    => 'main',
174
+					'capability'   => 'ee_read_ee',
175
+					'menu_order'   => 0,
176
+					'parent_slug'  => 'espresso_events',
177
+				)
178
+			),
179
+			'management' => new EE_Admin_Page_Menu_Group(
180
+				array(
181
+					'menu_label'   => __('Management', 'event_espresso'),
182
+					'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
183
+					'menu_slug'    => 'management',
184
+					'capability'   => 'ee_read_ee',
185
+					'menu_order'   => 10,
186
+					'parent_slug'  => 'espresso_events',
187
+				)
188
+			),
189
+			'settings'   => new EE_Admin_Page_Menu_Group(
190
+				array(
191
+					'menu_label'   => __('Settings', 'event_espresso'),
192
+					'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
193
+					'menu_slug'    => 'settings',
194
+					'capability'   => 'ee_read_ee',
195
+					'menu_order'   => 30,
196
+					'parent_slug'  => 'espresso_events',
197
+				)
198
+			),
199
+			'templates'  => new EE_Admin_Page_Menu_Group(
200
+				array(
201
+					'menu_label'   => __('Templates', 'event_espresso'),
202
+					'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
203
+					'menu_slug'    => 'templates',
204
+					'capability'   => 'ee_read_ee',
205
+					'menu_order'   => 40,
206
+					'parent_slug'  => 'espresso_events',
207
+				)
208
+			),
209
+			'extras'     => new EE_Admin_Page_Menu_Group(
210
+				array(
211
+					'menu_label'              => __('Extras', 'event_espresso'),
212
+					'show_on_menu'            => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN,
213
+					'menu_slug'               => 'extras',
214
+					'capability'              => 'ee_read_ee',
215
+					'menu_order'              => 50,
216
+					'parent_slug'             => 'espresso_events',
217
+					'maintenance_mode_parent' => 'espresso_maintenance_settings',
218
+				)
219
+			),
220
+			'tools'      => new EE_Admin_Page_Menu_Group(
221
+				array(
222
+					'menu_label'   => __("Tools", "event_espresso"),
223
+					'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
224
+					'menu_slug'    => 'tools',
225
+					'capability'   => 'ee_read_ee',
226
+					'menu_order'   => 60,
227
+					'parent_slug'  => 'espresso_events',
228
+				)
229
+			),
230
+			'addons'     => new EE_Admin_Page_Menu_Group(
231
+				array(
232
+					'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN,
233
+					'menu_label'   => __('Add-ons', 'event_espresso'),
234
+					'menu_slug'    => 'addons',
235
+					'capability'   => 'ee_read_ee',
236
+					'menu_order'   => 20,
237
+					'parent_slug'  => 'espresso_events',
238
+				)
239
+			),
240
+		);
241
+		$this->_admin_menu_groups = apply_filters(
242
+			'FHEE__EE_Admin_Page_Loader___set_menu_groups__admin_menu_groups',
243
+			$groups
244
+		);
245
+	}
246
+
247
+
248
+
249
+	/**
250
+	 * This takes all the groups in the _admin_menu_groups array and returns the array indexed by group
251
+	 * slug.  The other utility with this function is it validates that all the groups are instances of
252
+	 * EE_Admin_Page_Menu_Group (cause some invalid things might have slipped in via addons).
253
+	 *
254
+	 * @since  4.4.0
255
+	 * @throws \EE_Error
256
+	 * @return EE_Admin_Page_Menu_Group[]
257
+	 */
258
+	private function _rearrange_menu_groups()
259
+	{
260
+		$groups = array();
261
+		//first let's order the menu groups by their internal menu order (note usort type hinting to ensure the incoming array is EE_Admin_Page_Menu_Map objects )
262
+		usort($this->_admin_menu_groups, array($this, '_sort_menu_maps'));
263
+		foreach ($this->_admin_menu_groups as $group) {
264
+			if (! $group instanceof EE_Admin_Page_Menu_Group) {
265
+				throw new EE_Error(
266
+					sprintf(
267
+						__(
268
+							'Unable to continue sorting the menu groups array because there is an invalid value for the menu groups.  All values in this array are required to be a EE_Admin_Page_Menu_Group object.  Instead there was: %s',
269
+							'event_espresso'
270
+						),
271
+						print_r($group, true)
272
+					)
273
+				);
274
+			}
275
+			$groups[$group->menu_slug] = $group;
276
+		}
277
+		return $groups;
278
+	}
279
+
280
+
281
+
282
+	/**
283
+	 * _get_installed_pages
284
+	 * This just gets the list of installed EE_Admin_pages.
285
+	 *
286
+	 * @access private
287
+	 * @throws EE_Error
288
+	 * @return void
289
+	 */
290
+	private function _get_installed_pages()
291
+	{
292
+		$installed_refs = array();
293
+		$exclude        = array('assets', 'templates');
294
+		// grab everything in the  admin core directory
295
+		$admin_screens = glob(EE_ADMIN_PAGES . '*', GLOB_ONLYDIR);
296
+		if ($admin_screens) {
297
+			foreach ($admin_screens as $admin_screen) {
298
+				// files and anything in the exclude array need not apply
299
+				if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) {
300
+					// these folders represent the different EE admin pages
301
+					$installed_refs[basename($admin_screen)] = $admin_screen;
302
+				}
303
+			}
304
+		}
305
+		if (empty($installed_refs)) {
306
+			$error_msg[] = __(
307
+				'There are no EE_Admin pages detected, it looks like EE did not install properly',
308
+				'event_espresso'
309
+			);
310
+			$error_msg[] = $error_msg[0] . "\r\n" . sprintf(
311
+					__(
312
+						'Check that the %s folder exists and is writable. Maybe try deactivating, then reactivating Event Espresso again.',
313
+						'event_espresso'
314
+					),
315
+					EE_ADMIN_PAGES
316
+				);
317
+			throw new EE_Error(implode('||', $error_msg));
318
+		}
319
+		//this just checks the caffeinated folder and takes care of setting up any caffeinated stuff.
320
+		$installed_refs = $this->_set_caffeinated($installed_refs);
321
+		//allow plugins to add in their own pages (note at this point they will need to have an autoloader defined for their class) OR hook into EEH_Autoloader::load_admin_page() to add their path.;
322
+		$installed_refs             = apply_filters(
323
+			'FHEE__EE_Admin_Page_Loader___get_installed_pages__installed_refs',
324
+			$installed_refs
325
+		);
326
+		$this->_caffeinated_extends = apply_filters(
327
+			'FHEE__EE_Admin_Page_Loader___get_installed_pages__caffeinated_extends',
328
+			$this->_caffeinated_extends
329
+		);
330
+		//loop through admin pages and setup the $_installed_pages array.
331
+		$hooks_ref = array();
332
+		foreach ($installed_refs as $page => $path) {
333
+			// set autoloaders for our admin page classes based on included path information
334
+			EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($path);
335
+			// build list of installed pages
336
+			$this->_installed_pages[$page] = $this->_load_admin_page($page, $path);
337
+			// verify returned object
338
+			if ($this->_installed_pages[$page] instanceof EE_Admin_Page_Init) {
339
+				if (! $this->_installed_pages[$page]->get_menu_map() instanceof EE_Admin_Page_Menu_Map) {
340
+					continue;
341
+				}
342
+				//skip if in full maintenance mode and maintenance_mode_parent is set
343
+				$maintenance_mode_parent = $this->_installed_pages[$page]->get_menu_map()->maintenance_mode_parent;
344
+				if (empty($maintenance_mode_parent)
345
+					&& EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance
346
+				) {
347
+					unset($installed_refs[$page]);
348
+					continue;
349
+				}
350
+				$menu_slug = $this->_installed_pages[$page]->get_menu_map()->menu_slug;
351
+				$this->_menu_slugs[$menu_slug] = $page;
352
+				//flag for register hooks on extended pages b/c extended pages use the default INIT.
353
+				$extend = false;
354
+				//now that we've got the admin_init objects... lets see if there are any caffeinated pages extending the originals.  If there are then let's hook into the init admin filter and load our extend instead.
355
+				if (isset($this->_caffeinated_extends[$page])) {
356
+					$this->_current_caf_extend_slug = $page;
357
+					$admin_page_name = $this->_installed_pages[$page]->get_admin_page_name();
358
+					$caf_path = $this->_caffeinated_extends[$this->_current_caf_extend_slug]['path'];
359
+					$caf_admin_page = $this->_caffeinated_extends[$this->_current_caf_extend_slug]['admin_page'];
360
+					add_filter(
361
+						"FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$menu_slug}_{$admin_page_name}",
362
+						function($path_to_file) use ($caf_path) {
363
+							return $caf_path;
364
+						}
365
+					);
366
+					add_filter(
367
+						"FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$menu_slug}_{$admin_page_name}",
368
+						function ($admin_page) use ($caf_admin_page)
369
+						{
370
+							return $caf_admin_page;
371
+						}
372
+					);
373
+					$extend = true;
374
+				}
375
+				//let's do the registered hooks
376
+				$extended_hooks = $this->_installed_pages[$page]->register_hooks($extend);
377
+				$hooks_ref      = array_merge($hooks_ref, $extended_hooks);
378
+			}
379
+		}
380
+		//the hooks_ref is all the pages where we have $extended _Hooks files that will extend a class in a different folder.  So we want to make sure we load the file for the parent.
381
+		//first make sure we've got unique values
382
+		$hooks_ref = array_unique($hooks_ref);
383
+		//now let's loop and require!
384
+		foreach ($hooks_ref as $path) {
385
+			require_once($path);
386
+		}
387
+		//make sure we have menu slugs global setup. Used in EE_Admin_Page->page_setup() to ensure we don't do a full class load for an admin page that isn't requested.
388
+		global $ee_menu_slugs;
389
+		$ee_menu_slugs = $this->_menu_slugs;
390
+		//we need to loop again to run any early code
391
+		foreach ($installed_refs as $page => $path) {
392
+			if ($this->_installed_pages[$page] instanceof EE_Admin_Page_Init) {
393
+				$this->_installed_pages[$page]->do_initial_loads();
394
+			}
395
+		}
396
+		do_action('AHEE__EE_Admin_Page_Loader___get_installed_pages_loaded', $this->_installed_pages);
397
+	}
398
+
399
+
400
+
401
+	/**
402
+	 * get_admin_page_object
403
+	 *
404
+	 * @param string $page_slug
405
+	 * @return EE_Admin_Page
406
+	 */
407
+	public function get_admin_page_object($page_slug = '')
408
+	{
409
+		if (isset($this->_installed_pages[$page_slug])) {
410
+			return $this->_installed_pages[$page_slug]->loaded_page_object();
411
+		}
412
+		return null;
413
+	}
414
+
415
+
416
+
417
+	/**
418
+	 * _get_classname_for_admin_page
419
+	 * generates an "Admin Page" class based on the directory  name
420
+	 *
421
+	 * @param $dir_name
422
+	 * @return string
423
+	 */
424
+	private function _get_classname_for_admin_page($dir_name = '')
425
+	{
426
+		$class_name = str_replace('_', ' ', strtolower($dir_name));
427
+		return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page';
428
+	}
429
+
430
+
431
+
432
+	/**
433
+	 * _get_classname_for_admin_init_page
434
+	 * generates an "Admin Page Init" class based on the directory  name
435
+	 *
436
+	 * @param $dir_name
437
+	 * @return string
438
+	 */
439
+	private function _get_classname_for_admin_init_page($dir_name = '')
440
+	{
441
+		$class_name = str_replace('_', ' ', strtolower($dir_name));
442
+		return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page_Init';
443
+	}
444
+
445
+
446
+
447
+	/**
448
+	 * _load_admin_page
449
+	 * Loads and instantiates page_init object for a single EE_admin page.
450
+	 *
451
+	 * @param  string $page page_reference
452
+	 * @param string  $path
453
+	 * @throws EE_Error
454
+	 * @return object|bool  return page object if valid, bool false if not.
455
+	 */
456
+	private function _load_admin_page($page = '', $path = '')
457
+	{
458
+		$class_name = $this->_get_classname_for_admin_init_page($page);
459
+		EE_Registry::instance()->load_file($path, $class_name, 'core');
460
+		if (! class_exists($class_name)) {
461
+			$inner_error_msg = '<br />' . sprintf(
462
+					esc_html__(
463
+						'Make sure you have %1$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class',
464
+						'event_espresso'
465
+					),
466
+					'<strong>' . $class_name . '</strong>'
467
+				);
468
+			$error_msg[]     = sprintf(
469
+				__('Something went wrong with loading the %s admin page.', 'event_espresso'),
470
+				$page
471
+			);
472
+			$error_msg[]     = $error_msg[0]
473
+							   . "\r\n"
474
+							   . sprintf(
475
+								   esc_html__(
476
+									   'There is no Init class in place for the %s admin page.',
477
+									   'event_espresso'
478
+								   ),
479
+								   $page
480
+							   )
481
+							   . $inner_error_msg;
482
+			throw new EE_Error(implode('||', $error_msg));
483
+		}
484
+		$a = new ReflectionClass($class_name);
485
+		return $a->newInstance();
486
+	}
487
+
488
+
489
+
490
+	/**
491
+	 * set_menus
492
+	 * This method sets up the menus for EE Admin Pages
493
+	 *
494
+	 * @access private
495
+	 * @return void
496
+	 */
497
+	public function set_menus()
498
+	{
499
+		//prep the menu pages (sort, group.)
500
+		$this->_prep_pages();
501
+		foreach ($this->_prepped_menu_maps as $menu_map) {
502
+			if (EE_Registry::instance()->CAP->current_user_can($menu_map->capability, $menu_map->menu_slug)) {
503
+				$menu_map->add_menu_page(false);
504
+			}
505
+		}
506
+	}
507
+
508
+
509
+	/**
510
+	 * set_network_menus
511
+	 * This method sets up the menus for network EE Admin Pages.
512
+	 * Almost identical to EE_Admin_Page_Loader::set_menus() except pages
513
+	 * are only added to the menu map if they are intended for the admin menu
514
+	 *
515
+	 * @return void
516
+	 */
517
+	public function set_network_menus()
518
+	{
519
+		$this->_prep_pages();
520
+		foreach ($this->_prepped_menu_maps as $menu_map) {
521
+			if (EE_Registry::instance()->CAP->current_user_can($menu_map->capability, $menu_map->menu_slug)) {
522
+				$menu_map->add_menu_page(true);
523
+			}
524
+		}
525
+	}
526
+
527
+
528
+
529
+	/**
530
+	 * _prep_pages
531
+	 * sets the _prepped_menu_maps property
532
+	 *
533
+	 * @access private
534
+	 * @throws EE_Error
535
+	 * @return void
536
+	 */
537
+	private function _prep_pages()
538
+	{
539
+		$pages_array = array();
540
+		//rearrange _admin_menu_groups to be indexed by group slug.
541
+		$menu_groups = $this->_rearrange_menu_groups();
542
+		foreach ($this->_installed_pages as $page) {
543
+			if ($page instanceof EE_Admin_page_Init) {
544
+				$page_map = $page->get_menu_map();
545
+				//if we've got an array then the menu map is in the old format so let's throw a persistent notice that the admin system isn't setup correctly for this item.
546
+				if (is_array($page_map) || empty($page_map)) {
547
+					  new PersistentAdminNotice(
548
+						'menu_map_warning_' . str_replace(' ', '_', $page->label) . '_' . EVENT_ESPRESSO_VERSION,
549
+						sprintf(
550
+							__(
551
+								'The admin page for %s was not correctly setup because it is using an older method for integrating with Event Espresso Core.  This means that full functionality for this component is not available.  This error message usually appears with an Add-on that is out of date.  Make sure you update all your Event Espresso 4 add-ons to the latest version to ensure they have necessary compatibility updates in place.',
552
+								'event_espresso'
553
+							),
554
+							$page->label
555
+						)
556
+					);
557
+					continue;
558
+				}
559
+				//if page map is NOT a EE_Admin_Page_Menu_Map object then throw error.
560
+				if (! $page_map instanceof EE_Admin_Page_Menu_Map) {
561
+					throw new EE_Error(
562
+						sprintf(
563
+							__(
564
+								'The menu map for %s must be an EE_Admin_Page_Menu_Map object.  Instead it is %s.  Please double check that the menu map has been configured correctly.',
565
+								'event_espresso'
566
+							),
567
+							$page->label,
568
+							$page_map
569
+						)
570
+					);
571
+				}
572
+				//use the maintenance_mode_parent property and maintenance mode status to determine if this page even gets added to array.
573
+				if (empty($page_map->maintenance_mode_parent)
574
+					&& EE_Maintenance_Mode::instance()->level()
575
+					   == EE_Maintenance_Mode::level_2_complete_maintenance) {
576
+					continue;
577
+				}
578
+				//assign to group (remember $page_map has the admin page stored in it).
579
+				$pages_array[$page_map->menu_group][] = $page_map;
580
+			}
581
+		}
582
+		if (empty($pages_array)) {
583
+			throw new EE_Error(__('Something went wrong when prepping the admin pages', 'event_espresso'));
584
+		}
585
+		//let's sort the groups, make sure it's a valid group, add header (if to show).
586
+		foreach ($pages_array as $group => $menu_maps) {
587
+			//valid_group?
588
+			if (! array_key_exists($group, $menu_groups)) {
589
+				continue;
590
+			}
591
+			//sort pages.
592
+			usort($menu_maps, array($this, '_sort_menu_maps'));
593
+			//prepend header
594
+			array_unshift($menu_maps, $menu_groups[$group]);
595
+			//reset $pages_array with prepped data
596
+			$pages_array[$group] = $menu_maps;
597
+		}
598
+		//now let's setup the _prepped_menu_maps property
599
+		foreach ($menu_groups as $group => $group_objs) {
600
+			if (isset($pages_array[$group])) {
601
+				$this->_prepped_menu_maps = array_merge($this->_prepped_menu_maps, $pages_array[$group]);
602
+			}
603
+		}/**/
604
+	}
605
+
606
+
607
+	/**
608
+	 * This method is the "workhorse" for detecting and setting up caffeinated functionality.
609
+	 * In this method there are three checks being done:
610
+	 * 1. Do we have any NEW admin page sets.  If we do, lets add them into the menu setup (via the $installed_refs
611
+	 * array) etc.  (new page sets are found in caffeinated/new/{page})
612
+	 * 2. Do we have any EXTENDED page sets.  Basically an extended EE_Admin Page extends the core {child}_Admin_Page
613
+	 * class.  eg. would be caffeinated/extend/events/Extend_Events_Admin_Page.core.php and in there would be a class:
614
+	 * Extend_Events_Admin_Page extends Events_Admin_Page.
615
+	 * 3. Do we have any files just for setting up hooks into other core pages.  The files can be any name in
616
+	 * "caffeinated/hooks" EXCEPT they need a ".class.php" extension and the file name must correspond with the
617
+	 * classname inside.  These classes are instantiated really early so that any hooks in them are run before the
618
+	 * corresponding apply_filters/do_actions that are found in any future loaded EE_Admin pages (INCLUDING caffeinated
619
+	 * admin_pages)
620
+	 *
621
+	 * @param array $installed_refs the original installed_refs array that may contain our NEW EE_Admin_Pages to be
622
+	 *                              loaded.
623
+	 * @return array
624
+	 */
625
+	private function _set_caffeinated($installed_refs)
626
+	{
627
+
628
+		//first let's check if there IS a caffeinated folder. If there is not then lets get out.
629
+		if (! is_dir(EE_PLUGIN_DIR_PATH . 'caffeinated' . DS . 'admin') || (defined('EE_DECAF') && EE_DECAF)) {
630
+			return $installed_refs;
631
+		}
632
+		$this->_define_caffeinated_constants();
633
+		$exclude = array('tickets');
634
+		//okay let's setup an "New" pages first (we'll return installed refs later)
635
+		$new_admin_screens = glob(EE_CORE_CAF_ADMIN . 'new/*', GLOB_ONLYDIR);
636
+		if ($new_admin_screens) {
637
+			foreach ($new_admin_screens as $admin_screen) {
638
+				// files and anything in the exclude array need not apply
639
+				if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) {
640
+					// these folders represent the different NEW EE admin pages
641
+					$installed_refs[basename($admin_screen)] = $admin_screen;
642
+					// set autoloaders for our admin page classes based on included path information
643
+					EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($admin_screen);
644
+					//					$this->_caf_autoloader[] = array(
645
+					//						'dir' => 'new',
646
+					//						'folder' => basename( $admin_screen )
647
+					//					);
648
+				}
649
+			}
650
+		}
651
+		//let's see if there are any EXTENDS to setup in the $_caffeinated_extends array (that will be used later for hooking into the _initialize_admin_age in the related core_init admin page)
652
+		$extends = glob(EE_CORE_CAF_ADMIN . 'extend/*', GLOB_ONLYDIR);
653
+		if ($extends) {
654
+			foreach ($extends as $extend) {
655
+				if (is_dir($extend)) {
656
+					$extend_ref = basename($extend);
657
+					//now let's make sure there is a file that matches the expected format
658
+					$filename                                              = str_replace(
659
+						' ',
660
+						'_',
661
+						ucwords(
662
+							str_replace(
663
+								'_',
664
+								' ',
665
+								$extend_ref
666
+							)
667
+						)
668
+					);
669
+					$filename                                              = 'Extend_' . $filename . '_Admin_Page';
670
+					$this->_caffeinated_extends[$extend_ref]['path']       = str_replace(
671
+						array('\\', '/'),
672
+						DS,
673
+						EE_CORE_CAF_ADMIN
674
+						. 'extend'
675
+						. DS
676
+						. $extend_ref
677
+						. DS
678
+						. $filename
679
+						. '.core.php'
680
+					);
681
+					$this->_caffeinated_extends[$extend_ref]['admin_page'] = $filename;
682
+					// set autoloaders for our admin page classes based on included path information
683
+					EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($extend);
684
+					//					$this->_caf_autoloader[] = array(
685
+					//						'dir' => 'extend',
686
+					//						'folder' => $extend_ref
687
+					//					);
688
+				}
689
+			}
690
+		}
691
+		//let's see if there are any HOOK files and instantiate them if there are (so that hooks are loaded early!).
692
+		$ee_admin_hooks = array();
693
+		$hooks          = glob(EE_CORE_CAF_ADMIN . 'hooks/*.class.php');
694
+		if ($hooks) {
695
+			foreach ($hooks as $hook) {
696
+				if (is_readable($hook)) {
697
+					require_once $hook;
698
+					$classname = str_replace(EE_CORE_CAF_ADMIN . 'hooks/', '', $hook);
699
+					$classname = str_replace('.class.php', '', $classname);
700
+					if (class_exists($classname)) {
701
+						$a                = new ReflectionClass($classname);
702
+						$ee_admin_hooks[] = $a->newInstance();
703
+					}
704
+				}
705
+			}
706
+		}/**/
707
+		$ee_admin_hooks = apply_filters('FHEE__EE_Admin_Page_Loader__set_caffeinated__ee_admin_hooks', $ee_admin_hooks);
708
+		return $installed_refs;
709
+	}
710
+
711
+
712
+
713
+
714
+
715
+	/**
716
+	 * Initial autoloader registration
717
+	 * This just sets up the autoloader for the root admin files
718
+	 *
719
+	 * @param  string $className incoming classname to check for autoload
720
+	 * @return void
721
+	 */
722
+	//	public function init_autoloaders( $className ) {
723
+	//		$dir_ref = array(
724
+	//			EE_ADMIN => array('core', 'class')
725
+	//		);
726
+	//		EEH_Autoloader::try_autoload($dir_ref, $className );
727
+	//	}
728
+	/**
729
+	 * This method takes care of setting up the autoloader dynamically for any NEW EE_Admin pages found in the
730
+	 * caffeinated folders.
731
+	 *
732
+	 * @access public
733
+	 * @param  string $className in coming classname being called
734
+	 * @return void
735
+	 */
736
+	//	public function caffeinated_autoloaders( $className ) {
737
+	//		//let's setup an array of paths to check (for each subsystem)
738
+	//		$dir_ref = array();
739
+	//		foreach ( $this->_caf_autoloader as $pathinfo) {
740
+	//			$dir_ref[ EE_CORE_CAF_ADMIN . $pathinfo['dir'] . DS . $pathinfo['folder'] . DS] = array('core', 'class');
741
+	//		}
742
+	//
743
+	//		EEH_Autoloader::try_autoload($dir_ref, $className );
744
+	//	}
745
+	/**
746
+	 * Utility method for sorting the _menu_maps (callback for usort php function)
747
+	 *
748
+	 * @since  4.4.0
749
+	 * @param  EE_Admin_Page_Menu_Map $a menu_map object
750
+	 * @param  EE_Admin_Page_Menu_Map $b being compared to
751
+	 * @return int    sort order
752
+	 */
753
+	private function _sort_menu_maps(EE_Admin_Page_Menu_Map $a, EE_Admin_Page_Menu_Map $b)
754
+	{
755
+		if ($a->menu_order == $b->menu_order) {
756
+			return 0;
757
+		}
758
+		return ($a->menu_order < $b->menu_order) ? -1 : 1;
759
+	}
760
+
761
+
762
+
763
+	/**
764
+	 * _default_header_link
765
+	 * This is just a dummy method to use with header submenu items
766
+	 *
767
+	 * @return bool false
768
+	 */
769
+	public function _default_header_link()
770
+	{
771
+		return false;
772
+	}
773 773
 
774 774
 
775 775
 }
Please login to merge, or discard this patch.
Spacing   +31 added lines, -31 removed lines patch added patch discarded remove patch
@@ -2,7 +2,7 @@  discard block
 block discarded – undo
2 2
 use EventEspresso\core\domain\entities\notifications\PersistentAdminNotice;
3 3
 use EventEspresso\core\exceptions\InvalidDataTypeException;
4 4
 
5
-if (!defined('EVENT_ESPRESSO_VERSION') )
5
+if ( ! defined('EVENT_ESPRESSO_VERSION'))
6 6
 	exit('NO direct script access allowed');
7 7
 
8 8
 
@@ -142,13 +142,13 @@  discard block
 block discarded – undo
142 142
      */
143 143
     private function _define_caffeinated_constants()
144 144
     {
145
-        if (! defined('EE_CORE_CAF_ADMIN')) {
146
-            define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH . 'caffeinated/admin/');
147
-            define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL . 'caffeinated/admin/');
148
-            define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN . 'new/');
149
-            define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN . 'extend/');
150
-            define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL . 'extend/');
151
-            define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN . 'hooks/');
145
+        if ( ! defined('EE_CORE_CAF_ADMIN')) {
146
+            define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH.'caffeinated/admin/');
147
+            define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL.'caffeinated/admin/');
148
+            define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN.'new/');
149
+            define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN.'extend/');
150
+            define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL.'extend/');
151
+            define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN.'hooks/');
152 152
         }
153 153
     }
154 154
 
@@ -261,7 +261,7 @@  discard block
 block discarded – undo
261 261
         //first let's order the menu groups by their internal menu order (note usort type hinting to ensure the incoming array is EE_Admin_Page_Menu_Map objects )
262 262
         usort($this->_admin_menu_groups, array($this, '_sort_menu_maps'));
263 263
         foreach ($this->_admin_menu_groups as $group) {
264
-            if (! $group instanceof EE_Admin_Page_Menu_Group) {
264
+            if ( ! $group instanceof EE_Admin_Page_Menu_Group) {
265 265
                 throw new EE_Error(
266 266
                     sprintf(
267 267
                         __(
@@ -292,7 +292,7 @@  discard block
 block discarded – undo
292 292
         $installed_refs = array();
293 293
         $exclude        = array('assets', 'templates');
294 294
         // grab everything in the  admin core directory
295
-        $admin_screens = glob(EE_ADMIN_PAGES . '*', GLOB_ONLYDIR);
295
+        $admin_screens = glob(EE_ADMIN_PAGES.'*', GLOB_ONLYDIR);
296 296
         if ($admin_screens) {
297 297
             foreach ($admin_screens as $admin_screen) {
298 298
                 // files and anything in the exclude array need not apply
@@ -307,7 +307,7 @@  discard block
 block discarded – undo
307 307
                 'There are no EE_Admin pages detected, it looks like EE did not install properly',
308 308
                 'event_espresso'
309 309
             );
310
-            $error_msg[] = $error_msg[0] . "\r\n" . sprintf(
310
+            $error_msg[] = $error_msg[0]."\r\n".sprintf(
311 311
                     __(
312 312
                         'Check that the %s folder exists and is writable. Maybe try deactivating, then reactivating Event Espresso again.',
313 313
                         'event_espresso'
@@ -319,7 +319,7 @@  discard block
 block discarded – undo
319 319
         //this just checks the caffeinated folder and takes care of setting up any caffeinated stuff.
320 320
         $installed_refs = $this->_set_caffeinated($installed_refs);
321 321
         //allow plugins to add in their own pages (note at this point they will need to have an autoloader defined for their class) OR hook into EEH_Autoloader::load_admin_page() to add their path.;
322
-        $installed_refs             = apply_filters(
322
+        $installed_refs = apply_filters(
323 323
             'FHEE__EE_Admin_Page_Loader___get_installed_pages__installed_refs',
324 324
             $installed_refs
325 325
         );
@@ -336,7 +336,7 @@  discard block
 block discarded – undo
336 336
             $this->_installed_pages[$page] = $this->_load_admin_page($page, $path);
337 337
             // verify returned object
338 338
             if ($this->_installed_pages[$page] instanceof EE_Admin_Page_Init) {
339
-                if (! $this->_installed_pages[$page]->get_menu_map() instanceof EE_Admin_Page_Menu_Map) {
339
+                if ( ! $this->_installed_pages[$page]->get_menu_map() instanceof EE_Admin_Page_Menu_Map) {
340 340
                     continue;
341 341
                 }
342 342
                 //skip if in full maintenance mode and maintenance_mode_parent is set
@@ -365,7 +365,7 @@  discard block
 block discarded – undo
365 365
                     );
366 366
                     add_filter(
367 367
                         "FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$menu_slug}_{$admin_page_name}",
368
-                        function ($admin_page) use ($caf_admin_page)
368
+                        function($admin_page) use ($caf_admin_page)
369 369
                         {
370 370
                             return $caf_admin_page;
371 371
                         }
@@ -424,7 +424,7 @@  discard block
 block discarded – undo
424 424
     private function _get_classname_for_admin_page($dir_name = '')
425 425
     {
426 426
         $class_name = str_replace('_', ' ', strtolower($dir_name));
427
-        return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page';
427
+        return str_replace(' ', '_', ucwords($class_name)).'_Admin_Page';
428 428
     }
429 429
 
430 430
 
@@ -439,7 +439,7 @@  discard block
 block discarded – undo
439 439
     private function _get_classname_for_admin_init_page($dir_name = '')
440 440
     {
441 441
         $class_name = str_replace('_', ' ', strtolower($dir_name));
442
-        return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page_Init';
442
+        return str_replace(' ', '_', ucwords($class_name)).'_Admin_Page_Init';
443 443
     }
444 444
 
445 445
 
@@ -457,19 +457,19 @@  discard block
 block discarded – undo
457 457
     {
458 458
         $class_name = $this->_get_classname_for_admin_init_page($page);
459 459
         EE_Registry::instance()->load_file($path, $class_name, 'core');
460
-        if (! class_exists($class_name)) {
461
-            $inner_error_msg = '<br />' . sprintf(
460
+        if ( ! class_exists($class_name)) {
461
+            $inner_error_msg = '<br />'.sprintf(
462 462
                     esc_html__(
463 463
                         'Make sure you have %1$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class',
464 464
                         'event_espresso'
465 465
                     ),
466
-                    '<strong>' . $class_name . '</strong>'
466
+                    '<strong>'.$class_name.'</strong>'
467 467
                 );
468
-            $error_msg[]     = sprintf(
468
+            $error_msg[] = sprintf(
469 469
                 __('Something went wrong with loading the %s admin page.', 'event_espresso'),
470 470
                 $page
471 471
             );
472
-            $error_msg[]     = $error_msg[0]
472
+            $error_msg[] = $error_msg[0]
473 473
                                . "\r\n"
474 474
                                . sprintf(
475 475
                                    esc_html__(
@@ -545,7 +545,7 @@  discard block
 block discarded – undo
545 545
                 //if we've got an array then the menu map is in the old format so let's throw a persistent notice that the admin system isn't setup correctly for this item.
546 546
                 if (is_array($page_map) || empty($page_map)) {
547 547
                       new PersistentAdminNotice(
548
-                        'menu_map_warning_' . str_replace(' ', '_', $page->label) . '_' . EVENT_ESPRESSO_VERSION,
548
+                        'menu_map_warning_'.str_replace(' ', '_', $page->label).'_'.EVENT_ESPRESSO_VERSION,
549 549
                         sprintf(
550 550
                             __(
551 551
                                 'The admin page for %s was not correctly setup because it is using an older method for integrating with Event Espresso Core.  This means that full functionality for this component is not available.  This error message usually appears with an Add-on that is out of date.  Make sure you update all your Event Espresso 4 add-ons to the latest version to ensure they have necessary compatibility updates in place.',
@@ -557,7 +557,7 @@  discard block
 block discarded – undo
557 557
                     continue;
558 558
                 }
559 559
                 //if page map is NOT a EE_Admin_Page_Menu_Map object then throw error.
560
-                if (! $page_map instanceof EE_Admin_Page_Menu_Map) {
560
+                if ( ! $page_map instanceof EE_Admin_Page_Menu_Map) {
561 561
                     throw new EE_Error(
562 562
                         sprintf(
563 563
                             __(
@@ -585,7 +585,7 @@  discard block
 block discarded – undo
585 585
         //let's sort the groups, make sure it's a valid group, add header (if to show).
586 586
         foreach ($pages_array as $group => $menu_maps) {
587 587
             //valid_group?
588
-            if (! array_key_exists($group, $menu_groups)) {
588
+            if ( ! array_key_exists($group, $menu_groups)) {
589 589
                 continue;
590 590
             }
591 591
             //sort pages.
@@ -626,13 +626,13 @@  discard block
 block discarded – undo
626 626
     {
627 627
 
628 628
         //first let's check if there IS a caffeinated folder. If there is not then lets get out.
629
-        if (! is_dir(EE_PLUGIN_DIR_PATH . 'caffeinated' . DS . 'admin') || (defined('EE_DECAF') && EE_DECAF)) {
629
+        if ( ! is_dir(EE_PLUGIN_DIR_PATH.'caffeinated'.DS.'admin') || (defined('EE_DECAF') && EE_DECAF)) {
630 630
             return $installed_refs;
631 631
         }
632 632
         $this->_define_caffeinated_constants();
633 633
         $exclude = array('tickets');
634 634
         //okay let's setup an "New" pages first (we'll return installed refs later)
635
-        $new_admin_screens = glob(EE_CORE_CAF_ADMIN . 'new/*', GLOB_ONLYDIR);
635
+        $new_admin_screens = glob(EE_CORE_CAF_ADMIN.'new/*', GLOB_ONLYDIR);
636 636
         if ($new_admin_screens) {
637 637
             foreach ($new_admin_screens as $admin_screen) {
638 638
                 // files and anything in the exclude array need not apply
@@ -649,13 +649,13 @@  discard block
 block discarded – undo
649 649
             }
650 650
         }
651 651
         //let's see if there are any EXTENDS to setup in the $_caffeinated_extends array (that will be used later for hooking into the _initialize_admin_age in the related core_init admin page)
652
-        $extends = glob(EE_CORE_CAF_ADMIN . 'extend/*', GLOB_ONLYDIR);
652
+        $extends = glob(EE_CORE_CAF_ADMIN.'extend/*', GLOB_ONLYDIR);
653 653
         if ($extends) {
654 654
             foreach ($extends as $extend) {
655 655
                 if (is_dir($extend)) {
656 656
                     $extend_ref = basename($extend);
657 657
                     //now let's make sure there is a file that matches the expected format
658
-                    $filename                                              = str_replace(
658
+                    $filename = str_replace(
659 659
                         ' ',
660 660
                         '_',
661 661
                         ucwords(
@@ -666,7 +666,7 @@  discard block
 block discarded – undo
666 666
                             )
667 667
                         )
668 668
                     );
669
-                    $filename                                              = 'Extend_' . $filename . '_Admin_Page';
669
+                    $filename                                              = 'Extend_'.$filename.'_Admin_Page';
670 670
                     $this->_caffeinated_extends[$extend_ref]['path']       = str_replace(
671 671
                         array('\\', '/'),
672 672
                         DS,
@@ -690,12 +690,12 @@  discard block
 block discarded – undo
690 690
         }
691 691
         //let's see if there are any HOOK files and instantiate them if there are (so that hooks are loaded early!).
692 692
         $ee_admin_hooks = array();
693
-        $hooks          = glob(EE_CORE_CAF_ADMIN . 'hooks/*.class.php');
693
+        $hooks          = glob(EE_CORE_CAF_ADMIN.'hooks/*.class.php');
694 694
         if ($hooks) {
695 695
             foreach ($hooks as $hook) {
696 696
                 if (is_readable($hook)) {
697 697
                     require_once $hook;
698
-                    $classname = str_replace(EE_CORE_CAF_ADMIN . 'hooks/', '', $hook);
698
+                    $classname = str_replace(EE_CORE_CAF_ADMIN.'hooks/', '', $hook);
699 699
                     $classname = str_replace('.class.php', '', $classname);
700 700
                     if (class_exists($classname)) {
701 701
                         $a                = new ReflectionClass($classname);
Please login to merge, or discard this patch.
core/libraries/messages/messenger/EE_Pdf_messenger.class.php 3 patches
Braces   +2 added lines, -1 removed lines patch added patch discarded remove patch
@@ -6,8 +6,9 @@
 block discarded – undo
6 6
  * @package Event Espresso
7 7
  * @subpackage messages
8 8
  */
9
-if (!defined('EVENT_ESPRESSO_VERSION'))
9
+if (!defined('EVENT_ESPRESSO_VERSION')) {
10 10
     exit('NO direct script access allowed');
11
+}
11 12
 
12 13
 /**
13 14
  *
Please login to merge, or discard this patch.
Indentation   +339 added lines, -339 removed lines patch added patch discarded remove patch
@@ -7,7 +7,7 @@  discard block
 block discarded – undo
7 7
  * @subpackage messages
8 8
  */
9 9
 if (!defined('EVENT_ESPRESSO_VERSION'))
10
-    exit('NO direct script access allowed');
10
+	exit('NO direct script access allowed');
11 11
 
12 12
 /**
13 13
  *
@@ -24,343 +24,343 @@  discard block
 block discarded – undo
24 24
 {
25 25
 
26 26
 
27
-    /**
28
-     * The following are the properties that this messenger requires for generating pdf
29
-     */
30
-
31
-    /**
32
-     * This is the pdf body generated by the template via the message type.
33
-     *
34
-     * @var string
35
-     */
36
-    protected $_content;
37
-
38
-
39
-    /**
40
-     * This is for the page title that gets displayed.  This will end up being the filename for the generated pdf.
41
-     *
42
-     * @var string
43
-     */
44
-    protected $_subject;
45
-
46
-
47
-    /**
48
-     * @return EE_Pdf_messenger
49
-     */
50
-    public function __construct()
51
-    {
52
-        //set properties
53
-        $this->name = 'pdf';
54
-        $this->description = __('This messenger is used for generating a pdf version of the message.', 'event_espresso');
55
-        $this->label = array(
56
-            'singular' => __('PDF', 'event_espresso'),
57
-            'plural' => __('PDFs', 'event_espresso')
58
-        );
59
-        $this->activate_on_install = TRUE;
60
-
61
-        parent::__construct();
62
-    }
63
-
64
-
65
-    /**
66
-     * PDF Messenger desires execution immediately.
67
-     * @see  parent::send_now() for documentation.
68
-     * @since  4.9.0
69
-     * @return bool
70
-     */
71
-    public function send_now()
72
-    {
73
-        return true;
74
-    }
75
-
76
-
77
-    /**
78
-     * HTML Messenger allows an empty to field.
79
-     * @see parent::allow_empty_to_field() for documentation
80
-     * @since  4.9.0
81
-     * @return bool
82
-     */
83
-    public function allow_empty_to_field()
84
-    {
85
-        return true;
86
-    }
87
-
88
-
89
-    /**
90
-     * @see abstract declaration in EE_messenger for details.
91
-     */
92
-    protected function _set_admin_pages()
93
-    {
94
-        $this->admin_registered_pages = array('events_edit' => false);
95
-    }
96
-
97
-
98
-    /**
99
-     * @see abstract declaration in EE_messenger for details.
100
-     */
101
-    protected function _set_valid_shortcodes()
102
-    {
103
-        $this->_valid_shortcodes = array();
104
-    }
105
-
106
-
107
-    /**
108
-     * @see abstract declaration in EE_messenger for details.
109
-     */
110
-    protected function _set_validator_config()
111
-    {
112
-        $this->_validator_config = array(
113
-            'subject' => array(
114
-                'shortcodes' => array('recipient_details', 'organization', 'event', 'ticket', 'venue', 'primary_registration_details', 'event_author', 'email', 'event_meta', 'recipient_list', 'transaction', 'datetime_list', 'datetime')
115
-            ),
116
-            'content' => array(
117
-                'shortcodes' => array('recipient_details', 'organization', 'event', 'ticket', 'venue', 'primary_registration_details', 'event_author', 'email', 'event_meta', 'recipient_list', 'transaction', 'datetime_list', 'datetime')
118
-            ),
119
-            'attendee_list' => array(
120
-                'shortcodes' => array('attendee', 'event_list', 'ticket_list'),
121
-                'required' => array('[ATTENDEE_LIST]')
122
-            ),
123
-            'event_list' => array(
124
-                'shortcodes' => array('event', 'attendee_list', 'ticket_list', 'venue', 'datetime_list', 'attendee', 'primary_registration_details', 'primary_registration_list', 'event_author', 'recipient_details', 'recipient_list'),
125
-                'required' => array('[EVENT_LIST]')
126
-            ),
127
-            'ticket_list' => array(
128
-                'shortcodes' => array('event_list', 'attendee_list', 'ticket', 'datetime_list', 'primary_registration_details', 'recipient_details'),
129
-                'required' => array('[TICKET_LIST]')
130
-            ),
131
-            'datetime_list' => array(
132
-                'shortcodes' => array('datetime'),
133
-                'required' => array('[DATETIME_LIST]')
134
-            ),
135
-        );
136
-    }
137
-
138
-
139
-    /**
140
-     * Takes care of enqueuing any necessary scripts or styles for the page.  A do_action() so message types using this messenger can add their own js.
141
-     *
142
-     * @return void.
143
-     */
144
-    public function enqueue_scripts_styles()
145
-    {
146
-        parent::enqueue_scripts_styles();
147
-        do_action('AHEE__EE_Pdf_messenger__enqueue_scripts_styles');
148
-    }
149
-
150
-
151
-    /**
152
-     * _set_template_fields
153
-     * This sets up the fields that a messenger requires for the message to go out.
154
-     *
155
-     * @access  protected
156
-     * @return void
157
-     */
158
-    protected function _set_template_fields()
159
-    {
160
-        // any extra template fields that are NOT used by the messenger but will get used by a messenger field for shortcode replacement get added to the 'extra' key in an associated array indexed by the messenger field they relate to.  This is important for the Messages_admin to know what fields to display to the user.  Also, notice that the "values" are equal to the field type that messages admin will use to know what kind of field to display. The values ALSO have one index labeled "shortcode".  the values in that array indicate which ACTUAL SHORTCODE (i.e. [SHORTCODE]) is required in order for this extra field to be displayed.  If the required shortcode isn't part of the shortcodes array then the field is not needed and will not be displayed/parsed.
161
-        $this->_template_fields = array(
162
-            'subject' => array(
163
-                'input' => 'text',
164
-                'label' => __('Page Title', 'event_espresso'),
165
-                'type' => 'string',
166
-                'required' => TRUE,
167
-                'validation' => TRUE,
168
-                'css_class' => 'large-text',
169
-                'format' => '%s'
170
-            ),
171
-            'content' => '', //left empty b/c it is in the "extra array" but messenger still needs needs to know this is a field.
172
-            'extra' => array(
173
-                'content' => array(
174
-                    'main' => array(
175
-                        'input' => 'wp_editor',
176
-                        'label' => __('Main Content', 'event_espresso'),
177
-                        'type' => 'string',
178
-                        'required' => TRUE,
179
-                        'validation' => TRUE,
180
-                        'format' => '%s',
181
-                        'rows' => '15'
182
-                    ),
183
-                    'event_list' => array(
184
-                        'input' => 'wp_editor',
185
-                        'label' => '[EVENT_LIST]',
186
-                        'type' => 'string',
187
-                        'required' => TRUE,
188
-                        'validation' => TRUE,
189
-                        'format' => '%s',
190
-                        'rows' => '15',
191
-                        'shortcodes_required' => array('[EVENT_LIST]')
192
-                    ),
193
-                    'attendee_list' => array(
194
-                        'input' => 'textarea',
195
-                        'label' => '[ATTENDEE_LIST]',
196
-                        'type' => 'string',
197
-                        'required' => TRUE,
198
-                        'validation' => TRUE,
199
-                        'format' => '%s',
200
-                        'css_class' => 'large-text',
201
-                        'rows' => '5',
202
-                        'shortcodes_required' => array('[ATTENDEE_LIST]')
203
-                    ),
204
-                    'ticket_list' => array(
205
-                        'input' => 'textarea',
206
-                        'label' => '[TICKET_LIST]',
207
-                        'type' => 'string',
208
-                        'required' => TRUE,
209
-                        'validation' => TRUE,
210
-                        'format' => '%s',
211
-                        'css_class' => 'large-text',
212
-                        'rows' => '10',
213
-                        'shortcodes_required' => array('[TICKET_LIST]')
214
-                    ),
215
-                    'datetime_list' => array(
216
-                        'input' => 'textarea',
217
-                        'label' => '[DATETIME_LIST]',
218
-                        'type' => 'string',
219
-                        'required' => TRUE,
220
-                        'validation' => TRUE,
221
-                        'format' => '%s',
222
-                        'css_class' => 'large-text',
223
-                        'rows' => '10',
224
-                        'shortcodes_required' => array('[DATETIME_LIST]')
225
-                    )
226
-                )
227
-            )
228
-        );
229
-    }
230
-
231
-
232
-    /**
233
-     * @see definition of this method in parent
234
-     *
235
-     * @since 4.5.0
236
-     *
237
-     */
238
-    protected function _set_default_message_types()
239
-    {
240
-        //note currently PDF is only a secondary messenger so it never has any associated message types.
241
-        $this->_default_message_types = array();
242
-    }
243
-
244
-
245
-    /**
246
-     * @see definition of this method in parent
247
-     *
248
-     * @since 4.5.0
249
-     */
250
-    protected function _set_valid_message_types()
251
-    {
252
-        $this->_valid_message_types = array();
253
-    }
254
-
255
-
256
-    /**
257
-     * Generates html version of the message content and then sends it to the pdf generator.
258
-     *
259
-     *
260
-     * @since 4.5.0
261
-     *
262
-     * @return string.
263
-     */
264
-    protected function _send_message()
265
-    {
266
-        $this->_template_args = array(
267
-            'page_title' => html_entity_decode(stripslashes($this->_subject), ENT_QUOTES, "UTF-8"),
268
-            'base_css' => $this->get_variation($this->_tmp_pack, $this->_incoming_message_type->name, TRUE, 'base', $this->_variation),
269
-            'print_css' => $this->get_variation($this->_tmp_pack, $this->_incoming_message_type->name, TRUE, 'print', $this->_variation),
270
-            'main_css' => $this->get_variation($this->_tmp_pack, $this->_incoming_message_type->name, TRUE, 'main', $this->_variation),
271
-            'extra_css' => EE_LIBRARIES_URL . 'messages/defaults/default/variations/pdf_base_default.css',
272
-            'main_body' => apply_filters('FHEE__EE_Pdf_messenger___send_message__main_body', wpautop(stripslashes_deep(html_entity_decode($this->_content, ENT_QUOTES, "UTF-8"))), $this->_content)
273
-        );
274
-        $this->_deregister_wp_hooks();
275
-        add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts_styles'));
276
-        $content = $this->_get_main_template();
27
+	/**
28
+	 * The following are the properties that this messenger requires for generating pdf
29
+	 */
30
+
31
+	/**
32
+	 * This is the pdf body generated by the template via the message type.
33
+	 *
34
+	 * @var string
35
+	 */
36
+	protected $_content;
37
+
38
+
39
+	/**
40
+	 * This is for the page title that gets displayed.  This will end up being the filename for the generated pdf.
41
+	 *
42
+	 * @var string
43
+	 */
44
+	protected $_subject;
45
+
46
+
47
+	/**
48
+	 * @return EE_Pdf_messenger
49
+	 */
50
+	public function __construct()
51
+	{
52
+		//set properties
53
+		$this->name = 'pdf';
54
+		$this->description = __('This messenger is used for generating a pdf version of the message.', 'event_espresso');
55
+		$this->label = array(
56
+			'singular' => __('PDF', 'event_espresso'),
57
+			'plural' => __('PDFs', 'event_espresso')
58
+		);
59
+		$this->activate_on_install = TRUE;
60
+
61
+		parent::__construct();
62
+	}
63
+
64
+
65
+	/**
66
+	 * PDF Messenger desires execution immediately.
67
+	 * @see  parent::send_now() for documentation.
68
+	 * @since  4.9.0
69
+	 * @return bool
70
+	 */
71
+	public function send_now()
72
+	{
73
+		return true;
74
+	}
75
+
76
+
77
+	/**
78
+	 * HTML Messenger allows an empty to field.
79
+	 * @see parent::allow_empty_to_field() for documentation
80
+	 * @since  4.9.0
81
+	 * @return bool
82
+	 */
83
+	public function allow_empty_to_field()
84
+	{
85
+		return true;
86
+	}
87
+
88
+
89
+	/**
90
+	 * @see abstract declaration in EE_messenger for details.
91
+	 */
92
+	protected function _set_admin_pages()
93
+	{
94
+		$this->admin_registered_pages = array('events_edit' => false);
95
+	}
96
+
97
+
98
+	/**
99
+	 * @see abstract declaration in EE_messenger for details.
100
+	 */
101
+	protected function _set_valid_shortcodes()
102
+	{
103
+		$this->_valid_shortcodes = array();
104
+	}
105
+
106
+
107
+	/**
108
+	 * @see abstract declaration in EE_messenger for details.
109
+	 */
110
+	protected function _set_validator_config()
111
+	{
112
+		$this->_validator_config = array(
113
+			'subject' => array(
114
+				'shortcodes' => array('recipient_details', 'organization', 'event', 'ticket', 'venue', 'primary_registration_details', 'event_author', 'email', 'event_meta', 'recipient_list', 'transaction', 'datetime_list', 'datetime')
115
+			),
116
+			'content' => array(
117
+				'shortcodes' => array('recipient_details', 'organization', 'event', 'ticket', 'venue', 'primary_registration_details', 'event_author', 'email', 'event_meta', 'recipient_list', 'transaction', 'datetime_list', 'datetime')
118
+			),
119
+			'attendee_list' => array(
120
+				'shortcodes' => array('attendee', 'event_list', 'ticket_list'),
121
+				'required' => array('[ATTENDEE_LIST]')
122
+			),
123
+			'event_list' => array(
124
+				'shortcodes' => array('event', 'attendee_list', 'ticket_list', 'venue', 'datetime_list', 'attendee', 'primary_registration_details', 'primary_registration_list', 'event_author', 'recipient_details', 'recipient_list'),
125
+				'required' => array('[EVENT_LIST]')
126
+			),
127
+			'ticket_list' => array(
128
+				'shortcodes' => array('event_list', 'attendee_list', 'ticket', 'datetime_list', 'primary_registration_details', 'recipient_details'),
129
+				'required' => array('[TICKET_LIST]')
130
+			),
131
+			'datetime_list' => array(
132
+				'shortcodes' => array('datetime'),
133
+				'required' => array('[DATETIME_LIST]')
134
+			),
135
+		);
136
+	}
137
+
138
+
139
+	/**
140
+	 * Takes care of enqueuing any necessary scripts or styles for the page.  A do_action() so message types using this messenger can add their own js.
141
+	 *
142
+	 * @return void.
143
+	 */
144
+	public function enqueue_scripts_styles()
145
+	{
146
+		parent::enqueue_scripts_styles();
147
+		do_action('AHEE__EE_Pdf_messenger__enqueue_scripts_styles');
148
+	}
149
+
150
+
151
+	/**
152
+	 * _set_template_fields
153
+	 * This sets up the fields that a messenger requires for the message to go out.
154
+	 *
155
+	 * @access  protected
156
+	 * @return void
157
+	 */
158
+	protected function _set_template_fields()
159
+	{
160
+		// any extra template fields that are NOT used by the messenger but will get used by a messenger field for shortcode replacement get added to the 'extra' key in an associated array indexed by the messenger field they relate to.  This is important for the Messages_admin to know what fields to display to the user.  Also, notice that the "values" are equal to the field type that messages admin will use to know what kind of field to display. The values ALSO have one index labeled "shortcode".  the values in that array indicate which ACTUAL SHORTCODE (i.e. [SHORTCODE]) is required in order for this extra field to be displayed.  If the required shortcode isn't part of the shortcodes array then the field is not needed and will not be displayed/parsed.
161
+		$this->_template_fields = array(
162
+			'subject' => array(
163
+				'input' => 'text',
164
+				'label' => __('Page Title', 'event_espresso'),
165
+				'type' => 'string',
166
+				'required' => TRUE,
167
+				'validation' => TRUE,
168
+				'css_class' => 'large-text',
169
+				'format' => '%s'
170
+			),
171
+			'content' => '', //left empty b/c it is in the "extra array" but messenger still needs needs to know this is a field.
172
+			'extra' => array(
173
+				'content' => array(
174
+					'main' => array(
175
+						'input' => 'wp_editor',
176
+						'label' => __('Main Content', 'event_espresso'),
177
+						'type' => 'string',
178
+						'required' => TRUE,
179
+						'validation' => TRUE,
180
+						'format' => '%s',
181
+						'rows' => '15'
182
+					),
183
+					'event_list' => array(
184
+						'input' => 'wp_editor',
185
+						'label' => '[EVENT_LIST]',
186
+						'type' => 'string',
187
+						'required' => TRUE,
188
+						'validation' => TRUE,
189
+						'format' => '%s',
190
+						'rows' => '15',
191
+						'shortcodes_required' => array('[EVENT_LIST]')
192
+					),
193
+					'attendee_list' => array(
194
+						'input' => 'textarea',
195
+						'label' => '[ATTENDEE_LIST]',
196
+						'type' => 'string',
197
+						'required' => TRUE,
198
+						'validation' => TRUE,
199
+						'format' => '%s',
200
+						'css_class' => 'large-text',
201
+						'rows' => '5',
202
+						'shortcodes_required' => array('[ATTENDEE_LIST]')
203
+					),
204
+					'ticket_list' => array(
205
+						'input' => 'textarea',
206
+						'label' => '[TICKET_LIST]',
207
+						'type' => 'string',
208
+						'required' => TRUE,
209
+						'validation' => TRUE,
210
+						'format' => '%s',
211
+						'css_class' => 'large-text',
212
+						'rows' => '10',
213
+						'shortcodes_required' => array('[TICKET_LIST]')
214
+					),
215
+					'datetime_list' => array(
216
+						'input' => 'textarea',
217
+						'label' => '[DATETIME_LIST]',
218
+						'type' => 'string',
219
+						'required' => TRUE,
220
+						'validation' => TRUE,
221
+						'format' => '%s',
222
+						'css_class' => 'large-text',
223
+						'rows' => '10',
224
+						'shortcodes_required' => array('[DATETIME_LIST]')
225
+					)
226
+				)
227
+			)
228
+		);
229
+	}
230
+
231
+
232
+	/**
233
+	 * @see definition of this method in parent
234
+	 *
235
+	 * @since 4.5.0
236
+	 *
237
+	 */
238
+	protected function _set_default_message_types()
239
+	{
240
+		//note currently PDF is only a secondary messenger so it never has any associated message types.
241
+		$this->_default_message_types = array();
242
+	}
243
+
244
+
245
+	/**
246
+	 * @see definition of this method in parent
247
+	 *
248
+	 * @since 4.5.0
249
+	 */
250
+	protected function _set_valid_message_types()
251
+	{
252
+		$this->_valid_message_types = array();
253
+	}
254
+
255
+
256
+	/**
257
+	 * Generates html version of the message content and then sends it to the pdf generator.
258
+	 *
259
+	 *
260
+	 * @since 4.5.0
261
+	 *
262
+	 * @return string.
263
+	 */
264
+	protected function _send_message()
265
+	{
266
+		$this->_template_args = array(
267
+			'page_title' => html_entity_decode(stripslashes($this->_subject), ENT_QUOTES, "UTF-8"),
268
+			'base_css' => $this->get_variation($this->_tmp_pack, $this->_incoming_message_type->name, TRUE, 'base', $this->_variation),
269
+			'print_css' => $this->get_variation($this->_tmp_pack, $this->_incoming_message_type->name, TRUE, 'print', $this->_variation),
270
+			'main_css' => $this->get_variation($this->_tmp_pack, $this->_incoming_message_type->name, TRUE, 'main', $this->_variation),
271
+			'extra_css' => EE_LIBRARIES_URL . 'messages/defaults/default/variations/pdf_base_default.css',
272
+			'main_body' => apply_filters('FHEE__EE_Pdf_messenger___send_message__main_body', wpautop(stripslashes_deep(html_entity_decode($this->_content, ENT_QUOTES, "UTF-8"))), $this->_content)
273
+		);
274
+		$this->_deregister_wp_hooks();
275
+		add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts_styles'));
276
+		$content = $this->_get_main_template();
277 277
 //		die( $content );
278
-        $this->_do_pdf($content);
279
-        exit(0);
280
-    }
281
-
282
-
283
-    /**
284
-     * The purpose of this function is to de register all actions hooked into wp_head and wp_footer so that it doesn't interfere with our templates.  If users want to add any custom styles or scripts they must use the AHEE__EE_Pdf_messenger__enqueue_scripts_styles hook.
285
-     *
286
-     * @since 4.5.0
287
-     *
288
-     * @return void
289
-     */
290
-    protected function _deregister_wp_hooks()
291
-    {
292
-        remove_all_actions('wp_head');
293
-        remove_all_actions('wp_footer');
294
-        remove_all_actions('wp_print_footer_scripts');
295
-        remove_all_actions('wp_enqueue_scripts');
296
-        global $wp_scripts, $wp_styles;
297
-        $wp_scripts = $wp_styles = array();
298
-
299
-        //just add back in wp_enqueue_scripts and wp_print_footer_scripts cause that's all we want to load.
300
-        add_action('wp_head', 'wp_enqueue_scripts');
301
-        add_action('wp_footer', 'wp_print_footer_scripts');
302
-        add_action('wp_print_footer_scripts', '_wp_footer_scripts');
303
-    }
304
-
305
-
306
-    /**
307
-     * Overwrite parent _get_main_template for pdf purposes.
308
-     *
309
-     * @since  4.5.0
310
-     *
311
-     * @param bool $preview
312
-     * @return string
313
-     */
314
-    protected function _get_main_template($preview = FALSE)
315
-    {
316
-        $wrapper_template = $this->_tmp_pack->get_wrapper('html', 'main');
317
-        //add message type to template_args
318
-        $this->_template_args['message_type'] = $this->_incoming_message_type;
319
-        return EEH_Template::display_template($wrapper_template, $this->_template_args, TRUE);
320
-    }
321
-
322
-
323
-    /**
324
-     * This takes care of loading the dompdf library and generating the actual pdf
325
-     *
326
-     * @param string $content This is the generated html content being converted into a pdf.
327
-     *
328
-     * @return void
329
-     */
330
-    protected function _do_pdf($content = '')
331
-    {
332
-        $invoice_name = html_entity_decode($this->_subject, ENT_QUOTES, "UTF-8");
333
-
334
-        //only load dompdf if nobody else has yet...
335
-        if (!defined('DOMPDF_DIR')) {
336
-            define('DOMPDF_ENABLE_REMOTE', TRUE);
337
-            define('DOMPDF_ENABLE_JAVASCRIPT', FALSE);
338
-            define('DOMPDF_ENABLE_CSS_FLOAT', TRUE);
339
-            require_once(EE_THIRD_PARTY . 'dompdf/dompdf_config.inc.php');
340
-        }
341
-        $dompdf = new DOMPDF();
342
-        if (defined('DOMPDF_DEFAULT_PAPER_SIZE')) {
343
-            $dompdf->set_paper(DOMPDF_DEFAULT_PAPER_SIZE);
344
-        }
345
-        //Remove all spaces between HTML tags
346
-        $content = preg_replace('/>\s+</', '><', $content);
347
-        $dompdf->load_html($content);
348
-        $dompdf->render();
349
-        //forcing the browser to open a download dialog.
350
-        $dompdf->stream($invoice_name . ".pdf", array('Attachment' => TRUE));
351
-    }
352
-
353
-
354
-    /**
355
-     * @return string
356
-     */
357
-    protected function _preview()
358
-    {
359
-        return $this->_send_message();
360
-    }
361
-
362
-
363
-    protected function _set_admin_settings_fields()
364
-    {
365
-    }
278
+		$this->_do_pdf($content);
279
+		exit(0);
280
+	}
281
+
282
+
283
+	/**
284
+	 * The purpose of this function is to de register all actions hooked into wp_head and wp_footer so that it doesn't interfere with our templates.  If users want to add any custom styles or scripts they must use the AHEE__EE_Pdf_messenger__enqueue_scripts_styles hook.
285
+	 *
286
+	 * @since 4.5.0
287
+	 *
288
+	 * @return void
289
+	 */
290
+	protected function _deregister_wp_hooks()
291
+	{
292
+		remove_all_actions('wp_head');
293
+		remove_all_actions('wp_footer');
294
+		remove_all_actions('wp_print_footer_scripts');
295
+		remove_all_actions('wp_enqueue_scripts');
296
+		global $wp_scripts, $wp_styles;
297
+		$wp_scripts = $wp_styles = array();
298
+
299
+		//just add back in wp_enqueue_scripts and wp_print_footer_scripts cause that's all we want to load.
300
+		add_action('wp_head', 'wp_enqueue_scripts');
301
+		add_action('wp_footer', 'wp_print_footer_scripts');
302
+		add_action('wp_print_footer_scripts', '_wp_footer_scripts');
303
+	}
304
+
305
+
306
+	/**
307
+	 * Overwrite parent _get_main_template for pdf purposes.
308
+	 *
309
+	 * @since  4.5.0
310
+	 *
311
+	 * @param bool $preview
312
+	 * @return string
313
+	 */
314
+	protected function _get_main_template($preview = FALSE)
315
+	{
316
+		$wrapper_template = $this->_tmp_pack->get_wrapper('html', 'main');
317
+		//add message type to template_args
318
+		$this->_template_args['message_type'] = $this->_incoming_message_type;
319
+		return EEH_Template::display_template($wrapper_template, $this->_template_args, TRUE);
320
+	}
321
+
322
+
323
+	/**
324
+	 * This takes care of loading the dompdf library and generating the actual pdf
325
+	 *
326
+	 * @param string $content This is the generated html content being converted into a pdf.
327
+	 *
328
+	 * @return void
329
+	 */
330
+	protected function _do_pdf($content = '')
331
+	{
332
+		$invoice_name = html_entity_decode($this->_subject, ENT_QUOTES, "UTF-8");
333
+
334
+		//only load dompdf if nobody else has yet...
335
+		if (!defined('DOMPDF_DIR')) {
336
+			define('DOMPDF_ENABLE_REMOTE', TRUE);
337
+			define('DOMPDF_ENABLE_JAVASCRIPT', FALSE);
338
+			define('DOMPDF_ENABLE_CSS_FLOAT', TRUE);
339
+			require_once(EE_THIRD_PARTY . 'dompdf/dompdf_config.inc.php');
340
+		}
341
+		$dompdf = new DOMPDF();
342
+		if (defined('DOMPDF_DEFAULT_PAPER_SIZE')) {
343
+			$dompdf->set_paper(DOMPDF_DEFAULT_PAPER_SIZE);
344
+		}
345
+		//Remove all spaces between HTML tags
346
+		$content = preg_replace('/>\s+</', '><', $content);
347
+		$dompdf->load_html($content);
348
+		$dompdf->render();
349
+		//forcing the browser to open a download dialog.
350
+		$dompdf->stream($invoice_name . ".pdf", array('Attachment' => TRUE));
351
+	}
352
+
353
+
354
+	/**
355
+	 * @return string
356
+	 */
357
+	protected function _preview()
358
+	{
359
+		return $this->_send_message();
360
+	}
361
+
362
+
363
+	protected function _set_admin_settings_fields()
364
+	{
365
+	}
366 366
 }
Please login to merge, or discard this patch.
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -6,7 +6,7 @@  discard block
 block discarded – undo
6 6
  * @package Event Espresso
7 7
  * @subpackage messages
8 8
  */
9
-if (!defined('EVENT_ESPRESSO_VERSION'))
9
+if ( ! defined('EVENT_ESPRESSO_VERSION'))
10 10
     exit('NO direct script access allowed');
11 11
 
12 12
 /**
@@ -268,7 +268,7 @@  discard block
 block discarded – undo
268 268
             'base_css' => $this->get_variation($this->_tmp_pack, $this->_incoming_message_type->name, TRUE, 'base', $this->_variation),
269 269
             'print_css' => $this->get_variation($this->_tmp_pack, $this->_incoming_message_type->name, TRUE, 'print', $this->_variation),
270 270
             'main_css' => $this->get_variation($this->_tmp_pack, $this->_incoming_message_type->name, TRUE, 'main', $this->_variation),
271
-            'extra_css' => EE_LIBRARIES_URL . 'messages/defaults/default/variations/pdf_base_default.css',
271
+            'extra_css' => EE_LIBRARIES_URL.'messages/defaults/default/variations/pdf_base_default.css',
272 272
             'main_body' => apply_filters('FHEE__EE_Pdf_messenger___send_message__main_body', wpautop(stripslashes_deep(html_entity_decode($this->_content, ENT_QUOTES, "UTF-8"))), $this->_content)
273 273
         );
274 274
         $this->_deregister_wp_hooks();
@@ -332,11 +332,11 @@  discard block
 block discarded – undo
332 332
         $invoice_name = html_entity_decode($this->_subject, ENT_QUOTES, "UTF-8");
333 333
 
334 334
         //only load dompdf if nobody else has yet...
335
-        if (!defined('DOMPDF_DIR')) {
335
+        if ( ! defined('DOMPDF_DIR')) {
336 336
             define('DOMPDF_ENABLE_REMOTE', TRUE);
337 337
             define('DOMPDF_ENABLE_JAVASCRIPT', FALSE);
338 338
             define('DOMPDF_ENABLE_CSS_FLOAT', TRUE);
339
-            require_once(EE_THIRD_PARTY . 'dompdf/dompdf_config.inc.php');
339
+            require_once(EE_THIRD_PARTY.'dompdf/dompdf_config.inc.php');
340 340
         }
341 341
         $dompdf = new DOMPDF();
342 342
         if (defined('DOMPDF_DEFAULT_PAPER_SIZE')) {
@@ -347,7 +347,7 @@  discard block
 block discarded – undo
347 347
         $dompdf->load_html($content);
348 348
         $dompdf->render();
349 349
         //forcing the browser to open a download dialog.
350
-        $dompdf->stream($invoice_name . ".pdf", array('Attachment' => TRUE));
350
+        $dompdf->stream($invoice_name.".pdf", array('Attachment' => TRUE));
351 351
     }
352 352
 
353 353
 
Please login to merge, or discard this patch.
core/libraries/messages/messenger/EE_Html_messenger.class.php 2 patches
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php
2
-if (!defined('EVENT_ESPRESSO_VERSION')) {
2
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
3 3
     exit('NO direct script access allowed');
4 4
 }
5 5
 
@@ -318,7 +318,7 @@  discard block
 block discarded – undo
318 318
                     ),
319 319
                     'ticket_line_item_no_pms' => array(
320 320
                         'input' => 'textarea',
321
-                        'label' => '[TICKET_LINE_ITEM_LIST] <br>' . __(
321
+                        'label' => '[TICKET_LINE_ITEM_LIST] <br>'.__(
322 322
                                 'Ticket Line Item List with no Price Modifiers',
323 323
                                 'event_espresso'
324 324
                             ),
@@ -332,7 +332,7 @@  discard block
 block discarded – undo
332 332
                     ),
333 333
                     'ticket_line_item_pms' => array(
334 334
                         'input' => 'textarea',
335
-                        'label' => '[TICKET_LINE_ITEM_LIST] <br>' . __(
335
+                        'label' => '[TICKET_LINE_ITEM_LIST] <br>'.__(
336 336
                                 'Ticket Line Item List with Price Modifiers',
337 337
                                 'event_espresso'
338 338
                             ),
Please login to merge, or discard this patch.
Indentation   +554 added lines, -554 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 if (!defined('EVENT_ESPRESSO_VERSION')) {
3
-    exit('NO direct script access allowed');
3
+	exit('NO direct script access allowed');
4 4
 }
5 5
 
6 6
 
@@ -16,558 +16,558 @@  discard block
 block discarded – undo
16 16
 {
17 17
 
18 18
 
19
-    /**
20
-     * The following are the properties that this messenger requires for displaying the html
21
-     */
22
-    /**
23
-     * This is the html body generated by the template via the message type.
24
-     *
25
-     * @var string
26
-     */
27
-    protected $_content;
28
-
29
-
30
-    /**
31
-     * This is for the page title that gets displayed.  (Why use "subject"?  Because the "title" tag in html is
32
-     * equivalent to the "subject" of the page.
33
-     *
34
-     * @var string
35
-     */
36
-    protected $_subject;
37
-
38
-
39
-    /**
40
-     * EE_Html_messenger constructor.
41
-     */
42
-    public function __construct()
43
-    {
44
-        //set properties
45
-        $this->name = 'html';
46
-        $this->description = __('This messenger outputs a message to a browser for display.', 'event_espresso');
47
-        $this->label = array(
48
-            'singular' => __('html', 'event_espresso'),
49
-            'plural' => __('html', 'event_espresso'),
50
-        );
51
-        $this->activate_on_install = true;
52
-        // add the "powered by EE" credit link to the HTML receipt and invoice
53
-        add_filter(
54
-            'FHEE__EE_Html_messenger___send_message__main_body',
55
-            array($this, 'add_powered_by_credit_link_to_receipt_and_invoice'),
56
-            10,
57
-            3
58
-        );
59
-        parent::__construct();
60
-    }
61
-
62
-
63
-    /**
64
-     * HTML Messenger desires execution immediately.
65
-     *
66
-     * @see    parent::send_now() for documentation.
67
-     * @since  4.9.0
68
-     * @return bool
69
-     */
70
-    public function send_now()
71
-    {
72
-        return true;
73
-    }
74
-
75
-
76
-    /**
77
-     * HTML Messenger allows an empty to field.
78
-     *
79
-     * @see    parent::allow_empty_to_field() for documentation
80
-     * @since  4.9.0
81
-     * @return bool
82
-     */
83
-    public function allow_empty_to_field()
84
-    {
85
-        return true;
86
-    }
87
-
88
-
89
-    /**
90
-     * @see abstract declaration in EE_messenger for details.
91
-     */
92
-    protected function _set_admin_pages()
93
-    {
94
-        $this->admin_registered_pages = array('events_edit' => true);
95
-    }
96
-
97
-
98
-    /**
99
-     * @see abstract declaration in EE_messenger for details.
100
-     */
101
-    protected function _set_valid_shortcodes()
102
-    {
103
-        $this->_valid_shortcodes = array();
104
-    }
105
-
106
-
107
-    /**
108
-     * @see abstract declaration in EE_messenger for details.
109
-     */
110
-    protected function _set_validator_config()
111
-    {
112
-        $this->_validator_config = array(
113
-            'subject' => array(
114
-                'shortcodes' => array('organization', 'primary_registration_details', 'email', 'transaction'),
115
-            ),
116
-            'content' => array(
117
-                'shortcodes' => array(
118
-                    'organization',
119
-                    'primary_registration_list',
120
-                    'primary_registration_details',
121
-                    'email',
122
-                    'transaction',
123
-                    'event_list',
124
-                    'payment_list',
125
-                    'venue',
126
-                    'line_item_list',
127
-                    'messenger',
128
-                    'ticket_list',
129
-                ),
130
-            ),
131
-            'event_list' => array(
132
-                'shortcodes' => array(
133
-                    'event',
134
-                    'ticket_list',
135
-                    'venue',
136
-                    'primary_registration_details',
137
-                    'primary_registration_list',
138
-                    'event_author',
139
-                ),
140
-                'required' => array('[EVENT_LIST]'),
141
-            ),
142
-            'ticket_list' => array(
143
-                'shortcodes' => array(
144
-                    'attendee_list',
145
-                    'ticket',
146
-                    'datetime_list',
147
-                    'primary_registration_details',
148
-                    'line_item_list',
149
-                    'venue',
150
-                ),
151
-                'required' => array('[TICKET_LIST]'),
152
-            ),
153
-            'ticket_line_item_no_pms' => array(
154
-                'shortcodes' => array('line_item', 'ticket'),
155
-                'required' => array('[TICKET_LINE_ITEM_LIST]'),
156
-            ),
157
-            'ticket_line_item_pms' => array(
158
-                'shortcodes' => array('line_item', 'ticket', 'line_item_list'),
159
-                'required' => array('[TICKET_LINE_ITEM_LIST]'),
160
-            ),
161
-            'price_modifier_line_item_list' => array(
162
-                'shortcodes' => array('line_item'),
163
-                'required' => array('[PRICE_MODIFIER_LINE_ITEM_LIST]'),
164
-            ),
165
-            'datetime_list' => array(
166
-                'shortcodes' => array('datetime'),
167
-                'required' => array('[DATETIME_LIST]'),
168
-            ),
169
-            'attendee_list' => array(
170
-                'shortcodes' => array('attendee'),
171
-                'required' => array('[ATTENDEE_LIST]'),
172
-            ),
173
-            'tax_line_item_list' => array(
174
-                'shortcodes' => array('line_item'),
175
-                'required' => array('[TAX_LINE_ITEM_LIST]'),
176
-            ),
177
-            'additional_line_item_list' => array(
178
-                'shortcodes' => array('line_item'),
179
-                'required' => array('[ADDITIONAL_LINE_ITEM_LIST]'),
180
-            ),
181
-            'payment_list' => array(
182
-                'shortcodes' => array('payment'),
183
-                'required' => array('[PAYMENT_LIST_*]'),
184
-            ),
185
-        );
186
-    }
187
-
188
-
189
-    /**
190
-     * This is a method called from EE_messages when this messenger is a generating messenger and the sending messenger
191
-     * is a different messenger.  Child messengers can set hooks for the sending messenger to callback on if necessary
192
-     * (i.e. swap out css files or something else).
193
-     *
194
-     * @since 4.5.0
195
-     * @param string $sending_messenger_name the name of the sending messenger so we only set the hooks needed.
196
-     * @return void
197
-     */
198
-    public function do_secondary_messenger_hooks($sending_messenger_name)
199
-    {
200
-        if ($sending_messenger_name = 'pdf') {
201
-            add_filter('EE_messenger__get_variation__variation', array($this, 'add_html_css'), 10, 8);
202
-        }
203
-    }
204
-
205
-
206
-    /**
207
-     * @param                            $variation_path
208
-     * @param \EE_Messages_Template_Pack $template_pack
209
-     * @param                            $messenger_name
210
-     * @param                            $message_type_name
211
-     * @param                            $url
212
-     * @param                            $type
213
-     * @param                            $variation
214
-     * @param                            $skip_filters
215
-     * @return string
216
-     */
217
-    public function add_html_css(
218
-        $variation_path,
219
-        EE_Messages_Template_Pack $template_pack,
220
-        $messenger_name,
221
-        $message_type_name,
222
-        $url,
223
-        $type,
224
-        $variation,
225
-        $skip_filters
226
-    )
227
-    {
228
-        $variation = $template_pack->get_variation(
229
-            $this->name,
230
-            $message_type_name,
231
-            $type,
232
-            $variation,
233
-            $url,
234
-            '.css',
235
-            $skip_filters
236
-        );
237
-        return $variation;
238
-    }
239
-
240
-
241
-    /**
242
-     * Takes care of enqueuing any necessary scripts or styles for the page.  A do_action() so message types using this
243
-     * messenger can add their own js.
244
-     *
245
-     * @return void.
246
-     */
247
-    public function enqueue_scripts_styles()
248
-    {
249
-        parent::enqueue_scripts_styles();
250
-        do_action('AHEE__EE_Html_messenger__enqueue_scripts_styles');
251
-    }
252
-
253
-
254
-    /**
255
-     * _set_template_fields
256
-     * This sets up the fields that a messenger requires for the message to go out.
257
-     *
258
-     * @access  protected
259
-     * @return void
260
-     */
261
-    protected function _set_template_fields()
262
-    {
263
-        // any extra template fields that are NOT used by the messenger
264
-        // but will get used by a messenger field for shortcode replacement
265
-        // get added to the 'extra' key in an associated array
266
-        // indexed by the messenger field they relate to.
267
-        // This is important for the Messages_admin to know what fields to display to the user.
268
-        // Also, notice that the "values" are equal to the field type
269
-        // that messages admin will use to know what kind of field to display.
270
-        // The values ALSO have one index labeled "shortcode".
271
-        // The values in that array indicate which ACTUAL SHORTCODE (i.e. [SHORTCODE])
272
-        // is required in order for this extra field to be displayed.
273
-        //  If the required shortcode isn't part of the shortcodes array
274
-        // then the field is not needed and will not be displayed/parsed.
275
-        $this->_template_fields = array(
276
-            'subject' => array(
277
-                'input' => 'text',
278
-                'label' => __('Page Title', 'event_espresso'),
279
-                'type' => 'string',
280
-                'required' => true,
281
-                'validation' => true,
282
-                'css_class' => 'large-text',
283
-                'format' => '%s',
284
-            ),
285
-            'content' => '',
286
-            //left empty b/c it is in the "extra array" but messenger still needs needs to know this is a field.
287
-            'extra' => array(
288
-                'content' => array(
289
-                    'main' => array(
290
-                        'input' => 'wp_editor',
291
-                        'label' => __('Main Content', 'event_espresso'),
292
-                        'type' => 'string',
293
-                        'required' => true,
294
-                        'validation' => true,
295
-                        'format' => '%s',
296
-                        'rows' => '15',
297
-                    ),
298
-                    'event_list' => array(
299
-                        'input' => 'wp_editor',
300
-                        'label' => '[EVENT_LIST]',
301
-                        'type' => 'string',
302
-                        'required' => true,
303
-                        'validation' => true,
304
-                        'format' => '%s',
305
-                        'rows' => '15',
306
-                        'shortcodes_required' => array('[EVENT_LIST]'),
307
-                    ),
308
-                    'ticket_list' => array(
309
-                        'input' => 'textarea',
310
-                        'label' => '[TICKET_LIST]',
311
-                        'type' => 'string',
312
-                        'required' => true,
313
-                        'validation' => true,
314
-                        'format' => '%s',
315
-                        'css_class' => 'large-text',
316
-                        'rows' => '10',
317
-                        'shortcodes_required' => array('[TICKET_LIST]'),
318
-                    ),
319
-                    'ticket_line_item_no_pms' => array(
320
-                        'input' => 'textarea',
321
-                        'label' => '[TICKET_LINE_ITEM_LIST] <br>' . __(
322
-                                'Ticket Line Item List with no Price Modifiers',
323
-                                'event_espresso'
324
-                            ),
325
-                        'type' => 'string',
326
-                        'required' => false,
327
-                        'validation' => true,
328
-                        'format' => '%s',
329
-                        'css_class' => 'large-text',
330
-                        'rows' => '5',
331
-                        'shortcodes_required' => array('[TICKET_LINE_ITEM_LIST]'),
332
-                    ),
333
-                    'ticket_line_item_pms' => array(
334
-                        'input' => 'textarea',
335
-                        'label' => '[TICKET_LINE_ITEM_LIST] <br>' . __(
336
-                                'Ticket Line Item List with Price Modifiers',
337
-                                'event_espresso'
338
-                            ),
339
-                        'type' => 'string',
340
-                        'required' => false,
341
-                        'validation' => true,
342
-                        'format' => '%s',
343
-                        'css_class' => 'large-text',
344
-                        'rows' => '5',
345
-                        'shortcodes_required' => array('[TICKET_LINE_ITEM_LIST]'),
346
-                    ),
347
-                    'price_modifier_line_item_list' => array(
348
-                        'input' => 'textarea',
349
-                        'label' => '[PRICE_MODIFIER_LINE_ITEM_LIST]',
350
-                        'type' => 'string',
351
-                        'required' => false,
352
-                        'validation' => true,
353
-                        'format' => '%s',
354
-                        'css_class' => 'large-text',
355
-                        'rows' => '5',
356
-                        'shortcodes_required' => array('[PRICE_MODIFIER_LINE_ITEM_LIST]'),
357
-                    ),
358
-                    'datetime_list' => array(
359
-                        'input' => 'textarea',
360
-                        'label' => '[DATETIME_LIST]',
361
-                        'type' => 'string',
362
-                        'required' => true,
363
-                        'validation' => true,
364
-                        'format' => '%s',
365
-                        'css_class' => 'large-text',
366
-                        'rows' => '5',
367
-                        'shortcodes_required' => array('[DATETIME_LIST]'),
368
-                    ),
369
-                    'attendee_list' => array(
370
-                        'input' => 'textarea',
371
-                        'label' => '[ATTENDEE_LIST]',
372
-                        'type' => 'string',
373
-                        'required' => true,
374
-                        'validation' => true,
375
-                        'format' => '%s',
376
-                        'css_class' => 'large-text',
377
-                        'rows' => '5',
378
-                        'shortcodes_required' => array('[ATTENDEE_LIST]'),
379
-                    ),
380
-                    'tax_line_item_list' => array(
381
-                        'input' => 'textarea',
382
-                        'label' => '[TAX_LINE_ITEM_LIST]',
383
-                        'type' => 'string',
384
-                        'required' => false,
385
-                        'validation' => true,
386
-                        'format' => '%s',
387
-                        'css_class' => 'large-text',
388
-                        'rows' => '5',
389
-                        'shortcodes_required' => array('[TAX_LINE_ITEM_LIST]'),
390
-                    ),
391
-                    'additional_line_item_list' => array(
392
-                        'input' => 'textarea',
393
-                        'label' => '[ADDITIONAL_LINE_ITEM_LIST]',
394
-                        'type' => 'string',
395
-                        'required' => false,
396
-                        'validation' => true,
397
-                        'format' => '%s',
398
-                        'css_class' => 'large-text',
399
-                        'rows' => '5',
400
-                        'shortcodes_required' => array('[ADDITIONAL_LINE_ITEM_LIST]'),
401
-                    ),
402
-                    'payment_list' => array(
403
-                        'input' => 'textarea',
404
-                        'label' => '[PAYMENT_LIST]',
405
-                        'type' => 'string',
406
-                        'required' => true,
407
-                        'validation' => true,
408
-                        'format' => '%s',
409
-                        'css_class' => 'large-text',
410
-                        'rows' => '5',
411
-                        'shortcodes_required' => array('[PAYMENT_LIST_*]'),
412
-                    ),
413
-                ),
414
-            ),
415
-        );
416
-    }
417
-
418
-
419
-    /**
420
-     * @see   definition of this method in parent
421
-     * @since 4.5.0
422
-     */
423
-    protected function _set_default_message_types()
424
-    {
425
-        $this->_default_message_types = array('receipt', 'invoice');
426
-    }
427
-
428
-
429
-    /**
430
-     * @see   definition of this method in parent
431
-     * @since 4.5.0
432
-     */
433
-    protected function _set_valid_message_types()
434
-    {
435
-        $this->_valid_message_types = array('receipt', 'invoice');
436
-    }
437
-
438
-
439
-    /**
440
-     * Displays the message in the browser.
441
-     *
442
-     * @since 4.5.0
443
-     * @return string.
444
-     */
445
-    protected function _send_message()
446
-    {
447
-        $this->_template_args = array(
448
-            'page_title' => html_entity_decode(stripslashes($this->_subject), ENT_QUOTES, "UTF-8"),
449
-            'base_css' => $this->get_variation(
450
-                $this->_tmp_pack,
451
-                $this->_incoming_message_type->name,
452
-                true,
453
-                'base',
454
-                $this->_variation
455
-            ),
456
-            'print_css' => $this->get_variation(
457
-                $this->_tmp_pack,
458
-                $this->_incoming_message_type->name,
459
-                true,
460
-                'print',
461
-                $this->_variation
462
-            ),
463
-            'main_css' => $this->get_variation(
464
-                $this->_tmp_pack,
465
-                $this->_incoming_message_type->name,
466
-                true,
467
-                'main',
468
-                $this->_variation
469
-            ),
470
-            'main_body' => wpautop(
471
-                stripslashes_deep(
472
-                    html_entity_decode(
473
-                        apply_filters(
474
-                            'FHEE__EE_Html_messenger___send_message__main_body',
475
-                            $this->_content,
476
-                            $this->_content,
477
-                            $this->_incoming_message_type
478
-                        ),
479
-                        ENT_QUOTES,
480
-                        "UTF-8"
481
-                    )
482
-                )
483
-            ),
484
-        );
485
-        $this->_deregister_wp_hooks();
486
-        add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts_styles'));
487
-        echo $this->_get_main_template();
488
-        exit();
489
-    }
490
-
491
-
492
-    /**
493
-     * The purpose of this function is to de register all actions hooked into wp_head and wp_footer so that it doesn't
494
-     * interfere with our templates.  If users want to add any custom styles or scripts they must use the
495
-     * AHEE__EE_Html_messenger__enqueue_scripts_styles hook.
496
-     *
497
-     * @since 4.5.0
498
-     * @return void
499
-     */
500
-    protected function _deregister_wp_hooks()
501
-    {
502
-        remove_all_actions('wp_head');
503
-        remove_all_actions('wp_footer');
504
-        remove_all_actions('wp_print_footer_scripts');
505
-        remove_all_actions('wp_enqueue_scripts');
506
-        global $wp_scripts, $wp_styles;
507
-        $wp_scripts = $wp_styles = array();
508
-        //just add back in wp_enqueue_scripts and wp_print_footer_scripts cause that's all we want to load.
509
-        add_action('wp_footer', 'wp_print_footer_scripts');
510
-        add_action('wp_print_footer_scripts', '_wp_footer_scripts');
511
-        add_action('wp_head', 'wp_enqueue_scripts');
512
-    }
513
-
514
-
515
-    /**
516
-     * Overwrite parent _get_main_template for display_html purposes.
517
-     *
518
-     * @since  4.5.0
519
-     * @param bool $preview
520
-     * @return string
521
-     */
522
-    protected function _get_main_template($preview = false)
523
-    {
524
-        $wrapper_template = $this->_tmp_pack->get_wrapper($this->name, 'main');
525
-        //include message type as a template arg
526
-        $this->_template_args['message_type'] = $this->_incoming_message_type;
527
-        return EEH_Template::display_template($wrapper_template, $this->_template_args, true);
528
-    }
529
-
530
-
531
-    /**
532
-     * @return string
533
-     */
534
-    protected function _preview()
535
-    {
536
-        return $this->_send_message();
537
-    }
538
-
539
-
540
-    protected function _set_admin_settings_fields()
541
-    {
542
-    }
543
-
544
-
545
-    /**
546
-     * add the "powered by EE" credit link to the HTML receipt and invoice
547
-     *
548
-     * @param string $content
549
-     * @param string $content_again
550
-     * @param \EE_message_type $incoming_message_type
551
-     * @return string
552
-     */
553
-    public function add_powered_by_credit_link_to_receipt_and_invoice(
554
-        $content = '',
555
-        $content_again = '',
556
-        EE_message_type $incoming_message_type
557
-    )
558
-    {
559
-        if (
560
-            ($incoming_message_type->name === 'invoice' || $incoming_message_type->name === 'receipt')
561
-            && apply_filters('FHEE_EE_Html_messenger__add_powered_by_credit_link_to_receipt_and_invoice', true)
562
-        ) {
563
-            $content .= \EEH_Template::powered_by_event_espresso(
564
-                    'aln-cntr',
565
-                    '',
566
-                    array('utm_content' => 'messages_system')
567
-                )
568
-                . EEH_HTML::div(EEH_HTML::p('&nbsp;'));
569
-        }
570
-        return $content;
571
-    }
19
+	/**
20
+	 * The following are the properties that this messenger requires for displaying the html
21
+	 */
22
+	/**
23
+	 * This is the html body generated by the template via the message type.
24
+	 *
25
+	 * @var string
26
+	 */
27
+	protected $_content;
28
+
29
+
30
+	/**
31
+	 * This is for the page title that gets displayed.  (Why use "subject"?  Because the "title" tag in html is
32
+	 * equivalent to the "subject" of the page.
33
+	 *
34
+	 * @var string
35
+	 */
36
+	protected $_subject;
37
+
38
+
39
+	/**
40
+	 * EE_Html_messenger constructor.
41
+	 */
42
+	public function __construct()
43
+	{
44
+		//set properties
45
+		$this->name = 'html';
46
+		$this->description = __('This messenger outputs a message to a browser for display.', 'event_espresso');
47
+		$this->label = array(
48
+			'singular' => __('html', 'event_espresso'),
49
+			'plural' => __('html', 'event_espresso'),
50
+		);
51
+		$this->activate_on_install = true;
52
+		// add the "powered by EE" credit link to the HTML receipt and invoice
53
+		add_filter(
54
+			'FHEE__EE_Html_messenger___send_message__main_body',
55
+			array($this, 'add_powered_by_credit_link_to_receipt_and_invoice'),
56
+			10,
57
+			3
58
+		);
59
+		parent::__construct();
60
+	}
61
+
62
+
63
+	/**
64
+	 * HTML Messenger desires execution immediately.
65
+	 *
66
+	 * @see    parent::send_now() for documentation.
67
+	 * @since  4.9.0
68
+	 * @return bool
69
+	 */
70
+	public function send_now()
71
+	{
72
+		return true;
73
+	}
74
+
75
+
76
+	/**
77
+	 * HTML Messenger allows an empty to field.
78
+	 *
79
+	 * @see    parent::allow_empty_to_field() for documentation
80
+	 * @since  4.9.0
81
+	 * @return bool
82
+	 */
83
+	public function allow_empty_to_field()
84
+	{
85
+		return true;
86
+	}
87
+
88
+
89
+	/**
90
+	 * @see abstract declaration in EE_messenger for details.
91
+	 */
92
+	protected function _set_admin_pages()
93
+	{
94
+		$this->admin_registered_pages = array('events_edit' => true);
95
+	}
96
+
97
+
98
+	/**
99
+	 * @see abstract declaration in EE_messenger for details.
100
+	 */
101
+	protected function _set_valid_shortcodes()
102
+	{
103
+		$this->_valid_shortcodes = array();
104
+	}
105
+
106
+
107
+	/**
108
+	 * @see abstract declaration in EE_messenger for details.
109
+	 */
110
+	protected function _set_validator_config()
111
+	{
112
+		$this->_validator_config = array(
113
+			'subject' => array(
114
+				'shortcodes' => array('organization', 'primary_registration_details', 'email', 'transaction'),
115
+			),
116
+			'content' => array(
117
+				'shortcodes' => array(
118
+					'organization',
119
+					'primary_registration_list',
120
+					'primary_registration_details',
121
+					'email',
122
+					'transaction',
123
+					'event_list',
124
+					'payment_list',
125
+					'venue',
126
+					'line_item_list',
127
+					'messenger',
128
+					'ticket_list',
129
+				),
130
+			),
131
+			'event_list' => array(
132
+				'shortcodes' => array(
133
+					'event',
134
+					'ticket_list',
135
+					'venue',
136
+					'primary_registration_details',
137
+					'primary_registration_list',
138
+					'event_author',
139
+				),
140
+				'required' => array('[EVENT_LIST]'),
141
+			),
142
+			'ticket_list' => array(
143
+				'shortcodes' => array(
144
+					'attendee_list',
145
+					'ticket',
146
+					'datetime_list',
147
+					'primary_registration_details',
148
+					'line_item_list',
149
+					'venue',
150
+				),
151
+				'required' => array('[TICKET_LIST]'),
152
+			),
153
+			'ticket_line_item_no_pms' => array(
154
+				'shortcodes' => array('line_item', 'ticket'),
155
+				'required' => array('[TICKET_LINE_ITEM_LIST]'),
156
+			),
157
+			'ticket_line_item_pms' => array(
158
+				'shortcodes' => array('line_item', 'ticket', 'line_item_list'),
159
+				'required' => array('[TICKET_LINE_ITEM_LIST]'),
160
+			),
161
+			'price_modifier_line_item_list' => array(
162
+				'shortcodes' => array('line_item'),
163
+				'required' => array('[PRICE_MODIFIER_LINE_ITEM_LIST]'),
164
+			),
165
+			'datetime_list' => array(
166
+				'shortcodes' => array('datetime'),
167
+				'required' => array('[DATETIME_LIST]'),
168
+			),
169
+			'attendee_list' => array(
170
+				'shortcodes' => array('attendee'),
171
+				'required' => array('[ATTENDEE_LIST]'),
172
+			),
173
+			'tax_line_item_list' => array(
174
+				'shortcodes' => array('line_item'),
175
+				'required' => array('[TAX_LINE_ITEM_LIST]'),
176
+			),
177
+			'additional_line_item_list' => array(
178
+				'shortcodes' => array('line_item'),
179
+				'required' => array('[ADDITIONAL_LINE_ITEM_LIST]'),
180
+			),
181
+			'payment_list' => array(
182
+				'shortcodes' => array('payment'),
183
+				'required' => array('[PAYMENT_LIST_*]'),
184
+			),
185
+		);
186
+	}
187
+
188
+
189
+	/**
190
+	 * This is a method called from EE_messages when this messenger is a generating messenger and the sending messenger
191
+	 * is a different messenger.  Child messengers can set hooks for the sending messenger to callback on if necessary
192
+	 * (i.e. swap out css files or something else).
193
+	 *
194
+	 * @since 4.5.0
195
+	 * @param string $sending_messenger_name the name of the sending messenger so we only set the hooks needed.
196
+	 * @return void
197
+	 */
198
+	public function do_secondary_messenger_hooks($sending_messenger_name)
199
+	{
200
+		if ($sending_messenger_name = 'pdf') {
201
+			add_filter('EE_messenger__get_variation__variation', array($this, 'add_html_css'), 10, 8);
202
+		}
203
+	}
204
+
205
+
206
+	/**
207
+	 * @param                            $variation_path
208
+	 * @param \EE_Messages_Template_Pack $template_pack
209
+	 * @param                            $messenger_name
210
+	 * @param                            $message_type_name
211
+	 * @param                            $url
212
+	 * @param                            $type
213
+	 * @param                            $variation
214
+	 * @param                            $skip_filters
215
+	 * @return string
216
+	 */
217
+	public function add_html_css(
218
+		$variation_path,
219
+		EE_Messages_Template_Pack $template_pack,
220
+		$messenger_name,
221
+		$message_type_name,
222
+		$url,
223
+		$type,
224
+		$variation,
225
+		$skip_filters
226
+	)
227
+	{
228
+		$variation = $template_pack->get_variation(
229
+			$this->name,
230
+			$message_type_name,
231
+			$type,
232
+			$variation,
233
+			$url,
234
+			'.css',
235
+			$skip_filters
236
+		);
237
+		return $variation;
238
+	}
239
+
240
+
241
+	/**
242
+	 * Takes care of enqueuing any necessary scripts or styles for the page.  A do_action() so message types using this
243
+	 * messenger can add their own js.
244
+	 *
245
+	 * @return void.
246
+	 */
247
+	public function enqueue_scripts_styles()
248
+	{
249
+		parent::enqueue_scripts_styles();
250
+		do_action('AHEE__EE_Html_messenger__enqueue_scripts_styles');
251
+	}
252
+
253
+
254
+	/**
255
+	 * _set_template_fields
256
+	 * This sets up the fields that a messenger requires for the message to go out.
257
+	 *
258
+	 * @access  protected
259
+	 * @return void
260
+	 */
261
+	protected function _set_template_fields()
262
+	{
263
+		// any extra template fields that are NOT used by the messenger
264
+		// but will get used by a messenger field for shortcode replacement
265
+		// get added to the 'extra' key in an associated array
266
+		// indexed by the messenger field they relate to.
267
+		// This is important for the Messages_admin to know what fields to display to the user.
268
+		// Also, notice that the "values" are equal to the field type
269
+		// that messages admin will use to know what kind of field to display.
270
+		// The values ALSO have one index labeled "shortcode".
271
+		// The values in that array indicate which ACTUAL SHORTCODE (i.e. [SHORTCODE])
272
+		// is required in order for this extra field to be displayed.
273
+		//  If the required shortcode isn't part of the shortcodes array
274
+		// then the field is not needed and will not be displayed/parsed.
275
+		$this->_template_fields = array(
276
+			'subject' => array(
277
+				'input' => 'text',
278
+				'label' => __('Page Title', 'event_espresso'),
279
+				'type' => 'string',
280
+				'required' => true,
281
+				'validation' => true,
282
+				'css_class' => 'large-text',
283
+				'format' => '%s',
284
+			),
285
+			'content' => '',
286
+			//left empty b/c it is in the "extra array" but messenger still needs needs to know this is a field.
287
+			'extra' => array(
288
+				'content' => array(
289
+					'main' => array(
290
+						'input' => 'wp_editor',
291
+						'label' => __('Main Content', 'event_espresso'),
292
+						'type' => 'string',
293
+						'required' => true,
294
+						'validation' => true,
295
+						'format' => '%s',
296
+						'rows' => '15',
297
+					),
298
+					'event_list' => array(
299
+						'input' => 'wp_editor',
300
+						'label' => '[EVENT_LIST]',
301
+						'type' => 'string',
302
+						'required' => true,
303
+						'validation' => true,
304
+						'format' => '%s',
305
+						'rows' => '15',
306
+						'shortcodes_required' => array('[EVENT_LIST]'),
307
+					),
308
+					'ticket_list' => array(
309
+						'input' => 'textarea',
310
+						'label' => '[TICKET_LIST]',
311
+						'type' => 'string',
312
+						'required' => true,
313
+						'validation' => true,
314
+						'format' => '%s',
315
+						'css_class' => 'large-text',
316
+						'rows' => '10',
317
+						'shortcodes_required' => array('[TICKET_LIST]'),
318
+					),
319
+					'ticket_line_item_no_pms' => array(
320
+						'input' => 'textarea',
321
+						'label' => '[TICKET_LINE_ITEM_LIST] <br>' . __(
322
+								'Ticket Line Item List with no Price Modifiers',
323
+								'event_espresso'
324
+							),
325
+						'type' => 'string',
326
+						'required' => false,
327
+						'validation' => true,
328
+						'format' => '%s',
329
+						'css_class' => 'large-text',
330
+						'rows' => '5',
331
+						'shortcodes_required' => array('[TICKET_LINE_ITEM_LIST]'),
332
+					),
333
+					'ticket_line_item_pms' => array(
334
+						'input' => 'textarea',
335
+						'label' => '[TICKET_LINE_ITEM_LIST] <br>' . __(
336
+								'Ticket Line Item List with Price Modifiers',
337
+								'event_espresso'
338
+							),
339
+						'type' => 'string',
340
+						'required' => false,
341
+						'validation' => true,
342
+						'format' => '%s',
343
+						'css_class' => 'large-text',
344
+						'rows' => '5',
345
+						'shortcodes_required' => array('[TICKET_LINE_ITEM_LIST]'),
346
+					),
347
+					'price_modifier_line_item_list' => array(
348
+						'input' => 'textarea',
349
+						'label' => '[PRICE_MODIFIER_LINE_ITEM_LIST]',
350
+						'type' => 'string',
351
+						'required' => false,
352
+						'validation' => true,
353
+						'format' => '%s',
354
+						'css_class' => 'large-text',
355
+						'rows' => '5',
356
+						'shortcodes_required' => array('[PRICE_MODIFIER_LINE_ITEM_LIST]'),
357
+					),
358
+					'datetime_list' => array(
359
+						'input' => 'textarea',
360
+						'label' => '[DATETIME_LIST]',
361
+						'type' => 'string',
362
+						'required' => true,
363
+						'validation' => true,
364
+						'format' => '%s',
365
+						'css_class' => 'large-text',
366
+						'rows' => '5',
367
+						'shortcodes_required' => array('[DATETIME_LIST]'),
368
+					),
369
+					'attendee_list' => array(
370
+						'input' => 'textarea',
371
+						'label' => '[ATTENDEE_LIST]',
372
+						'type' => 'string',
373
+						'required' => true,
374
+						'validation' => true,
375
+						'format' => '%s',
376
+						'css_class' => 'large-text',
377
+						'rows' => '5',
378
+						'shortcodes_required' => array('[ATTENDEE_LIST]'),
379
+					),
380
+					'tax_line_item_list' => array(
381
+						'input' => 'textarea',
382
+						'label' => '[TAX_LINE_ITEM_LIST]',
383
+						'type' => 'string',
384
+						'required' => false,
385
+						'validation' => true,
386
+						'format' => '%s',
387
+						'css_class' => 'large-text',
388
+						'rows' => '5',
389
+						'shortcodes_required' => array('[TAX_LINE_ITEM_LIST]'),
390
+					),
391
+					'additional_line_item_list' => array(
392
+						'input' => 'textarea',
393
+						'label' => '[ADDITIONAL_LINE_ITEM_LIST]',
394
+						'type' => 'string',
395
+						'required' => false,
396
+						'validation' => true,
397
+						'format' => '%s',
398
+						'css_class' => 'large-text',
399
+						'rows' => '5',
400
+						'shortcodes_required' => array('[ADDITIONAL_LINE_ITEM_LIST]'),
401
+					),
402
+					'payment_list' => array(
403
+						'input' => 'textarea',
404
+						'label' => '[PAYMENT_LIST]',
405
+						'type' => 'string',
406
+						'required' => true,
407
+						'validation' => true,
408
+						'format' => '%s',
409
+						'css_class' => 'large-text',
410
+						'rows' => '5',
411
+						'shortcodes_required' => array('[PAYMENT_LIST_*]'),
412
+					),
413
+				),
414
+			),
415
+		);
416
+	}
417
+
418
+
419
+	/**
420
+	 * @see   definition of this method in parent
421
+	 * @since 4.5.0
422
+	 */
423
+	protected function _set_default_message_types()
424
+	{
425
+		$this->_default_message_types = array('receipt', 'invoice');
426
+	}
427
+
428
+
429
+	/**
430
+	 * @see   definition of this method in parent
431
+	 * @since 4.5.0
432
+	 */
433
+	protected function _set_valid_message_types()
434
+	{
435
+		$this->_valid_message_types = array('receipt', 'invoice');
436
+	}
437
+
438
+
439
+	/**
440
+	 * Displays the message in the browser.
441
+	 *
442
+	 * @since 4.5.0
443
+	 * @return string.
444
+	 */
445
+	protected function _send_message()
446
+	{
447
+		$this->_template_args = array(
448
+			'page_title' => html_entity_decode(stripslashes($this->_subject), ENT_QUOTES, "UTF-8"),
449
+			'base_css' => $this->get_variation(
450
+				$this->_tmp_pack,
451
+				$this->_incoming_message_type->name,
452
+				true,
453
+				'base',
454
+				$this->_variation
455
+			),
456
+			'print_css' => $this->get_variation(
457
+				$this->_tmp_pack,
458
+				$this->_incoming_message_type->name,
459
+				true,
460
+				'print',
461
+				$this->_variation
462
+			),
463
+			'main_css' => $this->get_variation(
464
+				$this->_tmp_pack,
465
+				$this->_incoming_message_type->name,
466
+				true,
467
+				'main',
468
+				$this->_variation
469
+			),
470
+			'main_body' => wpautop(
471
+				stripslashes_deep(
472
+					html_entity_decode(
473
+						apply_filters(
474
+							'FHEE__EE_Html_messenger___send_message__main_body',
475
+							$this->_content,
476
+							$this->_content,
477
+							$this->_incoming_message_type
478
+						),
479
+						ENT_QUOTES,
480
+						"UTF-8"
481
+					)
482
+				)
483
+			),
484
+		);
485
+		$this->_deregister_wp_hooks();
486
+		add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts_styles'));
487
+		echo $this->_get_main_template();
488
+		exit();
489
+	}
490
+
491
+
492
+	/**
493
+	 * The purpose of this function is to de register all actions hooked into wp_head and wp_footer so that it doesn't
494
+	 * interfere with our templates.  If users want to add any custom styles or scripts they must use the
495
+	 * AHEE__EE_Html_messenger__enqueue_scripts_styles hook.
496
+	 *
497
+	 * @since 4.5.0
498
+	 * @return void
499
+	 */
500
+	protected function _deregister_wp_hooks()
501
+	{
502
+		remove_all_actions('wp_head');
503
+		remove_all_actions('wp_footer');
504
+		remove_all_actions('wp_print_footer_scripts');
505
+		remove_all_actions('wp_enqueue_scripts');
506
+		global $wp_scripts, $wp_styles;
507
+		$wp_scripts = $wp_styles = array();
508
+		//just add back in wp_enqueue_scripts and wp_print_footer_scripts cause that's all we want to load.
509
+		add_action('wp_footer', 'wp_print_footer_scripts');
510
+		add_action('wp_print_footer_scripts', '_wp_footer_scripts');
511
+		add_action('wp_head', 'wp_enqueue_scripts');
512
+	}
513
+
514
+
515
+	/**
516
+	 * Overwrite parent _get_main_template for display_html purposes.
517
+	 *
518
+	 * @since  4.5.0
519
+	 * @param bool $preview
520
+	 * @return string
521
+	 */
522
+	protected function _get_main_template($preview = false)
523
+	{
524
+		$wrapper_template = $this->_tmp_pack->get_wrapper($this->name, 'main');
525
+		//include message type as a template arg
526
+		$this->_template_args['message_type'] = $this->_incoming_message_type;
527
+		return EEH_Template::display_template($wrapper_template, $this->_template_args, true);
528
+	}
529
+
530
+
531
+	/**
532
+	 * @return string
533
+	 */
534
+	protected function _preview()
535
+	{
536
+		return $this->_send_message();
537
+	}
538
+
539
+
540
+	protected function _set_admin_settings_fields()
541
+	{
542
+	}
543
+
544
+
545
+	/**
546
+	 * add the "powered by EE" credit link to the HTML receipt and invoice
547
+	 *
548
+	 * @param string $content
549
+	 * @param string $content_again
550
+	 * @param \EE_message_type $incoming_message_type
551
+	 * @return string
552
+	 */
553
+	public function add_powered_by_credit_link_to_receipt_and_invoice(
554
+		$content = '',
555
+		$content_again = '',
556
+		EE_message_type $incoming_message_type
557
+	)
558
+	{
559
+		if (
560
+			($incoming_message_type->name === 'invoice' || $incoming_message_type->name === 'receipt')
561
+			&& apply_filters('FHEE_EE_Html_messenger__add_powered_by_credit_link_to_receipt_and_invoice', true)
562
+		) {
563
+			$content .= \EEH_Template::powered_by_event_espresso(
564
+					'aln-cntr',
565
+					'',
566
+					array('utm_content' => 'messages_system')
567
+				)
568
+				. EEH_HTML::div(EEH_HTML::p('&nbsp;'));
569
+		}
570
+		return $content;
571
+	}
572 572
 
573 573
 }
Please login to merge, or discard this patch.
core/services/collections/iterators/CollectionFilterCallbackIterator.php 1 patch
Indentation   +47 added lines, -47 removed lines patch added patch discarded remove patch
@@ -9,51 +9,51 @@
 block discarded – undo
9 9
 class CollectionFilterCallbackIterator extends FilterIterator
10 10
 {
11 11
 
12
-    /**
13
-     * Used for determining whether the iterated object in the Collection is "valid" or not.
14
-     * @var Closure
15
-     */
16
-    private $acceptance_callback;
17
-
18
-
19
-    /**
20
-     * CollectionFilterCallbackIterator constructor.
21
-     *
22
-     * @param Collection $collection
23
-     * @param Closure    $acceptance_callback  The closure will receive an instance of whatever object is stored on the
24
-     *                                         collection when iterating over the collection and should return boolean.
25
-     */
26
-    public function __construct(Collection $collection, Closure $acceptance_callback)
27
-    {
28
-        $this->acceptance_callback = $acceptance_callback;
29
-        parent::__construct($collection);
30
-    }
31
-
32
-    /**
33
-     * Check whether the current element of the iterator is acceptable
34
-     *
35
-     * @link  http://php.net/manual/en/filteriterator.accept.php
36
-     * @return bool true if the current element is acceptable, otherwise false.
37
-     */
38
-    public function accept()
39
-    {
40
-        $acceptance_callback = $this->acceptance_callback;
41
-        return $acceptance_callback($this->getInnerIterator()->current());
42
-    }
43
-
44
-
45
-
46
-    /**
47
-     * Returns a filtered array of objects from the collection using the provided acceptance callback
48
-     * @return array
49
-     */
50
-    public function getFiltered()
51
-    {
52
-        $filtered_array = array();
53
-        $this->rewind();
54
-        foreach ($this as $filtered_object) {
55
-            $filtered_array[] = $filtered_object;
56
-        }
57
-        return $filtered_array;
58
-    }
12
+	/**
13
+	 * Used for determining whether the iterated object in the Collection is "valid" or not.
14
+	 * @var Closure
15
+	 */
16
+	private $acceptance_callback;
17
+
18
+
19
+	/**
20
+	 * CollectionFilterCallbackIterator constructor.
21
+	 *
22
+	 * @param Collection $collection
23
+	 * @param Closure    $acceptance_callback  The closure will receive an instance of whatever object is stored on the
24
+	 *                                         collection when iterating over the collection and should return boolean.
25
+	 */
26
+	public function __construct(Collection $collection, Closure $acceptance_callback)
27
+	{
28
+		$this->acceptance_callback = $acceptance_callback;
29
+		parent::__construct($collection);
30
+	}
31
+
32
+	/**
33
+	 * Check whether the current element of the iterator is acceptable
34
+	 *
35
+	 * @link  http://php.net/manual/en/filteriterator.accept.php
36
+	 * @return bool true if the current element is acceptable, otherwise false.
37
+	 */
38
+	public function accept()
39
+	{
40
+		$acceptance_callback = $this->acceptance_callback;
41
+		return $acceptance_callback($this->getInnerIterator()->current());
42
+	}
43
+
44
+
45
+
46
+	/**
47
+	 * Returns a filtered array of objects from the collection using the provided acceptance callback
48
+	 * @return array
49
+	 */
50
+	public function getFiltered()
51
+	{
52
+		$filtered_array = array();
53
+		$this->rewind();
54
+		foreach ($this as $filtered_object) {
55
+			$filtered_array[] = $filtered_object;
56
+		}
57
+		return $filtered_array;
58
+	}
59 59
 }
Please login to merge, or discard this patch.
core/services/collections/iterators/FilterIteratorsHelper.php 1 patch
Indentation   +14 added lines, -14 removed lines patch added patch discarded remove patch
@@ -17,18 +17,18 @@
 block discarded – undo
17 17
 {
18 18
 
19 19
 
20
-    /**
21
-     * Uses CollectionFilterCallbackIterator on a provided collection with provided Closure for filtering each object
22
-     * in the collection.
23
-     * The closure receives an instance of the object and should return false if it is not "valid" and true if it is.
24
-     *
25
-     * @param Collection $collection
26
-     * @param Closure    $acceptance_callback
27
-     * @return array
28
-     */
29
-    public static function getFilteredObjectsFromCollection(Collection $collection, Closure $acceptance_callback)
30
-    {
31
-        $collection_filter_iterator = new CollectionFilterCallbackIterator($collection, $acceptance_callback);
32
-        return $collection_filter_iterator->getFiltered();
33
-    }
20
+	/**
21
+	 * Uses CollectionFilterCallbackIterator on a provided collection with provided Closure for filtering each object
22
+	 * in the collection.
23
+	 * The closure receives an instance of the object and should return false if it is not "valid" and true if it is.
24
+	 *
25
+	 * @param Collection $collection
26
+	 * @param Closure    $acceptance_callback
27
+	 * @return array
28
+	 */
29
+	public static function getFilteredObjectsFromCollection(Collection $collection, Closure $acceptance_callback)
30
+	{
31
+		$collection_filter_iterator = new CollectionFilterCallbackIterator($collection, $acceptance_callback);
32
+		return $collection_filter_iterator->getFiltered();
33
+	}
34 34
 }
35 35
\ No newline at end of file
Please login to merge, or discard this patch.
espresso.php 1 patch
Indentation   +192 added lines, -192 removed lines patch added patch discarded remove patch
@@ -38,217 +38,217 @@
 block discarded – undo
38 38
  * @since       4.0
39 39
  */
40 40
 if (function_exists('espresso_version')) {
41
-    if (! function_exists('espresso_duplicate_plugin_error')) {
42
-        /**
43
-         *    espresso_duplicate_plugin_error
44
-         *    displays if more than one version of EE is activated at the same time
45
-         */
46
-        function espresso_duplicate_plugin_error()
47
-        {
48
-            ?>
41
+	if (! function_exists('espresso_duplicate_plugin_error')) {
42
+		/**
43
+		 *    espresso_duplicate_plugin_error
44
+		 *    displays if more than one version of EE is activated at the same time
45
+		 */
46
+		function espresso_duplicate_plugin_error()
47
+		{
48
+			?>
49 49
             <div class="error">
50 50
                 <p>
51 51
                     <?php
52
-                    echo esc_html__(
53
-                        'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
-                        'event_espresso'
55
-                    ); ?>
52
+					echo esc_html__(
53
+						'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
+						'event_espresso'
55
+					); ?>
56 56
                 </p>
57 57
             </div>
58 58
             <?php
59
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
60
-        }
61
-    }
62
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
59
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
60
+		}
61
+	}
62
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
63 63
 
64 64
 } else {
65
-    define('EE_MIN_PHP_VER_REQUIRED', '5.3.9');
66
-    if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
67
-        /**
68
-         * espresso_minimum_php_version_error
69
-         *
70
-         * @return void
71
-         */
72
-        function espresso_minimum_php_version_error()
73
-        {
74
-            ?>
65
+	define('EE_MIN_PHP_VER_REQUIRED', '5.3.9');
66
+	if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
67
+		/**
68
+		 * espresso_minimum_php_version_error
69
+		 *
70
+		 * @return void
71
+		 */
72
+		function espresso_minimum_php_version_error()
73
+		{
74
+			?>
75 75
             <div class="error">
76 76
                 <p>
77 77
                     <?php
78
-                    printf(
79
-                        esc_html__(
80
-                            'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
81
-                            'event_espresso'
82
-                        ),
83
-                        EE_MIN_PHP_VER_REQUIRED,
84
-                        PHP_VERSION,
85
-                        '<br/>',
86
-                        '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
87
-                    );
88
-                    ?>
78
+					printf(
79
+						esc_html__(
80
+							'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
81
+							'event_espresso'
82
+						),
83
+						EE_MIN_PHP_VER_REQUIRED,
84
+						PHP_VERSION,
85
+						'<br/>',
86
+						'<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
87
+					);
88
+					?>
89 89
                 </p>
90 90
             </div>
91 91
             <?php
92
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
93
-        }
92
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
93
+		}
94 94
 
95
-        add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
96
-    } else {
97
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
98
-        /**
99
-         * espresso_version
100
-         * Returns the plugin version
101
-         *
102
-         * @return string
103
-         */
104
-        function espresso_version()
105
-        {
106
-            return apply_filters('FHEE__espresso__espresso_version', '4.9.54.rc.004');
107
-        }
95
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
96
+	} else {
97
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
98
+		/**
99
+		 * espresso_version
100
+		 * Returns the plugin version
101
+		 *
102
+		 * @return string
103
+		 */
104
+		function espresso_version()
105
+		{
106
+			return apply_filters('FHEE__espresso__espresso_version', '4.9.54.rc.004');
107
+		}
108 108
 
109
-        /**
110
-         * espresso_plugin_activation
111
-         * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
112
-         */
113
-        function espresso_plugin_activation()
114
-        {
115
-            update_option('ee_espresso_activation', true);
116
-        }
109
+		/**
110
+		 * espresso_plugin_activation
111
+		 * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
112
+		 */
113
+		function espresso_plugin_activation()
114
+		{
115
+			update_option('ee_espresso_activation', true);
116
+		}
117 117
 
118
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
119
-        /**
120
-         *    espresso_load_error_handling
121
-         *    this function loads EE's class for handling exceptions and errors
122
-         */
123
-        function espresso_load_error_handling()
124
-        {
125
-            static $error_handling_loaded = false;
126
-            if ($error_handling_loaded) {
127
-                return;
128
-            }
129
-            // load debugging tools
130
-            if (WP_DEBUG === true && is_readable(EE_HELPERS . 'EEH_Debug_Tools.helper.php')) {
131
-                require_once   EE_HELPERS . 'EEH_Debug_Tools.helper.php';
132
-                \EEH_Debug_Tools::instance();
133
-            }
134
-            // load error handling
135
-            if (is_readable(EE_CORE . 'EE_Error.core.php')) {
136
-                require_once EE_CORE . 'EE_Error.core.php';
137
-            } else {
138
-                wp_die(esc_html__('The EE_Error core class could not be loaded.', 'event_espresso'));
139
-            }
140
-            $error_handling_loaded = true;
141
-        }
118
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
119
+		/**
120
+		 *    espresso_load_error_handling
121
+		 *    this function loads EE's class for handling exceptions and errors
122
+		 */
123
+		function espresso_load_error_handling()
124
+		{
125
+			static $error_handling_loaded = false;
126
+			if ($error_handling_loaded) {
127
+				return;
128
+			}
129
+			// load debugging tools
130
+			if (WP_DEBUG === true && is_readable(EE_HELPERS . 'EEH_Debug_Tools.helper.php')) {
131
+				require_once   EE_HELPERS . 'EEH_Debug_Tools.helper.php';
132
+				\EEH_Debug_Tools::instance();
133
+			}
134
+			// load error handling
135
+			if (is_readable(EE_CORE . 'EE_Error.core.php')) {
136
+				require_once EE_CORE . 'EE_Error.core.php';
137
+			} else {
138
+				wp_die(esc_html__('The EE_Error core class could not be loaded.', 'event_espresso'));
139
+			}
140
+			$error_handling_loaded = true;
141
+		}
142 142
 
143
-        /**
144
-         *    espresso_load_required
145
-         *    given a class name and path, this function will load that file or throw an exception
146
-         *
147
-         * @param    string $classname
148
-         * @param    string $full_path_to_file
149
-         * @throws    EE_Error
150
-         */
151
-        function espresso_load_required($classname, $full_path_to_file)
152
-        {
153
-            if (is_readable($full_path_to_file)) {
154
-                require_once $full_path_to_file;
155
-            } else {
156
-                throw new \EE_Error (
157
-                    sprintf(
158
-                        esc_html__(
159
-                            'The %s class file could not be located or is not readable due to file permissions.',
160
-                            'event_espresso'
161
-                        ),
162
-                        $classname
163
-                    )
164
-                );
165
-            }
166
-        }
143
+		/**
144
+		 *    espresso_load_required
145
+		 *    given a class name and path, this function will load that file or throw an exception
146
+		 *
147
+		 * @param    string $classname
148
+		 * @param    string $full_path_to_file
149
+		 * @throws    EE_Error
150
+		 */
151
+		function espresso_load_required($classname, $full_path_to_file)
152
+		{
153
+			if (is_readable($full_path_to_file)) {
154
+				require_once $full_path_to_file;
155
+			} else {
156
+				throw new \EE_Error (
157
+					sprintf(
158
+						esc_html__(
159
+							'The %s class file could not be located or is not readable due to file permissions.',
160
+							'event_espresso'
161
+						),
162
+						$classname
163
+					)
164
+				);
165
+			}
166
+		}
167 167
 
168
-        /**
169
-         * @since 4.9.27
170
-         * @throws \EE_Error
171
-         * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
172
-         * @throws \EventEspresso\core\exceptions\InvalidEntityException
173
-         * @throws \EventEspresso\core\exceptions\InvalidIdentifierException
174
-         * @throws \EventEspresso\core\exceptions\InvalidClassException
175
-         * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
176
-         * @throws \EventEspresso\core\services\container\exceptions\ServiceExistsException
177
-         * @throws \EventEspresso\core\services\container\exceptions\ServiceNotFoundException
178
-         * @throws \OutOfBoundsException
179
-         */
180
-        function bootstrap_espresso()
181
-        {
182
-            require_once __DIR__ . '/core/espresso_definitions.php';
183
-            try {
184
-                espresso_load_error_handling();
185
-                espresso_load_required(
186
-                    'EEH_Base',
187
-                    EE_CORE . 'helpers' . DS . 'EEH_Base.helper.php'
188
-                );
189
-                espresso_load_required(
190
-                    'EEH_File',
191
-                    EE_CORE . 'interfaces' . DS . 'EEHI_File.interface.php'
192
-                );
193
-                espresso_load_required(
194
-                    'EEH_File',
195
-                    EE_CORE . 'helpers' . DS . 'EEH_File.helper.php'
196
-                );
197
-                espresso_load_required(
198
-                    'EEH_Array',
199
-                    EE_CORE . 'helpers' . DS . 'EEH_Array.helper.php'
200
-                );
201
-                // instantiate and configure PSR4 autoloader
202
-                espresso_load_required(
203
-                    'Psr4Autoloader',
204
-                    EE_CORE . 'Psr4Autoloader.php'
205
-                );
206
-                espresso_load_required(
207
-                    'EE_Psr4AutoloaderInit',
208
-                    EE_CORE . 'EE_Psr4AutoloaderInit.core.php'
209
-                );
210
-                $AutoloaderInit = new EE_Psr4AutoloaderInit();
211
-                $AutoloaderInit->initializeAutoloader();
212
-                espresso_load_required(
213
-                    'EE_Request',
214
-                    EE_CORE . 'request_stack' . DS . 'EE_Request.core.php'
215
-                );
216
-                espresso_load_required(
217
-                    'EE_Response',
218
-                    EE_CORE . 'request_stack' . DS . 'EE_Response.core.php'
219
-                );
220
-                espresso_load_required(
221
-                    'EE_Bootstrap',
222
-                    EE_CORE . 'EE_Bootstrap.core.php'
223
-                );
224
-                // bootstrap EE and the request stack
225
-                new EE_Bootstrap(
226
-                    new EE_Request($_GET, $_POST, $_COOKIE),
227
-                    new EE_Response()
228
-                );
229
-            } catch (Exception $e) {
230
-                require_once EE_CORE . 'exceptions' . DS . 'ExceptionStackTraceDisplay.php';
231
-                new EventEspresso\core\exceptions\ExceptionStackTraceDisplay($e);
232
-            }
233
-        }
234
-        bootstrap_espresso();
235
-    }
168
+		/**
169
+		 * @since 4.9.27
170
+		 * @throws \EE_Error
171
+		 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
172
+		 * @throws \EventEspresso\core\exceptions\InvalidEntityException
173
+		 * @throws \EventEspresso\core\exceptions\InvalidIdentifierException
174
+		 * @throws \EventEspresso\core\exceptions\InvalidClassException
175
+		 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
176
+		 * @throws \EventEspresso\core\services\container\exceptions\ServiceExistsException
177
+		 * @throws \EventEspresso\core\services\container\exceptions\ServiceNotFoundException
178
+		 * @throws \OutOfBoundsException
179
+		 */
180
+		function bootstrap_espresso()
181
+		{
182
+			require_once __DIR__ . '/core/espresso_definitions.php';
183
+			try {
184
+				espresso_load_error_handling();
185
+				espresso_load_required(
186
+					'EEH_Base',
187
+					EE_CORE . 'helpers' . DS . 'EEH_Base.helper.php'
188
+				);
189
+				espresso_load_required(
190
+					'EEH_File',
191
+					EE_CORE . 'interfaces' . DS . 'EEHI_File.interface.php'
192
+				);
193
+				espresso_load_required(
194
+					'EEH_File',
195
+					EE_CORE . 'helpers' . DS . 'EEH_File.helper.php'
196
+				);
197
+				espresso_load_required(
198
+					'EEH_Array',
199
+					EE_CORE . 'helpers' . DS . 'EEH_Array.helper.php'
200
+				);
201
+				// instantiate and configure PSR4 autoloader
202
+				espresso_load_required(
203
+					'Psr4Autoloader',
204
+					EE_CORE . 'Psr4Autoloader.php'
205
+				);
206
+				espresso_load_required(
207
+					'EE_Psr4AutoloaderInit',
208
+					EE_CORE . 'EE_Psr4AutoloaderInit.core.php'
209
+				);
210
+				$AutoloaderInit = new EE_Psr4AutoloaderInit();
211
+				$AutoloaderInit->initializeAutoloader();
212
+				espresso_load_required(
213
+					'EE_Request',
214
+					EE_CORE . 'request_stack' . DS . 'EE_Request.core.php'
215
+				);
216
+				espresso_load_required(
217
+					'EE_Response',
218
+					EE_CORE . 'request_stack' . DS . 'EE_Response.core.php'
219
+				);
220
+				espresso_load_required(
221
+					'EE_Bootstrap',
222
+					EE_CORE . 'EE_Bootstrap.core.php'
223
+				);
224
+				// bootstrap EE and the request stack
225
+				new EE_Bootstrap(
226
+					new EE_Request($_GET, $_POST, $_COOKIE),
227
+					new EE_Response()
228
+				);
229
+			} catch (Exception $e) {
230
+				require_once EE_CORE . 'exceptions' . DS . 'ExceptionStackTraceDisplay.php';
231
+				new EventEspresso\core\exceptions\ExceptionStackTraceDisplay($e);
232
+			}
233
+		}
234
+		bootstrap_espresso();
235
+	}
236 236
 }
237 237
 if (! function_exists('espresso_deactivate_plugin')) {
238
-    /**
239
-     *    deactivate_plugin
240
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
241
-     *
242
-     * @access public
243
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
244
-     * @return    void
245
-     */
246
-    function espresso_deactivate_plugin($plugin_basename = '')
247
-    {
248
-        if (! function_exists('deactivate_plugins')) {
249
-            require_once ABSPATH . 'wp-admin/includes/plugin.php';
250
-        }
251
-        unset($_GET['activate'], $_REQUEST['activate']);
252
-        deactivate_plugins($plugin_basename);
253
-    }
238
+	/**
239
+	 *    deactivate_plugin
240
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
241
+	 *
242
+	 * @access public
243
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
244
+	 * @return    void
245
+	 */
246
+	function espresso_deactivate_plugin($plugin_basename = '')
247
+	{
248
+		if (! function_exists('deactivate_plugins')) {
249
+			require_once ABSPATH . 'wp-admin/includes/plugin.php';
250
+		}
251
+		unset($_GET['activate'], $_REQUEST['activate']);
252
+		deactivate_plugins($plugin_basename);
253
+	}
254 254
 }
Please login to merge, or discard this patch.