Completed
Branch BUG-10878-event-spaces-remaini... (62f9c8)
by
unknown
151:41 queued 139:39
created
modules/ticket_selector/DisplayTicketSelector.php 1 patch
Indentation   +680 added lines, -680 removed lines patch added patch discarded remove patch
@@ -17,7 +17,7 @@  discard block
 block discarded – undo
17 17
 use WP_Post;
18 18
 
19 19
 if ( ! defined( 'EVENT_ESPRESSO_VERSION' ) ) {
20
-    exit( 'No direct script access allowed' );
20
+	exit( 'No direct script access allowed' );
21 21
 }
22 22
 
23 23
 
@@ -34,688 +34,688 @@  discard block
 block discarded – undo
34 34
 class DisplayTicketSelector
35 35
 {
36 36
 
37
-    /**
38
-     * event that ticket selector is being generated for
39
-     *
40
-     * @access protected
41
-     * @var EE_Event $event
42
-     */
43
-    protected $event;
44
-
45
-    /**
46
-     * Used to flag when the ticket selector is being called from an external iframe.
47
-     *
48
-     * @var bool $iframe
49
-     */
50
-    protected $iframe = false;
51
-
52
-    /**
53
-     * max attendees that can register for event at one time
54
-     *
55
-     * @var int $max_attendees
56
-     */
57
-    private $max_attendees = EE_INF;
58
-
59
-    /**
60
-     *@var string $date_format
61
-     */
62
-    private $date_format;
63
-
64
-    /**
65
-     *@var string $time_format
66
-     */
67
-    private $time_format;
68
-
69
-
70
-
71
-    /**
72
-     * DisplayTicketSelector constructor.
73
-     */
74
-    public function __construct()
75
-    {
76
-        $this->date_format = apply_filters(
77
-            'FHEE__EED_Ticket_Selector__display_ticket_selector__date_format',
78
-            get_option('date_format')
79
-        );
80
-        $this->time_format = apply_filters(
81
-            'FHEE__EED_Ticket_Selector__display_ticket_selector__time_format',
82
-            get_option('time_format')
83
-        );
84
-    }
85
-
86
-
87
-
88
-    /**
89
-     * @param boolean $iframe
90
-     */
91
-    public function setIframe( $iframe = true )
92
-    {
93
-        $this->iframe = filter_var( $iframe, FILTER_VALIDATE_BOOLEAN );
94
-    }
95
-
96
-
97
-    /**
98
-     * finds and sets the \EE_Event object for use throughout class
99
-     *
100
-     * @param mixed $event
101
-     * @return bool
102
-     * @throws EE_Error
103
-     */
104
-    protected function setEvent( $event = null )
105
-    {
106
-        if ( $event === null ) {
107
-            global $post;
108
-            $event = $post;
109
-        }
110
-        if ( $event instanceof EE_Event ) {
111
-            $this->event = $event;
112
-        } else if ( $event instanceof WP_Post ) {
113
-            if ( isset( $event->EE_Event ) && $event->EE_Event instanceof EE_Event ) {
114
-                $this->event = $event->EE_Event;
115
-            } else if ( $event->post_type === 'espresso_events' ) {
116
-                $event->EE_Event = EEM_Event::instance()->instantiate_class_from_post_object( $event );
117
-                $this->event = $event->EE_Event;
118
-            }
119
-        } else {
120
-            $user_msg = __( 'No Event object or an invalid Event object was supplied.', 'event_espresso' );
121
-            $dev_msg = $user_msg . __(
122
-                    'In order to generate a ticket selector, please ensure you are passing either an EE_Event object or a WP_Post object of the post type "espresso_event" to the EE_Ticket_Selector class constructor.',
123
-                    'event_espresso'
124
-                );
125
-            EE_Error::add_error( $user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__ );
126
-            return false;
127
-        }
128
-        return true;
129
-    }
130
-
131
-
132
-
133
-    /**
134
-     * @return int
135
-     */
136
-    public function getMaxAttendees()
137
-    {
138
-        return $this->max_attendees;
139
-    }
140
-
141
-
142
-
143
-    /**
144
-     * @param int $max_attendees
145
-     */
146
-    public function setMaxAttendees($max_attendees)
147
-    {
148
-        $this->max_attendees = absint(
149
-            apply_filters(
150
-                'FHEE__EE_Ticket_Selector__display_ticket_selector__max_tickets',
151
-                $max_attendees
152
-            )
153
-        );
154
-    }
155
-
156
-
157
-
158
-    /**
159
-     * creates buttons for selecting number of attendees for an event
160
-     *
161
-     * @param WP_Post|int $event
162
-     * @param bool         $view_details
163
-     * @return string
164
-     * @throws EE_Error
165
-     */
166
-    public function display( $event = null, $view_details = false )
167
-    {
168
-        // reset filter for displaying submit button
169
-        remove_filter( 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true' );
170
-        // poke and prod incoming event till it tells us what it is
171
-        if ( ! $this->setEvent( $event ) ) {
172
-            return false;
173
-        }
174
-        // begin gathering template arguments by getting event status
175
-        $template_args = array( 'event_status' => $this->event->get_active_status() );
176
-        if ( $this->activeEventAndShowTicketSelector($event, $template_args['event_status'], $view_details) ) {
177
-            return ! is_single() ? $this->displayViewDetailsButton() : '';
178
-        }
179
-        // filter the maximum qty that can appear in the Ticket Selector qty dropdowns
180
-        $this->setMaxAttendees($this->event->additional_limit());
181
-        if ($this->getMaxAttendees() < 1) {
182
-            return $this->ticketSalesClosedMessage();
183
-        }
184
-        // is the event expired ?
185
-        $template_args['event_is_expired'] = $this->event->is_expired();
186
-        if ( $template_args[ 'event_is_expired' ] ) {
187
-            return $this->expiredEventMessage();
188
-        }
189
-        // get all tickets for this event ordered by the datetime
190
-        $tickets = $this->getTickets();
191
-        if (count($tickets) < 1) {
192
-            return $this->noTicketAvailableMessage();
193
-        }
194
-        if (EED_Events_Archive::is_iframe()){
195
-            $this->setIframe();
196
-        }
197
-        // redirecting to another site for registration ??
198
-        $external_url = (string) $this->event->external_url();
199
-        // if redirecting to another site for registration, then we don't load the TS
200
-        $ticket_selector = $external_url
201
-            ? $this->externalEventRegistration()
202
-            : $this->loadTicketSelector($tickets,$template_args);
203
-        // now set up the form (but not for the admin)
204
-        $ticket_selector = ! is_admin()
205
-            ? $this->formOpen($this->event->ID(), $external_url) . $ticket_selector
206
-            : $ticket_selector;
207
-        // submit button and form close tag
208
-        $ticket_selector .= ! is_admin() ? $this->displaySubmitButton($external_url) : '';
209
-        return $ticket_selector;
210
-    }
211
-
212
-
213
-
214
-    /**
215
-     * displayTicketSelector
216
-     * examines the event properties and determines whether a Ticket Selector should be displayed
217
-     *
218
-     * @param WP_Post|int $event
219
-     * @param string       $_event_active_status
220
-     * @param bool         $view_details
221
-     * @return bool
222
-     * @throws EE_Error
223
-     */
224
-    protected function activeEventAndShowTicketSelector($event, $_event_active_status, $view_details)
225
-    {
226
-        $event_post = $this->event instanceof EE_Event ? $this->event->ID() : $event;
227
-        return ! is_admin()
228
-               && (
229
-                   ! $this->event->display_ticket_selector()
230
-                   || $view_details
231
-                   || post_password_required($event_post)
232
-                   || (
233
-                       $_event_active_status !== EE_Datetime::active
234
-                       && $_event_active_status !== EE_Datetime::upcoming
235
-                       && $_event_active_status !== EE_Datetime::sold_out
236
-                       && ! (
237
-                           $_event_active_status === EE_Datetime::inactive
238
-                           && is_user_logged_in()
239
-                       )
240
-                   )
241
-               );
242
-    }
243
-
244
-
245
-
246
-    /**
247
-     * noTicketAvailableMessage
248
-     * notice displayed if event is expired
249
-     *
250
-     * @return string
251
-     * @throws EE_Error
252
-     */
253
-    protected function expiredEventMessage()
254
-    {
255
-        return '<div class="ee-event-expired-notice"><span class="important-notice">' . esc_html__(
256
-            'We\'re sorry, but all tickets sales have ended because the event is expired.',
257
-            'event_espresso'
258
-        ) . '</span></div><!-- .ee-event-expired-notice -->';
259
-    }
260
-
261
-
262
-
263
-    /**
264
-     * noTicketAvailableMessage
265
-     * notice displayed if event has no more tickets available
266
-     *
267
-     * @return string
268
-     * @throws EE_Error
269
-     */
270
-    protected function noTicketAvailableMessage()
271
-    {
272
-        $no_ticket_available_msg = esc_html__( 'We\'re sorry, but all ticket sales have ended.', 'event_espresso' );
273
-        if (current_user_can('edit_post', $this->event->ID())) {
274
-            $no_ticket_available_msg .= sprintf(
275
-                esc_html__(
276
-                    '%1$sNote to Event Admin:%2$sNo tickets were found for this event. This effectively turns off ticket sales. Please ensure that at least one ticket is available for if you want people to be able to register.%3$s(click to edit this event)%4$s',
277
-                    'event_espresso'
278
-                ),
279
-                '<div class="ee-attention" style="text-align: left;"><b>',
280
-                '</b><br />',
281
-                '<span class="edit-link"><a class="post-edit-link" href="'.get_edit_post_link($this->event->ID()).'">',
282
-                '</a></span></div><!-- .ee-attention noTicketAvailableMessage -->'
283
-            );
284
-        }
285
-        return '
37
+	/**
38
+	 * event that ticket selector is being generated for
39
+	 *
40
+	 * @access protected
41
+	 * @var EE_Event $event
42
+	 */
43
+	protected $event;
44
+
45
+	/**
46
+	 * Used to flag when the ticket selector is being called from an external iframe.
47
+	 *
48
+	 * @var bool $iframe
49
+	 */
50
+	protected $iframe = false;
51
+
52
+	/**
53
+	 * max attendees that can register for event at one time
54
+	 *
55
+	 * @var int $max_attendees
56
+	 */
57
+	private $max_attendees = EE_INF;
58
+
59
+	/**
60
+	 *@var string $date_format
61
+	 */
62
+	private $date_format;
63
+
64
+	/**
65
+	 *@var string $time_format
66
+	 */
67
+	private $time_format;
68
+
69
+
70
+
71
+	/**
72
+	 * DisplayTicketSelector constructor.
73
+	 */
74
+	public function __construct()
75
+	{
76
+		$this->date_format = apply_filters(
77
+			'FHEE__EED_Ticket_Selector__display_ticket_selector__date_format',
78
+			get_option('date_format')
79
+		);
80
+		$this->time_format = apply_filters(
81
+			'FHEE__EED_Ticket_Selector__display_ticket_selector__time_format',
82
+			get_option('time_format')
83
+		);
84
+	}
85
+
86
+
87
+
88
+	/**
89
+	 * @param boolean $iframe
90
+	 */
91
+	public function setIframe( $iframe = true )
92
+	{
93
+		$this->iframe = filter_var( $iframe, FILTER_VALIDATE_BOOLEAN );
94
+	}
95
+
96
+
97
+	/**
98
+	 * finds and sets the \EE_Event object for use throughout class
99
+	 *
100
+	 * @param mixed $event
101
+	 * @return bool
102
+	 * @throws EE_Error
103
+	 */
104
+	protected function setEvent( $event = null )
105
+	{
106
+		if ( $event === null ) {
107
+			global $post;
108
+			$event = $post;
109
+		}
110
+		if ( $event instanceof EE_Event ) {
111
+			$this->event = $event;
112
+		} else if ( $event instanceof WP_Post ) {
113
+			if ( isset( $event->EE_Event ) && $event->EE_Event instanceof EE_Event ) {
114
+				$this->event = $event->EE_Event;
115
+			} else if ( $event->post_type === 'espresso_events' ) {
116
+				$event->EE_Event = EEM_Event::instance()->instantiate_class_from_post_object( $event );
117
+				$this->event = $event->EE_Event;
118
+			}
119
+		} else {
120
+			$user_msg = __( 'No Event object or an invalid Event object was supplied.', 'event_espresso' );
121
+			$dev_msg = $user_msg . __(
122
+					'In order to generate a ticket selector, please ensure you are passing either an EE_Event object or a WP_Post object of the post type "espresso_event" to the EE_Ticket_Selector class constructor.',
123
+					'event_espresso'
124
+				);
125
+			EE_Error::add_error( $user_msg . '||' . $dev_msg, __FILE__, __FUNCTION__, __LINE__ );
126
+			return false;
127
+		}
128
+		return true;
129
+	}
130
+
131
+
132
+
133
+	/**
134
+	 * @return int
135
+	 */
136
+	public function getMaxAttendees()
137
+	{
138
+		return $this->max_attendees;
139
+	}
140
+
141
+
142
+
143
+	/**
144
+	 * @param int $max_attendees
145
+	 */
146
+	public function setMaxAttendees($max_attendees)
147
+	{
148
+		$this->max_attendees = absint(
149
+			apply_filters(
150
+				'FHEE__EE_Ticket_Selector__display_ticket_selector__max_tickets',
151
+				$max_attendees
152
+			)
153
+		);
154
+	}
155
+
156
+
157
+
158
+	/**
159
+	 * creates buttons for selecting number of attendees for an event
160
+	 *
161
+	 * @param WP_Post|int $event
162
+	 * @param bool         $view_details
163
+	 * @return string
164
+	 * @throws EE_Error
165
+	 */
166
+	public function display( $event = null, $view_details = false )
167
+	{
168
+		// reset filter for displaying submit button
169
+		remove_filter( 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true' );
170
+		// poke and prod incoming event till it tells us what it is
171
+		if ( ! $this->setEvent( $event ) ) {
172
+			return false;
173
+		}
174
+		// begin gathering template arguments by getting event status
175
+		$template_args = array( 'event_status' => $this->event->get_active_status() );
176
+		if ( $this->activeEventAndShowTicketSelector($event, $template_args['event_status'], $view_details) ) {
177
+			return ! is_single() ? $this->displayViewDetailsButton() : '';
178
+		}
179
+		// filter the maximum qty that can appear in the Ticket Selector qty dropdowns
180
+		$this->setMaxAttendees($this->event->additional_limit());
181
+		if ($this->getMaxAttendees() < 1) {
182
+			return $this->ticketSalesClosedMessage();
183
+		}
184
+		// is the event expired ?
185
+		$template_args['event_is_expired'] = $this->event->is_expired();
186
+		if ( $template_args[ 'event_is_expired' ] ) {
187
+			return $this->expiredEventMessage();
188
+		}
189
+		// get all tickets for this event ordered by the datetime
190
+		$tickets = $this->getTickets();
191
+		if (count($tickets) < 1) {
192
+			return $this->noTicketAvailableMessage();
193
+		}
194
+		if (EED_Events_Archive::is_iframe()){
195
+			$this->setIframe();
196
+		}
197
+		// redirecting to another site for registration ??
198
+		$external_url = (string) $this->event->external_url();
199
+		// if redirecting to another site for registration, then we don't load the TS
200
+		$ticket_selector = $external_url
201
+			? $this->externalEventRegistration()
202
+			: $this->loadTicketSelector($tickets,$template_args);
203
+		// now set up the form (but not for the admin)
204
+		$ticket_selector = ! is_admin()
205
+			? $this->formOpen($this->event->ID(), $external_url) . $ticket_selector
206
+			: $ticket_selector;
207
+		// submit button and form close tag
208
+		$ticket_selector .= ! is_admin() ? $this->displaySubmitButton($external_url) : '';
209
+		return $ticket_selector;
210
+	}
211
+
212
+
213
+
214
+	/**
215
+	 * displayTicketSelector
216
+	 * examines the event properties and determines whether a Ticket Selector should be displayed
217
+	 *
218
+	 * @param WP_Post|int $event
219
+	 * @param string       $_event_active_status
220
+	 * @param bool         $view_details
221
+	 * @return bool
222
+	 * @throws EE_Error
223
+	 */
224
+	protected function activeEventAndShowTicketSelector($event, $_event_active_status, $view_details)
225
+	{
226
+		$event_post = $this->event instanceof EE_Event ? $this->event->ID() : $event;
227
+		return ! is_admin()
228
+			   && (
229
+				   ! $this->event->display_ticket_selector()
230
+				   || $view_details
231
+				   || post_password_required($event_post)
232
+				   || (
233
+					   $_event_active_status !== EE_Datetime::active
234
+					   && $_event_active_status !== EE_Datetime::upcoming
235
+					   && $_event_active_status !== EE_Datetime::sold_out
236
+					   && ! (
237
+						   $_event_active_status === EE_Datetime::inactive
238
+						   && is_user_logged_in()
239
+					   )
240
+				   )
241
+			   );
242
+	}
243
+
244
+
245
+
246
+	/**
247
+	 * noTicketAvailableMessage
248
+	 * notice displayed if event is expired
249
+	 *
250
+	 * @return string
251
+	 * @throws EE_Error
252
+	 */
253
+	protected function expiredEventMessage()
254
+	{
255
+		return '<div class="ee-event-expired-notice"><span class="important-notice">' . esc_html__(
256
+			'We\'re sorry, but all tickets sales have ended because the event is expired.',
257
+			'event_espresso'
258
+		) . '</span></div><!-- .ee-event-expired-notice -->';
259
+	}
260
+
261
+
262
+
263
+	/**
264
+	 * noTicketAvailableMessage
265
+	 * notice displayed if event has no more tickets available
266
+	 *
267
+	 * @return string
268
+	 * @throws EE_Error
269
+	 */
270
+	protected function noTicketAvailableMessage()
271
+	{
272
+		$no_ticket_available_msg = esc_html__( 'We\'re sorry, but all ticket sales have ended.', 'event_espresso' );
273
+		if (current_user_can('edit_post', $this->event->ID())) {
274
+			$no_ticket_available_msg .= sprintf(
275
+				esc_html__(
276
+					'%1$sNote to Event Admin:%2$sNo tickets were found for this event. This effectively turns off ticket sales. Please ensure that at least one ticket is available for if you want people to be able to register.%3$s(click to edit this event)%4$s',
277
+					'event_espresso'
278
+				),
279
+				'<div class="ee-attention" style="text-align: left;"><b>',
280
+				'</b><br />',
281
+				'<span class="edit-link"><a class="post-edit-link" href="'.get_edit_post_link($this->event->ID()).'">',
282
+				'</a></span></div><!-- .ee-attention noTicketAvailableMessage -->'
283
+			);
284
+		}
285
+		return '
286 286
             <div class="ee-event-expired-notice">
287 287
                 <span class="important-notice">' . $no_ticket_available_msg . '</span>
288 288
             </div><!-- .ee-event-expired-notice -->';
289
-    }
290
-
291
-
292
-
293
-    /**
294
-     * ticketSalesClosed
295
-     * notice displayed if event ticket sales are turned off
296
-     *
297
-     * @return string
298
-     * @throws EE_Error
299
-     */
300
-    protected function ticketSalesClosedMessage()
301
-    {
302
-        $sales_closed_msg = esc_html__(
303
-            'We\'re sorry, but ticket sales have been closed at this time. Please check back again later.',
304
-            'event_espresso'
305
-        );
306
-        if (current_user_can('edit_post', $this->event->ID())) {
307
-            $sales_closed_msg .= sprintf(
308
-                esc_html__(
309
-                    '%sNote to Event Admin:%sThe "Maximum number of tickets allowed per order for this event" in the Event Registration Options has been set to "0". This effectively turns off ticket sales. %s(click to edit this event)%s',
310
-                    'event_espresso'
311
-                ),
312
-                '<div class="ee-attention" style="text-align: left;"><b>',
313
-                '</b><br />',
314
-                '<span class="edit-link"><a class="post-edit-link" href="'.get_edit_post_link($this->event->ID()).'">',
315
-                '</a></span></div><!-- .ee-attention ticketSalesClosedMessage -->'
316
-            );
317
-        }
318
-        return '<p><span class="important-notice">' . $sales_closed_msg . '</span></p>';
319
-    }
320
-
321
-
322
-
323
-    /**
324
-     * getTickets
325
-     *
326
-     * @return \EE_Base_Class[]|\EE_Ticket[]
327
-     * @throws EE_Error
328
-     */
329
-    protected function getTickets()
330
-    {
331
-        $ticket_query_args = array(
332
-            array('Datetime.EVT_ID' => $this->event->ID()),
333
-            'order_by' => array(
334
-                'TKT_order'              => 'ASC',
335
-                'TKT_required'           => 'DESC',
336
-                'TKT_start_date'         => 'ASC',
337
-                'TKT_end_date'           => 'ASC',
338
-                'Datetime.DTT_EVT_start' => 'DESC',
339
-            ),
340
-        );
341
-        if (
342
-            ! (
343
-                EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector instanceof EE_Ticket_Selector_Config
344
-                && EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector->show_expired_tickets
345
-            )
346
-        ) {
347
-            //use the correct applicable time query depending on what version of core is being run.
348
-            $current_time = method_exists('EEM_Datetime', 'current_time_for_query')
349
-                ? time()
350
-                : current_time('timestamp');
351
-            $ticket_query_args[0]['TKT_end_date'] = array('>', $current_time);
352
-        }
353
-        return EEM_Ticket::instance()->get_all($ticket_query_args);
354
-    }
355
-
356
-
357
-
358
-    /**
359
-     * loadTicketSelector
360
-     * begins to assemble template arguments
361
-     * and decides whether to load a "simple" ticket selector, or the standard
362
-     *
363
-     * @param \EE_Ticket[] $tickets
364
-     * @param array $template_args
365
-     * @return string
366
-     * @throws EE_Error
367
-     */
368
-    protected function loadTicketSelector(array $tickets, array $template_args)
369
-    {
370
-        $template_args['event'] = $this->event;
371
-        $template_args['EVT_ID'] = $this->event->ID();
372
-        $template_args['event_is_expired'] = $this->event->is_expired();
373
-        $template_args['max_atndz'] = $this->getMaxAttendees();
374
-        $template_args['date_format'] = $this->date_format;
375
-        $template_args['time_format'] = $this->time_format;
376
-        /**
377
-         * Filters the anchor ID used when redirecting to the Ticket Selector if no quantity selected
378
-         *
379
-         * @since 4.9.13
380
-         * @param     string  '#tkt-slctr-tbl-' . $EVT_ID The html ID to anchor to
381
-         * @param int $EVT_ID The Event ID
382
-         */
383
-        $template_args['anchor_id'] = apply_filters(
384
-            'FHEE__EE_Ticket_Selector__redirect_anchor_id',
385
-            '#tkt-slctr-tbl-' . $this->event->ID(),
386
-            $this->event->ID()
387
-        );
388
-        $template_args['tickets'] = $tickets;
389
-        $template_args['ticket_count'] = count($tickets);
390
-        $ticket_selector = $this->simpleTicketSelector( $tickets, $template_args);
391
-        return $ticket_selector instanceof TicketSelectorSimple
392
-            ? $ticket_selector
393
-            : new TicketSelectorStandard(
394
-                $this->event,
395
-                $tickets,
396
-                $this->getMaxAttendees(),
397
-                $template_args,
398
-                $this->date_format,
399
-                $this->time_format
400
-            );
401
-    }
402
-
403
-
404
-
405
-    /**
406
-     * simpleTicketSelector
407
-     * there's one ticket, and max attendees is set to one,
408
-     * so if the event is free, then this is a "simple" ticket selector
409
-     * a.k.a. "Dude Where's my Ticket Selector?"
410
-     *
411
-     * @param \EE_Ticket[] $tickets
412
-     * @param array  $template_args
413
-     * @return string
414
-     * @throws EE_Error
415
-     */
416
-    protected function simpleTicketSelector($tickets, array $template_args)
417
-    {
418
-        // if there is only ONE ticket with a max qty of ONE
419
-        if (count($tickets) > 1 || $this->getMaxAttendees() !== 1) {
420
-            return '';
421
-        }
422
-        /** @var \EE_Ticket $ticket */
423
-        $ticket = reset($tickets);
424
-        // if the ticket is free... then not much need for the ticket selector
425
-        if (
426
-            apply_filters(
427
-                'FHEE__ticket_selector_chart_template__hide_ticket_selector',
428
-                $ticket->is_free(),
429
-                $this->event->ID()
430
-            )
431
-        ) {
432
-            return new TicketSelectorSimple(
433
-                $this->event,
434
-                $ticket,
435
-                $this->getMaxAttendees(),
436
-                $template_args
437
-            );
438
-        }
439
-        return '';
440
-    }
441
-
442
-
443
-
444
-    /**
445
-     * externalEventRegistration
446
-     *
447
-     * @return string
448
-     */
449
-    public function externalEventRegistration()
450
-    {
451
-        // if not we still need to trigger the display of the submit button
452
-        add_filter('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true');
453
-        //display notice to admin that registration is external
454
-        return is_admin()
455
-            ? esc_html__(
456
-                'Registration is at an external URL for this event.',
457
-                'event_espresso'
458
-            )
459
-            : '';
460
-    }
461
-
462
-
463
-
464
-    /**
465
-     * formOpen
466
-     *
467
-     * @param        int    $ID
468
-     * @param        string $external_url
469
-     * @return        string
470
-     */
471
-    public function formOpen( $ID = 0, $external_url = '' )
472
-    {
473
-        // if redirecting, we don't need any anything else
474
-        if ( $external_url ) {
475
-            $html = '<form method="GET" action="' . EEH_URL::refactor_url($external_url) . '"';
476
-            // open link in new window ?
477
-            $html .= apply_filters(
478
-                'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__formOpen__external_url_target_blank',
479
-                EED_Events_Archive::is_iframe()
480
-            )
481
-                ? ' target="_blank"'
482
-                : '';
483
-            $html .= '>';
484
-            $query_args = EEH_URL::get_query_string( $external_url );
485
-            foreach ( (array)$query_args as $query_arg => $value ) {
486
-                $html .= '<input type="hidden" name="' . $query_arg . '" value="' . $value . '">';
487
-            }
488
-            return $html;
489
-        }
490
-        // if there is no submit button, then don't start building a form
491
-        // because the "View Details" button will build its own form
492
-        if ( ! apply_filters( 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false ) ) {
493
-            return '';
494
-        }
495
-        $checkout_url = EEH_Event_View::event_link_url( $ID );
496
-        if ( ! $checkout_url ) {
497
-            EE_Error::add_error(
498
-                esc_html__( 'The URL for the Event Details page could not be retrieved.', 'event_espresso' ),
499
-                __FILE__,
500
-                __FUNCTION__,
501
-                __LINE__
502
-            );
503
-        }
504
-        // set no cache headers and constants
505
-        EE_System::do_not_cache();
506
-        $extra_params = $this->iframe ? ' target="_blank"' : '';
507
-        $html = '<form method="POST" action="' . $checkout_url . '"' . $extra_params . '>';
508
-        $html .= '<input type="hidden" name="ee" value="process_ticket_selections">';
509
-        $html = apply_filters( 'FHEE__EE_Ticket_Selector__ticket_selector_form_open__html', $html, $this->event );
510
-        return $html;
511
-    }
512
-
513
-
514
-
515
-    /**
516
-     * displaySubmitButton
517
-     *
518
-     * @param  string $external_url
519
-     * @return string
520
-     * @throws EE_Error
521
-     */
522
-    public function displaySubmitButton($external_url = '')
523
-    {
524
-        $html = '';
525
-        if ( ! is_admin()) {
526
-            // standard TS displayed with submit button, ie: "Register Now"
527
-            if (apply_filters('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false)) {
528
-                $html .= $this->displayRegisterNowButton();
529
-                $html .= empty($external_url)
530
-                    ? $this->ticketSelectorEndDiv()
531
-                    : $this->clearTicketSelector();
532
-                $html .= '<br/>' . $this->formClose();
533
-            } else if ($this->getMaxAttendees() === 1) {
534
-                // its a "Dude Where's my Ticket Selector?" (DWMTS) type event (ie: $_max_atndz === 1)
535
-                if ($this->event->is_sold_out()) {
536
-                    // then instead of a View Details or Submit button, just display a "Sold Out" message
537
-                    $html .= apply_filters(
538
-                        'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__sold_out_msg',
539
-                        sprintf(
540
-                            __(
541
-                                '%1$s"%2$s" is currently sold out.%4$sPlease check back again later, as spots may become available.%3$s',
542
-                                'event_espresso'
543
-                            ),
544
-                            '<p class="no-ticket-selector-msg clear-float">',
545
-                            $this->event->name(),
546
-                            '</p>',
547
-                            '<br />'
548
-                        ),
549
-                        $this->event
550
-                    );
551
-                    if (
552
-                        apply_filters(
553
-                            'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__no_tickets_but_display_register_now_button',
554
-                            false,
555
-                            $this->event
556
-                        )
557
-                    ) {
558
-                        $html .= $this->displayRegisterNowButton();
559
-                    }
560
-                    // sold out DWMTS event, no TS, no submit or view details button, but has additional content
561
-                    $html .=  $this->ticketSelectorEndDiv();
562
-                } else if (
563
-                    apply_filters('FHEE__EE_Ticket_Selector__hide_ticket_selector', false)
564
-                    && ! is_single()
565
-                ) {
566
-                    // this is a "Dude Where's my Ticket Selector?" (DWMTS) type event,
567
-                    // but no tickets are available, so display event's "View Details" button.
568
-                    // it is being viewed via somewhere other than a single post
569
-                    $html .= $this->displayViewDetailsButton(true);
570
-                } else {
571
-                    $html .= $this->ticketSelectorEndDiv();
572
-                }
573
-            } else if (is_archive()) {
574
-                // event list, no tickets available so display event's "View Details" button
575
-                $html .= $this->ticketSelectorEndDiv();
576
-                $html .= $this->displayViewDetailsButton();
577
-            } else {
578
-                if (
579
-                    apply_filters(
580
-                        'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__no_tickets_but_display_register_now_button',
581
-                        false,
582
-                        $this->event
583
-                    )
584
-                ) {
585
-                    $html .= $this->displayRegisterNowButton();
586
-                }
587
-                // no submit or view details button, and no additional content
588
-                $html .= $this->ticketSelectorEndDiv();
589
-            }
590
-            if ( ! $this->iframe && ! is_archive()) {
591
-                $html .= EEH_Template::powered_by_event_espresso('', '', array('utm_content' => 'ticket_selector'));
592
-            }
593
-        }
594
-	    return apply_filters(
595
-		    'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__displaySubmitButton__html',
596
-		    $html,
597
-		    $this->event
598
-	    );
599
-    }
600
-
601
-
602
-
603
-    /**
604
-     * @return string
605
-     * @throws EE_Error
606
-     */
607
-    public function displayRegisterNowButton()
608
-    {
609
-        $btn_text = apply_filters(
610
-            'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__btn_text',
611
-            __('Register Now', 'event_espresso'),
612
-            $this->event
613
-        );
614
-        $external_url = $this->event->external_url();
615
-        $html = EEH_HTML::div(
616
-            '', 'ticket-selector-submit-' . $this->event->ID() . '-btn-wrap', 'ticket-selector-submit-btn-wrap'
617
-        );
618
-        $html .= '<input id="ticket-selector-submit-' . $this->event->ID() . '-btn"';
619
-        $html .= ' class="ticket-selector-submit-btn ';
620
-        $html .= empty($external_url) ? 'ticket-selector-submit-ajax"' : '"';
621
-        $html .= ' type="submit" value="' . $btn_text . '" />';
622
-        $html .= EEH_HTML::divx() . '<!-- .ticket-selector-submit-btn-wrap -->';
623
-        $html .= apply_filters(
624
-            'FHEE__EE_Ticket_Selector__after_ticket_selector_submit',
625
-            '',
626
-            $this->event
627
-        );
628
-        return $html;
629
-    }
630
-
631
-
632
-    /**
633
-     * displayViewDetailsButton
634
-     *
635
-     * @param bool $DWMTS indicates a "Dude Where's my Ticket Selector?" (DWMTS) type event
636
-     *                    (ie: $_max_atndz === 1) where there are no available tickets,
637
-     *                    either because they are sold out, expired, or not yet on sale.
638
-     *                    In this case, we need to close the form BEFORE adding any closing divs
639
-     * @return string
640
-     * @throws EE_Error
641
-     */
642
-    public function displayViewDetailsButton( $DWMTS = false )
643
-    {
644
-        if ( ! $this->event->get_permalink() ) {
645
-            EE_Error::add_error(
646
-                esc_html__( 'The URL for the Event Details page could not be retrieved.', 'event_espresso' ),
647
-                __FILE__, __FUNCTION__, __LINE__
648
-            );
649
-        }
650
-        $view_details_btn = '<form method="POST" action="';
651
-        $view_details_btn .= apply_filters(
652
-            'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_url',
653
-            $this->event->get_permalink(),
654
-            $this->event
655
-        );
656
-        $view_details_btn .= '"';
657
-        // open link in new window ?
658
-        $view_details_btn .= apply_filters(
659
-            'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__displayViewDetailsButton__url_target_blank',
660
-            EED_Events_Archive::is_iframe()
661
-        )
662
-            ? ' target="_blank"'
663
-            : '';
664
-        $view_details_btn .='>';
665
-        $btn_text = apply_filters(
666
-            'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_text',
667
-            esc_html__('View Details', 'event_espresso'),
668
-            $this->event
669
-        );
670
-        $view_details_btn .= '<input id="ticket-selector-submit-'
671
-                             . $this->event->ID()
672
-                             . '-btn" class="ticket-selector-submit-btn view-details-btn" type="submit" value="'
673
-                             . $btn_text
674
-                             . '" />';
675
-        $view_details_btn .= apply_filters( 'FHEE__EE_Ticket_Selector__after_view_details_btn', '', $this->event );
676
-        if ($DWMTS) {
677
-            $view_details_btn .= $this->formClose();
678
-            $view_details_btn .= $this->ticketSelectorEndDiv();
679
-            $view_details_btn .= '<br/>';
680
-        } else {
681
-            $view_details_btn .= $this->clearTicketSelector();
682
-            $view_details_btn .= '<br/>';
683
-            $view_details_btn .= $this->formClose();
684
-        }
685
-        return $view_details_btn;
686
-    }
687
-
688
-
689
-
690
-    /**
691
-     * @return string
692
-     */
693
-    public function ticketSelectorEndDiv()
694
-    {
695
-        return $this->clearTicketSelector() . '</div><!-- ticketSelectorEndDiv -->';
696
-    }
697
-
698
-
699
-
700
-    /**
701
-     * @return string
702
-     */
703
-    public function clearTicketSelector()
704
-    {
705
-        // standard TS displayed, appears after a "Register Now" or "view Details" button
706
-        return '<div class="clear"></div><!-- clearTicketSelector -->';
707
-    }
708
-
709
-
710
-
711
-    /**
712
-     * @access        public
713
-     * @return        string
714
-     */
715
-    public function formClose()
716
-    {
717
-        return '</form>';
718
-    }
289
+	}
290
+
291
+
292
+
293
+	/**
294
+	 * ticketSalesClosed
295
+	 * notice displayed if event ticket sales are turned off
296
+	 *
297
+	 * @return string
298
+	 * @throws EE_Error
299
+	 */
300
+	protected function ticketSalesClosedMessage()
301
+	{
302
+		$sales_closed_msg = esc_html__(
303
+			'We\'re sorry, but ticket sales have been closed at this time. Please check back again later.',
304
+			'event_espresso'
305
+		);
306
+		if (current_user_can('edit_post', $this->event->ID())) {
307
+			$sales_closed_msg .= sprintf(
308
+				esc_html__(
309
+					'%sNote to Event Admin:%sThe "Maximum number of tickets allowed per order for this event" in the Event Registration Options has been set to "0". This effectively turns off ticket sales. %s(click to edit this event)%s',
310
+					'event_espresso'
311
+				),
312
+				'<div class="ee-attention" style="text-align: left;"><b>',
313
+				'</b><br />',
314
+				'<span class="edit-link"><a class="post-edit-link" href="'.get_edit_post_link($this->event->ID()).'">',
315
+				'</a></span></div><!-- .ee-attention ticketSalesClosedMessage -->'
316
+			);
317
+		}
318
+		return '<p><span class="important-notice">' . $sales_closed_msg . '</span></p>';
319
+	}
320
+
321
+
322
+
323
+	/**
324
+	 * getTickets
325
+	 *
326
+	 * @return \EE_Base_Class[]|\EE_Ticket[]
327
+	 * @throws EE_Error
328
+	 */
329
+	protected function getTickets()
330
+	{
331
+		$ticket_query_args = array(
332
+			array('Datetime.EVT_ID' => $this->event->ID()),
333
+			'order_by' => array(
334
+				'TKT_order'              => 'ASC',
335
+				'TKT_required'           => 'DESC',
336
+				'TKT_start_date'         => 'ASC',
337
+				'TKT_end_date'           => 'ASC',
338
+				'Datetime.DTT_EVT_start' => 'DESC',
339
+			),
340
+		);
341
+		if (
342
+			! (
343
+				EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector instanceof EE_Ticket_Selector_Config
344
+				&& EE_Registry::instance()->CFG->template_settings->EED_Ticket_Selector->show_expired_tickets
345
+			)
346
+		) {
347
+			//use the correct applicable time query depending on what version of core is being run.
348
+			$current_time = method_exists('EEM_Datetime', 'current_time_for_query')
349
+				? time()
350
+				: current_time('timestamp');
351
+			$ticket_query_args[0]['TKT_end_date'] = array('>', $current_time);
352
+		}
353
+		return EEM_Ticket::instance()->get_all($ticket_query_args);
354
+	}
355
+
356
+
357
+
358
+	/**
359
+	 * loadTicketSelector
360
+	 * begins to assemble template arguments
361
+	 * and decides whether to load a "simple" ticket selector, or the standard
362
+	 *
363
+	 * @param \EE_Ticket[] $tickets
364
+	 * @param array $template_args
365
+	 * @return string
366
+	 * @throws EE_Error
367
+	 */
368
+	protected function loadTicketSelector(array $tickets, array $template_args)
369
+	{
370
+		$template_args['event'] = $this->event;
371
+		$template_args['EVT_ID'] = $this->event->ID();
372
+		$template_args['event_is_expired'] = $this->event->is_expired();
373
+		$template_args['max_atndz'] = $this->getMaxAttendees();
374
+		$template_args['date_format'] = $this->date_format;
375
+		$template_args['time_format'] = $this->time_format;
376
+		/**
377
+		 * Filters the anchor ID used when redirecting to the Ticket Selector if no quantity selected
378
+		 *
379
+		 * @since 4.9.13
380
+		 * @param     string  '#tkt-slctr-tbl-' . $EVT_ID The html ID to anchor to
381
+		 * @param int $EVT_ID The Event ID
382
+		 */
383
+		$template_args['anchor_id'] = apply_filters(
384
+			'FHEE__EE_Ticket_Selector__redirect_anchor_id',
385
+			'#tkt-slctr-tbl-' . $this->event->ID(),
386
+			$this->event->ID()
387
+		);
388
+		$template_args['tickets'] = $tickets;
389
+		$template_args['ticket_count'] = count($tickets);
390
+		$ticket_selector = $this->simpleTicketSelector( $tickets, $template_args);
391
+		return $ticket_selector instanceof TicketSelectorSimple
392
+			? $ticket_selector
393
+			: new TicketSelectorStandard(
394
+				$this->event,
395
+				$tickets,
396
+				$this->getMaxAttendees(),
397
+				$template_args,
398
+				$this->date_format,
399
+				$this->time_format
400
+			);
401
+	}
402
+
403
+
404
+
405
+	/**
406
+	 * simpleTicketSelector
407
+	 * there's one ticket, and max attendees is set to one,
408
+	 * so if the event is free, then this is a "simple" ticket selector
409
+	 * a.k.a. "Dude Where's my Ticket Selector?"
410
+	 *
411
+	 * @param \EE_Ticket[] $tickets
412
+	 * @param array  $template_args
413
+	 * @return string
414
+	 * @throws EE_Error
415
+	 */
416
+	protected function simpleTicketSelector($tickets, array $template_args)
417
+	{
418
+		// if there is only ONE ticket with a max qty of ONE
419
+		if (count($tickets) > 1 || $this->getMaxAttendees() !== 1) {
420
+			return '';
421
+		}
422
+		/** @var \EE_Ticket $ticket */
423
+		$ticket = reset($tickets);
424
+		// if the ticket is free... then not much need for the ticket selector
425
+		if (
426
+			apply_filters(
427
+				'FHEE__ticket_selector_chart_template__hide_ticket_selector',
428
+				$ticket->is_free(),
429
+				$this->event->ID()
430
+			)
431
+		) {
432
+			return new TicketSelectorSimple(
433
+				$this->event,
434
+				$ticket,
435
+				$this->getMaxAttendees(),
436
+				$template_args
437
+			);
438
+		}
439
+		return '';
440
+	}
441
+
442
+
443
+
444
+	/**
445
+	 * externalEventRegistration
446
+	 *
447
+	 * @return string
448
+	 */
449
+	public function externalEventRegistration()
450
+	{
451
+		// if not we still need to trigger the display of the submit button
452
+		add_filter('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', '__return_true');
453
+		//display notice to admin that registration is external
454
+		return is_admin()
455
+			? esc_html__(
456
+				'Registration is at an external URL for this event.',
457
+				'event_espresso'
458
+			)
459
+			: '';
460
+	}
461
+
462
+
463
+
464
+	/**
465
+	 * formOpen
466
+	 *
467
+	 * @param        int    $ID
468
+	 * @param        string $external_url
469
+	 * @return        string
470
+	 */
471
+	public function formOpen( $ID = 0, $external_url = '' )
472
+	{
473
+		// if redirecting, we don't need any anything else
474
+		if ( $external_url ) {
475
+			$html = '<form method="GET" action="' . EEH_URL::refactor_url($external_url) . '"';
476
+			// open link in new window ?
477
+			$html .= apply_filters(
478
+				'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__formOpen__external_url_target_blank',
479
+				EED_Events_Archive::is_iframe()
480
+			)
481
+				? ' target="_blank"'
482
+				: '';
483
+			$html .= '>';
484
+			$query_args = EEH_URL::get_query_string( $external_url );
485
+			foreach ( (array)$query_args as $query_arg => $value ) {
486
+				$html .= '<input type="hidden" name="' . $query_arg . '" value="' . $value . '">';
487
+			}
488
+			return $html;
489
+		}
490
+		// if there is no submit button, then don't start building a form
491
+		// because the "View Details" button will build its own form
492
+		if ( ! apply_filters( 'FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false ) ) {
493
+			return '';
494
+		}
495
+		$checkout_url = EEH_Event_View::event_link_url( $ID );
496
+		if ( ! $checkout_url ) {
497
+			EE_Error::add_error(
498
+				esc_html__( 'The URL for the Event Details page could not be retrieved.', 'event_espresso' ),
499
+				__FILE__,
500
+				__FUNCTION__,
501
+				__LINE__
502
+			);
503
+		}
504
+		// set no cache headers and constants
505
+		EE_System::do_not_cache();
506
+		$extra_params = $this->iframe ? ' target="_blank"' : '';
507
+		$html = '<form method="POST" action="' . $checkout_url . '"' . $extra_params . '>';
508
+		$html .= '<input type="hidden" name="ee" value="process_ticket_selections">';
509
+		$html = apply_filters( 'FHEE__EE_Ticket_Selector__ticket_selector_form_open__html', $html, $this->event );
510
+		return $html;
511
+	}
512
+
513
+
514
+
515
+	/**
516
+	 * displaySubmitButton
517
+	 *
518
+	 * @param  string $external_url
519
+	 * @return string
520
+	 * @throws EE_Error
521
+	 */
522
+	public function displaySubmitButton($external_url = '')
523
+	{
524
+		$html = '';
525
+		if ( ! is_admin()) {
526
+			// standard TS displayed with submit button, ie: "Register Now"
527
+			if (apply_filters('FHEE__EE_Ticket_Selector__display_ticket_selector_submit', false)) {
528
+				$html .= $this->displayRegisterNowButton();
529
+				$html .= empty($external_url)
530
+					? $this->ticketSelectorEndDiv()
531
+					: $this->clearTicketSelector();
532
+				$html .= '<br/>' . $this->formClose();
533
+			} else if ($this->getMaxAttendees() === 1) {
534
+				// its a "Dude Where's my Ticket Selector?" (DWMTS) type event (ie: $_max_atndz === 1)
535
+				if ($this->event->is_sold_out()) {
536
+					// then instead of a View Details or Submit button, just display a "Sold Out" message
537
+					$html .= apply_filters(
538
+						'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__sold_out_msg',
539
+						sprintf(
540
+							__(
541
+								'%1$s"%2$s" is currently sold out.%4$sPlease check back again later, as spots may become available.%3$s',
542
+								'event_espresso'
543
+							),
544
+							'<p class="no-ticket-selector-msg clear-float">',
545
+							$this->event->name(),
546
+							'</p>',
547
+							'<br />'
548
+						),
549
+						$this->event
550
+					);
551
+					if (
552
+						apply_filters(
553
+							'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__no_tickets_but_display_register_now_button',
554
+							false,
555
+							$this->event
556
+						)
557
+					) {
558
+						$html .= $this->displayRegisterNowButton();
559
+					}
560
+					// sold out DWMTS event, no TS, no submit or view details button, but has additional content
561
+					$html .=  $this->ticketSelectorEndDiv();
562
+				} else if (
563
+					apply_filters('FHEE__EE_Ticket_Selector__hide_ticket_selector', false)
564
+					&& ! is_single()
565
+				) {
566
+					// this is a "Dude Where's my Ticket Selector?" (DWMTS) type event,
567
+					// but no tickets are available, so display event's "View Details" button.
568
+					// it is being viewed via somewhere other than a single post
569
+					$html .= $this->displayViewDetailsButton(true);
570
+				} else {
571
+					$html .= $this->ticketSelectorEndDiv();
572
+				}
573
+			} else if (is_archive()) {
574
+				// event list, no tickets available so display event's "View Details" button
575
+				$html .= $this->ticketSelectorEndDiv();
576
+				$html .= $this->displayViewDetailsButton();
577
+			} else {
578
+				if (
579
+					apply_filters(
580
+						'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__no_tickets_but_display_register_now_button',
581
+						false,
582
+						$this->event
583
+					)
584
+				) {
585
+					$html .= $this->displayRegisterNowButton();
586
+				}
587
+				// no submit or view details button, and no additional content
588
+				$html .= $this->ticketSelectorEndDiv();
589
+			}
590
+			if ( ! $this->iframe && ! is_archive()) {
591
+				$html .= EEH_Template::powered_by_event_espresso('', '', array('utm_content' => 'ticket_selector'));
592
+			}
593
+		}
594
+		return apply_filters(
595
+			'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__displaySubmitButton__html',
596
+			$html,
597
+			$this->event
598
+		);
599
+	}
600
+
601
+
602
+
603
+	/**
604
+	 * @return string
605
+	 * @throws EE_Error
606
+	 */
607
+	public function displayRegisterNowButton()
608
+	{
609
+		$btn_text = apply_filters(
610
+			'FHEE__EE_Ticket_Selector__display_ticket_selector_submit__btn_text',
611
+			__('Register Now', 'event_espresso'),
612
+			$this->event
613
+		);
614
+		$external_url = $this->event->external_url();
615
+		$html = EEH_HTML::div(
616
+			'', 'ticket-selector-submit-' . $this->event->ID() . '-btn-wrap', 'ticket-selector-submit-btn-wrap'
617
+		);
618
+		$html .= '<input id="ticket-selector-submit-' . $this->event->ID() . '-btn"';
619
+		$html .= ' class="ticket-selector-submit-btn ';
620
+		$html .= empty($external_url) ? 'ticket-selector-submit-ajax"' : '"';
621
+		$html .= ' type="submit" value="' . $btn_text . '" />';
622
+		$html .= EEH_HTML::divx() . '<!-- .ticket-selector-submit-btn-wrap -->';
623
+		$html .= apply_filters(
624
+			'FHEE__EE_Ticket_Selector__after_ticket_selector_submit',
625
+			'',
626
+			$this->event
627
+		);
628
+		return $html;
629
+	}
630
+
631
+
632
+	/**
633
+	 * displayViewDetailsButton
634
+	 *
635
+	 * @param bool $DWMTS indicates a "Dude Where's my Ticket Selector?" (DWMTS) type event
636
+	 *                    (ie: $_max_atndz === 1) where there are no available tickets,
637
+	 *                    either because they are sold out, expired, or not yet on sale.
638
+	 *                    In this case, we need to close the form BEFORE adding any closing divs
639
+	 * @return string
640
+	 * @throws EE_Error
641
+	 */
642
+	public function displayViewDetailsButton( $DWMTS = false )
643
+	{
644
+		if ( ! $this->event->get_permalink() ) {
645
+			EE_Error::add_error(
646
+				esc_html__( 'The URL for the Event Details page could not be retrieved.', 'event_espresso' ),
647
+				__FILE__, __FUNCTION__, __LINE__
648
+			);
649
+		}
650
+		$view_details_btn = '<form method="POST" action="';
651
+		$view_details_btn .= apply_filters(
652
+			'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_url',
653
+			$this->event->get_permalink(),
654
+			$this->event
655
+		);
656
+		$view_details_btn .= '"';
657
+		// open link in new window ?
658
+		$view_details_btn .= apply_filters(
659
+			'FHEE__EventEspresso_modules_ticket_selector_DisplayTicketSelector__displayViewDetailsButton__url_target_blank',
660
+			EED_Events_Archive::is_iframe()
661
+		)
662
+			? ' target="_blank"'
663
+			: '';
664
+		$view_details_btn .='>';
665
+		$btn_text = apply_filters(
666
+			'FHEE__EE_Ticket_Selector__display_view_details_btn__btn_text',
667
+			esc_html__('View Details', 'event_espresso'),
668
+			$this->event
669
+		);
670
+		$view_details_btn .= '<input id="ticket-selector-submit-'
671
+							 . $this->event->ID()
672
+							 . '-btn" class="ticket-selector-submit-btn view-details-btn" type="submit" value="'
673
+							 . $btn_text
674
+							 . '" />';
675
+		$view_details_btn .= apply_filters( 'FHEE__EE_Ticket_Selector__after_view_details_btn', '', $this->event );
676
+		if ($DWMTS) {
677
+			$view_details_btn .= $this->formClose();
678
+			$view_details_btn .= $this->ticketSelectorEndDiv();
679
+			$view_details_btn .= '<br/>';
680
+		} else {
681
+			$view_details_btn .= $this->clearTicketSelector();
682
+			$view_details_btn .= '<br/>';
683
+			$view_details_btn .= $this->formClose();
684
+		}
685
+		return $view_details_btn;
686
+	}
687
+
688
+
689
+
690
+	/**
691
+	 * @return string
692
+	 */
693
+	public function ticketSelectorEndDiv()
694
+	{
695
+		return $this->clearTicketSelector() . '</div><!-- ticketSelectorEndDiv -->';
696
+	}
697
+
698
+
699
+
700
+	/**
701
+	 * @return string
702
+	 */
703
+	public function clearTicketSelector()
704
+	{
705
+		// standard TS displayed, appears after a "Register Now" or "view Details" button
706
+		return '<div class="clear"></div><!-- clearTicketSelector -->';
707
+	}
708
+
709
+
710
+
711
+	/**
712
+	 * @access        public
713
+	 * @return        string
714
+	 */
715
+	public function formClose()
716
+	{
717
+		return '</form>';
718
+	}
719 719
 
720 720
 
721 721
 
Please login to merge, or discard this patch.
core/domain/entities/shortcodes/EspressoEventAttendees.php 2 patches
Indentation   +260 added lines, -260 removed lines patch added patch discarded remove patch
@@ -29,266 +29,266 @@
 block discarded – undo
29 29
 class EspressoEventAttendees extends EspressoShortcode
30 30
 {
31 31
 
32
-    private $query_params = array(
33
-        0 => array()
34
-    );
35
-
36
-    private $template_args = array(
37
-        'contacts'      => array(),
38
-        'event'         => null,
39
-        'datetime'      => null,
40
-        'ticket'        => null,
41
-    );
42
-
43
-    /**
44
-     * the actual shortcode tag that gets registered with WordPress
45
-     *
46
-     * @return string
47
-     */
48
-    public function getTag()
49
-    {
50
-        return 'ESPRESSO_EVENT_ATTENDEES';
51
-    }
52
-
53
-
54
-
55
-    /**
56
-     * the time in seconds to cache the results of the processShortcode() method
57
-     * 0 means the processShortcode() results will NOT be cached at all
58
-     *
59
-     * @return int
60
-     */
61
-    public function cacheExpiration()
62
-    {
63
-        return 0;
64
-    }
65
-
66
-
67
-
68
-    /**
69
-     * a place for adding any initialization code that needs to run prior to wp_header().
70
-     * this may be required for shortcodes that utilize a corresponding module,
71
-     * and need to enqueue assets for that module
72
-     *
73
-     * @return void
74
-     */
75
-    public function initializeShortcode()
76
-    {
77
-        $this->shortcodeHasBeenInitialized();
78
-    }
79
-
80
-
81
-
82
-    /**
83
-     * process_shortcode - ESPRESSO_EVENT_ATTENDEES - Returns a list of attendees to an event.
84
-     *  [ESPRESSO_EVENT_ATTENDEES]
85
-     *  - defaults to attendees for earliest active event, or earliest upcoming event.
86
-     *
87
-     *  [ESPRESSO_EVENT_ATTENDEES event_id=123]
88
-     *  - attendees for specific event.
89
-     *
90
-     *  [ESPRESSO_EVENT_ATTENDEES datetime_id=245]
91
-     *  - attendees for a specific datetime.
92
-     *
93
-     *  [ESPRESSO_EVENT_ATTENDEES ticket_id=123]
94
-     *  - attendees for a specific ticket.
95
-     *
96
-     *  [ESPRESSO_EVENT_ATTENDEES status=all]
97
-     *  - specific registration status (use status id) or all for all attendees regardless of status.
98
-     *  Note default is to only return approved attendees
99
-     *
100
-     *  [ESPRESSO_EVENT_ATTENDEES show_gravatar=true]
101
-     *  - default is to not return gravatar.  Otherwise if this is set then return gravatar for email address given.
102
-     *
103
-     *  [ESPRESSO_EVENT_ATTENDEES display_on_archives=true]
104
-     *  - default is to not display attendees list on archive pages.
105
-     *
106
-     * Note: because of the relationship between event_id, ticket_id, and datetime_id:
107
-     * If more than one of those params is included, then preference is given to the following:
108
-     *  - event_id is used whenever its present and any others are ignored.
109
-     *  - if no event_id then datetime is used whenever its present and any others are ignored.
110
-     *  - otherwise ticket_id is used if present.
111
-     *
112
-     * @param array $attributes
113
-     * @return string
114
-     * @throws EE_Error
115
-     */
116
-    public function processShortcode($attributes = array())
117
-    {
118
-        // grab attributes and merge with defaults
119
-        $attributes = $this->getAttributes((array)$attributes);
120
-        $archive = is_archive();
121
-        $display_on_archives = filter_var($attributes['display_on_archives'], FILTER_VALIDATE_BOOLEAN);
122
-        // don't display on archives unless 'display_on_archives' is true
123
-        if($archive && ! $display_on_archives) {
124
-            return '';
125
-        }
126
-        // add attributes to template args
127
-        $this->template_args['show_gravatar'] = $attributes['show_gravatar'];
128
-        // add required objects: event, datetime, and ticket
129
-        $this->template_args['event'] = $this->getEventAndQueryParams($attributes);
130
-        $this->template_args['datetime'] = $this->getDatetimeAndQueryParams($attributes);
131
-        $this->template_args['ticket'] = $this->getTicketAndQueryParams($attributes);
132
-
133
-        // if any of the above objects is invalid or missing,
134
-        // then there was an invalid parameter or the shortcode was used incorrectly
135
-        // so when WP_DEBUG is set and true, we'll show a message,
136
-        // otherwise we'll just return an empty string.
137
-         if (
138
-            ! $this->template_args['event'] instanceof EE_Event
139
-            || empty($this->query_params[0])
140
-            || ($attributes['datetime_id'] && ! $this->template_args['datetime'] instanceof EE_Datetime)
141
-            || ($attributes['ticket_id'] && ! $this->template_args['ticket'] instanceof EE_Ticket)
142
-        ) {
143
-            if (WP_DEBUG) {
144
-                return '<div class="important-notice ee-attention">'
145
-                       . esc_html__('The [ESPRESSO_EVENT_ATTENDEES] shortcode has been used incorrectly.  Please double check the arguments you used for any typos.  In the case of ID type arguments, its possible the given ID does not correspond to existing data in the database.',
146
-                        'event_espresso')
147
-                       . '</div>';
148
-            }
149
-             return '';
150
-        }
151
-        $this->setAdditionalQueryParams($attributes);
152
-        //get contacts!
153
-        $this->template_args['contacts'] = EEM_Attendee::instance()->get_all($this->query_params);
154
-        //all set let's load up the template and return.
155
-        return EEH_Template::locate_template(
156
-            'loop-espresso_event_attendees.php',
157
-            $this->template_args
158
-        );
159
-
160
-    }
161
-
162
-
163
-
164
-    /**
165
-     * merge incoming attributes with filtered defaults
166
-     *
167
-     * @param array $attributes
168
-     * @return array
169
-     */
170
-    private function getAttributes(array $attributes)
171
-    {
172
-        return (array) apply_filters(
173
-            'EES_Espresso_Event_Attendees__process_shortcode__default_shortcode_atts',
174
-            $attributes + array(
175
-                'event_id'            => null,
176
-                'datetime_id'         => null,
177
-                'ticket_id'           => null,
178
-                'status'              => EEM_Registration::status_id_approved,
179
-                'show_gravatar'       => false,
180
-                'display_on_archives' => false,
181
-            )
182
-        );
183
-    }
184
-
185
-
186
-
187
-    /**
188
-     * @param array $attributes
189
-     * @return EE_Event|null
190
-     * @throws EE_Error
191
-     */
192
-    private function getEventAndQueryParams(array $attributes){
193
-        if ( ! empty($attributes['event_id'])) {
194
-            $event = EEM_Event::instance()->get_one_by_ID($attributes['event_id']);
195
-            if ($event instanceof EE_Event) {
196
-                $this->query_params[0]['Registration.EVT_ID'] = $attributes['event_id'];
197
-                return $event;
198
-            }
199
-        }
200
-        if (is_espresso_event()) {
201
-            $event = EEH_Event_View::get_event();
202
-            if ($event instanceof EE_Event) {
203
-                $this->query_params[0]['Registration.EVT_ID'] = $event->ID();
204
-                return $event;
205
-            }
206
-        }
207
-        // one last shot...
208
-        // try getting the earliest active event
209
-        $events = EEM_Event::instance()->get_active_events(array(
210
-            'limit'    => 1,
211
-            'order_by' => array('Datetime.DTT_EVT_start' => 'ASC')
212
-        ));
213
-        //  if none then get the next upcoming
214
-        $events = empty($events)
215
-            ? EEM_Event::instance()->get_upcoming_events(array(
216
-                'limit'    => 1,
217
-                'order_by' => array('Datetime.DTT_EVT_start' => 'ASC')
218
-            ))
219
-            : $events;
220
-        $event = reset($events);
221
-        if ($event instanceof EE_Event) {
222
-            $this->query_params[0]['Registration.EVT_ID'] = $event->ID();
223
-            return $event;
224
-        }
225
-        return null;
226
-    }
227
-
228
-
229
-
230
-    /**
231
-     * @param array $attributes
232
-     * @return EE_Datetime|null
233
-     */
234
-    private function getDatetimeAndQueryParams(array $attributes)
235
-    {
236
-        if ( ! empty($attributes['datetime_id'])) {
237
-            $datetime = EEM_Datetime::instance()->get_one_by_ID($attributes['datetime_id']);
238
-            if ($datetime instanceof EE_Datetime) {
239
-                $this->query_params[0]['Registration.Ticket.Datetime.DTT_ID'] = $attributes['datetime_id'];
240
-                $this->query_params['default_where_conditions'] = 'this_model_only';
241
-                if ( ! $this->template_args['event'] instanceof EE_Event) {
242
-                    $this->template_args['event'] = $datetime->event();
243
-                }
244
-                return $datetime;
245
-            }
246
-        }
247
-        return null;
248
-    }
249
-
250
-
251
-
252
-    /**
253
-     * @param array $attributes
254
-     * @return \EE_Base_Class|null
255
-     * @throws EE_Error
256
-     */
257
-    private function getTicketAndQueryParams(array $attributes)
258
-    {
259
-        if ( ! empty($attributes['ticket_id']) && empty($attributes['event_id']) && empty($attributes['datetime_id'])) {
260
-            $ticket = EEM_Ticket::instance()->get_one_by_ID($attributes['ticket_id']);
261
-            if ($ticket instanceof EE_Ticket) {
262
-                $this->query_params[0]['Registration.TKT_ID'] = $attributes['ticket_id'];
263
-                if ( ! $this->template_args['event'] instanceof EE_Event) {
264
-                    $this->template_args['event'] = $ticket->first_datetime() instanceof EE_Datetime
265
-                        ? $ticket->first_datetime()->event()
266
-                        : null;
267
-                }
268
-                return $ticket;
269
-            }
270
-        }
271
-        return null;
272
-    }
273
-
274
-
275
-
276
-    /**
277
-     * @param array $attributes
278
-     * @throws EE_Error
279
-     */
280
-    private function setAdditionalQueryParams(array $attributes)
281
-    {
282
-        $reg_status_array = EEM_Registration::reg_status_array();
283
-        if ($attributes['status'] !== 'all' && isset($reg_status_array[$attributes['status']])) {
284
-            $this->query_params[0]['Registration.STS_ID'] = $attributes['status'];
285
-        }
286
-        $this->query_params['group_by'] = array('ATT_ID');
287
-        $this->query_params['order_by'] = (array) apply_filters(
288
-            'FHEE__EES_Espresso_Event_Attendees__process_shortcode__order_by',
289
-            array('ATT_lname' => 'ASC', 'ATT_fname' => 'ASC')
290
-        );
291
-    }
32
+	private $query_params = array(
33
+		0 => array()
34
+	);
35
+
36
+	private $template_args = array(
37
+		'contacts'      => array(),
38
+		'event'         => null,
39
+		'datetime'      => null,
40
+		'ticket'        => null,
41
+	);
42
+
43
+	/**
44
+	 * the actual shortcode tag that gets registered with WordPress
45
+	 *
46
+	 * @return string
47
+	 */
48
+	public function getTag()
49
+	{
50
+		return 'ESPRESSO_EVENT_ATTENDEES';
51
+	}
52
+
53
+
54
+
55
+	/**
56
+	 * the time in seconds to cache the results of the processShortcode() method
57
+	 * 0 means the processShortcode() results will NOT be cached at all
58
+	 *
59
+	 * @return int
60
+	 */
61
+	public function cacheExpiration()
62
+	{
63
+		return 0;
64
+	}
65
+
66
+
67
+
68
+	/**
69
+	 * a place for adding any initialization code that needs to run prior to wp_header().
70
+	 * this may be required for shortcodes that utilize a corresponding module,
71
+	 * and need to enqueue assets for that module
72
+	 *
73
+	 * @return void
74
+	 */
75
+	public function initializeShortcode()
76
+	{
77
+		$this->shortcodeHasBeenInitialized();
78
+	}
79
+
80
+
81
+
82
+	/**
83
+	 * process_shortcode - ESPRESSO_EVENT_ATTENDEES - Returns a list of attendees to an event.
84
+	 *  [ESPRESSO_EVENT_ATTENDEES]
85
+	 *  - defaults to attendees for earliest active event, or earliest upcoming event.
86
+	 *
87
+	 *  [ESPRESSO_EVENT_ATTENDEES event_id=123]
88
+	 *  - attendees for specific event.
89
+	 *
90
+	 *  [ESPRESSO_EVENT_ATTENDEES datetime_id=245]
91
+	 *  - attendees for a specific datetime.
92
+	 *
93
+	 *  [ESPRESSO_EVENT_ATTENDEES ticket_id=123]
94
+	 *  - attendees for a specific ticket.
95
+	 *
96
+	 *  [ESPRESSO_EVENT_ATTENDEES status=all]
97
+	 *  - specific registration status (use status id) or all for all attendees regardless of status.
98
+	 *  Note default is to only return approved attendees
99
+	 *
100
+	 *  [ESPRESSO_EVENT_ATTENDEES show_gravatar=true]
101
+	 *  - default is to not return gravatar.  Otherwise if this is set then return gravatar for email address given.
102
+	 *
103
+	 *  [ESPRESSO_EVENT_ATTENDEES display_on_archives=true]
104
+	 *  - default is to not display attendees list on archive pages.
105
+	 *
106
+	 * Note: because of the relationship between event_id, ticket_id, and datetime_id:
107
+	 * If more than one of those params is included, then preference is given to the following:
108
+	 *  - event_id is used whenever its present and any others are ignored.
109
+	 *  - if no event_id then datetime is used whenever its present and any others are ignored.
110
+	 *  - otherwise ticket_id is used if present.
111
+	 *
112
+	 * @param array $attributes
113
+	 * @return string
114
+	 * @throws EE_Error
115
+	 */
116
+	public function processShortcode($attributes = array())
117
+	{
118
+		// grab attributes and merge with defaults
119
+		$attributes = $this->getAttributes((array)$attributes);
120
+		$archive = is_archive();
121
+		$display_on_archives = filter_var($attributes['display_on_archives'], FILTER_VALIDATE_BOOLEAN);
122
+		// don't display on archives unless 'display_on_archives' is true
123
+		if($archive && ! $display_on_archives) {
124
+			return '';
125
+		}
126
+		// add attributes to template args
127
+		$this->template_args['show_gravatar'] = $attributes['show_gravatar'];
128
+		// add required objects: event, datetime, and ticket
129
+		$this->template_args['event'] = $this->getEventAndQueryParams($attributes);
130
+		$this->template_args['datetime'] = $this->getDatetimeAndQueryParams($attributes);
131
+		$this->template_args['ticket'] = $this->getTicketAndQueryParams($attributes);
132
+
133
+		// if any of the above objects is invalid or missing,
134
+		// then there was an invalid parameter or the shortcode was used incorrectly
135
+		// so when WP_DEBUG is set and true, we'll show a message,
136
+		// otherwise we'll just return an empty string.
137
+		 if (
138
+			! $this->template_args['event'] instanceof EE_Event
139
+			|| empty($this->query_params[0])
140
+			|| ($attributes['datetime_id'] && ! $this->template_args['datetime'] instanceof EE_Datetime)
141
+			|| ($attributes['ticket_id'] && ! $this->template_args['ticket'] instanceof EE_Ticket)
142
+		) {
143
+			if (WP_DEBUG) {
144
+				return '<div class="important-notice ee-attention">'
145
+					   . esc_html__('The [ESPRESSO_EVENT_ATTENDEES] shortcode has been used incorrectly.  Please double check the arguments you used for any typos.  In the case of ID type arguments, its possible the given ID does not correspond to existing data in the database.',
146
+						'event_espresso')
147
+					   . '</div>';
148
+			}
149
+			 return '';
150
+		}
151
+		$this->setAdditionalQueryParams($attributes);
152
+		//get contacts!
153
+		$this->template_args['contacts'] = EEM_Attendee::instance()->get_all($this->query_params);
154
+		//all set let's load up the template and return.
155
+		return EEH_Template::locate_template(
156
+			'loop-espresso_event_attendees.php',
157
+			$this->template_args
158
+		);
159
+
160
+	}
161
+
162
+
163
+
164
+	/**
165
+	 * merge incoming attributes with filtered defaults
166
+	 *
167
+	 * @param array $attributes
168
+	 * @return array
169
+	 */
170
+	private function getAttributes(array $attributes)
171
+	{
172
+		return (array) apply_filters(
173
+			'EES_Espresso_Event_Attendees__process_shortcode__default_shortcode_atts',
174
+			$attributes + array(
175
+				'event_id'            => null,
176
+				'datetime_id'         => null,
177
+				'ticket_id'           => null,
178
+				'status'              => EEM_Registration::status_id_approved,
179
+				'show_gravatar'       => false,
180
+				'display_on_archives' => false,
181
+			)
182
+		);
183
+	}
184
+
185
+
186
+
187
+	/**
188
+	 * @param array $attributes
189
+	 * @return EE_Event|null
190
+	 * @throws EE_Error
191
+	 */
192
+	private function getEventAndQueryParams(array $attributes){
193
+		if ( ! empty($attributes['event_id'])) {
194
+			$event = EEM_Event::instance()->get_one_by_ID($attributes['event_id']);
195
+			if ($event instanceof EE_Event) {
196
+				$this->query_params[0]['Registration.EVT_ID'] = $attributes['event_id'];
197
+				return $event;
198
+			}
199
+		}
200
+		if (is_espresso_event()) {
201
+			$event = EEH_Event_View::get_event();
202
+			if ($event instanceof EE_Event) {
203
+				$this->query_params[0]['Registration.EVT_ID'] = $event->ID();
204
+				return $event;
205
+			}
206
+		}
207
+		// one last shot...
208
+		// try getting the earliest active event
209
+		$events = EEM_Event::instance()->get_active_events(array(
210
+			'limit'    => 1,
211
+			'order_by' => array('Datetime.DTT_EVT_start' => 'ASC')
212
+		));
213
+		//  if none then get the next upcoming
214
+		$events = empty($events)
215
+			? EEM_Event::instance()->get_upcoming_events(array(
216
+				'limit'    => 1,
217
+				'order_by' => array('Datetime.DTT_EVT_start' => 'ASC')
218
+			))
219
+			: $events;
220
+		$event = reset($events);
221
+		if ($event instanceof EE_Event) {
222
+			$this->query_params[0]['Registration.EVT_ID'] = $event->ID();
223
+			return $event;
224
+		}
225
+		return null;
226
+	}
227
+
228
+
229
+
230
+	/**
231
+	 * @param array $attributes
232
+	 * @return EE_Datetime|null
233
+	 */
234
+	private function getDatetimeAndQueryParams(array $attributes)
235
+	{
236
+		if ( ! empty($attributes['datetime_id'])) {
237
+			$datetime = EEM_Datetime::instance()->get_one_by_ID($attributes['datetime_id']);
238
+			if ($datetime instanceof EE_Datetime) {
239
+				$this->query_params[0]['Registration.Ticket.Datetime.DTT_ID'] = $attributes['datetime_id'];
240
+				$this->query_params['default_where_conditions'] = 'this_model_only';
241
+				if ( ! $this->template_args['event'] instanceof EE_Event) {
242
+					$this->template_args['event'] = $datetime->event();
243
+				}
244
+				return $datetime;
245
+			}
246
+		}
247
+		return null;
248
+	}
249
+
250
+
251
+
252
+	/**
253
+	 * @param array $attributes
254
+	 * @return \EE_Base_Class|null
255
+	 * @throws EE_Error
256
+	 */
257
+	private function getTicketAndQueryParams(array $attributes)
258
+	{
259
+		if ( ! empty($attributes['ticket_id']) && empty($attributes['event_id']) && empty($attributes['datetime_id'])) {
260
+			$ticket = EEM_Ticket::instance()->get_one_by_ID($attributes['ticket_id']);
261
+			if ($ticket instanceof EE_Ticket) {
262
+				$this->query_params[0]['Registration.TKT_ID'] = $attributes['ticket_id'];
263
+				if ( ! $this->template_args['event'] instanceof EE_Event) {
264
+					$this->template_args['event'] = $ticket->first_datetime() instanceof EE_Datetime
265
+						? $ticket->first_datetime()->event()
266
+						: null;
267
+				}
268
+				return $ticket;
269
+			}
270
+		}
271
+		return null;
272
+	}
273
+
274
+
275
+
276
+	/**
277
+	 * @param array $attributes
278
+	 * @throws EE_Error
279
+	 */
280
+	private function setAdditionalQueryParams(array $attributes)
281
+	{
282
+		$reg_status_array = EEM_Registration::reg_status_array();
283
+		if ($attributes['status'] !== 'all' && isset($reg_status_array[$attributes['status']])) {
284
+			$this->query_params[0]['Registration.STS_ID'] = $attributes['status'];
285
+		}
286
+		$this->query_params['group_by'] = array('ATT_ID');
287
+		$this->query_params['order_by'] = (array) apply_filters(
288
+			'FHEE__EES_Espresso_Event_Attendees__process_shortcode__order_by',
289
+			array('ATT_lname' => 'ASC', 'ATT_fname' => 'ASC')
290
+		);
291
+	}
292 292
 
293 293
 
294 294
 
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -116,11 +116,11 @@  discard block
 block discarded – undo
116 116
     public function processShortcode($attributes = array())
117 117
     {
118 118
         // grab attributes and merge with defaults
119
-        $attributes = $this->getAttributes((array)$attributes);
119
+        $attributes = $this->getAttributes((array) $attributes);
120 120
         $archive = is_archive();
121 121
         $display_on_archives = filter_var($attributes['display_on_archives'], FILTER_VALIDATE_BOOLEAN);
122 122
         // don't display on archives unless 'display_on_archives' is true
123
-        if($archive && ! $display_on_archives) {
123
+        if ($archive && ! $display_on_archives) {
124 124
             return '';
125 125
         }
126 126
         // add attributes to template args
@@ -189,7 +189,7 @@  discard block
 block discarded – undo
189 189
      * @return EE_Event|null
190 190
      * @throws EE_Error
191 191
      */
192
-    private function getEventAndQueryParams(array $attributes){
192
+    private function getEventAndQueryParams(array $attributes) {
193 193
         if ( ! empty($attributes['event_id'])) {
194 194
             $event = EEM_Event::instance()->get_one_by_ID($attributes['event_id']);
195 195
             if ($event instanceof EE_Event) {
Please login to merge, or discard this patch.
core/db_classes/EE_Base_Class.class.php 1 patch
Indentation   +2681 added lines, -2681 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
 do_action('AHEE_log', __FILE__, ' FILE LOADED', '');
5 5
 
@@ -25,2686 +25,2686 @@  discard block
 block discarded – undo
25 25
 abstract class EE_Base_Class
26 26
 {
27 27
 
28
-    /**
29
-     * This is an array of the original properties and values provided during construction
30
-     * of this model object. (keys are model field names, values are their values).
31
-     * This list is important to remember so that when we are merging data from the db, we know
32
-     * which values to override and which to not override.
33
-     *
34
-     * @var array
35
-     */
36
-    protected $_props_n_values_provided_in_constructor;
37
-
38
-    /**
39
-     * Timezone
40
-     * This gets set by the "set_timezone()" method so that we know what timezone incoming strings|timestamps are in.
41
-     * This can also be used before a get to set what timezone you want strings coming out of the object to be in.  NOT
42
-     * all EE_Base_Class child classes use this property but any that use a EE_Datetime_Field data type will have
43
-     * access to it.
44
-     *
45
-     * @var string
46
-     */
47
-    protected $_timezone;
48
-
49
-
50
-
51
-    /**
52
-     * date format
53
-     * pattern or format for displaying dates
54
-     *
55
-     * @var string $_dt_frmt
56
-     */
57
-    protected $_dt_frmt;
58
-
59
-
60
-
61
-    /**
62
-     * time format
63
-     * pattern or format for displaying time
64
-     *
65
-     * @var string $_tm_frmt
66
-     */
67
-    protected $_tm_frmt;
68
-
69
-
70
-
71
-    /**
72
-     * This property is for holding a cached array of object properties indexed by property name as the key.
73
-     * The purpose of this is for setting a cache on properties that may have calculated values after a
74
-     * prepare_for_get.  That way the cache can be checked first and the calculated property returned instead of having
75
-     * to recalculate. Used by _set_cached_property() and _get_cached_property() methods.
76
-     *
77
-     * @var array
78
-     */
79
-    protected $_cached_properties = array();
80
-
81
-    /**
82
-     * An array containing keys of the related model, and values are either an array of related mode objects or a
83
-     * single
84
-     * related model object. see the model's _model_relations. The keys should match those specified. And if the
85
-     * relation is of type EE_Belongs_To (or one of its children), then there should only be ONE related model object,
86
-     * all others have an array)
87
-     *
88
-     * @var array
89
-     */
90
-    protected $_model_relations = array();
91
-
92
-    /**
93
-     * Array where keys are field names (see the model's _fields property) and values are their values. To see what
94
-     * their types should be, look at what that field object returns on its prepare_for_get and prepare_for_set methods)
95
-     *
96
-     * @var array
97
-     */
98
-    protected $_fields = array();
99
-
100
-    /**
101
-     * @var boolean indicating whether or not this model object is intended to ever be saved
102
-     * For example, we might create model objects intended to only be used for the duration
103
-     * of this request and to be thrown away, and if they were accidentally saved
104
-     * it would be a bug.
105
-     */
106
-    protected $_allow_persist = true;
107
-
108
-    /**
109
-     * @var boolean indicating whether or not this model object's properties have changed since construction
110
-     */
111
-    protected $_has_changes = false;
112
-
113
-
114
-
115
-    /**
116
-     * basic constructor for Event Espresso classes, performs any necessary initialization, and verifies it's children
117
-     * play nice
118
-     *
119
-     * @param array   $fieldValues                             where each key is a field (ie, array key in the 2nd
120
-     *                                                         layer of the model's _fields array, (eg, EVT_ID,
121
-     *                                                         TXN_amount, QST_name, etc) and values are their values
122
-     * @param boolean $bydb                                    a flag for setting if the class is instantiated by the
123
-     *                                                         corresponding db model or not.
124
-     * @param string  $timezone                                indicate what timezone you want any datetime fields to
125
-     *                                                         be in when instantiating a EE_Base_Class object.
126
-     * @param array   $date_formats                            An array of date formats to set on construct where first
127
-     *                                                         value is the date_format and second value is the time
128
-     *                                                         format.
129
-     * @throws EE_Error
130
-     */
131
-    protected function __construct($fieldValues = array(), $bydb = false, $timezone = '', $date_formats = array())
132
-    {
133
-        $className = get_class($this);
134
-        do_action("AHEE__{$className}__construct", $this, $fieldValues);
135
-        $model = $this->get_model();
136
-        $model_fields = $model->field_settings(false);
137
-        // ensure $fieldValues is an array
138
-        $fieldValues = is_array($fieldValues) ? $fieldValues : array($fieldValues);
139
-        // EEH_Debug_Tools::printr( $fieldValues, '$fieldValues  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
140
-        // verify client code has not passed any invalid field names
141
-        foreach ($fieldValues as $field_name => $field_value) {
142
-            if ( ! isset($model_fields[$field_name])) {
143
-                throw new EE_Error(sprintf(__("Invalid field (%s) passed to constructor of %s. Allowed fields are :%s",
144
-                    "event_espresso"), $field_name, get_class($this), implode(", ", array_keys($model_fields))));
145
-            }
146
-        }
147
-        // EEH_Debug_Tools::printr( $model_fields, '$model_fields  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
148
-        $this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
149
-        if ( ! empty($date_formats) && is_array($date_formats)) {
150
-            list($this->_dt_frmt, $this->_tm_frmt) = $date_formats;
151
-        } else {
152
-            //set default formats for date and time
153
-            $this->_dt_frmt = (string)get_option('date_format', 'Y-m-d');
154
-            $this->_tm_frmt = (string)get_option('time_format', 'g:i a');
155
-        }
156
-        //if db model is instantiating
157
-        if ($bydb) {
158
-            //client code has indicated these field values are from the database
159
-            foreach ($model_fields as $fieldName => $field) {
160
-                $this->set_from_db($fieldName, isset($fieldValues[$fieldName]) ? $fieldValues[$fieldName] : null);
161
-            }
162
-        } else {
163
-            //we're constructing a brand
164
-            //new instance of the model object. Generally, this means we'll need to do more field validation
165
-            foreach ($model_fields as $fieldName => $field) {
166
-                $this->set($fieldName, isset($fieldValues[$fieldName]) ? $fieldValues[$fieldName] : null, true);
167
-            }
168
-        }
169
-        //remember what values were passed to this constructor
170
-        $this->_props_n_values_provided_in_constructor = $fieldValues;
171
-        //remember in entity mapper
172
-        if ( ! $bydb && $model->has_primary_key_field() && $this->ID()) {
173
-            $model->add_to_entity_map($this);
174
-        }
175
-        //setup all the relations
176
-        foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
177
-            if ($relation_obj instanceof EE_Belongs_To_Relation) {
178
-                $this->_model_relations[$relation_name] = null;
179
-            } else {
180
-                $this->_model_relations[$relation_name] = array();
181
-            }
182
-        }
183
-        /**
184
-         * Action done at the end of each model object construction
185
-         *
186
-         * @param EE_Base_Class $this the model object just created
187
-         */
188
-        do_action('AHEE__EE_Base_Class__construct__finished', $this);
189
-    }
190
-
191
-
192
-
193
-    /**
194
-     * Gets whether or not this model object is allowed to persist/be saved to the database.
195
-     *
196
-     * @return boolean
197
-     */
198
-    public function allow_persist()
199
-    {
200
-        return $this->_allow_persist;
201
-    }
202
-
203
-
204
-
205
-    /**
206
-     * Sets whether or not this model object should be allowed to be saved to the DB.
207
-     * Normally once this is set to FALSE you wouldn't set it back to TRUE, unless
208
-     * you got new information that somehow made you change your mind.
209
-     *
210
-     * @param boolean $allow_persist
211
-     * @return boolean
212
-     */
213
-    public function set_allow_persist($allow_persist)
214
-    {
215
-        return $this->_allow_persist = $allow_persist;
216
-    }
217
-
218
-
219
-
220
-    /**
221
-     * Gets the field's original value when this object was constructed during this request.
222
-     * This can be helpful when determining if a model object has changed or not
223
-     *
224
-     * @param string $field_name
225
-     * @return mixed|null
226
-     * @throws \EE_Error
227
-     */
228
-    public function get_original($field_name)
229
-    {
230
-        if (isset($this->_props_n_values_provided_in_constructor[$field_name])
231
-            && $field_settings = $this->get_model()->field_settings_for($field_name)
232
-        ) {
233
-            return $field_settings->prepare_for_get($this->_props_n_values_provided_in_constructor[$field_name]);
234
-        } else {
235
-            return null;
236
-        }
237
-    }
238
-
239
-
240
-
241
-    /**
242
-     * @param EE_Base_Class $obj
243
-     * @return string
244
-     */
245
-    public function get_class($obj)
246
-    {
247
-        return get_class($obj);
248
-    }
249
-
250
-
251
-
252
-    /**
253
-     * Overrides parent because parent expects old models.
254
-     * This also doesn't do any validation, and won't work for serialized arrays
255
-     *
256
-     * @param    string $field_name
257
-     * @param    mixed  $field_value
258
-     * @param bool      $use_default
259
-     * @throws \EE_Error
260
-     */
261
-    public function set($field_name, $field_value, $use_default = false)
262
-    {
263
-        // if not using default and nothing has changed, and object has already been setup (has ID),
264
-        // then don't do anything
265
-        if (
266
-            ! $use_default
267
-            && $this->_fields[$field_name] === $field_value
268
-            && $this->ID()
269
-        ) {
270
-            return;
271
-        }
272
-        $this->_has_changes = true;
273
-        $field_obj = $this->get_model()->field_settings_for($field_name);
274
-        if ($field_obj instanceof EE_Model_Field_Base) {
275
-            //			if ( method_exists( $field_obj, 'set_timezone' )) {
276
-            if ($field_obj instanceof EE_Datetime_Field) {
277
-                $field_obj->set_timezone($this->_timezone);
278
-                $field_obj->set_date_format($this->_dt_frmt);
279
-                $field_obj->set_time_format($this->_tm_frmt);
280
-            }
281
-            $holder_of_value = $field_obj->prepare_for_set($field_value);
282
-            //should the value be null?
283
-            if (($field_value === null || $holder_of_value === null || $holder_of_value === '') && $use_default) {
284
-                $this->_fields[$field_name] = $field_obj->get_default_value();
285
-                /**
286
-                 * To save having to refactor all the models, if a default value is used for a
287
-                 * EE_Datetime_Field, and that value is not null nor is it a DateTime
288
-                 * object.  Then let's do a set again to ensure that it becomes a DateTime
289
-                 * object.
290
-                 *
291
-                 * @since 4.6.10+
292
-                 */
293
-                if (
294
-                    $field_obj instanceof EE_Datetime_Field
295
-                    && $this->_fields[$field_name] !== null
296
-                    && ! $this->_fields[$field_name] instanceof DateTime
297
-                ) {
298
-                    empty($this->_fields[$field_name])
299
-                        ? $this->set($field_name, time())
300
-                        : $this->set($field_name, $this->_fields[$field_name]);
301
-                }
302
-            } else {
303
-                $this->_fields[$field_name] = $holder_of_value;
304
-            }
305
-            //if we're not in the constructor...
306
-            //now check if what we set was a primary key
307
-            if (
308
-                //note: props_n_values_provided_in_constructor is only set at the END of the constructor
309
-                $this->_props_n_values_provided_in_constructor
310
-                && $field_value
311
-                && $field_name === self::_get_primary_key_name(get_class($this))
312
-            ) {
313
-                //if so, we want all this object's fields to be filled either with
314
-                //what we've explicitly set on this model
315
-                //or what we have in the db
316
-                // echo "setting primary key!";
317
-                $fields_on_model = self::_get_model(get_class($this))->field_settings();
318
-                $obj_in_db = self::_get_model(get_class($this))->get_one_by_ID($field_value);
319
-                foreach ($fields_on_model as $field_obj) {
320
-                    if ( ! array_key_exists($field_obj->get_name(), $this->_props_n_values_provided_in_constructor)
321
-                         && $field_obj->get_name() !== $field_name
322
-                    ) {
323
-                        $this->set($field_obj->get_name(), $obj_in_db->get($field_obj->get_name()));
324
-                    }
325
-                }
326
-                //oh this model object has an ID? well make sure its in the entity mapper
327
-                $this->get_model()->add_to_entity_map($this);
328
-            }
329
-            //let's unset any cache for this field_name from the $_cached_properties property.
330
-            $this->_clear_cached_property($field_name);
331
-        } else {
332
-            throw new EE_Error(sprintf(__("A valid EE_Model_Field_Base could not be found for the given field name: %s",
333
-                "event_espresso"), $field_name));
334
-        }
335
-    }
336
-
337
-
338
-
339
-    /**
340
-     * This sets the field value on the db column if it exists for the given $column_name or
341
-     * saves it to EE_Extra_Meta if the given $column_name does not match a db column.
342
-     *
343
-     * @see EE_message::get_column_value for related documentation on the necessity of this method.
344
-     * @param string $field_name  Must be the exact column name.
345
-     * @param mixed  $field_value The value to set.
346
-     * @return int|bool @see EE_Base_Class::update_extra_meta() for return docs.
347
-     * @throws \EE_Error
348
-     */
349
-    public function set_field_or_extra_meta($field_name, $field_value)
350
-    {
351
-        if ($this->get_model()->has_field($field_name)) {
352
-            $this->set($field_name, $field_value);
353
-            return true;
354
-        } else {
355
-            //ensure this object is saved first so that extra meta can be properly related.
356
-            $this->save();
357
-            return $this->update_extra_meta($field_name, $field_value);
358
-        }
359
-    }
360
-
361
-
362
-
363
-    /**
364
-     * This retrieves the value of the db column set on this class or if that's not present
365
-     * it will attempt to retrieve from extra_meta if found.
366
-     * Example Usage:
367
-     * Via EE_Message child class:
368
-     * Due to the dynamic nature of the EE_messages system, EE_messengers will always have a "to",
369
-     * "from", "subject", and "content" field (as represented in the EE_Message schema), however they may
370
-     * also have additional main fields specific to the messenger.  The system accommodates those extra
371
-     * fields through the EE_Extra_Meta table.  This method allows for EE_messengers to retrieve the
372
-     * value for those extra fields dynamically via the EE_message object.
373
-     *
374
-     * @param  string $field_name expecting the fully qualified field name.
375
-     * @return mixed|null  value for the field if found.  null if not found.
376
-     * @throws \EE_Error
377
-     */
378
-    public function get_field_or_extra_meta($field_name)
379
-    {
380
-        if ($this->get_model()->has_field($field_name)) {
381
-            $column_value = $this->get($field_name);
382
-        } else {
383
-            //This isn't a column in the main table, let's see if it is in the extra meta.
384
-            $column_value = $this->get_extra_meta($field_name, true, null);
385
-        }
386
-        return $column_value;
387
-    }
388
-
389
-
390
-
391
-    /**
392
-     * See $_timezone property for description of what the timezone property is for.  This SETS the timezone internally
393
-     * for being able to reference what timezone we are running conversions on when converting TO the internal timezone
394
-     * (UTC Unix Timestamp) for the object OR when converting FROM the internal timezone (UTC Unix Timestamp). This is
395
-     * available to all child classes that may be using the EE_Datetime_Field for a field data type.
396
-     *
397
-     * @access public
398
-     * @param string $timezone A valid timezone string as described by @link http://www.php.net/manual/en/timezones.php
399
-     * @return void
400
-     * @throws \EE_Error
401
-     */
402
-    public function set_timezone($timezone = '')
403
-    {
404
-        $this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
405
-        //make sure we clear all cached properties because they won't be relevant now
406
-        $this->_clear_cached_properties();
407
-        //make sure we update field settings and the date for all EE_Datetime_Fields
408
-        $model_fields = $this->get_model()->field_settings(false);
409
-        foreach ($model_fields as $field_name => $field_obj) {
410
-            if ($field_obj instanceof EE_Datetime_Field) {
411
-                $field_obj->set_timezone($this->_timezone);
412
-                if (isset($this->_fields[$field_name]) && $this->_fields[$field_name] instanceof DateTime) {
413
-                    $this->_fields[$field_name]->setTimezone(new DateTimeZone($this->_timezone));
414
-                }
415
-            }
416
-        }
417
-    }
418
-
419
-
420
-
421
-    /**
422
-     * This just returns whatever is set for the current timezone.
423
-     *
424
-     * @access public
425
-     * @return string timezone string
426
-     */
427
-    public function get_timezone()
428
-    {
429
-        return $this->_timezone;
430
-    }
431
-
432
-
433
-
434
-    /**
435
-     * This sets the internal date format to what is sent in to be used as the new default for the class
436
-     * internally instead of wp set date format options
437
-     *
438
-     * @since 4.6
439
-     * @param string $format should be a format recognizable by PHP date() functions.
440
-     */
441
-    public function set_date_format($format)
442
-    {
443
-        $this->_dt_frmt = $format;
444
-        //clear cached_properties because they won't be relevant now.
445
-        $this->_clear_cached_properties();
446
-    }
447
-
448
-
449
-
450
-    /**
451
-     * This sets the internal time format string to what is sent in to be used as the new default for the
452
-     * class internally instead of wp set time format options.
453
-     *
454
-     * @since 4.6
455
-     * @param string $format should be a format recognizable by PHP date() functions.
456
-     */
457
-    public function set_time_format($format)
458
-    {
459
-        $this->_tm_frmt = $format;
460
-        //clear cached_properties because they won't be relevant now.
461
-        $this->_clear_cached_properties();
462
-    }
463
-
464
-
465
-
466
-    /**
467
-     * This returns the current internal set format for the date and time formats.
468
-     *
469
-     * @param bool $full           if true (default), then return the full format.  Otherwise will return an array
470
-     *                             where the first value is the date format and the second value is the time format.
471
-     * @return mixed string|array
472
-     */
473
-    public function get_format($full = true)
474
-    {
475
-        return $full ? $this->_dt_frmt . ' ' . $this->_tm_frmt : array($this->_dt_frmt, $this->_tm_frmt);
476
-    }
477
-
478
-
479
-
480
-    /**
481
-     * cache
482
-     * stores the passed model object on the current model object.
483
-     * In certain circumstances, we can use this cached model object instead of querying for another one entirely.
484
-     *
485
-     * @param string        $relationName    one of the keys in the _model_relations array on the model. Eg
486
-     *                                       'Registration' associated with this model object
487
-     * @param EE_Base_Class $object_to_cache that has a relation to this model object. (Eg, if this is a Transaction,
488
-     *                                       that could be a payment or a registration)
489
-     * @param null          $cache_id        a string or number that will be used as the key for any Belongs_To_Many
490
-     *                                       items which will be stored in an array on this object
491
-     * @throws EE_Error
492
-     * @return mixed    index into cache, or just TRUE if the relation is of type Belongs_To (because there's only one
493
-     *                  related thing, no array)
494
-     */
495
-    public function cache($relationName = '', $object_to_cache = null, $cache_id = null)
496
-    {
497
-        // its entirely possible that there IS no related object yet in which case there is nothing to cache.
498
-        if ( ! $object_to_cache instanceof EE_Base_Class) {
499
-            return false;
500
-        }
501
-        // also get "how" the object is related, or throw an error
502
-        if ( ! $relationship_to_model = $this->get_model()->related_settings_for($relationName)) {
503
-            throw new EE_Error(sprintf(__('There is no relationship to %s on a %s. Cannot cache it', 'event_espresso'),
504
-                $relationName, get_class($this)));
505
-        }
506
-        // how many things are related ?
507
-        if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
508
-            // if it's a "belongs to" relationship, then there's only one related model object  eg, if this is a registration, there's only 1 attendee for it
509
-            // so for these model objects just set it to be cached
510
-            $this->_model_relations[$relationName] = $object_to_cache;
511
-            $return = true;
512
-        } else {
513
-            // otherwise, this is the "many" side of a one to many relationship, so we'll add the object to the array of related objects for that type.
514
-            // eg: if this is an event, there are many registrations for that event, so we cache the registrations in an array
515
-            if ( ! is_array($this->_model_relations[$relationName])) {
516
-                // if for some reason, the cached item is a model object, then stick that in the array, otherwise start with an empty array
517
-                $this->_model_relations[$relationName] = $this->_model_relations[$relationName] instanceof EE_Base_Class
518
-                    ? array($this->_model_relations[$relationName]) : array();
519
-            }
520
-            // first check for a cache_id which is normally empty
521
-            if ( ! empty($cache_id)) {
522
-                // if the cache_id exists, then it means we are purposely trying to cache this with a known key that can then be used to retrieve the object later on
523
-                $this->_model_relations[$relationName][$cache_id] = $object_to_cache;
524
-                $return = $cache_id;
525
-            } elseif ($object_to_cache->ID()) {
526
-                // OR the cached object originally came from the db, so let's just use it's PK for an ID
527
-                $this->_model_relations[$relationName][$object_to_cache->ID()] = $object_to_cache;
528
-                $return = $object_to_cache->ID();
529
-            } else {
530
-                // OR it's a new object with no ID, so just throw it in the array with an auto-incremented ID
531
-                $this->_model_relations[$relationName][] = $object_to_cache;
532
-                // move the internal pointer to the end of the array
533
-                end($this->_model_relations[$relationName]);
534
-                // and grab the key so that we can return it
535
-                $return = key($this->_model_relations[$relationName]);
536
-            }
537
-        }
538
-        return $return;
539
-    }
540
-
541
-
542
-
543
-    /**
544
-     * For adding an item to the cached_properties property.
545
-     *
546
-     * @access protected
547
-     * @param string      $fieldname the property item the corresponding value is for.
548
-     * @param mixed       $value     The value we are caching.
549
-     * @param string|null $cache_type
550
-     * @return void
551
-     * @throws \EE_Error
552
-     */
553
-    protected function _set_cached_property($fieldname, $value, $cache_type = null)
554
-    {
555
-        //first make sure this property exists
556
-        $this->get_model()->field_settings_for($fieldname);
557
-        $cache_type = empty($cache_type) ? 'standard' : $cache_type;
558
-        $this->_cached_properties[$fieldname][$cache_type] = $value;
559
-    }
560
-
561
-
562
-
563
-    /**
564
-     * This returns the value cached property if it exists OR the actual property value if the cache doesn't exist.
565
-     * This also SETS the cache if we return the actual property!
566
-     *
567
-     * @param string $fieldname        the name of the property we're trying to retrieve
568
-     * @param bool   $pretty
569
-     * @param string $extra_cache_ref  This allows the user to specify an extra cache ref for the given property
570
-     *                                 (in cases where the same property may be used for different outputs
571
-     *                                 - i.e. datetime, money etc.)
572
-     *                                 It can also accept certain pre-defined "schema" strings
573
-     *                                 to define how to output the property.
574
-     *                                 see the field's prepare_for_pretty_echoing for what strings can be used
575
-     * @return mixed                   whatever the value for the property is we're retrieving
576
-     * @throws \EE_Error
577
-     */
578
-    protected function _get_cached_property($fieldname, $pretty = false, $extra_cache_ref = null)
579
-    {
580
-        //verify the field exists
581
-        $this->get_model()->field_settings_for($fieldname);
582
-        $cache_type = $pretty ? 'pretty' : 'standard';
583
-        $cache_type .= ! empty($extra_cache_ref) ? '_' . $extra_cache_ref : '';
584
-        if (isset($this->_cached_properties[$fieldname][$cache_type])) {
585
-            return $this->_cached_properties[$fieldname][$cache_type];
586
-        }
587
-        $value = $this->_get_fresh_property($fieldname, $pretty, $extra_cache_ref);
588
-        $this->_set_cached_property($fieldname, $value, $cache_type);
589
-        return $value;
590
-    }
591
-
592
-
593
-
594
-    /**
595
-     * If the cache didn't fetch the needed item, this fetches it.
596
-     * @param string $fieldname
597
-     * @param bool $pretty
598
-     * @param string $extra_cache_ref
599
-     * @return mixed
600
-     */
601
-    protected function _get_fresh_property($fieldname, $pretty = false, $extra_cache_ref = null)
602
-    {
603
-        $field_obj = $this->get_model()->field_settings_for($fieldname);
604
-        // If this is an EE_Datetime_Field we need to make sure timezone, formats, and output are correct
605
-        if ($field_obj instanceof EE_Datetime_Field) {
606
-            $this->_prepare_datetime_field($field_obj, $pretty, $extra_cache_ref);
607
-        }
608
-        if ( ! isset($this->_fields[$fieldname])) {
609
-            $this->_fields[$fieldname] = null;
610
-        }
611
-        $value = $pretty
612
-            ? $field_obj->prepare_for_pretty_echoing($this->_fields[$fieldname], $extra_cache_ref)
613
-            : $field_obj->prepare_for_get($this->_fields[$fieldname]);
614
-        return $value;
615
-    }
616
-
617
-
618
-
619
-    /**
620
-     * set timezone, formats, and output for EE_Datetime_Field objects
621
-     *
622
-     * @param \EE_Datetime_Field $datetime_field
623
-     * @param bool               $pretty
624
-     * @param null $date_or_time
625
-     * @return void
626
-     * @throws \EE_Error
627
-     */
628
-    protected function _prepare_datetime_field(
629
-        EE_Datetime_Field $datetime_field,
630
-        $pretty = false,
631
-        $date_or_time = null
632
-    ) {
633
-        $datetime_field->set_timezone($this->_timezone);
634
-        $datetime_field->set_date_format($this->_dt_frmt, $pretty);
635
-        $datetime_field->set_time_format($this->_tm_frmt, $pretty);
636
-        //set the output returned
637
-        switch ($date_or_time) {
638
-            case 'D' :
639
-                $datetime_field->set_date_time_output('date');
640
-                break;
641
-            case 'T' :
642
-                $datetime_field->set_date_time_output('time');
643
-                break;
644
-            default :
645
-                $datetime_field->set_date_time_output();
646
-        }
647
-    }
648
-
649
-
650
-
651
-    /**
652
-     * This just takes care of clearing out the cached_properties
653
-     *
654
-     * @return void
655
-     */
656
-    protected function _clear_cached_properties()
657
-    {
658
-        $this->_cached_properties = array();
659
-    }
660
-
661
-
662
-
663
-    /**
664
-     * This just clears out ONE property if it exists in the cache
665
-     *
666
-     * @param  string $property_name the property to remove if it exists (from the _cached_properties array)
667
-     * @return void
668
-     */
669
-    protected function _clear_cached_property($property_name)
670
-    {
671
-        if (isset($this->_cached_properties[$property_name])) {
672
-            unset($this->_cached_properties[$property_name]);
673
-        }
674
-    }
675
-
676
-
677
-
678
-    /**
679
-     * Ensures that this related thing is a model object.
680
-     *
681
-     * @param mixed  $object_or_id EE_base_Class/int/string either a related model object, or its ID
682
-     * @param string $model_name   name of the related thing, eg 'Attendee',
683
-     * @return EE_Base_Class
684
-     * @throws \EE_Error
685
-     */
686
-    protected function ensure_related_thing_is_model_obj($object_or_id, $model_name)
687
-    {
688
-        $other_model_instance = self::_get_model_instance_with_name(
689
-            self::_get_model_classname($model_name),
690
-            $this->_timezone
691
-        );
692
-        return $other_model_instance->ensure_is_obj($object_or_id);
693
-    }
694
-
695
-
696
-
697
-    /**
698
-     * Forgets the cached model of the given relation Name. So the next time we request it,
699
-     * we will fetch it again from the database. (Handy if you know it's changed somehow).
700
-     * If a specific object is supplied, and the relationship to it is either a HasMany or HABTM,
701
-     * then only remove that one object from our cached array. Otherwise, clear the entire list
702
-     *
703
-     * @param string $relationName                         one of the keys in the _model_relations array on the model.
704
-     *                                                     Eg 'Registration'
705
-     * @param mixed  $object_to_remove_or_index_into_array or an index into the array of cached things, or NULL
706
-     *                                                     if you intend to use $clear_all = TRUE, or the relation only
707
-     *                                                     has 1 object anyways (ie, it's a BelongsToRelation)
708
-     * @param bool   $clear_all                            This flags clearing the entire cache relation property if
709
-     *                                                     this is HasMany or HABTM.
710
-     * @throws EE_Error
711
-     * @return EE_Base_Class | boolean from which was cleared from the cache, or true if we requested to remove a
712
-     *                       relation from all
713
-     */
714
-    public function clear_cache($relationName, $object_to_remove_or_index_into_array = null, $clear_all = false)
715
-    {
716
-        $relationship_to_model = $this->get_model()->related_settings_for($relationName);
717
-        $index_in_cache = '';
718
-        if ( ! $relationship_to_model) {
719
-            throw new EE_Error(
720
-                sprintf(
721
-                    __("There is no relationship to %s on a %s. Cannot clear that cache", 'event_espresso'),
722
-                    $relationName,
723
-                    get_class($this)
724
-                )
725
-            );
726
-        }
727
-        if ($clear_all) {
728
-            $obj_removed = true;
729
-            $this->_model_relations[$relationName] = null;
730
-        } elseif ($relationship_to_model instanceof EE_Belongs_To_Relation) {
731
-            $obj_removed = $this->_model_relations[$relationName];
732
-            $this->_model_relations[$relationName] = null;
733
-        } else {
734
-            if ($object_to_remove_or_index_into_array instanceof EE_Base_Class
735
-                && $object_to_remove_or_index_into_array->ID()
736
-            ) {
737
-                $index_in_cache = $object_to_remove_or_index_into_array->ID();
738
-                if (is_array($this->_model_relations[$relationName])
739
-                    && ! isset($this->_model_relations[$relationName][$index_in_cache])
740
-                ) {
741
-                    $index_found_at = null;
742
-                    //find this object in the array even though it has a different key
743
-                    foreach ($this->_model_relations[$relationName] as $index => $obj) {
744
-                        if (
745
-                            $obj instanceof EE_Base_Class
746
-                            && (
747
-                                $obj == $object_to_remove_or_index_into_array
748
-                                || $obj->ID() === $object_to_remove_or_index_into_array->ID()
749
-                            )
750
-                        ) {
751
-                            $index_found_at = $index;
752
-                            break;
753
-                        }
754
-                    }
755
-                    if ($index_found_at) {
756
-                        $index_in_cache = $index_found_at;
757
-                    } else {
758
-                        //it wasn't found. huh. well obviously it doesn't need to be removed from teh cache
759
-                        //if it wasn't in it to begin with. So we're done
760
-                        return $object_to_remove_or_index_into_array;
761
-                    }
762
-                }
763
-            } elseif ($object_to_remove_or_index_into_array instanceof EE_Base_Class) {
764
-                //so they provided a model object, but it's not yet saved to the DB... so let's go hunting for it!
765
-                foreach ($this->get_all_from_cache($relationName) as $index => $potentially_obj_we_want) {
766
-                    if ($potentially_obj_we_want == $object_to_remove_or_index_into_array) {
767
-                        $index_in_cache = $index;
768
-                    }
769
-                }
770
-            } else {
771
-                $index_in_cache = $object_to_remove_or_index_into_array;
772
-            }
773
-            //supposedly we've found it. But it could just be that the client code
774
-            //provided a bad index/object
775
-            if (
776
-            isset(
777
-                $this->_model_relations[$relationName],
778
-                $this->_model_relations[$relationName][$index_in_cache]
779
-            )
780
-            ) {
781
-                $obj_removed = $this->_model_relations[$relationName][$index_in_cache];
782
-                unset($this->_model_relations[$relationName][$index_in_cache]);
783
-            } else {
784
-                //that thing was never cached anyways.
785
-                $obj_removed = null;
786
-            }
787
-        }
788
-        return $obj_removed;
789
-    }
790
-
791
-
792
-
793
-    /**
794
-     * update_cache_after_object_save
795
-     * Allows a cached item to have it's cache ID (within the array of cached items) reset using the new ID it has
796
-     * obtained after being saved to the db
797
-     *
798
-     * @param string         $relationName       - the type of object that is cached
799
-     * @param \EE_Base_Class $newly_saved_object - the newly saved object to be re-cached
800
-     * @param string         $current_cache_id   - the ID that was used when originally caching the object
801
-     * @return boolean TRUE on success, FALSE on fail
802
-     * @throws \EE_Error
803
-     */
804
-    public function update_cache_after_object_save(
805
-        $relationName,
806
-        EE_Base_Class $newly_saved_object,
807
-        $current_cache_id = ''
808
-    ) {
809
-        // verify that incoming object is of the correct type
810
-        $obj_class = 'EE_' . $relationName;
811
-        if ($newly_saved_object instanceof $obj_class) {
812
-            /* @type EE_Base_Class $newly_saved_object */
813
-            // now get the type of relation
814
-            $relationship_to_model = $this->get_model()->related_settings_for($relationName);
815
-            // if this is a 1:1 relationship
816
-            if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
817
-                // then just replace the cached object with the newly saved object
818
-                $this->_model_relations[$relationName] = $newly_saved_object;
819
-                return true;
820
-                // or if it's some kind of sordid feral polyamorous relationship...
821
-            } elseif (is_array($this->_model_relations[$relationName])
822
-                      && isset($this->_model_relations[$relationName][$current_cache_id])
823
-            ) {
824
-                // then remove the current cached item
825
-                unset($this->_model_relations[$relationName][$current_cache_id]);
826
-                // and cache the newly saved object using it's new ID
827
-                $this->_model_relations[$relationName][$newly_saved_object->ID()] = $newly_saved_object;
828
-                return true;
829
-            }
830
-        }
831
-        return false;
832
-    }
833
-
834
-
835
-
836
-    /**
837
-     * Fetches a single EE_Base_Class on that relation. (If the relation is of type
838
-     * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
839
-     *
840
-     * @param string $relationName
841
-     * @return EE_Base_Class
842
-     */
843
-    public function get_one_from_cache($relationName)
844
-    {
845
-        $cached_array_or_object = isset($this->_model_relations[$relationName]) ? $this->_model_relations[$relationName]
846
-            : null;
847
-        if (is_array($cached_array_or_object)) {
848
-            return array_shift($cached_array_or_object);
849
-        } else {
850
-            return $cached_array_or_object;
851
-        }
852
-    }
853
-
854
-
855
-
856
-    /**
857
-     * Fetches a single EE_Base_Class on that relation. (If the relation is of type
858
-     * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
859
-     *
860
-     * @param string $relationName
861
-     * @throws \EE_Error
862
-     * @return EE_Base_Class[] NOT necessarily indexed by primary keys
863
-     */
864
-    public function get_all_from_cache($relationName)
865
-    {
866
-        $objects = isset($this->_model_relations[$relationName]) ? $this->_model_relations[$relationName] : array();
867
-        // if the result is not an array, but exists, make it an array
868
-        $objects = is_array($objects) ? $objects : array($objects);
869
-        //bugfix for https://events.codebasehq.com/projects/event-espresso/tickets/7143
870
-        //basically, if this model object was stored in the session, and these cached model objects
871
-        //already have IDs, let's make sure they're in their model's entity mapper
872
-        //otherwise we will have duplicates next time we call
873
-        // EE_Registry::instance()->load_model( $relationName )->get_one_by_ID( $result->ID() );
874
-        $model = EE_Registry::instance()->load_model($relationName);
875
-        foreach ($objects as $model_object) {
876
-            if ($model instanceof EEM_Base && $model_object instanceof EE_Base_Class) {
877
-                //ensure its in the map if it has an ID; otherwise it will be added to the map when its saved
878
-                if ($model_object->ID()) {
879
-                    $model->add_to_entity_map($model_object);
880
-                }
881
-            } else {
882
-                throw new EE_Error(
883
-                    sprintf(
884
-                        __(
885
-                            'Error retrieving related model objects. Either $1%s is not a model or $2%s is not a model object',
886
-                            'event_espresso'
887
-                        ),
888
-                        $relationName,
889
-                        gettype($model_object)
890
-                    )
891
-                );
892
-            }
893
-        }
894
-        return $objects;
895
-    }
896
-
897
-
898
-
899
-    /**
900
-     * Returns the next x number of EE_Base_Class objects in sequence from this object as found in the database
901
-     * matching the given query conditions.
902
-     *
903
-     * @param null  $field_to_order_by  What field is being used as the reference point.
904
-     * @param int   $limit              How many objects to return.
905
-     * @param array $query_params       Any additional conditions on the query.
906
-     * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
907
-     *                                  you can indicate just the columns you want returned
908
-     * @return array|EE_Base_Class[]
909
-     * @throws \EE_Error
910
-     */
911
-    public function next_x($field_to_order_by = null, $limit = 1, $query_params = array(), $columns_to_select = null)
912
-    {
913
-        $field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
914
-            ? $this->get_model()->get_primary_key_field()->get_name()
915
-            : $field_to_order_by;
916
-        $current_value = ! empty($field) ? $this->get($field) : null;
917
-        if (empty($field) || empty($current_value)) {
918
-            return array();
919
-        }
920
-        return $this->get_model()->next_x($current_value, $field, $limit, $query_params, $columns_to_select);
921
-    }
922
-
923
-
924
-
925
-    /**
926
-     * Returns the previous x number of EE_Base_Class objects in sequence from this object as found in the database
927
-     * matching the given query conditions.
928
-     *
929
-     * @param null  $field_to_order_by  What field is being used as the reference point.
930
-     * @param int   $limit              How many objects to return.
931
-     * @param array $query_params       Any additional conditions on the query.
932
-     * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
933
-     *                                  you can indicate just the columns you want returned
934
-     * @return array|EE_Base_Class[]
935
-     * @throws \EE_Error
936
-     */
937
-    public function previous_x(
938
-        $field_to_order_by = null,
939
-        $limit = 1,
940
-        $query_params = array(),
941
-        $columns_to_select = null
942
-    ) {
943
-        $field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
944
-            ? $this->get_model()->get_primary_key_field()->get_name()
945
-            : $field_to_order_by;
946
-        $current_value = ! empty($field) ? $this->get($field) : null;
947
-        if (empty($field) || empty($current_value)) {
948
-            return array();
949
-        }
950
-        return $this->get_model()->previous_x($current_value, $field, $limit, $query_params, $columns_to_select);
951
-    }
952
-
953
-
954
-
955
-    /**
956
-     * Returns the next EE_Base_Class object in sequence from this object as found in the database
957
-     * matching the given query conditions.
958
-     *
959
-     * @param null  $field_to_order_by  What field is being used as the reference point.
960
-     * @param array $query_params       Any additional conditions on the query.
961
-     * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
962
-     *                                  you can indicate just the columns you want returned
963
-     * @return array|EE_Base_Class
964
-     * @throws \EE_Error
965
-     */
966
-    public function next($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
967
-    {
968
-        $field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
969
-            ? $this->get_model()->get_primary_key_field()->get_name()
970
-            : $field_to_order_by;
971
-        $current_value = ! empty($field) ? $this->get($field) : null;
972
-        if (empty($field) || empty($current_value)) {
973
-            return array();
974
-        }
975
-        return $this->get_model()->next($current_value, $field, $query_params, $columns_to_select);
976
-    }
977
-
978
-
979
-
980
-    /**
981
-     * Returns the previous EE_Base_Class object in sequence from this object as found in the database
982
-     * matching the given query conditions.
983
-     *
984
-     * @param null  $field_to_order_by  What field is being used as the reference point.
985
-     * @param array $query_params       Any additional conditions on the query.
986
-     * @param null  $columns_to_select  If left null, then an EE_Base_Class object is returned, otherwise
987
-     *                                  you can indicate just the column you want returned
988
-     * @return array|EE_Base_Class
989
-     * @throws \EE_Error
990
-     */
991
-    public function previous($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
992
-    {
993
-        $field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
994
-            ? $this->get_model()->get_primary_key_field()->get_name()
995
-            : $field_to_order_by;
996
-        $current_value = ! empty($field) ? $this->get($field) : null;
997
-        if (empty($field) || empty($current_value)) {
998
-            return array();
999
-        }
1000
-        return $this->get_model()->previous($current_value, $field, $query_params, $columns_to_select);
1001
-    }
1002
-
1003
-
1004
-
1005
-    /**
1006
-     * Overrides parent because parent expects old models.
1007
-     * This also doesn't do any validation, and won't work for serialized arrays
1008
-     *
1009
-     * @param string $field_name
1010
-     * @param mixed  $field_value_from_db
1011
-     * @throws \EE_Error
1012
-     */
1013
-    public function set_from_db($field_name, $field_value_from_db)
1014
-    {
1015
-        $field_obj = $this->get_model()->field_settings_for($field_name);
1016
-        if ($field_obj instanceof EE_Model_Field_Base) {
1017
-            //you would think the DB has no NULLs for non-null label fields right? wrong!
1018
-            //eg, a CPT model object could have an entry in the posts table, but no
1019
-            //entry in the meta table. Meaning that all its columns in the meta table
1020
-            //are null! yikes! so when we find one like that, use defaults for its meta columns
1021
-            if ($field_value_from_db === null) {
1022
-                if ($field_obj->is_nullable()) {
1023
-                    //if the field allows nulls, then let it be null
1024
-                    $field_value = null;
1025
-                } else {
1026
-                    $field_value = $field_obj->get_default_value();
1027
-                }
1028
-            } else {
1029
-                $field_value = $field_obj->prepare_for_set_from_db($field_value_from_db);
1030
-            }
1031
-            $this->_fields[$field_name] = $field_value;
1032
-            $this->_clear_cached_property($field_name);
1033
-        }
1034
-    }
1035
-
1036
-
1037
-
1038
-    /**
1039
-     * verifies that the specified field is of the correct type
1040
-     *
1041
-     * @param string $field_name
1042
-     * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1043
-     *                                (in cases where the same property may be used for different outputs
1044
-     *                                - i.e. datetime, money etc.)
1045
-     * @return mixed
1046
-     * @throws \EE_Error
1047
-     */
1048
-    public function get($field_name, $extra_cache_ref = null)
1049
-    {
1050
-        return $this->_get_cached_property($field_name, false, $extra_cache_ref);
1051
-    }
1052
-
1053
-
1054
-
1055
-    /**
1056
-     * This method simply returns the RAW unprocessed value for the given property in this class
1057
-     *
1058
-     * @param  string $field_name A valid fieldname
1059
-     * @return mixed              Whatever the raw value stored on the property is.
1060
-     * @throws EE_Error if fieldSettings is misconfigured or the field doesn't exist.
1061
-     */
1062
-    public function get_raw($field_name)
1063
-    {
1064
-        $field_settings = $this->get_model()->field_settings_for($field_name);
1065
-        return $field_settings instanceof EE_Datetime_Field && $this->_fields[$field_name] instanceof DateTime
1066
-            ? $this->_fields[$field_name]->format('U')
1067
-            : $this->_fields[$field_name];
1068
-    }
1069
-
1070
-
1071
-
1072
-    /**
1073
-     * This is used to return the internal DateTime object used for a field that is a
1074
-     * EE_Datetime_Field.
1075
-     *
1076
-     * @param string $field_name               The field name retrieving the DateTime object.
1077
-     * @return mixed null | false | DateTime  If the requested field is NOT a EE_Datetime_Field then
1078
-     * @throws \EE_Error
1079
-     *                                         an error is set and false returned.  If the field IS an
1080
-     *                                         EE_Datetime_Field and but the field value is null, then
1081
-     *                                         just null is returned (because that indicates that likely
1082
-     *                                         this field is nullable).
1083
-     */
1084
-    public function get_DateTime_object($field_name)
1085
-    {
1086
-        $field_settings = $this->get_model()->field_settings_for($field_name);
1087
-        if ( ! $field_settings instanceof EE_Datetime_Field) {
1088
-            EE_Error::add_error(
1089
-                sprintf(
1090
-                    __(
1091
-                        'The field %s is not an EE_Datetime_Field field.  There is no DateTime object stored on this field type.',
1092
-                        'event_espresso'
1093
-                    ),
1094
-                    $field_name
1095
-                ),
1096
-                __FILE__,
1097
-                __FUNCTION__,
1098
-                __LINE__
1099
-            );
1100
-            return false;
1101
-        }
1102
-        return $this->_fields[$field_name];
1103
-    }
1104
-
1105
-
1106
-
1107
-    /**
1108
-     * To be used in template to immediately echo out the value, and format it for output.
1109
-     * Eg, should call stripslashes and whatnot before echoing
1110
-     *
1111
-     * @param string $field_name      the name of the field as it appears in the DB
1112
-     * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1113
-     *                                (in cases where the same property may be used for different outputs
1114
-     *                                - i.e. datetime, money etc.)
1115
-     * @return void
1116
-     * @throws \EE_Error
1117
-     */
1118
-    public function e($field_name, $extra_cache_ref = null)
1119
-    {
1120
-        echo $this->get_pretty($field_name, $extra_cache_ref);
1121
-    }
1122
-
1123
-
1124
-
1125
-    /**
1126
-     * Exactly like e(), echoes out the field, but sets its schema to 'form_input', so that it
1127
-     * can be easily used as the value of form input.
1128
-     *
1129
-     * @param string $field_name
1130
-     * @return void
1131
-     * @throws \EE_Error
1132
-     */
1133
-    public function f($field_name)
1134
-    {
1135
-        $this->e($field_name, 'form_input');
1136
-    }
1137
-
1138
-
1139
-
1140
-    /**
1141
-     * Gets a pretty view of the field's value. $extra_cache_ref can specify different formats for this.
1142
-     * The $extra_cache_ref will be passed to the model field's prepare_for_pretty_echoing, so consult the field's class
1143
-     * to see what options are available.
1144
-     * @param string $field_name
1145
-     * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1146
-     *                                (in cases where the same property may be used for different outputs
1147
-     *                                - i.e. datetime, money etc.)
1148
-     * @return mixed
1149
-     * @throws \EE_Error
1150
-     */
1151
-    public function get_pretty($field_name, $extra_cache_ref = null)
1152
-    {
1153
-        return $this->_get_cached_property($field_name, true, $extra_cache_ref);
1154
-    }
1155
-
1156
-
1157
-
1158
-    /**
1159
-     * This simply returns the datetime for the given field name
1160
-     * Note: this protected function is called by the wrapper get_date or get_time or get_datetime functions
1161
-     * (and the equivalent e_date, e_time, e_datetime).
1162
-     *
1163
-     * @access   protected
1164
-     * @param string   $field_name   Field on the instantiated EE_Base_Class child object
1165
-     * @param string   $dt_frmt      valid datetime format used for date
1166
-     *                               (if '' then we just use the default on the field,
1167
-     *                               if NULL we use the last-used format)
1168
-     * @param string   $tm_frmt      Same as above except this is for time format
1169
-     * @param string   $date_or_time if NULL then both are returned, otherwise "D" = only date and "T" = only time.
1170
-     * @param  boolean $echo         Whether the dtt is echoing using pretty echoing or just returned using vanilla get
1171
-     * @return string|bool|EE_Error string on success, FALSE on fail, or EE_Error Exception is thrown
1172
-     *                               if field is not a valid dtt field, or void if echoing
1173
-     * @throws \EE_Error
1174
-     */
1175
-    protected function _get_datetime($field_name, $dt_frmt = '', $tm_frmt = '', $date_or_time = '', $echo = false)
1176
-    {
1177
-        // clear cached property
1178
-        $this->_clear_cached_property($field_name);
1179
-        //reset format properties because they are used in get()
1180
-        $this->_dt_frmt = $dt_frmt !== '' ? $dt_frmt : $this->_dt_frmt;
1181
-        $this->_tm_frmt = $tm_frmt !== '' ? $tm_frmt : $this->_tm_frmt;
1182
-        if ($echo) {
1183
-            $this->e($field_name, $date_or_time);
1184
-            return '';
1185
-        }
1186
-        return $this->get($field_name, $date_or_time);
1187
-    }
1188
-
1189
-
1190
-
1191
-    /**
1192
-     * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the date
1193
-     * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1194
-     * other echoes the pretty value for dtt)
1195
-     *
1196
-     * @param  string $field_name name of model object datetime field holding the value
1197
-     * @param  string $format     format for the date returned (if NULL we use default in dt_frmt property)
1198
-     * @return string            datetime value formatted
1199
-     * @throws \EE_Error
1200
-     */
1201
-    public function get_date($field_name, $format = '')
1202
-    {
1203
-        return $this->_get_datetime($field_name, $format, null, 'D');
1204
-    }
1205
-
1206
-
1207
-
1208
-    /**
1209
-     * @param      $field_name
1210
-     * @param string $format
1211
-     * @throws \EE_Error
1212
-     */
1213
-    public function e_date($field_name, $format = '')
1214
-    {
1215
-        $this->_get_datetime($field_name, $format, null, 'D', true);
1216
-    }
1217
-
1218
-
1219
-
1220
-    /**
1221
-     * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the time
1222
-     * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1223
-     * other echoes the pretty value for dtt)
1224
-     *
1225
-     * @param  string $field_name name of model object datetime field holding the value
1226
-     * @param  string $format     format for the time returned ( if NULL we use default in tm_frmt property)
1227
-     * @return string             datetime value formatted
1228
-     * @throws \EE_Error
1229
-     */
1230
-    public function get_time($field_name, $format = '')
1231
-    {
1232
-        return $this->_get_datetime($field_name, null, $format, 'T');
1233
-    }
1234
-
1235
-
1236
-
1237
-    /**
1238
-     * @param      $field_name
1239
-     * @param string $format
1240
-     * @throws \EE_Error
1241
-     */
1242
-    public function e_time($field_name, $format = '')
1243
-    {
1244
-        $this->_get_datetime($field_name, null, $format, 'T', true);
1245
-    }
1246
-
1247
-
1248
-
1249
-    /**
1250
-     * below are wrapper functions for the various datetime outputs that can be obtained for returning the date AND
1251
-     * time portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1252
-     * other echoes the pretty value for dtt)
1253
-     *
1254
-     * @param  string $field_name name of model object datetime field holding the value
1255
-     * @param  string $dt_frmt    format for the date returned (if NULL we use default in dt_frmt property)
1256
-     * @param  string $tm_frmt    format for the time returned (if NULL we use default in tm_frmt property)
1257
-     * @return string             datetime value formatted
1258
-     * @throws \EE_Error
1259
-     */
1260
-    public function get_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1261
-    {
1262
-        return $this->_get_datetime($field_name, $dt_frmt, $tm_frmt);
1263
-    }
1264
-
1265
-
1266
-
1267
-    /**
1268
-     * @param string $field_name
1269
-     * @param string $dt_frmt
1270
-     * @param string $tm_frmt
1271
-     * @throws \EE_Error
1272
-     */
1273
-    public function e_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1274
-    {
1275
-        $this->_get_datetime($field_name, $dt_frmt, $tm_frmt, null, true);
1276
-    }
1277
-
1278
-
1279
-
1280
-    /**
1281
-     * Get the i8ln value for a date using the WordPress @see date_i18n function.
1282
-     *
1283
-     * @param string $field_name The EE_Datetime_Field reference for the date being retrieved.
1284
-     * @param string $format     PHP valid date/time string format.  If none is provided then the internal set format
1285
-     *                           on the object will be used.
1286
-     * @return string Date and time string in set locale or false if no field exists for the given
1287
-     * @throws \EE_Error
1288
-     *                           field name.
1289
-     */
1290
-    public function get_i18n_datetime($field_name, $format = '')
1291
-    {
1292
-        $format = empty($format) ? $this->_dt_frmt . ' ' . $this->_tm_frmt : $format;
1293
-        return date_i18n(
1294
-            $format,
1295
-            EEH_DTT_Helper::get_timestamp_with_offset($this->get_raw($field_name), $this->_timezone)
1296
-        );
1297
-    }
1298
-
1299
-
1300
-
1301
-    /**
1302
-     * This method validates whether the given field name is a valid field on the model object as well as it is of a
1303
-     * type EE_Datetime_Field.  On success there will be returned the field settings.  On fail an EE_Error exception is
1304
-     * thrown.
1305
-     *
1306
-     * @param  string $field_name The field name being checked
1307
-     * @throws EE_Error
1308
-     * @return EE_Datetime_Field
1309
-     */
1310
-    protected function _get_dtt_field_settings($field_name)
1311
-    {
1312
-        $field = $this->get_model()->field_settings_for($field_name);
1313
-        //check if field is dtt
1314
-        if ($field instanceof EE_Datetime_Field) {
1315
-            return $field;
1316
-        } else {
1317
-            throw new EE_Error(sprintf(__('The field name "%s" has been requested for the EE_Base_Class datetime functions and it is not a valid EE_Datetime_Field.  Please check the spelling of the field and make sure it has been setup as a EE_Datetime_Field in the %s model constructor',
1318
-                'event_espresso'), $field_name, self::_get_model_classname(get_class($this))));
1319
-        }
1320
-    }
1321
-
1322
-
1323
-
1324
-
1325
-    /**
1326
-     * NOTE ABOUT BELOW:
1327
-     * These convenience date and time setters are for setting date and time independently.  In other words you might
1328
-     * want to change the time on a datetime_field but leave the date the same (or vice versa). IF on the other hand
1329
-     * you want to set both date and time at the same time, you can just use the models default set($fieldname,$value)
1330
-     * method and make sure you send the entire datetime value for setting.
1331
-     */
1332
-    /**
1333
-     * sets the time on a datetime property
1334
-     *
1335
-     * @access protected
1336
-     * @param string|Datetime $time      a valid time string for php datetime functions (or DateTime object)
1337
-     * @param string          $fieldname the name of the field the time is being set on (must match a EE_Datetime_Field)
1338
-     * @throws \EE_Error
1339
-     */
1340
-    protected function _set_time_for($time, $fieldname)
1341
-    {
1342
-        $this->_set_date_time('T', $time, $fieldname);
1343
-    }
1344
-
1345
-
1346
-
1347
-    /**
1348
-     * sets the date on a datetime property
1349
-     *
1350
-     * @access protected
1351
-     * @param string|DateTime $date      a valid date string for php datetime functions ( or DateTime object)
1352
-     * @param string          $fieldname the name of the field the date is being set on (must match a EE_Datetime_Field)
1353
-     * @throws \EE_Error
1354
-     */
1355
-    protected function _set_date_for($date, $fieldname)
1356
-    {
1357
-        $this->_set_date_time('D', $date, $fieldname);
1358
-    }
1359
-
1360
-
1361
-
1362
-    /**
1363
-     * This takes care of setting a date or time independently on a given model object property. This method also
1364
-     * verifies that the given fieldname matches a model object property and is for a EE_Datetime_Field field
1365
-     *
1366
-     * @access protected
1367
-     * @param string          $what           "T" for time, 'B' for both, 'D' for Date.
1368
-     * @param string|DateTime $datetime_value A valid Date or Time string (or DateTime object)
1369
-     * @param string          $fieldname      the name of the field the date OR time is being set on (must match a
1370
-     *                                        EE_Datetime_Field property)
1371
-     * @throws \EE_Error
1372
-     */
1373
-    protected function _set_date_time($what = 'T', $datetime_value, $fieldname)
1374
-    {
1375
-        $field = $this->_get_dtt_field_settings($fieldname);
1376
-        $field->set_timezone($this->_timezone);
1377
-        $field->set_date_format($this->_dt_frmt);
1378
-        $field->set_time_format($this->_tm_frmt);
1379
-        switch ($what) {
1380
-            case 'T' :
1381
-                $this->_fields[$fieldname] = $field->prepare_for_set_with_new_time(
1382
-                    $datetime_value,
1383
-                    $this->_fields[$fieldname]
1384
-                );
1385
-                break;
1386
-            case 'D' :
1387
-                $this->_fields[$fieldname] = $field->prepare_for_set_with_new_date(
1388
-                    $datetime_value,
1389
-                    $this->_fields[$fieldname]
1390
-                );
1391
-                break;
1392
-            case 'B' :
1393
-                $this->_fields[$fieldname] = $field->prepare_for_set($datetime_value);
1394
-                break;
1395
-        }
1396
-        $this->_clear_cached_property($fieldname);
1397
-    }
1398
-
1399
-
1400
-
1401
-    /**
1402
-     * This will return a timestamp for the website timezone but ONLY when the current website timezone is different
1403
-     * than the timezone set for the website. NOTE, this currently only works well with methods that return values.  If
1404
-     * you use it with methods that echo values the $_timestamp property may not get reset to its original value and
1405
-     * that could lead to some unexpected results!
1406
-     *
1407
-     * @access public
1408
-     * @param string               $field_name This is the name of the field on the object that contains the date/time
1409
-     *                                         value being returned.
1410
-     * @param string               $callback   must match a valid method in this class (defaults to get_datetime)
1411
-     * @param mixed (array|string) $args       This is the arguments that will be passed to the callback.
1412
-     * @param string               $prepend    You can include something to prepend on the timestamp
1413
-     * @param string               $append     You can include something to append on the timestamp
1414
-     * @throws EE_Error
1415
-     * @return string timestamp
1416
-     */
1417
-    public function display_in_my_timezone(
1418
-        $field_name,
1419
-        $callback = 'get_datetime',
1420
-        $args = null,
1421
-        $prepend = '',
1422
-        $append = ''
1423
-    ) {
1424
-        $timezone = EEH_DTT_Helper::get_timezone();
1425
-        if ($timezone === $this->_timezone) {
1426
-            return '';
1427
-        }
1428
-        $original_timezone = $this->_timezone;
1429
-        $this->set_timezone($timezone);
1430
-        $fn = (array)$field_name;
1431
-        $args = array_merge($fn, (array)$args);
1432
-        if ( ! method_exists($this, $callback)) {
1433
-            throw new EE_Error(
1434
-                sprintf(
1435
-                    __(
1436
-                        'The method named "%s" given as the callback param in "display_in_my_timezone" does not exist.  Please check your spelling',
1437
-                        'event_espresso'
1438
-                    ),
1439
-                    $callback
1440
-                )
1441
-            );
1442
-        }
1443
-        $args = (array)$args;
1444
-        $return = $prepend . call_user_func_array(array($this, $callback), $args) . $append;
1445
-        $this->set_timezone($original_timezone);
1446
-        return $return;
1447
-    }
1448
-
1449
-
1450
-
1451
-    /**
1452
-     * Deletes this model object.
1453
-     * This calls the `EE_Base_Class::_delete` method.  Child classes wishing to change default behaviour should
1454
-     * override
1455
-     * `EE_Base_Class::_delete` NOT this class.
1456
-     *
1457
-     * @return boolean | int
1458
-     * @throws \EE_Error
1459
-     */
1460
-    public function delete()
1461
-    {
1462
-        /**
1463
-         * Called just before the `EE_Base_Class::_delete` method call.
1464
-         * Note: `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1465
-         * should be aware that `_delete` may not always result in a permanent delete.  For example, `EE_Soft_Delete_Base_Class::_delete`
1466
-         * soft deletes (trash) the object and does not permanently delete it.
1467
-         *
1468
-         * @param EE_Base_Class $model_object about to be 'deleted'
1469
-         */
1470
-        do_action('AHEE__EE_Base_Class__delete__before', $this);
1471
-        $result = $this->_delete();
1472
-        /**
1473
-         * Called just after the `EE_Base_Class::_delete` method call.
1474
-         * Note: `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1475
-         * should be aware that `_delete` may not always result in a permanent delete.  For example `EE_Soft_Base_Class::_delete`
1476
-         * soft deletes (trash) the object and does not permanently delete it.
1477
-         *
1478
-         * @param EE_Base_Class $model_object that was just 'deleted'
1479
-         * @param boolean       $result
1480
-         */
1481
-        do_action('AHEE__EE_Base_Class__delete__end', $this, $result);
1482
-        return $result;
1483
-    }
1484
-
1485
-
1486
-
1487
-    /**
1488
-     * Calls the specific delete method for the instantiated class.
1489
-     * This method is called by the public `EE_Base_Class::delete` method.  Any child classes desiring to override
1490
-     * default functionality for "delete" (which is to call `permanently_delete`) should override this method NOT
1491
-     * `EE_Base_Class::delete`
1492
-     *
1493
-     * @return bool|int
1494
-     * @throws \EE_Error
1495
-     */
1496
-    protected function _delete()
1497
-    {
1498
-        return $this->delete_permanently();
1499
-    }
1500
-
1501
-
1502
-
1503
-    /**
1504
-     * Deletes this model object permanently from db (but keep in mind related models my block the delete and return an
1505
-     * error)
1506
-     *
1507
-     * @return bool | int
1508
-     * @throws \EE_Error
1509
-     */
1510
-    public function delete_permanently()
1511
-    {
1512
-        /**
1513
-         * Called just before HARD deleting a model object
1514
-         *
1515
-         * @param EE_Base_Class $model_object about to be 'deleted'
1516
-         */
1517
-        do_action('AHEE__EE_Base_Class__delete_permanently__before', $this);
1518
-        $model = $this->get_model();
1519
-        $result = $model->delete_permanently_by_ID($this->ID());
1520
-        $this->refresh_cache_of_related_objects();
1521
-        /**
1522
-         * Called just after HARD deleting a model object
1523
-         *
1524
-         * @param EE_Base_Class $model_object that was just 'deleted'
1525
-         * @param boolean       $result
1526
-         */
1527
-        do_action('AHEE__EE_Base_Class__delete_permanently__end', $this, $result);
1528
-        return $result;
1529
-    }
1530
-
1531
-
1532
-
1533
-    /**
1534
-     * When this model object is deleted, it may still be cached on related model objects. This clears the cache of
1535
-     * related model objects
1536
-     *
1537
-     * @throws \EE_Error
1538
-     */
1539
-    public function refresh_cache_of_related_objects()
1540
-    {
1541
-        foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
1542
-            if ( ! empty($this->_model_relations[$relation_name])) {
1543
-                $related_objects = $this->_model_relations[$relation_name];
1544
-                if ($relation_obj instanceof EE_Belongs_To_Relation) {
1545
-                    //this relation only stores a single model object, not an array
1546
-                    //but let's make it consistent
1547
-                    $related_objects = array($related_objects);
1548
-                }
1549
-                foreach ($related_objects as $related_object) {
1550
-                    //only refresh their cache if they're in memory
1551
-                    if ($related_object instanceof EE_Base_Class) {
1552
-                        $related_object->clear_cache($this->get_model()->get_this_model_name(), $this);
1553
-                    }
1554
-                }
1555
-            }
1556
-        }
1557
-    }
1558
-
1559
-
1560
-
1561
-    /**
1562
-     *        Saves this object to the database. An array may be supplied to set some values on this
1563
-     * object just before saving.
1564
-     *
1565
-     * @access public
1566
-     * @param array $set_cols_n_values keys are field names, values are their new values,
1567
-     *                                 if provided during the save() method (often client code will change the fields'
1568
-     *                                 values before calling save)
1569
-     * @throws \EE_Error
1570
-     * @return int , 1 on a successful update, the ID of the new entry on insert; 0 on failure or if the model object
1571
-     *                                 isn't allowed to persist (as determined by EE_Base_Class::allow_persist())
1572
-     */
1573
-    public function save($set_cols_n_values = array())
1574
-    {
1575
-        /**
1576
-         * Filters the fields we're about to save on the model object
1577
-         *
1578
-         * @param array         $set_cols_n_values
1579
-         * @param EE_Base_Class $model_object
1580
-         */
1581
-        $set_cols_n_values = (array)apply_filters('FHEE__EE_Base_Class__save__set_cols_n_values', $set_cols_n_values,
1582
-            $this);
1583
-        //set attributes as provided in $set_cols_n_values
1584
-        foreach ($set_cols_n_values as $column => $value) {
1585
-            $this->set($column, $value);
1586
-        }
1587
-        // no changes ? then don't do anything
1588
-        if (! $this->_has_changes && $this->ID() && $this->get_model()->get_primary_key_field()->is_auto_increment()) {
1589
-            return 0;
1590
-        }
1591
-        /**
1592
-         * Saving a model object.
1593
-         * Before we perform a save, this action is fired.
1594
-         *
1595
-         * @param EE_Base_Class $model_object the model object about to be saved.
1596
-         */
1597
-        do_action('AHEE__EE_Base_Class__save__begin', $this);
1598
-        if ( ! $this->allow_persist()) {
1599
-            return 0;
1600
-        }
1601
-        //now get current attribute values
1602
-        $save_cols_n_values = $this->_fields;
1603
-        //if the object already has an ID, update it. Otherwise, insert it
1604
-        //also: change the assumption about values passed to the model NOT being prepare dby the model object. They have been
1605
-        $old_assumption_concerning_value_preparation = $this->get_model()
1606
-                                                            ->get_assumption_concerning_values_already_prepared_by_model_object();
1607
-        $this->get_model()->assume_values_already_prepared_by_model_object(true);
1608
-        //does this model have an autoincrement PK?
1609
-        if ($this->get_model()->has_primary_key_field()) {
1610
-            if ($this->get_model()->get_primary_key_field()->is_auto_increment()) {
1611
-                //ok check if it's set, if so: update; if not, insert
1612
-                if ( ! empty($save_cols_n_values[self::_get_primary_key_name(get_class($this))])) {
1613
-                    $results = $this->get_model()->update_by_ID($save_cols_n_values, $this->ID());
1614
-                } else {
1615
-                    unset($save_cols_n_values[self::_get_primary_key_name(get_class($this))]);
1616
-                    $results = $this->get_model()->insert($save_cols_n_values);
1617
-                    if ($results) {
1618
-                        //if successful, set the primary key
1619
-                        //but don't use the normal SET method, because it will check if
1620
-                        //an item with the same ID exists in the mapper & db, then
1621
-                        //will find it in the db (because we just added it) and THAT object
1622
-                        //will get added to the mapper before we can add this one!
1623
-                        //but if we just avoid using the SET method, all that headache can be avoided
1624
-                        $pk_field_name = self::_get_primary_key_name(get_class($this));
1625
-                        $this->_fields[$pk_field_name] = $results;
1626
-                        $this->_clear_cached_property($pk_field_name);
1627
-                        $this->get_model()->add_to_entity_map($this);
1628
-                        $this->_update_cached_related_model_objs_fks();
1629
-                    }
1630
-                }
1631
-            } else {//PK is NOT auto-increment
1632
-                //so check if one like it already exists in the db
1633
-                if ($this->get_model()->exists_by_ID($this->ID())) {
1634
-                    if (WP_DEBUG && ! $this->in_entity_map()) {
1635
-                        throw new EE_Error(
1636
-                            sprintf(
1637
-                                __('Using a model object %1$s that is NOT in the entity map, can lead to unexpected errors. You should either: %4$s 1. Put it in the entity mapper by calling %2$s %4$s 2. Discard this model object and use what is in the entity mapper %4$s 3. Fetch from the database using %3$s',
1638
-                                    'event_espresso'),
1639
-                                get_class($this),
1640
-                                get_class($this->get_model()) . '::instance()->add_to_entity_map()',
1641
-                                get_class($this->get_model()) . '::instance()->get_one_by_ID()',
1642
-                                '<br />'
1643
-                            )
1644
-                        );
1645
-                    }
1646
-                    $results = $this->get_model()->update_by_ID($save_cols_n_values, $this->ID());
1647
-                } else {
1648
-                    $results = $this->get_model()->insert($save_cols_n_values);
1649
-                    $this->_update_cached_related_model_objs_fks();
1650
-                }
1651
-            }
1652
-        } else {//there is NO primary key
1653
-            $already_in_db = false;
1654
-            foreach ($this->get_model()->unique_indexes() as $index) {
1655
-                $uniqueness_where_params = array_intersect_key($save_cols_n_values, $index->fields());
1656
-                if ($this->get_model()->exists(array($uniqueness_where_params))) {
1657
-                    $already_in_db = true;
1658
-                }
1659
-            }
1660
-            if ($already_in_db) {
1661
-                $combined_pk_fields_n_values = array_intersect_key($save_cols_n_values,
1662
-                    $this->get_model()->get_combined_primary_key_fields());
1663
-                $results = $this->get_model()->update($save_cols_n_values, $combined_pk_fields_n_values);
1664
-            } else {
1665
-                $results = $this->get_model()->insert($save_cols_n_values);
1666
-            }
1667
-        }
1668
-        //restore the old assumption about values being prepared by the model object
1669
-        $this->get_model()
1670
-             ->assume_values_already_prepared_by_model_object($old_assumption_concerning_value_preparation);
1671
-        /**
1672
-         * After saving the model object this action is called
1673
-         *
1674
-         * @param EE_Base_Class $model_object which was just saved
1675
-         * @param boolean|int   $results      if it were updated, TRUE or FALSE; if it were newly inserted
1676
-         *                                    the new ID (or 0 if an error occurred and it wasn't updated)
1677
-         */
1678
-        do_action('AHEE__EE_Base_Class__save__end', $this, $results);
1679
-        $this->_has_changes = false;
1680
-        return $results;
1681
-    }
1682
-
1683
-
1684
-
1685
-    /**
1686
-     * Updates the foreign key on related models objects pointing to this to have this model object's ID
1687
-     * as their foreign key.  If the cached related model objects already exist in the db, saves them (so that the DB
1688
-     * is consistent) Especially useful in case we JUST added this model object ot the database and we want to let its
1689
-     * cached relations with foreign keys to it know about that change. Eg: we've created a transaction but haven't
1690
-     * saved it to the db. We also create a registration and don't save it to the DB, but we DO cache it on the
1691
-     * transaction. Now, when we save the transaction, the registration's TXN_ID will be automatically updated, whether
1692
-     * or not they exist in the DB (if they do, their DB records will be automatically updated)
1693
-     *
1694
-     * @return void
1695
-     * @throws \EE_Error
1696
-     */
1697
-    protected function _update_cached_related_model_objs_fks()
1698
-    {
1699
-        foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
1700
-            if ($relation_obj instanceof EE_Has_Many_Relation) {
1701
-                foreach ($this->get_all_from_cache($relation_name) as $related_model_obj_in_cache) {
1702
-                    $fk_to_this = $related_model_obj_in_cache->get_model()->get_foreign_key_to(
1703
-                        $this->get_model()->get_this_model_name()
1704
-                    );
1705
-                    $related_model_obj_in_cache->set($fk_to_this->get_name(), $this->ID());
1706
-                    if ($related_model_obj_in_cache->ID()) {
1707
-                        $related_model_obj_in_cache->save();
1708
-                    }
1709
-                }
1710
-            }
1711
-        }
1712
-    }
1713
-
1714
-
1715
-
1716
-    /**
1717
-     * Saves this model object and its NEW cached relations to the database.
1718
-     * (Meaning, for now, IT DOES NOT WORK if the cached items already exist in the DB.
1719
-     * In order for that to work, we would need to mark model objects as dirty/clean...
1720
-     * because otherwise, there's a potential for infinite looping of saving
1721
-     * Saves the cached related model objects, and ensures the relation between them
1722
-     * and this object and properly setup
1723
-     *
1724
-     * @return int ID of new model object on save; 0 on failure+
1725
-     * @throws \EE_Error
1726
-     */
1727
-    public function save_new_cached_related_model_objs()
1728
-    {
1729
-        //make sure this has been saved
1730
-        if ( ! $this->ID()) {
1731
-            $id = $this->save();
1732
-        } else {
1733
-            $id = $this->ID();
1734
-        }
1735
-        //now save all the NEW cached model objects  (ie they don't exist in the DB)
1736
-        foreach ($this->get_model()->relation_settings() as $relationName => $relationObj) {
1737
-            if ($this->_model_relations[$relationName]) {
1738
-                //is this a relation where we should expect just ONE related object (ie, EE_Belongs_To_relation)
1739
-                //or MANY related objects (ie, EE_HABTM_Relation or EE_Has_Many_Relation)?
1740
-                if ($relationObj instanceof EE_Belongs_To_Relation) {
1741
-                    //add a relation to that relation type (which saves the appropriate thing in the process)
1742
-                    //but ONLY if it DOES NOT exist in the DB
1743
-                    /* @var $related_model_obj EE_Base_Class */
1744
-                    $related_model_obj = $this->_model_relations[$relationName];
1745
-                    //					if( ! $related_model_obj->ID()){
1746
-                    $this->_add_relation_to($related_model_obj, $relationName);
1747
-                    $related_model_obj->save_new_cached_related_model_objs();
1748
-                    //					}
1749
-                } else {
1750
-                    foreach ($this->_model_relations[$relationName] as $related_model_obj) {
1751
-                        //add a relation to that relation type (which saves the appropriate thing in the process)
1752
-                        //but ONLY if it DOES NOT exist in the DB
1753
-                        //						if( ! $related_model_obj->ID()){
1754
-                        $this->_add_relation_to($related_model_obj, $relationName);
1755
-                        $related_model_obj->save_new_cached_related_model_objs();
1756
-                        //						}
1757
-                    }
1758
-                }
1759
-            }
1760
-        }
1761
-        return $id;
1762
-    }
1763
-
1764
-
1765
-
1766
-    /**
1767
-     * for getting a model while instantiated.
1768
-     *
1769
-     * @return \EEM_Base | \EEM_CPT_Base
1770
-     */
1771
-    public function get_model()
1772
-    {
1773
-        $modelName = self::_get_model_classname(get_class($this));
1774
-        return self::_get_model_instance_with_name($modelName, $this->_timezone);
1775
-    }
1776
-
1777
-
1778
-
1779
-    /**
1780
-     * @param $props_n_values
1781
-     * @param $classname
1782
-     * @return mixed bool|EE_Base_Class|EEM_CPT_Base
1783
-     * @throws \EE_Error
1784
-     */
1785
-    protected static function _get_object_from_entity_mapper($props_n_values, $classname)
1786
-    {
1787
-        //TODO: will not work for Term_Relationships because they have no PK!
1788
-        $primary_id_ref = self::_get_primary_key_name($classname);
1789
-        if (array_key_exists($primary_id_ref, $props_n_values) && ! empty($props_n_values[$primary_id_ref])) {
1790
-            $id = $props_n_values[$primary_id_ref];
1791
-            return self::_get_model($classname)->get_from_entity_map($id);
1792
-        }
1793
-        return false;
1794
-    }
1795
-
1796
-
1797
-
1798
-    /**
1799
-     * This is called by child static "new_instance" method and we'll check to see if there is an existing db entry for
1800
-     * the primary key (if present in incoming values). If there is a key in the incoming array that matches the
1801
-     * primary key for the model AND it is not null, then we check the db. If there's a an object we return it.  If not
1802
-     * we return false.
1803
-     *
1804
-     * @param  array  $props_n_values   incoming array of properties and their values
1805
-     * @param  string $classname        the classname of the child class
1806
-     * @param null    $timezone
1807
-     * @param array   $date_formats     incoming date_formats in an array where the first value is the
1808
-     *                                  date_format and the second value is the time format
1809
-     * @return mixed (EE_Base_Class|bool)
1810
-     * @throws \EE_Error
1811
-     */
1812
-    protected static function _check_for_object($props_n_values, $classname, $timezone = null, $date_formats = array())
1813
-    {
1814
-        $existing = null;
1815
-        if (self::_get_model($classname)->has_primary_key_field()) {
1816
-            $primary_id_ref = self::_get_primary_key_name($classname);
1817
-            if (array_key_exists($primary_id_ref, $props_n_values)
1818
-                && ! empty($props_n_values[$primary_id_ref])
1819
-            ) {
1820
-                $existing = self::_get_model($classname, $timezone)->get_one_by_ID(
1821
-                    $props_n_values[$primary_id_ref]
1822
-                );
1823
-            }
1824
-        } elseif (self::_get_model($classname, $timezone)->has_all_combined_primary_key_fields($props_n_values)) {
1825
-            //no primary key on this model, but there's still a matching item in the DB
1826
-            $existing = self::_get_model($classname, $timezone)->get_one_by_ID(
1827
-                self::_get_model($classname, $timezone)->get_index_primary_key_string($props_n_values)
1828
-            );
1829
-        }
1830
-        if ($existing) {
1831
-            //set date formats if present before setting values
1832
-            if ( ! empty($date_formats) && is_array($date_formats)) {
1833
-                $existing->set_date_format($date_formats[0]);
1834
-                $existing->set_time_format($date_formats[1]);
1835
-            } else {
1836
-                //set default formats for date and time
1837
-                $existing->set_date_format(get_option('date_format'));
1838
-                $existing->set_time_format(get_option('time_format'));
1839
-            }
1840
-            foreach ($props_n_values as $property => $field_value) {
1841
-                $existing->set($property, $field_value);
1842
-            }
1843
-            return $existing;
1844
-        } else {
1845
-            return false;
1846
-        }
1847
-    }
1848
-
1849
-
1850
-
1851
-    /**
1852
-     * Gets the EEM_*_Model for this class
1853
-     *
1854
-     * @access public now, as this is more convenient
1855
-     * @param      $classname
1856
-     * @param null $timezone
1857
-     * @throws EE_Error
1858
-     * @return EEM_Base
1859
-     */
1860
-    protected static function _get_model($classname, $timezone = null)
1861
-    {
1862
-        //find model for this class
1863
-        if ( ! $classname) {
1864
-            throw new EE_Error(
1865
-                sprintf(
1866
-                    __(
1867
-                        "What were you thinking calling _get_model(%s)?? You need to specify the class name",
1868
-                        "event_espresso"
1869
-                    ),
1870
-                    $classname
1871
-                )
1872
-            );
1873
-        }
1874
-        $modelName = self::_get_model_classname($classname);
1875
-        return self::_get_model_instance_with_name($modelName, $timezone);
1876
-    }
1877
-
1878
-
1879
-
1880
-    /**
1881
-     * Gets the model instance (eg instance of EEM_Attendee) given its classname (eg EE_Attendee)
1882
-     *
1883
-     * @param string $model_classname
1884
-     * @param null   $timezone
1885
-     * @return EEM_Base
1886
-     */
1887
-    protected static function _get_model_instance_with_name($model_classname, $timezone = null)
1888
-    {
1889
-        $model_classname = str_replace('EEM_', '', $model_classname);
1890
-        $model = EE_Registry::instance()->load_model($model_classname);
1891
-        $model->set_timezone($timezone);
1892
-        return $model;
1893
-    }
1894
-
1895
-
1896
-
1897
-    /**
1898
-     * If a model name is provided (eg Registration), gets the model classname for that model.
1899
-     * Also works if a model class's classname is provided (eg EE_Registration).
1900
-     *
1901
-     * @param null $model_name
1902
-     * @return string like EEM_Attendee
1903
-     */
1904
-    private static function _get_model_classname($model_name = null)
1905
-    {
1906
-        if (strpos($model_name, "EE_") === 0) {
1907
-            $model_classname = str_replace("EE_", "EEM_", $model_name);
1908
-        } else {
1909
-            $model_classname = "EEM_" . $model_name;
1910
-        }
1911
-        return $model_classname;
1912
-    }
1913
-
1914
-
1915
-
1916
-    /**
1917
-     * returns the name of the primary key attribute
1918
-     *
1919
-     * @param null $classname
1920
-     * @throws EE_Error
1921
-     * @return string
1922
-     */
1923
-    protected static function _get_primary_key_name($classname = null)
1924
-    {
1925
-        if ( ! $classname) {
1926
-            throw new EE_Error(
1927
-                sprintf(
1928
-                    __("What were you thinking calling _get_primary_key_name(%s)", "event_espresso"),
1929
-                    $classname
1930
-                )
1931
-            );
1932
-        }
1933
-        return self::_get_model($classname)->get_primary_key_field()->get_name();
1934
-    }
1935
-
1936
-
1937
-
1938
-    /**
1939
-     * Gets the value of the primary key.
1940
-     * If the object hasn't yet been saved, it should be whatever the model field's default was
1941
-     * (eg, if this were the EE_Event class, look at the primary key field on EEM_Event and see what its default value
1942
-     * is. Usually defaults for integer primary keys are 0; string primary keys are usually NULL).
1943
-     *
1944
-     * @return mixed, if the primary key is of type INT it'll be an int. Otherwise it could be a string
1945
-     * @throws \EE_Error
1946
-     */
1947
-    public function ID()
1948
-    {
1949
-        //now that we know the name of the variable, use a variable variable to get its value and return its
1950
-        if ($this->get_model()->has_primary_key_field()) {
1951
-            return $this->_fields[self::_get_primary_key_name(get_class($this))];
1952
-        } else {
1953
-            return $this->get_model()->get_index_primary_key_string($this->_fields);
1954
-        }
1955
-    }
1956
-
1957
-
1958
-
1959
-    /**
1960
-     * Adds a relationship to the specified EE_Base_Class object, given the relationship's name. Eg, if the current
1961
-     * model is related to a group of events, the $relationName should be 'Event', and should be a key in the EE
1962
-     * Model's $_model_relations array. If this model object doesn't exist in the DB, just caches the related thing
1963
-     *
1964
-     * @param mixed  $otherObjectModelObjectOrID       EE_Base_Class or the ID of the other object
1965
-     * @param string $relationName                     eg 'Events','Question',etc.
1966
-     *                                                 an attendee to a group, you also want to specify which role they
1967
-     *                                                 will have in that group. So you would use this parameter to
1968
-     *                                                 specify array('role-column-name'=>'role-id')
1969
-     * @param array  $extra_join_model_fields_n_values You can optionally include an array of key=>value pairs that
1970
-     *                                                 allow you to further constrict the relation to being added.
1971
-     *                                                 However, keep in mind that the columns (keys) given must match a
1972
-     *                                                 column on the JOIN table and currently only the HABTM models
1973
-     *                                                 accept these additional conditions.  Also remember that if an
1974
-     *                                                 exact match isn't found for these extra cols/val pairs, then a
1975
-     *                                                 NEW row is created in the join table.
1976
-     * @param null   $cache_id
1977
-     * @throws EE_Error
1978
-     * @return EE_Base_Class the object the relation was added to
1979
-     */
1980
-    public function _add_relation_to(
1981
-        $otherObjectModelObjectOrID,
1982
-        $relationName,
1983
-        $extra_join_model_fields_n_values = array(),
1984
-        $cache_id = null
1985
-    ) {
1986
-        //if this thing exists in the DB, save the relation to the DB
1987
-        if ($this->ID()) {
1988
-            $otherObject = $this->get_model()
1989
-                                ->add_relationship_to($this, $otherObjectModelObjectOrID, $relationName,
1990
-                                    $extra_join_model_fields_n_values);
1991
-            //clear cache so future get_many_related and get_first_related() return new results.
1992
-            $this->clear_cache($relationName, $otherObject, true);
1993
-            if ($otherObject instanceof EE_Base_Class) {
1994
-                $otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
1995
-            }
1996
-        } else {
1997
-            //this thing doesn't exist in the DB,  so just cache it
1998
-            if ( ! $otherObjectModelObjectOrID instanceof EE_Base_Class) {
1999
-                throw new EE_Error(sprintf(
2000
-                    __('Before a model object is saved to the database, calls to _add_relation_to must be passed an actual object, not just an ID. You provided %s as the model object to a %s',
2001
-                        'event_espresso'),
2002
-                    $otherObjectModelObjectOrID,
2003
-                    get_class($this)
2004
-                ));
2005
-            } else {
2006
-                $otherObject = $otherObjectModelObjectOrID;
2007
-            }
2008
-            $this->cache($relationName, $otherObjectModelObjectOrID, $cache_id);
2009
-        }
2010
-        if ($otherObject instanceof EE_Base_Class) {
2011
-            //fix the reciprocal relation too
2012
-            if ($otherObject->ID()) {
2013
-                //its saved so assumed relations exist in the DB, so we can just
2014
-                //clear the cache so future queries use the updated info in the DB
2015
-                $otherObject->clear_cache($this->get_model()->get_this_model_name(), null, true);
2016
-            } else {
2017
-                //it's not saved, so it caches relations like this
2018
-                $otherObject->cache($this->get_model()->get_this_model_name(), $this);
2019
-            }
2020
-        }
2021
-        return $otherObject;
2022
-    }
2023
-
2024
-
2025
-
2026
-    /**
2027
-     * Removes a relationship to the specified EE_Base_Class object, given the relationships' name. Eg, if the current
2028
-     * model is related to a group of events, the $relationName should be 'Events', and should be a key in the EE
2029
-     * Model's $_model_relations array. If this model object doesn't exist in the DB, just removes the related thing
2030
-     * from the cache
2031
-     *
2032
-     * @param mixed  $otherObjectModelObjectOrID
2033
-     *                EE_Base_Class or the ID of the other object, OR an array key into the cache if this isn't saved
2034
-     *                to the DB yet
2035
-     * @param string $relationName
2036
-     * @param array  $where_query
2037
-     *                You can optionally include an array of key=>value pairs that allow you to further constrict the
2038
-     *                relation to being added. However, keep in mind that the columns (keys) given must match a column
2039
-     *                on the JOIN table and currently only the HABTM models accept these additional conditions. Also
2040
-     *                remember that if an exact match isn't found for these extra cols/val pairs, then a NEW row is
2041
-     *                created in the join table.
2042
-     * @return EE_Base_Class the relation was removed from
2043
-     * @throws \EE_Error
2044
-     */
2045
-    public function _remove_relation_to($otherObjectModelObjectOrID, $relationName, $where_query = array())
2046
-    {
2047
-        if ($this->ID()) {
2048
-            //if this exists in the DB, save the relation change to the DB too
2049
-            $otherObject = $this->get_model()
2050
-                                ->remove_relationship_to($this, $otherObjectModelObjectOrID, $relationName,
2051
-                                    $where_query);
2052
-            $this->clear_cache($relationName, $otherObject);
2053
-        } else {
2054
-            //this doesn't exist in the DB, just remove it from the cache
2055
-            $otherObject = $this->clear_cache($relationName, $otherObjectModelObjectOrID);
2056
-        }
2057
-        if ($otherObject instanceof EE_Base_Class) {
2058
-            $otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
2059
-        }
2060
-        return $otherObject;
2061
-    }
2062
-
2063
-
2064
-
2065
-    /**
2066
-     * Removes ALL the related things for the $relationName.
2067
-     *
2068
-     * @param string $relationName
2069
-     * @param array  $where_query_params like EEM_Base::get_all's $query_params[0] (where conditions)
2070
-     * @return EE_Base_Class
2071
-     * @throws \EE_Error
2072
-     */
2073
-    public function _remove_relations($relationName, $where_query_params = array())
2074
-    {
2075
-        if ($this->ID()) {
2076
-            //if this exists in the DB, save the relation change to the DB too
2077
-            $otherObjects = $this->get_model()->remove_relations($this, $relationName, $where_query_params);
2078
-            $this->clear_cache($relationName, null, true);
2079
-        } else {
2080
-            //this doesn't exist in the DB, just remove it from the cache
2081
-            $otherObjects = $this->clear_cache($relationName, null, true);
2082
-        }
2083
-        if (is_array($otherObjects)) {
2084
-            foreach ($otherObjects as $otherObject) {
2085
-                $otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
2086
-            }
2087
-        }
2088
-        return $otherObjects;
2089
-    }
2090
-
2091
-
2092
-
2093
-    /**
2094
-     * Gets all the related model objects of the specified type. Eg, if the current class if
2095
-     * EE_Event, you could call $this->get_many_related('Registration') to get an array of all the
2096
-     * EE_Registration objects which related to this event. Note: by default, we remove the "default query params"
2097
-     * because we want to get even deleted items etc.
2098
-     *
2099
-     * @param string $relationName key in the model's _model_relations array
2100
-     * @param array  $query_params like EEM_Base::get_all
2101
-     * @return EE_Base_Class[] Results not necessarily indexed by IDs, because some results might not have primary keys
2102
-     * @throws \EE_Error
2103
-     *                             or might not be saved yet. Consider using EEM_Base::get_IDs() on these results if
2104
-     *                             you want IDs
2105
-     */
2106
-    public function get_many_related($relationName, $query_params = array())
2107
-    {
2108
-        if ($this->ID()) {
2109
-            //this exists in the DB, so get the related things from either the cache or the DB
2110
-            //if there are query parameters, forget about caching the related model objects.
2111
-            if ($query_params) {
2112
-                $related_model_objects = $this->get_model()->get_all_related($this, $relationName, $query_params);
2113
-            } else {
2114
-                //did we already cache the result of this query?
2115
-                $cached_results = $this->get_all_from_cache($relationName);
2116
-                if ( ! $cached_results) {
2117
-                    $related_model_objects = $this->get_model()->get_all_related($this, $relationName, $query_params);
2118
-                    //if no query parameters were passed, then we got all the related model objects
2119
-                    //for that relation. We can cache them then.
2120
-                    foreach ($related_model_objects as $related_model_object) {
2121
-                        $this->cache($relationName, $related_model_object);
2122
-                    }
2123
-                } else {
2124
-                    $related_model_objects = $cached_results;
2125
-                }
2126
-            }
2127
-        } else {
2128
-            //this doesn't exist in the DB, so just get the related things from the cache
2129
-            $related_model_objects = $this->get_all_from_cache($relationName);
2130
-        }
2131
-        return $related_model_objects;
2132
-    }
2133
-
2134
-
2135
-
2136
-    /**
2137
-     * Instead of getting the related model objects, simply counts them. Ignores default_where_conditions by default,
2138
-     * unless otherwise specified in the $query_params
2139
-     *
2140
-     * @param string $relation_name  model_name like 'Event', or 'Registration'
2141
-     * @param array  $query_params   like EEM_Base::get_all's
2142
-     * @param string $field_to_count name of field to count by. By default, uses primary key
2143
-     * @param bool   $distinct       if we want to only count the distinct values for the column then you can trigger
2144
-     *                               that by the setting $distinct to TRUE;
2145
-     * @return int
2146
-     */
2147
-    public function count_related($relation_name, $query_params = array(), $field_to_count = null, $distinct = false)
2148
-    {
2149
-        return $this->get_model()->count_related($this, $relation_name, $query_params, $field_to_count, $distinct);
2150
-    }
2151
-
2152
-
2153
-
2154
-    /**
2155
-     * Instead of getting the related model objects, simply sums up the values of the specified field.
2156
-     * Note: ignores default_where_conditions by default, unless otherwise specified in the $query_params
2157
-     *
2158
-     * @param string $relation_name model_name like 'Event', or 'Registration'
2159
-     * @param array  $query_params  like EEM_Base::get_all's
2160
-     * @param string $field_to_sum  name of field to count by.
2161
-     *                              By default, uses primary key (which doesn't make much sense, so you should probably
2162
-     *                              change it)
2163
-     * @return int
2164
-     */
2165
-    public function sum_related($relation_name, $query_params = array(), $field_to_sum = null)
2166
-    {
2167
-        return $this->get_model()->sum_related($this, $relation_name, $query_params, $field_to_sum);
2168
-    }
2169
-
2170
-
2171
-
2172
-    /**
2173
-     * Gets the first (ie, one) related model object of the specified type.
2174
-     *
2175
-     * @param string $relationName key in the model's _model_relations array
2176
-     * @param array  $query_params like EEM_Base::get_all
2177
-     * @return EE_Base_Class (not an array, a single object)
2178
-     * @throws \EE_Error
2179
-     */
2180
-    public function get_first_related($relationName, $query_params = array())
2181
-    {
2182
-        if ($this->ID()) {//this exists in the DB, get from the cache OR the DB
2183
-            //if they've provided some query parameters, don't bother trying to cache the result
2184
-            //also make sure we're not caching the result of get_first_related
2185
-            //on a relation which should have an array of objects (because the cache might have an array of objects)
2186
-            if ($query_params
2187
-                || ! $this->get_model()->related_settings_for($relationName)
2188
-                     instanceof
2189
-                     EE_Belongs_To_Relation
2190
-            ) {
2191
-                $related_model_object = $this->get_model()->get_first_related($this, $relationName, $query_params);
2192
-            } else {
2193
-                //first, check if we've already cached the result of this query
2194
-                $cached_result = $this->get_one_from_cache($relationName);
2195
-                if ( ! $cached_result) {
2196
-                    $related_model_object = $this->get_model()->get_first_related($this, $relationName, $query_params);
2197
-                    $this->cache($relationName, $related_model_object);
2198
-                } else {
2199
-                    $related_model_object = $cached_result;
2200
-                }
2201
-            }
2202
-        } else {
2203
-            $related_model_object = null;
2204
-            //this doesn't exist in the Db, but maybe the relation is of type belongs to, and so the related thing might
2205
-            if ($this->get_model()->related_settings_for($relationName) instanceof EE_Belongs_To_Relation) {
2206
-                $related_model_object = $this->get_model()->get_first_related($this, $relationName, $query_params);
2207
-            }
2208
-            //this doesn't exist in the DB and apparently the thing it belongs to doesn't either, just get what's cached on this object
2209
-            if ( ! $related_model_object) {
2210
-                $related_model_object = $this->get_one_from_cache($relationName);
2211
-            }
2212
-        }
2213
-        return $related_model_object;
2214
-    }
2215
-
2216
-
2217
-
2218
-    /**
2219
-     * Does a delete on all related objects of type $relationName and removes
2220
-     * the current model object's relation to them. If they can't be deleted (because
2221
-     * of blocking related model objects) does nothing. If the related model objects are
2222
-     * soft-deletable, they will be soft-deleted regardless of related blocking model objects.
2223
-     * If this model object doesn't exist yet in the DB, just removes its related things
2224
-     *
2225
-     * @param string $relationName
2226
-     * @param array  $query_params like EEM_Base::get_all's
2227
-     * @return int how many deleted
2228
-     * @throws \EE_Error
2229
-     */
2230
-    public function delete_related($relationName, $query_params = array())
2231
-    {
2232
-        if ($this->ID()) {
2233
-            $count = $this->get_model()->delete_related($this, $relationName, $query_params);
2234
-        } else {
2235
-            $count = count($this->get_all_from_cache($relationName));
2236
-            $this->clear_cache($relationName, null, true);
2237
-        }
2238
-        return $count;
2239
-    }
2240
-
2241
-
2242
-
2243
-    /**
2244
-     * Does a hard delete (ie, removes the DB row) on all related objects of type $relationName and removes
2245
-     * the current model object's relation to them. If they can't be deleted (because
2246
-     * of blocking related model objects) just does a soft delete on it instead, if possible.
2247
-     * If the related thing isn't a soft-deletable model object, this function is identical
2248
-     * to delete_related(). If this model object doesn't exist in the DB, just remove its related things
2249
-     *
2250
-     * @param string $relationName
2251
-     * @param array  $query_params like EEM_Base::get_all's
2252
-     * @return int how many deleted (including those soft deleted)
2253
-     * @throws \EE_Error
2254
-     */
2255
-    public function delete_related_permanently($relationName, $query_params = array())
2256
-    {
2257
-        if ($this->ID()) {
2258
-            $count = $this->get_model()->delete_related_permanently($this, $relationName, $query_params);
2259
-        } else {
2260
-            $count = count($this->get_all_from_cache($relationName));
2261
-        }
2262
-        $this->clear_cache($relationName, null, true);
2263
-        return $count;
2264
-    }
2265
-
2266
-
2267
-
2268
-    /**
2269
-     * is_set
2270
-     * Just a simple utility function children can use for checking if property exists
2271
-     *
2272
-     * @access  public
2273
-     * @param  string $field_name property to check
2274
-     * @return bool                              TRUE if existing,FALSE if not.
2275
-     */
2276
-    public function is_set($field_name)
2277
-    {
2278
-        return isset($this->_fields[$field_name]);
2279
-    }
2280
-
2281
-
2282
-
2283
-    /**
2284
-     * Just a simple utility function children can use for checking if property (or properties) exists and throwing an
2285
-     * EE_Error exception if they don't
2286
-     *
2287
-     * @param  mixed (string|array) $properties properties to check
2288
-     * @throws EE_Error
2289
-     * @return bool                              TRUE if existing, throw EE_Error if not.
2290
-     */
2291
-    protected function _property_exists($properties)
2292
-    {
2293
-        foreach ((array)$properties as $property_name) {
2294
-            //first make sure this property exists
2295
-            if ( ! $this->_fields[$property_name]) {
2296
-                throw new EE_Error(
2297
-                    sprintf(
2298
-                        __(
2299
-                            'Trying to retrieve a non-existent property (%s).  Double check the spelling please',
2300
-                            'event_espresso'
2301
-                        ),
2302
-                        $property_name
2303
-                    )
2304
-                );
2305
-            }
2306
-        }
2307
-        return true;
2308
-    }
2309
-
2310
-
2311
-
2312
-    /**
2313
-     * This simply returns an array of model fields for this object
2314
-     *
2315
-     * @return array
2316
-     * @throws \EE_Error
2317
-     */
2318
-    public function model_field_array()
2319
-    {
2320
-        $fields = $this->get_model()->field_settings(false);
2321
-        $properties = array();
2322
-        //remove prepended underscore
2323
-        foreach ($fields as $field_name => $settings) {
2324
-            $properties[$field_name] = $this->get($field_name);
2325
-        }
2326
-        return $properties;
2327
-    }
2328
-
2329
-
2330
-
2331
-    /**
2332
-     * Very handy general function to allow for plugins to extend any child of EE_Base_Class.
2333
-     * If a method is called on a child of EE_Base_Class that doesn't exist, this function is called
2334
-     * (http://www.garfieldtech.com/blog/php-magic-call) and passed the method's name and arguments. Instead of
2335
-     * requiring a plugin to extend the EE_Base_Class (which works fine is there's only 1 plugin, but when will that
2336
-     * happen?) they can add a hook onto 'filters_hook_espresso__{className}__{methodName}' (eg,
2337
-     * filters_hook_espresso__EE_Answer__my_great_function) and accepts 2 arguments: the object on which the function
2338
-     * was called, and an array of the original arguments passed to the function. Whatever their callback function
2339
-     * returns will be returned by this function. Example: in functions.php (or in a plugin):
2340
-     * add_filter('FHEE__EE_Answer__my_callback','my_callback',10,3); function
2341
-     * my_callback($previousReturnValue,EE_Base_Class $object,$argsArray){
2342
-     * $returnString= "you called my_callback! and passed args:".implode(",",$argsArray);
2343
-     *        return $previousReturnValue.$returnString;
2344
-     * }
2345
-     * require('EE_Answer.class.php');
2346
-     * $answer= EE_Answer::new_instance(array('REG_ID' => 2,'QST_ID' => 3,'ANS_value' => The answer is 42'));
2347
-     * echo $answer->my_callback('monkeys',100);
2348
-     * //will output "you called my_callback! and passed args:monkeys,100"
2349
-     *
2350
-     * @param string $methodName name of method which was called on a child of EE_Base_Class, but which
2351
-     * @param array  $args       array of original arguments passed to the function
2352
-     * @throws EE_Error
2353
-     * @return mixed whatever the plugin which calls add_filter decides
2354
-     */
2355
-    public function __call($methodName, $args)
2356
-    {
2357
-        $className = get_class($this);
2358
-        $tagName = "FHEE__{$className}__{$methodName}";
2359
-        if ( ! has_filter($tagName)) {
2360
-            throw new EE_Error(
2361
-                sprintf(
2362
-                    __(
2363
-                        "Method %s on class %s does not exist! You can create one with the following code in functions.php or in a plugin: add_filter('%s','my_callback',10,3);function my_callback(\$previousReturnValue,EE_Base_Class \$object, \$argsArray){/*function body*/return \$whatever;}",
2364
-                        "event_espresso"
2365
-                    ),
2366
-                    $methodName,
2367
-                    $className,
2368
-                    $tagName
2369
-                )
2370
-            );
2371
-        }
2372
-        return apply_filters($tagName, null, $this, $args);
2373
-    }
2374
-
2375
-
2376
-
2377
-    /**
2378
-     * Similar to insert_post_meta, adds a record in the Extra_Meta model's table with the given key and value.
2379
-     * A $previous_value can be specified in case there are many meta rows with the same key
2380
-     *
2381
-     * @param string $meta_key
2382
-     * @param mixed  $meta_value
2383
-     * @param mixed  $previous_value
2384
-     * @return bool|int # of records updated (or BOOLEAN if we actually ended up inserting the extra meta row)
2385
-     * @throws \EE_Error
2386
-     * NOTE: if the values haven't changed, returns 0
2387
-     */
2388
-    public function update_extra_meta($meta_key, $meta_value, $previous_value = null)
2389
-    {
2390
-        $query_params = array(
2391
-            array(
2392
-                'EXM_key'  => $meta_key,
2393
-                'OBJ_ID'   => $this->ID(),
2394
-                'EXM_type' => $this->get_model()->get_this_model_name(),
2395
-            ),
2396
-        );
2397
-        if ($previous_value !== null) {
2398
-            $query_params[0]['EXM_value'] = $meta_value;
2399
-        }
2400
-        $existing_rows_like_that = EEM_Extra_Meta::instance()->get_all($query_params);
2401
-        if ( ! $existing_rows_like_that) {
2402
-            return $this->add_extra_meta($meta_key, $meta_value);
2403
-        }
2404
-        foreach ($existing_rows_like_that as $existing_row) {
2405
-            $existing_row->save(array('EXM_value' => $meta_value));
2406
-        }
2407
-        return count($existing_rows_like_that);
2408
-    }
2409
-
2410
-
2411
-
2412
-    /**
2413
-     * Adds a new extra meta record. If $unique is set to TRUE, we'll first double-check
2414
-     * no other extra meta for this model object have the same key. Returns TRUE if the
2415
-     * extra meta row was entered, false if not
2416
-     *
2417
-     * @param string  $meta_key
2418
-     * @param string  $meta_value
2419
-     * @param boolean $unique
2420
-     * @return boolean
2421
-     * @throws \EE_Error
2422
-     */
2423
-    public function add_extra_meta($meta_key, $meta_value, $unique = false)
2424
-    {
2425
-        if ($unique) {
2426
-            $existing_extra_meta = EEM_Extra_Meta::instance()->get_one(
2427
-                array(
2428
-                    array(
2429
-                        'EXM_key'  => $meta_key,
2430
-                        'OBJ_ID'   => $this->ID(),
2431
-                        'EXM_type' => $this->get_model()->get_this_model_name(),
2432
-                    ),
2433
-                )
2434
-            );
2435
-            if ($existing_extra_meta) {
2436
-                return false;
2437
-            }
2438
-        }
2439
-        $new_extra_meta = EE_Extra_Meta::new_instance(
2440
-            array(
2441
-                'EXM_key'   => $meta_key,
2442
-                'EXM_value' => $meta_value,
2443
-                'OBJ_ID'    => $this->ID(),
2444
-                'EXM_type'  => $this->get_model()->get_this_model_name(),
2445
-            )
2446
-        );
2447
-        $new_extra_meta->save();
2448
-        return true;
2449
-    }
2450
-
2451
-
2452
-
2453
-    /**
2454
-     * Deletes all the extra meta rows for this record as specified by key. If $meta_value
2455
-     * is specified, only deletes extra meta records with that value.
2456
-     *
2457
-     * @param string $meta_key
2458
-     * @param string $meta_value
2459
-     * @return int number of extra meta rows deleted
2460
-     * @throws \EE_Error
2461
-     */
2462
-    public function delete_extra_meta($meta_key, $meta_value = null)
2463
-    {
2464
-        $query_params = array(
2465
-            array(
2466
-                'EXM_key'  => $meta_key,
2467
-                'OBJ_ID'   => $this->ID(),
2468
-                'EXM_type' => $this->get_model()->get_this_model_name(),
2469
-            ),
2470
-        );
2471
-        if ($meta_value !== null) {
2472
-            $query_params[0]['EXM_value'] = $meta_value;
2473
-        }
2474
-        return EEM_Extra_Meta::instance()->delete($query_params);
2475
-    }
2476
-
2477
-
2478
-
2479
-    /**
2480
-     * Gets the extra meta with the given meta key. If you specify "single" we just return 1, otherwise
2481
-     * an array of everything found. Requires that this model actually have a relation of type EE_Has_Many_Any_Relation.
2482
-     * You can specify $default is case you haven't found the extra meta
2483
-     *
2484
-     * @param string  $meta_key
2485
-     * @param boolean $single
2486
-     * @param mixed   $default if we don't find anything, what should we return?
2487
-     * @return mixed single value if $single; array if ! $single
2488
-     * @throws \EE_Error
2489
-     */
2490
-    public function get_extra_meta($meta_key, $single = false, $default = null)
2491
-    {
2492
-        if ($single) {
2493
-            $result = $this->get_first_related('Extra_Meta', array(array('EXM_key' => $meta_key)));
2494
-            if ($result instanceof EE_Extra_Meta) {
2495
-                return $result->value();
2496
-            } else {
2497
-                return $default;
2498
-            }
2499
-        } else {
2500
-            $results = $this->get_many_related('Extra_Meta', array(array('EXM_key' => $meta_key)));
2501
-            if ($results) {
2502
-                $values = array();
2503
-                foreach ($results as $result) {
2504
-                    if ($result instanceof EE_Extra_Meta) {
2505
-                        $values[$result->ID()] = $result->value();
2506
-                    }
2507
-                }
2508
-                return $values;
2509
-            } else {
2510
-                return $default;
2511
-            }
2512
-        }
2513
-    }
2514
-
2515
-
2516
-
2517
-    /**
2518
-     * Returns a simple array of all the extra meta associated with this model object.
2519
-     * If $one_of_each_key is true (Default), it will be an array of simple key-value pairs, keys being the
2520
-     * extra meta's key, and teh value being its value. However, if there are duplicate extra meta rows with
2521
-     * the same key, only one will be used. (eg array('foo'=>'bar','monkey'=>123))
2522
-     * If $one_of_each_key is false, it will return an array with the top-level keys being
2523
-     * the extra meta keys, but their values are also arrays, which have the extra-meta's ID as their sub-key, and
2524
-     * finally the extra meta's value as each sub-value. (eg
2525
-     * array('foo'=>array(1=>'bar',2=>'bill'),'monkey'=>array(3=>123)))
2526
-     *
2527
-     * @param boolean $one_of_each_key
2528
-     * @return array
2529
-     * @throws \EE_Error
2530
-     */
2531
-    public function all_extra_meta_array($one_of_each_key = true)
2532
-    {
2533
-        $return_array = array();
2534
-        if ($one_of_each_key) {
2535
-            $extra_meta_objs = $this->get_many_related('Extra_Meta', array('group_by' => 'EXM_key'));
2536
-            foreach ($extra_meta_objs as $extra_meta_obj) {
2537
-                if ($extra_meta_obj instanceof EE_Extra_Meta) {
2538
-                    $return_array[$extra_meta_obj->key()] = $extra_meta_obj->value();
2539
-                }
2540
-            }
2541
-        } else {
2542
-            $extra_meta_objs = $this->get_many_related('Extra_Meta');
2543
-            foreach ($extra_meta_objs as $extra_meta_obj) {
2544
-                if ($extra_meta_obj instanceof EE_Extra_Meta) {
2545
-                    if ( ! isset($return_array[$extra_meta_obj->key()])) {
2546
-                        $return_array[$extra_meta_obj->key()] = array();
2547
-                    }
2548
-                    $return_array[$extra_meta_obj->key()][$extra_meta_obj->ID()] = $extra_meta_obj->value();
2549
-                }
2550
-            }
2551
-        }
2552
-        return $return_array;
2553
-    }
2554
-
2555
-
2556
-
2557
-    /**
2558
-     * Gets a pretty nice displayable nice for this model object. Often overridden
2559
-     *
2560
-     * @return string
2561
-     * @throws \EE_Error
2562
-     */
2563
-    public function name()
2564
-    {
2565
-        //find a field that's not a text field
2566
-        $field_we_can_use = $this->get_model()->get_a_field_of_type('EE_Text_Field_Base');
2567
-        if ($field_we_can_use) {
2568
-            return $this->get($field_we_can_use->get_name());
2569
-        } else {
2570
-            $first_few_properties = $this->model_field_array();
2571
-            $first_few_properties = array_slice($first_few_properties, 0, 3);
2572
-            $name_parts = array();
2573
-            foreach ($first_few_properties as $name => $value) {
2574
-                $name_parts[] = "$name:$value";
2575
-            }
2576
-            return implode(",", $name_parts);
2577
-        }
2578
-    }
2579
-
2580
-
2581
-
2582
-    /**
2583
-     * in_entity_map
2584
-     * Checks if this model object has been proven to already be in the entity map
2585
-     *
2586
-     * @return boolean
2587
-     * @throws \EE_Error
2588
-     */
2589
-    public function in_entity_map()
2590
-    {
2591
-        if ($this->ID() && $this->get_model()->get_from_entity_map($this->ID()) === $this) {
2592
-            //well, if we looked, did we find it in the entity map?
2593
-            return true;
2594
-        } else {
2595
-            return false;
2596
-        }
2597
-    }
2598
-
2599
-
2600
-
2601
-    /**
2602
-     * refresh_from_db
2603
-     * Makes sure the fields and values on this model object are in-sync with what's in the database.
2604
-     *
2605
-     * @throws EE_Error if this model object isn't in the entity mapper (because then you should
2606
-     * just use what's in the entity mapper and refresh it) and WP_DEBUG is TRUE
2607
-     */
2608
-    public function refresh_from_db()
2609
-    {
2610
-        if ($this->ID() && $this->in_entity_map()) {
2611
-            $this->get_model()->refresh_entity_map_from_db($this->ID());
2612
-        } else {
2613
-            //if it doesn't have ID, you shouldn't be asking to refresh it from teh database (because its not in the database)
2614
-            //if it has an ID but it's not in the map, and you're asking me to refresh it
2615
-            //that's kinda dangerous. You should just use what's in the entity map, or add this to the entity map if there's
2616
-            //absolutely nothing in it for this ID
2617
-            if (WP_DEBUG) {
2618
-                throw new EE_Error(
2619
-                    sprintf(
2620
-                        __('Trying to refresh a model object with ID "%1$s" that\'s not in the entity map? First off: you should put it in the entity map by calling %2$s. Second off, if you want what\'s in the database right now, you should just call %3$s yourself and discard this model object.',
2621
-                            'event_espresso'),
2622
-                        $this->ID(),
2623
-                        get_class($this->get_model()) . '::instance()->add_to_entity_map()',
2624
-                        get_class($this->get_model()) . '::instance()->refresh_entity_map()'
2625
-                    )
2626
-                );
2627
-            }
2628
-        }
2629
-    }
2630
-
2631
-
2632
-
2633
-    /**
2634
-     * Because some other plugins, like Advanced Cron Manager, expect all objects to have this method
2635
-     * (probably a bad assumption they have made, oh well)
2636
-     *
2637
-     * @return string
2638
-     */
2639
-    public function __toString()
2640
-    {
2641
-        try {
2642
-            return sprintf('%s (%s)', $this->name(), $this->ID());
2643
-        } catch (Exception $e) {
2644
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
2645
-            return '';
2646
-        }
2647
-    }
2648
-
2649
-
2650
-
2651
-    /**
2652
-     * Clear related model objects if they're already in the DB, because otherwise when we
2653
-     * UN-serialize this model object we'll need to be careful to add them to the entity map.
2654
-     * This means if we have made changes to those related model objects, and want to unserialize
2655
-     * the this model object on a subsequent request, changes to those related model objects will be lost.
2656
-     * Instead, those related model objects should be directly serialized and stored.
2657
-     * Eg, the following won't work:
2658
-     * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
2659
-     * $att = $reg->attendee();
2660
-     * $att->set( 'ATT_fname', 'Dirk' );
2661
-     * update_option( 'my_option', serialize( $reg ) );
2662
-     * //END REQUEST
2663
-     * //START NEXT REQUEST
2664
-     * $reg = get_option( 'my_option' );
2665
-     * $reg->attendee()->save();
2666
-     * And would need to be replace with:
2667
-     * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
2668
-     * $att = $reg->attendee();
2669
-     * $att->set( 'ATT_fname', 'Dirk' );
2670
-     * update_option( 'my_option', serialize( $reg ) );
2671
-     * //END REQUEST
2672
-     * //START NEXT REQUEST
2673
-     * $att = get_option( 'my_option' );
2674
-     * $att->save();
2675
-     *
2676
-     * @return array
2677
-     * @throws \EE_Error
2678
-     */
2679
-    public function __sleep()
2680
-    {
2681
-        foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
2682
-            if ($relation_obj instanceof EE_Belongs_To_Relation) {
2683
-                $classname = 'EE_' . $this->get_model()->get_this_model_name();
2684
-                if (
2685
-                    $this->get_one_from_cache($relation_name) instanceof $classname
2686
-                    && $this->get_one_from_cache($relation_name)->ID()
2687
-                ) {
2688
-                    $this->clear_cache($relation_name, $this->get_one_from_cache($relation_name)->ID());
2689
-                }
2690
-            }
2691
-        }
2692
-        $this->_props_n_values_provided_in_constructor = array();
2693
-        return array_keys(get_object_vars($this));
2694
-    }
2695
-
2696
-
2697
-
2698
-    /**
2699
-     * restore _props_n_values_provided_in_constructor
2700
-     * PLZ NOTE: this will reset the array to whatever fields values were present prior to serialization,
2701
-     * and therefore should NOT be used to determine if state change has occurred since initial construction.
2702
-     * At best, you would only be able to detect if state change has occurred during THIS request.
2703
-     */
2704
-    public function __wakeup()
2705
-    {
2706
-        $this->_props_n_values_provided_in_constructor = $this->_fields;
2707
-    }
28
+	/**
29
+	 * This is an array of the original properties and values provided during construction
30
+	 * of this model object. (keys are model field names, values are their values).
31
+	 * This list is important to remember so that when we are merging data from the db, we know
32
+	 * which values to override and which to not override.
33
+	 *
34
+	 * @var array
35
+	 */
36
+	protected $_props_n_values_provided_in_constructor;
37
+
38
+	/**
39
+	 * Timezone
40
+	 * This gets set by the "set_timezone()" method so that we know what timezone incoming strings|timestamps are in.
41
+	 * This can also be used before a get to set what timezone you want strings coming out of the object to be in.  NOT
42
+	 * all EE_Base_Class child classes use this property but any that use a EE_Datetime_Field data type will have
43
+	 * access to it.
44
+	 *
45
+	 * @var string
46
+	 */
47
+	protected $_timezone;
48
+
49
+
50
+
51
+	/**
52
+	 * date format
53
+	 * pattern or format for displaying dates
54
+	 *
55
+	 * @var string $_dt_frmt
56
+	 */
57
+	protected $_dt_frmt;
58
+
59
+
60
+
61
+	/**
62
+	 * time format
63
+	 * pattern or format for displaying time
64
+	 *
65
+	 * @var string $_tm_frmt
66
+	 */
67
+	protected $_tm_frmt;
68
+
69
+
70
+
71
+	/**
72
+	 * This property is for holding a cached array of object properties indexed by property name as the key.
73
+	 * The purpose of this is for setting a cache on properties that may have calculated values after a
74
+	 * prepare_for_get.  That way the cache can be checked first and the calculated property returned instead of having
75
+	 * to recalculate. Used by _set_cached_property() and _get_cached_property() methods.
76
+	 *
77
+	 * @var array
78
+	 */
79
+	protected $_cached_properties = array();
80
+
81
+	/**
82
+	 * An array containing keys of the related model, and values are either an array of related mode objects or a
83
+	 * single
84
+	 * related model object. see the model's _model_relations. The keys should match those specified. And if the
85
+	 * relation is of type EE_Belongs_To (or one of its children), then there should only be ONE related model object,
86
+	 * all others have an array)
87
+	 *
88
+	 * @var array
89
+	 */
90
+	protected $_model_relations = array();
91
+
92
+	/**
93
+	 * Array where keys are field names (see the model's _fields property) and values are their values. To see what
94
+	 * their types should be, look at what that field object returns on its prepare_for_get and prepare_for_set methods)
95
+	 *
96
+	 * @var array
97
+	 */
98
+	protected $_fields = array();
99
+
100
+	/**
101
+	 * @var boolean indicating whether or not this model object is intended to ever be saved
102
+	 * For example, we might create model objects intended to only be used for the duration
103
+	 * of this request and to be thrown away, and if they were accidentally saved
104
+	 * it would be a bug.
105
+	 */
106
+	protected $_allow_persist = true;
107
+
108
+	/**
109
+	 * @var boolean indicating whether or not this model object's properties have changed since construction
110
+	 */
111
+	protected $_has_changes = false;
112
+
113
+
114
+
115
+	/**
116
+	 * basic constructor for Event Espresso classes, performs any necessary initialization, and verifies it's children
117
+	 * play nice
118
+	 *
119
+	 * @param array   $fieldValues                             where each key is a field (ie, array key in the 2nd
120
+	 *                                                         layer of the model's _fields array, (eg, EVT_ID,
121
+	 *                                                         TXN_amount, QST_name, etc) and values are their values
122
+	 * @param boolean $bydb                                    a flag for setting if the class is instantiated by the
123
+	 *                                                         corresponding db model or not.
124
+	 * @param string  $timezone                                indicate what timezone you want any datetime fields to
125
+	 *                                                         be in when instantiating a EE_Base_Class object.
126
+	 * @param array   $date_formats                            An array of date formats to set on construct where first
127
+	 *                                                         value is the date_format and second value is the time
128
+	 *                                                         format.
129
+	 * @throws EE_Error
130
+	 */
131
+	protected function __construct($fieldValues = array(), $bydb = false, $timezone = '', $date_formats = array())
132
+	{
133
+		$className = get_class($this);
134
+		do_action("AHEE__{$className}__construct", $this, $fieldValues);
135
+		$model = $this->get_model();
136
+		$model_fields = $model->field_settings(false);
137
+		// ensure $fieldValues is an array
138
+		$fieldValues = is_array($fieldValues) ? $fieldValues : array($fieldValues);
139
+		// EEH_Debug_Tools::printr( $fieldValues, '$fieldValues  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
140
+		// verify client code has not passed any invalid field names
141
+		foreach ($fieldValues as $field_name => $field_value) {
142
+			if ( ! isset($model_fields[$field_name])) {
143
+				throw new EE_Error(sprintf(__("Invalid field (%s) passed to constructor of %s. Allowed fields are :%s",
144
+					"event_espresso"), $field_name, get_class($this), implode(", ", array_keys($model_fields))));
145
+			}
146
+		}
147
+		// EEH_Debug_Tools::printr( $model_fields, '$model_fields  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
148
+		$this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
149
+		if ( ! empty($date_formats) && is_array($date_formats)) {
150
+			list($this->_dt_frmt, $this->_tm_frmt) = $date_formats;
151
+		} else {
152
+			//set default formats for date and time
153
+			$this->_dt_frmt = (string)get_option('date_format', 'Y-m-d');
154
+			$this->_tm_frmt = (string)get_option('time_format', 'g:i a');
155
+		}
156
+		//if db model is instantiating
157
+		if ($bydb) {
158
+			//client code has indicated these field values are from the database
159
+			foreach ($model_fields as $fieldName => $field) {
160
+				$this->set_from_db($fieldName, isset($fieldValues[$fieldName]) ? $fieldValues[$fieldName] : null);
161
+			}
162
+		} else {
163
+			//we're constructing a brand
164
+			//new instance of the model object. Generally, this means we'll need to do more field validation
165
+			foreach ($model_fields as $fieldName => $field) {
166
+				$this->set($fieldName, isset($fieldValues[$fieldName]) ? $fieldValues[$fieldName] : null, true);
167
+			}
168
+		}
169
+		//remember what values were passed to this constructor
170
+		$this->_props_n_values_provided_in_constructor = $fieldValues;
171
+		//remember in entity mapper
172
+		if ( ! $bydb && $model->has_primary_key_field() && $this->ID()) {
173
+			$model->add_to_entity_map($this);
174
+		}
175
+		//setup all the relations
176
+		foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
177
+			if ($relation_obj instanceof EE_Belongs_To_Relation) {
178
+				$this->_model_relations[$relation_name] = null;
179
+			} else {
180
+				$this->_model_relations[$relation_name] = array();
181
+			}
182
+		}
183
+		/**
184
+		 * Action done at the end of each model object construction
185
+		 *
186
+		 * @param EE_Base_Class $this the model object just created
187
+		 */
188
+		do_action('AHEE__EE_Base_Class__construct__finished', $this);
189
+	}
190
+
191
+
192
+
193
+	/**
194
+	 * Gets whether or not this model object is allowed to persist/be saved to the database.
195
+	 *
196
+	 * @return boolean
197
+	 */
198
+	public function allow_persist()
199
+	{
200
+		return $this->_allow_persist;
201
+	}
202
+
203
+
204
+
205
+	/**
206
+	 * Sets whether or not this model object should be allowed to be saved to the DB.
207
+	 * Normally once this is set to FALSE you wouldn't set it back to TRUE, unless
208
+	 * you got new information that somehow made you change your mind.
209
+	 *
210
+	 * @param boolean $allow_persist
211
+	 * @return boolean
212
+	 */
213
+	public function set_allow_persist($allow_persist)
214
+	{
215
+		return $this->_allow_persist = $allow_persist;
216
+	}
217
+
218
+
219
+
220
+	/**
221
+	 * Gets the field's original value when this object was constructed during this request.
222
+	 * This can be helpful when determining if a model object has changed or not
223
+	 *
224
+	 * @param string $field_name
225
+	 * @return mixed|null
226
+	 * @throws \EE_Error
227
+	 */
228
+	public function get_original($field_name)
229
+	{
230
+		if (isset($this->_props_n_values_provided_in_constructor[$field_name])
231
+			&& $field_settings = $this->get_model()->field_settings_for($field_name)
232
+		) {
233
+			return $field_settings->prepare_for_get($this->_props_n_values_provided_in_constructor[$field_name]);
234
+		} else {
235
+			return null;
236
+		}
237
+	}
238
+
239
+
240
+
241
+	/**
242
+	 * @param EE_Base_Class $obj
243
+	 * @return string
244
+	 */
245
+	public function get_class($obj)
246
+	{
247
+		return get_class($obj);
248
+	}
249
+
250
+
251
+
252
+	/**
253
+	 * Overrides parent because parent expects old models.
254
+	 * This also doesn't do any validation, and won't work for serialized arrays
255
+	 *
256
+	 * @param    string $field_name
257
+	 * @param    mixed  $field_value
258
+	 * @param bool      $use_default
259
+	 * @throws \EE_Error
260
+	 */
261
+	public function set($field_name, $field_value, $use_default = false)
262
+	{
263
+		// if not using default and nothing has changed, and object has already been setup (has ID),
264
+		// then don't do anything
265
+		if (
266
+			! $use_default
267
+			&& $this->_fields[$field_name] === $field_value
268
+			&& $this->ID()
269
+		) {
270
+			return;
271
+		}
272
+		$this->_has_changes = true;
273
+		$field_obj = $this->get_model()->field_settings_for($field_name);
274
+		if ($field_obj instanceof EE_Model_Field_Base) {
275
+			//			if ( method_exists( $field_obj, 'set_timezone' )) {
276
+			if ($field_obj instanceof EE_Datetime_Field) {
277
+				$field_obj->set_timezone($this->_timezone);
278
+				$field_obj->set_date_format($this->_dt_frmt);
279
+				$field_obj->set_time_format($this->_tm_frmt);
280
+			}
281
+			$holder_of_value = $field_obj->prepare_for_set($field_value);
282
+			//should the value be null?
283
+			if (($field_value === null || $holder_of_value === null || $holder_of_value === '') && $use_default) {
284
+				$this->_fields[$field_name] = $field_obj->get_default_value();
285
+				/**
286
+				 * To save having to refactor all the models, if a default value is used for a
287
+				 * EE_Datetime_Field, and that value is not null nor is it a DateTime
288
+				 * object.  Then let's do a set again to ensure that it becomes a DateTime
289
+				 * object.
290
+				 *
291
+				 * @since 4.6.10+
292
+				 */
293
+				if (
294
+					$field_obj instanceof EE_Datetime_Field
295
+					&& $this->_fields[$field_name] !== null
296
+					&& ! $this->_fields[$field_name] instanceof DateTime
297
+				) {
298
+					empty($this->_fields[$field_name])
299
+						? $this->set($field_name, time())
300
+						: $this->set($field_name, $this->_fields[$field_name]);
301
+				}
302
+			} else {
303
+				$this->_fields[$field_name] = $holder_of_value;
304
+			}
305
+			//if we're not in the constructor...
306
+			//now check if what we set was a primary key
307
+			if (
308
+				//note: props_n_values_provided_in_constructor is only set at the END of the constructor
309
+				$this->_props_n_values_provided_in_constructor
310
+				&& $field_value
311
+				&& $field_name === self::_get_primary_key_name(get_class($this))
312
+			) {
313
+				//if so, we want all this object's fields to be filled either with
314
+				//what we've explicitly set on this model
315
+				//or what we have in the db
316
+				// echo "setting primary key!";
317
+				$fields_on_model = self::_get_model(get_class($this))->field_settings();
318
+				$obj_in_db = self::_get_model(get_class($this))->get_one_by_ID($field_value);
319
+				foreach ($fields_on_model as $field_obj) {
320
+					if ( ! array_key_exists($field_obj->get_name(), $this->_props_n_values_provided_in_constructor)
321
+						 && $field_obj->get_name() !== $field_name
322
+					) {
323
+						$this->set($field_obj->get_name(), $obj_in_db->get($field_obj->get_name()));
324
+					}
325
+				}
326
+				//oh this model object has an ID? well make sure its in the entity mapper
327
+				$this->get_model()->add_to_entity_map($this);
328
+			}
329
+			//let's unset any cache for this field_name from the $_cached_properties property.
330
+			$this->_clear_cached_property($field_name);
331
+		} else {
332
+			throw new EE_Error(sprintf(__("A valid EE_Model_Field_Base could not be found for the given field name: %s",
333
+				"event_espresso"), $field_name));
334
+		}
335
+	}
336
+
337
+
338
+
339
+	/**
340
+	 * This sets the field value on the db column if it exists for the given $column_name or
341
+	 * saves it to EE_Extra_Meta if the given $column_name does not match a db column.
342
+	 *
343
+	 * @see EE_message::get_column_value for related documentation on the necessity of this method.
344
+	 * @param string $field_name  Must be the exact column name.
345
+	 * @param mixed  $field_value The value to set.
346
+	 * @return int|bool @see EE_Base_Class::update_extra_meta() for return docs.
347
+	 * @throws \EE_Error
348
+	 */
349
+	public function set_field_or_extra_meta($field_name, $field_value)
350
+	{
351
+		if ($this->get_model()->has_field($field_name)) {
352
+			$this->set($field_name, $field_value);
353
+			return true;
354
+		} else {
355
+			//ensure this object is saved first so that extra meta can be properly related.
356
+			$this->save();
357
+			return $this->update_extra_meta($field_name, $field_value);
358
+		}
359
+	}
360
+
361
+
362
+
363
+	/**
364
+	 * This retrieves the value of the db column set on this class or if that's not present
365
+	 * it will attempt to retrieve from extra_meta if found.
366
+	 * Example Usage:
367
+	 * Via EE_Message child class:
368
+	 * Due to the dynamic nature of the EE_messages system, EE_messengers will always have a "to",
369
+	 * "from", "subject", and "content" field (as represented in the EE_Message schema), however they may
370
+	 * also have additional main fields specific to the messenger.  The system accommodates those extra
371
+	 * fields through the EE_Extra_Meta table.  This method allows for EE_messengers to retrieve the
372
+	 * value for those extra fields dynamically via the EE_message object.
373
+	 *
374
+	 * @param  string $field_name expecting the fully qualified field name.
375
+	 * @return mixed|null  value for the field if found.  null if not found.
376
+	 * @throws \EE_Error
377
+	 */
378
+	public function get_field_or_extra_meta($field_name)
379
+	{
380
+		if ($this->get_model()->has_field($field_name)) {
381
+			$column_value = $this->get($field_name);
382
+		} else {
383
+			//This isn't a column in the main table, let's see if it is in the extra meta.
384
+			$column_value = $this->get_extra_meta($field_name, true, null);
385
+		}
386
+		return $column_value;
387
+	}
388
+
389
+
390
+
391
+	/**
392
+	 * See $_timezone property for description of what the timezone property is for.  This SETS the timezone internally
393
+	 * for being able to reference what timezone we are running conversions on when converting TO the internal timezone
394
+	 * (UTC Unix Timestamp) for the object OR when converting FROM the internal timezone (UTC Unix Timestamp). This is
395
+	 * available to all child classes that may be using the EE_Datetime_Field for a field data type.
396
+	 *
397
+	 * @access public
398
+	 * @param string $timezone A valid timezone string as described by @link http://www.php.net/manual/en/timezones.php
399
+	 * @return void
400
+	 * @throws \EE_Error
401
+	 */
402
+	public function set_timezone($timezone = '')
403
+	{
404
+		$this->_timezone = EEH_DTT_Helper::get_valid_timezone_string($timezone);
405
+		//make sure we clear all cached properties because they won't be relevant now
406
+		$this->_clear_cached_properties();
407
+		//make sure we update field settings and the date for all EE_Datetime_Fields
408
+		$model_fields = $this->get_model()->field_settings(false);
409
+		foreach ($model_fields as $field_name => $field_obj) {
410
+			if ($field_obj instanceof EE_Datetime_Field) {
411
+				$field_obj->set_timezone($this->_timezone);
412
+				if (isset($this->_fields[$field_name]) && $this->_fields[$field_name] instanceof DateTime) {
413
+					$this->_fields[$field_name]->setTimezone(new DateTimeZone($this->_timezone));
414
+				}
415
+			}
416
+		}
417
+	}
418
+
419
+
420
+
421
+	/**
422
+	 * This just returns whatever is set for the current timezone.
423
+	 *
424
+	 * @access public
425
+	 * @return string timezone string
426
+	 */
427
+	public function get_timezone()
428
+	{
429
+		return $this->_timezone;
430
+	}
431
+
432
+
433
+
434
+	/**
435
+	 * This sets the internal date format to what is sent in to be used as the new default for the class
436
+	 * internally instead of wp set date format options
437
+	 *
438
+	 * @since 4.6
439
+	 * @param string $format should be a format recognizable by PHP date() functions.
440
+	 */
441
+	public function set_date_format($format)
442
+	{
443
+		$this->_dt_frmt = $format;
444
+		//clear cached_properties because they won't be relevant now.
445
+		$this->_clear_cached_properties();
446
+	}
447
+
448
+
449
+
450
+	/**
451
+	 * This sets the internal time format string to what is sent in to be used as the new default for the
452
+	 * class internally instead of wp set time format options.
453
+	 *
454
+	 * @since 4.6
455
+	 * @param string $format should be a format recognizable by PHP date() functions.
456
+	 */
457
+	public function set_time_format($format)
458
+	{
459
+		$this->_tm_frmt = $format;
460
+		//clear cached_properties because they won't be relevant now.
461
+		$this->_clear_cached_properties();
462
+	}
463
+
464
+
465
+
466
+	/**
467
+	 * This returns the current internal set format for the date and time formats.
468
+	 *
469
+	 * @param bool $full           if true (default), then return the full format.  Otherwise will return an array
470
+	 *                             where the first value is the date format and the second value is the time format.
471
+	 * @return mixed string|array
472
+	 */
473
+	public function get_format($full = true)
474
+	{
475
+		return $full ? $this->_dt_frmt . ' ' . $this->_tm_frmt : array($this->_dt_frmt, $this->_tm_frmt);
476
+	}
477
+
478
+
479
+
480
+	/**
481
+	 * cache
482
+	 * stores the passed model object on the current model object.
483
+	 * In certain circumstances, we can use this cached model object instead of querying for another one entirely.
484
+	 *
485
+	 * @param string        $relationName    one of the keys in the _model_relations array on the model. Eg
486
+	 *                                       'Registration' associated with this model object
487
+	 * @param EE_Base_Class $object_to_cache that has a relation to this model object. (Eg, if this is a Transaction,
488
+	 *                                       that could be a payment or a registration)
489
+	 * @param null          $cache_id        a string or number that will be used as the key for any Belongs_To_Many
490
+	 *                                       items which will be stored in an array on this object
491
+	 * @throws EE_Error
492
+	 * @return mixed    index into cache, or just TRUE if the relation is of type Belongs_To (because there's only one
493
+	 *                  related thing, no array)
494
+	 */
495
+	public function cache($relationName = '', $object_to_cache = null, $cache_id = null)
496
+	{
497
+		// its entirely possible that there IS no related object yet in which case there is nothing to cache.
498
+		if ( ! $object_to_cache instanceof EE_Base_Class) {
499
+			return false;
500
+		}
501
+		// also get "how" the object is related, or throw an error
502
+		if ( ! $relationship_to_model = $this->get_model()->related_settings_for($relationName)) {
503
+			throw new EE_Error(sprintf(__('There is no relationship to %s on a %s. Cannot cache it', 'event_espresso'),
504
+				$relationName, get_class($this)));
505
+		}
506
+		// how many things are related ?
507
+		if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
508
+			// if it's a "belongs to" relationship, then there's only one related model object  eg, if this is a registration, there's only 1 attendee for it
509
+			// so for these model objects just set it to be cached
510
+			$this->_model_relations[$relationName] = $object_to_cache;
511
+			$return = true;
512
+		} else {
513
+			// otherwise, this is the "many" side of a one to many relationship, so we'll add the object to the array of related objects for that type.
514
+			// eg: if this is an event, there are many registrations for that event, so we cache the registrations in an array
515
+			if ( ! is_array($this->_model_relations[$relationName])) {
516
+				// if for some reason, the cached item is a model object, then stick that in the array, otherwise start with an empty array
517
+				$this->_model_relations[$relationName] = $this->_model_relations[$relationName] instanceof EE_Base_Class
518
+					? array($this->_model_relations[$relationName]) : array();
519
+			}
520
+			// first check for a cache_id which is normally empty
521
+			if ( ! empty($cache_id)) {
522
+				// if the cache_id exists, then it means we are purposely trying to cache this with a known key that can then be used to retrieve the object later on
523
+				$this->_model_relations[$relationName][$cache_id] = $object_to_cache;
524
+				$return = $cache_id;
525
+			} elseif ($object_to_cache->ID()) {
526
+				// OR the cached object originally came from the db, so let's just use it's PK for an ID
527
+				$this->_model_relations[$relationName][$object_to_cache->ID()] = $object_to_cache;
528
+				$return = $object_to_cache->ID();
529
+			} else {
530
+				// OR it's a new object with no ID, so just throw it in the array with an auto-incremented ID
531
+				$this->_model_relations[$relationName][] = $object_to_cache;
532
+				// move the internal pointer to the end of the array
533
+				end($this->_model_relations[$relationName]);
534
+				// and grab the key so that we can return it
535
+				$return = key($this->_model_relations[$relationName]);
536
+			}
537
+		}
538
+		return $return;
539
+	}
540
+
541
+
542
+
543
+	/**
544
+	 * For adding an item to the cached_properties property.
545
+	 *
546
+	 * @access protected
547
+	 * @param string      $fieldname the property item the corresponding value is for.
548
+	 * @param mixed       $value     The value we are caching.
549
+	 * @param string|null $cache_type
550
+	 * @return void
551
+	 * @throws \EE_Error
552
+	 */
553
+	protected function _set_cached_property($fieldname, $value, $cache_type = null)
554
+	{
555
+		//first make sure this property exists
556
+		$this->get_model()->field_settings_for($fieldname);
557
+		$cache_type = empty($cache_type) ? 'standard' : $cache_type;
558
+		$this->_cached_properties[$fieldname][$cache_type] = $value;
559
+	}
560
+
561
+
562
+
563
+	/**
564
+	 * This returns the value cached property if it exists OR the actual property value if the cache doesn't exist.
565
+	 * This also SETS the cache if we return the actual property!
566
+	 *
567
+	 * @param string $fieldname        the name of the property we're trying to retrieve
568
+	 * @param bool   $pretty
569
+	 * @param string $extra_cache_ref  This allows the user to specify an extra cache ref for the given property
570
+	 *                                 (in cases where the same property may be used for different outputs
571
+	 *                                 - i.e. datetime, money etc.)
572
+	 *                                 It can also accept certain pre-defined "schema" strings
573
+	 *                                 to define how to output the property.
574
+	 *                                 see the field's prepare_for_pretty_echoing for what strings can be used
575
+	 * @return mixed                   whatever the value for the property is we're retrieving
576
+	 * @throws \EE_Error
577
+	 */
578
+	protected function _get_cached_property($fieldname, $pretty = false, $extra_cache_ref = null)
579
+	{
580
+		//verify the field exists
581
+		$this->get_model()->field_settings_for($fieldname);
582
+		$cache_type = $pretty ? 'pretty' : 'standard';
583
+		$cache_type .= ! empty($extra_cache_ref) ? '_' . $extra_cache_ref : '';
584
+		if (isset($this->_cached_properties[$fieldname][$cache_type])) {
585
+			return $this->_cached_properties[$fieldname][$cache_type];
586
+		}
587
+		$value = $this->_get_fresh_property($fieldname, $pretty, $extra_cache_ref);
588
+		$this->_set_cached_property($fieldname, $value, $cache_type);
589
+		return $value;
590
+	}
591
+
592
+
593
+
594
+	/**
595
+	 * If the cache didn't fetch the needed item, this fetches it.
596
+	 * @param string $fieldname
597
+	 * @param bool $pretty
598
+	 * @param string $extra_cache_ref
599
+	 * @return mixed
600
+	 */
601
+	protected function _get_fresh_property($fieldname, $pretty = false, $extra_cache_ref = null)
602
+	{
603
+		$field_obj = $this->get_model()->field_settings_for($fieldname);
604
+		// If this is an EE_Datetime_Field we need to make sure timezone, formats, and output are correct
605
+		if ($field_obj instanceof EE_Datetime_Field) {
606
+			$this->_prepare_datetime_field($field_obj, $pretty, $extra_cache_ref);
607
+		}
608
+		if ( ! isset($this->_fields[$fieldname])) {
609
+			$this->_fields[$fieldname] = null;
610
+		}
611
+		$value = $pretty
612
+			? $field_obj->prepare_for_pretty_echoing($this->_fields[$fieldname], $extra_cache_ref)
613
+			: $field_obj->prepare_for_get($this->_fields[$fieldname]);
614
+		return $value;
615
+	}
616
+
617
+
618
+
619
+	/**
620
+	 * set timezone, formats, and output for EE_Datetime_Field objects
621
+	 *
622
+	 * @param \EE_Datetime_Field $datetime_field
623
+	 * @param bool               $pretty
624
+	 * @param null $date_or_time
625
+	 * @return void
626
+	 * @throws \EE_Error
627
+	 */
628
+	protected function _prepare_datetime_field(
629
+		EE_Datetime_Field $datetime_field,
630
+		$pretty = false,
631
+		$date_or_time = null
632
+	) {
633
+		$datetime_field->set_timezone($this->_timezone);
634
+		$datetime_field->set_date_format($this->_dt_frmt, $pretty);
635
+		$datetime_field->set_time_format($this->_tm_frmt, $pretty);
636
+		//set the output returned
637
+		switch ($date_or_time) {
638
+			case 'D' :
639
+				$datetime_field->set_date_time_output('date');
640
+				break;
641
+			case 'T' :
642
+				$datetime_field->set_date_time_output('time');
643
+				break;
644
+			default :
645
+				$datetime_field->set_date_time_output();
646
+		}
647
+	}
648
+
649
+
650
+
651
+	/**
652
+	 * This just takes care of clearing out the cached_properties
653
+	 *
654
+	 * @return void
655
+	 */
656
+	protected function _clear_cached_properties()
657
+	{
658
+		$this->_cached_properties = array();
659
+	}
660
+
661
+
662
+
663
+	/**
664
+	 * This just clears out ONE property if it exists in the cache
665
+	 *
666
+	 * @param  string $property_name the property to remove if it exists (from the _cached_properties array)
667
+	 * @return void
668
+	 */
669
+	protected function _clear_cached_property($property_name)
670
+	{
671
+		if (isset($this->_cached_properties[$property_name])) {
672
+			unset($this->_cached_properties[$property_name]);
673
+		}
674
+	}
675
+
676
+
677
+
678
+	/**
679
+	 * Ensures that this related thing is a model object.
680
+	 *
681
+	 * @param mixed  $object_or_id EE_base_Class/int/string either a related model object, or its ID
682
+	 * @param string $model_name   name of the related thing, eg 'Attendee',
683
+	 * @return EE_Base_Class
684
+	 * @throws \EE_Error
685
+	 */
686
+	protected function ensure_related_thing_is_model_obj($object_or_id, $model_name)
687
+	{
688
+		$other_model_instance = self::_get_model_instance_with_name(
689
+			self::_get_model_classname($model_name),
690
+			$this->_timezone
691
+		);
692
+		return $other_model_instance->ensure_is_obj($object_or_id);
693
+	}
694
+
695
+
696
+
697
+	/**
698
+	 * Forgets the cached model of the given relation Name. So the next time we request it,
699
+	 * we will fetch it again from the database. (Handy if you know it's changed somehow).
700
+	 * If a specific object is supplied, and the relationship to it is either a HasMany or HABTM,
701
+	 * then only remove that one object from our cached array. Otherwise, clear the entire list
702
+	 *
703
+	 * @param string $relationName                         one of the keys in the _model_relations array on the model.
704
+	 *                                                     Eg 'Registration'
705
+	 * @param mixed  $object_to_remove_or_index_into_array or an index into the array of cached things, or NULL
706
+	 *                                                     if you intend to use $clear_all = TRUE, or the relation only
707
+	 *                                                     has 1 object anyways (ie, it's a BelongsToRelation)
708
+	 * @param bool   $clear_all                            This flags clearing the entire cache relation property if
709
+	 *                                                     this is HasMany or HABTM.
710
+	 * @throws EE_Error
711
+	 * @return EE_Base_Class | boolean from which was cleared from the cache, or true if we requested to remove a
712
+	 *                       relation from all
713
+	 */
714
+	public function clear_cache($relationName, $object_to_remove_or_index_into_array = null, $clear_all = false)
715
+	{
716
+		$relationship_to_model = $this->get_model()->related_settings_for($relationName);
717
+		$index_in_cache = '';
718
+		if ( ! $relationship_to_model) {
719
+			throw new EE_Error(
720
+				sprintf(
721
+					__("There is no relationship to %s on a %s. Cannot clear that cache", 'event_espresso'),
722
+					$relationName,
723
+					get_class($this)
724
+				)
725
+			);
726
+		}
727
+		if ($clear_all) {
728
+			$obj_removed = true;
729
+			$this->_model_relations[$relationName] = null;
730
+		} elseif ($relationship_to_model instanceof EE_Belongs_To_Relation) {
731
+			$obj_removed = $this->_model_relations[$relationName];
732
+			$this->_model_relations[$relationName] = null;
733
+		} else {
734
+			if ($object_to_remove_or_index_into_array instanceof EE_Base_Class
735
+				&& $object_to_remove_or_index_into_array->ID()
736
+			) {
737
+				$index_in_cache = $object_to_remove_or_index_into_array->ID();
738
+				if (is_array($this->_model_relations[$relationName])
739
+					&& ! isset($this->_model_relations[$relationName][$index_in_cache])
740
+				) {
741
+					$index_found_at = null;
742
+					//find this object in the array even though it has a different key
743
+					foreach ($this->_model_relations[$relationName] as $index => $obj) {
744
+						if (
745
+							$obj instanceof EE_Base_Class
746
+							&& (
747
+								$obj == $object_to_remove_or_index_into_array
748
+								|| $obj->ID() === $object_to_remove_or_index_into_array->ID()
749
+							)
750
+						) {
751
+							$index_found_at = $index;
752
+							break;
753
+						}
754
+					}
755
+					if ($index_found_at) {
756
+						$index_in_cache = $index_found_at;
757
+					} else {
758
+						//it wasn't found. huh. well obviously it doesn't need to be removed from teh cache
759
+						//if it wasn't in it to begin with. So we're done
760
+						return $object_to_remove_or_index_into_array;
761
+					}
762
+				}
763
+			} elseif ($object_to_remove_or_index_into_array instanceof EE_Base_Class) {
764
+				//so they provided a model object, but it's not yet saved to the DB... so let's go hunting for it!
765
+				foreach ($this->get_all_from_cache($relationName) as $index => $potentially_obj_we_want) {
766
+					if ($potentially_obj_we_want == $object_to_remove_or_index_into_array) {
767
+						$index_in_cache = $index;
768
+					}
769
+				}
770
+			} else {
771
+				$index_in_cache = $object_to_remove_or_index_into_array;
772
+			}
773
+			//supposedly we've found it. But it could just be that the client code
774
+			//provided a bad index/object
775
+			if (
776
+			isset(
777
+				$this->_model_relations[$relationName],
778
+				$this->_model_relations[$relationName][$index_in_cache]
779
+			)
780
+			) {
781
+				$obj_removed = $this->_model_relations[$relationName][$index_in_cache];
782
+				unset($this->_model_relations[$relationName][$index_in_cache]);
783
+			} else {
784
+				//that thing was never cached anyways.
785
+				$obj_removed = null;
786
+			}
787
+		}
788
+		return $obj_removed;
789
+	}
790
+
791
+
792
+
793
+	/**
794
+	 * update_cache_after_object_save
795
+	 * Allows a cached item to have it's cache ID (within the array of cached items) reset using the new ID it has
796
+	 * obtained after being saved to the db
797
+	 *
798
+	 * @param string         $relationName       - the type of object that is cached
799
+	 * @param \EE_Base_Class $newly_saved_object - the newly saved object to be re-cached
800
+	 * @param string         $current_cache_id   - the ID that was used when originally caching the object
801
+	 * @return boolean TRUE on success, FALSE on fail
802
+	 * @throws \EE_Error
803
+	 */
804
+	public function update_cache_after_object_save(
805
+		$relationName,
806
+		EE_Base_Class $newly_saved_object,
807
+		$current_cache_id = ''
808
+	) {
809
+		// verify that incoming object is of the correct type
810
+		$obj_class = 'EE_' . $relationName;
811
+		if ($newly_saved_object instanceof $obj_class) {
812
+			/* @type EE_Base_Class $newly_saved_object */
813
+			// now get the type of relation
814
+			$relationship_to_model = $this->get_model()->related_settings_for($relationName);
815
+			// if this is a 1:1 relationship
816
+			if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
817
+				// then just replace the cached object with the newly saved object
818
+				$this->_model_relations[$relationName] = $newly_saved_object;
819
+				return true;
820
+				// or if it's some kind of sordid feral polyamorous relationship...
821
+			} elseif (is_array($this->_model_relations[$relationName])
822
+					  && isset($this->_model_relations[$relationName][$current_cache_id])
823
+			) {
824
+				// then remove the current cached item
825
+				unset($this->_model_relations[$relationName][$current_cache_id]);
826
+				// and cache the newly saved object using it's new ID
827
+				$this->_model_relations[$relationName][$newly_saved_object->ID()] = $newly_saved_object;
828
+				return true;
829
+			}
830
+		}
831
+		return false;
832
+	}
833
+
834
+
835
+
836
+	/**
837
+	 * Fetches a single EE_Base_Class on that relation. (If the relation is of type
838
+	 * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
839
+	 *
840
+	 * @param string $relationName
841
+	 * @return EE_Base_Class
842
+	 */
843
+	public function get_one_from_cache($relationName)
844
+	{
845
+		$cached_array_or_object = isset($this->_model_relations[$relationName]) ? $this->_model_relations[$relationName]
846
+			: null;
847
+		if (is_array($cached_array_or_object)) {
848
+			return array_shift($cached_array_or_object);
849
+		} else {
850
+			return $cached_array_or_object;
851
+		}
852
+	}
853
+
854
+
855
+
856
+	/**
857
+	 * Fetches a single EE_Base_Class on that relation. (If the relation is of type
858
+	 * BelongsTo, it will only ever have 1 object. However, other relations could have an array of objects)
859
+	 *
860
+	 * @param string $relationName
861
+	 * @throws \EE_Error
862
+	 * @return EE_Base_Class[] NOT necessarily indexed by primary keys
863
+	 */
864
+	public function get_all_from_cache($relationName)
865
+	{
866
+		$objects = isset($this->_model_relations[$relationName]) ? $this->_model_relations[$relationName] : array();
867
+		// if the result is not an array, but exists, make it an array
868
+		$objects = is_array($objects) ? $objects : array($objects);
869
+		//bugfix for https://events.codebasehq.com/projects/event-espresso/tickets/7143
870
+		//basically, if this model object was stored in the session, and these cached model objects
871
+		//already have IDs, let's make sure they're in their model's entity mapper
872
+		//otherwise we will have duplicates next time we call
873
+		// EE_Registry::instance()->load_model( $relationName )->get_one_by_ID( $result->ID() );
874
+		$model = EE_Registry::instance()->load_model($relationName);
875
+		foreach ($objects as $model_object) {
876
+			if ($model instanceof EEM_Base && $model_object instanceof EE_Base_Class) {
877
+				//ensure its in the map if it has an ID; otherwise it will be added to the map when its saved
878
+				if ($model_object->ID()) {
879
+					$model->add_to_entity_map($model_object);
880
+				}
881
+			} else {
882
+				throw new EE_Error(
883
+					sprintf(
884
+						__(
885
+							'Error retrieving related model objects. Either $1%s is not a model or $2%s is not a model object',
886
+							'event_espresso'
887
+						),
888
+						$relationName,
889
+						gettype($model_object)
890
+					)
891
+				);
892
+			}
893
+		}
894
+		return $objects;
895
+	}
896
+
897
+
898
+
899
+	/**
900
+	 * Returns the next x number of EE_Base_Class objects in sequence from this object as found in the database
901
+	 * matching the given query conditions.
902
+	 *
903
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
904
+	 * @param int   $limit              How many objects to return.
905
+	 * @param array $query_params       Any additional conditions on the query.
906
+	 * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
907
+	 *                                  you can indicate just the columns you want returned
908
+	 * @return array|EE_Base_Class[]
909
+	 * @throws \EE_Error
910
+	 */
911
+	public function next_x($field_to_order_by = null, $limit = 1, $query_params = array(), $columns_to_select = null)
912
+	{
913
+		$field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
914
+			? $this->get_model()->get_primary_key_field()->get_name()
915
+			: $field_to_order_by;
916
+		$current_value = ! empty($field) ? $this->get($field) : null;
917
+		if (empty($field) || empty($current_value)) {
918
+			return array();
919
+		}
920
+		return $this->get_model()->next_x($current_value, $field, $limit, $query_params, $columns_to_select);
921
+	}
922
+
923
+
924
+
925
+	/**
926
+	 * Returns the previous x number of EE_Base_Class objects in sequence from this object as found in the database
927
+	 * matching the given query conditions.
928
+	 *
929
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
930
+	 * @param int   $limit              How many objects to return.
931
+	 * @param array $query_params       Any additional conditions on the query.
932
+	 * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
933
+	 *                                  you can indicate just the columns you want returned
934
+	 * @return array|EE_Base_Class[]
935
+	 * @throws \EE_Error
936
+	 */
937
+	public function previous_x(
938
+		$field_to_order_by = null,
939
+		$limit = 1,
940
+		$query_params = array(),
941
+		$columns_to_select = null
942
+	) {
943
+		$field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
944
+			? $this->get_model()->get_primary_key_field()->get_name()
945
+			: $field_to_order_by;
946
+		$current_value = ! empty($field) ? $this->get($field) : null;
947
+		if (empty($field) || empty($current_value)) {
948
+			return array();
949
+		}
950
+		return $this->get_model()->previous_x($current_value, $field, $limit, $query_params, $columns_to_select);
951
+	}
952
+
953
+
954
+
955
+	/**
956
+	 * Returns the next EE_Base_Class object in sequence from this object as found in the database
957
+	 * matching the given query conditions.
958
+	 *
959
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
960
+	 * @param array $query_params       Any additional conditions on the query.
961
+	 * @param null  $columns_to_select  If left null, then an array of EE_Base_Class objects is returned, otherwise
962
+	 *                                  you can indicate just the columns you want returned
963
+	 * @return array|EE_Base_Class
964
+	 * @throws \EE_Error
965
+	 */
966
+	public function next($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
967
+	{
968
+		$field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
969
+			? $this->get_model()->get_primary_key_field()->get_name()
970
+			: $field_to_order_by;
971
+		$current_value = ! empty($field) ? $this->get($field) : null;
972
+		if (empty($field) || empty($current_value)) {
973
+			return array();
974
+		}
975
+		return $this->get_model()->next($current_value, $field, $query_params, $columns_to_select);
976
+	}
977
+
978
+
979
+
980
+	/**
981
+	 * Returns the previous EE_Base_Class object in sequence from this object as found in the database
982
+	 * matching the given query conditions.
983
+	 *
984
+	 * @param null  $field_to_order_by  What field is being used as the reference point.
985
+	 * @param array $query_params       Any additional conditions on the query.
986
+	 * @param null  $columns_to_select  If left null, then an EE_Base_Class object is returned, otherwise
987
+	 *                                  you can indicate just the column you want returned
988
+	 * @return array|EE_Base_Class
989
+	 * @throws \EE_Error
990
+	 */
991
+	public function previous($field_to_order_by = null, $query_params = array(), $columns_to_select = null)
992
+	{
993
+		$field = empty($field_to_order_by) && $this->get_model()->has_primary_key_field()
994
+			? $this->get_model()->get_primary_key_field()->get_name()
995
+			: $field_to_order_by;
996
+		$current_value = ! empty($field) ? $this->get($field) : null;
997
+		if (empty($field) || empty($current_value)) {
998
+			return array();
999
+		}
1000
+		return $this->get_model()->previous($current_value, $field, $query_params, $columns_to_select);
1001
+	}
1002
+
1003
+
1004
+
1005
+	/**
1006
+	 * Overrides parent because parent expects old models.
1007
+	 * This also doesn't do any validation, and won't work for serialized arrays
1008
+	 *
1009
+	 * @param string $field_name
1010
+	 * @param mixed  $field_value_from_db
1011
+	 * @throws \EE_Error
1012
+	 */
1013
+	public function set_from_db($field_name, $field_value_from_db)
1014
+	{
1015
+		$field_obj = $this->get_model()->field_settings_for($field_name);
1016
+		if ($field_obj instanceof EE_Model_Field_Base) {
1017
+			//you would think the DB has no NULLs for non-null label fields right? wrong!
1018
+			//eg, a CPT model object could have an entry in the posts table, but no
1019
+			//entry in the meta table. Meaning that all its columns in the meta table
1020
+			//are null! yikes! so when we find one like that, use defaults for its meta columns
1021
+			if ($field_value_from_db === null) {
1022
+				if ($field_obj->is_nullable()) {
1023
+					//if the field allows nulls, then let it be null
1024
+					$field_value = null;
1025
+				} else {
1026
+					$field_value = $field_obj->get_default_value();
1027
+				}
1028
+			} else {
1029
+				$field_value = $field_obj->prepare_for_set_from_db($field_value_from_db);
1030
+			}
1031
+			$this->_fields[$field_name] = $field_value;
1032
+			$this->_clear_cached_property($field_name);
1033
+		}
1034
+	}
1035
+
1036
+
1037
+
1038
+	/**
1039
+	 * verifies that the specified field is of the correct type
1040
+	 *
1041
+	 * @param string $field_name
1042
+	 * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1043
+	 *                                (in cases where the same property may be used for different outputs
1044
+	 *                                - i.e. datetime, money etc.)
1045
+	 * @return mixed
1046
+	 * @throws \EE_Error
1047
+	 */
1048
+	public function get($field_name, $extra_cache_ref = null)
1049
+	{
1050
+		return $this->_get_cached_property($field_name, false, $extra_cache_ref);
1051
+	}
1052
+
1053
+
1054
+
1055
+	/**
1056
+	 * This method simply returns the RAW unprocessed value for the given property in this class
1057
+	 *
1058
+	 * @param  string $field_name A valid fieldname
1059
+	 * @return mixed              Whatever the raw value stored on the property is.
1060
+	 * @throws EE_Error if fieldSettings is misconfigured or the field doesn't exist.
1061
+	 */
1062
+	public function get_raw($field_name)
1063
+	{
1064
+		$field_settings = $this->get_model()->field_settings_for($field_name);
1065
+		return $field_settings instanceof EE_Datetime_Field && $this->_fields[$field_name] instanceof DateTime
1066
+			? $this->_fields[$field_name]->format('U')
1067
+			: $this->_fields[$field_name];
1068
+	}
1069
+
1070
+
1071
+
1072
+	/**
1073
+	 * This is used to return the internal DateTime object used for a field that is a
1074
+	 * EE_Datetime_Field.
1075
+	 *
1076
+	 * @param string $field_name               The field name retrieving the DateTime object.
1077
+	 * @return mixed null | false | DateTime  If the requested field is NOT a EE_Datetime_Field then
1078
+	 * @throws \EE_Error
1079
+	 *                                         an error is set and false returned.  If the field IS an
1080
+	 *                                         EE_Datetime_Field and but the field value is null, then
1081
+	 *                                         just null is returned (because that indicates that likely
1082
+	 *                                         this field is nullable).
1083
+	 */
1084
+	public function get_DateTime_object($field_name)
1085
+	{
1086
+		$field_settings = $this->get_model()->field_settings_for($field_name);
1087
+		if ( ! $field_settings instanceof EE_Datetime_Field) {
1088
+			EE_Error::add_error(
1089
+				sprintf(
1090
+					__(
1091
+						'The field %s is not an EE_Datetime_Field field.  There is no DateTime object stored on this field type.',
1092
+						'event_espresso'
1093
+					),
1094
+					$field_name
1095
+				),
1096
+				__FILE__,
1097
+				__FUNCTION__,
1098
+				__LINE__
1099
+			);
1100
+			return false;
1101
+		}
1102
+		return $this->_fields[$field_name];
1103
+	}
1104
+
1105
+
1106
+
1107
+	/**
1108
+	 * To be used in template to immediately echo out the value, and format it for output.
1109
+	 * Eg, should call stripslashes and whatnot before echoing
1110
+	 *
1111
+	 * @param string $field_name      the name of the field as it appears in the DB
1112
+	 * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1113
+	 *                                (in cases where the same property may be used for different outputs
1114
+	 *                                - i.e. datetime, money etc.)
1115
+	 * @return void
1116
+	 * @throws \EE_Error
1117
+	 */
1118
+	public function e($field_name, $extra_cache_ref = null)
1119
+	{
1120
+		echo $this->get_pretty($field_name, $extra_cache_ref);
1121
+	}
1122
+
1123
+
1124
+
1125
+	/**
1126
+	 * Exactly like e(), echoes out the field, but sets its schema to 'form_input', so that it
1127
+	 * can be easily used as the value of form input.
1128
+	 *
1129
+	 * @param string $field_name
1130
+	 * @return void
1131
+	 * @throws \EE_Error
1132
+	 */
1133
+	public function f($field_name)
1134
+	{
1135
+		$this->e($field_name, 'form_input');
1136
+	}
1137
+
1138
+
1139
+
1140
+	/**
1141
+	 * Gets a pretty view of the field's value. $extra_cache_ref can specify different formats for this.
1142
+	 * The $extra_cache_ref will be passed to the model field's prepare_for_pretty_echoing, so consult the field's class
1143
+	 * to see what options are available.
1144
+	 * @param string $field_name
1145
+	 * @param string $extra_cache_ref This allows the user to specify an extra cache ref for the given property
1146
+	 *                                (in cases where the same property may be used for different outputs
1147
+	 *                                - i.e. datetime, money etc.)
1148
+	 * @return mixed
1149
+	 * @throws \EE_Error
1150
+	 */
1151
+	public function get_pretty($field_name, $extra_cache_ref = null)
1152
+	{
1153
+		return $this->_get_cached_property($field_name, true, $extra_cache_ref);
1154
+	}
1155
+
1156
+
1157
+
1158
+	/**
1159
+	 * This simply returns the datetime for the given field name
1160
+	 * Note: this protected function is called by the wrapper get_date or get_time or get_datetime functions
1161
+	 * (and the equivalent e_date, e_time, e_datetime).
1162
+	 *
1163
+	 * @access   protected
1164
+	 * @param string   $field_name   Field on the instantiated EE_Base_Class child object
1165
+	 * @param string   $dt_frmt      valid datetime format used for date
1166
+	 *                               (if '' then we just use the default on the field,
1167
+	 *                               if NULL we use the last-used format)
1168
+	 * @param string   $tm_frmt      Same as above except this is for time format
1169
+	 * @param string   $date_or_time if NULL then both are returned, otherwise "D" = only date and "T" = only time.
1170
+	 * @param  boolean $echo         Whether the dtt is echoing using pretty echoing or just returned using vanilla get
1171
+	 * @return string|bool|EE_Error string on success, FALSE on fail, or EE_Error Exception is thrown
1172
+	 *                               if field is not a valid dtt field, or void if echoing
1173
+	 * @throws \EE_Error
1174
+	 */
1175
+	protected function _get_datetime($field_name, $dt_frmt = '', $tm_frmt = '', $date_or_time = '', $echo = false)
1176
+	{
1177
+		// clear cached property
1178
+		$this->_clear_cached_property($field_name);
1179
+		//reset format properties because they are used in get()
1180
+		$this->_dt_frmt = $dt_frmt !== '' ? $dt_frmt : $this->_dt_frmt;
1181
+		$this->_tm_frmt = $tm_frmt !== '' ? $tm_frmt : $this->_tm_frmt;
1182
+		if ($echo) {
1183
+			$this->e($field_name, $date_or_time);
1184
+			return '';
1185
+		}
1186
+		return $this->get($field_name, $date_or_time);
1187
+	}
1188
+
1189
+
1190
+
1191
+	/**
1192
+	 * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the date
1193
+	 * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1194
+	 * other echoes the pretty value for dtt)
1195
+	 *
1196
+	 * @param  string $field_name name of model object datetime field holding the value
1197
+	 * @param  string $format     format for the date returned (if NULL we use default in dt_frmt property)
1198
+	 * @return string            datetime value formatted
1199
+	 * @throws \EE_Error
1200
+	 */
1201
+	public function get_date($field_name, $format = '')
1202
+	{
1203
+		return $this->_get_datetime($field_name, $format, null, 'D');
1204
+	}
1205
+
1206
+
1207
+
1208
+	/**
1209
+	 * @param      $field_name
1210
+	 * @param string $format
1211
+	 * @throws \EE_Error
1212
+	 */
1213
+	public function e_date($field_name, $format = '')
1214
+	{
1215
+		$this->_get_datetime($field_name, $format, null, 'D', true);
1216
+	}
1217
+
1218
+
1219
+
1220
+	/**
1221
+	 * below are wrapper functions for the various datetime outputs that can be obtained for JUST returning the time
1222
+	 * portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1223
+	 * other echoes the pretty value for dtt)
1224
+	 *
1225
+	 * @param  string $field_name name of model object datetime field holding the value
1226
+	 * @param  string $format     format for the time returned ( if NULL we use default in tm_frmt property)
1227
+	 * @return string             datetime value formatted
1228
+	 * @throws \EE_Error
1229
+	 */
1230
+	public function get_time($field_name, $format = '')
1231
+	{
1232
+		return $this->_get_datetime($field_name, null, $format, 'T');
1233
+	}
1234
+
1235
+
1236
+
1237
+	/**
1238
+	 * @param      $field_name
1239
+	 * @param string $format
1240
+	 * @throws \EE_Error
1241
+	 */
1242
+	public function e_time($field_name, $format = '')
1243
+	{
1244
+		$this->_get_datetime($field_name, null, $format, 'T', true);
1245
+	}
1246
+
1247
+
1248
+
1249
+	/**
1250
+	 * below are wrapper functions for the various datetime outputs that can be obtained for returning the date AND
1251
+	 * time portion of a datetime value. (note the only difference between get_ and e_ is one returns the value and the
1252
+	 * other echoes the pretty value for dtt)
1253
+	 *
1254
+	 * @param  string $field_name name of model object datetime field holding the value
1255
+	 * @param  string $dt_frmt    format for the date returned (if NULL we use default in dt_frmt property)
1256
+	 * @param  string $tm_frmt    format for the time returned (if NULL we use default in tm_frmt property)
1257
+	 * @return string             datetime value formatted
1258
+	 * @throws \EE_Error
1259
+	 */
1260
+	public function get_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1261
+	{
1262
+		return $this->_get_datetime($field_name, $dt_frmt, $tm_frmt);
1263
+	}
1264
+
1265
+
1266
+
1267
+	/**
1268
+	 * @param string $field_name
1269
+	 * @param string $dt_frmt
1270
+	 * @param string $tm_frmt
1271
+	 * @throws \EE_Error
1272
+	 */
1273
+	public function e_datetime($field_name, $dt_frmt = '', $tm_frmt = '')
1274
+	{
1275
+		$this->_get_datetime($field_name, $dt_frmt, $tm_frmt, null, true);
1276
+	}
1277
+
1278
+
1279
+
1280
+	/**
1281
+	 * Get the i8ln value for a date using the WordPress @see date_i18n function.
1282
+	 *
1283
+	 * @param string $field_name The EE_Datetime_Field reference for the date being retrieved.
1284
+	 * @param string $format     PHP valid date/time string format.  If none is provided then the internal set format
1285
+	 *                           on the object will be used.
1286
+	 * @return string Date and time string in set locale or false if no field exists for the given
1287
+	 * @throws \EE_Error
1288
+	 *                           field name.
1289
+	 */
1290
+	public function get_i18n_datetime($field_name, $format = '')
1291
+	{
1292
+		$format = empty($format) ? $this->_dt_frmt . ' ' . $this->_tm_frmt : $format;
1293
+		return date_i18n(
1294
+			$format,
1295
+			EEH_DTT_Helper::get_timestamp_with_offset($this->get_raw($field_name), $this->_timezone)
1296
+		);
1297
+	}
1298
+
1299
+
1300
+
1301
+	/**
1302
+	 * This method validates whether the given field name is a valid field on the model object as well as it is of a
1303
+	 * type EE_Datetime_Field.  On success there will be returned the field settings.  On fail an EE_Error exception is
1304
+	 * thrown.
1305
+	 *
1306
+	 * @param  string $field_name The field name being checked
1307
+	 * @throws EE_Error
1308
+	 * @return EE_Datetime_Field
1309
+	 */
1310
+	protected function _get_dtt_field_settings($field_name)
1311
+	{
1312
+		$field = $this->get_model()->field_settings_for($field_name);
1313
+		//check if field is dtt
1314
+		if ($field instanceof EE_Datetime_Field) {
1315
+			return $field;
1316
+		} else {
1317
+			throw new EE_Error(sprintf(__('The field name "%s" has been requested for the EE_Base_Class datetime functions and it is not a valid EE_Datetime_Field.  Please check the spelling of the field and make sure it has been setup as a EE_Datetime_Field in the %s model constructor',
1318
+				'event_espresso'), $field_name, self::_get_model_classname(get_class($this))));
1319
+		}
1320
+	}
1321
+
1322
+
1323
+
1324
+
1325
+	/**
1326
+	 * NOTE ABOUT BELOW:
1327
+	 * These convenience date and time setters are for setting date and time independently.  In other words you might
1328
+	 * want to change the time on a datetime_field but leave the date the same (or vice versa). IF on the other hand
1329
+	 * you want to set both date and time at the same time, you can just use the models default set($fieldname,$value)
1330
+	 * method and make sure you send the entire datetime value for setting.
1331
+	 */
1332
+	/**
1333
+	 * sets the time on a datetime property
1334
+	 *
1335
+	 * @access protected
1336
+	 * @param string|Datetime $time      a valid time string for php datetime functions (or DateTime object)
1337
+	 * @param string          $fieldname the name of the field the time is being set on (must match a EE_Datetime_Field)
1338
+	 * @throws \EE_Error
1339
+	 */
1340
+	protected function _set_time_for($time, $fieldname)
1341
+	{
1342
+		$this->_set_date_time('T', $time, $fieldname);
1343
+	}
1344
+
1345
+
1346
+
1347
+	/**
1348
+	 * sets the date on a datetime property
1349
+	 *
1350
+	 * @access protected
1351
+	 * @param string|DateTime $date      a valid date string for php datetime functions ( or DateTime object)
1352
+	 * @param string          $fieldname the name of the field the date is being set on (must match a EE_Datetime_Field)
1353
+	 * @throws \EE_Error
1354
+	 */
1355
+	protected function _set_date_for($date, $fieldname)
1356
+	{
1357
+		$this->_set_date_time('D', $date, $fieldname);
1358
+	}
1359
+
1360
+
1361
+
1362
+	/**
1363
+	 * This takes care of setting a date or time independently on a given model object property. This method also
1364
+	 * verifies that the given fieldname matches a model object property and is for a EE_Datetime_Field field
1365
+	 *
1366
+	 * @access protected
1367
+	 * @param string          $what           "T" for time, 'B' for both, 'D' for Date.
1368
+	 * @param string|DateTime $datetime_value A valid Date or Time string (or DateTime object)
1369
+	 * @param string          $fieldname      the name of the field the date OR time is being set on (must match a
1370
+	 *                                        EE_Datetime_Field property)
1371
+	 * @throws \EE_Error
1372
+	 */
1373
+	protected function _set_date_time($what = 'T', $datetime_value, $fieldname)
1374
+	{
1375
+		$field = $this->_get_dtt_field_settings($fieldname);
1376
+		$field->set_timezone($this->_timezone);
1377
+		$field->set_date_format($this->_dt_frmt);
1378
+		$field->set_time_format($this->_tm_frmt);
1379
+		switch ($what) {
1380
+			case 'T' :
1381
+				$this->_fields[$fieldname] = $field->prepare_for_set_with_new_time(
1382
+					$datetime_value,
1383
+					$this->_fields[$fieldname]
1384
+				);
1385
+				break;
1386
+			case 'D' :
1387
+				$this->_fields[$fieldname] = $field->prepare_for_set_with_new_date(
1388
+					$datetime_value,
1389
+					$this->_fields[$fieldname]
1390
+				);
1391
+				break;
1392
+			case 'B' :
1393
+				$this->_fields[$fieldname] = $field->prepare_for_set($datetime_value);
1394
+				break;
1395
+		}
1396
+		$this->_clear_cached_property($fieldname);
1397
+	}
1398
+
1399
+
1400
+
1401
+	/**
1402
+	 * This will return a timestamp for the website timezone but ONLY when the current website timezone is different
1403
+	 * than the timezone set for the website. NOTE, this currently only works well with methods that return values.  If
1404
+	 * you use it with methods that echo values the $_timestamp property may not get reset to its original value and
1405
+	 * that could lead to some unexpected results!
1406
+	 *
1407
+	 * @access public
1408
+	 * @param string               $field_name This is the name of the field on the object that contains the date/time
1409
+	 *                                         value being returned.
1410
+	 * @param string               $callback   must match a valid method in this class (defaults to get_datetime)
1411
+	 * @param mixed (array|string) $args       This is the arguments that will be passed to the callback.
1412
+	 * @param string               $prepend    You can include something to prepend on the timestamp
1413
+	 * @param string               $append     You can include something to append on the timestamp
1414
+	 * @throws EE_Error
1415
+	 * @return string timestamp
1416
+	 */
1417
+	public function display_in_my_timezone(
1418
+		$field_name,
1419
+		$callback = 'get_datetime',
1420
+		$args = null,
1421
+		$prepend = '',
1422
+		$append = ''
1423
+	) {
1424
+		$timezone = EEH_DTT_Helper::get_timezone();
1425
+		if ($timezone === $this->_timezone) {
1426
+			return '';
1427
+		}
1428
+		$original_timezone = $this->_timezone;
1429
+		$this->set_timezone($timezone);
1430
+		$fn = (array)$field_name;
1431
+		$args = array_merge($fn, (array)$args);
1432
+		if ( ! method_exists($this, $callback)) {
1433
+			throw new EE_Error(
1434
+				sprintf(
1435
+					__(
1436
+						'The method named "%s" given as the callback param in "display_in_my_timezone" does not exist.  Please check your spelling',
1437
+						'event_espresso'
1438
+					),
1439
+					$callback
1440
+				)
1441
+			);
1442
+		}
1443
+		$args = (array)$args;
1444
+		$return = $prepend . call_user_func_array(array($this, $callback), $args) . $append;
1445
+		$this->set_timezone($original_timezone);
1446
+		return $return;
1447
+	}
1448
+
1449
+
1450
+
1451
+	/**
1452
+	 * Deletes this model object.
1453
+	 * This calls the `EE_Base_Class::_delete` method.  Child classes wishing to change default behaviour should
1454
+	 * override
1455
+	 * `EE_Base_Class::_delete` NOT this class.
1456
+	 *
1457
+	 * @return boolean | int
1458
+	 * @throws \EE_Error
1459
+	 */
1460
+	public function delete()
1461
+	{
1462
+		/**
1463
+		 * Called just before the `EE_Base_Class::_delete` method call.
1464
+		 * Note: `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1465
+		 * should be aware that `_delete` may not always result in a permanent delete.  For example, `EE_Soft_Delete_Base_Class::_delete`
1466
+		 * soft deletes (trash) the object and does not permanently delete it.
1467
+		 *
1468
+		 * @param EE_Base_Class $model_object about to be 'deleted'
1469
+		 */
1470
+		do_action('AHEE__EE_Base_Class__delete__before', $this);
1471
+		$result = $this->_delete();
1472
+		/**
1473
+		 * Called just after the `EE_Base_Class::_delete` method call.
1474
+		 * Note: `EE_Base_Class::_delete` might be overridden by child classes so any client code hooking into these actions
1475
+		 * should be aware that `_delete` may not always result in a permanent delete.  For example `EE_Soft_Base_Class::_delete`
1476
+		 * soft deletes (trash) the object and does not permanently delete it.
1477
+		 *
1478
+		 * @param EE_Base_Class $model_object that was just 'deleted'
1479
+		 * @param boolean       $result
1480
+		 */
1481
+		do_action('AHEE__EE_Base_Class__delete__end', $this, $result);
1482
+		return $result;
1483
+	}
1484
+
1485
+
1486
+
1487
+	/**
1488
+	 * Calls the specific delete method for the instantiated class.
1489
+	 * This method is called by the public `EE_Base_Class::delete` method.  Any child classes desiring to override
1490
+	 * default functionality for "delete" (which is to call `permanently_delete`) should override this method NOT
1491
+	 * `EE_Base_Class::delete`
1492
+	 *
1493
+	 * @return bool|int
1494
+	 * @throws \EE_Error
1495
+	 */
1496
+	protected function _delete()
1497
+	{
1498
+		return $this->delete_permanently();
1499
+	}
1500
+
1501
+
1502
+
1503
+	/**
1504
+	 * Deletes this model object permanently from db (but keep in mind related models my block the delete and return an
1505
+	 * error)
1506
+	 *
1507
+	 * @return bool | int
1508
+	 * @throws \EE_Error
1509
+	 */
1510
+	public function delete_permanently()
1511
+	{
1512
+		/**
1513
+		 * Called just before HARD deleting a model object
1514
+		 *
1515
+		 * @param EE_Base_Class $model_object about to be 'deleted'
1516
+		 */
1517
+		do_action('AHEE__EE_Base_Class__delete_permanently__before', $this);
1518
+		$model = $this->get_model();
1519
+		$result = $model->delete_permanently_by_ID($this->ID());
1520
+		$this->refresh_cache_of_related_objects();
1521
+		/**
1522
+		 * Called just after HARD deleting a model object
1523
+		 *
1524
+		 * @param EE_Base_Class $model_object that was just 'deleted'
1525
+		 * @param boolean       $result
1526
+		 */
1527
+		do_action('AHEE__EE_Base_Class__delete_permanently__end', $this, $result);
1528
+		return $result;
1529
+	}
1530
+
1531
+
1532
+
1533
+	/**
1534
+	 * When this model object is deleted, it may still be cached on related model objects. This clears the cache of
1535
+	 * related model objects
1536
+	 *
1537
+	 * @throws \EE_Error
1538
+	 */
1539
+	public function refresh_cache_of_related_objects()
1540
+	{
1541
+		foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
1542
+			if ( ! empty($this->_model_relations[$relation_name])) {
1543
+				$related_objects = $this->_model_relations[$relation_name];
1544
+				if ($relation_obj instanceof EE_Belongs_To_Relation) {
1545
+					//this relation only stores a single model object, not an array
1546
+					//but let's make it consistent
1547
+					$related_objects = array($related_objects);
1548
+				}
1549
+				foreach ($related_objects as $related_object) {
1550
+					//only refresh their cache if they're in memory
1551
+					if ($related_object instanceof EE_Base_Class) {
1552
+						$related_object->clear_cache($this->get_model()->get_this_model_name(), $this);
1553
+					}
1554
+				}
1555
+			}
1556
+		}
1557
+	}
1558
+
1559
+
1560
+
1561
+	/**
1562
+	 *        Saves this object to the database. An array may be supplied to set some values on this
1563
+	 * object just before saving.
1564
+	 *
1565
+	 * @access public
1566
+	 * @param array $set_cols_n_values keys are field names, values are their new values,
1567
+	 *                                 if provided during the save() method (often client code will change the fields'
1568
+	 *                                 values before calling save)
1569
+	 * @throws \EE_Error
1570
+	 * @return int , 1 on a successful update, the ID of the new entry on insert; 0 on failure or if the model object
1571
+	 *                                 isn't allowed to persist (as determined by EE_Base_Class::allow_persist())
1572
+	 */
1573
+	public function save($set_cols_n_values = array())
1574
+	{
1575
+		/**
1576
+		 * Filters the fields we're about to save on the model object
1577
+		 *
1578
+		 * @param array         $set_cols_n_values
1579
+		 * @param EE_Base_Class $model_object
1580
+		 */
1581
+		$set_cols_n_values = (array)apply_filters('FHEE__EE_Base_Class__save__set_cols_n_values', $set_cols_n_values,
1582
+			$this);
1583
+		//set attributes as provided in $set_cols_n_values
1584
+		foreach ($set_cols_n_values as $column => $value) {
1585
+			$this->set($column, $value);
1586
+		}
1587
+		// no changes ? then don't do anything
1588
+		if (! $this->_has_changes && $this->ID() && $this->get_model()->get_primary_key_field()->is_auto_increment()) {
1589
+			return 0;
1590
+		}
1591
+		/**
1592
+		 * Saving a model object.
1593
+		 * Before we perform a save, this action is fired.
1594
+		 *
1595
+		 * @param EE_Base_Class $model_object the model object about to be saved.
1596
+		 */
1597
+		do_action('AHEE__EE_Base_Class__save__begin', $this);
1598
+		if ( ! $this->allow_persist()) {
1599
+			return 0;
1600
+		}
1601
+		//now get current attribute values
1602
+		$save_cols_n_values = $this->_fields;
1603
+		//if the object already has an ID, update it. Otherwise, insert it
1604
+		//also: change the assumption about values passed to the model NOT being prepare dby the model object. They have been
1605
+		$old_assumption_concerning_value_preparation = $this->get_model()
1606
+															->get_assumption_concerning_values_already_prepared_by_model_object();
1607
+		$this->get_model()->assume_values_already_prepared_by_model_object(true);
1608
+		//does this model have an autoincrement PK?
1609
+		if ($this->get_model()->has_primary_key_field()) {
1610
+			if ($this->get_model()->get_primary_key_field()->is_auto_increment()) {
1611
+				//ok check if it's set, if so: update; if not, insert
1612
+				if ( ! empty($save_cols_n_values[self::_get_primary_key_name(get_class($this))])) {
1613
+					$results = $this->get_model()->update_by_ID($save_cols_n_values, $this->ID());
1614
+				} else {
1615
+					unset($save_cols_n_values[self::_get_primary_key_name(get_class($this))]);
1616
+					$results = $this->get_model()->insert($save_cols_n_values);
1617
+					if ($results) {
1618
+						//if successful, set the primary key
1619
+						//but don't use the normal SET method, because it will check if
1620
+						//an item with the same ID exists in the mapper & db, then
1621
+						//will find it in the db (because we just added it) and THAT object
1622
+						//will get added to the mapper before we can add this one!
1623
+						//but if we just avoid using the SET method, all that headache can be avoided
1624
+						$pk_field_name = self::_get_primary_key_name(get_class($this));
1625
+						$this->_fields[$pk_field_name] = $results;
1626
+						$this->_clear_cached_property($pk_field_name);
1627
+						$this->get_model()->add_to_entity_map($this);
1628
+						$this->_update_cached_related_model_objs_fks();
1629
+					}
1630
+				}
1631
+			} else {//PK is NOT auto-increment
1632
+				//so check if one like it already exists in the db
1633
+				if ($this->get_model()->exists_by_ID($this->ID())) {
1634
+					if (WP_DEBUG && ! $this->in_entity_map()) {
1635
+						throw new EE_Error(
1636
+							sprintf(
1637
+								__('Using a model object %1$s that is NOT in the entity map, can lead to unexpected errors. You should either: %4$s 1. Put it in the entity mapper by calling %2$s %4$s 2. Discard this model object and use what is in the entity mapper %4$s 3. Fetch from the database using %3$s',
1638
+									'event_espresso'),
1639
+								get_class($this),
1640
+								get_class($this->get_model()) . '::instance()->add_to_entity_map()',
1641
+								get_class($this->get_model()) . '::instance()->get_one_by_ID()',
1642
+								'<br />'
1643
+							)
1644
+						);
1645
+					}
1646
+					$results = $this->get_model()->update_by_ID($save_cols_n_values, $this->ID());
1647
+				} else {
1648
+					$results = $this->get_model()->insert($save_cols_n_values);
1649
+					$this->_update_cached_related_model_objs_fks();
1650
+				}
1651
+			}
1652
+		} else {//there is NO primary key
1653
+			$already_in_db = false;
1654
+			foreach ($this->get_model()->unique_indexes() as $index) {
1655
+				$uniqueness_where_params = array_intersect_key($save_cols_n_values, $index->fields());
1656
+				if ($this->get_model()->exists(array($uniqueness_where_params))) {
1657
+					$already_in_db = true;
1658
+				}
1659
+			}
1660
+			if ($already_in_db) {
1661
+				$combined_pk_fields_n_values = array_intersect_key($save_cols_n_values,
1662
+					$this->get_model()->get_combined_primary_key_fields());
1663
+				$results = $this->get_model()->update($save_cols_n_values, $combined_pk_fields_n_values);
1664
+			} else {
1665
+				$results = $this->get_model()->insert($save_cols_n_values);
1666
+			}
1667
+		}
1668
+		//restore the old assumption about values being prepared by the model object
1669
+		$this->get_model()
1670
+			 ->assume_values_already_prepared_by_model_object($old_assumption_concerning_value_preparation);
1671
+		/**
1672
+		 * After saving the model object this action is called
1673
+		 *
1674
+		 * @param EE_Base_Class $model_object which was just saved
1675
+		 * @param boolean|int   $results      if it were updated, TRUE or FALSE; if it were newly inserted
1676
+		 *                                    the new ID (or 0 if an error occurred and it wasn't updated)
1677
+		 */
1678
+		do_action('AHEE__EE_Base_Class__save__end', $this, $results);
1679
+		$this->_has_changes = false;
1680
+		return $results;
1681
+	}
1682
+
1683
+
1684
+
1685
+	/**
1686
+	 * Updates the foreign key on related models objects pointing to this to have this model object's ID
1687
+	 * as their foreign key.  If the cached related model objects already exist in the db, saves them (so that the DB
1688
+	 * is consistent) Especially useful in case we JUST added this model object ot the database and we want to let its
1689
+	 * cached relations with foreign keys to it know about that change. Eg: we've created a transaction but haven't
1690
+	 * saved it to the db. We also create a registration and don't save it to the DB, but we DO cache it on the
1691
+	 * transaction. Now, when we save the transaction, the registration's TXN_ID will be automatically updated, whether
1692
+	 * or not they exist in the DB (if they do, their DB records will be automatically updated)
1693
+	 *
1694
+	 * @return void
1695
+	 * @throws \EE_Error
1696
+	 */
1697
+	protected function _update_cached_related_model_objs_fks()
1698
+	{
1699
+		foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
1700
+			if ($relation_obj instanceof EE_Has_Many_Relation) {
1701
+				foreach ($this->get_all_from_cache($relation_name) as $related_model_obj_in_cache) {
1702
+					$fk_to_this = $related_model_obj_in_cache->get_model()->get_foreign_key_to(
1703
+						$this->get_model()->get_this_model_name()
1704
+					);
1705
+					$related_model_obj_in_cache->set($fk_to_this->get_name(), $this->ID());
1706
+					if ($related_model_obj_in_cache->ID()) {
1707
+						$related_model_obj_in_cache->save();
1708
+					}
1709
+				}
1710
+			}
1711
+		}
1712
+	}
1713
+
1714
+
1715
+
1716
+	/**
1717
+	 * Saves this model object and its NEW cached relations to the database.
1718
+	 * (Meaning, for now, IT DOES NOT WORK if the cached items already exist in the DB.
1719
+	 * In order for that to work, we would need to mark model objects as dirty/clean...
1720
+	 * because otherwise, there's a potential for infinite looping of saving
1721
+	 * Saves the cached related model objects, and ensures the relation between them
1722
+	 * and this object and properly setup
1723
+	 *
1724
+	 * @return int ID of new model object on save; 0 on failure+
1725
+	 * @throws \EE_Error
1726
+	 */
1727
+	public function save_new_cached_related_model_objs()
1728
+	{
1729
+		//make sure this has been saved
1730
+		if ( ! $this->ID()) {
1731
+			$id = $this->save();
1732
+		} else {
1733
+			$id = $this->ID();
1734
+		}
1735
+		//now save all the NEW cached model objects  (ie they don't exist in the DB)
1736
+		foreach ($this->get_model()->relation_settings() as $relationName => $relationObj) {
1737
+			if ($this->_model_relations[$relationName]) {
1738
+				//is this a relation where we should expect just ONE related object (ie, EE_Belongs_To_relation)
1739
+				//or MANY related objects (ie, EE_HABTM_Relation or EE_Has_Many_Relation)?
1740
+				if ($relationObj instanceof EE_Belongs_To_Relation) {
1741
+					//add a relation to that relation type (which saves the appropriate thing in the process)
1742
+					//but ONLY if it DOES NOT exist in the DB
1743
+					/* @var $related_model_obj EE_Base_Class */
1744
+					$related_model_obj = $this->_model_relations[$relationName];
1745
+					//					if( ! $related_model_obj->ID()){
1746
+					$this->_add_relation_to($related_model_obj, $relationName);
1747
+					$related_model_obj->save_new_cached_related_model_objs();
1748
+					//					}
1749
+				} else {
1750
+					foreach ($this->_model_relations[$relationName] as $related_model_obj) {
1751
+						//add a relation to that relation type (which saves the appropriate thing in the process)
1752
+						//but ONLY if it DOES NOT exist in the DB
1753
+						//						if( ! $related_model_obj->ID()){
1754
+						$this->_add_relation_to($related_model_obj, $relationName);
1755
+						$related_model_obj->save_new_cached_related_model_objs();
1756
+						//						}
1757
+					}
1758
+				}
1759
+			}
1760
+		}
1761
+		return $id;
1762
+	}
1763
+
1764
+
1765
+
1766
+	/**
1767
+	 * for getting a model while instantiated.
1768
+	 *
1769
+	 * @return \EEM_Base | \EEM_CPT_Base
1770
+	 */
1771
+	public function get_model()
1772
+	{
1773
+		$modelName = self::_get_model_classname(get_class($this));
1774
+		return self::_get_model_instance_with_name($modelName, $this->_timezone);
1775
+	}
1776
+
1777
+
1778
+
1779
+	/**
1780
+	 * @param $props_n_values
1781
+	 * @param $classname
1782
+	 * @return mixed bool|EE_Base_Class|EEM_CPT_Base
1783
+	 * @throws \EE_Error
1784
+	 */
1785
+	protected static function _get_object_from_entity_mapper($props_n_values, $classname)
1786
+	{
1787
+		//TODO: will not work for Term_Relationships because they have no PK!
1788
+		$primary_id_ref = self::_get_primary_key_name($classname);
1789
+		if (array_key_exists($primary_id_ref, $props_n_values) && ! empty($props_n_values[$primary_id_ref])) {
1790
+			$id = $props_n_values[$primary_id_ref];
1791
+			return self::_get_model($classname)->get_from_entity_map($id);
1792
+		}
1793
+		return false;
1794
+	}
1795
+
1796
+
1797
+
1798
+	/**
1799
+	 * This is called by child static "new_instance" method and we'll check to see if there is an existing db entry for
1800
+	 * the primary key (if present in incoming values). If there is a key in the incoming array that matches the
1801
+	 * primary key for the model AND it is not null, then we check the db. If there's a an object we return it.  If not
1802
+	 * we return false.
1803
+	 *
1804
+	 * @param  array  $props_n_values   incoming array of properties and their values
1805
+	 * @param  string $classname        the classname of the child class
1806
+	 * @param null    $timezone
1807
+	 * @param array   $date_formats     incoming date_formats in an array where the first value is the
1808
+	 *                                  date_format and the second value is the time format
1809
+	 * @return mixed (EE_Base_Class|bool)
1810
+	 * @throws \EE_Error
1811
+	 */
1812
+	protected static function _check_for_object($props_n_values, $classname, $timezone = null, $date_formats = array())
1813
+	{
1814
+		$existing = null;
1815
+		if (self::_get_model($classname)->has_primary_key_field()) {
1816
+			$primary_id_ref = self::_get_primary_key_name($classname);
1817
+			if (array_key_exists($primary_id_ref, $props_n_values)
1818
+				&& ! empty($props_n_values[$primary_id_ref])
1819
+			) {
1820
+				$existing = self::_get_model($classname, $timezone)->get_one_by_ID(
1821
+					$props_n_values[$primary_id_ref]
1822
+				);
1823
+			}
1824
+		} elseif (self::_get_model($classname, $timezone)->has_all_combined_primary_key_fields($props_n_values)) {
1825
+			//no primary key on this model, but there's still a matching item in the DB
1826
+			$existing = self::_get_model($classname, $timezone)->get_one_by_ID(
1827
+				self::_get_model($classname, $timezone)->get_index_primary_key_string($props_n_values)
1828
+			);
1829
+		}
1830
+		if ($existing) {
1831
+			//set date formats if present before setting values
1832
+			if ( ! empty($date_formats) && is_array($date_formats)) {
1833
+				$existing->set_date_format($date_formats[0]);
1834
+				$existing->set_time_format($date_formats[1]);
1835
+			} else {
1836
+				//set default formats for date and time
1837
+				$existing->set_date_format(get_option('date_format'));
1838
+				$existing->set_time_format(get_option('time_format'));
1839
+			}
1840
+			foreach ($props_n_values as $property => $field_value) {
1841
+				$existing->set($property, $field_value);
1842
+			}
1843
+			return $existing;
1844
+		} else {
1845
+			return false;
1846
+		}
1847
+	}
1848
+
1849
+
1850
+
1851
+	/**
1852
+	 * Gets the EEM_*_Model for this class
1853
+	 *
1854
+	 * @access public now, as this is more convenient
1855
+	 * @param      $classname
1856
+	 * @param null $timezone
1857
+	 * @throws EE_Error
1858
+	 * @return EEM_Base
1859
+	 */
1860
+	protected static function _get_model($classname, $timezone = null)
1861
+	{
1862
+		//find model for this class
1863
+		if ( ! $classname) {
1864
+			throw new EE_Error(
1865
+				sprintf(
1866
+					__(
1867
+						"What were you thinking calling _get_model(%s)?? You need to specify the class name",
1868
+						"event_espresso"
1869
+					),
1870
+					$classname
1871
+				)
1872
+			);
1873
+		}
1874
+		$modelName = self::_get_model_classname($classname);
1875
+		return self::_get_model_instance_with_name($modelName, $timezone);
1876
+	}
1877
+
1878
+
1879
+
1880
+	/**
1881
+	 * Gets the model instance (eg instance of EEM_Attendee) given its classname (eg EE_Attendee)
1882
+	 *
1883
+	 * @param string $model_classname
1884
+	 * @param null   $timezone
1885
+	 * @return EEM_Base
1886
+	 */
1887
+	protected static function _get_model_instance_with_name($model_classname, $timezone = null)
1888
+	{
1889
+		$model_classname = str_replace('EEM_', '', $model_classname);
1890
+		$model = EE_Registry::instance()->load_model($model_classname);
1891
+		$model->set_timezone($timezone);
1892
+		return $model;
1893
+	}
1894
+
1895
+
1896
+
1897
+	/**
1898
+	 * If a model name is provided (eg Registration), gets the model classname for that model.
1899
+	 * Also works if a model class's classname is provided (eg EE_Registration).
1900
+	 *
1901
+	 * @param null $model_name
1902
+	 * @return string like EEM_Attendee
1903
+	 */
1904
+	private static function _get_model_classname($model_name = null)
1905
+	{
1906
+		if (strpos($model_name, "EE_") === 0) {
1907
+			$model_classname = str_replace("EE_", "EEM_", $model_name);
1908
+		} else {
1909
+			$model_classname = "EEM_" . $model_name;
1910
+		}
1911
+		return $model_classname;
1912
+	}
1913
+
1914
+
1915
+
1916
+	/**
1917
+	 * returns the name of the primary key attribute
1918
+	 *
1919
+	 * @param null $classname
1920
+	 * @throws EE_Error
1921
+	 * @return string
1922
+	 */
1923
+	protected static function _get_primary_key_name($classname = null)
1924
+	{
1925
+		if ( ! $classname) {
1926
+			throw new EE_Error(
1927
+				sprintf(
1928
+					__("What were you thinking calling _get_primary_key_name(%s)", "event_espresso"),
1929
+					$classname
1930
+				)
1931
+			);
1932
+		}
1933
+		return self::_get_model($classname)->get_primary_key_field()->get_name();
1934
+	}
1935
+
1936
+
1937
+
1938
+	/**
1939
+	 * Gets the value of the primary key.
1940
+	 * If the object hasn't yet been saved, it should be whatever the model field's default was
1941
+	 * (eg, if this were the EE_Event class, look at the primary key field on EEM_Event and see what its default value
1942
+	 * is. Usually defaults for integer primary keys are 0; string primary keys are usually NULL).
1943
+	 *
1944
+	 * @return mixed, if the primary key is of type INT it'll be an int. Otherwise it could be a string
1945
+	 * @throws \EE_Error
1946
+	 */
1947
+	public function ID()
1948
+	{
1949
+		//now that we know the name of the variable, use a variable variable to get its value and return its
1950
+		if ($this->get_model()->has_primary_key_field()) {
1951
+			return $this->_fields[self::_get_primary_key_name(get_class($this))];
1952
+		} else {
1953
+			return $this->get_model()->get_index_primary_key_string($this->_fields);
1954
+		}
1955
+	}
1956
+
1957
+
1958
+
1959
+	/**
1960
+	 * Adds a relationship to the specified EE_Base_Class object, given the relationship's name. Eg, if the current
1961
+	 * model is related to a group of events, the $relationName should be 'Event', and should be a key in the EE
1962
+	 * Model's $_model_relations array. If this model object doesn't exist in the DB, just caches the related thing
1963
+	 *
1964
+	 * @param mixed  $otherObjectModelObjectOrID       EE_Base_Class or the ID of the other object
1965
+	 * @param string $relationName                     eg 'Events','Question',etc.
1966
+	 *                                                 an attendee to a group, you also want to specify which role they
1967
+	 *                                                 will have in that group. So you would use this parameter to
1968
+	 *                                                 specify array('role-column-name'=>'role-id')
1969
+	 * @param array  $extra_join_model_fields_n_values You can optionally include an array of key=>value pairs that
1970
+	 *                                                 allow you to further constrict the relation to being added.
1971
+	 *                                                 However, keep in mind that the columns (keys) given must match a
1972
+	 *                                                 column on the JOIN table and currently only the HABTM models
1973
+	 *                                                 accept these additional conditions.  Also remember that if an
1974
+	 *                                                 exact match isn't found for these extra cols/val pairs, then a
1975
+	 *                                                 NEW row is created in the join table.
1976
+	 * @param null   $cache_id
1977
+	 * @throws EE_Error
1978
+	 * @return EE_Base_Class the object the relation was added to
1979
+	 */
1980
+	public function _add_relation_to(
1981
+		$otherObjectModelObjectOrID,
1982
+		$relationName,
1983
+		$extra_join_model_fields_n_values = array(),
1984
+		$cache_id = null
1985
+	) {
1986
+		//if this thing exists in the DB, save the relation to the DB
1987
+		if ($this->ID()) {
1988
+			$otherObject = $this->get_model()
1989
+								->add_relationship_to($this, $otherObjectModelObjectOrID, $relationName,
1990
+									$extra_join_model_fields_n_values);
1991
+			//clear cache so future get_many_related and get_first_related() return new results.
1992
+			$this->clear_cache($relationName, $otherObject, true);
1993
+			if ($otherObject instanceof EE_Base_Class) {
1994
+				$otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
1995
+			}
1996
+		} else {
1997
+			//this thing doesn't exist in the DB,  so just cache it
1998
+			if ( ! $otherObjectModelObjectOrID instanceof EE_Base_Class) {
1999
+				throw new EE_Error(sprintf(
2000
+					__('Before a model object is saved to the database, calls to _add_relation_to must be passed an actual object, not just an ID. You provided %s as the model object to a %s',
2001
+						'event_espresso'),
2002
+					$otherObjectModelObjectOrID,
2003
+					get_class($this)
2004
+				));
2005
+			} else {
2006
+				$otherObject = $otherObjectModelObjectOrID;
2007
+			}
2008
+			$this->cache($relationName, $otherObjectModelObjectOrID, $cache_id);
2009
+		}
2010
+		if ($otherObject instanceof EE_Base_Class) {
2011
+			//fix the reciprocal relation too
2012
+			if ($otherObject->ID()) {
2013
+				//its saved so assumed relations exist in the DB, so we can just
2014
+				//clear the cache so future queries use the updated info in the DB
2015
+				$otherObject->clear_cache($this->get_model()->get_this_model_name(), null, true);
2016
+			} else {
2017
+				//it's not saved, so it caches relations like this
2018
+				$otherObject->cache($this->get_model()->get_this_model_name(), $this);
2019
+			}
2020
+		}
2021
+		return $otherObject;
2022
+	}
2023
+
2024
+
2025
+
2026
+	/**
2027
+	 * Removes a relationship to the specified EE_Base_Class object, given the relationships' name. Eg, if the current
2028
+	 * model is related to a group of events, the $relationName should be 'Events', and should be a key in the EE
2029
+	 * Model's $_model_relations array. If this model object doesn't exist in the DB, just removes the related thing
2030
+	 * from the cache
2031
+	 *
2032
+	 * @param mixed  $otherObjectModelObjectOrID
2033
+	 *                EE_Base_Class or the ID of the other object, OR an array key into the cache if this isn't saved
2034
+	 *                to the DB yet
2035
+	 * @param string $relationName
2036
+	 * @param array  $where_query
2037
+	 *                You can optionally include an array of key=>value pairs that allow you to further constrict the
2038
+	 *                relation to being added. However, keep in mind that the columns (keys) given must match a column
2039
+	 *                on the JOIN table and currently only the HABTM models accept these additional conditions. Also
2040
+	 *                remember that if an exact match isn't found for these extra cols/val pairs, then a NEW row is
2041
+	 *                created in the join table.
2042
+	 * @return EE_Base_Class the relation was removed from
2043
+	 * @throws \EE_Error
2044
+	 */
2045
+	public function _remove_relation_to($otherObjectModelObjectOrID, $relationName, $where_query = array())
2046
+	{
2047
+		if ($this->ID()) {
2048
+			//if this exists in the DB, save the relation change to the DB too
2049
+			$otherObject = $this->get_model()
2050
+								->remove_relationship_to($this, $otherObjectModelObjectOrID, $relationName,
2051
+									$where_query);
2052
+			$this->clear_cache($relationName, $otherObject);
2053
+		} else {
2054
+			//this doesn't exist in the DB, just remove it from the cache
2055
+			$otherObject = $this->clear_cache($relationName, $otherObjectModelObjectOrID);
2056
+		}
2057
+		if ($otherObject instanceof EE_Base_Class) {
2058
+			$otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
2059
+		}
2060
+		return $otherObject;
2061
+	}
2062
+
2063
+
2064
+
2065
+	/**
2066
+	 * Removes ALL the related things for the $relationName.
2067
+	 *
2068
+	 * @param string $relationName
2069
+	 * @param array  $where_query_params like EEM_Base::get_all's $query_params[0] (where conditions)
2070
+	 * @return EE_Base_Class
2071
+	 * @throws \EE_Error
2072
+	 */
2073
+	public function _remove_relations($relationName, $where_query_params = array())
2074
+	{
2075
+		if ($this->ID()) {
2076
+			//if this exists in the DB, save the relation change to the DB too
2077
+			$otherObjects = $this->get_model()->remove_relations($this, $relationName, $where_query_params);
2078
+			$this->clear_cache($relationName, null, true);
2079
+		} else {
2080
+			//this doesn't exist in the DB, just remove it from the cache
2081
+			$otherObjects = $this->clear_cache($relationName, null, true);
2082
+		}
2083
+		if (is_array($otherObjects)) {
2084
+			foreach ($otherObjects as $otherObject) {
2085
+				$otherObject->clear_cache($this->get_model()->get_this_model_name(), $this);
2086
+			}
2087
+		}
2088
+		return $otherObjects;
2089
+	}
2090
+
2091
+
2092
+
2093
+	/**
2094
+	 * Gets all the related model objects of the specified type. Eg, if the current class if
2095
+	 * EE_Event, you could call $this->get_many_related('Registration') to get an array of all the
2096
+	 * EE_Registration objects which related to this event. Note: by default, we remove the "default query params"
2097
+	 * because we want to get even deleted items etc.
2098
+	 *
2099
+	 * @param string $relationName key in the model's _model_relations array
2100
+	 * @param array  $query_params like EEM_Base::get_all
2101
+	 * @return EE_Base_Class[] Results not necessarily indexed by IDs, because some results might not have primary keys
2102
+	 * @throws \EE_Error
2103
+	 *                             or might not be saved yet. Consider using EEM_Base::get_IDs() on these results if
2104
+	 *                             you want IDs
2105
+	 */
2106
+	public function get_many_related($relationName, $query_params = array())
2107
+	{
2108
+		if ($this->ID()) {
2109
+			//this exists in the DB, so get the related things from either the cache or the DB
2110
+			//if there are query parameters, forget about caching the related model objects.
2111
+			if ($query_params) {
2112
+				$related_model_objects = $this->get_model()->get_all_related($this, $relationName, $query_params);
2113
+			} else {
2114
+				//did we already cache the result of this query?
2115
+				$cached_results = $this->get_all_from_cache($relationName);
2116
+				if ( ! $cached_results) {
2117
+					$related_model_objects = $this->get_model()->get_all_related($this, $relationName, $query_params);
2118
+					//if no query parameters were passed, then we got all the related model objects
2119
+					//for that relation. We can cache them then.
2120
+					foreach ($related_model_objects as $related_model_object) {
2121
+						$this->cache($relationName, $related_model_object);
2122
+					}
2123
+				} else {
2124
+					$related_model_objects = $cached_results;
2125
+				}
2126
+			}
2127
+		} else {
2128
+			//this doesn't exist in the DB, so just get the related things from the cache
2129
+			$related_model_objects = $this->get_all_from_cache($relationName);
2130
+		}
2131
+		return $related_model_objects;
2132
+	}
2133
+
2134
+
2135
+
2136
+	/**
2137
+	 * Instead of getting the related model objects, simply counts them. Ignores default_where_conditions by default,
2138
+	 * unless otherwise specified in the $query_params
2139
+	 *
2140
+	 * @param string $relation_name  model_name like 'Event', or 'Registration'
2141
+	 * @param array  $query_params   like EEM_Base::get_all's
2142
+	 * @param string $field_to_count name of field to count by. By default, uses primary key
2143
+	 * @param bool   $distinct       if we want to only count the distinct values for the column then you can trigger
2144
+	 *                               that by the setting $distinct to TRUE;
2145
+	 * @return int
2146
+	 */
2147
+	public function count_related($relation_name, $query_params = array(), $field_to_count = null, $distinct = false)
2148
+	{
2149
+		return $this->get_model()->count_related($this, $relation_name, $query_params, $field_to_count, $distinct);
2150
+	}
2151
+
2152
+
2153
+
2154
+	/**
2155
+	 * Instead of getting the related model objects, simply sums up the values of the specified field.
2156
+	 * Note: ignores default_where_conditions by default, unless otherwise specified in the $query_params
2157
+	 *
2158
+	 * @param string $relation_name model_name like 'Event', or 'Registration'
2159
+	 * @param array  $query_params  like EEM_Base::get_all's
2160
+	 * @param string $field_to_sum  name of field to count by.
2161
+	 *                              By default, uses primary key (which doesn't make much sense, so you should probably
2162
+	 *                              change it)
2163
+	 * @return int
2164
+	 */
2165
+	public function sum_related($relation_name, $query_params = array(), $field_to_sum = null)
2166
+	{
2167
+		return $this->get_model()->sum_related($this, $relation_name, $query_params, $field_to_sum);
2168
+	}
2169
+
2170
+
2171
+
2172
+	/**
2173
+	 * Gets the first (ie, one) related model object of the specified type.
2174
+	 *
2175
+	 * @param string $relationName key in the model's _model_relations array
2176
+	 * @param array  $query_params like EEM_Base::get_all
2177
+	 * @return EE_Base_Class (not an array, a single object)
2178
+	 * @throws \EE_Error
2179
+	 */
2180
+	public function get_first_related($relationName, $query_params = array())
2181
+	{
2182
+		if ($this->ID()) {//this exists in the DB, get from the cache OR the DB
2183
+			//if they've provided some query parameters, don't bother trying to cache the result
2184
+			//also make sure we're not caching the result of get_first_related
2185
+			//on a relation which should have an array of objects (because the cache might have an array of objects)
2186
+			if ($query_params
2187
+				|| ! $this->get_model()->related_settings_for($relationName)
2188
+					 instanceof
2189
+					 EE_Belongs_To_Relation
2190
+			) {
2191
+				$related_model_object = $this->get_model()->get_first_related($this, $relationName, $query_params);
2192
+			} else {
2193
+				//first, check if we've already cached the result of this query
2194
+				$cached_result = $this->get_one_from_cache($relationName);
2195
+				if ( ! $cached_result) {
2196
+					$related_model_object = $this->get_model()->get_first_related($this, $relationName, $query_params);
2197
+					$this->cache($relationName, $related_model_object);
2198
+				} else {
2199
+					$related_model_object = $cached_result;
2200
+				}
2201
+			}
2202
+		} else {
2203
+			$related_model_object = null;
2204
+			//this doesn't exist in the Db, but maybe the relation is of type belongs to, and so the related thing might
2205
+			if ($this->get_model()->related_settings_for($relationName) instanceof EE_Belongs_To_Relation) {
2206
+				$related_model_object = $this->get_model()->get_first_related($this, $relationName, $query_params);
2207
+			}
2208
+			//this doesn't exist in the DB and apparently the thing it belongs to doesn't either, just get what's cached on this object
2209
+			if ( ! $related_model_object) {
2210
+				$related_model_object = $this->get_one_from_cache($relationName);
2211
+			}
2212
+		}
2213
+		return $related_model_object;
2214
+	}
2215
+
2216
+
2217
+
2218
+	/**
2219
+	 * Does a delete on all related objects of type $relationName and removes
2220
+	 * the current model object's relation to them. If they can't be deleted (because
2221
+	 * of blocking related model objects) does nothing. If the related model objects are
2222
+	 * soft-deletable, they will be soft-deleted regardless of related blocking model objects.
2223
+	 * If this model object doesn't exist yet in the DB, just removes its related things
2224
+	 *
2225
+	 * @param string $relationName
2226
+	 * @param array  $query_params like EEM_Base::get_all's
2227
+	 * @return int how many deleted
2228
+	 * @throws \EE_Error
2229
+	 */
2230
+	public function delete_related($relationName, $query_params = array())
2231
+	{
2232
+		if ($this->ID()) {
2233
+			$count = $this->get_model()->delete_related($this, $relationName, $query_params);
2234
+		} else {
2235
+			$count = count($this->get_all_from_cache($relationName));
2236
+			$this->clear_cache($relationName, null, true);
2237
+		}
2238
+		return $count;
2239
+	}
2240
+
2241
+
2242
+
2243
+	/**
2244
+	 * Does a hard delete (ie, removes the DB row) on all related objects of type $relationName and removes
2245
+	 * the current model object's relation to them. If they can't be deleted (because
2246
+	 * of blocking related model objects) just does a soft delete on it instead, if possible.
2247
+	 * If the related thing isn't a soft-deletable model object, this function is identical
2248
+	 * to delete_related(). If this model object doesn't exist in the DB, just remove its related things
2249
+	 *
2250
+	 * @param string $relationName
2251
+	 * @param array  $query_params like EEM_Base::get_all's
2252
+	 * @return int how many deleted (including those soft deleted)
2253
+	 * @throws \EE_Error
2254
+	 */
2255
+	public function delete_related_permanently($relationName, $query_params = array())
2256
+	{
2257
+		if ($this->ID()) {
2258
+			$count = $this->get_model()->delete_related_permanently($this, $relationName, $query_params);
2259
+		} else {
2260
+			$count = count($this->get_all_from_cache($relationName));
2261
+		}
2262
+		$this->clear_cache($relationName, null, true);
2263
+		return $count;
2264
+	}
2265
+
2266
+
2267
+
2268
+	/**
2269
+	 * is_set
2270
+	 * Just a simple utility function children can use for checking if property exists
2271
+	 *
2272
+	 * @access  public
2273
+	 * @param  string $field_name property to check
2274
+	 * @return bool                              TRUE if existing,FALSE if not.
2275
+	 */
2276
+	public function is_set($field_name)
2277
+	{
2278
+		return isset($this->_fields[$field_name]);
2279
+	}
2280
+
2281
+
2282
+
2283
+	/**
2284
+	 * Just a simple utility function children can use for checking if property (or properties) exists and throwing an
2285
+	 * EE_Error exception if they don't
2286
+	 *
2287
+	 * @param  mixed (string|array) $properties properties to check
2288
+	 * @throws EE_Error
2289
+	 * @return bool                              TRUE if existing, throw EE_Error if not.
2290
+	 */
2291
+	protected function _property_exists($properties)
2292
+	{
2293
+		foreach ((array)$properties as $property_name) {
2294
+			//first make sure this property exists
2295
+			if ( ! $this->_fields[$property_name]) {
2296
+				throw new EE_Error(
2297
+					sprintf(
2298
+						__(
2299
+							'Trying to retrieve a non-existent property (%s).  Double check the spelling please',
2300
+							'event_espresso'
2301
+						),
2302
+						$property_name
2303
+					)
2304
+				);
2305
+			}
2306
+		}
2307
+		return true;
2308
+	}
2309
+
2310
+
2311
+
2312
+	/**
2313
+	 * This simply returns an array of model fields for this object
2314
+	 *
2315
+	 * @return array
2316
+	 * @throws \EE_Error
2317
+	 */
2318
+	public function model_field_array()
2319
+	{
2320
+		$fields = $this->get_model()->field_settings(false);
2321
+		$properties = array();
2322
+		//remove prepended underscore
2323
+		foreach ($fields as $field_name => $settings) {
2324
+			$properties[$field_name] = $this->get($field_name);
2325
+		}
2326
+		return $properties;
2327
+	}
2328
+
2329
+
2330
+
2331
+	/**
2332
+	 * Very handy general function to allow for plugins to extend any child of EE_Base_Class.
2333
+	 * If a method is called on a child of EE_Base_Class that doesn't exist, this function is called
2334
+	 * (http://www.garfieldtech.com/blog/php-magic-call) and passed the method's name and arguments. Instead of
2335
+	 * requiring a plugin to extend the EE_Base_Class (which works fine is there's only 1 plugin, but when will that
2336
+	 * happen?) they can add a hook onto 'filters_hook_espresso__{className}__{methodName}' (eg,
2337
+	 * filters_hook_espresso__EE_Answer__my_great_function) and accepts 2 arguments: the object on which the function
2338
+	 * was called, and an array of the original arguments passed to the function. Whatever their callback function
2339
+	 * returns will be returned by this function. Example: in functions.php (or in a plugin):
2340
+	 * add_filter('FHEE__EE_Answer__my_callback','my_callback',10,3); function
2341
+	 * my_callback($previousReturnValue,EE_Base_Class $object,$argsArray){
2342
+	 * $returnString= "you called my_callback! and passed args:".implode(",",$argsArray);
2343
+	 *        return $previousReturnValue.$returnString;
2344
+	 * }
2345
+	 * require('EE_Answer.class.php');
2346
+	 * $answer= EE_Answer::new_instance(array('REG_ID' => 2,'QST_ID' => 3,'ANS_value' => The answer is 42'));
2347
+	 * echo $answer->my_callback('monkeys',100);
2348
+	 * //will output "you called my_callback! and passed args:monkeys,100"
2349
+	 *
2350
+	 * @param string $methodName name of method which was called on a child of EE_Base_Class, but which
2351
+	 * @param array  $args       array of original arguments passed to the function
2352
+	 * @throws EE_Error
2353
+	 * @return mixed whatever the plugin which calls add_filter decides
2354
+	 */
2355
+	public function __call($methodName, $args)
2356
+	{
2357
+		$className = get_class($this);
2358
+		$tagName = "FHEE__{$className}__{$methodName}";
2359
+		if ( ! has_filter($tagName)) {
2360
+			throw new EE_Error(
2361
+				sprintf(
2362
+					__(
2363
+						"Method %s on class %s does not exist! You can create one with the following code in functions.php or in a plugin: add_filter('%s','my_callback',10,3);function my_callback(\$previousReturnValue,EE_Base_Class \$object, \$argsArray){/*function body*/return \$whatever;}",
2364
+						"event_espresso"
2365
+					),
2366
+					$methodName,
2367
+					$className,
2368
+					$tagName
2369
+				)
2370
+			);
2371
+		}
2372
+		return apply_filters($tagName, null, $this, $args);
2373
+	}
2374
+
2375
+
2376
+
2377
+	/**
2378
+	 * Similar to insert_post_meta, adds a record in the Extra_Meta model's table with the given key and value.
2379
+	 * A $previous_value can be specified in case there are many meta rows with the same key
2380
+	 *
2381
+	 * @param string $meta_key
2382
+	 * @param mixed  $meta_value
2383
+	 * @param mixed  $previous_value
2384
+	 * @return bool|int # of records updated (or BOOLEAN if we actually ended up inserting the extra meta row)
2385
+	 * @throws \EE_Error
2386
+	 * NOTE: if the values haven't changed, returns 0
2387
+	 */
2388
+	public function update_extra_meta($meta_key, $meta_value, $previous_value = null)
2389
+	{
2390
+		$query_params = array(
2391
+			array(
2392
+				'EXM_key'  => $meta_key,
2393
+				'OBJ_ID'   => $this->ID(),
2394
+				'EXM_type' => $this->get_model()->get_this_model_name(),
2395
+			),
2396
+		);
2397
+		if ($previous_value !== null) {
2398
+			$query_params[0]['EXM_value'] = $meta_value;
2399
+		}
2400
+		$existing_rows_like_that = EEM_Extra_Meta::instance()->get_all($query_params);
2401
+		if ( ! $existing_rows_like_that) {
2402
+			return $this->add_extra_meta($meta_key, $meta_value);
2403
+		}
2404
+		foreach ($existing_rows_like_that as $existing_row) {
2405
+			$existing_row->save(array('EXM_value' => $meta_value));
2406
+		}
2407
+		return count($existing_rows_like_that);
2408
+	}
2409
+
2410
+
2411
+
2412
+	/**
2413
+	 * Adds a new extra meta record. If $unique is set to TRUE, we'll first double-check
2414
+	 * no other extra meta for this model object have the same key. Returns TRUE if the
2415
+	 * extra meta row was entered, false if not
2416
+	 *
2417
+	 * @param string  $meta_key
2418
+	 * @param string  $meta_value
2419
+	 * @param boolean $unique
2420
+	 * @return boolean
2421
+	 * @throws \EE_Error
2422
+	 */
2423
+	public function add_extra_meta($meta_key, $meta_value, $unique = false)
2424
+	{
2425
+		if ($unique) {
2426
+			$existing_extra_meta = EEM_Extra_Meta::instance()->get_one(
2427
+				array(
2428
+					array(
2429
+						'EXM_key'  => $meta_key,
2430
+						'OBJ_ID'   => $this->ID(),
2431
+						'EXM_type' => $this->get_model()->get_this_model_name(),
2432
+					),
2433
+				)
2434
+			);
2435
+			if ($existing_extra_meta) {
2436
+				return false;
2437
+			}
2438
+		}
2439
+		$new_extra_meta = EE_Extra_Meta::new_instance(
2440
+			array(
2441
+				'EXM_key'   => $meta_key,
2442
+				'EXM_value' => $meta_value,
2443
+				'OBJ_ID'    => $this->ID(),
2444
+				'EXM_type'  => $this->get_model()->get_this_model_name(),
2445
+			)
2446
+		);
2447
+		$new_extra_meta->save();
2448
+		return true;
2449
+	}
2450
+
2451
+
2452
+
2453
+	/**
2454
+	 * Deletes all the extra meta rows for this record as specified by key. If $meta_value
2455
+	 * is specified, only deletes extra meta records with that value.
2456
+	 *
2457
+	 * @param string $meta_key
2458
+	 * @param string $meta_value
2459
+	 * @return int number of extra meta rows deleted
2460
+	 * @throws \EE_Error
2461
+	 */
2462
+	public function delete_extra_meta($meta_key, $meta_value = null)
2463
+	{
2464
+		$query_params = array(
2465
+			array(
2466
+				'EXM_key'  => $meta_key,
2467
+				'OBJ_ID'   => $this->ID(),
2468
+				'EXM_type' => $this->get_model()->get_this_model_name(),
2469
+			),
2470
+		);
2471
+		if ($meta_value !== null) {
2472
+			$query_params[0]['EXM_value'] = $meta_value;
2473
+		}
2474
+		return EEM_Extra_Meta::instance()->delete($query_params);
2475
+	}
2476
+
2477
+
2478
+
2479
+	/**
2480
+	 * Gets the extra meta with the given meta key. If you specify "single" we just return 1, otherwise
2481
+	 * an array of everything found. Requires that this model actually have a relation of type EE_Has_Many_Any_Relation.
2482
+	 * You can specify $default is case you haven't found the extra meta
2483
+	 *
2484
+	 * @param string  $meta_key
2485
+	 * @param boolean $single
2486
+	 * @param mixed   $default if we don't find anything, what should we return?
2487
+	 * @return mixed single value if $single; array if ! $single
2488
+	 * @throws \EE_Error
2489
+	 */
2490
+	public function get_extra_meta($meta_key, $single = false, $default = null)
2491
+	{
2492
+		if ($single) {
2493
+			$result = $this->get_first_related('Extra_Meta', array(array('EXM_key' => $meta_key)));
2494
+			if ($result instanceof EE_Extra_Meta) {
2495
+				return $result->value();
2496
+			} else {
2497
+				return $default;
2498
+			}
2499
+		} else {
2500
+			$results = $this->get_many_related('Extra_Meta', array(array('EXM_key' => $meta_key)));
2501
+			if ($results) {
2502
+				$values = array();
2503
+				foreach ($results as $result) {
2504
+					if ($result instanceof EE_Extra_Meta) {
2505
+						$values[$result->ID()] = $result->value();
2506
+					}
2507
+				}
2508
+				return $values;
2509
+			} else {
2510
+				return $default;
2511
+			}
2512
+		}
2513
+	}
2514
+
2515
+
2516
+
2517
+	/**
2518
+	 * Returns a simple array of all the extra meta associated with this model object.
2519
+	 * If $one_of_each_key is true (Default), it will be an array of simple key-value pairs, keys being the
2520
+	 * extra meta's key, and teh value being its value. However, if there are duplicate extra meta rows with
2521
+	 * the same key, only one will be used. (eg array('foo'=>'bar','monkey'=>123))
2522
+	 * If $one_of_each_key is false, it will return an array with the top-level keys being
2523
+	 * the extra meta keys, but their values are also arrays, which have the extra-meta's ID as their sub-key, and
2524
+	 * finally the extra meta's value as each sub-value. (eg
2525
+	 * array('foo'=>array(1=>'bar',2=>'bill'),'monkey'=>array(3=>123)))
2526
+	 *
2527
+	 * @param boolean $one_of_each_key
2528
+	 * @return array
2529
+	 * @throws \EE_Error
2530
+	 */
2531
+	public function all_extra_meta_array($one_of_each_key = true)
2532
+	{
2533
+		$return_array = array();
2534
+		if ($one_of_each_key) {
2535
+			$extra_meta_objs = $this->get_many_related('Extra_Meta', array('group_by' => 'EXM_key'));
2536
+			foreach ($extra_meta_objs as $extra_meta_obj) {
2537
+				if ($extra_meta_obj instanceof EE_Extra_Meta) {
2538
+					$return_array[$extra_meta_obj->key()] = $extra_meta_obj->value();
2539
+				}
2540
+			}
2541
+		} else {
2542
+			$extra_meta_objs = $this->get_many_related('Extra_Meta');
2543
+			foreach ($extra_meta_objs as $extra_meta_obj) {
2544
+				if ($extra_meta_obj instanceof EE_Extra_Meta) {
2545
+					if ( ! isset($return_array[$extra_meta_obj->key()])) {
2546
+						$return_array[$extra_meta_obj->key()] = array();
2547
+					}
2548
+					$return_array[$extra_meta_obj->key()][$extra_meta_obj->ID()] = $extra_meta_obj->value();
2549
+				}
2550
+			}
2551
+		}
2552
+		return $return_array;
2553
+	}
2554
+
2555
+
2556
+
2557
+	/**
2558
+	 * Gets a pretty nice displayable nice for this model object. Often overridden
2559
+	 *
2560
+	 * @return string
2561
+	 * @throws \EE_Error
2562
+	 */
2563
+	public function name()
2564
+	{
2565
+		//find a field that's not a text field
2566
+		$field_we_can_use = $this->get_model()->get_a_field_of_type('EE_Text_Field_Base');
2567
+		if ($field_we_can_use) {
2568
+			return $this->get($field_we_can_use->get_name());
2569
+		} else {
2570
+			$first_few_properties = $this->model_field_array();
2571
+			$first_few_properties = array_slice($first_few_properties, 0, 3);
2572
+			$name_parts = array();
2573
+			foreach ($first_few_properties as $name => $value) {
2574
+				$name_parts[] = "$name:$value";
2575
+			}
2576
+			return implode(",", $name_parts);
2577
+		}
2578
+	}
2579
+
2580
+
2581
+
2582
+	/**
2583
+	 * in_entity_map
2584
+	 * Checks if this model object has been proven to already be in the entity map
2585
+	 *
2586
+	 * @return boolean
2587
+	 * @throws \EE_Error
2588
+	 */
2589
+	public function in_entity_map()
2590
+	{
2591
+		if ($this->ID() && $this->get_model()->get_from_entity_map($this->ID()) === $this) {
2592
+			//well, if we looked, did we find it in the entity map?
2593
+			return true;
2594
+		} else {
2595
+			return false;
2596
+		}
2597
+	}
2598
+
2599
+
2600
+
2601
+	/**
2602
+	 * refresh_from_db
2603
+	 * Makes sure the fields and values on this model object are in-sync with what's in the database.
2604
+	 *
2605
+	 * @throws EE_Error if this model object isn't in the entity mapper (because then you should
2606
+	 * just use what's in the entity mapper and refresh it) and WP_DEBUG is TRUE
2607
+	 */
2608
+	public function refresh_from_db()
2609
+	{
2610
+		if ($this->ID() && $this->in_entity_map()) {
2611
+			$this->get_model()->refresh_entity_map_from_db($this->ID());
2612
+		} else {
2613
+			//if it doesn't have ID, you shouldn't be asking to refresh it from teh database (because its not in the database)
2614
+			//if it has an ID but it's not in the map, and you're asking me to refresh it
2615
+			//that's kinda dangerous. You should just use what's in the entity map, or add this to the entity map if there's
2616
+			//absolutely nothing in it for this ID
2617
+			if (WP_DEBUG) {
2618
+				throw new EE_Error(
2619
+					sprintf(
2620
+						__('Trying to refresh a model object with ID "%1$s" that\'s not in the entity map? First off: you should put it in the entity map by calling %2$s. Second off, if you want what\'s in the database right now, you should just call %3$s yourself and discard this model object.',
2621
+							'event_espresso'),
2622
+						$this->ID(),
2623
+						get_class($this->get_model()) . '::instance()->add_to_entity_map()',
2624
+						get_class($this->get_model()) . '::instance()->refresh_entity_map()'
2625
+					)
2626
+				);
2627
+			}
2628
+		}
2629
+	}
2630
+
2631
+
2632
+
2633
+	/**
2634
+	 * Because some other plugins, like Advanced Cron Manager, expect all objects to have this method
2635
+	 * (probably a bad assumption they have made, oh well)
2636
+	 *
2637
+	 * @return string
2638
+	 */
2639
+	public function __toString()
2640
+	{
2641
+		try {
2642
+			return sprintf('%s (%s)', $this->name(), $this->ID());
2643
+		} catch (Exception $e) {
2644
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
2645
+			return '';
2646
+		}
2647
+	}
2648
+
2649
+
2650
+
2651
+	/**
2652
+	 * Clear related model objects if they're already in the DB, because otherwise when we
2653
+	 * UN-serialize this model object we'll need to be careful to add them to the entity map.
2654
+	 * This means if we have made changes to those related model objects, and want to unserialize
2655
+	 * the this model object on a subsequent request, changes to those related model objects will be lost.
2656
+	 * Instead, those related model objects should be directly serialized and stored.
2657
+	 * Eg, the following won't work:
2658
+	 * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
2659
+	 * $att = $reg->attendee();
2660
+	 * $att->set( 'ATT_fname', 'Dirk' );
2661
+	 * update_option( 'my_option', serialize( $reg ) );
2662
+	 * //END REQUEST
2663
+	 * //START NEXT REQUEST
2664
+	 * $reg = get_option( 'my_option' );
2665
+	 * $reg->attendee()->save();
2666
+	 * And would need to be replace with:
2667
+	 * $reg = EEM_Registration::instance()->get_one_by_ID( 123 );
2668
+	 * $att = $reg->attendee();
2669
+	 * $att->set( 'ATT_fname', 'Dirk' );
2670
+	 * update_option( 'my_option', serialize( $reg ) );
2671
+	 * //END REQUEST
2672
+	 * //START NEXT REQUEST
2673
+	 * $att = get_option( 'my_option' );
2674
+	 * $att->save();
2675
+	 *
2676
+	 * @return array
2677
+	 * @throws \EE_Error
2678
+	 */
2679
+	public function __sleep()
2680
+	{
2681
+		foreach ($this->get_model()->relation_settings() as $relation_name => $relation_obj) {
2682
+			if ($relation_obj instanceof EE_Belongs_To_Relation) {
2683
+				$classname = 'EE_' . $this->get_model()->get_this_model_name();
2684
+				if (
2685
+					$this->get_one_from_cache($relation_name) instanceof $classname
2686
+					&& $this->get_one_from_cache($relation_name)->ID()
2687
+				) {
2688
+					$this->clear_cache($relation_name, $this->get_one_from_cache($relation_name)->ID());
2689
+				}
2690
+			}
2691
+		}
2692
+		$this->_props_n_values_provided_in_constructor = array();
2693
+		return array_keys(get_object_vars($this));
2694
+	}
2695
+
2696
+
2697
+
2698
+	/**
2699
+	 * restore _props_n_values_provided_in_constructor
2700
+	 * PLZ NOTE: this will reset the array to whatever fields values were present prior to serialization,
2701
+	 * and therefore should NOT be used to determine if state change has occurred since initial construction.
2702
+	 * At best, you would only be able to detect if state change has occurred during THIS request.
2703
+	 */
2704
+	public function __wakeup()
2705
+	{
2706
+		$this->_props_n_values_provided_in_constructor = $this->_fields;
2707
+	}
2708 2708
 
2709 2709
 
2710 2710
 
Please login to merge, or discard this patch.
core/helpers/EEH_Debug_Tools.helper.php 3 patches
Doc Comments   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -375,7 +375,7 @@  discard block
 block discarded – undo
375 375
 
376 376
 
377 377
     /**
378
-     * @param mixed      $var
378
+     * @param string      $var
379 379
      * @param string     $var_name
380 380
      * @param string     $file
381 381
      * @param int|string $line
@@ -513,7 +513,7 @@  discard block
 block discarded – undo
513 513
      * @param mixed      $var
514 514
      * @param string     $var_name
515 515
      * @param string     $file
516
-     * @param int|string $line
516
+     * @param integer $line
517 517
      * @param int        $heading_tag
518 518
      * @param bool       $die
519 519
      */
@@ -576,7 +576,7 @@  discard block
 block discarded – undo
576 576
 
577 577
     /**
578 578
      * @deprecated 4.9.39.rc.034
579
-     * @param null $timer_name
579
+     * @param string $timer_name
580 580
      */
581 581
     public function start_timer($timer_name = null)
582 582
     {
Please login to merge, or discard this patch.
Indentation   +642 added lines, -642 removed lines patch added patch discarded remove patch
@@ -1,7 +1,7 @@  discard block
 block discarded – undo
1 1
 <?php use EventEspresso\core\services\Benchmark;
2 2
 
3 3
 if (! defined('EVENT_ESPRESSO_VERSION')) {
4
-    exit('No direct script access allowed');
4
+	exit('No direct script access allowed');
5 5
 }
6 6
 
7 7
 
@@ -17,632 +17,632 @@  discard block
 block discarded – undo
17 17
 class EEH_Debug_Tools
18 18
 {
19 19
 
20
-    /**
21
-     *    instance of the EEH_Autoloader object
22
-     *
23
-     * @var    $_instance
24
-     * @access    private
25
-     */
26
-    private static $_instance;
27
-
28
-    /**
29
-     * @var array
30
-     */
31
-    protected $_memory_usage_points = array();
32
-
33
-
34
-
35
-    /**
36
-     * @singleton method used to instantiate class object
37
-     * @access    public
38
-     * @return EEH_Debug_Tools
39
-     */
40
-    public static function instance()
41
-    {
42
-        // check if class object is instantiated, and instantiated properly
43
-        if (! self::$_instance instanceof EEH_Debug_Tools) {
44
-            self::$_instance = new self();
45
-        }
46
-        return self::$_instance;
47
-    }
48
-
49
-
50
-
51
-    /**
52
-     * private class constructor
53
-     */
54
-    private function __construct()
55
-    {
56
-        // load Kint PHP debugging library
57
-        if (! class_exists('Kint') && file_exists(EE_PLUGIN_DIR_PATH . 'tests' . DS . 'kint' . DS . 'Kint.class.php')) {
58
-            // despite EE4 having a check for an existing copy of the Kint debugging class,
59
-            // if another plugin was loaded AFTER EE4 and they did NOT perform a similar check,
60
-            // then hilarity would ensue as PHP throws a "Cannot redeclare class Kint" error
61
-            // so we've moved it to our test folder so that it is not included with production releases
62
-            // plz use https://wordpress.org/plugins/kint-debugger/  if testing production versions of EE
63
-            require_once(EE_PLUGIN_DIR_PATH . 'tests' . DS . 'kint' . DS . 'Kint.class.php');
64
-        }
65
-        // if ( ! defined('DOING_AJAX') || $_REQUEST['noheader'] !== 'true' || ! isset( $_REQUEST['noheader'], $_REQUEST['TB_iframe'] ) ) {
66
-        //add_action( 'shutdown', array($this,'espresso_session_footer_dump') );
67
-        // }
68
-        $plugin = basename(EE_PLUGIN_DIR_PATH);
69
-        add_action("activate_{$plugin}", array('EEH_Debug_Tools', 'ee_plugin_activation_errors'));
70
-        add_action('activated_plugin', array('EEH_Debug_Tools', 'ee_plugin_activation_errors'));
71
-        add_action('shutdown', array('EEH_Debug_Tools', 'show_db_name'));
72
-    }
73
-
74
-
75
-
76
-    /**
77
-     *    show_db_name
78
-     *
79
-     * @return void
80
-     */
81
-    public static function show_db_name()
82
-    {
83
-        if (! defined('DOING_AJAX') && (defined('EE_ERROR_EMAILS') && EE_ERROR_EMAILS)) {
84
-            echo '<p style="font-size:10px;font-weight:normal;color:#E76700;margin: 1em 2em; text-align: right;">DB_NAME: '
85
-                 . DB_NAME
86
-                 . '</p>';
87
-        }
88
-        if (EE_DEBUG) {
89
-            Benchmark::displayResults();
90
-        }
91
-    }
92
-
93
-
94
-
95
-    /**
96
-     *    dump EE_Session object at bottom of page after everything else has happened
97
-     *
98
-     * @return void
99
-     */
100
-    public function espresso_session_footer_dump()
101
-    {
102
-        if (
103
-            (defined('WP_DEBUG') && WP_DEBUG)
104
-            && ! defined('DOING_AJAX')
105
-            && class_exists('Kint')
106
-            && function_exists('wp_get_current_user')
107
-            && current_user_can('update_core')
108
-            && class_exists('EE_Registry')
109
-        ) {
110
-            Kint::dump(EE_Registry::instance()->SSN->id());
111
-            Kint::dump(EE_Registry::instance()->SSN);
112
-            //			Kint::dump( EE_Registry::instance()->SSN->get_session_data('cart')->get_tickets() );
113
-            $this->espresso_list_hooked_functions();
114
-            Benchmark::displayResults();
115
-        }
116
-    }
117
-
118
-
119
-
120
-    /**
121
-     *    List All Hooked Functions
122
-     *    to list all functions for a specific hook, add ee_list_hooks={hook-name} to URL
123
-     *    http://wp.smashingmagazine.com/2009/08/18/10-useful-wordpress-hook-hacks/
124
-     *
125
-     * @param string $tag
126
-     * @return void
127
-     */
128
-    public function espresso_list_hooked_functions($tag = '')
129
-    {
130
-        global $wp_filter;
131
-        echo '<br/><br/><br/><h3>Hooked Functions</h3>';
132
-        if ($tag) {
133
-            $hook[$tag] = $wp_filter[$tag];
134
-            if (! is_array($hook[$tag])) {
135
-                trigger_error("Nothing found for '$tag' hook", E_USER_WARNING);
136
-                return;
137
-            }
138
-            echo '<h5>For Tag: ' . $tag . '</h5>';
139
-        } else {
140
-            $hook = is_array($wp_filter) ? $wp_filter : array($wp_filter);
141
-            ksort($hook);
142
-        }
143
-        foreach ($hook as $tag_name => $priorities) {
144
-            echo "<br />&gt;&gt;&gt;&gt;&gt;\t<strong>$tag_name</strong><br />";
145
-            ksort($priorities);
146
-            foreach ($priorities as $priority => $function) {
147
-                echo $priority;
148
-                foreach ($function as $name => $properties) {
149
-                    echo "\t$name<br />";
150
-                }
151
-            }
152
-        }
153
-    }
154
-
155
-
156
-
157
-    /**
158
-     *    registered_filter_callbacks
159
-     *
160
-     * @param string $hook_name
161
-     * @return array
162
-     */
163
-    public static function registered_filter_callbacks($hook_name = '')
164
-    {
165
-        $filters = array();
166
-        global $wp_filter;
167
-        if (isset($wp_filter[$hook_name])) {
168
-            $filters[$hook_name] = array();
169
-            foreach ($wp_filter[$hook_name] as $priority => $callbacks) {
170
-                $filters[$hook_name][$priority] = array();
171
-                foreach ($callbacks as $callback) {
172
-                    $filters[$hook_name][$priority][] = $callback['function'];
173
-                }
174
-            }
175
-        }
176
-        return $filters;
177
-    }
178
-
179
-
180
-
181
-    /**
182
-     *    captures plugin activation errors for debugging
183
-     *
184
-     * @return void
185
-     * @throws EE_Error
186
-     */
187
-    public static function ee_plugin_activation_errors()
188
-    {
189
-        if (WP_DEBUG) {
190
-            $activation_errors = ob_get_contents();
191
-            if (! empty($activation_errors)) {
192
-                $activation_errors = date('Y-m-d H:i:s') . "\n" . $activation_errors;
193
-            }
194
-            espresso_load_required('EEH_File', EE_HELPERS . 'EEH_File.helper.php');
195
-            if (class_exists('EEH_File')) {
196
-                try {
197
-                    EEH_File::ensure_file_exists_and_is_writable(
198
-                        EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . 'espresso_plugin_activation_errors.html'
199
-                    );
200
-                    EEH_File::write_to_file(
201
-                        EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . 'espresso_plugin_activation_errors.html',
202
-                        $activation_errors
203
-                    );
204
-                } catch (EE_Error $e) {
205
-                    EE_Error::add_error(
206
-                        sprintf(
207
-                            __(
208
-                                'The Event Espresso activation errors file could not be setup because: %s',
209
-                                'event_espresso'
210
-                            ),
211
-                            $e->getMessage()
212
-                        ),
213
-                        __FILE__, __FUNCTION__, __LINE__
214
-                    );
215
-                }
216
-            } else {
217
-                // old school attempt
218
-                file_put_contents(
219
-                    EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . 'espresso_plugin_activation_errors.html',
220
-                    $activation_errors
221
-                );
222
-            }
223
-            $activation_errors = get_option('ee_plugin_activation_errors', '') . $activation_errors;
224
-            update_option('ee_plugin_activation_errors', $activation_errors);
225
-        }
226
-    }
227
-
228
-
229
-
230
-    /**
231
-     * This basically mimics the WordPress _doing_it_wrong() function except adds our own messaging etc.
232
-     * Very useful for providing helpful messages to developers when the method of doing something has been deprecated,
233
-     * or we want to make sure they use something the right way.
234
-     *
235
-     * @access public
236
-     * @param string $function      The function that was called
237
-     * @param string $message       A message explaining what has been done incorrectly
238
-     * @param string $version       The version of Event Espresso where the error was added
239
-     * @param string $applies_when  a version string for when you want the doing_it_wrong notice to begin appearing
240
-     *                              for a deprecated function. This allows deprecation to occur during one version,
241
-     *                              but not have any notices appear until a later version. This allows developers
242
-     *                              extra time to update their code before notices appear.
243
-     * @param int    $error_type
244
-     * @uses   trigger_error()
245
-     */
246
-    public function doing_it_wrong(
247
-        $function,
248
-        $message,
249
-        $version,
250
-        $applies_when = '',
251
-        $error_type = null
252
-    ) {
253
-        $applies_when = ! empty($applies_when) ? $applies_when : espresso_version();
254
-        $error_type = $error_type !== null ? $error_type : E_USER_NOTICE;
255
-        // because we swapped the parameter order around for the last two params,
256
-        // let's verify that some third party isn't still passing an error type value for the third param
257
-        if (is_int($applies_when)) {
258
-            $error_type = $applies_when;
259
-            $applies_when = espresso_version();
260
-        }
261
-        // if not displaying notices yet, then just leave
262
-        if (version_compare(espresso_version(), $applies_when, '<')) {
263
-            return;
264
-        }
265
-        do_action('AHEE__EEH_Debug_Tools__doing_it_wrong_run', $function, $message, $version);
266
-        $version = $version === null
267
-            ? ''
268
-            : sprintf(
269
-                __('(This message was added in version %s of Event Espresso)', 'event_espresso'),
270
-                $version
271
-            );
272
-        $error_message = sprintf(
273
-            esc_html__('%1$s was called %2$sincorrectly%3$s. %4$s %5$s', 'event_espresso'),
274
-            $function,
275
-            '<strong>',
276
-            '</strong>',
277
-            $message,
278
-            $version
279
-        );
280
-        // don't trigger error if doing ajax,
281
-        // instead we'll add a transient EE_Error notice that in theory should show on the next request.
282
-        if (defined('DOING_AJAX') && DOING_AJAX) {
283
-            $error_message .= ' ' . esc_html__(
284
-                    'This is a doing_it_wrong message that was triggered during an ajax request.  The request params on this request were: ',
285
-                    'event_espresso'
286
-                );
287
-            $error_message .= '<ul><li>';
288
-            $error_message .= implode('</li><li>', EE_Registry::instance()->REQ->params());
289
-            $error_message .= '</ul>';
290
-            EE_Error::add_error($error_message, 'debug::doing_it_wrong', $function, '42');
291
-            //now we set this on the transient so it shows up on the next request.
292
-            EE_Error::get_notices(false, true);
293
-        } else {
294
-            trigger_error($error_message, $error_type);
295
-        }
296
-    }
297
-
298
-
299
-
300
-
301
-    /**
302
-     * Logger helpers
303
-     */
304
-    /**
305
-     * debug
306
-     *
307
-     * @param string $class
308
-     * @param string $func
309
-     * @param string $line
310
-     * @param array  $info
311
-     * @param bool   $display_request
312
-     * @param string $debug_index
313
-     * @param string $debug_key
314
-     * @throws EE_Error
315
-     * @throws \EventEspresso\core\exceptions\InvalidSessionDataException
316
-     */
317
-    public static function log(
318
-        $class = '',
319
-        $func = '',
320
-        $line = '',
321
-        $info = array(),
322
-        $display_request = false,
323
-        $debug_index = '',
324
-        $debug_key = 'EE_DEBUG_SPCO'
325
-    ) {
326
-        if (WP_DEBUG) {
327
-            $debug_key = $debug_key . '_' . EE_Session::instance()->id();
328
-            $debug_data = get_option($debug_key, array());
329
-            $default_data = array(
330
-                $class => $func . '() : ' . $line,
331
-                'REQ'  => $display_request ? $_REQUEST : '',
332
-            );
333
-            // don't serialize objects
334
-            $info = self::strip_objects($info);
335
-            $index = ! empty($debug_index) ? $debug_index : 0;
336
-            if (! isset($debug_data[$index])) {
337
-                $debug_data[$index] = array();
338
-            }
339
-            $debug_data[$index][microtime()] = array_merge($default_data, $info);
340
-            update_option($debug_key, $debug_data);
341
-        }
342
-    }
343
-
344
-
345
-
346
-    /**
347
-     * strip_objects
348
-     *
349
-     * @param array $info
350
-     * @return array
351
-     */
352
-    public static function strip_objects($info = array())
353
-    {
354
-        foreach ($info as $key => $value) {
355
-            if (is_array($value)) {
356
-                $info[$key] = self::strip_objects($value);
357
-            } else if (is_object($value)) {
358
-                $object_class = get_class($value);
359
-                $info[$object_class] = array();
360
-                $info[$object_class]['ID'] = method_exists($value, 'ID') ? $value->ID() : spl_object_hash($value);
361
-                if (method_exists($value, 'ID')) {
362
-                    $info[$object_class]['ID'] = $value->ID();
363
-                }
364
-                if (method_exists($value, 'status')) {
365
-                    $info[$object_class]['status'] = $value->status();
366
-                } else if (method_exists($value, 'status_ID')) {
367
-                    $info[$object_class]['status'] = $value->status_ID();
368
-                }
369
-                unset($info[$key]);
370
-            }
371
-        }
372
-        return (array)$info;
373
-    }
374
-
375
-
376
-
377
-    /**
378
-     * @param mixed      $var
379
-     * @param string     $var_name
380
-     * @param string     $file
381
-     * @param int|string $line
382
-     * @param int        $heading_tag
383
-     * @param bool       $die
384
-     * @param string     $margin
385
-     */
386
-    public static function printv(
387
-        $var,
388
-        $var_name = '',
389
-        $file = '',
390
-        $line = '',
391
-        $heading_tag = 5,
392
-        $die = false,
393
-        $margin = ''
394
-    ) {
395
-        $var_name = ! $var_name ? 'string' : $var_name;
396
-        $var_name = ucwords(str_replace('$', '', $var_name));
397
-        $is_method = method_exists($var_name, $var);
398
-        $var_name = ucwords(str_replace('_', ' ', $var_name));
399
-        $heading_tag = is_int($heading_tag) ? "h{$heading_tag}" : 'h5';
400
-        $result = EEH_Debug_Tools::heading($var_name, $heading_tag, $margin);
401
-        $result .= $is_method
402
-            ? EEH_Debug_Tools::grey_span('::') . EEH_Debug_Tools::orange_span($var . '()')
403
-            : EEH_Debug_Tools::grey_span(' : ') . EEH_Debug_Tools::orange_span($var);
404
-        $result .= EEH_Debug_Tools::file_and_line($file, $line);
405
-        $result .= EEH_Debug_Tools::headingX($heading_tag);
406
-        if ($die) {
407
-            die($result);
408
-        }
409
-        echo $result;
410
-    }
411
-
412
-
413
-
414
-    /**
415
-     * @param string $var_name
416
-     * @param string $heading_tag
417
-     * @param string $margin
418
-     * @return string
419
-     */
420
-    protected static function heading($var_name = '', $heading_tag = 'h5', $margin = '')
421
-    {
422
-        if (defined('EE_TESTS_DIR')) {
423
-            return "\n{$var_name}";
424
-        }
425
-        $margin = "25px 0 0 {$margin}";
426
-        return '<' . $heading_tag . ' style="color:#2EA2CC; margin:' . $margin . ';"><b>' . $var_name . '</b>';
427
-    }
428
-
429
-
430
-
431
-    /**
432
-     * @param string $heading_tag
433
-     * @return string
434
-     */
435
-    protected static function headingX($heading_tag = 'h5')
436
-    {
437
-        if (defined('EE_TESTS_DIR')) {
438
-            return '';
439
-        }
440
-        return '</' . $heading_tag . '>';
441
-    }
442
-
443
-
444
-
445
-    /**
446
-     * @param string $content
447
-     * @return string
448
-     */
449
-    protected static function grey_span($content = '')
450
-    {
451
-        if (defined('EE_TESTS_DIR')) {
452
-            return $content;
453
-        }
454
-        return '<span style="color:#999">' . $content . '</span>';
455
-    }
456
-
457
-
458
-
459
-    /**
460
-     * @param string $file
461
-     * @param int    $line
462
-     * @return string
463
-     */
464
-    protected static function file_and_line($file, $line)
465
-    {
466
-        if ($file === '' || $line === '') {
467
-            return '';
468
-        }
469
-        if (defined('EE_TESTS_DIR')) {
470
-            return "\n (" . $file . ' line no: ' . $line . ' ) ';
471
-        }
472
-        return '<br /><span style="font-size:9px;font-weight:normal;color:#666;line-height: 12px;">'
473
-               . $file
474
-               . '<br />line no: '
475
-               . $line
476
-               . '</span>';
477
-    }
478
-
479
-
480
-
481
-    /**
482
-     * @param string $content
483
-     * @return string
484
-     */
485
-    protected static function orange_span($content = '')
486
-    {
487
-        if (defined('EE_TESTS_DIR')) {
488
-            return $content;
489
-        }
490
-        return '<span style="color:#E76700">' . $content . '</span>';
491
-    }
492
-
493
-
494
-
495
-    /**
496
-     * @param mixed $var
497
-     * @return string
498
-     */
499
-    protected static function pre_span($var)
500
-    {
501
-        ob_start();
502
-        var_dump($var);
503
-        $var = ob_get_clean();
504
-        if (defined('EE_TESTS_DIR')) {
505
-            return "\n" . $var;
506
-        }
507
-        return '<pre style="color:#999; padding:1em; background: #fff">' . $var . '</pre>';
508
-    }
509
-
510
-
511
-
512
-    /**
513
-     * @param mixed      $var
514
-     * @param string     $var_name
515
-     * @param string     $file
516
-     * @param int|string $line
517
-     * @param int        $heading_tag
518
-     * @param bool       $die
519
-     */
520
-    public static function printr(
521
-        $var,
522
-        $var_name = '',
523
-        $file = '',
524
-        $line = '',
525
-        $heading_tag = 5,
526
-        $die = false
527
-    ) {
528
-        // return;
529
-        $file = str_replace(rtrim(ABSPATH, '\\/'), '', $file);
530
-        $margin = is_admin() ? ' 180px' : '0';
531
-        //$print_r = false;
532
-        if (is_string($var)) {
533
-            EEH_Debug_Tools::printv($var, $var_name, $file, $line, $heading_tag, $die, $margin);
534
-            return;
535
-        }
536
-        if (is_object($var)) {
537
-            $var_name = ! $var_name ? 'object' : $var_name;
538
-            //$print_r = true;
539
-        } else if (is_array($var)) {
540
-            $var_name = ! $var_name ? 'array' : $var_name;
541
-            //$print_r = true;
542
-        } else if (is_numeric($var)) {
543
-            $var_name = ! $var_name ? 'numeric' : $var_name;
544
-        } else if ($var === null) {
545
-            $var_name = ! $var_name ? 'null' : $var_name;
546
-        }
547
-        $var_name = ucwords(str_replace(array('$', '_'), array('', ' '), $var_name));
548
-        $heading_tag = is_int($heading_tag) ? "h{$heading_tag}" : 'h5';
549
-        $result = EEH_Debug_Tools::heading($var_name, $heading_tag, $margin);
550
-        $result .= EEH_Debug_Tools::grey_span(' : ') . EEH_Debug_Tools::orange_span(
551
-                EEH_Debug_Tools::pre_span($var)
552
-            );
553
-        $result .= EEH_Debug_Tools::file_and_line($file, $line);
554
-        $result .= EEH_Debug_Tools::headingX($heading_tag);
555
-        if ($die) {
556
-            die($result);
557
-        }
558
-        echo $result;
559
-    }
560
-
561
-
562
-
563
-    /******************** deprecated ********************/
564
-
565
-
566
-
567
-    /**
568
-     * @deprecated 4.9.39.rc.034
569
-     */
570
-    public function reset_times()
571
-    {
572
-        Benchmark::resetTimes();
573
-    }
574
-
575
-
576
-
577
-    /**
578
-     * @deprecated 4.9.39.rc.034
579
-     * @param null $timer_name
580
-     */
581
-    public function start_timer($timer_name = null)
582
-    {
583
-        Benchmark::startTimer($timer_name);
584
-    }
585
-
586
-
587
-
588
-    /**
589
-     * @deprecated 4.9.39.rc.034
590
-     * @param string $timer_name
591
-     */
592
-    public function stop_timer($timer_name = '')
593
-    {
594
-        Benchmark::stopTimer($timer_name);
595
-    }
596
-
597
-
598
-
599
-    /**
600
-     * @deprecated 4.9.39.rc.034
601
-     * @param string  $label      The label to show for this time eg "Start of calling Some_Class::some_function"
602
-     * @param boolean $output_now whether to echo now, or wait until EEH_Debug_Tools::show_times() is called
603
-     * @return void
604
-     */
605
-    public function measure_memory($label, $output_now = false)
606
-    {
607
-        Benchmark::measureMemory($label, $output_now);
608
-    }
609
-
610
-
611
-
612
-    /**
613
-     * @deprecated 4.9.39.rc.034
614
-     * @param int $size
615
-     * @return string
616
-     */
617
-    public function convert($size)
618
-    {
619
-        return Benchmark::convert($size);
620
-    }
621
-
622
-
623
-
624
-    /**
625
-     * @deprecated 4.9.39.rc.034
626
-     * @param bool $output_now
627
-     * @return string
628
-     */
629
-    public function show_times($output_now = true)
630
-    {
631
-        return Benchmark::displayResults($output_now);
632
-    }
633
-
634
-
635
-
636
-    /**
637
-     * @deprecated 4.9.39.rc.034
638
-     * @param string $timer_name
639
-     * @param float  $total_time
640
-     * @return string
641
-     */
642
-    public function format_time($timer_name, $total_time)
643
-    {
644
-        return Benchmark::formatTime($timer_name, $total_time);
645
-    }
20
+	/**
21
+	 *    instance of the EEH_Autoloader object
22
+	 *
23
+	 * @var    $_instance
24
+	 * @access    private
25
+	 */
26
+	private static $_instance;
27
+
28
+	/**
29
+	 * @var array
30
+	 */
31
+	protected $_memory_usage_points = array();
32
+
33
+
34
+
35
+	/**
36
+	 * @singleton method used to instantiate class object
37
+	 * @access    public
38
+	 * @return EEH_Debug_Tools
39
+	 */
40
+	public static function instance()
41
+	{
42
+		// check if class object is instantiated, and instantiated properly
43
+		if (! self::$_instance instanceof EEH_Debug_Tools) {
44
+			self::$_instance = new self();
45
+		}
46
+		return self::$_instance;
47
+	}
48
+
49
+
50
+
51
+	/**
52
+	 * private class constructor
53
+	 */
54
+	private function __construct()
55
+	{
56
+		// load Kint PHP debugging library
57
+		if (! class_exists('Kint') && file_exists(EE_PLUGIN_DIR_PATH . 'tests' . DS . 'kint' . DS . 'Kint.class.php')) {
58
+			// despite EE4 having a check for an existing copy of the Kint debugging class,
59
+			// if another plugin was loaded AFTER EE4 and they did NOT perform a similar check,
60
+			// then hilarity would ensue as PHP throws a "Cannot redeclare class Kint" error
61
+			// so we've moved it to our test folder so that it is not included with production releases
62
+			// plz use https://wordpress.org/plugins/kint-debugger/  if testing production versions of EE
63
+			require_once(EE_PLUGIN_DIR_PATH . 'tests' . DS . 'kint' . DS . 'Kint.class.php');
64
+		}
65
+		// if ( ! defined('DOING_AJAX') || $_REQUEST['noheader'] !== 'true' || ! isset( $_REQUEST['noheader'], $_REQUEST['TB_iframe'] ) ) {
66
+		//add_action( 'shutdown', array($this,'espresso_session_footer_dump') );
67
+		// }
68
+		$plugin = basename(EE_PLUGIN_DIR_PATH);
69
+		add_action("activate_{$plugin}", array('EEH_Debug_Tools', 'ee_plugin_activation_errors'));
70
+		add_action('activated_plugin', array('EEH_Debug_Tools', 'ee_plugin_activation_errors'));
71
+		add_action('shutdown', array('EEH_Debug_Tools', 'show_db_name'));
72
+	}
73
+
74
+
75
+
76
+	/**
77
+	 *    show_db_name
78
+	 *
79
+	 * @return void
80
+	 */
81
+	public static function show_db_name()
82
+	{
83
+		if (! defined('DOING_AJAX') && (defined('EE_ERROR_EMAILS') && EE_ERROR_EMAILS)) {
84
+			echo '<p style="font-size:10px;font-weight:normal;color:#E76700;margin: 1em 2em; text-align: right;">DB_NAME: '
85
+				 . DB_NAME
86
+				 . '</p>';
87
+		}
88
+		if (EE_DEBUG) {
89
+			Benchmark::displayResults();
90
+		}
91
+	}
92
+
93
+
94
+
95
+	/**
96
+	 *    dump EE_Session object at bottom of page after everything else has happened
97
+	 *
98
+	 * @return void
99
+	 */
100
+	public function espresso_session_footer_dump()
101
+	{
102
+		if (
103
+			(defined('WP_DEBUG') && WP_DEBUG)
104
+			&& ! defined('DOING_AJAX')
105
+			&& class_exists('Kint')
106
+			&& function_exists('wp_get_current_user')
107
+			&& current_user_can('update_core')
108
+			&& class_exists('EE_Registry')
109
+		) {
110
+			Kint::dump(EE_Registry::instance()->SSN->id());
111
+			Kint::dump(EE_Registry::instance()->SSN);
112
+			//			Kint::dump( EE_Registry::instance()->SSN->get_session_data('cart')->get_tickets() );
113
+			$this->espresso_list_hooked_functions();
114
+			Benchmark::displayResults();
115
+		}
116
+	}
117
+
118
+
119
+
120
+	/**
121
+	 *    List All Hooked Functions
122
+	 *    to list all functions for a specific hook, add ee_list_hooks={hook-name} to URL
123
+	 *    http://wp.smashingmagazine.com/2009/08/18/10-useful-wordpress-hook-hacks/
124
+	 *
125
+	 * @param string $tag
126
+	 * @return void
127
+	 */
128
+	public function espresso_list_hooked_functions($tag = '')
129
+	{
130
+		global $wp_filter;
131
+		echo '<br/><br/><br/><h3>Hooked Functions</h3>';
132
+		if ($tag) {
133
+			$hook[$tag] = $wp_filter[$tag];
134
+			if (! is_array($hook[$tag])) {
135
+				trigger_error("Nothing found for '$tag' hook", E_USER_WARNING);
136
+				return;
137
+			}
138
+			echo '<h5>For Tag: ' . $tag . '</h5>';
139
+		} else {
140
+			$hook = is_array($wp_filter) ? $wp_filter : array($wp_filter);
141
+			ksort($hook);
142
+		}
143
+		foreach ($hook as $tag_name => $priorities) {
144
+			echo "<br />&gt;&gt;&gt;&gt;&gt;\t<strong>$tag_name</strong><br />";
145
+			ksort($priorities);
146
+			foreach ($priorities as $priority => $function) {
147
+				echo $priority;
148
+				foreach ($function as $name => $properties) {
149
+					echo "\t$name<br />";
150
+				}
151
+			}
152
+		}
153
+	}
154
+
155
+
156
+
157
+	/**
158
+	 *    registered_filter_callbacks
159
+	 *
160
+	 * @param string $hook_name
161
+	 * @return array
162
+	 */
163
+	public static function registered_filter_callbacks($hook_name = '')
164
+	{
165
+		$filters = array();
166
+		global $wp_filter;
167
+		if (isset($wp_filter[$hook_name])) {
168
+			$filters[$hook_name] = array();
169
+			foreach ($wp_filter[$hook_name] as $priority => $callbacks) {
170
+				$filters[$hook_name][$priority] = array();
171
+				foreach ($callbacks as $callback) {
172
+					$filters[$hook_name][$priority][] = $callback['function'];
173
+				}
174
+			}
175
+		}
176
+		return $filters;
177
+	}
178
+
179
+
180
+
181
+	/**
182
+	 *    captures plugin activation errors for debugging
183
+	 *
184
+	 * @return void
185
+	 * @throws EE_Error
186
+	 */
187
+	public static function ee_plugin_activation_errors()
188
+	{
189
+		if (WP_DEBUG) {
190
+			$activation_errors = ob_get_contents();
191
+			if (! empty($activation_errors)) {
192
+				$activation_errors = date('Y-m-d H:i:s') . "\n" . $activation_errors;
193
+			}
194
+			espresso_load_required('EEH_File', EE_HELPERS . 'EEH_File.helper.php');
195
+			if (class_exists('EEH_File')) {
196
+				try {
197
+					EEH_File::ensure_file_exists_and_is_writable(
198
+						EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . 'espresso_plugin_activation_errors.html'
199
+					);
200
+					EEH_File::write_to_file(
201
+						EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . 'espresso_plugin_activation_errors.html',
202
+						$activation_errors
203
+					);
204
+				} catch (EE_Error $e) {
205
+					EE_Error::add_error(
206
+						sprintf(
207
+							__(
208
+								'The Event Espresso activation errors file could not be setup because: %s',
209
+								'event_espresso'
210
+							),
211
+							$e->getMessage()
212
+						),
213
+						__FILE__, __FUNCTION__, __LINE__
214
+					);
215
+				}
216
+			} else {
217
+				// old school attempt
218
+				file_put_contents(
219
+					EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . 'espresso_plugin_activation_errors.html',
220
+					$activation_errors
221
+				);
222
+			}
223
+			$activation_errors = get_option('ee_plugin_activation_errors', '') . $activation_errors;
224
+			update_option('ee_plugin_activation_errors', $activation_errors);
225
+		}
226
+	}
227
+
228
+
229
+
230
+	/**
231
+	 * This basically mimics the WordPress _doing_it_wrong() function except adds our own messaging etc.
232
+	 * Very useful for providing helpful messages to developers when the method of doing something has been deprecated,
233
+	 * or we want to make sure they use something the right way.
234
+	 *
235
+	 * @access public
236
+	 * @param string $function      The function that was called
237
+	 * @param string $message       A message explaining what has been done incorrectly
238
+	 * @param string $version       The version of Event Espresso where the error was added
239
+	 * @param string $applies_when  a version string for when you want the doing_it_wrong notice to begin appearing
240
+	 *                              for a deprecated function. This allows deprecation to occur during one version,
241
+	 *                              but not have any notices appear until a later version. This allows developers
242
+	 *                              extra time to update their code before notices appear.
243
+	 * @param int    $error_type
244
+	 * @uses   trigger_error()
245
+	 */
246
+	public function doing_it_wrong(
247
+		$function,
248
+		$message,
249
+		$version,
250
+		$applies_when = '',
251
+		$error_type = null
252
+	) {
253
+		$applies_when = ! empty($applies_when) ? $applies_when : espresso_version();
254
+		$error_type = $error_type !== null ? $error_type : E_USER_NOTICE;
255
+		// because we swapped the parameter order around for the last two params,
256
+		// let's verify that some third party isn't still passing an error type value for the third param
257
+		if (is_int($applies_when)) {
258
+			$error_type = $applies_when;
259
+			$applies_when = espresso_version();
260
+		}
261
+		// if not displaying notices yet, then just leave
262
+		if (version_compare(espresso_version(), $applies_when, '<')) {
263
+			return;
264
+		}
265
+		do_action('AHEE__EEH_Debug_Tools__doing_it_wrong_run', $function, $message, $version);
266
+		$version = $version === null
267
+			? ''
268
+			: sprintf(
269
+				__('(This message was added in version %s of Event Espresso)', 'event_espresso'),
270
+				$version
271
+			);
272
+		$error_message = sprintf(
273
+			esc_html__('%1$s was called %2$sincorrectly%3$s. %4$s %5$s', 'event_espresso'),
274
+			$function,
275
+			'<strong>',
276
+			'</strong>',
277
+			$message,
278
+			$version
279
+		);
280
+		// don't trigger error if doing ajax,
281
+		// instead we'll add a transient EE_Error notice that in theory should show on the next request.
282
+		if (defined('DOING_AJAX') && DOING_AJAX) {
283
+			$error_message .= ' ' . esc_html__(
284
+					'This is a doing_it_wrong message that was triggered during an ajax request.  The request params on this request were: ',
285
+					'event_espresso'
286
+				);
287
+			$error_message .= '<ul><li>';
288
+			$error_message .= implode('</li><li>', EE_Registry::instance()->REQ->params());
289
+			$error_message .= '</ul>';
290
+			EE_Error::add_error($error_message, 'debug::doing_it_wrong', $function, '42');
291
+			//now we set this on the transient so it shows up on the next request.
292
+			EE_Error::get_notices(false, true);
293
+		} else {
294
+			trigger_error($error_message, $error_type);
295
+		}
296
+	}
297
+
298
+
299
+
300
+
301
+	/**
302
+	 * Logger helpers
303
+	 */
304
+	/**
305
+	 * debug
306
+	 *
307
+	 * @param string $class
308
+	 * @param string $func
309
+	 * @param string $line
310
+	 * @param array  $info
311
+	 * @param bool   $display_request
312
+	 * @param string $debug_index
313
+	 * @param string $debug_key
314
+	 * @throws EE_Error
315
+	 * @throws \EventEspresso\core\exceptions\InvalidSessionDataException
316
+	 */
317
+	public static function log(
318
+		$class = '',
319
+		$func = '',
320
+		$line = '',
321
+		$info = array(),
322
+		$display_request = false,
323
+		$debug_index = '',
324
+		$debug_key = 'EE_DEBUG_SPCO'
325
+	) {
326
+		if (WP_DEBUG) {
327
+			$debug_key = $debug_key . '_' . EE_Session::instance()->id();
328
+			$debug_data = get_option($debug_key, array());
329
+			$default_data = array(
330
+				$class => $func . '() : ' . $line,
331
+				'REQ'  => $display_request ? $_REQUEST : '',
332
+			);
333
+			// don't serialize objects
334
+			$info = self::strip_objects($info);
335
+			$index = ! empty($debug_index) ? $debug_index : 0;
336
+			if (! isset($debug_data[$index])) {
337
+				$debug_data[$index] = array();
338
+			}
339
+			$debug_data[$index][microtime()] = array_merge($default_data, $info);
340
+			update_option($debug_key, $debug_data);
341
+		}
342
+	}
343
+
344
+
345
+
346
+	/**
347
+	 * strip_objects
348
+	 *
349
+	 * @param array $info
350
+	 * @return array
351
+	 */
352
+	public static function strip_objects($info = array())
353
+	{
354
+		foreach ($info as $key => $value) {
355
+			if (is_array($value)) {
356
+				$info[$key] = self::strip_objects($value);
357
+			} else if (is_object($value)) {
358
+				$object_class = get_class($value);
359
+				$info[$object_class] = array();
360
+				$info[$object_class]['ID'] = method_exists($value, 'ID') ? $value->ID() : spl_object_hash($value);
361
+				if (method_exists($value, 'ID')) {
362
+					$info[$object_class]['ID'] = $value->ID();
363
+				}
364
+				if (method_exists($value, 'status')) {
365
+					$info[$object_class]['status'] = $value->status();
366
+				} else if (method_exists($value, 'status_ID')) {
367
+					$info[$object_class]['status'] = $value->status_ID();
368
+				}
369
+				unset($info[$key]);
370
+			}
371
+		}
372
+		return (array)$info;
373
+	}
374
+
375
+
376
+
377
+	/**
378
+	 * @param mixed      $var
379
+	 * @param string     $var_name
380
+	 * @param string     $file
381
+	 * @param int|string $line
382
+	 * @param int        $heading_tag
383
+	 * @param bool       $die
384
+	 * @param string     $margin
385
+	 */
386
+	public static function printv(
387
+		$var,
388
+		$var_name = '',
389
+		$file = '',
390
+		$line = '',
391
+		$heading_tag = 5,
392
+		$die = false,
393
+		$margin = ''
394
+	) {
395
+		$var_name = ! $var_name ? 'string' : $var_name;
396
+		$var_name = ucwords(str_replace('$', '', $var_name));
397
+		$is_method = method_exists($var_name, $var);
398
+		$var_name = ucwords(str_replace('_', ' ', $var_name));
399
+		$heading_tag = is_int($heading_tag) ? "h{$heading_tag}" : 'h5';
400
+		$result = EEH_Debug_Tools::heading($var_name, $heading_tag, $margin);
401
+		$result .= $is_method
402
+			? EEH_Debug_Tools::grey_span('::') . EEH_Debug_Tools::orange_span($var . '()')
403
+			: EEH_Debug_Tools::grey_span(' : ') . EEH_Debug_Tools::orange_span($var);
404
+		$result .= EEH_Debug_Tools::file_and_line($file, $line);
405
+		$result .= EEH_Debug_Tools::headingX($heading_tag);
406
+		if ($die) {
407
+			die($result);
408
+		}
409
+		echo $result;
410
+	}
411
+
412
+
413
+
414
+	/**
415
+	 * @param string $var_name
416
+	 * @param string $heading_tag
417
+	 * @param string $margin
418
+	 * @return string
419
+	 */
420
+	protected static function heading($var_name = '', $heading_tag = 'h5', $margin = '')
421
+	{
422
+		if (defined('EE_TESTS_DIR')) {
423
+			return "\n{$var_name}";
424
+		}
425
+		$margin = "25px 0 0 {$margin}";
426
+		return '<' . $heading_tag . ' style="color:#2EA2CC; margin:' . $margin . ';"><b>' . $var_name . '</b>';
427
+	}
428
+
429
+
430
+
431
+	/**
432
+	 * @param string $heading_tag
433
+	 * @return string
434
+	 */
435
+	protected static function headingX($heading_tag = 'h5')
436
+	{
437
+		if (defined('EE_TESTS_DIR')) {
438
+			return '';
439
+		}
440
+		return '</' . $heading_tag . '>';
441
+	}
442
+
443
+
444
+
445
+	/**
446
+	 * @param string $content
447
+	 * @return string
448
+	 */
449
+	protected static function grey_span($content = '')
450
+	{
451
+		if (defined('EE_TESTS_DIR')) {
452
+			return $content;
453
+		}
454
+		return '<span style="color:#999">' . $content . '</span>';
455
+	}
456
+
457
+
458
+
459
+	/**
460
+	 * @param string $file
461
+	 * @param int    $line
462
+	 * @return string
463
+	 */
464
+	protected static function file_and_line($file, $line)
465
+	{
466
+		if ($file === '' || $line === '') {
467
+			return '';
468
+		}
469
+		if (defined('EE_TESTS_DIR')) {
470
+			return "\n (" . $file . ' line no: ' . $line . ' ) ';
471
+		}
472
+		return '<br /><span style="font-size:9px;font-weight:normal;color:#666;line-height: 12px;">'
473
+			   . $file
474
+			   . '<br />line no: '
475
+			   . $line
476
+			   . '</span>';
477
+	}
478
+
479
+
480
+
481
+	/**
482
+	 * @param string $content
483
+	 * @return string
484
+	 */
485
+	protected static function orange_span($content = '')
486
+	{
487
+		if (defined('EE_TESTS_DIR')) {
488
+			return $content;
489
+		}
490
+		return '<span style="color:#E76700">' . $content . '</span>';
491
+	}
492
+
493
+
494
+
495
+	/**
496
+	 * @param mixed $var
497
+	 * @return string
498
+	 */
499
+	protected static function pre_span($var)
500
+	{
501
+		ob_start();
502
+		var_dump($var);
503
+		$var = ob_get_clean();
504
+		if (defined('EE_TESTS_DIR')) {
505
+			return "\n" . $var;
506
+		}
507
+		return '<pre style="color:#999; padding:1em; background: #fff">' . $var . '</pre>';
508
+	}
509
+
510
+
511
+
512
+	/**
513
+	 * @param mixed      $var
514
+	 * @param string     $var_name
515
+	 * @param string     $file
516
+	 * @param int|string $line
517
+	 * @param int        $heading_tag
518
+	 * @param bool       $die
519
+	 */
520
+	public static function printr(
521
+		$var,
522
+		$var_name = '',
523
+		$file = '',
524
+		$line = '',
525
+		$heading_tag = 5,
526
+		$die = false
527
+	) {
528
+		// return;
529
+		$file = str_replace(rtrim(ABSPATH, '\\/'), '', $file);
530
+		$margin = is_admin() ? ' 180px' : '0';
531
+		//$print_r = false;
532
+		if (is_string($var)) {
533
+			EEH_Debug_Tools::printv($var, $var_name, $file, $line, $heading_tag, $die, $margin);
534
+			return;
535
+		}
536
+		if (is_object($var)) {
537
+			$var_name = ! $var_name ? 'object' : $var_name;
538
+			//$print_r = true;
539
+		} else if (is_array($var)) {
540
+			$var_name = ! $var_name ? 'array' : $var_name;
541
+			//$print_r = true;
542
+		} else if (is_numeric($var)) {
543
+			$var_name = ! $var_name ? 'numeric' : $var_name;
544
+		} else if ($var === null) {
545
+			$var_name = ! $var_name ? 'null' : $var_name;
546
+		}
547
+		$var_name = ucwords(str_replace(array('$', '_'), array('', ' '), $var_name));
548
+		$heading_tag = is_int($heading_tag) ? "h{$heading_tag}" : 'h5';
549
+		$result = EEH_Debug_Tools::heading($var_name, $heading_tag, $margin);
550
+		$result .= EEH_Debug_Tools::grey_span(' : ') . EEH_Debug_Tools::orange_span(
551
+				EEH_Debug_Tools::pre_span($var)
552
+			);
553
+		$result .= EEH_Debug_Tools::file_and_line($file, $line);
554
+		$result .= EEH_Debug_Tools::headingX($heading_tag);
555
+		if ($die) {
556
+			die($result);
557
+		}
558
+		echo $result;
559
+	}
560
+
561
+
562
+
563
+	/******************** deprecated ********************/
564
+
565
+
566
+
567
+	/**
568
+	 * @deprecated 4.9.39.rc.034
569
+	 */
570
+	public function reset_times()
571
+	{
572
+		Benchmark::resetTimes();
573
+	}
574
+
575
+
576
+
577
+	/**
578
+	 * @deprecated 4.9.39.rc.034
579
+	 * @param null $timer_name
580
+	 */
581
+	public function start_timer($timer_name = null)
582
+	{
583
+		Benchmark::startTimer($timer_name);
584
+	}
585
+
586
+
587
+
588
+	/**
589
+	 * @deprecated 4.9.39.rc.034
590
+	 * @param string $timer_name
591
+	 */
592
+	public function stop_timer($timer_name = '')
593
+	{
594
+		Benchmark::stopTimer($timer_name);
595
+	}
596
+
597
+
598
+
599
+	/**
600
+	 * @deprecated 4.9.39.rc.034
601
+	 * @param string  $label      The label to show for this time eg "Start of calling Some_Class::some_function"
602
+	 * @param boolean $output_now whether to echo now, or wait until EEH_Debug_Tools::show_times() is called
603
+	 * @return void
604
+	 */
605
+	public function measure_memory($label, $output_now = false)
606
+	{
607
+		Benchmark::measureMemory($label, $output_now);
608
+	}
609
+
610
+
611
+
612
+	/**
613
+	 * @deprecated 4.9.39.rc.034
614
+	 * @param int $size
615
+	 * @return string
616
+	 */
617
+	public function convert($size)
618
+	{
619
+		return Benchmark::convert($size);
620
+	}
621
+
622
+
623
+
624
+	/**
625
+	 * @deprecated 4.9.39.rc.034
626
+	 * @param bool $output_now
627
+	 * @return string
628
+	 */
629
+	public function show_times($output_now = true)
630
+	{
631
+		return Benchmark::displayResults($output_now);
632
+	}
633
+
634
+
635
+
636
+	/**
637
+	 * @deprecated 4.9.39.rc.034
638
+	 * @param string $timer_name
639
+	 * @param float  $total_time
640
+	 * @return string
641
+	 */
642
+	public function format_time($timer_name, $total_time)
643
+	{
644
+		return Benchmark::formatTime($timer_name, $total_time);
645
+	}
646 646
 
647 647
 
648 648
 
@@ -655,31 +655,31 @@  discard block
 block discarded – undo
655 655
  * Plugin URI: http://upthemes.com/plugins/kint-debugger/
656 656
  */
657 657
 if (class_exists('Kint') && ! function_exists('dump_wp_query')) {
658
-    function dump_wp_query()
659
-    {
660
-        global $wp_query;
661
-        d($wp_query);
662
-    }
658
+	function dump_wp_query()
659
+	{
660
+		global $wp_query;
661
+		d($wp_query);
662
+	}
663 663
 }
664 664
 /**
665 665
  * borrowed from Kint Debugger
666 666
  * Plugin URI: http://upthemes.com/plugins/kint-debugger/
667 667
  */
668 668
 if (class_exists('Kint') && ! function_exists('dump_wp')) {
669
-    function dump_wp()
670
-    {
671
-        global $wp;
672
-        d($wp);
673
-    }
669
+	function dump_wp()
670
+	{
671
+		global $wp;
672
+		d($wp);
673
+	}
674 674
 }
675 675
 /**
676 676
  * borrowed from Kint Debugger
677 677
  * Plugin URI: http://upthemes.com/plugins/kint-debugger/
678 678
  */
679 679
 if (class_exists('Kint') && ! function_exists('dump_post')) {
680
-    function dump_post()
681
-    {
682
-        global $post;
683
-        d($post);
684
-    }
680
+	function dump_post()
681
+	{
682
+		global $post;
683
+		d($post);
684
+	}
685 685
 }
Please login to merge, or discard this patch.
Spacing   +29 added lines, -29 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php use EventEspresso\core\services\Benchmark;
2 2
 
3
-if (! defined('EVENT_ESPRESSO_VERSION')) {
3
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
4 4
     exit('No direct script access allowed');
5 5
 }
6 6
 
@@ -40,7 +40,7 @@  discard block
 block discarded – undo
40 40
     public static function instance()
41 41
     {
42 42
         // check if class object is instantiated, and instantiated properly
43
-        if (! self::$_instance instanceof EEH_Debug_Tools) {
43
+        if ( ! self::$_instance instanceof EEH_Debug_Tools) {
44 44
             self::$_instance = new self();
45 45
         }
46 46
         return self::$_instance;
@@ -54,13 +54,13 @@  discard block
 block discarded – undo
54 54
     private function __construct()
55 55
     {
56 56
         // load Kint PHP debugging library
57
-        if (! class_exists('Kint') && file_exists(EE_PLUGIN_DIR_PATH . 'tests' . DS . 'kint' . DS . 'Kint.class.php')) {
57
+        if ( ! class_exists('Kint') && file_exists(EE_PLUGIN_DIR_PATH.'tests'.DS.'kint'.DS.'Kint.class.php')) {
58 58
             // despite EE4 having a check for an existing copy of the Kint debugging class,
59 59
             // if another plugin was loaded AFTER EE4 and they did NOT perform a similar check,
60 60
             // then hilarity would ensue as PHP throws a "Cannot redeclare class Kint" error
61 61
             // so we've moved it to our test folder so that it is not included with production releases
62 62
             // plz use https://wordpress.org/plugins/kint-debugger/  if testing production versions of EE
63
-            require_once(EE_PLUGIN_DIR_PATH . 'tests' . DS . 'kint' . DS . 'Kint.class.php');
63
+            require_once(EE_PLUGIN_DIR_PATH.'tests'.DS.'kint'.DS.'Kint.class.php');
64 64
         }
65 65
         // if ( ! defined('DOING_AJAX') || $_REQUEST['noheader'] !== 'true' || ! isset( $_REQUEST['noheader'], $_REQUEST['TB_iframe'] ) ) {
66 66
         //add_action( 'shutdown', array($this,'espresso_session_footer_dump') );
@@ -80,7 +80,7 @@  discard block
 block discarded – undo
80 80
      */
81 81
     public static function show_db_name()
82 82
     {
83
-        if (! defined('DOING_AJAX') && (defined('EE_ERROR_EMAILS') && EE_ERROR_EMAILS)) {
83
+        if ( ! defined('DOING_AJAX') && (defined('EE_ERROR_EMAILS') && EE_ERROR_EMAILS)) {
84 84
             echo '<p style="font-size:10px;font-weight:normal;color:#E76700;margin: 1em 2em; text-align: right;">DB_NAME: '
85 85
                  . DB_NAME
86 86
                  . '</p>';
@@ -131,11 +131,11 @@  discard block
 block discarded – undo
131 131
         echo '<br/><br/><br/><h3>Hooked Functions</h3>';
132 132
         if ($tag) {
133 133
             $hook[$tag] = $wp_filter[$tag];
134
-            if (! is_array($hook[$tag])) {
134
+            if ( ! is_array($hook[$tag])) {
135 135
                 trigger_error("Nothing found for '$tag' hook", E_USER_WARNING);
136 136
                 return;
137 137
             }
138
-            echo '<h5>For Tag: ' . $tag . '</h5>';
138
+            echo '<h5>For Tag: '.$tag.'</h5>';
139 139
         } else {
140 140
             $hook = is_array($wp_filter) ? $wp_filter : array($wp_filter);
141 141
             ksort($hook);
@@ -188,17 +188,17 @@  discard block
 block discarded – undo
188 188
     {
189 189
         if (WP_DEBUG) {
190 190
             $activation_errors = ob_get_contents();
191
-            if (! empty($activation_errors)) {
192
-                $activation_errors = date('Y-m-d H:i:s') . "\n" . $activation_errors;
191
+            if ( ! empty($activation_errors)) {
192
+                $activation_errors = date('Y-m-d H:i:s')."\n".$activation_errors;
193 193
             }
194
-            espresso_load_required('EEH_File', EE_HELPERS . 'EEH_File.helper.php');
194
+            espresso_load_required('EEH_File', EE_HELPERS.'EEH_File.helper.php');
195 195
             if (class_exists('EEH_File')) {
196 196
                 try {
197 197
                     EEH_File::ensure_file_exists_and_is_writable(
198
-                        EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . 'espresso_plugin_activation_errors.html'
198
+                        EVENT_ESPRESSO_UPLOAD_DIR.'logs'.DS.'espresso_plugin_activation_errors.html'
199 199
                     );
200 200
                     EEH_File::write_to_file(
201
-                        EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . 'espresso_plugin_activation_errors.html',
201
+                        EVENT_ESPRESSO_UPLOAD_DIR.'logs'.DS.'espresso_plugin_activation_errors.html',
202 202
                         $activation_errors
203 203
                     );
204 204
                 } catch (EE_Error $e) {
@@ -216,11 +216,11 @@  discard block
 block discarded – undo
216 216
             } else {
217 217
                 // old school attempt
218 218
                 file_put_contents(
219
-                    EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . 'espresso_plugin_activation_errors.html',
219
+                    EVENT_ESPRESSO_UPLOAD_DIR.'logs'.DS.'espresso_plugin_activation_errors.html',
220 220
                     $activation_errors
221 221
                 );
222 222
             }
223
-            $activation_errors = get_option('ee_plugin_activation_errors', '') . $activation_errors;
223
+            $activation_errors = get_option('ee_plugin_activation_errors', '').$activation_errors;
224 224
             update_option('ee_plugin_activation_errors', $activation_errors);
225 225
         }
226 226
     }
@@ -280,7 +280,7 @@  discard block
 block discarded – undo
280 280
         // don't trigger error if doing ajax,
281 281
         // instead we'll add a transient EE_Error notice that in theory should show on the next request.
282 282
         if (defined('DOING_AJAX') && DOING_AJAX) {
283
-            $error_message .= ' ' . esc_html__(
283
+            $error_message .= ' '.esc_html__(
284 284
                     'This is a doing_it_wrong message that was triggered during an ajax request.  The request params on this request were: ',
285 285
                     'event_espresso'
286 286
                 );
@@ -324,16 +324,16 @@  discard block
 block discarded – undo
324 324
         $debug_key = 'EE_DEBUG_SPCO'
325 325
     ) {
326 326
         if (WP_DEBUG) {
327
-            $debug_key = $debug_key . '_' . EE_Session::instance()->id();
327
+            $debug_key = $debug_key.'_'.EE_Session::instance()->id();
328 328
             $debug_data = get_option($debug_key, array());
329 329
             $default_data = array(
330
-                $class => $func . '() : ' . $line,
330
+                $class => $func.'() : '.$line,
331 331
                 'REQ'  => $display_request ? $_REQUEST : '',
332 332
             );
333 333
             // don't serialize objects
334 334
             $info = self::strip_objects($info);
335 335
             $index = ! empty($debug_index) ? $debug_index : 0;
336
-            if (! isset($debug_data[$index])) {
336
+            if ( ! isset($debug_data[$index])) {
337 337
                 $debug_data[$index] = array();
338 338
             }
339 339
             $debug_data[$index][microtime()] = array_merge($default_data, $info);
@@ -369,7 +369,7 @@  discard block
 block discarded – undo
369 369
                 unset($info[$key]);
370 370
             }
371 371
         }
372
-        return (array)$info;
372
+        return (array) $info;
373 373
     }
374 374
 
375 375
 
@@ -399,8 +399,8 @@  discard block
 block discarded – undo
399 399
         $heading_tag = is_int($heading_tag) ? "h{$heading_tag}" : 'h5';
400 400
         $result = EEH_Debug_Tools::heading($var_name, $heading_tag, $margin);
401 401
         $result .= $is_method
402
-            ? EEH_Debug_Tools::grey_span('::') . EEH_Debug_Tools::orange_span($var . '()')
403
-            : EEH_Debug_Tools::grey_span(' : ') . EEH_Debug_Tools::orange_span($var);
402
+            ? EEH_Debug_Tools::grey_span('::').EEH_Debug_Tools::orange_span($var.'()')
403
+            : EEH_Debug_Tools::grey_span(' : ').EEH_Debug_Tools::orange_span($var);
404 404
         $result .= EEH_Debug_Tools::file_and_line($file, $line);
405 405
         $result .= EEH_Debug_Tools::headingX($heading_tag);
406 406
         if ($die) {
@@ -423,7 +423,7 @@  discard block
 block discarded – undo
423 423
             return "\n{$var_name}";
424 424
         }
425 425
         $margin = "25px 0 0 {$margin}";
426
-        return '<' . $heading_tag . ' style="color:#2EA2CC; margin:' . $margin . ';"><b>' . $var_name . '</b>';
426
+        return '<'.$heading_tag.' style="color:#2EA2CC; margin:'.$margin.';"><b>'.$var_name.'</b>';
427 427
     }
428 428
 
429 429
 
@@ -437,7 +437,7 @@  discard block
 block discarded – undo
437 437
         if (defined('EE_TESTS_DIR')) {
438 438
             return '';
439 439
         }
440
-        return '</' . $heading_tag . '>';
440
+        return '</'.$heading_tag.'>';
441 441
     }
442 442
 
443 443
 
@@ -451,7 +451,7 @@  discard block
 block discarded – undo
451 451
         if (defined('EE_TESTS_DIR')) {
452 452
             return $content;
453 453
         }
454
-        return '<span style="color:#999">' . $content . '</span>';
454
+        return '<span style="color:#999">'.$content.'</span>';
455 455
     }
456 456
 
457 457
 
@@ -467,7 +467,7 @@  discard block
 block discarded – undo
467 467
             return '';
468 468
         }
469 469
         if (defined('EE_TESTS_DIR')) {
470
-            return "\n (" . $file . ' line no: ' . $line . ' ) ';
470
+            return "\n (".$file.' line no: '.$line.' ) ';
471 471
         }
472 472
         return '<br /><span style="font-size:9px;font-weight:normal;color:#666;line-height: 12px;">'
473 473
                . $file
@@ -487,7 +487,7 @@  discard block
 block discarded – undo
487 487
         if (defined('EE_TESTS_DIR')) {
488 488
             return $content;
489 489
         }
490
-        return '<span style="color:#E76700">' . $content . '</span>';
490
+        return '<span style="color:#E76700">'.$content.'</span>';
491 491
     }
492 492
 
493 493
 
@@ -502,9 +502,9 @@  discard block
 block discarded – undo
502 502
         var_dump($var);
503 503
         $var = ob_get_clean();
504 504
         if (defined('EE_TESTS_DIR')) {
505
-            return "\n" . $var;
505
+            return "\n".$var;
506 506
         }
507
-        return '<pre style="color:#999; padding:1em; background: #fff">' . $var . '</pre>';
507
+        return '<pre style="color:#999; padding:1em; background: #fff">'.$var.'</pre>';
508 508
     }
509 509
 
510 510
 
@@ -547,7 +547,7 @@  discard block
 block discarded – undo
547 547
         $var_name = ucwords(str_replace(array('$', '_'), array('', ' '), $var_name));
548 548
         $heading_tag = is_int($heading_tag) ? "h{$heading_tag}" : 'h5';
549 549
         $result = EEH_Debug_Tools::heading($var_name, $heading_tag, $margin);
550
-        $result .= EEH_Debug_Tools::grey_span(' : ') . EEH_Debug_Tools::orange_span(
550
+        $result .= EEH_Debug_Tools::grey_span(' : ').EEH_Debug_Tools::orange_span(
551 551
                 EEH_Debug_Tools::pre_span($var)
552 552
             );
553 553
         $result .= EEH_Debug_Tools::file_and_line($file, $line);
Please login to merge, or discard this patch.
core/EED_Module.module.php 1 patch
Indentation   +115 added lines, -115 removed lines patch added patch discarded remove patch
@@ -14,121 +14,121 @@
 block discarded – undo
14 14
 abstract class EED_Module extends EE_Configurable implements ResettableInterface
15 15
 {
16 16
 
17
-    /**
18
-     * rendered output to be returned to WP
19
-     *
20
-     * @var    string $output
21
-     */
22
-    protected $output = '';
23
-
24
-    /**
25
-     * the current active espresso template theme
26
-     *
27
-     * @var    string $theme
28
-     */
29
-    protected $theme = '';
30
-
31
-
32
-
33
-    /**
34
-     * @return void
35
-     */
36
-    public static function reset()
37
-    {
38
-        $module_name = get_called_class();
39
-        new $module_name();
40
-    }
41
-
42
-
43
-
44
-    /**
45
-     *    set_hooks - for hooking into EE Core, other modules, etc
46
-     *
47
-     * @access    public
48
-     * @return    void
49
-     */
50
-    public static function set_hooks()
51
-    {
52
-    }
53
-
54
-
55
-
56
-    /**
57
-     *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
58
-     *
59
-     * @access    public
60
-     * @return    void
61
-     */
62
-    public static function set_hooks_admin()
63
-    {
64
-    }
65
-
66
-
67
-
68
-    /**
69
-     *    run - initial module setup
70
-     *    this method is primarily used for activating resources in the EE_Front_Controller thru the use of filters
71
-     *
72
-     * @access    public
73
-     * @var            WP $WP
74
-     * @return    void
75
-     */
76
-    abstract public function run($WP);
77
-
78
-
79
-
80
-    /**
81
-     * EED_Module constructor.
82
-     */
83
-    final public function __construct()
84
-    {
85
-        $this->theme = EE_Config::get_current_theme();
86
-        $module_name = $this->module_name();
87
-        EE_Registry::instance()->modules->{$module_name} = $this;
88
-    }
89
-
90
-
91
-
92
-    /**
93
-     * @param $module_name
94
-     * @return EED_Module
95
-     */
96
-    protected static function get_instance($module_name = '')
97
-    {
98
-        $module_name = ! empty($module_name)
99
-            ? $module_name
100
-            : get_called_class();
101
-        if (
102
-            ! isset(EE_Registry::instance()->modules->{$module_name})
103
-            || ! EE_Registry::instance()->modules->{$module_name} instanceof EED_Module
104
-        ) {
105
-            EE_Registry::instance()->add_module($module_name);
106
-        }
107
-        return EE_Registry::instance()->get_module($module_name);
108
-    }
109
-
110
-
111
-
112
-    /**
113
-     *    module_name
114
-     *
115
-     * @access    public
116
-     * @return    string
117
-     */
118
-    public function module_name()
119
-    {
120
-        return get_class($this);
121
-    }
122
-
123
-
124
-
125
-    /**
126
-     * @return string
127
-     */
128
-    public function theme()
129
-    {
130
-        return $this->theme;
131
-    }
17
+	/**
18
+	 * rendered output to be returned to WP
19
+	 *
20
+	 * @var    string $output
21
+	 */
22
+	protected $output = '';
23
+
24
+	/**
25
+	 * the current active espresso template theme
26
+	 *
27
+	 * @var    string $theme
28
+	 */
29
+	protected $theme = '';
30
+
31
+
32
+
33
+	/**
34
+	 * @return void
35
+	 */
36
+	public static function reset()
37
+	{
38
+		$module_name = get_called_class();
39
+		new $module_name();
40
+	}
41
+
42
+
43
+
44
+	/**
45
+	 *    set_hooks - for hooking into EE Core, other modules, etc
46
+	 *
47
+	 * @access    public
48
+	 * @return    void
49
+	 */
50
+	public static function set_hooks()
51
+	{
52
+	}
53
+
54
+
55
+
56
+	/**
57
+	 *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
58
+	 *
59
+	 * @access    public
60
+	 * @return    void
61
+	 */
62
+	public static function set_hooks_admin()
63
+	{
64
+	}
65
+
66
+
67
+
68
+	/**
69
+	 *    run - initial module setup
70
+	 *    this method is primarily used for activating resources in the EE_Front_Controller thru the use of filters
71
+	 *
72
+	 * @access    public
73
+	 * @var            WP $WP
74
+	 * @return    void
75
+	 */
76
+	abstract public function run($WP);
77
+
78
+
79
+
80
+	/**
81
+	 * EED_Module constructor.
82
+	 */
83
+	final public function __construct()
84
+	{
85
+		$this->theme = EE_Config::get_current_theme();
86
+		$module_name = $this->module_name();
87
+		EE_Registry::instance()->modules->{$module_name} = $this;
88
+	}
89
+
90
+
91
+
92
+	/**
93
+	 * @param $module_name
94
+	 * @return EED_Module
95
+	 */
96
+	protected static function get_instance($module_name = '')
97
+	{
98
+		$module_name = ! empty($module_name)
99
+			? $module_name
100
+			: get_called_class();
101
+		if (
102
+			! isset(EE_Registry::instance()->modules->{$module_name})
103
+			|| ! EE_Registry::instance()->modules->{$module_name} instanceof EED_Module
104
+		) {
105
+			EE_Registry::instance()->add_module($module_name);
106
+		}
107
+		return EE_Registry::instance()->get_module($module_name);
108
+	}
109
+
110
+
111
+
112
+	/**
113
+	 *    module_name
114
+	 *
115
+	 * @access    public
116
+	 * @return    string
117
+	 */
118
+	public function module_name()
119
+	{
120
+		return get_class($this);
121
+	}
122
+
123
+
124
+
125
+	/**
126
+	 * @return string
127
+	 */
128
+	public function theme()
129
+	{
130
+		return $this->theme;
131
+	}
132 132
 
133 133
 
134 134
 
Please login to merge, or discard this patch.
core/helpers/EEH_Schema.helper.php 2 patches
Indentation   +73 added lines, -73 removed lines patch added patch discarded remove patch
@@ -17,74 +17,74 @@  discard block
 block discarded – undo
17 17
 class EEH_Schema {
18 18
 
19 19
 
20
-    /**
21
-     * generates JSON-based linked data for an event
22
-     *
23
-     * @param EE_Event $event
24
-     * @throws EE_Error
25
-     */
26
-    public static function add_json_linked_data_for_event(EE_Event $event)
27
-    {
28
-    	//Check we have a valid datetime for the event
29
-    	if(! $event->primary_datetime() instanceof EE_Datetime) {
30
-    		return;
31
-    	}
32
-
33
-        $template_args = array(
34
-            'event_permalink' => '',
35
-            'event_name' => '',
36
-            'event_description' => '',
37
-            'event_start' => '',
38
-            'event_end' => '',
39
-            'currency' => '',
40
-            'event_tickets' => array(),
41
-            'venue_name' => '',
42
-            'venue_url' => '',
43
-            'venue_locality' => '',
44
-            'venue_region' => '',
45
-            'event_image' => '',
46
-        );
47
-        $template_args['event_permalink'] = $event->get_permalink();
48
-        $template_args['event_name'] = $event->name();
49
-        $template_args['event_description'] = wp_strip_all_tags($event->short_description(200));
50
-        // clone datetime so that date formats don't override those for the original datetime
51
-        $primary_datetime = clone $event->primary_datetime();
52
-        $template_args['event_start'] = $primary_datetime->start_date(DateTime::ATOM);
53
-        $template_args['event_end'] = $primary_datetime->end_date(DateTime::ATOM);
54
-        unset($primary_datetime);
55
-        $template_args['currency'] = EE_Registry::instance()->CFG->currency->code;
56
-        foreach ($event->tickets() as $original_ticket) {
57
-            // clone tickets so that date formats don't override those for the original ticket
58
-            $ticket= clone $original_ticket;
59
-            $ID = $ticket->ID();
60
-            $template_args['event_tickets'][$ID]['start_date'] = $ticket->start_date(DateTime::ATOM, null);
61
-            $template_args['event_tickets'][$ID]['end_date'] = $ticket->end_date(DateTime::ATOM, null);
62
-            $template_args['event_tickets'][$ID]['price'] = number_format(
63
-                $ticket->price(),
64
-                EE_Registry::instance()->CFG->currency->dec_plc,
65
-                EE_Registry::instance()->CFG->currency->dec_mrk,
66
-                EE_Registry::instance()->CFG->currency->thsnds
67
-            );
68
-            unset($ticket);
69
-        }
70
-        $VNU_ID = espresso_venue_id();
71
-        if ( ! empty($VNU_ID) && ! espresso_is_venue_private($VNU_ID)) {
72
-            $venue = EEH_Venue_View::get_venue($VNU_ID);
73
-            $template_args['venue_name'] = get_the_title($VNU_ID);
74
-            $template_args['venue_url'] = get_permalink($VNU_ID);
75
-            $template_args['venue_locality'] = $venue->city();
76
-            $template_args['venue_region'] = $venue->state_name();
77
-        }
78
-        $template_args['event_image'] = $event->feature_image_url();
79
-        $template_args = apply_filters(
80
-            'FHEE__EEH_Schema__add_json_linked_data_for_event__template_args',
81
-            $template_args,
82
-            $event,
83
-            $VNU_ID
84
-        );
85
-        extract($template_args, EXTR_OVERWRITE);
86
-        include EE_TEMPLATES . 'json_linked_data_for_event.template.php';
87
-    }
20
+	/**
21
+	 * generates JSON-based linked data for an event
22
+	 *
23
+	 * @param EE_Event $event
24
+	 * @throws EE_Error
25
+	 */
26
+	public static function add_json_linked_data_for_event(EE_Event $event)
27
+	{
28
+		//Check we have a valid datetime for the event
29
+		if(! $event->primary_datetime() instanceof EE_Datetime) {
30
+			return;
31
+		}
32
+
33
+		$template_args = array(
34
+			'event_permalink' => '',
35
+			'event_name' => '',
36
+			'event_description' => '',
37
+			'event_start' => '',
38
+			'event_end' => '',
39
+			'currency' => '',
40
+			'event_tickets' => array(),
41
+			'venue_name' => '',
42
+			'venue_url' => '',
43
+			'venue_locality' => '',
44
+			'venue_region' => '',
45
+			'event_image' => '',
46
+		);
47
+		$template_args['event_permalink'] = $event->get_permalink();
48
+		$template_args['event_name'] = $event->name();
49
+		$template_args['event_description'] = wp_strip_all_tags($event->short_description(200));
50
+		// clone datetime so that date formats don't override those for the original datetime
51
+		$primary_datetime = clone $event->primary_datetime();
52
+		$template_args['event_start'] = $primary_datetime->start_date(DateTime::ATOM);
53
+		$template_args['event_end'] = $primary_datetime->end_date(DateTime::ATOM);
54
+		unset($primary_datetime);
55
+		$template_args['currency'] = EE_Registry::instance()->CFG->currency->code;
56
+		foreach ($event->tickets() as $original_ticket) {
57
+			// clone tickets so that date formats don't override those for the original ticket
58
+			$ticket= clone $original_ticket;
59
+			$ID = $ticket->ID();
60
+			$template_args['event_tickets'][$ID]['start_date'] = $ticket->start_date(DateTime::ATOM, null);
61
+			$template_args['event_tickets'][$ID]['end_date'] = $ticket->end_date(DateTime::ATOM, null);
62
+			$template_args['event_tickets'][$ID]['price'] = number_format(
63
+				$ticket->price(),
64
+				EE_Registry::instance()->CFG->currency->dec_plc,
65
+				EE_Registry::instance()->CFG->currency->dec_mrk,
66
+				EE_Registry::instance()->CFG->currency->thsnds
67
+			);
68
+			unset($ticket);
69
+		}
70
+		$VNU_ID = espresso_venue_id();
71
+		if ( ! empty($VNU_ID) && ! espresso_is_venue_private($VNU_ID)) {
72
+			$venue = EEH_Venue_View::get_venue($VNU_ID);
73
+			$template_args['venue_name'] = get_the_title($VNU_ID);
74
+			$template_args['venue_url'] = get_permalink($VNU_ID);
75
+			$template_args['venue_locality'] = $venue->city();
76
+			$template_args['venue_region'] = $venue->state_name();
77
+		}
78
+		$template_args['event_image'] = $event->feature_image_url();
79
+		$template_args = apply_filters(
80
+			'FHEE__EEH_Schema__add_json_linked_data_for_event__template_args',
81
+			$template_args,
82
+			$event,
83
+			$VNU_ID
84
+		);
85
+		extract($template_args, EXTR_OVERWRITE);
86
+		include EE_TEMPLATES . 'json_linked_data_for_event.template.php';
87
+	}
88 88
 
89 89
 
90 90
 	/**
@@ -98,8 +98,8 @@  discard block
 block discarded – undo
98 98
 	 */
99 99
 	public static function location( $location = null ) {
100 100
 		return ! empty( $location ) ? '<div itemprop="location" itemscope itemtype="http://schema.org/Place">'
101
-		                              . $location
102
-		                              . '</div>' : '';
101
+									  . $location
102
+									  . '</div>' : '';
103 103
 	}
104 104
 
105 105
 
@@ -219,8 +219,8 @@  discard block
 block discarded – undo
219 219
 	 */
220 220
 	public static function postalCode( EEI_Address $obj_with_address = null ) {
221 221
 		return $obj_with_address->zip() !== null && $obj_with_address->zip() !== '' ? '<span itemprop="postalCode">'
222
-		                                                                              . $obj_with_address->zip()
223
-		                                                                              . '</span>' : '';
222
+																					  . $obj_with_address->zip()
223
+																					  . '</span>' : '';
224 224
 	}
225 225
 
226 226
 
@@ -254,7 +254,7 @@  discard block
 block discarded – undo
254 254
 		//Check the URL includes a scheme
255 255
 		$parsed_url = parse_url($url);
256 256
 		if ( empty($parsed_url['scheme']) ) {
257
-		    $url = 'http://' . ltrim($url, '/');
257
+			$url = 'http://' . ltrim($url, '/');
258 258
 		}
259 259
 
260 260
 		$atts = '';
Please login to merge, or discard this patch.
Spacing   +32 added lines, -32 removed lines patch added patch discarded remove patch
@@ -1,7 +1,7 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 
3
-if ( ! defined( 'EVENT_ESPRESSO_VERSION' ) ) {
4
-	exit( 'No direct script access allowed' );
3
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
4
+	exit('No direct script access allowed');
5 5
 }
6 6
 
7 7
 
@@ -26,7 +26,7 @@  discard block
 block discarded – undo
26 26
     public static function add_json_linked_data_for_event(EE_Event $event)
27 27
     {
28 28
     	//Check we have a valid datetime for the event
29
-    	if(! $event->primary_datetime() instanceof EE_Datetime) {
29
+    	if ( ! $event->primary_datetime() instanceof EE_Datetime) {
30 30
     		return;
31 31
     	}
32 32
 
@@ -55,7 +55,7 @@  discard block
 block discarded – undo
55 55
         $template_args['currency'] = EE_Registry::instance()->CFG->currency->code;
56 56
         foreach ($event->tickets() as $original_ticket) {
57 57
             // clone tickets so that date formats don't override those for the original ticket
58
-            $ticket= clone $original_ticket;
58
+            $ticket = clone $original_ticket;
59 59
             $ID = $ticket->ID();
60 60
             $template_args['event_tickets'][$ID]['start_date'] = $ticket->start_date(DateTime::ATOM, null);
61 61
             $template_args['event_tickets'][$ID]['end_date'] = $ticket->end_date(DateTime::ATOM, null);
@@ -83,7 +83,7 @@  discard block
 block discarded – undo
83 83
             $VNU_ID
84 84
         );
85 85
         extract($template_args, EXTR_OVERWRITE);
86
-        include EE_TEMPLATES . 'json_linked_data_for_event.template.php';
86
+        include EE_TEMPLATES.'json_linked_data_for_event.template.php';
87 87
     }
88 88
 
89 89
 
@@ -96,8 +96,8 @@  discard block
 block discarded – undo
96 96
 	 * @param string $location
97 97
 	 * @return string
98 98
 	 */
99
-	public static function location( $location = null ) {
100
-		return ! empty( $location ) ? '<div itemprop="location" itemscope itemtype="http://schema.org/Place">'
99
+	public static function location($location = null) {
100
+		return ! empty($location) ? '<div itemprop="location" itemscope itemtype="http://schema.org/Place">'
101 101
 		                              . $location
102 102
 		                              . '</div>' : '';
103 103
 	}
@@ -112,8 +112,8 @@  discard block
 block discarded – undo
112 112
 	 * @param string $name
113 113
 	 * @return string
114 114
 	 */
115
-	public static function name( $name = null ) {
116
-		return ! empty( $name ) ? '<span itemprop="name">' . $name . '</span>' : '';
115
+	public static function name($name = null) {
116
+		return ! empty($name) ? '<span itemprop="name">'.$name.'</span>' : '';
117 117
 	}
118 118
 
119 119
 
@@ -126,9 +126,9 @@  discard block
 block discarded – undo
126 126
 	 * @param EEI_Address $obj_with_address
127 127
 	 * @return string
128 128
 	 */
129
-	public static function streetAddress( EEI_Address $obj_with_address = null ) {
129
+	public static function streetAddress(EEI_Address $obj_with_address = null) {
130 130
 		return $obj_with_address->address() !== null && $obj_with_address->address() !== ''
131
-			? '<span itemprop="streetAddress">' . $obj_with_address->address() . '</span>' : '';
131
+			? '<span itemprop="streetAddress">'.$obj_with_address->address().'</span>' : '';
132 132
 	}
133 133
 
134 134
 
@@ -141,14 +141,14 @@  discard block
 block discarded – undo
141 141
 	 * @param EEI_Address $obj_with_address
142 142
 	 * @return string
143 143
 	 */
144
-	public static function postOfficeBoxNumber( EEI_Address $obj_with_address = null ) {
144
+	public static function postOfficeBoxNumber(EEI_Address $obj_with_address = null) {
145 145
 		// regex check for some form of PO Box or P.O. Box, etc, etc, etc
146
-		if ( preg_match(
146
+		if (preg_match(
147 147
 			"/^\s*((P(OST)?.?\s*(O(FF(ICE)?)?)?.?\s+(B(IN|OX))?)|B(IN|OX))/i",
148 148
 			$obj_with_address->address2()
149
-		) ) {
149
+		)) {
150 150
 			return $obj_with_address->address2() !== null && $obj_with_address->address2() !== ''
151
-				? '<span itemprop="postOfficeBoxNumber">' . $obj_with_address->address2() . '</span>' : '';
151
+				? '<span itemprop="postOfficeBoxNumber">'.$obj_with_address->address2().'</span>' : '';
152 152
 		} else {
153 153
 			return $obj_with_address->address2();
154 154
 		}
@@ -164,9 +164,9 @@  discard block
 block discarded – undo
164 164
 	 * @param EEI_Address $obj_with_address
165 165
 	 * @return string
166 166
 	 */
167
-	public static function addressLocality( EEI_Address $obj_with_address = null ) {
167
+	public static function addressLocality(EEI_Address $obj_with_address = null) {
168 168
 		return $obj_with_address->city() !== null && $obj_with_address->city() !== ''
169
-			? '<span itemprop="addressLocality">' . $obj_with_address->city() . '</span>' : '';
169
+			? '<span itemprop="addressLocality">'.$obj_with_address->city().'</span>' : '';
170 170
 	}
171 171
 
172 172
 
@@ -179,10 +179,10 @@  discard block
 block discarded – undo
179 179
 	 * @param EEI_Address $obj_with_address
180 180
 	 * @return string
181 181
 	 */
182
-	public static function addressRegion( EEI_Address $obj_with_address = null ) {
182
+	public static function addressRegion(EEI_Address $obj_with_address = null) {
183 183
 		$state = $obj_with_address->state_name();
184
-		if ( ! empty( $state ) ) {
185
-			return '<span itemprop="addressRegion">' . $state . '</span>';
184
+		if ( ! empty($state)) {
185
+			return '<span itemprop="addressRegion">'.$state.'</span>';
186 186
 		} else {
187 187
 			return '';
188 188
 		}
@@ -198,10 +198,10 @@  discard block
 block discarded – undo
198 198
 	 * @param EEI_Address $obj_with_address
199 199
 	 * @return string
200 200
 	 */
201
-	public static function addressCountry( EEI_Address $obj_with_address = null ) {
201
+	public static function addressCountry(EEI_Address $obj_with_address = null) {
202 202
 		$country = $obj_with_address->country_name();
203
-		if ( ! empty( $country ) ) {
204
-			return '<span itemprop="addressCountry">' . $country . '</span>';
203
+		if ( ! empty($country)) {
204
+			return '<span itemprop="addressCountry">'.$country.'</span>';
205 205
 		} else {
206 206
 			return '';
207 207
 		}
@@ -217,7 +217,7 @@  discard block
 block discarded – undo
217 217
 	 * @param EEI_Address $obj_with_address
218 218
 	 * @return string
219 219
 	 */
220
-	public static function postalCode( EEI_Address $obj_with_address = null ) {
220
+	public static function postalCode(EEI_Address $obj_with_address = null) {
221 221
 		return $obj_with_address->zip() !== null && $obj_with_address->zip() !== '' ? '<span itemprop="postalCode">'
222 222
 		                                                                              . $obj_with_address->zip()
223 223
 		                                                                              . '</span>' : '';
@@ -233,8 +233,8 @@  discard block
 block discarded – undo
233 233
 	 * @param string $phone_nmbr
234 234
 	 * @return string
235 235
 	 */
236
-	public static function telephone( $phone_nmbr = null ) {
237
-		return $phone_nmbr !== null && $phone_nmbr !== '' ? '<span itemprop="telephone">' . $phone_nmbr . '</span>'
236
+	public static function telephone($phone_nmbr = null) {
237
+		return $phone_nmbr !== null && $phone_nmbr !== '' ? '<span itemprop="telephone">'.$phone_nmbr.'</span>'
238 238
 			: '';
239 239
 	}
240 240
 
@@ -250,19 +250,19 @@  discard block
 block discarded – undo
250 250
 	 * @param array  $attributes - array of additional link attributes in  attribute_name => value pairs. ie: array( 'title' => 'click here', 'class' => 'link-class' )
251 251
 	 * @return string (link)
252 252
 	 */
253
-	public static function url( $url = null, $text = null, $attributes = array() ) {
253
+	public static function url($url = null, $text = null, $attributes = array()) {
254 254
 		//Check the URL includes a scheme
255 255
 		$parsed_url = parse_url($url);
256
-		if ( empty($parsed_url['scheme']) ) {
257
-		    $url = 'http://' . ltrim($url, '/');
256
+		if (empty($parsed_url['scheme'])) {
257
+		    $url = 'http://'.ltrim($url, '/');
258 258
 		}
259 259
 
260 260
 		$atts = '';
261
-		foreach ( $attributes as $attribute => $value ) {
262
-			$atts .= ' ' . $attribute . '="' . $value . '"';
261
+		foreach ($attributes as $attribute => $value) {
262
+			$atts .= ' '.$attribute.'="'.$value.'"';
263 263
 		}
264 264
 		$text = $text !== null && $text !== '' ? $text : $url;
265
-		return $url !== null && $url !== '' ? '<a itemprop="url" href="' . $url . '"' . $atts . '>' . $text . '</a>'
265
+		return $url !== null && $url !== '' ? '<a itemprop="url" href="'.$url.'"'.$atts.'>'.$text.'</a>'
266 266
 			: '';
267 267
 	}
268 268
 
Please login to merge, or discard this patch.
admin_pages/events/Events_Admin_List_Table.class.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -165,7 +165,7 @@
 block discarded – undo
165 165
 
166 166
     /**
167 167
      * @param EE_Event $item
168
-     * @return mixed|string
168
+     * @return string
169 169
      */
170 170
     public function column_id(EE_Event $item)
171 171
     {
Please login to merge, or discard this patch.
Indentation   +401 added lines, -401 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
 /**
@@ -26,406 +26,406 @@  discard block
 block discarded – undo
26 26
 {
27 27
 
28 28
 
29
-    /**
30
-     * @var EE_Datetime
31
-     */
32
-    private $_dtt;
33
-
34
-
35
-    /**
36
-     * Events_Admin_List_Table constructor.
37
-     *
38
-     * @param EE_Admin_Page $admin_page
39
-     */
40
-    public function __construct($admin_page)
41
-    {
42
-        parent::__construct($admin_page);
43
-        require_once(EE_HELPERS . 'EEH_DTT_Helper.helper.php');
44
-    }
45
-
46
-
47
-    /**
48
-     * Initial setup of data properties for the list table.
49
-     */
50
-    protected function _setup_data()
51
-    {
52
-        $this->_data           = $this->_admin_page->get_events($this->_per_page, $this->_current_page);
53
-        $this->_all_data_count = $this->_admin_page->get_events(0, 0, true);
54
-    }
55
-
56
-
57
-    /**
58
-     * Set up of additional properties for the list table.
59
-     */
60
-    protected function _set_properties()
61
-    {
62
-        $this->_wp_list_args = array(
63
-            'singular' => __('event', 'event_espresso'),
64
-            'plural'   => __('events', 'event_espresso'),
65
-            'ajax'     => true, //for now
66
-            'screen'   => $this->_admin_page->get_current_screen()->id,
67
-        );
68
-
69
-
70
-        $this->_columns = array(
71
-            'cb'              => '<input type="checkbox" />',
72
-            'id'              => __('ID', 'event_espresso'),
73
-            'name'            => __('Name', 'event_espresso'),
74
-            'author'          => __('Author', 'event_espresso'),
75
-            'venue'           => __('Venue', 'event_espresso'),
76
-            'start_date_time' => __('Event Start', 'event_espresso'),
77
-            'reg_begins'      => __('On Sale', 'event_espresso'),
78
-            'attendees'       => '<span class="dashicons dashicons-groups ee-icon-color-ee-green ee-icon-size-20"></span>',
79
-            //'tkts_sold' => __('Tickets Sold', 'event_espresso'),
80
-            'actions'         => __('Actions', 'event_espresso'),
81
-        );
82
-
83
-
84
-        $this->_sortable_columns = array(
85
-            'id'              => array('EVT_ID' => true),
86
-            'name'            => array('EVT_name' => false),
87
-            'author'          => array('EVT_wp_user' => false),
88
-            'venue'           => array('Venue.VNU_name' => false),
89
-            'start_date_time' => array('Datetime.DTT_EVT_start' => false),
90
-            'reg_begins'      => array('Datetime.Ticket.TKT_start_date' => false),
91
-        );
92
-
93
-        $this->_primary_column = 'id';
94
-
95
-        $this->_hidden_columns = array('author');
96
-    }
97
-
98
-
99
-    /**
100
-     * @return array
101
-     */
102
-    protected function _get_table_filters()
103
-    {
104
-        return array(); //no filters with decaf
105
-    }
106
-
107
-
108
-    /**
109
-     * Setup of views properties.
110
-     */
111
-    protected function _add_view_counts()
112
-    {
113
-        $this->_views['all']['count']   = $this->_admin_page->total_events();
114
-        $this->_views['draft']['count'] = $this->_admin_page->total_events_draft();
115
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
116
-            $this->_views['trash']['count'] = $this->_admin_page->total_trashed_events();
117
-        }
118
-    }
119
-
120
-
121
-    /**
122
-     * @param EE_Event $item
123
-     * @return string
124
-     */
125
-    protected function _get_row_class($item)
126
-    {
127
-        $class = parent::_get_row_class($item);
128
-        //add status class
129
-        $class .= $item instanceof EE_Event ? ' ee-status-strip event-status-' . $item->get_active_status() : '';
130
-        if ($this->_has_checkbox_column) {
131
-            $class .= ' has-checkbox-column';
132
-        }
133
-        return $class;
134
-    }
135
-
136
-
137
-    /**
138
-     * @param EE_Event $item
139
-     * @return string
140
-     */
141
-    public function column_status(EE_Event $item)
142
-    {
143
-        return '<span class="ee-status-strip ee-status-strip-td event-status-' . $item->get_active_status() . '"></span>';
144
-    }/**/
145
-
146
-
147
-    /**
148
-     * @param  EE_Event $item
149
-     * @return string
150
-     */
151
-    public function column_cb($item)
152
-    {
153
-        if (! $item instanceof EE_Event) {
154
-            return '';
155
-        }
156
-        $this->_dtt = $item->primary_datetime(); //set this for use in other columns
157
-
158
-        //does event have any attached registrations?
159
-        $regs = $item->count_related('Registration');
160
-        return $regs > 0 && $this->_view == 'trash' ? '<span class="ee-lock-icon"></span>' : sprintf(
161
-            '<input type="checkbox" name="EVT_IDs[]" value="%s" />', $item->ID()
162
-        );
163
-    }
164
-
165
-
166
-    /**
167
-     * @param EE_Event $item
168
-     * @return mixed|string
169
-     */
170
-    public function column_id(EE_Event $item)
171
-    {
172
-        $content = $item->ID();
173
-        $content .= '  <span class="show-on-mobile-view-only">' . $item->name() . '</span>';
174
-        return $content;
175
-    }
176
-
177
-
178
-    /**
179
-     * @param EE_Event $item
180
-     * @return string
181
-     */
182
-    public function column_name(EE_Event $item)
183
-    {
184
-        $edit_query_args = array(
185
-            'action' => 'edit',
186
-            'post'   => $item->ID(),
187
-        );
188
-        $edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
189
-        $actions         = $this->_column_name_action_setup($item);
190
-        $status          = ''; //$item->status() !== 'publish' ? ' (' . $item->status() . ')' : '';
191
-        $content         = '<strong><a class="row-title" href="' . $edit_link . '">' . $item->name() . '</a></strong>' . $status;
192
-        $content         .= '<br><span class="ee-status-text-small">' . EEH_Template::pretty_status($item->get_active_status(),
193
-                false, 'sentence') . '</span>';
194
-        $content         .= $this->row_actions($actions);
195
-        return $content;
196
-
197
-    }
198
-
199
-
200
-    /**
201
-     * Just a method for setting up the actions for the name column
202
-     *
203
-     * @param EE_Event $item
204
-     * @return array array of actions
205
-     */
206
-    protected function _column_name_action_setup(EE_Event $item)
207
-    {
208
-        //todo: remove when attendees is active
209
-        if (! defined('REG_ADMIN_URL')) {
210
-            define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
211
-        }
212
-
213
-        $actions = array();
214
-
215
-        if (EE_Registry::instance()->CAP->current_user_can('ee_edit_event', 'espresso_events_edit', $item->ID())) {
216
-            $edit_query_args = array(
217
-                'action' => 'edit',
218
-                'post'   => $item->ID(),
219
-            );
220
-            $edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
221
-            $actions['edit'] = '<a href="' . $edit_link . '" title="' . esc_attr__('Edit Event',
222
-                    'event_espresso') . '">' . __('Edit', 'event_espresso') . '</a>';
223
-
224
-        }
225
-
226
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_registration',
227
-            'espresso_registrations_view_registration', $item->ID())) {
228
-            $attendees_query_args = array(
229
-                'action'   => 'default',
230
-                'event_id' => $item->ID(),
231
-            );
232
-            $attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
233
-            $actions['attendees'] = '<a href="' . $attendees_link . '" title="' . esc_attr__('View Registrations',
234
-                    'event_espresso') . '">' . __('Registrations', 'event_espresso') . '</a>';
235
-        }
236
-
237
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_event', 'espresso_events_trash_event',
238
-            $item->ID())) {
239
-            $trash_event_query_args = array(
240
-                'action' => 'trash_event',
241
-                'EVT_ID' => $item->ID(),
242
-            );
243
-            $trash_event_link       = EE_Admin_Page::add_query_args_and_nonce($trash_event_query_args,
244
-                EVENTS_ADMIN_URL);
245
-        }
246
-
247
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_event', 'espresso_events_restore_event',
248
-            $item->ID())) {
249
-            $restore_event_query_args = array(
250
-                'action' => 'restore_event',
251
-                'EVT_ID' => $item->ID(),
252
-            );
253
-            $restore_event_link       = EE_Admin_Page::add_query_args_and_nonce($restore_event_query_args,
254
-                EVENTS_ADMIN_URL);
255
-        }
256
-
257
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_event', 'espresso_events_delete_event',
258
-            $item->ID())) {
259
-            $delete_event_query_args = array(
260
-                'action' => 'delete_event',
261
-                'EVT_ID' => $item->ID(),
262
-            );
263
-            $delete_event_link       = EE_Admin_Page::add_query_args_and_nonce($delete_event_query_args,
264
-                EVENTS_ADMIN_URL);
265
-        }
266
-
267
-        $view_link = get_permalink($item->ID());
268
-
269
-        $actions['view'] = '<a href="' . $view_link . '" title="' . esc_attr__('View Event',
270
-                'event_espresso') . '">' . __('View', 'event_espresso') . '</a>';
271
-
272
-        switch ($item->get('status')) {
273
-            case 'trash' :
274
-                if (EE_Registry::instance()->CAP->current_user_can('ee_delete_event', 'espresso_events_restore_event',
275
-                    $item->ID())) {
276
-                    $actions['restore_from_trash'] = '<a href="' . $restore_event_link . '" title="' . esc_attr__('Restore from Trash',
277
-                            'event_espresso') . '">' . __('Restore from Trash', 'event_espresso') . '</a>';
278
-                }
279
-                if ($item->count_related('Registration') === 0 && EE_Registry::instance()->CAP->current_user_can('ee_delete_event',
280
-                        'espresso_events_delete_event', $item->ID())) {
281
-                    $actions['delete'] = '<a href="' . $delete_event_link . '" title="' . esc_attr__('Delete Permanently',
282
-                            'event_espresso') . '">' . __('Delete Permanently', 'event_espresso') . '</a>';
283
-                }
284
-                break;
285
-            default :
286
-                if (EE_Registry::instance()->CAP->current_user_can('ee_delete_event', 'espresso_events_trash_event',
287
-                    $item->ID())) {
288
-                    $actions['move to trash'] = '<a href="' . $trash_event_link . '" title="' . esc_attr__('Trash Event',
289
-                            'event_espresso') . '">' . __('Trash', 'event_espresso') . '</a>';
290
-                }
291
-        }
292
-        return $actions;
293
-    }
294
-
295
-
296
-    /**
297
-     * @param EE_Event $item
298
-     * @return string
299
-     */
300
-    public function column_author(EE_Event $item)
301
-    {
302
-        //user author info
303
-        $event_author = get_userdata($item->wp_user());
304
-        $gravatar     = get_avatar($item->wp_user(), '15');
305
-        //filter link
306
-        $query_args = array(
307
-            'action'      => 'default',
308
-            'EVT_wp_user' => $item->wp_user(),
309
-        );
310
-        $filter_url = EE_Admin_Page::add_query_args_and_nonce($query_args, EVENTS_ADMIN_URL);
311
-        return $gravatar . '  <a href="' . $filter_url . '" title="' . esc_attr__('Click to filter events by this author.',
312
-                'event_espresso') . '">' . $event_author->display_name . '</a>';
313
-    }
314
-
315
-
316
-    /**
317
-     * @param EE_Event $item
318
-     * @return string
319
-     */
320
-    public function column_venue(EE_Event $item)
321
-    {
322
-        $venue = $item->get_first_related('Venue');
323
-        return ! empty($venue) ? $venue->name() : '';
324
-    }
325
-
326
-
327
-    /**
328
-     * @param EE_Event $item
329
-     * @throws EE_Error
330
-     */
331
-    public function column_start_date_time(EE_Event $item)
332
-    {
333
-        echo ! empty($this->_dtt) ? $this->_dtt->get_i18n_datetime('DTT_EVT_start') : __('No Date was saved for this Event',
334
-            'event_espresso');
335
-        //display in user's timezone?
336
-        echo ! empty($this->_dtt) ? $this->_dtt->display_in_my_timezone('DTT_EVT_start', 'get_i18n_datetime', '',
337
-            'My Timezone: ') : '';
338
-
339
-    }
340
-
341
-
342
-    /**
343
-     * @param EE_Event $item
344
-     * @throws EE_Error
345
-     */
346
-    public function column_reg_begins(EE_Event $item)
347
-    {
348
-        $reg_start = $item->get_ticket_with_earliest_start_time();
349
-        echo ! empty($reg_start) ? $reg_start->get_i18n_datetime('TKT_start_date') : __('No Tickets have been setup for this Event',
350
-            'event_espresso');
351
-        //display in user's timezone?
352
-        echo ! empty($reg_start) ? $reg_start->display_in_my_timezone('TKT_start_date', 'get_i18n_datetime', '',
353
-            'My Timezone: ') : '';/**/
354
-    }
355
-
356
-
357
-    /**
358
-     * @param EE_Event $item
359
-     * @return int|string
360
-     */
361
-    public function column_attendees(EE_Event $item)
362
-    {
363
-        $attendees_query_args = array(
364
-            'action'   => 'default',
365
-            'event_id' => $item->ID(),
366
-        );
367
-        $attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
368
-        $registered_attendees = EEM_Registration::instance()->get_event_registration_count($item->ID());
369
-        return EE_Registry::instance()->CAP->current_user_can('ee_read_registration',
370
-            'espresso_registrations_view_registration',
371
-            $item->ID()) ? '<a href="' . $attendees_link . '">' . $registered_attendees . '</a>' : $registered_attendees;
372
-    }
373
-
374
-
375
-    /**
376
-     * @param EE_Event $item
377
-     * @return float
378
-     */
379
-    public function column_tkts_sold(EE_Event $item)
380
-    {
381
-        return EEM_Ticket::instance()->sum(array(array('Datetime.EVT_ID' => $item->ID())), 'TKT_sold');
382
-    }
383
-
384
-
385
-    /**
386
-     * @param EE_Event $item
387
-     * @return string
388
-     */
389
-    public function column_actions(EE_Event $item)
390
-    {
391
-        //todo: remove when attendees is active
392
-        if (! defined('REG_ADMIN_URL')) {
393
-            define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
394
-        }
395
-        $actionlinks = array();
396
-
397
-        $view_link = get_permalink($item->ID());
398
-
399
-        $actionlinks[] = '<a href="' . $view_link . '" title="' . esc_attr__('View Event',
400
-                'event_espresso') . '" target="_blank">';
401
-        $actionlinks[] = '<div class="dashicons dashicons-search"></div></a>';
402
-
403
-        if (EE_Registry::instance()->CAP->current_user_can('ee_edit_event', 'espresso_events_edit', $item->ID())) {
404
-            $edit_query_args = array(
405
-                'action' => 'edit',
406
-                'post'   => $item->ID(),
407
-            );
408
-            $edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
409
-            $actionlinks[]   = '<a href="' . $edit_link . '" title="' . esc_attr__('Edit Event',
410
-                    'event_espresso') . '"><div class="ee-icon ee-icon-calendar-edit"></div></a>';
411
-        }
412
-
413
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_registration',
414
-            'espresso_registrations_view_registration', $item->ID())) {
415
-            $attendees_query_args = array(
416
-                'action'   => 'default',
417
-                'event_id' => $item->ID(),
418
-            );
419
-            $attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
420
-            $actionlinks[]        = '<a href="' . $attendees_link . '" title="' . esc_attr__('View Registrants',
421
-                    'event_espresso') . '"><div class="dashicons dashicons-groups"></div></a>';
422
-        }
423
-
424
-        $actionlinks = apply_filters('FHEE__Events_Admin_List_Table__column_actions__action_links', $actionlinks,
425
-            $item);
426
-
427
-        return $this->_action_string(implode("\n\t", $actionlinks), $item, 'div');
428
-    }
29
+	/**
30
+	 * @var EE_Datetime
31
+	 */
32
+	private $_dtt;
33
+
34
+
35
+	/**
36
+	 * Events_Admin_List_Table constructor.
37
+	 *
38
+	 * @param EE_Admin_Page $admin_page
39
+	 */
40
+	public function __construct($admin_page)
41
+	{
42
+		parent::__construct($admin_page);
43
+		require_once(EE_HELPERS . 'EEH_DTT_Helper.helper.php');
44
+	}
45
+
46
+
47
+	/**
48
+	 * Initial setup of data properties for the list table.
49
+	 */
50
+	protected function _setup_data()
51
+	{
52
+		$this->_data           = $this->_admin_page->get_events($this->_per_page, $this->_current_page);
53
+		$this->_all_data_count = $this->_admin_page->get_events(0, 0, true);
54
+	}
55
+
56
+
57
+	/**
58
+	 * Set up of additional properties for the list table.
59
+	 */
60
+	protected function _set_properties()
61
+	{
62
+		$this->_wp_list_args = array(
63
+			'singular' => __('event', 'event_espresso'),
64
+			'plural'   => __('events', 'event_espresso'),
65
+			'ajax'     => true, //for now
66
+			'screen'   => $this->_admin_page->get_current_screen()->id,
67
+		);
68
+
69
+
70
+		$this->_columns = array(
71
+			'cb'              => '<input type="checkbox" />',
72
+			'id'              => __('ID', 'event_espresso'),
73
+			'name'            => __('Name', 'event_espresso'),
74
+			'author'          => __('Author', 'event_espresso'),
75
+			'venue'           => __('Venue', 'event_espresso'),
76
+			'start_date_time' => __('Event Start', 'event_espresso'),
77
+			'reg_begins'      => __('On Sale', 'event_espresso'),
78
+			'attendees'       => '<span class="dashicons dashicons-groups ee-icon-color-ee-green ee-icon-size-20"></span>',
79
+			//'tkts_sold' => __('Tickets Sold', 'event_espresso'),
80
+			'actions'         => __('Actions', 'event_espresso'),
81
+		);
82
+
83
+
84
+		$this->_sortable_columns = array(
85
+			'id'              => array('EVT_ID' => true),
86
+			'name'            => array('EVT_name' => false),
87
+			'author'          => array('EVT_wp_user' => false),
88
+			'venue'           => array('Venue.VNU_name' => false),
89
+			'start_date_time' => array('Datetime.DTT_EVT_start' => false),
90
+			'reg_begins'      => array('Datetime.Ticket.TKT_start_date' => false),
91
+		);
92
+
93
+		$this->_primary_column = 'id';
94
+
95
+		$this->_hidden_columns = array('author');
96
+	}
97
+
98
+
99
+	/**
100
+	 * @return array
101
+	 */
102
+	protected function _get_table_filters()
103
+	{
104
+		return array(); //no filters with decaf
105
+	}
106
+
107
+
108
+	/**
109
+	 * Setup of views properties.
110
+	 */
111
+	protected function _add_view_counts()
112
+	{
113
+		$this->_views['all']['count']   = $this->_admin_page->total_events();
114
+		$this->_views['draft']['count'] = $this->_admin_page->total_events_draft();
115
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
116
+			$this->_views['trash']['count'] = $this->_admin_page->total_trashed_events();
117
+		}
118
+	}
119
+
120
+
121
+	/**
122
+	 * @param EE_Event $item
123
+	 * @return string
124
+	 */
125
+	protected function _get_row_class($item)
126
+	{
127
+		$class = parent::_get_row_class($item);
128
+		//add status class
129
+		$class .= $item instanceof EE_Event ? ' ee-status-strip event-status-' . $item->get_active_status() : '';
130
+		if ($this->_has_checkbox_column) {
131
+			$class .= ' has-checkbox-column';
132
+		}
133
+		return $class;
134
+	}
135
+
136
+
137
+	/**
138
+	 * @param EE_Event $item
139
+	 * @return string
140
+	 */
141
+	public function column_status(EE_Event $item)
142
+	{
143
+		return '<span class="ee-status-strip ee-status-strip-td event-status-' . $item->get_active_status() . '"></span>';
144
+	}/**/
145
+
146
+
147
+	/**
148
+	 * @param  EE_Event $item
149
+	 * @return string
150
+	 */
151
+	public function column_cb($item)
152
+	{
153
+		if (! $item instanceof EE_Event) {
154
+			return '';
155
+		}
156
+		$this->_dtt = $item->primary_datetime(); //set this for use in other columns
157
+
158
+		//does event have any attached registrations?
159
+		$regs = $item->count_related('Registration');
160
+		return $regs > 0 && $this->_view == 'trash' ? '<span class="ee-lock-icon"></span>' : sprintf(
161
+			'<input type="checkbox" name="EVT_IDs[]" value="%s" />', $item->ID()
162
+		);
163
+	}
164
+
165
+
166
+	/**
167
+	 * @param EE_Event $item
168
+	 * @return mixed|string
169
+	 */
170
+	public function column_id(EE_Event $item)
171
+	{
172
+		$content = $item->ID();
173
+		$content .= '  <span class="show-on-mobile-view-only">' . $item->name() . '</span>';
174
+		return $content;
175
+	}
176
+
177
+
178
+	/**
179
+	 * @param EE_Event $item
180
+	 * @return string
181
+	 */
182
+	public function column_name(EE_Event $item)
183
+	{
184
+		$edit_query_args = array(
185
+			'action' => 'edit',
186
+			'post'   => $item->ID(),
187
+		);
188
+		$edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
189
+		$actions         = $this->_column_name_action_setup($item);
190
+		$status          = ''; //$item->status() !== 'publish' ? ' (' . $item->status() . ')' : '';
191
+		$content         = '<strong><a class="row-title" href="' . $edit_link . '">' . $item->name() . '</a></strong>' . $status;
192
+		$content         .= '<br><span class="ee-status-text-small">' . EEH_Template::pretty_status($item->get_active_status(),
193
+				false, 'sentence') . '</span>';
194
+		$content         .= $this->row_actions($actions);
195
+		return $content;
196
+
197
+	}
198
+
199
+
200
+	/**
201
+	 * Just a method for setting up the actions for the name column
202
+	 *
203
+	 * @param EE_Event $item
204
+	 * @return array array of actions
205
+	 */
206
+	protected function _column_name_action_setup(EE_Event $item)
207
+	{
208
+		//todo: remove when attendees is active
209
+		if (! defined('REG_ADMIN_URL')) {
210
+			define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
211
+		}
212
+
213
+		$actions = array();
214
+
215
+		if (EE_Registry::instance()->CAP->current_user_can('ee_edit_event', 'espresso_events_edit', $item->ID())) {
216
+			$edit_query_args = array(
217
+				'action' => 'edit',
218
+				'post'   => $item->ID(),
219
+			);
220
+			$edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
221
+			$actions['edit'] = '<a href="' . $edit_link . '" title="' . esc_attr__('Edit Event',
222
+					'event_espresso') . '">' . __('Edit', 'event_espresso') . '</a>';
223
+
224
+		}
225
+
226
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_registration',
227
+			'espresso_registrations_view_registration', $item->ID())) {
228
+			$attendees_query_args = array(
229
+				'action'   => 'default',
230
+				'event_id' => $item->ID(),
231
+			);
232
+			$attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
233
+			$actions['attendees'] = '<a href="' . $attendees_link . '" title="' . esc_attr__('View Registrations',
234
+					'event_espresso') . '">' . __('Registrations', 'event_espresso') . '</a>';
235
+		}
236
+
237
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_event', 'espresso_events_trash_event',
238
+			$item->ID())) {
239
+			$trash_event_query_args = array(
240
+				'action' => 'trash_event',
241
+				'EVT_ID' => $item->ID(),
242
+			);
243
+			$trash_event_link       = EE_Admin_Page::add_query_args_and_nonce($trash_event_query_args,
244
+				EVENTS_ADMIN_URL);
245
+		}
246
+
247
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_event', 'espresso_events_restore_event',
248
+			$item->ID())) {
249
+			$restore_event_query_args = array(
250
+				'action' => 'restore_event',
251
+				'EVT_ID' => $item->ID(),
252
+			);
253
+			$restore_event_link       = EE_Admin_Page::add_query_args_and_nonce($restore_event_query_args,
254
+				EVENTS_ADMIN_URL);
255
+		}
256
+
257
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_event', 'espresso_events_delete_event',
258
+			$item->ID())) {
259
+			$delete_event_query_args = array(
260
+				'action' => 'delete_event',
261
+				'EVT_ID' => $item->ID(),
262
+			);
263
+			$delete_event_link       = EE_Admin_Page::add_query_args_and_nonce($delete_event_query_args,
264
+				EVENTS_ADMIN_URL);
265
+		}
266
+
267
+		$view_link = get_permalink($item->ID());
268
+
269
+		$actions['view'] = '<a href="' . $view_link . '" title="' . esc_attr__('View Event',
270
+				'event_espresso') . '">' . __('View', 'event_espresso') . '</a>';
271
+
272
+		switch ($item->get('status')) {
273
+			case 'trash' :
274
+				if (EE_Registry::instance()->CAP->current_user_can('ee_delete_event', 'espresso_events_restore_event',
275
+					$item->ID())) {
276
+					$actions['restore_from_trash'] = '<a href="' . $restore_event_link . '" title="' . esc_attr__('Restore from Trash',
277
+							'event_espresso') . '">' . __('Restore from Trash', 'event_espresso') . '</a>';
278
+				}
279
+				if ($item->count_related('Registration') === 0 && EE_Registry::instance()->CAP->current_user_can('ee_delete_event',
280
+						'espresso_events_delete_event', $item->ID())) {
281
+					$actions['delete'] = '<a href="' . $delete_event_link . '" title="' . esc_attr__('Delete Permanently',
282
+							'event_espresso') . '">' . __('Delete Permanently', 'event_espresso') . '</a>';
283
+				}
284
+				break;
285
+			default :
286
+				if (EE_Registry::instance()->CAP->current_user_can('ee_delete_event', 'espresso_events_trash_event',
287
+					$item->ID())) {
288
+					$actions['move to trash'] = '<a href="' . $trash_event_link . '" title="' . esc_attr__('Trash Event',
289
+							'event_espresso') . '">' . __('Trash', 'event_espresso') . '</a>';
290
+				}
291
+		}
292
+		return $actions;
293
+	}
294
+
295
+
296
+	/**
297
+	 * @param EE_Event $item
298
+	 * @return string
299
+	 */
300
+	public function column_author(EE_Event $item)
301
+	{
302
+		//user author info
303
+		$event_author = get_userdata($item->wp_user());
304
+		$gravatar     = get_avatar($item->wp_user(), '15');
305
+		//filter link
306
+		$query_args = array(
307
+			'action'      => 'default',
308
+			'EVT_wp_user' => $item->wp_user(),
309
+		);
310
+		$filter_url = EE_Admin_Page::add_query_args_and_nonce($query_args, EVENTS_ADMIN_URL);
311
+		return $gravatar . '  <a href="' . $filter_url . '" title="' . esc_attr__('Click to filter events by this author.',
312
+				'event_espresso') . '">' . $event_author->display_name . '</a>';
313
+	}
314
+
315
+
316
+	/**
317
+	 * @param EE_Event $item
318
+	 * @return string
319
+	 */
320
+	public function column_venue(EE_Event $item)
321
+	{
322
+		$venue = $item->get_first_related('Venue');
323
+		return ! empty($venue) ? $venue->name() : '';
324
+	}
325
+
326
+
327
+	/**
328
+	 * @param EE_Event $item
329
+	 * @throws EE_Error
330
+	 */
331
+	public function column_start_date_time(EE_Event $item)
332
+	{
333
+		echo ! empty($this->_dtt) ? $this->_dtt->get_i18n_datetime('DTT_EVT_start') : __('No Date was saved for this Event',
334
+			'event_espresso');
335
+		//display in user's timezone?
336
+		echo ! empty($this->_dtt) ? $this->_dtt->display_in_my_timezone('DTT_EVT_start', 'get_i18n_datetime', '',
337
+			'My Timezone: ') : '';
338
+
339
+	}
340
+
341
+
342
+	/**
343
+	 * @param EE_Event $item
344
+	 * @throws EE_Error
345
+	 */
346
+	public function column_reg_begins(EE_Event $item)
347
+	{
348
+		$reg_start = $item->get_ticket_with_earliest_start_time();
349
+		echo ! empty($reg_start) ? $reg_start->get_i18n_datetime('TKT_start_date') : __('No Tickets have been setup for this Event',
350
+			'event_espresso');
351
+		//display in user's timezone?
352
+		echo ! empty($reg_start) ? $reg_start->display_in_my_timezone('TKT_start_date', 'get_i18n_datetime', '',
353
+			'My Timezone: ') : '';/**/
354
+	}
355
+
356
+
357
+	/**
358
+	 * @param EE_Event $item
359
+	 * @return int|string
360
+	 */
361
+	public function column_attendees(EE_Event $item)
362
+	{
363
+		$attendees_query_args = array(
364
+			'action'   => 'default',
365
+			'event_id' => $item->ID(),
366
+		);
367
+		$attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
368
+		$registered_attendees = EEM_Registration::instance()->get_event_registration_count($item->ID());
369
+		return EE_Registry::instance()->CAP->current_user_can('ee_read_registration',
370
+			'espresso_registrations_view_registration',
371
+			$item->ID()) ? '<a href="' . $attendees_link . '">' . $registered_attendees . '</a>' : $registered_attendees;
372
+	}
373
+
374
+
375
+	/**
376
+	 * @param EE_Event $item
377
+	 * @return float
378
+	 */
379
+	public function column_tkts_sold(EE_Event $item)
380
+	{
381
+		return EEM_Ticket::instance()->sum(array(array('Datetime.EVT_ID' => $item->ID())), 'TKT_sold');
382
+	}
383
+
384
+
385
+	/**
386
+	 * @param EE_Event $item
387
+	 * @return string
388
+	 */
389
+	public function column_actions(EE_Event $item)
390
+	{
391
+		//todo: remove when attendees is active
392
+		if (! defined('REG_ADMIN_URL')) {
393
+			define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
394
+		}
395
+		$actionlinks = array();
396
+
397
+		$view_link = get_permalink($item->ID());
398
+
399
+		$actionlinks[] = '<a href="' . $view_link . '" title="' . esc_attr__('View Event',
400
+				'event_espresso') . '" target="_blank">';
401
+		$actionlinks[] = '<div class="dashicons dashicons-search"></div></a>';
402
+
403
+		if (EE_Registry::instance()->CAP->current_user_can('ee_edit_event', 'espresso_events_edit', $item->ID())) {
404
+			$edit_query_args = array(
405
+				'action' => 'edit',
406
+				'post'   => $item->ID(),
407
+			);
408
+			$edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
409
+			$actionlinks[]   = '<a href="' . $edit_link . '" title="' . esc_attr__('Edit Event',
410
+					'event_espresso') . '"><div class="ee-icon ee-icon-calendar-edit"></div></a>';
411
+		}
412
+
413
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_registration',
414
+			'espresso_registrations_view_registration', $item->ID())) {
415
+			$attendees_query_args = array(
416
+				'action'   => 'default',
417
+				'event_id' => $item->ID(),
418
+			);
419
+			$attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
420
+			$actionlinks[]        = '<a href="' . $attendees_link . '" title="' . esc_attr__('View Registrants',
421
+					'event_espresso') . '"><div class="dashicons dashicons-groups"></div></a>';
422
+		}
423
+
424
+		$actionlinks = apply_filters('FHEE__Events_Admin_List_Table__column_actions__action_links', $actionlinks,
425
+			$item);
426
+
427
+		return $this->_action_string(implode("\n\t", $actionlinks), $item, 'div');
428
+	}
429 429
 
430 430
 
431 431
 }
Please login to merge, or discard this patch.
Spacing   +36 added lines, -36 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
 
@@ -40,7 +40,7 @@  discard block
 block discarded – undo
40 40
     public function __construct($admin_page)
41 41
     {
42 42
         parent::__construct($admin_page);
43
-        require_once(EE_HELPERS . 'EEH_DTT_Helper.helper.php');
43
+        require_once(EE_HELPERS.'EEH_DTT_Helper.helper.php');
44 44
     }
45 45
 
46 46
 
@@ -126,7 +126,7 @@  discard block
 block discarded – undo
126 126
     {
127 127
         $class = parent::_get_row_class($item);
128 128
         //add status class
129
-        $class .= $item instanceof EE_Event ? ' ee-status-strip event-status-' . $item->get_active_status() : '';
129
+        $class .= $item instanceof EE_Event ? ' ee-status-strip event-status-'.$item->get_active_status() : '';
130 130
         if ($this->_has_checkbox_column) {
131 131
             $class .= ' has-checkbox-column';
132 132
         }
@@ -140,7 +140,7 @@  discard block
 block discarded – undo
140 140
      */
141 141
     public function column_status(EE_Event $item)
142 142
     {
143
-        return '<span class="ee-status-strip ee-status-strip-td event-status-' . $item->get_active_status() . '"></span>';
143
+        return '<span class="ee-status-strip ee-status-strip-td event-status-'.$item->get_active_status().'"></span>';
144 144
     }/**/
145 145
 
146 146
 
@@ -150,7 +150,7 @@  discard block
 block discarded – undo
150 150
      */
151 151
     public function column_cb($item)
152 152
     {
153
-        if (! $item instanceof EE_Event) {
153
+        if ( ! $item instanceof EE_Event) {
154 154
             return '';
155 155
         }
156 156
         $this->_dtt = $item->primary_datetime(); //set this for use in other columns
@@ -170,7 +170,7 @@  discard block
 block discarded – undo
170 170
     public function column_id(EE_Event $item)
171 171
     {
172 172
         $content = $item->ID();
173
-        $content .= '  <span class="show-on-mobile-view-only">' . $item->name() . '</span>';
173
+        $content .= '  <span class="show-on-mobile-view-only">'.$item->name().'</span>';
174 174
         return $content;
175 175
     }
176 176
 
@@ -188,9 +188,9 @@  discard block
 block discarded – undo
188 188
         $edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
189 189
         $actions         = $this->_column_name_action_setup($item);
190 190
         $status          = ''; //$item->status() !== 'publish' ? ' (' . $item->status() . ')' : '';
191
-        $content         = '<strong><a class="row-title" href="' . $edit_link . '">' . $item->name() . '</a></strong>' . $status;
192
-        $content         .= '<br><span class="ee-status-text-small">' . EEH_Template::pretty_status($item->get_active_status(),
193
-                false, 'sentence') . '</span>';
191
+        $content         = '<strong><a class="row-title" href="'.$edit_link.'">'.$item->name().'</a></strong>'.$status;
192
+        $content         .= '<br><span class="ee-status-text-small">'.EEH_Template::pretty_status($item->get_active_status(),
193
+                false, 'sentence').'</span>';
194 194
         $content         .= $this->row_actions($actions);
195 195
         return $content;
196 196
 
@@ -206,7 +206,7 @@  discard block
 block discarded – undo
206 206
     protected function _column_name_action_setup(EE_Event $item)
207 207
     {
208 208
         //todo: remove when attendees is active
209
-        if (! defined('REG_ADMIN_URL')) {
209
+        if ( ! defined('REG_ADMIN_URL')) {
210 210
             define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
211 211
         }
212 212
 
@@ -218,8 +218,8 @@  discard block
 block discarded – undo
218 218
                 'post'   => $item->ID(),
219 219
             );
220 220
             $edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
221
-            $actions['edit'] = '<a href="' . $edit_link . '" title="' . esc_attr__('Edit Event',
222
-                    'event_espresso') . '">' . __('Edit', 'event_espresso') . '</a>';
221
+            $actions['edit'] = '<a href="'.$edit_link.'" title="'.esc_attr__('Edit Event',
222
+                    'event_espresso').'">'.__('Edit', 'event_espresso').'</a>';
223 223
 
224 224
         }
225 225
 
@@ -230,8 +230,8 @@  discard block
 block discarded – undo
230 230
                 'event_id' => $item->ID(),
231 231
             );
232 232
             $attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
233
-            $actions['attendees'] = '<a href="' . $attendees_link . '" title="' . esc_attr__('View Registrations',
234
-                    'event_espresso') . '">' . __('Registrations', 'event_espresso') . '</a>';
233
+            $actions['attendees'] = '<a href="'.$attendees_link.'" title="'.esc_attr__('View Registrations',
234
+                    'event_espresso').'">'.__('Registrations', 'event_espresso').'</a>';
235 235
         }
236 236
 
237 237
         if (EE_Registry::instance()->CAP->current_user_can('ee_delete_event', 'espresso_events_trash_event',
@@ -240,7 +240,7 @@  discard block
 block discarded – undo
240 240
                 'action' => 'trash_event',
241 241
                 'EVT_ID' => $item->ID(),
242 242
             );
243
-            $trash_event_link       = EE_Admin_Page::add_query_args_and_nonce($trash_event_query_args,
243
+            $trash_event_link = EE_Admin_Page::add_query_args_and_nonce($trash_event_query_args,
244 244
                 EVENTS_ADMIN_URL);
245 245
         }
246 246
 
@@ -250,7 +250,7 @@  discard block
 block discarded – undo
250 250
                 'action' => 'restore_event',
251 251
                 'EVT_ID' => $item->ID(),
252 252
             );
253
-            $restore_event_link       = EE_Admin_Page::add_query_args_and_nonce($restore_event_query_args,
253
+            $restore_event_link = EE_Admin_Page::add_query_args_and_nonce($restore_event_query_args,
254 254
                 EVENTS_ADMIN_URL);
255 255
         }
256 256
 
@@ -260,33 +260,33 @@  discard block
 block discarded – undo
260 260
                 'action' => 'delete_event',
261 261
                 'EVT_ID' => $item->ID(),
262 262
             );
263
-            $delete_event_link       = EE_Admin_Page::add_query_args_and_nonce($delete_event_query_args,
263
+            $delete_event_link = EE_Admin_Page::add_query_args_and_nonce($delete_event_query_args,
264 264
                 EVENTS_ADMIN_URL);
265 265
         }
266 266
 
267 267
         $view_link = get_permalink($item->ID());
268 268
 
269
-        $actions['view'] = '<a href="' . $view_link . '" title="' . esc_attr__('View Event',
270
-                'event_espresso') . '">' . __('View', 'event_espresso') . '</a>';
269
+        $actions['view'] = '<a href="'.$view_link.'" title="'.esc_attr__('View Event',
270
+                'event_espresso').'">'.__('View', 'event_espresso').'</a>';
271 271
 
272 272
         switch ($item->get('status')) {
273 273
             case 'trash' :
274 274
                 if (EE_Registry::instance()->CAP->current_user_can('ee_delete_event', 'espresso_events_restore_event',
275 275
                     $item->ID())) {
276
-                    $actions['restore_from_trash'] = '<a href="' . $restore_event_link . '" title="' . esc_attr__('Restore from Trash',
277
-                            'event_espresso') . '">' . __('Restore from Trash', 'event_espresso') . '</a>';
276
+                    $actions['restore_from_trash'] = '<a href="'.$restore_event_link.'" title="'.esc_attr__('Restore from Trash',
277
+                            'event_espresso').'">'.__('Restore from Trash', 'event_espresso').'</a>';
278 278
                 }
279 279
                 if ($item->count_related('Registration') === 0 && EE_Registry::instance()->CAP->current_user_can('ee_delete_event',
280 280
                         'espresso_events_delete_event', $item->ID())) {
281
-                    $actions['delete'] = '<a href="' . $delete_event_link . '" title="' . esc_attr__('Delete Permanently',
282
-                            'event_espresso') . '">' . __('Delete Permanently', 'event_espresso') . '</a>';
281
+                    $actions['delete'] = '<a href="'.$delete_event_link.'" title="'.esc_attr__('Delete Permanently',
282
+                            'event_espresso').'">'.__('Delete Permanently', 'event_espresso').'</a>';
283 283
                 }
284 284
                 break;
285 285
             default :
286 286
                 if (EE_Registry::instance()->CAP->current_user_can('ee_delete_event', 'espresso_events_trash_event',
287 287
                     $item->ID())) {
288
-                    $actions['move to trash'] = '<a href="' . $trash_event_link . '" title="' . esc_attr__('Trash Event',
289
-                            'event_espresso') . '">' . __('Trash', 'event_espresso') . '</a>';
288
+                    $actions['move to trash'] = '<a href="'.$trash_event_link.'" title="'.esc_attr__('Trash Event',
289
+                            'event_espresso').'">'.__('Trash', 'event_espresso').'</a>';
290 290
                 }
291 291
         }
292 292
         return $actions;
@@ -308,8 +308,8 @@  discard block
 block discarded – undo
308 308
             'EVT_wp_user' => $item->wp_user(),
309 309
         );
310 310
         $filter_url = EE_Admin_Page::add_query_args_and_nonce($query_args, EVENTS_ADMIN_URL);
311
-        return $gravatar . '  <a href="' . $filter_url . '" title="' . esc_attr__('Click to filter events by this author.',
312
-                'event_espresso') . '">' . $event_author->display_name . '</a>';
311
+        return $gravatar.'  <a href="'.$filter_url.'" title="'.esc_attr__('Click to filter events by this author.',
312
+                'event_espresso').'">'.$event_author->display_name.'</a>';
313 313
     }
314 314
 
315 315
 
@@ -350,7 +350,7 @@  discard block
 block discarded – undo
350 350
             'event_espresso');
351 351
         //display in user's timezone?
352 352
         echo ! empty($reg_start) ? $reg_start->display_in_my_timezone('TKT_start_date', 'get_i18n_datetime', '',
353
-            'My Timezone: ') : '';/**/
353
+            'My Timezone: ') : ''; /**/
354 354
     }
355 355
 
356 356
 
@@ -368,7 +368,7 @@  discard block
 block discarded – undo
368 368
         $registered_attendees = EEM_Registration::instance()->get_event_registration_count($item->ID());
369 369
         return EE_Registry::instance()->CAP->current_user_can('ee_read_registration',
370 370
             'espresso_registrations_view_registration',
371
-            $item->ID()) ? '<a href="' . $attendees_link . '">' . $registered_attendees . '</a>' : $registered_attendees;
371
+            $item->ID()) ? '<a href="'.$attendees_link.'">'.$registered_attendees.'</a>' : $registered_attendees;
372 372
     }
373 373
 
374 374
 
@@ -389,15 +389,15 @@  discard block
 block discarded – undo
389 389
     public function column_actions(EE_Event $item)
390 390
     {
391 391
         //todo: remove when attendees is active
392
-        if (! defined('REG_ADMIN_URL')) {
392
+        if ( ! defined('REG_ADMIN_URL')) {
393 393
             define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
394 394
         }
395 395
         $actionlinks = array();
396 396
 
397 397
         $view_link = get_permalink($item->ID());
398 398
 
399
-        $actionlinks[] = '<a href="' . $view_link . '" title="' . esc_attr__('View Event',
400
-                'event_espresso') . '" target="_blank">';
399
+        $actionlinks[] = '<a href="'.$view_link.'" title="'.esc_attr__('View Event',
400
+                'event_espresso').'" target="_blank">';
401 401
         $actionlinks[] = '<div class="dashicons dashicons-search"></div></a>';
402 402
 
403 403
         if (EE_Registry::instance()->CAP->current_user_can('ee_edit_event', 'espresso_events_edit', $item->ID())) {
@@ -406,8 +406,8 @@  discard block
 block discarded – undo
406 406
                 'post'   => $item->ID(),
407 407
             );
408 408
             $edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
409
-            $actionlinks[]   = '<a href="' . $edit_link . '" title="' . esc_attr__('Edit Event',
410
-                    'event_espresso') . '"><div class="ee-icon ee-icon-calendar-edit"></div></a>';
409
+            $actionlinks[]   = '<a href="'.$edit_link.'" title="'.esc_attr__('Edit Event',
410
+                    'event_espresso').'"><div class="ee-icon ee-icon-calendar-edit"></div></a>';
411 411
         }
412 412
 
413 413
         if (EE_Registry::instance()->CAP->current_user_can('ee_read_registration',
@@ -417,8 +417,8 @@  discard block
 block discarded – undo
417 417
                 'event_id' => $item->ID(),
418 418
             );
419 419
             $attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
420
-            $actionlinks[]        = '<a href="' . $attendees_link . '" title="' . esc_attr__('View Registrants',
421
-                    'event_espresso') . '"><div class="dashicons dashicons-groups"></div></a>';
420
+            $actionlinks[]        = '<a href="'.$attendees_link.'" title="'.esc_attr__('View Registrants',
421
+                    'event_espresso').'"><div class="dashicons dashicons-groups"></div></a>';
422 422
         }
423 423
 
424 424
         $actionlinks = apply_filters('FHEE__Events_Admin_List_Table__column_actions__action_links', $actionlinks,
Please login to merge, or discard this patch.
core/EE_Module_Request_Router.core.php 2 patches
Indentation   +215 added lines, -215 removed lines patch added patch discarded remove patch
@@ -17,243 +17,243 @@
 block discarded – undo
17 17
 final class EE_Module_Request_Router implements InterminableInterface
18 18
 {
19 19
 
20
-    /**
21
-     * @var array $_previous_routes
22
-     */
23
-    private static $_previous_routes = array();
20
+	/**
21
+	 * @var array $_previous_routes
22
+	 */
23
+	private static $_previous_routes = array();
24 24
 
25
-    /**
26
-     * @var WP_Query $WP_Query
27
-     */
28
-    public $WP_Query;
25
+	/**
26
+	 * @var WP_Query $WP_Query
27
+	 */
28
+	public $WP_Query;
29 29
 
30 30
 
31 31
 
32
-    /**
33
-     * EE_Module_Request_Router constructor.
34
-     */
35
-    public function __construct()
36
-    {
37
-    }
32
+	/**
33
+	 * EE_Module_Request_Router constructor.
34
+	 */
35
+	public function __construct()
36
+	{
37
+	}
38 38
 
39 39
 
40 40
 
41
-    /**
42
-     * on the first call  to this method, it checks the EE_Request_Handler for a "route"
43
-     * on subsequent calls to this method,
44
-     * instead of checking the EE_Request_Handler for a route, it checks the previous routes array,
45
-     * and checks if the last called route has any forwarding routes registered for it
46
-     *
47
-     * @param WP_Query $WP_Query
48
-     * @return NULL|string
49
-     * @throws EE_Error
50
-     * @throws ReflectionException
51
-     */
52
-    public function get_route(WP_Query $WP_Query)
53
-    {
54
-        $this->WP_Query = $WP_Query;
55
-        // assume this if first route being called
56
-        $previous_route = false;
57
-        // but is it really ???
58
-        if (! empty(self::$_previous_routes)) {
59
-            // get last run route
60
-            $previous_routes = array_values(self::$_previous_routes);
61
-            $previous_route = array_pop($previous_routes);
62
-        }
63
-        //  has another route already been run ?
64
-        if ($previous_route) {
65
-            // check if  forwarding has been set
66
-            $current_route = $this->get_forward($previous_route);
67
-            try {
68
-                //check for recursive forwarding
69
-                if (isset(self::$_previous_routes[$current_route])) {
70
-                    throw new EE_Error(
71
-                        sprintf(
72
-                            __(
73
-                                'An error occurred. The %s route has already been called, and therefore can not be forwarded to, because an infinite loop would be created and break the interweb.',
74
-                                'event_espresso'
75
-                            ),
76
-                            $current_route
77
-                        )
78
-                    );
79
-                }
80
-            } catch (EE_Error $e) {
81
-                $e->get_error();
82
-                return null;
83
-            }
84
-        } else {
85
-            // first route called
86
-            $current_route = null;
87
-            // grab all routes
88
-            $routes = EE_Config::get_routes();
89
-            //d( $routes );
90
-            foreach ($routes as $key => $route) {
91
-                // check request for module route
92
-                if (EE_Registry::instance()->REQ->is_set($key)) {
93
-                    //echo '<b style="color:#2EA2CC;">key : <span style="color:#E76700">' . $key . '</span></b><br />';
94
-                    $current_route = sanitize_text_field(EE_Registry::instance()->REQ->get($key));
95
-                    if ($current_route) {
96
-                        $current_route = array($key, $current_route);
97
-                        //echo '<b style="color:#2EA2CC;">current_route : <span style="color:#E76700">' . $current_route . '</span></b><br />';
98
-                        break;
99
-                    }
100
-                }
101
-            }
102
-        }
103
-        // sorry, but I can't read what you route !
104
-        if (empty($current_route)) {
105
-            return null;
106
-        }
107
-        //add route to previous routes array
108
-        self::$_previous_routes[] = $current_route;
109
-        return $current_route;
110
-    }
41
+	/**
42
+	 * on the first call  to this method, it checks the EE_Request_Handler for a "route"
43
+	 * on subsequent calls to this method,
44
+	 * instead of checking the EE_Request_Handler for a route, it checks the previous routes array,
45
+	 * and checks if the last called route has any forwarding routes registered for it
46
+	 *
47
+	 * @param WP_Query $WP_Query
48
+	 * @return NULL|string
49
+	 * @throws EE_Error
50
+	 * @throws ReflectionException
51
+	 */
52
+	public function get_route(WP_Query $WP_Query)
53
+	{
54
+		$this->WP_Query = $WP_Query;
55
+		// assume this if first route being called
56
+		$previous_route = false;
57
+		// but is it really ???
58
+		if (! empty(self::$_previous_routes)) {
59
+			// get last run route
60
+			$previous_routes = array_values(self::$_previous_routes);
61
+			$previous_route = array_pop($previous_routes);
62
+		}
63
+		//  has another route already been run ?
64
+		if ($previous_route) {
65
+			// check if  forwarding has been set
66
+			$current_route = $this->get_forward($previous_route);
67
+			try {
68
+				//check for recursive forwarding
69
+				if (isset(self::$_previous_routes[$current_route])) {
70
+					throw new EE_Error(
71
+						sprintf(
72
+							__(
73
+								'An error occurred. The %s route has already been called, and therefore can not be forwarded to, because an infinite loop would be created and break the interweb.',
74
+								'event_espresso'
75
+							),
76
+							$current_route
77
+						)
78
+					);
79
+				}
80
+			} catch (EE_Error $e) {
81
+				$e->get_error();
82
+				return null;
83
+			}
84
+		} else {
85
+			// first route called
86
+			$current_route = null;
87
+			// grab all routes
88
+			$routes = EE_Config::get_routes();
89
+			//d( $routes );
90
+			foreach ($routes as $key => $route) {
91
+				// check request for module route
92
+				if (EE_Registry::instance()->REQ->is_set($key)) {
93
+					//echo '<b style="color:#2EA2CC;">key : <span style="color:#E76700">' . $key . '</span></b><br />';
94
+					$current_route = sanitize_text_field(EE_Registry::instance()->REQ->get($key));
95
+					if ($current_route) {
96
+						$current_route = array($key, $current_route);
97
+						//echo '<b style="color:#2EA2CC;">current_route : <span style="color:#E76700">' . $current_route . '</span></b><br />';
98
+						break;
99
+					}
100
+				}
101
+			}
102
+		}
103
+		// sorry, but I can't read what you route !
104
+		if (empty($current_route)) {
105
+			return null;
106
+		}
107
+		//add route to previous routes array
108
+		self::$_previous_routes[] = $current_route;
109
+		return $current_route;
110
+	}
111 111
 
112 112
 
113 113
 
114
-    /**
115
-     * this method simply takes a valid route, and resolves what module class method the route points to
116
-     *
117
-     * @param string $key
118
-     * @param string $current_route
119
-     * @return mixed EED_Module | boolean
120
-     * @throws EE_Error
121
-     * @throws ReflectionException
122
-     */
123
-    public function resolve_route($key, $current_route)
124
-    {
125
-        // get module method that route has been mapped to
126
-        $module_method = EE_Config::get_route($current_route, $key);
127
-        //EEH_Debug_Tools::printr( $module_method, '$module_method  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
128
-        // verify result was returned
129
-        if (empty($module_method)) {
130
-            $msg = sprintf(
131
-                __('The requested route %s could not be mapped to any registered modules.', 'event_espresso'),
132
-                $current_route
133
-            );
134
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
135
-            return false;
136
-        }
137
-        // verify that result is an array
138
-        if (! is_array($module_method)) {
139
-            $msg = sprintf(__('The %s  route has not been properly registered.', 'event_espresso'), $current_route);
140
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
141
-            return false;
142
-        }
143
-        // grab module name
144
-        $module_name = $module_method[0];
145
-        // verify that a class method was registered properly
146
-        if (! isset($module_method[1])) {
147
-            $msg = sprintf(
148
-                __('A class method for the %s  route has not been properly registered.', 'event_espresso'),
149
-                $current_route
150
-            );
151
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
152
-            return false;
153
-        }
154
-        // grab method
155
-        $method = $module_method[1];
156
-        // verify that class exists
157
-        if (! class_exists($module_name)) {
158
-            $msg = sprintf(__('The requested %s class could not be found.', 'event_espresso'), $module_name);
159
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
160
-            return false;
161
-        }
162
-        // verify that method exists
163
-        if (! method_exists($module_name, $method)) {
164
-            $msg = sprintf(
165
-                __('The class method %s for the %s route is in invalid.', 'event_espresso'), $method, $current_route
166
-            );
167
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
168
-            return false;
169
-        }
170
-        // instantiate module and call route method
171
-        return $this->_module_router($module_name, $method);
172
-    }
114
+	/**
115
+	 * this method simply takes a valid route, and resolves what module class method the route points to
116
+	 *
117
+	 * @param string $key
118
+	 * @param string $current_route
119
+	 * @return mixed EED_Module | boolean
120
+	 * @throws EE_Error
121
+	 * @throws ReflectionException
122
+	 */
123
+	public function resolve_route($key, $current_route)
124
+	{
125
+		// get module method that route has been mapped to
126
+		$module_method = EE_Config::get_route($current_route, $key);
127
+		//EEH_Debug_Tools::printr( $module_method, '$module_method  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
128
+		// verify result was returned
129
+		if (empty($module_method)) {
130
+			$msg = sprintf(
131
+				__('The requested route %s could not be mapped to any registered modules.', 'event_espresso'),
132
+				$current_route
133
+			);
134
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
135
+			return false;
136
+		}
137
+		// verify that result is an array
138
+		if (! is_array($module_method)) {
139
+			$msg = sprintf(__('The %s  route has not been properly registered.', 'event_espresso'), $current_route);
140
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
141
+			return false;
142
+		}
143
+		// grab module name
144
+		$module_name = $module_method[0];
145
+		// verify that a class method was registered properly
146
+		if (! isset($module_method[1])) {
147
+			$msg = sprintf(
148
+				__('A class method for the %s  route has not been properly registered.', 'event_espresso'),
149
+				$current_route
150
+			);
151
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
152
+			return false;
153
+		}
154
+		// grab method
155
+		$method = $module_method[1];
156
+		// verify that class exists
157
+		if (! class_exists($module_name)) {
158
+			$msg = sprintf(__('The requested %s class could not be found.', 'event_espresso'), $module_name);
159
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
160
+			return false;
161
+		}
162
+		// verify that method exists
163
+		if (! method_exists($module_name, $method)) {
164
+			$msg = sprintf(
165
+				__('The class method %s for the %s route is in invalid.', 'event_espresso'), $method, $current_route
166
+			);
167
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
168
+			return false;
169
+		}
170
+		// instantiate module and call route method
171
+		return $this->_module_router($module_name, $method);
172
+	}
173 173
 
174 174
 
175 175
 
176
-    /**
177
-     * this method instantiates modules and calls the method that was defined when the route was registered
178
-     *
179
-     * @param string $module_name
180
-     * @return EED_Module|object|null
181
-     * @throws ReflectionException
182
-     */
183
-    public static function module_factory($module_name)
184
-    {
185
-        if ($module_name === 'EED_Module') {
186
-            EE_Error::add_error(
187
-                sprintf(
188
-                    __(
189
-                        'EED_Module is an abstract parent class an can not be instantiated. Please provide a proper module name.',
190
-                        'event_espresso'
191
-                    ), $module_name
192
-                ), __FILE__, __FUNCTION__, __LINE__
193
-            );
194
-            return null;
195
-        }
196
-        // instantiate module class
197
-        $module = new $module_name();
198
-        // ensure that class is actually a module
199
-        if (! $module instanceof EED_Module) {
200
-            EE_Error::add_error(
201
-                sprintf(__('The requested %s module is not of the class EED_Module.', 'event_espresso'), $module_name),
202
-                __FILE__, __FUNCTION__, __LINE__
203
-            );
204
-            return null;
205
-        }
206
-        return $module;
207
-    }
176
+	/**
177
+	 * this method instantiates modules and calls the method that was defined when the route was registered
178
+	 *
179
+	 * @param string $module_name
180
+	 * @return EED_Module|object|null
181
+	 * @throws ReflectionException
182
+	 */
183
+	public static function module_factory($module_name)
184
+	{
185
+		if ($module_name === 'EED_Module') {
186
+			EE_Error::add_error(
187
+				sprintf(
188
+					__(
189
+						'EED_Module is an abstract parent class an can not be instantiated. Please provide a proper module name.',
190
+						'event_espresso'
191
+					), $module_name
192
+				), __FILE__, __FUNCTION__, __LINE__
193
+			);
194
+			return null;
195
+		}
196
+		// instantiate module class
197
+		$module = new $module_name();
198
+		// ensure that class is actually a module
199
+		if (! $module instanceof EED_Module) {
200
+			EE_Error::add_error(
201
+				sprintf(__('The requested %s module is not of the class EED_Module.', 'event_espresso'), $module_name),
202
+				__FILE__, __FUNCTION__, __LINE__
203
+			);
204
+			return null;
205
+		}
206
+		return $module;
207
+	}
208 208
 
209 209
 
210 210
 
211
-    /**
212
-     * this method instantiates modules and calls the method that was defined when the route was registered
213
-     *
214
-     * @param string $module_name
215
-     * @param string $method
216
-     * @return EED_Module|null
217
-     * @throws EE_Error
218
-     * @throws ReflectionException
219
-     */
220
-    private function _module_router($module_name, $method)
221
-    {
222
-        // instantiate module class
223
-        $module = EE_Module_Request_Router::module_factory($module_name);
224
-        if ($module instanceof EED_Module) {
225
-            // and call whatever action the route was for
226
-            try {
227
-                call_user_func(array($module, $method), $this->WP_Query);
228
-            } catch (EE_Error $e) {
229
-                $e->get_error();
230
-                return null;
231
-            }
232
-        }
233
-        return $module;
234
-    }
211
+	/**
212
+	 * this method instantiates modules and calls the method that was defined when the route was registered
213
+	 *
214
+	 * @param string $module_name
215
+	 * @param string $method
216
+	 * @return EED_Module|null
217
+	 * @throws EE_Error
218
+	 * @throws ReflectionException
219
+	 */
220
+	private function _module_router($module_name, $method)
221
+	{
222
+		// instantiate module class
223
+		$module = EE_Module_Request_Router::module_factory($module_name);
224
+		if ($module instanceof EED_Module) {
225
+			// and call whatever action the route was for
226
+			try {
227
+				call_user_func(array($module, $method), $this->WP_Query);
228
+			} catch (EE_Error $e) {
229
+				$e->get_error();
230
+				return null;
231
+			}
232
+		}
233
+		return $module;
234
+	}
235 235
 
236 236
 
237 237
 
238
-    /**
239
-     * @param $current_route
240
-     * @return string
241
-     */
242
-    public function get_forward($current_route)
243
-    {
244
-        return EE_Config::get_forward($current_route);
245
-    }
238
+	/**
239
+	 * @param $current_route
240
+	 * @return string
241
+	 */
242
+	public function get_forward($current_route)
243
+	{
244
+		return EE_Config::get_forward($current_route);
245
+	}
246 246
 
247 247
 
248 248
 
249
-    /**
250
-     * @param $current_route
251
-     * @return string
252
-     */
253
-    public function get_view($current_route)
254
-    {
255
-        return EE_Config::get_view($current_route);
256
-    }
249
+	/**
250
+	 * @param $current_route
251
+	 * @return string
252
+	 */
253
+	public function get_view($current_route)
254
+	{
255
+		return EE_Config::get_view($current_route);
256
+	}
257 257
 
258 258
 
259 259
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -55,7 +55,7 @@  discard block
 block discarded – undo
55 55
         // assume this if first route being called
56 56
         $previous_route = false;
57 57
         // but is it really ???
58
-        if (! empty(self::$_previous_routes)) {
58
+        if ( ! empty(self::$_previous_routes)) {
59 59
             // get last run route
60 60
             $previous_routes = array_values(self::$_previous_routes);
61 61
             $previous_route = array_pop($previous_routes);
@@ -135,36 +135,36 @@  discard block
 block discarded – undo
135 135
             return false;
136 136
         }
137 137
         // verify that result is an array
138
-        if (! is_array($module_method)) {
138
+        if ( ! is_array($module_method)) {
139 139
             $msg = sprintf(__('The %s  route has not been properly registered.', 'event_espresso'), $current_route);
140
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
140
+            EE_Error::add_error($msg.'||'.$msg, __FILE__, __FUNCTION__, __LINE__);
141 141
             return false;
142 142
         }
143 143
         // grab module name
144 144
         $module_name = $module_method[0];
145 145
         // verify that a class method was registered properly
146
-        if (! isset($module_method[1])) {
146
+        if ( ! isset($module_method[1])) {
147 147
             $msg = sprintf(
148 148
                 __('A class method for the %s  route has not been properly registered.', 'event_espresso'),
149 149
                 $current_route
150 150
             );
151
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
151
+            EE_Error::add_error($msg.'||'.$msg, __FILE__, __FUNCTION__, __LINE__);
152 152
             return false;
153 153
         }
154 154
         // grab method
155 155
         $method = $module_method[1];
156 156
         // verify that class exists
157
-        if (! class_exists($module_name)) {
157
+        if ( ! class_exists($module_name)) {
158 158
             $msg = sprintf(__('The requested %s class could not be found.', 'event_espresso'), $module_name);
159 159
             EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
160 160
             return false;
161 161
         }
162 162
         // verify that method exists
163
-        if (! method_exists($module_name, $method)) {
163
+        if ( ! method_exists($module_name, $method)) {
164 164
             $msg = sprintf(
165 165
                 __('The class method %s for the %s route is in invalid.', 'event_espresso'), $method, $current_route
166 166
             );
167
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
167
+            EE_Error::add_error($msg.'||'.$msg, __FILE__, __FUNCTION__, __LINE__);
168 168
             return false;
169 169
         }
170 170
         // instantiate module and call route method
@@ -196,7 +196,7 @@  discard block
 block discarded – undo
196 196
         // instantiate module class
197 197
         $module = new $module_name();
198 198
         // ensure that class is actually a module
199
-        if (! $module instanceof EED_Module) {
199
+        if ( ! $module instanceof EED_Module) {
200 200
             EE_Error::add_error(
201 201
                 sprintf(__('The requested %s module is not of the class EED_Module.', 'event_espresso'), $module_name),
202 202
                 __FILE__, __FUNCTION__, __LINE__
Please login to merge, or discard this patch.
admin/extend/registrations/Extend_EE_Registrations_List_Table.class.php 2 patches
Indentation   +91 added lines, -91 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
 /**
@@ -23,104 +23,104 @@  discard block
 block discarded – undo
23 23
 {
24 24
 
25 25
 
26
-    /**
27
-     *        REG_date
28
-     */
29
-    function column_REG_date(EE_Registration $item)
30
-    {
26
+	/**
27
+	 *        REG_date
28
+	 */
29
+	function column_REG_date(EE_Registration $item)
30
+	{
31 31
 
32
-        //Build row actions
33
-        $actions = array();
32
+		//Build row actions
33
+		$actions = array();
34 34
 
35
-        //Build row actions
36
-        $check_in_url        = EE_Admin_Page::add_query_args_and_nonce(array(
37
-            'action'   => 'event_registrations',
38
-            'event_id' => $item->event_ID(),
39
-        ), REG_ADMIN_URL);
40
-        $actions['check_in'] = EE_Registry::instance()->CAP->current_user_can('ee_read_checkin',
41
-            'espresso_registrations_registration_checkins', $item->ID()) ? '
35
+		//Build row actions
36
+		$check_in_url        = EE_Admin_Page::add_query_args_and_nonce(array(
37
+			'action'   => 'event_registrations',
38
+			'event_id' => $item->event_ID(),
39
+		), REG_ADMIN_URL);
40
+		$actions['check_in'] = EE_Registry::instance()->CAP->current_user_can('ee_read_checkin',
41
+			'espresso_registrations_registration_checkins', $item->ID()) ? '
42 42
 			<a href="' . $check_in_url . '" title="' . esc_attr__('The Check-In List allows you to easily toggle check-in status for this event',
43
-                'event_espresso') . '">' . __('View Check-ins', 'event_espresso') . '</a>' : __('View Check-ins',
44
-            'event_espresso');
43
+				'event_espresso') . '">' . __('View Check-ins', 'event_espresso') . '</a>' : __('View Check-ins',
44
+			'event_espresso');
45 45
 
46
-        $view_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
47
-            'action' => 'view_transaction',
48
-            'TXN_ID' => $item->transaction()->ID(),
49
-        ), TXN_ADMIN_URL);
50
-        $REG_date     = EE_Regisry::instance()->CAP->current_user_can('ee_read_transaction',
51
-            'espresso_transactions_view_transaction') ? '<a href="' . $view_lnk_url . '" title="' . esc_attr__('View Transaction Details',
52
-                'event_espresso') . '">' . $item->get_i18n_datetime('REG_date') . '</a>' : $item->get_i18n_datetime('REG_date');
46
+		$view_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
47
+			'action' => 'view_transaction',
48
+			'TXN_ID' => $item->transaction()->ID(),
49
+		), TXN_ADMIN_URL);
50
+		$REG_date     = EE_Regisry::instance()->CAP->current_user_can('ee_read_transaction',
51
+			'espresso_transactions_view_transaction') ? '<a href="' . $view_lnk_url . '" title="' . esc_attr__('View Transaction Details',
52
+				'event_espresso') . '">' . $item->get_i18n_datetime('REG_date') . '</a>' : $item->get_i18n_datetime('REG_date');
53 53
 
54
-        return sprintf('%1$s %2$s', $REG_date, $this->row_actions($actions));
54
+		return sprintf('%1$s %2$s', $REG_date, $this->row_actions($actions));
55 55
 
56
-    }
56
+	}
57 57
 
58 58
 
59
-    /**
60
-     *        column_default
61
-     *
62
-     * @param \EE_Registration $item
63
-     * @return string
64
-     */
65
-    public function column_DTT_EVT_start(EE_Registration $item)
66
-    {
67
-        $remove_defaults = array('default_where_conditions' => 'none');
68
-        $ticket          = $item->ticket();
69
-        $datetimes       = $ticket instanceof EE_Ticket ? $ticket->datetimes($remove_defaults) : array();
70
-        $EVT_ID          = $item->event_ID();
71
-        $datetime_string = '';
72
-        foreach ($datetimes as $datetime) {
73
-            if (
74
-            EE_Registry::instance()->CAP->current_user_can(
75
-                'ee_read_checkin',
76
-                'espresso_registrations_registration_checkins',
77
-                $item->ID()
78
-            )
79
-            ) {
80
-                // open "a" tag and "href"
81
-                $datetime_string .= '<a href="';
82
-                // checkin URL
83
-                $datetime_string .= EE_Admin_Page::add_query_args_and_nonce(
84
-                    array(
85
-                        'action'   => 'event_registrations',
86
-                        'event_id' => $EVT_ID,
87
-                        'DTT_ID'   => $datetime->ID(),
88
-                    ),
89
-                    REG_ADMIN_URL
90
-                );
91
-                // close "href"
92
-                $datetime_string .= '"';
93
-                // open "title" tag
94
-                $datetime_string .= ' title="';
95
-                // link title text
96
-                $datetime_string .= esc_attr__('View Checkins for this Event', 'event_espresso');
97
-                // close "title" tag and end of "a" tag opening
98
-                $datetime_string .= '">';
99
-                // link text
100
-                $datetime_string .= $datetime->get_i18n_datetime('DTT_EVT_start');
101
-                // close "a" tag
102
-                $datetime_string .= '</a>';
103
-            } else {
104
-                $datetime_string .= $datetime->get_i18n_datetime('DTT_EVT_start');
105
-            }
106
-            // add a "View Registrations" link that filters list by event AND datetime
107
-            $datetime_string .= $this->row_actions(
108
-                array(
109
-                    'event_datetime_filter' => '<a href="' . EE_Admin_Page::add_query_args_and_nonce(
110
-                            array('event_id' => $EVT_ID, 'datetime_id' => $datetime->ID()),
111
-                            REG_ADMIN_URL
112
-                        ) . '" title="' . sprintf(
113
-                                                   esc_attr__(
114
-                                                       'Filter this list to only show registrations for this datetime %s',
115
-                                                       'event_espresso'
116
-                                                   ),
117
-                                                   $datetime->name()
118
-                                               ) . '">' . __('View Registrations', 'event_espresso') . '</a>',
119
-                )
120
-            );
121
-        }
122
-        return $datetime_string;
123
-    }
59
+	/**
60
+	 *        column_default
61
+	 *
62
+	 * @param \EE_Registration $item
63
+	 * @return string
64
+	 */
65
+	public function column_DTT_EVT_start(EE_Registration $item)
66
+	{
67
+		$remove_defaults = array('default_where_conditions' => 'none');
68
+		$ticket          = $item->ticket();
69
+		$datetimes       = $ticket instanceof EE_Ticket ? $ticket->datetimes($remove_defaults) : array();
70
+		$EVT_ID          = $item->event_ID();
71
+		$datetime_string = '';
72
+		foreach ($datetimes as $datetime) {
73
+			if (
74
+			EE_Registry::instance()->CAP->current_user_can(
75
+				'ee_read_checkin',
76
+				'espresso_registrations_registration_checkins',
77
+				$item->ID()
78
+			)
79
+			) {
80
+				// open "a" tag and "href"
81
+				$datetime_string .= '<a href="';
82
+				// checkin URL
83
+				$datetime_string .= EE_Admin_Page::add_query_args_and_nonce(
84
+					array(
85
+						'action'   => 'event_registrations',
86
+						'event_id' => $EVT_ID,
87
+						'DTT_ID'   => $datetime->ID(),
88
+					),
89
+					REG_ADMIN_URL
90
+				);
91
+				// close "href"
92
+				$datetime_string .= '"';
93
+				// open "title" tag
94
+				$datetime_string .= ' title="';
95
+				// link title text
96
+				$datetime_string .= esc_attr__('View Checkins for this Event', 'event_espresso');
97
+				// close "title" tag and end of "a" tag opening
98
+				$datetime_string .= '">';
99
+				// link text
100
+				$datetime_string .= $datetime->get_i18n_datetime('DTT_EVT_start');
101
+				// close "a" tag
102
+				$datetime_string .= '</a>';
103
+			} else {
104
+				$datetime_string .= $datetime->get_i18n_datetime('DTT_EVT_start');
105
+			}
106
+			// add a "View Registrations" link that filters list by event AND datetime
107
+			$datetime_string .= $this->row_actions(
108
+				array(
109
+					'event_datetime_filter' => '<a href="' . EE_Admin_Page::add_query_args_and_nonce(
110
+							array('event_id' => $EVT_ID, 'datetime_id' => $datetime->ID()),
111
+							REG_ADMIN_URL
112
+						) . '" title="' . sprintf(
113
+												   esc_attr__(
114
+													   'Filter this list to only show registrations for this datetime %s',
115
+													   'event_espresso'
116
+												   ),
117
+												   $datetime->name()
118
+											   ) . '">' . __('View Registrations', 'event_espresso') . '</a>',
119
+				)
120
+			);
121
+		}
122
+		return $datetime_string;
123
+	}
124 124
 
125 125
 
126 126
 } //end Extend_EE_Registrations_List_Table
Please login to merge, or discard this patch.
Spacing   +10 added lines, -10 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
 
@@ -33,23 +33,23 @@  discard block
 block discarded – undo
33 33
         $actions = array();
34 34
 
35 35
         //Build row actions
36
-        $check_in_url        = EE_Admin_Page::add_query_args_and_nonce(array(
36
+        $check_in_url = EE_Admin_Page::add_query_args_and_nonce(array(
37 37
             'action'   => 'event_registrations',
38 38
             'event_id' => $item->event_ID(),
39 39
         ), REG_ADMIN_URL);
40 40
         $actions['check_in'] = EE_Registry::instance()->CAP->current_user_can('ee_read_checkin',
41 41
             'espresso_registrations_registration_checkins', $item->ID()) ? '
42
-			<a href="' . $check_in_url . '" title="' . esc_attr__('The Check-In List allows you to easily toggle check-in status for this event',
43
-                'event_espresso') . '">' . __('View Check-ins', 'event_espresso') . '</a>' : __('View Check-ins',
42
+			<a href="' . $check_in_url.'" title="'.esc_attr__('The Check-In List allows you to easily toggle check-in status for this event',
43
+                'event_espresso').'">'.__('View Check-ins', 'event_espresso').'</a>' : __('View Check-ins',
44 44
             'event_espresso');
45 45
 
46 46
         $view_lnk_url = EE_Admin_Page::add_query_args_and_nonce(array(
47 47
             'action' => 'view_transaction',
48 48
             'TXN_ID' => $item->transaction()->ID(),
49 49
         ), TXN_ADMIN_URL);
50
-        $REG_date     = EE_Regisry::instance()->CAP->current_user_can('ee_read_transaction',
51
-            'espresso_transactions_view_transaction') ? '<a href="' . $view_lnk_url . '" title="' . esc_attr__('View Transaction Details',
52
-                'event_espresso') . '">' . $item->get_i18n_datetime('REG_date') . '</a>' : $item->get_i18n_datetime('REG_date');
50
+        $REG_date = EE_Regisry::instance()->CAP->current_user_can('ee_read_transaction',
51
+            'espresso_transactions_view_transaction') ? '<a href="'.$view_lnk_url.'" title="'.esc_attr__('View Transaction Details',
52
+                'event_espresso').'">'.$item->get_i18n_datetime('REG_date').'</a>' : $item->get_i18n_datetime('REG_date');
53 53
 
54 54
         return sprintf('%1$s %2$s', $REG_date, $this->row_actions($actions));
55 55
 
@@ -106,16 +106,16 @@  discard block
 block discarded – undo
106 106
             // add a "View Registrations" link that filters list by event AND datetime
107 107
             $datetime_string .= $this->row_actions(
108 108
                 array(
109
-                    'event_datetime_filter' => '<a href="' . EE_Admin_Page::add_query_args_and_nonce(
109
+                    'event_datetime_filter' => '<a href="'.EE_Admin_Page::add_query_args_and_nonce(
110 110
                             array('event_id' => $EVT_ID, 'datetime_id' => $datetime->ID()),
111 111
                             REG_ADMIN_URL
112
-                        ) . '" title="' . sprintf(
112
+                        ).'" title="'.sprintf(
113 113
                                                    esc_attr__(
114 114
                                                        'Filter this list to only show registrations for this datetime %s',
115 115
                                                        'event_espresso'
116 116
                                                    ),
117 117
                                                    $datetime->name()
118
-                                               ) . '">' . __('View Registrations', 'event_espresso') . '</a>',
118
+                                               ).'">'.__('View Registrations', 'event_espresso').'</a>',
119 119
                 )
120 120
             );
121 121
         }
Please login to merge, or discard this patch.