Completed
Branch BUG/11312/auto-promoted-regist... (47a443)
by
unknown
15:03
created
core/EE_Log.core.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -249,7 +249,7 @@
 block discarded – undo
249 249
      * @param string $class
250 250
      * @param string $func
251 251
      * @param string $line
252
-     * @param mixed|object $object
252
+     * @param EE_Transaction $object
253 253
      * @param array $extra_data
254 254
      * @param bool   $display_request
255 255
      * @throws \InvalidArgumentException
Please login to merge, or discard this patch.
Indentation   +87 added lines, -87 removed lines patch added patch discarded remove patch
@@ -243,93 +243,93 @@
 block discarded – undo
243 243
 	}
244 244
 
245 245
 
246
-    /**
247
-     * debug
248
-     *
249
-     * @param string $class
250
-     * @param string $func
251
-     * @param string $line
252
-     * @param mixed|object $object
253
-     * @param array $extra_data
254
-     * @param bool   $display_request
255
-     * @throws \InvalidArgumentException
256
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
257
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
258
-     * @throws \EE_Error
259
-     */
260
-    public static function logTxn(
261
-        $class = '',
262
-        $func = '',
263
-        $line = '',
264
-        $object = null,
265
-        array $extra_data = array(),
266
-        $display_request = true
267
-    ) {
268
-        $disabled = false; // true false
269
-        if (WP_DEBUG && ! $disabled && EE_Registry::instance()->SSN instanceof EE_Session) {
270
-            $ID                            = $object instanceof EE_Base_Class
271
-                ? get_class($object) . ': ' . $object->ID()
272
-                : '';
273
-            $ID                            = $ID === '' && is_object($object)
274
-                ? get_class($object)
275
-                : $ID;
276
-            $debug_data                    = get_option('EE_DEBUG_SPCO_' . EE_Registry::instance()->SSN->id(), array());
277
-            // $time = array_sum(explode(' ', microtime()));
278
-            $time = EE_Log::microTime();
279
-            $debug_data[ $time ] = array_merge(
280
-                EE_Log::stripObjects(
281
-                    array(
282
-                        $class => $func . '() : ' . $line,
283
-                        $ID    => $object,
284
-                    )
285
-                ),
286
-                EE_Log::stripObjects($extra_data),
287
-                array(
288
-                    'REQ' => $display_request ? $_REQUEST : '',
289
-                )
290
-            );
291
-            update_option('EE_DEBUG_SPCO_' . EE_Registry::instance()->SSN->id(), $debug_data);
292
-        }
293
-    }
294
-
295
-
296
-    /**
297
-     * _strip_objects
298
-     *
299
-     * @param array $info
300
-     * @return array
301
-     */
302
-    public static function stripObjects($info = array())
303
-    {
304
-        foreach ((array) $info as $key => $value) {
305
-            if (is_array($value)) {
306
-                $info[ $key ] = EE_Log::stripObjects($value);
307
-            } elseif (is_object($value)) {
308
-                $object_class                = get_class($value);
309
-                $info[ $object_class ]       = array();
310
-                $info[ $object_class ]['ID'] = method_exists($value, 'ID') ? $value->ID() : 0;
311
-                if (method_exists($value, 'status')) {
312
-                    $info[ $object_class ]['status'] = $value->status();
313
-                } elseif (method_exists($value, 'status_ID')) {
314
-                    $info[ $object_class ]['status'] = $value->status_ID();
315
-                }
316
-                unset($info[ $key ]);
317
-            } else  {
318
-                $info[ $key ] = $value;
319
-            }
320
-        }
321
-        return (array) $info;
322
-    }
323
-
324
-
325
-    /**
326
-     * @return string
327
-     */
328
-    private static function microTime()
329
-    {
330
-        $temp = explode(' ', microtime());
331
-        return bcadd($temp[0], $temp[1], 6);
332
-    }
246
+	/**
247
+	 * debug
248
+	 *
249
+	 * @param string $class
250
+	 * @param string $func
251
+	 * @param string $line
252
+	 * @param mixed|object $object
253
+	 * @param array $extra_data
254
+	 * @param bool   $display_request
255
+	 * @throws \InvalidArgumentException
256
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
257
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
258
+	 * @throws \EE_Error
259
+	 */
260
+	public static function logTxn(
261
+		$class = '',
262
+		$func = '',
263
+		$line = '',
264
+		$object = null,
265
+		array $extra_data = array(),
266
+		$display_request = true
267
+	) {
268
+		$disabled = false; // true false
269
+		if (WP_DEBUG && ! $disabled && EE_Registry::instance()->SSN instanceof EE_Session) {
270
+			$ID                            = $object instanceof EE_Base_Class
271
+				? get_class($object) . ': ' . $object->ID()
272
+				: '';
273
+			$ID                            = $ID === '' && is_object($object)
274
+				? get_class($object)
275
+				: $ID;
276
+			$debug_data                    = get_option('EE_DEBUG_SPCO_' . EE_Registry::instance()->SSN->id(), array());
277
+			// $time = array_sum(explode(' ', microtime()));
278
+			$time = EE_Log::microTime();
279
+			$debug_data[ $time ] = array_merge(
280
+				EE_Log::stripObjects(
281
+					array(
282
+						$class => $func . '() : ' . $line,
283
+						$ID    => $object,
284
+					)
285
+				),
286
+				EE_Log::stripObjects($extra_data),
287
+				array(
288
+					'REQ' => $display_request ? $_REQUEST : '',
289
+				)
290
+			);
291
+			update_option('EE_DEBUG_SPCO_' . EE_Registry::instance()->SSN->id(), $debug_data);
292
+		}
293
+	}
294
+
295
+
296
+	/**
297
+	 * _strip_objects
298
+	 *
299
+	 * @param array $info
300
+	 * @return array
301
+	 */
302
+	public static function stripObjects($info = array())
303
+	{
304
+		foreach ((array) $info as $key => $value) {
305
+			if (is_array($value)) {
306
+				$info[ $key ] = EE_Log::stripObjects($value);
307
+			} elseif (is_object($value)) {
308
+				$object_class                = get_class($value);
309
+				$info[ $object_class ]       = array();
310
+				$info[ $object_class ]['ID'] = method_exists($value, 'ID') ? $value->ID() : 0;
311
+				if (method_exists($value, 'status')) {
312
+					$info[ $object_class ]['status'] = $value->status();
313
+				} elseif (method_exists($value, 'status_ID')) {
314
+					$info[ $object_class ]['status'] = $value->status_ID();
315
+				}
316
+				unset($info[ $key ]);
317
+			} else  {
318
+				$info[ $key ] = $value;
319
+			}
320
+		}
321
+		return (array) $info;
322
+	}
323
+
324
+
325
+	/**
326
+	 * @return string
327
+	 */
328
+	private static function microTime()
329
+	{
330
+		$temp = explode(' ', microtime());
331
+		return bcadd($temp[0], $temp[1], 6);
332
+	}
333 333
 }
334 334
 // End of file EE_Log.core.php
335 335
 // Location: /core/EE_Log.core.php
Please login to merge, or discard this patch.
Spacing   +69 added lines, -69 removed lines patch added patch discarded remove patch
@@ -1,4 +1,4 @@  discard block
 block discarded – undo
1
-<?php if (!defined('EVENT_ESPRESSO_VERSION')) exit('No direct script access allowed');
1
+<?php if ( ! defined('EVENT_ESPRESSO_VERSION')) exit('No direct script access allowed');
2 2
 /**
3 3
  *
4 4
  * Class EE_Log
@@ -62,7 +62,7 @@  discard block
 block discarded – undo
62 62
 	 * @return EE_Log
63 63
 	 */
64 64
 	public static function instance() {
65
-		if ( ! self::$_instance instanceof EE_Log ) {
65
+		if ( ! self::$_instance instanceof EE_Log) {
66 66
 			self::$_instance = new self();
67 67
 		}
68 68
 		return self::$_instance;
@@ -74,11 +74,11 @@  discard block
 block discarded – undo
74 74
 	 */
75 75
 	private function __construct() {
76 76
 
77
-		if ( ! EE_Registry::instance()->CFG->admin->use_full_logging && ! EE_Registry::instance()->CFG->admin->use_remote_logging ) {
77
+		if ( ! EE_Registry::instance()->CFG->admin->use_full_logging && ! EE_Registry::instance()->CFG->admin->use_remote_logging) {
78 78
 			return;
79 79
 		}
80 80
 
81
-		$this->_logs_folder = EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS;
81
+		$this->_logs_folder = EVENT_ESPRESSO_UPLOAD_DIR.'logs'.DS;
82 82
 		$this->_log_file = EE_Registry::instance()->CFG->admin->log_file_name();
83 83
 		$this->_log = '';
84 84
 		$this->_debug_file = EE_Registry::instance()->CFG->admin->debug_file_name();
@@ -86,15 +86,15 @@  discard block
 block discarded – undo
86 86
 		$this->_remote_logging_url = EE_Registry::instance()->CFG->admin->remote_logging_url;
87 87
 		$this->_remote_log = '';
88 88
 
89
-		add_action( 'admin_init', array( $this, 'verify_filesystem' ), -10 );
90
-		add_action( 'AHEE_log', array( $this, 'log' ), 10, 4 );
91
-		if ( EE_Registry::instance()->CFG->admin->use_full_logging ) {
92
-			add_action( 'shutdown', array( $this, 'write_log' ), 9999 );
89
+		add_action('admin_init', array($this, 'verify_filesystem'), -10);
90
+		add_action('AHEE_log', array($this, 'log'), 10, 4);
91
+		if (EE_Registry::instance()->CFG->admin->use_full_logging) {
92
+			add_action('shutdown', array($this, 'write_log'), 9999);
93 93
 			// if WP_DEBUG
94
-			add_action( 'shutdown', array( $this, 'write_debug' ), 9999 );
94
+			add_action('shutdown', array($this, 'write_debug'), 9999);
95 95
 		}
96
-		if ( EE_Registry::instance()->CFG->admin->use_remote_logging ) {
97
-			add_action( 'shutdown', array( $this, 'send_log' ), 9999 );
96
+		if (EE_Registry::instance()->CFG->admin->use_remote_logging) {
97
+			add_action('shutdown', array($this, 'send_log'), 9999);
98 98
 		}
99 99
 
100 100
 	}
@@ -108,11 +108,11 @@  discard block
 block discarded – undo
108 108
 	 */
109 109
 	public function verify_filesystem() {
110 110
 		try {
111
-			EEH_File::ensure_file_exists_and_is_writable( $this->_logs_folder . $this->_log_file );
112
-			EEH_File::ensure_file_exists_and_is_writable( $this->_logs_folder . $this->_debug_file );
113
-			EEH_File::add_htaccess_deny_from_all( $this->_logs_folder );
114
-		} catch( EE_Error $e ){
115
-			EE_Error::add_error( sprintf( __(  'Event Espresso logging could not be setup because: %s', 'event_espresso' ), ' &nbsp; &nbsp; ' . $e->getMessage() ), __FILE__, __FUNCTION__, __LINE__ );
111
+			EEH_File::ensure_file_exists_and_is_writable($this->_logs_folder.$this->_log_file);
112
+			EEH_File::ensure_file_exists_and_is_writable($this->_logs_folder.$this->_debug_file);
113
+			EEH_File::add_htaccess_deny_from_all($this->_logs_folder);
114
+		} catch (EE_Error $e) {
115
+			EE_Error::add_error(sprintf(__('Event Espresso logging could not be setup because: %s', 'event_espresso'), ' &nbsp; &nbsp; '.$e->getMessage()), __FILE__, __FUNCTION__, __LINE__);
116 116
 			return;
117 117
 		}
118 118
 	}
@@ -129,15 +129,15 @@  discard block
 block discarded – undo
129 129
 	 * @param string $type
130 130
 	 * @return string
131 131
 	 */
132
-	private function _format_message( $file = '', $function = '', $message = '', $type = '' ) {
133
-		$msg = '----------------------------------------------------------------------------------------' . PHP_EOL;
134
-		$msg .= '[' . current_time( 'mysql' ) . '] ';
135
-		$msg .= ! empty( $file ) ? basename( $file ) : '';
136
-		$msg .= ! empty( $file ) && ! empty( $function ) ? ' -> ' : '';
137
-		$msg .= ! empty( $function ) ? $function . '()' : '';
132
+	private function _format_message($file = '', $function = '', $message = '', $type = '') {
133
+		$msg = '----------------------------------------------------------------------------------------'.PHP_EOL;
134
+		$msg .= '['.current_time('mysql').'] ';
135
+		$msg .= ! empty($file) ? basename($file) : '';
136
+		$msg .= ! empty($file) && ! empty($function) ? ' -> ' : '';
137
+		$msg .= ! empty($function) ? $function.'()' : '';
138 138
 		$msg .= PHP_EOL;
139
-		$type = ! empty( $type ) ? $type : 'log message';
140
-		$msg .= ! empty( $message ) ? "\t" . '[' . $type . '] ' . $message . PHP_EOL : '';
139
+		$type = ! empty($type) ? $type : 'log message';
140
+		$msg .= ! empty($message) ? "\t".'['.$type.'] '.$message.PHP_EOL : '';
141 141
 		return $msg;
142 142
 	}
143 143
 
@@ -152,8 +152,8 @@  discard block
 block discarded – undo
152 152
 	 * @param string $message
153 153
 	 * @param string $type
154 154
 	 */
155
-	public function log( $file = '', $function = '', $message = '', $type = '' ) {
156
-		$this->_log .= $this->_format_message( $file, $function, $message, $type );
155
+	public function log($file = '', $function = '', $message = '', $type = '') {
156
+		$this->_log .= $this->_format_message($file, $function, $message, $type);
157 157
 	}
158 158
 
159 159
 
@@ -165,10 +165,10 @@  discard block
 block discarded – undo
165 165
 	public function write_log() {
166 166
 		try {
167 167
 			//get existing log file and append new log info
168
-			$this->_log = EEH_File::get_file_contents( $this->_logs_folder . $this->_log_file ) . $this->_log;
169
-			EEH_File::write_to_file( $this->_logs_folder . $this->_log_file, $this->_log, 'Event Espresso Log' );
170
-		} catch( EE_Error $e ){
171
-			EE_Error::add_error( sprintf( __(  'Could not write to the Event Espresso log file because: %s', 'event_espresso' ), ' &nbsp; &nbsp; ' . $e->getMessage() ), __FILE__, __FUNCTION__, __LINE__ );
168
+			$this->_log = EEH_File::get_file_contents($this->_logs_folder.$this->_log_file).$this->_log;
169
+			EEH_File::write_to_file($this->_logs_folder.$this->_log_file, $this->_log, 'Event Espresso Log');
170
+		} catch (EE_Error $e) {
171
+			EE_Error::add_error(sprintf(__('Could not write to the Event Espresso log file because: %s', 'event_espresso'), ' &nbsp; &nbsp; '.$e->getMessage()), __FILE__, __FUNCTION__, __LINE__);
172 172
 			return;
173 173
 		}
174 174
 	}
@@ -181,31 +181,31 @@  discard block
 block discarded – undo
181 181
 	 */
182 182
 	public function send_log() {
183 183
 
184
-		if ( empty( $this->_remote_logging_url )) {
184
+		if (empty($this->_remote_logging_url)) {
185 185
 			return;
186 186
 		}
187 187
 
188
-		$data = 'domain=' . $_SERVER['HTTP_HOST'];
189
-		$data .= '&ip=' . $_SERVER['SERVER_ADDR'];
190
-		$data .= '&server_type=' . $_SERVER['SERVER_SOFTWARE'];
191
-		$data .= '&time=' . time();
192
-		$data .= '&remote_log=' . $this->_log;
193
-		$data .= '&request_array=' . json_encode( $_REQUEST );
188
+		$data = 'domain='.$_SERVER['HTTP_HOST'];
189
+		$data .= '&ip='.$_SERVER['SERVER_ADDR'];
190
+		$data .= '&server_type='.$_SERVER['SERVER_SOFTWARE'];
191
+		$data .= '&time='.time();
192
+		$data .= '&remote_log='.$this->_log;
193
+		$data .= '&request_array='.json_encode($_REQUEST);
194 194
 		$data .= '&action=save';
195 195
 
196
-		if ( defined( 'EELOGGING_PASS' )) {
197
-			$data .= '&pass=' . EELOGGING_PASS;
196
+		if (defined('EELOGGING_PASS')) {
197
+			$data .= '&pass='.EELOGGING_PASS;
198 198
 		}
199
-		if ( defined( 'EELOGGING_KEY' )) {
200
-			$data .= '&key=' . EELOGGING_KEY;
199
+		if (defined('EELOGGING_KEY')) {
200
+			$data .= '&key='.EELOGGING_KEY;
201 201
 		}
202 202
 
203
-		$c = curl_init( $this->_remote_logging_url );
204
-		curl_setopt( $c, CURLOPT_POST, TRUE );
205
-		curl_setopt( $c, CURLOPT_POSTFIELDS, $data );
206
-		curl_setopt( $c, CURLOPT_RETURNTRANSFER, TRUE );
207
-		curl_exec( $c );
208
-		curl_close( $c );
203
+		$c = curl_init($this->_remote_logging_url);
204
+		curl_setopt($c, CURLOPT_POST, TRUE);
205
+		curl_setopt($c, CURLOPT_POSTFIELDS, $data);
206
+		curl_setopt($c, CURLOPT_RETURNTRANSFER, TRUE);
207
+		curl_exec($c);
208
+		curl_close($c);
209 209
 	}
210 210
 
211 211
 
@@ -216,18 +216,18 @@  discard block
 block discarded – undo
216 216
 	 * previous entries are overwritten
217 217
 	 */
218 218
 	public function write_debug() {
219
-		if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
219
+		if (defined('WP_DEBUG') && WP_DEBUG) {
220 220
 			$this->_debug_log = '';
221
-			foreach ( $_GET as $key => $value ) {
222
-				$this->_debug_log .= '$_GET["' . $key . '"] = "' . serialize($value) . '"' . PHP_EOL;
221
+			foreach ($_GET as $key => $value) {
222
+				$this->_debug_log .= '$_GET["'.$key.'"] = "'.serialize($value).'"'.PHP_EOL;
223 223
 			}
224
-			foreach ( $_POST as $key => $value ) {
225
-				$this->_debug_log .= '$_POST["' . $key . '"] = "' . serialize($value) . '"' . PHP_EOL;
224
+			foreach ($_POST as $key => $value) {
225
+				$this->_debug_log .= '$_POST["'.$key.'"] = "'.serialize($value).'"'.PHP_EOL;
226 226
 			}
227 227
 			try {
228
-				EEH_File::write_to_file( $this->_logs_folder . $this->_debug_file, $this->_debug_log, 'Event Espresso Debug Log' );
229
-			} catch( EE_Error $e ){
230
-				EE_Error::add_error( sprintf( __(  'Could not write to the Event Espresso debug log file because: %s', 'event_espresso' ), ' &nbsp; &nbsp; ' . $e->getMessage() ), __FILE__, __FUNCTION__, __LINE__ );
228
+				EEH_File::write_to_file($this->_logs_folder.$this->_debug_file, $this->_debug_log, 'Event Espresso Debug Log');
229
+			} catch (EE_Error $e) {
230
+				EE_Error::add_error(sprintf(__('Could not write to the Event Espresso debug log file because: %s', 'event_espresso'), ' &nbsp; &nbsp; '.$e->getMessage()), __FILE__, __FUNCTION__, __LINE__);
231 231
 				return;
232 232
 			}
233 233
 		}
@@ -239,7 +239,7 @@  discard block
 block discarded – undo
239 239
 	 * __clone
240 240
 	 */
241 241
 	public function __clone() {
242
-		trigger_error( __( 'Clone is not allowed.', 'event_espresso' ), E_USER_ERROR );
242
+		trigger_error(__('Clone is not allowed.', 'event_espresso'), E_USER_ERROR);
243 243
 	}
244 244
 
245 245
 
@@ -268,18 +268,18 @@  discard block
 block discarded – undo
268 268
         $disabled = false; // true false
269 269
         if (WP_DEBUG && ! $disabled && EE_Registry::instance()->SSN instanceof EE_Session) {
270 270
             $ID                            = $object instanceof EE_Base_Class
271
-                ? get_class($object) . ': ' . $object->ID()
271
+                ? get_class($object).': '.$object->ID()
272 272
                 : '';
273 273
             $ID                            = $ID === '' && is_object($object)
274 274
                 ? get_class($object)
275 275
                 : $ID;
276
-            $debug_data                    = get_option('EE_DEBUG_SPCO_' . EE_Registry::instance()->SSN->id(), array());
276
+            $debug_data                    = get_option('EE_DEBUG_SPCO_'.EE_Registry::instance()->SSN->id(), array());
277 277
             // $time = array_sum(explode(' ', microtime()));
278 278
             $time = EE_Log::microTime();
279
-            $debug_data[ $time ] = array_merge(
279
+            $debug_data[$time] = array_merge(
280 280
                 EE_Log::stripObjects(
281 281
                     array(
282
-                        $class => $func . '() : ' . $line,
282
+                        $class => $func.'() : '.$line,
283 283
                         $ID    => $object,
284 284
                     )
285 285
                 ),
@@ -288,7 +288,7 @@  discard block
 block discarded – undo
288 288
                     'REQ' => $display_request ? $_REQUEST : '',
289 289
                 )
290 290
             );
291
-            update_option('EE_DEBUG_SPCO_' . EE_Registry::instance()->SSN->id(), $debug_data);
291
+            update_option('EE_DEBUG_SPCO_'.EE_Registry::instance()->SSN->id(), $debug_data);
292 292
         }
293 293
     }
294 294
 
@@ -303,19 +303,19 @@  discard block
 block discarded – undo
303 303
     {
304 304
         foreach ((array) $info as $key => $value) {
305 305
             if (is_array($value)) {
306
-                $info[ $key ] = EE_Log::stripObjects($value);
306
+                $info[$key] = EE_Log::stripObjects($value);
307 307
             } elseif (is_object($value)) {
308 308
                 $object_class                = get_class($value);
309
-                $info[ $object_class ]       = array();
310
-                $info[ $object_class ]['ID'] = method_exists($value, 'ID') ? $value->ID() : 0;
309
+                $info[$object_class]       = array();
310
+                $info[$object_class]['ID'] = method_exists($value, 'ID') ? $value->ID() : 0;
311 311
                 if (method_exists($value, 'status')) {
312
-                    $info[ $object_class ]['status'] = $value->status();
312
+                    $info[$object_class]['status'] = $value->status();
313 313
                 } elseif (method_exists($value, 'status_ID')) {
314
-                    $info[ $object_class ]['status'] = $value->status_ID();
314
+                    $info[$object_class]['status'] = $value->status_ID();
315 315
                 }
316
-                unset($info[ $key ]);
317
-            } else  {
318
-                $info[ $key ] = $value;
316
+                unset($info[$key]);
317
+            } else {
318
+                $info[$key] = $value;
319 319
             }
320 320
         }
321 321
         return (array) $info;
Please login to merge, or discard this patch.
admin_pages/transactions/Transactions_Admin_Page.core.php 2 patches
Indentation   +1957 added lines, -1957 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
 /**
@@ -22,1965 +22,1965 @@  discard block
 block discarded – undo
22 22
 class Transactions_Admin_Page extends EE_Admin_Page
23 23
 {
24 24
 
25
-    /**
26
-     * @var EE_Transaction
27
-     */
28
-    private $_transaction;
29
-
30
-    /**
31
-     * @var EE_Session
32
-     */
33
-    private $_session;
34
-
35
-    /**
36
-     * @var array $_txn_status
37
-     */
38
-    private static $_txn_status;
39
-
40
-    /**
41
-     * @var array $_pay_status
42
-     */
43
-    private static $_pay_status;
44
-
45
-    /**
46
-     * @var array $_existing_reg_payment_REG_IDs
47
-     */
48
-    protected $_existing_reg_payment_REG_IDs = null;
49
-
50
-
51
-    /**
52
-     * @Constructor
53
-     * @access public
54
-     * @param bool $routing
55
-     * @return Transactions_Admin_Page
56
-     */
57
-    public function __construct($routing = true)
58
-    {
59
-        parent::__construct($routing);
60
-    }
61
-
62
-
63
-    /**
64
-     *    _init_page_props
65
-     *
66
-     * @return void
67
-     */
68
-    protected function _init_page_props()
69
-    {
70
-        $this->page_slug        = TXN_PG_SLUG;
71
-        $this->page_label       = esc_html__('Transactions', 'event_espresso');
72
-        $this->_admin_base_url  = TXN_ADMIN_URL;
73
-        $this->_admin_base_path = TXN_ADMIN;
74
-    }
75
-
76
-
77
-    /**
78
-     *    _ajax_hooks
79
-     *
80
-     * @return void
81
-     */
82
-    protected function _ajax_hooks()
83
-    {
84
-        add_action('wp_ajax_espresso_apply_payment', array($this, 'apply_payments_or_refunds'));
85
-        add_action('wp_ajax_espresso_apply_refund', array($this, 'apply_payments_or_refunds'));
86
-        add_action('wp_ajax_espresso_delete_payment', array($this, 'delete_payment'));
87
-    }
88
-
89
-
90
-    /**
91
-     *    _define_page_props
92
-     *
93
-     * @return void
94
-     */
95
-    protected function _define_page_props()
96
-    {
97
-        $this->_admin_page_title = $this->page_label;
98
-        $this->_labels           = array(
99
-            'buttons' => array(
100
-                'add'    => esc_html__('Add New Transaction', 'event_espresso'),
101
-                'edit'   => esc_html__('Edit Transaction', 'event_espresso'),
102
-                'delete' => esc_html__('Delete Transaction', 'event_espresso'),
103
-            ),
104
-        );
105
-    }
106
-
107
-
108
-    /**
109
-     *        grab url requests and route them
110
-     *
111
-     * @access private
112
-     * @return void
113
-     */
114
-    public function _set_page_routes()
115
-    {
116
-
117
-        $this->_set_transaction_status_array();
118
-
119
-        $txn_id = ! empty($this->_req_data['TXN_ID']) && ! is_array($this->_req_data['TXN_ID']) ? $this->_req_data['TXN_ID'] : 0;
120
-
121
-        $this->_page_routes = array(
122
-
123
-            'default' => array(
124
-                'func'       => '_transactions_overview_list_table',
125
-                'capability' => 'ee_read_transactions',
126
-            ),
127
-
128
-            'view_transaction' => array(
129
-                'func'       => '_transaction_details',
130
-                'capability' => 'ee_read_transaction',
131
-                'obj_id'     => $txn_id,
132
-            ),
133
-
134
-            'send_payment_reminder' => array(
135
-                'func'       => '_send_payment_reminder',
136
-                'noheader'   => true,
137
-                'capability' => 'ee_send_message',
138
-            ),
139
-
140
-            'espresso_apply_payment' => array(
141
-                'func'       => 'apply_payments_or_refunds',
142
-                'noheader'   => true,
143
-                'capability' => 'ee_edit_payments',
144
-            ),
145
-
146
-            'espresso_apply_refund' => array(
147
-                'func'       => 'apply_payments_or_refunds',
148
-                'noheader'   => true,
149
-                'capability' => 'ee_edit_payments',
150
-            ),
151
-
152
-            'espresso_delete_payment' => array(
153
-                'func'       => 'delete_payment',
154
-                'noheader'   => true,
155
-                'capability' => 'ee_delete_payments',
156
-            ),
157
-
158
-        );
159
-
160
-    }
161
-
162
-
163
-    protected function _set_page_config()
164
-    {
165
-        $this->_page_config = array(
166
-            'default'          => array(
167
-                'nav'           => array(
168
-                    'label' => esc_html__('Overview', 'event_espresso'),
169
-                    'order' => 10,
170
-                ),
171
-                'list_table'    => 'EE_Admin_Transactions_List_Table',
172
-                'help_tabs'     => array(
173
-                    'transactions_overview_help_tab'                       => array(
174
-                        'title'    => esc_html__('Transactions Overview', 'event_espresso'),
175
-                        'filename' => 'transactions_overview',
176
-                    ),
177
-                    'transactions_overview_table_column_headings_help_tab' => array(
178
-                        'title'    => esc_html__('Transactions Table Column Headings', 'event_espresso'),
179
-                        'filename' => 'transactions_overview_table_column_headings',
180
-                    ),
181
-                    'transactions_overview_views_filters_help_tab'         => array(
182
-                        'title'    => esc_html__('Transaction Views & Filters & Search', 'event_espresso'),
183
-                        'filename' => 'transactions_overview_views_filters_search',
184
-                    ),
185
-                ),
186
-                'help_tour'     => array('Transactions_Overview_Help_Tour'),
187
-                /**
188
-                 * commented out because currently we are not displaying tips for transaction list table status but this
189
-                 * may change in a later iteration so want to keep the code for then.
190
-                 */
191
-                //'qtips' => array( 'Transactions_List_Table_Tips' ),
192
-                'require_nonce' => false,
193
-            ),
194
-            'view_transaction' => array(
195
-                'nav'       => array(
196
-                    'label'      => esc_html__('View Transaction', 'event_espresso'),
197
-                    'order'      => 5,
198
-                    'url'        => isset($this->_req_data['TXN_ID']) ? add_query_arg(array('TXN_ID' => $this->_req_data['TXN_ID']),
199
-                        $this->_current_page_view_url) : $this->_admin_base_url,
200
-                    'persistent' => false,
201
-                ),
202
-                'help_tabs' => array(
203
-                    'transactions_view_transaction_help_tab'                                              => array(
204
-                        'title'    => esc_html__('View Transaction', 'event_espresso'),
205
-                        'filename' => 'transactions_view_transaction',
206
-                    ),
207
-                    'transactions_view_transaction_transaction_details_table_help_tab'                    => array(
208
-                        'title'    => esc_html__('Transaction Details Table', 'event_espresso'),
209
-                        'filename' => 'transactions_view_transaction_transaction_details_table',
210
-                    ),
211
-                    'transactions_view_transaction_attendees_registered_help_tab'                         => array(
212
-                        'title'    => esc_html__('Attendees Registered', 'event_espresso'),
213
-                        'filename' => 'transactions_view_transaction_attendees_registered',
214
-                    ),
215
-                    'transactions_view_transaction_views_primary_registrant_billing_information_help_tab' => array(
216
-                        'title'    => esc_html__('Primary Registrant & Billing Information', 'event_espresso'),
217
-                        'filename' => 'transactions_view_transaction_primary_registrant_billing_information',
218
-                    ),
219
-                ),
220
-                'qtips'     => array('Transaction_Details_Tips'),
221
-                'help_tour' => array('Transaction_Details_Help_Tour'),
222
-                'metaboxes' => array('_transaction_details_metaboxes'),
223
-
224
-                'require_nonce' => false,
225
-            ),
226
-        );
227
-    }
228
-
229
-
230
-    /**
231
-     * The below methods aren't used by this class currently
232
-     */
233
-    protected function _add_screen_options()
234
-    {
235
-    }
236
-
237
-    protected function _add_feature_pointers()
238
-    {
239
-    }
240
-
241
-    public function admin_init()
242
-    {
243
-        // IF a registration was JUST added via the admin...
244
-        if (
245
-        isset(
246
-            $this->_req_data['redirect_from'],
247
-            $this->_req_data['EVT_ID'],
248
-            $this->_req_data['event_name']
249
-        )
250
-        ) {
251
-            // then set a cookie so that we can block any attempts to use
252
-            // the back button as a way to enter another registration.
253
-            setcookie('ee_registration_added', $this->_req_data['EVT_ID'], time() + WEEK_IN_SECONDS, '/');
254
-            // and update the global
255
-            $_COOKIE['ee_registration_added'] = $this->_req_data['EVT_ID'];
256
-        }
257
-        EE_Registry::$i18n_js_strings['invalid_server_response'] = esc_html__('An error occurred! Your request may have been processed, but a valid response from the server was not received. Please refresh the page and try again.',
258
-            'event_espresso');
259
-        EE_Registry::$i18n_js_strings['error_occurred']          = esc_html__('An error occurred! Please refresh the page and try again.',
260
-            'event_espresso');
261
-        EE_Registry::$i18n_js_strings['txn_status_array']        = self::$_txn_status;
262
-        EE_Registry::$i18n_js_strings['pay_status_array']        = self::$_pay_status;
263
-        EE_Registry::$i18n_js_strings['payments_total']          = esc_html__('Payments Total', 'event_espresso');
264
-        EE_Registry::$i18n_js_strings['transaction_overpaid']    = esc_html__('This transaction has been overpaid ! Payments Total',
265
-            'event_espresso');
266
-    }
267
-
268
-    public function admin_notices()
269
-    {
270
-    }
271
-
272
-    public function admin_footer_scripts()
273
-    {
274
-    }
275
-
276
-
277
-    /**
278
-     * _set_transaction_status_array
279
-     * sets list of transaction statuses
280
-     *
281
-     * @access private
282
-     * @return void
283
-     */
284
-    private function _set_transaction_status_array()
285
-    {
286
-        self::$_txn_status = EEM_Transaction::instance()->status_array(true);
287
-    }
288
-
289
-
290
-    /**
291
-     * get_transaction_status_array
292
-     * return the transaction status array for wp_list_table
293
-     *
294
-     * @access public
295
-     * @return array
296
-     */
297
-    public function get_transaction_status_array()
298
-    {
299
-        return self::$_txn_status;
300
-    }
301
-
302
-
303
-    /**
304
-     *    get list of payment statuses
305
-     *
306
-     * @access private
307
-     * @return void
308
-     */
309
-    private function _get_payment_status_array()
310
-    {
311
-        self::$_pay_status                      = EEM_Payment::instance()->status_array(true);
312
-        $this->_template_args['payment_status'] = self::$_pay_status;
313
-
314
-    }
315
-
316
-
317
-    /**
318
-     *    _add_screen_options_default
319
-     *
320
-     * @access protected
321
-     * @return void
322
-     */
323
-    protected function _add_screen_options_default()
324
-    {
325
-        $this->_per_page_screen_option();
326
-    }
327
-
328
-
329
-    /**
330
-     * load_scripts_styles
331
-     *
332
-     * @access public
333
-     * @return void
334
-     */
335
-    public function load_scripts_styles()
336
-    {
337
-        //enqueue style
338
-        wp_register_style('espresso_txn', TXN_ASSETS_URL . 'espresso_transactions_admin.css', array(),
339
-            EVENT_ESPRESSO_VERSION);
340
-        wp_enqueue_style('espresso_txn');
341
-        //scripts
342
-        wp_register_script('espresso_txn', TXN_ASSETS_URL . 'espresso_transactions_admin.js', array(
343
-            'ee_admin_js',
344
-            'ee-datepicker',
345
-            'jquery-ui-datepicker',
346
-            'jquery-ui-draggable',
347
-            'ee-dialog',
348
-            'ee-accounting',
349
-            'ee-serialize-full-array',
350
-        ), EVENT_ESPRESSO_VERSION, true);
351
-        wp_enqueue_script('espresso_txn');
352
-
353
-    }
354
-
355
-
356
-    /**
357
-     *    load_scripts_styles_view_transaction
358
-     *
359
-     * @access public
360
-     * @return void
361
-     */
362
-    public function load_scripts_styles_view_transaction()
363
-    {
364
-        //styles
365
-        wp_enqueue_style('espresso-ui-theme');
366
-    }
367
-
368
-
369
-    /**
370
-     *    load_scripts_styles_default
371
-     *
372
-     * @access public
373
-     * @return void
374
-     */
375
-    public function load_scripts_styles_default()
376
-    {
377
-        //styles
378
-        wp_enqueue_style('espresso-ui-theme');
379
-    }
380
-
381
-
382
-    /**
383
-     *    _set_list_table_views_default
384
-     *
385
-     * @access protected
386
-     * @return void
387
-     */
388
-    protected function _set_list_table_views_default()
389
-    {
390
-        $this->_views = array(
391
-            'all'       => array(
392
-                'slug'  => 'all',
393
-                'label' => esc_html__('View All Transactions', 'event_espresso'),
394
-                'count' => 0,
395
-            ),
396
-            'abandoned' => array(
397
-                'slug'  => 'abandoned',
398
-                'label' => esc_html__('Abandoned Transactions', 'event_espresso'),
399
-                'count' => 0,
400
-            ),
401
-            'failed'    => array(
402
-                'slug'  => 'failed',
403
-                'label' => esc_html__('Failed Transactions', 'event_espresso'),
404
-                'count' => 0,
405
-            ),
406
-        );
407
-    }
408
-
409
-
410
-    /**
411
-     * _set_transaction_object
412
-     * This sets the _transaction property for the transaction details screen
413
-     *
414
-     * @access private
415
-     * @return void
416
-     */
417
-    private function _set_transaction_object()
418
-    {
419
-        if (is_object($this->_transaction)) {
420
-            return;
421
-        } //get out we've already set the object
422
-
423
-        $TXN = EEM_Transaction::instance();
424
-
425
-        $TXN_ID = (! empty($this->_req_data['TXN_ID'])) ? absint($this->_req_data['TXN_ID']) : false;
426
-
427
-        //get transaction object
428
-        $this->_transaction = $TXN->get_one_by_ID($TXN_ID);
429
-        $this->_session     = ! empty($this->_transaction) ? $this->_transaction->get('TXN_session_data') : null;
430
-        $this->_transaction->verify_abandoned_transaction_status();
431
-
432
-        if (empty($this->_transaction)) {
433
-            $error_msg = esc_html__('An error occurred and the details for Transaction ID #',
434
-                    'event_espresso') . $TXN_ID . esc_html__(' could not be retrieved.', 'event_espresso');
435
-            EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
436
-        }
437
-    }
438
-
439
-
440
-    /**
441
-     *    _transaction_legend_items
442
-     *
443
-     * @access protected
444
-     * @return array
445
-     */
446
-    protected function _transaction_legend_items()
447
-    {
448
-        EE_Registry::instance()->load_helper('MSG_Template');
449
-        $items = array();
450
-
451
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
452
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
453
-            if (isset($related_for_icon['css_class']) && isset($related_for_icon['label'])) {
454
-                $items['view_related_messages'] = array(
455
-                    'class' => $related_for_icon['css_class'],
456
-                    'desc'  => $related_for_icon['label'],
457
-                );
458
-            }
459
-        }
460
-
461
-        $items = apply_filters(
462
-            'FHEE__Transactions_Admin_Page___transaction_legend_items__items',
463
-            array_merge($items,
464
-                array(
465
-                    'view_details'          => array(
466
-                        'class' => 'dashicons dashicons-cart',
467
-                        'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
468
-                    ),
469
-                    'view_invoice'          => array(
470
-                        'class' => 'dashicons dashicons-media-spreadsheet',
471
-                        'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
472
-                    ),
473
-                    'view_receipt'          => array(
474
-                        'class' => 'dashicons dashicons-media-default',
475
-                        'desc'  => esc_html__('View Transaction Receipt', 'event_espresso'),
476
-                    ),
477
-                    'view_registration'     => array(
478
-                        'class' => 'dashicons dashicons-clipboard',
479
-                        'desc'  => esc_html__('View Registration Details', 'event_espresso'),
480
-                    ),
481
-                    'payment_overview_link' => array(
482
-                        'class' => 'dashicons dashicons-money',
483
-                        'desc'  => esc_html__('Make Payment on Frontend', 'event_espresso'),
484
-                    ),
485
-                )
486
-            )
487
-        );
488
-
489
-        if (EE_Registry::instance()->CAP->current_user_can('ee_send_message',
490
-            'espresso_transactions_send_payment_reminder')
491
-        ) {
492
-            if (EEH_MSG_Template::is_mt_active('payment_reminder')) {
493
-                $items['send_payment_reminder'] = array(
494
-                    'class' => 'dashicons dashicons-email-alt',
495
-                    'desc'  => esc_html__('Send Payment Reminder', 'event_espresso'),
496
-                );
497
-            } else {
498
-                $items['blank*'] = array(
499
-                    'class' => '',
500
-                    'desc'  => '',
501
-                );
502
-            }
503
-        } else {
504
-            $items['blank*'] = array(
505
-                'class' => '',
506
-                'desc'  => '',
507
-            );
508
-        }
509
-        $more_items = apply_filters(
510
-            'FHEE__Transactions_Admin_Page___transaction_legend_items__more_items',
511
-            array(
512
-                'overpaid'   => array(
513
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::overpaid_status_code,
514
-                    'desc'  => EEH_Template::pretty_status(EEM_Transaction::overpaid_status_code, false, 'sentence'),
515
-                ),
516
-                'complete'   => array(
517
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::complete_status_code,
518
-                    'desc'  => EEH_Template::pretty_status(EEM_Transaction::complete_status_code, false, 'sentence'),
519
-                ),
520
-                'incomplete' => array(
521
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::incomplete_status_code,
522
-                    'desc'  => EEH_Template::pretty_status(EEM_Transaction::incomplete_status_code, false, 'sentence'),
523
-                ),
524
-                'abandoned'  => array(
525
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::abandoned_status_code,
526
-                    'desc'  => EEH_Template::pretty_status(EEM_Transaction::abandoned_status_code, false, 'sentence'),
527
-                ),
528
-                'failed'     => array(
529
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::failed_status_code,
530
-                    'desc'  => EEH_Template::pretty_status(EEM_Transaction::failed_status_code, false, 'sentence'),
531
-                ),
532
-            )
533
-        );
534
-
535
-        return array_merge($items, $more_items);
536
-    }
537
-
538
-
539
-    /**
540
-     *    _transactions_overview_list_table
541
-     *
542
-     * @access protected
543
-     * @return void
544
-     */
545
-    protected function _transactions_overview_list_table()
546
-    {
547
-        $this->_admin_page_title                   = esc_html__('Transactions', 'event_espresso');
548
-        $event                                     = isset($this->_req_data['EVT_ID']) ? EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID']) : null;
549
-        $this->_template_args['admin_page_header'] = $event instanceof EE_Event ? sprintf(esc_html__('%sViewing Transactions for the Event: %s%s',
550
-            'event_espresso'), '<h3>',
551
-            '<a href="' . EE_Admin_Page::add_query_args_and_nonce(array('action' => 'edit', 'post' => $event->ID()),
552
-                EVENTS_ADMIN_URL) . '" title="' . esc_attr__('Click to Edit event',
553
-                'event_espresso') . '">' . $event->get('EVT_name') . '</a>', '</h3>') : '';
554
-        $this->_template_args['after_list_table']  = $this->_display_legend($this->_transaction_legend_items());
555
-        $this->display_admin_list_table_page_with_no_sidebar();
556
-    }
557
-
558
-
559
-    /**
560
-     *    _transaction_details
561
-     * generates HTML for the View Transaction Details Admin page
562
-     *
563
-     * @access protected
564
-     * @return void
565
-     */
566
-    protected function _transaction_details()
567
-    {
568
-        do_action('AHEE__Transactions_Admin_Page__transaction_details__start', $this->_transaction);
569
-        $total_line_item = $this->_transaction->total_line_item(false);
570
-        if($total_line_item instanceof EE_Line_Item) {
571
-            $initial_total = $total_line_item->total();
572
-            $total_line_item->recalculate_total_including_taxes();
573
-        }
574
-        $this->_transaction->update_status_based_on_total_paid();
575
-        $this->_set_transaction_status_array();
576
-
577
-        $this->_template_args                      = array();
578
-        $this->_template_args['transactions_page'] = $this->_wp_page_slug;
579
-
580
-        $this->_set_transaction_object();
581
-
582
-        $primary_registration = $this->_transaction->primary_registration();
583
-        $attendee             = $primary_registration instanceof EE_Registration ? $primary_registration->attendee() : null;
584
-
585
-        $this->_template_args['txn_nmbr']['value'] = $this->_transaction->ID();
586
-        $this->_template_args['txn_nmbr']['label'] = esc_html__('Transaction Number', 'event_espresso');
587
-
588
-        $this->_template_args['txn_datetime']['value'] = $this->_transaction->get_i18n_datetime('TXN_timestamp');
589
-        $this->_template_args['txn_datetime']['label'] = esc_html__('Date', 'event_espresso');
590
-
591
-        $this->_template_args['txn_status']['value'] = self::$_txn_status[$this->_transaction->get('STS_ID')];
592
-        $this->_template_args['txn_status']['label'] = esc_html__('Transaction Status', 'event_espresso');
593
-        $this->_template_args['txn_status']['class'] = 'status-' . $this->_transaction->get('STS_ID');
594
-
595
-        $this->_template_args['grand_total'] = $this->_transaction->get('TXN_total');
596
-        $this->_template_args['total_paid']  = $this->_transaction->get('TXN_paid');
597
-
598
-        if (
599
-            $attendee instanceof EE_Attendee
600
-            && EE_Registry::instance()->CAP->current_user_can(
601
-                'ee_send_message',
602
-                'espresso_transactions_send_payment_reminder'
603
-            )
604
-        ) {
605
-            $this->_template_args['send_payment_reminder_button'] =
606
-                EEH_MSG_Template::is_mt_active('payment_reminder')
607
-                && $this->_transaction->get('STS_ID') != EEM_Transaction::complete_status_code
608
-                && $this->_transaction->get('STS_ID') != EEM_Transaction::overpaid_status_code
609
-                    ? EEH_Template::get_button_or_link(
610
-                    EE_Admin_Page::add_query_args_and_nonce(
611
-                        array(
612
-                            'action'      => 'send_payment_reminder',
613
-                            'TXN_ID'      => $this->_transaction->ID(),
614
-                            'redirect_to' => 'view_transaction',
615
-                        ),
616
-                        TXN_ADMIN_URL
617
-                    ),
618
-                    __(' Send Payment Reminder', 'event_espresso'),
619
-                    'button secondary-button right',
620
-                    'dashicons dashicons-email-alt'
621
-                )
622
-                    : '';
623
-        } else {
624
-            $this->_template_args['send_payment_reminder_button'] = '';
625
-        }
626
-
627
-        $amount_due                         = $this->_transaction->get('TXN_total') - $this->_transaction->get('TXN_paid');
628
-        $this->_template_args['amount_due'] = EEH_Template::format_currency($amount_due, true);
629
-        if (EE_Registry::instance()->CFG->currency->sign_b4) {
630
-            $this->_template_args['amount_due'] = EE_Registry::instance()->CFG->currency->sign . $this->_template_args['amount_due'];
631
-        } else {
632
-            $this->_template_args['amount_due'] = $this->_template_args['amount_due'] . EE_Registry::instance()->CFG->currency->sign;
633
-        }
634
-        $this->_template_args['amount_due_class'] = '';
635
-
636
-        if ($this->_transaction->get('TXN_paid') == $this->_transaction->get('TXN_total')) {
637
-            // paid in full
638
-            $this->_template_args['amount_due'] = false;
639
-        } elseif ($this->_transaction->get('TXN_paid') > $this->_transaction->get('TXN_total')) {
640
-            // overpaid
641
-            $this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
642
-        } elseif (($this->_transaction->get('TXN_total') > 0) && ($this->_transaction->get('TXN_paid') > 0)) {
643
-            // monies owing
644
-            $this->_template_args['amount_due_class'] = 'txn-overview-part-payment-spn';
645
-        } elseif (($this->_transaction->get('TXN_total') > 0) && ($this->_transaction->get('TXN_paid') == 0)) {
646
-            // no payments made yet
647
-            $this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
648
-        } elseif ($this->_transaction->get('TXN_total') == 0) {
649
-            // free event
650
-            $this->_template_args['amount_due'] = false;
651
-        }
652
-
653
-        $payment_method = $this->_transaction->payment_method();
654
-
655
-        $this->_template_args['method_of_payment_name'] = $payment_method instanceof EE_Payment_Method
656
-            ? $payment_method->admin_name()
657
-            : esc_html__('Unknown', 'event_espresso');
658
-
659
-        $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
660
-        // link back to overview
661
-        $this->_template_args['txn_overview_url'] = ! empty ($_SERVER['HTTP_REFERER'])
662
-            ? $_SERVER['HTTP_REFERER']
663
-            : TXN_ADMIN_URL;
664
-
665
-
666
-        // next link
667
-        $next_txn                                 = $this->_transaction->next(
668
-            null,
669
-            array(array('STS_ID' => array('!=', EEM_Transaction::failed_status_code))),
670
-            'TXN_ID'
671
-        );
672
-        $this->_template_args['next_transaction'] = $next_txn
673
-            ? $this->_next_link(
674
-                EE_Admin_Page::add_query_args_and_nonce(
675
-                    array('action' => 'view_transaction', 'TXN_ID' => $next_txn['TXN_ID']),
676
-                    TXN_ADMIN_URL
677
-                ),
678
-                'dashicons dashicons-arrow-right ee-icon-size-22'
679
-            )
680
-            : '';
681
-        // previous link
682
-        $previous_txn                                 = $this->_transaction->previous(
683
-            null,
684
-            array(array('STS_ID' => array('!=', EEM_Transaction::failed_status_code))),
685
-            'TXN_ID'
686
-        );
687
-        $this->_template_args['previous_transaction'] = $previous_txn
688
-            ? $this->_previous_link(
689
-                EE_Admin_Page::add_query_args_and_nonce(
690
-                    array('action' => 'view_transaction', 'TXN_ID' => $previous_txn['TXN_ID']),
691
-                    TXN_ADMIN_URL
692
-                ),
693
-                'dashicons dashicons-arrow-left ee-icon-size-22'
694
-            )
695
-            : '';
696
-
697
-        // were we just redirected here after adding a new registration ???
698
-        if (
699
-        isset(
700
-            $this->_req_data['redirect_from'],
701
-            $this->_req_data['EVT_ID'],
702
-            $this->_req_data['event_name']
703
-        )
704
-        ) {
705
-            if (
706
-            EE_Registry::instance()->CAP->current_user_can(
707
-                'ee_edit_registrations',
708
-                'espresso_registrations_new_registration',
709
-                $this->_req_data['EVT_ID']
710
-            )
711
-            ) {
712
-                $this->_admin_page_title .= '<a id="add-new-registration" class="add-new-h2 button-primary" href="';
713
-                $this->_admin_page_title .= EE_Admin_Page::add_query_args_and_nonce(
714
-                    array(
715
-                        'page'     => 'espresso_registrations',
716
-                        'action'   => 'new_registration',
717
-                        'return'   => 'default',
718
-                        'TXN_ID'   => $this->_transaction->ID(),
719
-                        'event_id' => $this->_req_data['EVT_ID'],
720
-                    ),
721
-                    REG_ADMIN_URL
722
-                );
723
-                $this->_admin_page_title .= '">';
724
-
725
-                $this->_admin_page_title .= sprintf(
726
-                    esc_html__('Add Another New Registration to Event: "%1$s" ?', 'event_espresso'),
727
-                    htmlentities(urldecode($this->_req_data['event_name']), ENT_QUOTES, 'UTF-8')
728
-                );
729
-                $this->_admin_page_title .= '</a>';
730
-            }
731
-            EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
732
-        }
733
-        // grab messages at the last second
734
-        $this->_template_args['notices'] = EE_Error::get_notices();
735
-        // path to template
736
-        $template_path                             = TXN_TEMPLATE_PATH . 'txn_admin_details_header.template.php';
737
-        $this->_template_args['admin_page_header'] = EEH_Template::display_template($template_path,
738
-            $this->_template_args, true);
739
-
740
-        // the details template wrapper
741
-        $this->display_admin_page_with_sidebar();
742
-
743
-    }
744
-
745
-
746
-    /**
747
-     *        _transaction_details_metaboxes
748
-     *
749
-     * @access protected
750
-     * @return void
751
-     */
752
-    protected function _transaction_details_metaboxes()
753
-    {
754
-
755
-        $this->_set_transaction_object();
756
-
757
-        add_meta_box('edit-txn-details-mbox', esc_html__('Transaction Details', 'event_espresso'),
758
-            array($this, 'txn_details_meta_box'), $this->_wp_page_slug, 'normal', 'high');
759
-        add_meta_box(
760
-            'edit-txn-attendees-mbox',
761
-            esc_html__('Attendees Registered in this Transaction', 'event_espresso'),
762
-            array($this, 'txn_attendees_meta_box'),
763
-            $this->_wp_page_slug,
764
-            'normal',
765
-            'high',
766
-            array('TXN_ID' => $this->_transaction->ID())
767
-        );
768
-        add_meta_box('edit-txn-registrant-mbox', esc_html__('Primary Contact', 'event_espresso'),
769
-            array($this, 'txn_registrant_side_meta_box'), $this->_wp_page_slug, 'side', 'high');
770
-        add_meta_box('edit-txn-billing-info-mbox', esc_html__('Billing Information', 'event_espresso'),
771
-            array($this, 'txn_billing_info_side_meta_box'), $this->_wp_page_slug, 'side', 'high');
772
-
773
-    }
774
-
775
-
776
-    /**
777
-     * txn_details_meta_box
778
-     * generates HTML for the Transaction main meta box
779
-     *
780
-     * @access public
781
-     * @return void
782
-     */
783
-    public function txn_details_meta_box()
784
-    {
785
-
786
-        $this->_set_transaction_object();
787
-        $this->_template_args['TXN_ID']   = $this->_transaction->ID();
788
-        $this->_template_args['attendee'] = $this->_transaction->primary_registration() instanceof EE_Registration ? $this->_transaction->primary_registration()->attendee() : null;
789
-
790
-        //get line table
791
-        EEH_Autoloader::register_line_item_display_autoloaders();
792
-        $Line_Item_Display                       = new EE_Line_Item_Display('admin_table',
793
-            'EE_Admin_Table_Line_Item_Display_Strategy');
794
-        $this->_template_args['line_item_table'] = $Line_Item_Display->display_line_item($this->_transaction->total_line_item());
795
-        $this->_template_args['REG_code']        = $this->_transaction->get_first_related('Registration')->get('REG_code');
796
-
797
-        // process taxes
798
-        $taxes                         = $this->_transaction->get_many_related('Line_Item',
799
-            array(array('LIN_type' => EEM_Line_Item::type_tax)));
800
-        $this->_template_args['taxes'] = ! empty($taxes) ? $taxes : false;
801
-
802
-        $this->_template_args['grand_total']     = EEH_Template::format_currency($this->_transaction->get('TXN_total'),
803
-            false, false);
804
-        $this->_template_args['grand_raw_total'] = $this->_transaction->get('TXN_total');
805
-        $this->_template_args['TXN_status']      = $this->_transaction->get('STS_ID');
25
+	/**
26
+	 * @var EE_Transaction
27
+	 */
28
+	private $_transaction;
29
+
30
+	/**
31
+	 * @var EE_Session
32
+	 */
33
+	private $_session;
34
+
35
+	/**
36
+	 * @var array $_txn_status
37
+	 */
38
+	private static $_txn_status;
39
+
40
+	/**
41
+	 * @var array $_pay_status
42
+	 */
43
+	private static $_pay_status;
44
+
45
+	/**
46
+	 * @var array $_existing_reg_payment_REG_IDs
47
+	 */
48
+	protected $_existing_reg_payment_REG_IDs = null;
49
+
50
+
51
+	/**
52
+	 * @Constructor
53
+	 * @access public
54
+	 * @param bool $routing
55
+	 * @return Transactions_Admin_Page
56
+	 */
57
+	public function __construct($routing = true)
58
+	{
59
+		parent::__construct($routing);
60
+	}
61
+
62
+
63
+	/**
64
+	 *    _init_page_props
65
+	 *
66
+	 * @return void
67
+	 */
68
+	protected function _init_page_props()
69
+	{
70
+		$this->page_slug        = TXN_PG_SLUG;
71
+		$this->page_label       = esc_html__('Transactions', 'event_espresso');
72
+		$this->_admin_base_url  = TXN_ADMIN_URL;
73
+		$this->_admin_base_path = TXN_ADMIN;
74
+	}
75
+
76
+
77
+	/**
78
+	 *    _ajax_hooks
79
+	 *
80
+	 * @return void
81
+	 */
82
+	protected function _ajax_hooks()
83
+	{
84
+		add_action('wp_ajax_espresso_apply_payment', array($this, 'apply_payments_or_refunds'));
85
+		add_action('wp_ajax_espresso_apply_refund', array($this, 'apply_payments_or_refunds'));
86
+		add_action('wp_ajax_espresso_delete_payment', array($this, 'delete_payment'));
87
+	}
88
+
89
+
90
+	/**
91
+	 *    _define_page_props
92
+	 *
93
+	 * @return void
94
+	 */
95
+	protected function _define_page_props()
96
+	{
97
+		$this->_admin_page_title = $this->page_label;
98
+		$this->_labels           = array(
99
+			'buttons' => array(
100
+				'add'    => esc_html__('Add New Transaction', 'event_espresso'),
101
+				'edit'   => esc_html__('Edit Transaction', 'event_espresso'),
102
+				'delete' => esc_html__('Delete Transaction', 'event_espresso'),
103
+			),
104
+		);
105
+	}
106
+
107
+
108
+	/**
109
+	 *        grab url requests and route them
110
+	 *
111
+	 * @access private
112
+	 * @return void
113
+	 */
114
+	public function _set_page_routes()
115
+	{
116
+
117
+		$this->_set_transaction_status_array();
118
+
119
+		$txn_id = ! empty($this->_req_data['TXN_ID']) && ! is_array($this->_req_data['TXN_ID']) ? $this->_req_data['TXN_ID'] : 0;
120
+
121
+		$this->_page_routes = array(
122
+
123
+			'default' => array(
124
+				'func'       => '_transactions_overview_list_table',
125
+				'capability' => 'ee_read_transactions',
126
+			),
127
+
128
+			'view_transaction' => array(
129
+				'func'       => '_transaction_details',
130
+				'capability' => 'ee_read_transaction',
131
+				'obj_id'     => $txn_id,
132
+			),
133
+
134
+			'send_payment_reminder' => array(
135
+				'func'       => '_send_payment_reminder',
136
+				'noheader'   => true,
137
+				'capability' => 'ee_send_message',
138
+			),
139
+
140
+			'espresso_apply_payment' => array(
141
+				'func'       => 'apply_payments_or_refunds',
142
+				'noheader'   => true,
143
+				'capability' => 'ee_edit_payments',
144
+			),
145
+
146
+			'espresso_apply_refund' => array(
147
+				'func'       => 'apply_payments_or_refunds',
148
+				'noheader'   => true,
149
+				'capability' => 'ee_edit_payments',
150
+			),
151
+
152
+			'espresso_delete_payment' => array(
153
+				'func'       => 'delete_payment',
154
+				'noheader'   => true,
155
+				'capability' => 'ee_delete_payments',
156
+			),
157
+
158
+		);
159
+
160
+	}
161
+
162
+
163
+	protected function _set_page_config()
164
+	{
165
+		$this->_page_config = array(
166
+			'default'          => array(
167
+				'nav'           => array(
168
+					'label' => esc_html__('Overview', 'event_espresso'),
169
+					'order' => 10,
170
+				),
171
+				'list_table'    => 'EE_Admin_Transactions_List_Table',
172
+				'help_tabs'     => array(
173
+					'transactions_overview_help_tab'                       => array(
174
+						'title'    => esc_html__('Transactions Overview', 'event_espresso'),
175
+						'filename' => 'transactions_overview',
176
+					),
177
+					'transactions_overview_table_column_headings_help_tab' => array(
178
+						'title'    => esc_html__('Transactions Table Column Headings', 'event_espresso'),
179
+						'filename' => 'transactions_overview_table_column_headings',
180
+					),
181
+					'transactions_overview_views_filters_help_tab'         => array(
182
+						'title'    => esc_html__('Transaction Views & Filters & Search', 'event_espresso'),
183
+						'filename' => 'transactions_overview_views_filters_search',
184
+					),
185
+				),
186
+				'help_tour'     => array('Transactions_Overview_Help_Tour'),
187
+				/**
188
+				 * commented out because currently we are not displaying tips for transaction list table status but this
189
+				 * may change in a later iteration so want to keep the code for then.
190
+				 */
191
+				//'qtips' => array( 'Transactions_List_Table_Tips' ),
192
+				'require_nonce' => false,
193
+			),
194
+			'view_transaction' => array(
195
+				'nav'       => array(
196
+					'label'      => esc_html__('View Transaction', 'event_espresso'),
197
+					'order'      => 5,
198
+					'url'        => isset($this->_req_data['TXN_ID']) ? add_query_arg(array('TXN_ID' => $this->_req_data['TXN_ID']),
199
+						$this->_current_page_view_url) : $this->_admin_base_url,
200
+					'persistent' => false,
201
+				),
202
+				'help_tabs' => array(
203
+					'transactions_view_transaction_help_tab'                                              => array(
204
+						'title'    => esc_html__('View Transaction', 'event_espresso'),
205
+						'filename' => 'transactions_view_transaction',
206
+					),
207
+					'transactions_view_transaction_transaction_details_table_help_tab'                    => array(
208
+						'title'    => esc_html__('Transaction Details Table', 'event_espresso'),
209
+						'filename' => 'transactions_view_transaction_transaction_details_table',
210
+					),
211
+					'transactions_view_transaction_attendees_registered_help_tab'                         => array(
212
+						'title'    => esc_html__('Attendees Registered', 'event_espresso'),
213
+						'filename' => 'transactions_view_transaction_attendees_registered',
214
+					),
215
+					'transactions_view_transaction_views_primary_registrant_billing_information_help_tab' => array(
216
+						'title'    => esc_html__('Primary Registrant & Billing Information', 'event_espresso'),
217
+						'filename' => 'transactions_view_transaction_primary_registrant_billing_information',
218
+					),
219
+				),
220
+				'qtips'     => array('Transaction_Details_Tips'),
221
+				'help_tour' => array('Transaction_Details_Help_Tour'),
222
+				'metaboxes' => array('_transaction_details_metaboxes'),
223
+
224
+				'require_nonce' => false,
225
+			),
226
+		);
227
+	}
228
+
229
+
230
+	/**
231
+	 * The below methods aren't used by this class currently
232
+	 */
233
+	protected function _add_screen_options()
234
+	{
235
+	}
236
+
237
+	protected function _add_feature_pointers()
238
+	{
239
+	}
240
+
241
+	public function admin_init()
242
+	{
243
+		// IF a registration was JUST added via the admin...
244
+		if (
245
+		isset(
246
+			$this->_req_data['redirect_from'],
247
+			$this->_req_data['EVT_ID'],
248
+			$this->_req_data['event_name']
249
+		)
250
+		) {
251
+			// then set a cookie so that we can block any attempts to use
252
+			// the back button as a way to enter another registration.
253
+			setcookie('ee_registration_added', $this->_req_data['EVT_ID'], time() + WEEK_IN_SECONDS, '/');
254
+			// and update the global
255
+			$_COOKIE['ee_registration_added'] = $this->_req_data['EVT_ID'];
256
+		}
257
+		EE_Registry::$i18n_js_strings['invalid_server_response'] = esc_html__('An error occurred! Your request may have been processed, but a valid response from the server was not received. Please refresh the page and try again.',
258
+			'event_espresso');
259
+		EE_Registry::$i18n_js_strings['error_occurred']          = esc_html__('An error occurred! Please refresh the page and try again.',
260
+			'event_espresso');
261
+		EE_Registry::$i18n_js_strings['txn_status_array']        = self::$_txn_status;
262
+		EE_Registry::$i18n_js_strings['pay_status_array']        = self::$_pay_status;
263
+		EE_Registry::$i18n_js_strings['payments_total']          = esc_html__('Payments Total', 'event_espresso');
264
+		EE_Registry::$i18n_js_strings['transaction_overpaid']    = esc_html__('This transaction has been overpaid ! Payments Total',
265
+			'event_espresso');
266
+	}
267
+
268
+	public function admin_notices()
269
+	{
270
+	}
271
+
272
+	public function admin_footer_scripts()
273
+	{
274
+	}
275
+
276
+
277
+	/**
278
+	 * _set_transaction_status_array
279
+	 * sets list of transaction statuses
280
+	 *
281
+	 * @access private
282
+	 * @return void
283
+	 */
284
+	private function _set_transaction_status_array()
285
+	{
286
+		self::$_txn_status = EEM_Transaction::instance()->status_array(true);
287
+	}
288
+
289
+
290
+	/**
291
+	 * get_transaction_status_array
292
+	 * return the transaction status array for wp_list_table
293
+	 *
294
+	 * @access public
295
+	 * @return array
296
+	 */
297
+	public function get_transaction_status_array()
298
+	{
299
+		return self::$_txn_status;
300
+	}
301
+
302
+
303
+	/**
304
+	 *    get list of payment statuses
305
+	 *
306
+	 * @access private
307
+	 * @return void
308
+	 */
309
+	private function _get_payment_status_array()
310
+	{
311
+		self::$_pay_status                      = EEM_Payment::instance()->status_array(true);
312
+		$this->_template_args['payment_status'] = self::$_pay_status;
313
+
314
+	}
315
+
316
+
317
+	/**
318
+	 *    _add_screen_options_default
319
+	 *
320
+	 * @access protected
321
+	 * @return void
322
+	 */
323
+	protected function _add_screen_options_default()
324
+	{
325
+		$this->_per_page_screen_option();
326
+	}
327
+
328
+
329
+	/**
330
+	 * load_scripts_styles
331
+	 *
332
+	 * @access public
333
+	 * @return void
334
+	 */
335
+	public function load_scripts_styles()
336
+	{
337
+		//enqueue style
338
+		wp_register_style('espresso_txn', TXN_ASSETS_URL . 'espresso_transactions_admin.css', array(),
339
+			EVENT_ESPRESSO_VERSION);
340
+		wp_enqueue_style('espresso_txn');
341
+		//scripts
342
+		wp_register_script('espresso_txn', TXN_ASSETS_URL . 'espresso_transactions_admin.js', array(
343
+			'ee_admin_js',
344
+			'ee-datepicker',
345
+			'jquery-ui-datepicker',
346
+			'jquery-ui-draggable',
347
+			'ee-dialog',
348
+			'ee-accounting',
349
+			'ee-serialize-full-array',
350
+		), EVENT_ESPRESSO_VERSION, true);
351
+		wp_enqueue_script('espresso_txn');
352
+
353
+	}
354
+
355
+
356
+	/**
357
+	 *    load_scripts_styles_view_transaction
358
+	 *
359
+	 * @access public
360
+	 * @return void
361
+	 */
362
+	public function load_scripts_styles_view_transaction()
363
+	{
364
+		//styles
365
+		wp_enqueue_style('espresso-ui-theme');
366
+	}
367
+
368
+
369
+	/**
370
+	 *    load_scripts_styles_default
371
+	 *
372
+	 * @access public
373
+	 * @return void
374
+	 */
375
+	public function load_scripts_styles_default()
376
+	{
377
+		//styles
378
+		wp_enqueue_style('espresso-ui-theme');
379
+	}
380
+
381
+
382
+	/**
383
+	 *    _set_list_table_views_default
384
+	 *
385
+	 * @access protected
386
+	 * @return void
387
+	 */
388
+	protected function _set_list_table_views_default()
389
+	{
390
+		$this->_views = array(
391
+			'all'       => array(
392
+				'slug'  => 'all',
393
+				'label' => esc_html__('View All Transactions', 'event_espresso'),
394
+				'count' => 0,
395
+			),
396
+			'abandoned' => array(
397
+				'slug'  => 'abandoned',
398
+				'label' => esc_html__('Abandoned Transactions', 'event_espresso'),
399
+				'count' => 0,
400
+			),
401
+			'failed'    => array(
402
+				'slug'  => 'failed',
403
+				'label' => esc_html__('Failed Transactions', 'event_espresso'),
404
+				'count' => 0,
405
+			),
406
+		);
407
+	}
408
+
409
+
410
+	/**
411
+	 * _set_transaction_object
412
+	 * This sets the _transaction property for the transaction details screen
413
+	 *
414
+	 * @access private
415
+	 * @return void
416
+	 */
417
+	private function _set_transaction_object()
418
+	{
419
+		if (is_object($this->_transaction)) {
420
+			return;
421
+		} //get out we've already set the object
422
+
423
+		$TXN = EEM_Transaction::instance();
424
+
425
+		$TXN_ID = (! empty($this->_req_data['TXN_ID'])) ? absint($this->_req_data['TXN_ID']) : false;
426
+
427
+		//get transaction object
428
+		$this->_transaction = $TXN->get_one_by_ID($TXN_ID);
429
+		$this->_session     = ! empty($this->_transaction) ? $this->_transaction->get('TXN_session_data') : null;
430
+		$this->_transaction->verify_abandoned_transaction_status();
431
+
432
+		if (empty($this->_transaction)) {
433
+			$error_msg = esc_html__('An error occurred and the details for Transaction ID #',
434
+					'event_espresso') . $TXN_ID . esc_html__(' could not be retrieved.', 'event_espresso');
435
+			EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
436
+		}
437
+	}
438
+
439
+
440
+	/**
441
+	 *    _transaction_legend_items
442
+	 *
443
+	 * @access protected
444
+	 * @return array
445
+	 */
446
+	protected function _transaction_legend_items()
447
+	{
448
+		EE_Registry::instance()->load_helper('MSG_Template');
449
+		$items = array();
450
+
451
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
452
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
453
+			if (isset($related_for_icon['css_class']) && isset($related_for_icon['label'])) {
454
+				$items['view_related_messages'] = array(
455
+					'class' => $related_for_icon['css_class'],
456
+					'desc'  => $related_for_icon['label'],
457
+				);
458
+			}
459
+		}
460
+
461
+		$items = apply_filters(
462
+			'FHEE__Transactions_Admin_Page___transaction_legend_items__items',
463
+			array_merge($items,
464
+				array(
465
+					'view_details'          => array(
466
+						'class' => 'dashicons dashicons-cart',
467
+						'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
468
+					),
469
+					'view_invoice'          => array(
470
+						'class' => 'dashicons dashicons-media-spreadsheet',
471
+						'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
472
+					),
473
+					'view_receipt'          => array(
474
+						'class' => 'dashicons dashicons-media-default',
475
+						'desc'  => esc_html__('View Transaction Receipt', 'event_espresso'),
476
+					),
477
+					'view_registration'     => array(
478
+						'class' => 'dashicons dashicons-clipboard',
479
+						'desc'  => esc_html__('View Registration Details', 'event_espresso'),
480
+					),
481
+					'payment_overview_link' => array(
482
+						'class' => 'dashicons dashicons-money',
483
+						'desc'  => esc_html__('Make Payment on Frontend', 'event_espresso'),
484
+					),
485
+				)
486
+			)
487
+		);
488
+
489
+		if (EE_Registry::instance()->CAP->current_user_can('ee_send_message',
490
+			'espresso_transactions_send_payment_reminder')
491
+		) {
492
+			if (EEH_MSG_Template::is_mt_active('payment_reminder')) {
493
+				$items['send_payment_reminder'] = array(
494
+					'class' => 'dashicons dashicons-email-alt',
495
+					'desc'  => esc_html__('Send Payment Reminder', 'event_espresso'),
496
+				);
497
+			} else {
498
+				$items['blank*'] = array(
499
+					'class' => '',
500
+					'desc'  => '',
501
+				);
502
+			}
503
+		} else {
504
+			$items['blank*'] = array(
505
+				'class' => '',
506
+				'desc'  => '',
507
+			);
508
+		}
509
+		$more_items = apply_filters(
510
+			'FHEE__Transactions_Admin_Page___transaction_legend_items__more_items',
511
+			array(
512
+				'overpaid'   => array(
513
+					'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::overpaid_status_code,
514
+					'desc'  => EEH_Template::pretty_status(EEM_Transaction::overpaid_status_code, false, 'sentence'),
515
+				),
516
+				'complete'   => array(
517
+					'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::complete_status_code,
518
+					'desc'  => EEH_Template::pretty_status(EEM_Transaction::complete_status_code, false, 'sentence'),
519
+				),
520
+				'incomplete' => array(
521
+					'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::incomplete_status_code,
522
+					'desc'  => EEH_Template::pretty_status(EEM_Transaction::incomplete_status_code, false, 'sentence'),
523
+				),
524
+				'abandoned'  => array(
525
+					'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::abandoned_status_code,
526
+					'desc'  => EEH_Template::pretty_status(EEM_Transaction::abandoned_status_code, false, 'sentence'),
527
+				),
528
+				'failed'     => array(
529
+					'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::failed_status_code,
530
+					'desc'  => EEH_Template::pretty_status(EEM_Transaction::failed_status_code, false, 'sentence'),
531
+				),
532
+			)
533
+		);
534
+
535
+		return array_merge($items, $more_items);
536
+	}
537
+
538
+
539
+	/**
540
+	 *    _transactions_overview_list_table
541
+	 *
542
+	 * @access protected
543
+	 * @return void
544
+	 */
545
+	protected function _transactions_overview_list_table()
546
+	{
547
+		$this->_admin_page_title                   = esc_html__('Transactions', 'event_espresso');
548
+		$event                                     = isset($this->_req_data['EVT_ID']) ? EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID']) : null;
549
+		$this->_template_args['admin_page_header'] = $event instanceof EE_Event ? sprintf(esc_html__('%sViewing Transactions for the Event: %s%s',
550
+			'event_espresso'), '<h3>',
551
+			'<a href="' . EE_Admin_Page::add_query_args_and_nonce(array('action' => 'edit', 'post' => $event->ID()),
552
+				EVENTS_ADMIN_URL) . '" title="' . esc_attr__('Click to Edit event',
553
+				'event_espresso') . '">' . $event->get('EVT_name') . '</a>', '</h3>') : '';
554
+		$this->_template_args['after_list_table']  = $this->_display_legend($this->_transaction_legend_items());
555
+		$this->display_admin_list_table_page_with_no_sidebar();
556
+	}
557
+
558
+
559
+	/**
560
+	 *    _transaction_details
561
+	 * generates HTML for the View Transaction Details Admin page
562
+	 *
563
+	 * @access protected
564
+	 * @return void
565
+	 */
566
+	protected function _transaction_details()
567
+	{
568
+		do_action('AHEE__Transactions_Admin_Page__transaction_details__start', $this->_transaction);
569
+		$total_line_item = $this->_transaction->total_line_item(false);
570
+		if($total_line_item instanceof EE_Line_Item) {
571
+			$initial_total = $total_line_item->total();
572
+			$total_line_item->recalculate_total_including_taxes();
573
+		}
574
+		$this->_transaction->update_status_based_on_total_paid();
575
+		$this->_set_transaction_status_array();
576
+
577
+		$this->_template_args                      = array();
578
+		$this->_template_args['transactions_page'] = $this->_wp_page_slug;
579
+
580
+		$this->_set_transaction_object();
581
+
582
+		$primary_registration = $this->_transaction->primary_registration();
583
+		$attendee             = $primary_registration instanceof EE_Registration ? $primary_registration->attendee() : null;
584
+
585
+		$this->_template_args['txn_nmbr']['value'] = $this->_transaction->ID();
586
+		$this->_template_args['txn_nmbr']['label'] = esc_html__('Transaction Number', 'event_espresso');
587
+
588
+		$this->_template_args['txn_datetime']['value'] = $this->_transaction->get_i18n_datetime('TXN_timestamp');
589
+		$this->_template_args['txn_datetime']['label'] = esc_html__('Date', 'event_espresso');
590
+
591
+		$this->_template_args['txn_status']['value'] = self::$_txn_status[$this->_transaction->get('STS_ID')];
592
+		$this->_template_args['txn_status']['label'] = esc_html__('Transaction Status', 'event_espresso');
593
+		$this->_template_args['txn_status']['class'] = 'status-' . $this->_transaction->get('STS_ID');
594
+
595
+		$this->_template_args['grand_total'] = $this->_transaction->get('TXN_total');
596
+		$this->_template_args['total_paid']  = $this->_transaction->get('TXN_paid');
597
+
598
+		if (
599
+			$attendee instanceof EE_Attendee
600
+			&& EE_Registry::instance()->CAP->current_user_can(
601
+				'ee_send_message',
602
+				'espresso_transactions_send_payment_reminder'
603
+			)
604
+		) {
605
+			$this->_template_args['send_payment_reminder_button'] =
606
+				EEH_MSG_Template::is_mt_active('payment_reminder')
607
+				&& $this->_transaction->get('STS_ID') != EEM_Transaction::complete_status_code
608
+				&& $this->_transaction->get('STS_ID') != EEM_Transaction::overpaid_status_code
609
+					? EEH_Template::get_button_or_link(
610
+					EE_Admin_Page::add_query_args_and_nonce(
611
+						array(
612
+							'action'      => 'send_payment_reminder',
613
+							'TXN_ID'      => $this->_transaction->ID(),
614
+							'redirect_to' => 'view_transaction',
615
+						),
616
+						TXN_ADMIN_URL
617
+					),
618
+					__(' Send Payment Reminder', 'event_espresso'),
619
+					'button secondary-button right',
620
+					'dashicons dashicons-email-alt'
621
+				)
622
+					: '';
623
+		} else {
624
+			$this->_template_args['send_payment_reminder_button'] = '';
625
+		}
626
+
627
+		$amount_due                         = $this->_transaction->get('TXN_total') - $this->_transaction->get('TXN_paid');
628
+		$this->_template_args['amount_due'] = EEH_Template::format_currency($amount_due, true);
629
+		if (EE_Registry::instance()->CFG->currency->sign_b4) {
630
+			$this->_template_args['amount_due'] = EE_Registry::instance()->CFG->currency->sign . $this->_template_args['amount_due'];
631
+		} else {
632
+			$this->_template_args['amount_due'] = $this->_template_args['amount_due'] . EE_Registry::instance()->CFG->currency->sign;
633
+		}
634
+		$this->_template_args['amount_due_class'] = '';
635
+
636
+		if ($this->_transaction->get('TXN_paid') == $this->_transaction->get('TXN_total')) {
637
+			// paid in full
638
+			$this->_template_args['amount_due'] = false;
639
+		} elseif ($this->_transaction->get('TXN_paid') > $this->_transaction->get('TXN_total')) {
640
+			// overpaid
641
+			$this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
642
+		} elseif (($this->_transaction->get('TXN_total') > 0) && ($this->_transaction->get('TXN_paid') > 0)) {
643
+			// monies owing
644
+			$this->_template_args['amount_due_class'] = 'txn-overview-part-payment-spn';
645
+		} elseif (($this->_transaction->get('TXN_total') > 0) && ($this->_transaction->get('TXN_paid') == 0)) {
646
+			// no payments made yet
647
+			$this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
648
+		} elseif ($this->_transaction->get('TXN_total') == 0) {
649
+			// free event
650
+			$this->_template_args['amount_due'] = false;
651
+		}
652
+
653
+		$payment_method = $this->_transaction->payment_method();
654
+
655
+		$this->_template_args['method_of_payment_name'] = $payment_method instanceof EE_Payment_Method
656
+			? $payment_method->admin_name()
657
+			: esc_html__('Unknown', 'event_espresso');
658
+
659
+		$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
660
+		// link back to overview
661
+		$this->_template_args['txn_overview_url'] = ! empty ($_SERVER['HTTP_REFERER'])
662
+			? $_SERVER['HTTP_REFERER']
663
+			: TXN_ADMIN_URL;
664
+
665
+
666
+		// next link
667
+		$next_txn                                 = $this->_transaction->next(
668
+			null,
669
+			array(array('STS_ID' => array('!=', EEM_Transaction::failed_status_code))),
670
+			'TXN_ID'
671
+		);
672
+		$this->_template_args['next_transaction'] = $next_txn
673
+			? $this->_next_link(
674
+				EE_Admin_Page::add_query_args_and_nonce(
675
+					array('action' => 'view_transaction', 'TXN_ID' => $next_txn['TXN_ID']),
676
+					TXN_ADMIN_URL
677
+				),
678
+				'dashicons dashicons-arrow-right ee-icon-size-22'
679
+			)
680
+			: '';
681
+		// previous link
682
+		$previous_txn                                 = $this->_transaction->previous(
683
+			null,
684
+			array(array('STS_ID' => array('!=', EEM_Transaction::failed_status_code))),
685
+			'TXN_ID'
686
+		);
687
+		$this->_template_args['previous_transaction'] = $previous_txn
688
+			? $this->_previous_link(
689
+				EE_Admin_Page::add_query_args_and_nonce(
690
+					array('action' => 'view_transaction', 'TXN_ID' => $previous_txn['TXN_ID']),
691
+					TXN_ADMIN_URL
692
+				),
693
+				'dashicons dashicons-arrow-left ee-icon-size-22'
694
+			)
695
+			: '';
696
+
697
+		// were we just redirected here after adding a new registration ???
698
+		if (
699
+		isset(
700
+			$this->_req_data['redirect_from'],
701
+			$this->_req_data['EVT_ID'],
702
+			$this->_req_data['event_name']
703
+		)
704
+		) {
705
+			if (
706
+			EE_Registry::instance()->CAP->current_user_can(
707
+				'ee_edit_registrations',
708
+				'espresso_registrations_new_registration',
709
+				$this->_req_data['EVT_ID']
710
+			)
711
+			) {
712
+				$this->_admin_page_title .= '<a id="add-new-registration" class="add-new-h2 button-primary" href="';
713
+				$this->_admin_page_title .= EE_Admin_Page::add_query_args_and_nonce(
714
+					array(
715
+						'page'     => 'espresso_registrations',
716
+						'action'   => 'new_registration',
717
+						'return'   => 'default',
718
+						'TXN_ID'   => $this->_transaction->ID(),
719
+						'event_id' => $this->_req_data['EVT_ID'],
720
+					),
721
+					REG_ADMIN_URL
722
+				);
723
+				$this->_admin_page_title .= '">';
724
+
725
+				$this->_admin_page_title .= sprintf(
726
+					esc_html__('Add Another New Registration to Event: "%1$s" ?', 'event_espresso'),
727
+					htmlentities(urldecode($this->_req_data['event_name']), ENT_QUOTES, 'UTF-8')
728
+				);
729
+				$this->_admin_page_title .= '</a>';
730
+			}
731
+			EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
732
+		}
733
+		// grab messages at the last second
734
+		$this->_template_args['notices'] = EE_Error::get_notices();
735
+		// path to template
736
+		$template_path                             = TXN_TEMPLATE_PATH . 'txn_admin_details_header.template.php';
737
+		$this->_template_args['admin_page_header'] = EEH_Template::display_template($template_path,
738
+			$this->_template_args, true);
739
+
740
+		// the details template wrapper
741
+		$this->display_admin_page_with_sidebar();
742
+
743
+	}
744
+
745
+
746
+	/**
747
+	 *        _transaction_details_metaboxes
748
+	 *
749
+	 * @access protected
750
+	 * @return void
751
+	 */
752
+	protected function _transaction_details_metaboxes()
753
+	{
754
+
755
+		$this->_set_transaction_object();
756
+
757
+		add_meta_box('edit-txn-details-mbox', esc_html__('Transaction Details', 'event_espresso'),
758
+			array($this, 'txn_details_meta_box'), $this->_wp_page_slug, 'normal', 'high');
759
+		add_meta_box(
760
+			'edit-txn-attendees-mbox',
761
+			esc_html__('Attendees Registered in this Transaction', 'event_espresso'),
762
+			array($this, 'txn_attendees_meta_box'),
763
+			$this->_wp_page_slug,
764
+			'normal',
765
+			'high',
766
+			array('TXN_ID' => $this->_transaction->ID())
767
+		);
768
+		add_meta_box('edit-txn-registrant-mbox', esc_html__('Primary Contact', 'event_espresso'),
769
+			array($this, 'txn_registrant_side_meta_box'), $this->_wp_page_slug, 'side', 'high');
770
+		add_meta_box('edit-txn-billing-info-mbox', esc_html__('Billing Information', 'event_espresso'),
771
+			array($this, 'txn_billing_info_side_meta_box'), $this->_wp_page_slug, 'side', 'high');
772
+
773
+	}
774
+
775
+
776
+	/**
777
+	 * txn_details_meta_box
778
+	 * generates HTML for the Transaction main meta box
779
+	 *
780
+	 * @access public
781
+	 * @return void
782
+	 */
783
+	public function txn_details_meta_box()
784
+	{
785
+
786
+		$this->_set_transaction_object();
787
+		$this->_template_args['TXN_ID']   = $this->_transaction->ID();
788
+		$this->_template_args['attendee'] = $this->_transaction->primary_registration() instanceof EE_Registration ? $this->_transaction->primary_registration()->attendee() : null;
789
+
790
+		//get line table
791
+		EEH_Autoloader::register_line_item_display_autoloaders();
792
+		$Line_Item_Display                       = new EE_Line_Item_Display('admin_table',
793
+			'EE_Admin_Table_Line_Item_Display_Strategy');
794
+		$this->_template_args['line_item_table'] = $Line_Item_Display->display_line_item($this->_transaction->total_line_item());
795
+		$this->_template_args['REG_code']        = $this->_transaction->get_first_related('Registration')->get('REG_code');
796
+
797
+		// process taxes
798
+		$taxes                         = $this->_transaction->get_many_related('Line_Item',
799
+			array(array('LIN_type' => EEM_Line_Item::type_tax)));
800
+		$this->_template_args['taxes'] = ! empty($taxes) ? $taxes : false;
801
+
802
+		$this->_template_args['grand_total']     = EEH_Template::format_currency($this->_transaction->get('TXN_total'),
803
+			false, false);
804
+		$this->_template_args['grand_raw_total'] = $this->_transaction->get('TXN_total');
805
+		$this->_template_args['TXN_status']      = $this->_transaction->get('STS_ID');
806 806
 
807 807
 //		$txn_status_class = 'status-' . $this->_transaction->get('STS_ID');
808 808
 
809
-        // process payment details
810
-        $payments = $this->_transaction->get_many_related('Payment');
811
-        if (! empty($payments)) {
812
-            $this->_template_args['payments']              = $payments;
813
-            $this->_template_args['existing_reg_payments'] = $this->_get_registration_payment_IDs($payments);
814
-        } else {
815
-            $this->_template_args['payments']              = false;
816
-            $this->_template_args['existing_reg_payments'] = array();
817
-        }
818
-
819
-        $this->_template_args['edit_payment_url']   = add_query_arg(array('action' => 'edit_payment'), TXN_ADMIN_URL);
820
-        $this->_template_args['delete_payment_url'] = add_query_arg(array('action' => 'espresso_delete_payment'),
821
-            TXN_ADMIN_URL);
822
-
823
-        if (isset($txn_details['invoice_number'])) {
824
-            $this->_template_args['txn_details']['invoice_number']['value'] = $this->_template_args['REG_code'];
825
-            $this->_template_args['txn_details']['invoice_number']['label'] = esc_html__('Invoice Number',
826
-                'event_espresso');
827
-        }
828
-
829
-        $this->_template_args['txn_details']['registration_session']['value'] = $this->_transaction->get_first_related('Registration')->get('REG_session');
830
-        $this->_template_args['txn_details']['registration_session']['label'] = esc_html__('Registration Session',
831
-            'event_espresso');
832
-
833
-        $this->_template_args['txn_details']['ip_address']['value'] = isset($this->_session['ip_address']) ? $this->_session['ip_address'] : '';
834
-        $this->_template_args['txn_details']['ip_address']['label'] = esc_html__('Transaction placed from IP',
835
-            'event_espresso');
836
-
837
-        $this->_template_args['txn_details']['user_agent']['value'] = isset($this->_session['user_agent']) ? $this->_session['user_agent'] : '';
838
-        $this->_template_args['txn_details']['user_agent']['label'] = esc_html__('Registrant User Agent',
839
-            'event_espresso');
840
-
841
-        $reg_steps = '<ul>';
842
-        foreach ($this->_transaction->reg_steps() as $reg_step => $reg_step_status) {
843
-            if ($reg_step_status === true) {
844
-                $reg_steps .= '<li style="color:#70cc50">' . sprintf(esc_html__('%1$s : Completed', 'event_espresso'),
845
-                        ucwords(str_replace('_', ' ', $reg_step))) . '</li>';
846
-            } else if (is_numeric($reg_step_status) && $reg_step_status !== false) {
847
-                $reg_steps .= '<li style="color:#2EA2CC">' . sprintf(
848
-                        esc_html__('%1$s : Initiated %2$s', 'event_espresso'),
849
-                        ucwords(str_replace('_', ' ', $reg_step)),
850
-                        date(get_option('date_format') . ' ' . get_option('time_format'),
851
-                            ($reg_step_status + (get_option('gmt_offset') * HOUR_IN_SECONDS)))
852
-                    ) . '</li>';
853
-            } else {
854
-                $reg_steps .= '<li style="color:#E76700">' . sprintf(esc_html__('%1$s : Never Initiated',
855
-                        'event_espresso'), ucwords(str_replace('_', ' ', $reg_step))) . '</li>';
856
-            }
857
-        }
858
-        $reg_steps                                                 .= '</ul>';
859
-        $this->_template_args['txn_details']['reg_steps']['value'] = $reg_steps;
860
-        $this->_template_args['txn_details']['reg_steps']['label'] = esc_html__('Registration Step Progress',
861
-            'event_espresso');
862
-
863
-
864
-        $this->_get_registrations_to_apply_payment_to();
865
-        $this->_get_payment_methods($payments);
866
-        $this->_get_payment_status_array();
867
-        $this->_get_reg_status_selection(); //sets up the template args for the reg status array for the transaction.
868
-
869
-        $this->_template_args['transaction_form_url']    = add_query_arg(array(
870
-            'action'  => 'edit_transaction',
871
-            'process' => 'transaction',
872
-        ), TXN_ADMIN_URL);
873
-        $this->_template_args['apply_payment_form_url']  = add_query_arg(array(
874
-            'page'   => 'espresso_transactions',
875
-            'action' => 'espresso_apply_payment',
876
-        ), WP_AJAX_URL);
877
-        $this->_template_args['delete_payment_form_url'] = add_query_arg(array(
878
-            'page'   => 'espresso_transactions',
879
-            'action' => 'espresso_delete_payment',
880
-        ), WP_AJAX_URL);
881
-
882
-        // 'espresso_delete_payment_nonce'
883
-
884
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_txn_details.template.php';
885
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
886
-
887
-    }
888
-
889
-
890
-    /**
891
-     * _get_registration_payment_IDs
892
-     *    generates an array of Payment IDs and their corresponding Registration IDs
893
-     *
894
-     * @access protected
895
-     * @param EE_Payment[] $payments
896
-     * @return array
897
-     */
898
-    protected function _get_registration_payment_IDs($payments = array())
899
-    {
900
-        $existing_reg_payments = array();
901
-        // get all reg payments for these payments
902
-        $reg_payments = EEM_Registration_Payment::instance()->get_all(array(
903
-            array(
904
-                'PAY_ID' => array(
905
-                    'IN',
906
-                    array_keys($payments),
907
-                ),
908
-            ),
909
-        ));
910
-        if (! empty($reg_payments)) {
911
-            foreach ($payments as $payment) {
912
-                if (! $payment instanceof EE_Payment) {
913
-                    continue;
914
-                } else if (! isset($existing_reg_payments[$payment->ID()])) {
915
-                    $existing_reg_payments[$payment->ID()] = array();
916
-                }
917
-                foreach ($reg_payments as $reg_payment) {
918
-                    if ($reg_payment instanceof EE_Registration_Payment && $reg_payment->payment_ID() === $payment->ID()) {
919
-                        $existing_reg_payments[$payment->ID()][] = $reg_payment->registration_ID();
920
-                    }
921
-                }
922
-            }
923
-        }
924
-
925
-        return $existing_reg_payments;
926
-    }
927
-
928
-
929
-    /**
930
-     * _get_registrations_to_apply_payment_to
931
-     *    generates HTML for displaying a series of checkboxes in the admin payment modal window
932
-     * which allows the admin to only apply the payment to the specific registrations
933
-     *
934
-     * @access protected
935
-     * @return void
936
-     * @throws \EE_Error
937
-     */
938
-    protected function _get_registrations_to_apply_payment_to()
939
-    {
940
-        // we want any registration with an active status (ie: not deleted or cancelled)
941
-        $query_params                      = array(
942
-            array(
943
-                'STS_ID' => array(
944
-                    'IN',
945
-                    array(
946
-                        EEM_Registration::status_id_approved,
947
-                        EEM_Registration::status_id_pending_payment,
948
-                        EEM_Registration::status_id_not_approved,
949
-                    ),
950
-                ),
951
-            ),
952
-        );
953
-        $registrations_to_apply_payment_to = EEH_HTML::br() . EEH_HTML::div(
954
-                '', 'txn-admin-apply-payment-to-registrations-dv', '', 'clear: both; margin: 1.5em 0 0; display: none;'
955
-            );
956
-        $registrations_to_apply_payment_to .= EEH_HTML::br() . EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
957
-        $registrations_to_apply_payment_to .= EEH_HTML::table('', '', 'admin-primary-mbox-tbl');
958
-        $registrations_to_apply_payment_to .= EEH_HTML::thead(
959
-            EEH_HTML::tr(
960
-                EEH_HTML::th(esc_html__('ID', 'event_espresso')) .
961
-                EEH_HTML::th(esc_html__('Registrant', 'event_espresso')) .
962
-                EEH_HTML::th(esc_html__('Ticket', 'event_espresso')) .
963
-                EEH_HTML::th(esc_html__('Event', 'event_espresso')) .
964
-                EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr') .
965
-                EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr') .
966
-                EEH_HTML::th(esc_html__('Apply', 'event_espresso'), '', 'jst-cntr')
967
-            )
968
-        );
969
-        $registrations_to_apply_payment_to .= EEH_HTML::tbody();
970
-        // get registrations for TXN
971
-        $registrations = $this->_transaction->registrations($query_params);
972
-        foreach ($registrations as $registration) {
973
-            if ($registration instanceof EE_Registration) {
974
-                $attendee_name                     = $registration->attendee() instanceof EE_Attendee
975
-                    ? $registration->attendee()->full_name()
976
-                    : esc_html__('Unknown Attendee', 'event_espresso');
977
-                $owing                             = $registration->final_price() - $registration->paid();
978
-                $taxable                           = $registration->ticket()->taxable()
979
-                    ? ' <span class="smaller-text lt-grey-text"> ' . esc_html__('+ tax', 'event_espresso') . '</span>'
980
-                    : '';
981
-                $checked                           = empty($existing_reg_payments) || in_array($registration->ID(),
982
-                    $existing_reg_payments)
983
-                    ? ' checked="checked"'
984
-                    : '';
985
-                $disabled                          = $registration->final_price() > 0 ? '' : ' disabled';
986
-                $registrations_to_apply_payment_to .= EEH_HTML::tr(
987
-                    EEH_HTML::td($registration->ID()) .
988
-                    EEH_HTML::td($attendee_name) .
989
-                    EEH_HTML::td(
990
-                        $registration->ticket()->name() . ' : ' . $registration->ticket()->pretty_price() . $taxable
991
-                    ) .
992
-                    EEH_HTML::td($registration->event_name()) .
993
-                    EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr') .
994
-                    EEH_HTML::td(EEH_Template::format_currency($owing), '', 'txn-admin-payment-owing-td jst-cntr') .
995
-                    EEH_HTML::td(
996
-                        '<input type="checkbox" value="' . $registration->ID()
997
-                        . '" name="txn_admin_payment[registrations]"'
998
-                        . $checked . $disabled . '>',
999
-                        '', 'jst-cntr'
1000
-                    ),
1001
-                    'apply-payment-registration-row-' . $registration->ID()
1002
-                );
1003
-            }
1004
-        }
1005
-        $registrations_to_apply_payment_to                         .= EEH_HTML::tbodyx();
1006
-        $registrations_to_apply_payment_to                         .= EEH_HTML::tablex();
1007
-        $registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1008
-        $registrations_to_apply_payment_to                         .= EEH_HTML::p(
1009
-            esc_html__(
1010
-                'The payment will only be applied to the registrations that have a check mark in their corresponding check box. Checkboxes for free registrations have been disabled.',
1011
-                'event_espresso'
1012
-            ),
1013
-            '', 'clear description'
1014
-        );
1015
-        $registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1016
-        $this->_template_args['registrations_to_apply_payment_to'] = $registrations_to_apply_payment_to;
1017
-    }
1018
-
1019
-
1020
-    /**
1021
-     * _get_reg_status_selection
1022
-     *
1023
-     * @todo   this will need to be adjusted either once MER comes along OR we move default reg status to tickets
1024
-     *         instead of events.
1025
-     * @access protected
1026
-     * @return void
1027
-     */
1028
-    protected function _get_reg_status_selection()
1029
-    {
1030
-        //first get all possible statuses
1031
-        $statuses = EEM_Registration::reg_status_array(array(), true);
1032
-        //let's add a "don't change" option.
1033
-        $status_array['NAN']                                 = esc_html__('Leave the Same', 'event_espresso');
1034
-        $status_array                                        = array_merge($status_array, $statuses);
1035
-        $this->_template_args['status_change_select']        = EEH_Form_Fields::select_input('txn_reg_status_change[reg_status]',
1036
-            $status_array, 'NAN', 'id="txn-admin-payment-reg-status-inp"', 'txn-reg-status-change-reg-status');
1037
-        $this->_template_args['delete_status_change_select'] = EEH_Form_Fields::select_input('delete_txn_reg_status_change[reg_status]',
1038
-            $status_array, 'NAN', 'delete-txn-admin-payment-reg-status-inp', 'delete-txn-reg-status-change-reg-status');
1039
-
1040
-    }
1041
-
1042
-
1043
-    /**
1044
-     *    _get_payment_methods
1045
-     * Gets all the payment methods available generally, or the ones that are already
1046
-     * selected on these payments (in case their payment methods are no longer active).
1047
-     * Has the side-effect of updating the template args' payment_methods item
1048
-     *
1049
-     * @access private
1050
-     * @param EE_Payment[] to show on this page
1051
-     * @return void
1052
-     */
1053
-    private function _get_payment_methods($payments = array())
1054
-    {
1055
-        $payment_methods_of_payments = array();
1056
-        foreach ($payments as $payment) {
1057
-            if ($payment instanceof EE_Payment) {
1058
-                $payment_methods_of_payments[] = $payment->get('PMD_ID');
1059
-            }
1060
-        }
1061
-        if ($payment_methods_of_payments) {
1062
-            $query_args = array(
1063
-                array(
1064
-                    'OR*payment_method_for_payment' => array(
1065
-                        'PMD_ID'    => array('IN', $payment_methods_of_payments),
1066
-                        'PMD_scope' => array('LIKE', '%' . EEM_Payment_Method::scope_admin . '%'),
1067
-                    ),
1068
-                ),
1069
-            );
1070
-        } else {
1071
-            $query_args = array(array('PMD_scope' => array('LIKE', '%' . EEM_Payment_Method::scope_admin . '%')));
1072
-        }
1073
-        $this->_template_args['payment_methods'] = EEM_Payment_Method::instance()->get_all($query_args);
1074
-    }
1075
-
1076
-
1077
-    /**
1078
-     * txn_attendees_meta_box
1079
-     *    generates HTML for the Attendees Transaction main meta box
1080
-     *
1081
-     * @access public
1082
-     * @param WP_Post $post
1083
-     * @param array   $metabox
1084
-     * @return void
1085
-     */
1086
-    public function txn_attendees_meta_box($post, $metabox = array('args' => array()))
1087
-    {
1088
-
1089
-        extract($metabox['args']);
1090
-        $this->_template_args['post']            = $post;
1091
-        $this->_template_args['event_attendees'] = array();
1092
-        // process items in cart
1093
-        $line_items = $this->_transaction->get_many_related('Line_Item', array(array('LIN_type' => 'line-item')));
1094
-        if (! empty($line_items)) {
1095
-            foreach ($line_items as $item) {
1096
-                if ($item instanceof EE_Line_Item) {
1097
-                    switch ($item->OBJ_type()) {
1098
-
1099
-                        case 'Event' :
1100
-                            break;
1101
-
1102
-                        case 'Ticket' :
1103
-                            $ticket = $item->ticket();
1104
-                            //right now we're only handling tickets here.  Cause its expected that only tickets will have attendees right?
1105
-                            if (! $ticket instanceof EE_Ticket) {
1106
-                                continue;
1107
-                            }
1108
-                            try {
1109
-                                $event_name = $ticket->get_event_name();
1110
-                            } catch (Exception $e) {
1111
-                                EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1112
-                                $event_name = esc_html__('Unknown Event', 'event_espresso');
1113
-                            }
1114
-                            $event_name   .= ' - ' . $item->get('LIN_name');
1115
-                            $ticket_price = EEH_Template::format_currency($item->get('LIN_unit_price'));
1116
-                            // now get all of the registrations for this transaction that use this ticket
1117
-                            $registrations = $ticket->get_many_related('Registration',
1118
-                                array(array('TXN_ID' => $this->_transaction->ID())));
1119
-                            foreach ($registrations as $registration) {
1120
-                                if (! $registration instanceof EE_Registration) {
1121
-                                    continue;
1122
-                                }
1123
-                                $this->_template_args['event_attendees'][$registration->ID()]['STS_ID']            = $registration->status_ID();
1124
-                                $this->_template_args['event_attendees'][$registration->ID()]['att_num']           = $registration->count();
1125
-                                $this->_template_args['event_attendees'][$registration->ID()]['event_ticket_name'] = $event_name;
1126
-                                $this->_template_args['event_attendees'][$registration->ID()]['ticket_price']      = $ticket_price;
1127
-                                // attendee info
1128
-                                $attendee = $registration->get_first_related('Attendee');
1129
-                                if ($attendee instanceof EE_Attendee) {
1130
-                                    $this->_template_args['event_attendees'][$registration->ID()]['att_id']   = $attendee->ID();
1131
-                                    $this->_template_args['event_attendees'][$registration->ID()]['attendee'] = $attendee->full_name();
1132
-                                    $this->_template_args['event_attendees'][$registration->ID()]['email']    = '<a href="mailto:' . $attendee->email() . '?subject=' . $event_name . esc_html__(' Event',
1133
-                                            'event_espresso') . '">' . $attendee->email() . '</a>';
1134
-                                    $this->_template_args['event_attendees'][$registration->ID()]['address']  = EEH_Address::format($attendee,
1135
-                                        'inline', false, false);
1136
-                                } else {
1137
-                                    $this->_template_args['event_attendees'][$registration->ID()]['att_id']   = '';
1138
-                                    $this->_template_args['event_attendees'][$registration->ID()]['attendee'] = '';
1139
-                                    $this->_template_args['event_attendees'][$registration->ID()]['email']    = '';
1140
-                                    $this->_template_args['event_attendees'][$registration->ID()]['address']  = '';
1141
-                                }
1142
-                            }
1143
-                            break;
1144
-
1145
-                    }
1146
-                }
1147
-            }
1148
-
1149
-            $this->_template_args['transaction_form_url'] = add_query_arg(array(
1150
-                'action'  => 'edit_transaction',
1151
-                'process' => 'attendees',
1152
-            ), TXN_ADMIN_URL);
1153
-            echo EEH_Template::display_template(TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_attendees.template.php',
1154
-                $this->_template_args, true);
1155
-
1156
-        } else {
1157
-            echo sprintf(
1158
-                esc_html__('%1$sFor some reason, there are no attendees registered for this transaction. Likely the registration was abandoned in process.%2$s',
1159
-                    'event_espresso'),
1160
-                '<p class="important-notice">',
1161
-                '</p>'
1162
-            );
1163
-        }
1164
-    }
1165
-
1166
-
1167
-    /**
1168
-     * txn_registrant_side_meta_box
1169
-     * generates HTML for the Edit Transaction side meta box
1170
-     *
1171
-     * @access public
1172
-     * @throws \EE_Error
1173
-     * @return void
1174
-     */
1175
-    public function txn_registrant_side_meta_box()
1176
-    {
1177
-        $primary_att = $this->_transaction->primary_registration() instanceof EE_Registration ? $this->_transaction->primary_registration()->get_first_related('Attendee') : null;
1178
-        if (! $primary_att instanceof EE_Attendee) {
1179
-            $this->_template_args['no_attendee_message'] = esc_html__('There is no attached contact for this transaction.  The transaction either failed due to an error or was abandoned.',
1180
-                'event_espresso');
1181
-            $primary_att                                 = EEM_Attendee::instance()->create_default_object();
1182
-        }
1183
-        $this->_template_args['ATT_ID']            = $primary_att->ID();
1184
-        $this->_template_args['prime_reg_fname']   = $primary_att->fname();
1185
-        $this->_template_args['prime_reg_lname']   = $primary_att->lname();
1186
-        $this->_template_args['prime_reg_email']   = $primary_att->email();
1187
-        $this->_template_args['prime_reg_phone']   = $primary_att->phone();
1188
-        $this->_template_args['edit_attendee_url'] = EE_Admin_Page::add_query_args_and_nonce(array(
1189
-            'action' => 'edit_attendee',
1190
-            'post'   => $primary_att->ID(),
1191
-        ), REG_ADMIN_URL);
1192
-        // get formatted address for registrant
1193
-        $this->_template_args['formatted_address'] = EEH_Address::format($primary_att);
1194
-        echo EEH_Template::display_template(TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_registrant.template.php',
1195
-            $this->_template_args, true);
1196
-    }
1197
-
1198
-
1199
-    /**
1200
-     * txn_billing_info_side_meta_box
1201
-     *    generates HTML for the Edit Transaction side meta box
1202
-     *
1203
-     * @access public
1204
-     * @return void
1205
-     */
1206
-    public function txn_billing_info_side_meta_box()
1207
-    {
1208
-
1209
-        $this->_template_args['billing_form']     = $this->_transaction->billing_info();
1210
-        $this->_template_args['billing_form_url'] = add_query_arg(
1211
-            array('action' => 'edit_transaction', 'process' => 'billing'),
1212
-            TXN_ADMIN_URL
1213
-        );
1214
-
1215
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_billing_info.template.php';
1216
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);/**/
1217
-    }
1218
-
1219
-
1220
-    /**
1221
-     * apply_payments_or_refunds
1222
-     *    registers a payment or refund made towards a transaction
1223
-     *
1224
-     * @access public
1225
-     * @return void
1226
-     */
1227
-    public function apply_payments_or_refunds()
1228
-    {
1229
-        $json_response_data = array('return_data' => false);
1230
-        $valid_data         = $this->_validate_payment_request_data();
1231
-        if (! empty($valid_data)
1232
-
1233
-        ) {
1234
-            $PAY_ID = $valid_data['PAY_ID'];
1235
-            //save  the new payment
1236
-            $payment = $this->_create_payment_from_request_data($valid_data);
1237
-            // get the TXN for this payment
1238
-            $transaction = $payment->transaction();
1239
-            // verify transaction
1240
-            if ($transaction instanceof EE_Transaction) {
1241
-                // calculate_total_payments_and_update_status
1242
-                $this->_process_transaction_payments($transaction);
1243
-                $REG_IDs = $this->_get_REG_IDs_to_apply_payment_to($payment);
1244
-                $this->_remove_existing_registration_payments($payment, $PAY_ID);
1245
-                // apply payment to registrations (if applicable)
1246
-                if (! empty($REG_IDs)) {
1247
-                    $this->_update_registration_payments($transaction, $payment, $REG_IDs);
1248
-                    $this->_maybe_send_notifications();
1249
-                    // now process status changes for the same registrations
1250
-                    $this->_process_registration_status_change($transaction, $REG_IDs);
1251
-                }
1252
-                $this->_maybe_send_notifications($payment);
1253
-                //prepare to render page
1254
-                $json_response_data['return_data'] = $this->_build_payment_json_response($payment, $REG_IDs);
1255
-                do_action('AHEE__Transactions_Admin_Page__apply_payments_or_refund__after_recording', $transaction,
1256
-                    $payment);
1257
-            } else {
1258
-                EE_Error::add_error(
1259
-                    esc_html__('A valid Transaction for this payment could not be retrieved.', 'event_espresso'),
1260
-                    __FILE__, __FUNCTION__, __LINE__
1261
-                );
1262
-            }
1263
-        } else {
1264
-            EE_Error::add_error(esc_html__('The payment form data could not be processed. Please try again.',
1265
-                'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
1266
-        }
1267
-
1268
-        $notices              = EE_Error::get_notices(false, false, false);
1269
-        $this->_template_args = array(
1270
-            'data'    => $json_response_data,
1271
-            'error'   => $notices['errors'],
1272
-            'success' => $notices['success'],
1273
-        );
1274
-        $this->_return_json();
1275
-    }
1276
-
1277
-
1278
-    /**
1279
-     * _validate_payment_request_data
1280
-     *
1281
-     * @return array
1282
-     */
1283
-    protected function _validate_payment_request_data()
1284
-    {
1285
-        if (! isset($this->_req_data['txn_admin_payment'])) {
1286
-            return false;
1287
-        }
1288
-        $payment_form = $this->_generate_payment_form_section();
1289
-        try {
1290
-            if ($payment_form->was_submitted()) {
1291
-                $payment_form->receive_form_submission();
1292
-                if (! $payment_form->is_valid()) {
1293
-                    $submission_error_messages = array();
1294
-                    foreach ($payment_form->get_validation_errors_accumulated() as $validation_error) {
1295
-                        if ($validation_error instanceof EE_Validation_Error) {
1296
-                            $submission_error_messages[] = sprintf(
1297
-                                _x('%s : %s', 'Form Section Name : Form Validation Error', 'event_espresso'),
1298
-                                $validation_error->get_form_section()->html_label_text(),
1299
-                                $validation_error->getMessage()
1300
-                            );
1301
-                        }
1302
-                    }
1303
-                    EE_Error::add_error(join('<br />', $submission_error_messages), __FILE__, __FUNCTION__, __LINE__);
1304
-
1305
-                    return array();
1306
-                }
1307
-            }
1308
-        } catch (EE_Error $e) {
1309
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1310
-
1311
-            return array();
1312
-        }
1313
-
1314
-        return $payment_form->valid_data();
1315
-    }
1316
-
1317
-
1318
-    /**
1319
-     * _generate_payment_form_section
1320
-     *
1321
-     * @return EE_Form_Section_Proper
1322
-     */
1323
-    protected function _generate_payment_form_section()
1324
-    {
1325
-        return new EE_Form_Section_Proper(
1326
-            array(
1327
-                'name'        => 'txn_admin_payment',
1328
-                'subsections' => array(
1329
-                    'PAY_ID'          => new EE_Text_Input(
1330
-                        array(
1331
-                            'default'               => 0,
1332
-                            'required'              => false,
1333
-                            'html_label_text'       => esc_html__('Payment ID', 'event_espresso'),
1334
-                            'validation_strategies' => array(new EE_Int_Normalization()),
1335
-                        )
1336
-                    ),
1337
-                    'TXN_ID'          => new EE_Text_Input(
1338
-                        array(
1339
-                            'default'               => 0,
1340
-                            'required'              => true,
1341
-                            'html_label_text'       => esc_html__('Transaction ID', 'event_espresso'),
1342
-                            'validation_strategies' => array(new EE_Int_Normalization()),
1343
-                        )
1344
-                    ),
1345
-                    'type'            => new EE_Text_Input(
1346
-                        array(
1347
-                            'default'               => 1,
1348
-                            'required'              => true,
1349
-                            'html_label_text'       => esc_html__('Payment or Refund', 'event_espresso'),
1350
-                            'validation_strategies' => array(new EE_Int_Normalization()),
1351
-                        )
1352
-                    ),
1353
-                    'amount'          => new EE_Text_Input(
1354
-                        array(
1355
-                            'default'               => 0,
1356
-                            'required'              => true,
1357
-                            'html_label_text'       => esc_html__('Payment amount', 'event_espresso'),
1358
-                            'validation_strategies' => array(new EE_Float_Normalization()),
1359
-                        )
1360
-                    ),
1361
-                    'status'          => new EE_Text_Input(
1362
-                        array(
1363
-                            'default'         => EEM_Payment::status_id_approved,
1364
-                            'required'        => true,
1365
-                            'html_label_text' => esc_html__('Payment status', 'event_espresso'),
1366
-                        )
1367
-                    ),
1368
-                    'PMD_ID'          => new EE_Text_Input(
1369
-                        array(
1370
-                            'default'               => 2,
1371
-                            'required'              => true,
1372
-                            'html_label_text'       => esc_html__('Payment Method', 'event_espresso'),
1373
-                            'validation_strategies' => array(new EE_Int_Normalization()),
1374
-                        )
1375
-                    ),
1376
-                    'date'            => new EE_Text_Input(
1377
-                        array(
1378
-                            'default'         => time(),
1379
-                            'required'        => true,
1380
-                            'html_label_text' => esc_html__('Payment date', 'event_espresso'),
1381
-                        )
1382
-                    ),
1383
-                    'txn_id_chq_nmbr' => new EE_Text_Input(
1384
-                        array(
1385
-                            'default'               => '',
1386
-                            'required'              => false,
1387
-                            'html_label_text'       => esc_html__('Transaction or Cheque Number', 'event_espresso'),
1388
-                            'validation_strategies' => array(
1389
-                                new EE_Max_Length_Validation_Strategy(esc_html__('Input too long', 'event_espresso'),
1390
-                                    100),
1391
-                            ),
1392
-                        )
1393
-                    ),
1394
-                    'po_number'       => new EE_Text_Input(
1395
-                        array(
1396
-                            'default'               => '',
1397
-                            'required'              => false,
1398
-                            'html_label_text'       => esc_html__('Purchase Order Number', 'event_espresso'),
1399
-                            'validation_strategies' => array(
1400
-                                new EE_Max_Length_Validation_Strategy(esc_html__('Input too long', 'event_espresso'),
1401
-                                    100),
1402
-                            ),
1403
-                        )
1404
-                    ),
1405
-                    'accounting'      => new EE_Text_Input(
1406
-                        array(
1407
-                            'default'               => '',
1408
-                            'required'              => false,
1409
-                            'html_label_text'       => esc_html__('Extra Field for Accounting', 'event_espresso'),
1410
-                            'validation_strategies' => array(
1411
-                                new EE_Max_Length_Validation_Strategy(esc_html__('Input too long', 'event_espresso'),
1412
-                                    100),
1413
-                            ),
1414
-                        )
1415
-                    ),
1416
-                ),
1417
-            )
1418
-        );
1419
-    }
1420
-
1421
-
1422
-    /**
1423
-     * _create_payment_from_request_data
1424
-     *
1425
-     * @param array $valid_data
1426
-     * @return EE_Payment
1427
-     */
1428
-    protected function _create_payment_from_request_data($valid_data)
1429
-    {
1430
-        $PAY_ID = $valid_data['PAY_ID'];
1431
-        // get payment amount
1432
-        $amount = $valid_data['amount'] ? abs($valid_data['amount']) : 0;
1433
-        // payments have a type value of 1 and refunds have a type value of -1
1434
-        // so multiplying amount by type will give a positive value for payments, and negative values for refunds
1435
-        $amount = $valid_data['type'] < 0 ? $amount * -1 : $amount;
1436
-        // for some reason the date string coming in has extra spaces between the date and time.  This fixes that.
1437
-        $date    = $valid_data['date'] ? preg_replace('/\s+/', ' ', $valid_data['date']) : date('Y-m-d g:i a',
1438
-            current_time('timestamp'));
1439
-        $payment = EE_Payment::new_instance(
1440
-            array(
1441
-                'TXN_ID'              => $valid_data['TXN_ID'],
1442
-                'STS_ID'              => $valid_data['status'],
1443
-                'PAY_timestamp'       => $date,
1444
-                'PAY_source'          => EEM_Payment_Method::scope_admin,
1445
-                'PMD_ID'              => $valid_data['PMD_ID'],
1446
-                'PAY_amount'          => $amount,
1447
-                'PAY_txn_id_chq_nmbr' => $valid_data['txn_id_chq_nmbr'],
1448
-                'PAY_po_number'       => $valid_data['po_number'],
1449
-                'PAY_extra_accntng'   => $valid_data['accounting'],
1450
-                'PAY_details'         => $valid_data,
1451
-                'PAY_ID'              => $PAY_ID,
1452
-            ),
1453
-            '',
1454
-            array('Y-m-d', 'g:i a')
1455
-        );
1456
-
1457
-        if (! $payment->save()) {
1458
-            EE_Error::add_error(
1459
-                sprintf(
1460
-                    esc_html__('Payment %1$d has not been successfully saved to the database.', 'event_espresso'),
1461
-                    $payment->ID()
1462
-                ),
1463
-                __FILE__, __FUNCTION__, __LINE__
1464
-            );
1465
-        }
1466
-
1467
-        return $payment;
1468
-    }
1469
-
1470
-
1471
-    /**
1472
-     * _process_transaction_payments
1473
-     *
1474
-     * @param \EE_Transaction $transaction
1475
-     * @return array
1476
-     */
1477
-    protected function _process_transaction_payments(EE_Transaction $transaction)
1478
-    {
1479
-        /** @type EE_Transaction_Payments $transaction_payments */
1480
-        $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1481
-        //update the transaction with this payment
1482
-        if ($transaction_payments->calculate_total_payments_and_update_status($transaction)) {
1483
-            EE_Error::add_success(esc_html__('The payment has been processed successfully.', 'event_espresso'),
1484
-                __FILE__, __FUNCTION__, __LINE__);
1485
-        } else {
1486
-            EE_Error::add_error(
1487
-                esc_html__('The payment was processed successfully but the amount paid for the transaction was not updated.',
1488
-                    'event_espresso')
1489
-                , __FILE__, __FUNCTION__, __LINE__
1490
-            );
1491
-        }
1492
-    }
1493
-
1494
-
1495
-    /**
1496
-     * _get_REG_IDs_to_apply_payment_to
1497
-     * returns a list of registration IDs that the payment will apply to
1498
-     *
1499
-     * @param \EE_Payment $payment
1500
-     * @return array
1501
-     */
1502
-    protected function _get_REG_IDs_to_apply_payment_to(EE_Payment $payment)
1503
-    {
1504
-        $REG_IDs = array();
1505
-        // grab array of IDs for specific registrations to apply changes to
1506
-        if (isset($this->_req_data['txn_admin_payment']['registrations'])) {
1507
-            $REG_IDs = (array)$this->_req_data['txn_admin_payment']['registrations'];
1508
-        }
1509
-        //nothing specified ? then get all reg IDs
1510
-        if (empty($REG_IDs)) {
1511
-            $registrations = $payment->transaction()->registrations();
1512
-            $REG_IDs       = ! empty($registrations) ? array_keys($registrations) : $this->_get_existing_reg_payment_REG_IDs($payment);
1513
-        }
1514
-
1515
-        // ensure that REG_IDs are integers and NOT strings
1516
-        return array_map('intval', $REG_IDs);
1517
-    }
1518
-
1519
-
1520
-    /**
1521
-     * @return array
1522
-     */
1523
-    public function existing_reg_payment_REG_IDs()
1524
-    {
1525
-        return $this->_existing_reg_payment_REG_IDs;
1526
-    }
1527
-
1528
-
1529
-    /**
1530
-     * @param array $existing_reg_payment_REG_IDs
1531
-     */
1532
-    public function set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs = null)
1533
-    {
1534
-        $this->_existing_reg_payment_REG_IDs = $existing_reg_payment_REG_IDs;
1535
-    }
1536
-
1537
-
1538
-    /**
1539
-     * _get_existing_reg_payment_REG_IDs
1540
-     * returns a list of registration IDs that the payment is currently related to
1541
-     * as recorded in the database
1542
-     *
1543
-     * @param \EE_Payment $payment
1544
-     * @return array
1545
-     */
1546
-    protected function _get_existing_reg_payment_REG_IDs(EE_Payment $payment)
1547
-    {
1548
-        if ($this->existing_reg_payment_REG_IDs() === null) {
1549
-            // let's get any existing reg payment records for this payment
1550
-            $existing_reg_payment_REG_IDs = $payment->get_many_related('Registration');
1551
-            // but we only want the REG IDs, so grab the array keys
1552
-            $existing_reg_payment_REG_IDs = ! empty($existing_reg_payment_REG_IDs) ? array_keys($existing_reg_payment_REG_IDs) : array();
1553
-            $this->set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs);
1554
-        }
1555
-
1556
-        return $this->existing_reg_payment_REG_IDs();
1557
-    }
1558
-
1559
-
1560
-    /**
1561
-     * _remove_existing_registration_payments
1562
-     * this calculates the difference between existing relations
1563
-     * to the supplied payment and the new list registration IDs,
1564
-     * removes any related registrations that no longer apply,
1565
-     * and then updates the registration paid fields
1566
-     *
1567
-     * @param \EE_Payment $payment
1568
-     * @param int         $PAY_ID
1569
-     * @return bool;
1570
-     */
1571
-    protected function _remove_existing_registration_payments(EE_Payment $payment, $PAY_ID = 0)
1572
-    {
1573
-        // newly created payments will have nothing recorded for $PAY_ID
1574
-        if ($PAY_ID == 0) {
1575
-            return false;
1576
-        }
1577
-        $existing_reg_payment_REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
1578
-        if (empty($existing_reg_payment_REG_IDs)) {
1579
-            return false;
1580
-        }
1581
-        /** @type EE_Transaction_Payments $transaction_payments */
1582
-        $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1583
-
1584
-        return $transaction_payments->delete_registration_payments_and_update_registrations(
1585
-            $payment,
1586
-            array(
1587
-                array(
1588
-                    'PAY_ID' => $payment->ID(),
1589
-                    'REG_ID' => array('IN', $existing_reg_payment_REG_IDs),
1590
-                ),
1591
-            )
1592
-        );
1593
-    }
1594
-
1595
-
1596
-    /**
1597
-     * _update_registration_payments
1598
-     * this applies the payments to the selected registrations
1599
-     * but only if they have not already been paid for
1600
-     *
1601
-     * @param  EE_Transaction $transaction
1602
-     * @param \EE_Payment     $payment
1603
-     * @param array           $REG_IDs
1604
-     * @return bool
1605
-     */
1606
-    protected function _update_registration_payments(
1607
-        EE_Transaction $transaction,
1608
-        EE_Payment $payment,
1609
-        $REG_IDs = array()
1610
-    ) {
1611
-        // we can pass our own custom set of registrations to EE_Payment_Processor::process_registration_payments()
1612
-        // so let's do that using our set of REG_IDs from the form
1613
-        $registration_query_where_params = array(
1614
-            'REG_ID' => array('IN', $REG_IDs),
1615
-        );
1616
-        // but add in some conditions regarding payment,
1617
-        // so that we don't apply payments to registrations that are free or have already been paid for
1618
-        // but ONLY if the payment is NOT a refund ( ie: the payment amount is not negative )
1619
-        if (! $payment->is_a_refund()) {
1620
-            $registration_query_where_params['REG_final_price']  = array('!=', 0);
1621
-            $registration_query_where_params['REG_final_price*'] = array('!=', 'REG_paid', true);
1622
-        }
1623
-        //EEH_Debug_Tools::printr( $registration_query_where_params, '$registration_query_where_params', __FILE__, __LINE__ );
1624
-        $registrations = $transaction->registrations(array($registration_query_where_params));
1625
-        if (! empty($registrations)) {
1626
-            /** @type EE_Payment_Processor $payment_processor */
1627
-            $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
1628
-            $payment_processor->process_registration_payments($transaction, $payment, $registrations);
1629
-        }
1630
-    }
1631
-
1632
-
1633
-    /**
1634
-     * _process_registration_status_change
1635
-     * This processes requested registration status changes for all the registrations
1636
-     * on a given transaction and (optionally) sends out notifications for the changes.
1637
-     *
1638
-     * @param  EE_Transaction $transaction
1639
-     * @param array           $REG_IDs
1640
-     * @return bool
1641
-     */
1642
-    protected function _process_registration_status_change(EE_Transaction $transaction, $REG_IDs = array())
1643
-    {
1644
-        // first if there is no change in status then we get out.
1645
-        if (
1646
-            ! isset($this->_req_data['txn_reg_status_change'], $this->_req_data['txn_reg_status_change']['reg_status'])
1647
-            || $this->_req_data['txn_reg_status_change']['reg_status'] == 'NAN'
1648
-        ) {
1649
-            //no error message, no change requested, just nothing to do man.
1650
-            return false;
1651
-        }
1652
-        /** @type EE_Transaction_Processor $transaction_processor */
1653
-        $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
1654
-
1655
-        // made it here dude?  Oh WOW.  K, let's take care of changing the statuses
1656
-        return $transaction_processor->manually_update_registration_statuses(
1657
-            $transaction,
1658
-            sanitize_text_field($this->_req_data['txn_reg_status_change']['reg_status']),
1659
-            array(array('REG_ID' => array('IN', $REG_IDs)))
1660
-        );
1661
-    }
1662
-
1663
-
1664
-    /**
1665
-     * _build_payment_json_response
1666
-     *
1667
-     * @access public
1668
-     * @param \EE_Payment $payment
1669
-     * @param array       $REG_IDs
1670
-     * @param bool | null $delete_txn_reg_status_change
1671
-     * @return array
1672
-     */
1673
-    protected function _build_payment_json_response(
1674
-        EE_Payment $payment,
1675
-        $REG_IDs = array(),
1676
-        $delete_txn_reg_status_change = null
1677
-    ) {
1678
-        // was the payment deleted ?
1679
-        if (is_bool($delete_txn_reg_status_change)) {
1680
-            return array(
1681
-                'PAY_ID'                       => $payment->ID(),
1682
-                'amount'                       => $payment->amount(),
1683
-                'total_paid'                   => $payment->transaction()->paid(),
1684
-                'txn_status'                   => $payment->transaction()->status_ID(),
1685
-                'pay_status'                   => $payment->STS_ID(),
1686
-                'registrations'                => $this->_registration_payment_data_array($REG_IDs),
1687
-                'delete_txn_reg_status_change' => $delete_txn_reg_status_change,
1688
-            );
1689
-        } else {
1690
-            $this->_get_payment_status_array();
1691
-
1692
-            return array(
1693
-                'amount'           => $payment->amount(),
1694
-                'total_paid'       => $payment->transaction()->paid(),
1695
-                'txn_status'       => $payment->transaction()->status_ID(),
1696
-                'pay_status'       => $payment->STS_ID(),
1697
-                'PAY_ID'           => $payment->ID(),
1698
-                'STS_ID'           => $payment->STS_ID(),
1699
-                'status'           => self::$_pay_status[$payment->STS_ID()],
1700
-                'date'             => $payment->timestamp('Y-m-d', 'h:i a'),
1701
-                'method'           => strtoupper($payment->source()),
1702
-                'PM_ID'            => $payment->payment_method() ? $payment->payment_method()->ID() : 1,
1703
-                'gateway'          => $payment->payment_method() ? $payment->payment_method()->admin_name() : esc_html__("Unknown",
1704
-                    'event_espresso'),
1705
-                'gateway_response' => $payment->gateway_response(),
1706
-                'txn_id_chq_nmbr'  => $payment->txn_id_chq_nmbr(),
1707
-                'po_number'        => $payment->po_number(),
1708
-                'extra_accntng'    => $payment->extra_accntng(),
1709
-                'registrations'    => $this->_registration_payment_data_array($REG_IDs),
1710
-            );
1711
-        }
1712
-    }
1713
-
1714
-
1715
-    /**
1716
-     * delete_payment
1717
-     *    delete a payment or refund made towards a transaction
1718
-     *
1719
-     * @access public
1720
-     * @return void
1721
-     */
1722
-    public function delete_payment()
1723
-    {
1724
-        $json_response_data = array('return_data' => false);
1725
-        $PAY_ID             = isset($this->_req_data['delete_txn_admin_payment'], $this->_req_data['delete_txn_admin_payment']['PAY_ID']) ? absint($this->_req_data['delete_txn_admin_payment']['PAY_ID']) : 0;
1726
-        if ($PAY_ID) {
1727
-            $delete_txn_reg_status_change = isset($this->_req_data['delete_txn_reg_status_change']) ? $this->_req_data['delete_txn_reg_status_change'] : false;
1728
-            $payment                      = EEM_Payment::instance()->get_one_by_ID($PAY_ID);
1729
-            if ($payment instanceof EE_Payment) {
1730
-                $REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
1731
-                /** @type EE_Transaction_Payments $transaction_payments */
1732
-                $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1733
-                if ($transaction_payments->delete_payment_and_update_transaction($payment)) {
1734
-                    $json_response_data['return_data'] = $this->_build_payment_json_response($payment, $REG_IDs,
1735
-                        $delete_txn_reg_status_change);
1736
-                    if ($delete_txn_reg_status_change) {
1737
-                        $this->_req_data['txn_reg_status_change'] = $delete_txn_reg_status_change;
1738
-                        //MAKE sure we also add the delete_txn_req_status_change to the
1739
-                        //$_REQUEST global because that's how messages will be looking for it.
1740
-                        $_REQUEST['txn_reg_status_change'] = $delete_txn_reg_status_change;
1741
-                        $this->_maybe_send_notifications();
1742
-                        $this->_process_registration_status_change($payment->transaction(), $REG_IDs);
1743
-                    }
1744
-                }
1745
-            } else {
1746
-                EE_Error::add_error(
1747
-                    esc_html__('Valid Payment data could not be retrieved from the database.', 'event_espresso'),
1748
-                    __FILE__, __FUNCTION__, __LINE__
1749
-                );
1750
-            }
1751
-        } else {
1752
-            EE_Error::add_error(
1753
-                esc_html__('A valid Payment ID was not received, therefore payment form data could not be loaded.',
1754
-                    'event_espresso'),
1755
-                __FILE__, __FUNCTION__, __LINE__
1756
-            );
1757
-        }
1758
-        $notices              = EE_Error::get_notices(false, false, false);
1759
-        $this->_template_args = array(
1760
-            'data'      => $json_response_data,
1761
-            'success'   => $notices['success'],
1762
-            'error'     => $notices['errors'],
1763
-            'attention' => $notices['attention'],
1764
-        );
1765
-        $this->_return_json();
1766
-    }
1767
-
1768
-
1769
-    /**
1770
-     * _registration_payment_data_array
1771
-     * adds info for 'owing' and 'paid' for each registration to the json response
1772
-     *
1773
-     * @access protected
1774
-     * @param array $REG_IDs
1775
-     * @return array
1776
-     */
1777
-    protected function _registration_payment_data_array($REG_IDs)
1778
-    {
1779
-        $registration_payment_data = array();
1780
-        //if non empty reg_ids lets get an array of registrations and update the values for the apply_payment/refund rows.
1781
-        if (! empty($REG_IDs)) {
1782
-            $registrations = EEM_Registration::instance()->get_all(array(array('REG_ID' => array('IN', $REG_IDs))));
1783
-            foreach ($registrations as $registration) {
1784
-                if ($registration instanceof EE_Registration) {
1785
-                    $registration_payment_data[$registration->ID()] = array(
1786
-                        'paid'  => $registration->pretty_paid(),
1787
-                        'owing' => EEH_Template::format_currency($registration->final_price() - $registration->paid()),
1788
-                    );
1789
-                }
1790
-            }
1791
-        }
1792
-
1793
-        return $registration_payment_data;
1794
-    }
1795
-
1796
-
1797
-    /**
1798
-     * _maybe_send_notifications
1799
-     * determines whether or not the admin has indicated that notifications should be sent.
1800
-     * If so, will toggle a filter switch for delivering registration notices.
1801
-     * If passed an EE_Payment object, then it will trigger payment notifications instead.
1802
-     *
1803
-     * @access protected
1804
-     * @param \EE_Payment | null $payment
1805
-     */
1806
-    protected function _maybe_send_notifications($payment = null)
1807
-    {
1808
-        switch ($payment instanceof EE_Payment) {
1809
-            // payment notifications
1810
-            case true :
1811
-                if (
1812
-                    isset(
1813
-                        $this->_req_data['txn_payments'],
1814
-                        $this->_req_data['txn_payments']['send_notifications']
1815
-                    ) &&
1816
-                    filter_var($this->_req_data['txn_payments']['send_notifications'], FILTER_VALIDATE_BOOLEAN)
1817
-                ) {
1818
-                    $this->_process_payment_notification($payment);
1819
-                }
1820
-                break;
1821
-            // registration notifications
1822
-            case false :
1823
-                if (
1824
-                    isset(
1825
-                        $this->_req_data['txn_reg_status_change'],
1826
-                        $this->_req_data['txn_reg_status_change']['send_notifications']
1827
-                    ) &&
1828
-                    filter_var($this->_req_data['txn_reg_status_change']['send_notifications'], FILTER_VALIDATE_BOOLEAN)
1829
-                ) {
1830
-                    add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true');
1831
-                }
1832
-                break;
1833
-        }
1834
-    }
1835
-
1836
-
1837
-    /**
1838
-     * _send_payment_reminder
1839
-     *    generates HTML for the View Transaction Details Admin page
1840
-     *
1841
-     * @access protected
1842
-     * @return void
1843
-     */
1844
-    protected function _send_payment_reminder()
1845
-    {
1846
-        $TXN_ID      = (! empty($this->_req_data['TXN_ID'])) ? absint($this->_req_data['TXN_ID']) : false;
1847
-        $transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
1848
-        $query_args  = isset($this->_req_data['redirect_to']) ? array(
1849
-            'action' => $this->_req_data['redirect_to'],
1850
-            'TXN_ID' => $this->_req_data['TXN_ID'],
1851
-        ) : array();
1852
-        do_action('AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
1853
-            $transaction);
1854
-        $this->_redirect_after_action(false, esc_html__('payment reminder', 'event_espresso'),
1855
-            esc_html__('sent', 'event_espresso'), $query_args, true);
1856
-    }
1857
-
1858
-
1859
-    /**
1860
-     *  get_transactions
1861
-     *    get transactions for given parameters (used by list table)
1862
-     *
1863
-     * @param  int     $perpage how many transactions displayed per page
1864
-     * @param  boolean $count   return the count or objects
1865
-     * @param string   $view
1866
-     * @return mixed int = count || array of transaction objects
1867
-     */
1868
-    public function get_transactions($perpage, $count = false, $view = '')
1869
-    {
1870
-
1871
-        $TXN = EEM_Transaction::instance();
1872
-
1873
-        $start_date = isset($this->_req_data['txn-filter-start-date']) ? wp_strip_all_tags($this->_req_data['txn-filter-start-date']) : date('m/d/Y',
1874
-            strtotime('-10 year'));
1875
-        $end_date   = isset($this->_req_data['txn-filter-end-date']) ? wp_strip_all_tags($this->_req_data['txn-filter-end-date']) : date('m/d/Y');
1876
-
1877
-        //make sure our timestamps start and end right at the boundaries for each day
1878
-        $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
1879
-        $end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
1880
-
1881
-
1882
-        //convert to timestamps
1883
-        $start_date = strtotime($start_date);
1884
-        $end_date   = strtotime($end_date);
1885
-
1886
-        //makes sure start date is the lowest value and vice versa
1887
-        $start_date = min($start_date, $end_date);
1888
-        $end_date   = max($start_date, $end_date);
1889
-
1890
-        //convert to correct format for query
1891
-        $start_date = EEM_Transaction::instance()->convert_datetime_for_query('TXN_timestamp',
1892
-            date('Y-m-d H:i:s', $start_date), 'Y-m-d H:i:s');
1893
-        $end_date   = EEM_Transaction::instance()->convert_datetime_for_query('TXN_timestamp',
1894
-            date('Y-m-d H:i:s', $end_date), 'Y-m-d H:i:s');
1895
-
1896
-
1897
-        //set orderby
1898
-        $this->_req_data['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : '';
1899
-
1900
-        switch ($this->_req_data['orderby']) {
1901
-            case 'TXN_ID':
1902
-                $orderby = 'TXN_ID';
1903
-                break;
1904
-            case 'ATT_fname':
1905
-                $orderby = 'Registration.Attendee.ATT_fname';
1906
-                break;
1907
-            case 'event_name':
1908
-                $orderby = 'Registration.Event.EVT_name';
1909
-                break;
1910
-            default: //'TXN_timestamp'
1911
-                $orderby = 'TXN_timestamp';
1912
-        }
1913
-
1914
-        $sort         = (isset($this->_req_data['order']) && ! empty($this->_req_data['order'])) ? $this->_req_data['order'] : 'DESC';
1915
-        $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged']) ? $this->_req_data['paged'] : 1;
1916
-        $per_page     = isset($perpage) && ! empty($perpage) ? $perpage : 10;
1917
-        $per_page     = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage']) ? $this->_req_data['perpage'] : $per_page;
1918
-
1919
-        $offset = ($current_page - 1) * $per_page;
1920
-        $limit  = array($offset, $per_page);
1921
-
1922
-        $_where = array(
1923
-            'TXN_timestamp'          => array('BETWEEN', array($start_date, $end_date)),
1924
-            'Registration.REG_count' => 1,
1925
-        );
1926
-
1927
-        if (isset($this->_req_data['EVT_ID'])) {
1928
-            $_where['Registration.EVT_ID'] = $this->_req_data['EVT_ID'];
1929
-        }
1930
-
1931
-        if (isset($this->_req_data['s'])) {
1932
-            $search_string = '%' . $this->_req_data['s'] . '%';
1933
-            $_where['OR']  = array(
1934
-                'Registration.Event.EVT_name'         => array('LIKE', $search_string),
1935
-                'Registration.Event.EVT_desc'         => array('LIKE', $search_string),
1936
-                'Registration.Event.EVT_short_desc'   => array('LIKE', $search_string),
1937
-                'Registration.Attendee.ATT_full_name' => array('LIKE', $search_string),
1938
-                'Registration.Attendee.ATT_fname'     => array('LIKE', $search_string),
1939
-                'Registration.Attendee.ATT_lname'     => array('LIKE', $search_string),
1940
-                'Registration.Attendee.ATT_short_bio' => array('LIKE', $search_string),
1941
-                'Registration.Attendee.ATT_email'     => array('LIKE', $search_string),
1942
-                'Registration.Attendee.ATT_address'   => array('LIKE', $search_string),
1943
-                'Registration.Attendee.ATT_address2'  => array('LIKE', $search_string),
1944
-                'Registration.Attendee.ATT_city'      => array('LIKE', $search_string),
1945
-                'Registration.REG_final_price'        => array('LIKE', $search_string),
1946
-                'Registration.REG_code'               => array('LIKE', $search_string),
1947
-                'Registration.REG_count'              => array('LIKE', $search_string),
1948
-                'Registration.REG_group_size'         => array('LIKE', $search_string),
1949
-                'Registration.Ticket.TKT_name'        => array('LIKE', $search_string),
1950
-                'Registration.Ticket.TKT_description' => array('LIKE', $search_string),
1951
-                'Payment.PAY_source'                  => array('LIKE', $search_string),
1952
-                'Payment.Payment_Method.PMD_name'     => array('LIKE', $search_string),
1953
-                'TXN_session_data'                    => array('LIKE', $search_string),
1954
-                'Payment.PAY_txn_id_chq_nmbr'         => array('LIKE', $search_string),
1955
-            );
1956
-        }
1957
-
1958
-        //failed transactions
1959
-        $failed    = (! empty($this->_req_data['status']) && $this->_req_data['status'] == 'failed' && ! $count) || ($count && $view == 'failed') ? true : false;
1960
-        $abandoned = (! empty($this->_req_data['status']) && $this->_req_data['status'] == 'abandoned' && ! $count) || ($count && $view == 'abandoned') ? true : false;
1961
-
1962
-        if ($failed) {
1963
-            $_where['STS_ID'] = EEM_Transaction::failed_status_code;
1964
-        } else if ($abandoned) {
1965
-            $_where['STS_ID'] = EEM_Transaction::abandoned_status_code;
1966
-        } else {
1967
-            $_where['STS_ID']  = array('!=', EEM_Transaction::failed_status_code);
1968
-            $_where['STS_ID*'] = array('!=', EEM_Transaction::abandoned_status_code);
1969
-        }
1970
-
1971
-        $query_params = array(
1972
-            $_where,
1973
-            'order_by'                 => array($orderby => $sort),
1974
-            'limit'                    => $limit,
1975
-            'default_where_conditions' => EEM_Base::default_where_conditions_this_only,
1976
-        );
1977
-
1978
-        $transactions = $count ? $TXN->count(array($_where), 'TXN_ID', true) : $TXN->get_all($query_params);
1979
-
1980
-
1981
-        return $transactions;
1982
-
1983
-    }
809
+		// process payment details
810
+		$payments = $this->_transaction->get_many_related('Payment');
811
+		if (! empty($payments)) {
812
+			$this->_template_args['payments']              = $payments;
813
+			$this->_template_args['existing_reg_payments'] = $this->_get_registration_payment_IDs($payments);
814
+		} else {
815
+			$this->_template_args['payments']              = false;
816
+			$this->_template_args['existing_reg_payments'] = array();
817
+		}
818
+
819
+		$this->_template_args['edit_payment_url']   = add_query_arg(array('action' => 'edit_payment'), TXN_ADMIN_URL);
820
+		$this->_template_args['delete_payment_url'] = add_query_arg(array('action' => 'espresso_delete_payment'),
821
+			TXN_ADMIN_URL);
822
+
823
+		if (isset($txn_details['invoice_number'])) {
824
+			$this->_template_args['txn_details']['invoice_number']['value'] = $this->_template_args['REG_code'];
825
+			$this->_template_args['txn_details']['invoice_number']['label'] = esc_html__('Invoice Number',
826
+				'event_espresso');
827
+		}
828
+
829
+		$this->_template_args['txn_details']['registration_session']['value'] = $this->_transaction->get_first_related('Registration')->get('REG_session');
830
+		$this->_template_args['txn_details']['registration_session']['label'] = esc_html__('Registration Session',
831
+			'event_espresso');
832
+
833
+		$this->_template_args['txn_details']['ip_address']['value'] = isset($this->_session['ip_address']) ? $this->_session['ip_address'] : '';
834
+		$this->_template_args['txn_details']['ip_address']['label'] = esc_html__('Transaction placed from IP',
835
+			'event_espresso');
836
+
837
+		$this->_template_args['txn_details']['user_agent']['value'] = isset($this->_session['user_agent']) ? $this->_session['user_agent'] : '';
838
+		$this->_template_args['txn_details']['user_agent']['label'] = esc_html__('Registrant User Agent',
839
+			'event_espresso');
840
+
841
+		$reg_steps = '<ul>';
842
+		foreach ($this->_transaction->reg_steps() as $reg_step => $reg_step_status) {
843
+			if ($reg_step_status === true) {
844
+				$reg_steps .= '<li style="color:#70cc50">' . sprintf(esc_html__('%1$s : Completed', 'event_espresso'),
845
+						ucwords(str_replace('_', ' ', $reg_step))) . '</li>';
846
+			} else if (is_numeric($reg_step_status) && $reg_step_status !== false) {
847
+				$reg_steps .= '<li style="color:#2EA2CC">' . sprintf(
848
+						esc_html__('%1$s : Initiated %2$s', 'event_espresso'),
849
+						ucwords(str_replace('_', ' ', $reg_step)),
850
+						date(get_option('date_format') . ' ' . get_option('time_format'),
851
+							($reg_step_status + (get_option('gmt_offset') * HOUR_IN_SECONDS)))
852
+					) . '</li>';
853
+			} else {
854
+				$reg_steps .= '<li style="color:#E76700">' . sprintf(esc_html__('%1$s : Never Initiated',
855
+						'event_espresso'), ucwords(str_replace('_', ' ', $reg_step))) . '</li>';
856
+			}
857
+		}
858
+		$reg_steps                                                 .= '</ul>';
859
+		$this->_template_args['txn_details']['reg_steps']['value'] = $reg_steps;
860
+		$this->_template_args['txn_details']['reg_steps']['label'] = esc_html__('Registration Step Progress',
861
+			'event_espresso');
862
+
863
+
864
+		$this->_get_registrations_to_apply_payment_to();
865
+		$this->_get_payment_methods($payments);
866
+		$this->_get_payment_status_array();
867
+		$this->_get_reg_status_selection(); //sets up the template args for the reg status array for the transaction.
868
+
869
+		$this->_template_args['transaction_form_url']    = add_query_arg(array(
870
+			'action'  => 'edit_transaction',
871
+			'process' => 'transaction',
872
+		), TXN_ADMIN_URL);
873
+		$this->_template_args['apply_payment_form_url']  = add_query_arg(array(
874
+			'page'   => 'espresso_transactions',
875
+			'action' => 'espresso_apply_payment',
876
+		), WP_AJAX_URL);
877
+		$this->_template_args['delete_payment_form_url'] = add_query_arg(array(
878
+			'page'   => 'espresso_transactions',
879
+			'action' => 'espresso_delete_payment',
880
+		), WP_AJAX_URL);
881
+
882
+		// 'espresso_delete_payment_nonce'
883
+
884
+		$template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_txn_details.template.php';
885
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
886
+
887
+	}
888
+
889
+
890
+	/**
891
+	 * _get_registration_payment_IDs
892
+	 *    generates an array of Payment IDs and their corresponding Registration IDs
893
+	 *
894
+	 * @access protected
895
+	 * @param EE_Payment[] $payments
896
+	 * @return array
897
+	 */
898
+	protected function _get_registration_payment_IDs($payments = array())
899
+	{
900
+		$existing_reg_payments = array();
901
+		// get all reg payments for these payments
902
+		$reg_payments = EEM_Registration_Payment::instance()->get_all(array(
903
+			array(
904
+				'PAY_ID' => array(
905
+					'IN',
906
+					array_keys($payments),
907
+				),
908
+			),
909
+		));
910
+		if (! empty($reg_payments)) {
911
+			foreach ($payments as $payment) {
912
+				if (! $payment instanceof EE_Payment) {
913
+					continue;
914
+				} else if (! isset($existing_reg_payments[$payment->ID()])) {
915
+					$existing_reg_payments[$payment->ID()] = array();
916
+				}
917
+				foreach ($reg_payments as $reg_payment) {
918
+					if ($reg_payment instanceof EE_Registration_Payment && $reg_payment->payment_ID() === $payment->ID()) {
919
+						$existing_reg_payments[$payment->ID()][] = $reg_payment->registration_ID();
920
+					}
921
+				}
922
+			}
923
+		}
924
+
925
+		return $existing_reg_payments;
926
+	}
927
+
928
+
929
+	/**
930
+	 * _get_registrations_to_apply_payment_to
931
+	 *    generates HTML for displaying a series of checkboxes in the admin payment modal window
932
+	 * which allows the admin to only apply the payment to the specific registrations
933
+	 *
934
+	 * @access protected
935
+	 * @return void
936
+	 * @throws \EE_Error
937
+	 */
938
+	protected function _get_registrations_to_apply_payment_to()
939
+	{
940
+		// we want any registration with an active status (ie: not deleted or cancelled)
941
+		$query_params                      = array(
942
+			array(
943
+				'STS_ID' => array(
944
+					'IN',
945
+					array(
946
+						EEM_Registration::status_id_approved,
947
+						EEM_Registration::status_id_pending_payment,
948
+						EEM_Registration::status_id_not_approved,
949
+					),
950
+				),
951
+			),
952
+		);
953
+		$registrations_to_apply_payment_to = EEH_HTML::br() . EEH_HTML::div(
954
+				'', 'txn-admin-apply-payment-to-registrations-dv', '', 'clear: both; margin: 1.5em 0 0; display: none;'
955
+			);
956
+		$registrations_to_apply_payment_to .= EEH_HTML::br() . EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
957
+		$registrations_to_apply_payment_to .= EEH_HTML::table('', '', 'admin-primary-mbox-tbl');
958
+		$registrations_to_apply_payment_to .= EEH_HTML::thead(
959
+			EEH_HTML::tr(
960
+				EEH_HTML::th(esc_html__('ID', 'event_espresso')) .
961
+				EEH_HTML::th(esc_html__('Registrant', 'event_espresso')) .
962
+				EEH_HTML::th(esc_html__('Ticket', 'event_espresso')) .
963
+				EEH_HTML::th(esc_html__('Event', 'event_espresso')) .
964
+				EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr') .
965
+				EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr') .
966
+				EEH_HTML::th(esc_html__('Apply', 'event_espresso'), '', 'jst-cntr')
967
+			)
968
+		);
969
+		$registrations_to_apply_payment_to .= EEH_HTML::tbody();
970
+		// get registrations for TXN
971
+		$registrations = $this->_transaction->registrations($query_params);
972
+		foreach ($registrations as $registration) {
973
+			if ($registration instanceof EE_Registration) {
974
+				$attendee_name                     = $registration->attendee() instanceof EE_Attendee
975
+					? $registration->attendee()->full_name()
976
+					: esc_html__('Unknown Attendee', 'event_espresso');
977
+				$owing                             = $registration->final_price() - $registration->paid();
978
+				$taxable                           = $registration->ticket()->taxable()
979
+					? ' <span class="smaller-text lt-grey-text"> ' . esc_html__('+ tax', 'event_espresso') . '</span>'
980
+					: '';
981
+				$checked                           = empty($existing_reg_payments) || in_array($registration->ID(),
982
+					$existing_reg_payments)
983
+					? ' checked="checked"'
984
+					: '';
985
+				$disabled                          = $registration->final_price() > 0 ? '' : ' disabled';
986
+				$registrations_to_apply_payment_to .= EEH_HTML::tr(
987
+					EEH_HTML::td($registration->ID()) .
988
+					EEH_HTML::td($attendee_name) .
989
+					EEH_HTML::td(
990
+						$registration->ticket()->name() . ' : ' . $registration->ticket()->pretty_price() . $taxable
991
+					) .
992
+					EEH_HTML::td($registration->event_name()) .
993
+					EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr') .
994
+					EEH_HTML::td(EEH_Template::format_currency($owing), '', 'txn-admin-payment-owing-td jst-cntr') .
995
+					EEH_HTML::td(
996
+						'<input type="checkbox" value="' . $registration->ID()
997
+						. '" name="txn_admin_payment[registrations]"'
998
+						. $checked . $disabled . '>',
999
+						'', 'jst-cntr'
1000
+					),
1001
+					'apply-payment-registration-row-' . $registration->ID()
1002
+				);
1003
+			}
1004
+		}
1005
+		$registrations_to_apply_payment_to                         .= EEH_HTML::tbodyx();
1006
+		$registrations_to_apply_payment_to                         .= EEH_HTML::tablex();
1007
+		$registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1008
+		$registrations_to_apply_payment_to                         .= EEH_HTML::p(
1009
+			esc_html__(
1010
+				'The payment will only be applied to the registrations that have a check mark in their corresponding check box. Checkboxes for free registrations have been disabled.',
1011
+				'event_espresso'
1012
+			),
1013
+			'', 'clear description'
1014
+		);
1015
+		$registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1016
+		$this->_template_args['registrations_to_apply_payment_to'] = $registrations_to_apply_payment_to;
1017
+	}
1018
+
1019
+
1020
+	/**
1021
+	 * _get_reg_status_selection
1022
+	 *
1023
+	 * @todo   this will need to be adjusted either once MER comes along OR we move default reg status to tickets
1024
+	 *         instead of events.
1025
+	 * @access protected
1026
+	 * @return void
1027
+	 */
1028
+	protected function _get_reg_status_selection()
1029
+	{
1030
+		//first get all possible statuses
1031
+		$statuses = EEM_Registration::reg_status_array(array(), true);
1032
+		//let's add a "don't change" option.
1033
+		$status_array['NAN']                                 = esc_html__('Leave the Same', 'event_espresso');
1034
+		$status_array                                        = array_merge($status_array, $statuses);
1035
+		$this->_template_args['status_change_select']        = EEH_Form_Fields::select_input('txn_reg_status_change[reg_status]',
1036
+			$status_array, 'NAN', 'id="txn-admin-payment-reg-status-inp"', 'txn-reg-status-change-reg-status');
1037
+		$this->_template_args['delete_status_change_select'] = EEH_Form_Fields::select_input('delete_txn_reg_status_change[reg_status]',
1038
+			$status_array, 'NAN', 'delete-txn-admin-payment-reg-status-inp', 'delete-txn-reg-status-change-reg-status');
1039
+
1040
+	}
1041
+
1042
+
1043
+	/**
1044
+	 *    _get_payment_methods
1045
+	 * Gets all the payment methods available generally, or the ones that are already
1046
+	 * selected on these payments (in case their payment methods are no longer active).
1047
+	 * Has the side-effect of updating the template args' payment_methods item
1048
+	 *
1049
+	 * @access private
1050
+	 * @param EE_Payment[] to show on this page
1051
+	 * @return void
1052
+	 */
1053
+	private function _get_payment_methods($payments = array())
1054
+	{
1055
+		$payment_methods_of_payments = array();
1056
+		foreach ($payments as $payment) {
1057
+			if ($payment instanceof EE_Payment) {
1058
+				$payment_methods_of_payments[] = $payment->get('PMD_ID');
1059
+			}
1060
+		}
1061
+		if ($payment_methods_of_payments) {
1062
+			$query_args = array(
1063
+				array(
1064
+					'OR*payment_method_for_payment' => array(
1065
+						'PMD_ID'    => array('IN', $payment_methods_of_payments),
1066
+						'PMD_scope' => array('LIKE', '%' . EEM_Payment_Method::scope_admin . '%'),
1067
+					),
1068
+				),
1069
+			);
1070
+		} else {
1071
+			$query_args = array(array('PMD_scope' => array('LIKE', '%' . EEM_Payment_Method::scope_admin . '%')));
1072
+		}
1073
+		$this->_template_args['payment_methods'] = EEM_Payment_Method::instance()->get_all($query_args);
1074
+	}
1075
+
1076
+
1077
+	/**
1078
+	 * txn_attendees_meta_box
1079
+	 *    generates HTML for the Attendees Transaction main meta box
1080
+	 *
1081
+	 * @access public
1082
+	 * @param WP_Post $post
1083
+	 * @param array   $metabox
1084
+	 * @return void
1085
+	 */
1086
+	public function txn_attendees_meta_box($post, $metabox = array('args' => array()))
1087
+	{
1088
+
1089
+		extract($metabox['args']);
1090
+		$this->_template_args['post']            = $post;
1091
+		$this->_template_args['event_attendees'] = array();
1092
+		// process items in cart
1093
+		$line_items = $this->_transaction->get_many_related('Line_Item', array(array('LIN_type' => 'line-item')));
1094
+		if (! empty($line_items)) {
1095
+			foreach ($line_items as $item) {
1096
+				if ($item instanceof EE_Line_Item) {
1097
+					switch ($item->OBJ_type()) {
1098
+
1099
+						case 'Event' :
1100
+							break;
1101
+
1102
+						case 'Ticket' :
1103
+							$ticket = $item->ticket();
1104
+							//right now we're only handling tickets here.  Cause its expected that only tickets will have attendees right?
1105
+							if (! $ticket instanceof EE_Ticket) {
1106
+								continue;
1107
+							}
1108
+							try {
1109
+								$event_name = $ticket->get_event_name();
1110
+							} catch (Exception $e) {
1111
+								EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1112
+								$event_name = esc_html__('Unknown Event', 'event_espresso');
1113
+							}
1114
+							$event_name   .= ' - ' . $item->get('LIN_name');
1115
+							$ticket_price = EEH_Template::format_currency($item->get('LIN_unit_price'));
1116
+							// now get all of the registrations for this transaction that use this ticket
1117
+							$registrations = $ticket->get_many_related('Registration',
1118
+								array(array('TXN_ID' => $this->_transaction->ID())));
1119
+							foreach ($registrations as $registration) {
1120
+								if (! $registration instanceof EE_Registration) {
1121
+									continue;
1122
+								}
1123
+								$this->_template_args['event_attendees'][$registration->ID()]['STS_ID']            = $registration->status_ID();
1124
+								$this->_template_args['event_attendees'][$registration->ID()]['att_num']           = $registration->count();
1125
+								$this->_template_args['event_attendees'][$registration->ID()]['event_ticket_name'] = $event_name;
1126
+								$this->_template_args['event_attendees'][$registration->ID()]['ticket_price']      = $ticket_price;
1127
+								// attendee info
1128
+								$attendee = $registration->get_first_related('Attendee');
1129
+								if ($attendee instanceof EE_Attendee) {
1130
+									$this->_template_args['event_attendees'][$registration->ID()]['att_id']   = $attendee->ID();
1131
+									$this->_template_args['event_attendees'][$registration->ID()]['attendee'] = $attendee->full_name();
1132
+									$this->_template_args['event_attendees'][$registration->ID()]['email']    = '<a href="mailto:' . $attendee->email() . '?subject=' . $event_name . esc_html__(' Event',
1133
+											'event_espresso') . '">' . $attendee->email() . '</a>';
1134
+									$this->_template_args['event_attendees'][$registration->ID()]['address']  = EEH_Address::format($attendee,
1135
+										'inline', false, false);
1136
+								} else {
1137
+									$this->_template_args['event_attendees'][$registration->ID()]['att_id']   = '';
1138
+									$this->_template_args['event_attendees'][$registration->ID()]['attendee'] = '';
1139
+									$this->_template_args['event_attendees'][$registration->ID()]['email']    = '';
1140
+									$this->_template_args['event_attendees'][$registration->ID()]['address']  = '';
1141
+								}
1142
+							}
1143
+							break;
1144
+
1145
+					}
1146
+				}
1147
+			}
1148
+
1149
+			$this->_template_args['transaction_form_url'] = add_query_arg(array(
1150
+				'action'  => 'edit_transaction',
1151
+				'process' => 'attendees',
1152
+			), TXN_ADMIN_URL);
1153
+			echo EEH_Template::display_template(TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_attendees.template.php',
1154
+				$this->_template_args, true);
1155
+
1156
+		} else {
1157
+			echo sprintf(
1158
+				esc_html__('%1$sFor some reason, there are no attendees registered for this transaction. Likely the registration was abandoned in process.%2$s',
1159
+					'event_espresso'),
1160
+				'<p class="important-notice">',
1161
+				'</p>'
1162
+			);
1163
+		}
1164
+	}
1165
+
1166
+
1167
+	/**
1168
+	 * txn_registrant_side_meta_box
1169
+	 * generates HTML for the Edit Transaction side meta box
1170
+	 *
1171
+	 * @access public
1172
+	 * @throws \EE_Error
1173
+	 * @return void
1174
+	 */
1175
+	public function txn_registrant_side_meta_box()
1176
+	{
1177
+		$primary_att = $this->_transaction->primary_registration() instanceof EE_Registration ? $this->_transaction->primary_registration()->get_first_related('Attendee') : null;
1178
+		if (! $primary_att instanceof EE_Attendee) {
1179
+			$this->_template_args['no_attendee_message'] = esc_html__('There is no attached contact for this transaction.  The transaction either failed due to an error or was abandoned.',
1180
+				'event_espresso');
1181
+			$primary_att                                 = EEM_Attendee::instance()->create_default_object();
1182
+		}
1183
+		$this->_template_args['ATT_ID']            = $primary_att->ID();
1184
+		$this->_template_args['prime_reg_fname']   = $primary_att->fname();
1185
+		$this->_template_args['prime_reg_lname']   = $primary_att->lname();
1186
+		$this->_template_args['prime_reg_email']   = $primary_att->email();
1187
+		$this->_template_args['prime_reg_phone']   = $primary_att->phone();
1188
+		$this->_template_args['edit_attendee_url'] = EE_Admin_Page::add_query_args_and_nonce(array(
1189
+			'action' => 'edit_attendee',
1190
+			'post'   => $primary_att->ID(),
1191
+		), REG_ADMIN_URL);
1192
+		// get formatted address for registrant
1193
+		$this->_template_args['formatted_address'] = EEH_Address::format($primary_att);
1194
+		echo EEH_Template::display_template(TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_registrant.template.php',
1195
+			$this->_template_args, true);
1196
+	}
1197
+
1198
+
1199
+	/**
1200
+	 * txn_billing_info_side_meta_box
1201
+	 *    generates HTML for the Edit Transaction side meta box
1202
+	 *
1203
+	 * @access public
1204
+	 * @return void
1205
+	 */
1206
+	public function txn_billing_info_side_meta_box()
1207
+	{
1208
+
1209
+		$this->_template_args['billing_form']     = $this->_transaction->billing_info();
1210
+		$this->_template_args['billing_form_url'] = add_query_arg(
1211
+			array('action' => 'edit_transaction', 'process' => 'billing'),
1212
+			TXN_ADMIN_URL
1213
+		);
1214
+
1215
+		$template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_billing_info.template.php';
1216
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);/**/
1217
+	}
1218
+
1219
+
1220
+	/**
1221
+	 * apply_payments_or_refunds
1222
+	 *    registers a payment or refund made towards a transaction
1223
+	 *
1224
+	 * @access public
1225
+	 * @return void
1226
+	 */
1227
+	public function apply_payments_or_refunds()
1228
+	{
1229
+		$json_response_data = array('return_data' => false);
1230
+		$valid_data         = $this->_validate_payment_request_data();
1231
+		if (! empty($valid_data)
1232
+
1233
+		) {
1234
+			$PAY_ID = $valid_data['PAY_ID'];
1235
+			//save  the new payment
1236
+			$payment = $this->_create_payment_from_request_data($valid_data);
1237
+			// get the TXN for this payment
1238
+			$transaction = $payment->transaction();
1239
+			// verify transaction
1240
+			if ($transaction instanceof EE_Transaction) {
1241
+				// calculate_total_payments_and_update_status
1242
+				$this->_process_transaction_payments($transaction);
1243
+				$REG_IDs = $this->_get_REG_IDs_to_apply_payment_to($payment);
1244
+				$this->_remove_existing_registration_payments($payment, $PAY_ID);
1245
+				// apply payment to registrations (if applicable)
1246
+				if (! empty($REG_IDs)) {
1247
+					$this->_update_registration_payments($transaction, $payment, $REG_IDs);
1248
+					$this->_maybe_send_notifications();
1249
+					// now process status changes for the same registrations
1250
+					$this->_process_registration_status_change($transaction, $REG_IDs);
1251
+				}
1252
+				$this->_maybe_send_notifications($payment);
1253
+				//prepare to render page
1254
+				$json_response_data['return_data'] = $this->_build_payment_json_response($payment, $REG_IDs);
1255
+				do_action('AHEE__Transactions_Admin_Page__apply_payments_or_refund__after_recording', $transaction,
1256
+					$payment);
1257
+			} else {
1258
+				EE_Error::add_error(
1259
+					esc_html__('A valid Transaction for this payment could not be retrieved.', 'event_espresso'),
1260
+					__FILE__, __FUNCTION__, __LINE__
1261
+				);
1262
+			}
1263
+		} else {
1264
+			EE_Error::add_error(esc_html__('The payment form data could not be processed. Please try again.',
1265
+				'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
1266
+		}
1267
+
1268
+		$notices              = EE_Error::get_notices(false, false, false);
1269
+		$this->_template_args = array(
1270
+			'data'    => $json_response_data,
1271
+			'error'   => $notices['errors'],
1272
+			'success' => $notices['success'],
1273
+		);
1274
+		$this->_return_json();
1275
+	}
1276
+
1277
+
1278
+	/**
1279
+	 * _validate_payment_request_data
1280
+	 *
1281
+	 * @return array
1282
+	 */
1283
+	protected function _validate_payment_request_data()
1284
+	{
1285
+		if (! isset($this->_req_data['txn_admin_payment'])) {
1286
+			return false;
1287
+		}
1288
+		$payment_form = $this->_generate_payment_form_section();
1289
+		try {
1290
+			if ($payment_form->was_submitted()) {
1291
+				$payment_form->receive_form_submission();
1292
+				if (! $payment_form->is_valid()) {
1293
+					$submission_error_messages = array();
1294
+					foreach ($payment_form->get_validation_errors_accumulated() as $validation_error) {
1295
+						if ($validation_error instanceof EE_Validation_Error) {
1296
+							$submission_error_messages[] = sprintf(
1297
+								_x('%s : %s', 'Form Section Name : Form Validation Error', 'event_espresso'),
1298
+								$validation_error->get_form_section()->html_label_text(),
1299
+								$validation_error->getMessage()
1300
+							);
1301
+						}
1302
+					}
1303
+					EE_Error::add_error(join('<br />', $submission_error_messages), __FILE__, __FUNCTION__, __LINE__);
1304
+
1305
+					return array();
1306
+				}
1307
+			}
1308
+		} catch (EE_Error $e) {
1309
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1310
+
1311
+			return array();
1312
+		}
1313
+
1314
+		return $payment_form->valid_data();
1315
+	}
1316
+
1317
+
1318
+	/**
1319
+	 * _generate_payment_form_section
1320
+	 *
1321
+	 * @return EE_Form_Section_Proper
1322
+	 */
1323
+	protected function _generate_payment_form_section()
1324
+	{
1325
+		return new EE_Form_Section_Proper(
1326
+			array(
1327
+				'name'        => 'txn_admin_payment',
1328
+				'subsections' => array(
1329
+					'PAY_ID'          => new EE_Text_Input(
1330
+						array(
1331
+							'default'               => 0,
1332
+							'required'              => false,
1333
+							'html_label_text'       => esc_html__('Payment ID', 'event_espresso'),
1334
+							'validation_strategies' => array(new EE_Int_Normalization()),
1335
+						)
1336
+					),
1337
+					'TXN_ID'          => new EE_Text_Input(
1338
+						array(
1339
+							'default'               => 0,
1340
+							'required'              => true,
1341
+							'html_label_text'       => esc_html__('Transaction ID', 'event_espresso'),
1342
+							'validation_strategies' => array(new EE_Int_Normalization()),
1343
+						)
1344
+					),
1345
+					'type'            => new EE_Text_Input(
1346
+						array(
1347
+							'default'               => 1,
1348
+							'required'              => true,
1349
+							'html_label_text'       => esc_html__('Payment or Refund', 'event_espresso'),
1350
+							'validation_strategies' => array(new EE_Int_Normalization()),
1351
+						)
1352
+					),
1353
+					'amount'          => new EE_Text_Input(
1354
+						array(
1355
+							'default'               => 0,
1356
+							'required'              => true,
1357
+							'html_label_text'       => esc_html__('Payment amount', 'event_espresso'),
1358
+							'validation_strategies' => array(new EE_Float_Normalization()),
1359
+						)
1360
+					),
1361
+					'status'          => new EE_Text_Input(
1362
+						array(
1363
+							'default'         => EEM_Payment::status_id_approved,
1364
+							'required'        => true,
1365
+							'html_label_text' => esc_html__('Payment status', 'event_espresso'),
1366
+						)
1367
+					),
1368
+					'PMD_ID'          => new EE_Text_Input(
1369
+						array(
1370
+							'default'               => 2,
1371
+							'required'              => true,
1372
+							'html_label_text'       => esc_html__('Payment Method', 'event_espresso'),
1373
+							'validation_strategies' => array(new EE_Int_Normalization()),
1374
+						)
1375
+					),
1376
+					'date'            => new EE_Text_Input(
1377
+						array(
1378
+							'default'         => time(),
1379
+							'required'        => true,
1380
+							'html_label_text' => esc_html__('Payment date', 'event_espresso'),
1381
+						)
1382
+					),
1383
+					'txn_id_chq_nmbr' => new EE_Text_Input(
1384
+						array(
1385
+							'default'               => '',
1386
+							'required'              => false,
1387
+							'html_label_text'       => esc_html__('Transaction or Cheque Number', 'event_espresso'),
1388
+							'validation_strategies' => array(
1389
+								new EE_Max_Length_Validation_Strategy(esc_html__('Input too long', 'event_espresso'),
1390
+									100),
1391
+							),
1392
+						)
1393
+					),
1394
+					'po_number'       => new EE_Text_Input(
1395
+						array(
1396
+							'default'               => '',
1397
+							'required'              => false,
1398
+							'html_label_text'       => esc_html__('Purchase Order Number', 'event_espresso'),
1399
+							'validation_strategies' => array(
1400
+								new EE_Max_Length_Validation_Strategy(esc_html__('Input too long', 'event_espresso'),
1401
+									100),
1402
+							),
1403
+						)
1404
+					),
1405
+					'accounting'      => new EE_Text_Input(
1406
+						array(
1407
+							'default'               => '',
1408
+							'required'              => false,
1409
+							'html_label_text'       => esc_html__('Extra Field for Accounting', 'event_espresso'),
1410
+							'validation_strategies' => array(
1411
+								new EE_Max_Length_Validation_Strategy(esc_html__('Input too long', 'event_espresso'),
1412
+									100),
1413
+							),
1414
+						)
1415
+					),
1416
+				),
1417
+			)
1418
+		);
1419
+	}
1420
+
1421
+
1422
+	/**
1423
+	 * _create_payment_from_request_data
1424
+	 *
1425
+	 * @param array $valid_data
1426
+	 * @return EE_Payment
1427
+	 */
1428
+	protected function _create_payment_from_request_data($valid_data)
1429
+	{
1430
+		$PAY_ID = $valid_data['PAY_ID'];
1431
+		// get payment amount
1432
+		$amount = $valid_data['amount'] ? abs($valid_data['amount']) : 0;
1433
+		// payments have a type value of 1 and refunds have a type value of -1
1434
+		// so multiplying amount by type will give a positive value for payments, and negative values for refunds
1435
+		$amount = $valid_data['type'] < 0 ? $amount * -1 : $amount;
1436
+		// for some reason the date string coming in has extra spaces between the date and time.  This fixes that.
1437
+		$date    = $valid_data['date'] ? preg_replace('/\s+/', ' ', $valid_data['date']) : date('Y-m-d g:i a',
1438
+			current_time('timestamp'));
1439
+		$payment = EE_Payment::new_instance(
1440
+			array(
1441
+				'TXN_ID'              => $valid_data['TXN_ID'],
1442
+				'STS_ID'              => $valid_data['status'],
1443
+				'PAY_timestamp'       => $date,
1444
+				'PAY_source'          => EEM_Payment_Method::scope_admin,
1445
+				'PMD_ID'              => $valid_data['PMD_ID'],
1446
+				'PAY_amount'          => $amount,
1447
+				'PAY_txn_id_chq_nmbr' => $valid_data['txn_id_chq_nmbr'],
1448
+				'PAY_po_number'       => $valid_data['po_number'],
1449
+				'PAY_extra_accntng'   => $valid_data['accounting'],
1450
+				'PAY_details'         => $valid_data,
1451
+				'PAY_ID'              => $PAY_ID,
1452
+			),
1453
+			'',
1454
+			array('Y-m-d', 'g:i a')
1455
+		);
1456
+
1457
+		if (! $payment->save()) {
1458
+			EE_Error::add_error(
1459
+				sprintf(
1460
+					esc_html__('Payment %1$d has not been successfully saved to the database.', 'event_espresso'),
1461
+					$payment->ID()
1462
+				),
1463
+				__FILE__, __FUNCTION__, __LINE__
1464
+			);
1465
+		}
1466
+
1467
+		return $payment;
1468
+	}
1469
+
1470
+
1471
+	/**
1472
+	 * _process_transaction_payments
1473
+	 *
1474
+	 * @param \EE_Transaction $transaction
1475
+	 * @return array
1476
+	 */
1477
+	protected function _process_transaction_payments(EE_Transaction $transaction)
1478
+	{
1479
+		/** @type EE_Transaction_Payments $transaction_payments */
1480
+		$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1481
+		//update the transaction with this payment
1482
+		if ($transaction_payments->calculate_total_payments_and_update_status($transaction)) {
1483
+			EE_Error::add_success(esc_html__('The payment has been processed successfully.', 'event_espresso'),
1484
+				__FILE__, __FUNCTION__, __LINE__);
1485
+		} else {
1486
+			EE_Error::add_error(
1487
+				esc_html__('The payment was processed successfully but the amount paid for the transaction was not updated.',
1488
+					'event_espresso')
1489
+				, __FILE__, __FUNCTION__, __LINE__
1490
+			);
1491
+		}
1492
+	}
1493
+
1494
+
1495
+	/**
1496
+	 * _get_REG_IDs_to_apply_payment_to
1497
+	 * returns a list of registration IDs that the payment will apply to
1498
+	 *
1499
+	 * @param \EE_Payment $payment
1500
+	 * @return array
1501
+	 */
1502
+	protected function _get_REG_IDs_to_apply_payment_to(EE_Payment $payment)
1503
+	{
1504
+		$REG_IDs = array();
1505
+		// grab array of IDs for specific registrations to apply changes to
1506
+		if (isset($this->_req_data['txn_admin_payment']['registrations'])) {
1507
+			$REG_IDs = (array)$this->_req_data['txn_admin_payment']['registrations'];
1508
+		}
1509
+		//nothing specified ? then get all reg IDs
1510
+		if (empty($REG_IDs)) {
1511
+			$registrations = $payment->transaction()->registrations();
1512
+			$REG_IDs       = ! empty($registrations) ? array_keys($registrations) : $this->_get_existing_reg_payment_REG_IDs($payment);
1513
+		}
1514
+
1515
+		// ensure that REG_IDs are integers and NOT strings
1516
+		return array_map('intval', $REG_IDs);
1517
+	}
1518
+
1519
+
1520
+	/**
1521
+	 * @return array
1522
+	 */
1523
+	public function existing_reg_payment_REG_IDs()
1524
+	{
1525
+		return $this->_existing_reg_payment_REG_IDs;
1526
+	}
1527
+
1528
+
1529
+	/**
1530
+	 * @param array $existing_reg_payment_REG_IDs
1531
+	 */
1532
+	public function set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs = null)
1533
+	{
1534
+		$this->_existing_reg_payment_REG_IDs = $existing_reg_payment_REG_IDs;
1535
+	}
1536
+
1537
+
1538
+	/**
1539
+	 * _get_existing_reg_payment_REG_IDs
1540
+	 * returns a list of registration IDs that the payment is currently related to
1541
+	 * as recorded in the database
1542
+	 *
1543
+	 * @param \EE_Payment $payment
1544
+	 * @return array
1545
+	 */
1546
+	protected function _get_existing_reg_payment_REG_IDs(EE_Payment $payment)
1547
+	{
1548
+		if ($this->existing_reg_payment_REG_IDs() === null) {
1549
+			// let's get any existing reg payment records for this payment
1550
+			$existing_reg_payment_REG_IDs = $payment->get_many_related('Registration');
1551
+			// but we only want the REG IDs, so grab the array keys
1552
+			$existing_reg_payment_REG_IDs = ! empty($existing_reg_payment_REG_IDs) ? array_keys($existing_reg_payment_REG_IDs) : array();
1553
+			$this->set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs);
1554
+		}
1555
+
1556
+		return $this->existing_reg_payment_REG_IDs();
1557
+	}
1558
+
1559
+
1560
+	/**
1561
+	 * _remove_existing_registration_payments
1562
+	 * this calculates the difference between existing relations
1563
+	 * to the supplied payment and the new list registration IDs,
1564
+	 * removes any related registrations that no longer apply,
1565
+	 * and then updates the registration paid fields
1566
+	 *
1567
+	 * @param \EE_Payment $payment
1568
+	 * @param int         $PAY_ID
1569
+	 * @return bool;
1570
+	 */
1571
+	protected function _remove_existing_registration_payments(EE_Payment $payment, $PAY_ID = 0)
1572
+	{
1573
+		// newly created payments will have nothing recorded for $PAY_ID
1574
+		if ($PAY_ID == 0) {
1575
+			return false;
1576
+		}
1577
+		$existing_reg_payment_REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
1578
+		if (empty($existing_reg_payment_REG_IDs)) {
1579
+			return false;
1580
+		}
1581
+		/** @type EE_Transaction_Payments $transaction_payments */
1582
+		$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1583
+
1584
+		return $transaction_payments->delete_registration_payments_and_update_registrations(
1585
+			$payment,
1586
+			array(
1587
+				array(
1588
+					'PAY_ID' => $payment->ID(),
1589
+					'REG_ID' => array('IN', $existing_reg_payment_REG_IDs),
1590
+				),
1591
+			)
1592
+		);
1593
+	}
1594
+
1595
+
1596
+	/**
1597
+	 * _update_registration_payments
1598
+	 * this applies the payments to the selected registrations
1599
+	 * but only if they have not already been paid for
1600
+	 *
1601
+	 * @param  EE_Transaction $transaction
1602
+	 * @param \EE_Payment     $payment
1603
+	 * @param array           $REG_IDs
1604
+	 * @return bool
1605
+	 */
1606
+	protected function _update_registration_payments(
1607
+		EE_Transaction $transaction,
1608
+		EE_Payment $payment,
1609
+		$REG_IDs = array()
1610
+	) {
1611
+		// we can pass our own custom set of registrations to EE_Payment_Processor::process_registration_payments()
1612
+		// so let's do that using our set of REG_IDs from the form
1613
+		$registration_query_where_params = array(
1614
+			'REG_ID' => array('IN', $REG_IDs),
1615
+		);
1616
+		// but add in some conditions regarding payment,
1617
+		// so that we don't apply payments to registrations that are free or have already been paid for
1618
+		// but ONLY if the payment is NOT a refund ( ie: the payment amount is not negative )
1619
+		if (! $payment->is_a_refund()) {
1620
+			$registration_query_where_params['REG_final_price']  = array('!=', 0);
1621
+			$registration_query_where_params['REG_final_price*'] = array('!=', 'REG_paid', true);
1622
+		}
1623
+		//EEH_Debug_Tools::printr( $registration_query_where_params, '$registration_query_where_params', __FILE__, __LINE__ );
1624
+		$registrations = $transaction->registrations(array($registration_query_where_params));
1625
+		if (! empty($registrations)) {
1626
+			/** @type EE_Payment_Processor $payment_processor */
1627
+			$payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
1628
+			$payment_processor->process_registration_payments($transaction, $payment, $registrations);
1629
+		}
1630
+	}
1631
+
1632
+
1633
+	/**
1634
+	 * _process_registration_status_change
1635
+	 * This processes requested registration status changes for all the registrations
1636
+	 * on a given transaction and (optionally) sends out notifications for the changes.
1637
+	 *
1638
+	 * @param  EE_Transaction $transaction
1639
+	 * @param array           $REG_IDs
1640
+	 * @return bool
1641
+	 */
1642
+	protected function _process_registration_status_change(EE_Transaction $transaction, $REG_IDs = array())
1643
+	{
1644
+		// first if there is no change in status then we get out.
1645
+		if (
1646
+			! isset($this->_req_data['txn_reg_status_change'], $this->_req_data['txn_reg_status_change']['reg_status'])
1647
+			|| $this->_req_data['txn_reg_status_change']['reg_status'] == 'NAN'
1648
+		) {
1649
+			//no error message, no change requested, just nothing to do man.
1650
+			return false;
1651
+		}
1652
+		/** @type EE_Transaction_Processor $transaction_processor */
1653
+		$transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
1654
+
1655
+		// made it here dude?  Oh WOW.  K, let's take care of changing the statuses
1656
+		return $transaction_processor->manually_update_registration_statuses(
1657
+			$transaction,
1658
+			sanitize_text_field($this->_req_data['txn_reg_status_change']['reg_status']),
1659
+			array(array('REG_ID' => array('IN', $REG_IDs)))
1660
+		);
1661
+	}
1662
+
1663
+
1664
+	/**
1665
+	 * _build_payment_json_response
1666
+	 *
1667
+	 * @access public
1668
+	 * @param \EE_Payment $payment
1669
+	 * @param array       $REG_IDs
1670
+	 * @param bool | null $delete_txn_reg_status_change
1671
+	 * @return array
1672
+	 */
1673
+	protected function _build_payment_json_response(
1674
+		EE_Payment $payment,
1675
+		$REG_IDs = array(),
1676
+		$delete_txn_reg_status_change = null
1677
+	) {
1678
+		// was the payment deleted ?
1679
+		if (is_bool($delete_txn_reg_status_change)) {
1680
+			return array(
1681
+				'PAY_ID'                       => $payment->ID(),
1682
+				'amount'                       => $payment->amount(),
1683
+				'total_paid'                   => $payment->transaction()->paid(),
1684
+				'txn_status'                   => $payment->transaction()->status_ID(),
1685
+				'pay_status'                   => $payment->STS_ID(),
1686
+				'registrations'                => $this->_registration_payment_data_array($REG_IDs),
1687
+				'delete_txn_reg_status_change' => $delete_txn_reg_status_change,
1688
+			);
1689
+		} else {
1690
+			$this->_get_payment_status_array();
1691
+
1692
+			return array(
1693
+				'amount'           => $payment->amount(),
1694
+				'total_paid'       => $payment->transaction()->paid(),
1695
+				'txn_status'       => $payment->transaction()->status_ID(),
1696
+				'pay_status'       => $payment->STS_ID(),
1697
+				'PAY_ID'           => $payment->ID(),
1698
+				'STS_ID'           => $payment->STS_ID(),
1699
+				'status'           => self::$_pay_status[$payment->STS_ID()],
1700
+				'date'             => $payment->timestamp('Y-m-d', 'h:i a'),
1701
+				'method'           => strtoupper($payment->source()),
1702
+				'PM_ID'            => $payment->payment_method() ? $payment->payment_method()->ID() : 1,
1703
+				'gateway'          => $payment->payment_method() ? $payment->payment_method()->admin_name() : esc_html__("Unknown",
1704
+					'event_espresso'),
1705
+				'gateway_response' => $payment->gateway_response(),
1706
+				'txn_id_chq_nmbr'  => $payment->txn_id_chq_nmbr(),
1707
+				'po_number'        => $payment->po_number(),
1708
+				'extra_accntng'    => $payment->extra_accntng(),
1709
+				'registrations'    => $this->_registration_payment_data_array($REG_IDs),
1710
+			);
1711
+		}
1712
+	}
1713
+
1714
+
1715
+	/**
1716
+	 * delete_payment
1717
+	 *    delete a payment or refund made towards a transaction
1718
+	 *
1719
+	 * @access public
1720
+	 * @return void
1721
+	 */
1722
+	public function delete_payment()
1723
+	{
1724
+		$json_response_data = array('return_data' => false);
1725
+		$PAY_ID             = isset($this->_req_data['delete_txn_admin_payment'], $this->_req_data['delete_txn_admin_payment']['PAY_ID']) ? absint($this->_req_data['delete_txn_admin_payment']['PAY_ID']) : 0;
1726
+		if ($PAY_ID) {
1727
+			$delete_txn_reg_status_change = isset($this->_req_data['delete_txn_reg_status_change']) ? $this->_req_data['delete_txn_reg_status_change'] : false;
1728
+			$payment                      = EEM_Payment::instance()->get_one_by_ID($PAY_ID);
1729
+			if ($payment instanceof EE_Payment) {
1730
+				$REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
1731
+				/** @type EE_Transaction_Payments $transaction_payments */
1732
+				$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1733
+				if ($transaction_payments->delete_payment_and_update_transaction($payment)) {
1734
+					$json_response_data['return_data'] = $this->_build_payment_json_response($payment, $REG_IDs,
1735
+						$delete_txn_reg_status_change);
1736
+					if ($delete_txn_reg_status_change) {
1737
+						$this->_req_data['txn_reg_status_change'] = $delete_txn_reg_status_change;
1738
+						//MAKE sure we also add the delete_txn_req_status_change to the
1739
+						//$_REQUEST global because that's how messages will be looking for it.
1740
+						$_REQUEST['txn_reg_status_change'] = $delete_txn_reg_status_change;
1741
+						$this->_maybe_send_notifications();
1742
+						$this->_process_registration_status_change($payment->transaction(), $REG_IDs);
1743
+					}
1744
+				}
1745
+			} else {
1746
+				EE_Error::add_error(
1747
+					esc_html__('Valid Payment data could not be retrieved from the database.', 'event_espresso'),
1748
+					__FILE__, __FUNCTION__, __LINE__
1749
+				);
1750
+			}
1751
+		} else {
1752
+			EE_Error::add_error(
1753
+				esc_html__('A valid Payment ID was not received, therefore payment form data could not be loaded.',
1754
+					'event_espresso'),
1755
+				__FILE__, __FUNCTION__, __LINE__
1756
+			);
1757
+		}
1758
+		$notices              = EE_Error::get_notices(false, false, false);
1759
+		$this->_template_args = array(
1760
+			'data'      => $json_response_data,
1761
+			'success'   => $notices['success'],
1762
+			'error'     => $notices['errors'],
1763
+			'attention' => $notices['attention'],
1764
+		);
1765
+		$this->_return_json();
1766
+	}
1767
+
1768
+
1769
+	/**
1770
+	 * _registration_payment_data_array
1771
+	 * adds info for 'owing' and 'paid' for each registration to the json response
1772
+	 *
1773
+	 * @access protected
1774
+	 * @param array $REG_IDs
1775
+	 * @return array
1776
+	 */
1777
+	protected function _registration_payment_data_array($REG_IDs)
1778
+	{
1779
+		$registration_payment_data = array();
1780
+		//if non empty reg_ids lets get an array of registrations and update the values for the apply_payment/refund rows.
1781
+		if (! empty($REG_IDs)) {
1782
+			$registrations = EEM_Registration::instance()->get_all(array(array('REG_ID' => array('IN', $REG_IDs))));
1783
+			foreach ($registrations as $registration) {
1784
+				if ($registration instanceof EE_Registration) {
1785
+					$registration_payment_data[$registration->ID()] = array(
1786
+						'paid'  => $registration->pretty_paid(),
1787
+						'owing' => EEH_Template::format_currency($registration->final_price() - $registration->paid()),
1788
+					);
1789
+				}
1790
+			}
1791
+		}
1792
+
1793
+		return $registration_payment_data;
1794
+	}
1795
+
1796
+
1797
+	/**
1798
+	 * _maybe_send_notifications
1799
+	 * determines whether or not the admin has indicated that notifications should be sent.
1800
+	 * If so, will toggle a filter switch for delivering registration notices.
1801
+	 * If passed an EE_Payment object, then it will trigger payment notifications instead.
1802
+	 *
1803
+	 * @access protected
1804
+	 * @param \EE_Payment | null $payment
1805
+	 */
1806
+	protected function _maybe_send_notifications($payment = null)
1807
+	{
1808
+		switch ($payment instanceof EE_Payment) {
1809
+			// payment notifications
1810
+			case true :
1811
+				if (
1812
+					isset(
1813
+						$this->_req_data['txn_payments'],
1814
+						$this->_req_data['txn_payments']['send_notifications']
1815
+					) &&
1816
+					filter_var($this->_req_data['txn_payments']['send_notifications'], FILTER_VALIDATE_BOOLEAN)
1817
+				) {
1818
+					$this->_process_payment_notification($payment);
1819
+				}
1820
+				break;
1821
+			// registration notifications
1822
+			case false :
1823
+				if (
1824
+					isset(
1825
+						$this->_req_data['txn_reg_status_change'],
1826
+						$this->_req_data['txn_reg_status_change']['send_notifications']
1827
+					) &&
1828
+					filter_var($this->_req_data['txn_reg_status_change']['send_notifications'], FILTER_VALIDATE_BOOLEAN)
1829
+				) {
1830
+					add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true');
1831
+				}
1832
+				break;
1833
+		}
1834
+	}
1835
+
1836
+
1837
+	/**
1838
+	 * _send_payment_reminder
1839
+	 *    generates HTML for the View Transaction Details Admin page
1840
+	 *
1841
+	 * @access protected
1842
+	 * @return void
1843
+	 */
1844
+	protected function _send_payment_reminder()
1845
+	{
1846
+		$TXN_ID      = (! empty($this->_req_data['TXN_ID'])) ? absint($this->_req_data['TXN_ID']) : false;
1847
+		$transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
1848
+		$query_args  = isset($this->_req_data['redirect_to']) ? array(
1849
+			'action' => $this->_req_data['redirect_to'],
1850
+			'TXN_ID' => $this->_req_data['TXN_ID'],
1851
+		) : array();
1852
+		do_action('AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
1853
+			$transaction);
1854
+		$this->_redirect_after_action(false, esc_html__('payment reminder', 'event_espresso'),
1855
+			esc_html__('sent', 'event_espresso'), $query_args, true);
1856
+	}
1857
+
1858
+
1859
+	/**
1860
+	 *  get_transactions
1861
+	 *    get transactions for given parameters (used by list table)
1862
+	 *
1863
+	 * @param  int     $perpage how many transactions displayed per page
1864
+	 * @param  boolean $count   return the count or objects
1865
+	 * @param string   $view
1866
+	 * @return mixed int = count || array of transaction objects
1867
+	 */
1868
+	public function get_transactions($perpage, $count = false, $view = '')
1869
+	{
1870
+
1871
+		$TXN = EEM_Transaction::instance();
1872
+
1873
+		$start_date = isset($this->_req_data['txn-filter-start-date']) ? wp_strip_all_tags($this->_req_data['txn-filter-start-date']) : date('m/d/Y',
1874
+			strtotime('-10 year'));
1875
+		$end_date   = isset($this->_req_data['txn-filter-end-date']) ? wp_strip_all_tags($this->_req_data['txn-filter-end-date']) : date('m/d/Y');
1876
+
1877
+		//make sure our timestamps start and end right at the boundaries for each day
1878
+		$start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
1879
+		$end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
1880
+
1881
+
1882
+		//convert to timestamps
1883
+		$start_date = strtotime($start_date);
1884
+		$end_date   = strtotime($end_date);
1885
+
1886
+		//makes sure start date is the lowest value and vice versa
1887
+		$start_date = min($start_date, $end_date);
1888
+		$end_date   = max($start_date, $end_date);
1889
+
1890
+		//convert to correct format for query
1891
+		$start_date = EEM_Transaction::instance()->convert_datetime_for_query('TXN_timestamp',
1892
+			date('Y-m-d H:i:s', $start_date), 'Y-m-d H:i:s');
1893
+		$end_date   = EEM_Transaction::instance()->convert_datetime_for_query('TXN_timestamp',
1894
+			date('Y-m-d H:i:s', $end_date), 'Y-m-d H:i:s');
1895
+
1896
+
1897
+		//set orderby
1898
+		$this->_req_data['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : '';
1899
+
1900
+		switch ($this->_req_data['orderby']) {
1901
+			case 'TXN_ID':
1902
+				$orderby = 'TXN_ID';
1903
+				break;
1904
+			case 'ATT_fname':
1905
+				$orderby = 'Registration.Attendee.ATT_fname';
1906
+				break;
1907
+			case 'event_name':
1908
+				$orderby = 'Registration.Event.EVT_name';
1909
+				break;
1910
+			default: //'TXN_timestamp'
1911
+				$orderby = 'TXN_timestamp';
1912
+		}
1913
+
1914
+		$sort         = (isset($this->_req_data['order']) && ! empty($this->_req_data['order'])) ? $this->_req_data['order'] : 'DESC';
1915
+		$current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged']) ? $this->_req_data['paged'] : 1;
1916
+		$per_page     = isset($perpage) && ! empty($perpage) ? $perpage : 10;
1917
+		$per_page     = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage']) ? $this->_req_data['perpage'] : $per_page;
1918
+
1919
+		$offset = ($current_page - 1) * $per_page;
1920
+		$limit  = array($offset, $per_page);
1921
+
1922
+		$_where = array(
1923
+			'TXN_timestamp'          => array('BETWEEN', array($start_date, $end_date)),
1924
+			'Registration.REG_count' => 1,
1925
+		);
1926
+
1927
+		if (isset($this->_req_data['EVT_ID'])) {
1928
+			$_where['Registration.EVT_ID'] = $this->_req_data['EVT_ID'];
1929
+		}
1930
+
1931
+		if (isset($this->_req_data['s'])) {
1932
+			$search_string = '%' . $this->_req_data['s'] . '%';
1933
+			$_where['OR']  = array(
1934
+				'Registration.Event.EVT_name'         => array('LIKE', $search_string),
1935
+				'Registration.Event.EVT_desc'         => array('LIKE', $search_string),
1936
+				'Registration.Event.EVT_short_desc'   => array('LIKE', $search_string),
1937
+				'Registration.Attendee.ATT_full_name' => array('LIKE', $search_string),
1938
+				'Registration.Attendee.ATT_fname'     => array('LIKE', $search_string),
1939
+				'Registration.Attendee.ATT_lname'     => array('LIKE', $search_string),
1940
+				'Registration.Attendee.ATT_short_bio' => array('LIKE', $search_string),
1941
+				'Registration.Attendee.ATT_email'     => array('LIKE', $search_string),
1942
+				'Registration.Attendee.ATT_address'   => array('LIKE', $search_string),
1943
+				'Registration.Attendee.ATT_address2'  => array('LIKE', $search_string),
1944
+				'Registration.Attendee.ATT_city'      => array('LIKE', $search_string),
1945
+				'Registration.REG_final_price'        => array('LIKE', $search_string),
1946
+				'Registration.REG_code'               => array('LIKE', $search_string),
1947
+				'Registration.REG_count'              => array('LIKE', $search_string),
1948
+				'Registration.REG_group_size'         => array('LIKE', $search_string),
1949
+				'Registration.Ticket.TKT_name'        => array('LIKE', $search_string),
1950
+				'Registration.Ticket.TKT_description' => array('LIKE', $search_string),
1951
+				'Payment.PAY_source'                  => array('LIKE', $search_string),
1952
+				'Payment.Payment_Method.PMD_name'     => array('LIKE', $search_string),
1953
+				'TXN_session_data'                    => array('LIKE', $search_string),
1954
+				'Payment.PAY_txn_id_chq_nmbr'         => array('LIKE', $search_string),
1955
+			);
1956
+		}
1957
+
1958
+		//failed transactions
1959
+		$failed    = (! empty($this->_req_data['status']) && $this->_req_data['status'] == 'failed' && ! $count) || ($count && $view == 'failed') ? true : false;
1960
+		$abandoned = (! empty($this->_req_data['status']) && $this->_req_data['status'] == 'abandoned' && ! $count) || ($count && $view == 'abandoned') ? true : false;
1961
+
1962
+		if ($failed) {
1963
+			$_where['STS_ID'] = EEM_Transaction::failed_status_code;
1964
+		} else if ($abandoned) {
1965
+			$_where['STS_ID'] = EEM_Transaction::abandoned_status_code;
1966
+		} else {
1967
+			$_where['STS_ID']  = array('!=', EEM_Transaction::failed_status_code);
1968
+			$_where['STS_ID*'] = array('!=', EEM_Transaction::abandoned_status_code);
1969
+		}
1970
+
1971
+		$query_params = array(
1972
+			$_where,
1973
+			'order_by'                 => array($orderby => $sort),
1974
+			'limit'                    => $limit,
1975
+			'default_where_conditions' => EEM_Base::default_where_conditions_this_only,
1976
+		);
1977
+
1978
+		$transactions = $count ? $TXN->count(array($_where), 'TXN_ID', true) : $TXN->get_all($query_params);
1979
+
1980
+
1981
+		return $transactions;
1982
+
1983
+	}
1984 1984
 
1985 1985
 
1986 1986
 }
Please login to merge, or discard this patch.
Spacing   +86 added lines, -86 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
 
@@ -335,11 +335,11 @@  discard block
 block discarded – undo
335 335
     public function load_scripts_styles()
336 336
     {
337 337
         //enqueue style
338
-        wp_register_style('espresso_txn', TXN_ASSETS_URL . 'espresso_transactions_admin.css', array(),
338
+        wp_register_style('espresso_txn', TXN_ASSETS_URL.'espresso_transactions_admin.css', array(),
339 339
             EVENT_ESPRESSO_VERSION);
340 340
         wp_enqueue_style('espresso_txn');
341 341
         //scripts
342
-        wp_register_script('espresso_txn', TXN_ASSETS_URL . 'espresso_transactions_admin.js', array(
342
+        wp_register_script('espresso_txn', TXN_ASSETS_URL.'espresso_transactions_admin.js', array(
343 343
             'ee_admin_js',
344 344
             'ee-datepicker',
345 345
             'jquery-ui-datepicker',
@@ -422,7 +422,7 @@  discard block
 block discarded – undo
422 422
 
423 423
         $TXN = EEM_Transaction::instance();
424 424
 
425
-        $TXN_ID = (! empty($this->_req_data['TXN_ID'])) ? absint($this->_req_data['TXN_ID']) : false;
425
+        $TXN_ID = ( ! empty($this->_req_data['TXN_ID'])) ? absint($this->_req_data['TXN_ID']) : false;
426 426
 
427 427
         //get transaction object
428 428
         $this->_transaction = $TXN->get_one_by_ID($TXN_ID);
@@ -431,7 +431,7 @@  discard block
 block discarded – undo
431 431
 
432 432
         if (empty($this->_transaction)) {
433 433
             $error_msg = esc_html__('An error occurred and the details for Transaction ID #',
434
-                    'event_espresso') . $TXN_ID . esc_html__(' could not be retrieved.', 'event_espresso');
434
+                    'event_espresso').$TXN_ID.esc_html__(' could not be retrieved.', 'event_espresso');
435 435
             EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
436 436
         }
437 437
     }
@@ -510,23 +510,23 @@  discard block
 block discarded – undo
510 510
             'FHEE__Transactions_Admin_Page___transaction_legend_items__more_items',
511 511
             array(
512 512
                 'overpaid'   => array(
513
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::overpaid_status_code,
513
+                    'class' => 'ee-status-legend ee-status-legend-'.EEM_Transaction::overpaid_status_code,
514 514
                     'desc'  => EEH_Template::pretty_status(EEM_Transaction::overpaid_status_code, false, 'sentence'),
515 515
                 ),
516 516
                 'complete'   => array(
517
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::complete_status_code,
517
+                    'class' => 'ee-status-legend ee-status-legend-'.EEM_Transaction::complete_status_code,
518 518
                     'desc'  => EEH_Template::pretty_status(EEM_Transaction::complete_status_code, false, 'sentence'),
519 519
                 ),
520 520
                 'incomplete' => array(
521
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::incomplete_status_code,
521
+                    'class' => 'ee-status-legend ee-status-legend-'.EEM_Transaction::incomplete_status_code,
522 522
                     'desc'  => EEH_Template::pretty_status(EEM_Transaction::incomplete_status_code, false, 'sentence'),
523 523
                 ),
524 524
                 'abandoned'  => array(
525
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::abandoned_status_code,
525
+                    'class' => 'ee-status-legend ee-status-legend-'.EEM_Transaction::abandoned_status_code,
526 526
                     'desc'  => EEH_Template::pretty_status(EEM_Transaction::abandoned_status_code, false, 'sentence'),
527 527
                 ),
528 528
                 'failed'     => array(
529
-                    'class' => 'ee-status-legend ee-status-legend-' . EEM_Transaction::failed_status_code,
529
+                    'class' => 'ee-status-legend ee-status-legend-'.EEM_Transaction::failed_status_code,
530 530
                     'desc'  => EEH_Template::pretty_status(EEM_Transaction::failed_status_code, false, 'sentence'),
531 531
                 ),
532 532
             )
@@ -548,10 +548,10 @@  discard block
 block discarded – undo
548 548
         $event                                     = isset($this->_req_data['EVT_ID']) ? EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID']) : null;
549 549
         $this->_template_args['admin_page_header'] = $event instanceof EE_Event ? sprintf(esc_html__('%sViewing Transactions for the Event: %s%s',
550 550
             'event_espresso'), '<h3>',
551
-            '<a href="' . EE_Admin_Page::add_query_args_and_nonce(array('action' => 'edit', 'post' => $event->ID()),
552
-                EVENTS_ADMIN_URL) . '" title="' . esc_attr__('Click to Edit event',
553
-                'event_espresso') . '">' . $event->get('EVT_name') . '</a>', '</h3>') : '';
554
-        $this->_template_args['after_list_table']  = $this->_display_legend($this->_transaction_legend_items());
551
+            '<a href="'.EE_Admin_Page::add_query_args_and_nonce(array('action' => 'edit', 'post' => $event->ID()),
552
+                EVENTS_ADMIN_URL).'" title="'.esc_attr__('Click to Edit event',
553
+                'event_espresso').'">'.$event->get('EVT_name').'</a>', '</h3>') : '';
554
+        $this->_template_args['after_list_table'] = $this->_display_legend($this->_transaction_legend_items());
555 555
         $this->display_admin_list_table_page_with_no_sidebar();
556 556
     }
557 557
 
@@ -567,7 +567,7 @@  discard block
 block discarded – undo
567 567
     {
568 568
         do_action('AHEE__Transactions_Admin_Page__transaction_details__start', $this->_transaction);
569 569
         $total_line_item = $this->_transaction->total_line_item(false);
570
-        if($total_line_item instanceof EE_Line_Item) {
570
+        if ($total_line_item instanceof EE_Line_Item) {
571 571
             $initial_total = $total_line_item->total();
572 572
             $total_line_item->recalculate_total_including_taxes();
573 573
         }
@@ -590,7 +590,7 @@  discard block
 block discarded – undo
590 590
 
591 591
         $this->_template_args['txn_status']['value'] = self::$_txn_status[$this->_transaction->get('STS_ID')];
592 592
         $this->_template_args['txn_status']['label'] = esc_html__('Transaction Status', 'event_espresso');
593
-        $this->_template_args['txn_status']['class'] = 'status-' . $this->_transaction->get('STS_ID');
593
+        $this->_template_args['txn_status']['class'] = 'status-'.$this->_transaction->get('STS_ID');
594 594
 
595 595
         $this->_template_args['grand_total'] = $this->_transaction->get('TXN_total');
596 596
         $this->_template_args['total_paid']  = $this->_transaction->get('TXN_paid');
@@ -627,9 +627,9 @@  discard block
 block discarded – undo
627 627
         $amount_due                         = $this->_transaction->get('TXN_total') - $this->_transaction->get('TXN_paid');
628 628
         $this->_template_args['amount_due'] = EEH_Template::format_currency($amount_due, true);
629 629
         if (EE_Registry::instance()->CFG->currency->sign_b4) {
630
-            $this->_template_args['amount_due'] = EE_Registry::instance()->CFG->currency->sign . $this->_template_args['amount_due'];
630
+            $this->_template_args['amount_due'] = EE_Registry::instance()->CFG->currency->sign.$this->_template_args['amount_due'];
631 631
         } else {
632
-            $this->_template_args['amount_due'] = $this->_template_args['amount_due'] . EE_Registry::instance()->CFG->currency->sign;
632
+            $this->_template_args['amount_due'] = $this->_template_args['amount_due'].EE_Registry::instance()->CFG->currency->sign;
633 633
         }
634 634
         $this->_template_args['amount_due_class'] = '';
635 635
 
@@ -664,7 +664,7 @@  discard block
 block discarded – undo
664 664
 
665 665
 
666 666
         // next link
667
-        $next_txn                                 = $this->_transaction->next(
667
+        $next_txn = $this->_transaction->next(
668 668
             null,
669 669
             array(array('STS_ID' => array('!=', EEM_Transaction::failed_status_code))),
670 670
             'TXN_ID'
@@ -679,7 +679,7 @@  discard block
 block discarded – undo
679 679
             )
680 680
             : '';
681 681
         // previous link
682
-        $previous_txn                                 = $this->_transaction->previous(
682
+        $previous_txn = $this->_transaction->previous(
683 683
             null,
684 684
             array(array('STS_ID' => array('!=', EEM_Transaction::failed_status_code))),
685 685
             'TXN_ID'
@@ -733,7 +733,7 @@  discard block
 block discarded – undo
733 733
         // grab messages at the last second
734 734
         $this->_template_args['notices'] = EE_Error::get_notices();
735 735
         // path to template
736
-        $template_path                             = TXN_TEMPLATE_PATH . 'txn_admin_details_header.template.php';
736
+        $template_path                             = TXN_TEMPLATE_PATH.'txn_admin_details_header.template.php';
737 737
         $this->_template_args['admin_page_header'] = EEH_Template::display_template($template_path,
738 738
             $this->_template_args, true);
739 739
 
@@ -808,7 +808,7 @@  discard block
 block discarded – undo
808 808
 
809 809
         // process payment details
810 810
         $payments = $this->_transaction->get_many_related('Payment');
811
-        if (! empty($payments)) {
811
+        if ( ! empty($payments)) {
812 812
             $this->_template_args['payments']              = $payments;
813 813
             $this->_template_args['existing_reg_payments'] = $this->_get_registration_payment_IDs($payments);
814 814
         } else {
@@ -841,21 +841,21 @@  discard block
 block discarded – undo
841 841
         $reg_steps = '<ul>';
842 842
         foreach ($this->_transaction->reg_steps() as $reg_step => $reg_step_status) {
843 843
             if ($reg_step_status === true) {
844
-                $reg_steps .= '<li style="color:#70cc50">' . sprintf(esc_html__('%1$s : Completed', 'event_espresso'),
845
-                        ucwords(str_replace('_', ' ', $reg_step))) . '</li>';
844
+                $reg_steps .= '<li style="color:#70cc50">'.sprintf(esc_html__('%1$s : Completed', 'event_espresso'),
845
+                        ucwords(str_replace('_', ' ', $reg_step))).'</li>';
846 846
             } else if (is_numeric($reg_step_status) && $reg_step_status !== false) {
847
-                $reg_steps .= '<li style="color:#2EA2CC">' . sprintf(
847
+                $reg_steps .= '<li style="color:#2EA2CC">'.sprintf(
848 848
                         esc_html__('%1$s : Initiated %2$s', 'event_espresso'),
849 849
                         ucwords(str_replace('_', ' ', $reg_step)),
850
-                        date(get_option('date_format') . ' ' . get_option('time_format'),
850
+                        date(get_option('date_format').' '.get_option('time_format'),
851 851
                             ($reg_step_status + (get_option('gmt_offset') * HOUR_IN_SECONDS)))
852
-                    ) . '</li>';
852
+                    ).'</li>';
853 853
             } else {
854
-                $reg_steps .= '<li style="color:#E76700">' . sprintf(esc_html__('%1$s : Never Initiated',
855
-                        'event_espresso'), ucwords(str_replace('_', ' ', $reg_step))) . '</li>';
854
+                $reg_steps .= '<li style="color:#E76700">'.sprintf(esc_html__('%1$s : Never Initiated',
855
+                        'event_espresso'), ucwords(str_replace('_', ' ', $reg_step))).'</li>';
856 856
             }
857 857
         }
858
-        $reg_steps                                                 .= '</ul>';
858
+        $reg_steps .= '</ul>';
859 859
         $this->_template_args['txn_details']['reg_steps']['value'] = $reg_steps;
860 860
         $this->_template_args['txn_details']['reg_steps']['label'] = esc_html__('Registration Step Progress',
861 861
             'event_espresso');
@@ -866,11 +866,11 @@  discard block
 block discarded – undo
866 866
         $this->_get_payment_status_array();
867 867
         $this->_get_reg_status_selection(); //sets up the template args for the reg status array for the transaction.
868 868
 
869
-        $this->_template_args['transaction_form_url']    = add_query_arg(array(
869
+        $this->_template_args['transaction_form_url'] = add_query_arg(array(
870 870
             'action'  => 'edit_transaction',
871 871
             'process' => 'transaction',
872 872
         ), TXN_ADMIN_URL);
873
-        $this->_template_args['apply_payment_form_url']  = add_query_arg(array(
873
+        $this->_template_args['apply_payment_form_url'] = add_query_arg(array(
874 874
             'page'   => 'espresso_transactions',
875 875
             'action' => 'espresso_apply_payment',
876 876
         ), WP_AJAX_URL);
@@ -881,7 +881,7 @@  discard block
 block discarded – undo
881 881
 
882 882
         // 'espresso_delete_payment_nonce'
883 883
 
884
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_txn_details.template.php';
884
+        $template_path = TXN_TEMPLATE_PATH.'txn_admin_details_main_meta_box_txn_details.template.php';
885 885
         echo EEH_Template::display_template($template_path, $this->_template_args, true);
886 886
 
887 887
     }
@@ -907,11 +907,11 @@  discard block
 block discarded – undo
907 907
                 ),
908 908
             ),
909 909
         ));
910
-        if (! empty($reg_payments)) {
910
+        if ( ! empty($reg_payments)) {
911 911
             foreach ($payments as $payment) {
912
-                if (! $payment instanceof EE_Payment) {
912
+                if ( ! $payment instanceof EE_Payment) {
913 913
                     continue;
914
-                } else if (! isset($existing_reg_payments[$payment->ID()])) {
914
+                } else if ( ! isset($existing_reg_payments[$payment->ID()])) {
915 915
                     $existing_reg_payments[$payment->ID()] = array();
916 916
                 }
917 917
                 foreach ($reg_payments as $reg_payment) {
@@ -938,7 +938,7 @@  discard block
 block discarded – undo
938 938
     protected function _get_registrations_to_apply_payment_to()
939 939
     {
940 940
         // we want any registration with an active status (ie: not deleted or cancelled)
941
-        $query_params                      = array(
941
+        $query_params = array(
942 942
             array(
943 943
                 'STS_ID' => array(
944 944
                     'IN',
@@ -950,19 +950,19 @@  discard block
 block discarded – undo
950 950
                 ),
951 951
             ),
952 952
         );
953
-        $registrations_to_apply_payment_to = EEH_HTML::br() . EEH_HTML::div(
953
+        $registrations_to_apply_payment_to = EEH_HTML::br().EEH_HTML::div(
954 954
                 '', 'txn-admin-apply-payment-to-registrations-dv', '', 'clear: both; margin: 1.5em 0 0; display: none;'
955 955
             );
956
-        $registrations_to_apply_payment_to .= EEH_HTML::br() . EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
956
+        $registrations_to_apply_payment_to .= EEH_HTML::br().EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
957 957
         $registrations_to_apply_payment_to .= EEH_HTML::table('', '', 'admin-primary-mbox-tbl');
958 958
         $registrations_to_apply_payment_to .= EEH_HTML::thead(
959 959
             EEH_HTML::tr(
960
-                EEH_HTML::th(esc_html__('ID', 'event_espresso')) .
961
-                EEH_HTML::th(esc_html__('Registrant', 'event_espresso')) .
962
-                EEH_HTML::th(esc_html__('Ticket', 'event_espresso')) .
963
-                EEH_HTML::th(esc_html__('Event', 'event_espresso')) .
964
-                EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr') .
965
-                EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr') .
960
+                EEH_HTML::th(esc_html__('ID', 'event_espresso')).
961
+                EEH_HTML::th(esc_html__('Registrant', 'event_espresso')).
962
+                EEH_HTML::th(esc_html__('Ticket', 'event_espresso')).
963
+                EEH_HTML::th(esc_html__('Event', 'event_espresso')).
964
+                EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr').
965
+                EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr').
966 966
                 EEH_HTML::th(esc_html__('Apply', 'event_espresso'), '', 'jst-cntr')
967 967
             )
968 968
         );
@@ -976,29 +976,29 @@  discard block
 block discarded – undo
976 976
                     : esc_html__('Unknown Attendee', 'event_espresso');
977 977
                 $owing                             = $registration->final_price() - $registration->paid();
978 978
                 $taxable                           = $registration->ticket()->taxable()
979
-                    ? ' <span class="smaller-text lt-grey-text"> ' . esc_html__('+ tax', 'event_espresso') . '</span>'
979
+                    ? ' <span class="smaller-text lt-grey-text"> '.esc_html__('+ tax', 'event_espresso').'</span>'
980 980
                     : '';
981 981
                 $checked                           = empty($existing_reg_payments) || in_array($registration->ID(),
982 982
                     $existing_reg_payments)
983 983
                     ? ' checked="checked"'
984 984
                     : '';
985
-                $disabled                          = $registration->final_price() > 0 ? '' : ' disabled';
985
+                $disabled = $registration->final_price() > 0 ? '' : ' disabled';
986 986
                 $registrations_to_apply_payment_to .= EEH_HTML::tr(
987
-                    EEH_HTML::td($registration->ID()) .
988
-                    EEH_HTML::td($attendee_name) .
987
+                    EEH_HTML::td($registration->ID()).
988
+                    EEH_HTML::td($attendee_name).
989 989
                     EEH_HTML::td(
990
-                        $registration->ticket()->name() . ' : ' . $registration->ticket()->pretty_price() . $taxable
991
-                    ) .
992
-                    EEH_HTML::td($registration->event_name()) .
993
-                    EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr') .
994
-                    EEH_HTML::td(EEH_Template::format_currency($owing), '', 'txn-admin-payment-owing-td jst-cntr') .
990
+                        $registration->ticket()->name().' : '.$registration->ticket()->pretty_price().$taxable
991
+                    ).
992
+                    EEH_HTML::td($registration->event_name()).
993
+                    EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr').
994
+                    EEH_HTML::td(EEH_Template::format_currency($owing), '', 'txn-admin-payment-owing-td jst-cntr').
995 995
                     EEH_HTML::td(
996
-                        '<input type="checkbox" value="' . $registration->ID()
996
+                        '<input type="checkbox" value="'.$registration->ID()
997 997
                         . '" name="txn_admin_payment[registrations]"'
998
-                        . $checked . $disabled . '>',
998
+                        . $checked.$disabled.'>',
999 999
                         '', 'jst-cntr'
1000 1000
                     ),
1001
-                    'apply-payment-registration-row-' . $registration->ID()
1001
+                    'apply-payment-registration-row-'.$registration->ID()
1002 1002
                 );
1003 1003
             }
1004 1004
         }
@@ -1012,7 +1012,7 @@  discard block
 block discarded – undo
1012 1012
             ),
1013 1013
             '', 'clear description'
1014 1014
         );
1015
-        $registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1015
+        $registrations_to_apply_payment_to .= EEH_HTML::divx();
1016 1016
         $this->_template_args['registrations_to_apply_payment_to'] = $registrations_to_apply_payment_to;
1017 1017
     }
1018 1018
 
@@ -1063,12 +1063,12 @@  discard block
 block discarded – undo
1063 1063
                 array(
1064 1064
                     'OR*payment_method_for_payment' => array(
1065 1065
                         'PMD_ID'    => array('IN', $payment_methods_of_payments),
1066
-                        'PMD_scope' => array('LIKE', '%' . EEM_Payment_Method::scope_admin . '%'),
1066
+                        'PMD_scope' => array('LIKE', '%'.EEM_Payment_Method::scope_admin.'%'),
1067 1067
                     ),
1068 1068
                 ),
1069 1069
             );
1070 1070
         } else {
1071
-            $query_args = array(array('PMD_scope' => array('LIKE', '%' . EEM_Payment_Method::scope_admin . '%')));
1071
+            $query_args = array(array('PMD_scope' => array('LIKE', '%'.EEM_Payment_Method::scope_admin.'%')));
1072 1072
         }
1073 1073
         $this->_template_args['payment_methods'] = EEM_Payment_Method::instance()->get_all($query_args);
1074 1074
     }
@@ -1091,7 +1091,7 @@  discard block
 block discarded – undo
1091 1091
         $this->_template_args['event_attendees'] = array();
1092 1092
         // process items in cart
1093 1093
         $line_items = $this->_transaction->get_many_related('Line_Item', array(array('LIN_type' => 'line-item')));
1094
-        if (! empty($line_items)) {
1094
+        if ( ! empty($line_items)) {
1095 1095
             foreach ($line_items as $item) {
1096 1096
                 if ($item instanceof EE_Line_Item) {
1097 1097
                     switch ($item->OBJ_type()) {
@@ -1102,7 +1102,7 @@  discard block
 block discarded – undo
1102 1102
                         case 'Ticket' :
1103 1103
                             $ticket = $item->ticket();
1104 1104
                             //right now we're only handling tickets here.  Cause its expected that only tickets will have attendees right?
1105
-                            if (! $ticket instanceof EE_Ticket) {
1105
+                            if ( ! $ticket instanceof EE_Ticket) {
1106 1106
                                 continue;
1107 1107
                             }
1108 1108
                             try {
@@ -1111,13 +1111,13 @@  discard block
 block discarded – undo
1111 1111
                                 EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1112 1112
                                 $event_name = esc_html__('Unknown Event', 'event_espresso');
1113 1113
                             }
1114
-                            $event_name   .= ' - ' . $item->get('LIN_name');
1114
+                            $event_name   .= ' - '.$item->get('LIN_name');
1115 1115
                             $ticket_price = EEH_Template::format_currency($item->get('LIN_unit_price'));
1116 1116
                             // now get all of the registrations for this transaction that use this ticket
1117 1117
                             $registrations = $ticket->get_many_related('Registration',
1118 1118
                                 array(array('TXN_ID' => $this->_transaction->ID())));
1119 1119
                             foreach ($registrations as $registration) {
1120
-                                if (! $registration instanceof EE_Registration) {
1120
+                                if ( ! $registration instanceof EE_Registration) {
1121 1121
                                     continue;
1122 1122
                                 }
1123 1123
                                 $this->_template_args['event_attendees'][$registration->ID()]['STS_ID']            = $registration->status_ID();
@@ -1129,8 +1129,8 @@  discard block
 block discarded – undo
1129 1129
                                 if ($attendee instanceof EE_Attendee) {
1130 1130
                                     $this->_template_args['event_attendees'][$registration->ID()]['att_id']   = $attendee->ID();
1131 1131
                                     $this->_template_args['event_attendees'][$registration->ID()]['attendee'] = $attendee->full_name();
1132
-                                    $this->_template_args['event_attendees'][$registration->ID()]['email']    = '<a href="mailto:' . $attendee->email() . '?subject=' . $event_name . esc_html__(' Event',
1133
-                                            'event_espresso') . '">' . $attendee->email() . '</a>';
1132
+                                    $this->_template_args['event_attendees'][$registration->ID()]['email']    = '<a href="mailto:'.$attendee->email().'?subject='.$event_name.esc_html__(' Event',
1133
+                                            'event_espresso').'">'.$attendee->email().'</a>';
1134 1134
                                     $this->_template_args['event_attendees'][$registration->ID()]['address']  = EEH_Address::format($attendee,
1135 1135
                                         'inline', false, false);
1136 1136
                                 } else {
@@ -1150,7 +1150,7 @@  discard block
 block discarded – undo
1150 1150
                 'action'  => 'edit_transaction',
1151 1151
                 'process' => 'attendees',
1152 1152
             ), TXN_ADMIN_URL);
1153
-            echo EEH_Template::display_template(TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_attendees.template.php',
1153
+            echo EEH_Template::display_template(TXN_TEMPLATE_PATH.'txn_admin_details_main_meta_box_attendees.template.php',
1154 1154
                 $this->_template_args, true);
1155 1155
 
1156 1156
         } else {
@@ -1175,7 +1175,7 @@  discard block
 block discarded – undo
1175 1175
     public function txn_registrant_side_meta_box()
1176 1176
     {
1177 1177
         $primary_att = $this->_transaction->primary_registration() instanceof EE_Registration ? $this->_transaction->primary_registration()->get_first_related('Attendee') : null;
1178
-        if (! $primary_att instanceof EE_Attendee) {
1178
+        if ( ! $primary_att instanceof EE_Attendee) {
1179 1179
             $this->_template_args['no_attendee_message'] = esc_html__('There is no attached contact for this transaction.  The transaction either failed due to an error or was abandoned.',
1180 1180
                 'event_espresso');
1181 1181
             $primary_att                                 = EEM_Attendee::instance()->create_default_object();
@@ -1191,7 +1191,7 @@  discard block
 block discarded – undo
1191 1191
         ), REG_ADMIN_URL);
1192 1192
         // get formatted address for registrant
1193 1193
         $this->_template_args['formatted_address'] = EEH_Address::format($primary_att);
1194
-        echo EEH_Template::display_template(TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_registrant.template.php',
1194
+        echo EEH_Template::display_template(TXN_TEMPLATE_PATH.'txn_admin_details_side_meta_box_registrant.template.php',
1195 1195
             $this->_template_args, true);
1196 1196
     }
1197 1197
 
@@ -1212,8 +1212,8 @@  discard block
 block discarded – undo
1212 1212
             TXN_ADMIN_URL
1213 1213
         );
1214 1214
 
1215
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_billing_info.template.php';
1216
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);/**/
1215
+        $template_path = TXN_TEMPLATE_PATH.'txn_admin_details_side_meta_box_billing_info.template.php';
1216
+        echo EEH_Template::display_template($template_path, $this->_template_args, true); /**/
1217 1217
     }
1218 1218
 
1219 1219
 
@@ -1228,7 +1228,7 @@  discard block
 block discarded – undo
1228 1228
     {
1229 1229
         $json_response_data = array('return_data' => false);
1230 1230
         $valid_data         = $this->_validate_payment_request_data();
1231
-        if (! empty($valid_data)
1231
+        if ( ! empty($valid_data)
1232 1232
 
1233 1233
         ) {
1234 1234
             $PAY_ID = $valid_data['PAY_ID'];
@@ -1243,7 +1243,7 @@  discard block
 block discarded – undo
1243 1243
                 $REG_IDs = $this->_get_REG_IDs_to_apply_payment_to($payment);
1244 1244
                 $this->_remove_existing_registration_payments($payment, $PAY_ID);
1245 1245
                 // apply payment to registrations (if applicable)
1246
-                if (! empty($REG_IDs)) {
1246
+                if ( ! empty($REG_IDs)) {
1247 1247
                     $this->_update_registration_payments($transaction, $payment, $REG_IDs);
1248 1248
                     $this->_maybe_send_notifications();
1249 1249
                     // now process status changes for the same registrations
@@ -1282,14 +1282,14 @@  discard block
 block discarded – undo
1282 1282
      */
1283 1283
     protected function _validate_payment_request_data()
1284 1284
     {
1285
-        if (! isset($this->_req_data['txn_admin_payment'])) {
1285
+        if ( ! isset($this->_req_data['txn_admin_payment'])) {
1286 1286
             return false;
1287 1287
         }
1288 1288
         $payment_form = $this->_generate_payment_form_section();
1289 1289
         try {
1290 1290
             if ($payment_form->was_submitted()) {
1291 1291
                 $payment_form->receive_form_submission();
1292
-                if (! $payment_form->is_valid()) {
1292
+                if ( ! $payment_form->is_valid()) {
1293 1293
                     $submission_error_messages = array();
1294 1294
                     foreach ($payment_form->get_validation_errors_accumulated() as $validation_error) {
1295 1295
                         if ($validation_error instanceof EE_Validation_Error) {
@@ -1454,7 +1454,7 @@  discard block
 block discarded – undo
1454 1454
             array('Y-m-d', 'g:i a')
1455 1455
         );
1456 1456
 
1457
-        if (! $payment->save()) {
1457
+        if ( ! $payment->save()) {
1458 1458
             EE_Error::add_error(
1459 1459
                 sprintf(
1460 1460
                     esc_html__('Payment %1$d has not been successfully saved to the database.', 'event_espresso'),
@@ -1504,7 +1504,7 @@  discard block
 block discarded – undo
1504 1504
         $REG_IDs = array();
1505 1505
         // grab array of IDs for specific registrations to apply changes to
1506 1506
         if (isset($this->_req_data['txn_admin_payment']['registrations'])) {
1507
-            $REG_IDs = (array)$this->_req_data['txn_admin_payment']['registrations'];
1507
+            $REG_IDs = (array) $this->_req_data['txn_admin_payment']['registrations'];
1508 1508
         }
1509 1509
         //nothing specified ? then get all reg IDs
1510 1510
         if (empty($REG_IDs)) {
@@ -1616,13 +1616,13 @@  discard block
 block discarded – undo
1616 1616
         // but add in some conditions regarding payment,
1617 1617
         // so that we don't apply payments to registrations that are free or have already been paid for
1618 1618
         // but ONLY if the payment is NOT a refund ( ie: the payment amount is not negative )
1619
-        if (! $payment->is_a_refund()) {
1619
+        if ( ! $payment->is_a_refund()) {
1620 1620
             $registration_query_where_params['REG_final_price']  = array('!=', 0);
1621 1621
             $registration_query_where_params['REG_final_price*'] = array('!=', 'REG_paid', true);
1622 1622
         }
1623 1623
         //EEH_Debug_Tools::printr( $registration_query_where_params, '$registration_query_where_params', __FILE__, __LINE__ );
1624 1624
         $registrations = $transaction->registrations(array($registration_query_where_params));
1625
-        if (! empty($registrations)) {
1625
+        if ( ! empty($registrations)) {
1626 1626
             /** @type EE_Payment_Processor $payment_processor */
1627 1627
             $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
1628 1628
             $payment_processor->process_registration_payments($transaction, $payment, $registrations);
@@ -1778,7 +1778,7 @@  discard block
 block discarded – undo
1778 1778
     {
1779 1779
         $registration_payment_data = array();
1780 1780
         //if non empty reg_ids lets get an array of registrations and update the values for the apply_payment/refund rows.
1781
-        if (! empty($REG_IDs)) {
1781
+        if ( ! empty($REG_IDs)) {
1782 1782
             $registrations = EEM_Registration::instance()->get_all(array(array('REG_ID' => array('IN', $REG_IDs))));
1783 1783
             foreach ($registrations as $registration) {
1784 1784
                 if ($registration instanceof EE_Registration) {
@@ -1843,7 +1843,7 @@  discard block
 block discarded – undo
1843 1843
      */
1844 1844
     protected function _send_payment_reminder()
1845 1845
     {
1846
-        $TXN_ID      = (! empty($this->_req_data['TXN_ID'])) ? absint($this->_req_data['TXN_ID']) : false;
1846
+        $TXN_ID      = ( ! empty($this->_req_data['TXN_ID'])) ? absint($this->_req_data['TXN_ID']) : false;
1847 1847
         $transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
1848 1848
         $query_args  = isset($this->_req_data['redirect_to']) ? array(
1849 1849
             'action' => $this->_req_data['redirect_to'],
@@ -1875,8 +1875,8 @@  discard block
 block discarded – undo
1875 1875
         $end_date   = isset($this->_req_data['txn-filter-end-date']) ? wp_strip_all_tags($this->_req_data['txn-filter-end-date']) : date('m/d/Y');
1876 1876
 
1877 1877
         //make sure our timestamps start and end right at the boundaries for each day
1878
-        $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
1879
-        $end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
1878
+        $start_date = date('Y-m-d', strtotime($start_date)).' 00:00:00';
1879
+        $end_date   = date('Y-m-d', strtotime($end_date)).' 23:59:59';
1880 1880
 
1881 1881
 
1882 1882
         //convert to timestamps
@@ -1929,7 +1929,7 @@  discard block
 block discarded – undo
1929 1929
         }
1930 1930
 
1931 1931
         if (isset($this->_req_data['s'])) {
1932
-            $search_string = '%' . $this->_req_data['s'] . '%';
1932
+            $search_string = '%'.$this->_req_data['s'].'%';
1933 1933
             $_where['OR']  = array(
1934 1934
                 'Registration.Event.EVT_name'         => array('LIKE', $search_string),
1935 1935
                 'Registration.Event.EVT_desc'         => array('LIKE', $search_string),
@@ -1956,8 +1956,8 @@  discard block
 block discarded – undo
1956 1956
         }
1957 1957
 
1958 1958
         //failed transactions
1959
-        $failed    = (! empty($this->_req_data['status']) && $this->_req_data['status'] == 'failed' && ! $count) || ($count && $view == 'failed') ? true : false;
1960
-        $abandoned = (! empty($this->_req_data['status']) && $this->_req_data['status'] == 'abandoned' && ! $count) || ($count && $view == 'abandoned') ? true : false;
1959
+        $failed    = ( ! empty($this->_req_data['status']) && $this->_req_data['status'] == 'failed' && ! $count) || ($count && $view == 'failed') ? true : false;
1960
+        $abandoned = ( ! empty($this->_req_data['status']) && $this->_req_data['status'] == 'abandoned' && ! $count) || ($count && $view == 'abandoned') ? true : false;
1961 1961
 
1962 1962
         if ($failed) {
1963 1963
             $_where['STS_ID'] = EEM_Transaction::failed_status_code;
Please login to merge, or discard this patch.
core/db_classes/EE_Registration.class.php 1 patch
Indentation   +2021 added lines, -2021 removed lines patch added patch discarded remove patch
@@ -18,2027 +18,2027 @@
 block discarded – undo
18 18
 {
19 19
 
20 20
 
21
-    /**
22
-     * Used to reference when a registration has never been checked in.
23
-     *
24
-     * @deprecated use \EE_Checkin::status_checked_never instead
25
-     * @type int
26
-     */
27
-    const checkin_status_never = 2;
28
-
29
-    /**
30
-     * Used to reference when a registration has been checked in.
31
-     *
32
-     * @deprecated use \EE_Checkin::status_checked_in instead
33
-     * @type int
34
-     */
35
-    const checkin_status_in = 1;
36
-
37
-
38
-    /**
39
-     * Used to reference when a registration has been checked out.
40
-     *
41
-     * @deprecated use \EE_Checkin::status_checked_out instead
42
-     * @type int
43
-     */
44
-    const checkin_status_out = 0;
45
-
46
-
47
-    /**
48
-     * extra meta key for tracking reg status os trashed registrations
49
-     *
50
-     * @type string
51
-     */
52
-    const PRE_TRASH_REG_STATUS_KEY = 'pre_trash_registration_status';
53
-
54
-
55
-    /**
56
-     * extra meta key for tracking if registration has reserved ticket
57
-     *
58
-     * @type string
59
-     */
60
-    const HAS_RESERVED_TICKET_KEY = 'has_reserved_ticket';
61
-
62
-
63
-    /**
64
-     * @param array  $props_n_values          incoming values
65
-     * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
66
-     *                                        used.)
67
-     * @param array  $date_formats            incoming date_formats in an array where the first value is the
68
-     *                                        date_format and the second value is the time format
69
-     * @return EE_Registration
70
-     * @throws EE_Error
71
-     */
72
-    public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
73
-    {
74
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
75
-        return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
76
-    }
77
-
78
-
79
-    /**
80
-     * @param array  $props_n_values  incoming values from the database
81
-     * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
82
-     *                                the website will be used.
83
-     * @return EE_Registration
84
-     */
85
-    public static function new_instance_from_db($props_n_values = array(), $timezone = null)
86
-    {
87
-        return new self($props_n_values, true, $timezone);
88
-    }
89
-
90
-
91
-    /**
92
-     *        Set Event ID
93
-     *
94
-     * @param        int $EVT_ID Event ID
95
-     * @throws EE_Error
96
-     * @throws RuntimeException
97
-     */
98
-    public function set_event($EVT_ID = 0)
99
-    {
100
-        $this->set('EVT_ID', $EVT_ID);
101
-    }
102
-
103
-
104
-    /**
105
-     * Overrides parent set() method so that all calls to set( 'REG_code', $REG_code ) OR set( 'STS_ID', $STS_ID ) can
106
-     * be routed to internal methods
107
-     *
108
-     * @param string $field_name
109
-     * @param mixed  $field_value
110
-     * @param bool   $use_default
111
-     * @throws EE_Error
112
-     * @throws EntityNotFoundException
113
-     * @throws InvalidArgumentException
114
-     * @throws InvalidDataTypeException
115
-     * @throws InvalidInterfaceException
116
-     * @throws ReflectionException
117
-     * @throws RuntimeException
118
-     */
119
-    public function set($field_name, $field_value, $use_default = false)
120
-    {
121
-        switch ($field_name) {
122
-            case 'REG_code':
123
-                if (! empty($field_value) && $this->reg_code() === null) {
124
-                    $this->set_reg_code($field_value, $use_default);
125
-                }
126
-                break;
127
-            case 'STS_ID':
128
-                $this->set_status($field_value, $use_default);
129
-                break;
130
-            default:
131
-                parent::set($field_name, $field_value, $use_default);
132
-        }
133
-    }
134
-
135
-
136
-    /**
137
-     * Set Status ID
138
-     * updates the registration status and ALSO...
139
-     * calls reserve_registration_space() if the reg status changes TO approved from any other reg status
140
-     * calls release_registration_space() if the reg status changes FROM approved to any other reg status
141
-     *
142
-     * @param string       $new_STS_ID
143
-     * @param boolean      $use_default
144
-     * @param ContextInterface|null $context
145
-     * @return bool
146
-     * @throws EE_Error
147
-     * @throws EntityNotFoundException
148
-     * @throws InvalidArgumentException
149
-     * @throws ReflectionException
150
-     * @throws RuntimeException
151
-     * @throws InvalidDataTypeException
152
-     * @throws InvalidInterfaceException
153
-     */
154
-    public function set_status($new_STS_ID = null, $use_default = false, ContextInterface $context = null)
155
-    {
156
-        // get current REG_Status
157
-        $old_STS_ID = $this->status_ID();
158
-        // if status has changed
159
-        if ($old_STS_ID !== $new_STS_ID // and that status has actually changed
160
-            && ! empty($old_STS_ID) // and that old status is actually set
161
-            && ! empty($new_STS_ID) // as well as the new status
162
-            && $this->ID() // ensure registration is in the db
163
-        ) {
164
-            // TO approved
165
-            if ($new_STS_ID === EEM_Registration::status_id_approved) {
166
-                // reserve a space by incrementing ticket and datetime sold values
167
-                $this->_reserve_registration_space();
168
-                do_action('AHEE__EE_Registration__set_status__to_approved', $this, $old_STS_ID, $new_STS_ID, $context);
169
-                // OR FROM  approved
170
-            } elseif ($old_STS_ID === EEM_Registration::status_id_approved) {
171
-                // release a space by decrementing ticket and datetime sold values
172
-                $this->_release_registration_space();
173
-                do_action(
174
-                    'AHEE__EE_Registration__set_status__from_approved',
175
-                    $this,
176
-                    $old_STS_ID,
177
-                    $new_STS_ID,
178
-                    $context
179
-                );
180
-            }
181
-            // update status
182
-            parent::set('STS_ID', $new_STS_ID, $use_default);
183
-            $this->_update_if_canceled_or_declined($new_STS_ID, $old_STS_ID, $context);
184
-            if($this->statusChangeUpdatesTransaction($context)) {
185
-                $this->updateTransactionAfterStatusChange();
186
-            }
187
-            do_action('AHEE__EE_Registration__set_status__after_update', $this, $old_STS_ID, $new_STS_ID, $context);
188
-            return true;
189
-        }
190
-        //even though the old value matches the new value, it's still good to
191
-        //allow the parent set method to have a say
192
-        parent::set('STS_ID', $new_STS_ID, $use_default);
193
-        return true;
194
-    }
195
-
196
-
197
-    /**
198
-     * update REGs and TXN when cancelled or declined registrations involved
199
-     *
200
-     * @param string       $new_STS_ID
201
-     * @param string       $old_STS_ID
202
-     * @param ContextInterface|null $context
203
-     * @throws EE_Error
204
-     * @throws InvalidArgumentException
205
-     * @throws InvalidDataTypeException
206
-     * @throws InvalidInterfaceException
207
-     * @throws ReflectionException
208
-     */
209
-    private function _update_if_canceled_or_declined($new_STS_ID, $old_STS_ID, ContextInterface $context = null)
210
-    {
211
-        // these reg statuses should not be considered in any calculations involving monies owing
212
-        $closed_reg_statuses = EEM_Registration::closed_reg_statuses();
213
-        // true if registration has been cancelled or declined
214
-        $this->updateIfCanceled(
215
-            $closed_reg_statuses,
216
-            $new_STS_ID,
217
-            $old_STS_ID,
218
-            $context
219
-        );
220
-        $this->updateIfDeclined(
221
-            $closed_reg_statuses,
222
-            $new_STS_ID,
223
-            $old_STS_ID,
224
-            $context
225
-        );
226
-    }
227
-
228
-
229
-    /**
230
-     * update REGs and TXN when cancelled or declined registrations involved
231
-     *
232
-     * @param array        $closed_reg_statuses
233
-     * @param string       $new_STS_ID
234
-     * @param string       $old_STS_ID
235
-     * @param ContextInterface|null $context
236
-     * @throws EE_Error
237
-     * @throws InvalidArgumentException
238
-     * @throws InvalidDataTypeException
239
-     * @throws InvalidInterfaceException
240
-     * @throws ReflectionException
241
-     */
242
-    private function updateIfCanceled(array $closed_reg_statuses, $new_STS_ID, $old_STS_ID, ContextInterface $context = null)
243
-    {
244
-        // true if registration has been cancelled or declined
245
-        if (in_array($new_STS_ID, $closed_reg_statuses, true)
246
-            && ! in_array($old_STS_ID, $closed_reg_statuses, true)
247
-        ) {
248
-            /** @type EE_Registration_Processor $registration_processor */
249
-            $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
250
-            /** @type EE_Transaction_Processor $transaction_processor */
251
-            $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
252
-            // cancelled or declined registration
253
-            $registration_processor->update_registration_after_being_canceled_or_declined(
254
-                $this,
255
-                $closed_reg_statuses
256
-            );
257
-            $transaction_processor->update_transaction_after_canceled_or_declined_registration(
258
-                $this,
259
-                $closed_reg_statuses,
260
-                false
261
-            );
262
-            do_action(
263
-                'AHEE__EE_Registration__set_status__canceled_or_declined',
264
-                $this,
265
-                $old_STS_ID,
266
-                $new_STS_ID,
267
-                $context
268
-            );
269
-            return;
270
-        }
271
-    }
272
-
273
-
274
-    /**
275
-     * update REGs and TXN when cancelled or declined registrations involved
276
-     *
277
-     * @param array        $closed_reg_statuses
278
-     * @param string       $new_STS_ID
279
-     * @param string       $old_STS_ID
280
-     * @param ContextInterface|null $context
281
-     * @throws EE_Error
282
-     * @throws InvalidArgumentException
283
-     * @throws InvalidDataTypeException
284
-     * @throws InvalidInterfaceException
285
-     * @throws ReflectionException
286
-     */
287
-    private function updateIfDeclined(array $closed_reg_statuses, $new_STS_ID, $old_STS_ID, ContextInterface $context = null)
288
-    {
289
-        // true if reinstating cancelled or declined registration
290
-        if (in_array($old_STS_ID, $closed_reg_statuses, true)
291
-            && ! in_array($new_STS_ID, $closed_reg_statuses, true)
292
-        ) {
293
-            /** @type EE_Registration_Processor $registration_processor */
294
-            $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
295
-            /** @type EE_Transaction_Processor $transaction_processor */
296
-            $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
297
-            // reinstating cancelled or declined registration
298
-            $registration_processor->update_canceled_or_declined_registration_after_being_reinstated(
299
-                $this,
300
-                $closed_reg_statuses
301
-            );
302
-            $transaction_processor->update_transaction_after_reinstating_canceled_registration(
303
-                $this,
304
-                $closed_reg_statuses,
305
-                false
306
-            );
307
-            do_action(
308
-                'AHEE__EE_Registration__set_status__after_reinstated',
309
-                $this,
310
-                $old_STS_ID,
311
-                $new_STS_ID,
312
-                $context
313
-            );
314
-        }
315
-    }
316
-
317
-
318
-    /**
319
-     * @param ContextInterface|null $context
320
-     * @return bool
321
-     */
322
-    private function statusChangeUpdatesTransaction(ContextInterface $context = null)
323
-    {
324
-        $contexts_that_do_not_update_transaction = (array) apply_filters(
325
-            'AHEE__EE_Registration__statusChangeUpdatesTransaction__contexts_that_do_not_update_transaction',
326
-            array('spco_reg_step_attendee_information_process_registrations'),
327
-            $context,
328
-            $this
329
-        );
330
-        return ! (
331
-            $context instanceof ContextInterface
332
-            && in_array($context->slug(), $contexts_that_do_not_update_transaction, true)
333
-        );
334
-    }
335
-
336
-
337
-    /**
338
-     * @throws EE_Error
339
-     * @throws EntityNotFoundException
340
-     * @throws InvalidArgumentException
341
-     * @throws InvalidDataTypeException
342
-     * @throws InvalidInterfaceException
343
-     * @throws ReflectionException
344
-     * @throws RuntimeException
345
-     */
346
-    private function updateTransactionAfterStatusChange()
347
-    {
348
-        /** @type EE_Transaction_Payments $transaction_payments */
349
-        $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
350
-        $transaction_payments->recalculate_transaction_total($this->transaction(), false);
351
-        $this->transaction()->update_status_based_on_total_paid(true);
352
-    }
353
-
354
-
355
-    /**
356
-     *        get Status ID
357
-     */
358
-    public function status_ID()
359
-    {
360
-        return $this->get('STS_ID');
361
-    }
362
-
363
-
364
-    /**
365
-     * increments this registration's related ticket sold and corresponding datetime sold values
366
-     *
367
-     * @return void
368
-     * @throws EE_Error
369
-     * @throws EntityNotFoundException
370
-     */
371
-    private function _reserve_registration_space()
372
-    {
373
-        // reserved ticket and datetime counts will be decremented as sold counts are incremented
374
-        // so stop tracking that this reg has a ticket reserved
375
-        $this->release_reserved_ticket();
376
-        $ticket = $this->ticket();
377
-        $ticket->increase_sold();
378
-        $ticket->save();
379
-        // possibly set event status to sold out
380
-        $this->event()->perform_sold_out_status_check();
381
-    }
382
-
383
-
384
-    /**
385
-     * Gets the ticket this registration is for
386
-     *
387
-     * @param boolean $include_archived whether to include archived tickets or not.
388
-     *
389
-     * @return EE_Ticket|EE_Base_Class
390
-     * @throws EE_Error
391
-     */
392
-    public function ticket($include_archived = true)
393
-    {
394
-        $query_params = array();
395
-        if ($include_archived) {
396
-            $query_params['default_where_conditions'] = 'none';
397
-        }
398
-        return $this->get_first_related('Ticket', $query_params);
399
-    }
400
-
401
-
402
-    /**
403
-     * Gets the event this registration is for
404
-     *
405
-     * @return EE_Event
406
-     * @throws EE_Error
407
-     * @throws EntityNotFoundException
408
-     */
409
-    public function event()
410
-    {
411
-        $event = $this->get_first_related('Event');
412
-        if (! $event instanceof \EE_Event) {
413
-            throw new EntityNotFoundException('Event ID', $this->event_ID());
414
-        }
415
-        return $event;
416
-    }
417
-
418
-
419
-    /**
420
-     * Gets the "author" of the registration.  Note that for the purposes of registrations, the author will correspond
421
-     * with the author of the event this registration is for.
422
-     *
423
-     * @since 4.5.0
424
-     * @return int
425
-     * @throws EE_Error
426
-     * @throws EntityNotFoundException
427
-     */
428
-    public function wp_user()
429
-    {
430
-        $event = $this->event();
431
-        if ($event instanceof EE_Event) {
432
-            return $event->wp_user();
433
-        }
434
-        return 0;
435
-    }
436
-
437
-
438
-    /**
439
-     * decrements (subtracts) this registration's related ticket sold and corresponding datetime sold values
440
-     *
441
-     * @return void
442
-     * @throws EE_Error
443
-     */
444
-    private function _release_registration_space()
445
-    {
446
-        $ticket = $this->ticket();
447
-        $ticket->decrease_sold();
448
-        $ticket->save();
449
-    }
450
-
451
-
452
-    /**
453
-     * tracks this registration's ticket reservation in extra meta
454
-     * and can increment related ticket reserved and corresponding datetime reserved values
455
-     *
456
-     * @param bool $update_ticket if true, will increment ticket and datetime reserved count
457
-     *
458
-     * @return void
459
-     * @throws EE_Error
460
-     */
461
-    public function reserve_ticket($update_ticket = false)
462
-    {
463
-        if ($this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true, false) === false) {
464
-            // PLZ NOTE: although checking $update_ticket first would be more efficient,
465
-            // we NEED to ALWAYS call update_extra_meta(), which is why that is done first
466
-            if ($this->update_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true, false) && $update_ticket) {
467
-                $ticket = $this->ticket();
468
-                $ticket->increase_reserved();
469
-                $ticket->save();
470
-            }
471
-        }
472
-    }
473
-
474
-
475
-    /**
476
-     * stops tracking this registration's ticket reservation in extra meta
477
-     * decrements (subtracts) related ticket reserved and corresponding datetime reserved values
478
-     *
479
-     * @param bool $update_ticket if true, will decrement ticket and datetime reserved count
480
-     *
481
-     * @return void
482
-     * @throws EE_Error
483
-     */
484
-    public function release_reserved_ticket($update_ticket = false)
485
-    {
486
-        if ($this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true, false) !== false) {
487
-            // PLZ NOTE: although checking $update_ticket first would be more efficient,
488
-            // we NEED to ALWAYS call delete_extra_meta(), which is why that is done first
489
-            if ($this->delete_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY) && $update_ticket) {
490
-                $ticket = $this->ticket();
491
-                $ticket->decrease_reserved();
492
-                $ticket->save();
493
-            }
494
-        }
495
-    }
496
-
497
-
498
-    /**
499
-     * Set Attendee ID
500
-     *
501
-     * @param        int $ATT_ID Attendee ID
502
-     * @throws EE_Error
503
-     * @throws RuntimeException
504
-     */
505
-    public function set_attendee_id($ATT_ID = 0)
506
-    {
507
-        $this->set('ATT_ID', $ATT_ID);
508
-    }
509
-
510
-
511
-    /**
512
-     *        Set Transaction ID
513
-     *
514
-     * @param        int $TXN_ID Transaction ID
515
-     * @throws EE_Error
516
-     * @throws RuntimeException
517
-     */
518
-    public function set_transaction_id($TXN_ID = 0)
519
-    {
520
-        $this->set('TXN_ID', $TXN_ID);
521
-    }
522
-
523
-
524
-    /**
525
-     *        Set Session
526
-     *
527
-     * @param    string $REG_session PHP Session ID
528
-     * @throws EE_Error
529
-     * @throws RuntimeException
530
-     */
531
-    public function set_session($REG_session = '')
532
-    {
533
-        $this->set('REG_session', $REG_session);
534
-    }
535
-
536
-
537
-    /**
538
-     *        Set Registration URL Link
539
-     *
540
-     * @param    string $REG_url_link Registration URL Link
541
-     * @throws EE_Error
542
-     * @throws RuntimeException
543
-     */
544
-    public function set_reg_url_link($REG_url_link = '')
545
-    {
546
-        $this->set('REG_url_link', $REG_url_link);
547
-    }
548
-
549
-
550
-    /**
551
-     *        Set Attendee Counter
552
-     *
553
-     * @param        int $REG_count Primary Attendee
554
-     * @throws EE_Error
555
-     * @throws RuntimeException
556
-     */
557
-    public function set_count($REG_count = 1)
558
-    {
559
-        $this->set('REG_count', $REG_count);
560
-    }
561
-
562
-
563
-    /**
564
-     *        Set Group Size
565
-     *
566
-     * @param        boolean $REG_group_size Group Registration
567
-     * @throws EE_Error
568
-     * @throws RuntimeException
569
-     */
570
-    public function set_group_size($REG_group_size = false)
571
-    {
572
-        $this->set('REG_group_size', $REG_group_size);
573
-    }
574
-
575
-
576
-    /**
577
-     *    is_not_approved -  convenience method that returns TRUE if REG status ID ==
578
-     *    EEM_Registration::status_id_not_approved
579
-     *
580
-     * @return        boolean
581
-     */
582
-    public function is_not_approved()
583
-    {
584
-        return $this->status_ID() == EEM_Registration::status_id_not_approved ? true : false;
585
-    }
586
-
587
-
588
-    /**
589
-     *    is_pending_payment -  convenience method that returns TRUE if REG status ID ==
590
-     *    EEM_Registration::status_id_pending_payment
591
-     *
592
-     * @return        boolean
593
-     */
594
-    public function is_pending_payment()
595
-    {
596
-        return $this->status_ID() == EEM_Registration::status_id_pending_payment ? true : false;
597
-    }
598
-
599
-
600
-    /**
601
-     *    is_approved -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_approved
602
-     *
603
-     * @return        boolean
604
-     */
605
-    public function is_approved()
606
-    {
607
-        return $this->status_ID() == EEM_Registration::status_id_approved ? true : false;
608
-    }
609
-
610
-
611
-    /**
612
-     *    is_cancelled -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_cancelled
613
-     *
614
-     * @return        boolean
615
-     */
616
-    public function is_cancelled()
617
-    {
618
-        return $this->status_ID() == EEM_Registration::status_id_cancelled ? true : false;
619
-    }
620
-
621
-
622
-    /**
623
-     *    is_declined -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_declined
624
-     *
625
-     * @return        boolean
626
-     */
627
-    public function is_declined()
628
-    {
629
-        return $this->status_ID() == EEM_Registration::status_id_declined ? true : false;
630
-    }
631
-
632
-
633
-    /**
634
-     *    is_incomplete -  convenience method that returns TRUE if REG status ID ==
635
-     *    EEM_Registration::status_id_incomplete
636
-     *
637
-     * @return        boolean
638
-     */
639
-    public function is_incomplete()
640
-    {
641
-        return $this->status_ID() == EEM_Registration::status_id_incomplete ? true : false;
642
-    }
643
-
644
-
645
-    /**
646
-     *        Set Registration Date
647
-     *
648
-     * @param        mixed ( int or string ) $REG_date Registration Date - Unix timestamp or string representation of
649
-     *                                                 Date
650
-     * @throws EE_Error
651
-     * @throws RuntimeException
652
-     */
653
-    public function set_reg_date($REG_date = false)
654
-    {
655
-        $this->set('REG_date', $REG_date);
656
-    }
657
-
658
-
659
-    /**
660
-     *    Set final price owing for this registration after all ticket/price modifications
661
-     *
662
-     * @access    public
663
-     * @param    float $REG_final_price
664
-     * @throws EE_Error
665
-     * @throws RuntimeException
666
-     */
667
-    public function set_final_price($REG_final_price = 0.00)
668
-    {
669
-        $this->set('REG_final_price', $REG_final_price);
670
-    }
671
-
672
-
673
-    /**
674
-     *    Set amount paid towards this registration's final price
675
-     *
676
-     * @access    public
677
-     * @param    float $REG_paid
678
-     * @throws EE_Error
679
-     * @throws RuntimeException
680
-     */
681
-    public function set_paid($REG_paid = 0.00)
682
-    {
683
-        $this->set('REG_paid', $REG_paid);
684
-    }
685
-
686
-
687
-    /**
688
-     *        Attendee Is Going
689
-     *
690
-     * @param        boolean $REG_att_is_going Attendee Is Going
691
-     * @throws EE_Error
692
-     * @throws RuntimeException
693
-     */
694
-    public function set_att_is_going($REG_att_is_going = false)
695
-    {
696
-        $this->set('REG_att_is_going', $REG_att_is_going);
697
-    }
698
-
699
-
700
-    /**
701
-     * Gets the related attendee
702
-     *
703
-     * @return EE_Attendee
704
-     * @throws EE_Error
705
-     */
706
-    public function attendee()
707
-    {
708
-        return $this->get_first_related('Attendee');
709
-    }
710
-
711
-
712
-    /**
713
-     *        get Event ID
714
-     */
715
-    public function event_ID()
716
-    {
717
-        return $this->get('EVT_ID');
718
-    }
719
-
720
-
721
-    /**
722
-     *        get Event ID
723
-     */
724
-    public function event_name()
725
-    {
726
-        $event = $this->event_obj();
727
-        if ($event) {
728
-            return $event->name();
729
-        } else {
730
-            return null;
731
-        }
732
-    }
733
-
734
-
735
-    /**
736
-     * Fetches the event this registration is for
737
-     *
738
-     * @return EE_Event
739
-     * @throws EE_Error
740
-     */
741
-    public function event_obj()
742
-    {
743
-        return $this->get_first_related('Event');
744
-    }
745
-
746
-
747
-    /**
748
-     *        get Attendee ID
749
-     */
750
-    public function attendee_ID()
751
-    {
752
-        return $this->get('ATT_ID');
753
-    }
754
-
755
-
756
-    /**
757
-     *        get PHP Session ID
758
-     */
759
-    public function session_ID()
760
-    {
761
-        return $this->get('REG_session');
762
-    }
763
-
764
-
765
-    /**
766
-     * Gets the string which represents the URL trigger for the receipt template in the message template system.
767
-     *
768
-     * @param string $messenger 'pdf' or 'html'.  Default 'html'.
769
-     * @return string
770
-     */
771
-    public function receipt_url($messenger = 'html')
772
-    {
773
-
774
-        /**
775
-         * The below will be deprecated one version after this.  We check first if there is a custom receipt template
776
-         * already in use on old system.  If there is then we just return the standard url for it.
777
-         *
778
-         * @since 4.5.0
779
-         */
780
-        $template_relative_path = 'modules/gateways/Invoice/lib/templates/receipt_body.template.php';
781
-        $has_custom             = EEH_Template::locate_template(
782
-            $template_relative_path,
783
-            array(),
784
-            true,
785
-            true,
786
-            true
787
-        );
788
-
789
-        if ($has_custom) {
790
-            return add_query_arg(array('receipt' => 'true'), $this->invoice_url('launch'));
791
-        }
792
-        return apply_filters('FHEE__EE_Registration__receipt_url__receipt_url', '', $this, $messenger, 'receipt');
793
-    }
794
-
795
-
796
-    /**
797
-     * Gets the string which represents the URL trigger for the invoice template in the message template system.
798
-     *
799
-     * @param string $messenger 'pdf' or 'html'.  Default 'html'.
800
-     * @return string
801
-     * @throws EE_Error
802
-     */
803
-    public function invoice_url($messenger = 'html')
804
-    {
805
-        /**
806
-         * The below will be deprecated one version after this.  We check first if there is a custom invoice template
807
-         * already in use on old system.  If there is then we just return the standard url for it.
808
-         *
809
-         * @since 4.5.0
810
-         */
811
-        $template_relative_path = 'modules/gateways/Invoice/lib/templates/invoice_body.template.php';
812
-        $has_custom             = EEH_Template::locate_template(
813
-            $template_relative_path,
814
-            array(),
815
-            true,
816
-            true,
817
-            true
818
-        );
819
-
820
-        if ($has_custom) {
821
-            if ($messenger == 'html') {
822
-                return $this->invoice_url('launch');
823
-            }
824
-            $route = $messenger == 'download' || $messenger == 'pdf' ? 'download_invoice' : 'launch_invoice';
825
-
826
-            $query_args = array('ee' => $route, 'id' => $this->reg_url_link());
827
-            if ($messenger == 'html') {
828
-                $query_args['html'] = true;
829
-            }
830
-            return add_query_arg($query_args, get_permalink(EE_Registry::instance()->CFG->core->thank_you_page_id));
831
-        }
832
-        return apply_filters('FHEE__EE_Registration__invoice_url__invoice_url', '', $this, $messenger, 'invoice');
833
-    }
834
-
835
-
836
-    /**
837
-     * get Registration URL Link
838
-     *
839
-     * @access public
840
-     * @return string
841
-     * @throws EE_Error
842
-     */
843
-    public function reg_url_link()
844
-    {
845
-        return (string) $this->get('REG_url_link');
846
-    }
847
-
848
-
849
-    /**
850
-     * Echoes out invoice_url()
851
-     *
852
-     * @param string $type 'download','launch', or 'html' (default is 'launch')
853
-     * @return void
854
-     * @throws EE_Error
855
-     */
856
-    public function e_invoice_url($type = 'launch')
857
-    {
858
-        echo $this->invoice_url($type);
859
-    }
860
-
861
-
862
-    /**
863
-     * Echoes out payment_overview_url
864
-     */
865
-    public function e_payment_overview_url()
866
-    {
867
-        echo $this->payment_overview_url();
868
-    }
869
-
870
-
871
-    /**
872
-     * Gets the URL for the checkout payment options reg step
873
-     * with this registration's REG_url_link added as a query parameter
874
-     *
875
-     * @param bool $clear_session Set to true when you want to clear the session on revisiting the
876
-     *                            payment overview url.
877
-     * @return string
878
-     * @throws InvalidInterfaceException
879
-     * @throws InvalidDataTypeException
880
-     * @throws EE_Error
881
-     * @throws InvalidArgumentException
882
-     * @throws EntityNotFoundException
883
-     */
884
-    public function payment_overview_url($clear_session = false)
885
-    {
886
-        $payment_overview_url = add_query_arg(
887
-            (array) apply_filters(
888
-                'FHEE__EE_Registration__payment_overview_url__query_args',
889
-                array(
890
-                    'e_reg_url_link' => $this->reg_url_link(),
891
-                    'step'           => 'payment_options',
892
-                    'revisit'        => true,
893
-                    'clear_session'  => (bool) $clear_session,
894
-                ),
895
-                $this
896
-            ),
897
-            EE_Registry::instance()->CFG->core->reg_page_url()
898
-        );
899
-        EE_Log::logTxn(
900
-            __CLASS__, __FUNCTION__, __LINE__,
901
-            $this->transaction(),
902
-            array(
903
-                'REG_ID'               => $this->ID(),
904
-                'e_reg_url_link'       => $this->reg_url_link(),
905
-                'payment_overview_url' => $payment_overview_url,
906
-            )
907
-        );
908
-        return $payment_overview_url;
909
-    }
910
-
911
-
912
-    /**
913
-     * Gets the URL for the checkout attendee information reg step
914
-     * with this registration's REG_url_link added as a query parameter
915
-     *
916
-     * @return string
917
-     * @throws InvalidInterfaceException
918
-     * @throws InvalidDataTypeException
919
-     * @throws EE_Error
920
-     * @throws InvalidArgumentException
921
-     * @throws EntityNotFoundException
922
-     */
923
-    public function edit_attendee_information_url()
924
-    {
925
-        $attendee_information_url = add_query_arg(
926
-            (array) apply_filters(
927
-                'FHEE__EE_Registration__edit_attendee_information_url__query_args',
928
-                array(
929
-                    'e_reg_url_link' => $this->reg_url_link(),
930
-                    'step'           => 'attendee_information',
931
-                    'revisit'        => true,
932
-                ),
933
-                $this
934
-            ),
935
-            EE_Registry::instance()->CFG->core->reg_page_url()
936
-        );
937
-        EE_Log::logTxn(
938
-            __CLASS__, __FUNCTION__, __LINE__,
939
-            $this->transaction(),
940
-            array(
941
-                'REG_ID'                   => $this->ID(),
942
-                'e_reg_url_link'           => $this->reg_url_link(),
943
-                'attendee_information_url' => $attendee_information_url,
944
-            )
945
-        );
946
-        return $attendee_information_url;
947
-    }
948
-
949
-
950
-    /**
951
-     * Simply generates and returns the appropriate admin_url link to edit this registration
952
-     *
953
-     * @return string
954
-     * @throws EE_Error
955
-     */
956
-    public function get_admin_edit_url()
957
-    {
958
-        return EEH_URL::add_query_args_and_nonce(array(
959
-            'page'    => 'espresso_registrations',
960
-            'action'  => 'view_registration',
961
-            '_REG_ID' => $this->ID(),
962
-        ), admin_url('admin.php'));
963
-    }
964
-
965
-
966
-    /**
967
-     *    is_primary_registrant?
968
-     */
969
-    public function is_primary_registrant()
970
-    {
971
-        return $this->get('REG_count') == 1 ? true : false;
972
-    }
973
-
974
-
975
-    /**
976
-     * This returns the primary registration object for this registration group (which may be this object).
977
-     *
978
-     * @return EE_Registration
979
-     * @throws EE_Error
980
-     */
981
-    public function get_primary_registration()
982
-    {
983
-        if ($this->is_primary_registrant()) {
984
-            return $this;
985
-        }
986
-
987
-        //k reg_count !== 1 so let's get the EE_Registration object matching this txn_id and reg_count == 1
988
-        /** @var EE_Registration $primary_registrant */
989
-        $primary_registrant = EEM_Registration::instance()->get_one(array(
990
-            array(
991
-                'TXN_ID'    => $this->transaction_ID(),
992
-                'REG_count' => 1,
993
-            ),
994
-        ));
995
-        return $primary_registrant;
996
-    }
997
-
998
-
999
-    /**
1000
-     *        get  Attendee Number
1001
-     *
1002
-     * @access        public
1003
-     */
1004
-    public function count()
1005
-    {
1006
-        return $this->get('REG_count');
1007
-    }
1008
-
1009
-
1010
-    /**
1011
-     *        get Group Size
1012
-     */
1013
-    public function group_size()
1014
-    {
1015
-        return $this->get('REG_group_size');
1016
-    }
1017
-
1018
-
1019
-    /**
1020
-     *        get Registration Date
1021
-     */
1022
-    public function date()
1023
-    {
1024
-        return $this->get('REG_date');
1025
-    }
1026
-
1027
-
1028
-    /**
1029
-     * gets a pretty date
1030
-     *
1031
-     * @param string $date_format
1032
-     * @param string $time_format
1033
-     * @return string
1034
-     * @throws EE_Error
1035
-     */
1036
-    public function pretty_date($date_format = null, $time_format = null)
1037
-    {
1038
-        return $this->get_datetime('REG_date', $date_format, $time_format);
1039
-    }
1040
-
1041
-
1042
-    /**
1043
-     * final_price
1044
-     * the registration's share of the transaction total, so that the
1045
-     * sum of all the transaction's REG_final_prices equal the transaction's total
1046
-     *
1047
-     * @return float
1048
-     * @throws EE_Error
1049
-     */
1050
-    public function final_price()
1051
-    {
1052
-        return $this->get('REG_final_price');
1053
-    }
1054
-
1055
-
1056
-    /**
1057
-     * pretty_final_price
1058
-     *  final price as formatted string, with correct decimal places and currency symbol
1059
-     *
1060
-     * @return string
1061
-     * @throws EE_Error
1062
-     */
1063
-    public function pretty_final_price()
1064
-    {
1065
-        return $this->get_pretty('REG_final_price');
1066
-    }
1067
-
1068
-
1069
-    /**
1070
-     * get paid (yeah)
1071
-     *
1072
-     * @return float
1073
-     * @throws EE_Error
1074
-     */
1075
-    public function paid()
1076
-    {
1077
-        return $this->get('REG_paid');
1078
-    }
1079
-
1080
-
1081
-    /**
1082
-     * pretty_paid
1083
-     *
1084
-     * @return float
1085
-     * @throws EE_Error
1086
-     */
1087
-    public function pretty_paid()
1088
-    {
1089
-        return $this->get_pretty('REG_paid');
1090
-    }
1091
-
1092
-
1093
-    /**
1094
-     * owes_monies_and_can_pay
1095
-     * whether or not this registration has monies owing and it's' status allows payment
1096
-     *
1097
-     * @param array $requires_payment
1098
-     * @return bool
1099
-     * @throws EE_Error
1100
-     */
1101
-    public function owes_monies_and_can_pay($requires_payment = array())
1102
-    {
1103
-        // these reg statuses require payment (if event is not free)
1104
-        $requires_payment = ! empty($requires_payment)
1105
-            ? $requires_payment
1106
-            : EEM_Registration::reg_statuses_that_allow_payment();
1107
-        if (in_array($this->status_ID(), $requires_payment) &&
1108
-            $this->final_price() != 0 &&
1109
-            $this->final_price() != $this->paid()
1110
-        ) {
1111
-            return true;
1112
-        } else {
1113
-            return false;
1114
-        }
1115
-    }
1116
-
1117
-
1118
-    /**
1119
-     * Prints out the return value of $this->pretty_status()
1120
-     *
1121
-     * @param bool $show_icons
1122
-     * @return void
1123
-     * @throws EE_Error
1124
-     */
1125
-    public function e_pretty_status($show_icons = false)
1126
-    {
1127
-        echo $this->pretty_status($show_icons);
1128
-    }
1129
-
1130
-
1131
-    /**
1132
-     * Returns a nice version of the status for displaying to customers
1133
-     *
1134
-     * @param bool $show_icons
1135
-     * @return string
1136
-     * @throws EE_Error
1137
-     */
1138
-    public function pretty_status($show_icons = false)
1139
-    {
1140
-        $status = EEM_Status::instance()->localized_status(
1141
-            array($this->status_ID() => esc_html__('unknown', 'event_espresso')),
1142
-            false,
1143
-            'sentence'
1144
-        );
1145
-        $icon   = '';
1146
-        switch ($this->status_ID()) {
1147
-            case EEM_Registration::status_id_approved:
1148
-                $icon = $show_icons
1149
-                    ? '<span class="dashicons dashicons-star-filled ee-icon-size-16 green-text"></span>'
1150
-                    : '';
1151
-                break;
1152
-            case EEM_Registration::status_id_pending_payment:
1153
-                $icon = $show_icons
1154
-                    ? '<span class="dashicons dashicons-star-half ee-icon-size-16 orange-text"></span>'
1155
-                    : '';
1156
-                break;
1157
-            case EEM_Registration::status_id_not_approved:
1158
-                $icon = $show_icons
1159
-                    ? '<span class="dashicons dashicons-marker ee-icon-size-16 orange-text"></span>'
1160
-                    : '';
1161
-                break;
1162
-            case EEM_Registration::status_id_cancelled:
1163
-                $icon = $show_icons
1164
-                    ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-grey-text"></span>'
1165
-                    : '';
1166
-                break;
1167
-            case EEM_Registration::status_id_incomplete:
1168
-                $icon = $show_icons
1169
-                    ? '<span class="dashicons dashicons-no ee-icon-size-16 lt-orange-text"></span>'
1170
-                    : '';
1171
-                break;
1172
-            case EEM_Registration::status_id_declined:
1173
-                $icon = $show_icons
1174
-                    ? '<span class="dashicons dashicons-no ee-icon-size-16 red-text"></span>'
1175
-                    : '';
1176
-                break;
1177
-            case EEM_Registration::status_id_wait_list:
1178
-                $icon = $show_icons
1179
-                    ? '<span class="dashicons dashicons-clipboard ee-icon-size-16 purple-text"></span>'
1180
-                    : '';
1181
-                break;
1182
-        }
1183
-        return $icon . $status[$this->status_ID()];
1184
-    }
1185
-
1186
-
1187
-    /**
1188
-     *        get Attendee Is Going
1189
-     */
1190
-    public function att_is_going()
1191
-    {
1192
-        return $this->get('REG_att_is_going');
1193
-    }
1194
-
1195
-
1196
-    /**
1197
-     * Gets related answers
1198
-     *
1199
-     * @param array $query_params like EEM_Base::get_all
1200
-     * @return EE_Answer[]
1201
-     * @throws EE_Error
1202
-     */
1203
-    public function answers($query_params = null)
1204
-    {
1205
-        return $this->get_many_related('Answer', $query_params);
1206
-    }
1207
-
1208
-
1209
-    /**
1210
-     * Gets the registration's answer value to the specified question
1211
-     * (either the question's ID or a question object)
1212
-     *
1213
-     * @param EE_Question|int $question
1214
-     * @param bool            $pretty_value
1215
-     * @return array|string if pretty_value= true, the result will always be a string
1216
-     * (because the answer might be an array of answer values, so passing pretty_value=true
1217
-     * will convert it into some kind of string)
1218
-     * @throws EE_Error
1219
-     */
1220
-    public function answer_value_to_question($question, $pretty_value = true)
1221
-    {
1222
-        $question_id = EEM_Question::instance()->ensure_is_ID($question);
1223
-        return EEM_Answer::instance()->get_answer_value_to_question($this, $question_id, $pretty_value);
1224
-    }
1225
-
1226
-
1227
-    /**
1228
-     * question_groups
1229
-     * returns an array of EE_Question_Group objects for this registration
1230
-     *
1231
-     * @return EE_Question_Group[]
1232
-     * @throws EE_Error
1233
-     * @throws EntityNotFoundException
1234
-     */
1235
-    public function question_groups()
1236
-    {
1237
-        $question_groups = array();
1238
-        if ($this->event() instanceof EE_Event) {
1239
-            $question_groups = $this->event()->question_groups(
1240
-                array(
1241
-                    array(
1242
-                        'Event_Question_Group.EQG_primary' => $this->count() == 1 ? true : false,
1243
-                    ),
1244
-                    'order_by' => array('QSG_order' => 'ASC'),
1245
-                )
1246
-            );
1247
-        }
1248
-        return $question_groups;
1249
-    }
1250
-
1251
-
1252
-    /**
1253
-     * count_question_groups
1254
-     * returns a count of the number of EE_Question_Group objects for this registration
1255
-     *
1256
-     * @return int
1257
-     * @throws EE_Error
1258
-     * @throws EntityNotFoundException
1259
-     */
1260
-    public function count_question_groups()
1261
-    {
1262
-        $qg_count = 0;
1263
-        if ($this->event() instanceof EE_Event) {
1264
-            $qg_count = $this->event()->count_related(
1265
-                'Question_Group',
1266
-                array(
1267
-                    array(
1268
-                        'Event_Question_Group.EQG_primary' => $this->count() == 1 ? true : false,
1269
-                    ),
1270
-                )
1271
-            );
1272
-        }
1273
-        return $qg_count;
1274
-    }
1275
-
1276
-
1277
-    /**
1278
-     * Returns the registration date in the 'standard' string format
1279
-     * (function may be improved in the future to allow for different formats and timezones)
1280
-     *
1281
-     * @return string
1282
-     * @throws EE_Error
1283
-     */
1284
-    public function reg_date()
1285
-    {
1286
-        return $this->get_datetime('REG_date');
1287
-    }
1288
-
1289
-
1290
-    /**
1291
-     * Gets the datetime-ticket for this registration (ie, it can be used to isolate
1292
-     * the ticket this registration purchased, or the datetime they have registered
1293
-     * to attend)
1294
-     *
1295
-     * @return EE_Datetime_Ticket
1296
-     * @throws EE_Error
1297
-     */
1298
-    public function datetime_ticket()
1299
-    {
1300
-        return $this->get_first_related('Datetime_Ticket');
1301
-    }
1302
-
1303
-
1304
-    /**
1305
-     * Sets the registration's datetime_ticket.
1306
-     *
1307
-     * @param EE_Datetime_Ticket $datetime_ticket
1308
-     * @return EE_Datetime_Ticket
1309
-     * @throws EE_Error
1310
-     */
1311
-    public function set_datetime_ticket($datetime_ticket)
1312
-    {
1313
-        return $this->_add_relation_to($datetime_ticket, 'Datetime_Ticket');
1314
-    }
1315
-
1316
-    /**
1317
-     * Gets deleted
1318
-     *
1319
-     * @return bool
1320
-     * @throws EE_Error
1321
-     */
1322
-    public function deleted()
1323
-    {
1324
-        return $this->get('REG_deleted');
1325
-    }
1326
-
1327
-    /**
1328
-     * Sets deleted
1329
-     *
1330
-     * @param boolean $deleted
1331
-     * @return bool
1332
-     * @throws EE_Error
1333
-     * @throws RuntimeException
1334
-     */
1335
-    public function set_deleted($deleted)
1336
-    {
1337
-        if ($deleted) {
1338
-            $this->delete();
1339
-        } else {
1340
-            $this->restore();
1341
-        }
1342
-    }
1343
-
1344
-
1345
-    /**
1346
-     * Get the status object of this object
1347
-     *
1348
-     * @return EE_Status
1349
-     * @throws EE_Error
1350
-     */
1351
-    public function status_obj()
1352
-    {
1353
-        return $this->get_first_related('Status');
1354
-    }
1355
-
1356
-
1357
-    /**
1358
-     * Returns the number of times this registration has checked into any of the datetimes
1359
-     * its available for
1360
-     *
1361
-     * @return int
1362
-     * @throws EE_Error
1363
-     */
1364
-    public function count_checkins()
1365
-    {
1366
-        return $this->get_model()->count_related($this, 'Checkin');
1367
-    }
1368
-
1369
-
1370
-    /**
1371
-     * Returns the number of current Check-ins this registration is checked into for any of the datetimes the
1372
-     * registration is for.  Note, this is ONLY checked in (does not include checkedout)
1373
-     *
1374
-     * @return int
1375
-     * @throws EE_Error
1376
-     */
1377
-    public function count_checkins_not_checkedout()
1378
-    {
1379
-        return $this->get_model()->count_related($this, 'Checkin', array(array('CHK_in' => 1)));
1380
-    }
1381
-
1382
-
1383
-    /**
1384
-     * The purpose of this method is simply to check whether this registration can checkin to the given datetime.
1385
-     *
1386
-     * @param int | EE_Datetime $DTT_OR_ID      The datetime the registration is being checked against
1387
-     * @param bool              $check_approved This is used to indicate whether the caller wants can_checkin to also
1388
-     *                                          consider registration status as well as datetime access.
1389
-     * @return bool
1390
-     * @throws EE_Error
1391
-     */
1392
-    public function can_checkin($DTT_OR_ID, $check_approved = true)
1393
-    {
1394
-        $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID);
1395
-
1396
-        //first check registration status
1397
-        if (($check_approved && ! $this->is_approved()) || ! $DTT_ID) {
1398
-            return false;
1399
-        }
1400
-        //is there a datetime ticket that matches this dtt_ID?
1401
-        if (! (EEM_Datetime_Ticket::instance()->exists(array(
1402
-            array(
1403
-                'TKT_ID' => $this->get('TKT_ID'),
1404
-                'DTT_ID' => $DTT_ID,
1405
-            ),
1406
-        )))
1407
-        ) {
1408
-            return false;
1409
-        }
1410
-
1411
-        //final check is against TKT_uses
1412
-        return $this->verify_can_checkin_against_TKT_uses($DTT_ID);
1413
-    }
1414
-
1415
-
1416
-    /**
1417
-     * This method verifies whether the user can checkin for the given datetime considering the max uses value set on
1418
-     * the ticket. To do this,  a query is done to get the count of the datetime records already checked into.  If the
1419
-     * datetime given does not have a check-in record and checking in for that datetime will exceed the allowed uses,
1420
-     * then return false.  Otherwise return true.
1421
-     *
1422
-     * @param int | EE_Datetime $DTT_OR_ID The datetime the registration is being checked against
1423
-     * @return bool true means can checkin.  false means cannot checkin.
1424
-     * @throws EE_Error
1425
-     */
1426
-    public function verify_can_checkin_against_TKT_uses($DTT_OR_ID)
1427
-    {
1428
-        $DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID);
1429
-
1430
-        if (! $DTT_ID) {
1431
-            return false;
1432
-        }
1433
-
1434
-        $max_uses = $this->ticket() instanceof EE_Ticket ? $this->ticket()->uses() : EE_INF;
1435
-
1436
-        // if max uses is not set or equals infinity then return true cause its not a factor for whether user can
1437
-        // check-in or not.
1438
-        if (! $max_uses || $max_uses === EE_INF) {
1439
-            return true;
1440
-        }
1441
-
1442
-        //does this datetime have a checkin record?  If so, then the dtt count has already been verified so we can just
1443
-        //go ahead and toggle.
1444
-        if (EEM_Checkin::instance()->exists(array(array('REG_ID' => $this->ID(), 'DTT_ID' => $DTT_ID)))) {
1445
-            return true;
1446
-        }
1447
-
1448
-        //made it here so the last check is whether the number of checkins per unique datetime on this registration
1449
-        //disallows further check-ins.
1450
-        $count_unique_dtt_checkins = EEM_Checkin::instance()->count(array(
1451
-            array(
1452
-                'REG_ID' => $this->ID(),
1453
-                'CHK_in' => true,
1454
-            ),
1455
-        ), 'DTT_ID', true);
1456
-        // checkins have already reached their max number of uses
1457
-        // so registrant can NOT checkin
1458
-        if ($count_unique_dtt_checkins >= $max_uses) {
1459
-            EE_Error::add_error(
1460
-                esc_html__(
1461
-                    'Check-in denied because number of datetime uses for the ticket has been reached or exceeded.',
1462
-                    'event_espresso'
1463
-                ),
1464
-                __FILE__,
1465
-                __FUNCTION__,
1466
-                __LINE__
1467
-            );
1468
-            return false;
1469
-        }
1470
-        return true;
1471
-    }
1472
-
1473
-
1474
-    /**
1475
-     * toggle Check-in status for this registration
1476
-     * Check-ins are toggled in the following order:
1477
-     * never checked in -> checked in
1478
-     * checked in -> checked out
1479
-     * checked out -> checked in
1480
-     *
1481
-     * @param  int $DTT_ID  include specific datetime to toggle Check-in for.
1482
-     *                      If not included or null, then it is assumed latest datetime is being toggled.
1483
-     * @param bool $verify  If true then can_checkin() is used to verify whether the person
1484
-     *                      can be checked in or not.  Otherwise this forces change in checkin status.
1485
-     * @return bool|int     the chk_in status toggled to OR false if nothing got changed.
1486
-     * @throws EE_Error
1487
-     */
1488
-    public function toggle_checkin_status($DTT_ID = null, $verify = false)
1489
-    {
1490
-        if (empty($DTT_ID)) {
1491
-            $datetime = $this->get_latest_related_datetime();
1492
-            $DTT_ID   = $datetime instanceof EE_Datetime ? $datetime->ID() : 0;
1493
-            // verify the registration can checkin for the given DTT_ID
1494
-        } elseif (! $this->can_checkin($DTT_ID, $verify)) {
1495
-            EE_Error::add_error(
1496
-                sprintf(
1497
-                    esc_html__(
1498
-                        'The given registration (ID:%1$d) can not be checked in to the given DTT_ID (%2$d), because the registration does not have access',
1499
-                        'event_espresso'
1500
-                    ),
1501
-                    $this->ID(),
1502
-                    $DTT_ID
1503
-                ),
1504
-                __FILE__,
1505
-                __FUNCTION__,
1506
-                __LINE__
1507
-            );
1508
-            return false;
1509
-        }
1510
-        $status_paths = array(
1511
-            EE_Checkin::status_checked_never => EE_Checkin::status_checked_in,
1512
-            EE_Checkin::status_checked_in    => EE_Checkin::status_checked_out,
1513
-            EE_Checkin::status_checked_out   => EE_Checkin::status_checked_in,
1514
-        );
1515
-        //start by getting the current status so we know what status we'll be changing to.
1516
-        $cur_status = $this->check_in_status_for_datetime($DTT_ID, null);
1517
-        $status_to  = $status_paths[$cur_status];
1518
-        // database only records true for checked IN or false for checked OUT
1519
-        // no record ( null ) means checked in NEVER, but we obviously don't save that
1520
-        $new_status = $status_to === EE_Checkin::status_checked_in ? true : false;
1521
-        // add relation - note Check-ins are always creating new rows
1522
-        // because we are keeping track of Check-ins over time.
1523
-        // Eventually we'll probably want to show a list table
1524
-        // for the individual Check-ins so that they can be managed.
1525
-        $checkin = EE_Checkin::new_instance(array(
1526
-            'REG_ID' => $this->ID(),
1527
-            'DTT_ID' => $DTT_ID,
1528
-            'CHK_in' => $new_status,
1529
-        ));
1530
-        // if the record could not be saved then return false
1531
-        if ($checkin->save() === 0) {
1532
-            if (WP_DEBUG) {
1533
-                global $wpdb;
1534
-                $error = sprintf(
1535
-                    esc_html__(
1536
-                        'Registration check in update failed because of the following database error: %1$s%2$s',
1537
-                        'event_espresso'
1538
-                    ),
1539
-                    '<br />',
1540
-                    $wpdb->last_error
1541
-                );
1542
-            } else {
1543
-                $error = esc_html__(
1544
-                    'Registration check in update failed because of an unknown database error',
1545
-                    'event_espresso'
1546
-                );
1547
-            }
1548
-            EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
1549
-            return false;
1550
-        }
1551
-        return $status_to;
1552
-    }
1553
-
1554
-
1555
-    /**
1556
-     * Returns the latest datetime related to this registration (via the ticket attached to the registration).
1557
-     * "Latest" is defined by the `DTT_EVT_start` column.
1558
-     *
1559
-     * @return EE_Datetime|null
1560
-     * @throws EE_Error
1561
-     */
1562
-    public function get_latest_related_datetime()
1563
-    {
1564
-        return EEM_Datetime::instance()->get_one(
1565
-            array(
1566
-                array(
1567
-                    'Ticket.Registration.REG_ID' => $this->ID(),
1568
-                ),
1569
-                'order_by' => array('DTT_EVT_start' => 'DESC'),
1570
-            )
1571
-        );
1572
-    }
1573
-
1574
-
1575
-    /**
1576
-     * Returns the earliest datetime related to this registration (via the ticket attached to the registration).
1577
-     * "Earliest" is defined by the `DTT_EVT_start` column.
1578
-     *
1579
-     * @throws EE_Error
1580
-     */
1581
-    public function get_earliest_related_datetime()
1582
-    {
1583
-        return EEM_Datetime::instance()->get_one(
1584
-            array(
1585
-                array(
1586
-                    'Ticket.Registration.REG_ID' => $this->ID(),
1587
-                ),
1588
-                'order_by' => array('DTT_EVT_start' => 'ASC'),
1589
-            )
1590
-        );
1591
-    }
1592
-
1593
-
1594
-    /**
1595
-     * This method simply returns the check-in status for this registration and the given datetime.
1596
-     * If neither the datetime nor the checkin values are provided as arguments,
1597
-     * then this will return the LATEST check-in status for the registration across all datetimes it belongs to.
1598
-     *
1599
-     * @param  int       $DTT_ID  The ID of the datetime we're checking against
1600
-     *                            (if empty we'll get the primary datetime for
1601
-     *                            this registration (via event) and use it's ID);
1602
-     * @param EE_Checkin $checkin If present, we use the given checkin object rather than the dtt_id.
1603
-     *
1604
-     * @return int                Integer representing Check-in status.
1605
-     * @throws EE_Error
1606
-     */
1607
-    public function check_in_status_for_datetime($DTT_ID = 0, $checkin = null)
1608
-    {
1609
-        $checkin_query_params = array(
1610
-            'order_by' => array('CHK_timestamp' => 'DESC'),
1611
-        );
1612
-
1613
-        if ($DTT_ID > 0) {
1614
-            $checkin_query_params[0] = array('DTT_ID' => $DTT_ID);
1615
-        }
1616
-
1617
-        //get checkin object (if exists)
1618
-        $checkin = $checkin instanceof EE_Checkin
1619
-            ? $checkin
1620
-            : $this->get_first_related('Checkin', $checkin_query_params);
1621
-        if ($checkin instanceof EE_Checkin) {
1622
-            if ($checkin->get('CHK_in')) {
1623
-                return EE_Checkin::status_checked_in; //checked in
1624
-            }
1625
-            return EE_Checkin::status_checked_out; //had checked in but is now checked out.
1626
-        }
1627
-        return EE_Checkin::status_checked_never; //never been checked in
1628
-    }
1629
-
1630
-
1631
-    /**
1632
-     * This method returns a localized message for the toggled Check-in message.
1633
-     *
1634
-     * @param  int $DTT_ID include specific datetime to get the correct Check-in message.  If not included or null,
1635
-     *                     then it is assumed Check-in for primary datetime was toggled.
1636
-     * @param bool $error  This just flags that you want an error message returned. This is put in so that the error
1637
-     *                     message can be customized with the attendee name.
1638
-     * @return string internationalized message
1639
-     * @throws EE_Error
1640
-     */
1641
-    public function get_checkin_msg($DTT_ID, $error = false)
1642
-    {
1643
-        //let's get the attendee first so we can include the name of the attendee
1644
-        $attendee = $this->get_first_related('Attendee');
1645
-        if ($attendee instanceof EE_Attendee) {
1646
-            if ($error) {
1647
-                return sprintf(__("%s's check-in status was not changed.", "event_espresso"), $attendee->full_name());
1648
-            }
1649
-            $cur_status = $this->check_in_status_for_datetime($DTT_ID);
1650
-            //what is the status message going to be?
1651
-            switch ($cur_status) {
1652
-                case EE_Checkin::status_checked_never:
1653
-                    return sprintf(__("%s has been removed from Check-in records", "event_espresso"),
1654
-                        $attendee->full_name());
1655
-                    break;
1656
-                case EE_Checkin::status_checked_in:
1657
-                    return sprintf(__('%s has been checked in', 'event_espresso'), $attendee->full_name());
1658
-                    break;
1659
-                case EE_Checkin::status_checked_out:
1660
-                    return sprintf(__('%s has been checked out', 'event_espresso'), $attendee->full_name());
1661
-                    break;
1662
-            }
1663
-        }
1664
-        return esc_html__("The check-in status could not be determined.", "event_espresso");
1665
-    }
1666
-
1667
-
1668
-    /**
1669
-     * Returns the related EE_Transaction to this registration
1670
-     *
1671
-     * @return EE_Transaction
1672
-     * @throws EE_Error
1673
-     * @throws EntityNotFoundException
1674
-     */
1675
-    public function transaction()
1676
-    {
1677
-        $transaction = $this->get_first_related('Transaction');
1678
-        if (! $transaction instanceof \EE_Transaction) {
1679
-            throw new EntityNotFoundException('Transaction ID', $this->transaction_ID());
1680
-        }
1681
-        return $transaction;
1682
-    }
1683
-
1684
-
1685
-    /**
1686
-     *        get Registration Code
1687
-     */
1688
-    public function reg_code()
1689
-    {
1690
-        return $this->get('REG_code');
1691
-    }
1692
-
1693
-
1694
-    /**
1695
-     *        get Transaction ID
1696
-     */
1697
-    public function transaction_ID()
1698
-    {
1699
-        return $this->get('TXN_ID');
1700
-    }
1701
-
1702
-
1703
-    /**
1704
-     * @return int
1705
-     * @throws EE_Error
1706
-     */
1707
-    public function ticket_ID()
1708
-    {
1709
-        return $this->get('TKT_ID');
1710
-    }
1711
-
1712
-
1713
-    /**
1714
-     *        Set Registration Code
1715
-     *
1716
-     * @access    public
1717
-     * @param    string  $REG_code Registration Code
1718
-     * @param    boolean $use_default
1719
-     * @throws EE_Error
1720
-     */
1721
-    public function set_reg_code($REG_code, $use_default = false)
1722
-    {
1723
-        if (empty($REG_code)) {
1724
-            EE_Error::add_error(
1725
-                esc_html__('REG_code can not be empty.', 'event_espresso'),
1726
-                __FILE__,
1727
-                __FUNCTION__,
1728
-                __LINE__
1729
-            );
1730
-            return;
1731
-        }
1732
-        if (! $this->reg_code()) {
1733
-            parent::set('REG_code', $REG_code, $use_default);
1734
-        } else {
1735
-            EE_Error::doing_it_wrong(
1736
-                __CLASS__ . '::' . __FUNCTION__,
1737
-                esc_html__('Can not change a registration REG_code once it has been set.', 'event_espresso'),
1738
-                '4.6.0'
1739
-            );
1740
-        }
1741
-    }
1742
-
1743
-
1744
-    /**
1745
-     * Returns all other registrations in the same group as this registrant who have the same ticket option.
1746
-     * Note, if you want to just get all registrations in the same transaction (group), use:
1747
-     *    $registration->transaction()->registrations();
1748
-     *
1749
-     * @since 4.5.0
1750
-     * @return EE_Registration[] or empty array if this isn't a group registration.
1751
-     * @throws EE_Error
1752
-     */
1753
-    public function get_all_other_registrations_in_group()
1754
-    {
1755
-        if ($this->group_size() < 2) {
1756
-            return array();
1757
-        }
1758
-
1759
-        $query[0] = array(
1760
-            'TXN_ID' => $this->transaction_ID(),
1761
-            'REG_ID' => array('!=', $this->ID()),
1762
-            'TKT_ID' => $this->ticket_ID(),
1763
-        );
1764
-        /** @var EE_Registration[] $registrations */
1765
-        $registrations = $this->get_model()->get_all($query);
1766
-        return $registrations;
1767
-    }
1768
-
1769
-    /**
1770
-     * Return the link to the admin details for the object.
1771
-     *
1772
-     * @return string
1773
-     * @throws EE_Error
1774
-     */
1775
-    public function get_admin_details_link()
1776
-    {
1777
-        EE_Registry::instance()->load_helper('URL');
1778
-        return EEH_URL::add_query_args_and_nonce(
1779
-            array(
1780
-                'page'    => 'espresso_registrations',
1781
-                'action'  => 'view_registration',
1782
-                '_REG_ID' => $this->ID(),
1783
-            ),
1784
-            admin_url('admin.php')
1785
-        );
1786
-    }
1787
-
1788
-    /**
1789
-     * Returns the link to the editor for the object.  Sometimes this is the same as the details.
1790
-     *
1791
-     * @return string
1792
-     * @throws EE_Error
1793
-     */
1794
-    public function get_admin_edit_link()
1795
-    {
1796
-        return $this->get_admin_details_link();
1797
-    }
1798
-
1799
-    /**
1800
-     * Returns the link to a settings page for the object.
1801
-     *
1802
-     * @return string
1803
-     * @throws EE_Error
1804
-     */
1805
-    public function get_admin_settings_link()
1806
-    {
1807
-        return $this->get_admin_details_link();
1808
-    }
1809
-
1810
-    /**
1811
-     * Returns the link to the "overview" for the object (typically the "list table" view).
1812
-     *
1813
-     * @return string
1814
-     */
1815
-    public function get_admin_overview_link()
1816
-    {
1817
-        EE_Registry::instance()->load_helper('URL');
1818
-        return EEH_URL::add_query_args_and_nonce(
1819
-            array(
1820
-                'page' => 'espresso_registrations',
1821
-            ),
1822
-            admin_url('admin.php')
1823
-        );
1824
-    }
1825
-
1826
-
1827
-    /**
1828
-     * @param array $query_params
1829
-     *
1830
-     * @return \EE_Registration[]
1831
-     * @throws EE_Error
1832
-     */
1833
-    public function payments($query_params = array())
1834
-    {
1835
-        return $this->get_many_related('Payment', $query_params);
1836
-    }
1837
-
1838
-
1839
-    /**
1840
-     * @param array $query_params
1841
-     *
1842
-     * @return \EE_Registration_Payment[]
1843
-     * @throws EE_Error
1844
-     */
1845
-    public function registration_payments($query_params = array())
1846
-    {
1847
-        return $this->get_many_related('Registration_Payment', $query_params);
1848
-    }
1849
-
1850
-
1851
-    /**
1852
-     * This grabs the payment method corresponding to the last payment made for the amount owing on the registration.
1853
-     * Note: if there are no payments on the registration there will be no payment method returned.
1854
-     *
1855
-     * @return EE_Payment_Method|null
1856
-     */
1857
-    public function payment_method()
1858
-    {
1859
-        return EEM_Payment_Method::instance()->get_last_used_for_registration($this);
1860
-    }
1861
-
1862
-
1863
-    /**
1864
-     * @return \EE_Line_Item
1865
-     * @throws EntityNotFoundException
1866
-     * @throws EE_Error
1867
-     */
1868
-    public function ticket_line_item()
1869
-    {
1870
-        $ticket            = $this->ticket();
1871
-        $transaction       = $this->transaction();
1872
-        $line_item         = null;
1873
-        $ticket_line_items = \EEH_Line_Item::get_line_items_by_object_type_and_IDs(
1874
-            $transaction->total_line_item(),
1875
-            'Ticket',
1876
-            array($ticket->ID())
1877
-        );
1878
-        foreach ($ticket_line_items as $ticket_line_item) {
1879
-            if (
1880
-                $ticket_line_item instanceof \EE_Line_Item
1881
-                && $ticket_line_item->OBJ_type() === 'Ticket'
1882
-                && $ticket_line_item->OBJ_ID() === $ticket->ID()
1883
-            ) {
1884
-                $line_item = $ticket_line_item;
1885
-                break;
1886
-            }
1887
-        }
1888
-        if (! ($line_item instanceof \EE_Line_Item && $line_item->OBJ_type() === 'Ticket')) {
1889
-            throw new EntityNotFoundException('Line Item Ticket ID', $ticket->ID());
1890
-        }
1891
-        return $line_item;
1892
-    }
1893
-
1894
-
1895
-    /**
1896
-     * Soft Deletes this model object.
1897
-     *
1898
-     * @return boolean | int
1899
-     * @throws RuntimeException
1900
-     * @throws EE_Error
1901
-     */
1902
-    public function delete()
1903
-    {
1904
-        if ($this->update_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY, $this->status_ID()) === true) {
1905
-            $this->set_status(EEM_Registration::status_id_cancelled);
1906
-        }
1907
-        return parent::delete();
1908
-    }
1909
-
1910
-
1911
-    /**
1912
-     * Restores whatever the previous status was on a registration before it was trashed (if possible)
1913
-     *
1914
-     * @throws EE_Error
1915
-     * @throws RuntimeException
1916
-     */
1917
-    public function restore()
1918
-    {
1919
-        $previous_status = $this->get_extra_meta(
1920
-            EE_Registration::PRE_TRASH_REG_STATUS_KEY,
1921
-            true,
1922
-            EEM_Registration::status_id_cancelled
1923
-        );
1924
-        if ($previous_status) {
1925
-            $this->delete_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY);
1926
-            $this->set_status($previous_status);
1927
-        }
1928
-        return parent::restore();
1929
-    }
1930
-
1931
-
1932
-    /**
1933
-     * possibly toggle Registration status based on comparison of REG_paid vs REG_final_price
1934
-     *
1935
-     * @param  boolean $trigger_set_status_logic EE_Registration::set_status() can trigger additional logic
1936
-     *                                           depending on whether the reg status changes to or from "Approved"
1937
-     * @return boolean whether the Registration status was updated
1938
-     * @throws EE_Error
1939
-     * @throws RuntimeException
1940
-     */
1941
-    public function updateStatusBasedOnTotalPaid($trigger_set_status_logic = true)
1942
-    {
1943
-        $paid = $this->paid();
1944
-        $price = $this->final_price();
1945
-        switch(true) {
1946
-            // overpaid or paid
1947
-            case EEH_Money::compare_floats($paid, $price, '>'):
1948
-            case EEH_Money::compare_floats($paid, $price):
1949
-                $new_status = EEM_Registration::status_id_approved;
1950
-                break;
1951
-            //  underpaid
1952
-            case EEH_Money::compare_floats($paid, $price, '<'):
1953
-                $new_status = EEM_Registration::status_id_pending_payment;
1954
-                break;
1955
-            // uhhh Houston...
1956
-            default:
1957
-                throw new RuntimeException(
1958
-                    esc_html__('The total paid calculation for this registration is inaccurate.', 'event_espresso')
1959
-                );
1960
-        }
1961
-        if ($new_status !== $this->status_ID()) {
1962
-            if ($trigger_set_status_logic) {
1963
-                return $this->set_status($new_status);
1964
-            }
1965
-            parent::set('STS_ID', $new_status);
1966
-            return true;
1967
-        }
1968
-        return false;
1969
-    }
1970
-
1971
-
1972
-    /*************************** DEPRECATED ***************************/
1973
-
1974
-
1975
-    /**
1976
-     * @deprecated
1977
-     * @since     4.7.0
1978
-     * @access    public
1979
-     */
1980
-    public function price_paid()
1981
-    {
1982
-        EE_Error::doing_it_wrong('EE_Registration::price_paid()',
1983
-            esc_html__('This method is deprecated, please use EE_Registration::final_price() instead.', 'event_espresso'),
1984
-            '4.7.0');
1985
-        return $this->final_price();
1986
-    }
1987
-
1988
-
1989
-    /**
1990
-     * @deprecated
1991
-     * @since     4.7.0
1992
-     * @access    public
1993
-     * @param    float $REG_final_price
1994
-     * @throws EE_Error
1995
-     * @throws RuntimeException
1996
-     */
1997
-    public function set_price_paid($REG_final_price = 0.00)
1998
-    {
1999
-        EE_Error::doing_it_wrong('EE_Registration::set_price_paid()',
2000
-            esc_html__('This method is deprecated, please use EE_Registration::set_final_price() instead.', 'event_espresso'),
2001
-            '4.7.0');
2002
-        $this->set_final_price($REG_final_price);
2003
-    }
2004
-
2005
-
2006
-    /**
2007
-     * @deprecated
2008
-     * @since 4.7.0
2009
-     * @return string
2010
-     * @throws EE_Error
2011
-     */
2012
-    public function pretty_price_paid()
2013
-    {
2014
-        EE_Error::doing_it_wrong('EE_Registration::pretty_price_paid()',
2015
-            esc_html__('This method is deprecated, please use EE_Registration::pretty_final_price() instead.',
2016
-                'event_espresso'), '4.7.0');
2017
-        return $this->pretty_final_price();
2018
-    }
2019
-
2020
-
2021
-    /**
2022
-     * Gets the primary datetime related to this registration via the related Event to this registration
2023
-     *
2024
-     * @deprecated 4.9.17
2025
-     * @return EE_Datetime
2026
-     * @throws EE_Error
2027
-     * @throws EntityNotFoundException
2028
-     */
2029
-    public function get_related_primary_datetime()
2030
-    {
2031
-        EE_Error::doing_it_wrong(
2032
-            __METHOD__,
2033
-            esc_html__(
2034
-                'Use EE_Registration::get_latest_related_datetime() or EE_Registration::get_earliest_related_datetime()',
2035
-                'event_espresso'
2036
-            ),
2037
-            '4.9.17',
2038
-            '5.0.0'
2039
-        );
2040
-        return $this->event()->primary_datetime();
2041
-    }
21
+	/**
22
+	 * Used to reference when a registration has never been checked in.
23
+	 *
24
+	 * @deprecated use \EE_Checkin::status_checked_never instead
25
+	 * @type int
26
+	 */
27
+	const checkin_status_never = 2;
28
+
29
+	/**
30
+	 * Used to reference when a registration has been checked in.
31
+	 *
32
+	 * @deprecated use \EE_Checkin::status_checked_in instead
33
+	 * @type int
34
+	 */
35
+	const checkin_status_in = 1;
36
+
37
+
38
+	/**
39
+	 * Used to reference when a registration has been checked out.
40
+	 *
41
+	 * @deprecated use \EE_Checkin::status_checked_out instead
42
+	 * @type int
43
+	 */
44
+	const checkin_status_out = 0;
45
+
46
+
47
+	/**
48
+	 * extra meta key for tracking reg status os trashed registrations
49
+	 *
50
+	 * @type string
51
+	 */
52
+	const PRE_TRASH_REG_STATUS_KEY = 'pre_trash_registration_status';
53
+
54
+
55
+	/**
56
+	 * extra meta key for tracking if registration has reserved ticket
57
+	 *
58
+	 * @type string
59
+	 */
60
+	const HAS_RESERVED_TICKET_KEY = 'has_reserved_ticket';
61
+
62
+
63
+	/**
64
+	 * @param array  $props_n_values          incoming values
65
+	 * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
66
+	 *                                        used.)
67
+	 * @param array  $date_formats            incoming date_formats in an array where the first value is the
68
+	 *                                        date_format and the second value is the time format
69
+	 * @return EE_Registration
70
+	 * @throws EE_Error
71
+	 */
72
+	public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array())
73
+	{
74
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
75
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
76
+	}
77
+
78
+
79
+	/**
80
+	 * @param array  $props_n_values  incoming values from the database
81
+	 * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
82
+	 *                                the website will be used.
83
+	 * @return EE_Registration
84
+	 */
85
+	public static function new_instance_from_db($props_n_values = array(), $timezone = null)
86
+	{
87
+		return new self($props_n_values, true, $timezone);
88
+	}
89
+
90
+
91
+	/**
92
+	 *        Set Event ID
93
+	 *
94
+	 * @param        int $EVT_ID Event ID
95
+	 * @throws EE_Error
96
+	 * @throws RuntimeException
97
+	 */
98
+	public function set_event($EVT_ID = 0)
99
+	{
100
+		$this->set('EVT_ID', $EVT_ID);
101
+	}
102
+
103
+
104
+	/**
105
+	 * Overrides parent set() method so that all calls to set( 'REG_code', $REG_code ) OR set( 'STS_ID', $STS_ID ) can
106
+	 * be routed to internal methods
107
+	 *
108
+	 * @param string $field_name
109
+	 * @param mixed  $field_value
110
+	 * @param bool   $use_default
111
+	 * @throws EE_Error
112
+	 * @throws EntityNotFoundException
113
+	 * @throws InvalidArgumentException
114
+	 * @throws InvalidDataTypeException
115
+	 * @throws InvalidInterfaceException
116
+	 * @throws ReflectionException
117
+	 * @throws RuntimeException
118
+	 */
119
+	public function set($field_name, $field_value, $use_default = false)
120
+	{
121
+		switch ($field_name) {
122
+			case 'REG_code':
123
+				if (! empty($field_value) && $this->reg_code() === null) {
124
+					$this->set_reg_code($field_value, $use_default);
125
+				}
126
+				break;
127
+			case 'STS_ID':
128
+				$this->set_status($field_value, $use_default);
129
+				break;
130
+			default:
131
+				parent::set($field_name, $field_value, $use_default);
132
+		}
133
+	}
134
+
135
+
136
+	/**
137
+	 * Set Status ID
138
+	 * updates the registration status and ALSO...
139
+	 * calls reserve_registration_space() if the reg status changes TO approved from any other reg status
140
+	 * calls release_registration_space() if the reg status changes FROM approved to any other reg status
141
+	 *
142
+	 * @param string       $new_STS_ID
143
+	 * @param boolean      $use_default
144
+	 * @param ContextInterface|null $context
145
+	 * @return bool
146
+	 * @throws EE_Error
147
+	 * @throws EntityNotFoundException
148
+	 * @throws InvalidArgumentException
149
+	 * @throws ReflectionException
150
+	 * @throws RuntimeException
151
+	 * @throws InvalidDataTypeException
152
+	 * @throws InvalidInterfaceException
153
+	 */
154
+	public function set_status($new_STS_ID = null, $use_default = false, ContextInterface $context = null)
155
+	{
156
+		// get current REG_Status
157
+		$old_STS_ID = $this->status_ID();
158
+		// if status has changed
159
+		if ($old_STS_ID !== $new_STS_ID // and that status has actually changed
160
+			&& ! empty($old_STS_ID) // and that old status is actually set
161
+			&& ! empty($new_STS_ID) // as well as the new status
162
+			&& $this->ID() // ensure registration is in the db
163
+		) {
164
+			// TO approved
165
+			if ($new_STS_ID === EEM_Registration::status_id_approved) {
166
+				// reserve a space by incrementing ticket and datetime sold values
167
+				$this->_reserve_registration_space();
168
+				do_action('AHEE__EE_Registration__set_status__to_approved', $this, $old_STS_ID, $new_STS_ID, $context);
169
+				// OR FROM  approved
170
+			} elseif ($old_STS_ID === EEM_Registration::status_id_approved) {
171
+				// release a space by decrementing ticket and datetime sold values
172
+				$this->_release_registration_space();
173
+				do_action(
174
+					'AHEE__EE_Registration__set_status__from_approved',
175
+					$this,
176
+					$old_STS_ID,
177
+					$new_STS_ID,
178
+					$context
179
+				);
180
+			}
181
+			// update status
182
+			parent::set('STS_ID', $new_STS_ID, $use_default);
183
+			$this->_update_if_canceled_or_declined($new_STS_ID, $old_STS_ID, $context);
184
+			if($this->statusChangeUpdatesTransaction($context)) {
185
+				$this->updateTransactionAfterStatusChange();
186
+			}
187
+			do_action('AHEE__EE_Registration__set_status__after_update', $this, $old_STS_ID, $new_STS_ID, $context);
188
+			return true;
189
+		}
190
+		//even though the old value matches the new value, it's still good to
191
+		//allow the parent set method to have a say
192
+		parent::set('STS_ID', $new_STS_ID, $use_default);
193
+		return true;
194
+	}
195
+
196
+
197
+	/**
198
+	 * update REGs and TXN when cancelled or declined registrations involved
199
+	 *
200
+	 * @param string       $new_STS_ID
201
+	 * @param string       $old_STS_ID
202
+	 * @param ContextInterface|null $context
203
+	 * @throws EE_Error
204
+	 * @throws InvalidArgumentException
205
+	 * @throws InvalidDataTypeException
206
+	 * @throws InvalidInterfaceException
207
+	 * @throws ReflectionException
208
+	 */
209
+	private function _update_if_canceled_or_declined($new_STS_ID, $old_STS_ID, ContextInterface $context = null)
210
+	{
211
+		// these reg statuses should not be considered in any calculations involving monies owing
212
+		$closed_reg_statuses = EEM_Registration::closed_reg_statuses();
213
+		// true if registration has been cancelled or declined
214
+		$this->updateIfCanceled(
215
+			$closed_reg_statuses,
216
+			$new_STS_ID,
217
+			$old_STS_ID,
218
+			$context
219
+		);
220
+		$this->updateIfDeclined(
221
+			$closed_reg_statuses,
222
+			$new_STS_ID,
223
+			$old_STS_ID,
224
+			$context
225
+		);
226
+	}
227
+
228
+
229
+	/**
230
+	 * update REGs and TXN when cancelled or declined registrations involved
231
+	 *
232
+	 * @param array        $closed_reg_statuses
233
+	 * @param string       $new_STS_ID
234
+	 * @param string       $old_STS_ID
235
+	 * @param ContextInterface|null $context
236
+	 * @throws EE_Error
237
+	 * @throws InvalidArgumentException
238
+	 * @throws InvalidDataTypeException
239
+	 * @throws InvalidInterfaceException
240
+	 * @throws ReflectionException
241
+	 */
242
+	private function updateIfCanceled(array $closed_reg_statuses, $new_STS_ID, $old_STS_ID, ContextInterface $context = null)
243
+	{
244
+		// true if registration has been cancelled or declined
245
+		if (in_array($new_STS_ID, $closed_reg_statuses, true)
246
+			&& ! in_array($old_STS_ID, $closed_reg_statuses, true)
247
+		) {
248
+			/** @type EE_Registration_Processor $registration_processor */
249
+			$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
250
+			/** @type EE_Transaction_Processor $transaction_processor */
251
+			$transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
252
+			// cancelled or declined registration
253
+			$registration_processor->update_registration_after_being_canceled_or_declined(
254
+				$this,
255
+				$closed_reg_statuses
256
+			);
257
+			$transaction_processor->update_transaction_after_canceled_or_declined_registration(
258
+				$this,
259
+				$closed_reg_statuses,
260
+				false
261
+			);
262
+			do_action(
263
+				'AHEE__EE_Registration__set_status__canceled_or_declined',
264
+				$this,
265
+				$old_STS_ID,
266
+				$new_STS_ID,
267
+				$context
268
+			);
269
+			return;
270
+		}
271
+	}
272
+
273
+
274
+	/**
275
+	 * update REGs and TXN when cancelled or declined registrations involved
276
+	 *
277
+	 * @param array        $closed_reg_statuses
278
+	 * @param string       $new_STS_ID
279
+	 * @param string       $old_STS_ID
280
+	 * @param ContextInterface|null $context
281
+	 * @throws EE_Error
282
+	 * @throws InvalidArgumentException
283
+	 * @throws InvalidDataTypeException
284
+	 * @throws InvalidInterfaceException
285
+	 * @throws ReflectionException
286
+	 */
287
+	private function updateIfDeclined(array $closed_reg_statuses, $new_STS_ID, $old_STS_ID, ContextInterface $context = null)
288
+	{
289
+		// true if reinstating cancelled or declined registration
290
+		if (in_array($old_STS_ID, $closed_reg_statuses, true)
291
+			&& ! in_array($new_STS_ID, $closed_reg_statuses, true)
292
+		) {
293
+			/** @type EE_Registration_Processor $registration_processor */
294
+			$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
295
+			/** @type EE_Transaction_Processor $transaction_processor */
296
+			$transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
297
+			// reinstating cancelled or declined registration
298
+			$registration_processor->update_canceled_or_declined_registration_after_being_reinstated(
299
+				$this,
300
+				$closed_reg_statuses
301
+			);
302
+			$transaction_processor->update_transaction_after_reinstating_canceled_registration(
303
+				$this,
304
+				$closed_reg_statuses,
305
+				false
306
+			);
307
+			do_action(
308
+				'AHEE__EE_Registration__set_status__after_reinstated',
309
+				$this,
310
+				$old_STS_ID,
311
+				$new_STS_ID,
312
+				$context
313
+			);
314
+		}
315
+	}
316
+
317
+
318
+	/**
319
+	 * @param ContextInterface|null $context
320
+	 * @return bool
321
+	 */
322
+	private function statusChangeUpdatesTransaction(ContextInterface $context = null)
323
+	{
324
+		$contexts_that_do_not_update_transaction = (array) apply_filters(
325
+			'AHEE__EE_Registration__statusChangeUpdatesTransaction__contexts_that_do_not_update_transaction',
326
+			array('spco_reg_step_attendee_information_process_registrations'),
327
+			$context,
328
+			$this
329
+		);
330
+		return ! (
331
+			$context instanceof ContextInterface
332
+			&& in_array($context->slug(), $contexts_that_do_not_update_transaction, true)
333
+		);
334
+	}
335
+
336
+
337
+	/**
338
+	 * @throws EE_Error
339
+	 * @throws EntityNotFoundException
340
+	 * @throws InvalidArgumentException
341
+	 * @throws InvalidDataTypeException
342
+	 * @throws InvalidInterfaceException
343
+	 * @throws ReflectionException
344
+	 * @throws RuntimeException
345
+	 */
346
+	private function updateTransactionAfterStatusChange()
347
+	{
348
+		/** @type EE_Transaction_Payments $transaction_payments */
349
+		$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
350
+		$transaction_payments->recalculate_transaction_total($this->transaction(), false);
351
+		$this->transaction()->update_status_based_on_total_paid(true);
352
+	}
353
+
354
+
355
+	/**
356
+	 *        get Status ID
357
+	 */
358
+	public function status_ID()
359
+	{
360
+		return $this->get('STS_ID');
361
+	}
362
+
363
+
364
+	/**
365
+	 * increments this registration's related ticket sold and corresponding datetime sold values
366
+	 *
367
+	 * @return void
368
+	 * @throws EE_Error
369
+	 * @throws EntityNotFoundException
370
+	 */
371
+	private function _reserve_registration_space()
372
+	{
373
+		// reserved ticket and datetime counts will be decremented as sold counts are incremented
374
+		// so stop tracking that this reg has a ticket reserved
375
+		$this->release_reserved_ticket();
376
+		$ticket = $this->ticket();
377
+		$ticket->increase_sold();
378
+		$ticket->save();
379
+		// possibly set event status to sold out
380
+		$this->event()->perform_sold_out_status_check();
381
+	}
382
+
383
+
384
+	/**
385
+	 * Gets the ticket this registration is for
386
+	 *
387
+	 * @param boolean $include_archived whether to include archived tickets or not.
388
+	 *
389
+	 * @return EE_Ticket|EE_Base_Class
390
+	 * @throws EE_Error
391
+	 */
392
+	public function ticket($include_archived = true)
393
+	{
394
+		$query_params = array();
395
+		if ($include_archived) {
396
+			$query_params['default_where_conditions'] = 'none';
397
+		}
398
+		return $this->get_first_related('Ticket', $query_params);
399
+	}
400
+
401
+
402
+	/**
403
+	 * Gets the event this registration is for
404
+	 *
405
+	 * @return EE_Event
406
+	 * @throws EE_Error
407
+	 * @throws EntityNotFoundException
408
+	 */
409
+	public function event()
410
+	{
411
+		$event = $this->get_first_related('Event');
412
+		if (! $event instanceof \EE_Event) {
413
+			throw new EntityNotFoundException('Event ID', $this->event_ID());
414
+		}
415
+		return $event;
416
+	}
417
+
418
+
419
+	/**
420
+	 * Gets the "author" of the registration.  Note that for the purposes of registrations, the author will correspond
421
+	 * with the author of the event this registration is for.
422
+	 *
423
+	 * @since 4.5.0
424
+	 * @return int
425
+	 * @throws EE_Error
426
+	 * @throws EntityNotFoundException
427
+	 */
428
+	public function wp_user()
429
+	{
430
+		$event = $this->event();
431
+		if ($event instanceof EE_Event) {
432
+			return $event->wp_user();
433
+		}
434
+		return 0;
435
+	}
436
+
437
+
438
+	/**
439
+	 * decrements (subtracts) this registration's related ticket sold and corresponding datetime sold values
440
+	 *
441
+	 * @return void
442
+	 * @throws EE_Error
443
+	 */
444
+	private function _release_registration_space()
445
+	{
446
+		$ticket = $this->ticket();
447
+		$ticket->decrease_sold();
448
+		$ticket->save();
449
+	}
450
+
451
+
452
+	/**
453
+	 * tracks this registration's ticket reservation in extra meta
454
+	 * and can increment related ticket reserved and corresponding datetime reserved values
455
+	 *
456
+	 * @param bool $update_ticket if true, will increment ticket and datetime reserved count
457
+	 *
458
+	 * @return void
459
+	 * @throws EE_Error
460
+	 */
461
+	public function reserve_ticket($update_ticket = false)
462
+	{
463
+		if ($this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true, false) === false) {
464
+			// PLZ NOTE: although checking $update_ticket first would be more efficient,
465
+			// we NEED to ALWAYS call update_extra_meta(), which is why that is done first
466
+			if ($this->update_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true, false) && $update_ticket) {
467
+				$ticket = $this->ticket();
468
+				$ticket->increase_reserved();
469
+				$ticket->save();
470
+			}
471
+		}
472
+	}
473
+
474
+
475
+	/**
476
+	 * stops tracking this registration's ticket reservation in extra meta
477
+	 * decrements (subtracts) related ticket reserved and corresponding datetime reserved values
478
+	 *
479
+	 * @param bool $update_ticket if true, will decrement ticket and datetime reserved count
480
+	 *
481
+	 * @return void
482
+	 * @throws EE_Error
483
+	 */
484
+	public function release_reserved_ticket($update_ticket = false)
485
+	{
486
+		if ($this->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true, false) !== false) {
487
+			// PLZ NOTE: although checking $update_ticket first would be more efficient,
488
+			// we NEED to ALWAYS call delete_extra_meta(), which is why that is done first
489
+			if ($this->delete_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY) && $update_ticket) {
490
+				$ticket = $this->ticket();
491
+				$ticket->decrease_reserved();
492
+				$ticket->save();
493
+			}
494
+		}
495
+	}
496
+
497
+
498
+	/**
499
+	 * Set Attendee ID
500
+	 *
501
+	 * @param        int $ATT_ID Attendee ID
502
+	 * @throws EE_Error
503
+	 * @throws RuntimeException
504
+	 */
505
+	public function set_attendee_id($ATT_ID = 0)
506
+	{
507
+		$this->set('ATT_ID', $ATT_ID);
508
+	}
509
+
510
+
511
+	/**
512
+	 *        Set Transaction ID
513
+	 *
514
+	 * @param        int $TXN_ID Transaction ID
515
+	 * @throws EE_Error
516
+	 * @throws RuntimeException
517
+	 */
518
+	public function set_transaction_id($TXN_ID = 0)
519
+	{
520
+		$this->set('TXN_ID', $TXN_ID);
521
+	}
522
+
523
+
524
+	/**
525
+	 *        Set Session
526
+	 *
527
+	 * @param    string $REG_session PHP Session ID
528
+	 * @throws EE_Error
529
+	 * @throws RuntimeException
530
+	 */
531
+	public function set_session($REG_session = '')
532
+	{
533
+		$this->set('REG_session', $REG_session);
534
+	}
535
+
536
+
537
+	/**
538
+	 *        Set Registration URL Link
539
+	 *
540
+	 * @param    string $REG_url_link Registration URL Link
541
+	 * @throws EE_Error
542
+	 * @throws RuntimeException
543
+	 */
544
+	public function set_reg_url_link($REG_url_link = '')
545
+	{
546
+		$this->set('REG_url_link', $REG_url_link);
547
+	}
548
+
549
+
550
+	/**
551
+	 *        Set Attendee Counter
552
+	 *
553
+	 * @param        int $REG_count Primary Attendee
554
+	 * @throws EE_Error
555
+	 * @throws RuntimeException
556
+	 */
557
+	public function set_count($REG_count = 1)
558
+	{
559
+		$this->set('REG_count', $REG_count);
560
+	}
561
+
562
+
563
+	/**
564
+	 *        Set Group Size
565
+	 *
566
+	 * @param        boolean $REG_group_size Group Registration
567
+	 * @throws EE_Error
568
+	 * @throws RuntimeException
569
+	 */
570
+	public function set_group_size($REG_group_size = false)
571
+	{
572
+		$this->set('REG_group_size', $REG_group_size);
573
+	}
574
+
575
+
576
+	/**
577
+	 *    is_not_approved -  convenience method that returns TRUE if REG status ID ==
578
+	 *    EEM_Registration::status_id_not_approved
579
+	 *
580
+	 * @return        boolean
581
+	 */
582
+	public function is_not_approved()
583
+	{
584
+		return $this->status_ID() == EEM_Registration::status_id_not_approved ? true : false;
585
+	}
586
+
587
+
588
+	/**
589
+	 *    is_pending_payment -  convenience method that returns TRUE if REG status ID ==
590
+	 *    EEM_Registration::status_id_pending_payment
591
+	 *
592
+	 * @return        boolean
593
+	 */
594
+	public function is_pending_payment()
595
+	{
596
+		return $this->status_ID() == EEM_Registration::status_id_pending_payment ? true : false;
597
+	}
598
+
599
+
600
+	/**
601
+	 *    is_approved -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_approved
602
+	 *
603
+	 * @return        boolean
604
+	 */
605
+	public function is_approved()
606
+	{
607
+		return $this->status_ID() == EEM_Registration::status_id_approved ? true : false;
608
+	}
609
+
610
+
611
+	/**
612
+	 *    is_cancelled -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_cancelled
613
+	 *
614
+	 * @return        boolean
615
+	 */
616
+	public function is_cancelled()
617
+	{
618
+		return $this->status_ID() == EEM_Registration::status_id_cancelled ? true : false;
619
+	}
620
+
621
+
622
+	/**
623
+	 *    is_declined -  convenience method that returns TRUE if REG status ID == EEM_Registration::status_id_declined
624
+	 *
625
+	 * @return        boolean
626
+	 */
627
+	public function is_declined()
628
+	{
629
+		return $this->status_ID() == EEM_Registration::status_id_declined ? true : false;
630
+	}
631
+
632
+
633
+	/**
634
+	 *    is_incomplete -  convenience method that returns TRUE if REG status ID ==
635
+	 *    EEM_Registration::status_id_incomplete
636
+	 *
637
+	 * @return        boolean
638
+	 */
639
+	public function is_incomplete()
640
+	{
641
+		return $this->status_ID() == EEM_Registration::status_id_incomplete ? true : false;
642
+	}
643
+
644
+
645
+	/**
646
+	 *        Set Registration Date
647
+	 *
648
+	 * @param        mixed ( int or string ) $REG_date Registration Date - Unix timestamp or string representation of
649
+	 *                                                 Date
650
+	 * @throws EE_Error
651
+	 * @throws RuntimeException
652
+	 */
653
+	public function set_reg_date($REG_date = false)
654
+	{
655
+		$this->set('REG_date', $REG_date);
656
+	}
657
+
658
+
659
+	/**
660
+	 *    Set final price owing for this registration after all ticket/price modifications
661
+	 *
662
+	 * @access    public
663
+	 * @param    float $REG_final_price
664
+	 * @throws EE_Error
665
+	 * @throws RuntimeException
666
+	 */
667
+	public function set_final_price($REG_final_price = 0.00)
668
+	{
669
+		$this->set('REG_final_price', $REG_final_price);
670
+	}
671
+
672
+
673
+	/**
674
+	 *    Set amount paid towards this registration's final price
675
+	 *
676
+	 * @access    public
677
+	 * @param    float $REG_paid
678
+	 * @throws EE_Error
679
+	 * @throws RuntimeException
680
+	 */
681
+	public function set_paid($REG_paid = 0.00)
682
+	{
683
+		$this->set('REG_paid', $REG_paid);
684
+	}
685
+
686
+
687
+	/**
688
+	 *        Attendee Is Going
689
+	 *
690
+	 * @param        boolean $REG_att_is_going Attendee Is Going
691
+	 * @throws EE_Error
692
+	 * @throws RuntimeException
693
+	 */
694
+	public function set_att_is_going($REG_att_is_going = false)
695
+	{
696
+		$this->set('REG_att_is_going', $REG_att_is_going);
697
+	}
698
+
699
+
700
+	/**
701
+	 * Gets the related attendee
702
+	 *
703
+	 * @return EE_Attendee
704
+	 * @throws EE_Error
705
+	 */
706
+	public function attendee()
707
+	{
708
+		return $this->get_first_related('Attendee');
709
+	}
710
+
711
+
712
+	/**
713
+	 *        get Event ID
714
+	 */
715
+	public function event_ID()
716
+	{
717
+		return $this->get('EVT_ID');
718
+	}
719
+
720
+
721
+	/**
722
+	 *        get Event ID
723
+	 */
724
+	public function event_name()
725
+	{
726
+		$event = $this->event_obj();
727
+		if ($event) {
728
+			return $event->name();
729
+		} else {
730
+			return null;
731
+		}
732
+	}
733
+
734
+
735
+	/**
736
+	 * Fetches the event this registration is for
737
+	 *
738
+	 * @return EE_Event
739
+	 * @throws EE_Error
740
+	 */
741
+	public function event_obj()
742
+	{
743
+		return $this->get_first_related('Event');
744
+	}
745
+
746
+
747
+	/**
748
+	 *        get Attendee ID
749
+	 */
750
+	public function attendee_ID()
751
+	{
752
+		return $this->get('ATT_ID');
753
+	}
754
+
755
+
756
+	/**
757
+	 *        get PHP Session ID
758
+	 */
759
+	public function session_ID()
760
+	{
761
+		return $this->get('REG_session');
762
+	}
763
+
764
+
765
+	/**
766
+	 * Gets the string which represents the URL trigger for the receipt template in the message template system.
767
+	 *
768
+	 * @param string $messenger 'pdf' or 'html'.  Default 'html'.
769
+	 * @return string
770
+	 */
771
+	public function receipt_url($messenger = 'html')
772
+	{
773
+
774
+		/**
775
+		 * The below will be deprecated one version after this.  We check first if there is a custom receipt template
776
+		 * already in use on old system.  If there is then we just return the standard url for it.
777
+		 *
778
+		 * @since 4.5.0
779
+		 */
780
+		$template_relative_path = 'modules/gateways/Invoice/lib/templates/receipt_body.template.php';
781
+		$has_custom             = EEH_Template::locate_template(
782
+			$template_relative_path,
783
+			array(),
784
+			true,
785
+			true,
786
+			true
787
+		);
788
+
789
+		if ($has_custom) {
790
+			return add_query_arg(array('receipt' => 'true'), $this->invoice_url('launch'));
791
+		}
792
+		return apply_filters('FHEE__EE_Registration__receipt_url__receipt_url', '', $this, $messenger, 'receipt');
793
+	}
794
+
795
+
796
+	/**
797
+	 * Gets the string which represents the URL trigger for the invoice template in the message template system.
798
+	 *
799
+	 * @param string $messenger 'pdf' or 'html'.  Default 'html'.
800
+	 * @return string
801
+	 * @throws EE_Error
802
+	 */
803
+	public function invoice_url($messenger = 'html')
804
+	{
805
+		/**
806
+		 * The below will be deprecated one version after this.  We check first if there is a custom invoice template
807
+		 * already in use on old system.  If there is then we just return the standard url for it.
808
+		 *
809
+		 * @since 4.5.0
810
+		 */
811
+		$template_relative_path = 'modules/gateways/Invoice/lib/templates/invoice_body.template.php';
812
+		$has_custom             = EEH_Template::locate_template(
813
+			$template_relative_path,
814
+			array(),
815
+			true,
816
+			true,
817
+			true
818
+		);
819
+
820
+		if ($has_custom) {
821
+			if ($messenger == 'html') {
822
+				return $this->invoice_url('launch');
823
+			}
824
+			$route = $messenger == 'download' || $messenger == 'pdf' ? 'download_invoice' : 'launch_invoice';
825
+
826
+			$query_args = array('ee' => $route, 'id' => $this->reg_url_link());
827
+			if ($messenger == 'html') {
828
+				$query_args['html'] = true;
829
+			}
830
+			return add_query_arg($query_args, get_permalink(EE_Registry::instance()->CFG->core->thank_you_page_id));
831
+		}
832
+		return apply_filters('FHEE__EE_Registration__invoice_url__invoice_url', '', $this, $messenger, 'invoice');
833
+	}
834
+
835
+
836
+	/**
837
+	 * get Registration URL Link
838
+	 *
839
+	 * @access public
840
+	 * @return string
841
+	 * @throws EE_Error
842
+	 */
843
+	public function reg_url_link()
844
+	{
845
+		return (string) $this->get('REG_url_link');
846
+	}
847
+
848
+
849
+	/**
850
+	 * Echoes out invoice_url()
851
+	 *
852
+	 * @param string $type 'download','launch', or 'html' (default is 'launch')
853
+	 * @return void
854
+	 * @throws EE_Error
855
+	 */
856
+	public function e_invoice_url($type = 'launch')
857
+	{
858
+		echo $this->invoice_url($type);
859
+	}
860
+
861
+
862
+	/**
863
+	 * Echoes out payment_overview_url
864
+	 */
865
+	public function e_payment_overview_url()
866
+	{
867
+		echo $this->payment_overview_url();
868
+	}
869
+
870
+
871
+	/**
872
+	 * Gets the URL for the checkout payment options reg step
873
+	 * with this registration's REG_url_link added as a query parameter
874
+	 *
875
+	 * @param bool $clear_session Set to true when you want to clear the session on revisiting the
876
+	 *                            payment overview url.
877
+	 * @return string
878
+	 * @throws InvalidInterfaceException
879
+	 * @throws InvalidDataTypeException
880
+	 * @throws EE_Error
881
+	 * @throws InvalidArgumentException
882
+	 * @throws EntityNotFoundException
883
+	 */
884
+	public function payment_overview_url($clear_session = false)
885
+	{
886
+		$payment_overview_url = add_query_arg(
887
+			(array) apply_filters(
888
+				'FHEE__EE_Registration__payment_overview_url__query_args',
889
+				array(
890
+					'e_reg_url_link' => $this->reg_url_link(),
891
+					'step'           => 'payment_options',
892
+					'revisit'        => true,
893
+					'clear_session'  => (bool) $clear_session,
894
+				),
895
+				$this
896
+			),
897
+			EE_Registry::instance()->CFG->core->reg_page_url()
898
+		);
899
+		EE_Log::logTxn(
900
+			__CLASS__, __FUNCTION__, __LINE__,
901
+			$this->transaction(),
902
+			array(
903
+				'REG_ID'               => $this->ID(),
904
+				'e_reg_url_link'       => $this->reg_url_link(),
905
+				'payment_overview_url' => $payment_overview_url,
906
+			)
907
+		);
908
+		return $payment_overview_url;
909
+	}
910
+
911
+
912
+	/**
913
+	 * Gets the URL for the checkout attendee information reg step
914
+	 * with this registration's REG_url_link added as a query parameter
915
+	 *
916
+	 * @return string
917
+	 * @throws InvalidInterfaceException
918
+	 * @throws InvalidDataTypeException
919
+	 * @throws EE_Error
920
+	 * @throws InvalidArgumentException
921
+	 * @throws EntityNotFoundException
922
+	 */
923
+	public function edit_attendee_information_url()
924
+	{
925
+		$attendee_information_url = add_query_arg(
926
+			(array) apply_filters(
927
+				'FHEE__EE_Registration__edit_attendee_information_url__query_args',
928
+				array(
929
+					'e_reg_url_link' => $this->reg_url_link(),
930
+					'step'           => 'attendee_information',
931
+					'revisit'        => true,
932
+				),
933
+				$this
934
+			),
935
+			EE_Registry::instance()->CFG->core->reg_page_url()
936
+		);
937
+		EE_Log::logTxn(
938
+			__CLASS__, __FUNCTION__, __LINE__,
939
+			$this->transaction(),
940
+			array(
941
+				'REG_ID'                   => $this->ID(),
942
+				'e_reg_url_link'           => $this->reg_url_link(),
943
+				'attendee_information_url' => $attendee_information_url,
944
+			)
945
+		);
946
+		return $attendee_information_url;
947
+	}
948
+
949
+
950
+	/**
951
+	 * Simply generates and returns the appropriate admin_url link to edit this registration
952
+	 *
953
+	 * @return string
954
+	 * @throws EE_Error
955
+	 */
956
+	public function get_admin_edit_url()
957
+	{
958
+		return EEH_URL::add_query_args_and_nonce(array(
959
+			'page'    => 'espresso_registrations',
960
+			'action'  => 'view_registration',
961
+			'_REG_ID' => $this->ID(),
962
+		), admin_url('admin.php'));
963
+	}
964
+
965
+
966
+	/**
967
+	 *    is_primary_registrant?
968
+	 */
969
+	public function is_primary_registrant()
970
+	{
971
+		return $this->get('REG_count') == 1 ? true : false;
972
+	}
973
+
974
+
975
+	/**
976
+	 * This returns the primary registration object for this registration group (which may be this object).
977
+	 *
978
+	 * @return EE_Registration
979
+	 * @throws EE_Error
980
+	 */
981
+	public function get_primary_registration()
982
+	{
983
+		if ($this->is_primary_registrant()) {
984
+			return $this;
985
+		}
986
+
987
+		//k reg_count !== 1 so let's get the EE_Registration object matching this txn_id and reg_count == 1
988
+		/** @var EE_Registration $primary_registrant */
989
+		$primary_registrant = EEM_Registration::instance()->get_one(array(
990
+			array(
991
+				'TXN_ID'    => $this->transaction_ID(),
992
+				'REG_count' => 1,
993
+			),
994
+		));
995
+		return $primary_registrant;
996
+	}
997
+
998
+
999
+	/**
1000
+	 *        get  Attendee Number
1001
+	 *
1002
+	 * @access        public
1003
+	 */
1004
+	public function count()
1005
+	{
1006
+		return $this->get('REG_count');
1007
+	}
1008
+
1009
+
1010
+	/**
1011
+	 *        get Group Size
1012
+	 */
1013
+	public function group_size()
1014
+	{
1015
+		return $this->get('REG_group_size');
1016
+	}
1017
+
1018
+
1019
+	/**
1020
+	 *        get Registration Date
1021
+	 */
1022
+	public function date()
1023
+	{
1024
+		return $this->get('REG_date');
1025
+	}
1026
+
1027
+
1028
+	/**
1029
+	 * gets a pretty date
1030
+	 *
1031
+	 * @param string $date_format
1032
+	 * @param string $time_format
1033
+	 * @return string
1034
+	 * @throws EE_Error
1035
+	 */
1036
+	public function pretty_date($date_format = null, $time_format = null)
1037
+	{
1038
+		return $this->get_datetime('REG_date', $date_format, $time_format);
1039
+	}
1040
+
1041
+
1042
+	/**
1043
+	 * final_price
1044
+	 * the registration's share of the transaction total, so that the
1045
+	 * sum of all the transaction's REG_final_prices equal the transaction's total
1046
+	 *
1047
+	 * @return float
1048
+	 * @throws EE_Error
1049
+	 */
1050
+	public function final_price()
1051
+	{
1052
+		return $this->get('REG_final_price');
1053
+	}
1054
+
1055
+
1056
+	/**
1057
+	 * pretty_final_price
1058
+	 *  final price as formatted string, with correct decimal places and currency symbol
1059
+	 *
1060
+	 * @return string
1061
+	 * @throws EE_Error
1062
+	 */
1063
+	public function pretty_final_price()
1064
+	{
1065
+		return $this->get_pretty('REG_final_price');
1066
+	}
1067
+
1068
+
1069
+	/**
1070
+	 * get paid (yeah)
1071
+	 *
1072
+	 * @return float
1073
+	 * @throws EE_Error
1074
+	 */
1075
+	public function paid()
1076
+	{
1077
+		return $this->get('REG_paid');
1078
+	}
1079
+
1080
+
1081
+	/**
1082
+	 * pretty_paid
1083
+	 *
1084
+	 * @return float
1085
+	 * @throws EE_Error
1086
+	 */
1087
+	public function pretty_paid()
1088
+	{
1089
+		return $this->get_pretty('REG_paid');
1090
+	}
1091
+
1092
+
1093
+	/**
1094
+	 * owes_monies_and_can_pay
1095
+	 * whether or not this registration has monies owing and it's' status allows payment
1096
+	 *
1097
+	 * @param array $requires_payment
1098
+	 * @return bool
1099
+	 * @throws EE_Error
1100
+	 */
1101
+	public function owes_monies_and_can_pay($requires_payment = array())
1102
+	{
1103
+		// these reg statuses require payment (if event is not free)
1104
+		$requires_payment = ! empty($requires_payment)
1105
+			? $requires_payment
1106
+			: EEM_Registration::reg_statuses_that_allow_payment();
1107
+		if (in_array($this->status_ID(), $requires_payment) &&
1108
+			$this->final_price() != 0 &&
1109
+			$this->final_price() != $this->paid()
1110
+		) {
1111
+			return true;
1112
+		} else {
1113
+			return false;
1114
+		}
1115
+	}
1116
+
1117
+
1118
+	/**
1119
+	 * Prints out the return value of $this->pretty_status()
1120
+	 *
1121
+	 * @param bool $show_icons
1122
+	 * @return void
1123
+	 * @throws EE_Error
1124
+	 */
1125
+	public function e_pretty_status($show_icons = false)
1126
+	{
1127
+		echo $this->pretty_status($show_icons);
1128
+	}
1129
+
1130
+
1131
+	/**
1132
+	 * Returns a nice version of the status for displaying to customers
1133
+	 *
1134
+	 * @param bool $show_icons
1135
+	 * @return string
1136
+	 * @throws EE_Error
1137
+	 */
1138
+	public function pretty_status($show_icons = false)
1139
+	{
1140
+		$status = EEM_Status::instance()->localized_status(
1141
+			array($this->status_ID() => esc_html__('unknown', 'event_espresso')),
1142
+			false,
1143
+			'sentence'
1144
+		);
1145
+		$icon   = '';
1146
+		switch ($this->status_ID()) {
1147
+			case EEM_Registration::status_id_approved:
1148
+				$icon = $show_icons
1149
+					? '<span class="dashicons dashicons-star-filled ee-icon-size-16 green-text"></span>'
1150
+					: '';
1151
+				break;
1152
+			case EEM_Registration::status_id_pending_payment:
1153
+				$icon = $show_icons
1154
+					? '<span class="dashicons dashicons-star-half ee-icon-size-16 orange-text"></span>'
1155
+					: '';
1156
+				break;
1157
+			case EEM_Registration::status_id_not_approved:
1158
+				$icon = $show_icons
1159
+					? '<span class="dashicons dashicons-marker ee-icon-size-16 orange-text"></span>'
1160
+					: '';
1161
+				break;
1162
+			case EEM_Registration::status_id_cancelled:
1163
+				$icon = $show_icons
1164
+					? '<span class="dashicons dashicons-no ee-icon-size-16 lt-grey-text"></span>'
1165
+					: '';
1166
+				break;
1167
+			case EEM_Registration::status_id_incomplete:
1168
+				$icon = $show_icons
1169
+					? '<span class="dashicons dashicons-no ee-icon-size-16 lt-orange-text"></span>'
1170
+					: '';
1171
+				break;
1172
+			case EEM_Registration::status_id_declined:
1173
+				$icon = $show_icons
1174
+					? '<span class="dashicons dashicons-no ee-icon-size-16 red-text"></span>'
1175
+					: '';
1176
+				break;
1177
+			case EEM_Registration::status_id_wait_list:
1178
+				$icon = $show_icons
1179
+					? '<span class="dashicons dashicons-clipboard ee-icon-size-16 purple-text"></span>'
1180
+					: '';
1181
+				break;
1182
+		}
1183
+		return $icon . $status[$this->status_ID()];
1184
+	}
1185
+
1186
+
1187
+	/**
1188
+	 *        get Attendee Is Going
1189
+	 */
1190
+	public function att_is_going()
1191
+	{
1192
+		return $this->get('REG_att_is_going');
1193
+	}
1194
+
1195
+
1196
+	/**
1197
+	 * Gets related answers
1198
+	 *
1199
+	 * @param array $query_params like EEM_Base::get_all
1200
+	 * @return EE_Answer[]
1201
+	 * @throws EE_Error
1202
+	 */
1203
+	public function answers($query_params = null)
1204
+	{
1205
+		return $this->get_many_related('Answer', $query_params);
1206
+	}
1207
+
1208
+
1209
+	/**
1210
+	 * Gets the registration's answer value to the specified question
1211
+	 * (either the question's ID or a question object)
1212
+	 *
1213
+	 * @param EE_Question|int $question
1214
+	 * @param bool            $pretty_value
1215
+	 * @return array|string if pretty_value= true, the result will always be a string
1216
+	 * (because the answer might be an array of answer values, so passing pretty_value=true
1217
+	 * will convert it into some kind of string)
1218
+	 * @throws EE_Error
1219
+	 */
1220
+	public function answer_value_to_question($question, $pretty_value = true)
1221
+	{
1222
+		$question_id = EEM_Question::instance()->ensure_is_ID($question);
1223
+		return EEM_Answer::instance()->get_answer_value_to_question($this, $question_id, $pretty_value);
1224
+	}
1225
+
1226
+
1227
+	/**
1228
+	 * question_groups
1229
+	 * returns an array of EE_Question_Group objects for this registration
1230
+	 *
1231
+	 * @return EE_Question_Group[]
1232
+	 * @throws EE_Error
1233
+	 * @throws EntityNotFoundException
1234
+	 */
1235
+	public function question_groups()
1236
+	{
1237
+		$question_groups = array();
1238
+		if ($this->event() instanceof EE_Event) {
1239
+			$question_groups = $this->event()->question_groups(
1240
+				array(
1241
+					array(
1242
+						'Event_Question_Group.EQG_primary' => $this->count() == 1 ? true : false,
1243
+					),
1244
+					'order_by' => array('QSG_order' => 'ASC'),
1245
+				)
1246
+			);
1247
+		}
1248
+		return $question_groups;
1249
+	}
1250
+
1251
+
1252
+	/**
1253
+	 * count_question_groups
1254
+	 * returns a count of the number of EE_Question_Group objects for this registration
1255
+	 *
1256
+	 * @return int
1257
+	 * @throws EE_Error
1258
+	 * @throws EntityNotFoundException
1259
+	 */
1260
+	public function count_question_groups()
1261
+	{
1262
+		$qg_count = 0;
1263
+		if ($this->event() instanceof EE_Event) {
1264
+			$qg_count = $this->event()->count_related(
1265
+				'Question_Group',
1266
+				array(
1267
+					array(
1268
+						'Event_Question_Group.EQG_primary' => $this->count() == 1 ? true : false,
1269
+					),
1270
+				)
1271
+			);
1272
+		}
1273
+		return $qg_count;
1274
+	}
1275
+
1276
+
1277
+	/**
1278
+	 * Returns the registration date in the 'standard' string format
1279
+	 * (function may be improved in the future to allow for different formats and timezones)
1280
+	 *
1281
+	 * @return string
1282
+	 * @throws EE_Error
1283
+	 */
1284
+	public function reg_date()
1285
+	{
1286
+		return $this->get_datetime('REG_date');
1287
+	}
1288
+
1289
+
1290
+	/**
1291
+	 * Gets the datetime-ticket for this registration (ie, it can be used to isolate
1292
+	 * the ticket this registration purchased, or the datetime they have registered
1293
+	 * to attend)
1294
+	 *
1295
+	 * @return EE_Datetime_Ticket
1296
+	 * @throws EE_Error
1297
+	 */
1298
+	public function datetime_ticket()
1299
+	{
1300
+		return $this->get_first_related('Datetime_Ticket');
1301
+	}
1302
+
1303
+
1304
+	/**
1305
+	 * Sets the registration's datetime_ticket.
1306
+	 *
1307
+	 * @param EE_Datetime_Ticket $datetime_ticket
1308
+	 * @return EE_Datetime_Ticket
1309
+	 * @throws EE_Error
1310
+	 */
1311
+	public function set_datetime_ticket($datetime_ticket)
1312
+	{
1313
+		return $this->_add_relation_to($datetime_ticket, 'Datetime_Ticket');
1314
+	}
1315
+
1316
+	/**
1317
+	 * Gets deleted
1318
+	 *
1319
+	 * @return bool
1320
+	 * @throws EE_Error
1321
+	 */
1322
+	public function deleted()
1323
+	{
1324
+		return $this->get('REG_deleted');
1325
+	}
1326
+
1327
+	/**
1328
+	 * Sets deleted
1329
+	 *
1330
+	 * @param boolean $deleted
1331
+	 * @return bool
1332
+	 * @throws EE_Error
1333
+	 * @throws RuntimeException
1334
+	 */
1335
+	public function set_deleted($deleted)
1336
+	{
1337
+		if ($deleted) {
1338
+			$this->delete();
1339
+		} else {
1340
+			$this->restore();
1341
+		}
1342
+	}
1343
+
1344
+
1345
+	/**
1346
+	 * Get the status object of this object
1347
+	 *
1348
+	 * @return EE_Status
1349
+	 * @throws EE_Error
1350
+	 */
1351
+	public function status_obj()
1352
+	{
1353
+		return $this->get_first_related('Status');
1354
+	}
1355
+
1356
+
1357
+	/**
1358
+	 * Returns the number of times this registration has checked into any of the datetimes
1359
+	 * its available for
1360
+	 *
1361
+	 * @return int
1362
+	 * @throws EE_Error
1363
+	 */
1364
+	public function count_checkins()
1365
+	{
1366
+		return $this->get_model()->count_related($this, 'Checkin');
1367
+	}
1368
+
1369
+
1370
+	/**
1371
+	 * Returns the number of current Check-ins this registration is checked into for any of the datetimes the
1372
+	 * registration is for.  Note, this is ONLY checked in (does not include checkedout)
1373
+	 *
1374
+	 * @return int
1375
+	 * @throws EE_Error
1376
+	 */
1377
+	public function count_checkins_not_checkedout()
1378
+	{
1379
+		return $this->get_model()->count_related($this, 'Checkin', array(array('CHK_in' => 1)));
1380
+	}
1381
+
1382
+
1383
+	/**
1384
+	 * The purpose of this method is simply to check whether this registration can checkin to the given datetime.
1385
+	 *
1386
+	 * @param int | EE_Datetime $DTT_OR_ID      The datetime the registration is being checked against
1387
+	 * @param bool              $check_approved This is used to indicate whether the caller wants can_checkin to also
1388
+	 *                                          consider registration status as well as datetime access.
1389
+	 * @return bool
1390
+	 * @throws EE_Error
1391
+	 */
1392
+	public function can_checkin($DTT_OR_ID, $check_approved = true)
1393
+	{
1394
+		$DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID);
1395
+
1396
+		//first check registration status
1397
+		if (($check_approved && ! $this->is_approved()) || ! $DTT_ID) {
1398
+			return false;
1399
+		}
1400
+		//is there a datetime ticket that matches this dtt_ID?
1401
+		if (! (EEM_Datetime_Ticket::instance()->exists(array(
1402
+			array(
1403
+				'TKT_ID' => $this->get('TKT_ID'),
1404
+				'DTT_ID' => $DTT_ID,
1405
+			),
1406
+		)))
1407
+		) {
1408
+			return false;
1409
+		}
1410
+
1411
+		//final check is against TKT_uses
1412
+		return $this->verify_can_checkin_against_TKT_uses($DTT_ID);
1413
+	}
1414
+
1415
+
1416
+	/**
1417
+	 * This method verifies whether the user can checkin for the given datetime considering the max uses value set on
1418
+	 * the ticket. To do this,  a query is done to get the count of the datetime records already checked into.  If the
1419
+	 * datetime given does not have a check-in record and checking in for that datetime will exceed the allowed uses,
1420
+	 * then return false.  Otherwise return true.
1421
+	 *
1422
+	 * @param int | EE_Datetime $DTT_OR_ID The datetime the registration is being checked against
1423
+	 * @return bool true means can checkin.  false means cannot checkin.
1424
+	 * @throws EE_Error
1425
+	 */
1426
+	public function verify_can_checkin_against_TKT_uses($DTT_OR_ID)
1427
+	{
1428
+		$DTT_ID = EEM_Datetime::instance()->ensure_is_ID($DTT_OR_ID);
1429
+
1430
+		if (! $DTT_ID) {
1431
+			return false;
1432
+		}
1433
+
1434
+		$max_uses = $this->ticket() instanceof EE_Ticket ? $this->ticket()->uses() : EE_INF;
1435
+
1436
+		// if max uses is not set or equals infinity then return true cause its not a factor for whether user can
1437
+		// check-in or not.
1438
+		if (! $max_uses || $max_uses === EE_INF) {
1439
+			return true;
1440
+		}
1441
+
1442
+		//does this datetime have a checkin record?  If so, then the dtt count has already been verified so we can just
1443
+		//go ahead and toggle.
1444
+		if (EEM_Checkin::instance()->exists(array(array('REG_ID' => $this->ID(), 'DTT_ID' => $DTT_ID)))) {
1445
+			return true;
1446
+		}
1447
+
1448
+		//made it here so the last check is whether the number of checkins per unique datetime on this registration
1449
+		//disallows further check-ins.
1450
+		$count_unique_dtt_checkins = EEM_Checkin::instance()->count(array(
1451
+			array(
1452
+				'REG_ID' => $this->ID(),
1453
+				'CHK_in' => true,
1454
+			),
1455
+		), 'DTT_ID', true);
1456
+		// checkins have already reached their max number of uses
1457
+		// so registrant can NOT checkin
1458
+		if ($count_unique_dtt_checkins >= $max_uses) {
1459
+			EE_Error::add_error(
1460
+				esc_html__(
1461
+					'Check-in denied because number of datetime uses for the ticket has been reached or exceeded.',
1462
+					'event_espresso'
1463
+				),
1464
+				__FILE__,
1465
+				__FUNCTION__,
1466
+				__LINE__
1467
+			);
1468
+			return false;
1469
+		}
1470
+		return true;
1471
+	}
1472
+
1473
+
1474
+	/**
1475
+	 * toggle Check-in status for this registration
1476
+	 * Check-ins are toggled in the following order:
1477
+	 * never checked in -> checked in
1478
+	 * checked in -> checked out
1479
+	 * checked out -> checked in
1480
+	 *
1481
+	 * @param  int $DTT_ID  include specific datetime to toggle Check-in for.
1482
+	 *                      If not included or null, then it is assumed latest datetime is being toggled.
1483
+	 * @param bool $verify  If true then can_checkin() is used to verify whether the person
1484
+	 *                      can be checked in or not.  Otherwise this forces change in checkin status.
1485
+	 * @return bool|int     the chk_in status toggled to OR false if nothing got changed.
1486
+	 * @throws EE_Error
1487
+	 */
1488
+	public function toggle_checkin_status($DTT_ID = null, $verify = false)
1489
+	{
1490
+		if (empty($DTT_ID)) {
1491
+			$datetime = $this->get_latest_related_datetime();
1492
+			$DTT_ID   = $datetime instanceof EE_Datetime ? $datetime->ID() : 0;
1493
+			// verify the registration can checkin for the given DTT_ID
1494
+		} elseif (! $this->can_checkin($DTT_ID, $verify)) {
1495
+			EE_Error::add_error(
1496
+				sprintf(
1497
+					esc_html__(
1498
+						'The given registration (ID:%1$d) can not be checked in to the given DTT_ID (%2$d), because the registration does not have access',
1499
+						'event_espresso'
1500
+					),
1501
+					$this->ID(),
1502
+					$DTT_ID
1503
+				),
1504
+				__FILE__,
1505
+				__FUNCTION__,
1506
+				__LINE__
1507
+			);
1508
+			return false;
1509
+		}
1510
+		$status_paths = array(
1511
+			EE_Checkin::status_checked_never => EE_Checkin::status_checked_in,
1512
+			EE_Checkin::status_checked_in    => EE_Checkin::status_checked_out,
1513
+			EE_Checkin::status_checked_out   => EE_Checkin::status_checked_in,
1514
+		);
1515
+		//start by getting the current status so we know what status we'll be changing to.
1516
+		$cur_status = $this->check_in_status_for_datetime($DTT_ID, null);
1517
+		$status_to  = $status_paths[$cur_status];
1518
+		// database only records true for checked IN or false for checked OUT
1519
+		// no record ( null ) means checked in NEVER, but we obviously don't save that
1520
+		$new_status = $status_to === EE_Checkin::status_checked_in ? true : false;
1521
+		// add relation - note Check-ins are always creating new rows
1522
+		// because we are keeping track of Check-ins over time.
1523
+		// Eventually we'll probably want to show a list table
1524
+		// for the individual Check-ins so that they can be managed.
1525
+		$checkin = EE_Checkin::new_instance(array(
1526
+			'REG_ID' => $this->ID(),
1527
+			'DTT_ID' => $DTT_ID,
1528
+			'CHK_in' => $new_status,
1529
+		));
1530
+		// if the record could not be saved then return false
1531
+		if ($checkin->save() === 0) {
1532
+			if (WP_DEBUG) {
1533
+				global $wpdb;
1534
+				$error = sprintf(
1535
+					esc_html__(
1536
+						'Registration check in update failed because of the following database error: %1$s%2$s',
1537
+						'event_espresso'
1538
+					),
1539
+					'<br />',
1540
+					$wpdb->last_error
1541
+				);
1542
+			} else {
1543
+				$error = esc_html__(
1544
+					'Registration check in update failed because of an unknown database error',
1545
+					'event_espresso'
1546
+				);
1547
+			}
1548
+			EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
1549
+			return false;
1550
+		}
1551
+		return $status_to;
1552
+	}
1553
+
1554
+
1555
+	/**
1556
+	 * Returns the latest datetime related to this registration (via the ticket attached to the registration).
1557
+	 * "Latest" is defined by the `DTT_EVT_start` column.
1558
+	 *
1559
+	 * @return EE_Datetime|null
1560
+	 * @throws EE_Error
1561
+	 */
1562
+	public function get_latest_related_datetime()
1563
+	{
1564
+		return EEM_Datetime::instance()->get_one(
1565
+			array(
1566
+				array(
1567
+					'Ticket.Registration.REG_ID' => $this->ID(),
1568
+				),
1569
+				'order_by' => array('DTT_EVT_start' => 'DESC'),
1570
+			)
1571
+		);
1572
+	}
1573
+
1574
+
1575
+	/**
1576
+	 * Returns the earliest datetime related to this registration (via the ticket attached to the registration).
1577
+	 * "Earliest" is defined by the `DTT_EVT_start` column.
1578
+	 *
1579
+	 * @throws EE_Error
1580
+	 */
1581
+	public function get_earliest_related_datetime()
1582
+	{
1583
+		return EEM_Datetime::instance()->get_one(
1584
+			array(
1585
+				array(
1586
+					'Ticket.Registration.REG_ID' => $this->ID(),
1587
+				),
1588
+				'order_by' => array('DTT_EVT_start' => 'ASC'),
1589
+			)
1590
+		);
1591
+	}
1592
+
1593
+
1594
+	/**
1595
+	 * This method simply returns the check-in status for this registration and the given datetime.
1596
+	 * If neither the datetime nor the checkin values are provided as arguments,
1597
+	 * then this will return the LATEST check-in status for the registration across all datetimes it belongs to.
1598
+	 *
1599
+	 * @param  int       $DTT_ID  The ID of the datetime we're checking against
1600
+	 *                            (if empty we'll get the primary datetime for
1601
+	 *                            this registration (via event) and use it's ID);
1602
+	 * @param EE_Checkin $checkin If present, we use the given checkin object rather than the dtt_id.
1603
+	 *
1604
+	 * @return int                Integer representing Check-in status.
1605
+	 * @throws EE_Error
1606
+	 */
1607
+	public function check_in_status_for_datetime($DTT_ID = 0, $checkin = null)
1608
+	{
1609
+		$checkin_query_params = array(
1610
+			'order_by' => array('CHK_timestamp' => 'DESC'),
1611
+		);
1612
+
1613
+		if ($DTT_ID > 0) {
1614
+			$checkin_query_params[0] = array('DTT_ID' => $DTT_ID);
1615
+		}
1616
+
1617
+		//get checkin object (if exists)
1618
+		$checkin = $checkin instanceof EE_Checkin
1619
+			? $checkin
1620
+			: $this->get_first_related('Checkin', $checkin_query_params);
1621
+		if ($checkin instanceof EE_Checkin) {
1622
+			if ($checkin->get('CHK_in')) {
1623
+				return EE_Checkin::status_checked_in; //checked in
1624
+			}
1625
+			return EE_Checkin::status_checked_out; //had checked in but is now checked out.
1626
+		}
1627
+		return EE_Checkin::status_checked_never; //never been checked in
1628
+	}
1629
+
1630
+
1631
+	/**
1632
+	 * This method returns a localized message for the toggled Check-in message.
1633
+	 *
1634
+	 * @param  int $DTT_ID include specific datetime to get the correct Check-in message.  If not included or null,
1635
+	 *                     then it is assumed Check-in for primary datetime was toggled.
1636
+	 * @param bool $error  This just flags that you want an error message returned. This is put in so that the error
1637
+	 *                     message can be customized with the attendee name.
1638
+	 * @return string internationalized message
1639
+	 * @throws EE_Error
1640
+	 */
1641
+	public function get_checkin_msg($DTT_ID, $error = false)
1642
+	{
1643
+		//let's get the attendee first so we can include the name of the attendee
1644
+		$attendee = $this->get_first_related('Attendee');
1645
+		if ($attendee instanceof EE_Attendee) {
1646
+			if ($error) {
1647
+				return sprintf(__("%s's check-in status was not changed.", "event_espresso"), $attendee->full_name());
1648
+			}
1649
+			$cur_status = $this->check_in_status_for_datetime($DTT_ID);
1650
+			//what is the status message going to be?
1651
+			switch ($cur_status) {
1652
+				case EE_Checkin::status_checked_never:
1653
+					return sprintf(__("%s has been removed from Check-in records", "event_espresso"),
1654
+						$attendee->full_name());
1655
+					break;
1656
+				case EE_Checkin::status_checked_in:
1657
+					return sprintf(__('%s has been checked in', 'event_espresso'), $attendee->full_name());
1658
+					break;
1659
+				case EE_Checkin::status_checked_out:
1660
+					return sprintf(__('%s has been checked out', 'event_espresso'), $attendee->full_name());
1661
+					break;
1662
+			}
1663
+		}
1664
+		return esc_html__("The check-in status could not be determined.", "event_espresso");
1665
+	}
1666
+
1667
+
1668
+	/**
1669
+	 * Returns the related EE_Transaction to this registration
1670
+	 *
1671
+	 * @return EE_Transaction
1672
+	 * @throws EE_Error
1673
+	 * @throws EntityNotFoundException
1674
+	 */
1675
+	public function transaction()
1676
+	{
1677
+		$transaction = $this->get_first_related('Transaction');
1678
+		if (! $transaction instanceof \EE_Transaction) {
1679
+			throw new EntityNotFoundException('Transaction ID', $this->transaction_ID());
1680
+		}
1681
+		return $transaction;
1682
+	}
1683
+
1684
+
1685
+	/**
1686
+	 *        get Registration Code
1687
+	 */
1688
+	public function reg_code()
1689
+	{
1690
+		return $this->get('REG_code');
1691
+	}
1692
+
1693
+
1694
+	/**
1695
+	 *        get Transaction ID
1696
+	 */
1697
+	public function transaction_ID()
1698
+	{
1699
+		return $this->get('TXN_ID');
1700
+	}
1701
+
1702
+
1703
+	/**
1704
+	 * @return int
1705
+	 * @throws EE_Error
1706
+	 */
1707
+	public function ticket_ID()
1708
+	{
1709
+		return $this->get('TKT_ID');
1710
+	}
1711
+
1712
+
1713
+	/**
1714
+	 *        Set Registration Code
1715
+	 *
1716
+	 * @access    public
1717
+	 * @param    string  $REG_code Registration Code
1718
+	 * @param    boolean $use_default
1719
+	 * @throws EE_Error
1720
+	 */
1721
+	public function set_reg_code($REG_code, $use_default = false)
1722
+	{
1723
+		if (empty($REG_code)) {
1724
+			EE_Error::add_error(
1725
+				esc_html__('REG_code can not be empty.', 'event_espresso'),
1726
+				__FILE__,
1727
+				__FUNCTION__,
1728
+				__LINE__
1729
+			);
1730
+			return;
1731
+		}
1732
+		if (! $this->reg_code()) {
1733
+			parent::set('REG_code', $REG_code, $use_default);
1734
+		} else {
1735
+			EE_Error::doing_it_wrong(
1736
+				__CLASS__ . '::' . __FUNCTION__,
1737
+				esc_html__('Can not change a registration REG_code once it has been set.', 'event_espresso'),
1738
+				'4.6.0'
1739
+			);
1740
+		}
1741
+	}
1742
+
1743
+
1744
+	/**
1745
+	 * Returns all other registrations in the same group as this registrant who have the same ticket option.
1746
+	 * Note, if you want to just get all registrations in the same transaction (group), use:
1747
+	 *    $registration->transaction()->registrations();
1748
+	 *
1749
+	 * @since 4.5.0
1750
+	 * @return EE_Registration[] or empty array if this isn't a group registration.
1751
+	 * @throws EE_Error
1752
+	 */
1753
+	public function get_all_other_registrations_in_group()
1754
+	{
1755
+		if ($this->group_size() < 2) {
1756
+			return array();
1757
+		}
1758
+
1759
+		$query[0] = array(
1760
+			'TXN_ID' => $this->transaction_ID(),
1761
+			'REG_ID' => array('!=', $this->ID()),
1762
+			'TKT_ID' => $this->ticket_ID(),
1763
+		);
1764
+		/** @var EE_Registration[] $registrations */
1765
+		$registrations = $this->get_model()->get_all($query);
1766
+		return $registrations;
1767
+	}
1768
+
1769
+	/**
1770
+	 * Return the link to the admin details for the object.
1771
+	 *
1772
+	 * @return string
1773
+	 * @throws EE_Error
1774
+	 */
1775
+	public function get_admin_details_link()
1776
+	{
1777
+		EE_Registry::instance()->load_helper('URL');
1778
+		return EEH_URL::add_query_args_and_nonce(
1779
+			array(
1780
+				'page'    => 'espresso_registrations',
1781
+				'action'  => 'view_registration',
1782
+				'_REG_ID' => $this->ID(),
1783
+			),
1784
+			admin_url('admin.php')
1785
+		);
1786
+	}
1787
+
1788
+	/**
1789
+	 * Returns the link to the editor for the object.  Sometimes this is the same as the details.
1790
+	 *
1791
+	 * @return string
1792
+	 * @throws EE_Error
1793
+	 */
1794
+	public function get_admin_edit_link()
1795
+	{
1796
+		return $this->get_admin_details_link();
1797
+	}
1798
+
1799
+	/**
1800
+	 * Returns the link to a settings page for the object.
1801
+	 *
1802
+	 * @return string
1803
+	 * @throws EE_Error
1804
+	 */
1805
+	public function get_admin_settings_link()
1806
+	{
1807
+		return $this->get_admin_details_link();
1808
+	}
1809
+
1810
+	/**
1811
+	 * Returns the link to the "overview" for the object (typically the "list table" view).
1812
+	 *
1813
+	 * @return string
1814
+	 */
1815
+	public function get_admin_overview_link()
1816
+	{
1817
+		EE_Registry::instance()->load_helper('URL');
1818
+		return EEH_URL::add_query_args_and_nonce(
1819
+			array(
1820
+				'page' => 'espresso_registrations',
1821
+			),
1822
+			admin_url('admin.php')
1823
+		);
1824
+	}
1825
+
1826
+
1827
+	/**
1828
+	 * @param array $query_params
1829
+	 *
1830
+	 * @return \EE_Registration[]
1831
+	 * @throws EE_Error
1832
+	 */
1833
+	public function payments($query_params = array())
1834
+	{
1835
+		return $this->get_many_related('Payment', $query_params);
1836
+	}
1837
+
1838
+
1839
+	/**
1840
+	 * @param array $query_params
1841
+	 *
1842
+	 * @return \EE_Registration_Payment[]
1843
+	 * @throws EE_Error
1844
+	 */
1845
+	public function registration_payments($query_params = array())
1846
+	{
1847
+		return $this->get_many_related('Registration_Payment', $query_params);
1848
+	}
1849
+
1850
+
1851
+	/**
1852
+	 * This grabs the payment method corresponding to the last payment made for the amount owing on the registration.
1853
+	 * Note: if there are no payments on the registration there will be no payment method returned.
1854
+	 *
1855
+	 * @return EE_Payment_Method|null
1856
+	 */
1857
+	public function payment_method()
1858
+	{
1859
+		return EEM_Payment_Method::instance()->get_last_used_for_registration($this);
1860
+	}
1861
+
1862
+
1863
+	/**
1864
+	 * @return \EE_Line_Item
1865
+	 * @throws EntityNotFoundException
1866
+	 * @throws EE_Error
1867
+	 */
1868
+	public function ticket_line_item()
1869
+	{
1870
+		$ticket            = $this->ticket();
1871
+		$transaction       = $this->transaction();
1872
+		$line_item         = null;
1873
+		$ticket_line_items = \EEH_Line_Item::get_line_items_by_object_type_and_IDs(
1874
+			$transaction->total_line_item(),
1875
+			'Ticket',
1876
+			array($ticket->ID())
1877
+		);
1878
+		foreach ($ticket_line_items as $ticket_line_item) {
1879
+			if (
1880
+				$ticket_line_item instanceof \EE_Line_Item
1881
+				&& $ticket_line_item->OBJ_type() === 'Ticket'
1882
+				&& $ticket_line_item->OBJ_ID() === $ticket->ID()
1883
+			) {
1884
+				$line_item = $ticket_line_item;
1885
+				break;
1886
+			}
1887
+		}
1888
+		if (! ($line_item instanceof \EE_Line_Item && $line_item->OBJ_type() === 'Ticket')) {
1889
+			throw new EntityNotFoundException('Line Item Ticket ID', $ticket->ID());
1890
+		}
1891
+		return $line_item;
1892
+	}
1893
+
1894
+
1895
+	/**
1896
+	 * Soft Deletes this model object.
1897
+	 *
1898
+	 * @return boolean | int
1899
+	 * @throws RuntimeException
1900
+	 * @throws EE_Error
1901
+	 */
1902
+	public function delete()
1903
+	{
1904
+		if ($this->update_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY, $this->status_ID()) === true) {
1905
+			$this->set_status(EEM_Registration::status_id_cancelled);
1906
+		}
1907
+		return parent::delete();
1908
+	}
1909
+
1910
+
1911
+	/**
1912
+	 * Restores whatever the previous status was on a registration before it was trashed (if possible)
1913
+	 *
1914
+	 * @throws EE_Error
1915
+	 * @throws RuntimeException
1916
+	 */
1917
+	public function restore()
1918
+	{
1919
+		$previous_status = $this->get_extra_meta(
1920
+			EE_Registration::PRE_TRASH_REG_STATUS_KEY,
1921
+			true,
1922
+			EEM_Registration::status_id_cancelled
1923
+		);
1924
+		if ($previous_status) {
1925
+			$this->delete_extra_meta(EE_Registration::PRE_TRASH_REG_STATUS_KEY);
1926
+			$this->set_status($previous_status);
1927
+		}
1928
+		return parent::restore();
1929
+	}
1930
+
1931
+
1932
+	/**
1933
+	 * possibly toggle Registration status based on comparison of REG_paid vs REG_final_price
1934
+	 *
1935
+	 * @param  boolean $trigger_set_status_logic EE_Registration::set_status() can trigger additional logic
1936
+	 *                                           depending on whether the reg status changes to or from "Approved"
1937
+	 * @return boolean whether the Registration status was updated
1938
+	 * @throws EE_Error
1939
+	 * @throws RuntimeException
1940
+	 */
1941
+	public function updateStatusBasedOnTotalPaid($trigger_set_status_logic = true)
1942
+	{
1943
+		$paid = $this->paid();
1944
+		$price = $this->final_price();
1945
+		switch(true) {
1946
+			// overpaid or paid
1947
+			case EEH_Money::compare_floats($paid, $price, '>'):
1948
+			case EEH_Money::compare_floats($paid, $price):
1949
+				$new_status = EEM_Registration::status_id_approved;
1950
+				break;
1951
+			//  underpaid
1952
+			case EEH_Money::compare_floats($paid, $price, '<'):
1953
+				$new_status = EEM_Registration::status_id_pending_payment;
1954
+				break;
1955
+			// uhhh Houston...
1956
+			default:
1957
+				throw new RuntimeException(
1958
+					esc_html__('The total paid calculation for this registration is inaccurate.', 'event_espresso')
1959
+				);
1960
+		}
1961
+		if ($new_status !== $this->status_ID()) {
1962
+			if ($trigger_set_status_logic) {
1963
+				return $this->set_status($new_status);
1964
+			}
1965
+			parent::set('STS_ID', $new_status);
1966
+			return true;
1967
+		}
1968
+		return false;
1969
+	}
1970
+
1971
+
1972
+	/*************************** DEPRECATED ***************************/
1973
+
1974
+
1975
+	/**
1976
+	 * @deprecated
1977
+	 * @since     4.7.0
1978
+	 * @access    public
1979
+	 */
1980
+	public function price_paid()
1981
+	{
1982
+		EE_Error::doing_it_wrong('EE_Registration::price_paid()',
1983
+			esc_html__('This method is deprecated, please use EE_Registration::final_price() instead.', 'event_espresso'),
1984
+			'4.7.0');
1985
+		return $this->final_price();
1986
+	}
1987
+
1988
+
1989
+	/**
1990
+	 * @deprecated
1991
+	 * @since     4.7.0
1992
+	 * @access    public
1993
+	 * @param    float $REG_final_price
1994
+	 * @throws EE_Error
1995
+	 * @throws RuntimeException
1996
+	 */
1997
+	public function set_price_paid($REG_final_price = 0.00)
1998
+	{
1999
+		EE_Error::doing_it_wrong('EE_Registration::set_price_paid()',
2000
+			esc_html__('This method is deprecated, please use EE_Registration::set_final_price() instead.', 'event_espresso'),
2001
+			'4.7.0');
2002
+		$this->set_final_price($REG_final_price);
2003
+	}
2004
+
2005
+
2006
+	/**
2007
+	 * @deprecated
2008
+	 * @since 4.7.0
2009
+	 * @return string
2010
+	 * @throws EE_Error
2011
+	 */
2012
+	public function pretty_price_paid()
2013
+	{
2014
+		EE_Error::doing_it_wrong('EE_Registration::pretty_price_paid()',
2015
+			esc_html__('This method is deprecated, please use EE_Registration::pretty_final_price() instead.',
2016
+				'event_espresso'), '4.7.0');
2017
+		return $this->pretty_final_price();
2018
+	}
2019
+
2020
+
2021
+	/**
2022
+	 * Gets the primary datetime related to this registration via the related Event to this registration
2023
+	 *
2024
+	 * @deprecated 4.9.17
2025
+	 * @return EE_Datetime
2026
+	 * @throws EE_Error
2027
+	 * @throws EntityNotFoundException
2028
+	 */
2029
+	public function get_related_primary_datetime()
2030
+	{
2031
+		EE_Error::doing_it_wrong(
2032
+			__METHOD__,
2033
+			esc_html__(
2034
+				'Use EE_Registration::get_latest_related_datetime() or EE_Registration::get_earliest_related_datetime()',
2035
+				'event_espresso'
2036
+			),
2037
+			'4.9.17',
2038
+			'5.0.0'
2039
+		);
2040
+		return $this->event()->primary_datetime();
2041
+	}
2042 2042
 
2043 2043
 
2044 2044
 }
Please login to merge, or discard this patch.
modules/single_page_checkout/inc/EE_Checkout.class.php 2 patches
Indentation   +64 added lines, -64 removed lines patch added patch discarded remove patch
@@ -1,16 +1,16 @@  discard block
 block discarded – undo
1 1
 <?php if ( ! defined('EVENT_ESPRESSO_VERSION')) { exit('No direct script access allowed'); }
2 2
  /**
3
- *
4
- * Class EE_Checkout
5
- *
6
- * Description
7
- *
8
- * @package 			Event Espresso
9
- * @subpackage    core
10
- * @author				Brent Christensen
11
- * @since 				4.5.0
12
- *
13
- */
3
+  *
4
+  * Class EE_Checkout
5
+  *
6
+  * Description
7
+  *
8
+  * @package 			Event Espresso
9
+  * @subpackage    core
10
+  * @author				Brent Christensen
11
+  * @since 				4.5.0
12
+  *
13
+  */
14 14
 class EE_Checkout {
15 15
 
16 16
 	/**
@@ -250,9 +250,9 @@  discard block
 block discarded – undo
250 250
 		$this->continue_reg = apply_filters( 'FHEE__EE_Checkout___construct___continue_reg', TRUE );
251 251
 		$this->admin_request = is_admin() && ! EE_Registry::instance()->REQ->ajax;
252 252
 		$this->reg_cache_where_params = array(
253
-		    0 => array( 'REG_deleted' => false ),
254
-		    'order_by' => array( 'REG_count' => 'ASC' )
255
-        );
253
+			0 => array( 'REG_deleted' => false ),
254
+			'order_by' => array( 'REG_count' => 'ASC' )
255
+		);
256 256
 	}
257 257
 
258 258
 
@@ -807,10 +807,10 @@  discard block
 block discarded – undo
807 807
 	 */
808 808
 	public function visit_allows_processing_of_this_registration( EE_Registration $registration ) {
809 809
 		return ! $this->revisit
810
-		       || $this->primary_revisit
811
-		       || (
812
-			       $this->revisit && $this->reg_url_link === $registration->reg_url_link()
813
-		       )
810
+			   || $this->primary_revisit
811
+			   || (
812
+				   $this->revisit && $this->reg_url_link === $registration->reg_url_link()
813
+			   )
814 814
 			? true
815 815
 			: false;
816 816
 	}
@@ -1202,16 +1202,16 @@  discard block
 block discarded – undo
1202 1202
 	 * @return array
1203 1203
 	 * @throws \EE_Error
1204 1204
 	 */
1205
-    public function __sleep()
1206
-    {
1207
-	    if ( $this->primary_attendee_obj instanceof EE_Attendee && $this->primary_attendee_obj->ID() ) {
1208
-		    $this->primary_attendee_obj = $this->primary_attendee_obj->ID();
1209
-	    }        // remove the reg form and the checkout
1210
-	    if ( $this->transaction instanceof EE_Transaction && $this->transaction->ID() ) {
1211
-		    $this->transaction = $this->transaction->ID();
1212
-	    }        // remove the reg form and the checkout
1213
-        return array_diff( array_keys( get_object_vars( $this ) ), array( 'billing_form', 'registration_form' ) );
1214
-    }
1205
+	public function __sleep()
1206
+	{
1207
+		if ( $this->primary_attendee_obj instanceof EE_Attendee && $this->primary_attendee_obj->ID() ) {
1208
+			$this->primary_attendee_obj = $this->primary_attendee_obj->ID();
1209
+		}        // remove the reg form and the checkout
1210
+		if ( $this->transaction instanceof EE_Transaction && $this->transaction->ID() ) {
1211
+			$this->transaction = $this->transaction->ID();
1212
+		}        // remove the reg form and the checkout
1213
+		return array_diff( array_keys( get_object_vars( $this ) ), array( 'billing_form', 'registration_form' ) );
1214
+	}
1215 1215
 
1216 1216
 
1217 1217
 	/**
@@ -1243,42 +1243,42 @@  discard block
 block discarded – undo
1243 1243
 	 * @param string $line
1244 1244
 	 * @param array  $info
1245 1245
 	 * @param bool   $display_request
1246
-     * @throws \InvalidArgumentException
1247
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1248
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1249
-     * @throws \EE_Error
1250
-     */
1251
-    public function log($class = '', $func = '', $line = '', $info = array(), $display_request = true)
1252
-    {
1253
-        $data = array(
1254
-            'request->step'           => $this->step,
1255
-            'request->action'         => $this->action,
1256
-            'current_step->slug'      => $this->current_step instanceof EE_SPCO_Reg_Step
1257
-                ? $this->current_step->slug()
1258
-                : '',
1259
-            'current_step->completed' => $this->current_step instanceof EE_SPCO_Reg_Step
1260
-                ? $this->current_step->completed()
1261
-                : '',
1262
-            'next_step->slug' => $this->next_step instanceof EE_SPCO_Reg_Step
1263
-                ? $this->next_step->slug()
1264
-                : '',
1265
-            'txn_status_updated'      => $this->transaction->txn_status_updated(),
1266
-            'reg_status_updated'      => $this->reg_status_updated,
1267
-            'reg_url_link'            => $this->reg_url_link,
1268
-        );
1269
-        if ($this->transaction instanceof EE_Transaction) {
1270
-            $data['TXN_status']    = $this->transaction->status_ID();
1271
-            $data['TXN_reg_steps'] = $this->transaction->reg_steps();
1272
-            foreach ($this->transaction->registrations($this->reg_cache_where_params) as $REG_ID => $registration) {
1273
-                $data['registrations'][ $REG_ID ] = $registration->status_ID();
1274
-            }
1275
-            if ($this->transaction->ID()) {
1276
-                // don't serialize objects
1277
-                $data = array_merge($data, $info);
1278
-                EE_Log::logTxn($class, $func, $line, $this->transaction, $data, $display_request);
1279
-            }
1280
-        }
1281
-    }
1246
+	 * @throws \InvalidArgumentException
1247
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1248
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1249
+	 * @throws \EE_Error
1250
+	 */
1251
+	public function log($class = '', $func = '', $line = '', $info = array(), $display_request = true)
1252
+	{
1253
+		$data = array(
1254
+			'request->step'           => $this->step,
1255
+			'request->action'         => $this->action,
1256
+			'current_step->slug'      => $this->current_step instanceof EE_SPCO_Reg_Step
1257
+				? $this->current_step->slug()
1258
+				: '',
1259
+			'current_step->completed' => $this->current_step instanceof EE_SPCO_Reg_Step
1260
+				? $this->current_step->completed()
1261
+				: '',
1262
+			'next_step->slug' => $this->next_step instanceof EE_SPCO_Reg_Step
1263
+				? $this->next_step->slug()
1264
+				: '',
1265
+			'txn_status_updated'      => $this->transaction->txn_status_updated(),
1266
+			'reg_status_updated'      => $this->reg_status_updated,
1267
+			'reg_url_link'            => $this->reg_url_link,
1268
+		);
1269
+		if ($this->transaction instanceof EE_Transaction) {
1270
+			$data['TXN_status']    = $this->transaction->status_ID();
1271
+			$data['TXN_reg_steps'] = $this->transaction->reg_steps();
1272
+			foreach ($this->transaction->registrations($this->reg_cache_where_params) as $REG_ID => $registration) {
1273
+				$data['registrations'][ $REG_ID ] = $registration->status_ID();
1274
+			}
1275
+			if ($this->transaction->ID()) {
1276
+				// don't serialize objects
1277
+				$data = array_merge($data, $info);
1278
+				EE_Log::logTxn($class, $func, $line, $this->transaction, $data, $display_request);
1279
+			}
1280
+		}
1281
+	}
1282 1282
 
1283 1283
 
1284 1284
 	/**
Please login to merge, or discard this patch.
Spacing   +179 added lines, -179 removed lines patch added patch discarded remove patch
@@ -247,11 +247,11 @@  discard block
 block discarded – undo
247 247
 		$this->reg_page_base_url = EE_Registry::instance()->CFG->core->reg_page_url();
248 248
 		$this->thank_you_page_url = EE_Registry::instance()->CFG->core->thank_you_page_url();
249 249
 		$this->cancel_page_url = EE_Registry::instance()->CFG->core->cancel_page_url();
250
-		$this->continue_reg = apply_filters( 'FHEE__EE_Checkout___construct___continue_reg', TRUE );
250
+		$this->continue_reg = apply_filters('FHEE__EE_Checkout___construct___continue_reg', TRUE);
251 251
 		$this->admin_request = is_admin() && ! EE_Registry::instance()->REQ->ajax;
252 252
 		$this->reg_cache_where_params = array(
253
-		    0 => array( 'REG_deleted' => false ),
254
-		    'order_by' => array( 'REG_count' => 'ASC' )
253
+		    0 => array('REG_deleted' => false),
254
+		    'order_by' => array('REG_count' => 'ASC')
255 255
         );
256 256
 	}
257 257
 
@@ -263,8 +263,8 @@  discard block
 block discarded – undo
263 263
 	 * @return boolean
264 264
 	 */
265 265
 	public function any_reg_status_updated() {
266
-		foreach ( $this->reg_status_updated as $reg_status ) {
267
-			if ( $reg_status ) {
266
+		foreach ($this->reg_status_updated as $reg_status) {
267
+			if ($reg_status) {
268 268
 				return true;
269 269
 			}
270 270
 		}
@@ -277,8 +277,8 @@  discard block
 block discarded – undo
277 277
 	 * @param $REG_ID
278 278
 	 * @return boolean
279 279
 	 */
280
-	public function reg_status_updated( $REG_ID ) {
281
-		return isset( $this->reg_status_updated[ $REG_ID ] ) ? $this->reg_status_updated[ $REG_ID ] : false;
280
+	public function reg_status_updated($REG_ID) {
281
+		return isset($this->reg_status_updated[$REG_ID]) ? $this->reg_status_updated[$REG_ID] : false;
282 282
 	}
283 283
 
284 284
 
@@ -287,8 +287,8 @@  discard block
 block discarded – undo
287 287
 	 * @param $REG_ID
288 288
 	 * @param $reg_status
289 289
 	 */
290
-	public function set_reg_status_updated( $REG_ID, $reg_status ) {
291
-		$this->reg_status_updated[ $REG_ID ] = filter_var( $reg_status, FILTER_VALIDATE_BOOLEAN );
290
+	public function set_reg_status_updated($REG_ID, $reg_status) {
291
+		$this->reg_status_updated[$REG_ID] = filter_var($reg_status, FILTER_VALIDATE_BOOLEAN);
292 292
 	}
293 293
 
294 294
 
@@ -309,7 +309,7 @@  discard block
 block discarded – undo
309 309
 	 * can ONLY be set by the  Finalize_Registration reg step
310 310
 	 */
311 311
 	public function set_exit_spco() {
312
-		if ( $this->current_step instanceof EE_SPCO_Reg_Step_Finalize_Registration ) {
312
+		if ($this->current_step instanceof EE_SPCO_Reg_Step_Finalize_Registration) {
313 313
 			$this->exit_spco = true;
314 314
 		}
315 315
 	}
@@ -326,12 +326,12 @@  discard block
 block discarded – undo
326 326
 	 */
327 327
 	public function reset_for_current_request() {
328 328
 		$this->process_form_submission = FALSE;
329
-		$this->continue_reg = apply_filters( 'FHEE__EE_Checkout___construct___continue_reg', true );
329
+		$this->continue_reg = apply_filters('FHEE__EE_Checkout___construct___continue_reg', true);
330 330
 		$this->admin_request = is_admin() && ! EE_Registry::instance()->REQ->front_ajax;
331 331
 		$this->continue_reg = true;
332 332
 		$this->redirect = false;
333 333
 		// don't reset the cached redirect form if we're about to be asked to display it !!!
334
-		if ( EE_Registry::instance()->REQ->get( 'action', 'display_spco_reg_step' ) !== 'redirect_form' ) {
334
+		if (EE_Registry::instance()->REQ->get('action', 'display_spco_reg_step') !== 'redirect_form') {
335 335
 			$this->redirect_form = '';
336 336
 		}
337 337
 		$this->redirect_url = '';
@@ -348,8 +348,8 @@  discard block
 block discarded – undo
348 348
 	 * @param EE_SPCO_Reg_Step $reg_step_obj
349 349
 	 * @return    void
350 350
 	 */
351
-	public function add_reg_step( EE_SPCO_Reg_Step $reg_step_obj ) {
352
-		$this->reg_steps[ $reg_step_obj->slug()  ] = $reg_step_obj;
351
+	public function add_reg_step(EE_SPCO_Reg_Step $reg_step_obj) {
352
+		$this->reg_steps[$reg_step_obj->slug()] = $reg_step_obj;
353 353
 	}
354 354
 
355 355
 
@@ -365,22 +365,22 @@  discard block
 block discarded – undo
365 365
 	 * @return    void
366 366
 	 * @throws \EE_Error
367 367
 	 */
368
-	public function skip_reg_step( $reg_step_slug = '' ) {
369
-		$step_to_skip = $this->find_reg_step( $reg_step_slug );
370
-		if ( $step_to_skip instanceof EE_SPCO_Reg_Step && $step_to_skip->is_current_step() ) {
371
-			$step_to_skip->set_is_current_step( false );
368
+	public function skip_reg_step($reg_step_slug = '') {
369
+		$step_to_skip = $this->find_reg_step($reg_step_slug);
370
+		if ($step_to_skip instanceof EE_SPCO_Reg_Step && $step_to_skip->is_current_step()) {
371
+			$step_to_skip->set_is_current_step(false);
372 372
 			$step_to_skip->set_completed();
373 373
 			// advance to the next step
374
-			$this->set_current_step( $this->next_step->slug() );
374
+			$this->set_current_step($this->next_step->slug());
375 375
 			// also reset the step param in the request in case any other code references that directly
376
-			EE_Registry::instance()->REQ->set( 'step', $this->current_step->slug() );
376
+			EE_Registry::instance()->REQ->set('step', $this->current_step->slug());
377 377
 			// since we are skipping a step and setting the current step to be what was previously the next step,
378 378
 			// we need to check that the next step is now correct, and not still set to the current step.
379
-			if ( $this->current_step->slug() === $this->next_step->slug() ) {
379
+			if ($this->current_step->slug() === $this->next_step->slug()) {
380 380
 				// correctly setup the next step
381 381
 				$this->set_next_step();
382 382
 			}
383
-			$this->set_reg_step_initiated( $this->current_step );
383
+			$this->set_reg_step_initiated($this->current_step);
384 384
 		}
385 385
 	}
386 386
 
@@ -394,14 +394,14 @@  discard block
 block discarded – undo
394 394
 	 * @param bool   $reset whether to reset reg steps after removal
395 395
 	 * @throws EE_Error
396 396
 	 */
397
-	public function remove_reg_step( $reg_step_slug = '', $reset = true ) {
398
-		unset( $this->reg_steps[ $reg_step_slug  ] );
399
-		if ( $this->transaction instanceof EE_Transaction ) {
397
+	public function remove_reg_step($reg_step_slug = '', $reset = true) {
398
+		unset($this->reg_steps[$reg_step_slug]);
399
+		if ($this->transaction instanceof EE_Transaction) {
400 400
 			// now remove reg step from TXN and save
401
-			$this->transaction->remove_reg_step( $reg_step_slug );
401
+			$this->transaction->remove_reg_step($reg_step_slug);
402 402
 			$this->transaction->save();
403 403
 		}
404
-		if ( $reset ) {
404
+		if ($reset) {
405 405
 			$this->reset_reg_steps();
406 406
 		}
407 407
 	}
@@ -416,9 +416,9 @@  discard block
 block discarded – undo
416 416
 	 * @param int    $order
417 417
 	 * @return    void
418 418
 	 */
419
-	public function set_reg_step_order( $reg_step_slug = '', $order = 100 ) {
420
-		if ( isset( $this->reg_steps[ $reg_step_slug  ] )) {
421
-			$this->reg_steps[ $reg_step_slug ]->set_order( $order );
419
+	public function set_reg_step_order($reg_step_slug = '', $order = 100) {
420
+		if (isset($this->reg_steps[$reg_step_slug])) {
421
+			$this->reg_steps[$reg_step_slug]->set_order($order);
422 422
 		}
423 423
 	}
424 424
 
@@ -431,25 +431,25 @@  discard block
 block discarded – undo
431 431
 	 * @param string $current_step
432 432
 	 * @return    void
433 433
 	 */
434
-	public function set_current_step( $current_step ) {
434
+	public function set_current_step($current_step) {
435 435
 		// grab what step we're on
436
-		$this->current_step = isset( $this->reg_steps[ $current_step ] ) ? $this->reg_steps[ $current_step ] : reset( $this->reg_steps );
436
+		$this->current_step = isset($this->reg_steps[$current_step]) ? $this->reg_steps[$current_step] : reset($this->reg_steps);
437 437
 		// verify instance
438
-		if ( $this->current_step instanceof EE_SPCO_Reg_Step ) {
438
+		if ($this->current_step instanceof EE_SPCO_Reg_Step) {
439 439
 			// we don't want to repeat completed steps if this is the first time through SPCO
440
-			if ( $this->continue_reg && ! $this->revisit && $this->current_step->completed() ) {
440
+			if ($this->continue_reg && ! $this->revisit && $this->current_step->completed()) {
441 441
 				// so advance to the next step
442 442
 				$this->set_next_step();
443
-				if ( $this->next_step instanceof EE_SPCO_Reg_Step ) {
443
+				if ($this->next_step instanceof EE_SPCO_Reg_Step) {
444 444
 					// and attempt to set it as the current step
445
-					$this->set_current_step( $this->next_step->slug() );
445
+					$this->set_current_step($this->next_step->slug());
446 446
 				}
447 447
 				return;
448 448
 			}
449
-			$this->current_step->set_is_current_step( TRUE );
449
+			$this->current_step->set_is_current_step(TRUE);
450 450
 		} else {
451 451
 			EE_Error::add_error(
452
-				__( 'The current step could not be set.', 'event_espresso' ),
452
+				__('The current step could not be set.', 'event_espresso'),
453 453
 				__FILE__, __FUNCTION__, __LINE__
454 454
 			);
455 455
 		}
@@ -466,20 +466,20 @@  discard block
 block discarded – undo
466 466
 	 */
467 467
 	public function set_next_step() {
468 468
 		// set pointer to start of array
469
-		reset( $this->reg_steps );
469
+		reset($this->reg_steps);
470 470
 		// if there is more than one step
471
-		if ( count( $this->reg_steps ) > 1 ) {
471
+		if (count($this->reg_steps) > 1) {
472 472
 			// advance to the current step and set pointer
473
-			while ( key( $this->reg_steps ) !== $this->current_step->slug() && key( $this->reg_steps ) !== '' ) {
474
-				next( $this->reg_steps );
473
+			while (key($this->reg_steps) !== $this->current_step->slug() && key($this->reg_steps) !== '') {
474
+				next($this->reg_steps);
475 475
 			}
476 476
 		}
477 477
 		// advance one more spot ( if it exists )
478
-		$this->next_step = next( $this->reg_steps );
478
+		$this->next_step = next($this->reg_steps);
479 479
 		// verify instance
480
-		$this->next_step = $this->next_step instanceof EE_SPCO_Reg_Step ? $this->next_step  : NULL;
480
+		$this->next_step = $this->next_step instanceof EE_SPCO_Reg_Step ? $this->next_step : NULL;
481 481
 		// then back to current step to reset
482
-		prev( $this->reg_steps );
482
+		prev($this->reg_steps);
483 483
 	}
484 484
 
485 485
 
@@ -493,8 +493,8 @@  discard block
 block discarded – undo
493 493
 	 *  @return 	EE_SPCO_Reg_Step | null
494 494
 	 */
495 495
 	public function get_next_reg_step() {
496
-		$next = next( $this->reg_steps );
497
-		prev( $this->reg_steps );
496
+		$next = next($this->reg_steps);
497
+		prev($this->reg_steps);
498 498
 		return $next instanceof EE_SPCO_Reg_Step ? $next : null;
499 499
 	}
500 500
 
@@ -509,8 +509,8 @@  discard block
 block discarded – undo
509 509
 	 *  @return 	EE_SPCO_Reg_Step | null
510 510
 	 */
511 511
 	public function get_prev_reg_step() {
512
-		$prev = prev( $this->reg_steps );
513
-		next( $this->reg_steps );
512
+		$prev = prev($this->reg_steps);
513
+		next($this->reg_steps);
514 514
 		return $prev instanceof EE_SPCO_Reg_Step ? $prev : null;
515 515
 	}
516 516
 
@@ -523,8 +523,8 @@  discard block
 block discarded – undo
523 523
 	 * @return void
524 524
 	 */
525 525
 	public function sort_reg_steps() {
526
-		$reg_step_sorting_callback = apply_filters( 'FHEE__EE_Checkout__sort_reg_steps__reg_step_sorting_callback', 'reg_step_sorting_callback' );
527
-		uasort( $this->reg_steps, array( $this, $reg_step_sorting_callback ));
526
+		$reg_step_sorting_callback = apply_filters('FHEE__EE_Checkout__sort_reg_steps__reg_step_sorting_callback', 'reg_step_sorting_callback');
527
+		uasort($this->reg_steps, array($this, $reg_step_sorting_callback));
528 528
 	}
529 529
 
530 530
 
@@ -537,19 +537,19 @@  discard block
 block discarded – undo
537 537
 	 * @param string $reg_step_slug
538 538
 	 * @return EE_SPCO_Reg_Step|null
539 539
 	 */
540
-	public function find_reg_step( $reg_step_slug = '' ) {
541
-		if ( ! empty( $reg_step_slug ) ) {
540
+	public function find_reg_step($reg_step_slug = '') {
541
+		if ( ! empty($reg_step_slug)) {
542 542
 			// copy reg step array
543 543
 			$reg_steps = $this->reg_steps;
544 544
 			// set pointer to start of array
545
-			reset( $reg_steps );
545
+			reset($reg_steps);
546 546
 			// if there is more than one step
547
-			if ( count( $reg_steps ) > 1 ) {
547
+			if (count($reg_steps) > 1) {
548 548
 				// advance to the current step and set pointer
549
-				while ( key( $reg_steps ) !== $reg_step_slug && key( $reg_steps ) !== '' ) {
550
-					next( $reg_steps );
549
+				while (key($reg_steps) !== $reg_step_slug && key($reg_steps) !== '') {
550
+					next($reg_steps);
551 551
 				}
552
-				return current( $reg_steps );
552
+				return current($reg_steps);
553 553
 			}
554 554
 		}
555 555
 		return null;
@@ -565,17 +565,17 @@  discard block
 block discarded – undo
565 565
 	 * @param EE_SPCO_Reg_Step $reg_step_B
566 566
 	 * @return int
567 567
 	 */
568
-	public function reg_step_sorting_callback( EE_SPCO_Reg_Step $reg_step_A, EE_SPCO_Reg_Step $reg_step_B ) {
568
+	public function reg_step_sorting_callback(EE_SPCO_Reg_Step $reg_step_A, EE_SPCO_Reg_Step $reg_step_B) {
569 569
 		// send finalize_registration step to the end of the array
570
-		if ( $reg_step_A->slug() === 'finalize_registration' ) {
570
+		if ($reg_step_A->slug() === 'finalize_registration') {
571 571
 			return 1;
572
-		} else if ( $reg_step_B->slug() === 'finalize_registration' ) {
572
+		} else if ($reg_step_B->slug() === 'finalize_registration') {
573 573
 			return -1;
574 574
 		}
575
-		if ( $reg_step_A->order() === $reg_step_B->order() ) {
575
+		if ($reg_step_A->order() === $reg_step_B->order()) {
576 576
 			return 0;
577 577
 		}
578
-		return ( $reg_step_A->order() > $reg_step_B->order() ) ? 1 : -1;
578
+		return ($reg_step_A->order() > $reg_step_B->order()) ? 1 : -1;
579 579
 	}
580 580
 
581 581
 
@@ -587,7 +587,7 @@  discard block
 block discarded – undo
587 587
 	 * @param    EE_SPCO_Reg_Step $reg_step
588 588
 	 * @throws \EE_Error
589 589
 	 */
590
-	public function set_reg_step_initiated( EE_SPCO_Reg_Step $reg_step ) {
590
+	public function set_reg_step_initiated(EE_SPCO_Reg_Step $reg_step) {
591 591
 		// call set_reg_step_initiated ???
592 592
 		if (
593 593
 			// first time visiting SPCO ?
@@ -600,11 +600,11 @@  discard block
 block discarded – undo
600 600
 			)
601 601
 		) {
602 602
 			// set the start time for this reg step
603
-			if ( ! $this->transaction->set_reg_step_initiated( $reg_step->slug() ) ) {
604
-				if ( WP_DEBUG ) {
603
+			if ( ! $this->transaction->set_reg_step_initiated($reg_step->slug())) {
604
+				if (WP_DEBUG) {
605 605
 					EE_Error::add_error(
606 606
 						sprintf(
607
-							__( 'The "%1$s" registration step was not initialized properly.', 'event_espresso' ),
607
+							__('The "%1$s" registration step was not initialized properly.', 'event_espresso'),
608 608
 							$reg_step->name()
609 609
 						),
610 610
 						__FILE__, __FUNCTION__, __LINE__
@@ -623,10 +623,10 @@  discard block
 block discarded – undo
623 623
 	 * 	@return 	void
624 624
 	 */
625 625
 	public function set_reg_step_JSON_info() {
626
-		EE_Registry::$i18n_js_strings[ 'reg_steps' ] = array();
626
+		EE_Registry::$i18n_js_strings['reg_steps'] = array();
627 627
 		// pass basic reg step data to JS
628
-		foreach ( $this->reg_steps as $reg_step ) {
629
-			EE_Registry::$i18n_js_strings[ 'reg_steps' ][] = $reg_step->slug();
628
+		foreach ($this->reg_steps as $reg_step) {
629
+			EE_Registry::$i18n_js_strings['reg_steps'][] = $reg_step->slug();
630 630
 		}
631 631
 		// reset reg step html
632 632
 //		$this->json_response->set_reg_step_html( '' );
@@ -642,7 +642,7 @@  discard block
 block discarded – undo
642 642
 	 */
643 643
 	public function reset_reg_steps() {
644 644
 		$this->sort_reg_steps();
645
-		$this->set_current_step( EE_Registry::instance()->REQ->get( 'step' ));
645
+		$this->set_current_step(EE_Registry::instance()->REQ->get('step'));
646 646
 		$this->set_next_step();
647 647
 		// the text that appears on the reg step form submit button
648 648
 		$this->current_step->set_submit_button_text();
@@ -659,9 +659,9 @@  discard block
 block discarded – undo
659 659
 	 */
660 660
 	public function get_registration_time_limit() {
661 661
 
662
-		$registration_time_limit = (float)( EE_Registry::instance()	->SSN->expiration() - time() );
662
+		$registration_time_limit = (float) (EE_Registry::instance()	->SSN->expiration() - time());
663 663
 		$time_limit_format = $registration_time_limit > 60 * MINUTE_IN_SECONDS ? 'H:i:s' : 'i:s';
664
-		$registration_time_limit = date( $time_limit_format, $registration_time_limit );
664
+		$registration_time_limit = date($time_limit_format, $registration_time_limit);
665 665
 		return apply_filters(
666 666
 			'FHEE__EE_Checkout__get_registration_time_limit__registration_time_limit',
667 667
 			$registration_time_limit
@@ -681,7 +681,7 @@  discard block
 block discarded – undo
681 681
 		//		overpaid TXN
682 682
 		//		free TXN ( total = 0.00 )
683 683
 		// then payment required is TRUE
684
-		return ! ( $this->admin_request || $this->transaction->is_completed() || $this->transaction->is_overpaid() || $this->transaction->is_free() ) ? TRUE : FALSE;
684
+		return ! ($this->admin_request || $this->transaction->is_completed() || $this->transaction->is_overpaid() || $this->transaction->is_free()) ? TRUE : FALSE;
685 685
 	}
686 686
 
687 687
 
@@ -693,12 +693,12 @@  discard block
 block discarded – undo
693 693
 	 * @param EE_Transaction $transaction
694 694
 	 * @return EE_Cart
695 695
 	 */
696
-	public function get_cart_for_transaction( $transaction ) {
697
-		$session = EE_Registry::instance()->load_core( 'Session' );
698
-		$cart = $transaction instanceof EE_Transaction ? EE_Cart::get_cart_from_txn( $transaction, $session ) : null;
696
+	public function get_cart_for_transaction($transaction) {
697
+		$session = EE_Registry::instance()->load_core('Session');
698
+		$cart = $transaction instanceof EE_Transaction ? EE_Cart::get_cart_from_txn($transaction, $session) : null;
699 699
 		// verify cart
700
-		if ( ! $cart instanceof EE_Cart ) {
701
-			$cart = EE_Registry::instance()->load_core( 'Cart' );
700
+		if ( ! $cart instanceof EE_Cart) {
701
+			$cart = EE_Registry::instance()->load_core('Cart');
702 702
 		}
703 703
 
704 704
 		return $cart;
@@ -714,8 +714,8 @@  discard block
 block discarded – undo
714 714
 	 */
715 715
 	public function initialize_txn_reg_steps_array() {
716 716
 		$txn_reg_steps_array = array();
717
-		foreach ( $this->reg_steps as $reg_step ) {
718
-			$txn_reg_steps_array[ $reg_step->slug() ] = FALSE;
717
+		foreach ($this->reg_steps as $reg_step) {
718
+			$txn_reg_steps_array[$reg_step->slug()] = FALSE;
719 719
 		}
720 720
 		return $txn_reg_steps_array;
721 721
 	}
@@ -731,14 +731,14 @@  discard block
 block discarded – undo
731 731
 	 */
732 732
 	public function update_txn_reg_steps_array() {
733 733
 		$updated = false;
734
-		foreach ( $this->reg_steps as $reg_step ) {
735
-			if ( $reg_step->completed() ) {
736
-				$updated = $this->transaction->set_reg_step_completed( $reg_step->slug() )
734
+		foreach ($this->reg_steps as $reg_step) {
735
+			if ($reg_step->completed()) {
736
+				$updated = $this->transaction->set_reg_step_completed($reg_step->slug())
737 737
 					? true
738 738
 					: $updated;
739 739
 			}
740 740
 		}
741
-		if ( $updated ) {
741
+		if ($updated) {
742 742
 			$this->transaction->save();
743 743
 		}
744 744
 		return $updated;
@@ -754,14 +754,14 @@  discard block
 block discarded – undo
754 754
 	 * @throws \EE_Error
755 755
 	 */
756 756
 	public function stash_transaction_and_checkout() {
757
-		if ( ! $this->revisit ) {
757
+		if ( ! $this->revisit) {
758 758
 			$this->update_txn_reg_steps_array();
759 759
 		}
760 760
 		$this->track_transaction_and_registration_status_updates();
761 761
 		// save all data to the db, but suppress errors
762 762
 		//$this->save_all_data( FALSE );
763 763
 		// cache the checkout in the session
764
-		EE_Registry::instance()->SSN->set_checkout( $this );
764
+		EE_Registry::instance()->SSN->set_checkout($this);
765 765
 	}
766 766
 
767 767
 
@@ -776,15 +776,15 @@  discard block
 block discarded – undo
776 776
 	 */
777 777
 	public function track_transaction_and_registration_status_updates() {
778 778
 		// verify the transaction
779
-		if ( $this->transaction instanceof EE_Transaction ) {
779
+		if ($this->transaction instanceof EE_Transaction) {
780 780
 			// has there been a TXN status change during this checkout?
781 781
 			$this->txn_status_updated = $this->transaction->txn_status_updated();
782 782
 			/** @type EE_Registration_Processor $registration_processor */
783
-			$registration_processor = EE_Registry::instance()->load_class( 'Registration_Processor' );
783
+			$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
784 784
 			// grab the saved registrations from the transaction
785
-			foreach ( $this->transaction->registrations( $this->reg_cache_where_params ) as $registration ) {
786
-				if ( $registration_processor->reg_status_updated( $registration->ID() ) ) {
787
-					$this->set_reg_status_updated( $registration->ID(), true );
785
+			foreach ($this->transaction->registrations($this->reg_cache_where_params) as $registration) {
786
+				if ($registration_processor->reg_status_updated($registration->ID())) {
787
+					$this->set_reg_status_updated($registration->ID(), true);
788 788
 				}
789 789
 			}
790 790
 		}
@@ -805,7 +805,7 @@  discard block
 block discarded – undo
805 805
 	 * @return    bool
806 806
 	 * @throws \EE_Error
807 807
 	 */
808
-	public function visit_allows_processing_of_this_registration( EE_Registration $registration ) {
808
+	public function visit_allows_processing_of_this_registration(EE_Registration $registration) {
809 809
 		return ! $this->revisit
810 810
 		       || $this->primary_revisit
811 811
 		       || (
@@ -838,18 +838,18 @@  discard block
 block discarded – undo
838 838
 	 * @return bool
839 839
 	 * @throws \EE_Error
840 840
 	 */
841
-	public function save_all_data( $show_errors = TRUE ) {
841
+	public function save_all_data($show_errors = TRUE) {
842 842
 		// verify the transaction
843
-		if ( $this->transaction instanceof EE_Transaction ) {
843
+		if ($this->transaction instanceof EE_Transaction) {
844 844
 			// save to ensure that TXN has ID
845 845
 			$this->transaction->save();
846 846
 			// grab the saved registrations from the transaction
847
-			foreach ( $this->transaction->registrations( $this->reg_cache_where_params ) as  $registration ) {
848
-				$this->_save_registration( $registration, $show_errors );
847
+			foreach ($this->transaction->registrations($this->reg_cache_where_params) as  $registration) {
848
+				$this->_save_registration($registration, $show_errors);
849 849
 			}
850 850
 		} else {
851
-			if ( $show_errors ) {
852
-				EE_Error::add_error( __( 'A valid Transaction was not found when attempting to save your registration information.', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__);
851
+			if ($show_errors) {
852
+				EE_Error::add_error(__('A valid Transaction was not found when attempting to save your registration information.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
853 853
 			}
854 854
 			return FALSE;
855 855
 		}
@@ -866,32 +866,32 @@  discard block
 block discarded – undo
866 866
 	 * @return void
867 867
 	 * @throws \EE_Error
868 868
 	 */
869
-	private function _save_registration( $registration, $show_errors = TRUE  ) {
869
+	private function _save_registration($registration, $show_errors = TRUE) {
870 870
 		// verify object
871
-		if ( $registration instanceof EE_Registration ) {
871
+		if ($registration instanceof EE_Registration) {
872 872
 			// should this registration be processed during this visit ?
873
-			if ( $this->visit_allows_processing_of_this_registration( $registration ) ) {
873
+			if ($this->visit_allows_processing_of_this_registration($registration)) {
874 874
 				//set TXN ID
875
-				if ( ! $registration->transaction_ID() ) {
876
-					$registration->set_transaction_id( $this->transaction->ID() );
875
+				if ( ! $registration->transaction_ID()) {
876
+					$registration->set_transaction_id($this->transaction->ID());
877 877
 				}
878 878
 				// verify and save the attendee
879
-				$this->_save_registration_attendee( $registration, $show_errors );
879
+				$this->_save_registration_attendee($registration, $show_errors);
880 880
 				// save answers to reg form questions
881
-				$this->_save_registration_answers( $registration, $show_errors );
881
+				$this->_save_registration_answers($registration, $show_errors);
882 882
 				// save changes
883 883
 				$registration->save();
884 884
 				// update txn cache
885
-				if ( ! $this->transaction->update_cache_after_object_save( 'Registration', $registration )) {
886
-					if ( $show_errors ) {
887
-						EE_Error::add_error( __( 'The newly saved Registration object could not be cached on the Transaction.', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__);
885
+				if ( ! $this->transaction->update_cache_after_object_save('Registration', $registration)) {
886
+					if ($show_errors) {
887
+						EE_Error::add_error(__('The newly saved Registration object could not be cached on the Transaction.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
888 888
 					}
889 889
 				}
890 890
 			}
891 891
 		} else {
892
-			if ( $show_errors ) {
892
+			if ($show_errors) {
893 893
 				EE_Error::add_error(
894
-					__( 'An invalid Registration object was discovered when attempting to save your registration information.', 'event_espresso' ),
894
+					__('An invalid Registration object was discovered when attempting to save your registration information.', 'event_espresso'),
895 895
 					__FILE__, __FUNCTION__, __LINE__
896 896
 				);
897 897
 			}
@@ -908,25 +908,25 @@  discard block
 block discarded – undo
908 908
 	 * @return void
909 909
 	 * @throws \EE_Error
910 910
 	 */
911
-	private function _save_registration_attendee( $registration, $show_errors = TRUE ) {
912
-		if ( $registration->attendee() instanceof EE_Attendee ) {
911
+	private function _save_registration_attendee($registration, $show_errors = TRUE) {
912
+		if ($registration->attendee() instanceof EE_Attendee) {
913 913
 			// save so that ATT has ID
914 914
 			$registration->attendee()->save();
915
-			if ( ! $registration->update_cache_after_object_save( 'Attendee', $registration->attendee() ) ) {
916
-				if ( $show_errors ) {
915
+			if ( ! $registration->update_cache_after_object_save('Attendee', $registration->attendee())) {
916
+				if ($show_errors) {
917 917
 					EE_Error::add_error(
918
-						__( 'The newly saved Attendee object could not be cached on the registration.', 'event_espresso' ),
918
+						__('The newly saved Attendee object could not be cached on the registration.', 'event_espresso'),
919 919
 						__FILE__, __FUNCTION__, __LINE__
920 920
 					);
921 921
 				}
922 922
 			}
923 923
 		} else {
924
-			if ( $show_errors ) {
924
+			if ($show_errors) {
925 925
 				EE_Error::add_error(
926 926
 					sprintf(
927 927
 						'%1$s||%1$s $attendee = %2$s',
928
-						__( 'Either no Attendee information was found, or an invalid Attendee object was discovered when attempting to save your registration information.', 'event_espresso' ),
929
-						var_export( $registration->attendee(), true )
928
+						__('Either no Attendee information was found, or an invalid Attendee object was discovered when attempting to save your registration information.', 'event_espresso'),
929
+						var_export($registration->attendee(), true)
930 930
 					),
931 931
 					__FILE__, __FUNCTION__, __LINE__
932 932
 				);
@@ -944,25 +944,25 @@  discard block
 block discarded – undo
944 944
 	 * @return void
945 945
 	 * @throws \EE_Error
946 946
 	 */
947
-	private function _save_registration_answers( $registration, $show_errors = TRUE ) {
947
+	private function _save_registration_answers($registration, $show_errors = TRUE) {
948 948
 		// now save the answers
949
-		foreach ( $registration->answers() as $cache_key => $answer ) {
949
+		foreach ($registration->answers() as $cache_key => $answer) {
950 950
 			// verify object
951
-			if ( $answer instanceof EE_Answer ) {
952
-				$answer->set_registration( $registration->ID() );
951
+			if ($answer instanceof EE_Answer) {
952
+				$answer->set_registration($registration->ID());
953 953
 				$answer->save();
954
-				if ( ! $registration->update_cache_after_object_save( 'Answer', $answer, $cache_key )) {
955
-					if ( $show_errors ) {
954
+				if ( ! $registration->update_cache_after_object_save('Answer', $answer, $cache_key)) {
955
+					if ($show_errors) {
956 956
 						EE_Error::add_error(
957
-							__( 'The newly saved Answer object could not be cached on the registration.', 'event_espresso' ),
957
+							__('The newly saved Answer object could not be cached on the registration.', 'event_espresso'),
958 958
 							__FILE__, __FUNCTION__, __LINE__
959 959
 						);
960 960
 					}
961 961
 				}
962 962
 			} else {
963
-				if ( $show_errors ) {
963
+				if ($show_errors) {
964 964
 					EE_Error::add_error(
965
-						__( 'An invalid Answer object was discovered when attempting to save your registration information.', 'event_espresso' ),
965
+						__('An invalid Answer object was discovered when attempting to save your registration information.', 'event_espresso'),
966 966
 						__FILE__, __FUNCTION__, __LINE__
967 967
 					);
968 968
 				}
@@ -981,7 +981,7 @@  discard block
 block discarded – undo
981 981
 	 * @return bool
982 982
 	 * @throws \EE_Error
983 983
 	 */
984
-	public function refresh_all_entities( $from_db = false ) {
984
+	public function refresh_all_entities($from_db = false) {
985 985
 		$from_db = $this->current_step->is_final_step() || $this->action === 'process_gateway_response'
986 986
 			? true
987 987
 			: $from_db;
@@ -1005,11 +1005,11 @@  discard block
 block discarded – undo
1005 1005
 	 */
1006 1006
 	protected function refresh_from_db() {
1007 1007
 		// verify the transaction
1008
-		if ( $this->transaction instanceof EE_Transaction && $this->transaction->ID() ) {
1008
+		if ($this->transaction instanceof EE_Transaction && $this->transaction->ID()) {
1009 1009
 			// pull fresh TXN data from the db
1010
-			$this->transaction = $this->transaction->get_model()->refresh_entity_map_from_db( $this->transaction->ID() );
1010
+			$this->transaction = $this->transaction->get_model()->refresh_entity_map_from_db($this->transaction->ID());
1011 1011
 			// update EE_Checkout's cached primary_attendee object
1012
-			$this->primary_attendee_obj = $this->_refresh_primary_attendee_obj_from_db( $this->transaction );
1012
+			$this->primary_attendee_obj = $this->_refresh_primary_attendee_obj_from_db($this->transaction);
1013 1013
 			// update EE_Checkout's cached payment object
1014 1014
 			$payment = $this->transaction->last_payment();
1015 1015
 			$this->payment = $payment instanceof EE_Payment ? $payment : $this->payment;
@@ -1017,9 +1017,9 @@  discard block
 block discarded – undo
1017 1017
 			$payment_method = $this->payment instanceof EE_Payment ? $this->payment->payment_method() : null;
1018 1018
 			$this->payment_method = $payment_method instanceof EE_Payment_Method ? $payment_method : $this->payment_method;
1019 1019
 			//now refresh the cart, based on the TXN
1020
-			$this->cart = $this->get_cart_for_transaction( $this->transaction );
1020
+			$this->cart = $this->get_cart_for_transaction($this->transaction);
1021 1021
 		} else {
1022
-			EE_Error::add_error( __( 'A valid Transaction was not found when attempting to update the model entity mapper.', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__);
1022
+			EE_Error::add_error(__('A valid Transaction was not found when attempting to update the model entity mapper.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
1023 1023
 			return FALSE;
1024 1024
 		}
1025 1025
 		return TRUE;
@@ -1034,21 +1034,21 @@  discard block
 block discarded – undo
1034 1034
 	 * @return  EE_Attendee | null
1035 1035
 	 * @throws \EE_Error
1036 1036
 	 */
1037
-	protected function _refresh_primary_attendee_obj_from_db( EE_Transaction $transaction ) {
1037
+	protected function _refresh_primary_attendee_obj_from_db(EE_Transaction $transaction) {
1038 1038
 
1039 1039
 		$primary_attendee_obj = null;
1040 1040
 		// grab the saved registrations from the transaction
1041
-		foreach ( $transaction->registrations( $this->reg_cache_where_params, true ) as $registration ) {
1041
+		foreach ($transaction->registrations($this->reg_cache_where_params, true) as $registration) {
1042 1042
 			// verify object
1043
-			if ( $registration instanceof EE_Registration ) {
1043
+			if ($registration instanceof EE_Registration) {
1044 1044
 				$attendee = $registration->attendee();
1045 1045
 				// verify object && maybe cache primary_attendee_obj ?
1046
-				if ( $attendee instanceof EE_Attendee&& $registration->is_primary_registrant() ) {
1046
+				if ($attendee instanceof EE_Attendee && $registration->is_primary_registrant()) {
1047 1047
 					$primary_attendee_obj = $attendee;
1048 1048
 				}
1049 1049
 			} else {
1050 1050
 				EE_Error::add_error(
1051
-						__( 'An invalid Registration object was discovered when attempting to update the model entity mapper.', 'event_espresso' ),
1051
+						__('An invalid Registration object was discovered when attempting to update the model entity mapper.', 'event_espresso'),
1052 1052
 						__FILE__, __FUNCTION__, __LINE__
1053 1053
 				);
1054 1054
 			}
@@ -1069,43 +1069,43 @@  discard block
 block discarded – undo
1069 1069
 	 */
1070 1070
 	protected function refresh_entity_map() {
1071 1071
 		// verify the transaction
1072
-		if ( $this->transaction instanceof EE_Transaction && $this->transaction->ID() ) {
1072
+		if ($this->transaction instanceof EE_Transaction && $this->transaction->ID()) {
1073 1073
 			// never cache payment info
1074
-			$this->transaction->clear_cache( 'Payment' );
1074
+			$this->transaction->clear_cache('Payment');
1075 1075
 			// is the Payment Options Reg Step completed ?
1076
-			if ( $this->transaction->reg_step_completed( 'payment_options' ) ) {
1076
+			if ($this->transaction->reg_step_completed('payment_options')) {
1077 1077
 				// then check for payments and update TXN accordingly
1078 1078
 				/** @type EE_Transaction_Payments $transaction_payments */
1079
-				$transaction_payments = EE_Registry::instance()->load_class( 'Transaction_Payments' );
1080
-				$transaction_payments->calculate_total_payments_and_update_status( $this->transaction );
1079
+				$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1080
+				$transaction_payments->calculate_total_payments_and_update_status($this->transaction);
1081 1081
 			}
1082 1082
 			// grab the saved registrations from the transaction
1083 1083
 			foreach (
1084
-				$this->transaction->registrations( $this->reg_cache_where_params ) as $reg_cache_ID => $registration
1084
+				$this->transaction->registrations($this->reg_cache_where_params) as $reg_cache_ID => $registration
1085 1085
 			) {
1086
-				$this->_refresh_registration( $reg_cache_ID, $registration );
1086
+				$this->_refresh_registration($reg_cache_ID, $registration);
1087 1087
 			}
1088 1088
 			// make sure our cached TXN is added to the model entity mapper
1089
-			$this->transaction = $this->transaction->get_model()->refresh_entity_map_with( $this->transaction->ID(), $this->transaction );
1089
+			$this->transaction = $this->transaction->get_model()->refresh_entity_map_with($this->transaction->ID(), $this->transaction);
1090 1090
 
1091 1091
 		} else {
1092
-			EE_Error::add_error( __( 'A valid Transaction was not found when attempting to update the model entity mapper.', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__);
1092
+			EE_Error::add_error(__('A valid Transaction was not found when attempting to update the model entity mapper.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
1093 1093
 			return FALSE;
1094 1094
 		}
1095 1095
 		// verify and update the cart because inaccurate totals are not so much fun
1096
-		if ( $this->cart instanceof EE_Cart ) {
1096
+		if ($this->cart instanceof EE_Cart) {
1097 1097
 			$grand_total = $this->cart->get_grand_total();
1098
-			if ( $grand_total instanceof EE_Line_Item && $grand_total->ID() ) {
1098
+			if ($grand_total instanceof EE_Line_Item && $grand_total->ID()) {
1099 1099
 				$grand_total->recalculate_total_including_taxes();
1100 1100
 				$grand_total = $grand_total->get_model()->refresh_entity_map_with(
1101 1101
 					$this->cart->get_grand_total()->ID(),
1102 1102
 					$this->cart->get_grand_total()
1103 1103
 				);
1104 1104
 			}
1105
-			if ( $grand_total instanceof EE_Line_Item ) {
1106
-				$this->cart = EE_Cart::instance( $grand_total );
1105
+			if ($grand_total instanceof EE_Line_Item) {
1106
+				$this->cart = EE_Cart::instance($grand_total);
1107 1107
 			} else {
1108
-				EE_Error::add_error( __( 'A valid Cart was not found when attempting to update the model entity mapper.', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__ );
1108
+				EE_Error::add_error(__('A valid Cart was not found when attempting to update the model entity mapper.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
1109 1109
 				return false;
1110 1110
 			}
1111 1111
 		}
@@ -1122,19 +1122,19 @@  discard block
 block discarded – undo
1122 1122
 	 * @return void
1123 1123
 	 * @throws \EE_Error
1124 1124
 	 */
1125
-	protected function _refresh_registration( $reg_cache_ID, $registration ) {
1125
+	protected function _refresh_registration($reg_cache_ID, $registration) {
1126 1126
 
1127 1127
 		// verify object
1128
-		if ( $registration instanceof EE_Registration ) {
1128
+		if ($registration instanceof EE_Registration) {
1129 1129
 			// update the entity mapper attendee
1130
-			$this->_refresh_registration_attendee( $registration );
1130
+			$this->_refresh_registration_attendee($registration);
1131 1131
 			// update the entity mapper answers for reg form questions
1132
-			$this->_refresh_registration_answers( $registration );
1132
+			$this->_refresh_registration_answers($registration);
1133 1133
 			// make sure the cached registration is added to the model entity mapper
1134
-			$registration->get_model()->refresh_entity_map_with( $reg_cache_ID, $registration );
1134
+			$registration->get_model()->refresh_entity_map_with($reg_cache_ID, $registration);
1135 1135
 		} else {
1136 1136
 			EE_Error::add_error(
1137
-				__( 'An invalid Registration object was discovered when attempting to update the model entity mapper.', 'event_espresso' ),
1137
+				__('An invalid Registration object was discovered when attempting to update the model entity mapper.', 'event_espresso'),
1138 1138
 				__FILE__, __FUNCTION__, __LINE__
1139 1139
 			);
1140 1140
 		}
@@ -1149,15 +1149,15 @@  discard block
 block discarded – undo
1149 1149
 	 * @return void
1150 1150
 	 * @throws \EE_Error
1151 1151
 	 */
1152
-	protected function _refresh_registration_attendee( $registration ) {
1152
+	protected function _refresh_registration_attendee($registration) {
1153 1153
 
1154 1154
 		$attendee = $registration->attendee();
1155 1155
 		// verify object
1156
-		if ( $attendee instanceof EE_Attendee && $attendee->ID() ) {
1156
+		if ($attendee instanceof EE_Attendee && $attendee->ID()) {
1157 1157
 			// make sure the cached attendee is added to the model entity mapper
1158
-			$registration->attendee()->get_model()->refresh_entity_map_with( $attendee->ID(), $attendee );
1158
+			$registration->attendee()->get_model()->refresh_entity_map_with($attendee->ID(), $attendee);
1159 1159
 			// maybe cache primary_attendee_obj ?
1160
-			if ( $registration->is_primary_registrant() ) {
1160
+			if ($registration->is_primary_registrant()) {
1161 1161
 				$this->primary_attendee_obj = $attendee;
1162 1162
 			}
1163 1163
 		}
@@ -1172,19 +1172,19 @@  discard block
 block discarded – undo
1172 1172
 	 * @return void
1173 1173
 	 * @throws \EE_Error
1174 1174
 	 */
1175
-	protected function _refresh_registration_answers( $registration ) {
1175
+	protected function _refresh_registration_answers($registration) {
1176 1176
 
1177 1177
 		// now update the answers
1178
-		foreach ( $registration->answers() as $cache_key => $answer ) {
1178
+		foreach ($registration->answers() as $cache_key => $answer) {
1179 1179
 			// verify object
1180
-			if ( $answer instanceof EE_Answer ) {
1181
-				if ( $answer->ID() ) {
1180
+			if ($answer instanceof EE_Answer) {
1181
+				if ($answer->ID()) {
1182 1182
 					// make sure the cached answer is added to the model entity mapper
1183
-					$answer->get_model()->refresh_entity_map_with( $answer->ID(), $answer );
1183
+					$answer->get_model()->refresh_entity_map_with($answer->ID(), $answer);
1184 1184
 				}
1185 1185
 			} else {
1186 1186
 				EE_Error::add_error(
1187
-					__( 'An invalid Answer object was discovered when attempting to update the model entity mapper.', 'event_espresso' ),
1187
+					__('An invalid Answer object was discovered when attempting to update the model entity mapper.', 'event_espresso'),
1188 1188
 					__FILE__, __FUNCTION__, __LINE__
1189 1189
 				);
1190 1190
 			}
@@ -1204,13 +1204,13 @@  discard block
 block discarded – undo
1204 1204
 	 */
1205 1205
     public function __sleep()
1206 1206
     {
1207
-	    if ( $this->primary_attendee_obj instanceof EE_Attendee && $this->primary_attendee_obj->ID() ) {
1207
+	    if ($this->primary_attendee_obj instanceof EE_Attendee && $this->primary_attendee_obj->ID()) {
1208 1208
 		    $this->primary_attendee_obj = $this->primary_attendee_obj->ID();
1209 1209
 	    }        // remove the reg form and the checkout
1210
-	    if ( $this->transaction instanceof EE_Transaction && $this->transaction->ID() ) {
1210
+	    if ($this->transaction instanceof EE_Transaction && $this->transaction->ID()) {
1211 1211
 		    $this->transaction = $this->transaction->ID();
1212 1212
 	    }        // remove the reg form and the checkout
1213
-        return array_diff( array_keys( get_object_vars( $this ) ), array( 'billing_form', 'registration_form' ) );
1213
+        return array_diff(array_keys(get_object_vars($this)), array('billing_form', 'registration_form'));
1214 1214
     }
1215 1215
 
1216 1216
 
@@ -1220,15 +1220,15 @@  discard block
 block discarded – undo
1220 1220
 	 * this will reinstate the EE_Checkout object on each EE_SPCO_Reg_Step object
1221 1221
 	 */
1222 1222
 	public function __wakeup() {
1223
-		if ( ! $this->primary_attendee_obj instanceof EE_Attendee && absint( $this->primary_attendee_obj ) !== 0 ) {
1223
+		if ( ! $this->primary_attendee_obj instanceof EE_Attendee && absint($this->primary_attendee_obj) !== 0) {
1224 1224
 			// $this->primary_attendee_obj is actually just an ID, so use it to get the object from the db
1225
-			$this->primary_attendee_obj = EEM_Attendee::instance()->get_one_by_ID( $this->primary_attendee_obj );
1225
+			$this->primary_attendee_obj = EEM_Attendee::instance()->get_one_by_ID($this->primary_attendee_obj);
1226 1226
 		}
1227
-		if ( ! $this->transaction instanceof EE_Transaction && absint( $this->transaction ) !== 0 ) {
1227
+		if ( ! $this->transaction instanceof EE_Transaction && absint($this->transaction) !== 0) {
1228 1228
 			// $this->transaction is actually just an ID, so use it to get the object from the db
1229
-			$this->transaction = EEM_Transaction::instance()->get_one_by_ID( $this->transaction );
1229
+			$this->transaction = EEM_Transaction::instance()->get_one_by_ID($this->transaction);
1230 1230
 		}
1231
-		foreach ( $this->reg_steps as $reg_step ) {
1231
+		foreach ($this->reg_steps as $reg_step) {
1232 1232
 			$reg_step->checkout = $this;
1233 1233
 		}
1234 1234
 	}
@@ -1270,7 +1270,7 @@  discard block
 block discarded – undo
1270 1270
             $data['TXN_status']    = $this->transaction->status_ID();
1271 1271
             $data['TXN_reg_steps'] = $this->transaction->reg_steps();
1272 1272
             foreach ($this->transaction->registrations($this->reg_cache_where_params) as $REG_ID => $registration) {
1273
-                $data['registrations'][ $REG_ID ] = $registration->status_ID();
1273
+                $data['registrations'][$REG_ID] = $registration->status_ID();
1274 1274
             }
1275 1275
             if ($this->transaction->ID()) {
1276 1276
                 // don't serialize objects
@@ -1287,7 +1287,7 @@  discard block
 block discarded – undo
1287 1287
 	 * @param array $info
1288 1288
 	 * @return array
1289 1289
 	 */
1290
-	public function _strip_objects( $info = array() ) {
1290
+	public function _strip_objects($info = array()) {
1291 1291
 		return EE_Log::stripObjects($info);
1292 1292
 	}
1293 1293
 
Please login to merge, or discard this patch.
modules/single_page_checkout/EED_Single_Page_Checkout.module.php 2 patches
Indentation   +1872 added lines, -1872 removed lines patch added patch discarded remove patch
@@ -5,7 +5,7 @@  discard block
 block discarded – undo
5 5
 use EventEspresso\core\exceptions\InvalidEntityException;
6 6
 
7 7
 if ( ! defined('EVENT_ESPRESSO_VERSION')) {
8
-    exit('No direct script access allowed');
8
+	exit('No direct script access allowed');
9 9
 }
10 10
 
11 11
 
@@ -20,1877 +20,1877 @@  discard block
 block discarded – undo
20 20
 class EED_Single_Page_Checkout extends EED_Module
21 21
 {
22 22
 
23
-    /**
24
-     * $_initialized - has the SPCO controller already been initialized ?
25
-     *
26
-     * @access private
27
-     * @var bool $_initialized
28
-     */
29
-    private static $_initialized = false;
30
-
31
-
32
-    /**
33
-     * $_checkout_verified - is the EE_Checkout verified as correct for this request ?
34
-     *
35
-     * @access private
36
-     * @var bool $_valid_checkout
37
-     */
38
-    private static $_checkout_verified = true;
39
-
40
-    /**
41
-     *    $_reg_steps_array - holds initial array of reg steps
42
-     *
43
-     * @access private
44
-     * @var array $_reg_steps_array
45
-     */
46
-    private static $_reg_steps_array = array();
47
-
48
-    /**
49
-     *    $checkout - EE_Checkout object for handling the properties of the current checkout process
50
-     *
51
-     * @access public
52
-     * @var EE_Checkout $checkout
53
-     */
54
-    public $checkout;
55
-
56
-
57
-
58
-    /**
59
-     * @return EED_Module|EED_Single_Page_Checkout
60
-     */
61
-    public static function instance()
62
-    {
63
-        add_filter('EED_Single_Page_Checkout__SPCO_active', '__return_true');
64
-        return parent::get_instance(__CLASS__);
65
-    }
66
-
67
-
68
-
69
-    /**
70
-     * @return EE_CART
71
-     */
72
-    public function cart()
73
-    {
74
-        return $this->checkout->cart;
75
-    }
76
-
77
-
78
-
79
-    /**
80
-     * @return EE_Transaction
81
-     */
82
-    public function transaction()
83
-    {
84
-        return $this->checkout->transaction;
85
-    }
86
-
87
-
88
-
89
-    /**
90
-     *    set_hooks - for hooking into EE Core, other modules, etc
91
-     *
92
-     * @access    public
93
-     * @return    void
94
-     * @throws EE_Error
95
-     */
96
-    public static function set_hooks()
97
-    {
98
-        EED_Single_Page_Checkout::set_definitions();
99
-    }
100
-
101
-
102
-
103
-    /**
104
-     *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
105
-     *
106
-     * @access    public
107
-     * @return    void
108
-     * @throws EE_Error
109
-     */
110
-    public static function set_hooks_admin()
111
-    {
112
-        EED_Single_Page_Checkout::set_definitions();
113
-        if ( ! (defined('DOING_AJAX') && DOING_AJAX)) {
114
-            return;
115
-        }
116
-        // going to start an output buffer in case anything gets accidentally output
117
-        // that might disrupt our JSON response
118
-        ob_start();
119
-        EED_Single_Page_Checkout::load_request_handler();
120
-        EED_Single_Page_Checkout::load_reg_steps();
121
-        // set ajax hooks
122
-        add_action('wp_ajax_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step'));
123
-        add_action('wp_ajax_nopriv_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step'));
124
-        add_action('wp_ajax_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step'));
125
-        add_action('wp_ajax_nopriv_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step'));
126
-        add_action('wp_ajax_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step'));
127
-        add_action('wp_ajax_nopriv_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step'));
128
-    }
129
-
130
-
131
-
132
-    /**
133
-     *    process ajax request
134
-     *
135
-     * @param string $ajax_action
136
-     * @throws EE_Error
137
-     */
138
-    public static function process_ajax_request($ajax_action)
139
-    {
140
-        EE_Registry::instance()->REQ->set('action', $ajax_action);
141
-        EED_Single_Page_Checkout::instance()->_initialize();
142
-    }
143
-
144
-
145
-
146
-    /**
147
-     *    ajax display registration step
148
-     *
149
-     * @throws EE_Error
150
-     */
151
-    public static function display_reg_step()
152
-    {
153
-        EED_Single_Page_Checkout::process_ajax_request('display_spco_reg_step');
154
-    }
155
-
156
-
157
-
158
-    /**
159
-     *    ajax process registration step
160
-     *
161
-     * @throws EE_Error
162
-     */
163
-    public static function process_reg_step()
164
-    {
165
-        EED_Single_Page_Checkout::process_ajax_request('process_reg_step');
166
-    }
167
-
168
-
169
-
170
-    /**
171
-     *    ajax process registration step
172
-     *
173
-     * @throws EE_Error
174
-     */
175
-    public static function update_reg_step()
176
-    {
177
-        EED_Single_Page_Checkout::process_ajax_request('update_reg_step');
178
-    }
179
-
180
-
181
-
182
-    /**
183
-     *   update_checkout
184
-     *
185
-     * @access public
186
-     * @return void
187
-     * @throws EE_Error
188
-     */
189
-    public static function update_checkout()
190
-    {
191
-        EED_Single_Page_Checkout::process_ajax_request('update_checkout');
192
-    }
193
-
194
-
195
-
196
-    /**
197
-     *    load_request_handler
198
-     *
199
-     * @access    public
200
-     * @return    void
201
-     */
202
-    public static function load_request_handler()
203
-    {
204
-        // load core Request_Handler class
205
-        if (EE_Registry::instance()->REQ !== null) {
206
-            EE_Registry::instance()->load_core('Request_Handler');
207
-        }
208
-    }
209
-
210
-
211
-
212
-    /**
213
-     *    set_definitions
214
-     *
215
-     * @access    public
216
-     * @return    void
217
-     * @throws EE_Error
218
-     */
219
-    public static function set_definitions()
220
-    {
221
-        if(defined('SPCO_BASE_PATH')) {
222
-            return;
223
-        }
224
-        define(
225
-            'SPCO_BASE_PATH',
226
-            rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS) . DS
227
-        );
228
-        define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css' . DS);
229
-        define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img' . DS);
230
-        define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js' . DS);
231
-        define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc' . DS);
232
-        define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps' . DS);
233
-        define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates' . DS);
234
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true);
235
-        EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
236
-            __('%1$sWe\'re sorry, but you\'re registration time has expired.%2$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please except our apologies for any inconvenience this may have caused.%8$s',
237
-                'event_espresso'),
238
-            '<h4 class="important-notice">',
239
-            '</h4>',
240
-            '<br />',
241
-            '<p>',
242
-            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
243
-            '">',
244
-            '</a>',
245
-            '</p>'
246
-        );
247
-    }
248
-
249
-
250
-
251
-    /**
252
-     * load_reg_steps
253
-     * loads and instantiates each reg step based on the EE_Registry::instance()->CFG->registration->reg_steps array
254
-     *
255
-     * @access    private
256
-     * @throws EE_Error
257
-     */
258
-    public static function load_reg_steps()
259
-    {
260
-        static $reg_steps_loaded = false;
261
-        if ($reg_steps_loaded) {
262
-            return;
263
-        }
264
-        // filter list of reg_steps
265
-        $reg_steps_to_load = (array)apply_filters(
266
-            'AHEE__SPCO__load_reg_steps__reg_steps_to_load',
267
-            EED_Single_Page_Checkout::get_reg_steps()
268
-        );
269
-        // sort by key (order)
270
-        ksort($reg_steps_to_load);
271
-        // loop through folders
272
-        foreach ($reg_steps_to_load as $order => $reg_step) {
273
-            // we need a
274
-            if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) {
275
-                // copy over to the reg_steps_array
276
-                EED_Single_Page_Checkout::$_reg_steps_array[$order] = $reg_step;
277
-                // register custom key route for each reg step
278
-                // ie: step=>"slug" - this is the entire reason we load the reg steps array now
279
-                EE_Config::register_route(
280
-                    $reg_step['slug'],
281
-                    'EED_Single_Page_Checkout',
282
-                    'run',
283
-                    'step'
284
-                );
285
-                // add AJAX or other hooks
286
-                if (isset($reg_step['has_hooks']) && $reg_step['has_hooks']) {
287
-                    // setup autoloaders if necessary
288
-                    if ( ! class_exists($reg_step['class_name'])) {
289
-                        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(
290
-                            $reg_step['file_path'],
291
-                            true
292
-                        );
293
-                    }
294
-                    if (is_callable($reg_step['class_name'], 'set_hooks')) {
295
-                        call_user_func(array($reg_step['class_name'], 'set_hooks'));
296
-                    }
297
-                }
298
-            }
299
-        }
300
-        $reg_steps_loaded = true;
301
-    }
302
-
303
-
304
-
305
-    /**
306
-     *    get_reg_steps
307
-     *
308
-     * @access    public
309
-     * @return    array
310
-     */
311
-    public static function get_reg_steps()
312
-    {
313
-        $reg_steps = EE_Registry::instance()->CFG->registration->reg_steps;
314
-        if (empty($reg_steps)) {
315
-            $reg_steps = array(
316
-                10  => array(
317
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'attendee_information',
318
-                    'class_name' => 'EE_SPCO_Reg_Step_Attendee_Information',
319
-                    'slug'       => 'attendee_information',
320
-                    'has_hooks'  => false,
321
-                ),
322
-                20  => array(
323
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'registration_confirmation',
324
-                    'class_name' => 'EE_SPCO_Reg_Step_Registration_Confirmation',
325
-                    'slug'       => 'registration_confirmation',
326
-                    'has_hooks'  => false,
327
-                ),
328
-                30  => array(
329
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'payment_options',
330
-                    'class_name' => 'EE_SPCO_Reg_Step_Payment_Options',
331
-                    'slug'       => 'payment_options',
332
-                    'has_hooks'  => true,
333
-                ),
334
-                999 => array(
335
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'finalize_registration',
336
-                    'class_name' => 'EE_SPCO_Reg_Step_Finalize_Registration',
337
-                    'slug'       => 'finalize_registration',
338
-                    'has_hooks'  => false,
339
-                ),
340
-            );
341
-        }
342
-        return $reg_steps;
343
-    }
344
-
345
-
346
-
347
-    /**
348
-     *    registration_checkout_for_admin
349
-     *
350
-     * @access    public
351
-     * @return    string
352
-     * @throws EE_Error
353
-     */
354
-    public static function registration_checkout_for_admin()
355
-    {
356
-        EED_Single_Page_Checkout::load_request_handler();
357
-        EE_Registry::instance()->REQ->set('step', 'attendee_information');
358
-        EE_Registry::instance()->REQ->set('action', 'display_spco_reg_step');
359
-        EE_Registry::instance()->REQ->set('process_form_submission', false);
360
-        EED_Single_Page_Checkout::instance()->_initialize();
361
-        EED_Single_Page_Checkout::instance()->_display_spco_reg_form();
362
-        return EE_Registry::instance()->REQ->get_output();
363
-    }
364
-
365
-
366
-
367
-    /**
368
-     * process_registration_from_admin
369
-     *
370
-     * @access public
371
-     * @return \EE_Transaction
372
-     * @throws EE_Error
373
-     */
374
-    public static function process_registration_from_admin()
375
-    {
376
-        EED_Single_Page_Checkout::load_request_handler();
377
-        EE_Registry::instance()->REQ->set('step', 'attendee_information');
378
-        EE_Registry::instance()->REQ->set('action', 'process_reg_step');
379
-        EE_Registry::instance()->REQ->set('process_form_submission', true);
380
-        EED_Single_Page_Checkout::instance()->_initialize();
381
-        if (EED_Single_Page_Checkout::instance()->checkout->current_step->completed()) {
382
-            $final_reg_step = end(EED_Single_Page_Checkout::instance()->checkout->reg_steps);
383
-            if ($final_reg_step instanceof EE_SPCO_Reg_Step_Finalize_Registration) {
384
-                EED_Single_Page_Checkout::instance()->checkout->set_reg_step_initiated($final_reg_step);
385
-                if ($final_reg_step->process_reg_step()) {
386
-                    $final_reg_step->set_completed();
387
-                    EED_Single_Page_Checkout::instance()->checkout->update_txn_reg_steps_array();
388
-                    return EED_Single_Page_Checkout::instance()->checkout->transaction;
389
-                }
390
-            }
391
-        }
392
-        return null;
393
-    }
394
-
395
-
396
-
397
-    /**
398
-     *    run
399
-     *
400
-     * @access    public
401
-     * @param WP_Query $WP_Query
402
-     * @return    void
403
-     * @throws EE_Error
404
-     */
405
-    public function run($WP_Query)
406
-    {
407
-        if (
408
-            $WP_Query instanceof WP_Query
409
-            && $WP_Query->is_main_query()
410
-            && apply_filters('FHEE__EED_Single_Page_Checkout__run', true)
411
-            && $this->_is_reg_checkout()
412
-        ) {
413
-            $this->_initialize();
414
-        }
415
-    }
416
-
417
-
418
-
419
-    /**
420
-     * determines whether current url matches reg page url
421
-     *
422
-     * @return bool
423
-     */
424
-    protected function _is_reg_checkout()
425
-    {
426
-        // get current permalink for reg page without any extra query args
427
-        $reg_page_url = \get_permalink(EE_Config::instance()->core->reg_page_id);
428
-        // get request URI for current request, but without the scheme or host
429
-        $current_request_uri = \EEH_URL::filter_input_server_url('REQUEST_URI');
430
-        $current_request_uri = html_entity_decode($current_request_uri);
431
-        // get array of query args from the current request URI
432
-        $query_args = \EEH_URL::get_query_string($current_request_uri);
433
-        // grab page id if it is set
434
-        $page_id = isset($query_args['page_id']) ? absint($query_args['page_id']) : 0;
435
-        // and remove the page id from the query args (we will re-add it later)
436
-        unset($query_args['page_id']);
437
-        // now strip all query args from current request URI
438
-        $current_request_uri = remove_query_arg(array_keys($query_args), $current_request_uri);
439
-        // and re-add the page id if it was set
440
-        if ($page_id) {
441
-            $current_request_uri = add_query_arg('page_id', $page_id, $current_request_uri);
442
-        }
443
-        // remove slashes and ?
444
-        $current_request_uri = trim($current_request_uri, '?/');
445
-        // is current request URI part of the known full reg page URL ?
446
-        return ! empty($current_request_uri) && strpos($reg_page_url, $current_request_uri) !== false;
447
-    }
448
-
449
-
450
-
451
-    /**
452
-     * @param WP_Query $wp_query
453
-     * @return    void
454
-     * @throws EE_Error
455
-     */
456
-    public static function init($wp_query)
457
-    {
458
-        EED_Single_Page_Checkout::instance()->run($wp_query);
459
-    }
460
-
461
-
462
-
463
-    /**
464
-     *    _initialize - initial module setup
465
-     *
466
-     * @access    private
467
-     * @throws EE_Error
468
-     * @return    void
469
-     */
470
-    private function _initialize()
471
-    {
472
-        // ensure SPCO doesn't run twice
473
-        if (EED_Single_Page_Checkout::$_initialized) {
474
-            return;
475
-        }
476
-        try {
477
-            EED_Single_Page_Checkout::load_reg_steps();
478
-            $this->_verify_session();
479
-            // setup the EE_Checkout object
480
-            $this->checkout = $this->_initialize_checkout();
481
-            // filter checkout
482
-            $this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize__checkout', $this->checkout);
483
-            // get the $_GET
484
-            $this->_get_request_vars();
485
-            if ($this->_block_bots()) {
486
-                return;
487
-            }
488
-            // filter continue_reg
489
-            $this->checkout->continue_reg = apply_filters(
490
-                'FHEE__EED_Single_Page_Checkout__init___continue_reg',
491
-                true,
492
-                $this->checkout
493
-            );
494
-            // load the reg steps array
495
-            if ( ! $this->_load_and_instantiate_reg_steps()) {
496
-                EED_Single_Page_Checkout::$_initialized = true;
497
-                return;
498
-            }
499
-            // set the current step
500
-            $this->checkout->set_current_step($this->checkout->step);
501
-            // and the next step
502
-            $this->checkout->set_next_step();
503
-            // verify that everything has been setup correctly
504
-            if ( ! ($this->_verify_transaction_and_get_registrations() && $this->_final_verifications())) {
505
-                EED_Single_Page_Checkout::$_initialized = true;
506
-                return;
507
-            }
508
-            // lock the transaction
509
-            $this->checkout->transaction->lock();
510
-            // make sure all of our cached objects are added to their respective model entity mappers
511
-            $this->checkout->refresh_all_entities();
512
-            // set amount owing
513
-            $this->checkout->amount_owing = $this->checkout->transaction->remaining();
514
-            // initialize each reg step, which gives them the chance to potentially alter the process
515
-            $this->_initialize_reg_steps();
516
-            // DEBUG LOG
517
-            $this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
518
-            // get reg form
519
-            if( ! $this->_check_form_submission()) {
520
-                EED_Single_Page_Checkout::$_initialized = true;
521
-                return;
522
-            }
523
-            // checkout the action!!!
524
-            $this->_process_form_action();
525
-            // add some style and make it dance
526
-            $this->add_styles_and_scripts();
527
-            // kk... SPCO has successfully run
528
-            EED_Single_Page_Checkout::$_initialized = true;
529
-            // set no cache headers and constants
530
-            EE_System::do_not_cache();
531
-            // add anchor
532
-            add_action('loop_start', array($this, 'set_checkout_anchor'), 1);
533
-            // remove transaction lock
534
-            add_action('shutdown', array($this, 'unlock_transaction'), 1);
535
-        } catch (Exception $e) {
536
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
537
-        }
538
-    }
539
-
540
-
541
-
542
-    /**
543
-     *    _verify_session
544
-     * checks that the session is valid and not expired
545
-     *
546
-     * @access    private
547
-     * @throws EE_Error
548
-     */
549
-    private function _verify_session()
550
-    {
551
-        if ( ! EE_Registry::instance()->SSN instanceof EE_Session) {
552
-            throw new EE_Error(__('The EE_Session class could not be loaded.', 'event_espresso'));
553
-        }
554
-        $clear_session_requested = filter_var(
555
-            EE_Registry::instance()->REQ->get('clear_session', false),
556
-            FILTER_VALIDATE_BOOLEAN
557
-        );
558
-        // is session still valid ?
559
-        if ($clear_session_requested
560
-            || ( EE_Registry::instance()->SSN->expired()
561
-              && EE_Registry::instance()->REQ->get('e_reg_url_link', '') === ''
562
-            )
563
-        ) {
564
-            $this->checkout = new EE_Checkout();
565
-            EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
566
-            // EE_Registry::instance()->SSN->reset_cart();
567
-            // EE_Registry::instance()->SSN->reset_checkout();
568
-            // EE_Registry::instance()->SSN->reset_transaction();
569
-            if (! $clear_session_requested) {
570
-                EE_Error::add_attention(
571
-                    EE_Registry::$i18n_js_strings['registration_expiration_notice'],
572
-                    __FILE__, __FUNCTION__, __LINE__
573
-                );
574
-            }
575
-            // EE_Registry::instance()->SSN->reset_expired();
576
-        }
577
-    }
578
-
579
-
580
-
581
-    /**
582
-     *    _initialize_checkout
583
-     * loads and instantiates EE_Checkout
584
-     *
585
-     * @access    private
586
-     * @throws EE_Error
587
-     * @return EE_Checkout
588
-     */
589
-    private function _initialize_checkout()
590
-    {
591
-        // look in session for existing checkout
592
-        /** @type EE_Checkout $checkout */
593
-        $checkout = EE_Registry::instance()->SSN->checkout();
594
-        // verify
595
-        if ( ! $checkout instanceof EE_Checkout) {
596
-            // instantiate EE_Checkout object for handling the properties of the current checkout process
597
-            $checkout = EE_Registry::instance()->load_file(
598
-                SPCO_INC_PATH,
599
-                'EE_Checkout',
600
-                'class', array(),
601
-                false
602
-            );
603
-        } else {
604
-            if ($checkout->current_step->is_final_step() && $checkout->exit_spco() === true) {
605
-                $this->unlock_transaction();
606
-                wp_safe_redirect($checkout->redirect_url);
607
-                exit();
608
-            }
609
-        }
610
-        $checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize_checkout__checkout', $checkout);
611
-        // verify again
612
-        if ( ! $checkout instanceof EE_Checkout) {
613
-            throw new EE_Error(__('The EE_Checkout class could not be loaded.', 'event_espresso'));
614
-        }
615
-        // reset anything that needs a clean slate for each request
616
-        $checkout->reset_for_current_request();
617
-        return $checkout;
618
-    }
619
-
620
-
621
-
622
-    /**
623
-     *    _get_request_vars
624
-     *
625
-     * @access    private
626
-     * @return    void
627
-     * @throws EE_Error
628
-     */
629
-    private function _get_request_vars()
630
-    {
631
-        // load classes
632
-        EED_Single_Page_Checkout::load_request_handler();
633
-        //make sure this request is marked as belonging to EE
634
-        EE_Registry::instance()->REQ->set_espresso_page(true);
635
-        // which step is being requested ?
636
-        $this->checkout->step = EE_Registry::instance()->REQ->get('step', $this->_get_first_step());
637
-        // which step is being edited ?
638
-        $this->checkout->edit_step = EE_Registry::instance()->REQ->get('edit_step', '');
639
-        // and what we're doing on the current step
640
-        $this->checkout->action = EE_Registry::instance()->REQ->get('action', 'display_spco_reg_step');
641
-        // timestamp
642
-        $this->checkout->uts = EE_Registry::instance()->REQ->get('uts', 0);
643
-        // returning to edit ?
644
-        $this->checkout->reg_url_link = EE_Registry::instance()->REQ->get('e_reg_url_link', '');
645
-        // add reg url link to registration query params
646
-        if ($this->checkout->reg_url_link && strpos($this->checkout->reg_url_link, '1-') !== 0) {
647
-            $this->checkout->reg_cache_where_params[0]['REG_url_link'] = $this->checkout->reg_url_link;
648
-        }
649
-        // or some other kind of revisit ?
650
-        $this->checkout->revisit = filter_var(
651
-            EE_Registry::instance()->REQ->get('revisit', false),
652
-            FILTER_VALIDATE_BOOLEAN
653
-        );
654
-        // and whether or not to generate a reg form for this request
655
-        $this->checkout->generate_reg_form = filter_var(
656
-            EE_Registry::instance()->REQ->get('generate_reg_form', true),
657
-            FILTER_VALIDATE_BOOLEAN
658
-        );
659
-        // and whether or not to process a reg form submission for this request
660
-        $this->checkout->process_form_submission = filter_var(
661
-            EE_Registry::instance()->REQ->get(
662
-                'process_form_submission',
663
-                $this->checkout->action === 'process_reg_step'
664
-            ),
665
-            FILTER_VALIDATE_BOOLEAN
666
-        );
667
-        $this->checkout->process_form_submission = filter_var(
668
-            $this->checkout->action !== 'display_spco_reg_step'
669
-                ? $this->checkout->process_form_submission
670
-                : false,
671
-            FILTER_VALIDATE_BOOLEAN
672
-        );
673
-        // $this->_display_request_vars();
674
-    }
675
-
676
-
677
-
678
-    /**
679
-     *  _display_request_vars
680
-     *
681
-     * @access    protected
682
-     * @return    void
683
-     */
684
-    protected function _display_request_vars()
685
-    {
686
-        if ( ! WP_DEBUG) {
687
-            return;
688
-        }
689
-        EEH_Debug_Tools::printr($_REQUEST, '$_REQUEST', __FILE__, __LINE__);
690
-        EEH_Debug_Tools::printr($this->checkout->step, '$this->checkout->step', __FILE__, __LINE__);
691
-        EEH_Debug_Tools::printr($this->checkout->edit_step, '$this->checkout->edit_step', __FILE__, __LINE__);
692
-        EEH_Debug_Tools::printr($this->checkout->action, '$this->checkout->action', __FILE__, __LINE__);
693
-        EEH_Debug_Tools::printr($this->checkout->reg_url_link, '$this->checkout->reg_url_link', __FILE__, __LINE__);
694
-        EEH_Debug_Tools::printr($this->checkout->revisit, '$this->checkout->revisit', __FILE__, __LINE__);
695
-        EEH_Debug_Tools::printr($this->checkout->generate_reg_form, '$this->checkout->generate_reg_form', __FILE__, __LINE__);
696
-        EEH_Debug_Tools::printr($this->checkout->process_form_submission, '$this->checkout->process_form_submission', __FILE__, __LINE__);
697
-    }
698
-
699
-
700
-
701
-    /**
702
-     * _block_bots
703
-     * checks that the incoming request has either of the following set:
704
-     *  a uts (unix timestamp) which indicates that the request was redirected from the Ticket Selector
705
-     *  a REG URL Link, which indicates that the request is a return visit to SPCO for a valid TXN
706
-     * so if you're not coming from the Ticket Selector nor returning for a valid IP...
707
-     * then where you coming from man?
708
-     *
709
-     * @return boolean
710
-     */
711
-    private function _block_bots()
712
-    {
713
-        $invalid_checkout_access = EED_Invalid_Checkout_Access::getInvalidCheckoutAccess();
714
-        if ($invalid_checkout_access->checkoutAccessIsInvalid($this->checkout)) {
715
-            return true;
716
-        }
717
-        return false;
718
-    }
719
-
720
-
721
-
722
-    /**
723
-     *    _get_first_step
724
-     *  gets slug for first step in $_reg_steps_array
725
-     *
726
-     * @access    private
727
-     * @throws EE_Error
728
-     * @return    string
729
-     */
730
-    private function _get_first_step()
731
-    {
732
-        $first_step = reset(EED_Single_Page_Checkout::$_reg_steps_array);
733
-        return isset($first_step['slug']) ? $first_step['slug'] : 'attendee_information';
734
-    }
735
-
736
-
737
-
738
-    /**
739
-     *    _load_and_instantiate_reg_steps
740
-     *  instantiates each reg step based on the loaded reg_steps array
741
-     *
742
-     * @access    private
743
-     * @throws EE_Error
744
-     * @return    bool
745
-     */
746
-    private function _load_and_instantiate_reg_steps()
747
-    {
748
-        do_action('AHEE__Single_Page_Checkout___load_and_instantiate_reg_steps__start', $this->checkout);
749
-        // have reg_steps already been instantiated ?
750
-        if (
751
-            empty($this->checkout->reg_steps)
752
-            || apply_filters('FHEE__Single_Page_Checkout__load_reg_steps__reload_reg_steps', false, $this->checkout)
753
-        ) {
754
-            // if not, then loop through raw reg steps array
755
-            foreach (EED_Single_Page_Checkout::$_reg_steps_array as $order => $reg_step) {
756
-                if ( ! $this->_load_and_instantiate_reg_step($reg_step, $order)) {
757
-                    return false;
758
-                }
759
-            }
760
-            EE_Registry::instance()->CFG->registration->skip_reg_confirmation = true;
761
-            EE_Registry::instance()->CFG->registration->reg_confirmation_last = true;
762
-            // skip the registration_confirmation page ?
763
-            if (EE_Registry::instance()->CFG->registration->skip_reg_confirmation) {
764
-                // just remove it from the reg steps array
765
-                $this->checkout->remove_reg_step('registration_confirmation', false);
766
-            } else if (
767
-                isset($this->checkout->reg_steps['registration_confirmation'])
768
-                && EE_Registry::instance()->CFG->registration->reg_confirmation_last
769
-            ) {
770
-                // set the order to something big like 100
771
-                $this->checkout->set_reg_step_order('registration_confirmation', 100);
772
-            }
773
-            // filter the array for good luck
774
-            $this->checkout->reg_steps = apply_filters(
775
-                'FHEE__Single_Page_Checkout__load_reg_steps__reg_steps',
776
-                $this->checkout->reg_steps
777
-            );
778
-            // finally re-sort based on the reg step class order properties
779
-            $this->checkout->sort_reg_steps();
780
-        } else {
781
-            foreach ($this->checkout->reg_steps as $reg_step) {
782
-                // set all current step stati to FALSE
783
-                $reg_step->set_is_current_step(false);
784
-            }
785
-        }
786
-        if (empty($this->checkout->reg_steps)) {
787
-            EE_Error::add_error(
788
-                __('No Reg Steps were loaded..', 'event_espresso'),
789
-                __FILE__, __FUNCTION__, __LINE__
790
-            );
791
-            return false;
792
-        }
793
-        // make reg step details available to JS
794
-        $this->checkout->set_reg_step_JSON_info();
795
-        return true;
796
-    }
797
-
798
-
799
-
800
-    /**
801
-     *     _load_and_instantiate_reg_step
802
-     *
803
-     * @access    private
804
-     * @param array $reg_step
805
-     * @param int   $order
806
-     * @return bool
807
-     */
808
-    private function _load_and_instantiate_reg_step($reg_step = array(), $order = 0)
809
-    {
810
-        // we need a file_path, class_name, and slug to add a reg step
811
-        if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) {
812
-            // if editing a specific step, but this is NOT that step... (and it's not the 'finalize_registration' step)
813
-            if (
814
-                $this->checkout->reg_url_link
815
-                && $this->checkout->step !== $reg_step['slug']
816
-                && $reg_step['slug'] !== 'finalize_registration'
817
-                // normally at this point we would NOT load the reg step, but this filter can change that
818
-                && apply_filters(
819
-                    'FHEE__Single_Page_Checkout___load_and_instantiate_reg_step__bypass_reg_step',
820
-                    true,
821
-                    $reg_step,
822
-                    $this->checkout
823
-                )
824
-            ) {
825
-                return true;
826
-            }
827
-            // instantiate step class using file path and class name
828
-            $reg_step_obj = EE_Registry::instance()->load_file(
829
-                $reg_step['file_path'],
830
-                $reg_step['class_name'],
831
-                'class',
832
-                $this->checkout,
833
-                false
834
-            );
835
-            // did we gets the goods ?
836
-            if ($reg_step_obj instanceof EE_SPCO_Reg_Step) {
837
-                // set reg step order based on config
838
-                $reg_step_obj->set_order($order);
839
-                // add instantiated reg step object to the master reg steps array
840
-                $this->checkout->add_reg_step($reg_step_obj);
841
-            } else {
842
-                EE_Error::add_error(
843
-                    __('The current step could not be set.', 'event_espresso'),
844
-                    __FILE__, __FUNCTION__, __LINE__
845
-                );
846
-                return false;
847
-            }
848
-        } else {
849
-            if (WP_DEBUG) {
850
-                EE_Error::add_error(
851
-                    sprintf(
852
-                        __(
853
-                            'A registration step could not be loaded. One or more of the following data points is invalid:%4$s%5$sFile Path: %1$s%6$s%5$sClass Name: %2$s%6$s%5$sSlug: %3$s%6$s%7$s',
854
-                            'event_espresso'
855
-                        ),
856
-                        isset($reg_step['file_path']) ? $reg_step['file_path'] : '',
857
-                        isset($reg_step['class_name']) ? $reg_step['class_name'] : '',
858
-                        isset($reg_step['slug']) ? $reg_step['slug'] : '',
859
-                        '<ul>',
860
-                        '<li>',
861
-                        '</li>',
862
-                        '</ul>'
863
-                    ),
864
-                    __FILE__, __FUNCTION__, __LINE__
865
-                );
866
-            }
867
-            return false;
868
-        }
869
-        return true;
870
-    }
871
-
872
-
873
-    /**
874
-     * _verify_transaction_and_get_registrations
875
-     *
876
-     * @access private
877
-     * @return bool
878
-     * @throws InvalidDataTypeException
879
-     * @throws InvalidEntityException
880
-     * @throws EE_Error
881
-     */
882
-    private function _verify_transaction_and_get_registrations()
883
-    {
884
-        // was there already a valid transaction in the checkout from the session ?
885
-        if ( ! $this->checkout->transaction instanceof EE_Transaction) {
886
-            // get transaction from db or session
887
-            $this->checkout->transaction = $this->checkout->reg_url_link && ! is_admin()
888
-                ? $this->_get_transaction_and_cart_for_previous_visit()
889
-                : $this->_get_cart_for_current_session_and_setup_new_transaction();
890
-            if ( ! $this->checkout->transaction instanceof EE_Transaction) {
891
-                EE_Error::add_error(
892
-                    __('Your Registration and Transaction information could not be retrieved from the db.',
893
-                        'event_espresso'),
894
-                    __FILE__, __FUNCTION__, __LINE__
895
-                );
896
-                $this->checkout->transaction = EE_Transaction::new_instance();
897
-                // add some style and make it dance
898
-                $this->add_styles_and_scripts();
899
-                EED_Single_Page_Checkout::$_initialized = true;
900
-                return false;
901
-            }
902
-            // and the registrations for the transaction
903
-            $this->_get_registrations($this->checkout->transaction);
904
-        }
905
-        return true;
906
-    }
907
-
908
-
909
-
910
-    /**
911
-     * _get_transaction_and_cart_for_previous_visit
912
-     *
913
-     * @access private
914
-     * @return mixed EE_Transaction|NULL
915
-     */
916
-    private function _get_transaction_and_cart_for_previous_visit()
917
-    {
918
-        /** @var $TXN_model EEM_Transaction */
919
-        $TXN_model = EE_Registry::instance()->load_model('Transaction');
920
-        // because the reg_url_link is present in the request,
921
-        // this is a return visit to SPCO, so we'll get the transaction data from the db
922
-        $transaction = $TXN_model->get_transaction_from_reg_url_link($this->checkout->reg_url_link);
923
-        // verify transaction
924
-        if ($transaction instanceof EE_Transaction) {
925
-            // and get the cart that was used for that transaction
926
-            $this->checkout->cart = $this->_get_cart_for_transaction($transaction);
927
-            return $transaction;
928
-        }
929
-        EE_Error::add_error(
930
-            __('Your Registration and Transaction information could not be retrieved from the db.', 'event_espresso'),
931
-            __FILE__, __FUNCTION__, __LINE__
932
-        );
933
-        return null;
934
-
935
-    }
936
-
937
-
938
-
939
-    /**
940
-     * _get_cart_for_transaction
941
-     *
942
-     * @access private
943
-     * @param EE_Transaction $transaction
944
-     * @return EE_Cart
945
-     */
946
-    private function _get_cart_for_transaction($transaction)
947
-    {
948
-        return $this->checkout->get_cart_for_transaction($transaction);
949
-    }
950
-
951
-
952
-
953
-    /**
954
-     * get_cart_for_transaction
955
-     *
956
-     * @access public
957
-     * @param EE_Transaction $transaction
958
-     * @return EE_Cart
959
-     */
960
-    public function get_cart_for_transaction(EE_Transaction $transaction)
961
-    {
962
-        return $this->checkout->get_cart_for_transaction($transaction);
963
-    }
964
-
965
-
966
-
967
-    /**
968
-     * _get_transaction_and_cart_for_current_session
969
-     *    generates a new EE_Transaction object and adds it to the $_transaction property.
970
-     *
971
-     * @access private
972
-     * @return EE_Transaction
973
-     * @throws EE_Error
974
-     */
975
-    private function _get_cart_for_current_session_and_setup_new_transaction()
976
-    {
977
-        //  if there's no transaction, then this is the FIRST visit to SPCO
978
-        // so load up the cart ( passing nothing for the TXN because it doesn't exist yet )
979
-        $this->checkout->cart = $this->_get_cart_for_transaction(null);
980
-        // and then create a new transaction
981
-        $transaction = $this->_initialize_transaction();
982
-        // verify transaction
983
-        if ($transaction instanceof EE_Transaction) {
984
-            // save it so that we have an ID for other objects to use
985
-            $transaction->save();
986
-            // and save TXN data to the cart
987
-            $this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn($transaction->ID());
988
-        } else {
989
-            EE_Error::add_error(
990
-                __('A Valid Transaction could not be initialized.', 'event_espresso'),
991
-                __FILE__, __FUNCTION__, __LINE__
992
-            );
993
-        }
994
-        return $transaction;
995
-    }
996
-
997
-
998
-
999
-    /**
1000
-     *    generates a new EE_Transaction object and adds it to the $_transaction property.
1001
-     *
1002
-     * @access private
1003
-     * @return mixed EE_Transaction|NULL
1004
-     */
1005
-    private function _initialize_transaction()
1006
-    {
1007
-        try {
1008
-            // ensure cart totals have been calculated
1009
-            $this->checkout->cart->get_grand_total()->recalculate_total_including_taxes();
1010
-            // grab the cart grand total
1011
-            $cart_total = $this->checkout->cart->get_cart_grand_total();
1012
-            // create new TXN
1013
-            $transaction = EE_Transaction::new_instance(
1014
-                array(
1015
-                    'TXN_reg_steps' => $this->checkout->initialize_txn_reg_steps_array(),
1016
-                    'TXN_total'     => $cart_total > 0 ? $cart_total : 0,
1017
-                    'TXN_paid'      => 0,
1018
-                    'STS_ID'        => EEM_Transaction::failed_status_code,
1019
-                )
1020
-            );
1021
-            // save it so that we have an ID for other objects to use
1022
-            $transaction->save();
1023
-            // set cron job for following up on TXNs after their session has expired
1024
-            EE_Cron_Tasks::schedule_expired_transaction_check(
1025
-                EE_Registry::instance()->SSN->expiration() + 1,
1026
-                $transaction->ID()
1027
-            );
1028
-            return $transaction;
1029
-        } catch (Exception $e) {
1030
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1031
-        }
1032
-        return null;
1033
-    }
1034
-
1035
-
1036
-    /**
1037
-     * _get_registrations
1038
-     *
1039
-     * @access private
1040
-     * @param EE_Transaction $transaction
1041
-     * @return void
1042
-     * @throws InvalidDataTypeException
1043
-     * @throws InvalidEntityException
1044
-     * @throws EE_Error
1045
-     */
1046
-    private function _get_registrations(EE_Transaction $transaction)
1047
-    {
1048
-        // first step: grab the registrants  { : o
1049
-        $registrations = $transaction->registrations($this->checkout->reg_cache_where_params, false);
1050
-        $this->checkout->total_ticket_count = count($registrations);
1051
-        // verify registrations have been set
1052
-        if (empty($registrations)) {
1053
-            // if no cached registrations, then check the db
1054
-            $registrations = $transaction->registrations($this->checkout->reg_cache_where_params, false);
1055
-            // still nothing ? well as long as this isn't a revisit
1056
-            if (empty($registrations) && ! $this->checkout->revisit) {
1057
-                // generate new registrations from scratch
1058
-                $registrations = $this->_initialize_registrations($transaction);
1059
-            }
1060
-        }
1061
-        // sort by their original registration order
1062
-        usort($registrations, array('EED_Single_Page_Checkout', 'sort_registrations_by_REG_count'));
1063
-        // then loop thru the array
1064
-        foreach ($registrations as $registration) {
1065
-            // verify each registration
1066
-            if ($registration instanceof EE_Registration) {
1067
-                // we display all attendee info for the primary registrant
1068
-                if ($this->checkout->reg_url_link === $registration->reg_url_link()
1069
-                    && $registration->is_primary_registrant()
1070
-                ) {
1071
-                    $this->checkout->primary_revisit = true;
1072
-                    break;
1073
-                }
1074
-                if ($this->checkout->revisit && $this->checkout->reg_url_link !== $registration->reg_url_link()) {
1075
-                    // but hide info if it doesn't belong to you
1076
-                    $transaction->clear_cache('Registration', $registration->ID());
1077
-                    $this->checkout->total_ticket_count--;
1078
-                }
1079
-                $this->checkout->set_reg_status_updated($registration->ID(), false);
1080
-            }
1081
-        }
1082
-    }
1083
-
1084
-
1085
-    /**
1086
-     *    adds related EE_Registration objects for each ticket in the cart to the current EE_Transaction object
1087
-     *
1088
-     * @access private
1089
-     * @param EE_Transaction $transaction
1090
-     * @return    array
1091
-     * @throws InvalidDataTypeException
1092
-     * @throws InvalidEntityException
1093
-     * @throws EE_Error
1094
-     */
1095
-    private function _initialize_registrations(EE_Transaction $transaction)
1096
-    {
1097
-        $att_nmbr = 0;
1098
-        $registrations = array();
1099
-        if ($transaction instanceof EE_Transaction) {
1100
-            /** @type EE_Registration_Processor $registration_processor */
1101
-            $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
1102
-            $this->checkout->total_ticket_count = $this->checkout->cart->all_ticket_quantity_count();
1103
-            // now let's add the cart items to the $transaction
1104
-            foreach ($this->checkout->cart->get_tickets() as $line_item) {
1105
-                //do the following for each ticket of this type they selected
1106
-                for ($x = 1; $x <= $line_item->quantity(); $x++) {
1107
-                    $att_nmbr++;
1108
-                    /** @var EventEspresso\core\services\commands\registration\CreateRegistrationCommand $CreateRegistrationCommand */
1109
-                    $CreateRegistrationCommand = EE_Registry::instance()->create(
1110
-                        'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
1111
-                        array(
1112
-                            $transaction,
1113
-                            $line_item,
1114
-                            $att_nmbr,
1115
-                            $this->checkout->total_ticket_count,
1116
-                        )
1117
-                    );
1118
-                    // override capabilities for frontend registrations
1119
-                    if ( ! is_admin()) {
1120
-                        $CreateRegistrationCommand->setCapCheck(
1121
-                            new PublicCapabilities('', 'create_new_registration')
1122
-                        );
1123
-                    }
1124
-                    $registration = EE_Registry::instance()->BUS->execute($CreateRegistrationCommand);
1125
-                    if ( ! $registration instanceof EE_Registration) {
1126
-                        throw new InvalidEntityException($registration, 'EE_Registration');
1127
-                    }
1128
-                    $registrations[ $registration->ID() ] = $registration;
1129
-                }
1130
-            }
1131
-            $registration_processor->fix_reg_final_price_rounding_issue($transaction);
1132
-        }
1133
-        return $registrations;
1134
-    }
1135
-
1136
-
1137
-
1138
-    /**
1139
-     * sorts registrations by REG_count
1140
-     *
1141
-     * @access public
1142
-     * @param EE_Registration $reg_A
1143
-     * @param EE_Registration $reg_B
1144
-     * @return int
1145
-     */
1146
-    public static function sort_registrations_by_REG_count(EE_Registration $reg_A, EE_Registration $reg_B)
1147
-    {
1148
-        // this shouldn't ever happen within the same TXN, but oh well
1149
-        if ($reg_A->count() === $reg_B->count()) {
1150
-            return 0;
1151
-        }
1152
-        return ($reg_A->count() > $reg_B->count()) ? 1 : -1;
1153
-    }
1154
-
1155
-
1156
-
1157
-    /**
1158
-     *    _final_verifications
1159
-     * just makes sure that everything is set up correctly before proceeding
1160
-     *
1161
-     * @access    private
1162
-     * @return    bool
1163
-     * @throws EE_Error
1164
-     */
1165
-    private function _final_verifications()
1166
-    {
1167
-        // filter checkout
1168
-        $this->checkout = apply_filters(
1169
-            'FHEE__EED_Single_Page_Checkout___final_verifications__checkout',
1170
-            $this->checkout
1171
-        );
1172
-        //verify that current step is still set correctly
1173
-        if ( ! $this->checkout->current_step instanceof EE_SPCO_Reg_Step) {
1174
-            EE_Error::add_error(
1175
-                __('We\'re sorry but the registration process can not proceed because one or more registration steps were not setup correctly. Please refresh the page and try again or contact support.', 'event_espresso'),
1176
-                __FILE__,
1177
-                __FUNCTION__,
1178
-                __LINE__
1179
-            );
1180
-            return false;
1181
-        }
1182
-        // if returning to SPCO, then verify that primary registrant is set
1183
-        if ( ! empty($this->checkout->reg_url_link)) {
1184
-            $valid_registrant = $this->checkout->transaction->primary_registration();
1185
-            if ( ! $valid_registrant instanceof EE_Registration) {
1186
-                EE_Error::add_error(
1187
-                    __('We\'re sorry but there appears to be an error with the "reg_url_link" or the primary registrant for this transaction. Please refresh the page and try again or contact support.', 'event_espresso'),
1188
-                    __FILE__,
1189
-                    __FUNCTION__,
1190
-                    __LINE__
1191
-                );
1192
-                return false;
1193
-            }
1194
-            $valid_registrant = null;
1195
-            foreach (
1196
-                $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params) as $registration
1197
-            ) {
1198
-                if (
1199
-                    $registration instanceof EE_Registration
1200
-                    && $registration->reg_url_link() === $this->checkout->reg_url_link
1201
-                ) {
1202
-                    $valid_registrant = $registration;
1203
-                }
1204
-            }
1205
-            if ( ! $valid_registrant instanceof EE_Registration) {
1206
-                // hmmm... maybe we have the wrong session because the user is opening multiple tabs ?
1207
-                if (EED_Single_Page_Checkout::$_checkout_verified) {
1208
-                    // clear the session, mark the checkout as unverified, and try again
1209
-                    EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
1210
-                    EED_Single_Page_Checkout::$_initialized = false;
1211
-                    EED_Single_Page_Checkout::$_checkout_verified = false;
1212
-                    $this->_initialize();
1213
-                    EE_Error::reset_notices();
1214
-                    return false;
1215
-                }
1216
-                EE_Error::add_error(
1217
-                    __(
1218
-                        'We\'re sorry but there appears to be an error with the "reg_url_link" or the transaction itself. Please refresh the page and try again or contact support.',
1219
-                        'event_espresso'
1220
-                    ),
1221
-                    __FILE__,
1222
-                    __FUNCTION__,
1223
-                    __LINE__
1224
-                );
1225
-                return false;
1226
-            }
1227
-        }
1228
-        // now that things have been kinda sufficiently verified,
1229
-        // let's add the checkout to the session so that it's available to other systems
1230
-        EE_Registry::instance()->SSN->set_checkout($this->checkout);
1231
-        return true;
1232
-    }
1233
-
1234
-
1235
-
1236
-    /**
1237
-     *    _initialize_reg_steps
1238
-     * first makes sure that EE_Transaction_Processor::set_reg_step_initiated() is called as required
1239
-     * then loops thru all of the active reg steps and calls the initialize_reg_step() method
1240
-     *
1241
-     * @access    private
1242
-     * @param bool $reinitializing
1243
-     * @throws EE_Error
1244
-     */
1245
-    private function _initialize_reg_steps($reinitializing = false)
1246
-    {
1247
-        $this->checkout->set_reg_step_initiated($this->checkout->current_step);
1248
-        // loop thru all steps to call their individual "initialize" methods and set i18n strings for JS
1249
-        foreach ($this->checkout->reg_steps as $reg_step) {
1250
-            if ( ! $reg_step->initialize_reg_step()) {
1251
-                // if not initialized then maybe this step is being removed...
1252
-                if ( ! $reinitializing && $reg_step->is_current_step()) {
1253
-                    // if it was the current step, then we need to start over here
1254
-                    $this->_initialize_reg_steps(true);
1255
-                    return;
1256
-                }
1257
-                continue;
1258
-            }
1259
-            // add css and JS for current step
1260
-            $reg_step->enqueue_styles_and_scripts();
1261
-            // i18n
1262
-            $reg_step->translate_js_strings();
1263
-            if ($reg_step->is_current_step()) {
1264
-                // the text that appears on the reg step form submit button
1265
-                $reg_step->set_submit_button_text();
1266
-            }
1267
-        }
1268
-        // dynamically creates hook point like: AHEE__Single_Page_Checkout___initialize_reg_step__attendee_information
1269
-        do_action(
1270
-            "AHEE__Single_Page_Checkout___initialize_reg_step__{$this->checkout->current_step->slug()}",
1271
-            $this->checkout->current_step
1272
-        );
1273
-    }
1274
-
1275
-
1276
-
1277
-    /**
1278
-     * _check_form_submission
1279
-     *
1280
-     * @access private
1281
-     * @return boolean
1282
-     */
1283
-    private function _check_form_submission()
1284
-    {
1285
-        //does this request require the reg form to be generated ?
1286
-        if ($this->checkout->generate_reg_form) {
1287
-            // ever heard that song by Blue Rodeo ?
1288
-            try {
1289
-                $this->checkout->current_step->reg_form = $this->checkout->current_step->generate_reg_form();
1290
-                // if not displaying a form, then check for form submission
1291
-                if (
1292
-                    $this->checkout->process_form_submission
1293
-                    && $this->checkout->current_step->reg_form->was_submitted()
1294
-                ) {
1295
-                    // clear out any old data in case this step is being run again
1296
-                    $this->checkout->current_step->set_valid_data(array());
1297
-                    // capture submitted form data
1298
-                    $this->checkout->current_step->reg_form->receive_form_submission(
1299
-                        apply_filters(
1300
-                            'FHEE__Single_Page_Checkout___check_form_submission__request_params',
1301
-                            EE_Registry::instance()->REQ->params(),
1302
-                            $this->checkout
1303
-                        )
1304
-                    );
1305
-                    // validate submitted form data
1306
-                    if ( ! $this->checkout->continue_reg || ! $this->checkout->current_step->reg_form->is_valid()) {
1307
-                        // thou shall not pass !!!
1308
-                        $this->checkout->continue_reg = false;
1309
-                        // any form validation errors?
1310
-                        if ($this->checkout->current_step->reg_form->submission_error_message() !== '') {
1311
-                            $submission_error_messages = array();
1312
-                            // bad, bad, bad registrant
1313
-                            foreach (
1314
-                                $this->checkout->current_step->reg_form->get_validation_errors_accumulated()
1315
-                                as $validation_error
1316
-                            ) {
1317
-                                if ($validation_error instanceof EE_Validation_Error) {
1318
-                                    $submission_error_messages[] = sprintf(
1319
-                                        __('%s : %s', 'event_espresso'),
1320
-                                        $validation_error->get_form_section()->html_label_text(),
1321
-                                        $validation_error->getMessage()
1322
-                                    );
1323
-                                }
1324
-                            }
1325
-                            EE_Error::add_error(
1326
-                                implode('<br />', $submission_error_messages),
1327
-                                __FILE__, __FUNCTION__, __LINE__
1328
-                            );
1329
-                        }
1330
-                        // well not really... what will happen is
1331
-                        // we'll just get redirected back to redo the current step
1332
-                        $this->go_to_next_step();
1333
-                        return false;
1334
-                    }
1335
-                }
1336
-            } catch (EE_Error $e) {
1337
-                $e->get_error();
1338
-            }
1339
-        }
1340
-        return true;
1341
-    }
1342
-
1343
-
1344
-
1345
-    /**
1346
-     * _process_action
1347
-     *
1348
-     * @access private
1349
-     * @return void
1350
-     * @throws EE_Error
1351
-     */
1352
-    private function _process_form_action()
1353
-    {
1354
-        // what cha wanna do?
1355
-        switch ($this->checkout->action) {
1356
-            // AJAX next step reg form
1357
-            case 'display_spco_reg_step' :
1358
-                $this->checkout->redirect = false;
1359
-                if (EE_Registry::instance()->REQ->ajax) {
1360
-                    $this->checkout->json_response->set_reg_step_html(
1361
-                        $this->checkout->current_step->display_reg_form()
1362
-                    );
1363
-                }
1364
-                break;
1365
-            default :
1366
-                // meh... do one of those other steps first
1367
-                if (
1368
-                    ! empty($this->checkout->action)
1369
-                    && is_callable(array($this->checkout->current_step, $this->checkout->action))
1370
-                ) {
1371
-                    // dynamically creates hook point like:
1372
-                    //   AHEE__Single_Page_Checkout__before_attendee_information__process_reg_step
1373
-                    do_action(
1374
-                        "AHEE__Single_Page_Checkout__before_{$this->checkout->current_step->slug()}__{$this->checkout->action}",
1375
-                        $this->checkout->current_step
1376
-                    );
1377
-                    // call action on current step
1378
-                    if (call_user_func(array($this->checkout->current_step, $this->checkout->action))) {
1379
-                        // good registrant, you get to proceed
1380
-                        if (
1381
-                            $this->checkout->current_step->success_message() !== ''
1382
-                            && apply_filters(
1383
-                                'FHEE__Single_Page_Checkout___process_form_action__display_success',
1384
-                                false
1385
-                            )
1386
-                        ) {
1387
-                            EE_Error::add_success(
1388
-                                $this->checkout->current_step->success_message()
1389
-                                . '<br />' . $this->checkout->next_step->_instructions()
1390
-                            );
1391
-                        }
1392
-                        // pack it up, pack it in...
1393
-                        $this->_setup_redirect();
1394
-                    }
1395
-                    // dynamically creates hook point like:
1396
-                    //  AHEE__Single_Page_Checkout__after_payment_options__process_reg_step
1397
-                    do_action(
1398
-                        "AHEE__Single_Page_Checkout__after_{$this->checkout->current_step->slug()}__{$this->checkout->action}",
1399
-                        $this->checkout->current_step
1400
-                    );
1401
-                } else {
1402
-                    EE_Error::add_error(
1403
-                        sprintf(
1404
-                            __(
1405
-                                'The requested form action "%s" does not exist for the current "%s" registration step.',
1406
-                                'event_espresso'
1407
-                            ),
1408
-                            $this->checkout->action,
1409
-                            $this->checkout->current_step->name()
1410
-                        ),
1411
-                        __FILE__,
1412
-                        __FUNCTION__,
1413
-                        __LINE__
1414
-                    );
1415
-                }
1416
-            // end default
1417
-        }
1418
-        // store our progress so far
1419
-        $this->checkout->stash_transaction_and_checkout();
1420
-        // advance to the next step! If you pass GO, collect $200
1421
-        $this->go_to_next_step();
1422
-    }
1423
-
1424
-
1425
-
1426
-    /**
1427
-     *        add_styles_and_scripts
1428
-     *
1429
-     * @access        public
1430
-     * @return        void
1431
-     */
1432
-    public function add_styles_and_scripts()
1433
-    {
1434
-        // i18n
1435
-        $this->translate_js_strings();
1436
-        if ($this->checkout->admin_request) {
1437
-            add_action('admin_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10);
1438
-        } else {
1439
-            add_action('wp_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10);
1440
-        }
1441
-    }
1442
-
1443
-
1444
-
1445
-    /**
1446
-     *        translate_js_strings
1447
-     *
1448
-     * @access        public
1449
-     * @return        void
1450
-     */
1451
-    public function translate_js_strings()
1452
-    {
1453
-        EE_Registry::$i18n_js_strings['revisit'] = $this->checkout->revisit;
1454
-        EE_Registry::$i18n_js_strings['e_reg_url_link'] = $this->checkout->reg_url_link;
1455
-        EE_Registry::$i18n_js_strings['server_error'] = __(
1456
-            'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
1457
-            'event_espresso'
1458
-        );
1459
-        EE_Registry::$i18n_js_strings['invalid_json_response'] = __(
1460
-            'An invalid response was returned from the server while attempting to process your request. Please refresh the page and try again or contact support.',
1461
-            'event_espresso'
1462
-        );
1463
-        EE_Registry::$i18n_js_strings['validation_error'] = __(
1464
-            'There appears to be a problem with the form validation configuration! Please check the admin settings or contact support.',
1465
-            'event_espresso'
1466
-        );
1467
-        EE_Registry::$i18n_js_strings['invalid_payment_method'] = __(
1468
-            'There appears to be a problem with the payment method configuration! Please refresh the page and try again or contact support.',
1469
-            'event_espresso'
1470
-        );
1471
-        EE_Registry::$i18n_js_strings['reg_step_error'] = __(
1472
-            'This registration step could not be completed. Please refresh the page and try again.',
1473
-            'event_espresso'
1474
-        );
1475
-        EE_Registry::$i18n_js_strings['invalid_coupon'] = __(
1476
-            'We\'re sorry but that coupon code does not appear to be valid. If this is incorrect, please contact the site administrator.',
1477
-            'event_espresso'
1478
-        );
1479
-        EE_Registry::$i18n_js_strings['process_registration'] = sprintf(
1480
-            __(
1481
-                'Please wait while we process your registration.%sDo not refresh the page or navigate away while this is happening.%sThank you for your patience.',
1482
-                'event_espresso'
1483
-            ),
1484
-            '<br/>',
1485
-            '<br/>'
1486
-        );
1487
-        EE_Registry::$i18n_js_strings['language'] = get_bloginfo('language');
1488
-        EE_Registry::$i18n_js_strings['EESID'] = EE_Registry::instance()->SSN->id();
1489
-        EE_Registry::$i18n_js_strings['currency'] = EE_Registry::instance()->CFG->currency;
1490
-        EE_Registry::$i18n_js_strings['datepicker_yearRange'] = '-150:+20';
1491
-        EE_Registry::$i18n_js_strings['timer_years'] = __('years', 'event_espresso');
1492
-        EE_Registry::$i18n_js_strings['timer_months'] = __('months', 'event_espresso');
1493
-        EE_Registry::$i18n_js_strings['timer_weeks'] = __('weeks', 'event_espresso');
1494
-        EE_Registry::$i18n_js_strings['timer_days'] = __('days', 'event_espresso');
1495
-        EE_Registry::$i18n_js_strings['timer_hours'] = __('hours', 'event_espresso');
1496
-        EE_Registry::$i18n_js_strings['timer_minutes'] = __('minutes', 'event_espresso');
1497
-        EE_Registry::$i18n_js_strings['timer_seconds'] = __('seconds', 'event_espresso');
1498
-        EE_Registry::$i18n_js_strings['timer_year'] = __('year', 'event_espresso');
1499
-        EE_Registry::$i18n_js_strings['timer_month'] = __('month', 'event_espresso');
1500
-        EE_Registry::$i18n_js_strings['timer_week'] = __('week', 'event_espresso');
1501
-        EE_Registry::$i18n_js_strings['timer_day'] = __('day', 'event_espresso');
1502
-        EE_Registry::$i18n_js_strings['timer_hour'] = __('hour', 'event_espresso');
1503
-        EE_Registry::$i18n_js_strings['timer_minute'] = __('minute', 'event_espresso');
1504
-        EE_Registry::$i18n_js_strings['timer_second'] = __('second', 'event_espresso');
1505
-        EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
1506
-            __(
1507
-                '%1$sWe\'re sorry, but your registration time has expired.%2$s%3$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please except our apologies for any inconvenience this may have caused.%8$s',
1508
-                'event_espresso'
1509
-            ),
1510
-            '<h4 class="important-notice">',
1511
-            '</h4>',
1512
-            '<br />',
1513
-            '<p>',
1514
-            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
1515
-            '">',
1516
-            '</a>',
1517
-            '</p>'
1518
-        );
1519
-        EE_Registry::$i18n_js_strings['ajax_submit'] = apply_filters(
1520
-            'FHEE__Single_Page_Checkout__translate_js_strings__ajax_submit',
1521
-            true
1522
-        );
1523
-        EE_Registry::$i18n_js_strings['session_extension'] = absint(
1524
-            apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS)
1525
-        );
1526
-        EE_Registry::$i18n_js_strings['session_expiration'] = gmdate(
1527
-            'M d, Y H:i:s',
1528
-            EE_Registry::instance()->SSN->expiration() + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1529
-        );
1530
-    }
1531
-
1532
-
1533
-
1534
-    /**
1535
-     *    enqueue_styles_and_scripts
1536
-     *
1537
-     * @access        public
1538
-     * @return        void
1539
-     * @throws EE_Error
1540
-     */
1541
-    public function enqueue_styles_and_scripts()
1542
-    {
1543
-        // load css
1544
-        wp_register_style(
1545
-            'single_page_checkout',
1546
-            SPCO_CSS_URL . 'single_page_checkout.css',
1547
-            array('espresso_default'),
1548
-            EVENT_ESPRESSO_VERSION
1549
-        );
1550
-        wp_enqueue_style('single_page_checkout');
1551
-        // load JS
1552
-        wp_register_script(
1553
-            'jquery_plugin',
1554
-            EE_THIRD_PARTY_URL . 'jquery	.plugin.min.js',
1555
-            array('jquery'),
1556
-            '1.0.1',
1557
-            true
1558
-        );
1559
-        wp_register_script(
1560
-            'jquery_countdown',
1561
-            EE_THIRD_PARTY_URL . 'jquery	.countdown.min.js',
1562
-            array('jquery_plugin'),
1563
-            '2.0.2',
1564
-            true
1565
-        );
1566
-        wp_register_script(
1567
-            'single_page_checkout',
1568
-            SPCO_JS_URL . 'single_page_checkout.js',
1569
-            array('espresso_core', 'underscore', 'ee_form_section_validation', 'jquery_countdown'),
1570
-            EVENT_ESPRESSO_VERSION,
1571
-            true
1572
-        );
1573
-        if ($this->checkout->registration_form instanceof EE_Form_Section_Proper) {
1574
-            $this->checkout->registration_form->enqueue_js();
1575
-        }
1576
-        if ($this->checkout->current_step->reg_form instanceof EE_Form_Section_Proper) {
1577
-            $this->checkout->current_step->reg_form->enqueue_js();
1578
-        }
1579
-        wp_enqueue_script('single_page_checkout');
1580
-        /**
1581
-         * global action hook for enqueueing styles and scripts with
1582
-         * spco calls.
1583
-         */
1584
-        do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts', $this);
1585
-        /**
1586
-         * dynamic action hook for enqueueing styles and scripts with spco calls.
1587
-         * The hook will end up being something like:
1588
-         *      AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information
1589
-         */
1590
-        do_action(
1591
-            'AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(),
1592
-            $this
1593
-        );
1594
-    }
1595
-
1596
-
1597
-
1598
-    /**
1599
-     *    display the Registration Single Page Checkout Form
1600
-     *
1601
-     * @access    private
1602
-     * @return    void
1603
-     * @throws EE_Error
1604
-     */
1605
-    private function _display_spco_reg_form()
1606
-    {
1607
-        // if registering via the admin, just display the reg form for the current step
1608
-        if ($this->checkout->admin_request) {
1609
-            EE_Registry::instance()->REQ->add_output($this->checkout->current_step->display_reg_form());
1610
-        } else {
1611
-            // add powered by EE msg
1612
-            add_action('AHEE__SPCO__reg_form_footer', array('EED_Single_Page_Checkout', 'display_registration_footer'));
1613
-            $empty_cart = count(
1614
-                $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params)
1615
-            ) < 1;
1616
-            EE_Registry::$i18n_js_strings['empty_cart'] = $empty_cart;
1617
-            $cookies_not_set_msg = '';
1618
-            if ($empty_cart && ! isset($_COOKIE['ee_cookie_test'])) {
1619
-                $cookies_not_set_msg = apply_filters(
1620
-                    'FHEE__Single_Page_Checkout__display_spco_reg_form__cookies_not_set_msg',
1621
-                    sprintf(
1622
-                        __(
1623
-                            '%1$s%3$sIt appears your browser is not currently set to accept Cookies%4$s%5$sIn order to register for events, you need to enable cookies.%7$sIf you require assistance, then click the following link to learn how to %8$senable cookies%9$s%6$s%2$s',
1624
-                            'event_espresso'
1625
-                        ),
1626
-                        '<div class="ee-attention">',
1627
-                        '</div>',
1628
-                        '<h6 class="important-notice">',
1629
-                        '</h6>',
1630
-                        '<p>',
1631
-                        '</p>',
1632
-                        '<br />',
1633
-                        '<a href="http://www.whatarecookies.com/enable.asp" target="_blank">',
1634
-                        '</a>'
1635
-                    )
1636
-                );
1637
-            }
1638
-            $this->checkout->registration_form = new EE_Form_Section_Proper(
1639
-                array(
1640
-                    'name'            => 'single-page-checkout',
1641
-                    'html_id'         => 'ee-single-page-checkout-dv',
1642
-                    'layout_strategy' =>
1643
-                        new EE_Template_Layout(
1644
-                            array(
1645
-                                'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php',
1646
-                                'template_args'        => array(
1647
-                                    'empty_cart'              => $empty_cart,
1648
-                                    'revisit'                 => $this->checkout->revisit,
1649
-                                    'reg_steps'               => $this->checkout->reg_steps,
1650
-                                    'next_step'               => $this->checkout->next_step instanceof EE_SPCO_Reg_Step
1651
-                                        ? $this->checkout->next_step->slug()
1652
-                                        : '',
1653
-                                    'cancel_page_url'         => $this->checkout->cancel_page_url,
1654
-                                    'empty_msg'               => apply_filters(
1655
-                                        'FHEE__Single_Page_Checkout__display_spco_reg_form__empty_msg',
1656
-                                        sprintf(
1657
-                                            __(
1658
-                                                'You need to %1$sReturn to Events list%2$sselect at least one event%3$s before you can proceed with the registration process.',
1659
-                                                'event_espresso'
1660
-                                            ),
1661
-                                            '<a href="'
1662
-                                            . get_post_type_archive_link('espresso_events')
1663
-                                            . '" title="',
1664
-                                            '">',
1665
-                                            '</a>'
1666
-                                        )
1667
-                                    ),
1668
-                                    'cookies_not_set_msg'     => $cookies_not_set_msg,
1669
-                                    'registration_time_limit' => $this->checkout->get_registration_time_limit(),
1670
-                                    'session_expiration'      => gmdate(
1671
-                                        'M d, Y H:i:s',
1672
-                                        EE_Registry::instance()->SSN->expiration()
1673
-                                        + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1674
-                                    ),
1675
-                                ),
1676
-                            )
1677
-                        ),
1678
-                )
1679
-            );
1680
-            // load template and add to output sent that gets filtered into the_content()
1681
-            EE_Registry::instance()->REQ->add_output($this->checkout->registration_form->get_html());
1682
-        }
1683
-    }
1684
-
1685
-
1686
-
1687
-    /**
1688
-     *    add_extra_finalize_registration_inputs
1689
-     *
1690
-     * @access    public
1691
-     * @param $next_step
1692
-     * @internal  param string $label
1693
-     * @return void
1694
-     */
1695
-    public function add_extra_finalize_registration_inputs($next_step)
1696
-    {
1697
-        if ($next_step === 'finalize_registration') {
1698
-            echo '<div id="spco-extra-finalize_registration-inputs-dv"></div>';
1699
-        }
1700
-    }
1701
-
1702
-
1703
-
1704
-    /**
1705
-     *    display_registration_footer
1706
-     *
1707
-     * @access    public
1708
-     * @return    string
1709
-     */
1710
-    public static function display_registration_footer()
1711
-    {
1712
-        if (
1713
-        apply_filters(
1714
-            'FHEE__EE_Front__Controller__show_reg_footer',
1715
-            EE_Registry::instance()->CFG->admin->show_reg_footer
1716
-        )
1717
-        ) {
1718
-            add_filter(
1719
-                'FHEE__EEH_Template__powered_by_event_espresso__url',
1720
-                function ($url) {
1721
-                    return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url);
1722
-                }
1723
-            );
1724
-            echo apply_filters(
1725
-                'FHEE__EE_Front_Controller__display_registration_footer',
1726
-                \EEH_Template::powered_by_event_espresso(
1727
-                    '',
1728
-                    'espresso-registration-footer-dv',
1729
-                    array('utm_content' => 'registration_checkout')
1730
-                )
1731
-            );
1732
-        }
1733
-        return '';
1734
-    }
1735
-
1736
-
1737
-
1738
-    /**
1739
-     *    unlock_transaction
1740
-     *
1741
-     * @access    public
1742
-     * @return    void
1743
-     * @throws EE_Error
1744
-     */
1745
-    public function unlock_transaction()
1746
-    {
1747
-        if ($this->checkout->transaction instanceof EE_Transaction) {
1748
-            $this->checkout->transaction->unlock();
1749
-        }
1750
-    }
1751
-
1752
-
1753
-
1754
-    /**
1755
-     *        _setup_redirect
1756
-     *
1757
-     * @access    private
1758
-     * @return void
1759
-     */
1760
-    private function _setup_redirect()
1761
-    {
1762
-        if ($this->checkout->continue_reg && $this->checkout->next_step instanceof EE_SPCO_Reg_Step) {
1763
-            $this->checkout->redirect = true;
1764
-            if (empty($this->checkout->redirect_url)) {
1765
-                $this->checkout->redirect_url = $this->checkout->next_step->reg_step_url();
1766
-            }
1767
-            $this->checkout->redirect_url = apply_filters(
1768
-                'FHEE__EED_Single_Page_Checkout___setup_redirect__checkout_redirect_url',
1769
-                $this->checkout->redirect_url,
1770
-                $this->checkout
1771
-            );
1772
-        }
1773
-    }
1774
-
1775
-
1776
-
1777
-    /**
1778
-     *   handle ajax message responses and redirects
1779
-     *
1780
-     * @access public
1781
-     * @return void
1782
-     * @throws EE_Error
1783
-     */
1784
-    public function go_to_next_step()
1785
-    {
1786
-        if (EE_Registry::instance()->REQ->ajax) {
1787
-            // capture contents of output buffer we started earlier in the request, and insert into JSON response
1788
-            $this->checkout->json_response->set_unexpected_errors(ob_get_clean());
1789
-        }
1790
-        $this->unlock_transaction();
1791
-        // just return for these conditions
1792
-        if (
1793
-            $this->checkout->admin_request
1794
-            || $this->checkout->action === 'redirect_form'
1795
-            || $this->checkout->action === 'update_checkout'
1796
-        ) {
1797
-            // DEBUG LOG
1798
-            $this->checkout->log(
1799
-                __CLASS__, __FUNCTION__, __LINE__,
1800
-                array(
1801
-                    'action'                     => $this->checkout->action,
1802
-                    'redirect'                   => $this->checkout->redirect,
1803
-                    'json_response_redirect_url' => $this->checkout->json_response->redirect_url(),
1804
-                    'redirect_url'               => $this->checkout->redirect_url,
1805
-                    'continue_reg'               => $this->checkout->continue_reg,
1806
-                )
1807
-            );
1808
-            return;
1809
-        }
1810
-        // AJAX response
1811
-        $this->_handle_json_response();
1812
-        // redirect to next step or the Thank You page
1813
-        $this->_handle_html_redirects();
1814
-        // hmmm... must be something wrong, so let's just display the form again !
1815
-        $this->_display_spco_reg_form();
1816
-    }
1817
-
1818
-
1819
-
1820
-    /**
1821
-     *   _handle_json_response
1822
-     *
1823
-     * @access protected
1824
-     * @return void
1825
-     */
1826
-    protected function _handle_json_response()
1827
-    {
1828
-        // if this is an ajax request
1829
-        if (EE_Registry::instance()->REQ->ajax) {
1830
-            // DEBUG LOG
1831
-            $this->checkout->log(
1832
-            	__CLASS__, __FUNCTION__, __LINE__,
1833
-            	array(
1834
-                    'redirect'                   => $this->checkout->redirect,
1835
-                    'json_response_redirect_url' => $this->checkout->json_response->redirect_url(),
1836
-                    'redirect_url'               => $this->checkout->redirect_url,
1837
-                    'continue_reg'               => $this->checkout->continue_reg,
1838
-            	)
1839
-            );
1840
-            $this->checkout->json_response->set_registration_time_limit(
1841
-                $this->checkout->get_registration_time_limit()
1842
-            );
1843
-            $this->checkout->json_response->set_payment_amount($this->checkout->amount_owing);
1844
-            // just send the ajax (
1845
-            $json_response = apply_filters(
1846
-                'FHEE__EE_Single_Page_Checkout__JSON_response',
1847
-                $this->checkout->json_response
1848
-            );
1849
-            echo $json_response;
1850
-            exit();
1851
-        }
1852
-    }
1853
-
1854
-
1855
-
1856
-    /**
1857
-     *   _handle_redirects
1858
-     *
1859
-     * @access protected
1860
-     * @return void
1861
-     */
1862
-    protected function _handle_html_redirects()
1863
-    {
1864
-        // going somewhere ?
1865
-        if ($this->checkout->redirect && ! empty($this->checkout->redirect_url)) {
1866
-            // store notices in a transient
1867
-            EE_Error::get_notices(false, true, true);
1868
-            // DEBUG LOG
1869
-            $this->checkout->log(
1870
-            	__CLASS__, __FUNCTION__, __LINE__,
1871
-            	array(
1872
-            		'headers_sent' => headers_sent(),
1873
-            		'redirect_url'     => $this->checkout->redirect_url,
1874
-            		'headers_list'    => headers_list(),
1875
-            	)
1876
-            );
1877
-            wp_safe_redirect($this->checkout->redirect_url);
1878
-            exit();
1879
-        }
1880
-    }
1881
-
1882
-
1883
-
1884
-    /**
1885
-     *   set_checkout_anchor
1886
-     *
1887
-     * @access public
1888
-     * @return void
1889
-     */
1890
-    public function set_checkout_anchor()
1891
-    {
1892
-        echo '<a id="checkout" style="float: left; margin-left: -999em;"></a>';
1893
-    }
23
+	/**
24
+	 * $_initialized - has the SPCO controller already been initialized ?
25
+	 *
26
+	 * @access private
27
+	 * @var bool $_initialized
28
+	 */
29
+	private static $_initialized = false;
30
+
31
+
32
+	/**
33
+	 * $_checkout_verified - is the EE_Checkout verified as correct for this request ?
34
+	 *
35
+	 * @access private
36
+	 * @var bool $_valid_checkout
37
+	 */
38
+	private static $_checkout_verified = true;
39
+
40
+	/**
41
+	 *    $_reg_steps_array - holds initial array of reg steps
42
+	 *
43
+	 * @access private
44
+	 * @var array $_reg_steps_array
45
+	 */
46
+	private static $_reg_steps_array = array();
47
+
48
+	/**
49
+	 *    $checkout - EE_Checkout object for handling the properties of the current checkout process
50
+	 *
51
+	 * @access public
52
+	 * @var EE_Checkout $checkout
53
+	 */
54
+	public $checkout;
55
+
56
+
57
+
58
+	/**
59
+	 * @return EED_Module|EED_Single_Page_Checkout
60
+	 */
61
+	public static function instance()
62
+	{
63
+		add_filter('EED_Single_Page_Checkout__SPCO_active', '__return_true');
64
+		return parent::get_instance(__CLASS__);
65
+	}
66
+
67
+
68
+
69
+	/**
70
+	 * @return EE_CART
71
+	 */
72
+	public function cart()
73
+	{
74
+		return $this->checkout->cart;
75
+	}
76
+
77
+
78
+
79
+	/**
80
+	 * @return EE_Transaction
81
+	 */
82
+	public function transaction()
83
+	{
84
+		return $this->checkout->transaction;
85
+	}
86
+
87
+
88
+
89
+	/**
90
+	 *    set_hooks - for hooking into EE Core, other modules, etc
91
+	 *
92
+	 * @access    public
93
+	 * @return    void
94
+	 * @throws EE_Error
95
+	 */
96
+	public static function set_hooks()
97
+	{
98
+		EED_Single_Page_Checkout::set_definitions();
99
+	}
100
+
101
+
102
+
103
+	/**
104
+	 *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
105
+	 *
106
+	 * @access    public
107
+	 * @return    void
108
+	 * @throws EE_Error
109
+	 */
110
+	public static function set_hooks_admin()
111
+	{
112
+		EED_Single_Page_Checkout::set_definitions();
113
+		if ( ! (defined('DOING_AJAX') && DOING_AJAX)) {
114
+			return;
115
+		}
116
+		// going to start an output buffer in case anything gets accidentally output
117
+		// that might disrupt our JSON response
118
+		ob_start();
119
+		EED_Single_Page_Checkout::load_request_handler();
120
+		EED_Single_Page_Checkout::load_reg_steps();
121
+		// set ajax hooks
122
+		add_action('wp_ajax_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step'));
123
+		add_action('wp_ajax_nopriv_process_reg_step', array('EED_Single_Page_Checkout', 'process_reg_step'));
124
+		add_action('wp_ajax_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step'));
125
+		add_action('wp_ajax_nopriv_display_spco_reg_step', array('EED_Single_Page_Checkout', 'display_reg_step'));
126
+		add_action('wp_ajax_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step'));
127
+		add_action('wp_ajax_nopriv_update_reg_step', array('EED_Single_Page_Checkout', 'update_reg_step'));
128
+	}
129
+
130
+
131
+
132
+	/**
133
+	 *    process ajax request
134
+	 *
135
+	 * @param string $ajax_action
136
+	 * @throws EE_Error
137
+	 */
138
+	public static function process_ajax_request($ajax_action)
139
+	{
140
+		EE_Registry::instance()->REQ->set('action', $ajax_action);
141
+		EED_Single_Page_Checkout::instance()->_initialize();
142
+	}
143
+
144
+
145
+
146
+	/**
147
+	 *    ajax display registration step
148
+	 *
149
+	 * @throws EE_Error
150
+	 */
151
+	public static function display_reg_step()
152
+	{
153
+		EED_Single_Page_Checkout::process_ajax_request('display_spco_reg_step');
154
+	}
155
+
156
+
157
+
158
+	/**
159
+	 *    ajax process registration step
160
+	 *
161
+	 * @throws EE_Error
162
+	 */
163
+	public static function process_reg_step()
164
+	{
165
+		EED_Single_Page_Checkout::process_ajax_request('process_reg_step');
166
+	}
167
+
168
+
169
+
170
+	/**
171
+	 *    ajax process registration step
172
+	 *
173
+	 * @throws EE_Error
174
+	 */
175
+	public static function update_reg_step()
176
+	{
177
+		EED_Single_Page_Checkout::process_ajax_request('update_reg_step');
178
+	}
179
+
180
+
181
+
182
+	/**
183
+	 *   update_checkout
184
+	 *
185
+	 * @access public
186
+	 * @return void
187
+	 * @throws EE_Error
188
+	 */
189
+	public static function update_checkout()
190
+	{
191
+		EED_Single_Page_Checkout::process_ajax_request('update_checkout');
192
+	}
193
+
194
+
195
+
196
+	/**
197
+	 *    load_request_handler
198
+	 *
199
+	 * @access    public
200
+	 * @return    void
201
+	 */
202
+	public static function load_request_handler()
203
+	{
204
+		// load core Request_Handler class
205
+		if (EE_Registry::instance()->REQ !== null) {
206
+			EE_Registry::instance()->load_core('Request_Handler');
207
+		}
208
+	}
209
+
210
+
211
+
212
+	/**
213
+	 *    set_definitions
214
+	 *
215
+	 * @access    public
216
+	 * @return    void
217
+	 * @throws EE_Error
218
+	 */
219
+	public static function set_definitions()
220
+	{
221
+		if(defined('SPCO_BASE_PATH')) {
222
+			return;
223
+		}
224
+		define(
225
+			'SPCO_BASE_PATH',
226
+			rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS) . DS
227
+		);
228
+		define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css' . DS);
229
+		define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img' . DS);
230
+		define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js' . DS);
231
+		define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc' . DS);
232
+		define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps' . DS);
233
+		define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates' . DS);
234
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true);
235
+		EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
236
+			__('%1$sWe\'re sorry, but you\'re registration time has expired.%2$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please except our apologies for any inconvenience this may have caused.%8$s',
237
+				'event_espresso'),
238
+			'<h4 class="important-notice">',
239
+			'</h4>',
240
+			'<br />',
241
+			'<p>',
242
+			'<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
243
+			'">',
244
+			'</a>',
245
+			'</p>'
246
+		);
247
+	}
248
+
249
+
250
+
251
+	/**
252
+	 * load_reg_steps
253
+	 * loads and instantiates each reg step based on the EE_Registry::instance()->CFG->registration->reg_steps array
254
+	 *
255
+	 * @access    private
256
+	 * @throws EE_Error
257
+	 */
258
+	public static function load_reg_steps()
259
+	{
260
+		static $reg_steps_loaded = false;
261
+		if ($reg_steps_loaded) {
262
+			return;
263
+		}
264
+		// filter list of reg_steps
265
+		$reg_steps_to_load = (array)apply_filters(
266
+			'AHEE__SPCO__load_reg_steps__reg_steps_to_load',
267
+			EED_Single_Page_Checkout::get_reg_steps()
268
+		);
269
+		// sort by key (order)
270
+		ksort($reg_steps_to_load);
271
+		// loop through folders
272
+		foreach ($reg_steps_to_load as $order => $reg_step) {
273
+			// we need a
274
+			if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) {
275
+				// copy over to the reg_steps_array
276
+				EED_Single_Page_Checkout::$_reg_steps_array[$order] = $reg_step;
277
+				// register custom key route for each reg step
278
+				// ie: step=>"slug" - this is the entire reason we load the reg steps array now
279
+				EE_Config::register_route(
280
+					$reg_step['slug'],
281
+					'EED_Single_Page_Checkout',
282
+					'run',
283
+					'step'
284
+				);
285
+				// add AJAX or other hooks
286
+				if (isset($reg_step['has_hooks']) && $reg_step['has_hooks']) {
287
+					// setup autoloaders if necessary
288
+					if ( ! class_exists($reg_step['class_name'])) {
289
+						EEH_Autoloader::register_autoloaders_for_each_file_in_folder(
290
+							$reg_step['file_path'],
291
+							true
292
+						);
293
+					}
294
+					if (is_callable($reg_step['class_name'], 'set_hooks')) {
295
+						call_user_func(array($reg_step['class_name'], 'set_hooks'));
296
+					}
297
+				}
298
+			}
299
+		}
300
+		$reg_steps_loaded = true;
301
+	}
302
+
303
+
304
+
305
+	/**
306
+	 *    get_reg_steps
307
+	 *
308
+	 * @access    public
309
+	 * @return    array
310
+	 */
311
+	public static function get_reg_steps()
312
+	{
313
+		$reg_steps = EE_Registry::instance()->CFG->registration->reg_steps;
314
+		if (empty($reg_steps)) {
315
+			$reg_steps = array(
316
+				10  => array(
317
+					'file_path'  => SPCO_REG_STEPS_PATH . 'attendee_information',
318
+					'class_name' => 'EE_SPCO_Reg_Step_Attendee_Information',
319
+					'slug'       => 'attendee_information',
320
+					'has_hooks'  => false,
321
+				),
322
+				20  => array(
323
+					'file_path'  => SPCO_REG_STEPS_PATH . 'registration_confirmation',
324
+					'class_name' => 'EE_SPCO_Reg_Step_Registration_Confirmation',
325
+					'slug'       => 'registration_confirmation',
326
+					'has_hooks'  => false,
327
+				),
328
+				30  => array(
329
+					'file_path'  => SPCO_REG_STEPS_PATH . 'payment_options',
330
+					'class_name' => 'EE_SPCO_Reg_Step_Payment_Options',
331
+					'slug'       => 'payment_options',
332
+					'has_hooks'  => true,
333
+				),
334
+				999 => array(
335
+					'file_path'  => SPCO_REG_STEPS_PATH . 'finalize_registration',
336
+					'class_name' => 'EE_SPCO_Reg_Step_Finalize_Registration',
337
+					'slug'       => 'finalize_registration',
338
+					'has_hooks'  => false,
339
+				),
340
+			);
341
+		}
342
+		return $reg_steps;
343
+	}
344
+
345
+
346
+
347
+	/**
348
+	 *    registration_checkout_for_admin
349
+	 *
350
+	 * @access    public
351
+	 * @return    string
352
+	 * @throws EE_Error
353
+	 */
354
+	public static function registration_checkout_for_admin()
355
+	{
356
+		EED_Single_Page_Checkout::load_request_handler();
357
+		EE_Registry::instance()->REQ->set('step', 'attendee_information');
358
+		EE_Registry::instance()->REQ->set('action', 'display_spco_reg_step');
359
+		EE_Registry::instance()->REQ->set('process_form_submission', false);
360
+		EED_Single_Page_Checkout::instance()->_initialize();
361
+		EED_Single_Page_Checkout::instance()->_display_spco_reg_form();
362
+		return EE_Registry::instance()->REQ->get_output();
363
+	}
364
+
365
+
366
+
367
+	/**
368
+	 * process_registration_from_admin
369
+	 *
370
+	 * @access public
371
+	 * @return \EE_Transaction
372
+	 * @throws EE_Error
373
+	 */
374
+	public static function process_registration_from_admin()
375
+	{
376
+		EED_Single_Page_Checkout::load_request_handler();
377
+		EE_Registry::instance()->REQ->set('step', 'attendee_information');
378
+		EE_Registry::instance()->REQ->set('action', 'process_reg_step');
379
+		EE_Registry::instance()->REQ->set('process_form_submission', true);
380
+		EED_Single_Page_Checkout::instance()->_initialize();
381
+		if (EED_Single_Page_Checkout::instance()->checkout->current_step->completed()) {
382
+			$final_reg_step = end(EED_Single_Page_Checkout::instance()->checkout->reg_steps);
383
+			if ($final_reg_step instanceof EE_SPCO_Reg_Step_Finalize_Registration) {
384
+				EED_Single_Page_Checkout::instance()->checkout->set_reg_step_initiated($final_reg_step);
385
+				if ($final_reg_step->process_reg_step()) {
386
+					$final_reg_step->set_completed();
387
+					EED_Single_Page_Checkout::instance()->checkout->update_txn_reg_steps_array();
388
+					return EED_Single_Page_Checkout::instance()->checkout->transaction;
389
+				}
390
+			}
391
+		}
392
+		return null;
393
+	}
394
+
395
+
396
+
397
+	/**
398
+	 *    run
399
+	 *
400
+	 * @access    public
401
+	 * @param WP_Query $WP_Query
402
+	 * @return    void
403
+	 * @throws EE_Error
404
+	 */
405
+	public function run($WP_Query)
406
+	{
407
+		if (
408
+			$WP_Query instanceof WP_Query
409
+			&& $WP_Query->is_main_query()
410
+			&& apply_filters('FHEE__EED_Single_Page_Checkout__run', true)
411
+			&& $this->_is_reg_checkout()
412
+		) {
413
+			$this->_initialize();
414
+		}
415
+	}
416
+
417
+
418
+
419
+	/**
420
+	 * determines whether current url matches reg page url
421
+	 *
422
+	 * @return bool
423
+	 */
424
+	protected function _is_reg_checkout()
425
+	{
426
+		// get current permalink for reg page without any extra query args
427
+		$reg_page_url = \get_permalink(EE_Config::instance()->core->reg_page_id);
428
+		// get request URI for current request, but without the scheme or host
429
+		$current_request_uri = \EEH_URL::filter_input_server_url('REQUEST_URI');
430
+		$current_request_uri = html_entity_decode($current_request_uri);
431
+		// get array of query args from the current request URI
432
+		$query_args = \EEH_URL::get_query_string($current_request_uri);
433
+		// grab page id if it is set
434
+		$page_id = isset($query_args['page_id']) ? absint($query_args['page_id']) : 0;
435
+		// and remove the page id from the query args (we will re-add it later)
436
+		unset($query_args['page_id']);
437
+		// now strip all query args from current request URI
438
+		$current_request_uri = remove_query_arg(array_keys($query_args), $current_request_uri);
439
+		// and re-add the page id if it was set
440
+		if ($page_id) {
441
+			$current_request_uri = add_query_arg('page_id', $page_id, $current_request_uri);
442
+		}
443
+		// remove slashes and ?
444
+		$current_request_uri = trim($current_request_uri, '?/');
445
+		// is current request URI part of the known full reg page URL ?
446
+		return ! empty($current_request_uri) && strpos($reg_page_url, $current_request_uri) !== false;
447
+	}
448
+
449
+
450
+
451
+	/**
452
+	 * @param WP_Query $wp_query
453
+	 * @return    void
454
+	 * @throws EE_Error
455
+	 */
456
+	public static function init($wp_query)
457
+	{
458
+		EED_Single_Page_Checkout::instance()->run($wp_query);
459
+	}
460
+
461
+
462
+
463
+	/**
464
+	 *    _initialize - initial module setup
465
+	 *
466
+	 * @access    private
467
+	 * @throws EE_Error
468
+	 * @return    void
469
+	 */
470
+	private function _initialize()
471
+	{
472
+		// ensure SPCO doesn't run twice
473
+		if (EED_Single_Page_Checkout::$_initialized) {
474
+			return;
475
+		}
476
+		try {
477
+			EED_Single_Page_Checkout::load_reg_steps();
478
+			$this->_verify_session();
479
+			// setup the EE_Checkout object
480
+			$this->checkout = $this->_initialize_checkout();
481
+			// filter checkout
482
+			$this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize__checkout', $this->checkout);
483
+			// get the $_GET
484
+			$this->_get_request_vars();
485
+			if ($this->_block_bots()) {
486
+				return;
487
+			}
488
+			// filter continue_reg
489
+			$this->checkout->continue_reg = apply_filters(
490
+				'FHEE__EED_Single_Page_Checkout__init___continue_reg',
491
+				true,
492
+				$this->checkout
493
+			);
494
+			// load the reg steps array
495
+			if ( ! $this->_load_and_instantiate_reg_steps()) {
496
+				EED_Single_Page_Checkout::$_initialized = true;
497
+				return;
498
+			}
499
+			// set the current step
500
+			$this->checkout->set_current_step($this->checkout->step);
501
+			// and the next step
502
+			$this->checkout->set_next_step();
503
+			// verify that everything has been setup correctly
504
+			if ( ! ($this->_verify_transaction_and_get_registrations() && $this->_final_verifications())) {
505
+				EED_Single_Page_Checkout::$_initialized = true;
506
+				return;
507
+			}
508
+			// lock the transaction
509
+			$this->checkout->transaction->lock();
510
+			// make sure all of our cached objects are added to their respective model entity mappers
511
+			$this->checkout->refresh_all_entities();
512
+			// set amount owing
513
+			$this->checkout->amount_owing = $this->checkout->transaction->remaining();
514
+			// initialize each reg step, which gives them the chance to potentially alter the process
515
+			$this->_initialize_reg_steps();
516
+			// DEBUG LOG
517
+			$this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
518
+			// get reg form
519
+			if( ! $this->_check_form_submission()) {
520
+				EED_Single_Page_Checkout::$_initialized = true;
521
+				return;
522
+			}
523
+			// checkout the action!!!
524
+			$this->_process_form_action();
525
+			// add some style and make it dance
526
+			$this->add_styles_and_scripts();
527
+			// kk... SPCO has successfully run
528
+			EED_Single_Page_Checkout::$_initialized = true;
529
+			// set no cache headers and constants
530
+			EE_System::do_not_cache();
531
+			// add anchor
532
+			add_action('loop_start', array($this, 'set_checkout_anchor'), 1);
533
+			// remove transaction lock
534
+			add_action('shutdown', array($this, 'unlock_transaction'), 1);
535
+		} catch (Exception $e) {
536
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
537
+		}
538
+	}
539
+
540
+
541
+
542
+	/**
543
+	 *    _verify_session
544
+	 * checks that the session is valid and not expired
545
+	 *
546
+	 * @access    private
547
+	 * @throws EE_Error
548
+	 */
549
+	private function _verify_session()
550
+	{
551
+		if ( ! EE_Registry::instance()->SSN instanceof EE_Session) {
552
+			throw new EE_Error(__('The EE_Session class could not be loaded.', 'event_espresso'));
553
+		}
554
+		$clear_session_requested = filter_var(
555
+			EE_Registry::instance()->REQ->get('clear_session', false),
556
+			FILTER_VALIDATE_BOOLEAN
557
+		);
558
+		// is session still valid ?
559
+		if ($clear_session_requested
560
+			|| ( EE_Registry::instance()->SSN->expired()
561
+			  && EE_Registry::instance()->REQ->get('e_reg_url_link', '') === ''
562
+			)
563
+		) {
564
+			$this->checkout = new EE_Checkout();
565
+			EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
566
+			// EE_Registry::instance()->SSN->reset_cart();
567
+			// EE_Registry::instance()->SSN->reset_checkout();
568
+			// EE_Registry::instance()->SSN->reset_transaction();
569
+			if (! $clear_session_requested) {
570
+				EE_Error::add_attention(
571
+					EE_Registry::$i18n_js_strings['registration_expiration_notice'],
572
+					__FILE__, __FUNCTION__, __LINE__
573
+				);
574
+			}
575
+			// EE_Registry::instance()->SSN->reset_expired();
576
+		}
577
+	}
578
+
579
+
580
+
581
+	/**
582
+	 *    _initialize_checkout
583
+	 * loads and instantiates EE_Checkout
584
+	 *
585
+	 * @access    private
586
+	 * @throws EE_Error
587
+	 * @return EE_Checkout
588
+	 */
589
+	private function _initialize_checkout()
590
+	{
591
+		// look in session for existing checkout
592
+		/** @type EE_Checkout $checkout */
593
+		$checkout = EE_Registry::instance()->SSN->checkout();
594
+		// verify
595
+		if ( ! $checkout instanceof EE_Checkout) {
596
+			// instantiate EE_Checkout object for handling the properties of the current checkout process
597
+			$checkout = EE_Registry::instance()->load_file(
598
+				SPCO_INC_PATH,
599
+				'EE_Checkout',
600
+				'class', array(),
601
+				false
602
+			);
603
+		} else {
604
+			if ($checkout->current_step->is_final_step() && $checkout->exit_spco() === true) {
605
+				$this->unlock_transaction();
606
+				wp_safe_redirect($checkout->redirect_url);
607
+				exit();
608
+			}
609
+		}
610
+		$checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize_checkout__checkout', $checkout);
611
+		// verify again
612
+		if ( ! $checkout instanceof EE_Checkout) {
613
+			throw new EE_Error(__('The EE_Checkout class could not be loaded.', 'event_espresso'));
614
+		}
615
+		// reset anything that needs a clean slate for each request
616
+		$checkout->reset_for_current_request();
617
+		return $checkout;
618
+	}
619
+
620
+
621
+
622
+	/**
623
+	 *    _get_request_vars
624
+	 *
625
+	 * @access    private
626
+	 * @return    void
627
+	 * @throws EE_Error
628
+	 */
629
+	private function _get_request_vars()
630
+	{
631
+		// load classes
632
+		EED_Single_Page_Checkout::load_request_handler();
633
+		//make sure this request is marked as belonging to EE
634
+		EE_Registry::instance()->REQ->set_espresso_page(true);
635
+		// which step is being requested ?
636
+		$this->checkout->step = EE_Registry::instance()->REQ->get('step', $this->_get_first_step());
637
+		// which step is being edited ?
638
+		$this->checkout->edit_step = EE_Registry::instance()->REQ->get('edit_step', '');
639
+		// and what we're doing on the current step
640
+		$this->checkout->action = EE_Registry::instance()->REQ->get('action', 'display_spco_reg_step');
641
+		// timestamp
642
+		$this->checkout->uts = EE_Registry::instance()->REQ->get('uts', 0);
643
+		// returning to edit ?
644
+		$this->checkout->reg_url_link = EE_Registry::instance()->REQ->get('e_reg_url_link', '');
645
+		// add reg url link to registration query params
646
+		if ($this->checkout->reg_url_link && strpos($this->checkout->reg_url_link, '1-') !== 0) {
647
+			$this->checkout->reg_cache_where_params[0]['REG_url_link'] = $this->checkout->reg_url_link;
648
+		}
649
+		// or some other kind of revisit ?
650
+		$this->checkout->revisit = filter_var(
651
+			EE_Registry::instance()->REQ->get('revisit', false),
652
+			FILTER_VALIDATE_BOOLEAN
653
+		);
654
+		// and whether or not to generate a reg form for this request
655
+		$this->checkout->generate_reg_form = filter_var(
656
+			EE_Registry::instance()->REQ->get('generate_reg_form', true),
657
+			FILTER_VALIDATE_BOOLEAN
658
+		);
659
+		// and whether or not to process a reg form submission for this request
660
+		$this->checkout->process_form_submission = filter_var(
661
+			EE_Registry::instance()->REQ->get(
662
+				'process_form_submission',
663
+				$this->checkout->action === 'process_reg_step'
664
+			),
665
+			FILTER_VALIDATE_BOOLEAN
666
+		);
667
+		$this->checkout->process_form_submission = filter_var(
668
+			$this->checkout->action !== 'display_spco_reg_step'
669
+				? $this->checkout->process_form_submission
670
+				: false,
671
+			FILTER_VALIDATE_BOOLEAN
672
+		);
673
+		// $this->_display_request_vars();
674
+	}
675
+
676
+
677
+
678
+	/**
679
+	 *  _display_request_vars
680
+	 *
681
+	 * @access    protected
682
+	 * @return    void
683
+	 */
684
+	protected function _display_request_vars()
685
+	{
686
+		if ( ! WP_DEBUG) {
687
+			return;
688
+		}
689
+		EEH_Debug_Tools::printr($_REQUEST, '$_REQUEST', __FILE__, __LINE__);
690
+		EEH_Debug_Tools::printr($this->checkout->step, '$this->checkout->step', __FILE__, __LINE__);
691
+		EEH_Debug_Tools::printr($this->checkout->edit_step, '$this->checkout->edit_step', __FILE__, __LINE__);
692
+		EEH_Debug_Tools::printr($this->checkout->action, '$this->checkout->action', __FILE__, __LINE__);
693
+		EEH_Debug_Tools::printr($this->checkout->reg_url_link, '$this->checkout->reg_url_link', __FILE__, __LINE__);
694
+		EEH_Debug_Tools::printr($this->checkout->revisit, '$this->checkout->revisit', __FILE__, __LINE__);
695
+		EEH_Debug_Tools::printr($this->checkout->generate_reg_form, '$this->checkout->generate_reg_form', __FILE__, __LINE__);
696
+		EEH_Debug_Tools::printr($this->checkout->process_form_submission, '$this->checkout->process_form_submission', __FILE__, __LINE__);
697
+	}
698
+
699
+
700
+
701
+	/**
702
+	 * _block_bots
703
+	 * checks that the incoming request has either of the following set:
704
+	 *  a uts (unix timestamp) which indicates that the request was redirected from the Ticket Selector
705
+	 *  a REG URL Link, which indicates that the request is a return visit to SPCO for a valid TXN
706
+	 * so if you're not coming from the Ticket Selector nor returning for a valid IP...
707
+	 * then where you coming from man?
708
+	 *
709
+	 * @return boolean
710
+	 */
711
+	private function _block_bots()
712
+	{
713
+		$invalid_checkout_access = EED_Invalid_Checkout_Access::getInvalidCheckoutAccess();
714
+		if ($invalid_checkout_access->checkoutAccessIsInvalid($this->checkout)) {
715
+			return true;
716
+		}
717
+		return false;
718
+	}
719
+
720
+
721
+
722
+	/**
723
+	 *    _get_first_step
724
+	 *  gets slug for first step in $_reg_steps_array
725
+	 *
726
+	 * @access    private
727
+	 * @throws EE_Error
728
+	 * @return    string
729
+	 */
730
+	private function _get_first_step()
731
+	{
732
+		$first_step = reset(EED_Single_Page_Checkout::$_reg_steps_array);
733
+		return isset($first_step['slug']) ? $first_step['slug'] : 'attendee_information';
734
+	}
735
+
736
+
737
+
738
+	/**
739
+	 *    _load_and_instantiate_reg_steps
740
+	 *  instantiates each reg step based on the loaded reg_steps array
741
+	 *
742
+	 * @access    private
743
+	 * @throws EE_Error
744
+	 * @return    bool
745
+	 */
746
+	private function _load_and_instantiate_reg_steps()
747
+	{
748
+		do_action('AHEE__Single_Page_Checkout___load_and_instantiate_reg_steps__start', $this->checkout);
749
+		// have reg_steps already been instantiated ?
750
+		if (
751
+			empty($this->checkout->reg_steps)
752
+			|| apply_filters('FHEE__Single_Page_Checkout__load_reg_steps__reload_reg_steps', false, $this->checkout)
753
+		) {
754
+			// if not, then loop through raw reg steps array
755
+			foreach (EED_Single_Page_Checkout::$_reg_steps_array as $order => $reg_step) {
756
+				if ( ! $this->_load_and_instantiate_reg_step($reg_step, $order)) {
757
+					return false;
758
+				}
759
+			}
760
+			EE_Registry::instance()->CFG->registration->skip_reg_confirmation = true;
761
+			EE_Registry::instance()->CFG->registration->reg_confirmation_last = true;
762
+			// skip the registration_confirmation page ?
763
+			if (EE_Registry::instance()->CFG->registration->skip_reg_confirmation) {
764
+				// just remove it from the reg steps array
765
+				$this->checkout->remove_reg_step('registration_confirmation', false);
766
+			} else if (
767
+				isset($this->checkout->reg_steps['registration_confirmation'])
768
+				&& EE_Registry::instance()->CFG->registration->reg_confirmation_last
769
+			) {
770
+				// set the order to something big like 100
771
+				$this->checkout->set_reg_step_order('registration_confirmation', 100);
772
+			}
773
+			// filter the array for good luck
774
+			$this->checkout->reg_steps = apply_filters(
775
+				'FHEE__Single_Page_Checkout__load_reg_steps__reg_steps',
776
+				$this->checkout->reg_steps
777
+			);
778
+			// finally re-sort based on the reg step class order properties
779
+			$this->checkout->sort_reg_steps();
780
+		} else {
781
+			foreach ($this->checkout->reg_steps as $reg_step) {
782
+				// set all current step stati to FALSE
783
+				$reg_step->set_is_current_step(false);
784
+			}
785
+		}
786
+		if (empty($this->checkout->reg_steps)) {
787
+			EE_Error::add_error(
788
+				__('No Reg Steps were loaded..', 'event_espresso'),
789
+				__FILE__, __FUNCTION__, __LINE__
790
+			);
791
+			return false;
792
+		}
793
+		// make reg step details available to JS
794
+		$this->checkout->set_reg_step_JSON_info();
795
+		return true;
796
+	}
797
+
798
+
799
+
800
+	/**
801
+	 *     _load_and_instantiate_reg_step
802
+	 *
803
+	 * @access    private
804
+	 * @param array $reg_step
805
+	 * @param int   $order
806
+	 * @return bool
807
+	 */
808
+	private function _load_and_instantiate_reg_step($reg_step = array(), $order = 0)
809
+	{
810
+		// we need a file_path, class_name, and slug to add a reg step
811
+		if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) {
812
+			// if editing a specific step, but this is NOT that step... (and it's not the 'finalize_registration' step)
813
+			if (
814
+				$this->checkout->reg_url_link
815
+				&& $this->checkout->step !== $reg_step['slug']
816
+				&& $reg_step['slug'] !== 'finalize_registration'
817
+				// normally at this point we would NOT load the reg step, but this filter can change that
818
+				&& apply_filters(
819
+					'FHEE__Single_Page_Checkout___load_and_instantiate_reg_step__bypass_reg_step',
820
+					true,
821
+					$reg_step,
822
+					$this->checkout
823
+				)
824
+			) {
825
+				return true;
826
+			}
827
+			// instantiate step class using file path and class name
828
+			$reg_step_obj = EE_Registry::instance()->load_file(
829
+				$reg_step['file_path'],
830
+				$reg_step['class_name'],
831
+				'class',
832
+				$this->checkout,
833
+				false
834
+			);
835
+			// did we gets the goods ?
836
+			if ($reg_step_obj instanceof EE_SPCO_Reg_Step) {
837
+				// set reg step order based on config
838
+				$reg_step_obj->set_order($order);
839
+				// add instantiated reg step object to the master reg steps array
840
+				$this->checkout->add_reg_step($reg_step_obj);
841
+			} else {
842
+				EE_Error::add_error(
843
+					__('The current step could not be set.', 'event_espresso'),
844
+					__FILE__, __FUNCTION__, __LINE__
845
+				);
846
+				return false;
847
+			}
848
+		} else {
849
+			if (WP_DEBUG) {
850
+				EE_Error::add_error(
851
+					sprintf(
852
+						__(
853
+							'A registration step could not be loaded. One or more of the following data points is invalid:%4$s%5$sFile Path: %1$s%6$s%5$sClass Name: %2$s%6$s%5$sSlug: %3$s%6$s%7$s',
854
+							'event_espresso'
855
+						),
856
+						isset($reg_step['file_path']) ? $reg_step['file_path'] : '',
857
+						isset($reg_step['class_name']) ? $reg_step['class_name'] : '',
858
+						isset($reg_step['slug']) ? $reg_step['slug'] : '',
859
+						'<ul>',
860
+						'<li>',
861
+						'</li>',
862
+						'</ul>'
863
+					),
864
+					__FILE__, __FUNCTION__, __LINE__
865
+				);
866
+			}
867
+			return false;
868
+		}
869
+		return true;
870
+	}
871
+
872
+
873
+	/**
874
+	 * _verify_transaction_and_get_registrations
875
+	 *
876
+	 * @access private
877
+	 * @return bool
878
+	 * @throws InvalidDataTypeException
879
+	 * @throws InvalidEntityException
880
+	 * @throws EE_Error
881
+	 */
882
+	private function _verify_transaction_and_get_registrations()
883
+	{
884
+		// was there already a valid transaction in the checkout from the session ?
885
+		if ( ! $this->checkout->transaction instanceof EE_Transaction) {
886
+			// get transaction from db or session
887
+			$this->checkout->transaction = $this->checkout->reg_url_link && ! is_admin()
888
+				? $this->_get_transaction_and_cart_for_previous_visit()
889
+				: $this->_get_cart_for_current_session_and_setup_new_transaction();
890
+			if ( ! $this->checkout->transaction instanceof EE_Transaction) {
891
+				EE_Error::add_error(
892
+					__('Your Registration and Transaction information could not be retrieved from the db.',
893
+						'event_espresso'),
894
+					__FILE__, __FUNCTION__, __LINE__
895
+				);
896
+				$this->checkout->transaction = EE_Transaction::new_instance();
897
+				// add some style and make it dance
898
+				$this->add_styles_and_scripts();
899
+				EED_Single_Page_Checkout::$_initialized = true;
900
+				return false;
901
+			}
902
+			// and the registrations for the transaction
903
+			$this->_get_registrations($this->checkout->transaction);
904
+		}
905
+		return true;
906
+	}
907
+
908
+
909
+
910
+	/**
911
+	 * _get_transaction_and_cart_for_previous_visit
912
+	 *
913
+	 * @access private
914
+	 * @return mixed EE_Transaction|NULL
915
+	 */
916
+	private function _get_transaction_and_cart_for_previous_visit()
917
+	{
918
+		/** @var $TXN_model EEM_Transaction */
919
+		$TXN_model = EE_Registry::instance()->load_model('Transaction');
920
+		// because the reg_url_link is present in the request,
921
+		// this is a return visit to SPCO, so we'll get the transaction data from the db
922
+		$transaction = $TXN_model->get_transaction_from_reg_url_link($this->checkout->reg_url_link);
923
+		// verify transaction
924
+		if ($transaction instanceof EE_Transaction) {
925
+			// and get the cart that was used for that transaction
926
+			$this->checkout->cart = $this->_get_cart_for_transaction($transaction);
927
+			return $transaction;
928
+		}
929
+		EE_Error::add_error(
930
+			__('Your Registration and Transaction information could not be retrieved from the db.', 'event_espresso'),
931
+			__FILE__, __FUNCTION__, __LINE__
932
+		);
933
+		return null;
934
+
935
+	}
936
+
937
+
938
+
939
+	/**
940
+	 * _get_cart_for_transaction
941
+	 *
942
+	 * @access private
943
+	 * @param EE_Transaction $transaction
944
+	 * @return EE_Cart
945
+	 */
946
+	private function _get_cart_for_transaction($transaction)
947
+	{
948
+		return $this->checkout->get_cart_for_transaction($transaction);
949
+	}
950
+
951
+
952
+
953
+	/**
954
+	 * get_cart_for_transaction
955
+	 *
956
+	 * @access public
957
+	 * @param EE_Transaction $transaction
958
+	 * @return EE_Cart
959
+	 */
960
+	public function get_cart_for_transaction(EE_Transaction $transaction)
961
+	{
962
+		return $this->checkout->get_cart_for_transaction($transaction);
963
+	}
964
+
965
+
966
+
967
+	/**
968
+	 * _get_transaction_and_cart_for_current_session
969
+	 *    generates a new EE_Transaction object and adds it to the $_transaction property.
970
+	 *
971
+	 * @access private
972
+	 * @return EE_Transaction
973
+	 * @throws EE_Error
974
+	 */
975
+	private function _get_cart_for_current_session_and_setup_new_transaction()
976
+	{
977
+		//  if there's no transaction, then this is the FIRST visit to SPCO
978
+		// so load up the cart ( passing nothing for the TXN because it doesn't exist yet )
979
+		$this->checkout->cart = $this->_get_cart_for_transaction(null);
980
+		// and then create a new transaction
981
+		$transaction = $this->_initialize_transaction();
982
+		// verify transaction
983
+		if ($transaction instanceof EE_Transaction) {
984
+			// save it so that we have an ID for other objects to use
985
+			$transaction->save();
986
+			// and save TXN data to the cart
987
+			$this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn($transaction->ID());
988
+		} else {
989
+			EE_Error::add_error(
990
+				__('A Valid Transaction could not be initialized.', 'event_espresso'),
991
+				__FILE__, __FUNCTION__, __LINE__
992
+			);
993
+		}
994
+		return $transaction;
995
+	}
996
+
997
+
998
+
999
+	/**
1000
+	 *    generates a new EE_Transaction object and adds it to the $_transaction property.
1001
+	 *
1002
+	 * @access private
1003
+	 * @return mixed EE_Transaction|NULL
1004
+	 */
1005
+	private function _initialize_transaction()
1006
+	{
1007
+		try {
1008
+			// ensure cart totals have been calculated
1009
+			$this->checkout->cart->get_grand_total()->recalculate_total_including_taxes();
1010
+			// grab the cart grand total
1011
+			$cart_total = $this->checkout->cart->get_cart_grand_total();
1012
+			// create new TXN
1013
+			$transaction = EE_Transaction::new_instance(
1014
+				array(
1015
+					'TXN_reg_steps' => $this->checkout->initialize_txn_reg_steps_array(),
1016
+					'TXN_total'     => $cart_total > 0 ? $cart_total : 0,
1017
+					'TXN_paid'      => 0,
1018
+					'STS_ID'        => EEM_Transaction::failed_status_code,
1019
+				)
1020
+			);
1021
+			// save it so that we have an ID for other objects to use
1022
+			$transaction->save();
1023
+			// set cron job for following up on TXNs after their session has expired
1024
+			EE_Cron_Tasks::schedule_expired_transaction_check(
1025
+				EE_Registry::instance()->SSN->expiration() + 1,
1026
+				$transaction->ID()
1027
+			);
1028
+			return $transaction;
1029
+		} catch (Exception $e) {
1030
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1031
+		}
1032
+		return null;
1033
+	}
1034
+
1035
+
1036
+	/**
1037
+	 * _get_registrations
1038
+	 *
1039
+	 * @access private
1040
+	 * @param EE_Transaction $transaction
1041
+	 * @return void
1042
+	 * @throws InvalidDataTypeException
1043
+	 * @throws InvalidEntityException
1044
+	 * @throws EE_Error
1045
+	 */
1046
+	private function _get_registrations(EE_Transaction $transaction)
1047
+	{
1048
+		// first step: grab the registrants  { : o
1049
+		$registrations = $transaction->registrations($this->checkout->reg_cache_where_params, false);
1050
+		$this->checkout->total_ticket_count = count($registrations);
1051
+		// verify registrations have been set
1052
+		if (empty($registrations)) {
1053
+			// if no cached registrations, then check the db
1054
+			$registrations = $transaction->registrations($this->checkout->reg_cache_where_params, false);
1055
+			// still nothing ? well as long as this isn't a revisit
1056
+			if (empty($registrations) && ! $this->checkout->revisit) {
1057
+				// generate new registrations from scratch
1058
+				$registrations = $this->_initialize_registrations($transaction);
1059
+			}
1060
+		}
1061
+		// sort by their original registration order
1062
+		usort($registrations, array('EED_Single_Page_Checkout', 'sort_registrations_by_REG_count'));
1063
+		// then loop thru the array
1064
+		foreach ($registrations as $registration) {
1065
+			// verify each registration
1066
+			if ($registration instanceof EE_Registration) {
1067
+				// we display all attendee info for the primary registrant
1068
+				if ($this->checkout->reg_url_link === $registration->reg_url_link()
1069
+					&& $registration->is_primary_registrant()
1070
+				) {
1071
+					$this->checkout->primary_revisit = true;
1072
+					break;
1073
+				}
1074
+				if ($this->checkout->revisit && $this->checkout->reg_url_link !== $registration->reg_url_link()) {
1075
+					// but hide info if it doesn't belong to you
1076
+					$transaction->clear_cache('Registration', $registration->ID());
1077
+					$this->checkout->total_ticket_count--;
1078
+				}
1079
+				$this->checkout->set_reg_status_updated($registration->ID(), false);
1080
+			}
1081
+		}
1082
+	}
1083
+
1084
+
1085
+	/**
1086
+	 *    adds related EE_Registration objects for each ticket in the cart to the current EE_Transaction object
1087
+	 *
1088
+	 * @access private
1089
+	 * @param EE_Transaction $transaction
1090
+	 * @return    array
1091
+	 * @throws InvalidDataTypeException
1092
+	 * @throws InvalidEntityException
1093
+	 * @throws EE_Error
1094
+	 */
1095
+	private function _initialize_registrations(EE_Transaction $transaction)
1096
+	{
1097
+		$att_nmbr = 0;
1098
+		$registrations = array();
1099
+		if ($transaction instanceof EE_Transaction) {
1100
+			/** @type EE_Registration_Processor $registration_processor */
1101
+			$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
1102
+			$this->checkout->total_ticket_count = $this->checkout->cart->all_ticket_quantity_count();
1103
+			// now let's add the cart items to the $transaction
1104
+			foreach ($this->checkout->cart->get_tickets() as $line_item) {
1105
+				//do the following for each ticket of this type they selected
1106
+				for ($x = 1; $x <= $line_item->quantity(); $x++) {
1107
+					$att_nmbr++;
1108
+					/** @var EventEspresso\core\services\commands\registration\CreateRegistrationCommand $CreateRegistrationCommand */
1109
+					$CreateRegistrationCommand = EE_Registry::instance()->create(
1110
+						'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
1111
+						array(
1112
+							$transaction,
1113
+							$line_item,
1114
+							$att_nmbr,
1115
+							$this->checkout->total_ticket_count,
1116
+						)
1117
+					);
1118
+					// override capabilities for frontend registrations
1119
+					if ( ! is_admin()) {
1120
+						$CreateRegistrationCommand->setCapCheck(
1121
+							new PublicCapabilities('', 'create_new_registration')
1122
+						);
1123
+					}
1124
+					$registration = EE_Registry::instance()->BUS->execute($CreateRegistrationCommand);
1125
+					if ( ! $registration instanceof EE_Registration) {
1126
+						throw new InvalidEntityException($registration, 'EE_Registration');
1127
+					}
1128
+					$registrations[ $registration->ID() ] = $registration;
1129
+				}
1130
+			}
1131
+			$registration_processor->fix_reg_final_price_rounding_issue($transaction);
1132
+		}
1133
+		return $registrations;
1134
+	}
1135
+
1136
+
1137
+
1138
+	/**
1139
+	 * sorts registrations by REG_count
1140
+	 *
1141
+	 * @access public
1142
+	 * @param EE_Registration $reg_A
1143
+	 * @param EE_Registration $reg_B
1144
+	 * @return int
1145
+	 */
1146
+	public static function sort_registrations_by_REG_count(EE_Registration $reg_A, EE_Registration $reg_B)
1147
+	{
1148
+		// this shouldn't ever happen within the same TXN, but oh well
1149
+		if ($reg_A->count() === $reg_B->count()) {
1150
+			return 0;
1151
+		}
1152
+		return ($reg_A->count() > $reg_B->count()) ? 1 : -1;
1153
+	}
1154
+
1155
+
1156
+
1157
+	/**
1158
+	 *    _final_verifications
1159
+	 * just makes sure that everything is set up correctly before proceeding
1160
+	 *
1161
+	 * @access    private
1162
+	 * @return    bool
1163
+	 * @throws EE_Error
1164
+	 */
1165
+	private function _final_verifications()
1166
+	{
1167
+		// filter checkout
1168
+		$this->checkout = apply_filters(
1169
+			'FHEE__EED_Single_Page_Checkout___final_verifications__checkout',
1170
+			$this->checkout
1171
+		);
1172
+		//verify that current step is still set correctly
1173
+		if ( ! $this->checkout->current_step instanceof EE_SPCO_Reg_Step) {
1174
+			EE_Error::add_error(
1175
+				__('We\'re sorry but the registration process can not proceed because one or more registration steps were not setup correctly. Please refresh the page and try again or contact support.', 'event_espresso'),
1176
+				__FILE__,
1177
+				__FUNCTION__,
1178
+				__LINE__
1179
+			);
1180
+			return false;
1181
+		}
1182
+		// if returning to SPCO, then verify that primary registrant is set
1183
+		if ( ! empty($this->checkout->reg_url_link)) {
1184
+			$valid_registrant = $this->checkout->transaction->primary_registration();
1185
+			if ( ! $valid_registrant instanceof EE_Registration) {
1186
+				EE_Error::add_error(
1187
+					__('We\'re sorry but there appears to be an error with the "reg_url_link" or the primary registrant for this transaction. Please refresh the page and try again or contact support.', 'event_espresso'),
1188
+					__FILE__,
1189
+					__FUNCTION__,
1190
+					__LINE__
1191
+				);
1192
+				return false;
1193
+			}
1194
+			$valid_registrant = null;
1195
+			foreach (
1196
+				$this->checkout->transaction->registrations($this->checkout->reg_cache_where_params) as $registration
1197
+			) {
1198
+				if (
1199
+					$registration instanceof EE_Registration
1200
+					&& $registration->reg_url_link() === $this->checkout->reg_url_link
1201
+				) {
1202
+					$valid_registrant = $registration;
1203
+				}
1204
+			}
1205
+			if ( ! $valid_registrant instanceof EE_Registration) {
1206
+				// hmmm... maybe we have the wrong session because the user is opening multiple tabs ?
1207
+				if (EED_Single_Page_Checkout::$_checkout_verified) {
1208
+					// clear the session, mark the checkout as unverified, and try again
1209
+					EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
1210
+					EED_Single_Page_Checkout::$_initialized = false;
1211
+					EED_Single_Page_Checkout::$_checkout_verified = false;
1212
+					$this->_initialize();
1213
+					EE_Error::reset_notices();
1214
+					return false;
1215
+				}
1216
+				EE_Error::add_error(
1217
+					__(
1218
+						'We\'re sorry but there appears to be an error with the "reg_url_link" or the transaction itself. Please refresh the page and try again or contact support.',
1219
+						'event_espresso'
1220
+					),
1221
+					__FILE__,
1222
+					__FUNCTION__,
1223
+					__LINE__
1224
+				);
1225
+				return false;
1226
+			}
1227
+		}
1228
+		// now that things have been kinda sufficiently verified,
1229
+		// let's add the checkout to the session so that it's available to other systems
1230
+		EE_Registry::instance()->SSN->set_checkout($this->checkout);
1231
+		return true;
1232
+	}
1233
+
1234
+
1235
+
1236
+	/**
1237
+	 *    _initialize_reg_steps
1238
+	 * first makes sure that EE_Transaction_Processor::set_reg_step_initiated() is called as required
1239
+	 * then loops thru all of the active reg steps and calls the initialize_reg_step() method
1240
+	 *
1241
+	 * @access    private
1242
+	 * @param bool $reinitializing
1243
+	 * @throws EE_Error
1244
+	 */
1245
+	private function _initialize_reg_steps($reinitializing = false)
1246
+	{
1247
+		$this->checkout->set_reg_step_initiated($this->checkout->current_step);
1248
+		// loop thru all steps to call their individual "initialize" methods and set i18n strings for JS
1249
+		foreach ($this->checkout->reg_steps as $reg_step) {
1250
+			if ( ! $reg_step->initialize_reg_step()) {
1251
+				// if not initialized then maybe this step is being removed...
1252
+				if ( ! $reinitializing && $reg_step->is_current_step()) {
1253
+					// if it was the current step, then we need to start over here
1254
+					$this->_initialize_reg_steps(true);
1255
+					return;
1256
+				}
1257
+				continue;
1258
+			}
1259
+			// add css and JS for current step
1260
+			$reg_step->enqueue_styles_and_scripts();
1261
+			// i18n
1262
+			$reg_step->translate_js_strings();
1263
+			if ($reg_step->is_current_step()) {
1264
+				// the text that appears on the reg step form submit button
1265
+				$reg_step->set_submit_button_text();
1266
+			}
1267
+		}
1268
+		// dynamically creates hook point like: AHEE__Single_Page_Checkout___initialize_reg_step__attendee_information
1269
+		do_action(
1270
+			"AHEE__Single_Page_Checkout___initialize_reg_step__{$this->checkout->current_step->slug()}",
1271
+			$this->checkout->current_step
1272
+		);
1273
+	}
1274
+
1275
+
1276
+
1277
+	/**
1278
+	 * _check_form_submission
1279
+	 *
1280
+	 * @access private
1281
+	 * @return boolean
1282
+	 */
1283
+	private function _check_form_submission()
1284
+	{
1285
+		//does this request require the reg form to be generated ?
1286
+		if ($this->checkout->generate_reg_form) {
1287
+			// ever heard that song by Blue Rodeo ?
1288
+			try {
1289
+				$this->checkout->current_step->reg_form = $this->checkout->current_step->generate_reg_form();
1290
+				// if not displaying a form, then check for form submission
1291
+				if (
1292
+					$this->checkout->process_form_submission
1293
+					&& $this->checkout->current_step->reg_form->was_submitted()
1294
+				) {
1295
+					// clear out any old data in case this step is being run again
1296
+					$this->checkout->current_step->set_valid_data(array());
1297
+					// capture submitted form data
1298
+					$this->checkout->current_step->reg_form->receive_form_submission(
1299
+						apply_filters(
1300
+							'FHEE__Single_Page_Checkout___check_form_submission__request_params',
1301
+							EE_Registry::instance()->REQ->params(),
1302
+							$this->checkout
1303
+						)
1304
+					);
1305
+					// validate submitted form data
1306
+					if ( ! $this->checkout->continue_reg || ! $this->checkout->current_step->reg_form->is_valid()) {
1307
+						// thou shall not pass !!!
1308
+						$this->checkout->continue_reg = false;
1309
+						// any form validation errors?
1310
+						if ($this->checkout->current_step->reg_form->submission_error_message() !== '') {
1311
+							$submission_error_messages = array();
1312
+							// bad, bad, bad registrant
1313
+							foreach (
1314
+								$this->checkout->current_step->reg_form->get_validation_errors_accumulated()
1315
+								as $validation_error
1316
+							) {
1317
+								if ($validation_error instanceof EE_Validation_Error) {
1318
+									$submission_error_messages[] = sprintf(
1319
+										__('%s : %s', 'event_espresso'),
1320
+										$validation_error->get_form_section()->html_label_text(),
1321
+										$validation_error->getMessage()
1322
+									);
1323
+								}
1324
+							}
1325
+							EE_Error::add_error(
1326
+								implode('<br />', $submission_error_messages),
1327
+								__FILE__, __FUNCTION__, __LINE__
1328
+							);
1329
+						}
1330
+						// well not really... what will happen is
1331
+						// we'll just get redirected back to redo the current step
1332
+						$this->go_to_next_step();
1333
+						return false;
1334
+					}
1335
+				}
1336
+			} catch (EE_Error $e) {
1337
+				$e->get_error();
1338
+			}
1339
+		}
1340
+		return true;
1341
+	}
1342
+
1343
+
1344
+
1345
+	/**
1346
+	 * _process_action
1347
+	 *
1348
+	 * @access private
1349
+	 * @return void
1350
+	 * @throws EE_Error
1351
+	 */
1352
+	private function _process_form_action()
1353
+	{
1354
+		// what cha wanna do?
1355
+		switch ($this->checkout->action) {
1356
+			// AJAX next step reg form
1357
+			case 'display_spco_reg_step' :
1358
+				$this->checkout->redirect = false;
1359
+				if (EE_Registry::instance()->REQ->ajax) {
1360
+					$this->checkout->json_response->set_reg_step_html(
1361
+						$this->checkout->current_step->display_reg_form()
1362
+					);
1363
+				}
1364
+				break;
1365
+			default :
1366
+				// meh... do one of those other steps first
1367
+				if (
1368
+					! empty($this->checkout->action)
1369
+					&& is_callable(array($this->checkout->current_step, $this->checkout->action))
1370
+				) {
1371
+					// dynamically creates hook point like:
1372
+					//   AHEE__Single_Page_Checkout__before_attendee_information__process_reg_step
1373
+					do_action(
1374
+						"AHEE__Single_Page_Checkout__before_{$this->checkout->current_step->slug()}__{$this->checkout->action}",
1375
+						$this->checkout->current_step
1376
+					);
1377
+					// call action on current step
1378
+					if (call_user_func(array($this->checkout->current_step, $this->checkout->action))) {
1379
+						// good registrant, you get to proceed
1380
+						if (
1381
+							$this->checkout->current_step->success_message() !== ''
1382
+							&& apply_filters(
1383
+								'FHEE__Single_Page_Checkout___process_form_action__display_success',
1384
+								false
1385
+							)
1386
+						) {
1387
+							EE_Error::add_success(
1388
+								$this->checkout->current_step->success_message()
1389
+								. '<br />' . $this->checkout->next_step->_instructions()
1390
+							);
1391
+						}
1392
+						// pack it up, pack it in...
1393
+						$this->_setup_redirect();
1394
+					}
1395
+					// dynamically creates hook point like:
1396
+					//  AHEE__Single_Page_Checkout__after_payment_options__process_reg_step
1397
+					do_action(
1398
+						"AHEE__Single_Page_Checkout__after_{$this->checkout->current_step->slug()}__{$this->checkout->action}",
1399
+						$this->checkout->current_step
1400
+					);
1401
+				} else {
1402
+					EE_Error::add_error(
1403
+						sprintf(
1404
+							__(
1405
+								'The requested form action "%s" does not exist for the current "%s" registration step.',
1406
+								'event_espresso'
1407
+							),
1408
+							$this->checkout->action,
1409
+							$this->checkout->current_step->name()
1410
+						),
1411
+						__FILE__,
1412
+						__FUNCTION__,
1413
+						__LINE__
1414
+					);
1415
+				}
1416
+			// end default
1417
+		}
1418
+		// store our progress so far
1419
+		$this->checkout->stash_transaction_and_checkout();
1420
+		// advance to the next step! If you pass GO, collect $200
1421
+		$this->go_to_next_step();
1422
+	}
1423
+
1424
+
1425
+
1426
+	/**
1427
+	 *        add_styles_and_scripts
1428
+	 *
1429
+	 * @access        public
1430
+	 * @return        void
1431
+	 */
1432
+	public function add_styles_and_scripts()
1433
+	{
1434
+		// i18n
1435
+		$this->translate_js_strings();
1436
+		if ($this->checkout->admin_request) {
1437
+			add_action('admin_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10);
1438
+		} else {
1439
+			add_action('wp_enqueue_scripts', array($this, 'enqueue_styles_and_scripts'), 10);
1440
+		}
1441
+	}
1442
+
1443
+
1444
+
1445
+	/**
1446
+	 *        translate_js_strings
1447
+	 *
1448
+	 * @access        public
1449
+	 * @return        void
1450
+	 */
1451
+	public function translate_js_strings()
1452
+	{
1453
+		EE_Registry::$i18n_js_strings['revisit'] = $this->checkout->revisit;
1454
+		EE_Registry::$i18n_js_strings['e_reg_url_link'] = $this->checkout->reg_url_link;
1455
+		EE_Registry::$i18n_js_strings['server_error'] = __(
1456
+			'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
1457
+			'event_espresso'
1458
+		);
1459
+		EE_Registry::$i18n_js_strings['invalid_json_response'] = __(
1460
+			'An invalid response was returned from the server while attempting to process your request. Please refresh the page and try again or contact support.',
1461
+			'event_espresso'
1462
+		);
1463
+		EE_Registry::$i18n_js_strings['validation_error'] = __(
1464
+			'There appears to be a problem with the form validation configuration! Please check the admin settings or contact support.',
1465
+			'event_espresso'
1466
+		);
1467
+		EE_Registry::$i18n_js_strings['invalid_payment_method'] = __(
1468
+			'There appears to be a problem with the payment method configuration! Please refresh the page and try again or contact support.',
1469
+			'event_espresso'
1470
+		);
1471
+		EE_Registry::$i18n_js_strings['reg_step_error'] = __(
1472
+			'This registration step could not be completed. Please refresh the page and try again.',
1473
+			'event_espresso'
1474
+		);
1475
+		EE_Registry::$i18n_js_strings['invalid_coupon'] = __(
1476
+			'We\'re sorry but that coupon code does not appear to be valid. If this is incorrect, please contact the site administrator.',
1477
+			'event_espresso'
1478
+		);
1479
+		EE_Registry::$i18n_js_strings['process_registration'] = sprintf(
1480
+			__(
1481
+				'Please wait while we process your registration.%sDo not refresh the page or navigate away while this is happening.%sThank you for your patience.',
1482
+				'event_espresso'
1483
+			),
1484
+			'<br/>',
1485
+			'<br/>'
1486
+		);
1487
+		EE_Registry::$i18n_js_strings['language'] = get_bloginfo('language');
1488
+		EE_Registry::$i18n_js_strings['EESID'] = EE_Registry::instance()->SSN->id();
1489
+		EE_Registry::$i18n_js_strings['currency'] = EE_Registry::instance()->CFG->currency;
1490
+		EE_Registry::$i18n_js_strings['datepicker_yearRange'] = '-150:+20';
1491
+		EE_Registry::$i18n_js_strings['timer_years'] = __('years', 'event_espresso');
1492
+		EE_Registry::$i18n_js_strings['timer_months'] = __('months', 'event_espresso');
1493
+		EE_Registry::$i18n_js_strings['timer_weeks'] = __('weeks', 'event_espresso');
1494
+		EE_Registry::$i18n_js_strings['timer_days'] = __('days', 'event_espresso');
1495
+		EE_Registry::$i18n_js_strings['timer_hours'] = __('hours', 'event_espresso');
1496
+		EE_Registry::$i18n_js_strings['timer_minutes'] = __('minutes', 'event_espresso');
1497
+		EE_Registry::$i18n_js_strings['timer_seconds'] = __('seconds', 'event_espresso');
1498
+		EE_Registry::$i18n_js_strings['timer_year'] = __('year', 'event_espresso');
1499
+		EE_Registry::$i18n_js_strings['timer_month'] = __('month', 'event_espresso');
1500
+		EE_Registry::$i18n_js_strings['timer_week'] = __('week', 'event_espresso');
1501
+		EE_Registry::$i18n_js_strings['timer_day'] = __('day', 'event_espresso');
1502
+		EE_Registry::$i18n_js_strings['timer_hour'] = __('hour', 'event_espresso');
1503
+		EE_Registry::$i18n_js_strings['timer_minute'] = __('minute', 'event_espresso');
1504
+		EE_Registry::$i18n_js_strings['timer_second'] = __('second', 'event_espresso');
1505
+		EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
1506
+			__(
1507
+				'%1$sWe\'re sorry, but your registration time has expired.%2$s%3$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please except our apologies for any inconvenience this may have caused.%8$s',
1508
+				'event_espresso'
1509
+			),
1510
+			'<h4 class="important-notice">',
1511
+			'</h4>',
1512
+			'<br />',
1513
+			'<p>',
1514
+			'<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
1515
+			'">',
1516
+			'</a>',
1517
+			'</p>'
1518
+		);
1519
+		EE_Registry::$i18n_js_strings['ajax_submit'] = apply_filters(
1520
+			'FHEE__Single_Page_Checkout__translate_js_strings__ajax_submit',
1521
+			true
1522
+		);
1523
+		EE_Registry::$i18n_js_strings['session_extension'] = absint(
1524
+			apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS)
1525
+		);
1526
+		EE_Registry::$i18n_js_strings['session_expiration'] = gmdate(
1527
+			'M d, Y H:i:s',
1528
+			EE_Registry::instance()->SSN->expiration() + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1529
+		);
1530
+	}
1531
+
1532
+
1533
+
1534
+	/**
1535
+	 *    enqueue_styles_and_scripts
1536
+	 *
1537
+	 * @access        public
1538
+	 * @return        void
1539
+	 * @throws EE_Error
1540
+	 */
1541
+	public function enqueue_styles_and_scripts()
1542
+	{
1543
+		// load css
1544
+		wp_register_style(
1545
+			'single_page_checkout',
1546
+			SPCO_CSS_URL . 'single_page_checkout.css',
1547
+			array('espresso_default'),
1548
+			EVENT_ESPRESSO_VERSION
1549
+		);
1550
+		wp_enqueue_style('single_page_checkout');
1551
+		// load JS
1552
+		wp_register_script(
1553
+			'jquery_plugin',
1554
+			EE_THIRD_PARTY_URL . 'jquery	.plugin.min.js',
1555
+			array('jquery'),
1556
+			'1.0.1',
1557
+			true
1558
+		);
1559
+		wp_register_script(
1560
+			'jquery_countdown',
1561
+			EE_THIRD_PARTY_URL . 'jquery	.countdown.min.js',
1562
+			array('jquery_plugin'),
1563
+			'2.0.2',
1564
+			true
1565
+		);
1566
+		wp_register_script(
1567
+			'single_page_checkout',
1568
+			SPCO_JS_URL . 'single_page_checkout.js',
1569
+			array('espresso_core', 'underscore', 'ee_form_section_validation', 'jquery_countdown'),
1570
+			EVENT_ESPRESSO_VERSION,
1571
+			true
1572
+		);
1573
+		if ($this->checkout->registration_form instanceof EE_Form_Section_Proper) {
1574
+			$this->checkout->registration_form->enqueue_js();
1575
+		}
1576
+		if ($this->checkout->current_step->reg_form instanceof EE_Form_Section_Proper) {
1577
+			$this->checkout->current_step->reg_form->enqueue_js();
1578
+		}
1579
+		wp_enqueue_script('single_page_checkout');
1580
+		/**
1581
+		 * global action hook for enqueueing styles and scripts with
1582
+		 * spco calls.
1583
+		 */
1584
+		do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts', $this);
1585
+		/**
1586
+		 * dynamic action hook for enqueueing styles and scripts with spco calls.
1587
+		 * The hook will end up being something like:
1588
+		 *      AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information
1589
+		 */
1590
+		do_action(
1591
+			'AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(),
1592
+			$this
1593
+		);
1594
+	}
1595
+
1596
+
1597
+
1598
+	/**
1599
+	 *    display the Registration Single Page Checkout Form
1600
+	 *
1601
+	 * @access    private
1602
+	 * @return    void
1603
+	 * @throws EE_Error
1604
+	 */
1605
+	private function _display_spco_reg_form()
1606
+	{
1607
+		// if registering via the admin, just display the reg form for the current step
1608
+		if ($this->checkout->admin_request) {
1609
+			EE_Registry::instance()->REQ->add_output($this->checkout->current_step->display_reg_form());
1610
+		} else {
1611
+			// add powered by EE msg
1612
+			add_action('AHEE__SPCO__reg_form_footer', array('EED_Single_Page_Checkout', 'display_registration_footer'));
1613
+			$empty_cart = count(
1614
+				$this->checkout->transaction->registrations($this->checkout->reg_cache_where_params)
1615
+			) < 1;
1616
+			EE_Registry::$i18n_js_strings['empty_cart'] = $empty_cart;
1617
+			$cookies_not_set_msg = '';
1618
+			if ($empty_cart && ! isset($_COOKIE['ee_cookie_test'])) {
1619
+				$cookies_not_set_msg = apply_filters(
1620
+					'FHEE__Single_Page_Checkout__display_spco_reg_form__cookies_not_set_msg',
1621
+					sprintf(
1622
+						__(
1623
+							'%1$s%3$sIt appears your browser is not currently set to accept Cookies%4$s%5$sIn order to register for events, you need to enable cookies.%7$sIf you require assistance, then click the following link to learn how to %8$senable cookies%9$s%6$s%2$s',
1624
+							'event_espresso'
1625
+						),
1626
+						'<div class="ee-attention">',
1627
+						'</div>',
1628
+						'<h6 class="important-notice">',
1629
+						'</h6>',
1630
+						'<p>',
1631
+						'</p>',
1632
+						'<br />',
1633
+						'<a href="http://www.whatarecookies.com/enable.asp" target="_blank">',
1634
+						'</a>'
1635
+					)
1636
+				);
1637
+			}
1638
+			$this->checkout->registration_form = new EE_Form_Section_Proper(
1639
+				array(
1640
+					'name'            => 'single-page-checkout',
1641
+					'html_id'         => 'ee-single-page-checkout-dv',
1642
+					'layout_strategy' =>
1643
+						new EE_Template_Layout(
1644
+							array(
1645
+								'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php',
1646
+								'template_args'        => array(
1647
+									'empty_cart'              => $empty_cart,
1648
+									'revisit'                 => $this->checkout->revisit,
1649
+									'reg_steps'               => $this->checkout->reg_steps,
1650
+									'next_step'               => $this->checkout->next_step instanceof EE_SPCO_Reg_Step
1651
+										? $this->checkout->next_step->slug()
1652
+										: '',
1653
+									'cancel_page_url'         => $this->checkout->cancel_page_url,
1654
+									'empty_msg'               => apply_filters(
1655
+										'FHEE__Single_Page_Checkout__display_spco_reg_form__empty_msg',
1656
+										sprintf(
1657
+											__(
1658
+												'You need to %1$sReturn to Events list%2$sselect at least one event%3$s before you can proceed with the registration process.',
1659
+												'event_espresso'
1660
+											),
1661
+											'<a href="'
1662
+											. get_post_type_archive_link('espresso_events')
1663
+											. '" title="',
1664
+											'">',
1665
+											'</a>'
1666
+										)
1667
+									),
1668
+									'cookies_not_set_msg'     => $cookies_not_set_msg,
1669
+									'registration_time_limit' => $this->checkout->get_registration_time_limit(),
1670
+									'session_expiration'      => gmdate(
1671
+										'M d, Y H:i:s',
1672
+										EE_Registry::instance()->SSN->expiration()
1673
+										+ (get_option('gmt_offset') * HOUR_IN_SECONDS)
1674
+									),
1675
+								),
1676
+							)
1677
+						),
1678
+				)
1679
+			);
1680
+			// load template and add to output sent that gets filtered into the_content()
1681
+			EE_Registry::instance()->REQ->add_output($this->checkout->registration_form->get_html());
1682
+		}
1683
+	}
1684
+
1685
+
1686
+
1687
+	/**
1688
+	 *    add_extra_finalize_registration_inputs
1689
+	 *
1690
+	 * @access    public
1691
+	 * @param $next_step
1692
+	 * @internal  param string $label
1693
+	 * @return void
1694
+	 */
1695
+	public function add_extra_finalize_registration_inputs($next_step)
1696
+	{
1697
+		if ($next_step === 'finalize_registration') {
1698
+			echo '<div id="spco-extra-finalize_registration-inputs-dv"></div>';
1699
+		}
1700
+	}
1701
+
1702
+
1703
+
1704
+	/**
1705
+	 *    display_registration_footer
1706
+	 *
1707
+	 * @access    public
1708
+	 * @return    string
1709
+	 */
1710
+	public static function display_registration_footer()
1711
+	{
1712
+		if (
1713
+		apply_filters(
1714
+			'FHEE__EE_Front__Controller__show_reg_footer',
1715
+			EE_Registry::instance()->CFG->admin->show_reg_footer
1716
+		)
1717
+		) {
1718
+			add_filter(
1719
+				'FHEE__EEH_Template__powered_by_event_espresso__url',
1720
+				function ($url) {
1721
+					return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url);
1722
+				}
1723
+			);
1724
+			echo apply_filters(
1725
+				'FHEE__EE_Front_Controller__display_registration_footer',
1726
+				\EEH_Template::powered_by_event_espresso(
1727
+					'',
1728
+					'espresso-registration-footer-dv',
1729
+					array('utm_content' => 'registration_checkout')
1730
+				)
1731
+			);
1732
+		}
1733
+		return '';
1734
+	}
1735
+
1736
+
1737
+
1738
+	/**
1739
+	 *    unlock_transaction
1740
+	 *
1741
+	 * @access    public
1742
+	 * @return    void
1743
+	 * @throws EE_Error
1744
+	 */
1745
+	public function unlock_transaction()
1746
+	{
1747
+		if ($this->checkout->transaction instanceof EE_Transaction) {
1748
+			$this->checkout->transaction->unlock();
1749
+		}
1750
+	}
1751
+
1752
+
1753
+
1754
+	/**
1755
+	 *        _setup_redirect
1756
+	 *
1757
+	 * @access    private
1758
+	 * @return void
1759
+	 */
1760
+	private function _setup_redirect()
1761
+	{
1762
+		if ($this->checkout->continue_reg && $this->checkout->next_step instanceof EE_SPCO_Reg_Step) {
1763
+			$this->checkout->redirect = true;
1764
+			if (empty($this->checkout->redirect_url)) {
1765
+				$this->checkout->redirect_url = $this->checkout->next_step->reg_step_url();
1766
+			}
1767
+			$this->checkout->redirect_url = apply_filters(
1768
+				'FHEE__EED_Single_Page_Checkout___setup_redirect__checkout_redirect_url',
1769
+				$this->checkout->redirect_url,
1770
+				$this->checkout
1771
+			);
1772
+		}
1773
+	}
1774
+
1775
+
1776
+
1777
+	/**
1778
+	 *   handle ajax message responses and redirects
1779
+	 *
1780
+	 * @access public
1781
+	 * @return void
1782
+	 * @throws EE_Error
1783
+	 */
1784
+	public function go_to_next_step()
1785
+	{
1786
+		if (EE_Registry::instance()->REQ->ajax) {
1787
+			// capture contents of output buffer we started earlier in the request, and insert into JSON response
1788
+			$this->checkout->json_response->set_unexpected_errors(ob_get_clean());
1789
+		}
1790
+		$this->unlock_transaction();
1791
+		// just return for these conditions
1792
+		if (
1793
+			$this->checkout->admin_request
1794
+			|| $this->checkout->action === 'redirect_form'
1795
+			|| $this->checkout->action === 'update_checkout'
1796
+		) {
1797
+			// DEBUG LOG
1798
+			$this->checkout->log(
1799
+				__CLASS__, __FUNCTION__, __LINE__,
1800
+				array(
1801
+					'action'                     => $this->checkout->action,
1802
+					'redirect'                   => $this->checkout->redirect,
1803
+					'json_response_redirect_url' => $this->checkout->json_response->redirect_url(),
1804
+					'redirect_url'               => $this->checkout->redirect_url,
1805
+					'continue_reg'               => $this->checkout->continue_reg,
1806
+				)
1807
+			);
1808
+			return;
1809
+		}
1810
+		// AJAX response
1811
+		$this->_handle_json_response();
1812
+		// redirect to next step or the Thank You page
1813
+		$this->_handle_html_redirects();
1814
+		// hmmm... must be something wrong, so let's just display the form again !
1815
+		$this->_display_spco_reg_form();
1816
+	}
1817
+
1818
+
1819
+
1820
+	/**
1821
+	 *   _handle_json_response
1822
+	 *
1823
+	 * @access protected
1824
+	 * @return void
1825
+	 */
1826
+	protected function _handle_json_response()
1827
+	{
1828
+		// if this is an ajax request
1829
+		if (EE_Registry::instance()->REQ->ajax) {
1830
+			// DEBUG LOG
1831
+			$this->checkout->log(
1832
+				__CLASS__, __FUNCTION__, __LINE__,
1833
+				array(
1834
+					'redirect'                   => $this->checkout->redirect,
1835
+					'json_response_redirect_url' => $this->checkout->json_response->redirect_url(),
1836
+					'redirect_url'               => $this->checkout->redirect_url,
1837
+					'continue_reg'               => $this->checkout->continue_reg,
1838
+				)
1839
+			);
1840
+			$this->checkout->json_response->set_registration_time_limit(
1841
+				$this->checkout->get_registration_time_limit()
1842
+			);
1843
+			$this->checkout->json_response->set_payment_amount($this->checkout->amount_owing);
1844
+			// just send the ajax (
1845
+			$json_response = apply_filters(
1846
+				'FHEE__EE_Single_Page_Checkout__JSON_response',
1847
+				$this->checkout->json_response
1848
+			);
1849
+			echo $json_response;
1850
+			exit();
1851
+		}
1852
+	}
1853
+
1854
+
1855
+
1856
+	/**
1857
+	 *   _handle_redirects
1858
+	 *
1859
+	 * @access protected
1860
+	 * @return void
1861
+	 */
1862
+	protected function _handle_html_redirects()
1863
+	{
1864
+		// going somewhere ?
1865
+		if ($this->checkout->redirect && ! empty($this->checkout->redirect_url)) {
1866
+			// store notices in a transient
1867
+			EE_Error::get_notices(false, true, true);
1868
+			// DEBUG LOG
1869
+			$this->checkout->log(
1870
+				__CLASS__, __FUNCTION__, __LINE__,
1871
+				array(
1872
+					'headers_sent' => headers_sent(),
1873
+					'redirect_url'     => $this->checkout->redirect_url,
1874
+					'headers_list'    => headers_list(),
1875
+				)
1876
+			);
1877
+			wp_safe_redirect($this->checkout->redirect_url);
1878
+			exit();
1879
+		}
1880
+	}
1881
+
1882
+
1883
+
1884
+	/**
1885
+	 *   set_checkout_anchor
1886
+	 *
1887
+	 * @access public
1888
+	 * @return void
1889
+	 */
1890
+	public function set_checkout_anchor()
1891
+	{
1892
+		echo '<a id="checkout" style="float: left; margin-left: -999em;"></a>';
1893
+	}
1894 1894
 
1895 1895
 
1896 1896
 
Please login to merge, or discard this patch.
Spacing   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -218,19 +218,19 @@  discard block
 block discarded – undo
218 218
      */
219 219
     public static function set_definitions()
220 220
     {
221
-        if(defined('SPCO_BASE_PATH')) {
221
+        if (defined('SPCO_BASE_PATH')) {
222 222
             return;
223 223
         }
224 224
         define(
225 225
             'SPCO_BASE_PATH',
226
-            rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS) . DS
226
+            rtrim(str_replace(array('\\', '/'), DS, plugin_dir_path(__FILE__)), DS).DS
227 227
         );
228
-        define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css' . DS);
229
-        define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img' . DS);
230
-        define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js' . DS);
231
-        define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc' . DS);
232
-        define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps' . DS);
233
-        define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates' . DS);
228
+        define('SPCO_CSS_URL', plugin_dir_url(__FILE__).'css'.DS);
229
+        define('SPCO_IMG_URL', plugin_dir_url(__FILE__).'img'.DS);
230
+        define('SPCO_JS_URL', plugin_dir_url(__FILE__).'js'.DS);
231
+        define('SPCO_INC_PATH', SPCO_BASE_PATH.'inc'.DS);
232
+        define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH.'reg_steps'.DS);
233
+        define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH.'templates'.DS);
234 234
         EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true);
235 235
         EE_Registry::$i18n_js_strings['registration_expiration_notice'] = sprintf(
236 236
             __('%1$sWe\'re sorry, but you\'re registration time has expired.%2$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please except our apologies for any inconvenience this may have caused.%8$s',
@@ -239,7 +239,7 @@  discard block
 block discarded – undo
239 239
             '</h4>',
240 240
             '<br />',
241 241
             '<p>',
242
-            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
242
+            '<a href="'.get_post_type_archive_link('espresso_events').'" title="',
243 243
             '">',
244 244
             '</a>',
245 245
             '</p>'
@@ -262,7 +262,7 @@  discard block
 block discarded – undo
262 262
             return;
263 263
         }
264 264
         // filter list of reg_steps
265
-        $reg_steps_to_load = (array)apply_filters(
265
+        $reg_steps_to_load = (array) apply_filters(
266 266
             'AHEE__SPCO__load_reg_steps__reg_steps_to_load',
267 267
             EED_Single_Page_Checkout::get_reg_steps()
268 268
         );
@@ -314,25 +314,25 @@  discard block
 block discarded – undo
314 314
         if (empty($reg_steps)) {
315 315
             $reg_steps = array(
316 316
                 10  => array(
317
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'attendee_information',
317
+                    'file_path'  => SPCO_REG_STEPS_PATH.'attendee_information',
318 318
                     'class_name' => 'EE_SPCO_Reg_Step_Attendee_Information',
319 319
                     'slug'       => 'attendee_information',
320 320
                     'has_hooks'  => false,
321 321
                 ),
322 322
                 20  => array(
323
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'registration_confirmation',
323
+                    'file_path'  => SPCO_REG_STEPS_PATH.'registration_confirmation',
324 324
                     'class_name' => 'EE_SPCO_Reg_Step_Registration_Confirmation',
325 325
                     'slug'       => 'registration_confirmation',
326 326
                     'has_hooks'  => false,
327 327
                 ),
328 328
                 30  => array(
329
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'payment_options',
329
+                    'file_path'  => SPCO_REG_STEPS_PATH.'payment_options',
330 330
                     'class_name' => 'EE_SPCO_Reg_Step_Payment_Options',
331 331
                     'slug'       => 'payment_options',
332 332
                     'has_hooks'  => true,
333 333
                 ),
334 334
                 999 => array(
335
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'finalize_registration',
335
+                    'file_path'  => SPCO_REG_STEPS_PATH.'finalize_registration',
336 336
                     'class_name' => 'EE_SPCO_Reg_Step_Finalize_Registration',
337 337
                     'slug'       => 'finalize_registration',
338 338
                     'has_hooks'  => false,
@@ -514,9 +514,9 @@  discard block
 block discarded – undo
514 514
             // initialize each reg step, which gives them the chance to potentially alter the process
515 515
             $this->_initialize_reg_steps();
516 516
             // DEBUG LOG
517
-            $this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
517
+            $this->checkout->log(__CLASS__, __FUNCTION__, __LINE__);
518 518
             // get reg form
519
-            if( ! $this->_check_form_submission()) {
519
+            if ( ! $this->_check_form_submission()) {
520 520
                 EED_Single_Page_Checkout::$_initialized = true;
521 521
                 return;
522 522
             }
@@ -557,7 +557,7 @@  discard block
 block discarded – undo
557 557
         );
558 558
         // is session still valid ?
559 559
         if ($clear_session_requested
560
-            || ( EE_Registry::instance()->SSN->expired()
560
+            || (EE_Registry::instance()->SSN->expired()
561 561
               && EE_Registry::instance()->REQ->get('e_reg_url_link', '') === ''
562 562
             )
563 563
         ) {
@@ -566,7 +566,7 @@  discard block
 block discarded – undo
566 566
             // EE_Registry::instance()->SSN->reset_cart();
567 567
             // EE_Registry::instance()->SSN->reset_checkout();
568 568
             // EE_Registry::instance()->SSN->reset_transaction();
569
-            if (! $clear_session_requested) {
569
+            if ( ! $clear_session_requested) {
570 570
                 EE_Error::add_attention(
571 571
                     EE_Registry::$i18n_js_strings['registration_expiration_notice'],
572 572
                     __FILE__, __FUNCTION__, __LINE__
@@ -1125,7 +1125,7 @@  discard block
 block discarded – undo
1125 1125
                     if ( ! $registration instanceof EE_Registration) {
1126 1126
                         throw new InvalidEntityException($registration, 'EE_Registration');
1127 1127
                     }
1128
-                    $registrations[ $registration->ID() ] = $registration;
1128
+                    $registrations[$registration->ID()] = $registration;
1129 1129
                 }
1130 1130
             }
1131 1131
             $registration_processor->fix_reg_final_price_rounding_issue($transaction);
@@ -1386,7 +1386,7 @@  discard block
 block discarded – undo
1386 1386
                         ) {
1387 1387
                             EE_Error::add_success(
1388 1388
                                 $this->checkout->current_step->success_message()
1389
-                                . '<br />' . $this->checkout->next_step->_instructions()
1389
+                                . '<br />'.$this->checkout->next_step->_instructions()
1390 1390
                             );
1391 1391
                         }
1392 1392
                         // pack it up, pack it in...
@@ -1511,7 +1511,7 @@  discard block
 block discarded – undo
1511 1511
             '</h4>',
1512 1512
             '<br />',
1513 1513
             '<p>',
1514
-            '<a href="' . get_post_type_archive_link('espresso_events') . '" title="',
1514
+            '<a href="'.get_post_type_archive_link('espresso_events').'" title="',
1515 1515
             '">',
1516 1516
             '</a>',
1517 1517
             '</p>'
@@ -1543,7 +1543,7 @@  discard block
 block discarded – undo
1543 1543
         // load css
1544 1544
         wp_register_style(
1545 1545
             'single_page_checkout',
1546
-            SPCO_CSS_URL . 'single_page_checkout.css',
1546
+            SPCO_CSS_URL.'single_page_checkout.css',
1547 1547
             array('espresso_default'),
1548 1548
             EVENT_ESPRESSO_VERSION
1549 1549
         );
@@ -1551,21 +1551,21 @@  discard block
 block discarded – undo
1551 1551
         // load JS
1552 1552
         wp_register_script(
1553 1553
             'jquery_plugin',
1554
-            EE_THIRD_PARTY_URL . 'jquery	.plugin.min.js',
1554
+            EE_THIRD_PARTY_URL.'jquery	.plugin.min.js',
1555 1555
             array('jquery'),
1556 1556
             '1.0.1',
1557 1557
             true
1558 1558
         );
1559 1559
         wp_register_script(
1560 1560
             'jquery_countdown',
1561
-            EE_THIRD_PARTY_URL . 'jquery	.countdown.min.js',
1561
+            EE_THIRD_PARTY_URL.'jquery	.countdown.min.js',
1562 1562
             array('jquery_plugin'),
1563 1563
             '2.0.2',
1564 1564
             true
1565 1565
         );
1566 1566
         wp_register_script(
1567 1567
             'single_page_checkout',
1568
-            SPCO_JS_URL . 'single_page_checkout.js',
1568
+            SPCO_JS_URL.'single_page_checkout.js',
1569 1569
             array('espresso_core', 'underscore', 'ee_form_section_validation', 'jquery_countdown'),
1570 1570
             EVENT_ESPRESSO_VERSION,
1571 1571
             true
@@ -1588,7 +1588,7 @@  discard block
 block discarded – undo
1588 1588
          *      AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information
1589 1589
          */
1590 1590
         do_action(
1591
-            'AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(),
1591
+            'AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__'.$this->checkout->current_step->slug(),
1592 1592
             $this
1593 1593
         );
1594 1594
     }
@@ -1642,7 +1642,7 @@  discard block
 block discarded – undo
1642 1642
                     'layout_strategy' =>
1643 1643
                         new EE_Template_Layout(
1644 1644
                             array(
1645
-                                'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php',
1645
+                                'layout_template_file' => SPCO_TEMPLATES_PATH.'registration_page_wrapper.template.php',
1646 1646
                                 'template_args'        => array(
1647 1647
                                     'empty_cart'              => $empty_cart,
1648 1648
                                     'revisit'                 => $this->checkout->revisit,
@@ -1717,7 +1717,7 @@  discard block
 block discarded – undo
1717 1717
         ) {
1718 1718
             add_filter(
1719 1719
                 'FHEE__EEH_Template__powered_by_event_espresso__url',
1720
-                function ($url) {
1720
+                function($url) {
1721 1721
                     return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url);
1722 1722
                 }
1723 1723
             );
Please login to merge, or discard this patch.